DataTable
An interactive data grid that ships as an optional module. Sorting, multi-type filtering, pagination, row selection, column management and a fully themeable, framework-free renderer — configured with plain column definitions.
Installation
The DataTable is a standalone module — it carries no chart dependencies and can be used on its own. Import the class and point it at a container element and a data array.
import { DataTable } from 'katucharts.js/datatable';
const table = new DataTable('#grid', { data: rows });Quick start
Pass your rows as data and describe each column. With no columns supplied, the grid infers them from the first row.
const rows = [
{ id: 'm5gr84i9', amount: 316, status: 'success', email: '[email protected]' },
{ id: '3u1reuv4', amount: 242, status: 'success', email: '[email protected]' },
{ id: 'derv1ws0', amount: 837, status: 'processing', email: '[email protected]' },
];
new DataTable('#grid', {
data: rows,
columns: [
{ accessorKey: 'status', header: 'Status' },
{ accessorKey: 'email', header: 'Email' },
{ accessorKey: 'amount', header: 'Amount', type: 'number' },
],
pagination: { pageSize: 10 },
filtering: { enabled: true },
});Columns
Each column is an object. Use accessorKey, header, cell, enableSorting and related properties — or KatuCharts' own field, title and formatter names, which are accepted as equivalents.
| Property | Type | Default | Description |
|---|---|---|---|
accessorKey | string | — | Key into each row object for this column's value. Alias of field. |
accessorFn | (row) => any | — | Derive the value from the whole row instead of a flat key, e.g. row => row.first + ' ' + row.last. |
id | string | accessorKey | Explicit column id. Required for columns with no accessorKey (action or checkbox columns); otherwise defaults to the accessorKey. |
header | string | (ctx) => Node | — | Header content. A string for a plain label, or a function receiving the column and table that returns markup or a DOM node. |
cell | (ctx) => string | Node | — | Custom cell renderer receiving row, column, getValue and table. Return an HTML string or a DOM node. Alias of formatter. |
type | string | 'string' | Value type — string, number, date, boolean or html. Drives default alignment, formatting and the inferred filter type. |
enableSorting | boolean | true | Whether the column can be sorted. Alias of sortable. Set false on action / checkbox columns. |
enableHiding | boolean | true | Whether the column appears in the column-visibility menu and can be toggled off. |
enableColumnFilter | boolean | true | Whether the column shows a filter control. Alias of filterable. |
filterType | string | — | Filter UI for the column — see Filtering. Inferred from type when omitted. |
filterFn | (row, id, val) => boolean | — | Custom predicate (row, columnId, filterValue) => boolean that overrides the built-in filter logic. |
size / minSize / maxSize | number | — | Column width in pixels (alias width). minSize / maxSize bound resizing. |
pinned | 'left' | 'right' | — | Pin the column to the 'left' or 'right' edge so it stays visible while scrolling. |
align | string | — | Text alignment — left, center or right. Defaults from the column type. |
meta | object | — | Arbitrary data you can read back inside header / cell callbacks. |
Cell & header rendering
Show anything you like in a cell or header. A column's cell function renders its content — return text, an HTML string or a DOM node — and a header function builds custom header markup, like a sortable button.
const usd = (n) => new Intl.NumberFormat('en-US',
{ style: 'currency', currency: 'USD' }).format(n);
columns: [
// function header with a sort button
{
accessorKey: 'email',
header: ({ column }) => {
const b = document.createElement('button');
b.textContent = 'Email';
b.onclick = () => column.toggleSorting();
return b;
},
},
// cell returning markup
{
accessorKey: 'amount',
header: () => '<div style="text-align:right">Amount</div>',
cell: ({ row }) =>
`<div style="text-align:right">${usd(row.getValue('amount'))}</div>`,
},
// an action / checkbox column has no accessorKey — give it an id
{ id: 'actions', cell: ({ row }) => renderMenu(row.original) },
]Each callback receives row, column and table values you can use to read data and drive the grid:
| Helper | Description |
|---|---|
row.getValue('field') | Read a column's value in the current row. |
row.original | The full, original row object. |
row.toggleSelected() | Select or clear the row. |
column.toggleSorting() | Sort the grid by this column. |
column.setFilterValue(value) | Filter this column by a value. |
table.nextPage() | Move to the next page (also previousPage()). |
table.toggleAllPageRowsSelected() | Select every row on the current page. |
Sorting
Sorting is on by default; click a header to cycle ascending → descending → unsorted. Disable it globally, enable multi-column sort, or set an initial sort.
new DataTable('#grid', {
data: rows,
sorting: {
enabled: true,
multiSort: true,
defaultSort: [{ column: 'amount', direction: 'desc' }],
},
});
// or set an initial state
new DataTable('#grid', {
data: rows,
initialState: { sorting: [{ id: 'amount', desc: true }] },
});Filtering
The grid offers a global search box plus a per-column filter row. Both can be switched on or off independently, and every column picks (or infers) one of several filter types.
Turn the whole filter row off with filtering.enabled = false, or hide a single column's filter with filterable: false (enableColumnFilter: false). A Reset filters button appears automatically while any filter is active.
| Name | Description |
|---|---|
text | Substring match (case-insensitive by default). |
number | Exact value, or a min / max range. |
numberrange | Two inputs bounding a numeric range. |
select | Single-choice dropdown of the column's distinct values. |
multiselect | Multi-select dropdown — rows matching any selected value pass. |
faceted | Faceted multi-select popover with a count badge. |
boolean | True / False / All dropdown. |
date | Single date match. |
daterange | From / to date bounds. |
Enable the global search box in the toolbar; it matches across all visible columns (or a chosen subset).
new DataTable('#grid', {
data: rows,
search: { enabled: true, placeholder: 'Search…' },
filtering: { enabled: true }, // per-column filter row
columns: [
{ accessorKey: 'email', header: 'Email' }, // text filter
{ accessorKey: 'status', header: 'Status', filterType: 'faceted' },
{ accessorKey: 'amount', header: 'Amount', type: 'number',
filterType: 'numberrange' },
{ accessorKey: 'id', header: 'ID', filterable: false }, // no filter
],
});Pagination
Pagination is on by default. Configure the page size, the offered sizes, and which controls render.
| Property | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Turn pagination on or off. When off, all rows render (with virtual scrolling above the threshold). |
pageSize | number | 25 | Rows per page. |
pageSizes | number[] | [10,25,50,100] | Sizes offered in the rows-per-page dropdown. |
position | 'top' | 'bottom' | 'both' | 'bottom' | Where the footer renders — top, bottom or both. |
showPageSizeSelector | boolean | true | Show the rows-per-page dropdown. |
showPageInfo | boolean | true | Show the 'Showing 1–10 of 42' summary. |
showFirstLast | boolean | true | Show the jump-to-first / last buttons. |
Row selection
Enable single or multi-row selection, with optional checkboxes and a header select-all.
const table = new DataTable('#grid', {
data: rows,
selection: { mode: 'multi', checkbox: true },
});
table.on('selection:change', ({ selected }) => {
// do something with the selected rows
});| Property | Type | Default | Description |
|---|---|---|---|
mode | 'none' | 'single' | 'multi' | 'none' | 'none', 'single' or 'multi'. |
checkbox | boolean | false | Render a checkbox column (and a header select-all checkbox in multi mode). |
selectAll | boolean | true | Allow the header checkbox to select every row on the page. |
preserveOnFilter | boolean | false | Keep the current selection when filters change instead of clearing it. |
Column management
Beyond rendering, columns can be hidden, pinned, resized and reordered. Resizing is on by default; the others are opt-in.
- A Columns toolbar menu toggles each column on or off (respects enableHiding). Hide the button with columnVisibility.enabled = false.
- Pin columns left or right with pinned on the column, or columnPinning.enabled = true plus the pinColumn() method.
- Drag the right edge of a header to resize. Disable with columnResizing.enabled = false.
- Enable drag-to-reorder with columnReordering.enabled = true.
Theming & CSS
The whole visual layer is driven by --kdt-* CSS custom properties on a single class, so you can re-theme by setting one variable — no !important needed. Every part also carries a stable class name you can target directly.
Set any of these on .katucharts-datatable (or a wrapper) to retheme. The grid ships sensible light defaults and a built-in dark palette.
| Variable | Description |
|---|---|
--kdt-bg | Table background. Set to transparent to blend into the page. |
--kdt-popover-bg | Background for dropdowns / faceted menus — kept opaque even when the table background is transparent. |
--kdt-fg | Default text color. |
--kdt-muted | Subtle surface (header, group rows, badges). |
--kdt-muted-fg | Secondary / header / placeholder text color. |
--kdt-border | Border and divider color. |
--kdt-accent | Hover / active surface for rows, buttons and menu items. |
--kdt-primary | Primary accent — selected checkboxes, active pagination button. |
--kdt-radius | Corner radius for the container, inputs, buttons and menus. |
--kdt-row-height | Body row height (also set via density). |
--kdt-font-family | Font family for the whole grid. |
/* Re-theme by setting variables on a wrapper — no !important */
.my-grid .katucharts-datatable {
--kdt-primary: #b43417;
--kdt-radius: ;
--kdt-accent: #fbeae5;
}Theming & CSS · classNames
Prefer attaching your own classes? Pass a classNames object to hook any part — root, toolbar, table, header, row, cell, footer and pagination.
new DataTable('#grid', {
data: rows,
classNames: { root: 'my-grid', row: 'my-row', cell: 'my-cell' },
style: { theme: 'dark', density: 'compact', radius: 12 },
});density: 'compact' | 'normal' | 'comfortable' adjusts row height and padding. A 'Density' toolbar item lets users switch it live.
Flip the whole grid to dark with style.theme = 'dark' (or set data-theme="dark" on the root).
Events
Subscribe through the events option (or the .on(name, handler) method) to react to user interaction.
| Event | Description |
|---|---|
rowClick | A row was clicked — payload: row, rowIndex, originalEvent. |
cellClick | A cell was clicked — payload: value, row, column, rowIndex, colIndex. |
selectionChange | Selection changed — payload: selected, added, removed. |
sortChange | Sort changed — payload: column, direction, multiSort. |
filterChange | A filter changed — payload: column, value, allFilters. |
pageChange | Page changed — payload: page, pageSize, totalPages. |
cellEdit | A cell was edited — payload: row, column, oldValue, newValue. |
Localization
Built-in UI strings — search and filter placeholders, pagination, the export and density menus, column controls — ship in several languages. You can pick a language explicitly, let the grid follow the browser, or override individual strings.
By default the grid auto-detects the language from the browser and falls back to English when there's no match. Set locale to pin a language; once set it never changes on its own.
// Auto-detect from the browser language (default)
new DataTable('#grid', { data: rows });
// Pin a locale — stays fixed regardless of the browser
new DataTable('#grid', { data: rows, locale: 'pt-BR' });Locales included out of the box:
| Locale | Description |
|---|---|
en | English (base / fallback). |
pt-BR | Portuguese (Brazil). |
es | Spanish. |
zh | Simplified Chinese. |
Overriding individual strings
Pass lang to override any string for the active locale. Per-key overrides always win over the locale pack, so you can pin a locale and still customize a label or two.
new DataTable('#grid', {
data: rows,
locale: 'pt-BR',
lang: { search: 'Procurar produtos…' }, // wins over the locale pack
});Switch language at runtime with setLocale — the grid re-renders and keeps any lang overrides.
const table = new DataTable('#grid', { data: rows });
table.setLocale('es'); // switch language and redrawAdd your own language with registerLocale before creating the grid; omitted strings fall back to English.
import { DataTable, registerLocale } from 'katucharts.js/datatable';
registerLocale('fr', { search: 'Rechercher…', noData: 'Aucune donnée' });
new DataTable('#grid', { data: rows, locale: 'fr' });Options reference
Top-level options passed to new DataTable(container, options). Feature blocks are objects so you can enable and configure each in one place.
| Option | Type | Description |
|---|---|---|
data | any[] | The row array. Replaceable later with setData(). |
columns | ColumnDefinition[] | Column definitions. Inferred from the data when omitted. |
rowKey | string | Field used as a stable row identity. |
sorting | object | Sorting behaviour — enabled, multiSort, defaultSort. |
filtering | object | Per-column filtering — enabled, position, showReset. |
search | object | Global search box — enabled, placeholder, columns, debounceMs. |
pagination | object | Pagination — see the pagination table above. |
selection | object | Row selection — see the selection table above. |
columnVisibility | object | Column-visibility toolbar menu — enabled. |
columnPinning | object | Column pinning — enabled. |
columnResizing | object | Column resizing — enabled (default true). |
columnReordering | object | Drag-to-reorder columns — enabled. |
grouping | object | Row grouping by one or more columns with aggregates. |
virtualScroll | object | Virtualised rendering for large datasets — enabled, rowHeight, threshold. |
exporting | object | CSV / JSON / clipboard export and the Export toolbar menu — enabled, formats. |
serverSide | object | Server-side data, sorting, filtering and pagination via a URL. |
toolbar | object | Toolbar — enabled and which items show (search, columnToggle, export, density…). |
style | object | Visual style — density, theme, colors and the CSS-variable shortcuts. |
classNames | object | Per-part class hooks. |
initialState | object | Convenient starting state — pageSize, sorting, columnVisibility, columnFilters. |
events | object | Event handlers. |
locale | string | Locale code for the built-in strings (omitted or 'auto' auto-detects from the browser, any other value pins it). |
lang | object | Override UI strings (page info, no-data, button labels…). |
Programmatic API
The instance exposes methods to drive the grid from your own code.
| Method | Description |
|---|---|
setData | setData(rows) — replace all data; columns re-infer if not set. |
getData / getSelectedRows | getData() / getFilteredData() / getSelectedRows() — read current rows. |
sort / clearSort | sort(column, direction?) / clearSort() — control sorting. |
setFilter / clearFilter | setFilter(column, value) / clearFilter(column?) — control filters. |
search / clearSearch | search(query) / clearSearch() — drive the global search. |
goToPage / setPageSize | goToPage(n) / setPageSize(n) — control pagination. |
showColumn / pinColumn | showColumn(field) / hideColumn(field) / pinColumn(field, dir) — manage columns. |
selectRow / selectAll | selectRow(i) / deselectRow(i) / selectAll() / deselectAll(). |
exportCSV / exportJSON | exportCSV() / exportJSON() / copyToClipboard() — export data. |
getTableApi | getTableApi() — the table helpers object, for custom integrations. |
update / redraw / destroy | update(options) / redraw() / destroy() — update or tear down the grid. |