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

Do
import { Button, Cluster, ClusterGrow, Input } from "@hackcove/ui";

<Cluster>
  <ClusterGrow>
    <Input aria-label="Search" placeholder="Search invoices" />
  </ClusterGrow>
  <Button>Search</Button>
</Cluster>
The one item that should take the room left goes in ClusterGrow: the input fills the row and the buttons keep their size.
Don't
import { Button, Cluster, Input } from "@hackcove/ui";

<Cluster>
  <Input aria-label="Search" placeholder="Search invoices" width="sm" />
  <Button>Search</Button>
</Cluster>
Without ClusterGrow the input keeps a fixed width and the rest of the row sits empty. Wrap the input in ClusterGrow instead.

Buttons

Do
import { Button, ButtonGroup } from "@hackcove/ui";

<ButtonGroup label="Invoice" end={<Button variant="outline">Back</Button>}>
  <Button>Send</Button>
  <Button variant="outline">Download</Button>
</ButtonGroup>
A row of buttons is a ButtonGroup: it wraps on a phone and can pin one item to the end.
Don't
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

Do
Invoice 1042
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>
An empty ClusterGrow is a spacer: the title stays at the start and the actions go to the end.
Don't
Invoice 1042
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

  • gap is xs, sm (default) or md, the first steps of the Stack scale.
  • align is the cross axis: center (default), baseline for mixed text sizes, start or end. justify is the main axis: start (default), between for the two ends, end.
  • wrap lets 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 ClusterGrow is 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. Use Cluster for every other row.
  • justify="between" is for two items; with more, the middle one floats, so use a spacer.

Accessibility

  • A Cluster is a div and adds no role; the reading and tab order is the source order of its children.
  • ClusterGrow is a div too: put the labelled control inside it, with its own aria-label or Field.

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.