Deck
Browse the catalog

Build / Atoms

Stack

  • atom

The workhorse layout primitive: a flex container with token-bound spacing.

Reach for Stack instead of one-off margins — it keeps rhythm consistent and means components never need layout props of their own.

import { Stack } from '@meetcard/deck'

Example

<Stack direction="row" gap={8} align="center"> <Avatar name="Ada Lovelace" /> <Text>Ada Lovelace</Text> </Stack>

Stories

Every preview below is the real component, rendered in this page from the same story Storybook runs. The width control resizes each preview's container; CSS media queries still follow the browser window, so breakpoint behaviour is worth checking in Storybook.

A column — the default direction.

Column
Source
const Column = () => <Stack gap={12}>
    <Box label="First" />
    <Box label="Second" />
    <Box label="Third" />
</Stack>;

A row, for items laid side by side.

Row
Source
const Row = () => <Stack gap={12} direction="row">
    <Box label="First" />
    <Box label="Second" />
    <Box label="Third" />
</Stack>;

Gap accepts any Deck space step, so rhythm stays token-bound.

Gap Scale
Source
const GapScale = () => (
  <Stack gap={24}>
    {([4, 8, 16, 32] as const).map((gap) => (
      <Stack key={gap} direction="row" gap={gap} align="center">
        <Text size="xs" tone="muted" style={{ width: 48 }}>
          {gap}px
        </Text>
        <Box label="A" />
        <Box label="B" />
        <Box label="C" />
      </Stack>
    ))}
  </Stack>
);

Renders as a real list when the content is one.

As List
Source
const AsList = () => <Stack gap={8} as="ul">
    <li>
        <Box label="List item one" />
    </li>
    <li>
        <Box label="List item two" />
    </li>
</Stack>;

Props

PropTypeDefaultDescription
align'start' | 'center' | 'end' | 'stretch' | 'baseline''stretch'—
as| 'div' | 'section' | 'article' | 'header' | 'footer' | 'main' | 'nav' | 'ul' | 'ol' | 'li''div'—
direction'row' | 'column''column'—
gap(typeof space)[number]16Gap as a Deck space step (px). Defaults to 16.
inlinebooleanfalseRender as inline-flex instead of flex.
justify'start' | 'center' | 'end' | 'between' | 'around''start'—
wrapbooleanfalse—

Also accepts everything from HTMLAttributes, so id, data-* and event handlers pass straight through.

Open in Storybookfor controls, the a11y panel and the interaction runner.