Alert dialog
Une boîte de dialogue de confirmation pour les actions destructrices ou importantes, qui attend le travail asynchrone et devient une bottom sheet sur mobile.
pnpm dlx shadcn@latest add https://hextaui.com/r/alert-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/alert-dialog.tsx components/ui/sheet.tsx components/ui/button.tsx Mettez à jour les chemins d’import selon la configuration de votre projet.
Action asynchrone
Retournez une promesse depuis le onClick de <AlertDialogAction />. Le bouton affiche un spinner et la boîte de dialogue ne peut pas être fermée avant que la promesse soit réglée. Elle se ferme à la résolution et reste ouverte en cas de rejet, pour que l’on puisse réessayer.
Média
<AlertDialogMedia /> place une icône à côté du titre sur ordinateur et au-dessus sur téléphone. Utilisez variant="destructive" pour les actions destructrices.
Petit
size="sm" centre le contenu et place les boutons côte à côte, pour les questions courtes.
Déclencheurs détachés
Créez un handle avec createAlertDialogHandle() pour partager une même boîte de dialogue entre plusieurs déclencheurs. Chaque déclencheur transmet son propre payload, que la boîte lit via une fonction de rendu.
Contrôlé
Passez open et onOpenChange pour l’ouvrir depuis le code, sans déclencheur. Le focus arrive toujours sur Cancel.
Imbriqué
Une boîte de dialogue ouverte depuis une autre s’empile par-dessus. La parente se réduit tant que l’enfant est ouvert et revient au premier plan à sa fermeture.
Contenu long
Un contenu plus haut que l’écran défile à l’intérieur de la boîte de dialogue pendant que la page reste verrouillée.
De droite à gauche
Passez aussi dir au contenu, car il s’affiche dans un portail en dehors de votre conteneur RTL. Les flèches du pied de page suivent le sens de lecture.
| Touche | Action |
|---|---|
| EnterSpace | Sur le déclencheur, ouvre la boîte de dialogue et place le focus sur Cancel. |
| TabShift+Tab | Déplace le focus entre les contrôles. Le focus reste à l’intérieur. |
| ←→↑↓ | Passe d’un bouton du pied de page à l’autre en bouclant. Gauche et droite suivent le sens de lecture. |
| Esc | Ferme la boîte de dialogue et rend le focus au déclencheur. Ignoré pendant l’exécution d’une action asynchrone. |
- Le contenu a
role="alertdialog", est étiqueté par son titre et décrit par sa description. - Le focus démarre sur
<AlertDialogCancel />, le choix le moins destructeur. PassezinitialFocuspour le modifier. - Un clic sur l’arrière-plan ne la ferme pas : une décision n’est donc jamais écartée par accident. Définissez
disablePointerDismissal={false}pour l’autoriser. - Sur téléphone, elle devient une bottom sheet qu’on peut balayer vers le bas pour annuler. Pendant qu’une action est en cours, le balayage, Esc et Cancel sont bloqués et les boutons restent focusables.
- Avec la réduction des animations, elle apparaît en fondu au lieu de changer d’échelle.
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 |
onOpenChangeNon appelé pour les fermetures bloquées par une action en cours. | (open: boolean, details) => void | – |
onOpenChangeCompleteAppelé après l’animation d’ouverture ou de fermeture. | (open: boolean) => void | – |
disablePointerDismissalGarde la boîte de dialogue ouverte lors d’un clic sur l’arrière-plan. | boolean | true |
handleRelie des déclencheurs détachés. | AlertDialogHandle<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 | AlertDialogHandle<Payload> | – |
payloadTransmis à la fonction de rendu de la boîte de dialogue. | Payload | – |
render | ReactElement | (props, state) => ReactElement | <button> |
| Attribut | Description |
|---|---|
data-slot="alert-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 | "default" | "sm" | "default" |
initialFocus | boolean | RefObject | (openType) => HTMLElement | boolean | Cancel button |
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="alert-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 média, le titre et la description.
| Attribut | Description |
|---|---|
data-slot="alert-dialog-header" | Ciblez l’en-tête en CSS. |
| Prop | Type | Par défaut |
|---|---|---|
variant | "default" | "destructive" | "default" |
| Attribut | Description |
|---|---|
data-slot="alert-dialog-media" | Ciblez le média en CSS. |
| Prop | Type | Par défaut |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <h2> |
| Attribut | Description |
|---|---|
data-slot="alert-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="alert-dialog-description" | Ciblez la description en CSS. |
Un <div> pour les boutons. Les boutons s’empilent sur toute la largeur sur téléphone, et les flèches permettent de passer de l’un à l’autre.
| Attribut | Description |
|---|---|
data-slot="alert-dialog-footer" | Ciblez le pied de page en CSS. |
Un <Button /> qui ferme la boîte de dialogue au clic. Il accepte toutes les props de Button.
| Prop | Type | Par défaut |
|---|---|---|
onClickRetournez une promesse pour afficher un spinner et garder la boîte de dialogue ouverte jusqu’à son règlement. Appelez event.preventDefault() pour la garder ouverte. | (event) => void | PromiseLike<unknown> | – |
variant | ButtonVariant | "default" |
| Attribut | Description |
|---|---|
data-slot="alert-dialog-action" | Ciblez les actions en CSS. |
| Prop | Type | Par défaut |
|---|---|---|
variant | ButtonVariant | "outline" |
size | ButtonSize | – |
disabledÉgalement désactivé pendant qu’une action est en cours. | boolean | – |
| Attribut | Description |
|---|---|
data-slot="alert-dialog-cancel" | Ciblez le bouton d’annulation en CSS. Il reçoit le focus initial. |
data-disabled | Présent lorsque l’élément est désactivé. |
<AlertDialogContent /> 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 <AlertDialogTrigger /> placés n’importe où dans la page à un seul <AlertDialog />. Typez le payload avec un générique : createAlertDialogHandle<{ 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.
- 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.
Utilisé dans les blocks
Des blocks qui s’appuient sur Alert dialog.
- 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.
- NotificationsLa section Notifications des paramètres d’un produit d’IA. Une grille canal par événement avec bascules par ligne, par colonne et globale, des heures calmes avec une ligne « prochain calme » en direct, un résumé par e-mail, de vrais envois de test pour le bureau, l’e-mail, le push et Slack, la gestion des permissions du navigateur et un flux de connexion à Slack. S’intègre dans n’importe quelle section Settings.
- SecuritySessions et sécurité pour un produit d’IA. Appareils actifs avec déconnexion qui fait disparaître les lignes en animation, changement de mot de passe avec jauge de robustesse en direct, configuration de l’authentification à deux facteurs avec un vrai code QR, une vérification à 6 chiffres et des codes de récupération téléchargeables, des passkeys via WebAuthn, et la suppression du compte derrière une confirmation saisie.