Tabla semántica con columnas tipadas: fechas e importes formateados por idioma (importes en céntimos, alineados al final), celdas a medida y scroll horizontal accesible con teclado. Las filas alternan color por defecto; striped en false lo desactiva.
<FltTable :columns="columns" :rows="rows" row-key="id" caption="Últimos movimientos">
<template #cell-status="{ value }">
<FltTag :variant="statusVariant[value]" size="sm">{{ value }}</FltTag>
</template>
</FltTable>
Selección
Casillas por fila y «seleccionar todas» con estado intermedio. La selección va por clave de fila, así que sobrevive al reordenar: ordena con algo marcado y compruébalo.
editable añade un botón Editar por fila: sus celdas con editor pasan a campos (texto, importe, fecha u opciones) y la tabla se bloquea hasta Guardar o Cancelar (Escape cancela). Al guardar se valida; si todo está bien, la tabla emite rowSave y espera a que el consumidor responda con filas nuevas o con rowErrors. Aquí el «servidor» tarda 0,7 s y rechaza importes de más de 10.000 €; los movimientos devueltos no se pueden editar.
Con cards, cuando el contenedor de la tabla baja de 36rem cada fila pasa a ser una tarjeta: título con rowLabelKey, valores con su etiqueta y acciones al pie; los totales quedan como tarjeta resumen. Aquí la tabla vive en un contenedor de 30rem, así que se ve en tarjetas también en escritorio. La semántica de tabla se mantiene para el lector de pantalla.
expandable añade un botón por fila que abre su detalle debajo (el rayado sigue contando solo las filas de datos). Las columnas con total: 'sum' cierran la tabla con una fila de totales sobre todo el conjunto filtrado, no solo la página; en modo servidor, totals los trae del backend.
<FltTable :columns="columns" :rows="rows" row-key="id" caption="Movimientos con detalle y total"
expandable paginated>
<template #expanded="{ row }">
<FltDescriptionList :items="detail(row)" />
</template>
</FltTable>
Columnas, columna fija y densidad
columnChooser añade un selector de columnas (una divulgación con casillas; Concepto no se puede ocultar y siempre queda al menos una). stickyFirstColumn deja fijas la casilla y la primera columna al desplazar en horizontal. La densidad es la prop size, aquí conectada a un FltSegmented.
<FltTable v-model:hidden-columns="hidden" :columns="columns" :rows="rows" :size="density"
row-key="id" caption="Movimientos con todas sus columnas" selectable paginated
column-chooser sticky-first-column>
<template #filters>
<FltSegmented v-model="density" :options="densityOptions" label="Densidad" size="sm" />
</template>
</FltTable>
Búsqueda y filtros
searchable añade un buscador que no distingue mayúsculas ni tildes («libreria» encuentra «Librería») y mira el texto tal como se ve. Los controles de filtro los pone el consumidor y la tabla aplica filters (texto, opciones o rango). Cada cambio vuelve a la primera página y el número de resultados se anuncia al lector de pantalla.
rowActions añade columnas finales con un botón por fila (Devolver se desactiva en abonos y en lo ya devuelto). Con acciones en bloque, la barra queda siempre visible y cuenta la selección, para que la tabla no salte al marcar.
Con paginated, la tabla trocea las filas en cliente: selector de filas por página, rango visible y controles de página. Cambiar el orden o el tamaño de página vuelve a la primera. «Seleccionar todas» actúa sobre la página visible.
Con grid, la tabla es una rejilla con un solo punto de tabulación: las flechas van de celda en celda, Inicio y Fin al principio y fin de la fila, Ctrl+Inicio y Ctrl+Fin a las esquinas, y RePág y AvPág saltan 5 filas sin cambiar de página. En una celda con un solo control (casilla, orden, enlace) el foco va directo a él. Las celdas con varios controles no están soportadas todavía.
En modo servidor (mode «server») la tabla no ordena ni trocea: emite queryChange con orden, página, tamaño, búsqueda y filtros, y pinta la página que recibe; la búsqueda espera a que dejes de teclear; totalRows da el total para el rango y los controles. Aquí el «servidor» tiene 245 movimientos y tarda 0,7 s, y mientras tanto la tabla muestra el estado de carga.
Mientras carga, filas de esqueleto y aria-busy; sin filas, un mensaje que ocupa todas las columnas.
Angular
Vue
Cargando movimientos
Estado
Movimientos de noviembre
Estado
No hay movimientos en este periodo.
<flt-table [columns]="columns" rowKey="id" caption="Cargando movimientos" loading />
<flt-table [columns]="columns" [rows]="[]" rowKey="id" caption="Movimientos de noviembre"
emptyText="No hay movimientos en este periodo." />
<FltTable :columns="columns" row-key="id" caption="Cargando movimientos" loading />
<FltTable :columns="columns" :rows="[]" row-key="id" caption="Movimientos de noviembre"
empty-text="No hay movimientos en este periodo." />