Kobalte.v0.13.7

Search

Search a searchbox text input with a menu. Handle the case where dataset filtering needs to occur outside the combobox component.

Import

ts
import { Search } from "@kobalte/core/search";
// or
import { Root, Label, ... } from "@kobalte/core/search";
ts
import { Search } from "@kobalte/core/search";
// or
import { Root, Label, ... } from "@kobalte/core/search";

Features

  • Inherits all the features of combobox, except result filtering which should be managed externally.
  • Debouncing text input to rate limit search suggestions calls.
  • Optional indicator to show when suggestions are loading.

Anatomy

The search consists of:

  • Search: The root container for a search component.
  • Search.Label: The label that gives the user information on the search component.
  • Search.Description: The description that gives the user more information on the component.
  • Search.Control: Contains the search input and indicator.
  • Search.Indicator: Wrapper for icon to indicate loading status.
  • Search.Icon: A small icon often displayed next to the input as a visual affordance for the fact it can be open.
  • Search.Input: The input used to search and reflects the selected suggestion values.
  • Search.Portal: Portals its children into the body when the search is open.
  • Search.Content: Contains the content to be rendered when the search is open.
  • Search.Arrow: An optional arrow element to render alongside the search content.
  • Search.Listbox: Contains a list of items and allows a user to search one or more of them.
  • Search.Section: Used to render the label of an option group. It won't be focusable using arrow keys.
  • Search.Item: An item of the search suggestion.
  • Search.ItemLabel: An accessible label to be announced for the item.
  • Search.ItemDescription: An optional accessible description to be announced for the item.
  • Search.NoResult: Displayed when no suggestion options are given.
tsx
<Search>
<Search.Label />
<Search.Control>
<Search.Indicator>
<Search.Icon />
</Search.Indicator>
<Search.Input />
</Search.Control>
<Search.Description />
<Search.Portal>
<Search.Content>
<Search.Arrow />
<Search.Listbox />
<Search.NoResult>
</Search.Content>
</Search.Portal>
</Search>
tsx
<Search>
<Search.Label />
<Search.Control>
<Search.Indicator>
<Search.Icon />
</Search.Indicator>
<Search.Input />
</Search.Control>
<Search.Description />
<Search.Portal>
<Search.Content>
<Search.Arrow />
<Search.Listbox />
<Search.NoResult>
</Search.Content>
</Search.Portal>
</Search>

Example

Emoji selected:

Usage

Debounce

Set debounceOptionsMillisecond, to prevent new search queries immediately on input change. Instead, search queries are requested once input is idle for a set time.

Show a debouncing icon by adding a loadingComponent to Search.Indicator.

Emoji selected:
tsx
<Search
triggerMode="focus"
options={options()}
onInputChange={query => setOptions(queryEmojiData(query))}
onChange={result => setEmoji(result)}
debounceOptionsMillisecond={300}
optionValue="name"
optionLabel="name"
placeholder="Search an emoji…"
itemComponent={(props: any) => (
<Search.Item item={props.item}>
<Search.ItemLabel>{props.item.rawValue.emoji}</Search.ItemLabel>
</Search.Item>
)}
>
<Search.Control aria-label="Emoji">
<Search.Indicator
loadingComponent={
<Search.Icon>
<ReloadIcon />
</Search.Icon>
}
>
<Search.Icon>
<MagnifyingGlassIcon />
</Search.Icon>
</Search.Indicator>
<Search.Input />
</Search.Control>
<Search.Portal>
<Search.Content onCloseAutoFocus={(e) => e.preventDefault()}>
<Search.Listbox />
<Search.NoResult>
😬 No emoji found
</Search.NoResult>
</Search.Content>
</Search.Portal>
</Search>
tsx
<Search
triggerMode="focus"
options={options()}
onInputChange={query => setOptions(queryEmojiData(query))}
onChange={result => setEmoji(result)}
debounceOptionsMillisecond={300}
optionValue="name"
optionLabel="name"
placeholder="Search an emoji…"
itemComponent={(props: any) => (
<Search.Item item={props.item}>
<Search.ItemLabel>{props.item.rawValue.emoji}</Search.ItemLabel>
</Search.Item>
)}
>
<Search.Control aria-label="Emoji">
<Search.Indicator
loadingComponent={
<Search.Icon>
<ReloadIcon />
</Search.Icon>
}
>
<Search.Icon>
<MagnifyingGlassIcon />
</Search.Icon>
</Search.Indicator>
<Search.Input />
</Search.Control>
<Search.Portal>
<Search.Content onCloseAutoFocus={(e) => e.preventDefault()}>
<Search.Listbox />
<Search.NoResult>
😬 No emoji found
</Search.NoResult>
</Search.Content>
</Search.Portal>
</Search>

Cmdk style

To achieve the command menu look, add the open prop to permanently open dropdown. Replace Search.Portal and Search.Content with a div to directly mount your content below the search input.

    😬 No emoji found
    Emoji selected:
    tsx
    <Search
    open
    options={options()}
    onInputChange={query => setOptions(queryEmojiData(query))}
    onChange={result => setEmoji(result)}
    debounceOptionsMillisecond={300}
    optionValue="name"
    optionLabel="name"
    placeholder="Search an emoji…"
    itemComponent={(props: any) => (
    <Search.Item item={props.item}>
    <Search.ItemLabel>{props.item.rawValue.emoji}</Search.ItemLabel>
    </Search.Item>
    )}
    >
    <Search.Control aria-label="Emoji">
    <Search.Indicator>
    <Search.Icon>
    <MagnifyingGlassIcon />
    </Search.Icon>
    </Search.Indicator>
    <Search.Input />
    </Search.Control>
    <div>
    <Search.Listbox />
    <Search.NoResult>
    😬 No emoji found
    </Search.NoResult>
    </div>
    </Search>
    tsx
    <Search
    open
    options={options()}
    onInputChange={query => setOptions(queryEmojiData(query))}
    onChange={result => setEmoji(result)}
    debounceOptionsMillisecond={300}
    optionValue="name"
    optionLabel="name"
    placeholder="Search an emoji…"
    itemComponent={(props: any) => (
    <Search.Item item={props.item}>
    <Search.ItemLabel>{props.item.rawValue.emoji}</Search.ItemLabel>
    </Search.Item>
    )}
    >
    <Search.Control aria-label="Emoji">
    <Search.Indicator>
    <Search.Icon>
    <MagnifyingGlassIcon />
    </Search.Icon>
    </Search.Indicator>
    <Search.Input />
    </Search.Control>
    <div>
    <Search.Listbox />
    <Search.NoResult>
    😬 No emoji found
    </Search.NoResult>
    </div>
    </Search>

    API Reference

    Search

    Search is equivalent to the Root import from @kobalte/core/search.

    PropDescription
    optionsArray<T | U>
    An array of options to display as the available options.
    optionValuekeyof T | ((option: T) => string | number)
    Property name or getter function to use as the value of an option. This is the value that will be submitted when the search component is part of a <form>.
    optionTextValuekeyof T | ((option: T) => string)
    Property name or getter function to use as the text value of an option for typeahead purpose.
    optionLabelkeyof T | ((option: T) => string)
    Property name or getter function to use as the label of an option. This is the string representation of the option to display in the Search.Input.
    optionDisabledkeyof T | ((option: T) => boolean)
    Property name or getter function to use as the disabled flag of an option.
    optionGroupChildrenkeyof U
    Property name that refers to the children options of an option group.
    itemComponentComponent<SearchItemComponentProps<T>>
    When NOT virtualized, the component to render as an item in the Search.Listbox.
    sectionComponentComponent<SearchSectionComponentProps<U>>
    When NOT virtualized, the component to render as a section in the Search.Listbox.
    multipleboolean
    Whether the search component allows multi-selection.
    placeholderJSX.Element
    The content that will be rendered when no value or defaultValue is set.
    valueT | Array<T>
    The controlled value of the search input.
    defaultValueT | Array<T>
    The value of the search input when initially rendered. Useful when you do not need to control the value.
    onChange(value: T | Array<T>) => void
    Event handler called when the value changes.
    openboolean
    The controlled open state of the search suggestion.
    defaultOpenboolean
    The default open state when initially rendered. Useful when you do not need to control the open state.
    onOpenChange(open: boolean, triggerMode?: SearchTriggerMode) => void
    Event handler called when the open state of the search component changes. Returns the new open state and the action that caused the opening of the menu.
    onInputChange(value: string) => void
    Handler that is called when the search input value changes.
    triggerModeSearchTriggerMode
    The interaction required to display search suggestion, it can be one of the following:
    - input: open search suggestion when the user is typing.
    - focus: open search suggestion when the input is focused.
    - manual: open search suggestion when pressing arrow down/up while focus is on the input or clicking on the trigger.
    removeOnBackspaceboolean
    When multiple is true, whether the last selected option should be removed when the user press the Backspace key and the input is empty.
    allowDuplicateSelectionEventsboolean
    Whether onChange should fire even if the new value is the same as the last.
    disallowEmptySelectionboolean
    Whether the search component allows empty selection or not.
    allowsEmptyCollectionboolean
    Whether the search component allows the menu to be open when the collection is empty.
    closeOnSelectionboolean
    Whether the search component closes after selection.
    selectionBehavior'toggle' | 'replace'
    How selection should behave in the search component.
    virtualizedboolean
    Whether the search suggestion uses virtual scrolling.
    modalboolean
    Whether the search component should be the only visible content for screen readers, when set to true:
    - interaction with outside elements will be disabled.
    - scroll will be locked.
    - focus will be locked inside the search component content.
    - elements outside the search component content will not be visible for screen readers.
    preventScrollboolean
    Whether the scroll should be locked even if the search suggestion is not modal.
    forceMountboolean
    Used to force mounting the search suggestion (portal, positioner and content) when more control is needed. Useful when controlling animation with SolidJS animation libraries.
    namestring
    The name of the search component. Submitted with its owning form as part of a name/value pair.
    validationState'valid' | 'invalid'
    Whether the search component should display its "valid" or "invalid" visual styling.
    requiredboolean
    Whether the user must select an item before the owning form can be submitted.
    disabledboolean
    Whether the search component is disabled.
    readOnlyboolean
    Whether the search component items can be selected but not changed by the user.
    autoCompletestring
    Describes the type of autocomplete functionality the input should provide if any. See MDN
    translationsSearchIntlTranslations
    Localization strings.

    Search also accepts the following props to customize the placement of the Search.Content.

    PropDescription
    placementPlacement
    The placement of the search component content.
    gutternumber
    The distance between the search component content and the trigger element.
    shiftnumber
    The skidding of the search component content along the trigger element.
    flipboolean | string
    Controls the behavior of the search component content when it overflows the viewport:
    - If a boolean, specifies whether the search component content should flip to the opposite side when it overflows.
    - If a string, indicates the preferred fallback placements when it overflows.
    The placements must be spaced-delimited, e.g. "top left".
    slideboolean
    Whether the search component content should slide when it overflows.
    overlapboolean
    Whether the search component content can overlap the trigger element when it overflows.
    sameWidthboolean
    Whether the search component content should have the same width as the trigger element. This will be exposed to CSS as --kb-popper-anchor-width.
    fitViewportboolean
    Whether the search component content should fit the viewport. If this is set to true, the search component content will have maxWidth and maxHeight set to the viewport size. This will be exposed to CSS as --kb-popper-available-width and --kb-popper-available-height.
    hideWhenDetachedboolean
    Whether to hide the search component content when the trigger element becomes occluded.
    detachedPaddingnumber
    The minimum padding in order to consider the trigger element occluded.
    arrowPaddingnumber
    The minimum padding between the arrow and the search component content corner.
    overflowPaddingnumber
    The minimum padding between the search component content and the viewport edge. This will be exposed to CSS as --kb-popper-overflow-padding.
    Data attributeDescription
    data-validPresent when the search component is valid according to the validation rules.
    data-invalidPresent when the search component is invalid according to the validation rules.
    data-requiredPresent when the user must select an item before the owning form can be submitted.
    data-disabledPresent when the search component is disabled.
    data-readonlyPresent when the search component is read only.

    Search.Label, Search.Control, Search.Input, Search.Trigger, Search.Description and Search.ErrorMesssage shares the same data-attributes.

    Search.Control

    Render PropDescription
    selectedOptionsAccessor<T[]>
    An array of selected options.
    remove(option: T) => void
    A function to remove an option from the selection.
    clear() => void
    A function to clear the selection.

    Search.Indicator

    PropDescription
    loadingComponentJSX.Element
    The component that is displayed when suggestion options are being fetched.

    Search.Icon

    Data attributeDescription
    data-expandedPresent when the search component is open.
    data-closedPresent when the search component is close.

    Search.Content

    Data attributeDescription
    data-expandedPresent when the search component is open.
    data-closedPresent when the search component is close.

    Search.Arrow

    PropDescription
    sizenumber
    The size of the arrow.

    Search.Listbox

    PropDescription
    scrollRefAccessor<HTMLElement | undefined>
    The ref attached to the scrollable element, used to provide automatic scrolling on item focus. If not provided, defaults to the listbox.
    scrollToItem(key: string) => void
    When virtualized, the Virtualizer function used to scroll to the item of the given key.
    children(items: Accessor<Collection<CollectionNode<T | U>>>) => JSX.Element
    When virtualized, a map function that receives an items signal representing all items and sections.

    Search.Item

    PropDescription
    itemCollectionNode
    The collection node to render.
    Data attributeDescription
    data-disabledPresent when the item is disabled.
    data-selectedPresent when the item is selected.
    data-highlightedPresent when the item is highlighted.

    Search.ItemLabel and Search.ItemDescription shares the same data-attributes.

    Rendered elements

    ComponentDefault rendered element
    Searchdiv
    Search.Labelspan
    Search.Descriptiondiv
    Search.Controldiv
    Search.Indicatordiv
    Search.Iconspan
    Search.Inputinput
    Search.PortalPortal
    Search.Contentdiv
    Search.Arrowdiv
    Search.Listboxul
    Search.Sectionli
    Search.Itemli
    Search.ItemLabeldiv
    Search.ItemDescriptiondiv
    Search.NoResultdiv

    Accessibility

    Keyboard Interactions

    KeyDescription
    EnterWhen focus is virtualy on an item, selects the focused item.
    ArrowDownWhen focus is on the input, opens the search suggestion and virtual focuses the first or selected item.
    When focus is virtualy on an item, moves virtual focus to the next item.
    ArrowUpWhen focus is on the input, opens the search suggestion and virtual focuses the last or selected item.
    When focus is virtualy on an item, moves virtual focus to the previous item.
    Alt + ArrowDownWhen focus is on the input, opens the search suggestion.
    Alt + ArrowUpWhen focus is on the input, closes the search suggestion.
    HomeWhen focus is on the input, moves virtual focus to first item.
    EndWhen focus is on the input, moves virtual focus to last item.
    EscWhen the search suggestion is open, closes the search suggestion.
    When the search suggestion is closed, clear the input and selection.