# SelectMenu

> Select with a custom listbox popup, for option lists that need descriptions, groups or a styled popup.

Source: https://ui.jcsoftdev.com/docs/components/select-menu

Select with a custom listbox popup, for option lists that need descriptions, groups or a
styled popup. Select-only combobox pattern (WAI-ARIA APG): focus stays on the trigger and the
highlighted option is announced through `aria-activedescendant`. Use `NativeSelect` when the
system picker is preferable (long lists on phones).

## Import

```ts
import { SelectMenu } from "@jcsoftdev/ui/forms";
```

Single-component entry points tree-shake to just this component: `@jcsoftdev/ui/forms/select-menu`.

## Usage

```tsx
<SelectMenu
  aria-label="Barber"
  options={barbers}
  placeholder="Pick a barber"
/>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `options` * | `readonly (SelectMenuOption \| SelectMenuGroup)[]` |  | Options, optionally nested in labelled groups. A `value` of `""` is a real option, not "nothing". |
| `value` | `string` |  | Selected value (controlled). An unknown value or `undefined` shows the placeholder. |
| `defaultValue` | `string` |  |  |
| `onValueChange` | `((value: string) => void)` |  |  |
| `placeholder` | `string` |  | Shown while no option is selected. Defaults to the localized "Select…". |
| `name` | `string` |  | Submits the value with a surrounding `<form>` through a hidden input. |
| `required` | `boolean` |  |  |
| `invalid` | `boolean` |  |  |
| `size` | `"sm" \| "md"` | `"md"` |  |
| `container` | `HTMLElement \| null` |  | Portal target for the popup. Defaults to `document.body`; pass an element to keep a scoped `data-style`. |
| `material` | `"solid" \| "glass" \| "glass-clear" \| "liquid" \| "liquid-clear"` |  | Popup surface material; see `PopoverContent`. |
| `classNames` | `Partial<Record<SelectMenuPart, string>>` |  | Per-part classes merged with `cn`; consumer classes win. `className` still targets the trigger and is merged last. |

`*` marks a required prop.

It also accepts the native props of the element or primitive it renders (for example `className`, `id`, `aria-*` and event handlers).

## Storybook stories

- [Default](/storybook/?path=/story/forms-selectmenu--default)
- [Keyboard](/storybook/?path=/story/forms-selectmenu--keyboard)
- [Escape Closes](/storybook/?path=/story/forms-selectmenu--escape-closes)
- [Space Opens And Tab Closes](/storybook/?path=/story/forms-selectmenu--space-opens-and-tab-closes)
- [Typeahead](/storybook/?path=/story/forms-selectmenu--typeahead)
- [Groups](/storybook/?path=/story/forms-selectmenu--groups)
- [Empty String Is An Option](/storybook/?path=/story/forms-selectmenu--empty-string-is-an-option)
- [Inside Field](/storybook/?path=/story/forms-selectmenu--inside-field)
- [Submits With AF Orm](/storybook/?path=/story/forms-selectmenu--submits-with-af-orm)
- [Disabled](/storybook/?path=/story/forms-selectmenu--disabled)
- [Controlled](/storybook/?path=/story/forms-selectmenu--controlled)
- [Spanish Placeholder](/storybook/?path=/story/forms-selectmenu--spanish-placeholder)

## Source

`packages/ui/src/forms/select-menu/select-menu.tsx`
