Stack
The one-dimensional flex layout primitive — the answer to
<div style="display:flex">. Every spacing value is a
design token, so AI never invents a magic-number gap. Renders a plain
<div> (or as) in the browser.
Flex layout (row)
Stack is flexbox. The outer row sets width="full" so
justify="between" has room to push the identity group away
from the action buttons; nested Stacks group each side.
justify needs free space to distribute — without a width the
row only hugs its content.
AL
Ada Lovelace
Owner
import { Stack, Avatar, Text, Button } from "@usevyre/react";
<Stack width="full" direction="row" gap="md" align="center" justify="between">
<Stack direction="row" gap="sm" align="center">
<Avatar fallback="AL" />
<Stack direction="column" gap="none">
<Text>Ada Lovelace</Text>
<Text size="sm" color="muted">Owner</Text>
</Stack>
</Stack>
<Stack direction="row" gap="sm" align="center">
<Button variant="ghost">Cancel</Button>
<Button variant="primary">Save</Button>
</Stack>
</Stack> <script setup>
import { Stack, Avatar, Text, Button } from "@usevyre/vue";
</script>
<template>
<Stack width="full" direction="row" gap="md" align="center" justify="between">
<Stack direction="row" gap="sm" align="center">
<Avatar fallback="AL" />
<Stack direction="column" gap="none">
<Text>Ada Lovelace</Text>
<Text size="sm" color="muted">Owner</Text>
</Stack>
</Stack>
<Stack direction="row" gap="sm" align="center">
<Button variant="ghost">Cancel</Button>
<Button variant="primary">Save</Button>
</Stack>
</Stack>
</template> Column
Set direction="column" for a vertical stack.
Step 1Step 2Step 3
import { Stack, Badge } from "@usevyre/react";
<Stack direction="column" gap="sm">
<Badge variant="success">Step 1</Badge>
<Badge variant="success">Step 2</Badge>
<Badge>Step 3</Badge>
</Stack> <script setup>
import { Stack, Badge } from "@usevyre/vue";
</script>
<template>
<Stack direction="column" gap="sm">
<Badge variant="success">Step 1</Badge>
<Badge variant="success">Step 2</Badge>
<Badge>Step 3</Badge>
</Stack>
</template> Wrapping & per-axis gap
wrap="wrap" lets children flow onto multiple lines;
rowGap and columnGap control each axis
independently — both token-locked.
reactvuetypescriptdesign-systemsaccessibilitytokens
import { Stack, Tag } from "@usevyre/react";
<Stack wrap="wrap" rowGap="md" columnGap="sm">
<Tag>react</Tag>
<Tag>vue</Tag>
<Tag>typescript</Tag>
<Tag>design-systems</Tag>
<Tag>accessibility</Tag>
<Tag>tokens</Tag>
</Stack> <script setup>
import { Stack, Tag } from "@usevyre/vue";
</script>
<template>
<Stack wrap="wrap" rowGap="md" columnGap="sm">
<Tag>react</Tag>
<Tag>vue</Tag>
<Tag>typescript</Tag>
<Tag>design-systems</Tag>
<Tag>accessibility</Tag>
<Tag>tokens</Tag>
</Stack>
</template> Props
Props
| Prop | Type | Default | Description |
|---|---|---|---|
direction | "row" | "column" | "row-reverse" | "column-reverse" | "row" | flex-direction. |
inline | boolean | false | Render as inline-flex instead of flex. |
gap | "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "md" | Space between children. Maps to a --vyre-spacing token — never a raw number. |
rowGap | "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | — | row-gap override (token). |
columnGap | "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | — | column-gap override (token). |
align | "start" | "center" | "end" | "stretch" | "baseline" | "stretch" | align-items (cross axis). |
justify | "start" | "center" | "end" | "between" | "around" | "evenly" | "start" | justify-content (main axis). |
alignContent | "start" | "center" | "end" | "stretch" | "between" | "around" | "evenly" | — | align-content (multi-line cross axis). |
alignSelf | "auto" | "start" | "center" | "end" | "stretch" | "baseline" | — | align-self for this element. |
wrap | "nowrap" | "wrap" | "wrap-reverse" | "nowrap" | flex-wrap. |
grow | number | — | flex-grow. |
shrink | number | — | flex-shrink. |
basis | "none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "auto" | "content" | "0" | — | flex-basis — token or keyword. |
width | "auto" | "full" | "fit" | "screen" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | — | Width — keyword (full=100%, fit, screen) or fixed-rem token size. Replaces inline width style. |
height | "auto" | "full" | "fit" | "screen" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | — | Height — keyword or fixed-rem token size. Replaces inline height style. |
as | string | "div" | HTML tag to render. Still a real DOM element. |
class | string | — | Additional CSS class. |
Valid props
| Prop | Values | Default |
|---|---|---|
direction | "row"|"column"|"row-reverse"|"column-reverse" | row |
gap | "none"|"xs"|"sm"|"md"|"lg"|"xl"|"2xl" | md |
rowGap | "none"|"xs"|"sm"|"md"|"lg"|"xl"|"2xl" | — |
columnGap | "none"|"xs"|"sm"|"md"|"lg"|"xl"|"2xl" | — |
align | "start"|"center"|"end"|"stretch"|"baseline" | stretch |
justify | "start"|"center"|"end"|"between"|"around"|"evenly" | start |
alignContent | "start"|"center"|"end"|"stretch"|"between"|"around"|"evenly" | — |
alignSelf | "auto"|"start"|"center"|"end"|"stretch"|"baseline" | — |
wrap | "nowrap"|"wrap"|"wrap-reverse" | nowrap |
basis | "none"|"xs"|"sm"|"md"|"lg"|"xl"|"2xl"|"auto"|"content"|"0" | — |
width | "auto"|"full"|"fit"|"screen"|"xs"|"sm"|"md"|"lg"|"xl"|"2xl" | — |
height | "auto"|"full"|"fit"|"screen"|"xs"|"sm"|"md"|"lg"|"xl"|"2xl" | — |
inline | true|false | false |
Common AI mistakes
- <div style={{ display: 'flex', gap: 12 }}>→ Use <Stack gap="md"> — gap is a token
- gap={12} or gap="12px"→ Use gap="none|xs|sm|md|lg|xl|2xl"
- direction="vertical" / "horizontal"→ Use direction="row" or "column" (also row-reverse / column-reverse)
- style={{ width: "100%" }} / style={{ height: 320 }}→ Use the width / height prop: width="full", width="md", height="screen", etc.
Quick examples
Row, vertically centered, spaced apart
<Stack direction="row" gap="md" align="center" justify="between">
<Avatar src={user.avatar} />
<Text>{user.name}</Text>
<Button>Edit</Button>
</Stack>Wrapping grid-ish gallery with per-axis gap
<Stack wrap="wrap" rowGap="lg" columnGap="md">
{tags.map((t) => <Tag key={t}>{t}</Tag>)}
</Stack>