Árbol
Filas anidadas y expandibles para archivos y jerarquías, con guías de sangría, líneas conectoras, checkboxes en cascada, typeahead y soporte completo de teclado.
pnpm dlx shadcn@latest add https://hextaui.com/r/tree.jsonAñade el componente, los tokens del tema de HextaUI y los componentes de HextaUI de los que depende.
Añade los tokens del tema a tu CSS global, si aún no lo has hecho.
Instala las dependencias.
pnpm add @base-ui/react @tabler/icons-react class-variance-authority cnCopia y pega el siguiente código en tu proyecto.
components/ui/tree.tsx components/ui/checkbox.tsx Actualiza las rutas de importación para que coincidan con la configuración de tu proyecto.
Un elemento con un <TreeGroup /> es una rama: recibe un chevron, se abre y se cierra, y responde a las flechas. Cada elemento necesita un value único dentro del árbol.
Guías de sangría
variant="lines" dibuja una guía por cada nivel. La guía de la rama que contiene la fila seleccionada o enfocada se oscurece, para que veas dónde estás en árboles profundos.
Conectores
variant="connectors" une cada elemento con su padre mediante un codo, como el listado de árbol de una terminal. Usa meta para versiones, tamaños o recuentos.
Casillas de verificación
Con checkboxes, marcar una rama marca todos los elementos habilitados que contiene, y una rama parcialmente marcada muestra un guion. Marcar una rama también cuenta como marcar los hijos que cargues más tarde. Hacer clic en una fila la marca, y el chevron la abre.
Navegación
Renderiza las filas como enlaces con render. Pasa la página actual a selectedValues, abre su sección y define aria-current en su fila.
Selección múltiple
selectionMode="multiple" funciona como un gestor de archivos: clic para seleccionar una fila, Cmd/Ctrl+clic para añadir o quitar una, Shift+clic para seleccionar un rango. En pantallas táctiles un toque añade o quita la fila.
Controlado
Mantén las ramas abiertas en tu propio estado con expandedValues y onExpandedValuesChange. Este ejemplo también construye el árbol a partir de datos con una función recursiva.
Carga diferida
Obtén los hijos en onExpandedChange de <TreeItem />. Renderiza una fila de carga deshabilitada hasta que lleguen, para que la rama conserve su chevron.
Pequeño
size="sm" usa filas más cortas y sangrías más ajustadas, para sidebars. Las filas crecen en pantallas táctiles en ambos tamaños.
Deshabilitado
Un elemento deshabilitado no se puede seleccionar, marcar ni abrir, y las flechas lo omiten. Los elementos dentro de una rama deshabilitada también están deshabilitados.
Nombres largos
Los nombres se cortan con puntos suspensivos y meta permanece visible. Pasa title para mostrar el nombre completo al pasar el cursor.
De derecha a izquierda
Las sangrías, los conectores y los chevrons se reflejan, y las flechas izquierda y derecha se intercambian.
| Key | Acción |
|---|---|
| ↓ | Mueve el foco a la siguiente fila visible. |
| ↑ | Mueve el foco a la fila visible anterior. |
| → | Abre una rama cerrada. En una rama abierta, mueve el foco a su primer hijo. |
| ← | Cierra una rama abierta. En caso contrario, mueve el foco al padre. |
| Home | Mueve el foco a la primera fila. |
| End | Mueve el foco a la última fila visible. |
| Enter | Selecciona la fila y la abre o la cierra si es una rama. Sigue el enlace en las filas de enlace. |
| Space | Selecciona la fila, la añade o quita en modo múltiple, o la marca con checkboxes. |
| Shift + ↑Shift + ↓ | Amplía la selección en modo múltiple. |
| Cmd/Ctrl + A | Selecciona todas las filas visibles en modo múltiple. |
| * | Abre todas las ramas del nivel de la fila enfocada. |
| a–z | Mueve el foco a la siguiente fila cuyo nombre empieza por las letras escritas. |
El árbol sigue el patrón tree view de WAI-ARIA. Cada fila es el treeitem y es dueña de su grupo mediante aria-owns, así que el nombre de una fila es solo su propia etiqueta y las filas de enlace funcionan como enlaces reales. Solo una fila está en el orden de tabulación a la vez. Cuando una rama se cierra alrededor de la fila enfocada, el foco pasa a esa rama en lugar de perderse.
Los grupos cerrados permanecen en la página, así que la búsqueda en página del navegador abre las carpetas alrededor de una coincidencia, y marcar una rama ve todos los elementos que contiene. Dale al árbol un aria-label.
Las ramas se abren y cierran con el collapsible de Base UI. <TreeItem /> y <TreeGroup /> aceptan las props de las partes que envuelven.
| Prop | Tipo | Predeterminado |
|---|---|---|
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 | – |
checkboxesMuestra checkboxes en cascada. Las filas se marcan en lugar de seleccionarse. | boolean | false |
checkedValuesElementos marcados. Una rama en la lista cuenta como marcar a sus hijos. | string[] | – |
defaultCheckedValues | string[] | – |
onCheckedValuesChangeSe llama con cada hoja marcada y cada rama completamente marcada. | (values: string[]) => void | – |
disabled | boolean | false |
hiddenUntilFoundPermite que la búsqueda en página abra las ramas cerradas alrededor de una coincidencia. | boolean | true |
render | ReactElement | (props, state) => ReactElement | <div> |
| Atributo | Descripción |
|---|---|
data-slot="tree" | Apunta a la raíz en CSS. |
data-variant | La variante actual. |
data-size | El tamaño actual. |
--tree-row-height | Altura de la fila. Mayor en pantallas táctiles. |
--tree-indent | Cuánto se sangra cada nivel. |
| Prop | Tipo | Predeterminado |
|---|---|---|
valueObligatorio. Único dentro del árbol. | string | – |
disabled | boolean | false |
onExpandedChangeSe llama cuando este elemento se abre o se cierra. | (expanded: boolean) => void | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| Atributo | Descripción |
|---|---|
data-slot="tree-item" | Apunta a los elementos en CSS. |
data-open | Presente cuando el elemento está abierto. |
data-disabled | Presente cuando el elemento está deshabilitado. |
| Prop | Tipo | Predeterminado |
|---|---|---|
iconSe muestra antes de la etiqueta. | ReactNode | – |
expandedIconAparece con fundido cruzado para icon mientras la rama está abierta. | ReactNode | – |
metaSe muestra al final de la fila, como un tamaño, un recuento o un estado. | ReactNode | – |
className | string | – |
render | ReactElement | (props, state) => ReactElement | <div> |
| Atributo | Descripción |
|---|---|
data-slot="tree-item-label" | Apunta a las filas en CSS. |
data-value | El valor del elemento. |
data-expanded | Presente cuando la rama está abierta. |
data-selected | Presente cuando la fila está seleccionada. |
data-checked | Presente cuando la fila está marcada. |
data-indeterminate | Presente cuando solo están marcados algunos hijos. |
data-disabled | Presente cuando el elemento está deshabilitado. |
| Prop | Tipo | Predeterminado |
|---|---|---|
classNameSe aplica al contenedor interno, para que el padding nunca choque con la animación de altura. | string | – |
| Atributo | Descripción |
|---|---|
data-slot="tree-group" | Apunta a los grupos en CSS. |
data-open | Presente cuando el grupo está abierto. |
data-starting-style | Presente mientras el grupo se anima al entrar. |
data-ending-style | Presente mientras el grupo se anima al salir. |
--collapsible-panel-height | La altura medida del grupo, usada para la animación de altura. |
- CheckboxUna casilla de verificación cuya marca se dibuja, con padres indeterminados, grupos y etiquetas que comparten su hover.
- AvatarFotos de usuario con iniciales como alternativa, insignias de estado y grupos apilados que se colapsan en un contador.
- BadgeEtiquetas de estado con puntos de color, tags eliminables que se deslizan al cerrarse y contadores que ruedan hasta su nuevo valor.
- CardUna superficie para agrupar contenido, con tres variantes, contenido multimedia de borde a borde, radios concéntricos y enlaces en toda la tarjeta.
- ChartGráficos de Recharts con colores del tema, un tooltip y una leyenda que leen las etiquetas de una sola configuración, y navegación con teclado con un anillo de foco visible.
- Data tableUna tabla para datos reales, con ordenación, búsqueda, selección de filas, columnas fijadas, un encabezado fijo y paginación.
Usado en bloques
Bloques que se construyen sobre Tree.
- Diff ReviewRevisa las ediciones de un agente en todos los archivos antes de que se apliquen. Un árbol de archivos con contadores, aceptar o rechazar cada cambio, cada archivo o todo, comentarios en cualquier línea o rango que vuelven al agente, vistas unificada y dividida, resaltado a nivel de palabra, deshacer, ediciones en streaming y un resumen «Editados 4 archivos» para el chat.
- Tool CallsMuestra lo que hace un agente, una línea por paso. Las lecturas y búsquedas se pliegan en un resumen breve, mientras que las ediciones, comandos, aprobaciones y errores permanecen a la vista. Cada paso se abre en una vista real: el archivo, el diff, la terminal o los resultados. Cubre todos los estados de herramienta de AI SDK, incluidas las aprobaciones con un motivo para dar otra indicación.