KQ-1093 · CROSS/GRID
Cross Grid
A data table with a crosshair: the pointed cell lights a band along its row and a band down its column, and moving from cell to cell slides both on a spring at the house snap ratio (stiffness is a prop; its default is snap itself) rather than jumping. With followLabels, copies of the column header and the row label detach from their home and travel to sit just above and just left of the cell, so a far corner reads without tracing; appear and disappear are opacity tweens. It is a real grid: one cell is the tab stop, arrow keys, Home/End, Ctrl+Home/End and PageUp/PageDown move focus, and focus drives the same crosshair, labels and tick.
| Depot | Mon | Tue | Wed | Thu | Fri |
|---|---|---|---|---|---|
| Coldbrook | 412 | 388 | 455 | 431 | 502 |
| Basin Yard | 296 | 318 | 341 | 305 | 377 |
| Fern Hill | 184 | 205 | 199 | 226 | 248 |
| Gauge Row | 367 | 402 | 412 | 389 | 451 |
| Waylight | 523 | 498 | 547 | 561 | 604 |
point at a cell or use the arrow keys
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/cross-grid
Props
- label
- string
- default —
- The table's accessible name.
- columns
- { id: string; label: string }[]
- default —
- Column headers, in order.
- rows
- { id: string; label: string; values: number[] }[]
- default —
- Row labels and one value per column, in column order.
- corner
- string
- default ""
- Text for the top-left header cell, over the row labels.
- format
- (value: number) => string
- default Intl.NumberFormat("en-US")
- How a value is printed.
- density
- "compact" | "cosy"
- default "cosy"
- Row height (28 or 36px) and type size.
- followLabels
- boolean
- default true
- Copies of the column header and row label travel to sit beside the pointed cell.
- highlight
- "bar" | "glow"
- default "bar"
- Uniform bands, or bands that glow brightest where they cross.
- stiffness
- number
- default 640
- Spring stiffness for the crosshair and the travelling labels, at the house snap damping ratio.
- active / defaultActive
- { row: string; column: string } | null
- default — / null
- Controlled / uncontrolled crosshair cell, by row and column id.
- onActiveChange
- (cell: { row: string; column: string } | null) => void
- default —
- Fires from the pointer, tap or key that moved or cleared the crosshair.
- sound
- boolean
- default false
- A tick per cell, climbing a pentatonic step per column and panned by the column's place.
- className
- string
- default —
- Classes for the table's frame.
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | — | The table's accessible name. |
| columns | { id: string; label: string }[] | — | Column headers, in order. |
| rows | { id: string; label: string; values: number[] }[] | — | Row labels and one value per column, in column order. |
| corner | string | "" | Text for the top-left header cell, over the row labels. |
| format | (value: number) => string | Intl.NumberFormat("en-US") | How a value is printed. |
| density | "compact" | "cosy" | "cosy" | Row height (28 or 36px) and type size. |
| followLabels | boolean | true | Copies of the column header and row label travel to sit beside the pointed cell. |
| highlight | "bar" | "glow" | "bar" | Uniform bands, or bands that glow brightest where they cross. |
| stiffness | number | 640 | Spring stiffness for the crosshair and the travelling labels, at the house snap damping ratio. |
| active / defaultActive | { row: string; column: string } | null | — / null | Controlled / uncontrolled crosshair cell, by row and column id. |
| onActiveChange | (cell: { row: string; column: string } | null) => void | — | Fires from the pointer, tap or key that moved or cleared the crosshair. |
| sound | boolean | false | A tick per cell, climbing a pentatonic step per column and panned by the column's place. |
| className | string | — | Classes for the table's frame. |