Skip to Content
文档

组合框

一个多功能输入组件,将文本输入与列表框相结合,允许用户过滤选项列表并选择单个或多个值。

SourceStorybookRecipeArk

用法

¥Usage

import { Combobox } from "@chakra-ui/react"
<Combobox.Root>
  <Combobox.Label />

  <Combobox.Control>
    <Combobox.Input />
    <Combobox.IndicatorGroup>
      <Combobox.ClearTrigger />
      <Combobox.Trigger />
    </Combobox.IndicatorGroup>
  </Combobox.Control>

  <Combobox.Positioner>
    <Combobox.Content>
      <Combobox.Empty />
      <Combobox.Item />

      <Combobox.ItemGroup>
        <Combobox.ItemGroupLabel />
        <Combobox.Item />
      </Combobox.ItemGroup>
    </Combobox.Content>
  </Combobox.Positioner>
</Combobox.Root>

要设置组合框,你可能需要导入以下钩子:

¥To setup combobox, you might need to import the following hooks:

  • useListCollection:用于管理组合框中的项目列表,并提供用于过滤和修改列表的实用方法。

  • useFilter:用于基于 Intl.Collator API 为组合框提供过滤逻辑。

示例

¥Examples

基础

¥Basic

基本组合框提供了一个可搜索的单选下拉菜单。

¥The basic combobox provides a searchable dropdown with single selection.

尺寸

¥Sizes

size 属性传递给 Combobox.Root,以更改组合框的大小。

¥Pass the size prop to the Combobox.Root to change the size of the combobox.

变量

¥Variants

variant 属性传递给 Combobox.Root,以更改组合框的外观。

¥Pass the variant prop to the Combobox.Root to change the appearance of the combobox.

多个

¥Multiple

multiple 属性传递给 Combobox.Root 以启用多选。这允许用户从列表中选择多个项目。

¥Pass the multiple prop to the Combobox.Root to enable multiple selection. This allows users to select multiple items from the list.

设置此值后,组合框在选择项目时将始终清除输入值。

异步加载

¥Async Loading

以下是如何在用户输入时异步加载 collection 的示例,非常适合 API 驱动的搜索界面。

¥Here's an example of loading the collection asynchronously as users type, perfect for API-driven search interfaces.

高亮匹配文本

¥Highlight Matching Text

以下是组合 Combobox.ItemHighlight 组件以在搜索结果中高亮匹配文本的示例。

¥Here's an example of composing the Combobox.Item and Highlight components to highlight matching text in search results.

点击打开

¥Open on Click

使用 openOnClick 属性在用户点击输入框时打开组合框。

¥Use the openOnClick prop to open the combobox when the user clicks on the input.

自定义对象

¥Custom Objects

默认情况下,组合框集合需要一个包含 labelvalue 属性的对象数组。在某些情况下,你可能需要处理自定义对象。

¥By default, the combobox collection expects an array of objects with label and value properties. In some cases, you may need to deal with custom objects.

使用 itemToStringitemToValue 属性将自定义对象映射到所需的接口。

¥Use the itemToString and itemToValue props to map the custom object to the required interface.

const items = [
  { country: "United States", code: "US", flag: "🇺🇸" },
  { country: "Canada", code: "CA", flag: "🇨🇦" },
  { country: "Australia", code: "AU", flag: "🇦🇺" },
  // ...
]

const { contains } = useFilter({ sensitivity: "base" })

const { collection } = useListCollection({
  initialItems: items,
  itemToString: (item) => item.country,
  itemToValue: (item) => item.code,
  filter: contains,
})

最小字符数

¥Minimum Characters

使用 openOnChange 属性设置过滤列表前的最小字符数。

¥Use the openOnChange prop to set a minimum number of characters before filtering the list.

<Combobox.Root openOnChange={(e) => e.inputValue.length > 2} />

字段

¥Field

组合 Combobox 组件与 Field 组件,使其将组合框封装在表单字段中。用于表单布局。

¥Compose the Combobox component with the Field component to wrap the combobox in a form field. Useful for form layouts.

The framework you love to use

表单 + 自定义对象

¥Form + Custom Object

在表单中使用自定义对象时,你通常需要提交编程值而不是显示值。本示例展示了如何使用隐藏输入框将自定义对象映射与表单提交相结合。

¥When working with custom objects in forms, you often need to submit the programmatic value rather than the display value. This example shows how to combine custom object mapping with form submission using a hidden input.

关键在于使用 itemToValue 定义提交的内容,而 itemToString 控制用户看到的内容。隐藏输入框用于捕获表单提交的程序化值。

¥The key is using itemToValue to define what gets submitted, while itemToString controls what users see. A hidden input captures the programmatic value for form submission.

在此示例中,用户看到 "🇺🇸 美国",但表单提交的是 "US"。

The form will submit the country code (e.g. "US"), not the display name

钩子表单

¥Hook Form

本示例演示如何使用 Controller 组件将 Combobox 与 React Hook Form 集成。表单会自动接收项目的 value 属性,无需隐藏输入框。

¥This example demonstrates how to integrate the Combobox with React Hook Form using the Controller component. The form automatically receives the item's value property without needing a hidden input.

用户看到 "React",但表单收到的是 "react"。

¥Users see "React" but the form receives "react".

已禁用状态

¥Disabled State

disabled 属性传递给 Combobox.Root 以禁用整个组合框。

¥Pass the disabled prop to the Combobox.Root to disable the entire combobox.

已禁用项目

¥Disabled Item

要禁用下拉菜单中的特定项目,请将 disabled 属性添加到集合项目。

¥Disable specific items in the dropdown, add the disabled prop to the collection item.

const items = [
  { label: "Item 1", value: "item-1", disabled: true },
  { label: "Item 2", value: "item-2" },
]

const { collection } = useListCollection({
  initialItems: items,
  // ...
})

输入框组

¥Input Group

与 InputGroup 组合以添加图标或其他元素。

¥Combine with InputGroup to add icons or other elements.

无效

¥Invalid

invalid 属性传递给 Combobox.Root 以显示错误状态。

¥Pass the invalid prop to the Combobox.Root to show the error state.

受控值

¥Controlled Value

使用 valueonValueChange 属性以编程方式控制组合框的值。

¥Use the value and onValueChange props to control the combobox's value programmatically.

Selected:
N/A

商店

¥Store

控制组合框的另一种方法是使用 Combobox.RootProvider 组件和 useCombobox 存储钩子。

¥An alternative way to control the combobox is to use the Combobox.RootProvider component and the useCombobox store hook.

import { Combobox, useCombobox } from "@chakra-ui/react"

function Demo() {
  const combobox = useCombobox()

  return (
    <Combobox.RootProvider value={combobox}>{/* ... */}</Combobox.RootProvider>
  )
}

这样,你就可以从组合框外部访问组合框的状态和方法。

¥This way you can access the combobox state and methods from outside the combobox.

受控打开

¥Controlled Open

使用 openonOpenChange 属性以编程方式控制组合框的打开状态。

¥Use the open and onOpenChange props to control the combobox's open state programmatically.

限制大型数据集

¥Limit Large Datasets

管理大型列表的推荐方法是在 useListCollection 钩子上使用 limit 属性。这将限制 DOM 中渲染项的数量,以提高性能。

¥The recommended way of managing large lists is to use the limit property on the useListCollection hook. This will limit the number of rendered items in the DOM to improve performance.

虚拟化

¥Virtualization

或者,你可以利用 @tanstack/react-virtual 包中的虚拟化功能来高效地渲染大型数据集。

¥Alternatively, you can leverage virtualization from the @tanstack/react-virtual package to render large datasets efficiently.

链接

¥Links

使用 asChild 属性将组合框项渲染为链接。

¥Use the asChild prop to render the combobox items as links.

对于自定义路由链接,你可以在 Combobox.Root 组件上自定义 navigate 属性。

¥For custom router links, you can customize the navigate prop on the Combobox.Root component.

以下是使用 Tanstack 路由的示例。

¥Here's an example of using the Tanstack Router.

import { Combobox } from "@chakra-ui/react"
import { useNavigate } from "@tanstack/react-router"

function Demo() {
  const navigate = useNavigate()
  return (
    <Combobox.Root
      navigate={({ href }) => {
        navigate({ to: href })
      }}
    >
      {/* ... */}
    </Combobox.Root>
  )
}

补充值

¥Rehydrate Value

在某些情况下,如果组合框包含 defaultValue 但集合尚未加载,则以下示例将说明如何重新填充值并填充输入值。

¥In some cases, where a combobox has a defaultValue but the collection is not loaded yet, here's an example of how to rehydrate the value and populate the input value.

自定义项目

¥Custom Item

使用你自己的组件自定义下拉菜单中项目的外观。

¥Customize the appearance of items in the dropdown with your own components.

自定义滤镜

¥Custom Filter

以下是匹配项目多个属性的自定义过滤器的示例。

¥Here's an example of a custom filter that matches multiple properties of an item.

自定义动画

¥Custom Animation

要自定义组合框的动画,请将 _open_closed 属性传递给 Combobox.Content 组件。

¥To customize the animation of the combobox, pass the _open and _closed prop to the Combobox.Content component.

在对话框中

¥Within Dialog

要在对话框或弹出窗口组件中使用组合框,请避免将 Combobox.Positioner 封装在 Portal 中。

¥To use the combobox within a dialog or popover component, avoid wrapping the Combobox.Positioner within the Portal.

-<Portal>
  <Combobox.Positioner>
    <Combobox.Content>
      {/* ... */}
    </Combobox.Content>
  </Combobox.Positioner>
-</Portal>

如果你使用 Dialog 并设置了 scrollBehavior="inside",则需要:

¥If you use a Dialog and have set scrollBehavior="inside", you need to:

  • 将组合框定位设置为 fixed,以避免组合框被对话框裁剪。

  • hideWhenDetached 设置为 true,以便在触发器滚动出视图时隐藏组合框。

<Combobox.Root positioning={{ strategy: "fixed", hideWhenDetached: true }}>
  {/* ... */}
</Combobox.Root>

属性

¥Props

根元素

¥Root

PropDefaultType
collection *
ListCollection<T>

The collection of items

composite true
boolean

Whether the combobox is a composed with other composite widgets like tabs

defaultInputValue '\'\''
string

The initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input.

defaultValue '[]'
string[]

The initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items.

inputBehavior '\'none\''
'none' | 'autohighlight' | 'autocomplete'

Defines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated

lazyMount false
boolean

Whether to enable lazy mounting

loopFocus true
boolean

Whether to loop the keyboard navigation through the items

openOnChange true
boolean | ((details: InputValueChangeDetails) => boolean)

Whether to show the combobox when the input value changes

openOnClick false
boolean

Whether to open the combobox popup on initial click on the input

openOnKeyPress true
boolean

Whether to open the combobox on arrow key press

positioning '{ placement: \'bottom-start\' }'
PositioningOptions

The positioning options to dynamically position the menu

selectionBehavior '\'replace\''
'replace' | 'clear' | 'preserve'

The behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved

skipAnimationOnMount false
boolean

Whether to allow the initial presence animation.

unmountOnExit false
boolean

Whether to unmount on exit.

colorPalette 'gray'
'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink'

The color palette of the component

variant 'outline'
'outline' | 'subtle' | 'flushed'

The variant of the component

size 'md'
'xs' | 'sm' | 'md' | 'lg'

The size of the component

as
React.ElementType

The underlying element to render.

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
unstyled
boolean

Whether to remove the component's style.

allowCustomValue
boolean

Whether to allow typing custom values in the input

autoFocus
boolean

Whether to autofocus the input on mount

closeOnSelect
boolean

Whether to close the combobox when an item is selected.

defaultHighlightedValue
string

The initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox.

defaultOpen
boolean

The initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox.

disabled
boolean

Whether the combobox is disabled

disableLayer
boolean

Whether to disable registering this a dismissable layer

form
string

The associate form of the combobox.

highlightedValue
string

The controlled highlighted value of the combobox

id
string

The unique identifier of the machine.

ids
Partial<{ root: string label: string control: string input: string content: string trigger: string clearTrigger: string item: (id: string, index?: number | undefined) => string positioner: string itemGroup: (id: string | number) => string itemGroupLabel: (id: string | number) => string }>

The ids of the elements in the combobox. Useful for composition.

immediate
boolean

Whether to synchronize the present change immediately or defer it to the next frame

inputValue
string

The controlled value of the combobox's input

invalid
boolean

Whether the combobox is invalid

multiple
boolean

Whether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container.

name
string

The `name` attribute of the combobox's input. Useful for form submission

navigate
(details: NavigateDetails) => void

Function to navigate to the selected item

onExitComplete
VoidFunction

Function called when the animation ends in the closed state

onFocusOutside
(event: FocusOutsideEvent) => void

Function called when the focus is moved outside the component

onHighlightChange
(details: HighlightChangeDetails<T>) => void

Function called when an item is highlighted using the pointer or keyboard navigation.

onInputValueChange
(details: InputValueChangeDetails) => void

Function called when the input's value changes

onInteractOutside
(event: InteractOutsideEvent) => void

Function called when an interaction happens outside the component

onOpenChange
(details: OpenChangeDetails) => void

Function called when the popup is opened

onPointerDownOutside
(event: PointerDownOutsideEvent) => void

Function called when the pointer is pressed down outside the component

onSelect
(details: SelectionDetails) => void

Function called when an item is selected

onValueChange
(details: ValueChangeDetails<T>) => void

Function called when a new item is selected

open
boolean

The controlled open state of the combobox

placeholder
string

The placeholder text of the combobox's input

present
boolean

Whether the node is present (controlled by the user)

readOnly
boolean

Whether the combobox is readonly. This puts the combobox in a "non-editable" mode but the user can still interact with it

required
boolean

Whether the combobox is required

scrollToIndexFn
(details: ScrollToIndexDetails) => void

Function to scroll to a specific index

translations
IntlTranslations

Specifies the localized strings that identifies the accessibility elements and their states

value
string[]

The controlled value of the combobox's selected items

项目

¥Item

PropDefaultType
as
React.ElementType

The underlying element to render.

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
item
any

The item to render

persistFocus
boolean

Whether hovering outside should clear the highlighted state

Previous

文本区域

Next

列表框