registry:ui · Layout
grid — blowout-proof tracks, honest disclosure
The Layout family's GRID primitive: two-dimensional track arrangement over the typed space ladder. Numeric cols compile to the blowout-proof repeat(N, minmax(0, 1fr)) atom (the grid-law vocabulary); the rows lane carries the DISCLOSURE vocabulary (collapse = 0fr, open = 1fr — the 0fr-to-1fr collapse every drawer rides; grid-template-rows animates, height:auto never does). Bespoke track forms stay in surface modules — an open string domain cannot be pre-atomized.
$npx jixoai-ui add grid
https://ui.jixoai.com/r/grid.json
usage
Usage
cols sets equal track count (1–12); rows carries the single named row state — collapse (0fr) or open (1fr); gap rides the same typed ladder as stack.
<script lang="ts">
import Grid from '@ui/grid';
</script>
<!-- three equal, blowout-proof columns -->
<Grid cols={3} gap="12">
<Card>…</Card>
<Card>…</Card>
<Card>…</Card>
</Grid>
<!-- the disclosure lane: an expander row that animates honestly -->
<Grid rows={open ? 'open' : 'collapse'} gap="8">
<button onclick={() => (open = !open)}>toggle</button>
<div>…</div>
</Grid>grid
Equal tracks under the minmax(0, 1fr) law — the playground swaps the count; a long word in one cell can never widen its track at its siblings' expense.
<script lang="ts">
import Grid from '@ui/grid';
</script>
<Grid cols={3} gap="8">
{#each cells as cell}<Cell>{cell}</Cell>{/each}
</Grid>disclosure
The disclosure lane — 0fr → 1fr
Grid can animate a row's height between zero and full without measuring anything: the row track runs 0fr (collapse) → 1fr (open) and the content keeps min-height: 0 / overflow: hidden. The site's own canvas code drawers, terminal drawers and hero disclosures ride this lane (with the rAF motion interpolant where the browser's own transition falls to the Chrome clock-freeze).
grid · disclosure lane
<script lang="ts">
import Grid from '@ui/grid';
let open = $state(false);
</script>
<button class="pill" onclick={() => (open = !open)}>
{open ? 'collapse the lane' : 'open the lane'}
</button>
<Grid rows={open ? 'open' : 'collapse'} class="w-full">
<div class="border border-border p-3 text-[12px] min-h-0 overflow-hidden">…the lane's content…</div>
</Grid>a11y
Accessibility
Like stack, a plain div carrying layout only — no role, no announcements. The disclosure lane is a LAYOUT affordance: pair it with your own button + aria-expanded/aria-controls wiring (the consumer owns the semantics; the grid owns the geometry).
Properties
| Property | Type | Default | Description |
|---|---|---|---|
| (none) | — | — | No ARIA surface: the grid is transparent layout. Disclosure semantics belong to the toggling control, not the lane. |
Universal props
| Property | Type | Default | Description |
|---|---|---|---|
| size | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | the base scale — root font-size; parts size in em |
| shape | 'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto' | 'auto' · ambient scope | corner geometry (CSS corner-shape; §14 degrade table) |
| radius | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | corner size; auto = the concentric broadcast (§3) |
| density | 'small' | 'medium' | 'large' | 'auto' | number | 'auto' · ambient scope | spacing/leading scale over the kernel channels (§4) |
| color | 'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string | 'auto' · ambient scope | the hue axis of the fixed oklch primary system (§5) |
| theme | 'light' | 'dark' | 'system' | 'auto' | 'auto' · ambient scope | light/dark profile; system = the JS-mutable global (§6) |
| elevation | 'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number | 'auto' · ambient scope | official M3 levels over the surface ladder (§7) |
| motion | 'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number | 'auto' · ambient scope | intensity across the motion kernels (§8) |
theming
Tokens
The same single token family as stack: the --jx-space-N ladder feeds every gap rung. No paint of its own.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
| --jx-space-2 … 80 | 16 rungs | the sheet ladder | Every gap atom resolves one rung — the identical ladder stack rides. |
axes
Universal props
The eight-axis surface (explicit-props): size · shape · radius · density · color · theme · elevation · motion — each axis takes named steps, auto (inherit the ambient context; stamps nothing), an exact number (px · coefficient · dp · hue per axis), or query() for responsive/container-conditional values. FIRST-TIME contract, all no-own: cols/rows/gap stay STRUCTURAL props — the axes are the paint/kinetic surface a layout container forwards.
Grid · universal props
The layout primitive forwards the tree's axes to its tenants.
<Grid size="medium">…</Grid>api
API
Four structural props plus the HTML rest — all optional, all never-ambient (the same ruling as stack: a track count has nothing meaningful to inherit).
Properties
| Property | Type | Default | Description |
|---|---|---|---|
| cols | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | — (single column) | Equal track count — the blowout-proof repeat(N, minmax(0, 1fr)) law. |
| rows | 'collapse' | 'open' | — | The disclosure lane: collapse = the 0fr track (hidden), open = the 1fr track (full). Omitted = no named row state. |
| gap | '2' | '4' | '6' | '8' | '10' | '12' | '14' | '16' | '18' | '20' | '24' | '28' | '32' | '40' | '48' | '80' | — (none) | The typed space ladder rung (token-bound; the sheet’s --jx-space-N). |
| children | Snippet | — | The grid’s contents. |
| …rest | HTMLAttributes<HTMLDivElement> | spread | Every other attribute lands on the div — consumer attributes replace, never merge. |