Components · Layout
Flex
A flexbox container with the DS spacing scale baked into `gap` — direction, align, justify, wrap.
Examples
Direction
Justify
Align
Gap
Flex · direction row · gap middle · justify space-between · align center
One
Two
Three
<!-- Paste-and-run: save as .html and open in a browser. No build step.
<aha-flex> is the SAME shared custom element React and Vue consume — here in its
native form. Theming comes only from the --aha-* tokens in tokens.css. -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/tokens.css">
<script type="module">
import 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/aha-flex.js'; // registers <aha-flex>
</script>
<!-- gap takes a named DS step (small 8 / middle 16 / large 24) or a raw pixel number -->
<aha-flex gap="middle" align="center">
<button>Save</button>
<button>Cancel</button>
<button>More</button>
</aha-flex>
<!-- column: `vertical` is the shorthand; `direction` unlocks the full row/column-reverse matrix -->
<aha-flex vertical gap="large" style="margin-top:24px">
<div>Row one</div>
<div>Row two</div>
</aha-flex>
<!-- push items apart, cross-align centred -->
<aha-flex justify="space-between" align="center" style="margin-top:24px">
<strong>Title</strong>
<a href="#">Action</a>
</aha-flex>
<!-- wrap onto multiple lines with a small gap -->
<aha-flex wrap gap="small" style="margin-top:24px">
<span>Poll</span><span>Quiz</span><span>Word cloud</span><span>Q&A</span><span>Brainstorm</span>
</aha-flex>
import '@ahaslides-product/design/aha-flex'; // registers <aha-flex>
// A static layout primitive — the custom element renders identically in React, no wrapper needed.
<aha-flex gap="middle" align="center">
<Button>Save</Button>
<Button variant="secondary">Cancel</Button>
</aha-flex>
{/* `vertical` is the column shorthand; `direction` unlocks row/column-reverse */}
<aha-flex vertical gap="large">
<Card />
<Card />
</aha-flex>
<aha-flex justify="space-between" align="center">
<strong>Title</strong>
<a href="#">Action</a>
</aha-flex>
<aha-flex wrap gap="small">
{tags.map((t) => <Tag key={t}>{t}</Tag>)}
</aha-flex>
// main.ts — register the element + mark aha-* as custom elements
import '@ahaslides-product/design/aha-flex';
app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('aha-');
// Component.vue
<template>
<aha-flex gap="middle" align="center">
<button>Save</button>
<button>Cancel</button>
</aha-flex>
<!-- `vertical` is the column shorthand; `direction` unlocks row/column-reverse -->
<aha-flex vertical gap="large">
<Card />
<Card />
</aha-flex>
<aha-flex justify="space-between" align="center">
<strong>Title</strong>
<a href="#">Action</a>
</aha-flex>
<aha-flex wrap gap="small">
<span v-for="t in tags" :key="t">{{ t }}</span>
</aha-flex>
</template>
API
| Prop | Type | Default | Notes |
|---|---|---|---|
gap | small | middle | large | number | 0 | Space between items — named DS step (8/16/24) or a raw pixel number |
vertical | boolean | false | Stack in a column — AntD's boolean shorthand for direction=column (direction wins if both set) |
direction | row | row-reverse | column | column-reverse | row | Main-axis direction (flex-direction) — the full matrix; overrides `vertical` |
align | start | center | end | baseline | stretch | stretch | Cross-axis alignment (align-items) |
justify | start | center | end | space-between | space-around | space-evenly | start | Main-axis distribution (justify-content) |
wrap | boolean | false | Allow items to wrap onto multiple lines |
Install
# .npmrc — once: point the @ahaslides-product scope at GitHub Packages
@ahaslides-product:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} # a GitHub token with read:packages
npm i @ahaslides-product/design
import '@ahaslides-product/design/tokens.css'; // once, at the app root
import '@ahaslides-product/design/aha-flex'; // registers <aha-flex>
Agent feed for this component (absolute, fetchable anywhere): flex.agent.json · flex.md · flex.llms.txt
When to use
When to use
- Flex — arranging a block of items in one dimension with consistent DS spacing
- Grid — you need two-dimensional rows-and-columns, not a single flow
- Space — you only need even gaps between a small inline set of items
Keep gaps on the named scale (small/middle/large) so spacing stays consistent across surfaces — reach for a raw pixel number only for a genuine one-off. Flex is layout, never decoration: it paints no background.
Surfaces
editor dashboard settings audience
Spec
Display flex · Gap scale small 8 · middle 16 · large 24 (or a raw px number) · Direction row · row-reverse · column · column-reverse (or `vertical` for column) · Align start · center · end · baseline · stretch (align-items) · Justify start · center · end · space-between/around/evenly