<!-- Generated by scripts/gen-docs.mts from the JSDoc in registry/. Do not edit; run `pnpm run docs`. -->

# Stack

Lays its children out top to bottom with an even gap. It is layout only: it replaces the `flex flex-col gap-4` an agent would otherwise write by hand.

```tsx
import { Stack } from "@/components/ouro/stack/stack";
```

## Example

```tsx
<Stack gap="sm">
  <Heading level={2}>Ingredients</Heading>
  <Text>Two pounds of short ribs.</Text>
</Stack>
<Stack as="ul" gap="xs">{items.map((item) => <li key={item.id}>{item.name}</li>)}</Stack>
```

## Use instead when

- Use `Row` instead for a horizontal layout, `Card` when the group needs a surface, and `ItemGroup` for a list of rows with media, titles and actions.

## Props

Type: `StackProps`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `align` | `"start" \| "center" \| "end" \| "stretch"` | `"stretch"` | Where the children sit across the Stack. `stretch` makes each child full width. |
| `as` | `"form" \| "div" \| "aside" \| "fieldset" \| "footer" \| "header" \| "main" \| "nav" \| "ol" \| "section" \| "ul"` | `"div"` | The element to render. A `ul` or `ol` loses its bullets and indent, a `fieldset` its border. |
| `children` | `ReactNode` |  | The children, laid out top to bottom. |
| `className` | `string` |  | Layout only: margins, width, grid placement (`mt-4`, `max-w-md`). Appearance classes warn in development: a Stack has no look; use `Card` for a surface. So do the flex classes the props own: use `gap`, `align` and `justify`, not `gap-*`, `items-*` or `justify-*`, and `<Row>`, not `flex-row`. |
| `gap` | `"sm" \| "md" \| "lg" \| "xl" \| "xs" \| "none"` | `"md"` | Space between the children: `xs` 4px, `sm` 8px, `md` 16px, `lg` 24px, `xl` 32px. |
| `justify` | `"start" \| "center" \| "end" \| "between"` | `"start"` | Where the children sit down the Stack, when it is taller than they are. |
| `ref` | `Ref<HTMLElement>` |  | Reaches the rendered element. |

## Native attributes

Also accepts the attributes in React's `HTMLAttributes` (`id`, `aria-*`, event handlers), passed to the rendered element, except those named on this page.

## Don't use

These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.

- `alignItems`: Not a prop. Ouro UI uses `align`: `<Stack align="center">`.
- `direction`: Not a prop. Stack is vertical; for a horizontal layout use `<Row>`.
- `justifyContent`: Not a prop. Ouro UI uses `justify`: `<Stack justify="between">`.
- `spacing`: Not a prop. Ouro UI uses `gap`: `<Stack gap="sm">`.

## `className` is for layout only

Pass margins, width and grid placement (`mt-4`, `w-full`, `col-span-2`). Your classes always win over Ouro UI's: Stack merges `className` last with `cn` (tailwind-merge), so a class that conflicts with its own replaces it.[^layout-classes]

Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (`hover:`, `sm:`) and any `!` are removed, it starts with `bg-`, `text-`, `border-`, `rounded-`, `shadow-`, `font-`, `ring-`, `from-`, `via-`, `to-`, `fill-` or `stroke-`, or is `border`, `rounded`, `shadow` or `ring`, or has a `dark:` variant. Text wrapping, overflow and table layout classes (`text-wrap`, `text-ellipsis`, `border-collapse`) are layout and do not warn.

Alignment classes (`text-center`) warn too: use the `align` prop.

[^layout-classes]: test:registry/ouro/components/ouro/stack/stack.test.tsx::Stack > passes HTML attributes and a ref through, and lets layout classes win verify:testExists(registry/ouro/components/ouro/stack/stack.test.tsx::Stack > passes HTML attributes and a ref through, and lets layout classes win)
