Skip to content

Column definitions

Every key a column definition accepts. Leaf columns carry an accessorKey/field, a header, a type, and optional formatting, filtering, sorting, conditional-formatting, and cell-renderer keys; group columns nest columns; action columns carry actions. These are shared across the Dash component and the framework adapters.

NameTypeDefaultDescription
actions
Action
array<{id, label?, icon?, iconSvg?, title?}>Per-row action buttons for an action column (type:'action' or presence of actions[]). Each renders a button; clicking sets action_triggered to {row_id, action, n, row}. Built by engine.make_action_column.
actions[].icon (actionItem.icon)
Action
stringBuilt-in icon name for the action button: one of 'edit','delete','view','search','download','info','filter','more','plus','check','refresh','star'.
actions[].iconSvg (actionItem.iconSvg)
Action
stringRaw SVG string used as the action icon instead of a built-in name.
actions[].id (actionItem.id) *
Action
stringRequired. Stable action identifier reported back in action_triggered.action. Shared shape for both `actions` and `headerActions`.
actions[].label (actionItem.label)
Action
stringButton text for the action.
actions[].title (actionItem.title)
Action
stringNative hover title/tooltip for the action button.
headerActions
Action
array<{id, label?, icon?, iconSvg?, title?}>Clickable buttons rendered in the column header; clicking fires action_triggered with scope:'column'. Stored as meta.headerActions.
aggregationFn
Aggregation
stringClient-side aggregation function name for the optional frontend-aggregation mode ('sum'|'mean'|'min'|'max'|'count'|'median'|'uniqueCount'). make_column_defs advertises it by mapping the backend built-in via _FRONTEND_AGG (size/count_rows->count, n_unique/nunique/count_distinct->uniqueCount, avg/average->mean). Ignored unless grouping is active. NOT in column-def.schema.json; emitted by the engine and read by the bridge.
enableColumnFilter
Behaviour
booleantrueSchema-declared per-column filter toggle (default true). DRIFT: the component's toColumnDef reads `def.enableFilter`, not this key, so a def that sets enableColumnFilter alone is ignored at runtime. (`enableColumnFilter` IS the internal TanStack output prop the bridge writes, just not the input key it reads.)
enableFilter
Behaviour
booleantruePer-column filter toggle actually consumed by the component and emitted by config.py (`filterable`->enableFilter). IMPORTANT: column-def.schema.json documents this as `enableColumnFilter`, but the React bridge reads `def.enableFilter`; setting only the schema's `enableColumnFilter` has no effect.
enableHiding
Behaviour
booleantruePer-column show/hide toggle (column visibility menu). Set false to force the column always visible.
enableResizing
Behaviour
booleantruePer-column resize-handle toggle. Only false is forwarded (disables resizing); otherwise inherits grid default.
enableSorting
Behaviour
booleantruePer-column sort toggle. Effective only when grid sorting is on and the column is not a chart. Set false to disable.
cellStyle
Conditional-format
objectStatic per-cell CSS style object applied unconditionally to the column's data cells (spread onto the cell style).
conditionalFormat
Conditional-format
{type:'dataBar'|'colorScale'|'iconSet', ...}Value-driven visual applied per cell: dataBar (in-cell bar) and iconSet (icon+label) replace cell content; colorScale sets an interpolated cell background. Numeric bounds default to the column's faceted min/max EXCLUDING the synthetic grand-total row. Sub-fields enumerated in the conditionalFormat.* entries below. Schema requires `type` and is additionalProperties:false.
conditionalFormat.color
Conditional-format
stringvar(--tg-accent)dataBar: the positive/above-origin bar fill color.
conditionalFormat.colors
Conditional-format
array<string>colorScale ['#f8696b','#ffeb84','#63be7b']; iconSet ['#e03131','#f08c00','#2f9e44']colorScale: 2- or 3-stop interpolation palette (>=3 stops uses min/mid/max). Also an iconSet per-level color override (needs >=3 entries) that wins over the default red/amber/green.
conditionalFormat.max
Conditional-format
numberfaceted max (excl. grand total)Domain upper bound for dataBar/colorScale/iconSet. Defaults to the column's faceted max (grand-total row excluded).
conditionalFormat.mid
Conditional-format
number(min+max)/2colorScale: midpoint value mapped to the middle color of a 3-stop palette.
conditionalFormat.min
Conditional-format
numberfaceted min (excl. grand total)Domain lower bound for dataBar/colorScale/iconSet. Defaults to the column's faceted min (grand-total row excluded).
conditionalFormat.negativeColor
Conditional-format
stringvar(--tg-neg, #e03131)dataBar: fill color for negative values / below-origin bars.
conditionalFormat.origin
Conditional-format
numberdataBar: diverging origin value; the fill spans between the origin and the value (rightward in color above, leftward in negativeColor below). NOT in column-def.schema.json (which is additionalProperties:false) but consumed by the bridge and documented in the propType.
conditionalFormat.reverse
Conditional-format
booleanfalseiconSet: flip the level->icon/color mapping so a LOW value reads as 'good' (green/up) — for cost/rank/error measures. NOT in column-def.schema.json (additionalProperties:false) but consumed by the bridge and documented in the propType.
conditionalFormat.set
Conditional-format
'arrows'|'traffic'|'triangles''arrows'iconSet: which 3-level icon family to draw (arrows down/right/up, traffic-light circles, or triangles).
conditionalFormat.thresholds
Conditional-format
array<number>[min+range/3, min+2*range/3]iconSet: >=2 band boundaries [t1,t2] deciding the 3 levels. Absent -> auto thirds of [min,max]; a flat auto-domain is classified as the neutral middle level.
conditionalFormat.type *
Conditional-format
'dataBar'|'colorScale'|'iconSet'Required discriminator selecting the conditional-format variant.
styleRules
Conditional-format
array<{if, style?, className?}>Conditional formatting rules. Each rule's `if` is an engine-DSL formula tested per row against {value, ...other column values}; matching rules contribute a style object and/or className. Compiled once (compileFormulaSafe) at column build.
styleRules[].className
Conditional-format
stringCSS class name added to the cell when the rule's `if` matches.
styleRules[].if *
Conditional-format
stringRequired. Formula tested per row against { value, ...columns }. Truthy result applies the rule.
styleRules[].style
Conditional-format
objectCSS style object applied to the cell when the rule's `if` matches.
accessorKey
Data
stringSource data key for the column's leaf value (the row-object field to read). A leaf column carries this; group and action columns must not. Emitted by make_column_defs for every dimension/measure leaf. The React bridge falls back accessorKey||field.
field
Data
stringAlias for accessorKey (AG-Grid-style spelling). Resolved as `def.accessorKey || def.field`; also a fallback for header/id.
formula
Data
stringCalculated column: an engine-DSL formula over the row's other measure values (same syntax as the Python DSL, e.g. '(rev-cost)/rev'). Gives the column an accessorFn so it sorts (custom NaN-last, mixed-type-stable sortingFn) and range-filters like a real column. A calculated column carries `id`+`formula` and no accessorKey.
header
Data
stringHuman-readable column label. make_column_defs derives it from headers override or col.replace('_',' ').title(). Resolution order in the bridge: header > headerName > field > accessorKey > id.
headerName
Data
stringAlias for header (AG-Grid-style spelling), consumed as the second choice after header. NOT in column-def.schema.json — undocumented alias only the React bridge reads.
id
Data
stringExplicit column id. Required for calculated/formula columns (which have no accessorKey) and for action columns (defaults to 'actions'). Falls back to accessorKey then formula.
type
Data
'number'|'string'|'date'|'boolean'|'action'Column data-type tag. Drives numeric right-alignment, default filterType, editor input type, and grouping eligibility (only non-numeric columns are groupable). make_column_defs derives it from the Polars dtype (Utf8/Categorical->string, Date/Datetime/Time->date, Boolean->boolean, else number; derived/pivot measures->number).
description
Display
stringAlias/fallback source for headerTooltip (headerTooltip || description). NOT in column-def.schema.json; only the React bridge reads it.
enableTooltip
Display
booleanShow a hover tooltip on the cell (value or tooltipField). Stored as meta.enableTooltip.
headerTooltip
Display
stringTooltip text for the column header. config.py maps the friendly `tooltip` option to this. Also fed by the `description` alias.
pinned
Display
'left'|'right'Freezes the column on horizontal scroll to the given edge. The select column auto-pins left when anything is pinned.
tooltipField
Display
stringRow field whose value provides the cell tooltip text (paired with enableTooltip). Stored as meta.tooltipField.
wrapText
Display
booleanAllow the cell text to wrap onto multiple lines instead of truncating. Stored as meta.wrapText.
editable
Editing
booleanfalsePer-column opt-in to inline cell editing; effective only when the grid's enable_editing is set. Stored as meta.editable (strict === true).
filterOptions
Filtering
arrayAllowed values for a 'select' filter (dropdown) and the option list for a select inline-editor. make_column_defs auto-populates it with the column's sorted distinct source values when filters[col]=='select'.
filterType
Filtering
'text'|'range'|'select'|'set'|'conditions'|'date'Per-column filter UI/predicate. When omitted the bridge derives it: numeric->range, date->date, else text. 'range'=inNumberRange, 'set'=in-set checkbox filter, 'conditions'=multi-condition (op/val AND-OR op/val), 'date'=from/to ISO range, 'select'=equalsString dropdown. make_column_defs emits it when a filters override is given.
align
Formatting
'left'|'center'|'right'numeric->right, else leftText alignment stored on meta.align (defaults right for numeric, left otherwise). NOTE: the component sets meta.align but never actually consumes it for alignment (numeric/string CSS cell classes own alignment), so setting align is effectively a no-op; config.py intentionally does NOT expose it for that reason.
formatStr
Formatting
stringdims: None (date dims 'date'); measures '0,0.00'; pivot leaves '0,0'Display format string 'kind[:arg][:flag…][;modifier…]'. kind: number/currency/percentage/date. Numeric flags/modifiers: compact (1.2K/3.4M), accounting (negatives in parentheses), sign (+/-), unit=<suffix>. Examples: 'currency:USD:compact', 'number:2;accounting', 'number:0;unit=kg'. Raw numerics stay on the wire; formatting happens in JS. Defaults from make_column_defs: dimensions None (Date/Datetime dims default to 'date'), aggregation & calculated measures '0,0.00', pivot leaf measures '0,0'.
columns
Grouping
array<column-def>Child column definitions for a column GROUP (nested header). A group column carries { header, columns:[...] } and no accessorKey. Recursively normalized; each pivot column-dimension level nests via this key.
enableGrouping
Grouping
booleantruePer-column grouping toggle. Only non-numeric (dimension) columns are groupable; measures aggregate within groups. Set false to disable.
cellRenderer
Renderer
'sparkline'|'bar'|'badge'|'chip'|'progressBar'|'link'|'rating'|'boolean'|'checkbox'|'email'|'url'|'phone'|'tags'Named cell renderer. Charts sparkline/bar take an array-of-numbers value and are auto non-sortable/filterable/groupable. The other names are scalar widgets routed through CellWidget. Underlying value stays raw (sort/filter/aggregate keep working); only presentation changes.
cellRenderer: badge
Renderer
scalar widgetFilled pill. cellRendererParams: {colorMap (value->bg color, own-property lookup only), color, textColor}. Displays the formatted value.
cellRenderer: bar
Renderer
chart (value = number[])In-cell column/bar chart. Same cellRendererParams as sparkline (width, height, color, colorUp, colorDown). Auto non-sortable/filterable/groupable.
cellRenderer: boolean / checkbox
Renderer
scalar widgetCheck/dash glyph. Truthy set = {true,1,'1','true','yes','y'}. No params.
cellRenderer: chip
Renderer
scalar widgetOutlined pill (unfilled variant of badge). cellRendererParams: {colorMap, color, textColor}.
cellRenderer: email
Renderer
scalar widgetmailto: link (scheme-safe). No params.
cellRenderer: link
Renderer
scalar widgetAnchor around the display text. cellRendererParams: {href ('{value}' placeholder, URL-encoded), hrefField (row field supplying the href), target='_blank'}. Scheme-checked via safeHref; a blocked scheme (e.g. javascript:) renders plain text.
cellRenderer: phone
Renderer
scalar widgettel: link (non +/digit chars stripped from the href). No params.
cellRenderer: progressBar
Renderer
scalar widgetHorizontal progress fill. cellRendererParams: {min=0, max=100, color=var(--tg-accent), height=8, showValue (overlay formatted label)}. Percentage clamped to [0,1].
cellRenderer: rating
Renderer
scalar widgetStar rating. cellRendererParams: {max=5, color='#f59f00'}. Rounds the numeric value to filled stars.
cellRenderer: sparkline
Renderer
chart (value = number[])In-cell line chart. cellRendererParams: {width=80, height=22, color, colorUp, colorDown, fill (area fill), lineWidth=1.5}. Color auto-derives up (last>=first, colorUp/green) vs down (colorDown/red). Needs >=2 finite numbers or renders an em dash. Auto non-sortable/filterable/groupable.
cellRenderer: tags
Renderer
scalar widgetRenders an array value (or a separator-split string) as chips. cellRendererParams: {separator=',', colorMap (tag->color, own-property lookup)}.
cellRenderer: url
Renderer
scalar widgetExternal link; bare 'example.com' is prefixed https://. cellRendererParams: {target='_blank'}. Scheme-safe.
cellRendererParams
Renderer
objectOptions object passed to the named cellRenderer (per-renderer keys enumerated in the cellRenderer feature entries below). A null value is coalesced to {} so it is safe.
maxSize
Sizing
numberMaximum column width in px (TanStack-native). Takes precedence over `maxWidth`. Not in the schema; consumed by the bridge, emitted by config.py (max_width->maxSize).
maxWidth
Sizing
numberMaximum column width in px. Alias of `maxSize`.
minSize
Sizing
numberMinimum column width in px (TanStack-native). Takes precedence over `minWidth`. Not in the schema; consumed by the bridge, emitted by config.py (min_width->minSize).
minWidth
Sizing
numberMinimum column width in px. Alias of `minSize`.
size
Sizing
numberInitial column width in px (TanStack-native spelling). Takes precedence over `width`. NOT in column-def.schema.json (which lists width/minWidth/maxWidth) but consumed by the bridge and emitted by config.py (width->size).
width
Sizing
numberInitial column width in px. Alias of `size` (size||width wins).
validationRules
Validation
array<rule>Engine-evaluated edit-validation rules (discriminated union keyed by `type`). An invalid source-cell edit is rejected before the frame mutates. Extracted from the column def by the caller and enforced in engine.apply_edit. Sub-fields enumerated in validationRules.* entries below.
validationRules[].allowedValues
Validation
arrayenum rule: the permitted values.
validationRules[].code
Validation
string'validation.<type>'Stable machine code for the rejection.
validationRules[].flags
Validation
stringregex rule: flag subset.
validationRules[].if
Validation
stringpredicate rule: an engine-DSL scalar boolean over the candidate post-edit row; 'value' aliases the edited cell.
validationRules[].inclusive
Validation
booleantruerange rule: whether bounds are inclusive.
validationRules[].max
Validation
number|nullrange rule: upper bound.
validationRules[].message
Validation
stringCustom rejection message shown when the rule fails.
validationRules[].min
Validation
number|nullrange rule: lower bound.
validationRules[].pattern
Validation
stringregex rule: RE2-safe pattern (no backrefs/lookaround, so Python re == JS RegExp).
validationRules[].type *
Validation
'required'|'range'|'enum'|'regex'|'predicate'Required. Rule discriminator. required=non-null; range=numeric bounds; enum=allowedValues membership; regex=RE2-safe pattern match; predicate=DSL boolean over the candidate post-edit row.