SelectMenu is a fully custom select component built on react-aria-components, 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.
Selection is key-based: give each SelectMenu.Item an id, and control the value with selectedKey/defaultSelectedKey and onSelectionChange. Label the menu with aria-label (or aria-labelledby) on the root SelectMenu.
Basic usage
<SelectMenutheme="white"aria-label="Fruit"defaultSelectedKey="banana"><SelectMenu.Triggerplaceholder="Pick a fruit"/><SelectMenu.Content><SelectMenu.Itemid="apple">Apple</SelectMenu.Item><SelectMenu.Itemid="banana">Banana</SelectMenu.Item><SelectMenu.Itemid="cherry">Cherry</SelectMenu.Item></SelectMenu.Content></SelectMenu>
With groups
<SelectMenutheme="white"aria-label="Food"><SelectMenu.Triggerplaceholder="Pick a food"/><SelectMenu.Content><SelectMenu.Group><SelectMenu.Label>Fruits</SelectMenu.Label><SelectMenu.Itemid="apple">Apple</SelectMenu.Item><SelectMenu.Itemid="banana">Banana</SelectMenu.Item></SelectMenu.Group><SelectMenu.Separator/><SelectMenu.Group><SelectMenu.Label>Vegetables</SelectMenu.Label><SelectMenu.Itemid="carrot">Carrot</SelectMenu.Item><SelectMenu.Itemid="broccoli">Broccoli</SelectMenu.Item></SelectMenu.Group></SelectMenu.Content></SelectMenu>
<SelectMenutheme="white"aria-label="Options"><SelectMenu.Triggerplaceholder="Pick an option"/><SelectMenu.Content><SelectMenu.Itemid="enabled">Enabled option</SelectMenu.Item><SelectMenu.Itemid="disabled"isDisabled>Disabled option</SelectMenu.Item><SelectMenu.Itemid="another">Another option</SelectMenu.Item></SelectMenu.Content></SelectMenu>
Matching the trigger width
By default the dropdown floors at the trigger width but grows to fit its content (up to a viewport/400px cap). Pass matchTriggerWidth on SelectMenu.Content to pin it to the trigger width instead — longer option labels wrap to fit rather than widening the menu. Compare the two below (both triggers are w-56):
<divclassName="flex gap-4 items-start"><SelectMenutheme="white"aria-label="Grows to fit"defaultSelectedKey="a"className="w-56"><SelectMenu.Triggerplaceholder="Default"/><SelectMenu.Content><SelectMenu.Itemid="a">Apple</SelectMenu.Item><SelectMenu.Itemid="b">Pineapple, mango and passionfruit smoothie</SelectMenu.Item></SelectMenu.Content></SelectMenu><SelectMenutheme="white"aria-label="Matches trigger"defaultSelectedKey="a"className="w-56"><SelectMenu.Triggerplaceholder="matchTriggerWidth"/><SelectMenu.ContentmatchTriggerWidth><SelectMenu.Itemid="a">Apple</SelectMenu.Item><SelectMenu.Itemid="b">Pineapple, mango and passionfruit smoothie</SelectMenu.Item></SelectMenu.Content></SelectMenu></div>