MenuChevron Down
Select 选择器 - Docs - Artefact

Select 选择器

Forms
自动交互

简介

一个用于从列表中选择一个或多个选项的 dropdown 控件——可访问、可定制的原生 <select> 元素的替代方案。

何时选择其他组件:

  • 当选项少于 ~5 个时,RadioGroup 通常更清晰。
  • 如果用户需要输入来过滤选项,请使用 Combobox

该组件会在自定义 UI 旁渲染一个视觉上隐藏的原生 <select>,因此只需提供 name 属性即可使其参与常规表单提交,无需额外配置。

键盘交互

触发器是一个 role="combobox" 按钮;焦点停留在按钮上,而高亮的选项通过 aria-activedescendant 进行播报。

按键行为
Enter / Space打开列表;打开后,选择高亮的选项。
ArrowDown / ArrowUp打开列表,或移动高亮(循环,跳过禁用项)。
Home / End高亮第一个 / 最后一个可用选项。
Escape关闭列表。
Tab关闭列表并将焦点移走。
可打印字符预输入(Typeahead):跳转到标签与所输入前缀匹配的第一个选项。当列表关闭时(单选模式),会直接选中匹配项,类似于原生 <select>

打开列表时会高亮当前选中的选项(或第一个可用选项),键盘导航会保持高亮选项始终在视野内。

水合

Tier 1 — 自动交互。 打开下拉框和选择选项都需要客户端 JS,且不存在静态回退(原生 <select> 在视觉上隐藏,仅用于表单提交),因此 Select 默认会进行水合。传入 interactive={false} 可强制使用纯静态渲染。

interactive 属性结果
omitted作为岛屿进行水合
true作为岛屿进行水合
false静态 —— 无客户端 JS

库中所有交互相关的决策都通过 app/components/ui/island-utils.ts 中共享的 shouldHydrate() 辅助函数进行。

用法

React
Solid
Svelte
Vue
Hono
import { Select } from "../components/ui";

const items = [
  { label: "React", value: "react" },
  { label: "Solid", value: "solid" },
  { label: "Svelte", value: "svelte", disabled: true },
  { label: "Vue", value: "vue" },
  { label: "Hono", value: "hono" },
];

export default function MyPage() {
  return (
    <Select
      items={items}
      label="Framework"
      placeholder="Select a framework"
      allowClear
    />
  );
}

多选

在切换选项时列表保持打开,触发器会以逗号连接的方式显示已选标签。

<Select
  multiple
  items={items}
  label="Frameworks"
  placeholder="Select frameworks"
  defaultValue={["hono"]}
/>

在表单中

隐藏的原生 <select> 承载所选内容,因此普通的表单提交即可正常工作:

<form method="post" action="/frameworks">
  <Select name="framework" items={items} label="Framework" required />
  <Button type="submit">Save</Button>
</form>

尺寸与变体

<Select items={items} size="sm" placeholder="Small" />
<Select items={items} size="lg" variant="surface" placeholder="Large surface" />
<Select items={items} invalid placeholder="Invalid state" />

CMS 页面构建器

该组件可作为 select 区块在 页面构建器content/pages/*.json)中使用:

{
  "type": "select",
  "label": "Framework",
  "placeholder": "Select a framework",
  "items": [
    { "label": "React", "value": "react" },
    { "label": "Hono", "value": "hono" }
  ]
}

属性

属性类型说明
itemsSelectItem[]列表中显示的选项。
labelChild渲染在触发器上方并与其关联的标签。
placeholderstring未选择任何内容时触发器显示的文本。
allowClearboolean一旦有选中项即显示清除按钮。
multipleboolean允许选择多个选项;切换时列表保持打开。
defaultValuestring[]初始选择(非受控)。selectedValues 的别名。
selectedValuesstring[]初始选择(与 defaultValue 相同)。
deselectableboolean在单选模式下,再次点击已选选项可将其清除。
namestring隐藏的原生 <select> 的名称,用于表单提交。
disabledboolean禁用整个控件。
invalidboolean标记控件为无效(aria-invalid,错误边框)。
readOnlyboolean选择可见,但无法打开列表。
requiredboolean标记控件为必填(aria-required,隐藏的 select 的 required)。
openboolean下拉框的受控打开状态。

| size | `"xs" \ | "sm" \ | "md" \ | "lg" \ | "xl"` | 触发器与列表的尺寸。默认为 md。 |

| variant | `"outline" \ | "surface"` | 触发器的视觉变体。默认为 outline。 |

| interactive | boolean | 覆盖水合决策(见下文)。 | | onValueChange | (values: string[]) => void | 每当选择变化时(选择、取消选择、清除)都会调用,并传入完整的选项。 | | onItemSelect | (value: string) => void | 传入被交互的选项的 value 进行调用。 | | onClear | () => void | 清除按钮清空选择时调用。 | | onOpenChange | (open: boolean) => void | 下拉框打开或关闭时调用。 |

回调属性仅在 Select 由客户端代码(位于另一个岛屿内部)组合时才能生效。从服务端渲染路由序列化而来的属性必须是纯数据。

SelectItem

属性类型说明
labelstring选项的显示文本。也用于预输入匹配。
valuestring选项的唯一值。
disabledboolean该选项是否可被选中。