Select
用于从下拉列表中选择单个值的选择器
Select 用于在有限选项中选择一个值。组件基于 Radix Select 封装,支持数据驱动的选项、分组、分隔线、禁用项、自定义图标、尺寸和弹层位置。
import {
Select,
SelectContent,
SelectItem,
SelectLabel,
SelectSeparator,
SelectTrigger
} from '@skyroc/web-ui';何时使用
- 需要从一组选项中选择一个值,并希望节省页面空间。
- 选项数量中等,适合收纳到弹层中展示。
- 需要分组、分隔线、禁用选项或自定义选项内容。
- 少量选项且需要直接展示时使用 Radio 或 Segment;需要搜索过滤时使用 Combobox。
基础用法
通过 items 渲染选项,使用 triggerProps.placeholder 设置占位文案。
<Select
items={[
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' }
]}
triggerProps={{ placeholder: 'Please select a fruit' }}
/>受控模式
使用 value 和 onValueChange 控制当前选中值。
const [value, setValue] = useState('apple');
<Select
items={items}
onValueChange={setValue}
value={value}
/>默认值
使用 defaultValue 设置非受控模式下的默认选中项。
<Select
defaultValue="cherry"
items={items}
/>分组选项
选项数据可以通过 children 组织为分组。分组的 label 会渲染为组标题,children 内部渲染普通选项。
<Select
items={[
{
label: 'Fruits',
children: [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' }
]
}
]}
/>分隔线
在 items 中插入 { type: 'separator' } 可以渲染分隔线,用于区分不同选项区域。
<Select
items={[
{ label: 'Apple', value: 'apple' },
{ type: 'separator' },
{ label: 'Banana', value: 'banana' }
]}
/>弹层位置
默认 contentProps.position 为 popper,弹层会基于触发器尺寸和位置渲染。设置为 item-aligned 可以使用 Radix 的选项对齐模式。
<Select
contentProps={{ position: 'item-aligned' }}
items={items}
/>尺寸
通过 size 调整触发器、弹层、选项和分隔线尺寸,从 xs 到 2xl 共 6 个尺寸。
| 尺寸 | 适用场景 |
|---|---|
xs | 表格、紧凑筛选器 |
sm | 小型表单 |
md | 常规表单(默认) |
lg | 设置页表单 |
xl | 强调型选择区域 |
2xl | 大尺寸展示或触控区 |
自定义样式
通过 classNames 覆盖内部 slot。常用 slot 包括 trigger、content、item、groupLabel 和 separator。
<Select
classNames={{
content: 'border-primary/30',
item: 'focus:bg-primary/10',
trigger: 'border-primary/40'
}}
items={items}
/>禁用
可以禁用整个 Select,也可以在单个 item 上设置 disabled 禁用部分选项。
<Select disabled items={items} /><Select
items={[
{ label: 'Apple', value: 'apple' },
{ disabled: true, label: 'Banana', value: 'banana' }
]}
/>API
Select
主组件基于 Radix Select Root,使用 items 数据渲染 Trigger、Content 和 Option。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| items* | 下拉选项数据,支持普通项、分组和分隔线 | SelectOptionData[] | - |
| value | 受控模式下当前选中的值 | string | - |
| defaultValue | 非受控模式下默认选中的值 | string | - |
| onValueChange | 选中值变化时触发 | (value: string) => void | - |
| open | 受控模式下弹层是否打开 | boolean | - |
| defaultOpen | 非受控模式下弹层默认是否打开 | boolean | - |
| onOpenChange | 弹层打开状态变化时触发 | (open: boolean) => void | - |
| disabled | 是否禁用整个 Select | boolean | - |
| size | 尺寸,影响触发器、弹层和选项 | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'md' |
| indicatorIcon | 选中项指示器图标 | ReactNode | - |
| className | Root class | ClassValue | - |
| classNames | 各 slot 的自定义 class | SelectClassNames | - |
| triggerProps | 传递给 SelectTrigger 的额外 props | SelectTriggerProps | - |
| contentProps | 传递给 SelectContent 的额外 props | Omit<SelectContentProps, "children"> | - |
结构组件
结构组件适合需要手动组合 Select,或需要完全控制 Trigger / Content / Item 结构时使用。
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| SelectTrigger | 打开下拉弹层的触发器 | SelectTriggerProps | - |
| SelectContent | 下拉弹层内容容器 | SelectContentProps | - |
| SelectItem | 单个可选项 | SelectItemProps | - |
| SelectLabel | 分组标题 | SelectLabelProps | - |
| SelectSeparator | 分隔线 | SelectSeparatorProps | - |
| SelectOption | 根据 SelectOptionData 渲染 item、group 或 separator 的数据渲染组件 | SelectOptionProps | - |
类型
SelectProps
Select 主组件属性,基于 Radix Select Root,并增加数据驱动渲染和 slot 配置。
| 字段 | 类型 | 说明 |
|---|---|---|
| items | SelectOptionData[] | 下拉选项数据。 |
| value | string | 受控选中值。 |
| defaultValue | string | 默认选中值。 |
| onValueChange | (value: string) => void | 选中值变化回调。 |
| open | boolean | 受控打开状态。 |
| defaultOpen | boolean | 默认打开状态。 |
| onOpenChange | (open: boolean) => void | 打开状态变化回调。 |
| disabled | boolean | 是否禁用。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 尺寸。 |
| indicatorIcon | ReactNode | 选中项指示器图标。 |
| className | ClassValue | Root class。 |
| classNames | SelectClassNames | slot class 配置。 |
| triggerProps | SelectTriggerProps | 触发器属性。 |
| contentProps | Omit<SelectContentProps, "children"> | 弹层内容属性。 |
SelectClassNames
Select 各 slot 的自定义 class。
| 字段 | 类型 | 说明 |
|---|---|---|
| content | ClassValue | 弹层内容容器 class。 |
| group | ClassValue | 分组容器 class。 |
| groupLabel | ClassValue | 分组标题 class。 |
| item | ClassValue | 选项 class。 |
| itemIndicator | ClassValue | 选中指示器 class。 |
| itemText | ClassValue | 选项文本 class。 |
| scrollDownButton | ClassValue | 向下滚动按钮 class。 |
| scrollUpButton | ClassValue | 向上滚动按钮 class。 |
| selectedValue | ClassValue | 触发器当前值 class。 |
| separator | ClassValue | 分隔线 class。 |
| trigger | ClassValue | 触发器 class。 |
| triggerIcon | ClassValue | 触发器图标 class。 |
| viewport | ClassValue | 弹层视口 class。 |
SelectOptionItemData
普通选项数据。继承 SelectItemProps,但用 label 表示显示内容。
| 字段 | 类型 | 说明 |
|---|---|---|
| value | string | 选项值。 |
| label | ReactNode | 选项显示内容。 |
| type | 'item' | 选项类型标识,可省略。 |
| disabled | boolean | 是否禁用当前选项。 |
| leading | ReactNode | 前置内容。 |
| trailing | ReactNode | 后置内容。 |
| indicatorIcon | ReactNode | 当前选项的选中指示器图标。 |
| className | ClassValue | 选项 class。 |
| classNames | Pick<SelectClassNames, 'item' | 'itemIndicator' | 'itemText'> | 选项相关 slot class。 |
SelectGroupOptionData
分组选项数据。
| 字段 | 类型 | 说明 |
|---|---|---|
| type | 'group' | 分组类型标识,可省略。 |
| label | ReactNode | 分组标题。 |
| children | SelectOptionItemData[] | 分组内选项。 |
| className | ClassValue | 分组标题 class。 |
SelectTriggerProps
触发器属性,基于 Radix Select Trigger 和 Value。
| 字段 | 类型 | 说明 |
|---|---|---|
| children | ReactNode | 自定义当前值渲染内容。 |
| placeholder | ReactNode | 未选择时的占位内容。 |
| triggerIcon | ReactNode | 触发器图标。 |
| leading | ReactNode | 前置内容。 |
| trailing | ReactNode | 后置内容。 |
| disabled | boolean | 是否禁用触发器。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 触发器尺寸。 |
| className | ClassValue | 触发器 class。 |
| classNames | Pick<SelectClassNames, 'selectedValue' | 'trigger' | 'triggerIcon'> | 触发器相关 slot class。 |
SelectContentProps
弹层内容属性,基于 Radix Select Content。
| 字段 | 类型 | 说明 |
|---|---|---|
| children | ReactNode | 弹层内容。 |
| position | 'popper' | 'item-aligned' | 弹层定位模式。 |
| side | 'top' | 'right' | 'bottom' | 'left' | 弹层出现方向。 |
| align | 'start' | 'center' | 'end' | 弹层对齐方式。 |
| sideOffset | number | 弹层与触发器的距离。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 弹层尺寸。 |
| scrollUpButton | ReactNode | 向上滚动按钮内容。 |
| scrollDownButton | ReactNode | 向下滚动按钮内容。 |
| className | ClassValue | 弹层内容 class。 |
| classNames | Pick<SelectClassNames, 'content' | 'scrollDownButton' | 'scrollUpButton' | 'viewport'> | 弹层相关 slot class。 |
SelectItemProps
单个选项属性,基于 Radix Select Item,并增加前后置内容和指示器图标。
| 字段 | 类型 | 说明 |
|---|---|---|
| value | string | 选项值。 |
| children | ReactNode | 选项内容。 |
| disabled | boolean | 是否禁用选项。 |
| textValue | string | 用于无障碍和类型选择的文本值。 |
| leading | ReactNode | 前置内容。 |
| trailing | ReactNode | 后置内容。 |
| indicatorIcon | ReactNode | 选中指示器图标。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 选项尺寸。 |
| className | ClassValue | 选项 class。 |
| classNames | Pick<SelectClassNames, 'item' | 'itemIndicator' | 'itemText'> | 选项相关 slot class。 |
SelectLabelProps
分组标题属性,基于 Radix Select Label。
| 字段 | 类型 | 说明 |
|---|---|---|
| children | ReactNode | 标题内容。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 标题尺寸。 |
| className | ClassValue | 标题 class。 |
SelectSeparatorProps
分隔线属性,基于 Radix Select Separator。
| 字段 | 类型 | 说明 |
|---|---|---|
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 分隔线尺寸。 |
| className | ClassValue | 分隔线 class。 |
SelectOptionProps
数据渲染组件属性,用于根据 SelectOptionData 渲染普通项、分组或分隔线。
| 字段 | 类型 | 说明 |
|---|---|---|
| item | SelectOptionData | 待渲染的选项数据。 |
| size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 选项尺寸。 |
| indicatorIcon | ReactNode | 选中指示器图标。 |
| classNames | SelectClassNames | slot class 配置。 |
SelectOptionData
Select items 中可使用的选项数据联合类型