@fpkit/acss 3.1.1 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/libs/{chunk-2NRIP6RB.cjs → chunk-2C3YLBWP.cjs} +3 -3
- package/libs/{chunk-NWJDAHP6.cjs → chunk-2GJHKWEK.cjs} +3 -3
- package/libs/{chunk-FVROL3V5.js → chunk-2JCDEC32.js} +3 -3
- package/libs/{chunk-IRLFZ3OL.js → chunk-3XJC4XUG.js} +2 -2
- package/libs/{chunk-L6PRDL6F.cjs → chunk-5CJPTDK3.cjs} +3 -3
- package/libs/{chunk-E4OSROCA.cjs → chunk-5QSNJQVH.cjs} +3 -3
- package/libs/{chunk-O3JIHC5M.cjs → chunk-6BUJZ4DJ.cjs} +3 -3
- package/libs/{chunk-WXBFBWYF.cjs → chunk-AFINOD2L.cjs} +3 -3
- package/libs/{chunk-HRRHPLER.js → chunk-AWZLSWDO.js} +2 -2
- package/libs/chunk-DDSXKOUB.js +7 -0
- package/libs/chunk-DDSXKOUB.js.map +1 -0
- package/libs/{chunk-CWRNJA4P.js → chunk-DIJBIOFE.js} +3 -3
- package/libs/chunk-EJ6KYBFE.cjs +13 -0
- package/libs/chunk-EJ6KYBFE.cjs.map +1 -0
- package/libs/{chunk-GUJSMQ3V.cjs → chunk-EKJYOCLY.cjs} +3 -3
- package/libs/{chunk-X5RKCLDC.cjs → chunk-F64GE6RG.cjs} +4 -4
- package/libs/{chunk-5RAWNUVD.js → chunk-IBUTNPTQ.js} +2 -2
- package/libs/chunk-IWP4VJEP.cjs +18 -0
- package/libs/chunk-IWP4VJEP.cjs.map +1 -0
- package/libs/{chunk-ZFJ4U45S.js → chunk-KDMX3FAW.js} +2 -2
- package/libs/{chunk-DYFAUAB7.cjs → chunk-LXODKKA3.cjs} +4 -4
- package/libs/{chunk-MPTMPBFT.js → chunk-M7JLT62Q.js} +2 -2
- package/libs/{chunk-IQ76HGVP.js → chunk-MBWI67UT.js} +2 -2
- package/libs/{chunk-O5XAJ7BY.cjs → chunk-NCGVF2QS.cjs} +4 -4
- package/libs/{chunk-W2UIN7EV.cjs → chunk-NPWHQVYB.cjs} +3 -3
- package/libs/{chunk-43TK2ICH.js → chunk-PMWL5XZ4.js} +3 -3
- package/libs/{chunk-KVKQLRJG.js → chunk-TF3GQKOY.js} +2 -2
- package/libs/{chunk-IEB64SWY.js → chunk-U5VA34SU.js} +2 -2
- package/libs/chunk-UGMP72J2.js +8 -0
- package/libs/chunk-UGMP72J2.js.map +1 -0
- package/libs/{chunk-EE3ZWSBY.cjs → chunk-URBGDUFN.cjs} +6 -6
- package/libs/{chunk-TPIB3RQP.js → chunk-ZF6Y7W57.js} +5 -5
- package/libs/component-props-50e69975.d.ts +66 -0
- package/libs/components/box/box.css +1 -0
- package/libs/components/box/box.css.map +1 -0
- package/libs/components/box/box.min.css +3 -0
- package/libs/components/breadcrumbs/breadcrumb.cjs +6 -6
- package/libs/components/breadcrumbs/breadcrumb.js +3 -3
- package/libs/components/button.cjs +4 -4
- package/libs/components/button.d.cts +10 -3
- package/libs/components/button.d.ts +10 -3
- package/libs/components/button.js +2 -2
- package/libs/components/card.cjs +7 -7
- package/libs/components/card.d.cts +13 -85
- package/libs/components/card.d.ts +13 -85
- package/libs/components/card.js +2 -2
- package/libs/components/cards/card.css +1 -1
- package/libs/components/cards/card.css.map +1 -1
- package/libs/components/cards/card.min.css +2 -2
- package/libs/components/cluster/cluster.css +1 -0
- package/libs/components/cluster/cluster.css.map +1 -0
- package/libs/components/cluster/cluster.min.css +3 -0
- package/libs/components/dialog/dialog.cjs +7 -7
- package/libs/components/dialog/dialog.js +5 -5
- package/libs/components/form/fields.cjs +4 -4
- package/libs/components/form/fields.js +2 -2
- package/libs/components/form/textarea.cjs +4 -4
- package/libs/components/form/textarea.js +2 -2
- package/libs/components/grid/grid.css +1 -0
- package/libs/components/grid/grid.css.map +1 -0
- package/libs/components/grid/grid.min.css +3 -0
- package/libs/components/heading/heading.cjs +3 -3
- package/libs/components/heading/heading.js +2 -2
- package/libs/components/icons/icon.cjs +4 -4
- package/libs/components/icons/icon.d.cts +2 -2
- package/libs/components/icons/icon.d.ts +2 -2
- package/libs/components/icons/icon.js +2 -2
- package/libs/components/link/link.cjs +6 -6
- package/libs/components/link/link.js +2 -2
- package/libs/components/list/list.cjs +5 -5
- package/libs/components/list/list.js +2 -2
- package/libs/components/modal.cjs +4 -4
- package/libs/components/modal.d.cts +1 -1
- package/libs/components/modal.d.ts +1 -1
- package/libs/components/modal.js +3 -3
- package/libs/components/nav/nav.cjs +7 -7
- package/libs/components/nav/nav.js +3 -3
- package/libs/components/stack/stack.css +1 -0
- package/libs/components/stack/stack.css.map +1 -0
- package/libs/components/stack/stack.min.css +3 -0
- package/libs/components/tables/table.d.cts +1 -1
- package/libs/components/tables/table.d.ts +1 -1
- package/libs/components/text/text.cjs +5 -5
- package/libs/components/text/text.js +2 -2
- package/libs/hooks.cjs +4 -4
- package/libs/hooks.js +3 -3
- package/libs/{icons-287fce3a.d.ts → icons-df8e744f.d.ts} +1 -1
- package/libs/icons.cjs +3 -3
- package/libs/icons.d.cts +2 -2
- package/libs/icons.d.ts +2 -2
- package/libs/icons.js +2 -2
- package/libs/index.cjs +64 -63
- package/libs/index.cjs.map +1 -1
- package/libs/index.css +1 -1
- package/libs/index.css.map +1 -1
- package/libs/index.d.cts +923 -4
- package/libs/index.d.ts +923 -4
- package/libs/index.js +28 -28
- package/libs/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/alert/STYLES.mdx +790 -0
- package/src/components/badge/STYLES.mdx +610 -0
- package/src/components/box/README.mdx +401 -0
- package/src/components/box/STYLES.mdx +360 -0
- package/src/components/box/box.scss +245 -0
- package/src/components/box/box.stories.tsx +395 -0
- package/src/components/box/box.test.tsx +425 -0
- package/src/components/box/box.tsx +170 -0
- package/src/components/box/box.types.ts +166 -0
- package/src/components/breadcrumbs/STYLES.mdx +99 -0
- package/src/components/buttons/STYLES.mdx +766 -0
- package/src/components/cards/STYLES.mdx +835 -0
- package/src/components/cards/card.scss +29 -21
- package/src/components/cards/card.tsx +13 -3
- package/src/components/cards/card.types.ts +13 -0
- package/src/components/cluster/README.mdx +595 -0
- package/src/components/cluster/STYLES.mdx +626 -0
- package/src/components/cluster/cluster.scss +86 -0
- package/src/components/cluster/cluster.stories.tsx +385 -0
- package/src/components/cluster/cluster.test.tsx +655 -0
- package/src/components/cluster/cluster.tsx +94 -0
- package/src/components/cluster/cluster.types.ts +75 -0
- package/src/components/details/STYLES.mdx +445 -0
- package/src/components/dialog/STYLES.mdx +888 -0
- package/src/components/flexbox/STYLES.mdx +1 -1
- package/src/components/form/STYLES.mdx +821 -0
- package/src/components/grid/README.mdx +709 -0
- package/src/components/grid/STYLES.mdx +785 -0
- package/src/components/grid/grid.scss +287 -0
- package/src/components/grid/grid.stories.tsx +486 -0
- package/src/components/grid/grid.test.tsx +981 -0
- package/src/components/grid/grid.tsx +222 -0
- package/src/components/grid/grid.types.ts +344 -0
- package/src/components/icons/STYLES.mdx +56 -0
- package/src/components/images/STYLES.mdx +75 -0
- package/src/components/layout/STYLES.mdx +556 -0
- package/src/components/link/STYLES.mdx +75 -0
- package/src/components/list/STYLES.mdx +631 -0
- package/src/components/nav/STYLES.mdx +460 -0
- package/src/components/progress/STYLES.mdx +64 -0
- package/src/components/stack/README.mdx +400 -0
- package/src/components/stack/STYLES.mdx +414 -0
- package/src/components/stack/stack.scss +109 -0
- package/src/components/stack/stack.stories.tsx +559 -0
- package/src/components/stack/stack.test.tsx +426 -0
- package/src/components/stack/stack.tsx +141 -0
- package/src/components/stack/stack.types.ts +133 -0
- package/src/components/tag/STYLES.mdx +105 -0
- package/src/components/text-to-speech/STYLES.mdx +80 -0
- package/src/components/ui.tsx +3 -3
- package/src/index.scss +5 -1
- package/src/index.ts +305 -12
- package/src/sass/GLOBALS-STYLES.md +631 -0
- package/src/sass/_globals.scss +45 -24
- package/src/styles/box/box.css +220 -0
- package/src/styles/box/box.css.map +1 -0
- package/src/styles/cards/card.css +22 -17
- package/src/styles/cards/card.css.map +1 -1
- package/src/styles/cluster/cluster.css +71 -0
- package/src/styles/cluster/cluster.css.map +1 -0
- package/src/styles/grid/grid.css +238 -0
- package/src/styles/grid/grid.css.map +1 -0
- package/src/styles/index.css +667 -49
- package/src/styles/index.css.map +1 -1
- package/src/styles/stack/stack.css +86 -0
- package/src/styles/stack/stack.css.map +1 -0
- package/src/types/component-props.ts +42 -14
- package/src/types/layout-primitives.ts +48 -0
- package/src/types/shared.ts +10 -26
- package/libs/chunk-ENTCUJ3A.cjs +0 -13
- package/libs/chunk-ENTCUJ3A.cjs.map +0 -1
- package/libs/chunk-HHLNOC5T.js +0 -7
- package/libs/chunk-HHLNOC5T.js.map +0 -1
- package/libs/chunk-KK47SYZI.js +0 -8
- package/libs/chunk-KK47SYZI.js.map +0 -1
- package/libs/chunk-W5TKWBFC.cjs +0 -18
- package/libs/chunk-W5TKWBFC.cjs.map +0 -1
- package/libs/component-props-67d978a2.d.ts +0 -38
- /package/libs/{chunk-2NRIP6RB.cjs.map → chunk-2C3YLBWP.cjs.map} +0 -0
- /package/libs/{chunk-NWJDAHP6.cjs.map → chunk-2GJHKWEK.cjs.map} +0 -0
- /package/libs/{chunk-FVROL3V5.js.map → chunk-2JCDEC32.js.map} +0 -0
- /package/libs/{chunk-IRLFZ3OL.js.map → chunk-3XJC4XUG.js.map} +0 -0
- /package/libs/{chunk-L6PRDL6F.cjs.map → chunk-5CJPTDK3.cjs.map} +0 -0
- /package/libs/{chunk-E4OSROCA.cjs.map → chunk-5QSNJQVH.cjs.map} +0 -0
- /package/libs/{chunk-O3JIHC5M.cjs.map → chunk-6BUJZ4DJ.cjs.map} +0 -0
- /package/libs/{chunk-WXBFBWYF.cjs.map → chunk-AFINOD2L.cjs.map} +0 -0
- /package/libs/{chunk-HRRHPLER.js.map → chunk-AWZLSWDO.js.map} +0 -0
- /package/libs/{chunk-CWRNJA4P.js.map → chunk-DIJBIOFE.js.map} +0 -0
- /package/libs/{chunk-GUJSMQ3V.cjs.map → chunk-EKJYOCLY.cjs.map} +0 -0
- /package/libs/{chunk-X5RKCLDC.cjs.map → chunk-F64GE6RG.cjs.map} +0 -0
- /package/libs/{chunk-5RAWNUVD.js.map → chunk-IBUTNPTQ.js.map} +0 -0
- /package/libs/{chunk-ZFJ4U45S.js.map → chunk-KDMX3FAW.js.map} +0 -0
- /package/libs/{chunk-DYFAUAB7.cjs.map → chunk-LXODKKA3.cjs.map} +0 -0
- /package/libs/{chunk-MPTMPBFT.js.map → chunk-M7JLT62Q.js.map} +0 -0
- /package/libs/{chunk-IQ76HGVP.js.map → chunk-MBWI67UT.js.map} +0 -0
- /package/libs/{chunk-O5XAJ7BY.cjs.map → chunk-NCGVF2QS.cjs.map} +0 -0
- /package/libs/{chunk-W2UIN7EV.cjs.map → chunk-NPWHQVYB.cjs.map} +0 -0
- /package/libs/{chunk-43TK2ICH.js.map → chunk-PMWL5XZ4.js.map} +0 -0
- /package/libs/{chunk-KVKQLRJG.js.map → chunk-TF3GQKOY.js.map} +0 -0
- /package/libs/{chunk-IEB64SWY.js.map → chunk-U5VA34SU.js.map} +0 -0
- /package/libs/{chunk-EE3ZWSBY.cjs.map → chunk-URBGDUFN.cjs.map} +0 -0
- /package/libs/{chunk-TPIB3RQP.js.map → chunk-ZF6Y7W57.js.map} +0 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import { Meta, Story, Canvas } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as StackStories from './stack.stories';
|
|
3
|
+
|
|
4
|
+
<Meta of={StackStories} />
|
|
5
|
+
|
|
6
|
+
# Stack Component
|
|
7
|
+
|
|
8
|
+
A simplified flexbox primitive for vertical or horizontal layouts with consistent gap spacing.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Stack provides an easy-to-use layout component for the most common flexbox patterns: stacking items vertically or horizontally with consistent spacing. It's designed to be simpler than the full Flex component while covering 80% of typical use cases.
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Simple API**: Fewer props than Flex for common stacking patterns
|
|
17
|
+
- **Fluid Spacing**: Responsive gap using CSS `clamp()` for automatic viewport adaptation
|
|
18
|
+
- **Flexbox-Based**: Reliable cross-browser layout engine
|
|
19
|
+
- **Polymorphic**: Render as any semantic HTML element
|
|
20
|
+
- **Type-Safe**: Full TypeScript support with IntelliSense
|
|
21
|
+
- **Zero Runtime**: Utility classes compiled at build time
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @fpkit/acss
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Basic Usage
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import { Stack } from '@fpkit/acss';
|
|
33
|
+
import '@fpkit/acss/styles';
|
|
34
|
+
|
|
35
|
+
// Vertical stack (default)
|
|
36
|
+
function App() {
|
|
37
|
+
return (
|
|
38
|
+
<Stack gap="md">
|
|
39
|
+
<h1>Title</h1>
|
|
40
|
+
<p>Paragraph 1</p>
|
|
41
|
+
<p>Paragraph 2</p>
|
|
42
|
+
</Stack>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## API Reference
|
|
48
|
+
|
|
49
|
+
### Props
|
|
50
|
+
|
|
51
|
+
| Prop | Type | Default | Description |
|
|
52
|
+
|------|------|---------|-------------|
|
|
53
|
+
| `gap` | `SpacingScale` | - | Gap between children |
|
|
54
|
+
| `direction` | `'vertical' \| 'horizontal'` | `'vertical'` | Layout direction |
|
|
55
|
+
| `align` | `'start' \| 'center' \| 'end' \| 'stretch'` | - | Cross-axis alignment |
|
|
56
|
+
| `justify` | `'start' \| 'center' \| 'end' \| 'between'` | - | Main-axis alignment |
|
|
57
|
+
| `wrap` | `'wrap' \| 'nowrap'` | `'nowrap'` | Allow wrapping |
|
|
58
|
+
| `as` | `StackElement` | `'div'` | HTML element to render |
|
|
59
|
+
| `className` | `string` | - | Additional CSS classes |
|
|
60
|
+
| `styles` | `CSSProperties` | - | Inline styles |
|
|
61
|
+
| `children` | `ReactNode` | - | Child elements |
|
|
62
|
+
|
|
63
|
+
#### SpacingScale
|
|
64
|
+
|
|
65
|
+
- `'0'`: No gap
|
|
66
|
+
- `'xs'`: 4-8px (extra small)
|
|
67
|
+
- `'sm'`: 8-12px (small)
|
|
68
|
+
- `'md'`: 12-18px (medium)
|
|
69
|
+
- `'lg'`: 16-24px (large)
|
|
70
|
+
- `'xl'`: 24-32px (extra large)
|
|
71
|
+
|
|
72
|
+
#### StackElement
|
|
73
|
+
|
|
74
|
+
- `'div'` (default)
|
|
75
|
+
- `'section'`
|
|
76
|
+
- `'article'`
|
|
77
|
+
- `'ul'` | `'ol'` (for lists)
|
|
78
|
+
- `'nav'` (for navigation)
|
|
79
|
+
|
|
80
|
+
## Usage Examples
|
|
81
|
+
|
|
82
|
+
### Vertical Content Stack
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
<Stack gap="lg">
|
|
86
|
+
<h1>Article Title</h1>
|
|
87
|
+
<p>Introduction paragraph...</p>
|
|
88
|
+
<p>Body paragraph...</p>
|
|
89
|
+
</Stack>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Horizontal Button Group
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
<Stack direction="horizontal" gap="sm">
|
|
96
|
+
<Button>Cancel</Button>
|
|
97
|
+
<Button variant="primary">Submit</Button>
|
|
98
|
+
</Stack>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Centered Hero Section
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
<Stack
|
|
105
|
+
gap="lg"
|
|
106
|
+
align="center"
|
|
107
|
+
justify="center"
|
|
108
|
+
style={{ minHeight: '100vh' }}
|
|
109
|
+
>
|
|
110
|
+
<Logo />
|
|
111
|
+
<h1>Welcome</h1>
|
|
112
|
+
<p>Get started with our platform</p>
|
|
113
|
+
<Button>Get Started</Button>
|
|
114
|
+
</Stack>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Navigation Bar
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
<Stack
|
|
121
|
+
as="nav"
|
|
122
|
+
direction="horizontal"
|
|
123
|
+
gap="md"
|
|
124
|
+
justify="between"
|
|
125
|
+
align="center"
|
|
126
|
+
style={{ padding: '1rem' }}
|
|
127
|
+
>
|
|
128
|
+
<Logo />
|
|
129
|
+
<Stack direction="horizontal" gap="sm">
|
|
130
|
+
<a href="/about">About</a>
|
|
131
|
+
<a href="/contact">Contact</a>
|
|
132
|
+
</Stack>
|
|
133
|
+
</Stack>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Form Layout
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
<Stack gap="lg">
|
|
140
|
+
<Stack gap="xs">
|
|
141
|
+
<label htmlFor="name">Name</label>
|
|
142
|
+
<input id="name" type="text" />
|
|
143
|
+
</Stack>
|
|
144
|
+
<Stack gap="xs">
|
|
145
|
+
<label htmlFor="email">Email</label>
|
|
146
|
+
<input id="email" type="email" />
|
|
147
|
+
</Stack>
|
|
148
|
+
<Stack direction="horizontal" gap="sm" justify="end">
|
|
149
|
+
<Button>Cancel</Button>
|
|
150
|
+
<Button variant="primary">Submit</Button>
|
|
151
|
+
</Stack>
|
|
152
|
+
</Stack>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Nested Stacks
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
<Stack gap="xl">
|
|
159
|
+
<h2>Dashboard</h2>
|
|
160
|
+
<Stack direction="horizontal" gap="lg" wrap="wrap">
|
|
161
|
+
<Stack gap="md" style={{ flex: 1, minWidth: '250px' }}>
|
|
162
|
+
<h3>Card 1</h3>
|
|
163
|
+
<p>Content...</p>
|
|
164
|
+
</Stack>
|
|
165
|
+
<Stack gap="md" style={{ flex: 1, minWidth: '250px' }}>
|
|
166
|
+
<h3>Card 2</h3>
|
|
167
|
+
<p>Content...</p>
|
|
168
|
+
</Stack>
|
|
169
|
+
</Stack>
|
|
170
|
+
</Stack>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Alignment Guide
|
|
174
|
+
|
|
175
|
+
### Cross-Axis Alignment (`align` prop)
|
|
176
|
+
|
|
177
|
+
Controls alignment perpendicular to the direction:
|
|
178
|
+
|
|
179
|
+
- **`start`**: Items at start (left in horizontal, top in vertical)
|
|
180
|
+
- **`center`**: Items centered
|
|
181
|
+
- **`end`**: Items at end (right in horizontal, bottom in vertical)
|
|
182
|
+
- **`stretch`**: Items stretch to fill (default flexbox behavior)
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
<Stack direction="horizontal" align="center" gap="sm">
|
|
186
|
+
<Icon />
|
|
187
|
+
<span>Vertically centered with icon</span>
|
|
188
|
+
</Stack>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Main-Axis Alignment (`justify` prop)
|
|
192
|
+
|
|
193
|
+
Controls alignment along the direction:
|
|
194
|
+
|
|
195
|
+
- **`start`**: Items at start (default)
|
|
196
|
+
- **`center`**: Items centered
|
|
197
|
+
- **`end`**: Items at end
|
|
198
|
+
- **`between`**: Space evenly between items
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
<Stack justify="between" style={{ minHeight: '100vh' }}>
|
|
202
|
+
<Header />
|
|
203
|
+
<Main />
|
|
204
|
+
<Footer />
|
|
205
|
+
</Stack>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## When to Use
|
|
209
|
+
|
|
210
|
+
### Use Stack When:
|
|
211
|
+
- ✅ Simple vertical or horizontal layouts
|
|
212
|
+
- ✅ Consistent spacing between items
|
|
213
|
+
- ✅ Basic alignment needs
|
|
214
|
+
- ✅ Form layouts
|
|
215
|
+
- ✅ Content sections
|
|
216
|
+
|
|
217
|
+
### Use Flex When:
|
|
218
|
+
- 🔄 Complex responsive layouts
|
|
219
|
+
- 🔄 Multiple breakpoint adjustments
|
|
220
|
+
- 🔄 Advanced flex properties (grow, shrink, basis)
|
|
221
|
+
- 🔄 Preset layout variants
|
|
222
|
+
|
|
223
|
+
### Use Box When:
|
|
224
|
+
- 📦 Padding/margin on containers
|
|
225
|
+
- 📦 No gap spacing between children
|
|
226
|
+
- 📦 Width constraints (max-width)
|
|
227
|
+
|
|
228
|
+
## Accessibility
|
|
229
|
+
|
|
230
|
+
### Semantic HTML
|
|
231
|
+
|
|
232
|
+
Use appropriate semantic elements:
|
|
233
|
+
|
|
234
|
+
```tsx
|
|
235
|
+
// ✅ Good - semantic navigation
|
|
236
|
+
<Stack as="nav" direction="horizontal" gap="md">
|
|
237
|
+
<a href="/">Home</a>
|
|
238
|
+
<a href="/about">About</a>
|
|
239
|
+
</Stack>
|
|
240
|
+
|
|
241
|
+
// ✅ Good - semantic list
|
|
242
|
+
<Stack as="ul" gap="sm">
|
|
243
|
+
<li>Item 1</li>
|
|
244
|
+
<li>Item 2</li>
|
|
245
|
+
</Stack>
|
|
246
|
+
|
|
247
|
+
// ❌ Avoid - div soup when semantic elements available
|
|
248
|
+
<Stack>
|
|
249
|
+
<div>Nav item</div>
|
|
250
|
+
<div>Nav item</div>
|
|
251
|
+
</Stack>
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Focus Order
|
|
255
|
+
|
|
256
|
+
Stack maintains natural focus order (visual order matches DOM order):
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
<Stack direction="horizontal" gap="sm">
|
|
260
|
+
<button>First in focus order</button>
|
|
261
|
+
<button>Second in focus order</button>
|
|
262
|
+
<button>Third in focus order</button>
|
|
263
|
+
</Stack>
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### ARIA Attributes
|
|
267
|
+
|
|
268
|
+
Stack forwards all ARIA attributes:
|
|
269
|
+
|
|
270
|
+
```tsx
|
|
271
|
+
<Stack
|
|
272
|
+
as="section"
|
|
273
|
+
aria-label="Features"
|
|
274
|
+
role="region"
|
|
275
|
+
gap="lg"
|
|
276
|
+
>
|
|
277
|
+
<Feature />
|
|
278
|
+
<Feature />
|
|
279
|
+
</Stack>
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Best Practices
|
|
283
|
+
|
|
284
|
+
### 1. Choose Appropriate Direction
|
|
285
|
+
|
|
286
|
+
```tsx
|
|
287
|
+
// ✅ Good - vertical for content
|
|
288
|
+
<Stack gap="md">
|
|
289
|
+
<h2>Title</h2>
|
|
290
|
+
<p>Content...</p>
|
|
291
|
+
</Stack>
|
|
292
|
+
|
|
293
|
+
// ✅ Good - horizontal for actions
|
|
294
|
+
<Stack direction="horizontal" gap="sm">
|
|
295
|
+
<Button>Cancel</Button>
|
|
296
|
+
<Button>Submit</Button>
|
|
297
|
+
</Stack>
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### 2. Use Semantic Elements
|
|
301
|
+
|
|
302
|
+
```tsx
|
|
303
|
+
// ✅ Good
|
|
304
|
+
<Stack as="article" gap="lg">
|
|
305
|
+
<h1>Article</h1>
|
|
306
|
+
<p>Content</p>
|
|
307
|
+
</Stack>
|
|
308
|
+
|
|
309
|
+
// ❌ Avoid
|
|
310
|
+
<Stack>
|
|
311
|
+
<h1>Article</h1>
|
|
312
|
+
<p>Content</p>
|
|
313
|
+
</Stack>
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### 3. Leverage Wrapping
|
|
317
|
+
|
|
318
|
+
```tsx
|
|
319
|
+
// ✅ Good - responsive with wrap
|
|
320
|
+
<Stack direction="horizontal" gap="md" wrap="wrap">
|
|
321
|
+
{items.map(item => <Card key={item.id} />)}
|
|
322
|
+
</Stack>
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### 4. Compose for Complex Layouts
|
|
326
|
+
|
|
327
|
+
```tsx
|
|
328
|
+
// ✅ Good - nested Stacks
|
|
329
|
+
<Stack gap="xl">
|
|
330
|
+
<Stack direction="horizontal" justify="between">
|
|
331
|
+
<h1>Title</h1>
|
|
332
|
+
<Button>Action</Button>
|
|
333
|
+
</Stack>
|
|
334
|
+
<Stack gap="md">
|
|
335
|
+
<p>Content...</p>
|
|
336
|
+
</Stack>
|
|
337
|
+
</Stack>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Related Components
|
|
341
|
+
|
|
342
|
+
- **Box**: Container with padding/margin controls (no gap)
|
|
343
|
+
- **Cluster**: Wrapping flex for inline groups (tags, chips)
|
|
344
|
+
- **Grid**: CSS Grid with responsive columns
|
|
345
|
+
- **Flex**: Full-featured flexbox with advanced controls
|
|
346
|
+
|
|
347
|
+
## CSS Variables
|
|
348
|
+
|
|
349
|
+
Stack uses the unified spacing scale:
|
|
350
|
+
|
|
351
|
+
```css
|
|
352
|
+
--spacing-xs: clamp(0.25rem, 0.2rem + 0.25vw, 0.5rem);
|
|
353
|
+
--spacing-sm: clamp(0.5rem, 0.45rem + 0.35vw, 0.75rem);
|
|
354
|
+
--spacing-md: clamp(0.75rem, 0.65rem + 0.45vw, 1.125rem);
|
|
355
|
+
--spacing-lg: clamp(1rem, 0.85rem + 0.6vw, 1.5rem);
|
|
356
|
+
--spacing-xl: clamp(1.5rem, 1.25rem + 0.75vw, 2rem);
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Override for custom spacing:
|
|
360
|
+
|
|
361
|
+
```tsx
|
|
362
|
+
<Stack
|
|
363
|
+
gap="lg"
|
|
364
|
+
styles={{ '--spacing-lg': '2rem' } as React.CSSProperties}
|
|
365
|
+
>
|
|
366
|
+
Content with custom gap
|
|
367
|
+
</Stack>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
See [STYLES.mdx](./STYLES.mdx) for complete CSS reference.
|
|
371
|
+
|
|
372
|
+
## TypeScript Support
|
|
373
|
+
|
|
374
|
+
Stack is fully typed:
|
|
375
|
+
|
|
376
|
+
```tsx
|
|
377
|
+
import type { StackProps } from '@fpkit/acss';
|
|
378
|
+
|
|
379
|
+
const MyStack: React.FC<StackProps> = (props) => {
|
|
380
|
+
return <Stack {...props} />;
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
// Type-safe polymorphic rendering
|
|
384
|
+
<Stack
|
|
385
|
+
as="nav"
|
|
386
|
+
// TypeScript knows nav-specific props are available
|
|
387
|
+
aria-label="Primary navigation"
|
|
388
|
+
>
|
|
389
|
+
<a href="/">Home</a>
|
|
390
|
+
</Stack>
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
## Browser Support
|
|
394
|
+
|
|
395
|
+
Works in all modern browsers supporting:
|
|
396
|
+
- CSS Flexbox
|
|
397
|
+
- CSS Custom Properties
|
|
398
|
+
- CSS `clamp()` function
|
|
399
|
+
|
|
400
|
+
For legacy support, consider PostCSS with appropriate polyfills.
|