Design-system component · Layout

DsStack

A flex column or row whose gaps come only from the spacing scale. The default way to space things.

import DsStack from "#core/design-system/components/DsStack.vue";

Demo

column, gap 2 (10px)
Item 1
Item 2
Item 3
row, gap 4 (20px), centered
Item 1
Item 2
Item 3

Use it whenever children need space between them: a card's content, a form, a list of results, a row of chips. Space comes from the stack's gap, never from margins on the children. That keeps every gap on the 5px scale.

Use plain tw-grid for real grids, such as a results grid with columns.

Usage

<script setup lang="ts">
import DsStack from "#core/design-system/components/DsStack.vue";
</script>

<template>
  <DsStack gap="4">
    <h2 class="tw-text-20 tw-font-semibold">Title</h2>
    <DsStack direction="row" gap="2" align="center" wrap>
      <span>Chip</span>
      <span>Chip</span>
    </DsStack>
  </DsStack>
</template>

Do / Don't

  • Do nest stacks: a column of rows is the usual card layout.
  • Its direction is fixed (it's set inline). For a row that becomes a column at a breakpoint, use classes instead: tw-flex tw-flex-col tw-gap-4 md:tw-flex-row.
  • Don't add tw-mt-* or tw-mb-* to children to fix spacing. Change the stack's gap, or split it into two stacks.

API

PropTypeDefaultDescription
direction?"column" | "row""column"Lay children out top-to-bottom (`column`) or left-to-right (`row`).
gap?SpaceKey"2"Space between children: a key of the spacing scale (`"2"` is 10px).
align?"center" | "stretch" | "baseline" | "start" | "end""stretch"Cross-axis alignment.
justify?"center" | "start" | "end" | "between""start"Main-axis distribution.
wrap?booleanfalseLet a row wrap onto more lines.
as?string"div"The element to render, e.g. `ul` for a list or `section`.

Slots: default