@fpkit/acss 3.0.0 → 3.1.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.
Files changed (66) hide show
  1. package/libs/chunk-5RAWNUVD.js +8 -0
  2. package/libs/chunk-5RAWNUVD.js.map +1 -0
  3. package/libs/{chunk-D2PSO7MU.js → chunk-CWRNJA4P.js} +2 -2
  4. package/libs/{chunk-C622WBGW.cjs → chunk-DYFAUAB7.cjs} +3 -3
  5. package/libs/chunk-NWJDAHP6.cjs +17 -0
  6. package/libs/chunk-NWJDAHP6.cjs.map +1 -0
  7. package/libs/components/breadcrumbs/breadcrumb.cjs +5 -5
  8. package/libs/components/breadcrumbs/breadcrumb.js +2 -2
  9. package/libs/components/flexbox/flex.css +1 -0
  10. package/libs/components/flexbox/flex.css.map +1 -0
  11. package/libs/components/flexbox/flex.min.css +3 -0
  12. package/libs/components/link/link.cjs +5 -5
  13. package/libs/components/link/link.css +1 -1
  14. package/libs/components/link/link.css.map +1 -1
  15. package/libs/components/link/link.js +1 -1
  16. package/libs/components/link/link.min.css +2 -2
  17. package/libs/hooks.cjs +3 -3
  18. package/libs/hooks.js +2 -2
  19. package/libs/index.cjs +29 -28
  20. package/libs/index.cjs.map +1 -1
  21. package/libs/index.css +1 -1
  22. package/libs/index.css.map +1 -1
  23. package/libs/index.d.cts +243 -52
  24. package/libs/index.d.ts +243 -52
  25. package/libs/index.js +14 -14
  26. package/libs/index.js.map +1 -1
  27. package/package.json +2 -2
  28. package/src/components/flexbox/README.mdx +996 -0
  29. package/src/components/flexbox/flex.scss +847 -0
  30. package/src/components/flexbox/flex.stories.tsx +1233 -0
  31. package/src/components/flexbox/flex.test.tsx +689 -0
  32. package/src/components/flexbox/flex.tsx +484 -0
  33. package/src/components/flexbox/flex.types.ts +224 -0
  34. package/src/components/link/link.tsx +1 -1
  35. package/src/index.scss +1 -0
  36. package/src/index.ts +17 -0
  37. package/src/styles/flexbox/flex.css +736 -0
  38. package/src/styles/flexbox/flex.css.map +1 -0
  39. package/src/styles/index.css +735 -1
  40. package/src/styles/index.css.map +1 -1
  41. package/src/styles/link/link.css +1 -1
  42. package/libs/chunk-KG4GHIQJ.js +0 -8
  43. package/libs/chunk-KG4GHIQJ.js.map +0 -1
  44. package/libs/chunk-ZOBAJTNE.cjs +0 -17
  45. package/libs/chunk-ZOBAJTNE.cjs.map +0 -1
  46. package/libs/components/alert/alert.min.min.css +0 -2
  47. package/libs/components/badge/badge.min.min.css +0 -2
  48. package/libs/components/breadcrumbs/breadcrumb.min.min.css +0 -2
  49. package/libs/components/buttons/button.min.min.css +0 -2
  50. package/libs/components/cards/card-style.min.min.css +0 -2
  51. package/libs/components/cards/card.min.min.css +0 -2
  52. package/libs/components/details/details.min.min.css +0 -2
  53. package/libs/components/dialog/dialog.min.min.css +0 -2
  54. package/libs/components/form/form.min.min.css +0 -2
  55. package/libs/components/icons/icon.min.min.css +0 -2
  56. package/libs/components/images/img.min.min.css +0 -2
  57. package/libs/components/layout/landmarks.min.min.css +0 -2
  58. package/libs/components/link/link.min.min.css +0 -2
  59. package/libs/components/list/list.min.min.css +0 -2
  60. package/libs/components/nav/nav.min.min.css +0 -2
  61. package/libs/components/progress/progress.min.min.css +0 -2
  62. package/libs/components/styles/index.min.min.css +0 -2
  63. package/libs/components/tag/tag.min.min.css +0 -2
  64. package/libs/components/text-to-speech/text-to-speech.min.min.css +0 -2
  65. /package/libs/{chunk-D2PSO7MU.js.map → chunk-CWRNJA4P.js.map} +0 -0
  66. /package/libs/{chunk-C622WBGW.cjs.map → chunk-DYFAUAB7.cjs.map} +0 -0
@@ -0,0 +1,1233 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import { within, expect } from "storybook/test";
3
+ import Flex from "./flex";
4
+ import "./flex.scss";
5
+
6
+ /**
7
+ * Flexbox Utilities and Component Story
8
+ * Comprehensive documentation of responsive flexbox utility classes and React Flex component
9
+ */
10
+ const meta: Meta<typeof Flex> = {
11
+ title: "FP.React Components/Layout/Flex",
12
+ component: Flex,
13
+ tags: ["autodocs", "rc"],
14
+ parameters: {
15
+ docs: {
16
+ description: {
17
+ component: `
18
+ # Flex Container Component
19
+
20
+ A flexible container component for creating flexbox layouts with a declarative React API.
21
+ Supports responsive props, preset variants, and compound pattern with Flex.Item and Flex.Spacer.
22
+
23
+ ## Features
24
+
25
+ - **Compound Pattern**: Use \`Flex.Item\` and \`Flex.Spacer\` sub-components
26
+ - **Responsive Props**: Different layouts at sm/md/lg/xl breakpoints
27
+ - **Preset Variants**: Common patterns like 'center', 'between', 'stack'
28
+ - **CSS Custom Properties**: Runtime theming via styles prop
29
+ - **Polymorphic**: Render as any HTML element via 'as' prop
30
+ - **Type-Safe**: Full TypeScript support with autocomplete
31
+
32
+ ## Usage Approaches
33
+
34
+ ### 1. React Component (Recommended)
35
+ \`\`\`tsx
36
+ <Flex gap="md" justify="between" align="center">
37
+ <Flex.Item flex="1">Content 1</Flex.Item>
38
+ <Flex.Item flex="1">Content 2</Flex.Item>
39
+ </Flex>
40
+ \`\`\`
41
+
42
+ ### 2. Utility Classes (Direct HTML)
43
+ \`\`\`html
44
+ <div className="flex gap-md justify-between items-center">
45
+ <div className="flex-1">Content 1</div>
46
+ <div className="flex-1">Content 2</div>
47
+ </div>
48
+ \`\`\`
49
+
50
+ ## Breakpoints
51
+
52
+ - **sm**: 30rem (480px)
53
+ - **md**: 48rem (768px)
54
+ - **lg**: 62rem (992px)
55
+ - **xl**: 80rem (1280px)
56
+
57
+ ## CSS Custom Properties
58
+
59
+ Override default spacing:
60
+
61
+ \`\`\`css
62
+ :root {
63
+ --flex-gap-xs: 0.25rem;
64
+ --flex-gap-sm: 0.5rem;
65
+ --flex-gap-md: 0.75rem;
66
+ --flex-gap-lg: 1rem;
67
+ --flex-gap-xl: 1.5rem;
68
+ }
69
+ \`\`\`
70
+ `,
71
+ },
72
+ },
73
+ },
74
+ };
75
+
76
+ export default meta;
77
+ type Story = StoryObj<typeof Flex>;
78
+
79
+ // ============================================================================
80
+ // REACT COMPONENT STORIES
81
+ // ============================================================================
82
+
83
+ /**
84
+ * Basic Flex component usage
85
+ */
86
+ export const FlexComponent: Story = {
87
+ args: {
88
+ gap: "md",
89
+ children: (
90
+ <>
91
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
92
+ Item 1
93
+ </div>
94
+ <div style={{ padding: "1rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
95
+ Item 2
96
+ </div>
97
+ <div style={{ padding: "1rem", background: "#90caf9", borderRadius: "0.25rem" }}>
98
+ Item 3
99
+ </div>
100
+ </>
101
+ ),
102
+ },
103
+ play: async ({ canvasElement, step }) => {
104
+ const canvas = within(canvasElement);
105
+
106
+ await step("Flex container renders correctly", async () => {
107
+ const flexContainer = canvas.getByText("Item 1").parentElement?.parentElement;
108
+ expect(flexContainer).toBeInTheDocument();
109
+ expect(flexContainer).toHaveClass("flex");
110
+ });
111
+ },
112
+ parameters: {
113
+ docs: {
114
+ description: {
115
+ story:
116
+ "Basic Flex component with gap spacing. The component automatically generates the appropriate utility classes from props.",
117
+ },
118
+ },
119
+ },
120
+ };
121
+
122
+ /**
123
+ * Flex with various layout props
124
+ */
125
+ export const FlexWithProps: Story = {
126
+ render: () => (
127
+ <div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
128
+ <div>
129
+ <h4 style={{ marginBottom: "0.5rem" }}>Row direction with space between</h4>
130
+ <Flex
131
+ direction="row"
132
+ justify="between"
133
+ align="center"
134
+ gap="md"
135
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
136
+ >
137
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
138
+ Left
139
+ </div>
140
+ <div style={{ padding: "0.75rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
141
+ Center
142
+ </div>
143
+ <div style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}>
144
+ Right
145
+ </div>
146
+ </Flex>
147
+ </div>
148
+
149
+ <div>
150
+ <h4 style={{ marginBottom: "0.5rem" }}>Column direction with center alignment</h4>
151
+ <Flex
152
+ direction="column"
153
+ align="center"
154
+ gap="sm"
155
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
156
+ >
157
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
158
+ Item 1
159
+ </div>
160
+ <div style={{ padding: "0.75rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
161
+ Item 2
162
+ </div>
163
+ <div style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}>
164
+ Item 3
165
+ </div>
166
+ </Flex>
167
+ </div>
168
+ </div>
169
+ ),
170
+ parameters: {
171
+ docs: {
172
+ description: {
173
+ story: "Demonstrates different combinations of direction, justify, align, and gap props.",
174
+ },
175
+ },
176
+ },
177
+ };
178
+
179
+ /**
180
+ * Responsive Flex layout
181
+ */
182
+ export const FlexResponsive: Story = {
183
+ render: () => (
184
+ <Flex
185
+ direction="column"
186
+ gap="sm"
187
+ md={{ direction: "row", gap: "lg", justify: "between" }}
188
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
189
+ >
190
+ <Flex.Item flex="none" md={{ flex: "1" }}>
191
+ <div
192
+ style={{
193
+ padding: "1rem",
194
+ background: "#e3f2fd",
195
+ borderRadius: "0.25rem",
196
+ minHeight: "6rem",
197
+ }}
198
+ >
199
+ Column on mobile<br />Row on medium+<br />flex="1" on medium+
200
+ </div>
201
+ </Flex.Item>
202
+ <Flex.Item flex="none" md={{ flex: "1" }}>
203
+ <div
204
+ style={{
205
+ padding: "1rem",
206
+ background: "#bbdefb",
207
+ borderRadius: "0.25rem",
208
+ minHeight: "6rem",
209
+ }}
210
+ >
211
+ Responsive layout with gap changes
212
+ </div>
213
+ </Flex.Item>
214
+ <Flex.Item flex="none" md={{ flex: "1" }}>
215
+ <div
216
+ style={{
217
+ padding: "1rem",
218
+ background: "#90caf9",
219
+ borderRadius: "0.25rem",
220
+ minHeight: "6rem",
221
+ }}
222
+ >
223
+ Resize to see behavior
224
+ </div>
225
+ </Flex.Item>
226
+ </Flex>
227
+ ),
228
+ parameters: {
229
+ docs: {
230
+ description: {
231
+ story:
232
+ "Responsive layout that changes from column on mobile to row on medium+ screens, with different gap sizes at different breakpoints.",
233
+ },
234
+ },
235
+ chromatic: {
236
+ viewports: [375, 768, 1280],
237
+ },
238
+ },
239
+ };
240
+
241
+ /**
242
+ * Flex.Item sub-component
243
+ */
244
+ export const FlexWithItems: Story = {
245
+ render: () => (
246
+ <div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
247
+ <div>
248
+ <h4 style={{ marginBottom: "0.5rem" }}>Equal width items (flex="1")</h4>
249
+ <Flex
250
+ gap="md"
251
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
252
+ >
253
+ <Flex.Item flex="1">
254
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
255
+ flex="1"
256
+ </div>
257
+ </Flex.Item>
258
+ <Flex.Item flex="1">
259
+ <div style={{ padding: "1rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
260
+ flex="1"
261
+ </div>
262
+ </Flex.Item>
263
+ <Flex.Item flex="1">
264
+ <div style={{ padding: "1rem", background: "#90caf9", borderRadius: "0.25rem" }}>
265
+ flex="1"
266
+ </div>
267
+ </Flex.Item>
268
+ </Flex>
269
+ </div>
270
+
271
+ <div>
272
+ <h4 style={{ marginBottom: "0.5rem" }}>Mixed sizing (flex="none" + flex="1")</h4>
273
+ <Flex
274
+ gap="md"
275
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
276
+ >
277
+ <Flex.Item flex="none" styles={{ width: "8rem" }}>
278
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
279
+ Fixed 8rem
280
+ </div>
281
+ </Flex.Item>
282
+ <Flex.Item flex="1">
283
+ <div style={{ padding: "1rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
284
+ Fills remaining space
285
+ </div>
286
+ </Flex.Item>
287
+ </Flex>
288
+ </div>
289
+
290
+ <div>
291
+ <h4 style={{ marginBottom: "0.5rem" }}>Custom alignment (alignSelf)</h4>
292
+ <Flex
293
+ gap="md"
294
+ style={{
295
+ padding: "1rem",
296
+ border: "2px dashed #ccc",
297
+ borderRadius: "0.5rem",
298
+ minHeight: "8rem",
299
+ }}
300
+ >
301
+ <Flex.Item alignSelf="start">
302
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
303
+ Start
304
+ </div>
305
+ </Flex.Item>
306
+ <Flex.Item alignSelf="center">
307
+ <div style={{ padding: "0.75rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
308
+ Center
309
+ </div>
310
+ </Flex.Item>
311
+ <Flex.Item alignSelf="end">
312
+ <div style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}>
313
+ End
314
+ </div>
315
+ </Flex.Item>
316
+ </Flex>
317
+ </div>
318
+ </div>
319
+ ),
320
+ parameters: {
321
+ docs: {
322
+ description: {
323
+ story:
324
+ "Demonstrates Flex.Item sub-component with different flex sizing and alignment options.",
325
+ },
326
+ },
327
+ },
328
+ };
329
+
330
+ /**
331
+ * Flex.Spacer sub-component
332
+ */
333
+ export const FlexWithSpacer: Story = {
334
+ render: () => (
335
+ <div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
336
+ <div>
337
+ <h4 style={{ marginBottom: "0.5rem" }}>Push items to opposite edges</h4>
338
+ <Flex
339
+ gap="md"
340
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
341
+ >
342
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
343
+ Left side
344
+ </div>
345
+ <Flex.Spacer />
346
+ <div style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}>
347
+ Right side
348
+ </div>
349
+ </Flex>
350
+ </div>
351
+
352
+ <div>
353
+ <h4 style={{ marginBottom: "0.5rem" }}>Multiple spacers for even distribution</h4>
354
+ <Flex
355
+ gap="md"
356
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
357
+ >
358
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
359
+ Start
360
+ </div>
361
+ <Flex.Spacer />
362
+ <div style={{ padding: "0.75rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
363
+ Middle
364
+ </div>
365
+ <Flex.Spacer />
366
+ <div style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}>
367
+ End
368
+ </div>
369
+ </Flex>
370
+ </div>
371
+ </div>
372
+ ),
373
+ parameters: {
374
+ docs: {
375
+ description: {
376
+ story:
377
+ "Flex.Spacer creates auto-expanding space (flex: 1) to push items apart. Commonly used for navbar layouts and toolbars.",
378
+ },
379
+ },
380
+ },
381
+ };
382
+
383
+ /**
384
+ * Preset variants
385
+ */
386
+ export const FlexVariants: Story = {
387
+ render: () => (
388
+ <div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
389
+ <div>
390
+ <h4 style={{ marginBottom: "0.5rem" }}>variant="center"</h4>
391
+ <Flex
392
+ variant="center"
393
+ style={{
394
+ padding: "2rem",
395
+ border: "2px dashed #ccc",
396
+ borderRadius: "0.5rem",
397
+ minHeight: "8rem",
398
+ }}
399
+ >
400
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
401
+ Centered both axes
402
+ </div>
403
+ </Flex>
404
+ </div>
405
+
406
+ <div>
407
+ <h4 style={{ marginBottom: "0.5rem" }}>variant="between"</h4>
408
+ <Flex
409
+ variant="between"
410
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
411
+ >
412
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
413
+ Left
414
+ </div>
415
+ <div style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}>
416
+ Right
417
+ </div>
418
+ </Flex>
419
+ </div>
420
+
421
+ <div>
422
+ <h4 style={{ marginBottom: "0.5rem" }}>variant="stack"</h4>
423
+ <Flex
424
+ variant="stack"
425
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
426
+ >
427
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
428
+ Stacked Item 1
429
+ </div>
430
+ <div style={{ padding: "1rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
431
+ Stacked Item 2
432
+ </div>
433
+ <div style={{ padding: "1rem", background: "#90caf9", borderRadius: "0.25rem" }}>
434
+ Stacked Item 3
435
+ </div>
436
+ </Flex>
437
+ <p style={{ marginTop: "0.5rem", fontSize: "0.875rem", color: "#666" }}>
438
+ Stack variant uses column layout by default, becomes row on medium+ screens
439
+ </p>
440
+ </div>
441
+
442
+ <div>
443
+ <h4 style={{ marginBottom: "0.5rem" }}>variant="spread"</h4>
444
+ <Flex
445
+ variant="spread"
446
+ gap="sm"
447
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
448
+ >
449
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
450
+ Equal
451
+ </div>
452
+ <div style={{ padding: "0.75rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
453
+ Width
454
+ </div>
455
+ <div style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}>
456
+ Items
457
+ </div>
458
+ </Flex>
459
+ </div>
460
+ </div>
461
+ ),
462
+ parameters: {
463
+ docs: {
464
+ description: {
465
+ story:
466
+ "Preset variants provide common flexbox patterns: 'center', 'between', 'around', 'stack', 'spread'.",
467
+ },
468
+ },
469
+ },
470
+ };
471
+
472
+ /**
473
+ * Nested Flex containers
474
+ */
475
+ export const NestedFlex: Story = {
476
+ render: () => (
477
+ <Flex
478
+ direction="column"
479
+ gap="md"
480
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
481
+ >
482
+ <Flex justify="between" align="center" gap="md">
483
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
484
+ Header Left
485
+ </div>
486
+ <Flex.Spacer />
487
+ <Flex gap="sm">
488
+ <div style={{ padding: "0.5rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
489
+ Nav 1
490
+ </div>
491
+ <div style={{ padding: "0.5rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
492
+ Nav 2
493
+ </div>
494
+ <div style={{ padding: "0.5rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
495
+ Nav 3
496
+ </div>
497
+ </Flex>
498
+ </Flex>
499
+
500
+ <Flex gap="md">
501
+ <Flex.Item flex="none" styles={{ width: "12rem" }}>
502
+ <div
503
+ style={{
504
+ padding: "1rem",
505
+ background: "#f3e5f5",
506
+ borderRadius: "0.25rem",
507
+ minHeight: "12rem",
508
+ }}
509
+ >
510
+ Sidebar
511
+ </div>
512
+ </Flex.Item>
513
+ <Flex.Item flex="1">
514
+ <Flex
515
+ direction="column"
516
+ gap="md"
517
+ style={{ padding: "1rem", background: "#f1f8e9", borderRadius: "0.25rem" }}
518
+ >
519
+ <div style={{ padding: "0.75rem", background: "#dcedc8", borderRadius: "0.25rem" }}>
520
+ Main content area
521
+ </div>
522
+ <Flex gap="sm">
523
+ <Flex.Item flex="1">
524
+ <div style={{ padding: "0.75rem", background: "#c5e1a5", borderRadius: "0.25rem" }}>
525
+ Column 1
526
+ </div>
527
+ </Flex.Item>
528
+ <Flex.Item flex="1">
529
+ <div style={{ padding: "0.75rem", background: "#c5e1a5", borderRadius: "0.25rem" }}>
530
+ Column 2
531
+ </div>
532
+ </Flex.Item>
533
+ </Flex>
534
+ </Flex>
535
+ </Flex.Item>
536
+ </Flex>
537
+ </Flex>
538
+ ),
539
+ parameters: {
540
+ docs: {
541
+ description: {
542
+ story:
543
+ "Complex layout demonstrating nested Flex containers to create a typical application layout with header, sidebar, and main content.",
544
+ },
545
+ },
546
+ },
547
+ };
548
+
549
+ /**
550
+ * Custom styling with CSS variables
551
+ */
552
+ export const CustomStyling: Story = {
553
+ render: () => (
554
+ <Flex
555
+ gap="md"
556
+ styles={
557
+ {
558
+ "--flex-gap": "3rem",
559
+ padding: "2rem",
560
+ border: "2px solid #1976d2",
561
+ borderRadius: "0.5rem",
562
+ background: "linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%)",
563
+ } as React.CSSProperties
564
+ }
565
+ >
566
+ <div style={{ padding: "1rem", background: "white", borderRadius: "0.25rem" }}>
567
+ Custom gap via --flex-gap
568
+ </div>
569
+ <div style={{ padding: "1rem", background: "white", borderRadius: "0.25rem" }}>
570
+ Custom styles
571
+ </div>
572
+ <div style={{ padding: "1rem", background: "white", borderRadius: "0.25rem" }}>
573
+ Via styles prop
574
+ </div>
575
+ </Flex>
576
+ ),
577
+ parameters: {
578
+ docs: {
579
+ description: {
580
+ story:
581
+ "Demonstrates custom styling using CSS custom properties and inline styles via the styles prop.",
582
+ },
583
+ },
584
+ },
585
+ };
586
+
587
+ /**
588
+ * Polymorphic rendering
589
+ */
590
+ export const PolymorphicFlex: Story = {
591
+ render: () => (
592
+ <div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
593
+ <div>
594
+ <h4 style={{ marginBottom: "0.5rem" }}>Render as &lt;nav&gt;</h4>
595
+ <Flex
596
+ as="nav"
597
+ role="navigation"
598
+ aria-label="Main navigation"
599
+ gap="md"
600
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
601
+ >
602
+ <a href="#" style={{ padding: "0.5rem", textDecoration: "none", color: "#1976d2" }}>
603
+ Home
604
+ </a>
605
+ <a href="#" style={{ padding: "0.5rem", textDecoration: "none", color: "#1976d2" }}>
606
+ About
607
+ </a>
608
+ <a href="#" style={{ padding: "0.5rem", textDecoration: "none", color: "#1976d2" }}>
609
+ Contact
610
+ </a>
611
+ </Flex>
612
+ </div>
613
+
614
+ <div>
615
+ <h4 style={{ marginBottom: "0.5rem" }}>Render as &lt;section&gt;</h4>
616
+ <Flex
617
+ as="section"
618
+ direction="column"
619
+ gap="md"
620
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
621
+ >
622
+ <h3 style={{ margin: 0 }}>Section Title</h3>
623
+ <p style={{ margin: 0 }}>Content in a semantic section element</p>
624
+ </Flex>
625
+ </div>
626
+ </div>
627
+ ),
628
+ parameters: {
629
+ docs: {
630
+ description: {
631
+ story:
632
+ "The 'as' prop allows Flex to render as any HTML element, enabling semantic markup while maintaining flexbox behavior.",
633
+ },
634
+ },
635
+ },
636
+ };
637
+
638
+ // ============================================================================
639
+ // UTILITY CLASS STORIES (Preserved for backward compatibility)
640
+ // ============================================================================
641
+
642
+ /**
643
+ * Basic flex container with default gap
644
+ */
645
+ export const BasicFlex: Story = {
646
+ render: () => (
647
+ <div
648
+ className="flex"
649
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
650
+ >
651
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
652
+ Item 1
653
+ </div>
654
+ <div style={{ padding: "1rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
655
+ Item 2
656
+ </div>
657
+ <div style={{ padding: "1rem", background: "#90caf9", borderRadius: "0.25rem" }}>
658
+ Item 3
659
+ </div>
660
+ </div>
661
+ ),
662
+ parameters: {
663
+ docs: {
664
+ description: {
665
+ story: "Basic flex container with default gap. The `.flex` class provides `display: flex` with automatic gap spacing.",
666
+ },
667
+ },
668
+ },
669
+ };
670
+
671
+ /**
672
+ * Flex direction utilities
673
+ */
674
+ export const FlexDirection: Story = {
675
+ render: () => (
676
+ <div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
677
+ <div>
678
+ <h3 style={{ marginBottom: "0.5rem" }}>Row (default)</h3>
679
+ <div
680
+ className="flex flex-row gap-sm"
681
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
682
+ >
683
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>1</div>
684
+ <div style={{ padding: "1rem", background: "#bbdefb", borderRadius: "0.25rem" }}>2</div>
685
+ <div style={{ padding: "1rem", background: "#90caf9", borderRadius: "0.25rem" }}>3</div>
686
+ </div>
687
+ </div>
688
+
689
+ <div>
690
+ <h3 style={{ marginBottom: "0.5rem" }}>Column</h3>
691
+ <div
692
+ className="flex flex-col gap-sm"
693
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
694
+ >
695
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>1</div>
696
+ <div style={{ padding: "1rem", background: "#bbdefb", borderRadius: "0.25rem" }}>2</div>
697
+ <div style={{ padding: "1rem", background: "#90caf9", borderRadius: "0.25rem" }}>3</div>
698
+ </div>
699
+ </div>
700
+
701
+ <div>
702
+ <h3 style={{ marginBottom: "0.5rem" }}>Row Reverse</h3>
703
+ <div
704
+ className="flex flex-row-reverse gap-sm"
705
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
706
+ >
707
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>1</div>
708
+ <div style={{ padding: "1rem", background: "#bbdefb", borderRadius: "0.25rem" }}>2</div>
709
+ <div style={{ padding: "1rem", background: "#90caf9", borderRadius: "0.25rem" }}>3</div>
710
+ </div>
711
+ </div>
712
+ </div>
713
+ ),
714
+ parameters: {
715
+ docs: {
716
+ description: {
717
+ story: "Flex direction utilities: `.flex-row`, `.flex-col`, `.flex-row-reverse`, `.flex-col-reverse`",
718
+ },
719
+ },
720
+ },
721
+ };
722
+
723
+ /**
724
+ * Justify content (main axis alignment)
725
+ */
726
+ export const JustifyContent: Story = {
727
+ render: () => (
728
+ <div style={{ display: "flex", flexDirection: "column", gap: "1.5rem" }}>
729
+ {[
730
+ { class: "justify-start", label: "Start" },
731
+ { class: "justify-center", label: "Center" },
732
+ { class: "justify-end", label: "End" },
733
+ { class: "justify-between", label: "Space Between" },
734
+ { class: "justify-around", label: "Space Around" },
735
+ { class: "justify-evenly", label: "Space Evenly" },
736
+ ].map(({ class: className, label }) => (
737
+ <div key={className}>
738
+ <h4 style={{ marginBottom: "0.5rem", fontSize: "0.875rem" }}>{label}</h4>
739
+ <div
740
+ className={`flex ${className}`}
741
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
742
+ >
743
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
744
+ A
745
+ </div>
746
+ <div style={{ padding: "0.75rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
747
+ B
748
+ </div>
749
+ <div style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}>
750
+ C
751
+ </div>
752
+ </div>
753
+ </div>
754
+ ))}
755
+ </div>
756
+ ),
757
+ parameters: {
758
+ docs: {
759
+ description: {
760
+ story:
761
+ "Justify content utilities control main axis alignment: `.justify-start`, `.justify-center`, `.justify-end`, `.justify-between`, `.justify-around`, `.justify-evenly`",
762
+ },
763
+ },
764
+ },
765
+ };
766
+
767
+ /**
768
+ * Align items (cross axis alignment)
769
+ */
770
+ export const AlignItems: Story = {
771
+ render: () => (
772
+ <div style={{ display: "flex", flexDirection: "column", gap: "1.5rem" }}>
773
+ {[
774
+ { class: "items-start", label: "Start" },
775
+ { class: "items-center", label: "Center" },
776
+ { class: "items-end", label: "End" },
777
+ { class: "items-stretch", label: "Stretch" },
778
+ { class: "items-baseline", label: "Baseline" },
779
+ ].map(({ class: className, label }) => (
780
+ <div key={className}>
781
+ <h4 style={{ marginBottom: "0.5rem", fontSize: "0.875rem" }}>{label}</h4>
782
+ <div
783
+ className={`flex ${className}`}
784
+ style={{
785
+ padding: "1rem",
786
+ border: "2px dashed #ccc",
787
+ borderRadius: "0.5rem",
788
+ minHeight: "6rem",
789
+ }}
790
+ >
791
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
792
+ Small
793
+ </div>
794
+ <div
795
+ style={{
796
+ padding: "0.75rem",
797
+ background: "#bbdefb",
798
+ borderRadius: "0.25rem",
799
+ height: "4rem",
800
+ }}
801
+ >
802
+ Medium
803
+ </div>
804
+ <div style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}>
805
+ Small
806
+ </div>
807
+ </div>
808
+ </div>
809
+ ))}
810
+ </div>
811
+ ),
812
+ parameters: {
813
+ docs: {
814
+ description: {
815
+ story:
816
+ "Align items utilities control cross axis alignment: `.items-start`, `.items-center`, `.items-end`, `.items-stretch`, `.items-baseline`",
817
+ },
818
+ },
819
+ },
820
+ };
821
+
822
+ /**
823
+ * Gap utilities
824
+ */
825
+ export const GapUtilities: Story = {
826
+ render: () => (
827
+ <div style={{ display: "flex", flexDirection: "column", gap: "1.5rem" }}>
828
+ {[
829
+ { class: "gap-0", label: "No Gap (gap-0)" },
830
+ { class: "gap-xs", label: "Extra Small (gap-xs)" },
831
+ { class: "gap-sm", label: "Small (gap-sm)" },
832
+ { class: "gap-md", label: "Medium (gap-md)" },
833
+ { class: "gap-lg", label: "Large (gap-lg)" },
834
+ { class: "gap-xl", label: "Extra Large (gap-xl)" },
835
+ ].map(({ class: className, label }) => (
836
+ <div key={className}>
837
+ <h4 style={{ marginBottom: "0.5rem", fontSize: "0.875rem" }}>{label}</h4>
838
+ <div
839
+ className={`flex ${className}`}
840
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
841
+ >
842
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
843
+ Item 1
844
+ </div>
845
+ <div style={{ padding: "0.75rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
846
+ Item 2
847
+ </div>
848
+ <div style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}>
849
+ Item 3
850
+ </div>
851
+ </div>
852
+ </div>
853
+ ))}
854
+ </div>
855
+ ),
856
+ parameters: {
857
+ docs: {
858
+ description: {
859
+ story:
860
+ "Gap utilities use fluid spacing with `clamp()`. Available: `.gap-0`, `.gap-xs`, `.gap-sm`, `.gap-md`, `.gap-lg`, `.gap-xl`. Also supports `.row-gap-*` and `.col-gap-*` for independent control.",
861
+ },
862
+ },
863
+ },
864
+ };
865
+
866
+ /**
867
+ * Flex item sizing
868
+ */
869
+ export const FlexSizing: Story = {
870
+ render: () => (
871
+ <div style={{ display: "flex", flexDirection: "column", gap: "1.5rem" }}>
872
+ <div>
873
+ <h4 style={{ marginBottom: "0.5rem", fontSize: "0.875rem" }}>
874
+ flex-1 (Equal width items)
875
+ </h4>
876
+ <div
877
+ className="flex gap-sm"
878
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
879
+ >
880
+ <div
881
+ className="flex-1"
882
+ style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}
883
+ >
884
+ flex-1
885
+ </div>
886
+ <div
887
+ className="flex-1"
888
+ style={{ padding: "0.75rem", background: "#bbdefb", borderRadius: "0.25rem" }}
889
+ >
890
+ flex-1
891
+ </div>
892
+ <div
893
+ className="flex-1"
894
+ style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}
895
+ >
896
+ flex-1
897
+ </div>
898
+ </div>
899
+ </div>
900
+
901
+ <div>
902
+ <h4 style={{ marginBottom: "0.5rem", fontSize: "0.875rem" }}>
903
+ flex-auto (Content-based sizing)
904
+ </h4>
905
+ <div
906
+ className="flex gap-sm"
907
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
908
+ >
909
+ <div
910
+ className="flex-auto"
911
+ style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}
912
+ >
913
+ Short
914
+ </div>
915
+ <div
916
+ className="flex-auto"
917
+ style={{ padding: "0.75rem", background: "#bbdefb", borderRadius: "0.25rem" }}
918
+ >
919
+ Medium content here
920
+ </div>
921
+ <div
922
+ className="flex-auto"
923
+ style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}
924
+ >
925
+ Longer content that takes more space
926
+ </div>
927
+ </div>
928
+ </div>
929
+
930
+ <div>
931
+ <h4 style={{ marginBottom: "0.5rem", fontSize: "0.875rem" }}>
932
+ flex-none (Fixed width)
933
+ </h4>
934
+ <div
935
+ className="flex gap-sm"
936
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
937
+ >
938
+ <div
939
+ className="flex-none"
940
+ style={{
941
+ padding: "0.75rem",
942
+ background: "#e3f2fd",
943
+ borderRadius: "0.25rem",
944
+ width: "8rem",
945
+ }}
946
+ >
947
+ Fixed 8rem
948
+ </div>
949
+ <div
950
+ className="flex-1"
951
+ style={{ padding: "0.75rem", background: "#bbdefb", borderRadius: "0.25rem" }}
952
+ >
953
+ flex-1 fills remaining
954
+ </div>
955
+ </div>
956
+ </div>
957
+ </div>
958
+ ),
959
+ parameters: {
960
+ docs: {
961
+ description: {
962
+ story:
963
+ "Flex item sizing: `.flex-1` (equal distribution), `.flex-auto` (content-based), `.flex-initial` (default), `.flex-none` (no grow/shrink)",
964
+ },
965
+ },
966
+ },
967
+ };
968
+
969
+ /**
970
+ * Common patterns
971
+ */
972
+ export const CommonPatterns: Story = {
973
+ render: () => (
974
+ <div style={{ display: "flex", flexDirection: "column", gap: "1.5rem" }}>
975
+ <div>
976
+ <h4 style={{ marginBottom: "0.5rem", fontSize: "0.875rem" }}>
977
+ flex-center (Center both axes)
978
+ </h4>
979
+ <div
980
+ className="flex-center"
981
+ style={{
982
+ padding: "2rem",
983
+ border: "2px dashed #ccc",
984
+ borderRadius: "0.5rem",
985
+ minHeight: "8rem",
986
+ }}
987
+ >
988
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
989
+ Centered Content
990
+ </div>
991
+ </div>
992
+ </div>
993
+
994
+ <div>
995
+ <h4 style={{ marginBottom: "0.5rem", fontSize: "0.875rem" }}>
996
+ flex-between (Space between with center alignment)
997
+ </h4>
998
+ <div
999
+ className="flex-between"
1000
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
1001
+ >
1002
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
1003
+ Left
1004
+ </div>
1005
+ <div style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}>
1006
+ Right
1007
+ </div>
1008
+ </div>
1009
+ </div>
1010
+
1011
+ <div>
1012
+ <h4 style={{ marginBottom: "0.5rem", fontSize: "0.875rem" }}>
1013
+ flex-stack (Vertical stack, becomes row on md+)
1014
+ </h4>
1015
+ <div
1016
+ className="flex-stack"
1017
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
1018
+ >
1019
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
1020
+ Item 1
1021
+ </div>
1022
+ <div style={{ padding: "1rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
1023
+ Item 2
1024
+ </div>
1025
+ <div style={{ padding: "1rem", background: "#90caf9", borderRadius: "0.25rem" }}>
1026
+ Item 3
1027
+ </div>
1028
+ </div>
1029
+ <p style={{ marginTop: "0.5rem", fontSize: "0.875rem", color: "#666" }}>
1030
+ Resize viewport to see responsive behavior (column → row at 48rem)
1031
+ </p>
1032
+ </div>
1033
+
1034
+ <div>
1035
+ <h4 style={{ marginBottom: "0.5rem", fontSize: "0.875rem" }}>
1036
+ flex-spread (Equal width children)
1037
+ </h4>
1038
+ <div
1039
+ className="flex-spread gap-sm"
1040
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
1041
+ >
1042
+ <div style={{ padding: "0.75rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
1043
+ A
1044
+ </div>
1045
+ <div style={{ padding: "0.75rem", background: "#bbdefb", borderRadius: "0.25rem" }}>
1046
+ B
1047
+ </div>
1048
+ <div style={{ padding: "0.75rem", background: "#90caf9", borderRadius: "0.25rem" }}>
1049
+ C
1050
+ </div>
1051
+ </div>
1052
+ </div>
1053
+ </div>
1054
+ ),
1055
+ parameters: {
1056
+ docs: {
1057
+ description: {
1058
+ story:
1059
+ "Common flexbox patterns: `.flex-center`, `.flex-between`, `.flex-around`, `.flex-stack`, `.flex-spread`",
1060
+ },
1061
+ },
1062
+ },
1063
+ };
1064
+
1065
+ /**
1066
+ * Responsive utilities demonstration
1067
+ */
1068
+ export const ResponsiveUtilities: Story = {
1069
+ render: () => (
1070
+ <div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
1071
+ <div>
1072
+ <h3 style={{ marginBottom: "1rem" }}>Responsive Direction</h3>
1073
+ <p style={{ marginBottom: "0.5rem", fontSize: "0.875rem", color: "#666" }}>
1074
+ Column on mobile, row on medium+ screens
1075
+ </p>
1076
+ <div
1077
+ className="flex flex-col md:flex-row gap-md"
1078
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
1079
+ >
1080
+ <div
1081
+ className="flex-1"
1082
+ style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}
1083
+ >
1084
+ Column 1
1085
+ </div>
1086
+ <div
1087
+ className="flex-1"
1088
+ style={{ padding: "1rem", background: "#bbdefb", borderRadius: "0.25rem" }}
1089
+ >
1090
+ Column 2
1091
+ </div>
1092
+ <div
1093
+ className="flex-1"
1094
+ style={{ padding: "1rem", background: "#90caf9", borderRadius: "0.25rem" }}
1095
+ >
1096
+ Column 3
1097
+ </div>
1098
+ </div>
1099
+ </div>
1100
+
1101
+ <div>
1102
+ <h3 style={{ marginBottom: "1rem" }}>Responsive Gaps</h3>
1103
+ <p style={{ marginBottom: "0.5rem", fontSize: "0.875rem", color: "#666" }}>
1104
+ Small gap on mobile, large gap on medium+ screens
1105
+ </p>
1106
+ <div
1107
+ className="flex gap-sm md:gap-lg"
1108
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
1109
+ >
1110
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>1</div>
1111
+ <div style={{ padding: "1rem", background: "#bbdefb", borderRadius: "0.25rem" }}>2</div>
1112
+ <div style={{ padding: "1rem", background: "#90caf9", borderRadius: "0.25rem" }}>3</div>
1113
+ </div>
1114
+ </div>
1115
+
1116
+ <div>
1117
+ <h3 style={{ marginBottom: "1rem" }}>Responsive Justification</h3>
1118
+ <p style={{ marginBottom: "0.5rem", fontSize: "0.875rem", color: "#666" }}>
1119
+ Start alignment on mobile, space between on large+ screens
1120
+ </p>
1121
+ <div
1122
+ className="flex justify-start lg:justify-between"
1123
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
1124
+ >
1125
+ <div style={{ padding: "1rem", background: "#e3f2fd", borderRadius: "0.25rem" }}>
1126
+ Left
1127
+ </div>
1128
+ <div style={{ padding: "1rem", background: "#90caf9", borderRadius: "0.25rem" }}>
1129
+ Right
1130
+ </div>
1131
+ </div>
1132
+ </div>
1133
+
1134
+ <div
1135
+ style={{
1136
+ padding: "1rem",
1137
+ background: "#fff3cd",
1138
+ border: "1px solid #ffc107",
1139
+ borderRadius: "0.5rem",
1140
+ marginTop: "1rem",
1141
+ }}
1142
+ >
1143
+ <strong>💡 Tip:</strong> Resize your browser window or use Storybook&apos;s viewport
1144
+ toolbar to see responsive behavior at different breakpoints (sm: 480px, md: 768px, lg:
1145
+ 992px, xl: 1280px).
1146
+ </div>
1147
+ </div>
1148
+ ),
1149
+ parameters: {
1150
+ docs: {
1151
+ description: {
1152
+ story: `Responsive modifiers allow utilities to activate at specific breakpoints.
1153
+
1154
+ **Format:** \`{breakpoint}:{utility}\`
1155
+
1156
+ **Examples:**
1157
+ - \`sm:flex-row\` - Row direction on screens ≥ 480px
1158
+ - \`md:justify-center\` - Center justify on screens ≥ 768px
1159
+ - \`lg:gap-xl\` - Extra large gap on screens ≥ 992px
1160
+ - \`xl:items-end\` - End alignment on screens ≥ 1280px
1161
+
1162
+ All base utilities support responsive modifiers: direction, wrap, justify, align, gap, and flex sizing.`,
1163
+ },
1164
+ },
1165
+ chromatic: {
1166
+ viewports: [375, 480, 768, 992, 1280],
1167
+ },
1168
+ },
1169
+ };
1170
+
1171
+ /**
1172
+ * Wrapping behavior
1173
+ */
1174
+ export const FlexWrap: Story = {
1175
+ render: () => (
1176
+ <div style={{ display: "flex", flexDirection: "column", gap: "1.5rem" }}>
1177
+ <div>
1178
+ <h4 style={{ marginBottom: "0.5rem", fontSize: "0.875rem" }}>flex-wrap (default)</h4>
1179
+ <div
1180
+ className="flex flex-wrap gap-sm"
1181
+ style={{ padding: "1rem", border: "2px dashed #ccc", borderRadius: "0.5rem" }}
1182
+ >
1183
+ {Array.from({ length: 12 }, (_, i) => (
1184
+ <div
1185
+ key={i}
1186
+ style={{
1187
+ padding: "0.75rem 1.5rem",
1188
+ background: "#e3f2fd",
1189
+ borderRadius: "0.25rem",
1190
+ }}
1191
+ >
1192
+ Item {i + 1}
1193
+ </div>
1194
+ ))}
1195
+ </div>
1196
+ </div>
1197
+
1198
+ <div>
1199
+ <h4 style={{ marginBottom: "0.5rem", fontSize: "0.875rem" }}>flex-nowrap</h4>
1200
+ <div
1201
+ className="flex flex-nowrap gap-sm"
1202
+ style={{
1203
+ padding: "1rem",
1204
+ border: "2px dashed #ccc",
1205
+ borderRadius: "0.5rem",
1206
+ overflowX: "auto",
1207
+ }}
1208
+ >
1209
+ {Array.from({ length: 12 }, (_, i) => (
1210
+ <div
1211
+ key={i}
1212
+ className="flex-shrink-0"
1213
+ style={{
1214
+ padding: "0.75rem 1.5rem",
1215
+ background: "#bbdefb",
1216
+ borderRadius: "0.25rem",
1217
+ }}
1218
+ >
1219
+ Item {i + 1}
1220
+ </div>
1221
+ ))}
1222
+ </div>
1223
+ </div>
1224
+ </div>
1225
+ ),
1226
+ parameters: {
1227
+ docs: {
1228
+ description: {
1229
+ story: "Flex wrap utilities: `.flex-wrap`, `.flex-nowrap`, `.flex-wrap-reverse`",
1230
+ },
1231
+ },
1232
+ },
1233
+ };