Datatable
UiDatatable renders rows from an items array against an explicit columns definition. Each column's key is the data field, the sort key, and the cell-<key> slot name; label is the header text.
Add a datatable
<script setup lang="ts">
import type { IDatatableColumn } from '@colorffy/ui'
const columns: IDatatableColumn[] = [
{ key: 'name', label: 'Name' },
{ key: 'email', label: 'Email' },
{ key: 'total', label: 'Total', align: 'end' },
]
const items = [
{ name: 'John Doe', email: 'john@example.com', total: 1280 },
{ name: 'Jane Smith', email: 'jane@example.com', total: 940 },
]
</script>
<template>
<UiDatatable
:columns="columns"
:items="items"
default-sort-key="name"
table-class="table-bordered"
/>
</template>
Customize a cell
The cell slot name is cell-<key>:
<template>
<UiDatatable :columns="columns" :items="items">
<template #cell-total="{ item }">
<strong>${{ item.total }}</strong>
</template>
</UiDatatable>
</template>
Hide, align, and manage columns
Mark a column hidden to start it collapsed, then enable column-manager so users can toggle it:
<script setup lang="ts">
import type { IDatatableColumn } from '@colorffy/ui'
const columns: IDatatableColumn[] = [
{ key: 'id', label: 'ID', hidden: true },
{ key: 'name', label: 'Name' },
{ key: 'actions', label: 'Actions', sortable: false, align: 'end' },
]
</script>
<template>
<UiDatatable :columns="columns" :items="items" column-manager>
<template #cell-actions="{ item }">
<UiButton variant="outline" size="sm" :text="`Edit ${item.name}`" />
</template>
</UiDatatable>
</template>
Select rows
Set selectable and bind v-model:selected to an array of row identities. A row's identity is the same value used for its :key — rowKey if set, else the row's id, else its array index (see Props). The header checkbox selects/clears every currently sorted row and shows an indeterminate state when only some are selected; selection stays attached to the row across sorting as long as rows have a stable id (or rowKey).
<script setup lang="ts">
import { ref } from 'vue'
const selected = ref<(string | number)[]>([])
</script>
<template>
<UiDatatable
:columns="columns"
:items="items"
selectable
v-model:selected="selected"
/>
</template>
Stick the header while scrolling
Set stickyHeader to keep the header visible while the body scrolls. It automatically wraps the table in a bounded, vertically-scrollable container (.table-responsive-sticky); override its height with the --_table-sticky-max-height CSS variable (default 32rem):
<template>
<UiDatatable
:columns="columns"
:items="items"
sticky-header
style="--_table-sticky-max-height: 20rem"
/>
</template>
Show loading and empty states
<template>
<!-- Skeleton rows while data loads -->
<UiDatatable :columns="columns" :items="[]" :is-loading="true" :skeleton-rows="6" />
<!-- Built-in empty state -->
<UiDatatable
:columns="columns"
:items="[]"
empty-state-title="No customers yet"
empty-state-subtitle="New customers will appear here."
/>
</template>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
columns | IDatatableColumn[] | — | Column definitions (required). |
items | Record<string, any>[] | — | Row data (required). |
rowKey | string | id → index | Stable key field for rows; also the row-selection identity. |
selectable | boolean | false | Show a leading checkbox column. Pair with v-model:selected. |
selected | (string | number)[] | [] | Selected row identities. Bind with v-model:selected. |
stickyHeader | boolean | false | Stick the header while the body scrolls (wraps in .table-responsive-sticky). |
sortable | boolean | true | Enable sorting (per-column opt-out via column.sortable). |
defaultSortKey | string | '' | Column key to sort by initially. |
defaultSortOrder | 'asc' | 'desc' | 'asc' | Initial sort direction. |
columnManager | boolean | false | Show the show / hide column menu. |
tableClass | 'table-bordered' | 'table-striped' | 'table-borderless' | string | '' | Table style. |
isLoading | boolean | false | Show skeleton rows. |
skeletonRows / skeletonCols | number | 10 / 5 | Skeleton dimensions. |
caption | string | — | Accessible <caption>. |
emptyStateTitle | string | 'No data available' | Empty-state title. |
emptyStateSubtitle | string | … | Empty-state subtitle. |
Column (IDatatableColumn): key, label, sortable?, hidden?, align? (start / center / end), thClass?, tdClass?.
Slots: cell-<key> per column.