Columns
A Column declares how one field is read, presented, and allowed to participate in Table behavior. The Laravel producer prepares a cell payload; React chooses the renderer from the Column’s type.
Start with inference
Section titled “Start with inference”The quick start asks InertiaX to infer every allowed model field:
InertiaX::table('users') ->data(User::class) ->autoColumns();This is useful while establishing a Table. Inference uses model casts and database metadata to choose built-in types, respects the model’s visible/fillable and hidden attributes, and adds a hidden identity column when needed.
Declare a field explicitly when its presentation becomes intentional. Bulk inference skips keys that are already present:
InertiaX::table('users') ->data(User::class) ->autoColumns() ->addColumn( TextColumn::make('name', 'Full name') ->sortable() ->searchable() ->filterable(), );The remaining allowed fields stay automatic. Move to a completely explicit columns() method
when you want the Table class to declare and review every displayed field.
Built-in Columns
Section titled “Built-in Columns”| Column | Use it for | Useful options |
|---|---|---|
TextColumn |
General text | all common capabilities |
NumberColumn |
Integers and decimals | numberCast('int' | 'float') |
BooleanColumn |
Canonical Boolean values with configurable presentation | trueLabel(), falseLabel(), trueIcon(), falseIcon() |
DateColumn |
Formatted calendar dates | format(), timezone(), translate() |
DateTimeColumn |
Formatted date and time values | date formatting options |
TimeColumn |
Formatted time values | time formatting options |
JsonColumn |
Structured JSON values formatted by the renderer | wrapping and the common capabilities |
BadgeColumn |
Status/category values | variant(), icon(); all maintained variants are supported |
use InertiaX\Components\Table\Columns\BadgeColumn;use InertiaX\Components\Table\Columns\BooleanColumn;use InertiaX\Components\Table\Columns\DateColumn;use InertiaX\Components\Table\Columns\NumberColumn;use InertiaX\Components\Table\Columns\TextColumn;
protected function columns(): array{ return [ NumberColumn::make('id', 'ID')->numberCast('int')->sortable(), TextColumn::make('name', 'Name')->sortable()->searchable()->filterable(), BooleanColumn::make('active', 'Active') ->trueLabel('Enabled') ->falseLabel('Disabled'), BadgeColumn::make('status', 'Status')->variant([ 'active' => 'success', 'invited' => 'secondary', ]), DateColumn::make('joined_on', 'Joined')->format('Y-m-d')->sortable(), ];}The first argument is the stable key. The optional second argument is the user-facing label.
Boolean labels and icons are definition-level presentation options; the cell value remains a JSON
Boolean. JSON cells likewise retain their structured value on the wire, and the React renderer owns
their readable display formatting. Date Columns format a clone of a mutable Carbon value, so
rendering a cell never changes the model-owned instance. Badge variants include primary,
secondary, default, destructive, outline, success, warning, and info.
Common capabilities
Section titled “Common capabilities”Columns opt into behavior explicitly:
TextColumn::make('name', 'Name') ->sortable() ->searchable() ->filterable() ->copyable() ->toggleable() ->visible() ->wrap() ->truncate(80);The defaults are conservative: visible columns render, but sorting, searching, filtering, copying, and visibility toggling are disabled unless enabled on the Column or for the whole Table.
Table-wide calls such as sortableColumns() and searchableColumns() set the default for every
Column. A Column-level option remains the better choice for exceptions and sensitive fields.
Transform the displayed value
Section titled “Transform the displayed value”Value transformers run on the server before the cell payload is serialized:
TextColumn::make('name', 'Name') ->transformUsing(fn (string $value): string => mb_strtoupper($value));For a finite mapping:
TextColumn::make('role', 'Role')->mapAs([ 'admin' => 'Administrator', 'member' => 'Member',], default: 'Unknown');transformUsing() is the one-transformer convenience. For inherited definitions, named
addValueTransformer(), replaceValueTransformer(), removeValueTransformer(), and
clearValueTransformers() provide deterministic mutation. Lower numeric priorities run first;
stages at the same priority retain declaration order, and replacing a named stage retains its
position.
For reusable, container-resolved behavior, implement the public ValueTransformer contract and
pass its class name instead of a closure. Its transform() method receives the current value,
record, Column, and Table. Returning null deliberately produces a JSON null cell value.
Use cell decorators when you need to change payload metadata rather than its value. The built-in
Badge and Boolean Columns expose focused methods so most applications do not need a decorator.
Reusable decorators implement CellDecorator::decorate(). They receive the current
CellPayload, record, Column, and Table; they may mutate or replace the payload, while returning
null keeps the current payload.
Column metadata describes the definition once and applies to every row. Metadata added by a cell
decorator belongs to one row’s CellPayload, so it can vary with the current record. Custom
renderers receive both scopes and can use definition metadata for shared configuration and cell
metadata for record-specific presentation.
Infer one named model field
Section titled “Infer one named model field”AutoColumn lets schema inspection choose the built-in Column type while you still opt into
capabilities explicitly:
use InertiaX\Components\Table\Columns\AutoColumn;
AutoColumn::make('score', 'Score')->sortable()Inference uses the Eloquent model’s casts and database schema. Prefer an explicit Column when the
domain presentation is important or when the source is a Collection. autoColumns() is broader:
it asks InertiaX to infer the complete model allowlist rather than one named field.
Custom sorting and search
Section titled “Custom sorting and search”Use sortUsing() or searchUsing() when the field’s storage differs from its public Column key.
Custom operations must declare supported source kinds:
TextColumn::make('customer', 'Customer') ->sortable() ->sortUsing( fn ($query, string $column, string $direction) => $query->orderBy('customer_name', $direction), DataSourceKind::Eloquent, );If a custom implementation supports another kind, list it explicitly with
supportsSortSources() or supportsSearchSources(). Source declarations prevent an SQL callback
from being called with a Collection.
Attach a Filter
Section titled “Attach a Filter”A filterable Column can use its inferred built-in Filter, or attach one directly:
BadgeColumn::make('status', 'Status') ->filterable() ->filter( SelectFilter::make('status', 'Status')->options([ 'active' => 'Active', 'invited' => 'Invited', ]), );You may instead declare filters centrally in the Table’s filters() method. See
Filters and Clauses.