@gridui/select

中文文档
1.0.2发布于 2026/11/01UNLICENSEDTypeScriptES Module

GridUI React select

原始使用文档
文档目录5 节
  1. Select and Combobox
  2. Actions
  3. Search and keyboard interaction
  4. Server rendering
  5. Implementation and lifecycle

@gridui/select

Core family. Public API: Combobox, ComboboxProps, MultiSelect, MultiSelectProps, Select, SelectAction, SelectGroup, SelectOption, SelectProps.

Import components from @gridui/select and load @gridui/select/styles.css after Theme. Load styles for any composed dependency used by this family. Applications own routes, labels, state persistence, and branding.

See component ownership and release history.

Select and Combobox

Select and Combobox share options, actions, selection state, form integration, and the dropdown surface, highlight, indicators, typography, and motion. Radix Select owns option navigation; Combobox combines Radix Popover with a native editable input and an active-descendant listbox. Each popup contains an option listbox and a separate action footer; buttons and links never masquerade as options. Select defaults to position="popper", opening below the trigger and flipping at viewport edges. position="item-aligned" places the selected item over the trigger when space permits, with a viewport-safe fallback. Both modes match the trigger's outer width and limit height to available space. The option list scrolls independently of actions. Standard and small triggers retain 2.75rem and 2.25rem minimum heights. Option labels and descriptions wrap; the editable input displays one line. portalContainer can keep popups within an enclosing overlay's ownership and focus boundary. Inside a Modal or Drawer, use portalContainer when the popup must inherit a local theme or custom portal location. Radix layers coordinate nested focus and Escape handling. Attach a custom container to the panel, not its scrolling body, to avoid clipping menus.

options accepts SelectOption entries or SelectGroup entries with label and options. Option values must be unique across groups; group labels must be unique. Each option has a string label, optional string description, decorative icon React node, and disabled. Descriptions wrap below labels. Select shows the label and icon in its trigger; Combobox shows the label in its input. Do not put interactive content in icons.

Use value / onValueChange for controlled state or defaultValue for local state. The default value is empty; no option is implicitly selected. A selected value missing from options displays its raw value and remains in native form submission until its matching option arrives. An explicit empty-valued option is supported for filters such as “All statuses”. Otherwise, placeholder supplies empty-state text. Provide a label through Label.htmlFor and id, or an accessible name on the trigger. Select forwards button props and refs; Combobox forwards input props and refs. For both components, name, form, required, and disabled configure the native hidden select used for form submission and constraints. Invalid controls focus the visible trigger. Native form reset restores initial values; controlled callers receive resets through onValueChange, including while disabled. A cancelled reset has no effect. Setting disabled on an open control closes its popup; re-enabling it leaves the popup closed. Combobox also closes and clears its search when it becomes read-only; making it editable again does not reopen it. Selections and actions also check inherited fieldset availability at activation time, rejecting stale portalled interactions.

Supplying a localized clearLabel adds a separate clear button. It emits the empty string and returns focus to the trigger. Clearing is disabled for required, disabled, or already-empty controls. Combobox also disables clearing while readOnly; external controlled updates and native form reset retain their normal behavior.

Actions

Both components accept actions: readonly SelectAction[]. Each action has a unique id, label, optional decorative icon, and optional disabled. Provide either href (with optional target and rel) for a native link or onAction for a button callback. Actions never update the selected value or emit onValueChange. They remain available when there are no matching options. No implicit option creation takes place.

Actions close the popup by default; closeOnAction: false keeps it open. Closing restores trigger focus before the callback runs, allowing a callback to open a dialog or focus another control without later focus theft. Links keep native navigation and modified-click behavior. Disabled actions are skipped in the Tab sequence. Actions are outside the option listbox and cannot be reached or selected with option-navigation keys.

Search and keyboard interaction

Combobox searches directly in its editable trigger. Supply localized searchLabel and emptyLabel strings. A visible Label associated through id or an explicit accessible name takes precedence over the search-label fallback. Search filters labels and descriptions using case-insensitive, NFKC-normalized substring matching. Empty groups disappear; disabled matches remain visible. Typing does not commit a selection. Selecting commits the label to the input; Escape, outside dismissal, or closing actions restore the selected label. Actions that keep the popup open preserve the current query.

Select opens with Enter, Space, or arrow keys and focuses the selected option. Up/Down navigate enabled options; Home/End and timed character-prefix navigation are also supported. Enter or Space commits. Combobox preserves native editing and IME composition; typing or its arrow button opens the list, Up/Down move the active option, and Enter commits enabled options. GridUI allows highlighting disabled Combobox options for discovery; activating them never commits. Its input retains DOM focus and exposes the active option through aria-activedescendant. If options change during search, the highlight stays on its current result when present, otherwise it falls back to the first current result. Enter always uses the current result collection. Escape dismisses without committing and returns focus to the trigger, leaving an enclosing owner open. Tab/Shift+Tab reach independent actions; disabled actions are skipped. Pointer dismissal leaves focus with the outside target.

Server rendering

Selected labels, icons, and native form values are rendered explicitly during SSR, including grouped options and defaultValue. The editable trigger renders its selected label before hydration; a closed popup does not render options or execute actions. The client hydrates before popup interaction; keep server and client initial values/options identical. Browser verification hydrates real Node-rendered HTML and exercises selection, reset, filtering, independent actions, focus handoff, and empty results across the viewport matrix. Remote search and implicit option creation are not included. Use MultiSelect for multiple selection.

Implementation and lifecycle

Select uses Radix Select; Combobox composes Radix Popover with a native input, sharing the GridUI surface, typography, spacing, and highlights. Select defaults to position="popper"; position="item-aligned" aligns the selected item with the trigger when space permits. Both modes use the trigger width, including borders and padding.

src/select/select.tsx and src/combobox/combobox.tsx own their trigger and popup compositions; src/shared/ owns their shared selection, form, action, and search collaborators. Their option renderers stay separate because Select owns item-text alignment while Combobox owns a filtered collection. Radix owns positioning and dismissal. Select delegates option navigation to Radix; Combobox owns its editable input and active-descendant keyboard model. use-selection-value.ts owns controlled/local selection and initial-value reset. use-selection-popup.ts owns availability, open/close transitions, and focus handoff. Combobox and MultiSelect share query, current-result highlighting, and keyboard movement through use-search-options.ts; option replacement never leaves an invalid active item. selection-form.tsx owns native form association, validation, and cancellable reset observation. selection-actions.tsx renders independent links and buttons.

types.ts owns shared option, action, and selection contracts; options.ts owns pure filtering and flattening; style.ts owns selection-specific presentation and composes Overlay surface styles without translating variables into DropdownMenu names. DropdownMenu still owns the public option-row style. selection-popup.tsx shares Combobox/MultiSelect portal geometry, explicit anchor containment, and focus/escape event plumbing; callers choose initial focus and dismissal policy. MultiSelect uses Form's ListFieldControl with useListField for the native multiple-value bridge. Internal parts are not package exports. See the selection contract for keyboard, form, server-rendering, and focus guarantees protected by browser tests.

Surface motion uses @gridui/overlay; load @gridui/overlay/styles.css after Theme and before this family.

版本与发布记录

@gridui/select 共发布 4 个版本,首次发布于 2026/10/31;过去 12 个月发布了 4 个版本。

版本发布日期距今
1.0.2latest2026/11/012 天前
1.0.02026/10/313 天前
0.0.02026/10/313 天前
0.0.0-stage2026/10/313 天前

关于 @gridui/select 的常见问题

@gridui/select 是什么?

GridUI React select

如何安装 @gridui/select?

在项目目录运行 npm install @gridui/select,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^19.2.0)、react-dom(^19.2.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@gridui/select 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@gridui/select 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@gridui/select 可以商用吗?

@gridui/select 使用 UNLICENSED 许可。作者声明为 UNLICENSED,即不授予公开使用许可(与公共领域的 Unlicense 不同)。使用前需获得作者授权。以上为概括,不构成法律意见,请以许可原文为准。

@gridui/select 还在维护吗?

最新版本 1.0.2 发布于 2026/11/01(2 天前);至今共发布 4 个版本,其中过去 12 个月发布了 4 个;首次发布于 2026/10/31。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。