Choice Picker 单值选择
明确区分选择一个值与执行一个动作。
选项较少时使用 SelectPicker;需要搜索时使用 SearchPicker。它们返回字符串值,支持选项说明、关键词与禁用状态。动作列表使用 Menu,而不是把菜单伪装成表单选择。
安装
pnpm dlx shadcn@4.22.1 add http://127.0.0.1:3040/r/v0.3.0/choice-picker.json首次使用请先完成 Registry 与主题接入。
变体与状态
在桌面中显示锚定浮层,在窄屏中使用底部面板。SearchPicker 的查询和选中值分离:取消不修改当前值,关闭后清空查询。customOption 只在应用明确允许自定义值时启用。
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | string | 必填 | 受控选中值 |
onValueChange | (value: string) => void | 必填 | 提交选择 |
options | readonly ChoiceOption[] | 必填 | { value, label, description?, keywords?, disabled? } |
name / label | string | 必填 | 提交字段名与可访问名称 |
disabled / required / invalid | boolean | false | 字段状态 |
SearchPicker.searchPlaceholder | string | 组件文案 | 搜索提示 |
SearchPicker.customOption | 查询转选项的回调 | — | 默认只允许列表项 |
ref | 可见触发按钮的 ref | — | 表单错误定位 |
还支持 id、describedBy、className;SearchPicker 提供 emptyMessage 与 onClosed。在 Field 中使用时启用 compound。
键盘与约束
触发器支持键盘打开,方向键移动,Enter 选择,Escape 关闭并恢复焦点。手机面板不应一打开就强制弹出软键盘;可见名称和实际提交值必须一致。
避免这样使用
不要用对象作为 value;不要默认把未知查询保存成新选项;不要把菜单动作、过滤多选和单值表单选择混为一种行为。
来源与版本
0.1.0,来自 Subtic apps/web/components/ui/choice-picker.tsx 与 picker-styles.ts。保留自适应交互,时区等业务数据由应用传入。
查看由当前源码生成的类型参考
只展示 Kitseed 自身定义的属性,原生 HTML 与 Base UI 透传属性请参阅对应上游说明。
SelectPicker
| 属性 | 类型 | 默认值 |
|---|---|---|
value | string | — |
onValueChange | (value: string) => void | — |
options | readonly ChoiceOption[] | — |
name | string | — |
label | string | — |
id? | string | — |
disabled? | boolean | — |
required? | boolean | — |
invalid? | boolean | — |
describedBy? | string | — |
className? | string | — |
ref? | Ref<HTMLButtonElement> | — |
classNames?Slot class names replace the default appearance without changing selection behavior. | Partial<
Record<"trigger" | "item" | "description" | "searchInput" | "inputTrigger", string>
> | — |
density?null leaves density entirely to the consuming layout. | KitseedDensity | null | — |
SearchPicker
| 属性 | 类型 | 默认值 |
|---|---|---|
value | string | — |
onValueChange | (value: string) => void | — |
options | readonly ChoiceOption[] | — |
name | string | — |
label | string | — |
id? | string | — |
disabled? | boolean | — |
required? | boolean | — |
invalid? | boolean | — |
describedBy? | string | — |
className? | string | — |
ref? | Ref<HTMLButtonElement> | — |
classNames?Slot class names replace the default appearance without changing selection behavior. | Partial<
Record<"trigger" | "item" | "description" | "searchInput" | "inputTrigger", string>
> | — |
density?null leaves density entirely to the consuming layout. | KitseedDensity | null | — |
searchPlaceholder? | string | — |
emptyMessage? | string | — |
customOption?Resolve a typed custom value into an explicit option. Selection still requires confirmation. | (query: string) => ChoiceOption | null | — |
input?Optional independent input, e.g. the time field next to its quick-choice trigger. | ReactNode | — |
onClosed? | () => void | — |