Select
Displays a list of options for the user to pick from, triggered by a button.
Code
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue,} from "@falcon/ui-kit";
const items = [ { label: "Select a crop", value: null }, { label: "Corn", value: "corn" }, { label: "Soybeans", value: "soybeans" }, { label: "Wheat", value: "wheat" }, { label: "Cotton", value: "cotton" }, { label: "Sorghum", value: "sorghum" },];
export function Example() { return ( <div className="tw:flex tw:h-56 tw:items-center tw:justify-center"> <Select items={items}> <SelectTrigger className="tw:w-full tw:max-w-48" aria-label="Crop"> <SelectValue /> </SelectTrigger> <SelectContent> <SelectGroup> <SelectLabel>Crops</SelectLabel> {items.map((item) => ( <SelectItem key={item.label} value={item.value}> {item.label} </SelectItem> ))} </SelectGroup> </SelectContent> </Select> </div> );}Composition
Section titled “Composition”Use the following composition to build a Select:
Select├── SelectTrigger│ └── SelectValue└── SelectContent ├── SelectGroup │ ├── SelectLabel │ ├── SelectItem │ └── SelectItem ├── SelectSeparator └── SelectGroup ├── SelectLabel ├── SelectItem └── SelectItemAlign Item With Trigger
Section titled “Align Item With Trigger”Use alignItemWithTrigger on SelectContent to control whether the selected
item aligns with the trigger. When true (default), the popup positions so the
selected item appears over the trigger. When false, the popup aligns to the
trigger edge.
Code
import { Field, FieldContent, FieldDescription, FieldGroup, FieldLabel, Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue, Switch,} from "@falcon/ui-kit";import { useState } from "react";
const items = [ { label: "Select a crop", value: null }, { label: "Corn", value: "corn" }, { label: "Soybeans", value: "soybeans" }, { label: "Wheat", value: "wheat" }, { label: "Cotton", value: "cotton" }, { label: "Sorghum", value: "sorghum" },];
export function Example() { const [alignItemWithTrigger, setAlignItemWithTrigger] = useState(true);
return ( <FieldGroup className="tw:w-full tw:max-w-xs"> <Field orientation="horizontal"> <FieldContent> <FieldLabel htmlFor="align-item">Align item</FieldLabel> <FieldDescription> Toggle to align the option with the trigger. </FieldDescription> </FieldContent> <Switch id="align-item" checked={alignItemWithTrigger} onCheckedChange={setAlignItemWithTrigger} /> </Field> <Field> <Select items={items} defaultValue="soybeans"> <SelectTrigger aria-label="Crop"> <SelectValue /> </SelectTrigger> <SelectContent alignItemWithTrigger={alignItemWithTrigger}> <SelectGroup> {items.map((item) => ( <SelectItem key={item.label} value={item.value}> {item.label} </SelectItem> ))} </SelectGroup> </SelectContent> </Select> </Field> </FieldGroup> );}Groups
Section titled “Groups”Use SelectGroup, SelectLabel, and SelectSeparator to organize items.
Code
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue,} from "@falcon/ui-kit";
export function Example() { const grains = [ { label: "Corn", value: "corn" }, { label: "Soybeans", value: "soybeans" }, { label: "Wheat", value: "wheat" }, ]; const cropInputs = [ { label: "Seed", value: "seed" }, { label: "Fertilizer", value: "fertilizer" }, { label: "Crop protection", value: "crop-protection" }, ]; const allItems = [ { label: "Select a category", value: null }, ...grains, ...cropInputs, ]; return ( <Select items={allItems}> <SelectTrigger className="tw:w-full tw:max-w-48" aria-label="Product category" > <SelectValue /> </SelectTrigger> <SelectContent> <SelectGroup> <SelectLabel>Grains</SelectLabel> {grains.map((item) => ( <SelectItem key={item.value} value={item.value}> {item.label} </SelectItem> ))} </SelectGroup> <SelectSeparator /> <SelectGroup> <SelectLabel>Crop inputs</SelectLabel> {cropInputs.map((item) => ( <SelectItem key={item.value} value={item.value}> {item.label} </SelectItem> ))} </SelectGroup> </SelectContent> </Select> );}Scrollable
Section titled “Scrollable”A select with many items that scrolls.
Code
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue,} from "@falcon/ui-kit";
const northAmerica = [ { label: "Eastern Standard Time", value: "est" }, { label: "Central Standard Time", value: "cst" }, { label: "Mountain Standard Time", value: "mst" }, { label: "Pacific Standard Time", value: "pst" }, { label: "Alaska Standard Time", value: "akst" }, { label: "Hawaii Standard Time", value: "hst" },];
const europeAfrica = [ { label: "Greenwich Mean Time", value: "gmt" }, { label: "Central European Time", value: "cet" }, { label: "Eastern European Time", value: "eet" }, { label: "Western European Summer Time", value: "west" }, { label: "Central Africa Time", value: "cat" }, { label: "East Africa Time", value: "eat" },];
const asia = [ { label: "Moscow Time", value: "msk" }, { label: "India Standard Time", value: "ist" }, { label: "China Standard Time", value: "cst_china" }, { label: "Japan Standard Time", value: "jst" }, { label: "Korea Standard Time", value: "kst" }, { label: "Indonesia Central Standard Time", value: "ist_indonesia" },];
const australiaPacific = [ { label: "Australian Western Standard Time", value: "awst" }, { label: "Australian Central Standard Time", value: "acst" }, { label: "Australian Eastern Standard Time", value: "aest" }, { label: "New Zealand Standard Time", value: "nzst" }, { label: "Fiji Time", value: "fjt" },];
const southAmerica = [ { label: "Argentina Time", value: "art" }, { label: "Bolivia Time", value: "bot" }, { label: "Brasilia Time", value: "brt" }, { label: "Chile Standard Time", value: "clt" },];
const items = [ { label: "Select a timezone", value: null }, ...northAmerica, ...europeAfrica, ...asia, ...australiaPacific, ...southAmerica,];
export function Example() { return ( <Select items={items}> <SelectTrigger className="tw:w-full tw:max-w-64" aria-label="Time zone"> <SelectValue /> </SelectTrigger> <SelectContent> <SelectGroup> <SelectLabel>North America</SelectLabel> {northAmerica.map((item) => ( <SelectItem key={item.value} value={item.value}> {item.label} </SelectItem> ))} </SelectGroup> <SelectGroup> <SelectLabel>Europe & Africa</SelectLabel> {europeAfrica.map((item) => ( <SelectItem key={item.value} value={item.value}> {item.label} </SelectItem> ))} </SelectGroup> <SelectGroup> <SelectLabel>Asia</SelectLabel> {asia.map((item) => ( <SelectItem key={item.value} value={item.value}> {item.label} </SelectItem> ))} </SelectGroup> <SelectGroup> <SelectLabel>Australia & Pacific</SelectLabel> {australiaPacific.map((item) => ( <SelectItem key={item.value} value={item.value}> {item.label} </SelectItem> ))} </SelectGroup> <SelectGroup> <SelectLabel>South America</SelectLabel> {southAmerica.map((item) => ( <SelectItem key={item.value} value={item.value}> {item.label} </SelectItem> ))} </SelectGroup> </SelectContent> </Select> );}Disabled
Section titled “Disabled”Code
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue,} from "@falcon/ui-kit";
export function Example() { const items = [ { label: "Select an order status", value: null }, { label: "Draft", value: "draft" }, { label: "Confirmed", value: "confirmed" }, { label: "In progress", value: "in-progress" }, { label: "Canceled", value: "canceled", disabled: true }, { label: "Fulfilled", value: "fulfilled" }, ]; return ( <Select items={items} disabled> <SelectTrigger className="tw:w-full tw:max-w-48" aria-label="Order status" > <SelectValue /> </SelectTrigger> <SelectContent> <SelectGroup> {items.map((item) => ( <SelectItem key={item.label} value={item.value} disabled={item.disabled} > {item.label} </SelectItem> ))} </SelectGroup> </SelectContent> </Select> );}Invalid
Section titled “Invalid”Set data-invalid on Field and aria-invalid on SelectTrigger to show an
error state.
<Field data-invalid> <FieldLabel htmlFor="order-status">Order status</FieldLabel> <SelectTrigger id="order-status" aria-invalid> <SelectValue /> </SelectTrigger></Field>Code
import { Field, FieldError, FieldLabel, Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue,} from "@falcon/ui-kit";
const items = [ { label: "Select an order status", value: null }, { label: "Draft", value: "draft" }, { label: "Confirmed", value: "confirmed" }, { label: "Fulfilled", value: "fulfilled" },];
export function Example() { return ( <Field data-invalid className="tw:w-full tw:max-w-48"> <FieldLabel htmlFor="order-status">Order status</FieldLabel> <Select items={items}> <SelectTrigger id="order-status" aria-describedby="order-status-error" aria-invalid > <SelectValue /> </SelectTrigger> <SelectContent> <SelectGroup> {items.map((item) => ( <SelectItem key={item.label} value={item.value}> {item.label} </SelectItem> ))} </SelectGroup> </SelectContent> </Select> <FieldError id="order-status-error"> Please select an order status. </FieldError> </Field> );}Select
Section titled “Select”Groups all parts of the select. Does not render its own HTML element.
autoComplete
Section titled “autoComplete”autoComplete?: stringProvides a hint to the browser for autofill.
children
Section titled “children”children?: React.ReactNodeThe select trigger and popup content.
defaultOpen
Section titled “defaultOpen”defaultOpen?: booleanWhether the select popup is initially open. Use open for controlled
state. Defaults to false.
defaultValue
Section titled “defaultValue”defaultValue?: SelectValueType<Value, Multiple> | nullThe uncontrolled value of the select. Use value for controlled state.
disabled
Section titled “disabled”disabled?: booleanWhether the component ignores user interaction. Defaults to false.
form?: stringIdentifies the form that owns the hidden input.
highlightItemOnHover
Section titled “highlightItemOnHover”highlightItemOnHover?: booleanWhether moving the pointer over items highlights them. Defaults to true.
id?: stringThe ID of the select.
inputRef
Section titled “inputRef”inputRef?: React.Ref<HTMLInputElement>A ref to access the hidden input element.
isItemEqualToValue
Section titled “isItemEqualToValue”isItemEqualToValue?: ((itemValue: Value, value: Value) => boolean)Custom comparison logic for item values and the selected value. Defaults to
Object.is.
items?: readonly Group<any>[] | Record<string, React.ReactNode> | readonly { label: React.ReactNode; value: any; }[]Data for items rendered in the select popup.
itemToStringLabel
Section titled “itemToStringLabel”itemToStringLabel?: ((itemValue: Value) => string)Converts object item values to labels displayed in the trigger.
itemToStringValue
Section titled “itemToStringValue”itemToStringValue?: ((itemValue: Value) => string)Converts object item values to strings for form submission.
modal?: booleanWhether the open select limits outside interaction. Defaults to true.
multiple
Section titled “multiple”multiple?: MultipleWhether multiple items can be selected. Defaults to false.
name?: stringIdentifies the field when a form is submitted.
onOpenChange
Section titled “onOpenChange”onOpenChange?: ((open: boolean, eventDetails: SelectRootChangeEventDetails) => void)Event handler called when the select popup is opened or closed.
onOpenChangeComplete
Section titled “onOpenChangeComplete”onOpenChangeComplete?: ((open: boolean) => void)Event handler called after select popup animations complete.
onValueChange
Section titled “onValueChange”onValueChange?: ((value: SelectValueType<Value, Multiple> | (Multiple extends true ? never : null), eventDetails: SelectRootChangeEventDetails) => void)Event handler called when the selected value changes.
open?: booleanWhether the select popup is currently open.
readOnly
Section titled “readOnly”readOnly?: booleanWhether users can choose a different option. Defaults to false.
required
Section titled “required”required?: booleanWhether a value is required for form submission. Defaults to false.
value?: SelectValueType<Value, NoInfer<Multiple>> | nullThe controlled value of the select.
SelectContent
Section titled “SelectContent”Includes the portal, positioned popup, list, and scroll controls. Renders a
<div> element by default and accepts standard <div> props. Pair it with
SelectItem components.
align?: Align = "center"Popup alignment relative to its trigger. Defaults to "center".
alignItemWithTrigger
Section titled “alignItemWithTrigger”alignItemWithTrigger?: boolean = trueWhether the popup aligns item text with the trigger. Defaults to true.
alignOffset
Section titled “alignOffset”alignOffset?: number | OffsetFunction = 0Alignment-axis offset in pixels. Defaults to 0.
children
Section titled “children”children?: React.ReactNodeThe select items and groups.
className
Section titled “className”className?: stringCSS class applied to the select popup.
finalFocus
Section titled “finalFocus”finalFocus?: boolean | React.RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | HTMLElement | null | void)Determines the element to focus when the select popup is closed.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SelectPopupState>Allows replacing the popup element or composing it with another component.
side?: Side = "bottom"Side of the trigger where the popup is placed. Defaults to "bottom".
sideOffset
Section titled “sideOffset”sideOffset?: number | OffsetFunction = 4Distance between the trigger and popup in pixels. Defaults to 4.
style?: React.CSSProperties | ((state: SelectPopupState) => React.CSSProperties | undefined)Style applied to the popup, or a function based on its state.
SelectGroup
Section titled “SelectGroup”Groups related select items with a corresponding label. Renders a <div>
element by default and accepts standard <div> props.
className
Section titled “className”className?: stringCSS class applied to the group.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SelectGroupState>Allows replacing the group element or composing it with another component.
style?: React.CSSProperties | ((state: SelectGroupState) => React.CSSProperties | undefined)Style applied to the group, or a function based on its state.
SelectItem
Section titled “SelectItem”Selects a value in the parent select. Renders a <div> element by default
and accepts standard <div> props.
children
Section titled “children”children?: React.ReactNodeThe item’s visible label and optional icon.
className
Section titled “className”className?: stringCSS class applied to the item.
disabled
Section titled “disabled”disabled?: booleanWhether the component ignores user interaction. Defaults to false.
label?: stringText used to match the item during keyboard text navigation.
nativeButton
Section titled “nativeButton”nativeButton?: booleanWhether render produces a native <button> element. Defaults to false.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SelectItemState>Allows replacing the item element or composing it with another component.
style?: React.CSSProperties | ((state: SelectItemState) => React.CSSProperties | undefined)Style applied to the item, or a function based on its state.
value?: anyA unique value that identifies this select item. Defaults to null.
SelectLabel
Section titled “SelectLabel”Labels its parent select group. Renders a <div> element by default and
accepts standard <div> props.
className
Section titled “className”className?: stringCSS class applied to the group label.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SelectGroupLabelState>Allows replacing the label element or composing it with another component.
style?: React.CSSProperties | ((state: SelectGroupLabelState) => React.CSSProperties | undefined)Style applied to the label, or a function based on its state.
SelectScrollDownButton
Section titled “SelectScrollDownButton”Scrolls the select popup down while hovered and does not render for touch
input. Renders a <div> element by default and accepts standard <div>
props.
className
Section titled “className”className?: stringCSS class applied to the scroll control.
keepMounted
Section titled “keepMounted”keepMounted?: booleanWhether the element stays mounted when not scrollable. Defaults to false.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SelectScrollDownArrowState>Allows replacing the scroll control element or composing it with another component.
style?: React.CSSProperties | ((state: SelectScrollDownArrowState) => React.CSSProperties | undefined)Style applied to the scroll control, or a function based on its state.
SelectScrollUpButton
Section titled “SelectScrollUpButton”Scrolls the select popup up while hovered and does not render for touch
input. Renders a <div> element by default and accepts standard <div>
props.
className
Section titled “className”className?: stringCSS class applied to the scroll control.
keepMounted
Section titled “keepMounted”keepMounted?: booleanWhether the element stays mounted when not scrollable. Defaults to false.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SelectScrollUpArrowState>Allows replacing the scroll control element or composing it with another component.
style?: React.CSSProperties | ((state: SelectScrollUpArrowState) => React.CSSProperties | undefined)Style applied to the scroll control, or a function based on its state.
SelectSeparator
Section titled “SelectSeparator”Separates select items. Renders a <div> element by default and accepts
standard <div> props.
className
Section titled “className”className?: stringCSS class applied to the separator.
orientation
Section titled “orientation”orientation?: OrientationThe separator’s orientation. Defaults to "horizontal".
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SeparatorState>Allows replacing the separator element or composing it with another component.
style?: React.CSSProperties | ((state: SeparatorState) => React.CSSProperties | undefined)Style applied to the separator, or a function based on its state.
SelectTrigger
Section titled “SelectTrigger”Opens the select popup. Renders a <button> element by default, accepts
standard <button> props, and includes a disclosure icon.
children
Section titled “children”children?: React.ReactNodeThe trigger’s selected value.
className
Section titled “className”className?: stringCSS class applied to the trigger.
disabled
Section titled “disabled”disabled?: booleanWhether the component ignores user interaction. Defaults to false.
nativeButton
Section titled “nativeButton”nativeButton?: booleanWhether render produces a native <button> element. Defaults to true.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SelectTriggerState>Allows replacing the trigger element or composing it with another component.
size?: "sm" | "default" = "default"Controls the trigger’s dimensions. Defaults to "default".
style?: React.CSSProperties | ((state: SelectTriggerState) => React.CSSProperties | undefined)Style applied to the trigger, or a function based on its state.
SelectValue
Section titled “SelectValue”Displays the selected value or placeholder. Renders a <span> element by
default and accepts standard <span> props.
children
Section titled “children”children?: React.ReactNode | ((value: any) => React.ReactNode)Content or a function that formats the selected value.
className
Section titled “className”className?: stringCSS class applied to the selected value.
placeholder
Section titled “placeholder”placeholder?: React.ReactNodeThe value displayed when no item is selected.
render
Section titled “render”render?: React.ReactElement<any, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, SelectValueState>Allows replacing the value element or composing it with another component.
style?: React.CSSProperties | ((state: SelectValueState) => React.CSSProperties | undefined)Style applied to the value, or a function based on its state.