リストボックス(セレクト)

リストボックスは、キーボードナビゲーションの堅牢なサポートを備え、アプリ用のカスタムでアクセス可能なセレクトメニューを構築するための優れた基盤です。

まず、npm経由でHeadless UIをインストールします。

npm install @headlessui/react

リストボックスは、ListboxListbox.ButtonListbox.OptionsListbox.Option、およびListbox.Labelコンポーネントを使用して構築されます。

Listbox.Buttonをクリックすると、自動的にListbox.Optionsが開閉します。メニューが開いている場合、項目のリストにフォーカスが移動し、キーボードで自動的にナビゲートできるようになります。

import { useState } from 'react' import { Listbox } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds', unavailable: false }, { id: 2, name: 'Kenton Towne', unavailable: false }, { id: 3, name: 'Therese Wunsch', unavailable: false }, { id: 4, name: 'Benedict Kessler', unavailable: true }, { id: 5, name: 'Katelyn Rohan', unavailable: false }, ] function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return ( <Listbox value={selectedPerson} onChange={setSelectedPerson}> <Listbox.Button>{selectedPerson.name}</Listbox.Button> <Listbox.Options> {people.map((person) => ( <Listbox.Option key={person.id} value={person} disabled={person.unavailable} > {person.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

Headless UIは、どのリストボックスオプションが現在選択されているか、ポップオーバーが開いているか閉じているか、またはメニュー内のどの項目がキーボードで現在アクティブになっているかなど、各コンポーネントに関する多くの状態を追跡します。

しかし、コンポーネントはヘッドレスであり、初期状態では完全にスタイルされていないため、各状態に必要なスタイルを自分で指定するまで、UIでこの情報を確認することはできません。

各コンポーネントは、異なるスタイルを条件付きで適用したり、異なるコンテンツをレンダリングしたりするために使用できるレンダープロップスを介して、現在の状態に関する情報を公開します。

たとえば、Listbox.Optionコンポーネントは、オプションがマウスまたはキーボードで現在フォーカスされているかどうかを示すactive状態と、オプションがListboxの現在のvalueと一致するかどうかを示すselected状態を公開します。

import { useState, Fragment } from 'react' import { Listbox } from '@headlessui/react' import { CheckIcon } from '@heroicons/react/20/solid' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ] function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return ( <Listbox value={selectedPerson} onChange={setSelectedPerson}> <Listbox.Button>{selectedPerson.name}</Listbox.Button> <Listbox.Options> {people.map((person) => ( /* Use the `active` state to conditionally style the active option. */ /* Use the `selected` state to conditionally style the selected option. */ <Listbox.Option key={person.id} value={person} as={Fragment}>
{({ active, selected }) => (
<li className={`${
active ? 'bg-blue-500 text-white' : 'bg-white text-black'
}
`
}
>
{selected && <CheckIcon />}
{person.name} </li> )} </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

各コンポーネントの完全なレンダープロップスAPIについては、コンポーネントAPIドキュメントを参照してください。

各コンポーネントは、異なるスタイルを条件付きで適用するために使用できるdata-headlessui-state属性を介して、現在の状態に関する情報も公開します。

レンダープロップスAPIの状態のいずれかがtrueの場合、スペースで区切られた文字列としてこの属性にリストされるため、[attr~=value]形式のCSS属性セレクターでそれらをターゲットにできます。

たとえば、リストボックスが開いていて、2番目のオプションがselectedactiveの両方である場合、いくつかの子Listbox.Optionコンポーネントを持つListbox.Optionsコンポーネントがレンダリングする内容は次のとおりです。

<!-- Rendered `Listbox.Options` --> <ul data-headlessui-state="open"> <li data-headlessui-state="">Wade Cooper</li> <li data-headlessui-state="active selected">Arlene Mccoy</li> <li data-headlessui-state="">Devon Webb</li> </ul>

Tailwind CSSを使用している場合は、@headlessui/tailwindcssプラグインを使用して、ui-open:*ui-active:*のような修飾子を使用してこの属性をターゲットにできます。

import { useState } from 'react' import { Listbox } from '@headlessui/react' import { CheckIcon } from '@heroicons/react/20/solid' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ] function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return ( <Listbox value={selectedPerson} onChange={setSelectedPerson}> <Listbox.Button>{selectedPerson.name}</Listbox.Button> <Listbox.Options> {people.map((person) => ( <Listbox.Option key={person.id} value={person}
className="ui-active:bg-blue-500 ui-active:text-white ui-not-active:bg-white ui-not-active:text-black"
>
<CheckIcon className="hidden ui-selected:block" />
{person.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

文字列のみを値として提供できるネイティブHTMLフォームコントロールとは異なり、Headless UIは複雑なオブジェクトのバインディングもサポートしています。

import { useState } from 'react' import { Listbox } from '@headlessui/react'
const people = [
{ id: 1, name: 'Durward Reynolds', unavailable: false },
{ id: 2, name: 'Kenton Towne', unavailable: false },
{ id: 3, name: 'Therese Wunsch', unavailable: false },
{ id: 4, name: 'Benedict Kessler', unavailable: true },
{ id: 5, name: 'Katelyn Rohan', unavailable: false },
]
function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return (
<Listbox value={selectedPerson} onChange={setSelectedPerson}>
<Listbox.Button>{selectedPerson.name}</Listbox.Button> <Listbox.Options> {people.map((person) => ( <Listbox.Option key={person.id}
value={person}
disabled={person.unavailable} >
{person.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

オブジェクトを値としてバインドする場合は、Listboxvalueと対応するListbox.Optionの両方で、オブジェクトの同じインスタンスを使用していることを確認することが重要です。そうしないと、それらは等しくなくなり、リストボックスが正しく動作しなくなります。

同じオブジェクトの異なるインスタンスを簡単に操作できるように、オブジェクトの同一性を比較する代わりに、特定のフィールドでオブジェクトを比較するためにbyプロップを使用できます。

import { Listbox } from '@headlessui/react' const departments = [ { id: 1, name: 'Marketing', contact: 'Durward Reynolds' }, { id: 2, name: 'HR', contact: 'Kenton Towne' }, { id: 3, name: 'Sales', contact: 'Therese Wunsch' }, { id: 4, name: 'Finance', contact: 'Benedict Kessler' }, { id: 5, name: 'Customer service', contact: 'Katelyn Rohan' }, ]
function DepartmentPicker({ selectedDepartment, onChange }) {
return (
<Listbox value={selectedDepartment} by="id" onChange={onChange}>
<Listbox.Button>{selectedDepartment.name}</Listbox.Button> <Listbox.Options> {departments.map((department) => ( <Listbox.Option key={department.id} value={department}> {department.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

オブジェクトの比較方法を完全に制御したい場合は、独自の比較関数をbyプロップに渡すこともできます。

import { Listbox } from '@headlessui/react' const departments = [ { id: 1, name: 'Marketing', contact: 'Durward Reynolds' }, { id: 2, name: 'HR', contact: 'Kenton Towne' }, { id: 3, name: 'Sales', contact: 'Therese Wunsch' }, { id: 4, name: 'Finance', contact: 'Benedict Kessler' }, { id: 5, name: 'Customer service', contact: 'Katelyn Rohan' }, ]
function compareDepartments(a, b) {
return a.name.toLowerCase() === b.name.toLowerCase()
}
function DepartmentPicker({ selectedDepartment, onChange }) { return ( <Listbox value={selectedDepartment}
by={compareDepartments}
onChange={onChange} >
<Listbox.Button>{selectedDepartment.name}</Listbox.Button> <Listbox.Options> {departments.map((department) => ( <Listbox.Option key={department.id} value={department}> {department.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

リストボックスで複数の値を選択できるようにするには、multipleプロップを使用し、単一のオプションの代わりに配列をvalueに渡します。

import { useState } from 'react' import { Listbox } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ] function MyListbox() {
const [selectedPeople, setSelectedPeople] = useState([people[0], people[1]])
return (
<Listbox value={selectedPeople} onChange={setSelectedPeople} multiple>
<Listbox.Button> {selectedPeople.map((person) => person.name).join(', ')} </Listbox.Button> <Listbox.Options> {people.map((person) => ( <Listbox.Option key={person.id} value={person}> {person.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

これにより、オプションを選択するときにリストボックスが開いたままになり、オプションを選択すると、その場で切り替えられます。

オプションが追加または削除されるたびに、選択したすべてのオプションを含む配列でonChangeハンドラーが呼び出されます。

デフォルトでは、Listboxはスクリーンリーダーのラベルとしてボタンの内容を使用します。支援技術に発表する内容をより細かく制御したい場合は、Listbox.Labelコンポーネントを使用します。

import { useState } from 'react' import { Listbox } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ] function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return ( <Listbox value={selectedPerson} onChange={setSelectedPerson}>
<Listbox.Label>Assignee:</Listbox.Label>
<Listbox.Button>{selectedPerson.name}</Listbox.Button> <Listbox.Options> {people.map((person) => ( <Listbox.Option key={person.id} value={person}> {person.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

リストボックスにnameプロップを追加すると、非表示のinput要素がレンダリングされ、選択した値と同期されます。

import { useState } from 'react' import { Listbox } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ] function Example() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return ( <form action="/projects/1/assignee" method="post"> <Listbox value={selectedPerson} onChange={setSelectedPerson}
name="assignee"
>
<Listbox.Button>{selectedPerson.name}</Listbox.Button> <Listbox.Options> {people.map((person) => ( <Listbox.Option key={person.id} value={person}> {person.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> <button>Submit</button> </form> ) }

これにより、ネイティブHTML <form>内でリストボックスを使用し、リストボックスがネイティブHTMLフォームコントロールであるかのように、従来のフォーム送信を行うことができます。

文字列のような基本的な値は、その値を含む単一の非表示入力としてレンダリングされますが、オブジェクトのような複雑な値は、名前の角かっこ表記を使用して複数の入力にエンコードされます。

<input type="hidden" name="assignee[id]" value="1" /> <input type="hidden" name="assignee[name]" value="Durward Reynolds" />

valueの代わりにdefaultValueプロップをListboxに提供すると、Headless UIは内部で状態を追跡し、非制御コンポーネントとして使用できます。

ListboxおよびListbox.Buttonコンポーネントのvalueレンダープロップを介して、現在選択されているオプションにアクセスできます。

import { Listbox } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ] function Example() { return ( <form action="/projects/1/assignee" method="post">
<Listbox name="assignee" defaultValue={people[0]}>
<Listbox.Button>{({ value }) => value.name}</Listbox.Button>
<Listbox.Options> {people.map((person) => ( <Listbox.Option key={person.id} value={person}> {person.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> <button>Submit</button> </form> ) }

これにより、リストボックスをHTMLフォームで使用したり、Reactの状態を使用して追跡する代わりに、FormDataを使用して状態を収集するフォームAPIで使用したりする場合に、コードを簡略化できます。

副作用を実行する必要がある場合に備えて、コンポーネントの値が変更されると、提供するonChangeプロップは引き続き呼び出されますが、コンポーネントの状態を自分で追跡するために使用する必要はありません。

デフォルトでは、Listbox.Optionsインスタンスは、Listboxコンポーネント自体内で追跡される内部のopen状態に基づいて、自動的に表示/非表示になります。

import { useState } from 'react' import { Listbox } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ] function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return ( <Listbox value={selectedPerson} onChange={setSelectedPerson}> <Listbox.Button>{selectedPerson.name}</Listbox.Button> {/* By default, the `Listbox.Options` will automatically show/hide when the `Listbox.Button` is pressed. */} <Listbox.Options> {people.map((person) => ( <Listbox.Option key={person.id} value={person}> {person.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

これを自分で処理したい場合(おそらく、何らかの理由で追加のラッパー要素を追加する必要がある場合)、staticプロップをListbox.Optionsインスタンスに追加して常にレンダリングするように指示し、Listboxによって提供されるopenレンダープロップを調べて、表示/非表示にする要素を自分で制御できます。

import { useState } from 'react' import { Listbox } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ] function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return ( <Listbox value={selectedPerson} onChange={setSelectedPerson}> {({ open }) => ( <> <Listbox.Button>{selectedPerson.name}</Listbox.Button>
{open && (
<div> {/* Using the `static` prop, the `Listbox.Options` are always rendered and the `open` state is ignored. */}
<Listbox.Options static>
{people.map((person) => ( <Listbox.Option key={person.id} value={person}> {person.name} </Listbox.Option> ))} </Listbox.Options> </div> )} </> )} </Listbox> ) }

disabledプロップを使用して、Listbox.Optionを無効にします。これにより、マウスとキーボードで選択できなくなり、上/下矢印を押すとスキップされます。

import { useState } from 'react' import { Listbox } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds', unavailable: false }, { id: 2, name: 'Kenton Towne', unavailable: false }, { id: 3, name: 'Therese Wunsch', unavailable: false }, { id: 4, name: 'Benedict Kessler', unavailable: true }, { id: 5, name: 'Katelyn Rohan', unavailable: false }, ] function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return ( <Listbox value={selectedPerson} onChange={setSelectedPerson}> <Listbox.Button>{selectedPerson.name}</Listbox.Button> <Listbox.Options> {people.map((person) => ( /* Disabled options will be skipped by keyboard navigation. */ <Listbox.Option key={person.id} value={person}
disabled={person.unavailable}
>
<span className={person.unavailable ? 'opacity-75' : ''}> {person.name} </span> </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

リストボックスパネルの開閉をアニメーション化するには、提供されているTransitionコンポーネントを使用します。Listbox.Options<Transition>でラップするだけで、トランジションが自動的に適用されます。

import { useState } from 'react' import { Listbox, Transition } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ] function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return ( <Listbox value={selectedPerson} onChange={setSelectedPerson}> <Listbox.Button>{selectedPerson.name}</Listbox.Button>
<Transition
enter="transition duration-100 ease-out"
enterFrom="transform scale-95 opacity-0"
enterTo="transform scale-100 opacity-100"
leave="transition duration-75 ease-out"
leaveFrom="transform scale-100 opacity-100"
leaveTo="transform scale-95 opacity-0"
>
<Listbox.Options> {people.map((person) => ( <Listbox.Option key={person.id} value={person}> {person.name} </Listbox.Option> ))} </Listbox.Options>
</Transition>
</Listbox> ) }

デフォルトでは、組み込みのTransitionコンポーネントは、Listboxコンポーネントと自動的に通信して、開閉状態を処理します。ただし、この動作をより細かく制御する必要がある場合は、明示的に制御できます。

import { useState } from 'react' import { Listbox, Transition } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ] function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return ( <Listbox value={selectedPerson} onChange={setSelectedPerson}>
{({ open }) => (
<>
<Listbox.Button>{selectedPerson.name}</Listbox.Button> {/* Use the `Transition` + `open` render prop argument to add transitions. */} <Transition
show={open}
enter="transition duration-100 ease-out" enterFrom="transform scale-95 opacity-0" enterTo="transform scale-100 opacity-100" leave="transition duration-75 ease-out" leaveFrom="transform scale-100 opacity-100" leaveTo="transform scale-95 opacity-0" >
{/* Don't forget to add `static` to your `Listbox.Options`! */}
<Listbox.Options static>
{people.map((person) => ( <Listbox.Option key={person.id} value={person}> {person.name} </Listbox.Option> ))} </Listbox.Options> </Transition>
</>
)}
</Listbox> ) }

レンダリングしないため、Headless UIコンポーネントは、Framer MotionReact Springなど、Reactエコシステムの他のアニメーションライブラリともうまく構成されます。

デフォルトでは、Listboxとそのサブコンポーネントはそれぞれ、そのコンポーネントに適したデフォルト要素をレンダリングします。

たとえば、Listbox.Labelはデフォルトでlabelをレンダリングし、Listbox.Buttonbuttonをレンダリングし、Listbox.Optionsulをレンダリングし、Listbox.Optionliをレンダリングします。対照的に、Listbox要素をレンダリングせず、代わりに子を直接レンダリングします。

カスタムコンポーネントがforward refsを確実に実行して、Headless UIが正しく配線できるように、asプロップを使用してコンポーネントを異なる要素として、または独自のカスタムコンポーネントとしてレンダリングします。

import { forwardRef, useState } from 'react' import { Listbox } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ]
let MyCustomButton = forwardRef(function (props, ref) {
return <button className="..." ref={ref} {...props} />
})
function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return (
<Listbox as="div" value={selectedPerson} onChange={setSelectedPerson}>
<Listbox.Button as={MyCustomButton}>
{selectedPerson.name} </Listbox.Button>
<Listbox.Options as="div">
{people.map((person) => (
<Listbox.Option as="span" key={person.id} value={person}>
{person.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

ラッパー要素なしで子を直接レンダリングするように要素に指示するには、Fragmentを使用します。

import { useState, Fragment } from 'react' import { Listbox } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ] function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return ( <Listbox value={selectedPerson} onChange={setSelectedPerson}> {/* Render a `Fragment` instead of a `button` */}
<Listbox.Button as={Fragment}>
<button>{selectedPerson.name}</button> </Listbox.Button> <Listbox.Options> {people.map((person) => ( <Listbox.Option key={person.id} value={person}> {person.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

Listbox.Optionsが水平に表示されるようにスタイル設定している場合は、Listboxコンポーネントでhorizontalプロップを使用して、上/下矢印キーの代わりに左/右矢印キーで項目をナビゲートできるようにし、支援技術用のaria-orientation属性を更新します。

import { useState, Fragment } from 'react' import { Listbox } from '@headlessui/react' const people = [ { id: 1, name: 'Durward Reynolds' }, { id: 2, name: 'Kenton Towne' }, { id: 3, name: 'Therese Wunsch' }, { id: 4, name: 'Benedict Kessler' }, { id: 5, name: 'Katelyn Rohan' }, ] function MyListbox() { const [selectedPerson, setSelectedPerson] = useState(people[0]) return (
<Listbox value={selectedPerson} onChange={setSelectedPerson} horizontal>
<Listbox.Button>{selectedPerson.name}</Listbox.Button> <Listbox.Options className="flex flex-row"> {people.map((person) => ( <Listbox.Option key={person.id} value={person}> {person.name} </Listbox.Option> ))} </Listbox.Options> </Listbox> ) }

リストボックスが開かれると、Listbox.Options がフォーカスを受け取ります。フォーカスは、Escape キーが押されるか、ユーザーがオプションの外側をクリックするまで、項目リスト内でトラップされます。リストボックスを閉じると、フォーカスは Listbox.Button に戻ります。

Listbox.Button をクリックすると、オプションリストが開閉します。オプションリストの外側をクリックすると、リストボックスが閉じます。

コマンド説明

Enter, Space, 下矢印, または 上矢印Listbox.Button がフォーカスされている場合

リストボックスを開き、選択された項目にフォーカスを当てます

Esc リストボックスが開いている場合

リストボックスを閉じます

下矢印 または 上矢印リストボックスが開いている場合

前の/次の無効でない項目にフォーカスを当てます

左矢印 または 右矢印リストボックスが開いていて、horizontal が設定されている場合

前の/次の無効でない項目にフォーカスを当てます

Home または PageUp リストボックスが開いている場合

最初の無効でない項目にフォーカスを当てます

End または PageDown リストボックスが開いている場合

最後の無効でない項目にフォーカスを当てます

Enter または Space リストボックスが開いている場合

現在の項目を選択します

A–Z または a–z リストボックスが開いている場合

キーボード入力に一致する最初の項目にフォーカスを当てます

関連するすべての ARIA 属性は自動的に管理されます。

メインのリストボックスコンポーネント。

Propデフォルト説明
asFragment
String | Component

Listbox がレンダリングする要素またはコンポーネント。

disabledfalse
Boolean

リストボックスコンポーネント全体と関連する子要素を無効にするために使用します。

value
T

選択された値。

defaultValue
T

非制御コンポーネントとして使用する場合のデフォルト値。

by
keyof T | ((a: T, z: T) => boolean)

特定のフィールドでオブジェクトを比較したり、オブジェクトの比較方法を完全に制御するための独自の比較関数を渡すために使用します。

onChange
(value: T) => void

新しいオプションが選択されたときに呼び出す関数。

horizontalfalse
Boolean

true の場合、Listbox.Options の向きは horizontal になり、それ以外の場合は vertical になります。

name
String

このコンポーネントをフォーム内で使用する場合に使用される名前。

multiplefalse
Boolean

複数のオプションを選択できるかどうか。

レンダリング Prop説明
value

T

選択された値。

open

Boolean

リストボックスが開いているかどうか。

disabled

Boolean

リストボックスが無効になっているかどうか。

リストボックスのボタン。

Propデフォルト説明
asbutton
String | Component

Listbox.Button がレンダリングする要素またはコンポーネント。

レンダリング Prop説明
value

T

選択された値。

open

Boolean

リストボックスが開いているかどうか。

disabled

Boolean

リストボックスが無効になっているかどうか。

リストボックスがスクリーンリーダーにアナウンスするテキストをより細かく制御するために使用できるラベル。その id 属性は自動的に生成され、aria-labelledby 属性を介してルート Listbox コンポーネントにリンクされます。

Propデフォルト説明
aslabel
String | Component

Listbox.Label がレンダリングする要素またはコンポーネント。

レンダリング Prop説明
open

Boolean

リストボックスが開いているかどうか。

disabled

Boolean

リストボックスが無効になっているかどうか。

カスタムリストボックスのオプションリストを直接ラップするコンポーネント。

Propデフォルト説明
asul
String | Component

Listbox.Options がレンダリングする要素またはコンポーネント。

staticfalse
Boolean

要素が内部で管理される開閉状態を無視するかどうか。

注:staticunmount は同時に使用できません。試みると、TypeScript エラーが発生します。

unmounttrue
Boolean

開閉状態に基づいて要素をアンマウントするか、非表示にするか。

注:staticunmount は同時に使用できません。試みると、TypeScript エラーが発生します。

レンダリング Prop説明
open

Boolean

リストボックスが開いているかどうか。

リストボックス内の各項目をラップするために使用されます。

Propデフォルト説明
value
T

オプション値。

asli
String | Component

Listbox.Option がレンダリングする要素またはコンポーネント。

disabledfalse
Boolean

キーボードナビゲーションおよび ARIA の目的で、オプションを無効にするかどうか。

レンダリング Prop説明
active

Boolean

オプションがアクティブ/フォーカスされているオプションかどうか。

selected

Boolean

オプションが選択されたオプションかどうか。

disabled

Boolean

キーボードナビゲーションおよび ARIA の目的で、オプションを無効にするかどうか。

Headless UI と Tailwind CSS を使用した事前設計されたコンポーネントの例に興味がある場合は、Tailwind UI をご覧ください。これは、私たちが作成した美しく設計され、専門的に作成されたコンポーネントのコレクションです。

これは、このようなオープンソースプロジェクトでの私たちの活動をサポートするのに最適な方法であり、それらの改善と適切に保守された状態を保つことを可能にします。