Empty
Un espace réservé pour les écrans sans contenu à afficher, avec une icône, un message et l’action suivante.
pnpm dlx shadcn@latest add https://hextaui.com/r/empty.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 class-variance-authority cnCopiez et collez le code suivant dans votre projet.
components/ui/empty.tsx Mettez à jour les chemins d’import selon la configuration de votre projet.
Entrée
Lorsqu’un état vide remplace du contenu, ses parties apparaissent en fondu l’une après l’autre : média, titre, description, puis actions. Fermez les notifications pour le voir. Avec la réduction des animations, il apparaît simplement. Définissez animated={false} pour les états vides présents dès le premier rendu.
Outline
variant="outline" dessine une bordure fine en pointillés, la manière habituelle de marquer une zone de dépôt ou une zone en attente de contenu.
Atténué
variant="muted" repose sur un fond doux. La tuile d’icône passe à une surface blanche surélevée pour rester visible.
Petit
size="sm" resserre le remplissage, les écarts, la tuile d’icône et le titre pour les barres latérales, les popovers et les panneaux étroits.
Avatar
La variante EmptyMedia par défaut ne fait que centrer son contenu : n’importe quel avatar, badge ou illustration convient.
Groupe d’avatars
Montrez qui pourrait être là, pour les invitations et les espaces partagés.
Image
Donnez aux images des dimensions explicites pour que la mise en page ne bouge pas pendant leur chargement.
Aucun résultat de recherche
Remplacez les résultats par un état vide lorsque les filtres ne correspondent à rien, et proposez une issue. Un role="status" masqué visuellement annonce le nombre : les utilisateurs de lecteurs d’écran entendent le changement sans que toute la liste soit lue.
Dans une carte
Utilisez size="sm" avec la variante muted pour remplir une carte qui n’a pas encore de données.
Dans un tableau
Placez-le dans une seule cellule qui couvre toutes les colonnes avec colSpan, pour que l’en-tête reste aligné.
Dans un popover
Un état vide compact pour les menus et les panneaux de notifications.
Dans une liste de commandes
<CommandEmpty /> transmet la recherche actuelle à un enfant fonction, pour que le message puisse la citer.
Niveau de titre
Le titre est un <div> pour ne jamais casser le plan de votre page. Rendez-le avec le niveau de titre adapté, et étiquetez la région avec lui.
Contenu long
Les noms sans coupure et les longues adresses passent à la ligne dans le conteneur, et les libellés de bouton longs sont tronqués.
De droite à gauche
Tout est centré et utilise des propriétés logiques : il se lit donc naturellement dans les mises en page de droite à gauche.
<EmptyTitle />rend un<div>. Passezrender={<h2 />}(ou le niveau adapté) lorsque l’état vide est une section de la page.<EmptyMedia variant="icon" />est masqué aux technologies d’assistance, car le titre dit déjà ce qu’il signifie. Les images de la variante par défaut restent exposées : donnez-leur unaltoualt="".- Lorsque des résultats disparaissent après une recherche ou un filtre, annoncez le changement par un court message
role="status"à côté de la liste. Ne faites pas de tout l’état vide une région live, car ses boutons et ses liens seraient lus à chaque fois.
Chaque partie rend un élément simple, accepte ses attributs et prend en charge la prop render pour le remplacer.
| Prop | Type | Par défaut |
|---|---|---|
variant | "default" | "outline" | "muted" | "default" |
sizesm resserre le remplissage, les écarts, la tuile d’icône et le titre. | "default" | "sm" | "default" |
animatedFait apparaître les parties en fondu l’une après l’autre au montage de l’état vide. Ignoré avec la réduction des animations. | boolean | true |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="empty" | Ciblez la racine en CSS. |
data-variant | La variante actuelle. |
data-size | La taille actuelle. |
data-animated | Présent lorsque l’animation d’entrée est activée. |
--empty-padding | Remplissage de tous les côtés. Défini par size. |
--empty-gap | Espace entre l’en-tête et le contenu. Défini par size. |
| Prop | Type | Par défaut |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="empty-header" | Ciblez l’en-tête en CSS. |
| Prop | Type | Par défaut |
|---|---|---|
varianticon place une icône dans une tuile atténuée. stack élève la tuile au-dessus de deux cartes en éventail qui s’écartent au survol de l’état vide. Les deux masquent le média aux technologies d’assistance. | "default" | "icon" | "stack" | "default" |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="empty-icon" | Ciblez le média en CSS. Compatible avec shadcn. |
data-variant | La variante actuelle. |
| Prop | Type | Par défaut |
|---|---|---|
renderRendez un titre, par exemple render={<h2 />}. | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="empty-title" | Ciblez le titre en CSS. |
| Prop | Type | Par défaut |
|---|---|---|
renderLes liens simples à l’intérieur sont soulignés. Les composants rendus comme liens gardent leur propre style. | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="empty-description" | Ciblez la description en CSS. |
| Prop | Type | Par défaut |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="empty-content" | Ciblez la zone d’actions en CSS. |
- AlertDes messages en ligne pour le statut et les retours, avec une surface neutre, une icône colorée et une fermeture qui se replie en douceur.
- ProgressUne barre ou un anneau qui montre l’avancement d’une tâche, s’adoucit entre les mises à jour et glisse tant que le total est inconnu.
- SkeletonDes placeholders qui attendent 150ms avant de s’afficher, prennent la taille exacte du contenu qu’ils enveloppent et l’affichent en fondu sans rien déplacer.
- SpinnerUn indicateur de chargement avec des graduations façon Apple ou un anneau qui respire, pouvant attendre avant de s’afficher et rester assez longtemps pour ne pas clignoter.
- ToastDe brefs messages qui s’empilent proprement, se déploient au survol, se balayent pour disparaître et transforment un état de chargement en succès ou en erreur sur place.
Utilisé dans les blocks
Des blocks qui s’appuient sur Empty.
- 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é.
- Diff ReviewRelisez les modifications d’un agent dans plusieurs fichiers avant qu’elles ne soient appliquées. Une arborescence de fichiers avec compteurs, acceptation ou rejet de chaque changement, de chaque fichier ou de tout, des commentaires sur n’importe quelle ligne ou plage renvoyés à l’agent, des vues unifiée et côte à côte, des surlignages au niveau du mot, l’annulation, des modifications en streaming et un résumé « 4 fichiers modifiés » pour le chat.
- 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.
- SettingsParamètres pour un produit d’IA, présentés comme dans Cursor et Claude. Une barre latérale pleine avec recherche, groupes et liens externes, des cartes de lignes avec sélecteurs discrets et options imbriquées, un îlot d’enregistrement sombre qui n’apparaît que si quelque chose a changé, ⌘S pour enregistrer, des erreurs de champ issues de vos contrôles ou de votre serveur, et des états de chargement qui épousent la forme du contenu.