Tree
Des lignes imbriquées et dépliables pour les fichiers et les hiérarchies, avec guides d'indentation, lignes de connexion, cases à cocher en cascade, saisie prédictive et prise en charge complète du clavier.
pnpm dlx shadcn@latest add https://hextaui.com/r/tree.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/tree.tsx components/ui/checkbox.tsx Mettez à jour les chemins d’import selon la configuration de votre projet.
Un élément avec un <TreeGroup /> est une branche : il reçoit un chevron, s'ouvre et se ferme, et répond aux flèches. Chaque élément a besoin d'une value unique dans l'arbre.
Guides d'indentation
variant="lines" trace un guide pour chaque niveau. Le guide de la branche qui contient la ligne sélectionnée ou focalisée devient plus foncé, pour que vous voyiez où vous êtes dans les arbres profonds.
Connecteurs
variant="connectors" relie chaque élément à son parent par un coude, comme un listing d'arbre dans un terminal. Utilisez meta pour des versions, tailles ou compteurs.
Cases à cocher
Avec checkboxes, cocher une branche coche tous les éléments activés qu'elle contient, et une branche partiellement cochée affiche un tiret. Cocher une branche vaut aussi pour les enfants chargés plus tard. Cliquer sur une ligne la coche, et le chevron l'ouvre.
Navigation
Rendez les lignes comme des liens avec render. Passez la page courante à selectedValues, ouvrez sa section et définissez aria-current sur sa ligne.
Sélection multiple
selectionMode="multiple" fonctionne comme un gestionnaire de fichiers : cliquez pour sélectionner une ligne, Cmd/Ctrl+clic pour en ajouter ou en retirer une, Maj+clic pour sélectionner une plage. Sur écran tactile, un tap ajoute ou retire la ligne.
Contrôlé
Gardez les branches ouvertes dans votre propre état avec expandedValues et onExpandedValuesChange. Cet exemple construit aussi l'arbre à partir de données avec une fonction récursive.
Chargement différé
Récupérez les enfants dans onExpandedChange sur <TreeItem />. Affichez une ligne de chargement désactivée jusqu'à leur arrivée, pour que la branche garde son chevron.
Petit
size="sm" utilise des lignes plus courtes et des retraits plus serrés, pour les sidebars. Les lignes grandissent sur écran tactile dans les deux tailles.
Désactivé
Un élément désactivé ne peut être ni sélectionné, ni coché, ni ouvert, et les flèches le sautent. Les éléments d'une branche désactivée le sont aussi.
Noms longs
Les noms sont coupés par des points de suspension et meta reste visible. Passez title pour afficher le nom complet au survol.
De droite à gauche
Les retraits, connecteurs et chevrons sont inversés, et les flèches gauche et droite échangent leur rôle.
| Touche | Action |
|---|---|
| ↓ | Place le focus sur la ligne visible suivante. |
| ↑ | Place le focus sur la ligne visible précédente. |
| → | Ouvre une branche fermée. Sur une branche ouverte, place le focus sur son premier enfant. |
| ← | Ferme une branche ouverte. Sinon, déplace le focus vers le parent. |
| Home | Place le focus sur la première ligne. |
| End | Place le focus sur la dernière ligne visible. |
| Enter | Sélectionne la ligne et l'ouvre ou la ferme s'il s'agit d'une branche. Suit le lien sur les lignes de lien. |
| Space | Sélectionne la ligne, l'ajoute ou la retire en mode multiple, ou la coche avec les cases à cocher. |
| Shift + ↑Shift + ↓ | Étend la sélection en mode multiple. |
| Cmd/Ctrl + A | Sélectionne toutes les lignes visibles en mode multiple. |
| * | Ouvre toutes les branches du niveau de la ligne qui a le focus. |
| a–z | Place le focus sur la prochaine ligne dont le nom commence par les lettres saisies. |
L'arbre suit le motif tree view de WAI-ARIA. Chaque ligne est le treeitem et possède son groupe via aria-owns : le nom d'une ligne n'est donc que son propre label, et les lignes de lien fonctionnent comme de vrais liens. Une seule ligne est dans l'ordre de tabulation à la fois. Quand une branche se ferme autour de la ligne qui a le focus, le focus passe à cette branche au lieu de se perdre.
Les groupes fermés restent dans la page : la recherche dans la page du navigateur ouvre donc les dossiers autour d'une correspondance, et cocher une branche voit tous les éléments qu'elle contient. Donnez un aria-label à l'arbre.
Les branches s'ouvrent et se ferment avec le collapsible de Base UI. <TreeItem /> et <TreeGroup /> acceptent les props des parties qu'ils enveloppent.
| Prop | Type | Par défaut |
|---|---|---|
variant | "default" | "lines" | "connectors" | "default" |
size | "default" | "sm" | "default" |
selectionMode | "none" | "single" | "multiple" | "single" |
selectedValues | string[] | – |
defaultSelectedValues | string[] | – |
onSelectedValuesChange | (values: string[]) => void | – |
expandedValues | string[] | – |
defaultExpandedValues | string[] | – |
onExpandedValuesChange | (values: string[]) => void | – |
checkboxesAffiche des cases à cocher en cascade. Les lignes sont cochées au lieu d'être sélectionnées. | boolean | false |
checkedValuesÉléments cochés. Une branche présente dans la liste équivaut à cocher ses enfants. | string[] | – |
defaultCheckedValues | string[] | – |
onCheckedValuesChangeAppelé avec chaque feuille cochée et chaque branche entièrement cochée. | (values: string[]) => void | – |
disabled | boolean | false |
hiddenUntilFoundLaisse la recherche dans la page ouvrir les branches fermées autour d'une correspondance. | boolean | true |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="tree" | Ciblez la racine en CSS. |
data-variant | La variante actuelle. |
data-size | La taille actuelle. |
--tree-row-height | Hauteur de ligne. Plus grande sur écran tactile. |
--tree-indent | Retrait de chaque niveau. |
| Prop | Type | Par défaut |
|---|---|---|
valueObligatoire. Unique dans l'arbre. | string | – |
disabled | boolean | false |
onExpandedChangeAppelé quand cet élément s'ouvre ou se ferme. | (expanded: boolean) => void | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="tree-item" | Ciblez les items en CSS. |
data-open | Présent lorsque l’élément est ouvert. |
data-disabled | Présent lorsque l’item est désactivé. |
| Prop | Type | Par défaut |
|---|---|---|
iconAffiché avant le label. | ReactNode | – |
expandedIconApparaît en fondu enchaîné à la place de icon tant que la branche est ouverte. | ReactNode | – |
metaAffiché à la fin de la ligne, par exemple une taille, un compteur ou un statut. | ReactNode | – |
className | string | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| Attribut | Description |
|---|---|
data-slot="tree-item-label" | Cible les lignes en CSS. |
data-value | La valeur de l'élément. |
data-expanded | Présent quand la branche est ouverte. |
data-selected | Présent quand la ligne est sélectionnée. |
data-checked | Présent quand la ligne est cochée. |
data-indeterminate | Présent quand seuls certains enfants sont cochés. |
data-disabled | Présent lorsque l’item est désactivé. |
| Prop | Type | Par défaut |
|---|---|---|
classNameAppliqué au conteneur interne, afin que le padding n’entre jamais en conflit avec l’animation de hauteur. | string | – |
| Attribut | Description |
|---|---|
data-slot="tree-group" | Ciblez les groupes en CSS. |
data-open | Présent quand le groupe est ouvert. |
data-starting-style | Présent pendant l'animation d'entrée du groupe. |
data-ending-style | Présent pendant l'animation de sortie du groupe. |
--collapsible-panel-height | La hauteur mesurée du groupe, utilisée pour l'animation de hauteur. |
- CheckboxUne case à cocher dont la coche se dessine, avec des parents indéterminés, des groupes et des libellés qui partagent son survol.
- AvatarDes photos d’utilisateurs avec initiales en repli, badges de statut et groupes empilés qui se réduisent en compteur.
- BadgeDes libellés de statut avec pastilles colorées, des tags amovibles qui se referment en glissant et des compteurs qui défilent vers leur nouvelle valeur.
- CardUne surface pour regrouper du contenu, avec trois variantes, médias bord à bord, rayons concentriques et liens sur toute la carte.
- ChartDes graphiques Recharts aux couleurs du thème, avec une infobulle et une légende qui lisent leurs libellés depuis une seule config, et une navigation au clavier avec anneau de focus visible.
- Data tableUn tableau pour de vraies données, avec tri, recherche, sélection de lignes, colonnes épinglées, en-tête fixe et pagination.
Utilisé dans les blocks
Des blocks qui s’appuient sur Tree.
- 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.
- Tool CallsMontrez ce que fait un agent, une ligne par étape. Les lectures et recherches se replient en un court résumé, tandis que les modifications, commandes, approbations et erreurs restent visibles. Chaque étape s’ouvre sur une vraie vue : le fichier, le diff, le terminal ou les résultats. Tous les états d’outil d’AI SDK sont couverts, y compris les approbations avec un motif à donner en échange.