Combobox

候補から 1 つを選ぶ入力欄。打った文字で絞り込むか、サーバーに問い合わせて探す

インポート

ts
import { Combobox } from '@k8ordo/ui';

使い方

打つと一覧が開き、クリックか Enter で選ぶまで値は変わりません。打ちかけで離れると選んだ候補の表示名に戻り、空にして離れると選択を外します。↓ / ↑ で一覧を開いて移り(Alt+↓ は開くだけ)、Escape で閉じ、もう一度で打った文字を戻します。複数を選ぶなら Autocomplete を使います。

tsx
<Combobox aria-label="Prefecture" name="prefecture" options={prefectures} />

サーバーに問い合わせる

search を渡すと、打つたびに呼んで候補を受け取ります。打ち直すと前の呼び出しの signal が打ち切られるので、fetch に渡してください。探している間は一覧が busy になり、失敗や 0 件は一覧と読み上げで知らせます。options は打つ前に見せる候補になります。

tsx
<Combobox
  aria-label="City"
  name="city"
  search={async (query, { signal }) => {
    const response = await fetch(
      `/api/cities?q=${encodeURIComponent(query)}`,
      { signal },
    );
    return response.json();
  }}
/>

@k8ordo/form と使う

z.enum() から導いた input をそのまま spread できます。選んだ値は見えない <select> で送られるので、required・ルール・reset・送信に失敗したときのフォーカスの移動がそのまま効きます。

tsx
// schema.ts
export const addressSchema = z.object({
  prefecture: z.enum(['hokkaido', 'tokyo', 'osaka']),
});

// address-form.tsx
const prefecture = form.field('prefecture');

<FormControl
  errorText={prefecture.error}
  invalid={prefecture.invalid}
  label="Prefecture"
  required={prefecture.required}
  renderInput={(props) => (
    <Combobox {...props} {...prefecture.input} options={prefectures} />
  )}
/>

Props

defaultValue?
Type: string
Default: -
invalid?
Type: boolean
Default: false
onChange?
Type: (value: string) => void
Default: -
options?
Type: readonly Option[]
Default: -
ref?
Type: Ref<HTMLInputElement>
Default: -
search?
Type: ComboboxSearch
Default: -
type?
Type: string
Default: -
value?
Type: string
Default: -

型ベース(内部で固定する一部attrsは除外): InputHTMLAttributes<HTMLInputElement>

このコンポーネントが描画する文言(ラベルやプレースホルダーなど)は、propsで指定しないとき文言辞書から解決されます。差し替え方は次を参照してください: i18n