Skip to content

Column sizing

View as Markdown

width, minWidth, and maxWidth on table column metadata and report GridDatasetColumn values are approximate displayed-character counts. They are not CSS pixels or database length limits; Sapporta turns them into font-relative grid tracks.

Use width for a fixed column. Prefer minWidth when a column may use extra space, and add maxWidth when long text should stop growing.

  • Title or description: 40–80
  • Project, person, or lookup name: 24–48
  • Status, priority, or other short controlled value: 12–24
  • Date: 12–16
  • Timestamp: 18–22
  • Labels or tags: 24–40

Size for the formatted value people need to scan, not the longest value the database can store. A date cell reads 2026-08-23 and a timestamp cell reads 2026-08-23 16:38, so size for those rather than for the stored 2026-08-23T11:08:00Z. Leave numeric, date, and timestamp report columns unsized when their built-in defaults are sufficient: each preset carries its own width, and schema-declared sizing wins where it is present.

The built-in widths of numeric, date, timestamp, select, and reference columns fit Sapporta’s default 12px monospace data. An application that sets its data in a larger face raises their floors with the columnSizing prop of TGrid and ReportGridDataset:

const ledgerColumnSizing = {
minWidths: { numeric: 128, timestamp: 176 },
};
<ReportGridDataset dataset={dataset} columnSizing={ledgerColumnSizing} />;

minWidths is keyed by the preset’s named widths: numeric (number, currency, and percentage columns), date, timestamp, enum (select columns), foreignKey, compact, content, and fill. Each value is a floor in pixels, and a floor above a width’s ceiling lifts the ceiling with it. Columns with schema-declared width, minWidth, or maxWidth, and columns a person has dragged, keep their own widths.

columnSizing takes every ColumnPreset sizing option except storageKey; each grid names its own storage for dragged widths. Keep the object’s identity stable, at module level or in useMemo: the grid chrome is rebuilt whenever it changes.

Table metadata:

columns: {
title: { minWidth: 64 },
assignee_id: { label: "Assignee", minWidth: 32 },
status: { minWidth: 20 },
}

Report dataset columns:

columns: [
{ id: "title", label: "Task", kind: "text", minWidth: 80 },
{ id: "project", label: "Project", kind: "text", minWidth: 40 },
{ id: "status", label: "Status", kind: "text", minWidth: 20 },
{ id: "dueDate", label: "Due date", kind: "date" },
{ id: "updatedAt", label: "Updated", kind: "timestamp" },
]