Select

Listbox for picking one option.

Usage

Compose Select.Root, Select.Trigger, Select.Content, and Select.Item. The content portals to the body, so it escapes overflow clipping.

States

Individual items can be disabled while the rest remain interactive.

Props

Select.Root

PropTypeDefault
allowDeselect bits-ui Whether to allow the user to deselect an item by clicking on an already selected item. This is only applicable to `type="single"` selects/comboboxes.boolean | undefined
autocomplete bits-ui The autocomplete attribute to forward to the hidden input element.FullAutoFill | null | undefined
children bits-ui Snippet<[]> | undefined
disabled bits-ui Whether the combobox is disabled.boolean | undefined`false`
items bits-ui Optionally provide an array of `value` and `label` pairs that will be used to match and trigger selection when the trigger is focused and a key is pressed while the content is closed. It's also used to handle form autofill. By providing this value, you enable selecting a value when the trigger is focused and a key is pressed without the content being open, similar to how a native `<select>` works. For this to work, you must The label is what the user will potentially search for via typeahead, and the value is what is set as the selected value when a typeahead match is found. We can't rely on the individual `Item` components to do this because they may not ever be mounted to do the DOM if using a conditional block with a Svelte transition or certain animation libraries. IMPORTANT: This functionality is only available for single-select listboxes.{ value: string; label: string; disabled?: boolean | undefined; }[] | undefined
loop bits-ui Whether or not the combobox menu should loop through the items when navigating with the keyboard.boolean | undefined`false`
name bits-ui The name to apply to the hidden input element for form submission. If not provided, a hidden input will not be rendered and the combobox will not be part of a form.string | undefined
onOpenChange bits-ui A callback function called when the open state changes.OnChangeFn<boolean> | undefined
onOpenChangeComplete bits-ui A callback function called when the open state changes and the animation is complete.OnChangeFn<boolean> | undefined
onValueChange bits-ui A callback function called when the value changes.OnChangeFn<string> | OnChangeFn<string[]> | undefined
open bits-ui Whether the combobox popover is open.boolean | undefined`false`
required bits-ui Whether the combobox is required (for form submission).boolean | undefined`false`
scrollAlignment bits-ui How to scroll the combobox items into view when navigating with the keyboard."center" | "nearest" | undefined`"nearest"`
type required bits-ui The type of combobox."multiple" | "single"
value bits-ui The value of the selected combobox item.string | string[] | undefined

Select.Trigger

PropTypeDefault
invalid Marks the control as failing validation. Always applies the invalid styling. Does NOT set `aria-invalid`: this renders as `button`, and ARIA does not support the attribute there, so assistive technology is free to ignore it. axe does NOT flag it either way — verified by injecting it and watching the suite still pass — so this is a decision taken from the spec, not one a tool enforces. The accessible signal comes from `Field` wiring the error message through `aria-describedby`. Prefer letting `Field` drive this: passing `Field` an `error` is what makes a field invalid, so the message the user reads and the state of the control cannot disagree.booleanfalse
required Accepted and deliberately NOT forwarded. This renders as a `<button>`. A native `required` attribute is inert there, and `aria-required` is worse — axe reports it as an `aria-allowed-attr` violation, verified rather than assumed. (Note `aria-invalid` differs: axe accepts that one on a button. The two rules are not the same.) So it is swallowed here rather than emitted as dead markup. When wrapped by `Field`, the required signal a user gets is the marker on the visible label plus the error on submit — which is what `Field` is for.booleanfalse
class string
children Snippet
child bits-ui Snippet<[{ props: Record<string, unknown>; }]> | undefined
id bits-ui string | undefined
ref bits-ui HTMLElement | null | undefined

Select.Content

PropTypeDefault
class string
align bits-ui The preferred alignment of the anchor to render against when open. This may change when collisions occur."start" | "center" | "end" | undefined
alignOffset bits-ui An offset in pixels from the "start" or "end" alignment options.number | undefined
arrowPadding bits-ui This describes the padding between the arrow and the edges of the floating element. If your floating element has border-radius, this will prevent it from overflowing the corners.number | undefined
avoidCollisions bits-ui When `true`, overrides the `side` and `align` options to prevent collisions with the boundary edges.boolean | undefinedtrue
child bits-ui Snippet<[FloatingContentSnippetProps & { props: Record<string, unknown>; }]> | undefined
children bits-ui Snippet<[]> | undefined
collisionBoundary bits-ui A boundary element or array of elements to check for collisions against.Arrayable<Boundary> | undefined
collisionPadding bits-ui The amount in pixels of virtual padding around the viewport edges to check for overflow which will cause a collision.number | Partial<Record<"top" | "right" | "bottom" | "left", number>> | undefined8
customAnchor bits-ui Use an element other than the trigger to anchor the content to. If provided, the content will be anchored to the provided element instead of the trigger. You can pass a selector string or an HTMLElement.string | HTMLElement | Measurable | null | undefined
dir bits-ui The text direction of the content.Direction | undefined
escapeKeydownBehavior bits-ui Escape behavior type. `close`: Closes the element immediately. `defer-otherwise-close`: Delegates the action to its parent component that has an escape keydown handler. If no parent is found, it closes the element. `defer-otherwise-ignore`: Delegates the action to the parent element. If no parent is found, nothing is done. `ignore`: Prevents the element from closing and also blocks the parent element from closing in response to an escape key press.EscapeBehaviorType | undefined`close`
forceMount bits-ui Whether to force mount the component.boolean | undefined
hideWhenDetached bits-ui boolean | undefined
id bits-ui string | undefined
interactOutsideBehavior bits-ui Interact outside behavior type. `close`: Closes the element immediately. `defer-otherwise-close`: Delegates the action to the parent element. If no parent is found, it closes the element. `defer-otherwise-ignore`: Delegates the action to the parent element. If no parent is found, nothing is done. `ignore`: Prevents the element from closing and also blocks the parent element from closing in response to an outside interaction.InteractOutsideBehaviorType | undefined`close`
loop bits-ui Whether or not to loop through the items when navigating with the keyboard.boolean | undefined`false`
onEscapeKeydown bits-ui Callback fired when escape is pressed.((e: KeyboardEvent) => void) | undefined
onFocusOutside bits-ui Callback fired when focus leaves the dismissible layer.((event: FocusEvent) => void) | undefined
onInteractOutside bits-ui Callback fired when an outside interaction event completes, which is either a `pointerup`, `mouseup`, or `touchend` event, depending on the user's input device.InteractOutsideEventHandler | undefined
preventOverflowTextSelection bits-ui Passing `true` will prevent the overflow of text selection outside the element, provided the element is the top layer.boolean | undefined`true`
preventScroll bits-ui Whether to prevent scrolling the body when the content is open. Whether to prevent body scrolling when the content is open.boolean | undefinedtrue
ref bits-ui HTMLElement | null | undefined
side bits-ui The preferred side of the anchor to render against when open. Will be reversed when collisions occur."top" | "right" | "bottom" | "left" | undefined
sideOffset bits-ui The distance in pixels from the anchor to the floating element.number | undefined
sticky bits-ui "partial" | "always" | undefined
strategy bits-ui The positioning strategy to use for the floating element."absolute" | "fixed" | undefined
updatePositionStrategy bits-ui "optimized" will only update the position when necessary, while "always" will update the position on each animation frame, which is useful if the floating content is following something like a mouse cursor."always" | "optimized" | undefined"optimized"

Select.Item

PropTypeDefault
class string
child bits-ui Snippet<[SelectItemSnippetProps & { props: Record<string, unknown>; }]> | undefined
children bits-ui Snippet<[SelectItemSnippetProps]> | undefined
disabled bits-ui Whether the item is disabled.boolean | undefined`false`
id bits-ui string | undefined
label bits-ui The label of the item. If provided, this is the item that users will search for. If not provided, the value will be used as the label.string | undefined
onHighlight bits-ui A callback function called when the item is highlighted. This can be used as a replacement for `onfocus` since we don't actually focus the item and instead rely on the `aria-activedescendant` attribute to indicate the highlighted item.(() => void) | undefined
onUnhighlight bits-ui A callback function called when the item is unhighlighted. This can be used as a replacement for `onblur` since we don't actually focus the item and instead rely on the `aria-activedescendant` attribute to indicate the highlighted item.(() => void) | undefined
ref bits-ui HTMLElement | null | undefined
value required bits-ui The value of the item.string

All subcomponents also forward their corresponding Bits props via spreading.