Unify Logo Footer.svg
Unify Applications
Logo
Column Types

Column Types

Logo

8 mins READ

Shared Column Properties

These apply to every column regardless of type. Set them in the column's detail panel (select the column header in the builder).

PropertyTypeDefaultDescription
labelstringColumn header text. Translatable
typecolumn typeTEXTPicks the renderer and type-specific options
fieldKeyfield keyBinds the column to a row field. Accepts dot paths like details.status for nested fields
valueexpressionA computed value. When both Value and Field Key are set, Value wins for display; Field Key still identifies the underlying field for editing
visibilityconditionshownShow or hide the column, optionally per condition
appearance.widthnumber (px)Fixed column width
appearance.growbooleanoffLets the column stretch to fill leftover horizontal space
appearance.pinned"Start" | "None" | "End"NoneFreezes the column to the left or right edge during horizontal scroll
appearance.align"left" | "center" | "right"leftHorizontal alignment of cell content
editableboolean or conditionoffTurns on inline editing. Only available for editable types with a Field Key and a table Primary Key
permissionspermission ruleRestricts who sees the column

Row Context in Expressions

Inside a column's Value, in any per-row condition (Editable condition, row action Disabled or Visibility), and in blocks placed inside a cell, the current row is available:

ExpressionWhat it holds
{{ <tableId>.context.currentRow.<field> }}The current row's field value. There is no bare currentRow — always prefix with the table's block ID
{{ <tableId>.context.currentRowIndex }}The row's position, counted from 0
{{ <tableId>.context.currentColumn }}The mapped-column entry that produced this column — only when using data-driven columns

Note: Row context pills appear in the expression editor only while the inspector is targeting the table or a block inside it. Outside the table, use {{ id.selectedRow }} instead.

Column Slots

Every column has a Slots area in its detail panel. Drop blocks into a slot to render them as part of that column. Blocks inside a slot read the current row via the row context expressions above.

SlotAvailable onWhat it does
Custom HeaderEvery typeReplaces the column's header text with your own blocks
Custom CellCustom type only (required)The entire cell body — the column renders nothing else; this slot cannot be deleted
Custom FallbackEvery type except CustomShown when a cell has no value, in place of plain Fallback Value text
Empty StateEvery typeShown for the column when it has no data
Start Decorator / End DecoratorEvery type except Tag, Attachment, CustomAn icon or small element placed before/after the cell content

Column Types Reference

Types marked Editable (required) support inline editing when the column has a Field Key and the table has a Primary Key.

Type NameType IDEditableType-Specific Options
TextTEXTYesFallback Value, text weight/variant, Text Overflow: clip (truncate) or wrap
NumberNUMBERYesMaximum Fraction Digits, Notation (Standard / Compact / Scientific), Pad Decimal Places, Fallback Value
CurrencyCURRENCYYesMaximum Fraction Digits, Notation (Standard / Compact — no Scientific), Currency Code, Fallback Value
PercentPERCENTYesMaximum Fraction Digits
Date TimeDATEYesFormat preset, input Date Format (iso8601 or unix), Fallback Value, Date Selection Limits (when editable)
DateDATE_ONLYYesDate-only Format presets, input Date Format, Fallback Value
TimeTIME_ONLYYesStep size in minutes (default 15) when editable
DurationTIMENoPrecision, Notation: compact ("3h 51m") or comfortable ("3 hours 51 minutes")
LinkLINKNoURL (bindable), Is External flag, Fallback Value
TagTAGYesVariant (soft/clear/solid), Color, mapped label/value fields, Start/End decorators, Fallback Value. When editable: dropdown with Static options or a lookup field
BooleanTOGGLEYes*Boolean Type: Toggle switch or Icon pair (true icon + false icon with colors). *Toggles flip in place — no editor overlay
ProgressPROGRESSNoMin (default 0), Max (default 100), Maximum Fraction Digits, Hide Label, bar styling
AttachmentATTACHMENTNoMapped URL, Caption, and Preview URL fields
Text with DescriptionTEXT_DESCRIPTIONNoDescription value, separate title and description typography, Fallback Value
IconICONNoIcon, Size (sm/md/lg), Fallback Value
Icon ButtonICON_BUTTONNoIcon, Color, Size, Fallback Value. Fires On Click (not On Click Cell)
AvatarAVATARNoMapped Image URL and Caption, avatar Size (default xs), Color, Fallback Value
HTMLHTMLNoRenders the cell value as raw HTML. Text typography, Fallback Value
MappedMAPPEDYes*Mapped Column Type + Additional Fields. Resolves its real type per row from data. *Editable when the resolved type is editable
CustomCUSTOMNoCustom Cell slot — drop any blocks in. Each row gets its own copy filled with that row's data via row context bindings

Warning: Type naming gotcha: The calendar-only Date type has id DATE_ONLY; the date-with-time type is DATE. The clock-time type is TIME_ONLY; the duration type is TIME. Use the type id, not the display name, when binding by type in an expression.

Data-Driven (Mapped) Columns

The whole column list can be generated from a data source instead of configured by hand. This is distinct from the Mapped column type — mapped columns decide which columns exist, while the Mapped type changes what one column renders per row.

Switch the table's Columns from a manual list to mapped mode in the table's detail panel, then configure:

SettingDescription
Data SourceReturns one entry per column — the count of entries decides the number of columns
NameWhich field of each entry supplies the column header text
Field KeyWhich field of each entry names the row field the column displays
TypeWhich field of each entry supplies the column type id (TEXT, NUMBER, TAG, …)
Width / PinnedWhich field supplies the column's width / pinning
ValueA computed cell value shared by every generated column
EditableToggle or condition — turns on inline editing per column

Note: Slots in mapped mode are shared, not per column. The one Custom Header template you build is repeated as the header of every generated column — bind {{ tableId.context.currentColumn.<field> }} inside it to vary content per column.

Warning: Exports ignore column visibility in mapped mode — every generated column is exported regardless of its visibility setting.

Behavior & Gotchas

Clicking a column header never sorts

Header-click sorting is turned off by design. Sorting only happens through the toolbar Sort action, which re-runs the data source with the chosen order. The table never sorts rows client-side.

Icon Button fires On Click, not On Click Cell

Every other column type emits On Click Cell when its cell is clicked. The Icon Button column instead emits its own On Click event, because it represents an action rather than a value.

Boolean columns toggle in place

Unlike other editable types, an editable Boolean column does not open an editor overlay. The switch flips directly in the cell, and each flip fires On Change Value and lands in the changeset like any other edit.

Editable toggle requires type + Field Key + Primary Key

The Editable toggle appears only when all three hold: the column type is one of the editable types (Text, Number, Currency, Percent, Date Time, Date, Time, Tag, Boolean, Mapped), the column has a Field Key, and the table has a Primary Key. Fix whichever is missing if the toggle does not appear.

Custom cell values cannot be read from outside the table

All rows render from one configured set of blocks. There is no per-row binding to reach a specific row's inner-block value from outside the table. To capture per-row input (a dropdown choice), use an editable column instead — edits land in the changeset, which the page can read.

Frequently Asked Questions

How do I show a tag whose color changes per row?

Add a Tag column and bind its Value to the row's status field, e.g. {{ orders.context.currentRow.status }}. For automatic coloring, leave Color unset — the same value always gets the same color, assigned deterministically. To color explicitly, bind the column's Color to a condition expression like: {{ orders.context.currentRow.status === 'active' ? 'success' : orders.context.currentRow.status === 'error' ? 'error' : 'neutral' }}.

Why can't I turn on Editable for my column?

Three conditions must all hold: (1) the column's type is one of the editable types (Text, Number, Currency, Percent, Date Time, Date, Time, Tag, Boolean, Mapped), (2) the column has a Field Key set, and (3) the table has a Primary Key configured. Check each in order — the toggle only appears when all three are satisfied.

What is the difference between the Mapped column type and data-driven (mapped) columns?

Three separate things share the word "mapped": the Mapped column type changes what one column renders per row (different row, different renderer). Data-driven columns generate the whole column list from a data source (add/remove columns at runtime). A mapped field on any column picks a per-row value from the row's data. The table's data Source toggle also offers "Mapped" — that refers to where the rows come from.

Can I put a button with different text on each row?

Yes — use a Custom column and drop a Button block into its Custom Cell slot. Bind the Button's label to a row field: {{ orders.context.currentRow.buttonLabel }}. Each row's copy of the cell block renders with that row's data.

I need a column to show different content types per row (a tag in one row, text in another). How?

Use the Mapped column type. Set its Mapped Column Type field to the row field that contains the type id (e.g., columnKind whose values are "TAG" or "TEXT"). The column resolves its real renderer per row from that field's value.

PageRelationship
Table OverviewThe block these columns belong to — events, methods, exposed state
Inline Editing & ChangesetsHow editable columns work and how edits are saved
Row Actions & SelectionHow row context drives row actions
Toolbar & ViewsColumn visibility and sorting from the toolbar