Hecho sobre el UI SDK 0.1.0-beta.1 de Vercel. Su API puede cambiar.
Árbol
Una vista de árbol sobre el UI SDK de Vercel para archivos y páginas anidadas, con rutas de archivo, casillas, enlaces e hijos que cargan bajo demanda.
- Componentes de visualización de datos
- 7 partes
- 12 ejemplos
@tabler/icons-react@ui-sdk/core@ui-sdk/reactclass-variance-authority
pnpm dlx shadcn@latest add https://hextaui.com/r/ui-sdk-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 @ui-sdk/react@0.1.0-beta.1 @ui-sdk/core@0.1.0-beta.1 @tabler/icons-react class-variance-authority cnCopia y pega el siguiente código en tu proyecto.
components/ui/ui-sdk-tree.tsx Actualiza las rutas de importación para que coincidan con la configuración de tu proyecto.
UI SDK añade un poco de CSS propio en una capa de cascada llamada ui-sdk. Declara esa capa al principio de tu hoja de estilos global, encima del import de Tailwind, para que tus clases ganen.
Un elemento con un TreeGroup dentro es una rama. Da a cada elemento un value único y al árbol un nombre accesible. El foco se queda en el elemento y su label es la fila que ves, así que los estilos de seleccionado, actual y enfocado van en el label.
Pasa items sin hijos y el árbol renderiza por ti filas con estilo y chevrons. Cada elemento tiene un value, un label y children opcionales.
Pasa paths para un explorador de archivos, con las carpetas primero. Con activation="automatic" las flechas seleccionan, y un onAction que devuelve una promesa marca la fila como pendiente hasta que termine.
Con mode="multiple", Cmd o Ctrl con clic alterna un elemento y Shift amplía un rango. expandOnPress={false} deja la expansión al chevron y a las flechas.
Añade checkable y un TreeItemCheckbox en cada label. Marcar una rama marca todo lo que contiene, y una rama marcada en parte muestra un guion.
Los elementos con href se renderizan como enlaces. Con mode="none" y current, la página actual recibe aria-current, sus padres se abren y toma la parada de tabulación.
Marca un elemento como branch antes de que existan sus hijos, y loadChildren se ejecuta la primera vez que se abre. El chevron se convierte en un spinner mientras carga y en un icono de reintento si falla. Archive falla una vez.
variant="lines" dibuja una guía de sangría para cada grupo abierto, y size="sm" hace las filas más bajas.
Un controlador de createTreeController() expande, contrae, selecciona y revela elementos desde cualquier lugar.
Con hiddenUntilFound, los grupos cerrados siguen en la página, así la búsqueda del navegador encuentra Phobos y abre Mars para mostrarlo.
Un elemento deshabilitado puede recibir foco, así los lectores de pantalla lo encuentran, pero no se puede seleccionar, marcar ni abrir.
Las filas se sangran desde la derecha, el chevron apunta a la izquierda y las flechas izquierda y derecha se intercambian.
| Key | Acción |
|---|---|
| ↓↑ | Pasa al elemento visible siguiente o anterior. |
| → | Abre una rama o pasa a su primer hijo. |
| ← | Cierra una rama o pasa a su padre. |
| HomeEnd | Pasa al primer o último elemento visible. |
| Alt→ | Abre una rama y todo lo que contiene. |
| * | Abre todas las ramas junto a la enfocada. |
| Enter | Selecciona el elemento y ejecuta su acción, o sigue su enlace. |
| Space | Marca el elemento si el árbol es marcable; si no, lo selecciona. |
| Shift↓ | Amplía una selección múltiple. |
| ⌘A | Selecciona todos los elementos visibles en modo múltiple. |
El árbol sigue el patrón WAI-ARIA de vista de árbol con una sola parada de tabulación. Tab llega a la página actual, al elemento seleccionado o al primero. Escribir una letra pasa al siguiente elemento que empieza por ella. Mientras corre un onAction lento, los lectores de pantalla oyen pendingAnnouncement tras un segundo, así que ponlo en el idioma de tu página.
Los grupos se abren y cierran por altura solo cuando se permite el movimiento. En pantallas táctiles las filas son más altas, y en modo de colores forzados las filas seleccionada y actual tienen un contorno.
Cada parte envuelve la parte de UI SDK del mismo nombre y acepta todas sus props, incluidas render y un className que puede ser una función del estado de la parte.
| Prop | Tipo | Predeterminado |
|---|---|---|
itemsToda la jerarquía. Sin hijos, el árbol renderiza filas con estilo a partir de ella. | TreeItemData[] | – |
pathsRutas de archivo. Las carpetas se vuelven ramas; una ruta que termina en / es una carpeta vacía. | string[] | – |
mode | "single" | "multiple" | "none" | "single" |
value | string | string[] | null | – |
defaultValue | string | string[] | null | – |
onValueChange | (value, details) => void | – |
activation | "automatic" | "manual" | "manual" |
expanded | string[] | – |
defaultExpanded | string[] | – |
onExpandedChange | (expanded, details) => void | – |
expandOnPress | boolean | true |
checkable | boolean | false |
checked | string[] | – |
defaultChecked | string[] | – |
onCheckedChange | (checked, details) => void | – |
checkStrategy | "leaf" | "trunk" | "branch" | "independent" | "leaf" |
onActionSe ejecuta al pulsar o con Enter. Devuelve una promesa para marcar el elemento como pendiente. | (value, details) => unknown | – |
pendingAnnouncement | string | – |
loadChildren | (value, { signal }) => Promise<unknown> | – |
current | string | null | – |
disabled | boolean | false |
hiddenUntilFound | boolean | false |
keepMounted | boolean | false |
variant | "default" | "lines" | "default" |
size | "default" | "sm" | "default" |
controllerDe createTreeController(). | TreeController | – |
| Atributo | Descripción |
|---|---|
data-slot="tree" | Selecciona el árbol en CSS. |
data-variant | La variante: default o lines. |
data-size | El tamaño: default o sm. |
--tree-row-height | La altura de cada fila, definida por size. |
--tree-indent | Cuánto se sangra cada nivel. |
| Prop | Tipo | Predeterminado |
|---|---|---|
valueÚnico en el árbol. | string | – |
branchÚsalo para una rama cuyos hijos cargan después. | boolean | – |
disabled | boolean | false |
labelEl texto que busca la escritura anticipada cuando el label no es texto plano. | string | – |
render | ReactElement | (props, state) => ReactElement | – |
| Atributo | Descripción |
|---|---|
data-slot="tree-item" | Selecciona un elemento en CSS. Tiene el foco. |
data-level | La profundidad, desde 1. |
data-branch | Presente en una rama. |
data-expanded | Presente mientras una rama está abierta. |
--tree-level | La profundidad, para sangrar una lista plana. |
| Prop | Tipo | Predeterminado |
|---|---|---|
render | ReactElement | (props, state) => ReactElement | – |
| Atributo | Descripción |
|---|---|
data-slot="tree-label" | Selecciona una fila en CSS. |
data-selected | Presente mientras el elemento está seleccionado. |
data-current | Presente en el elemento de la página actual. |
data-expanded | Presente mientras una rama está abierta. |
data-pending | Presente mientras se ejecuta el onAction del elemento. |
data-disabled | Presente cuando el elemento está deshabilitado. |
| Prop | Tipo | Predeterminado |
|---|---|---|
childrenPor defecto, un chevron, un spinner mientras carga y un icono de reintento tras un fallo. | ReactNode | (state) => ReactNode | – |
| Atributo | Descripción |
|---|---|
data-slot="tree-indicator" | Apunta al chevron en CSS. |
data-loading | Presente mientras cargan los hijos. |
data-failed | Presente tras fallar la carga de los hijos. |
| Prop | Tipo | Predeterminado |
|---|---|---|
childrenPor defecto, una marca, o un guion si está mixto. | ReactNode | (state) => ReactNode | – |
| Atributo | Descripción |
|---|---|
data-slot="tree-checkbox" | Selecciona la casilla en CSS. |
data-checked | Presente mientras está marcado. |
data-indeterminate | Presente mientras una rama está marcada en parte. |
| Prop | Tipo | Predeterminado |
|---|---|---|
keepMounted | boolean | – |
hiddenUntilFound | boolean | – |
| Atributo | Descripción |
|---|---|
data-slot="tree-group" | Selecciona un grupo en CSS. |
data-open | Presente mientras está abierto. |
--tree-group-height | La altura del grupo mientras se anima. |
- 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.
- ItemUna fila de contenido multimedia, texto y acciones para listas, ajustes y selectores, con una superficie agrupada y un resaltado al pasar el cursor que se desliza entre filas.