Officina UI
Components

AsyncSelect

Combobox that loads options remotely as you type, powered by a React Query fetcher.

AsyncSelect is a Combobox that fetches its options from a server as the user types. You supply queryFn (returns a promise of ComboboxOptions for the query) and queryKey (the React Query cache key for that query); loading and empty states are handled for you. Use minChars to avoid firing requests on short input and minCharsMessage to prompt the user. It is controlled via value/onChange like a regular Combobox.

Example

Preview
import { AsyncSelect } from '@officina/ui';
import { useState } from 'react';

function UserSearch() {
  const [value, setValue] = useState<string | null>(null);
  return (
    <AsyncSelect
      value={value}
      onChange={setValue}
      minChars={2}
      placeholder="Search users…"
      queryKey={(query) => ['users', query]}
      queryFn={async (query) => {
        const res = await fetch(`/api/users?q=${query}`);
        const users = await res.json();
        return users.map((u) => ({ value: u.id, label: u.name }));
      }}
    />
  );
}

API

PropTypeDefaultDescription
onChange*(value: T | null) => void—Called with the chosen value (or null when cleared).
queryFn*(query: string) => Promise<ComboboxOption<T>[]>—
queryKey*(query: string) => unknown[]—
value*T | null—Currently selected value, or null.
clearableboolean—Show a clear button to reset the selection.
disabledboolean—Disables the input and prevents selection.
emptyMessagestring—Message shown when no options match the query.
invalidboolean—Marks the field invalid for validation styling and `aria-invalid`.
minCharsnumber1
minCharsMessagestring—
namestring—Form field name for the underlying input.
placeholderstring—Placeholder text for the input when nothing is selected.
renderOption(option: ComboboxOption<T>) => ReactNode—Custom renderer for an option row.
requiredboolean—Marks the field as required for validation styling and `aria-required`.
sizeenum—Control size.

On this page