Columns configuration, types, order, and visibility
Columns Reference
Declare columns in columns.definitions, then control order and visibility via columns.order and columns.visible.
columns: {
definitions: [
{ id: 'name', type: 'text', header: 'Name', enableSorting: true, enableColumnFilter: true },
{
id: 'price',
type: 'number',
header: 'Price',
numberFormat: { thousandsSeparator: ' ', decimals: 0, suffix: ' €' },
},
{ id: 'status', type: 'tag', header: 'Status' },
{ id: 'createdAt', type: 'date', header: 'Created', dateDisplayPreset: 'dmy-numeric' },
{ id: 'isActive', type: 'boolean', header: 'Active' },
{ id: 'actions', type: 'actions', header: 'Actions' },
{ id: 'value', type: 'dynamicType', typeKey: 'valueType', header: 'Value' },
],
order: ['select', 'name', 'price', 'status', 'createdAt', 'actions'],
visible: ['select', 'name', 'price', 'status', 'createdAt', 'actions'],
mandatory: ['name'],
}Types
Supported column types:
textnumberbooleandatetagactionsdynamicType(renderer selected viatypeKey)select(row selection checkbox; virtual column)
Options per column
Common properties:
id: string– Unique identifierheader: string | React.ReactNodeenableSorting?: boolean(defaulttrue)enableColumnFilter?: boolean(defaulttrue)accessorKey?: string– Optional accessor if data key differs fromiddateDisplayPreset?: DateDisplayPreset– strict preset for date rendering (date columns only)dateFormat?: string– legacy date-fns format fallback for date columnsenableCalculation?: boolean– enable/disable footer calculations for this column oncetable.enableCalculationsis enabled (defaulttrue, except system columns likeselect/actions)defaultCalculation?: CalculationType– default footer calculation shown for this column (validated against column type)inlineEdit?: boolean | InlineEditColumnConfig– enable/configure inline editing for this column- For number columns:
numberFormat?: NumberFormatConfig– display format (thousands/decimal separators, decimals, prefix/suffix for currency). See Number column below. - For tag columns:
tagColorMap?: Record<string, string>– optional value → Tailwind class map (see below).
Footer calculations by column
You can preconfigure calculations directly on columns:
{
id: 'price',
type: 'number',
header: 'Price',
defaultCalculation: 'average',
}Useful defaults by type:
- Any type:
count_all,count_values,count_unique,count_empty,count_not_empty,percent_empty,percent_not_empty - Number:
sum,average,median,min,max,range - Date:
min,max,range - Boolean:
count_true,count_false,percent_true,percent_false
If a defaultCalculation is invalid for the column type, it is ignored safely.
Inline Edit by Column
Enable inline edit directly on a column:
{
id: 'name',
type: 'text',
header: 'Name',
inlineEdit: true,
}Advanced per-column config:
{
id: 'status',
type: 'tag',
header: 'Status',
inlineEdit: {
enabled: true,
editor: 'select',
formField: 'status',
debounceMs: 700,
options: [
{ label: 'Draft', value: 'draft' },
{ label: 'Published', value: 'published' },
],
},
}InlineEditColumnConfig fields:
enabled?: boolean– explicit on/off for this columneditor?: 'auto' | 'text' | 'number' | 'boolean' | 'date' | 'select' | 'textarea' | 'json'debounceMs?: number– overrides table-level debounceformField?: string– form field name used for schema validation and update payload keyoptions?: Array<{ label: string; value: string | number | boolean }>– select choicesreadonly?: boolean– force non-editable in inline mode
Number column (number)
Number columns render numeric values with optional formatting and are right-aligned (header and cells) by default.
Display format: numberFormat
Use numberFormat to control thousands separator, decimal separator, number of decimals, and optional monetary prefix/suffix.
Presets (string):
'space'– space as thousands separator, dot for decimals (e.g.1 234 567.89)'dot'– dot for thousands, comma for decimals (e.g.1.234.567,89)'comma'– comma for thousands, dot for decimals (e.g.1,234,567.89)'locale'– use browserIntl.NumberFormat(locale-dependent)
Explicit options (object):
thousandsSeparator?: string– e.g.' ','.',','decimalSeparator?: string– e.g.'.',','decimals?: number– fixed decimal places (omit for default)prefix?: string– text before the number (e.g.'€ 'for currency)suffix?: string– text after the number (e.g.' €'for euros)
Examples:
// Euros, no decimals, space thousands (e.g. 2 499 €)
{
id: 'price',
type: 'number',
header: 'Price',
numberFormat: { thousandsSeparator: ' ', decimals: 0, suffix: ' €' },
}
// US-style with prefix
{
id: 'amount',
type: 'number',
header: 'Amount',
numberFormat: { thousandsSeparator: ',', decimalSeparator: '.', decimals: 2, prefix: '$ ' },
}
// Preset only
{ id: 'count', type: 'number', header: 'Count', numberFormat: 'space' }When numberFormat is not set, numbers are shown as plain values (no thousands grouping). A custom formatter (if provided when building columns programmatically) overrides numberFormat.
Date display presets
For type: 'date', you can use strict presets:
localized-shortlocalized-mediumlocalized-longmonth-name-longmonth-yeardmy-numericdmy-shortmdy-numericmdy-shortiso-date
Example:
{
id: 'createdAt',
type: 'date',
header: 'Created',
dateDisplayPreset: 'month-name-long',
}Tag column (tag)
Tag columns render values as colored badges. Colors are deterministic: the same tag value always gets the same color across sessions and page reloads (derived from a hash of the value). Values are normalized (trim + lowercase) for matching, so e.g. "Urgent" and "urgent" share the same color.
Custom colors per value: tagColorMap
You can override colors for specific tag values by passing a tagColorMap in the column definition. Keys are tag values (lookup tries the raw value, then the normalized value); values are Tailwind classes for the badge (e.g. background + text).
This works directly from columns.definitions without custom column wiring.
Example:
{
id: 'status',
type: 'tag',
header: 'Status',
tagColorMap: {
Urgent: 'bg-red-500/80 text-white dark:bg-red-600/90',
Done: 'bg-green-500/80 text-white dark:bg-green-600/90',
'In progress': 'bg-amber-500/80 text-white dark:bg-amber-600/90',
},
}Entries in tagColorMap use the given class; any other value falls back to the deterministic hash-based color.
Dynamic type columns
Use type: 'dynamicType' and specify typeKey on the row to pick the renderer at runtime.
Selection column (select)
- The
selectcolumn is virtual and does not need a definition entry. - Add
'select'tocolumns.orderand tocolumns.visibleto show it when you provide an explicit visible list. - Controlled by
table.enableRowSelection(defaulttrue). - Rendered as a narrow fixed-width column with a centered checkbox; same width as the actions column.
- To hide it, remove
'select'fromcolumns.visible. - It is not toggleable from the options menu UI.
Actions column (actions)
- Add
{ id: 'actions', type: 'actions', header: '...' }tocolumns.definitions(the header label is not shown in the UI; useheader: ''or any label for accessibility/column menu). - Rendered as a narrow fixed-width column with a centered actions menu (ellipsis) per row; same width as the selection column.
- To hide it, remove
'actions'fromcolumns.visible. - It is not toggleable from the options menu UI.
See also: