> ## 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.

# Listă derulantă

> Meniuri de acțiuni, selectoare cu căutare și panouri de formular cu prezentare și interacțiune comune.

## Prezentare generală

`Dropdown` combină o fereastră pop-up poziționată, rânduri vizuale, navigare prin tastatură, focalizare și închidere. Aplicația dvs. gestionează datele, filtrarea, preluarea și paginarea. `SelectionGroup` gestionează valori de selecție independente în interiorul ferestrei popup. Importați-l din `twenty-ui/components`.

**Light**

[Acțiuni Dropdown (light)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--display\&viewMode=story\&globals=colorScheme:light)

**Dark**

[Acțiuni Dropdown (dark)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--display\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-components-dropdown--display)

Dropdown.Content acceptă decalaje numerice sau funcții pentru `sideOffset` și `alignOffset`. Funcțiile de decalare primesc dimensiunile ancorei și ale ferestrei pop-up, latura și alinierea. Folosește-le pentru a păstra suprapunerea unui selector de câmp ancorat atunci când celula este scalată.

## Utilizare

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

export const RecordActions = () => (
  <Dropdown.Root type="menu">
    <Dropdown.Trigger render={<Button>Record actions</Button>} />
    <Dropdown.Content aria-label="Record actions" width={240}>
      <Dropdown.Section>
        <Dropdown.ActionItem startIcon={<IconCopy />}>
          Duplicate
        </Dropdown.ActionItem>
        <Dropdown.Submenu>
          <Dropdown.SubmenuTrigger startIcon={<IconDownload />}>
            Export
          </Dropdown.SubmenuTrigger>
          <Dropdown.Content aria-label="Export formats">
            <Dropdown.Section>
              <Dropdown.ActionItem>CSV</Dropdown.ActionItem>
              <Dropdown.ActionItem>Excel</Dropdown.ActionItem>
            </Dropdown.Section>
          </Dropdown.Content>
        </Dropdown.Submenu>
      </Dropdown.Section>
      <Dropdown.Separator />
      <Dropdown.Section>
        <Dropdown.ActionItem startIcon={<IconArchive />}>
          Archive
        </Dropdown.ActionItem>
        <Dropdown.ActionItem
          render={
            <a href="#dropdown-documentation" aria-label="Documentation" />
          }
        >
          Documentation
        </Dropdown.ActionItem>
      </Dropdown.Section>
    </Dropdown.Content>
  </Dropdown.Root>
);
```

## Alegeți un tip de interacțiune

Setați `type` în `Dropdown.Root` pentru a corespunde conținutului ferestrei pop-up.

| Tip | Conținut | Interacțiune |
| - | - | - |
| `menu` | Comenzi și linkuri de navigare | Semantică de meniu cu navigare prin săgeți și căutare pe măsură ce tastați. |
| `picker` | Căutare, valori selectabile și comenzi opționale | O casetă de dialog care conține căutare, casete cu listă selectabile și comenzi opționale. Tastele săgeată navighează printre rândurile de rezultate. |
| `panel` | Câmpuri de introducere, formulare și acțiuni de asistență | Un dialog cu comportament nativ al câmpurilor de introducere și navigare cu Tab. |

Selectoarele permit acțiuni de creare și grupuri de selecție independente în aceeași pagină, în orice ordine. Fiecare grup de selectare este o casetă cu listă, iar opțiunile sale expun `aria-selected`. Grupurile de meniu utilizează elemente de meniu radio sau cu casetă de bifare bifate. Grupurile de panouri utilizează butoane cu `aria-pressed`. Comenzile păstrează semantica acțiunilor modului lor. Atribuiți fiecărui grup și lui `Search` un nume accesibil. Acest selector personalizat nu este un Combobox nativ.

`Content` își preia numele accesibil de la `Trigger` sau de la `SubmenuTrigger` într-un submeniu. Transmiteți `aria-label` în `Content` atunci când declanșatorul afișează o valoare, cum ar fi opțiunea selectată, sau când rădăcina nu are declanșator. Un `aria-label` sau `aria-labelledby` explicit și un `Title` dintr-un `Header` au prioritate față de numele declanșatorului.

[Select](https://docs.twenty.com/ro/ui/primitives/input/select.md) și [Popover](https://docs.twenty.com/ro/ui/primitives/surfaces/popover.md) rămân disponibile pentru compunere directă.

## Anatomie

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

`Content` include portalul și poziționatorul. Utilizați `width`, `side`, `align`, `sideOffset` și `alignOffset` pentru a controla poziționarea, iar `collisionPadding` pentru a menține fereastra pop-up mai departe de marginile ferestrei de vizualizare înainte de a se deplasa sau inversa (5 pixeli în mod implicit). `Section` grupează rânduri cu spațiere comună, iar `Separator` separă secțiunile. O secțiune `scrollable` își limitează înălțimea și se derulează; imbricați în ea secțiuni etichetate pentru a le derula ca pe o singură listă. Rândurile utilizează [ListItem](https://docs.twenty.com/ro/ui/primitives/navigation/list-item.md) pentru aspectul lor.

```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>
);
```

Transmiteți elemente de declanșare personalizate prin `render`, astfel încât declanșatorul să rămână un singur element interactiv. Componentele personalizate trebuie să redirecționeze props și ref furnizate. `ActionItem` acceptă, de asemenea, `render` pentru linkuri.

## Acțiuni pentru elemente

`ActionItem` și `OptionItem` acceptă `actions` pentru controalele de final, cum ar fi butonul de editare al unei file. Folosește-le numai în paginile `picker` și `panel`: un `menu` poate conține doar elemente de meniu, deci nu poate include alte controale. Setează `actionsVisibility="always"` pentru a le menține vizibile; valoarea implicită este `"hover"`. Controalele secundare sunt afișate lângă controlul rândului principal și se activează independent: nu închid fereastra pop-up, așadar închide-o din handlerul acțiunii atunci când este necesar. Proprietatea `render` și referința se aplică în continuare controlului principal, astfel încât acesta poate servi și ca mâner de glisare.

Utilizează `tabIndex={-1}` pentru o acțiune secundară disponibilă doar cu indicatorul, care are o alternativă separată pentru tastatură. Navigarea cu tastatura continuă să focalizeze și să activeze controlul principal.

## Anteturi

`Header` aranjează un rând în partea de sus a ferestrei pop-up. Introduceți un `Title` în acesta pentru a denumi fereastra pop-up după titlu, în loc de declanșator. `Close` închide fereastra pop-up în același mod ca o apăsare în exterior. În mod implicit, acesta redă un buton cu pictogramă X, așadar oferiți-i un `aria-label` sau transmiteți `render` și elemente copil pentru un alt control. Alte controale, cum ar fi un buton care revine la un pas anterior, pot fi în același rând. Utilizați `Dropdown.Back` când navigați în istoricul paginilor rădăcinii.

## Căutare și selecție

`Search` furnizează câmpul de introducere și navigarea către rândurile de rezultate. Transmiteți `value` și `onValueChange`; calculați sau preluați rezultatele potrivite în aplicația dvs. Redați `Loading` cât timp o solicitare este în așteptare și `Empty` când nu există rezultate potrivite. Ambele acceptă text de stare furnizat de apelant.

**Light**

[Selector cu căutare și creare în linie (light)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--picker-documentation\&viewMode=story\&globals=colorScheme:light)

**Dark**

[Selector cu căutare și creare în linie (dark)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--picker-documentation\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-components-dropdown--picker-documentation)

Încadrați opțiunile selectabile în `SelectionGroup` și atribuiți fiecărei opțiuni un `value` stabil, unic în cadrul grupului. Un grup necontrolat necesită, de asemenea, un `id` unic în cadrul arborelui său derulant, inclusiv în submeniuri. Componentele `Root` imbricate independent își păstrează propriul depozit de selecție. Selecția unică utilizează un șir sau `null` pentru lipsa unei selecții. Selecția multiplă utilizează un tablou, inclusiv `[]` pentru lipsa unei selecții.

```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<string | null>(null);
  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.SelectionGroup
          id="person"
          aria-label="Person"
          value={selectedPerson}
          onValueChange={setSelectedPerson}
        >
          {people.map((person) => (
            <Dropdown.OptionItem key={person} value={person}>
              {person}
            </Dropdown.OptionItem>
          ))}
        </Dropdown.SelectionGroup>
      </Dropdown.Content>
    </Dropdown.Root>
  );
};
```

Transmiteți `value` și `onValueChange` pentru selecția controlată. Omiterea lui `value` sau transmiterea lui `undefined` lasă selecția necontrolată; `defaultValue` îi stabilește valoarea inițială. Un grup necontrolat are implicit valoarea `null` sau `[]` cu `multiple`. `id`-ul său stabil păstrează selecția la închidere și redeschidere, precum și la navigarea între pagini. Eliminarea sau filtrarea unei opțiuni nu îi șterge identificatorul selectat și nu emite o modificare; opțiunea este selectată din nou când revine. Utilizați o valoare controlată atunci când aplicația trebuie să elimine alegerile indisponibile.

Fiecare grup se modifică independent. O opțiune se confirmă în cel mai apropiat grup al său, în timp ce pagina activă furnizează o colecție ordonată pentru navigarea cu săgețile între grupuri și rânduri de acțiuni. Activarea repetată a unei opțiuni unice selectate îi păstrează valoarea fără un alt callback de modificare. Activarea multiplă comută opțiunea în tablou.

**Light**

[Selecții independente ale proprietarului și observatorului (light)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--selection-groups-documentation\&viewMode=story\&globals=colorScheme:light)

**Dark**

[Selecții independente ale proprietarului și observatorului (dark)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--selection-groups-documentation\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-components-dropdown--selection-groups-documentation)

Selecția unică se închide implicit; selecția multiplă rămâne deschisă. `SelectionGroup.closeOnSelect` modifică valoarea implicită a grupului, iar `OptionItem.closeOnSelect` o suprascrie pentru o opțiune. Rândurile de acțiuni utilizează `closeOnClick` independent. O modificare anulată păstrează selecția anterioară și nu închide automat fereastra popup.

`onValueChange` primește următoarea valoare și detaliile evenimentului cu `event`, `reason`, `trigger`, `cancel()` și `isCanceled`. Motivul este `item-press`, iar `event` este evenimentul original de activare. `OptionItem.onSelect` primește aceleași detalii înainte ca proprietarul să confirme. Apelați `cancel()` în oricare dintre callback-uri pentru a preveni selecția și închiderea automată.

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

<Dropdown.SelectionGroup
  id="watchers"
  aria-label="Watchers"
  multiple
  defaultValue={[]}
  onValueChange={(value, eventDetails) => {
    if (value.length > 3) {
      eventDetails.cancel();
    }
  }}
>
  <Dropdown.OptionItem value="ada">Ada Lovelace</Dropdown.OptionItem>
  <Dropdown.OptionItem value="grace">Grace Hopper</Dropdown.OptionItem>
</Dropdown.SelectionGroup>;
```

Căutarea primește focalizarea când selectorul se deschide. Fără căutare, prima opțiune selectată și activată primește focalizarea sau primul rând activat când nu există nicio opțiune selectată. Cât timp `Search` are focalizarea și o interogare nevidă, primul `OptionItem` eligibil din grupurile de selecție este evidențiat, iar Enter îl activează. Rândurile de acțiuni nu sunt niciodată selectate în acest mod. ArrowDown mută focalizarea pe primul rând activat, inclusiv pe acțiuni. Ieșirea din căutare șterge previzualizarea și `aria-activedescendant`, chiar și atunci când fereastra pop-up rămâne deschisă. Revenirea la căutare restaurează previzualizarea pentru interogarea curentă.

Enter nu face nimic pentru o interogare goală sau care conține doar spații albe ori când nu mai rămâne nicio opțiune eligibilă. Compunerea textului cu o metodă de introducere nu activează o opțiune și nu mută focalizarea cu tastele săgeată. Când rândurile sunt fixate deasupra rezultatelor, cum ar fi valoarea curentă sau un rând „niciuna”, redați-le numai când corespund textului de căutare. Fereastra pop-up rămâne deschisă când nicio opțiune nu se potrivește. Filtrarea rămâne în responsabilitatea apelantului.

**Light**

[Selecție multiplă (light)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--multiple-selection-documentation\&viewMode=story\&globals=colorScheme:light)

**Dark**

[Selecție multiplă (dark)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--multiple-selection-documentation\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-components-dropdown--multiple-selection-documentation)

`OptionItem` independent acceptă în continuare `selected` și `onSelect` pentru apelanții care gestionează singuri selecția. Opțiunile grupate derivă selecția din valoarea grupului; nu duplicați acea stare în opțiune. Grupurile de selecție personalizate nu oferă trimitere nativă a formularelor, resetare, validare obligatorie, comportament doar în citire sau integrare Field. Utilizați [Select](https://docs.twenty.com/ro/ui/primitives/input/select.md) când sunt necesare aceste contracte native ale formularelor.

## Grile de pictograme

**Light**

[Grilă de pictograme cu stilizarea celulei selectate (light)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--icon-grid-documentation\&viewMode=story\&globals=colorScheme:light)

**Dark**

[Grilă de pictograme cu stilizarea celulei selectate (dark)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--icon-grid-documentation\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-components-dropdown--icon-grid-documentation)

Setați `columns` în `Section` pentru a aranja elementele în coloane de grilă cu lățime egală. Același număr controlează navigarea prin tastatură: Left și Right se deplasează într-un rând, iar Up și Down se deplasează între rânduri. Navigarea omite opțiunile dezactivate și urmează direcția de citire. Când nu mai există nicio opțiune activată în coloană, Up și Down se deplasează la cea mai apropiată opțiune activată din rândul următor. Up din primul rând revine la câmpul de căutare când nu există nicio secțiune anterioară. Un ultim rând scurt utilizează ultimul său element când coloana solicitată lipsește. Într-un submeniu, săgeata înapoi închide submeniul când nu mai rămâne nicio opțiune activată în stânga sa.

Redați fiecare pictogramă ca `OptionItem` cu o etichetă accesibilă și un buton cu pictogramă prin `render`. Utilizați `indicator="none"` pentru a afișa selecția prin fundalul butonului. Funcția callback `render` primește starea `{ selected, multiple, disabled }`; utilizați-o pentru a stiliza o celulă selectată și transmiteți prop-urile și ref furnizate.

```tsx theme={null}
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 = () => (
  <Dropdown.Root type="picker">
    <Dropdown.Trigger render={<Button>Choose icon</Button>} />
    <Dropdown.Content>
      <Dropdown.SelectionGroup
        id="icon"
        aria-label="Icon"
        defaultValue="calendar"
      >
        <Dropdown.Section columns={5}>
          <Dropdown.OptionItem
            value="calendar"
            aria-label="Calendar"
            indicator="none"
            nativeButton
            render={(props, state) => (
              <LightIconButton
                // oxlint-disable-next-line react/jsx-props-no-spreading
                {...props}
                size="md"
                color={state.selected ? 'accent' : 'neutral'}
                aria-label="Calendar"
              >
                <IconCalendar />
              </LightIconButton>
            )}
          />
        </Dropdown.Section>
      </Dropdown.SelectionGroup>
    </Dropdown.Content>
  </Dropdown.Root>
);
```

## Focalizare tastatură

În paginile `menu` și `picker`, rândurile formează un singur punct de oprire Tab. Tastele săgeată mută focalizarea între secțiuni, acțiuni și opțiuni, iar Home și End o mută la primul și ultimul rând activat, cu excepția cazului în care câmpul de căutare are focalizarea. Mutarea focalizării nu selectează niciodată o opțiune; Enter sau Space activează rândul focalizat. Revenirea cu Tab la rânduri readuce focalizarea la ultimul rând focalizat sau la primul rând activat după ce acel rând nu mai există. Căutarea, `Back` de lângă o căutare, butoanele antetului și alte controale din fereastra pop-up își păstrează propriile puncte de oprire Tab.

Tab și Shift+Tab închid un `menu`, împreună cu meniurile sale părinte atunci când focalizarea este într-un submeniu. Într-un `picker`, Tab parcurge controalele ferestrei pop-up și închide fereastra pop-up atunci când focalizarea o părăsește. Un `panel` păstrează ordinea Tab nativă a controalelor sale.

## Pagini și submeniuri

Utilizați `Page` pentru navigare care înlocuiește conținutul aceleiași ferestre pop-up. Încadrați prima pagină în `Page id="root"` sau alegeți o altă pagină inițială cu `defaultPage`. Setați `page` pentru o acțiune ca să navigați fără a închide. `Back` revine la pagina anterioară și restaurează focalizarea pe rândul care a invocat-o.

Paginile sunt montate la prima vizitare și rămân montate pe durata sesiunii deschise. Revenirea la o pagină îi păstrează căutarea locală, schițele de formular și secțiunile derulabile. Paginile inactive sunt ascunse și inerte: nu participă la navigarea prin tastatură, la focalizare sau la arborele de accesibilitate, iar ferestrele lor popup Dropdown imbricate sunt inactive.

Redeschiderea începe o sesiune nouă la `defaultPage`, cu conținut nou, inclusiv când este setat `Content.keepMounted` sau când fereastra popup se redeschide în timpul tranziției sale de ieșire. Istoricul paginii, căutarea locală și schițele se resetează. Pagina care se închide rămâne montată în timpul tranziției sale de ieșire.

Valorile necontrolate ale `SelectionGroup` rămân stocate în `Root` sub `id`-ul stabil al fiecărui grup și se păstrează la redeschidere. Valorile controlate de apelant rămân în proprietatea apelantului. De exemplu, o valoare de căutare stocată deasupra lui `Content` rămâne neschimbată până când apelantul o actualizează. Pune starea temporară de căutare sau de schiță într-o componentă din `Content` sau `Page` atunci când ar trebui să se reseteze odată cu sesiunea; păstrează starea durabilă a aplicației deasupra lui `Content`.

O pagină poate suprascrie `type` al rădăcinii. De exemplu, un meniu de acțiuni poate deschide o pagină de selector cu căutare sau un panou de formular. Căutarea primește focalizarea la intrarea într-o pagină cu căutare; celelalte pagini își focalizează primul rând după `Back`.

**Light**

[Navigare de la meniu la pagina selectorului (light)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--pages-documentation\&viewMode=story\&globals=colorScheme:light)

**Dark**

[Navigare de la meniu la pagina selectorului (dark)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--pages-documentation\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-components-dropdown--pages-documentation)

```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.SelectionGroup id="status" aria-label="Status">
            <Dropdown.OptionItem value="active">Active</Dropdown.OptionItem>
            <Dropdown.OptionItem value="archived">Archived</Dropdown.OptionItem>
          </Dropdown.SelectionGroup>
        </Dropdown.Section>
      </Dropdown.Page>
    </Dropdown.Content>
  </Dropdown.Root>
);
```

Pentru a naviga din cod, apelați `useDropdownPage` într-o componentă redată în interiorul rădăcinii. Returnează `page`-ul curent, `goToPage(page)`, `goBack()`, `canGoBack` și `isActive`. Într-o pagină, `isActive` este adevărat numai cât timp pagina respectivă este activă și meniul său derulant este deschis. Folosește `isActive` pentru a afișa ferestrele popup personalizate ale unei pagini, randate prin portal, astfel încât acestea să dispară când pagina devine inactivă sau meniul derulant se închide. De exemplu, o opțiune poate reveni la pagina anterioară după o selecție, în timp ce fereastra pop-up rămâne deschisă:

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

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

  return (
    <Dropdown.SelectionGroup
      id="status"
      aria-label="Status"
      value={status}
      closeOnSelect={false}
      onValueChange={(value) => {
        onStatusChange(value);
        goBack();
      }}
    >
      {['Active', 'Archived'].map((option) => (
        <Dropdown.OptionItem key={option} value={option}>
          {option}
        </Dropdown.OptionItem>
      ))}
    </Dropdown.SelectionGroup>
  );
};
```

Utilizați `Submenu` cu `SubmenuTrigger` și un `Content` imbricat pentru un meniu alăturat. Arrow Right intră în submeniu; Arrow Left revine la părintele său. Selectarea unei acțiuni de închidere închide întregul dropdown.

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

## Selectoare imbricate independente

Plasați un alt `Dropdown.Root` în `Content` când un control își deschide propriul selector, cum ar fi un selector pentru direcția de sortare. Selectarea unei opțiuni interioare închide numai acel selector și restaurează focalizarea pe declanșatorul său. Escape și apăsările în exterior închid câte un strat pe rând. Utilizați `Submenu` pentru comenzi care ar trebui să închidă întregul arbore de meniuri când sunt selectate.

**Light**

[Selector de sortare cu un selector de direcție imbricat (light)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--nested-documentation\&viewMode=story\&globals=colorScheme:light)

**Dark**

[Selector de sortare cu un selector de direcție imbricat (dark)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--nested-documentation\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-components-dropdown--nested-documentation)

## Panouri și stare controlată

Utilizați `type="panel"` pentru câmpuri de formular. Interacțiunea cu câmpul de introducere menține panoul deschis; o acțiune de salvare îl poate închide. Gestionați `open` și `onOpenChange` când o altă componentă sau o comandă rapidă trebuie să deschidă dropdownul. Păstrați această stare împreună cu funcționalitatea care coordonează interacțiunea.

**Light**

[Panou de formular controlat (light)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--panel-documentation\&viewMode=story\&globals=colorScheme:light)

**Dark**

[Panou de formular controlat (dark)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--panel-documentation\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-components-dropdown--panel-documentation)

Escape închide fereastra pop-up și restaurează focalizarea pe declanșatorul său. Interacțiunea în exterior o închide, de asemenea, iar clicul care o închide nu activează elementul pe care ajunge. Tastele apăsate în fereastra pop-up rămân în interiorul acesteia, cu excepția comenzilor rapide Ctrl sau Cmd pe care dropdownul nu le gestionează, astfel încât comenzile rapide la nivel de pagină să continue să funcționeze. `Content` acceptă opțiuni de focalizare și portal de la Popover, inclusiv o țintă explicită pentru revenirea focalizării în fluxurile de lucru ale editorului.

## Închidere

Escape, o apăsare în exteriorul ferestrei pop-up și ieșirea cu Tab din aceasta închid dropdownul. Transmiteți `onEscapeKeyDown` sau `onInteractOutside` la `Root` pentru a reacționa înainte de închidere și apelați `event.preventDefault()` pentru a o menține deschisă. `event.target` este elementul apăsat în exterior sau `null` când focalizarea părăsește elementul cu Tab, iar `event.type` este tipul evenimentului DOM care l-a declanșat, cum ar fi `touchmove` pentru o glisare în exteriorul ferestrei pop-up. O apăsare în exterior prevenită ajunge totuși la elementul pe care aterizează.

```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>
);
```

## Ancorare fără declanșator

O rădăcină se poate deschide fără un `Trigger`, de exemplu ca meniu contextual. Controlați-o cu `open` și `onOpenChange` și transmiteți `anchor` la `Content`: un element, un ref sau un element virtual care returnează un dreptunghi în coordonatele ferestrei de vizualizare. Oferiți lui `Content` un `aria-label`, deoarece nu există un declanșator după care să fie denumit. La închidere, focalizarea revine la elementul care era focalizat când s-a deschis fereastra pop-up.

**Light**

[Meniu contextual ancorat la indicator (light)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--context-menu-documentation\&viewMode=story\&globals=colorScheme:light)

**Dark**

[Meniu contextual ancorat la indicator (dark)](https://storybook.twenty.com/iframe.html?id=ui-components-dropdown--context-menu-documentation\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-components-dropdown--context-menu-documentation)

```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>
    </>
  );
};
```

Un clic dreapta în altă parte, cât timp meniul este deschis, îl mută în noul punct.

Apelați `useDropdownPlacementOrThrow` în `Dropdown.Content` pentru a citi valorile rezolvate pentru `side` și `align`, inclusiv inversările cauzate de coliziuni. Folosiți latura rezolvată pentru a poziționa căutarea și controalele de creare ale unui selector lângă declanșatorul acestuia. Păstrați controalele în ordinea lor vizuală în DOM, astfel încât navigarea cu tastatura să urmeze aspectul. O căutare de sub rezultate primește focalizarea de la `ArrowDown` pe ultimul rezultat; `ArrowUp` din acea căutare revine la ultimul rezultat.

## Etichete

Fiecare parte își gestionează propriul text: furnizați `Search.placeholder` și nume accesibile native, atribute accesibile pentru `Close` și elemente copil pentru `Back`, `Loading` și `Empty`. `Back` are implicit valoarea `Back`; stările de încărcare și gol nu au mesaj integrat. Părțile elementului acceptă `shortcutJoinLabel` pentru a înlocui `then` implicit dintre pașii secvențiali ai unei comenzi rapide. `aria-labelledby` nativ are prioritate față de `aria-label`.

## Proprietăți

### Dropdown.Root

**Root.defaultOpen** `boolean`

Whether the popup is initially open when uncontrolled.

**Root.defaultPage** `string`

ID of the `Page` shown when the popup opens. Closing the popup resets the page history to it. Defaults to `root`.

**Root.multiple** `boolean`

Default for standalone options. Use `SelectionGroup.multiple` for independently owned selection values.

**Root.onEscapeKeyDown** `((event: DropdownDismissEvent) =\> void)`

Called when Escape is about to close the popup. Call `event.preventDefault()` to keep it open.

**Root.onInteractOutside** `((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, and `event.type` is the type of the DOM event that triggered it. Call `event.preventDefault()` to keep it open.

**Root.onOpenChange** `((open: boolean) =\> void)`

Called with the next open state when the popup opens or closes.

**Root.open** `boolean`

Whether the popup is open. Use with `onOpenChange` to control it.

**Root.type** `"menu" | "panel" | "picker"` *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.

### Dropdown.Trigger

**Trigger.className** `string | ((state: PopoverTriggerState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Trigger.closeDelay** `number` (default: 0)

How long to wait before closing the popover that was opened on hover.
Specified in milliseconds.

Requires the `openOnHover` prop.

**Trigger.delay** `number` (default: 300)

How long to wait before the popover may be opened on hover. Specified in milliseconds.

Requires the `openOnHover` prop.

**Trigger.id** `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).

**Trigger.nativeButton** `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>`).

**Trigger.openOnHover** `boolean` (default: false)

Whether the popover should also open when the trigger is hovered.

**Trigger.render** `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.

**Trigger.style** `CSSProperties | ((state: PopoverTriggerState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

### Dropdown.Content

**Content.align** `"center" | "end" | "start"` (default: start)

Alignment along the anchor. Defaults to start.

**Content.alignOffset** `number | OffsetFunction` (default: 0)

Offset along the alignment axis. Accepts a number or positioning function.

**Content.anchor** `Element | VirtualElement | RefObject\<Element | null\> | (() =\> Element | VirtualElement | null) | null`

An element to position the popup against.
By default, the popup will be positioned against the trigger.

**Content.className** `string | ((state: PopoverPopupState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Content.collisionPadding** `Padding` (default: 5)

Additional space to maintain from the edge of the collision boundary.

**Content.container** `HTMLElement | ShadowRoot | RefObject\<HTMLElement | ShadowRoot | null\> | null`

Portal destination, using the scoped theme when omitted. Explicit null waits for a target, matching Popover.Portal.

**Content.finalFocus** `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.

**Content.initialFocus** `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.

**Content.keepMounted** `boolean` (default: false)

Keeps the popup mounted while closed.

**Content.render** `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.

**Content.side** `"bottom" | "inline-end" | "inline-start" | "left" | "right" | "top"` (default: bottom)

Preferred side of the anchor. Defaults to bottom, or inline-end in a submenu.

**Content.sideOffset** `number | OffsetFunction` (default: 0)

Distance from the anchor. Defaults to 0. Accepts a number or positioning function.

**Content.style** `CSSProperties | ((state: PopoverPopupState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

**Content.width** `Width\<string | number\>` (default: 200)

CSS width of the popup. Numbers are in pixels.

### Dropdown.ActionItem

**ActionItem.actions** `ReactNode`

Trailing controls rendered beside the primary row control. Only supported in picker and panel pages, since a menu may only contain menu items. Secondary actions activate independently of the row.

**ActionItem.actionsVisibility** `"always" | "hover"`

Whether trailing actions appear on hover or remain visible. Defaults to `hover`.

**ActionItem.className** `string`

CSS class applied to the row.

**ActionItem.closeOnClick** `boolean` (default: true)

Closes the dropdown after activation, along with parent menus when inside a submenu. Ignored when `page` is set.

**ActionItem.color** `"danger" | "neutral"`

Color of the text and icons. `danger` marks a destructive action.

**ActionItem.description** `ReactNode`

Supporting text, placed according to `descriptionPlacement`.

**ActionItem.descriptionPlacement** `"below" | "end" | "inline"`

Places supporting content inline after the label, at the end, or below it with wrapping. Inline is the default.

**ActionItem.endIcon** `ReactNode`

Icon rendered after the content.

**ActionItem.focusableWhenDisabled** `boolean` (default: false)

Whether the button should be focusable when disabled.

**ActionItem.hasSubmenu** `boolean`

Shows a chevron indicating that the item opens a submenu.

**ActionItem.nativeButton** `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>`).

**ActionItem.page** `string`

ID of the `Page` to show on activation. The popup stays open, and the row shows a chevron by default.

**ActionItem.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\>`

Element rendered as the row instead of a native button. Custom components must forward the supplied props and ref.

**ActionItem.shortcut** `ShortcutDefinition`

Keyboard shortcut keys displayed at the end of the row. Registering the
shortcut is up to the application.

**ActionItem.shortcutJoinLabel** `string`

Text between sequential shortcut steps. Defaults to `then`.

**ActionItem.startIcon** `ReactNode`

Icon rendered before the content.

**ActionItem.style** `CSSProperties`

Inline styles applied to the row.

### Dropdown.OptionItem

**OptionItem.actions** `ReactNode`

Trailing controls rendered beside the primary row control. Only supported in picker and panel pages, since a menu may only contain menu items. Secondary actions activate independently of the row.

**OptionItem.actionsVisibility** `"always" | "hover"`

Whether trailing actions appear on hover or remain visible. Defaults to `hover`.

**OptionItem.className** `string`

CSS class applied to the row.

**OptionItem.closeOnSelect** `boolean`

Overrides the nearest group close policy for this option. A cancelled selection never closes automatically.

**OptionItem.color** `"danger" | "neutral"`

Color of the text and icons. `danger` marks a destructive action.

**OptionItem.description** `ReactNode`

Supporting text, placed according to `descriptionPlacement`.

**OptionItem.descriptionPlacement** `"below" | "end" | "inline"`

Places supporting content inline after the label, at the end, or below it with wrapping. Inline is the default.

**OptionItem.endIcon** `ReactNode`

Icon rendered after the content.

**OptionItem.focusableWhenDisabled** `boolean` (default: false)

Whether the button should be focusable when disabled.

**OptionItem.hasSubmenu** `boolean`

Shows a chevron indicating that the item opens a submenu.

**OptionItem.indicator** `"check" | "checkbox" | "none"`

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.

**OptionItem.nativeButton** `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>`).

**OptionItem.onSelect** `((eventDetails: DropdownSelectionGroupChangeEventDetails) =\> void)`

Called before the nearest group commits selection, with `event`, `reason`, `trigger`, `cancel` and `isCanceled`. Calling `cancel()` prevents the value change and automatic close.

**OptionItem.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, DropdownOptionItemState\>`

Element or function rendered as the row. Functions receive the supplied props and `{ selected, multiple, disabled }` state. Forward the props and ref to the rendered control.

**OptionItem.selected** `boolean`

Selected state for standalone options. Options inside a `SelectionGroup` derive it from their owner. Grouped picker options expose `aria-selected`, menu options expose `aria-checked`, and panel options expose `aria-pressed`.

**OptionItem.shortcut** `ShortcutDefinition`

Keyboard shortcut keys displayed at the end of the row. Registering the
shortcut is up to the application.

**OptionItem.shortcutJoinLabel** `string`

Text between sequential shortcut steps. Defaults to `then`.

**OptionItem.startIcon** `ReactNode`

Icon rendered before the content.

**OptionItem.style** `CSSProperties`

Inline styles applied to the row.

**OptionItem.value** `string`

Stable option identifier within its nearest `SelectionGroup`. The group supplies selected state and commits this value on activation.

### Dropdown.SelectionGroup

**SelectionGroup.closeOnSelect** `boolean`

Default close policy for owned options: true for single selection, false for multiple selection. Individual options can override it.

**SelectionGroup.defaultValue** `string | string[] | null`

Initial uncontrolled selection. Defaults to null for single selection and an empty array for multiple selection.

**SelectionGroup.id** `string`

Stable identifier unique within the dropdown root. Required for uncontrolled groups, whose values persist under it across popup close and page navigation. Optional for controlled groups.

**SelectionGroup.multiple** `boolean`

Uses an array of selected identifiers when true. Otherwise the value is one identifier or null.

**SelectionGroup.onValueChange** `((value: string | null, eventDetails: DropdownSelectionGroupChangeEventDetails) =\> void) | ((value: string[], eventDetails: DropdownSelectionGroupChangeEventDetails) =\> void)`

Called with the next value and cancellable event details: `event`, `reason`, `trigger`, `cancel` and `isCanceled`. Calling `cancel()` preserves the value and keeps the popup open. Repeated single selection does not emit another change.

**SelectionGroup.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, DropdownSelectionGroupState\>`

Element or function rendered as the group. Functions receive supplied props and `{ value, multiple }` state. Forward the props and ref.

**SelectionGroup.value** `string | string[] | null`

Controlled selection: a string or null for single selection, or an array for multiple selection. Undefined leaves selection uncontrolled.

### Dropdown.Search

**Search.className** `string | ((state: InputState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Search.defaultValue** `string | number | readonly string[]`

The default value of the input. Use when uncontrolled.

**Search.hasFocusRing** `boolean` (default: false)

Shows the search input focus outline. Defaults to false for all dropdown searches. Set true to opt in. Error styling remains visible.

**Search.onValueChange** `((value: string) =\> void)`

Called with the search text on every change. The application filters the results.

**Search.render** `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.

**Search.style** `CSSProperties | ((state: InputState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

**Search.textAlign** `"end" | "start"`

Aligns text to the logical start or end of the input. Follows the text direction.

**Search.value** `string | number | readonly string[]`

The value of the input. Use when controlled.

### Dropdown.Header

**Header.render** `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.

### Dropdown.Title

**Title.className** `string | ((state: PopoverTitleState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Title.render** `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.

**Title.style** `CSSProperties | ((state: PopoverTitleState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

### Dropdown.Close

**Close.aria-label** `string` *required*

Accessible name of the close control. Required because the default control only shows an icon.

**Close.className** `string | ((state: PopoverCloseState) =\> string | undefined)`

CSS class applied to the element, or a function that
returns a class based on the component's state.

**Close.nativeButton** `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>`).

**Close.render** `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.

**Close.style** `CSSProperties | ((state: PopoverCloseState) =\> CSSProperties | undefined)`

Style applied to the element, or a function that
returns a style object based on the component's state.

### Dropdown.Page

**Page.id** `string` *required*

Identifier matched by `defaultPage`, the `page` prop of actions, and `goToPage`. The page renders only while it is current.

**Page.type** `"menu" | "panel" | "picker"`

Interaction model while the page is shown. Defaults to the root `type`.

### Dropdown.Back

**Back.className** `string`

CSS class applied to the row.

**Back.color** `"danger" | "neutral"`

Color of the text and icons. `danger` marks a destructive action.

**Back.description** `ReactNode`

Supporting text, placed according to `descriptionPlacement`.

**Back.descriptionPlacement** `"below" | "end" | "inline"`

Places supporting content inline after the label, at the end, or below it with wrapping. Inline is the default.

**Back.endIcon** `ReactNode`

Icon rendered after the content.

**Back.focusableWhenDisabled** `boolean` (default: false)

Whether the button should be focusable when disabled.

**Back.hasSubmenu** `boolean`

Shows a chevron indicating that the item opens a submenu.

**Back.nativeButton** `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>`).

**Back.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\>`

Element rendered as the row instead of a native button. Custom components must forward the supplied props and ref.

**Back.shortcut** `ShortcutDefinition`

Keyboard shortcut keys displayed at the end of the row. Registering the
shortcut is up to the application.

**Back.shortcutJoinLabel** `string`

Text between sequential shortcut steps. Defaults to `then`.

**Back.startIcon** `ReactNode`

Icon rendered before the content.

**Back.style** `CSSProperties`

Inline styles applied to the row.

### Dropdown.Submenu

**Submenu.defaultOpen** `boolean`

Whether the popup is initially open when uncontrolled.

**Submenu.defaultPage** `string`

ID of the `Page` shown when the popup opens. Closing the popup resets the page history to it. Defaults to `root`.

**Submenu.multiple** `boolean`

Default for standalone options. Use `SelectionGroup.multiple` for independently owned selection values.

**Submenu.onOpenChange** `((open: boolean) =\> void)`

Called with the next open state when the popup opens or closes.

**Submenu.open** `boolean`

Whether the popup is open. Use with `onOpenChange` to control it.

**Submenu.type** `"menu" | "panel" | "picker"` (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.

### Dropdown.SubmenuTrigger

**SubmenuTrigger.className** `string`

CSS class applied to the row.

**SubmenuTrigger.closeDelay** `number`

Delay in milliseconds before a submenu opened on hover closes. Requires `openOnHover`. Defaults to `0`.

**SubmenuTrigger.color** `"danger" | "neutral"`

Color of the text and icons. `danger` marks a destructive action.

**SubmenuTrigger.delay** `number`

Delay in milliseconds before the submenu opens on hover. Requires `openOnHover`. Defaults to `300`.

**SubmenuTrigger.description** `ReactNode`

Supporting text, placed according to `descriptionPlacement`.

**SubmenuTrigger.descriptionPlacement** `"below" | "end" | "inline"`

Places supporting content inline after the label, at the end, or below it with wrapping. Inline is the default.

**SubmenuTrigger.endIcon** `ReactNode`

Icon rendered after the content.

**SubmenuTrigger.focusableWhenDisabled** `boolean` (default: false)

Whether the button should be focusable when disabled.

**SubmenuTrigger.hasSubmenu** `boolean` (default: true)

Shows a chevron indicating that the item opens a submenu.

**SubmenuTrigger.nativeButton** `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>`).

**SubmenuTrigger.openOnHover** `boolean` (default: true)

Also opens the submenu when the row is hovered.

**SubmenuTrigger.render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\>`

Element rendered as the row instead of a native button. Custom components must forward the supplied props and ref.

**SubmenuTrigger.shortcut** `ShortcutDefinition`

Keyboard shortcut keys displayed at the end of the row. Registering the
shortcut is up to the application.

**SubmenuTrigger.shortcutJoinLabel** `string`

Text between sequential shortcut steps. Defaults to `then`.

**SubmenuTrigger.startIcon** `ReactNode`

Icon rendered before the content.

**SubmenuTrigger.style** `CSSProperties`

Inline styles applied to the row.

### Dropdown.Section

**Section.columns** `number`

Number of grid columns. Sets the grid layout and enables horizontal arrow navigation and vertical movement by row.

**Section.label** `ReactNode`

Heading displayed above the rows. It also names the group for assistive technologies.

**Section.scrollable** `boolean`

Caps the section height and scrolls its rows. Nest labelled sections inside it to scroll them as one list.

### Dropdown.Separator

**Separator.className** `string`

Class applied to the separator. Native div attributes and refs are also accepted.

### Dropdown.Loading

**Loading.children** `ReactNode`

Loading message announced as a polite, busy status.

**Loading.className** `string`

Class applied to the status. Native div attributes and refs are also accepted.

### Dropdown.Empty

**Empty.children** `ReactNode`

Empty-state message announced as a polite status.

**Empty.className** `string`

Class applied to the status. Native div attributes and refs are also accepted.


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