Skip to content

Modify input value in Search #578

@amad3v

Description

@amad3v

Problem:
Currently, when using the Search component, there are cases where there is need to clear the search input (for example, clearing the input after an item is selected).

At the moment, the only workaround is to use a ref to access the underlying <Search.Input> element and manually change its value (unless I'm missing something).

Proposed Solution:
Expose a controlled input API for the Search component. For example, add a setInputValue prop.

Current workaround

import { createSignal } from "solid-js";
import { Search } from "@kobalte/core/search";
import { MagnifyingGlassIcon, ReloadIcon } from "some-icon-library";
import { queryEmojiData } from "your-search-function";

function App() {
  const [options, setOptions] = createSignal([]);
  const [emoji, setEmoji] = createSignal();
  let inputRef: HTMLInputElement | undefined;

  return (
    <>
      <Search
        triggerMode="focus"
        options={options()}
        onInputChange={(query) => setOptions(queryEmojiData(query))}
        onChange={(result) => {
          setEmoji(result);
          // Manually clear input using a ref
          if (inputRef) {
            inputRef.value = "";
          }
        }}
        optionValue="name"
        optionLabel="name"
        placeholder="Search an emoji…"
        itemComponent={(props) => (
          <Search.Item item={props.item} class="search__item">
            <Search.ItemLabel>{props.item.rawValue.emoji}</Search.ItemLabel>
          </Search.Item>
        )}
      >
        <Search.Control class="search__control" aria-label="Emoji">
          <Search.Indicator
            class="search__indicator"
            loadingComponent={
              <Search.Icon class="load__icon">
                <ReloadIcon class="spin__icon" />
              </Search.Icon>
            }
          >
            <Search.Icon class="search__icon">
              <MagnifyingGlassIcon class="center__icon" />
            </Search.Icon>
          </Search.Indicator>
          {/* Binding ref to access input manually */}
          <Search.Input class="search__input" ref={inputRef} />
        </Search.Control>
        <Search.Portal>
          <Search.Content class="search__content" onCloseAutoFocus={(e) => e.preventDefault()}>
            <Search.Listbox class="search__listbox" />
            <Search.NoResult class="search__no_result">
              😬 No emoji found
            </Search.NoResult>
          </Search.Content>
        </Search.Portal>
      </Search>
      <div class="result__content">
        Emoji selected: {emoji()?.emoji} {emoji()?.name}
      </div>
    </>
  );
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions