SelectMenu is a fully custom, Radix-based select component designed for app-like experiences (e.g. webviews in native apps). Unlike the native Select, it renders an in-page dropdown instead of delegating to the OS picker.

It uses the modern appearance by default with support for white and grey themes, three sizes (sm, md, lg), and an error state.

Read more about the underlying UI component on the Radix UI documentation site.

Basic usage

<SelectMenu theme="white" defaultValue="banana">
  <SelectMenu.Trigger placeholder="Pick a fruit" aria-label="Fruit" />
  <SelectMenu.Content>
    <SelectMenu.Item value="apple">Apple</SelectMenu.Item>
    <SelectMenu.Item value="banana">Banana</SelectMenu.Item>
    <SelectMenu.Item value="cherry">Cherry</SelectMenu.Item>
  </SelectMenu.Content>
</SelectMenu>

With groups

<SelectMenu theme="white">
  <SelectMenu.Trigger placeholder="Pick a food" aria-label="Food" />
  <SelectMenu.Content>
    <SelectMenu.Group>
      <SelectMenu.Label>Fruits</SelectMenu.Label>
      <SelectMenu.Item value="apple">Apple</SelectMenu.Item>
      <SelectMenu.Item value="banana">Banana</SelectMenu.Item>
    </SelectMenu.Group>
    <SelectMenu.Separator />
    <SelectMenu.Group>
      <SelectMenu.Label>Vegetables</SelectMenu.Label>
      <SelectMenu.Item value="carrot">Carrot</SelectMenu.Item>
      <SelectMenu.Item value="broccoli">Broccoli</SelectMenu.Item>
    </SelectMenu.Group>
  </SelectMenu.Content>
</SelectMenu>

Sizes

<div className="flex flex-col gap-4 min-w-70">
  <SelectMenu theme="white" size="sm" defaultValue="apple">
    <SelectMenu.Trigger placeholder="Small" aria-label="Small" />
    <SelectMenu.Content>
      <SelectMenu.Item value="apple">Apple</SelectMenu.Item>
      <SelectMenu.Item value="banana">Banana</SelectMenu.Item>
    </SelectMenu.Content>
  </SelectMenu>
  <SelectMenu theme="white" size="md" defaultValue="apple">
    <SelectMenu.Trigger placeholder="Medium" aria-label="Medium" />
    <SelectMenu.Content>
      <SelectMenu.Item value="apple">Apple</SelectMenu.Item>
      <SelectMenu.Item value="banana">Banana</SelectMenu.Item>
    </SelectMenu.Content>
  </SelectMenu>
  <SelectMenu theme="white" size="lg" defaultValue="apple">
    <SelectMenu.Trigger placeholder="Large" aria-label="Large" />
    <SelectMenu.Content>
      <SelectMenu.Item value="apple">Apple</SelectMenu.Item>
      <SelectMenu.Item value="banana">Banana</SelectMenu.Item>
    </SelectMenu.Content>
  </SelectMenu>
</div>

Disabled items

<SelectMenu theme="white">
  <SelectMenu.Trigger placeholder="Pick an option" aria-label="Options" />
  <SelectMenu.Content>
    <SelectMenu.Item value="enabled">Enabled option</SelectMenu.Item>
    <SelectMenu.Item value="disabled" disabled>Disabled option</SelectMenu.Item>
    <SelectMenu.Item value="another">Another option</SelectMenu.Item>
  </SelectMenu.Content>
</SelectMenu>

API Reference

SelectMenu
PropTypeDefaultRequired
autoComplete
string
--
defaultOpen
boolean
--
defaultValue
string
--
dir
"ltr" | "rtl"
--
disabled
boolean
--
form
string
--
name
string
--
onOpenChange
(open: boolean) => void
--
onValueChange
(value: string) => void
--
open
boolean
--
required
boolean
--
size
"sm" | "md" | "lg"
md-
state
"error"
--
theme
"white" | "grey"
grey-
value
string
--
SelectMenu.Trigger
PropTypeDefaultRequired
asChild
boolean
--
placeholder
string
--
SelectMenu.Content
PropTypeDefaultRequired
align
"center" | "start" | "end"
--
alignOffset
number
--
arrowPadding
number
--
asChild
boolean
--
avoidCollisions
boolean
--
collisionBoundary
null | Element | Boundary[]
--
collisionPadding
number | Partial<Record<"left" | "right" | "top" | "bottom", number>>
--
hideWhenDetached
boolean
--
onCloseAutoFocus
(event: Event) => void
--
onEscapeKeyDown
(event: KeyboardEvent) => void
--
onPointerDownOutside
(event: PointerDownOutsideEvent) => void
--
position
"item-aligned" | "popper"
popper-
side
"left" | "right" | "top" | "bottom"
--
sideOffset
number
4-
sticky
"partial" | "always"
--
updatePositionStrategy
"always" | "optimized"
--
SelectMenu.Item
PropTypeDefaultRequired
asChild
boolean
--
disabled
boolean
--
textValue
string
--
valuestring-
SelectMenu.Label
PropTypeDefaultRequired
asChild
boolean
--
SelectMenu.Separator
PropTypeDefaultRequired
asJSX.IntrinsicElements--
asChild
boolean
--