Select
Overview
Displays a list of options for the user to pick from, triggered by a button. The trigger renders the selected value (or placeholder), and the popup supports keyboard navigation, typeahead, grouping, multiple selection, and clearable mode. Use it to pick one or more values from a bounded set; for free-text search over a list, use SCombobox; for cascading hierarchical data, use SCascader.
Usage
Features
- 📊 Data-driven
SelectCompactAPI — passitems(options uselabel/valuefields) - ⌨️ Full combobox interaction — pointer/keyboard open, Arrow/Home/End navigation, typeahead search, Enter/Space select, Escape close
- 🗂 Grouping with group labels, separators, and item indicators
- ✅
multipleselection with accumulation and deduplication - 🧹 Clearable mode — trigger hover-reveal clear, plus
selectionBehaviorfor whether re-selecting toggles or resets - 📍 Item-aligned positioning (
position="item-aligned") - 📋 Native form submission via a hidden proxy
<select>(SelectBubbleSelect) - 📌
top/bottomslots for fixed header and footer content inside the popup - ♿ Full accessibility support —
role="combobox"/listbox/option, axe-clean
Demos
Basic
Default Value
Disabled
Separator
Group
Top & Bottom Slots
API
Aria Layer
20Select<T, M>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
class | ClassValue | — | the class of select trigger |
ui | Partial<SelectUi> | — | Per-slot class overrides for the component. |
size | ThemeSize | — | Visual size of the component. |
items | SelectOptionData<T>[] | — | Items rendered by the component. |
showArrow | boolean | — | Whether to show an arrow. |
triggerProps | SelectTriggerProps | — | Properties forwarded to the trigger element. |
triggerIconProps | SelectTriggerIconProps | — | Properties forwarded to the trigger icon element. |
showTriggerIcon | boolean | true | Whether to show the trigger icon. |
clearLabel | string | — | Clear label. |
clearProps | SelectClearProps | — | Properties forwarded to the clear element. |
placeholder | string | — | Placeholder. |
valueProps | SelectValueProps | — | Properties forwarded to the value element. |
portalProps | SelectPortalProps | — | Properties forwarded to the portal element. |
contentProps | SelectContentProps | — | Properties forwarded to the content element. |
placement | import("@/index").Placement | — | Placement. |
popupProps | SelectPopupProps | — | Properties forwarded to the popup element. |
viewportProps | SelectViewportProps | — | Properties forwarded to the viewport element. |
scrollDownButtonProps | SelectScrollDownButtonProps | — | Properties forwarded to the scroll down button element. |
scrollUpButtonProps | SelectScrollUpButtonProps | — | Properties forwarded to the scroll up button element. |
groupProps | SelectGroupProps | — | Properties forwarded to the group element. |
groupLabelProps | SelectGroupLabelProps | — | Properties forwarded to the group label element. |
itemProps | SelectItemProps | — | Properties forwarded to the item element. |
itemTextProps | SelectItemTextProps | — | Properties forwarded to the item text element. |
itemIndicatorProps | SelectItemIndicatorProps | — | Properties forwarded to the item indicator element. |
separatorProps | SelectSeparatorProps | — | Properties forwarded to the separator element. |
arrowProps | PopperArrowProps | — | Properties forwarded to the arrow element. |
open | boolean | — | The controlled open state of the Select. Can be bind as `v-model:open`. |
defaultOpen | boolean | — | The open state of the select when it is initially rendered. Use when you do not need to control its open state. |
nullableValue | string | — | The value of the hidden native select option when the model value is nullish. |
dir | Direction | — | The reading direction of the combobox when applicable. <br> If omitted, inherits globally from `ConfigProvider` or
assumes LTR (left-to-right) reading mode. |
autocomplete | string | — | Native html input `autocomplete` attribute. |
disabled | boolean | — | When `true`, prevents the user from interacting with Select |
modelValue | (M extends true ? T[] : T) | — | The controlled value of the selected item(s).
Use this when you need to control the state of the items. Can be bound with `v-model` |
defaultValue | (M extends true ? T[] : T) | — | The default value of the selected item(s).
Use this when you need to set the initial state of the items. |
multiple | M | — | Determines whether a "single" or "multiple" items can be selected at a time.
This prop will overwrite the inferred type from `modelValue` and `defaultValue`. |
clearable | boolean | — | Whether selected item can be cleared when `multiple` is false. |
selectionBehavior | SelectionBehavior | 'toggle' | How multiple selection should behave in the collection. |
name | string | — | The name of the field. Submitted with its owning form as part of a name/value pair. |
required | boolean | — | When `true`, indicates that the user must set the value before the owning form can be submitted. |
Emits
| Emit Name | Parameters | Description |
|---|---|---|
update:modelValue | M extends true ? T[] : T | — |
update:open | boolean | Event handler called when the open state of the context menu changes. |
closeAutoFocus | Event | Emitted when close auto focus occurs. |
escapeKeyDown | KeyboardEvent | Event handler called when the escape key is down. Can be prevented. |
pointerDownOutside | PointerDownOutsideEvent | Event handler called when the a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented. |
select | SelectItemEvent<T> | Event handler called when the selecting item. <br> It can be prevented by calling `event.preventDefault`. |
Slots
| Slot Name | Parameters | Description |
|---|---|---|
top | — | Custom content rendered at the top of the popup, fixed above the scrollable list. |
bottom | — | Custom content rendered at the bottom of the popup, fixed below the scrollable list. |
trigger-leading | — | Custom content for the trigger leading slot. |
trigger-value | SelectCompactTriggerValueSlotProps<T, M> | Custom content for the trigger value slot. |
trigger-trailing | — | Custom content for the trigger trailing slot. |
trigger-icon | — | Custom content for the trigger icon slot. |
scroll-up-button | — | Custom content for the scroll up button slot. |
scroll-down-button | — | Custom content for the scroll down button slot. |
group-label | SelectCompactGroupLabelSlotProps<T> | Custom content for the group label slot. |
item-text | SelectCompactItemSlotProps<T> | Custom content for the item text slot. |
item-leading | SelectCompactItemSlotProps<T> | Custom content for the item leading slot. |
item-trailing | SelectCompactItemSlotProps<T> | Custom content for the item trailing slot. |
item-indicator | SelectCompactItemSlotProps<T> | Custom content for the item indicator slot. |
SelectArrow
SelectClear
Props
| Prop | Type | Default | Description |
|---|---|---|---|
ariaLabel | string | — | Aria label for the clear button. |
disabled | boolean | — | Whether the clear button is disabled. |
SelectCompact<T, M>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | SelectOptionData<T>[] | — | Items rendered by the component. |
showArrow | boolean | — | Whether to show an arrow. |
triggerProps | SelectTriggerProps | — | Properties forwarded to the trigger element. |
triggerIconProps | SelectTriggerIconProps | — | Properties forwarded to the trigger icon element. |
showTriggerIcon | boolean | true | Whether to show the trigger icon. |
clearLabel | string | — | Clear label. |
clearProps | SelectClearProps | — | Properties forwarded to the clear element. |
placeholder | string | — | Placeholder. |
valueProps | SelectValueProps | — | Properties forwarded to the value element. |
portalProps | SelectPortalProps | — | Properties forwarded to the portal element. |
contentProps | SelectContentProps | — | Properties forwarded to the content element. |
placement | import("@/index").Placement | — | Placement. |
popupProps | SelectPopupProps | — | Properties forwarded to the popup element. |
viewportProps | SelectViewportProps | — | Properties forwarded to the viewport element. |
scrollDownButtonProps | SelectScrollDownButtonProps | — | Properties forwarded to the scroll down button element. |
scrollUpButtonProps | SelectScrollUpButtonProps | — | Properties forwarded to the scroll up button element. |
groupProps | SelectGroupProps | — | Properties forwarded to the group element. |
groupLabelProps | SelectGroupLabelProps | — | Properties forwarded to the group label element. |
itemProps | SelectItemProps | — | Properties forwarded to the item element. |
itemTextProps | SelectItemTextProps | — | Properties forwarded to the item text element. |
itemIndicatorProps | SelectItemIndicatorProps | — | Properties forwarded to the item indicator element. |
separatorProps | SelectSeparatorProps | — | Properties forwarded to the separator element. |
arrowProps | PopperArrowProps | — | Properties forwarded to the arrow element. |
open | boolean | — | The controlled open state of the Select. Can be bind as `v-model:open`. |
defaultOpen | boolean | — | The open state of the select when it is initially rendered. Use when you do not need to control its open state. |
nullableValue | string | — | The value of the hidden native select option when the model value is nullish. |
dir | Direction | — | The reading direction of the combobox when applicable. <br> If omitted, inherits globally from `ConfigProvider` or
assumes LTR (left-to-right) reading mode. |
autocomplete | string | — | Native html input `autocomplete` attribute. |
disabled | boolean | — | When `true`, prevents the user from interacting with Select |
modelValue | (M extends true ? T[] : T) | — | The controlled value of the selected item(s).
Use this when you need to control the state of the items. Can be bound with `v-model` |
defaultValue | (M extends true ? T[] : T) | — | The default value of the selected item(s).
Use this when you need to set the initial state of the items. |
multiple | M | — | Determines whether a "single" or "multiple" items can be selected at a time.
This prop will overwrite the inferred type from `modelValue` and `defaultValue`. |
clearable | boolean | — | Whether selected item can be cleared when `multiple` is false. |
selectionBehavior | SelectionBehavior | 'toggle' | How multiple selection should behave in the collection. |
name | string | — | The name of the field. Submitted with its owning form as part of a name/value pair. |
required | boolean | — | When `true`, indicates that the user must set the value before the owning form can be submitted. |
Emits
| Emit Name | Parameters | Description |
|---|---|---|
update:modelValue | M extends true ? T[] : T | — |
update:open | boolean | Event handler called when the open state of the context menu changes. |
closeAutoFocus | Event | Emitted when close auto focus occurs. |
escapeKeyDown | KeyboardEvent | Event handler called when the escape key is down. Can be prevented. |
pointerDownOutside | PointerDownOutsideEvent | Event handler called when the a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented. |
select | SelectItemEvent<T> | Event handler called when the selecting item. <br> It can be prevented by calling `event.preventDefault`. |
Slots
| Slot Name | Parameters | Description |
|---|---|---|
top | — | Custom content rendered at the top of the popup, fixed above the scrollable list. |
bottom | — | Custom content rendered at the bottom of the popup, fixed below the scrollable list. |
trigger-leading | — | Custom content for the trigger leading slot. |
trigger-value | SelectCompactTriggerValueSlotProps<T, M> | Custom content for the trigger value slot. |
trigger-trailing | — | Custom content for the trigger trailing slot. |
trigger-icon | — | Custom content for the trigger icon slot. |
scroll-up-button | — | Custom content for the scroll up button slot. |
scroll-down-button | — | Custom content for the scroll down button slot. |
group-label | SelectCompactGroupLabelSlotProps<T> | Custom content for the group label slot. |
item-text | SelectCompactItemSlotProps<T> | Custom content for the item text slot. |
item-leading | SelectCompactItemSlotProps<T> | Custom content for the item leading slot. |
item-trailing | SelectCompactItemSlotProps<T> | Custom content for the item trailing slot. |
item-indicator | SelectCompactItemSlotProps<T> | Custom content for the item indicator slot. |
SelectContent
Props
| Prop | Type | Default | Description |
|---|---|---|---|
position | SelectPosition | — | The positioning mode to use
`item-aligned (default)` - behaves similarly to a native MacOS menu by positioning content relative to the active
item. <br> `popper` - positions content in the same way as our other primitives, for example `Popover` or
`DropdownMenu`. |
bodyLock | boolean | true | The document.body will be lock, and scrolling will be disabled. |
popupProps | SelectPopupProps | — | Properties forwarded to the popup element. |
open | boolean | true | Whether the floating layer is open. Drives the positioning lifecycle (`isPositioned`
resets when open flips); the positioning primitive itself has no open state, so
consumers wire their own open state here. |
placement | Placement | undefined | The placement of the floating element.
If used, it will override the `side` and `align` props. |
side | Side | 'bottom' | The preferred side of the anchor to render against when open. Will be reversed when collisions occur and
avoidCollisions is enabled. |
sideOffset | number | 0 | The distance in pixels from the anchor. |
sideFlip | boolean | true | Flip to the opposite side when colliding with boundary. |
align | Align | 'center' | The preferred alignment against the anchor. May change when collisions occur. |
alignOffset | number | 0 | An offset in pixels from the `start` or `end` alignment options. |
alignFlip | boolean | true | Flip alignment when colliding with boundary.
May only occur when `prioritizePosition` is true. |
avoidCollisions | boolean | true | When `true`, overrides the side and align preferences to prevent collisions with boundary edges. |
collisionBoundary | Element | (Element | null)[] | null | [ ] | The element used as the collision boundary. By default this is the viewport, though you can provide additional
element(s) to be included in this check. |
collisionPadding | Padding | 0 | The distance in pixels from the boundary edges where collision detection should occur. Accepts a number (same for
all sides), or a partial padding object, for example: { top: 20, left: 20 }. |
arrowPadding | number | 0 | The padding between the arrow and the edges of the content. If your content has border-radius, this will prevent it
from overflowing the corners. |
hideShiftedArrow | boolean | false | When `true`, hides the arrow when it cannot be centered
to the reference element. |
sticky | 'partial' | 'always' | 'partial' | The sticky behavior on the align axis. `partial` will keep the content in the boundary as long as the anchor is at
least partially in the boundary whilst "always" will keep the content in the boundary regardless. |
hideWhenDetached | boolean | false | Whether to hide the content when the anchor becomes fully occluded. |
positionStrategy | 'fixed' | 'absolute' | 'fixed' | The type of CSS position property to use. |
updatePositionStrategy | 'always' | 'optimized' | 'optimized' | Strategy to update the position of the floating element on every animation frame. |
disableUpdateOnLayoutShift | boolean | false | Whether to disable the update position for the content when the layout shifted. |
prioritizePosition | boolean | false | Force content to be position within the viewport. Might overlap the reference element, which may not be desired. |
reference | ReferenceElement | — | The custom element or virtual element that will be set as the reference to position the floating element. If
provided, it will replace the default anchor element. |
disableOutsidePointerEvents | boolean | — | When `true`, hover/focus/click interactions will be disabled on elements outside the `DismissableLayer`. Users will
need to click twice on outside elements to interact with them: once to close the `DismissableLayer`, and again to
trigger the element. |
forceMount | boolean | — | Used to force mounting when more control is needed.
Useful when controlling animation with Vue animation libraries. |
Emits
| Emit Name | Parameters | Description |
|---|---|---|
closeAutoFocus | Event | Emitted when close auto focus occurs. |
escapeKeyDown | KeyboardEvent | Event handler called when the escape key is down. Can be prevented. |
pointerDownOutside | PointerDownOutsideEvent | Event handler called when the a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented. |
SelectGroup
SelectGroupLabel
SelectItem
Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | DefinedValue | — | The value given as data when submitted with a `name`. |
disabled | boolean | — | When `true`, prevents the user from interacting with the item. |
textValue | string | — | Optional text used for typeahead purposes. By default the typeahead behavior will use the `.textContent` of the
`SelectItemText` part. Use this when the content is complex, or you have non-textual content inside. |
asChild | boolean | — | Change the default rendered element for the one passed as a child, merging their props and behavior. |
as | AsTag | Component | 'div' | The element or component this component should render as. Can be overwrite by `asChild` |
Emits
| Emit Name | Parameters | Description |
|---|---|---|
select | SelectItemEvent<T> | Event handler called when the selecting item. <br> It can be prevented by calling `event.preventDefault`. |
SelectItemIndicator
Props
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | — | Change the default rendered element for the one passed as a child, merging their props and behavior. |
as | AsTag | Component | 'div' | The element or component this component should render as. Can be overwrite by `asChild` |
SelectItemText
SelectPopup
SelectPortal
SelectRoot<T, M>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | — | The controlled open state of the Select. Can be bind as `v-model:open`. |
defaultOpen | boolean | — | The open state of the select when it is initially rendered. Use when you do not need to control its open state. |
nullableValue | string | — | The value of the hidden native select option when the model value is nullish. |
dir | Direction | — | The reading direction of the combobox when applicable. <br> If omitted, inherits globally from `ConfigProvider` or
assumes LTR (left-to-right) reading mode. |
autocomplete | string | — | Native html input `autocomplete` attribute. |
disabled | boolean | — | When `true`, prevents the user from interacting with Select |
modelValue | (M extends true ? T[] : T) | — | The controlled value of the selected item(s).
Use this when you need to control the state of the items. Can be bound with `v-model` |
defaultValue | (M extends true ? T[] : T) | — | The default value of the selected item(s).
Use this when you need to set the initial state of the items. |
multiple | M | — | Determines whether a "single" or "multiple" items can be selected at a time.
This prop will overwrite the inferred type from `modelValue` and `defaultValue`. |
clearable | boolean | — | Whether selected item can be cleared when `multiple` is false. |
selectionBehavior | SelectionBehavior | 'toggle' | How multiple selection should behave in the collection. |
name | string | — | The name of the field. Submitted with its owning form as part of a name/value pair. |
required | boolean | — | When `true`, indicates that the user must set the value before the owning form can be submitted. |
Emits
| Emit Name | Parameters | Description |
|---|---|---|
update:modelValue | M extends true ? T[] : T | — |
update:open | boolean | Event handler called when the open state of the context menu changes. |
SelectScrollDownButton
Props
| Prop | Type | Default | Description |
|---|---|---|---|
type | ButtonType | 'button' | The type of the button element. Can be one of 'button', 'submit', or 'reset'. |
disabled | boolean | — | Whether the component is disabled. |
asChild | boolean | — | Change the default rendered element for the one passed as a child, merging their props and behavior. |
as | AsTag | Component | 'div' | The element or component this component should render as. Can be overwrite by `asChild` |
SelectScrollUpButton
Props
| Prop | Type | Default | Description |
|---|---|---|---|
type | ButtonType | 'button' | The type of the button element. Can be one of 'button', 'submit', or 'reset'. |
disabled | boolean | — | Whether the component is disabled. |
asChild | boolean | — | Change the default rendered element for the one passed as a child, merging their props and behavior. |
as | AsTag | Component | 'div' | The element or component this component should render as. Can be overwrite by `asChild` |
SelectSeparator
SelectTrigger
Props
| Prop | Type | Default | Description |
|---|---|---|---|
disabled | boolean | — | Whether the component is disabled. |
reference | ReferenceElement | — | — |
asChild | boolean | — | Change the default rendered element for the one passed as a child, merging their props and behavior. |
as | AsTag | Component | 'div' | The element or component this component should render as. Can be overwrite by `asChild` |
SelectTriggerIcon
SelectValue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
placeholder | string | — | The content that will be rendered inside the `SelectValue` when no `value` or `defaultValue` is set. |
SelectViewport
Props
| Prop | Type | Default | Description |
|---|---|---|---|
nonce | string | — | Will add `nonce` attribute to the style tag which can be used by Content Security Policy. <br> If omitted, inherits
globally from `ConfigProvider`. |
Notes
Architecture and benchmark differences
VeanUI builds select on a full ComboBox base: SelectRoot → SelectTrigger (role="combobox") → SelectValue (collection label lookup) → SelectContentImpl (DismissableLayer + FocusScope + typeahead + keyboard nav) → SelectItem, with SelectBubbleSelect proxying native form submission. The scv() recipe selectVariants declares 16 slots and 7 size variants. This mirrors reka-ui / shadcn select semantics with a data-driven SelectCompact aggregation as the VeanUI differentiator.
| Capability | VeanUI | reka-ui Select | shadcn Select | Element Plus el-select |
|---|---|---|---|---|
| Aria/styled split | ✅ | ✅ | — | — |
| combobox role + keyboard nav | ✅ | ✅ | ✅ | ✅ |
| Typeahead search | ✅ | ✅ | — | ✅ |
| Controlled / uncontrolled + multiple | ✅ | ✅ | — | ✅ |
| Grouping + group labels | ✅ | ✅ | ✅ | ✅ |
| Form proxying (BubbleSelect) | ✅ | ✅ | — | ✅ |
| Item-aligned positioning | ✅ | ✅ | — | — |
| Data-driven Compact API | ✅ | — | — | — |
| Virtual scrolling | — | — | — | ✅ |
| axe-clean (open state) | ✅ | — | ✅ | — |
Cautions
- Before the popup first opens, label lookup relies on the data-driven
fallbackLabelcomputed fromitems— passitems(not just composition children) so the trigger text renders fordefaultValue/ controlledmodelValue. virtualscrolling is not implemented; very large option lists may need custom virtualization.multiplewithclearableusesselectionBehaviorto decide whether clearing toggles off or resets the selection.
FAQ
How do I show the selected label before the popup is opened?
Pass items to SSelect. SelectCompact resolves the label from items via fallbackLabel, so defaultValue / controlled modelValue render on the trigger immediately.
How do I enable multiple selection?
Pass multiple. Selections accumulate and deduplicate; modelValue becomes an array.
How do I group options?
Pass grouped items — a group entry carries a label and a nested items array. Group headers render via the group-label slot, and separators via separator.
How does the select submit in a native form?
The component renders a hidden native <select> (SelectBubbleSelect) mirroring the current value, so native form submission and browser autofill work.
How do I make the trigger show an arrow or custom content?
Use the trigger-icon / value slots or the showArrow-equivalent slot surface; all 16 recipe slots are forwarded by SSelect.
How do I clear the selected value from the trigger?
clearable defaults to true. With a value selected, hover or focus the trigger to reveal an ✕ button; clicking it resets modelValue to undefined (or [] when multiple). Pass :clearable="false" to hide it. Re-clicking the selected option still follows selectionBehavior.
How do I add fixed header or footer content inside the popup?
Use the top and bottom slots. top renders above the scrollable list and bottom below it; both stay fixed while only the middle option list scrolls.