Dropdown menu
Un menu d’actions et d’options derrière un bouton, avec groupes, sous-menus, éléments case à cocher et radio, et raccourcis.
pnpm dlx shadcn@latest add https://hextaui.com/r/dropdown-menu.jsonAjoute le composant, les tokens de thème HextaUI et les composants HextaUI dont il dépend.
Ajoutez les tokens de thème à votre CSS global, si ce n’est pas déjà fait.
Installez les dépendances.
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cnCopiez et collez le code suivant dans votre projet.
components/ui/dropdown-menu.tsx Mettez à jour les chemins d’import selon la configuration de votre projet.
Zone de sécurité
Se déplacer en diagonale d’un déclencheur de sous-menu vers son sous-menu croise les déclencheurs voisins. La zone de sécurité garde le sous-menu ouvert pendant que le pointeur s’y dirige. Activez showSafeArea pour la voir en direct : le point devient vert dans la zone et rouge là où le sous-menu changerait.
Cases à cocher
<DropdownMenuCheckboxItem /> bascule un réglage et garde le menu ouvert, ce qui permet d’en modifier plusieurs à la suite. La coche se dessine et s’efface au lieu d’apparaître d’un coup.
Radio group
Enveloppez <DropdownMenuRadioItem /> dans un <DropdownMenuRadioGroup /> pour choisir une seule option. Un libellé dans le groupe le nomme pour les lecteurs d’écran.
Coche à droite
Définissez indicator="end" sur les éléments à case à cocher et radio pour afficher la coche après le libellé au lieu de décaler celui-ci, ce qui convient aux sélecteurs avec une description sous chaque option.
Type select
Le menu n’est jamais plus étroit que son déclencheur. Définissez closeOnClick sur les éléments radio lorsque choisir l’un d’eux doit aussi fermer le menu.
Actions de ligne
Un seul menu sert toutes les lignes. Créez un handle avec createDropdownMenuHandle, passez-le à chaque déclencheur avec un payload, et lisez le payload dans le menu. Delete passe la main à une boîte de dialogue d’alerte.
Contrôlé
Passez open et onOpenChange. Le deuxième argument indique pourquoi le menu a changé, par exemple un appui sur le déclencheur, sur un élément ou sur Escape. Les éléments avec closeOnClick={false} le gardent ouvert.
Ouverture au survol
openOnHover sur le déclencheur ouvre le menu après delay et le ferme après closeDelay. Le clic et le clavier fonctionnent toujours : les utilisateurs du toucher et du clavier ne sont donc pas bloqués.
Désactivé
Un déclencheur désactivé ne s’ouvre jamais. Les éléments désactivés restent visibles et sont ignorés par les flèches.
Contenu long
Les libellés passent à la ligne au lieu d’étirer le menu au-delà de 20 rem, les chaînes sans coupure se coupent n’importe où, et les raccourcis restent sur la première ligne.
Défilement
Lorsqu’il n’y a pas de place pour tous les éléments, le menu défile dans le viewport et l’élément en surbrillance défile dans la vue.
Dans une sheet
Le menu se superpose à la sheet. Escape ferme d’abord le menu, puis la sheet.
De droite à gauche
Le menu, le chevron du sous-menu et le côté du sous-menu suivent la direction du déclencheur. Les raccourcis gardent leur ordre de gauche à droite.
| Touche | Action |
|---|---|
| EnterSpace↓ | Sur le déclencheur, ouvre le menu et met en évidence le premier élément. |
| ↓ | Met en évidence l’élément suivant, en rebouclant à la fin. |
| ↑ | Met en évidence l’élément précédent, en rebouclant au début. |
| Home | Met en évidence le premier élément. |
| End | Met en évidence le dernier élément. |
| EnterSpace | Exécute l’élément en surbrillance. Les éléments à case à cocher et radio basculent et gardent le menu ouvert. |
| → | Ouvre le sous-menu en surbrillance et s’y déplace. ← dans les mises en page de droite à gauche. |
| ← | Ferme le sous-menu actuel et revient à son déclencheur. → dans les mises en page de droite à gauche. |
| Esc | Ferme le menu actuel et rend le focus à son déclencheur. Dans un sous-menu, seul ce sous-menu se ferme. |
| A–Z | Met en évidence l’élément suivant commençant par cette lettre. |
- Le déclencheur est annoncé comme un bouton de menu, et le focus lui revient à la fermeture du menu.
- Donnez un
aria-labelaux déclencheurs réduits à une icône, comme le fait l’exemple des actions de ligne. <DropdownMenuShortcut />n’est qu’un libellé visuel. Associez les touches vous-même.- Avec la réduction des animations, le menu apparaît en fondu sans changer d’échelle et le clignotement des éléments est ignoré.
Construit sur le menu de Base UI. Chaque partie accepte les props de la primitive qu’elle enveloppe.
| Prop | Type | Par défaut |
|---|---|---|
open | boolean | – |
defaultOpen | boolean | false |
showSafeAreaDessine la zone de sécurité du sous-menu tant que le menu est ouvert. Pour le débogage et les démos. | boolean | false |
onOpenChangedetails.reason indique la cause du changement. | (open: boolean, details) => void | – |
modalVerrouille le défilement de la page et bloque les clics extérieurs pendant l’ouverture. | boolean | true |
loopFocusReboucle les flèches à chaque extrémité. | boolean | true |
handleRelie des déclencheurs détachés à ce menu. | DropdownMenuHandle<Payload> | – |
childrenUtilisez la forme fonction pour lire le payload du déclencheur d’ouverture. | ReactNode | ({ payload }) => ReactNode | – |
disabled | boolean | false |
| Prop | Type | Par défaut |
|---|---|---|
openOnHover | boolean | false |
delayMillisecondes avant qu’un survol n’ouvre le menu. | number | 100 |
closeDelayMillisecondes avant la fermeture d’un menu ouvert au survol. | number | 0 |
handle | DropdownMenuHandle<Payload> | – |
payloadTransmis au menu lorsque ce déclencheur l’ouvre. | Payload | – |
disabled | boolean | false |
render | ReactElement | (props, state) => ReactElement | <button> |
| Attribut | Description |
|---|---|
data-slot="dropdown-menu-trigger" | Ciblez le déclencheur en CSS. |
data-popup-open | Présent tant que son menu est ouvert. |
data-pressed | Présent tant que le déclencheur est enfoncé. |
data-disabled | Présent lorsque le déclencheur est désactivé. |
| Prop | Type | Par défaut |
|---|---|---|
side | "top" | "bottom" | "left" | "right" | "inline-start" | "inline-end" | "bottom" |
align | "start" | "center" | "end" | "start" |
sideOffset | number | 4 |
alignOffset | number | 0 |
collisionPaddingEspace conservé entre le menu et le bord du viewport. | number | Rect | 8 |
anchorSe positionne par rapport à un autre élément plutôt qu’au déclencheur. | Element | RefObject | VirtualElement | – |
sticky | boolean | false |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="dropdown-menu-content" | Ciblez le menu en CSS. |
data-open | Présent tant que le menu est ouvert. |
data-starting-style | Présent pendant l’animation d’entrée du menu. |
data-ending-style | Présent pendant l’animation de sortie du menu. |
data-side | Le côté retenu par le menu après la gestion des collisions. |
data-align | L’alignement retenu. |
data-chosen | Présent après le clic sur un élément : le menu attend donc le clignotement de confirmation de l’élément avant de se fermer. |
--anchor-width | La largeur du déclencheur. Le menu est au moins aussi large. |
--available-height | Espace restant dans le viewport. Les longs menus y défilent. |
--transform-origin | Le point d’où part l’animation d’agrandissement, à côté du déclencheur. |
| Prop | Type | Par défaut |
|---|---|---|
variant | "default" | "destructive" | "default" |
insetDécale l’élément pour l’aligner avec les éléments à case à cocher. | boolean | false |
closeOnClick | boolean | true |
onClick | (event) => void | – |
labelTexte utilisé pour la recherche à la frappe lorsque les enfants ne sont pas du texte simple. | string | – |
disabled | boolean | false |
renderRendez un lien avec render={<a href="…" />}. | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="dropdown-menu-item" | Ciblez les items en CSS. |
data-variant | La variante actuelle. |
data-highlighted | Présent tant que l’élément est mis en évidence par le pointeur ou le clavier. |
data-disabled | Présent lorsque l’item est désactivé. |
data-chosen | Présent sur l’élément qui vient d’être cliqué, pendant son clignotement. |
data-inset | Présent lorsque inset est défini. |
| Prop | Type | Par défaut |
|---|---|---|
checked | boolean | – |
defaultChecked | boolean | false |
onCheckedChange | (checked: boolean, details) => void | – |
closeOnClick | boolean | false |
inset | boolean | false |
indicator | "start" | "end" | "start" |
disabled | boolean | false |
| Attribut | Description |
|---|---|
data-slot="dropdown-menu-checkbox-item" | Ciblez les éléments à case à cocher en CSS. |
data-checked | Présent lorsqu’il est coché. |
data-unchecked | Présent lorsqu’il n’est pas coché. |
data-highlighted | Présent tant que l’élément est mis en évidence par le pointeur ou le clavier. |
data-disabled | Présent lorsque l’item est désactivé. |
data-chosen | Présent sur l’élément qui vient d’être cliqué, pendant son clignotement. |
data-inset | Présent lorsque inset est défini. |
| Prop | Type | Par défaut |
|---|---|---|
value | Value | – |
defaultValue | Value | – |
onValueChange | (value: Value, details) => void | – |
disabled | boolean | false |
| Prop | Type | Par défaut |
|---|---|---|
value | Value | – |
closeOnClick | boolean | false |
inset | boolean | false |
indicator | "start" | "end" | "start" |
disabled | boolean | false |
| Attribut | Description |
|---|---|
data-slot="dropdown-menu-radio-item" | Ciblez les éléments radio en CSS. |
data-checked | Présent sur l’élément sélectionné. |
data-unchecked | Présent sur les autres éléments. |
data-highlighted | Présent tant que l’élément est mis en évidence par le pointeur ou le clavier. |
data-disabled | Présent lorsque l’item est désactivé. |
data-chosen | Présent sur l’élément qui vient d’être cliqué, pendant son clignotement. |
data-inset | Présent lorsque inset est défini. |
Regroupe des éléments liés. Un <DropdownMenuLabel /> à l’intérieur devient le nom accessible du groupe.
| Prop | Type | Par défaut |
|---|---|---|
inset | boolean | false |
render | ReactElement | (props, state) => ReactElement | <div> |
Un séparateur entre les groupes, annoncé comme séparateur.
| Prop | Type | Par défaut |
|---|---|---|
dirLes raccourcis gardent l’ordre de leurs touches dans les menus de droite à gauche. | "ltr" | "rtl" | "ltr" |
| Prop | Type | Par défaut |
|---|---|---|
open | boolean | – |
defaultOpen | boolean | false |
onOpenChange | (open: boolean, details) => void | – |
closeParentOnEscFerme tout le menu avec Escape, et pas seulement ce sous-menu. | boolean | false |
| Prop | Type | Par défaut |
|---|---|---|
inset | boolean | false |
disabled | boolean | false |
delayMillisecondes avant qu’un survol n’ouvre le sous-menu. | number | 100 |
closeDelay | number | 0 |
| Attribut | Description |
|---|---|
data-slot="dropdown-menu-sub-trigger" | Ciblez les déclencheurs de sous-menu en CSS. |
data-popup-open | Présent tant que son sous-menu est ouvert. |
data-highlighted | Présent pendant la mise en surbrillance. |
| Prop | Type | Par défaut |
|---|---|---|
sideOffset | number | 0 |
alignOffset | number | -4 |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="dropdown-menu-sub-content" | Ciblez les sous-menus en CSS. |
data-open | Présent tant que le menu est ouvert. |
data-starting-style | Présent pendant l’animation d’entrée du menu. |
data-ending-style | Présent pendant l’animation de sortie du menu. |
data-side | Le côté retenu par le menu après la gestion des collisions. |
data-align | L’alignement retenu. |
data-chosen | Présent après le clic sur un élément : le menu attend donc le clignotement de confirmation de l’élément avant de se fermer. |
--available-height | Espace restant dans le viewport. Les longs menus y défilent. |
--transform-origin | Le point d’où part l’animation d’agrandissement, à côté du déclencheur. |
- Alert dialogUne boîte de dialogue de confirmation pour les actions destructrices ou importantes, qui attend le travail asynchrone et devient une bottom sheet sur mobile.
- CommandUne liste d’actions recherchable, intégrée ou en palette ⌘K, avec pages, raccourcis et correspondances surlignées.
- Context menuUn menu d’actions au clic droit ou à l’appui long, avec sous-menus, éléments case à cocher et radio, et retour visuel de maintien au toucher.
- DialogUne fenêtre au-dessus de la page pour les formulaires et les tâches ciblées, avec en-tête et pied de page épinglés, imbrication, et une bottom sheet balayable sur mobile.
- DrawerUn panneau qui glisse depuis n’importe quel bord et suit votre doigt, avec des points d’accroche, une poignée fonctionnelle et des drawers imbriqués qui s’empilent.
- Hover cardUne carte d’aperçu qui s’ouvre au survol ou au focus d’un lien, pour un contenu que les personnes voyantes peuvent parcourir du regard.
Utilisé dans les blocks
Des blocks qui s’appuient sur Dropdown menu.
- Prompt InputUn champ de discussion qui démarre sur une seule ligne sobre, grandit en carte à mesure que vous écrivez et descend une fois la conversation lancée. Entrée envoie, sans risque avec la saisie japonaise et chinoise. Collez, déposez ou choisissez des fichiers avec aperçus, progression et nouvel essai. @ ajoute des fichiers et / lance des commandes depuis un menu au niveau du curseur. Un sélecteur de modèle avec touches numériques, un curseur d’effort qui s’anime à Max, un anneau de contexte, la dictée avec forme d’onde en direct, des chips d’outils, une file pour les messages saisis pendant qu’une réponse arrive en streaming, et des brouillons qui survivent à un rechargement.
- API keysLa page des clés d’API d’un produit d’IA, comme les consoles d’OpenAI et d’Anthropic. Créez des clés avec des permissions limitées et une expiration, voyez le secret une seule fois avec une copie qui confirme, révoquez avec annulation, renommez sur place, effectuez une rotation avec période de grâce et consultez l’utilisation par clé.
- ArtifactLe panneau à côté d’un chat IA qui montre ce que le modèle a produit. Pages web, SVG, documents et code arrivent en direct, puis passent à un aperçu isolé en sandbox, avec des versions à comparer et à restaurer, une séparation redimensionnable et une bottom sheet sur mobile.
- Chat SidebarLa barre latérale d’une application de chat. Logo, recherche et Nouveau chat en haut, vos propres liens en dessous, chats épinglés, projets qui se déploient pour montrer leurs chats, récents regroupés par jour, et des lignes avec menus au survol et au clic droit, renommage en ligne, suppression avec annulation et états de réponse en direct.