Skip to main content

Stack

Stack arranges content in a row or column, like the fields of a form or the actions in a toolbar. It controls spacing, alignment, and wrapping, and can add dividers between items.

Import

import { Stack } from '@vortexlabs/vortex';
import type { StackProps } from '@vortexlabs/vortex';

Display

<Stack direction="row" gap={3}>{children}</Stack>

Other links

One
Two
Three
<Stack
  direction="row"
  gap={3}
>
  <Placeholder width={20}>One</Placeholder>
<Placeholder width={20}>Two</Placeholder>
<Placeholder width={20}>Three</Placeholder>
</Stack>

Features

  • Arranges children in rows or columns.
  • Supports responsive direction, alignment, and wrapping.
  • Grows, reorders, and sizes items with Stack.Item.
  • Adds dividers between children.
  • Renders different HTML elements with as.

Direction

Stack arranges children in a column by default. Use direction="row" for a horizontal layout.

One
Two
One
Two
import { Placeholder, Stack } from "@vortexlabs/vortex";

<Stack direction="row" gap={3}>
  <Placeholder width={20}>One</Placeholder>
  <Placeholder width={20}>Two</Placeholder>
</Stack>
<Stack gap={3}>
  <Placeholder>One</Placeholder>
  <Placeholder>Two</Placeholder>
</Stack>

Responsive Direction

Pass breakpoint objects to switch from a column to a row on larger screens.

Flexible content
<Stack
  direction={{ xs: "column", sm: "row" }}
  gap={{ xs: 3, md: 6 }}
  align={{ xs: "stretch", sm: "center" }}
>
  <Stack.Item grow>
    <Placeholder>Flexible content</Placeholder>
  </Stack.Item>
  <Button>Continue</Button>
</Stack>

Alignment

justify spaces items along the stack's direction. align positions them on the other axis.

Start
Center
End
<Stack
  direction="row"
  justify="space-between"
  align="center"
  gap={3}
  padding={4}
  backgroundColor="surface-subtlest"
>
  <Placeholder width={20} height={16}>Start</Placeholder>
  <Placeholder width={20} height={10}>Center</Placeholder>
  <Placeholder width={20} height={12}>End</Placeholder>
</Stack>

Wrapping

Rows wrap onto new lines when they run out of space. Set wrap={false} to keep items on one line, and add overflow="auto" to let the row scroll.

Research
Design
Development
Review
Research
Design
Development
Review
<Stack direction="row" gap={3}>
  <Placeholder width="9rem">Research</Placeholder>
  <Placeholder width="9rem">Design</Placeholder>
  <Placeholder width="9rem">Development</Placeholder>
  <Placeholder width="9rem">Review</Placeholder>
</Stack>
<Stack direction="row" wrap={false} overflow="auto" gap={3}>
  <Placeholder width="9rem">Research</Placeholder>
  <Placeholder width="9rem">Design</Placeholder>
  <Placeholder width="9rem">Development</Placeholder>
  <Placeholder width="9rem">Review</Placeholder>
</Stack>

A Stack.Item with grow or gapBefore="auto" also keeps a row on one line.

Spacing and Surfaces

Use padding for space inside the stack and gap for space between children. Both use theme spacing units.

Project update
The new release is ready for review.
import { Button, Stack, Text } from "@vortexlabs/vortex";

<Stack
  gap={3}
  padding={{ xs: 4, md: 6 }}
  backgroundColor="surface-subtlest"
  borderColor="default"
  borderRadius="md"
>
  <Text weight="medium">Project update</Text>
  <Text>The new release is ready for review.</Text>
  <Stack direction="row" gap={3}>
    <Button>Review release</Button>
    <Button variant="secondary">Later</Button>
  </Stack>
</Stack>

Flexible Items

Stack.Item grow fills the available space. gapBefore="auto" pushes an item to the end.

Growing item
Fixed
3 items selected
<Stack direction="row" gap={3}>
  <Stack.Item grow>
    <Placeholder>Growing item</Placeholder>
  </Stack.Item>
  <Placeholder width={20}>Fixed</Placeholder>
</Stack>
<Stack direction="row" gap={3} align="center">
  <Text>3 items selected</Text>
  <Stack.Item gapBefore="auto">
    <Button variant="secondary">Clear</Button>
  </Stack.Item>
</Stack>

Order

Set order on a Stack.Item to move it without changing the source, like showing a cover image first on small screens. To flip a whole stack, use row-reverse or column-reverse.

Article text
Cover image
<Stack direction={{ xs: "column", md: "row" }} gap={3}>
  <Stack.Item>
    <Placeholder>Article text</Placeholder>
  </Stack.Item>
  <Stack.Item order={{ xs: -1, md: 0 }}>
    <Placeholder>Cover image</Placeholder>
  </Stack.Item>
</Stack>

Columns

Set columns on a Stack.Item to give it a share of a 12-column row. Use a breakpoint object to change the split by screen size.

Main content
Sidebar
<Stack direction="row" gap={3}>
  <Stack.Item columns={{ xs: 12, md: 8 }}>
    <Placeholder>Main content</Placeholder>
  </Stack.Item>
  <Stack.Item columns={{ xs: 12, md: 4 }}>
    <Placeholder>Sidebar</Placeholder>
  </Stack.Item>
</Stack>

Dividers

Set divider to add a line between children. Rows get vertical lines; columns get horizontal ones.

Account settings
Notification preferences
Billing details
<Stack divider gap={3}>
  <Text>Account settings</Text>
  <Text>Notification preferences</Text>
  <Text>Billing details</Text>
</Stack>

Semantic Elements

Use as to render a semantic element and attributes for its native attributes. For a list, render each child as a Stack.Item with as="li".

  • Review changes
  • Run checks
  • Publish release
<Stack as="ul" gap={3} attributes={{ "aria-label": "Release checklist" }}>
  <Stack.Item as="li">Review changes</Stack.Item>
  <Stack.Item as="li">Run checks</Stack.Item>
  <Stack.Item as="li">Publish release</Stack.Item>
</Stack>

Accessibility

Description
Stack adds no role or keyboard behavior; choose a semantic element with as when the content is a list or region.
Reverse directions and order change visual placement only; reading and keyboard order follow the source.
Dividers render role="separator" elements; avoid divider when as is ul or ol.