Skip to main content

Guía de Expansión

Ejemplos

¿Quieres ir directamente a la implementación? Consulta estos ejemplos:

API

API de Expansión

Guía de la Característica de Expansión

La expansión es una característica que te permite mostrar y ocultar filas de datos adicionales relacionadas con una fila específica. Esto puede ser útil en casos donde tienes datos jerárquicos y quieres permitir a los usuarios profundizar en los datos desde un nivel superior. O puede ser útil para mostrar información adicional relacionada con una fila.

Diferentes casos de uso para las Características de Expansión

Existen múltiples casos de uso para las características de expansión en TanStack Table que se discutirán a continuación.

  1. Expansión de sub-filas (filas secundarias, filas agregadas, etc.)
  2. Expansión de interfaz de usuario personalizada (paneles de detalle, sub-tablas, etc.)

Habilitar la Expansión del Lado del Cliente

Para usar las características de expansión del lado del cliente, necesitas definir la función getExpandedRowModel en las opciones de tu tabla. Esta función es responsable de devolver el modelo de fila expandida.

const table = useReactTable({
// otras opciones...
getExpandedRowModel: getExpandedRowModel(),
});

Los datos expandidos pueden contener filas de tabla o cualquier otro dato que quieras mostrar. Discutiremos cómo manejar ambos casos en esta guía.

Filas de tabla como datos expandidos

Las filas expandidas son esencialmente filas secundarias que heredan la misma estructura de columnas que sus filas principales. Si tu objeto de datos ya incluye estos datos de filas expandidas, puedes utilizar la función getSubRows para especificar estas filas secundarias. Sin embargo, si tu objeto de datos no contiene los datos de las filas expandidas, pueden tratarse como datos expandidos personalizados, lo cual se discute en la siguiente sección.

Por ejemplo, si tienes un objeto de datos como este:

type Person = {
id: number;
name: string;
age: number;
children?: Person[] | undefined;
};

const data: Person[] = [
{
id: 1,
name: "John",
age: 30,
children: [
{ id: 2, name: "Jane", age: 5 },
{ id: 5, name: "Jim", age: 10 },
],
},
{
id: 3,
name: "Doe",
age: 40,
children: [{ id: 4, name: "Alice", age: 10 }],
},
];

Entonces puedes usar la función getSubRows para devolver el array children en cada fila como filas expandidas. La instancia de la tabla ahora entenderá dónde buscar las sub-filas en cada fila.

const table = useReactTable({
// otras opciones...
getSubRows: (row) => row.children, // devuelve el array children como sub-filas
getCoreRowModel: getCoreRowModel(),
getExpandedRowModel: getExpandedRowModel(),
});

Nota: Puedes tener una función getSubRows complicada, pero ten en cuenta que se ejecutará para cada fila y cada sub-fila. Esto puede ser costoso si la función no está optimizada. Las funciones asíncronas no son compatibles.

UI de Expansión Personalizada

En algunos casos, es posible que desees mostrar detalles o información adicional, que puede o no ser parte de tu objeto de datos de la tabla, como datos expandidos para filas. Este tipo de interfaz de usuario de fila expandible ha recibido muchos nombres a lo largo de los años, incluyendo "filas expandibles", "paneles de detalles", "subcomponentes", etc.

Por defecto, la API de instancia de fila row.getCanExpand() devolverá false a menos que encuentre subRows en una fila. Esto puede ser anulado implementando tu propia función getRowCanExpand en las opciones de la instancia de la tabla.

//...
const table = useReactTable({
// otras opciones...
getRowCanExpand: (row) => true, // Añade tu lógica para determinar si una fila puede expandirse. True significa que todas las filas incluyen datos expandidos
getCoreRowModel: getCoreRowModel(),
getExpandedRowModel: getExpandedRowModel(),
})
//...
<tbody>
{table.getRowModel().rows.map((row) => (
<React.Fragment key={row.id}>
{/* UI de fila normal */}
<tr>
{row.getVisibleCells().map((cell) => (
<td key={cell.id}>
<FlexRender
render={cell.column.columnDef.cell}
props={cell.getContext()}
/>
</td>
))}
</tr>
{/* Si la fila está expandida, renderiza la UI expandida como una fila separada con una sola celda que abarca el ancho de la tabla */}
{row.getIsExpanded() && (
<tr>
<td colSpan={row.getAllCells().length}> // El número de columnas que deseas abarcar para los datos expandidos si no es una fila que comparte las mismas columnas que la fila principal
// Tu UI personalizada va aquí
</td>
</tr>
)}
</React.Fragment>
))}
</tbody>
//...

Estado de filas expandidas

Si necesitas controlar el estado expandido de las filas en tu tabla, puedes hacerlo utilizando el estado expanded y la opción onExpandedChange. Esto te permite gestionar el estado expandido según tus requisitos.

const [expanded, setExpanded] = useState<ExpandedState>({});

const table = useReactTable({
// otras opciones...
state: {
expanded: expanded, // debe pasar el estado expandido de vuelta a la tabla
},
onExpandedChange: setExpanded,
});

El tipo ExpandedState se define de la siguiente manera:

type ExpandedState = true | Record<string, boolean>;

Si ExpandedState es true, significa que todas las filas están expandidas. Si es un registro, solo las filas con IDs presentes como claves en el registro y que tienen su valor establecido en true están expandidas. Por ejemplo, si el estado expandido es { row1: true, row2: false }, significa que la fila con ID row1 está expandida y la fila con ID row2 no lo está. Este estado es utilizado por la tabla para determinar qué filas están expandidas y deben mostrar sus subRows, si las hay.

Manejador de alternancia de UI para filas expandidas

TanStack table no añadirá una UI de manejador de alternancia para datos expandidos a tu tabla. Debes añadirlo manualmente dentro de la UI de cada fila para permitir a los usuarios expandir y colapsar la fila. Por ejemplo, puedes añadir una UI de botón dentro de la definición de columnas.

const columns = [
{
accessorKey: 'name',
header: 'Name',
},
{
accessorKey: 'age',
header: 'Age',
},
{
header: 'Children',
cell: ({ row }) => {
return row.getCanExpand() ?
<button
onClick={row.getToggleExpandedHandler()}
style={{ cursor: 'pointer' }}
>
{row.getIsExpanded() ? '👇' : '👉'}
</button>
: '';
},
},
]

Filtrado de Filas Expandidas

Por defecto, el proceso de filtrado comienza desde las filas principales y se mueve hacia abajo. Esto significa que si una fila principal es excluida por el filtro, todas sus filas secundarias también serán excluidas. Sin embargo, puedes cambiar este comportamiento utilizando la opción filterFromLeafRows. Cuando esta opción está habilitada, el proceso de filtrado comienza desde las filas hoja (secundarias) y se mueve hacia arriba. Esto asegura que una fila principal se incluirá en los resultados filtrados siempre y cuando al menos una de sus filas secundarias o nietas cumpla con los criterios del filtro. Además, puedes controlar la profundidad en la jerarquía de las filas secundarias que el proceso de filtrado abarca utilizando la opción maxLeafRowFilterDepth. Esta opción te permite especificar la profundidad máxima de las filas secundarias que el filtro debe considerar.

//...
const table = useReactTable({
// otras opciones...
getSubRows: (row) => row.subRows,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getExpandedRowModel: getExpandedRowModel(),
filterFromLeafRows: true, // busca a través de las filas expandidas
maxLeafRowFilterDepth: 1, // limita la profundidad de las filas expandidas que se buscan
});

Paginación de Filas Expandidas

Por defecto, las filas expandidas se paginan junto con el resto de la tabla (lo que significa que las filas expandidas pueden extenderse a varias páginas). Si deseas deshabilitar este comportamiento (lo que significa que las filas expandidas siempre se renderizarán en la página de sus padres. Esto también significa que se renderizarán más filas que el tamaño de página establecido), puedes usar la opción paginateExpandedRows.

const table = useReactTable({
// otras opciones...
paginateExpandedRows: false,
});

Fijación de Filas Expandidas

La fijación de filas expandidas funciona de la misma manera que la fijación de filas regulares. Puedes fijar filas expandidas en la parte superior o inferior de la tabla. Consulta la Guía de Fijación para obtener más información sobre la fijación de filas.

Ordenación de Filas Expandidas

Por defecto, las filas expandidas se ordenan junto con el resto de la tabla.

Expansión Manual (lado del servidor)

Si estás realizando una expansión del lado del servidor, puedes habilitar la expansión manual de filas estableciendo la opción manualExpanding en true. Esto significa que getExpandedRowModel no se utilizará para expandir filas y se esperaría que realices la expansión en tu propio modelo de datos.

const table = useReactTable({
// otras opciones...
manualExpanding: true,
});