Skip to content

fix: add debounced prop and ux to mui search input component - #209

Merged
smarcet merged 7 commits into
mainfrom
fix/mui-search-input-debounced
Apr 8, 2026
Merged

fix: add debounced prop and ux to mui search input component#209
smarcet merged 7 commits into
mainfrom
fix/mui-search-input-debounced

Conversation

@tomrndom

@tomrndom tomrndom commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

ref: https://app.clickup.com/t/86b84rhkb

Signed-off-by: Tomás Castillo tcastilloboireau@gmail.com

Summary by CodeRabbit

  • New Features

    • Optional debounced search execution to reduce search frequency
    • Search icon shown at the start of the input when debouncing is disabled
  • Bug Fixes / Improvements

    • Enter now triggers search only when debounced is not enabled
    • Pending debounced searches are canceled on clear and on unmount
    • End adornment now cleanly toggles between clear button and icon based on input
  • Tests

    • Added tests validating debounced typing, callback updates during pending debounces, and Enter-key behavior

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
@coderabbitai

coderabbitai Bot commented Apr 2, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

SearchInput gains an optional debounced prop that wraps onSearch with a lodash debounce (using DEBOUNCE_WAIT), stores latest callback in a ref, cancels pending calls on clear and unmount, updates local searchTerm on input, and only triggers immediate search on Enter when debounced is falsy.

Changes

Cohort / File(s) Summary
SearchInput component
src/components/mui/search-input.js
Adds optional debounced prop; uses refs for latest onSearch and a debounced wrapper (lodash debounce with DEBOUNCE_WAIT); input updates local searchTerm always; onChange calls debounced or immediate onSearch based on prop; Enter triggers onSearch only when not debounced; cancels pending debounced calls on clear and unmount; refactors adornments (startAdornment vs end InputAdornment).
Tests for SearchInput
src/components/mui/__tests__/search-input.test.js
Adds act and DEBOUNCE_WAIT imports; introduces describe("debounced prop") suite using fake timers to verify: typing defers onSearch until debounce wait, pending debounced calls use the latest onSearch after re-render, Enter does not trigger search when debounced, and non-debounced behavior remains unchanged.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SearchInput
    participant DebounceWrapper
    participant Parent_onSearch as Parent onSearch

    User->>SearchInput: type chars / press Enter
    Note right of SearchInput: updates local searchTerm
    alt debounced = true
        SearchInput->>DebounceWrapper: invoke debounced(searchTerm)
        DebounceWrapper-->>SearchInput: schedule call after DEBOUNCE_WAIT
        rect rgba(200,200,255,0.5)
        DebounceWrapper->>Parent_onSearch: call with latest searchTerm (after wait)
        end
    else debounced = false
        SearchInput->>Parent_onSearch: call immediately (onChange or Enter)
    end
    User->>SearchInput: clear input
    SearchInput->>DebounceWrapper: cancel pending (if any)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibble keys and count the ticks,
A silent pause that gently sticks.
Enter waits while echoes thrum,
Debounced hops — then results come.
🥕🔍

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a debounced prop and associated UX improvements to the MUI search input component.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/mui-search-input-debounced

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/mui/search-input.js (1)

58-75: ⚠️ Potential issue | 🟡 Minor

Two issues with adornment logic.

  1. Duplicate search icons: With the new startAdornment always showing a SearchIcon (lines 58-62), the fallback SearchIcon in endAdornment (lines 72-74) creates duplicate icons when no term exists. The end SearchIcon should be removed.

  2. Clear button uses prop instead of state: The condition term ? ... references the prop, not the local searchTerm state. If the user types something but the parent hasn't updated the term prop yet, the clear button won't appear. Use searchTerm for immediate feedback.

🐛 Proposed fix
           startAdornment: (
             <InputAdornment position="start">
               <SearchIcon sx={{ color: "#0000008F" }} />
             </InputAdornment>
           ),
-          endAdornment: term ? (
+          endAdornment: searchTerm ? (
             <IconButton
               size="small"
               onClick={handleClear}
               sx={{ position: "absolute", right: 0 }}
             >
               <ClearIcon sx={{ color: "#0000008F" }} />
             </IconButton>
-          ) : (
-            <SearchIcon
-              sx={{ mr: 1, color: "#0000008F", position: "absolute", right: 0 }}
-            />
-          )
+          ) : null
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/mui/search-input.js` around lines 58 - 75, The adornment logic
currently renders a SearchIcon in both startAdornment and in the endAdornment
fallback and uses the prop term to decide showing the clear button; to fix this
remove the fallback SearchIcon from endAdornment so only the startAdornment
SearchIcon is rendered, and change the clear-button condition to use the local
searchTerm state (instead of the prop term) so the IconButton with
onClick={handleClear} appears immediately when the user types; update the JSX
that defines startAdornment and endAdornment (InputAdornment, SearchIcon,
IconButton, ClearIcon, handleClear, term -> searchTerm) accordingly.
🧹 Nitpick comments (1)
src/components/mui/search-input.js (1)

45-49: Consider allowing Enter key to trigger immediate search even in debounced mode.

Currently, pressing Enter does nothing when debounced is true. Users commonly expect Enter to immediately submit their search query. Consider canceling the pending debounce and triggering the search immediately on Enter.

💡 Optional enhancement
   const handleKeyDown = (ev) => {
-    if (!debounced && ev.key === "Enter") {
+    if (ev.key === "Enter") {
+      onSearchDebounced?.cancel();
       onSearch(searchTerm);
     }
   };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/mui/search-input.js` around lines 45 - 49, handle the Enter
key in handleKeyDown so it triggers an immediate search even when debounced is
true: detect ev.key === "Enter", clear/cancel any pending debounce timer or
cancel the debounced call (e.g., clearTimeout on a timeoutId or call
debounced.cancel if using lodash/debounce), then call onSearch(searchTerm)
immediately; reference handleKeyDown, debounced, onSearch, and searchTerm so the
fix cancels the pending debounce and runs the search right away.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/mui/search-input.js`:
- Around line 33-36: Replace useCallback with useMemo when creating the
debounced function: the current onSearchDebounced is memoizing the result of
debounce((value) => onSearch(value), DEBOUNCE_WAIT) so wrap that expression in
useMemo and include onSearch and debounced in the dependency array (and
debounce/DEBOUNCE_WAIT if not stable) so a stable debounced function instance is
returned; ensure the import for useMemo is added and that when debounced is
false you return null (same behavior) to preserve existing logic.

---

Outside diff comments:
In `@src/components/mui/search-input.js`:
- Around line 58-75: The adornment logic currently renders a SearchIcon in both
startAdornment and in the endAdornment fallback and uses the prop term to decide
showing the clear button; to fix this remove the fallback SearchIcon from
endAdornment so only the startAdornment SearchIcon is rendered, and change the
clear-button condition to use the local searchTerm state (instead of the prop
term) so the IconButton with onClick={handleClear} appears immediately when the
user types; update the JSX that defines startAdornment and endAdornment
(InputAdornment, SearchIcon, IconButton, ClearIcon, handleClear, term ->
searchTerm) accordingly.

---

Nitpick comments:
In `@src/components/mui/search-input.js`:
- Around line 45-49: handle the Enter key in handleKeyDown so it triggers an
immediate search even when debounced is true: detect ev.key === "Enter",
clear/cancel any pending debounce timer or cancel the debounced call (e.g.,
clearTimeout on a timeoutId or call debounced.cancel if using lodash/debounce),
then call onSearch(searchTerm) immediately; reference handleKeyDown, debounced,
onSearch, and searchTerm so the fix cancels the pending debounce and runs the
search right away.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 36d2f051-31fb-4dac-9a9d-5cab289c16a9

📥 Commits

Reviewing files that changed from the base of the PR and between 54bca4e and 10075aa.

📒 Files selected for processing (1)
  • src/components/mui/search-input.js

Comment thread src/components/mui/search-input.js Outdated
tomrndom added 2 commits April 2, 2026 15:29
Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/mui/search-input.js (1)

58-75: ⚠️ Potential issue | 🟠 Major

Use searchTerm for end-adornment state and remove the duplicate search icon.

Line 63 currently keys off term, which can be stale in the new non-debounced flow (typing updates local state but not parent state yet). Also, with the new start adornment (Lines 58-62), the fallback right-side search icon (Lines 71-74) creates duplicate icons.

♻️ Proposed fix
-          endAdornment: term ? (
+          endAdornment: searchTerm ? (
             <IconButton
               size="small"
               onClick={handleClear}
               sx={{ position: "absolute", right: 0 }}
             >
               <ClearIcon sx={{ color: "#0000008F" }} />
             </IconButton>
-          ) : (
-            <SearchIcon
-              sx={{ mr: 1, color: "#0000008F", position: "absolute", right: 0 }}
-            />
-          )
+          ) : null
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/mui/search-input.js` around lines 58 - 75, The endAdornment
currently checks the stale prop/local variable term and renders a duplicate
SearchIcon on the right; change the condition to use the controlled value
searchTerm (the up-to-date state/prop) when deciding to show the Clear button,
and remove the right-side fallback SearchIcon since you already render a
startAdornment SearchIcon; update the endAdornment logic around IconButton and
handleClear to rely on searchTerm and render null (or nothing) when searchTerm
is empty so no duplicate icon appears.
🧹 Nitpick comments (1)
src/components/mui/__tests__/search-input.test.js (1)

63-96: Add a regression test for clearing with a pending debounced call.

Given the new debounced flow, we should explicitly assert that clear does not allow a previously typed value to fire later.

➕ Suggested test case
+    test("clearing input cancels pending debounced search", async () => {
+      const onSearch = jest.fn();
+      const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
+      render(<SearchInput term="initial" onSearch={onSearch} debounced />);
+
+      const input = screen.getByPlaceholderText("Search...");
+      await user.clear(input);
+      await user.type(input, "something");
+      await user.click(screen.getByRole("button"));
+
+      act(() => jest.advanceTimersByTime(DEBOUNCE_WAIT));
+      expect(onSearch).toHaveBeenCalledWith("");
+      expect(onSearch).not.toHaveBeenCalledWith("something");
+    });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/mui/__tests__/search-input.test.js` around lines 63 - 96, Add
a regression test in the "debounced prop" suite for SearchInput that ensures
clearing cancels a pending debounced call: render SearchInput with debounced and
a jest.fn() onSearch, use userEvent.setup({ advanceTimers:
jest.advanceTimersByTime }) to type a value, then trigger the component's clear
action (e.g., click the clear button or invoke the clear control exposed by
SearchInput), advance timers with act(() =>
jest.advanceTimersByTime(DEBOUNCE_WAIT)) and assert onSearch was not called;
keep the test alongside the existing tests and reuse DEBOUNCE_WAIT, SearchInput,
and onSearch identifiers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/mui/search-input.js`:
- Around line 40-43: handleClear can allow a previously scheduled trailing call
from handleChange to fire after the input is cleared; fix by cancelling any
pending debounced work before clearing. In the component, call the debounced
function's cancel method (e.g., debounced.cancel()) if present at the start of
handleClear, then proceed to setSearchTerm('') and emit any immediate clear
behavior (e.g., call onSearch or onSearchDebounced with an empty string as
needed), guarding for the existence of debounced and onSearchDebounced.

---

Outside diff comments:
In `@src/components/mui/search-input.js`:
- Around line 58-75: The endAdornment currently checks the stale prop/local
variable term and renders a duplicate SearchIcon on the right; change the
condition to use the controlled value searchTerm (the up-to-date state/prop)
when deciding to show the Clear button, and remove the right-side fallback
SearchIcon since you already render a startAdornment SearchIcon; update the
endAdornment logic around IconButton and handleClear to rely on searchTerm and
render null (or nothing) when searchTerm is empty so no duplicate icon appears.

---

Nitpick comments:
In `@src/components/mui/__tests__/search-input.test.js`:
- Around line 63-96: Add a regression test in the "debounced prop" suite for
SearchInput that ensures clearing cancels a pending debounced call: render
SearchInput with debounced and a jest.fn() onSearch, use userEvent.setup({
advanceTimers: jest.advanceTimersByTime }) to type a value, then trigger the
component's clear action (e.g., click the clear button or invoke the clear
control exposed by SearchInput), advance timers with act(() =>
jest.advanceTimersByTime(DEBOUNCE_WAIT)) and assert onSearch was not called;
keep the test alongside the existing tests and reuse DEBOUNCE_WAIT, SearchInput,
and onSearch identifiers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0184f1f4-9eaf-4b46-b783-a52629fbeb79

📥 Commits

Reviewing files that changed from the base of the PR and between baef896 and 39bac29.

📒 Files selected for processing (2)
  • src/components/mui/__tests__/search-input.test.js
  • src/components/mui/search-input.js

Comment thread src/components/mui/search-input.js
Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/mui/search-input.js (1)

59-76: ⚠️ Potential issue | 🟠 Major

Duplicate search icons when term is falsy.

The startAdornment always renders a SearchIcon (lines 59-63), and when term is falsy, the endAdornment also renders a SearchIcon (lines 73-75). This results in two search icons displayed simultaneously when the input is empty.

🐛 Proposed fix: Remove the redundant endAdornment SearchIcon
           endAdornment: term ? (
             <IconButton
               size="small"
               onClick={handleClear}
               sx={{ position: "absolute", right: 0 }}
             >
               <ClearIcon sx={{ color: "#0000008F" }} />
             </IconButton>
-          ) : (
-            <SearchIcon
-              sx={{ mr: 1, color: "#0000008F", position: "absolute", right: 0 }}
-            />
-          )
+          ) : null
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/mui/search-input.js` around lines 59 - 76, The UI renders
duplicate SearchIcon components because startAdornment always renders a
SearchIcon and endAdornment renders another SearchIcon when term is falsy;
update the endAdornment logic in the component (the JSX that sets startAdornment
and endAdornment) to remove the redundant SearchIcon branch so endAdornment only
renders the IconButton with ClearIcon when term is truthy (using term and
handleClear) and otherwise renders nothing; keep the startAdornment
InputAdornment with SearchIcon intact and ensure IconButton/clear flow remains
tied to handleClear and ClearIcon.
🧹 Nitpick comments (1)
src/components/mui/search-input.js (1)

28-37: Consider reordering declarations for clarity.

handleClear references onSearchDebounced before it's declared. This works at runtime (the closure is only evaluated when the click handler fires), but it harms readability and can confuse static analysis tools or future maintainers.

♻️ Suggested reordering
+  const onSearchDebounced = useMemo(
+    () => debounced ? debounce((value) => onSearch(value), DEBOUNCE_WAIT) : null,
+    [onSearch, debounced]
+  );
+
   const handleClear = () => {
     onSearchDebounced?.cancel();
     setSearchTerm("");
     onSearch("");
   };
-
-  const onSearchDebounced = useMemo(
-    () => debounced ? debounce((value) => onSearch(value), DEBOUNCE_WAIT) : null,
-    [onSearch, debounced]
-  );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/mui/search-input.js` around lines 28 - 37, Move the
onSearchDebounced declaration (the useMemo that returns debounce((value) =>
onSearch(value), DEBOUNCE_WAIT) or null) above the handleClear function so
handleClear no longer references onSearchDebounced before it's declared; update
handleClear to keep its current logic (onSearchDebounced?.cancel(),
setSearchTerm(""), onSearch("")) but ensure onSearchDebounced is defined earlier
and that the dependency array on the useMemo remains [onSearch, debounced].
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/components/mui/search-input.js`:
- Around line 59-76: The UI renders duplicate SearchIcon components because
startAdornment always renders a SearchIcon and endAdornment renders another
SearchIcon when term is falsy; update the endAdornment logic in the component
(the JSX that sets startAdornment and endAdornment) to remove the redundant
SearchIcon branch so endAdornment only renders the IconButton with ClearIcon
when term is truthy (using term and handleClear) and otherwise renders nothing;
keep the startAdornment InputAdornment with SearchIcon intact and ensure
IconButton/clear flow remains tied to handleClear and ClearIcon.

---

Nitpick comments:
In `@src/components/mui/search-input.js`:
- Around line 28-37: Move the onSearchDebounced declaration (the useMemo that
returns debounce((value) => onSearch(value), DEBOUNCE_WAIT) or null) above the
handleClear function so handleClear no longer references onSearchDebounced
before it's declared; update handleClear to keep its current logic
(onSearchDebounced?.cancel(), setSearchTerm(""), onSearch("")) but ensure
onSearchDebounced is defined earlier and that the dependency array on the
useMemo remains [onSearch, debounced].

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d7d95058-bab2-4ca5-a9a3-453a7069873f

📥 Commits

Reviewing files that changed from the base of the PR and between 39bac29 and 0dd6a00.

📒 Files selected for processing (1)
  • src/components/mui/search-input.js

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
@tomrndom
tomrndom requested a review from smarcet April 2, 2026 19:52
@smarcet
smarcet requested a review from santipalenque April 7, 2026 14:24
Comment thread src/components/mui/search-input.js Outdated
};

const handleClear = () => {
onSearchDebounced?.cancel();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomrndom handleClear references onSearchDebounced before it is declared

Comment thread src/components/mui/search-input.js Outdated
<SearchIcon sx={{ color: "#0000008F" }} />
</InputAdornment>
),
endAdornment: term && (

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomrndom
Clear button hidden during debounced typing
in debounced mode the parent doesn't learn about the new value for 500ms. The user types, there is text in the box, but no clear affordance until the debounce flushes , the affordance the icon refactor was supposed to improve. Pre-existing pattern, but debouncing amplifies it materiall.
Suggested fix
Use the local searchTerm (or searchTerm || term) to drive the clear-button visibility.

Comment thread src/components/mui/search-input.js Outdated
<SearchIcon
sx={{ mr: 1, color: "#0000008F", position: "absolute", right: 0 }}
/>
startAdornment: (

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomrndom
Visual/contract change for ALL existing consumers (regardless of debounced)
keep the legacy single-icon layout when debounced is not set

Comment thread src/components/mui/search-input.js Outdated
onSearch("");
};

const onSearchDebounced = useMemo(

@smarcet smarcet Apr 7, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomrndom
debounce silently broken when parent passes inline onSearch.
useMemo recomputes whenever onSearch changes identity. The cleanup effect then cancel()s the previous debounced instance. A debounced function cancelled before its timer fires loses its pending invocation forever. That is the entire bug.

Why the existing tests miss it

  render(<SearchInput term="" onSearch={onSearch} debounced />);

In a test, onSearch is a stable jest.fn() reference and there are no parent re-renders. So useMemo never recomputes, the debounced function is never cancelled, and the timer fires normally. The test passes. Production breaks.

Proposed fix

Replace the current memoization with a ref-stable wrapper so the debounced function is created once per debounced value and is not destroyed by parent re-renders, while still calling the latest
onSearch.

@smarcet smarcet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomrndom please review comments

…arent re render

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
Comment thread src/components/mui/search-input.js Outdated
}, [onSearch]);

const onSearchDebouncedRef = useRef(
debounced

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need this condition here, onSearchDebouncedRef is only called when debounced is true

Comment thread src/components/mui/search-input.js Outdated
<ClearIcon fontSize="small" sx={{ color: "#0000008F" }} />
</IconButton>
) : (
<SearchIcon

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so if no searchTerm and not debounced we have two searchIcons at start AND end adornments ? Doesn't look right

…ebouncedRef

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
@smarcet
smarcet requested review from santipalenque and smarcet April 8, 2026 16:08

@santipalenque santipalenque left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@smarcet smarcet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@smarcet
smarcet merged commit a35347c into main Apr 8, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants