Modules

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 });
The module ships its own scoped stylesheet automatically; you never import any CSS by hand.

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.

PropertyTypeDefaultDescription
accessorKeystring—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.
idstringaccessorKeyExplicit column id. Required for columns with no accessorKey (action or checkbox columns); otherwise defaults to the accessorKey.
headerstring | (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.
typestring'string'Value type — string, number, date, boolean or html. Drives default alignment, formatting and the inferred filter type.
enableSortingbooleantrueWhether the column can be sorted. Alias of sortable. Set false on action / checkbox columns.
enableHidingbooleantrueWhether the column appears in the column-visibility menu and can be toggled off.
enableColumnFilterbooleantrueWhether the column shows a filter control. Alias of filterable.
filterTypestring—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 / maxSizenumber—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.
alignstring—Text alignment — left, center or right. Defaults from the column type.
metaobject—Arbitrary data you can read back inside header / cell callbacks.
accessorKey and field are interchangeable, as are header (string) and title, and cell and formatter. Use whichever vocabulary you prefer; mixing them across columns is fine.

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:

HelperDescription
row.getValue('field')Read a column's value in the current row.
row.originalThe 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.
The same helpers are available outside the callbacks via table.getTableApi(), for building custom toolbars or controls.

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 }] },
});
With multiSort enabled, Shift-click headers to sort by several columns; a small badge shows each column's sort priority.

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.

NameDescription
textSubstring match (case-insensitive by default).
numberExact value, or a min / max range.
numberrangeTwo inputs bounding a numeric range.
selectSingle-choice dropdown of the column's distinct values.
multiselectMulti-select dropdown — rows matching any selected value pass.
facetedFaceted multi-select popover with a count badge.
booleanTrue / False / All dropdown.
dateSingle date match.
daterangeFrom / 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
  ],
});
The faceted type renders a multi-select popover, building its options from the data automatically.

Pagination

Pagination is on by default. Configure the page size, the offered sizes, and which controls render.

PropertyTypeDefaultDescription
enabledbooleantrueTurn pagination on or off. When off, all rows render (with virtual scrolling above the threshold).
pageSizenumber25Rows per page.
pageSizesnumber[][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.
showPageSizeSelectorbooleantrueShow the rows-per-page dropdown.
showPageInfobooleantrueShow the 'Showing 1–10 of 42' summary.
showFirstLastbooleantrueShow 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
});
PropertyTypeDefaultDescription
mode'none' | 'single' | 'multi''none''none', 'single' or 'multi'.
checkboxbooleanfalseRender a checkbox column (and a header select-all checkbox in multi mode).
selectAllbooleantrueAllow the header checkbox to select every row on the page.
preserveOnFilterbooleanfalseKeep 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.

VariableDescription
--kdt-bgTable background. Set to transparent to blend into the page.
--kdt-popover-bgBackground for dropdowns / faceted menus — kept opaque even when the table background is transparent.
--kdt-fgDefault text color.
--kdt-mutedSubtle surface (header, group rows, badges).
--kdt-muted-fgSecondary / header / placeholder text color.
--kdt-borderBorder and divider color.
--kdt-accentHover / active surface for rows, buttons and menu items.
--kdt-primaryPrimary accent — selected checkboxes, active pagination button.
--kdt-radiusCorner radius for the container, inputs, buttons and menus.
--kdt-row-heightBody row height (also set via density).
--kdt-font-familyFont 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).

The style object also accepts high-level shortcuts (borderColor, accentColor, radius, fontFamily, alternateRowColor, hoverRowColor …) which are translated to the matching CSS variables for you.

Events

Subscribe through the events option (or the .on(name, handler) method) to react to user interaction.

EventDescription
rowClickA row was clicked — payload: row, rowIndex, originalEvent.
cellClickA cell was clicked — payload: value, row, column, rowIndex, colIndex.
selectionChangeSelection changed — payload: selected, added, removed.
sortChangeSort changed — payload: column, direction, multiSort.
filterChangeA filter changed — payload: column, value, allFilters.
pageChangePage changed — payload: page, pageSize, totalPages.
cellEditA 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:

LocaleDescription
enEnglish (base / fallback).
pt-BRPortuguese (Brazil).
esSpanish.
zhSimplified Chinese.
An unknown or partially matched locale (for example pt-PT) falls back by primary language first, then to English.

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 redraw

Add 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' });
Pagination arrows (« » ‹ ›) are language-neutral and aren't translated; override them through lang if you need different symbols.

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.

OptionTypeDescription
dataany[]The row array. Replaceable later with setData().
columnsColumnDefinition[]Column definitions. Inferred from the data when omitted.
rowKeystringField used as a stable row identity.
sortingobjectSorting behaviour — enabled, multiSort, defaultSort.
filteringobjectPer-column filtering — enabled, position, showReset.
searchobjectGlobal search box — enabled, placeholder, columns, debounceMs.
paginationobjectPagination — see the pagination table above.
selectionobjectRow selection — see the selection table above.
columnVisibilityobjectColumn-visibility toolbar menu — enabled.
columnPinningobjectColumn pinning — enabled.
columnResizingobjectColumn resizing — enabled (default true).
columnReorderingobjectDrag-to-reorder columns — enabled.
groupingobjectRow grouping by one or more columns with aggregates.
virtualScrollobjectVirtualised rendering for large datasets — enabled, rowHeight, threshold.
exportingobjectCSV / JSON / clipboard export and the Export toolbar menu — enabled, formats.
serverSideobjectServer-side data, sorting, filtering and pagination via a URL.
toolbarobjectToolbar — enabled and which items show (search, columnToggle, export, density…).
styleobjectVisual style — density, theme, colors and the CSS-variable shortcuts.
classNamesobjectPer-part class hooks.
initialStateobjectConvenient starting state — pageSize, sorting, columnVisibility, columnFilters.
eventsobjectEvent handlers.
localestringLocale code for the built-in strings (omitted or 'auto' auto-detects from the browser, any other value pins it).
langobjectOverride UI strings (page info, no-data, button labels…).

Programmatic API

The instance exposes methods to drive the grid from your own code.

MethodDescription
setDatasetData(rows) — replace all data; columns re-infer if not set.
getData / getSelectedRowsgetData() / getFilteredData() / getSelectedRows() — read current rows.
sort / clearSortsort(column, direction?) / clearSort() — control sorting.
setFilter / clearFiltersetFilter(column, value) / clearFilter(column?) — control filters.
search / clearSearchsearch(query) / clearSearch() — drive the global search.
goToPage / setPageSizegoToPage(n) / setPageSize(n) — control pagination.
showColumn / pinColumnshowColumn(field) / hideColumn(field) / pinColumn(field, dir) — manage columns.
selectRow / selectAllselectRow(i) / deselectRow(i) / selectAll() / deselectAll().
exportCSV / exportJSONexportCSV() / exportJSON() / copyToClipboard() — export data.
getTableApigetTableApi() — the table helpers object, for custom integrations.
update / redraw / destroyupdate(options) / redraw() / destroy() — update or tear down the grid.
These options are layered: enable a feature with its block, refine columns individually, and theme everything through CSS variables. Browse the live grid on the home page.