Lattice Grid Buy a licence

developer guide

Grid Lines, Corners and Cell Alignment

Grid lines can run both ways, one way, or not at all, rows can be striped, and the frame can be rounded to match the panel it sits in. Where a row is taller than its text, a cell can align to the top, the middle or the bottom of it.

Developer guideTheming and density › Grid Lines, Corners and Cell Alignment

Grid lines and corners

Two settings that change how the grid is drawn rather than what it draws.

Rules between cells, and rounded corners

createGrid(element, {
  columns, rows,
  gridLines: 'both',      // 'horizontal' (default), 'vertical', 'both', 'none'
  cornerRadius: true,      // or a number of pixels, or a CSS length
});

gridLines chooses which rules are drawn between cells. 'horizontal' is the default and is what the grid has always drawn; vertical rules between body cells are additive, so the default is unchanged and nothing moves on upgrade. 'rows' and 'columns' are accepted as aliases. Only the rules between data are affected: the header underline and the seams beside pinned columns are structure rather than decoration, and removing them would make the pinned regions look detached.

cornerRadius rounds the grid's outer corners: true adopts the theme's own radius, a number is a count of pixels, and a string is used as written, so '0 0 8px 8px' rounds only the bottom. The body is clipped to match, so a row scrolling past a rounded corner is cut by it rather than squaring it off.

Zebra striping (opt-in)

createGrid(element, {
  columns, rows,
  stripedRows: true,       // shade alternate data rows; off by default
});

stripedRows shades every other data row. It is strictly opt-in and off by default, so a grid that never mentions it looks exactly as it did on upgrade. Parity is decided by each row's logical index rather than its position in the DOM: rows are virtualised and recycled, so a :nth-child rule would repaint the stripe onto whichever row landed in an odd slot after a scroll, and a logical-index stripe keeps a row shaded consistently across a scroll and across the left-pinned, centre and right-pinned segments of the same row. Group headings, group footers and the grand total are structure rather than data, so they are never striped. The stripe uses the theme's --lattice-surface-alt token, which every palette defines, so dark, high-contrast and terminal are correct without any extra rule, and both selection and hover still win over it.

Vertical alignment

verticalAlign is the vertical counterpart to the per-column align: where align places cell content across the column (start, center, end), verticalAlign places it down the row - 'top', 'middle' or 'bottom'. It is a grid-level default with a per-column override: set it on the grid to align every column, and a column's own verticalAlign (or cell.verticalAlign) wins for that column alone. center and centre are accepted as synonyms for middle, the same leniency align gives the horizontal names.

Omitted, the grid keeps the placement it has always had - content centred in a fixed-height row and top-aligned in an autoHeight row - so a grid that never mentions it is unchanged on upgrade. Where it earns its keep is a tall or autoHeight grid: a wrapped-text column can sit at the top while its single-line neighbours are middle, rather than every value floating in the middle of a tall row. The value beats the auto-height rule, so a column asked to sit middle does so even when the row is stretched to fit a wrapped sibling.

A grid default, with one column overriding it

const { createHeadlessGrid } = await import('../packages/core/src/index.js');

const grid = createHeadlessGrid({
  verticalAlign: 'middle',                 // the default for every column
  columns: [
    { field: 'name' },                       // follows the default: middle
    { field: 'note', verticalAlign: 'bottom' }, // this column overrides it
  ],
  rows: [{ name: 'a', note: 'b' }],
  rowKey: 'name',
});

// The resolved value the renderer reads for each column.
const a = grid.columns.get('name').verticalAlign;
const b = grid.columns.get('note').verticalAlign;
grid.destroy();
return `${a}, ${b}`;