Skip to content
design
Components

Combobox

A searchable choice whose value is a selected item, separate from the search query.

On this page

Select a known audience.

A searchable choice whose value is a selected item, separate from the search query.
Code
import { Combobox } from "@bosunkit/components/combobox";
import { Field } from "@bosunkit/components/field";
import type { ReactElement } from "react";
const items: readonly string[] = ["Engineering", "Product", "Investors"];
export const description: string =
  "Search the known audiences; typing filters the list and choosing commits one of its values.";
export default function Showcase(): ReactElement {
  return (
    <Field.Root>
      <Field.Label>Audience</Field.Label>
      <Combobox.Root items={items} defaultValue="Engineering">
        <Combobox.Input />
        <Combobox.Portal>
          <Combobox.Positioner sideOffset={4}>
            <Combobox.Popup>
              <Combobox.Empty>No matching audience</Combobox.Empty>
              <Combobox.List>
                {(item: string): ReactElement => (
                  <Combobox.Item key={item} value={item}>
                    {item}
                  </Combobox.Item>
                )}
              </Combobox.List>
            </Combobox.Popup>
          </Combobox.Positioner>
        </Combobox.Portal>
      </Combobox.Root>
      <Field.Description>Select a known audience.</Field.Description>
    </Field.Root>
  );
}
01Names describe behaviorUse the primitive for custom composition and a named recipe for an assembled control.
02One state contractControlled values, defaults and change callbacks follow Base UI; event details keep their reason and cancellation.
03Composition keeps semanticsA render target forwards its ref and every received DOM prop so keyboard interaction and accessible names survive.

Composition

Import { Combobox } from @bosunkit/components/combobox. Named parts follow Base UI Combobox. Each part retains the upstream render, ref, DOM props, state attributes and event contracts. The kit supplies its typography, surfaces and scoped overlay presentation.

Examples

Custom composition

Select a known audience.

Search the known audiences; typing filters the list and choosing commits one of its values.
Code
import { Combobox } from "@bosunkit/components/combobox";
import { Field } from "@bosunkit/components/field";
import type { ReactElement } from "react";
const items: readonly string[] = ["Engineering", "Product", "Investors"];
export const description: string =
  "Search the known audiences; typing filters the list and choosing commits one of its values.";
export default function Showcase(): ReactElement {
  return (
    <Field.Root>
      <Field.Label>Audience</Field.Label>
      <Combobox.Root items={items} defaultValue="Engineering">
        <Combobox.Input />
        <Combobox.Portal>
          <Combobox.Positioner sideOffset={4}>
            <Combobox.Popup>
              <Combobox.Empty>No matching audience</Combobox.Empty>
              <Combobox.List>
                {(item: string): ReactElement => (
                  <Combobox.Item key={item} value={item}>
                    {item}
                  </Combobox.Item>
                )}
              </Combobox.List>
            </Combobox.Popup>
          </Combobox.Positioner>
        </Combobox.Portal>
      </Combobox.Root>
      <Field.Description>Select a known audience.</Field.Description>
    </Field.Root>
  );
}

Props

PropTypeDefaultDescription
disabledboolean | undefined–Whether the component should ignore user interaction.
classNamestring | ((state: State) => string | undefined) | undefined–CSS class applied to the element, or a function that returns a class based on the component's state.
renderReact.ReactElement | ComponentRenderFn<RenderFunctionProps, State> | undefined–Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleReact.CSSProperties | ((state: State) => React.CSSProperties | undefined) | undefined–Style applied to the element, or a function that returns a style object based on the component's state.

Also takes every attribute of Primitive.Input.Props.

PropTypeDefaultDescription
initialFocusboolean | React.RefObject<HTMLElement | null> | ((openType: InteractionType) => void | boolean | HTMLElement | null) | undefined–Determines the element to focus when the popup is opened. - false: Do not move focus. - true: Move focus based on the default behavior (first tabbable element or popup). - RefObject: Move focus to the ref element. - function: Called with the interaction type (mouse, touch, pen, or keyboard). Return an element to focus, true to use the default behavior, or false/undefined to do nothing.
finalFocusboolean | React.RefObject<HTMLElement | null> | ((closeType: InteractionType) => void | boolean | HTMLElement | null) | undefined–Determines the element to focus when the popup is closed. - false: Do not move focus. - true: Move focus based on the default behavior (trigger or previously focused element). - RefObject: Move focus to the ref element. - function: Called with the interaction type (mouse, touch, pen, or keyboard). Return an element to focus, true to use the default behavior, or false/undefined to do nothing.
classNamestring | ((state: State) => string | undefined) | undefined–CSS class applied to the element, or a function that returns a class based on the component's state.
renderReact.ReactElement | ComponentRenderFn<RenderFunctionProps, State> | undefined–Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleReact.CSSProperties | ((state: State) => React.CSSProperties | undefined) | undefined–Style applied to the element, or a function that returns a style object based on the component's state.

Also takes every attribute of Primitive.Popup.Props.

PropTypeDefaultDescription
childrenReact.ReactNode–
onClickBaseUIComponentProps<'div', ComboboxItemState>['onClick'] | undefined–An optional click handler for the item when selected. It fires when clicking the item with the pointer, as well as when pressing Enter with the keyboard if the item is highlighted when the Input or List element has focus.
indexnumber | undefined–The index of the item in the list. Improves performance when specified by avoiding the need to calculate the index automatically from the DOM.
valueany–A unique value that identifies this item.
disabledboolean | undefined–Whether the component should ignore user interaction.
classNamestring | ((state: State) => string | undefined) | undefined–CSS class applied to the element, or a function that returns a class based on the component's state.
renderReact.ReactElement | ComponentRenderFn<RenderFunctionProps, State> | undefined–Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleReact.CSSProperties | ((state: State) => React.CSSProperties | undefined) | undefined–Style applied to the element, or a function that returns a style object based on the component's state.
nativeButtonboolean | undefined–Whether the component renders a native <button> element when replacing it via the render prop. Set to true if the rendered element is a native button.

Also takes every attribute of Primitive.Item.Props.

PropTypeDefaultDescription
childrenReact.ReactNode | ((item: any, index: number) => React.ReactNode)–
classNamestring | ((state: State) => string | undefined) | undefined–CSS class applied to the element, or a function that returns a class based on the component's state.
renderReact.ReactElement | ComponentRenderFn<RenderFunctionProps, State> | undefined–Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render.
styleReact.CSSProperties | ((state: State) => React.CSSProperties | undefined) | undefined–Style applied to the element, or a function that returns a style object based on the component's state.

Also takes every attribute of Primitive.List.Props.

Asynchronous suggestions

The selected record has both an ID and display text; the input's accessible label comes from Field.
Code
import { AsyncCombobox, type Suggestion } from "@bosunkit/components/combobox";
import { FormField } from "@bosunkit/components/form-field";
import type { ReactElement } from "react";
export const description: string =
  "The selected record has both an ID and display text; the input's accessible label comes from Field.";
const items: readonly Suggestion[] = [
  { value: "eng", label: "Engineering" },
  { value: "prod", label: "Product" },
];
export default function AsyncExample(): ReactElement {
  return (
    <FormField label="Audience">
      <AsyncCombobox
        name="audience"
        defaultValue={items[0]}
        suggest={(query: string): Promise<readonly Suggestion[]> =>
          Promise.resolve(
            items.filter((item: Suggestion): boolean => item.label.toLowerCase().includes(query.toLowerCase())),
          )
        }
      />
    </FormField>
  );
}

AsyncCombobox accepts suggest(query, signal) and minQueryLength. The caller owns the lookup; superseded requests are aborted and late answers are ignored. The callback keeps Base UI's cancellable event details.

PropTypeDefaultDescription
suggestrequired(query: string, signal: AbortSignal) => Promise<readonly Suggestion[]>–Caller-owned asynchronous lookup; no transport belongs to the kit.
minQueryLengthnumber | undefined–Minimum trimmed query length.
valueSuggestion | null | undefined–Selected record, including display text; null means no selection. Typed queries are separate.
defaultValueSuggestion | null | undefined–Initial selected record when uncontrolled.
onValueChangeBase.Root.Props<Suggestion>["onValueChange"]–Original cancellable selection event; only an item or null can be selected.
inputValuestring | undefined–Query text, independent of the selected value.
onInputValueChangeBase.Root.Props<Suggestion>["onInputValueChange"]–Reports query changes.
onBlurBase.Input.Props["onBlur"]–Input blur handler, preserving the native focus event.
idstring | undefined–Control ID for an external label.
aria-labelstring | undefined–Accessible control name when no visible label is associated.
aria-describedbystring | undefined–Hint and error element IDs.
placeholderstring | undefined–Input placeholder.
readOnlyboolean | undefined–Prevent editing.
disabledboolean | undefined–Prevent interaction and submission.
requiredboolean | undefined–Require a selection in a native form.
namestring | undefined–Submitted field name.
motionboolean | undefinedtrueEnable popup entrance motion.
classNamestring | undefined–Input classes.
refRef<HTMLInputElement> | undefined–Input element.
Do

Select a known audience.

Compose labeled parts and preserve their ref and DOM props.
Don't
Use the named parts for keyboard and focus behavior.
Do not replace semantic controls with clickable generic elements or discard event details.