# Data Tables Complete patterns for displaying and managing tabular data. ## Basic table ```vue ``` ## With search and filters (dashboard) ```vue ``` ## With row selection Row selection uses TanStack Table's `rowSelection` state — a `Record` keyed by row index. ```vue ``` Add a checkbox column using the `h` function. Use tri-state `modelValue` (`true`, `false`, or `'indeterminate'`) for the "select all" header: ```ts import { h } from 'vue' const UCheckbox = resolveComponent('UCheckbox') const columns: TableColumn[] = [{ id: 'select', header: ({ table }) => h(UCheckbox, { 'modelValue': table.getIsSomePageRowsSelected() ? 'indeterminate' : table.getIsAllPageRowsSelected(), 'onUpdate:modelValue': (value: boolean | 'indeterminate') => table.toggleAllPageRowsSelected(!!value), 'aria-label': 'Select all' }), cell: ({ row }) => h(UCheckbox, { 'modelValue': row.getIsSelected(), 'onUpdate:modelValue': (value: boolean | 'indeterminate') => row.toggleSelected(!!value), 'aria-label': 'Select row' }) }, // ... other columns ] ``` ## With pagination Use `v-model:pagination` on `UTable` with TanStack's `getPaginationRowModel`, then wire `UPagination` to the table API. `UPagination`'s `total` is total **items** (not pages) — it calculates page count from `total / items-per-page`. ```vue ``` ## With async data (Nuxt) Use `status === 'pending' || status === 'idle'` for loading state — `idle` covers the initial render before `useLazyFetch` starts. ```vue ``` For server-side pagination: ```vue ``` ## Tips - Table is built on [TanStack Table v8](https://tanstack.com/table/v8) — columns use `ColumnDef` format with `accessorKey`, `header`, `cell` - Use `#-cell` and `#-header` template slots to customize rendering with Vue templates - Alternatively, use the `h` function inside `header` and `cell` column properties for inline rendering - Row data in slots is accessed via `row.original` (not `row` directly) - Use `v-model:row-selection` for selection, `v-model:sorting` for sort state - Wrap tables in `UDashboardPanel` with `#header` toolbar for the dashboard pattern - For empty states, use the `#empty` slot