Dialog
Une 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.
pnpm dlx shadcn@latest add https://hextaui.com/r/dialog.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/dialog.tsx components/ui/sheet.tsx components/ui/button.tsx Mettez à jour les chemins d’import selon la configuration de votre projet.
Form
Gardez le formulaire dans <DialogBody /> et pointez le bouton de soumission du pied de page vers lui avec form. Enter soumet, et la boîte de dialogue se ferme via onOpenChange une fois la valeur enregistrée.
Bouton de fermeture personnalisé
Masquez le bouton du coin avec showCloseButton={false} sur le contenu et ajoutez un bouton Close au pied de page avec showCloseButton.
Sans bouton de fermeture
Sans bouton, la boîte de dialogue se ferme quand même avec Esc, un clic à l’extérieur ou, sur téléphone, un balayage vers le bas.
Tailles
size définit la largeur maximale sur les grands écrans : sm, default ou lg.
Pied de page fixe
Un long contenu dans <DialogBody /> défile tandis que l’en-tête et le pied de page restent en place : les actions sont donc toujours à portée.
Contenu défilant
Sans pied de page, le corps défile sous l’en-tête et conserve son remplissage inférieur.
Contrôlé
Passez open et onOpenChange pour l’ouvrir depuis le code, sans déclencheur.
Imbriqué
Une boîte de dialogue ou une boîte de dialogue d’alerte ouverte depuis une autre s’empile par-dessus. La parente recule et un arrière-plan plus clair la recouvre. Esc ne ferme que celle du dessus.
Déclencheurs détachés
Créez un handle avec createDialogHandle() pour partager une même boîte de dialogue entre plusieurs déclencheurs. Chaque déclencheur transmet un payload que la boîte lit via une fonction de rendu.
De droite à gauche
Passez aussi dir au contenu, car il s’affiche dans un portail en dehors de votre conteneur RTL.
| Touche | Action |
|---|---|
| EnterSpace | Sur le déclencheur, ouvre la boîte de dialogue et déplace le focus vers son premier contrôle. |
| TabShift+Tab | Déplace le focus entre les contrôles. Le focus reste à l’intérieur. |
| Esc | Ferme la boîte de dialogue du dessus et rend le focus à son déclencheur. |
- Le contenu a
role="dialog", est étiqueté par son titre et décrit par sa description. Incluez toujours un<DialogTitle />. - À la souris ou au clavier, le focus démarre sur le premier contrôle. Au toucher, il démarre sur la boîte de dialogue elle-même, pour que le clavier à l’écran ne recouvre pas le contenu avant que l’on choisisse un champ. Passez
initialFocuspour le modifier. - Le bouton de fermeture du coin est étiqueté « Close », et la page derrière est inerte et ne peut pas défiler.
- Sur téléphone, elle devient une bottom sheet qu’on peut balayer vers le bas pour la fermer. Avec la réduction des animations, elle apparaît en fondu au lieu de changer d’échelle ou de glisser.
Construit sur le drawer de Base UI, via <Sheet />. Chaque partie accepte les props de la primitive ou de l’élément qu’elle enveloppe.
| Prop | Type | Par défaut |
|---|---|---|
open | boolean | – |
defaultOpen | boolean | false |
onOpenChange | (open: boolean, details) => void | – |
onOpenChangeCompleteAppelé après l’animation d’ouverture ou de fermeture. | (open: boolean) => void | – |
modal | boolean | "trap-focus" | true |
disablePointerDismissalGarde la boîte de dialogue ouverte lors des clics à l’extérieur. | boolean | false |
handleRelie des déclencheurs détachés. | DialogHandle<Payload> | – |
actionsRefFerme ou démonte la boîte de dialogue de façon impérative. | RefObject<{ close, unmount }> | – |
children | ReactNode | ({ payload }) => ReactNode | – |
| Prop | Type | Par défaut |
|---|---|---|
handle | DialogHandle<Payload> | – |
payloadTransmis à la fonction de rendu de la boîte de dialogue. | Payload | – |
render | ReactElement | (props, state) => ReactElement | <button> |
| Attribut | Description |
|---|---|
data-slot="dialog-trigger" | Ciblez les déclencheurs en CSS. |
data-popup-open | Présent tant que sa boîte de dialogue est ouverte. |
| Prop | Type | Par défaut |
|---|---|---|
size | "sm" | "default" | "lg" | "default" |
showCloseButtonAffiche le bouton de fermeture dans le coin. | boolean | true |
initialFocus | boolean | RefObject | (openType) => HTMLElement | boolean | First control, or the dialog on touch |
finalFocus | boolean | RefObject | (closeType) => HTMLElement | boolean | The trigger |
dirÀ définir lorsque la boîte de dialogue doit être de droite à gauche. | "ltr" | "rtl" | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="dialog-content" | Ciblez la boîte de dialogue en CSS. |
data-size | La taille actuelle. |
data-open | Présent tant que l’élément est ouvert. |
data-starting-style | Présent pendant l’animation d’ouverture de la boîte de dialogue. |
data-ending-style | Présent pendant l’animation de fermeture de la boîte de dialogue. |
data-nested-drawer-open | Présent tant qu’une boîte de dialogue imbriquée est ouverte par-dessus. |
data-swiping | Présent pendant qu’on la balaie sur téléphone. |
--nested-drawers | Nombre de boîtes de dialogue ouvertes par-dessus celle-ci. |
Un <div> qui empile le titre et la description. Il laisse la place du bouton de fermeture.
| Attribut | Description |
|---|---|
data-slot="dialog-header" | Ciblez l’en-tête en CSS. |
Un <div> qui défile lorsque le contenu est plus haut que l’écran, en gardant l’en-tête et le pied de page en place.
| Attribut | Description |
|---|---|
data-slot="dialog-body" | Ciblez le corps en CSS. |
Un <div> pour les actions. Les boutons s’empilent sur toute la largeur sur téléphone, le premier en bas.
| Prop | Type | Par défaut |
|---|---|---|
showCloseButtonAjoute un bouton Close outline après les enfants. | boolean | false |
| Attribut | Description |
|---|---|
data-slot="dialog-footer" | Ciblez le pied de page en CSS. |
| Prop | Type | Par défaut |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <h2> |
| Attribut | Description |
|---|---|
data-slot="dialog-title" | Ciblez le titre en CSS. |
| Prop | Type | Par défaut |
|---|---|---|
renderUtilisez render={<div />} lorsqu’il contient plusieurs paragraphes. | ReactElement | (props, state) => ReactElement | <p> |
| Attribut | Description |
|---|---|
data-slot="dialog-description" | Ciblez la description en CSS. |
| Prop | Type | Par défaut |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <button> |
| Attribut | Description |
|---|---|
data-slot="dialog-close" | Ciblez les boutons de fermeture en CSS. |
<DialogContent /> affiche déjà les deux. Utilisez-les uniquement pour composer une fenêtre personnalisée.
| Prop | Type | Par défaut |
|---|---|---|
keepMountedSur le portail, garde la boîte de dialogue dans le DOM lorsqu’elle est fermée. | boolean | false |
Retourne un handle qui relie des éléments <DialogTrigger /> placés n’importe où dans la page à un seul <Dialog />. Typez le payload avec un générique : createDialogHandle<{ name: string }>().
- ButtonDes boutons dans toutes les variantes et tailles, avec un flux de chargement, de succès et d’erreur intégré qui évite le spinner pour les requêtes rapides.
- SheetUn panneau qui glisse depuis n’importe quel bord, avec fermeture par balayage, verrouillage du défilement et imbrication empilée.
- 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.
- 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.
Utilisé dans les blocks
Des blocks qui s’appuient sur Dialog.
- 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é.
- BillingForfait et utilisation pour un produit d’IA, dans le style de Cursor, Claude et Vercel. Un compteur d’utilisation réparti par modèle qui projette la fin du cycle et prévient avant la fin des crédits, un graphique quotidien explorable, une limite de dépenses avec des alertes prévisualisables sur le compteur, des changements de forfait avec proratisation exacte, un formulaire de carte avec une vraie validation, et des factures téléchargeables en PDF.
- ModelsLa page Modèles des paramètres d’un produit d’IA. Un modèle par défaut avec son contexte, sa vitesse et son coût en un coup d’œil, un effort par défaut qui sait ce que prend en charge chaque modèle, une liste de modèles consultable groupée par fournisseur avec filtres, épingles et bascules groupées, des serveurs compatibles OpenAI avec un vrai test de connexion, et une actualisation qui indique les nouveautés.