data
<tc-table>
Sortable, filterable, paginated data table with keyed rows and custom cell renderers.
import
"@ra9/tan-compose-kit/table"
Props
| Name | Type | Default | Description |
|---|---|---|---|
rows | Array<Record<string, unknown>> | [] | The data rows. Each row's `id` field is used as the stable key by default. |
columns | Array<{ key: string; label: string; sortable?: boolean; render?: (row) => string }> | [] | Column definitions. `render` returns raw HTML and is only available when columns are set as a JS property (functions don't survive JSON attributes). |
pageSize | number | 10 | How many rows to show per page. |
filterable | boolean | true | Show the search input above the table. |
emptyText | string | "No results." | Message shown when no rows match the filter. |
rowKey | string | "id" | Property name used as the stable row key. Identical IDs across renders reuse DOM nodes. |
Events
| Event | Detail | When |
|---|---|---|
tc-row-click | { row: object } | Fires when the user clicks a row. |
tc-sort-change | { key: string | null, direction: "asc" | "desc" | null } | Fires when the user clicks a sortable header. Cycles asc → desc → unsorted. |
CSS variables
| Variable | Default | Description |
|---|---|---|
--tc-table-surface | var(--tc-color-surface, #ffffff) | Table background. |
--tc-table-ink | var(--tc-color-ink, #14171f) | Cell text color. |
--tc-table-soft | var(--tc-color-ink-soft, #5a6072) | Header + pager text color. |
--tc-table-rule | var(--tc-color-rule, #ece5d3) | Border + row-divider color. |
--tc-table-head-bg | var(--tc-color-surface-alt, #faf8f3) | Header row background. |
--tc-table-row-hover | rgba(161, 105, 57, 0.05) | Row hover background. |
--tc-table-accent | var(--tc-color-accent, #a16939) | Sortable hover + focus color. |
--tc-table-radius | var(--tc-radius-lg, 10px) | Outer border-radius. |
--tc-table-font | var(--tc-font-sans, …) | Font family. |
Examples
Basic usage
Pass rows and columns as JSON. Each column needs a key matching a row property, plus a human label.
Sorting
Click a column header to sort ascending, click again for descending, click a third time to clear. Disable per column with sortable: false.
Filtering + pagination
The search input is shown when filterable is true (the default). It matches against every column's stringified value. Use pageSize to set the page count.
Hide the search input for small datasets:
Custom cell renderers
Set columns as a JS property to use the render function. It returns raw HTML — escape your own values.
Listening for clicks
Theming
Accessibility
aria-sorton each sortable header announces the current state to screen readers.- The search input has a
placeholderbut no visible label — consider wrapping in your own labelled region if you need stricter compliance. - Row clicks emit
tc-row-click; the row itself doesn't have arole="button", so wire up your own keyboard handler if the row needs to be activatable from the keyboard. - The pager buttons are real
<button>s — Tab-reachable and Enter-activatable.