bo-grid v3.1.0

Columns

.md

Column definitions

Describe each column once, with a key, a header and a type, and the grid handles display, sorting, filtering and export.

A grid takes columns, an array of column definitions in display order. Each definition names the row field to read (key), the title to show (header), and a type that decides how the value is formatted, aligned, sorted and filtered. Everything else, such as width, pinning, tooltips and editing, is an optional field on the same object.

Sort a column from its header, hover a cut-off value for its tooltip, or drag a header edge to resize:

columns.svelte GitHub ↗

The shape of a column

<script lang="ts">
  import { Grid, type ColumnDef } from 'bo-grid';

  const columns: ColumnDef[] = [
    { type: 'text', key: 'symbol', header: 'Symbol', sub: 'name', width: 170 },
    { type: 'price', key: 'price', header: 'Price', width: 96 },
    { type: 'percent', key: 'change', header: 'Chg %', width: 90 },
    { type: 'volume', key: 'volume', header: 'Volume', width: 100 },
    { type: 'text', key: 'sector', header: 'Sector', flex: 1 },
  ];

  let rows = $state([
    { id: 1, symbol: 'VNM', name: 'Vinamilk', price: 68.5, change: 1.2, volume: 1_204_000, sector: 'Consumer' },
  ]);
</script>

<Grid {rows} {columns} height={400} />
  • key is the row field the column reads. It is also the column’s identity: sorting, filtering, hiding and saved layouts refer to columns by key, so keep keys unique.
  • header is the title in the header row.
  • type picks the cell’s format and behaviour. ColumnDef is a union on type, so TypeScript checks each type’s own options (decimals on number, min and max on heatmap, currency on currency). See Column types for the full list.
  • Rows are plain objects with a unique id: a number, or a string such as a symbol or UUID. If your data has another identity field, pass getRowId instead of copying it into id.

Widths

A column is either fixed or flexible:

  • width sets a fixed width in pixels.
  • flex sets a grow weight: flex columns share the width that fixed columns leave over, in proportion to their weights. A column with flex ignores width.
  • minWidth and maxWidth bound what a drag-resize can do.

To make every column scale with the grid instead, set fitColumns on the grid. Column sizing covers resizing, fitColumns and autoWidth.

Alignment, classes and formatting

Number types line up on the right and the rest on the left. Set align to override that for one column, for example a custom column that holds numbers.

format(value, row) replaces the built-in formatter. It applies wherever the value is shown as text: the cell, its tooltip, copy and formatted export.

{ type: 'number', key: 'ratio', header: 'Ratio', format: (v) => `${Number(v).toFixed(1)}×` }

cellClass and headerClass add your own classes. cellClass can be a function of the value and the row. Rows render inside the grid, so target the classes with :global(...); see Row styles.

Defaults for every column

defaultColumn sets fields that every column starts from. A column’s own fields, and a registered cellType, win over it:

<Grid {rows} {columns} defaultColumn={{ tooltip: true, minWidth: 64, resizable: false }} height={480} />

To reuse a whole kind of column across grids, such as a money amount or an order status, register it once with cellTypes: see Registered cell types.

Locale

Built-in number, price, currency and date formatting uses en-US by default. Set the grid’s locale to change it for every column, or a column’s own locale to change one:

<Grid {rows} {columns} locale="vi-VN" height={480} />

Localization covers the grid’s own strings too.

Reference

Column options from the types
key* string

Field on the row to read for this column's value. Also the column's id: sort, filter, width and hidden state are keyed by it.

header* string

The column's title in the header row.

width number Default 96

Width in px. A flex column starts from it where columns have fixed widths (pinned columns, virtualizeColumns), and fitColumns scales columns in proportion to it.

flex number Default undefined

flex-grow weight: the column stretches to fill the space the fixed-width columns leave, shared by weight. When the columns no longer fit, the grid scrolls sideways, counting a flex column as its width, else its minWidth, else 64 px. Unset, the column keeps its width.

minWidth number Default 48

Smallest width (px) a drag-resize or autosize can give this column; never less than 48. Under fitColumns, also the narrowest the column gets before the grid scrolls sideways (64 px without one, or the column's width if smaller).

maxWidth number Default Infinity

Largest width (px) a drag-resize, an autosize, autoWidth or fitColumns can give this column.

align Align Default 'right' for number types, 'left' for the rest

Which side the header, cells and footer sit on. Set it to line a custom column's values up under its title.

Example
{ type: 'custom', key: 'pnl', header: 'P&L', align: 'right' }
format (value: unknown, row?: GridRow) => string

Custom display formatter, overriding the built-in type formatter. Applies to display, tooltip, copy and (formatted) export. row is absent for aggregate cells.

Example
{ type: 'number', key: 'qty', header: 'Qty', format: (v) => Number(v).toLocaleString('vi-VN') }
cellClass string | ((value: unknown, row: GridRow) => string | undefined) Default undefined

Extra class(es) for this column's data cells — a static string, or a function of the cell value/row for conditional styling. Target via :global(.bo-grid .c.your-class).

Example
{ type: 'price', key: 'last', header: 'Last', cellClass: (v, row) => (Number(v) >= Number(row.ceiling) ? 'at-ceiling' : undefined) }
headerClass string Default undefined

Extra class(es) for this column's header. Target via :global.

sortable boolean Default true

Set false to disable header-click sorting on this column.

locale string Default undefined

BCP 47 locale for this column's built-in formatting (price, date, currency, relative). Unset, the grid's locale, then en-US.

Grid props from the types
columns* ColumnDef[]

The columns, in display order. A column's type picks how its values show, sort and filter.

Example
const columns: ColumnDef[] = [
  { type: 'text', key: 'sym', header: 'Symbol', width: 90 },
  { type: 'price', key: 'last', header: 'Last', flash: 'auto' },
];
defaultColumn DefaultColumn Default undefined

Settings applied under every column — its own fields (and a registered cellType) win.

Example
<Grid {rows} {columns} height={480} defaultColumn={{ minWidth: 72, sortable: false }} />
getRowId (row: GridRow) => string | number Default (row) => row.id

Identity key for rows: selection, focus, pins and flashes follow it. Override for string/UUID/composite keys.

Example
<Grid {rows} {columns} height={480} getRowId={(row) => `${row.account}:${row.sym}`} />
locale string Default undefined

BCP 47 locale for the grid's own number formatting (aggregation bar, pager row count), and the default for each column's locale. Unset, the runtime's locale.