Stack

Vertical flex flow with token-bound gap. The headless equivalent of `<div className="flex flex-col gap-X">` with consistent spacing scale.

Installation

pnpm
pnpm dlx @hex-core/cli add stack

Usage

tsx
import { Stack } from "@/components/ui/stack"

Form sections

Lg gap separates labelled groups; nested Stack with sm gap groups label+input.

tsx
<Stack gap="lg">
  <Stack gap="sm"><Label>Email</Label><Input /></Stack>
  <Stack gap="sm"><Label>Password</Label><Input type="password" /></Stack>
  <Button>Submit</Button>
</Stack>

Centered hero

Center children horizontally for a centered call-to-action stack.

tsx
<Stack gap="md" align="center">
  <h1>Title</h1>
  <p>Subtitle</p>
  <Button>Get started</Button>
</Stack>

API Reference

PropTypeDefaultDescription
gap
"xs" | "sm" | "md" | "lg" | "xl"mdVertical spacing between children, bound to `--gap-*` tokens.
align
"start" | "center" | "end" | "stretch"stretchCross-axis alignment (CSS `align-items`).
justify
"start" | "center" | "end" | "between"startMain-axis distribution (CSS `justify-content`).

AI Guidance

When to use

Use anywhere you'd write `flex flex-col gap-X`. Default for vertical lists of dissimilar items (label + input + helper text), section bodies, sidebar items, button groups stacked vertically.

When not to use

Don't use for tabular data — use `<table>` or DataTable. Don't use for grid-like layouts — use `Grid`. Don't reach for `Stack` when a single child needs no spacing — just render the child.

Common mistakes

  • Setting `gap="md"` then adding `mt-*` / `space-y-*` on individual children — pick one spacing system
  • Using `align="center"` and wondering why children expand to full width — that's the `stretch` default for cross-axis
  • Nesting Stack inside Stack with the same gap when one Stack with two children would suffice

Accessibility

Stack is presentational. Wrap stacked navigation links in a `<nav>`, stacked form fields in a `<form>`, etc. — Stack does not contribute landmark semantics.

Related components

Token budget: 250