ui · Primitive
Select
@devalok/shilp-sutra/ui/selectView in Storybook Preview
Variants
size
variant
state
disabled
Reference
- Import: @devalok/shilp-sutra/ui/select
- Server-safe: No
- Category: ui
Props
SelectTrigger
variant: "default" | "outline" | "ghost"
state: "default" | "error" | "warning" | "success" (validation; sets aria-invalid when error. Inherited from FormField when omitted)
size: "xs" | "sm" | "md" | "lg"
Compound Components
Select (root — value, onValueChange, defaultValue)
SelectTrigger (variant/state/size go HERE, not on Select root)
SelectValue (placeholder)
SelectContent
SelectGroup (optional grouping)
SelectLabel (group header)
SelectItem (value: string, REQUIRED)
SelectSeparator
Defaults
SelectTrigger variant="default", state="default", size="md"
Example
<Select onValueChange={setValue}>
<SelectTrigger size="lg">
<SelectValue placeholder="Choose..." />
</SelectTrigger>
<SelectContent>
<SelectItem value="a">Option A</SelectItem>
<SelectItem value="b">Option B</SelectItem>
</SelectContent>
</Select>Composability
- Radix Select underneath —
value/onValueChange/defaultValue/open/onOpenChangestandard state. - Styling props live on SelectTrigger, not Select root. The Select root owns value/state; the Trigger owns appearance (variant/state/size). Setting
<Select size="lg">silently does nothing — TypeScript won't catch it. - SelectItem requires
value— unique within the Select. Labels are the children of SelectItem. - SelectGroup + SelectLabel: Organize options into sections with a non-interactive section heading.
- FormField integration: Set
state="error"on SelectTrigger for error visuals, or omit it inside a<FormField state="error">— SelectTrigger now inherits the field state from context (explicitstateprop wins). Unified with Input/Textarea/Checkbox/Radio/Switch/Combobox via the sharedFieldStatetype. - Portal + z-popover (1400): content portals to body, stacks above Dialog/Sheet/other overlays.
- Select vs Combobox vs Autocomplete: Select = short fixed list, click-to-open, no typeahead. Combobox = searchable, forced selection. Autocomplete = searchable, free text. Pick by list size and search need.
Gotchas
- Size goes on SelectTrigger, NOT on Select root
<Select size="lg">is silently ignored (no TypeScript error)
Changes
v0.49.0
- BREAKING Renamed the SelectTrigger
colorprop →state(unified field-state API across all form controls; typeFieldState = "default" | "error" | "warning" | "success"). Migrate<SelectTrigger color="error">→<SelectTrigger state="error">. - Added SelectTrigger now inherits validation state from
FormFieldcontext (was manual-only before).
v0.31.0
- Added
variantprop on SelectTrigger:default | outline | ghost - Added
colorprop on SelectTrigger:default | error | success | warning. Setsaria-invalidwhen error.
v0.15.0
- Changed
lgsize font changed fromtext-ds-lg(18px) totext-ds-md(14px) — all input sizes now use 14px for consistency
v0.14.0
- Changed z-index promoted from
z-dropdown(1000) toz-popover(1400) — fixes content rendering behind Sheet/Dialog overlays
v0.1.0
- Added Initial release