Molecule
SymmetricGrid
Requires <UIProvider> — Getting Started →
Installation
Install just this component (copies the source into your project, no npm dependency)
npx orn-ui add symmetric-gridOr install the whole package and import it
pnpm add orn-ui
import { SymmetricGrid } from 'orn-ui/symmetric-grid';Depends on:core (theme + icons)
Usage
- when to use — A grid of cards or tiles where a short last row would otherwise read as a broken layout.
- columns — `2` by default. Cell width is `100 / columns`, so the row still fills flush on any screen.
- balanceLastRow — Centers an incomplete last row by default instead of leaving it flush left with a gap on the right.
- gap — Applies to both axes. Leave it unset to inherit the theme's `spacing.md`.
Demo clip not recorded yet — see MEDIA.md
Variants
columns={2} — default, last row of 1 centered
<SymmetricGrid
data={ITEMS}
columns={2}
keyExtractor={(item) => item.id}
renderItem={(item) => <Tile name={item.name} />}
/>columns={3} — same 5 items, different grid
<SymmetricGrid
data={ITEMS}
columns={3}
keyExtractor={(item) => item.id}
renderItem={(item) => <Tile name={item.name} />}
/>balanceLastRow={false} — incomplete row left-aligned instead of centered
<SymmetricGrid
data={ITEMS}
columns={2}
balanceLastRow={false}
keyExtractor={(item) => item.id}
renderItem={(item) => <Tile name={item.name} />}
/>Full demo source
const variants: VariantDef[] = [
{
label: 'columns={2} — default, last row of 1 centered',
content: (
<SymmetricGrid
data={ITEMS}
columns={2}
keyExtractor={(item) => item.id}
renderItem={(item) => <Tile name={item.name} />}
/>
),
},
{
label: 'columns={3} — same 5 items, different grid',
content: (
<SymmetricGrid
data={ITEMS}
columns={3}
keyExtractor={(item) => item.id}
renderItem={(item) => <Tile name={item.name} />}
/>
),
},
{
label: 'balanceLastRow={false} — incomplete row left-aligned instead of centered',
content: (
<SymmetricGrid
data={ITEMS}
columns={2}
balanceLastRow={false}
keyExtractor={(item) => item.id}
renderItem={(item) => <Tile name={item.name} />}
/>
),
},
];
return <VariantList variants={variants} />;Props
| Name | Type | Default | Description |
|---|---|---|---|
data | T[] | — | — |
renderItem | (item: T, index: number) => ReactElement<unknown, string | JSXElementConstructor<any>> | — | — |
keyExtractor | (item: T, index: number) => string | — | — |
columns? | number | 2 | Columns per row. |
gap? | number | theme.tokens.spacing.md | Spacing between cells, on both axes. |
balanceLastRow? | boolean | true | Incomplete last row: centered (symmetric) instead of stuck to the left with a gap on the right. |
style? | StyleProp<ViewStyle> | — | — |