> ## Documentation Index
> Fetch the complete documentation index at: https://docs.twenty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Dropdown

> Action menus, searchable pickers, and form panels with shared presentation and interaction.

export const StoryEmbed = ({storyId, title, height = 240}) => <>
    <Tabs>
      <Tab title="Light">
        <iframe title={`${title} (light)`} src={`https://storybook.twenty.com/iframe.html?id=${storyId}&viewMode=story&globals=colorScheme:light`} width="100%" height={height} loading="lazy" style={{
  border: 0
}} />
      </Tab>
      <Tab title="Dark">
        <iframe title={`${title} (dark)`} src={`https://storybook.twenty.com/iframe.html?id=${storyId}&viewMode=story&globals=colorScheme:dark`} width="100%" height={height} loading="lazy" style={{
  border: 0
}} />
      </Tab>
    </Tabs>
    <a href={`https://storybook.twenty.com/?path=/story/${storyId}`}>
      Open in Storybook
    </a>
  </>;

`Dropdown` combines a positioned popup, visual rows, keyboard navigation, focus, and dismissal. Your application owns data, filtering, fetching, pagination, and selected values. Import it from `twenty-ui/components`.

<StoryEmbed storyId="ui-components-dropdown--documentation" title="Dropdown actions" height={380} />

Dropdown.Content accepts numeric offsets or functions for `sideOffset` and `alignOffset`. Offset functions receive the anchor and popup dimensions, side, and alignment. Use them to preserve an anchored field picker’s overlap when the cell is scaled.

## Choose an interaction type

Set `type` on `Dropdown.Root` to match the popup's contents.

| Type | Content | Interaction |
| - | - | - |
| `menu` | Commands and navigation links | Menu semantics with arrow navigation and typeahead. |
| `picker` | Search, selectable values, and optional commands | A dialog containing a search field and selectable toggle buttons. Arrow keys navigate result rows. |
| `panel` | Inputs, forms, and supporting actions | A dialog with native input behavior and Tab navigation. |

Pickers allow creation actions and selectable values in the same list, in any order. Options expose their selected state with `aria-pressed`; commands keep their button semantics. Omit `selected` on an option that navigates or applies without a selection state, so it exposes no pressed state. Give `Search` an accessible name.

`Content` takes its accessible name from `Trigger`, or from `SubmenuTrigger` in a submenu. Pass `aria-label` on `Content` when the trigger shows a value, such as the selected option, or when the root has no trigger. An explicit `aria-label` or `aria-labelledby`, and a `Title` inside a `Header`, take precedence over the trigger name.

The underlying [Menu](/ui/primitives/surfaces/menu), [Select](/ui/primitives/input/select), and [Popover](/ui/primitives/surfaces/popover) remain available for direct composition.

## Anatomy

```text theme={null}
Dropdown.Root
├── Dropdown.Trigger
└── Dropdown.Content
    ├── Dropdown.Header
    │   ├── Dropdown.Close
    │   └── Dropdown.Title
    ├── Dropdown.Search
    └── Dropdown.Section
        ├── Dropdown.ActionItem
        └── Dropdown.OptionItem
```

`Content` includes the portal and positioner. Use `width`, `side`, `align`, `sideOffset`, and `alignOffset` to control placement, and `collisionPadding` to keep the popup further from the edges of the viewport before it shifts or flips (5 pixels by default). `Section` groups rows with shared spacing, and `Separator` divides sections. A `scrollable` Section caps its height and scrolls; nest labelled sections inside it to scroll them as one list. Rows use [ListItem](/ui/primitives/navigation/list-item) for their appearance.

```tsx theme={null}
import { Dropdown } from 'twenty-ui/components/navigation';
import { IconCopy } from 'twenty-ui/icon';
import { Button } from 'twenty-ui/primitives/input';

export const RecordActions = ({ onDuplicate }: { onDuplicate: () => void }) => (
  <Dropdown.Root type="menu">
    <Dropdown.Trigger render={<Button>Record actions</Button>} />
    <Dropdown.Content>
      <Dropdown.Section>
        <Dropdown.ActionItem startIcon={<IconCopy />} onClick={onDuplicate}>
          Duplicate
        </Dropdown.ActionItem>
      </Dropdown.Section>
    </Dropdown.Content>
  </Dropdown.Root>
);
```

Pass custom trigger elements through `render` so the trigger remains one interactive element. Custom components must forward the supplied props and ref. `ActionItem` also accepts `render` for links.

## Headers

`Header` lays out a row at the top of the popup. Put a `Title` in it to name the popup after the title instead of the trigger. `Close` closes the popup the same way an outside press does. It renders an icon button with an X by default, so give it an `aria-label`, or pass `render` and children for another control. Other controls, such as a button that returns to a previous step, can sit in the same row. Use `Dropdown.Back` when navigating the root's page history.

## Search and selection

`Search` provides the input and navigation into the result rows. Pass `value` and `onValueChange`; compute or fetch matching results in your application. Render `Loading` while a request is pending and `Empty` when no results match. Both accept caller-provided status text.

<StoryEmbed storyId="ui-components-dropdown--picker-documentation" title="Searchable picker with inline creation" height={420} />

```tsx theme={null}
import { useState } from 'react';
import { Dropdown } from 'twenty-ui/components/navigation';
import { Button } from 'twenty-ui/primitives/input';

export const PersonPicker = () => {
  const [search, setSearch] = useState('');
  const [selectedPerson, setSelectedPerson] = useState('');
  const people = ['Ada Lovelace', 'Grace Hopper'].filter((person) =>
    person.toLowerCase().includes(search.toLowerCase()),
  );

  return (
    <Dropdown.Root type="picker">
      <Dropdown.Trigger render={<Button>Choose person</Button>} />
      <Dropdown.Content>
        <Dropdown.Search
          aria-label="Search people"
          value={search}
          onValueChange={setSearch}
        />
        <Dropdown.Section>
          {people.map((person) => (
            <Dropdown.OptionItem
              key={person}
              selected={selectedPerson === person}
              onSelect={() => setSelectedPerson(person)}
            >
              {person}
            </Dropdown.OptionItem>
          ))}
        </Dropdown.Section>
      </Dropdown.Content>
    </Dropdown.Root>
  );
};
```

While `Search` holds text, the first enabled `OptionItem` is highlighted and Enter activates it. Action rows are never picked this way. With an empty search, Enter does nothing; ArrowDown moves focus into the results. When rows are pinned above the matches, such as the current value or a "none" row, render them only when they match the search text, so Enter picks the first real match. The popup stays open when no option matches. Filtering remains caller-owned.

Actions and single selection close by default. Set `multiple` on the root to keep option selection open. The application still owns the selected values. `closeOnClick` on actions and `closeOnSelect` on options override those defaults, including repeated actions or asynchronous progress. Use `disabled` to prevent activation while retaining the row's appearance.

<StoryEmbed storyId="ui-components-dropdown--multiple-selection-documentation" title="Multiple selection" height={420} />

## Icon grids

Set `columns` on `Section` to lay out items in equal-width grid columns. The same count drives keyboard navigation: Left and Right move within a row, while Up and Down move between rows. Navigation skips disabled options and follows the reading direction. When no enabled option is left in the column, Up and Down move to the nearest enabled option of the next row. Up from the first row returns to the search field when no earlier section exists. A short final row uses its last item when the requested column is missing. Inside a submenu, the backward arrow closes the submenu when no enabled option remains to its left.

Render each icon as an `OptionItem` with an accessible label and an icon button through `render`. Use `indicator="none"` to show selection through the button background.

```tsx theme={null}
import { useState } from 'react';
import { LightIconButton } from 'twenty-ui/components/input';
import { Dropdown } from 'twenty-ui/components/navigation';
import { IconCalendar } from 'twenty-ui/icon';
import { Button } from 'twenty-ui/primitives/input';

export const IconGrid = () => {
  const [icon, setIcon] = useState('');

  return (
    <Dropdown.Root type="picker">
      <Dropdown.Trigger render={<Button>Choose icon</Button>} />
      <Dropdown.Content>
        <Dropdown.Section columns={5}>
          <Dropdown.OptionItem
            aria-label="Calendar"
            selected={icon === 'calendar'}
            indicator="none"
            nativeButton
            render={
              <LightIconButton size="md" aria-label="Calendar">
                <IconCalendar />
              </LightIconButton>
            }
            onSelect={() => setIcon('calendar')}
          />
        </Dropdown.Section>
      </Dropdown.Content>
    </Dropdown.Root>
  );
};
```

## Pages and submenus

Use `Page` for navigation that replaces the contents of the same popup. Wrap the first page in `Page id="root"`, or choose another initial page with `defaultPage`. Set `page` on an action to navigate without closing. `Back` returns to the previous page and restores focus to its invoking row. Closing the dropdown resets its page history.

A page can override the root's `type`. For example, an action menu can open a searchable picker page or a form panel. Search receives focus when entering a searchable page; other pages focus their first row after `Back`.

<StoryEmbed storyId="ui-components-dropdown--pages-documentation" title="Menu to picker page navigation" height={420} />

```tsx theme={null}
import { Dropdown } from 'twenty-ui/components/navigation';
import { Button } from 'twenty-ui/primitives/input';

export const FilterMenu = () => (
  <Dropdown.Root type="menu">
    <Dropdown.Trigger render={<Button>Filters</Button>} />
    <Dropdown.Content>
      <Dropdown.Page id="root">
        <Dropdown.Section>
          <Dropdown.ActionItem page="status">Status</Dropdown.ActionItem>
        </Dropdown.Section>
      </Dropdown.Page>
      <Dropdown.Page id="status" type="picker">
        <Dropdown.Back>Filters</Dropdown.Back>
        <Dropdown.Section>
          <Dropdown.OptionItem selected={false}>Active</Dropdown.OptionItem>
          <Dropdown.OptionItem selected={false}>Archived</Dropdown.OptionItem>
        </Dropdown.Section>
      </Dropdown.Page>
    </Dropdown.Content>
  </Dropdown.Root>
);
```

To navigate from code, call `useDropdownPage` in a component rendered inside the root. It returns the current `page`, `goToPage(page)`, `goBack()` and `canGoBack`. For example, an option can return to the previous page after a selection while the popup stays open:

```tsx theme={null}
import { Dropdown, useDropdownPage } from 'twenty-ui/components/navigation';

export const StatusOptions = ({
  status,
  onStatusChange,
}: {
  status: string;
  onStatusChange: (status: string) => void;
}) => {
  const { goBack } = useDropdownPage();

  return ['Active', 'Archived'].map((option) => (
    <Dropdown.OptionItem
      key={option}
      selected={status === option}
      closeOnSelect={false}
      onSelect={() => {
        onStatusChange(option);
        goBack();
      }}
    >
      {option}
    </Dropdown.OptionItem>
  ));
};
```

Use `Submenu` with `SubmenuTrigger` and a nested `Content` for a side-by-side menu. Arrow Right enters the submenu; Arrow Left returns to its parent. Selecting a closing action closes the whole dropdown.

```text theme={null}
Dropdown.Content
└── Dropdown.Submenu
    ├── Dropdown.SubmenuTrigger
    └── Dropdown.Content
        └── Dropdown.ActionItem
```

## Independent nested pickers

Place another `Dropdown.Root` inside `Content` when a control opens its own picker, such as a sort direction selector. Selecting an inner option closes only that picker and restores focus to its trigger. Escape and outside presses dismiss one layer at a time. Use `Submenu` for commands that should close the entire menu tree when selected.

<StoryEmbed storyId="ui-components-dropdown--nested-documentation" title="Sort picker with a nested direction picker" height={420} />

## Panels and controlled state

Use `type="panel"` for form inputs. Input interaction keeps the panel open; a save action can close it. Own `open` and `onOpenChange` when another component or a shortcut needs to open the dropdown. Keep that state with the feature that coordinates the interaction.

<StoryEmbed storyId="ui-components-dropdown--panel-documentation" title="Controlled form panel" height={380} />

Escape dismisses the popup and restores focus to its trigger. Outside interaction also dismisses it, and the click that dismisses it doesn't activate what it lands on. Keys pressed inside the popup stay inside it, except Ctrl or Cmd shortcuts the dropdown doesn't handle, so page-level shortcuts keep working. `Content` accepts focus and portal options from Popover, including an explicit return-focus target for editor workflows.

## Dismissal

Escape, a press outside the popup and Tab out of it close the dropdown. Pass `onEscapeKeyDown` or `onInteractOutside` to `Root` to react before it closes, and call `event.preventDefault()` to keep it open. `event.target` is the element pressed outside, or `null` when focus leaves with Tab. A prevented outside press still reaches the element it lands on.

```tsx theme={null}
import { Dropdown } from 'twenty-ui/components/navigation';
import { Button } from 'twenty-ui/primitives/input';

export const ViewSettings = ({ isEditing }: { isEditing: boolean }) => (
  <Dropdown.Root
    type="panel"
    onInteractOutside={(event) => {
      if (isEditing) {
        event.preventDefault();
      }
    }}
  >
    <Dropdown.Trigger render={<Button>View settings</Button>} />
    <Dropdown.Content>
      <Dropdown.ActionItem>Save view</Dropdown.ActionItem>
    </Dropdown.Content>
  </Dropdown.Root>
);
```

## Anchoring without a trigger

A root can open without a `Trigger`, for example as a context menu. Control it with `open` and `onOpenChange`, and pass `anchor` to `Content`: an element, a ref, or a virtual element that returns a rectangle in viewport coordinates. Give `Content` an `aria-label`, since there is no trigger to name it after. On close, focus returns to the element that was focused when the popup opened.

<StoryEmbed storyId="ui-components-dropdown--context-menu-documentation" title="Context menu anchored to the pointer" height={300} />

```tsx theme={null}
import { useState } from 'react';
import { Dropdown } from 'twenty-ui/components/navigation';

export const RecordContextMenu = ({ recordName }: { recordName: string }) => {
  const [open, setOpen] = useState(false);
  const [point, setPoint] = useState({ x: 0, y: 0 });

  return (
    <>
      <p
        onContextMenu={(event) => {
          event.preventDefault();
          setPoint({ x: event.clientX, y: event.clientY });
          setOpen(true);
        }}
      >
        {recordName}
      </p>
      <Dropdown.Root type="menu" open={open} onOpenChange={setOpen}>
        <Dropdown.Content
          aria-label="Record actions"
          anchor={{
            getBoundingClientRect: () => new DOMRect(point.x, point.y, 0, 0),
          }}
        >
          <Dropdown.ActionItem>Duplicate</Dropdown.ActionItem>
        </Dropdown.Content>
      </Dropdown.Root>
    </>
  );
};
```

Right-clicking elsewhere while the menu is open moves it to the new point.

## Labels

Each part owns its text: supply `Search.placeholder` and native accessible names, `Close` accessible attributes, and children for `Back`, `Loading`, and `Empty`. `Back` defaults to `Back`; loading and empty states have no built-in message. Item parts accept `shortcutJoinLabel` to replace the default `then` between sequential shortcut steps. Native `aria-labelledby` takes precedence over `aria-label`.

## Props

### Dropdown.Root

<ParamField body="Root.defaultOpen" type="boolean">
  Whether the popup is initially open when uncontrolled.
</ParamField>

<ParamField body="Root.defaultPage" type="string">
  ID of the `Page` shown when the popup opens. Closing the popup resets the page history to it. Defaults to `root`.
</ParamField>

<ParamField body="Root.multiple" type="boolean">
  Allows selecting several options. Options then keep the popup open and show a checkbox by default.
</ParamField>

<ParamField body="Root.onEscapeKeyDown" type="((event: DropdownDismissEvent) => void)">
  Called when Escape is about to close the popup. Call `event.preventDefault()` to keep it open.
</ParamField>

<ParamField body="Root.onInteractOutside" type="((event: DropdownDismissEvent) => void)">
  Called when a press outside the popup, or Tab out of it, is about to close it. `event.target` is the element pressed outside, or `null` after Tab. Call `event.preventDefault()` to keep it open.
</ParamField>

<ParamField body="Root.onOpenChange" type="((open: boolean) => void)">
  Called with the next open state when the popup opens or closes.
</ParamField>

<ParamField body="Root.open" type="boolean">
  Whether the popup is open. Use with `onOpenChange` to control it.
</ParamField>

<ParamField body="Root.type" type="&#x22;menu&#x22; | &#x22;panel&#x22; | &#x22;picker&#x22;" required>
  Interaction model: `menu` for commands and links, `picker` for search and selectable options, or `panel` for forms. It sets the ARIA roles, initial focus, and keyboard navigation.
</ParamField>

### Dropdown.Trigger

<ParamField body="Trigger.className" type="string | ((state: PopoverTriggerState) => string | undefined)">
  CSS class applied to the element, or a function that
  returns a class based on the component's state.
</ParamField>

<ParamField body="Trigger.closeDelay" type="number" default="0">
  How long to wait before closing the popover that was opened on hover.
  Specified in milliseconds.

  Requires the `openOnHover` prop.
</ParamField>

<ParamField body="Trigger.delay" type="number" default="300">
  How long to wait before the popover may be opened on hover. Specified in milliseconds.

  Requires the `openOnHover` prop.
</ParamField>

<ParamField body="Trigger.id" type="string">
  ID of the trigger. In addition to being forwarded to the rendered element,
  it is also used to specify the active trigger for the popover in controlled mode (with the PopoverRoot `triggerId` prop).
</ParamField>

<ParamField body="Trigger.nativeButton" type="boolean" default="true">
  Whether the component renders a native `<button>` element when replacing it
  via the `render` prop.
  Set to `false` if the rendered element is not a button (e.g. `<div>`).
</ParamField>

<ParamField body="Trigger.openOnHover" type="boolean" default="false">
  Whether the popover should also open when the trigger is hovered.
</ParamField>

<ParamField body="Trigger.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, PopoverTriggerState>">
  Allows you to replace the component's HTML element
  with a different tag, or compose it with another component.

  Accepts a `ReactElement` or a function that returns the element to render.
</ParamField>

<ParamField body="Trigger.style" type="CSSProperties | ((state: PopoverTriggerState) => CSSProperties | undefined)">
  Style applied to the element, or a function that
  returns a style object based on the component's state.
</ParamField>

### Dropdown.Content

<ParamField body="Content.align" type="&#x22;center&#x22; | &#x22;end&#x22; | &#x22;start&#x22;" default="start">
  Alignment of the popup along the anchor.
</ParamField>

<ParamField body="Content.alignOffset" type="number | OffsetFunction">
  Offset in pixels along the alignment axis.
</ParamField>

<ParamField body="Content.anchor" type="Element | VirtualElement | RefObject<Element | null> | (() => Element | VirtualElement | null) | null">
  Element or position the popup is anchored to. Defaults to the trigger.
</ParamField>

<ParamField body="Content.className" type="string | ((state: PopoverPopupState) => string | undefined)">
  CSS class applied to the element, or a function that
  returns a class based on the component's state.
</ParamField>

<ParamField body="Content.collisionPadding" type="Padding">
  Space in pixels kept between the popup and the edges of its collision
  boundary, for all sides or per side. Defaults to 5.
</ParamField>

<ParamField body="Content.container" type="HTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot | null> | null">
  Element the popup is portaled into. Defaults to the theme's portal
  container.
</ParamField>

<ParamField body="Content.finalFocus" type="boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | void | HTMLElement | null)">
  Determines the element to focus when the popover is closed.

  * `false`: Do not move focus.
  * `true`: Move focus based on the default behavior (trigger or previously focused element).
  * `RefObject`: Move focus to the ref element.
  * `function`: Called with the interaction type (`mouse`, `touch`, `pen`, or `keyboard`).
    Return an element to focus, `true` to use the default behavior, `null` to fall back to the default behavior, or `false`/`undefined` to do nothing.
</ParamField>

<ParamField body="Content.initialFocus" type="boolean | RefObject<HTMLElement | null> | ((openType: InteractionType) => boolean | void | HTMLElement | null)">
  Determines the element to focus when the popover is opened.
  By default, focus moves to the first tabbable element inside the popup, except when the popover
  is opened by touch — then the popup itself is focused to avoid opening the virtual keyboard.

  * `false`: Do not move focus.
  * `true`: Move focus based on the default behavior (first tabbable element or popup).
  * `RefObject`: Move focus to the ref element.
  * `function`: Called with the interaction type (`mouse`, `touch`, `pen`, or `keyboard`).
    Return an element to focus, `true` to use the default behavior, `null` to fall back to the default behavior, or `false`/`undefined` to do nothing.
</ParamField>

<ParamField body="Content.keepMounted" type="boolean">
  Keeps the popup mounted in the DOM while the popover is closed.
</ParamField>

<ParamField body="Content.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, PopoverPopupState>">
  Allows you to replace the component's HTML element
  with a different tag, or compose it with another component.

  Accepts a `ReactElement` or a function that returns the element to render.
</ParamField>

<ParamField body="Content.side" type="&#x22;bottom&#x22; | &#x22;inline-end&#x22; | &#x22;inline-start&#x22; | &#x22;left&#x22; | &#x22;right&#x22; | &#x22;top&#x22;">
  Side of the anchor the popup is placed on.
</ParamField>

<ParamField body="Content.sideOffset" type="number | OffsetFunction" default="0">
  Distance in pixels between the anchor and the popup.
</ParamField>

<ParamField body="Content.style" type="CSSProperties | ((state: PopoverPopupState) => CSSProperties | undefined)">
  Style applied to the element, or a function that
  returns a style object based on the component's state.
</ParamField>

<ParamField body="Content.width" type="Width<string | number>" default="200">
  CSS width of the popup. Numbers are in pixels.
</ParamField>

### Dropdown.ActionItem

<ParamField body="ActionItem.className" type="string">
  CSS class applied to the row.
</ParamField>

<ParamField body="ActionItem.closeOnClick" type="boolean" default="true">
  Closes the dropdown after activation, along with parent menus when inside a submenu. Ignored when `page` is set.
</ParamField>

<ParamField body="ActionItem.color" type="&#x22;danger&#x22; | &#x22;neutral&#x22;">
  Color of the text and icons. `danger` marks a destructive action.
</ParamField>

<ParamField body="ActionItem.description" type="ReactNode">
  Supporting text, placed according to `descriptionPlacement`.
</ParamField>

<ParamField body="ActionItem.descriptionPlacement" type="&#x22;end&#x22; | &#x22;inline&#x22;">
  Where the description renders: inline after the content or at the end of
  the row.
</ParamField>

<ParamField body="ActionItem.endIcon" type="ReactNode">
  Icon rendered after the content.
</ParamField>

<ParamField body="ActionItem.focusableWhenDisabled" type="boolean" default="false">
  Whether the button should be focusable when disabled.
</ParamField>

<ParamField body="ActionItem.hasSubmenu" type="boolean">
  Shows a chevron indicating that the item opens a submenu.
</ParamField>

<ParamField body="ActionItem.nativeButton" type="boolean" default="true when render is omitted; false otherwise">
  Whether the component renders a native `<button>` element when replacing it
  via the `render` prop.
  Set to `false` if the rendered element is not a button (for example, `<div>`).
</ParamField>

<ParamField body="ActionItem.page" type="string">
  ID of the `Page` to show on activation. The popup stays open, and the row shows a chevron by default.
</ParamField>

<ParamField body="ActionItem.render" type="ReactElement<unknown, string | JSXElementConstructor<any>>">
  Element rendered as the row instead of a native button. Custom components must forward the supplied props and ref.
</ParamField>

<ParamField body="ActionItem.shortcut" type="ShortcutDefinition">
  Keyboard shortcut keys displayed at the end of the row. Registering the
  shortcut is up to the application.
</ParamField>

<ParamField body="ActionItem.shortcutJoinLabel" type="string">
  Text between sequential shortcut steps. Defaults to `then`.
</ParamField>

<ParamField body="ActionItem.startIcon" type="ReactNode">
  Icon rendered before the content.
</ParamField>

<ParamField body="ActionItem.style" type="CSSProperties">
  Inline styles applied to the row.
</ParamField>

### Dropdown.OptionItem

<ParamField body="OptionItem.className" type="string">
  CSS class applied to the row.
</ParamField>

<ParamField body="OptionItem.closeOnSelect" type="boolean">
  Closes the dropdown after selection. Defaults to `true`, or `false` when `multiple` is set.
</ParamField>

<ParamField body="OptionItem.color" type="&#x22;danger&#x22; | &#x22;neutral&#x22;">
  Color of the text and icons. `danger` marks a destructive action.
</ParamField>

<ParamField body="OptionItem.description" type="ReactNode">
  Supporting text, placed according to `descriptionPlacement`.
</ParamField>

<ParamField body="OptionItem.descriptionPlacement" type="&#x22;end&#x22; | &#x22;inline&#x22;">
  Where the description renders: inline after the content or at the end of
  the row.
</ParamField>

<ParamField body="OptionItem.endIcon" type="ReactNode">
  Icon rendered after the content.
</ParamField>

<ParamField body="OptionItem.focusableWhenDisabled" type="boolean" default="false">
  Whether the button should be focusable when disabled.
</ParamField>

<ParamField body="OptionItem.hasSubmenu" type="boolean">
  Shows a chevron indicating that the item opens a submenu.
</ParamField>

<ParamField body="OptionItem.indicator" type="&#x22;check&#x22; | &#x22;checkbox&#x22; | &#x22;none&#x22;">
  Selection indicator: a check icon after the content, a checkbox before it, or none. Defaults to `checkbox` when `multiple` is set, otherwise `check`, and to `none` when `selected` is omitted.
</ParamField>

<ParamField body="OptionItem.nativeButton" type="boolean" default="true when render is omitted; false otherwise">
  Whether the component renders a native `<button>` element when replacing it
  via the `render` prop.
  Set to `false` if the rendered element is not a button (for example, `<div>`).
</ParamField>

<ParamField body="OptionItem.onSelect" type="(() => void)">
  Called when the option is activated. The application owns the selected value.
</ParamField>

<ParamField body="OptionItem.render" type="ReactElement<unknown, string | JSXElementConstructor<any>>">
  Element rendered as the row instead of a native button. Custom components must forward the supplied props and ref.
</ParamField>

<ParamField body="OptionItem.selected" type="boolean">
  Whether the option is selected. Exposed as `aria-checked` in menus and `aria-pressed` in other dropdown types, or as `aria-current` when `render` is not a button, such as a link. Omit it for options that navigate or apply without a selection state.
</ParamField>

<ParamField body="OptionItem.shortcut" type="ShortcutDefinition">
  Keyboard shortcut keys displayed at the end of the row. Registering the
  shortcut is up to the application.
</ParamField>

<ParamField body="OptionItem.shortcutJoinLabel" type="string">
  Text between sequential shortcut steps. Defaults to `then`.
</ParamField>

<ParamField body="OptionItem.startIcon" type="ReactNode">
  Icon rendered before the content.
</ParamField>

<ParamField body="OptionItem.style" type="CSSProperties">
  Inline styles applied to the row.
</ParamField>

### Dropdown.Search

<ParamField body="Search.className" type="string | ((state: InputState) => string | undefined)">
  CSS class applied to the element, or a function that
  returns a class based on the component's state.
</ParamField>

<ParamField body="Search.defaultValue" type="string | number | readonly string[]">
  The default value of the input. Use when uncontrolled.
</ParamField>

<ParamField body="Search.onValueChange" type="((value: string) => void)">
  Called with the search text on every change. The application filters the results.
</ParamField>

<ParamField body="Search.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, InputState>">
  Allows you to replace the component's HTML element
  with a different tag, or compose it with another component.

  Accepts a `ReactElement` or a function that returns the element to render.
</ParamField>

<ParamField body="Search.style" type="CSSProperties | ((state: InputState) => CSSProperties | undefined)">
  Style applied to the element, or a function that
  returns a style object based on the component's state.
</ParamField>

<ParamField body="Search.value" type="string | number | readonly string[]">
  The value of the input. Use when controlled.
</ParamField>

### Dropdown.Header

<ParamField body="Header.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, {}>">
  Allows you to replace the component's HTML element
  with a different tag, or compose it with another component.

  Accepts a `ReactElement` or a function that returns the element to render.
</ParamField>

### Dropdown.Title

<ParamField body="Title.className" type="string | ((state: PopoverTitleState) => string | undefined)">
  CSS class applied to the element, or a function that
  returns a class based on the component's state.
</ParamField>

<ParamField body="Title.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, PopoverTitleState>">
  Allows you to replace the component's HTML element
  with a different tag, or compose it with another component.

  Accepts a `ReactElement` or a function that returns the element to render.
</ParamField>

<ParamField body="Title.style" type="CSSProperties | ((state: PopoverTitleState) => CSSProperties | undefined)">
  Style applied to the element, or a function that
  returns a style object based on the component's state.
</ParamField>

### Dropdown.Close

<ParamField body="Close.aria-label" type="string" required>
  Accessible name of the close control. Required because the default control only shows an icon.
</ParamField>

<ParamField body="Close.className" type="string | ((state: PopoverCloseState) => string | undefined)">
  CSS class applied to the element, or a function that
  returns a class based on the component's state.
</ParamField>

<ParamField body="Close.nativeButton" type="boolean" default="true">
  Whether the component renders a native `<button>` element when replacing it
  via the `render` prop.
  Set to `false` if the rendered element is not a button (for example, `<div>`).
</ParamField>

<ParamField body="Close.render" type="ReactElement<unknown, string | JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, PopoverCloseState>">
  Allows you to replace the component's HTML element
  with a different tag, or compose it with another component.

  Accepts a `ReactElement` or a function that returns the element to render.
</ParamField>

<ParamField body="Close.style" type="CSSProperties | ((state: PopoverCloseState) => CSSProperties | undefined)">
  Style applied to the element, or a function that
  returns a style object based on the component's state.
</ParamField>

### Dropdown.Page

<ParamField body="Page.id" type="string" required>
  Identifier matched by `defaultPage`, the `page` prop of actions, and `goToPage`. The page renders only while it is current.
</ParamField>

<ParamField body="Page.type" type="&#x22;menu&#x22; | &#x22;panel&#x22; | &#x22;picker&#x22;">
  Interaction model while the page is shown. Defaults to the root `type`.
</ParamField>

### Dropdown.Back

<ParamField body="Back.className" type="string">
  CSS class applied to the row.
</ParamField>

<ParamField body="Back.color" type="&#x22;danger&#x22; | &#x22;neutral&#x22;">
  Color of the text and icons. `danger` marks a destructive action.
</ParamField>

<ParamField body="Back.description" type="ReactNode">
  Supporting text, placed according to `descriptionPlacement`.
</ParamField>

<ParamField body="Back.descriptionPlacement" type="&#x22;end&#x22; | &#x22;inline&#x22;">
  Where the description renders: inline after the content or at the end of
  the row.
</ParamField>

<ParamField body="Back.endIcon" type="ReactNode">
  Icon rendered after the content.
</ParamField>

<ParamField body="Back.focusableWhenDisabled" type="boolean" default="false">
  Whether the button should be focusable when disabled.
</ParamField>

<ParamField body="Back.hasSubmenu" type="boolean">
  Shows a chevron indicating that the item opens a submenu.
</ParamField>

<ParamField body="Back.nativeButton" type="boolean" default="true when render is omitted; false otherwise">
  Whether the component renders a native `<button>` element when replacing it
  via the `render` prop.
  Set to `false` if the rendered element is not a button (for example, `<div>`).
</ParamField>

<ParamField body="Back.render" type="ReactElement<unknown, string | JSXElementConstructor<any>>">
  Element rendered as the row instead of a native button. Custom components must forward the supplied props and ref.
</ParamField>

<ParamField body="Back.shortcut" type="ShortcutDefinition">
  Keyboard shortcut keys displayed at the end of the row. Registering the
  shortcut is up to the application.
</ParamField>

<ParamField body="Back.shortcutJoinLabel" type="string">
  Text between sequential shortcut steps. Defaults to `then`.
</ParamField>

<ParamField body="Back.startIcon" type="ReactNode">
  Icon rendered before the content.
</ParamField>

<ParamField body="Back.style" type="CSSProperties">
  Inline styles applied to the row.
</ParamField>

### Dropdown.Submenu

<ParamField body="Submenu.defaultOpen" type="boolean">
  Whether the popup is initially open when uncontrolled.
</ParamField>

<ParamField body="Submenu.defaultPage" type="string">
  ID of the `Page` shown when the popup opens. Closing the popup resets the page history to it. Defaults to `root`.
</ParamField>

<ParamField body="Submenu.multiple" type="boolean">
  Allows selecting several options. Options then keep the popup open and show a checkbox by default.
</ParamField>

<ParamField body="Submenu.onOpenChange" type="((open: boolean) => void)">
  Called with the next open state when the popup opens or closes.
</ParamField>

<ParamField body="Submenu.open" type="boolean">
  Whether the popup is open. Use with `onOpenChange` to control it.
</ParamField>

<ParamField body="Submenu.type" type="&#x22;menu&#x22; | &#x22;panel&#x22; | &#x22;picker&#x22;" default="menu">
  Interaction model: `menu` for commands and links, `picker` for search and selectable options, or `panel` for forms. It sets the ARIA roles, initial focus, and keyboard navigation.
</ParamField>

### Dropdown.SubmenuTrigger

<ParamField body="SubmenuTrigger.className" type="string">
  CSS class applied to the row.
</ParamField>

<ParamField body="SubmenuTrigger.closeDelay" type="number">
  Delay in milliseconds before a submenu opened on hover closes. Requires `openOnHover`. Defaults to `0`.
</ParamField>

<ParamField body="SubmenuTrigger.color" type="&#x22;danger&#x22; | &#x22;neutral&#x22;">
  Color of the text and icons. `danger` marks a destructive action.
</ParamField>

<ParamField body="SubmenuTrigger.delay" type="number">
  Delay in milliseconds before the submenu opens on hover. Requires `openOnHover`. Defaults to `300`.
</ParamField>

<ParamField body="SubmenuTrigger.description" type="ReactNode">
  Supporting text, placed according to `descriptionPlacement`.
</ParamField>

<ParamField body="SubmenuTrigger.descriptionPlacement" type="&#x22;end&#x22; | &#x22;inline&#x22;">
  Where the description renders: inline after the content or at the end of
  the row.
</ParamField>

<ParamField body="SubmenuTrigger.endIcon" type="ReactNode">
  Icon rendered after the content.
</ParamField>

<ParamField body="SubmenuTrigger.focusableWhenDisabled" type="boolean" default="false">
  Whether the button should be focusable when disabled.
</ParamField>

<ParamField body="SubmenuTrigger.hasSubmenu" type="boolean" default="true">
  Shows a chevron indicating that the item opens a submenu.
</ParamField>

<ParamField body="SubmenuTrigger.nativeButton" type="boolean" default="true when render is omitted; false otherwise">
  Whether the component renders a native `<button>` element when replacing it
  via the `render` prop.
  Set to `false` if the rendered element is not a button (for example, `<div>`).
</ParamField>

<ParamField body="SubmenuTrigger.openOnHover" type="boolean" default="true">
  Also opens the submenu when the row is hovered.
</ParamField>

<ParamField body="SubmenuTrigger.render" type="ReactElement<unknown, string | JSXElementConstructor<any>>">
  Element rendered as the row instead of a native button. Custom components must forward the supplied props and ref.
</ParamField>

<ParamField body="SubmenuTrigger.shortcut" type="ShortcutDefinition">
  Keyboard shortcut keys displayed at the end of the row. Registering the
  shortcut is up to the application.
</ParamField>

<ParamField body="SubmenuTrigger.shortcutJoinLabel" type="string">
  Text between sequential shortcut steps. Defaults to `then`.
</ParamField>

<ParamField body="SubmenuTrigger.startIcon" type="ReactNode">
  Icon rendered before the content.
</ParamField>

<ParamField body="SubmenuTrigger.style" type="CSSProperties">
  Inline styles applied to the row.
</ParamField>

### Dropdown.Section

<ParamField body="Section.columns" type="number">
  Number of grid columns. Sets the grid layout and enables horizontal arrow navigation and vertical movement by row.
</ParamField>

<ParamField body="Section.label" type="ReactNode">
  Heading displayed above the rows. It also names the group for assistive technologies.
</ParamField>

<ParamField body="Section.scrollable" type="boolean">
  Caps the section height and scrolls its rows. Nest labelled sections inside it to scroll them as one list.
</ParamField>

### Dropdown.Separator

<ParamField body="Separator.className" type="string">
  Class applied to the separator. Native div attributes and refs are also accepted.
</ParamField>

### Dropdown.Loading

<ParamField body="Loading.children" type="ReactNode">
  Loading message announced as a polite, busy status.
</ParamField>

<ParamField body="Loading.className" type="string">
  Class applied to the status. Native div attributes and refs are also accepted.
</ParamField>

### Dropdown.Empty

<ParamField body="Empty.children" type="ReactNode">
  Empty-state message announced as a polite status.
</ParamField>

<ParamField body="Empty.className" type="string">
  Class applied to the status. Native div attributes and refs are also accepted.
</ParamField>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.