# Board grid

The editable grid of WerkOS boards, where a team keeps hiring projects, candidates and work permits: one row per item, one column per field, edited in place.

* Kind: data
* Page: https://design.werklist.com/data/board-grid
* Version: 2.1.2

## When to use it

* Items that share fields and that people add, edit and compare
* Boards of hiring projects, candidates, companies and tasks, and the boards a team makes for itself

## When not to use it

* Final figures that are read or printed: use the report table
* A short run of items without columns: use a list
* Anything sent outside WerkOS: use a report table

## Rules

* Row and column rules in --border-rule, no stripes, no outer border
* Headers are centered on every column, numeric ones included
* Figures are right aligned, 14 px, weight 400, in tabular digits and in the reader's language. A negative takes the true minus sign (U+2212) and is never red
* The column header and the group header stay pinned on every board, under the app header
* A blank cell means nobody has filled it. Zero prints 0
* Below 640 px the card list replaces the grid. A tap on a status, a person, a date or a timeline opens a sheet
* The frozen name column is an option on each board, not the default

## Anatomy

* Row: 36 px compact (the default), 52 px comfortable, 76 px tall, plus a 1 px rule
* Row rule: 1 px under each row (--border-rule)
* Column rule: 1 px on the left of each data, header and footer cell, none on the trailing gutter (--border-rule)
* Column header: 13 px, weight 500, centered on every column, sentence case, 40 px plus its rule, 6 px between a title and its sort arrow. A title cut short shows in full in a tooltip (--text-label)
* Name header: a select all checkbox at the start, always shown, mixed when some rows are chosen, and the board's word for an item centered in the rest (--brand-blue)
* Name column: 280 px, 560 px on the boards of a WerkOS module, at least 140 px when resized
* Name cell: 14 px text, 12 px padding, 8 px gap, cut short at the end (--text)
* Data column: at least 60 px. Default widths: text 220, numbers 140, status 200, country 180, date 150, formula 160, timeline 220, time tracking 190 px
* Data cell padding: 8 px (--space-2)
* Figure: 14 px, weight 400, tabular digits, right aligned, with a currency code after it in 12 px muted ink (--text)
* Group header row: 40 px, with a 14 px gap above it on module boards. Chevron 16 px, title 14 px weight 700 in the group color, count 12 px. Pinned while its rows scroll, on --surface-1 at 85 percent with a 12 px blur (--text-muted)
* Row marker: 4 by 16 px, full radius, in the group color (--radius-full)
* Summary footer: 48 px with a rule above and below. Label 11 px in sentence case, value 14 px weight 500 in tabular digits, right aligned (--text-muted)
* Add item row: 40 px
* Trailing gutter: 44 px, for adding a column and deleting a row
* Frame: radius 12 px, no border, no shadow (--surface-1)
* Row checkbox: 14 px box, radius 4 px, with a 1 px edge: ink at 55 percent on white in light, white at 20 percent on --surface-control in dark. Checked, it fills with --brand-blue and shows an 11 px white tick. It appears on row hover, stays while the row is selected and has a 44 px target on touch screens (--radius-sm)
* Phone card: below 640 px. Radius 12 px, padding 12 px, 10 px gap, a soft shadow, no border. The name in 15 px weight 500, then one row of up to 4 fields: labels 11 px centered, values 36 px tall, a status in 12 px type (--surface-1)
* Phone sheet: rises from the bottom on the raised glass, with 16 px top corners and a 40 by 4 px grab handle. The column title in 16 px weight 700 over the item name in 12 px. One 44 px row per label at full radius, 14 px weight 500, with a 16 px check on the chosen one (--glass-fill-raised)

## Variants

* Team board: A board a team makes for itself: the toolbar inside the grid, rows to add, column menus and a row height switch
* Module board: A board of a WerkOS module, which holds its own toolbar: no add rows, no column menus, no row height switch
* Frozen name column: An option on a board that scrolls sideways, off by default

## Sizes

* Compact: height 36 px
* Comfortable: height 52 px
* Tall: height 76 px

## States

* Hover: a row fill of ink at 3 percent in light and of white at 3 percent in dark, on pointer devices only
* Selected row: brand blue at 25 percent over the row, with no hover on top. A frozen name cell mixes the tint into --surface-1 so it stays opaque (--brand-blue, --surface-1)
* Range: brand blue at 15 percent per cell (--brand-blue)
* Active cell: a 1 px inset ring of --brand-blue, or the 2 px focus ring while the keyboard is in the grid. An 8 px square fill handle at the bottom right, radius 1 px, ringed with 1 px of --surface-1 (--brand-blue, --focus-ring, --focus-ring-width, --surface-1)
* Editing: an editor over the cell on --surface-strong, 4 px inside its edges, holding a 28 px field: radius 6 px, a fill of ink at 5 percent in light and of white at 6 percent in dark, an inset 1 px ring of light brand blue, no shadow (--surface-strong, --radius-md)
* Group collapsed: the chevron points right and the rows and the footer are hidden
* Empty board: a card in place of the grid, without the column header. A headline of 20 px, 26 px from 640 px, weight 700, tracking minus 0.02 em. One sentence of 14 px, 16 px from 640 px, in --text-muted. One 44 px primary button and no icon (--text-muted)
* Filtered to nothing: the line No items match these filters in --text-muted and a quiet Clear filters button in place of the groups (--text-muted)
* Loading: skeleton rows at the board's row height inside a 12 px frame, with --border-rule lines and a soft shimmer (--border-rule)

## Keyboard

* Arrow keys: Move the active cell. The first press lands on the first cell
* Shift with an arrow: Extend the range
* Tab, Shift Tab: Next or previous cell, wrapping to the next row. After the last cell, Tab leaves the grid
* Home, End: First or last cell of the row
* Ctrl or Cmd with Home, End: First or last cell of the board
* Enter, F2: Edit the active cell
* Escape: Close the editor and clear the range
* Delete, Backspace: Clear the range
* Ctrl or Cmd with C, V, D, A: Copy, paste, fill down, select all
* Ctrl or Cmd with Z: Undo
* Ctrl or Cmd with Shift Z, or with Y: Redo
* Shift F10, the menu key: Open the row menu, which holds each action shown on hover

## Accessibility

* The board is a grid named by its title, with aria-rowcount and aria-colcount
* Each row has role row and its aria-rowindex
* The name cell is the row header
* Column headers carry aria-sort on the sorted column
* Cells are grid cells, with aria-selected inside a range and aria-readonly on read only columns
* Of the cells, only the active one is in the tab order
* Each group title is a button with aria-expanded that folds its rows
* A group header is a row whose header names the group and its count
* A status is read by its label, never its color. An empty status shows a hyphen on gray and is read as Empty
* Scroll padding matches the pinned headers, so a focused cell never hides behind them
* 44 px targets on touch screens

## Content

* Headers are short nouns in sentence case with no end punctuation
* The empty board reads This board is empty and Add your first project to get started. Its button reads Add your first project, with the board's own word for an item
* When filters hide every row, the line reads No items match these filters and the button reads Clear filters
* Footer labels name the aggregate in sentence case: Sum, Average, Median, Lowest, Highest

## Tokens

* --border-rule
* --text
* --text-label
* --text-muted
* --surface-1
* --surface-strong
* --brand-blue
* --focus-ring
* --focus-ring-width
* --radius-xl
* --radius-sm
* --radius-full
* --space-2
* --space-3
* --radius-md
* --surface-control
* --glass-fill-raised
* --overlay
* --layer-sticky
