Button
Des 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.
pnpm dlx shadcn@latest add https://hextaui.com/r/button.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/button.tsx Mettez à jour les chemins d’import selon la configuration de votre projet.
Avec feedback, retournez une promesse depuis onClick : le bouton affiche le chargement, puis le succès ou l’erreur, puis se réinitialise tout seul.
Variantes
Sept variantes. destructive est une teinte douce : une action dangereuse se lit clairement sans crier, et ghost-destructive est la version discrète pour les actions répétées sur des lignes comme Sign out ou Remove.
Tailles
Tailles de texte de xs à lg, et tailles carrées icon-*. Les petits boutons-icônes reçoivent une zone tactile invisible plus grande sur écran tactile.
Pill
shape="pill" arrondit entièrement les extrémités, et les tailles d’icône deviennent des cercles. Idéal pour les boutons placés dans des surfaces arrondies, comme un champ de saisie de conversation.
Avec icône
Marquez une icône avec data-icon="inline-start" ou "inline-end" et le remplissage de ce côté se resserre pour l’équilibrer.
Désactivé
focusableWhenDisabled garde un bouton désactivé dans l’ordre de tabulation, pour qu’un tooltip ou une explication reste accessible au clavier.
Libellés personnalisés
loadingLabel, successLabel et errorLabel remplacent le texte de chaque état. Chaque libellé bascule vers l’intérieur pendant que l’ancien bascule vers l’extérieur.
Largeur fluide
Le bouton s’adapte progressivement à la largeur de chaque libellé au lieu de réserver la place du plus long : rien autour de lui ne saute.
Détails de l’erreur
Passez une fonction à errorLabel pour afficher la raison du rejet. Tant que le pointeur ou le focus clavier reste sur le bouton, l’erreur reste affichée.
Formulaires
Pour les boutons de soumission, appelez track() de useButtonFeedback dans onSubmit et propagez buttonProps sur le bouton. Retirez le @ pour voir l’erreur.
Boutons-icônes
Les tailles d’icône ne remplacent que l’icône pour chaque état et gardent leur forme carrée. L’aria-label reste le nom accessible.
Retour d’état sur chaque variante
Les variantes pleines passent au vert ou au rouge une fois terminées. ghost et link ne changent que la couleur de leur texte.
Chargement contrôlé
Définissez vous-même loading lorsque le travail est suivi ailleurs. Le bouton reste focusable et annonce qu’il est occupé.
Statut contrôlé
Pilotez status directement, par exemple à partir de l’état de soumission d’une bibliothèque de formulaires.
Comme lien
Passez une ancre à render et définissez nativeButton={false} pour que le bouton conserve la sémantique d’un lien.
De droite à gauche
Les icônes et les libellés d’état suivent le sens de lecture.
| Touche | Action |
|---|---|
| EnterSpace | Active le bouton. Ignoré pendant qu’une requête de retour d’état est en cours. |
| Tab | Déplace le focus. Un bouton en chargement reste focusable, et donner le focus à une erreur la garde à l’écran jusqu’à ce que vous le déplaciez. |
- Chaque changement d’état est annoncé via une région live polie : le chargement, puis le libellé de succès ou d’erreur.
- Pendant le chargement, le bouton définit
aria-busyet reste focusable : le focus n’est donc jamais perdu en pleine requête. - Le spinner n’apparaît qu’après 150 ms puis reste au moins 400 ms : les requêtes rapides ne provoquent aucun flash et les lentes aucun scintillement.
- Avec la réduction des animations, les libellés d’état se fondent au lieu de basculer et la secousse d’erreur est ignorée.
Construit sur le bouton de Base UI. Il rend un <button> et accepte tous ses attributs.
| Prop | Type | Par défaut |
|---|---|---|
variant | "default" | "outline" | "secondary" | "ghost" | "ghost-destructive" | "destructive" | "link" | "default" |
size | "xs" | "sm" | "default" | "lg" | "icon-xs" | "icon-sm" | "icon" | "icon-lg" | "icon-xl" | "default" |
shape | "default" | "pill" | "default" |
feedbackSuit la promesse retournée par onClick et affiche son statut. | boolean | false |
onClickRetournez une promesse pour piloter le retour d’état. | (event) => unknown | – |
loadingÉtat de chargement contrôlé. | boolean | – |
statusStatut contrôlé. Prioritaire sur loading. | "idle" | "loading" | "success" | "error" | – |
onStatusChange | (status: ButtonStatus) => void | – |
onErrorAppelé avec la raison du rejet. | (error: unknown) => void | – |
resetAfterMillisecondes avant de revenir à l’état inactif. | number | { success?: number; error?: number } | { success: 2000, error: 4000 } |
loadingLabelAffiché à côté du spinner. Masqué sur les tailles d’icône. | ReactNode | – |
successLabel | ReactNode | "Done" |
errorLabel | ReactNode | (error: unknown) => ReactNode | "Failed" |
disabled | boolean | false |
focusableWhenDisabledToujours true pendant le chargement. | boolean | false |
nativeButtonÀ définir sur false lorsque render n’est pas un <button>. | boolean | true |
render | ReactElement | (props, state) => ReactElement | <button> |
| Attribut | Description |
|---|---|
data-slot="button" | Ciblez les boutons en CSS. |
data-status | idle, loading, success ou error. Présent dès que feedback, loading ou status est utilisé. |
data-disabled | Présent lorsque le bouton est désactivé. |
aria-busy | Présent pendant le chargement. |
Exécute le même flux de retour d’état depuis n’importe où, comme le onSubmit d’un formulaire. Accepte resetAfter, onStatusChange et onError. Consultez le guide de useButtonFeedback pour le détail des durées.
| Valeur de retour | Description |
|---|---|
track(action) | Passez une promesse ou une fonction qui en retourne une. Les appels effectués pendant qu’une requête est en cours sont ignorés. |
buttonProps | À propager sur <Button> pour afficher le statut et suspendre la réinitialisation au survol et au focus. |
status | Le ButtonStatus actuel. |
error | La dernière raison de rejet. |
reset() | Annule la requête et revient à l’état inactif. |
isPending() | Indique si une requête est en cours. |
- 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.
- useButtonFeedbackExécute une action asynchrone avec chargement, succès et erreur, en évitant le spinner pour les requêtes rapides et en maintenant une erreur le temps de la lire.
- Button groupDes boutons réunis en un seul contrôle, avec jointures partagées, séparateurs, addons de texte, imbrication et piles verticales.
- ToggleUn bouton qui reste activé ou désactivé, avec un remplissage qui se pose à l’appui, une étape claire entre survol et activation, et des icônes qui peuvent se remplir selon l’état.
- Toggle groupUne rangée de boutons à bascule pour un choix unique ou multiple, avec un remplissage qui glisse vers l’élément choisi, des éléments joints ou espacés et un focus aux flèches du clavier.
- 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.
Utilisé dans les blocks
Des blocks qui s’appuient sur Button.
- 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.
- Agent TodosAffichez le plan d’un agent pendant son travail. Chaque étape passe de backlog à à faire, en cours puis terminé, avec des durées en direct, les échecs et les appels d’outils qui les sous-tendent. Une pastille de statut à placer au-dessus du champ de saisie, des changements de plan visibles et une étape de relecture pour modifier le plan avant son exécution.
- 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é.
- AppearanceLa section Apparence des paramètres d’un produit d’IA : thème, couleur d’accent, teinte de fond, densité, police du chat, tailles de texte et options d’accessibilité, le tout conservé en brouillon jusqu’à l’enregistrement.