Elyra
Elyra The coding agent e The native code editor Elyra Grove Native local development environment Askr The real server for Laravel & PHP Elyra Framework Rust + Svelte 5 framework for desktop apps Elyra Conductor Local project conductor Elyra SQL Server MySQL-compatible SQL server in Rust Elyra SQL Client Native desktop SQL workbench Elyra SQL Anywhere Replication-ready SQL engine Elyra DataGrid Server-driven data grid for Laravel
Elyra
Columns, cell templates & editors

Columns, cell templates & editors

Columns are declared twice, by design:

  • On the server (GridDefinition::column) — the SQL mapping and security allow-list. See Defining grids.
  • On the client (a ColumnDef) — presentation: header, alignment, width, templates, editors, badges.

For Livewire the client column config is returned from columns(); for Svelte/Vue it is options.columns.

ColumnDef

interface ColumnDef {
  field: string;              // must match a server-declared column
  header?: string;           // display label (default: field)
  type?: 'string' | 'number' | 'date' | 'bool';
  align?: 'left' | 'right' | 'center';
  width?: number;            // px
  minWidth?: number;
  sortable?: boolean;        // per-column override
  filterable?: boolean;
  frozen?: boolean | 'left' | 'right';   // sticky to the left (true) or right edge
  hidden?: boolean;
  format?: (value, row) => string;   // client formatter
  badges?: Record<string, number>;   // value → pill palette slot (1–5)
  cell?: CellTemplate;               // declarative cell renderer
  editable?: boolean;
  editor?: 'text' | 'number' | 'select' | 'date' | 'checkbox';
  options?: { value: string | number; label: string }[];
}

Cell templates

Render cells declaratively — no custom components needed.

{ field: 'revenue', header: 'Revenue', type: 'number', align: 'right',
  cell: { type: 'currency', symbol: 'kr ', decimals: 2 } },

{ field: 'margin', header: 'Margin', cell: { type: 'bar', max: 1200 } },

{ field: 'sku', header: 'SKU', cell: { type: 'link', href: '/orders/{id}' } },

{ field: 'active', header: 'Active', cell: { type: 'boolean' } },

{ field: 'rate', header: 'Rate', cell: { type: 'percent', decimals: 1 } },
type Options Renders
currency symbol, suffix, decimals kr 1,234.56
percent decimals 12.5%
number decimals thousands-separated
bar max horizontal data bar (value / max)
boolean ✓ / ✗
link href (with {field} tokens) anchor
badge (uses badges map) status pill

Status pills (badges)

{ field: 'status', header: 'Status', badges: {
    pending: 1, paid: 2, shipped: 3, delivered: 4, returned: 5,
} },

The number is a palette slot (1–5), themed via --dg-status-1..5.

Cell editors

When a column is editable, its editor controls the input used in inline editing and in the modal/slideover form:

{ field: 'status', header: 'Status', editable: true, editor: 'select', options: [
    { value: 'pending', label: 'pending' },
    { value: 'paid', label: 'paid' },
] },
{ field: 'qty', header: 'Qty', type: 'number', editable: true, editor: 'number' },
{ field: 'due', header: 'Due', editable: true, editor: 'date' },
{ field: 'active', header: 'Active', editable: true, editor: 'checkbox' },

Editing also requires the column to be editable on the server with validation rules. See Editing.

Multi-column headers

Group columns under a spanning banner row with headerGroups. Grouped columns must be contiguous:

const options = {
  columns: [ /* sku, region, category, status, qty, revenue, margin */ ],
  headerGroups: [
    { header: 'Attributes', columns: ['region', 'category', 'status'] },
    { header: 'Financials', columns: ['revenue', 'margin'] },
  ],
};

Livewire equivalent — a $headerGroups property on the component.

Column operations (reorder / resize / freeze / hide)

Enable the columnOps feature to get the per-header ⋮ menu (sort, group, freeze, move, hide), a drag-to-resize handle, and a Columns chooser:

const options = { /* ... */ columnOps: true };
// or granular:
// columnOps: { reorder: true, resize: true, freeze: true, visibility: true }

For Livewire, column ops are always available via the header menu and the Columns toolbar button.

Frozen columns (left / right)

Pin columns to either edge; the rest scroll horizontally beneath them. Multiple frozen columns on the same side stack with cumulative offsets (give them a width for exact positioning).

columns: [
  { field: 'sku', header: 'SKU', frozen: true },              // or 'left'
  { field: 'actions', header: '', frozen: 'right', width: 120 },
]

Auto-fit

Double-click a column's resize handle to auto-size it to the widest visible cell (capped). Drag the handle to resize manually.

Column virtualization

For very wide grids (dozens of columns), render only the columns in the horizontal viewport:

const options = { /* ... */ columnVirtual: true };
// or: columnVirtual: { defaultWidth: 110, overscan: 2 }

Frozen columns are always rendered; the rest are windowed with spacers, keeping the DOM O(visible columns). Give columns a width for accurate offsets. Currently available in the Svelte/Vue clients.