Cluster
A horizontal row a fixed gap apart, and ClusterGrow for the item that takes the room left.
Overview
Items in a line that are not buttons: a label beside a value, an input beside its actions, a row of pills.
Fill row
import { Button, Cluster, ClusterGrow, Input } from "@hackcove/ui";
<Cluster>
<ClusterGrow>
<Input aria-label="Search" placeholder="Search invoices" />
</ClusterGrow>
<Button>Search</Button>
</Cluster>ClusterGrow: the input fills the row and the buttons keep their size.import { Button, Cluster, Input } from "@hackcove/ui";
<Cluster>
<Input aria-label="Search" placeholder="Search invoices" width="sm" />
<Button>Search</Button>
</Cluster>ClusterGrow the input keeps a fixed width and the rest of the row sits empty. Wrap the input in ClusterGrow instead.Buttons
import { Button, ButtonGroup } from "@hackcove/ui";
<ButtonGroup label="Invoice" end={<Button variant="outline">Back</Button>}>
<Button>Send</Button>
<Button variant="outline">Download</Button>
</ButtonGroup>ButtonGroup: it wraps on a phone and can pin one item to the end.import { Button, Cluster } from "@hackcove/ui";
<Cluster>
<Button>Send</Button>
<Button variant="outline">Download</Button>
<Button variant="outline">Back</Button>
</Cluster>Cluster is for every other row; a row of buttons in it does not wrap and has no end slot.Spacer
import { BodyStrong, Button, Cluster, ClusterGrow } from "@hackcove/ui";
<Cluster>
<BodyStrong>Invoice 1042</BodyStrong>
<ClusterGrow />
<Button size="sm" variant="outline">
Edit
</Button>
<Button size="sm" variant="outline" tone="danger">
Remove
</Button>
</Cluster>ClusterGrow is a spacer: the title stays at the start and the actions go to the end.import { BodyStrong, Button, Cluster } from "@hackcove/ui";
<Cluster justify="between">
<BodyStrong>Invoice 1042</BodyStrong>
<Button size="sm" variant="outline">
Edit
</Button>
<Button size="sm" variant="outline" tone="danger">
Remove
</Button>
</Cluster>justify="between" spreads three items evenly, so the middle one floats away from the group it belongs to.Usage
gapisxs,sm(default) ormd, the first steps of theStackscale.alignis the cross axis:center(default),baselinefor mixed text sizes,startorend.justifyis the main axis:start(default),betweenfor the two ends,end.wraplets the items flow onto more lines on a phone; without it the row stays on one line.- Wrap the one item that should fill the row in
ClusterGrow; it can shrink to nothing, so a long value truncates and the others stay. - An empty
ClusterGrowis a spacer: what follows it goes to the end. - A row of buttons is a
ButtonGroup, which wraps on a phone and can pin an item to the end. UseClusterfor every other row. justify="between"is for two items; with more, the middle one floats, so use a spacer.
Accessibility
- A
Clusteris adivand adds no role; the reading and tab order is the source order of its children. ClusterGrowis adivtoo: put the labelled control inside it, with its ownaria-labelorField.
API
Cluster
A horizontal row of items a fixed gap apart: the row counterpart of Stack. align is the cross axis (center default, baseline for mixed text sizes, start, end) and justify the main one (start default, between to push the first and last items to the two ends, end). wrap lets the items flow onto further lines on a narrow viewport (off by default, so a row stays on one line). Put one ClusterGrow around the item that takes the room left over, an input beside its buttons, say. An empty ClusterGrow is a spacer that pushes what follows it to the end. ButtonGroup is the row for buttons; use Cluster for any other row.
align- Type
"center" | "end" | "start" | "baseline"- Default
center
gap- Type
"sm" | "md" | "xs"- Default
sm
justify- Type
"end" | "start" | "between"- Default
start
wrap- Type
boolean- Default
false
ClusterGrow
The one child of a Cluster that grows to the room left in the row. It can shrink to nothing (min-w-0), so the items beside it stay on the line and a long value truncates instead of pushing them out. Empty, it is a spacer.