Todos los componentes (204)
Tabla
Datos · Table · .amset-table
Qué es y cuándo usarlo
Datos que se comparan por columnas (facturas, pedidos, clientes), con orden, filtros por columna, selección, paginación, columnas configurables y totales al pie.
Cuándo usarlo
- Listados de gestión en los que se busca, se ordena y se actúa sobre filas.
- Ordena, filtra, selecciona y pagina sola. Los callbacks (
onSort,onFilter,onSelectionChange,onVisibleColumnsChange,pagination.onPageChange) solo avisan: cada parte la controla quien la usa solo si le pasa también su valor (sort,filters,selectedKeys,visibleColumns,pagination.page). Estas fichas le pasan todos los callbacks y la tabla sigue funcionando sola. - Con
serverSide(o conpagination.total) no ordena ni filtra en local: pinta las filas tal como llegan, y quien la usa pide al servidor lo que dicen los avisos. selection="multiple"conselectionActionspara acciones en masa;footeren una columna para sumar lo que queda tras filtrar.renderExpandedRowconvierte cada fila en desplegable, con su detalle a todo el ancho debajo;maxHeightfija el alto y deja quietas la cabecera y el pie.- Sin paginación y dentro de un contenedor con
data-density="compact"en un cuadro de mando: la densidad es global, no una prop.
Cuándo no
- Los datos de una sola cosa, etiqueta y valor:
DataList. - Miles de filas que se recorren seguidas, sin columnas:
VirtualList. - Una comparativa de planes o precios:
PricingTable. - Una hoja de cálculo completa (fórmulas, selección de rangos, pegado masivo): la edición de aquí es celda a celda.
Más allá de lo básico
groupByagrupa por una columna, con una cabecera plegable por grupo (initialCollapsedGroups,renderGroupLabel).advancedFiltersañade un panel de condiciones «columna · operador · valor» unidas por «y» o por «o» (texto, números, fechas y sí/no, con «entre» y «está vacío»);advancedFilterlo controla desde fuera.exportCsvbaja a CSV todas las filas filtradas y ordenadas en las columnas visibles (con BOM para Excel, el separador del idioma y los textos que parecen fórmula neutralizados).exportable: falsedeja fuera una columna.persistKeyrecuerda columnas visibles, orden y anchos en el navegador; el panel de columnas ofrece «Restablecer».editoren una columna +onCellEditen la tabla: Intro, F2 o doble clic abren la celda; Intro guarda, Escape cancela, salir guarda. SionCellEditfalla, el campo sigue abierto con el error. La tabla no cambiarows: quien la usa actualiza sus datos.virtualized+maxHeightpinta solo las filas que se ven, para miles de filas (Inicio, Fin y las páginas saltan aunque la fila no esté pintada). No se combina conrenderExpandedRow.
Teclado: la tabla es una sola parada de Tab. Arriba y abajo van de fila en fila, conservando la columna; la flecha derecha entra en las celdas (al control que tengan dentro, como la casilla de selección, que se marca con Espacio) y la izquierda vuelve a la fila. Inicio y Fin van a la primera y a la última fila. Pulsar la cabecera de una columna sortable ordena (con el foco en ella, también Intro o Espacio): ascendente, descendente y sin orden. El embudo de la cabecera abre el filtro (en el de texto, Intro filtra) y «Columnas» abre un panel con casillas y botones de subir y bajar, sin arrastrar nada.
Accesibilidad: es un <table> de verdad con papel de rejilla (role="grid"), nombre obligatorio (label), cabeceras con aria-sort y, con rowHeader, la columna que nombra cada fila. Con el filtro puesto, el botón cambia de nombre («Filtro de Cliente (activo)») y de forma, no solo de color: el embudo se rellena, igual que el orden activo apaga una de sus dos flechas. Los dos son cajas iguales de 22 px junto al título. La barra de selección («3 filas seleccionadas») y el recuento de páginas van en role="status". Mientras carga (loading) lleva aria-busy y, si aún no hay filas, dice «Cargando…».
Aspecto fino: variables CSS --amset-table-*: -cell, -column, -font, -padding-row, -radius, -row. El tamaño mueve el relleno de la celda y el cuerpo de letra. El de arriba y abajo lo manda la densidad (data-density) cuando la hay.
Cómo se ve
| Pedido | Cliente | Estado | Total |
|---|---|---|---|
| 1041 | Aitor Etxeberria | Enviado | 1249,00 € |
| 1039 | Javier Ortega | Enviado | 420,00 € |
| 1043 | Pablo Gil | Entregado | 315,50 € |
| 1038 | Lucía Martín | Entregado | 189,00 € |
| 1042 | Nerea Sánchez | Pendiente | 89,00 € |
<Table
label="Pedidos de octubre"
columns={[
{ key: 'id', title: 'Pedido', rowHeader: true },
{ key: 'cliente', title: 'Cliente', sortable: true, filterable: 'text' },
{ key: 'estado', title: 'Estado', filterable: 'list' },
{ key: 'total', title: 'Total', numeric: true, sortable: true },
]}
rows={pedidos}
rowKey={(pedido) => pedido.id}
initialSort={{ column: 'total', direction: 'desc' }}
pagination={{ size: 5, sizes: [5, 10] }}
/>Props
Se importa con import { Table } from '@amset/ui'. Las obligatorias van marcadas.
| Prop | Tipo | Para qué sirve |
|---|---|---|
columnsobligatoria | readonly TableColumn<T>[] | — |
labelobligatoria | string | Lo que se anuncia al entrar en la tabla. Obligatorio: sin esto es "tabla" a secas. |
rowKeyobligatoria | (row: T) => string | — |
rowsobligatoria | readonly T[] | — |
advancedFilter | AdvancedFilter | El filtro avanzado, controlado desde fuera. Sin el, lo lleva la tabla. |
advancedFilters | boolean | Añade el panel de filtros con varias condiciones unidas por «y» / «o». |
className | string | Se une a las clases de la biblioteca, no las sustituye. |
configurableColumns | boolean | Añade el panel para mostrar, ocultar y reordenar columnas. |
emptyMessage | string | — |
expandedKeys | readonly string[] | Filas desplegadas (por su clave), controladas desde fuera. Sin ellas, las lleva la tabla. |
exportCsv | boolean | TableExportOptions | Añade un boton que baja a CSV lo que se ve en las columnas visibles: todas las filas ya filtradas y ordenadas, no solo la pagina. Con `serverSide` solo exporta las filas cargadas. |
filters | Readonly<Record<string, string | readonly string[]>> | Filtros controlados desde fuera. Sin ellos, los lleva la tabla. |
groupBy | string | Agrupa las filas por el valor de esta columna, con una fila de cabecera por grupo que se pliega. |
initialCollapsedGroups | readonly string[] | Grupos plegados al empezar (por el valor de su clave). |
initialExpandedKeys | readonly string[] | Las filas desplegadas al empezar, sin controlarlas desde fuera. |
initialSort | TableSort | null | — |
loading | boolean | — |
maxHeight | string | Alto maximo de la tabla (`'24rem'`, `'60vh'`): pasado, el cuerpo se desplaza y la cabecera y el pie se quedan fijos. Es la variable `--amset-table-height` hecha prop. |
onAdvancedFilterChange | (filter: AdvancedFilter) => void | Avisa del filtro avanzado nuevo. Solo avisa: no controla nada. |
onCellEdit | (edit: CellEdit<T>) => void | Promise<void> | Guarda lo editado en una celda con `editor`. Se abre con Intro, F2 o doble clic y se cierra con Intro (guarda), Escape (cancela) o saliendo del campo (guarda). Puede ser asincrona: si lanza, el campo sigue abierto con el error. La tabla NO cambia `rows`: quien la usa actualiza sus datos. |
onExpandedChange | (keys: readonly string[]) => void | Avisa con las claves desplegadas. Solo avisa: no controla ni apaga nada. |
onFilter | (filters: TableFilters) => void | Avisa de los filtros nuevos. Solo avisa: no controla ni apaga nada. |
onRowPress | (row: T) => void | Avisa de la fila pulsada. Desplegar el detalle no cuenta. |
onSelectionChange | (keys: readonly string[]) => void | Avisa con las claves seleccionadas. Solo avisa: no controla nada. |
onSort | (sort: TableSort | null) => void | Avisa del orden nuevo, o `null` al quitarlo. Solo avisa: no controla ni apaga nada. |
onVisibleColumnsChange | (keys: readonly string[]) => void | Avisa con las columnas visibles, en su orden. Solo avisa: no controla nada. |
pagination | false | TablePagination | — |
persistKey | string | Recuerda entre visitas que columnas se ven, en que orden y con que ancho, en el navegador, bajo esta clave. Con `visibleColumns` controlado no recuerda las visibles. |
renderExpandedRow | (row: T) => ReactNode | Convierte cada fila en desplegable y pinta aqui su detalle: un pedido con sus lineas, un cliente con su historial. Cada fila gana un boton con `aria-expanded` al principio y el detalle sale en una fila debajo, de ancho completo. Quien no tiene nada que desplegar se marca con `rowExpandable`. |
renderGroupLabel | (value: CellValue, rows: readonly T[]) => ReactNode | Lo que dice la cabecera de un grupo. Por defecto, el valor y el recuento. |
resizableColumns | boolean | Se puede arrastrar el borde de cada cabecera para cambiar el ancho de la columna. |
rowClassName | (row: T, index: number) => string | undefined | Una clase para marcar una fila concreta -una factura vencida en rojo- sin tocar el CSS global. Se SUMA a las de la tabla. `index` es la posicion en la pagina que se ve. |
rowExpandable | (row: T) => boolean | Que filas se pueden desplegar. Por defecto, todas. |
selectedKeys | readonly string[] | Claves seleccionadas, controladas desde fuera. Sin ellas, las lleva la tabla. |
selection | SelectionMode | — |
selectionActions | (keys: readonly string[]) => ReactNode | Barra que aparece cuando hay filas seleccionadas. |
serverSide | boolean | Ordenar y filtrar lo hace el servidor: la tabla pinta `rows` tal como llegan y solo avisa con `onSort` y `onFilter`. Con `pagination.total` es asi sin pedirlo, porque ordenar en local una sola pagina no tiene sentido. |
size | "sm" | "md" | "lg" | El tamaño de la tabla: mueve el relleno de las celdas y el cuerpo de letra. No confundir con `pagination.size`, que son las filas por pagina. |
sort | TableSort | null | Orden controlado desde fuera. Sin el, lo lleva la tabla empezando en `initialSort`. |
toolbar | ReactNode | Contenido propio en la barra de arriba (buscador, botón de exportar...). |
virtualized | boolean | TableVirtualization | Pinta solo las filas que se ven, para miles de filas. Necesita `maxHeight` (sin alto no hay desplazamiento) y no se combina con `renderExpandedRow`, cuyas filas miden distinto. |
visibleColumns | readonly string[] | Columnas visibles y su orden, controladas desde fuera. Sin ellas, las lleva la tabla. |
Acepta además los atributos del elemento que pinta: className, style, data-*, aria-* y sus eventos.
Mandos
Estas variables CSS son la forma de adaptarlo. Se declaran sobre el selector del componente, no en :root: la hoja las redeclara en la propia regla y una declaración en el mismo elemento gana siempre.
| Variable | Por defecto |
|---|---|
--amset-table-row | var(--amset-space-2) |
--amset-table-cell | var(--amset-space-3) |
--amset-table-font | var(--amset-text-base) |
--amset-table-column | var(--amset-text-sm) |
--amset-table-radius | var(--amset-radius-lg) |
Cómo se cambia
.amset-table {
--amset-table-row: ...;
--amset-table-cell: ...;
}En el banco de pruebas
Cada estado y cada variante, para tocarlos de uno en uno, en su ficha de ui.amset.tech:
