Data table
Comparar muchos elementos con varias columnas. Ordenar, filtrar, paginar y seleccionar filas.
Primitiva disponible en la biblioteca, sin uso directo en la app actual. Tabla con búsqueda, filtro, orden, selección y paginación, armada sobre Table.
Instalación
shadcn
npx shadcn@latest add https://design.moodinary.com/r/data-table.jsonimport
import { DataTable, type DataTableColumn } from "@moodinary/ui/components/data-table";Ejemplos
Completa
Ordená tocando el encabezado, filtrá por tipo y seleccioná para exportar.
Datos ilustrativos.
0 seleccionados
| 1.º A | Bien | 41 | |
| 2.º B | Neutral | 27 | |
| 3.º A | Bien | 33 | |
| 4.º A | Neutral | 6 | |
| 5.º B | Bien | 19 |
Código
teams.tsx
import {
DataTable,
type DataTableColumn,
} from "@moodinary/ui/components/data-table";
import { MoodWord } from "@moodinary/ui/components/mood-dot";
interface Team {
id: string;
kind: string;
mood: number;
name: string;
pulses: number;
}
const rows: Team[] = [
{ id: "1a", kind: "escuela", mood: 3.8, name: "1.º A", pulses: 41 },
{ id: "2b", kind: "escuela", mood: 3.1, name: "2.º B", pulses: 27 },
{ id: "3a", kind: "escuela", mood: 4.3, name: "3.º A", pulses: 33 },
{ id: "4a", kind: "escuela", mood: 2.7, name: "4.º A", pulses: 6 },
{ id: "5b", kind: "escuela", mood: 3.5, name: "5.º B", pulses: 19 },
{
id: "ventas",
kind: "empresa",
mood: 3.4,
name: "Equipo Ventas",
pulses: 22,
},
{
id: "soporte",
kind: "empresa",
mood: 2.9,
name: "Equipo Soporte",
pulses: 15,
},
{
id: "producto",
kind: "empresa",
mood: 4.0,
name: "Equipo Producto",
pulses: 12,
},
];
const level = (v: number) =>
Math.min(5, Math.max(1, Math.round(v))) as 1 | 2 | 3 | 4 | 5;
const columns: DataTableColumn<Team>[] = [
{ header: "Equipo", id: "name", sortable: true, value: (r) => r.name },
{
cell: (r) => <MoodWord level={level(r.mood)} />,
header: "Ánimo",
id: "mood",
sortable: true,
value: (r) => r.mood,
},
{
header: "Pulsos (7 días)",
id: "pulses",
sortable: true,
value: (r) => r.pulses,
},
];
export default function DataTableTeams() {
return (
<div className="w-full">
<p className="mb-2 text-ink-3 text-xs">Datos ilustrativos.</p>
<DataTable
bulkAction={{ label: "Exportar CSV", onAction: () => undefined }}
columns={columns}
defaultSort={{ column: "name", direction: "ascending" }}
filter={{
label: "Tipo",
options: [
{ label: "Escuela", value: "escuela" },
{ label: "Empresa", value: "empresa" },
],
value: (r) => r.kind,
}}
getRowId={(r) => r.id}
getRowLabel={(r) => r.name}
label="Equipos"
rows={rows}
searchPlaceholder="Filtrar equipos…"
searchText={(r) => r.name}
/>
</div>
);
}Sin resultados
Cuando no hay filas muestra un estado vacío.
| Equipo |
|---|
Ningún resultado coincideProbá con otro filtro. |
Código
empty.tsx
import { DataTable } from "@moodinary/ui/components/data-table";
export default function DataTableEmpty() {
return (
<div className="w-full">
<DataTable
columns={[
{
header: "Equipo",
id: "name",
value: (r: { id: string; name: string }) => r.name,
},
]}
getRowId={(r) => r.id}
getRowLabel={(r) => r.name}
label="Equipos sin resultados"
rows={[]}
searchText={(r) => r.name}
selectable={false}
/>
</div>
);
}Props
DataTable
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| label | string | - | Nombre de la tabla. |
| rows | Row[] | - | Filas. |
| columns | DataTableColumn<Row>[] | - | id, header, value, cell y sortable. |
| getRowId | (row) => string | - | Clave estable. |
| getRowLabel | (row) => string | - | Nombre para el checkbox. |
| searchText | (row) => string | - | Texto donde busca el filtro. |
| searchPlaceholder | string | "Filtrar…" | Placeholder del buscador. |
| pageSize | number | 5 | Filas por página. |
| defaultSort | { column, direction } | - | Orden inicial. |
| selectable | boolean | true | Muestra checkboxes. |
| filter | { label, options, value } | - | Filtro por una columna. |
| bulkAction | { label, onAction } | - | Acción sobre las seleccionadas. |
| emptyTitle | string | "Ningún resultado coincide" | Título vacío. |
| className | string | - | Clases extra. |
Cuándo sí y cuándo no
Hacé
- Ordená por la columna más útil.
- Mostrá cuántas filas hay seleccionadas.
- Usá estados vacíos con una salida.
Evitá
- No muestres datos de personas en un lugar anónimo.
- No pongas más de 6 columnas.
- No pagines tablas cortas.
Accesibilidad
- Los encabezados ordenables son botones con
aria-sort. - Cada checkbox nombra su fila.