列表框 (选择)

列表框是构建应用程序自定义、可访问选择菜单的绝佳基础,它提供了强大的键盘导航支持。

要开始使用,请通过 npm 安装 Headless UI

npm install @headlessui/react

列表框是使用 ListboxListbox.ButtonListbox.OptionsListbox.OptionListbox.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> ) }

无头 UI 会跟踪每个组件的大量状态,比如当前选择了哪个列表框选项,弹出窗口是打开还是关闭,或者菜单中的哪个项目当前通过键盘处于活动状态。

但是,由于组件是无头的,并且在开箱即用时完全没有样式,因此在您自己提供每个状态所需的样式之前,您无法在 UI 中看到此信息。

每个组件都会通过渲染道具公开其当前状态的信息,您可以使用这些道具来有条件地应用不同的样式或渲染不同的内容。

例如,Listbox.Option 组件公开了一个 active 状态,它告诉您选项当前是否通过鼠标或键盘获得焦点,以及一个 selected 状态,它告诉您该选项是否与 Listbox 的当前 value 相匹配。

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 时,它们将在此属性中作为以空格分隔的字符串列出,因此您可以使用CSS 属性选择器[attr~=value] 的形式进行定位。

例如,以下是 Listbox.Options 组件以及一些子 Listbox.Option 组件在列表框打开且第二个选项同时处于 selectedactive 状态时渲染的内容

<!-- 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 表单控件不同,无头 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" />

如果您向 Listbox 提供 defaultValue 道具而不是 value,无头 UI 将为您在内部跟踪其状态,使您可以将其用作非受控组件

您可以通过 ListboxListbox.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 表单一起使用或与使用FormData收集其状态而不是使用 React 状态进行跟踪的表单 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> ) }

如果您希望自己处理(也许是因为您需要为此添加额外的包装元素),您可以向 Listbox.Options 实例添加一个 static 道具,告诉它始终渲染,并检查 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> ) }

由于它们是无状态的,因此无头 UI 组件还可以与 React 生态系统中的其他动画库(如Framer MotionReact Spring)很好地组合。

默认情况下,Listbox 及其子组件都会渲染一个对该组件合理的默认元素。

例如,Listbox.Label 默认渲染 labelListbox.Button 渲染 buttonListbox.Options 渲染 ulListbox.Option 渲染 li。相反,Listbox不渲染元素,而是直接渲染其子元素。

使用 as 道具将组件渲染为不同的元素或您自己的自定义组件,确保您的自定义组件转发引用,以便无头 UI 可以正确地连接它们。

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空格向下箭头向上箭头Listbox.Button 获得焦点时

打开列表框并使选定的项目获得焦点

Esc 当列表框处于打开状态时

关闭列表框

向下箭头向上箭头当列表框处于打开状态时

使前一个/下一个非禁用的项目获得焦点

向左箭头向右箭头当列表框处于打开状态且 horizontal 设置为 true 时

使前一个/下一个非禁用的项目获得焦点

HomePageUp 当列表框处于打开状态时

使第一个非禁用的项目获得焦点

EndPageDown 当列表框处于打开状态时

使最后一个非禁用的项目获得焦点

Enter空格 当列表框处于打开状态时

选择当前项目

A–Za–z 当列表框处于打开状态时

使与键盘输入匹配的第一个项目获得焦点

所有相关的 ARIA 属性都会自动管理。

主要的列表框组件。

属性默认值描述
asFragment
String | Component

Listbox 应渲染成的元素或组件。

disabledfalse
Boolean

使用此属性禁用整个 Listbox 组件及其相关子元素。

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

是否可以选择多个选项。

渲染属性描述
value

T

选定的值。

open

Boolean

Listbox 是否处于打开状态。

disabled

Boolean

Listbox 是否被禁用。

Listbox 的按钮。

属性默认值描述
asbutton
String | Component

Listbox.Button 应渲染成的元素或组件。

渲染属性描述
value

T

选定的值。

open

Boolean

Listbox 是否处于打开状态。

disabled

Boolean

Listbox 是否被禁用。

可用于更精确地控制 Listbox 向屏幕阅读器宣布的文本的标签。其 id 属性将自动生成,并通过 aria-labelledby 属性链接到根 Listbox 组件。

属性默认值描述
aslabel
String | Component

Listbox.Label 应渲染成的元素或组件。

渲染属性描述
open

Boolean

Listbox 是否处于打开状态。

disabled

Boolean

Listbox 是否被禁用。

直接包装自定义 Listbox 中选项列表的组件。

属性默认值描述
asul
String | Component

Listbox.Options 应渲染成的元素或组件。

staticfalse
Boolean

元素是否应忽略内部管理的打开/关闭状态。

注意:staticunmount 不能同时使用。如果您尝试这样做,将会收到 TypeScript 错误。

unmounttrue
Boolean

元素是否应根据打开/关闭状态卸载或隐藏。

注意:staticunmount 不能同时使用。如果您尝试这样做,将会收到 TypeScript 错误。

渲染属性描述
open

Boolean

Listbox 是否处于打开状态。

用于包装 Listbox 中的每个项目。

属性默认值描述
value
T

选项值。

asli
String | Component

Listbox.Option 应渲染成的元素或组件。

disabledfalse
Boolean

选项是否应针对键盘导航和 ARIA 目的禁用。

渲染属性描述
active

Boolean

选项是否为活动/焦点选项。

selected

Boolean

选项是否为选定选项。

disabled

Boolean

选项是否针对键盘导航和 ARIA 目的禁用。

如果您对使用 Headless UI 和 Tailwind CSS 的预先设计的组件示例感兴趣,请查看 **Tailwind UI** — 我们精心打造的,包含精美设计的组件集合。

这是支持我们对诸如该项目之类的开源项目的极佳方式,它使我们能够改进项目并保持其良好的维护状态。