@fpkit/acss 2.2.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 (81) hide show
  1. package/libs/chunk-5RAWNUVD.js +8 -0
  2. package/libs/chunk-5RAWNUVD.js.map +1 -0
  3. package/libs/{chunk-UJAQVHWC.js → chunk-CWRNJA4P.js} +2 -2
  4. package/libs/{chunk-R7NLLZU2.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.d.cts +2 -2
  9. package/libs/components/breadcrumbs/breadcrumb.d.ts +2 -2
  10. package/libs/components/breadcrumbs/breadcrumb.js +2 -2
  11. package/libs/components/flexbox/flex.css +1 -0
  12. package/libs/components/flexbox/flex.css.map +1 -0
  13. package/libs/components/flexbox/flex.min.css +3 -0
  14. package/libs/components/link/link.cjs +5 -5
  15. package/libs/components/link/link.css +1 -1
  16. package/libs/components/link/link.css.map +1 -1
  17. package/libs/components/link/link.d.cts +2 -131
  18. package/libs/components/link/link.d.ts +2 -131
  19. package/libs/components/link/link.js +1 -1
  20. package/libs/components/link/link.min.css +2 -2
  21. package/libs/components/nav/nav.css +1 -1
  22. package/libs/components/nav/nav.css.map +1 -1
  23. package/libs/components/nav/nav.min.css +2 -2
  24. package/libs/hooks.cjs +3 -3
  25. package/libs/hooks.d.cts +1 -1
  26. package/libs/hooks.d.ts +1 -1
  27. package/libs/hooks.js +2 -2
  28. package/libs/index.cjs +30 -29
  29. package/libs/index.cjs.map +1 -1
  30. package/libs/index.css +1 -1
  31. package/libs/index.css.map +1 -1
  32. package/libs/index.d.cts +246 -290
  33. package/libs/index.d.ts +246 -290
  34. package/libs/index.js +15 -15
  35. package/libs/index.js.map +1 -1
  36. package/libs/link-59ad884f.d.ts +371 -0
  37. package/package.json +2 -2
  38. package/src/components/flexbox/README.mdx +996 -0
  39. package/src/components/flexbox/flex.scss +847 -0
  40. package/src/components/flexbox/flex.stories.tsx +1233 -0
  41. package/src/components/flexbox/flex.test.tsx +689 -0
  42. package/src/components/flexbox/flex.tsx +484 -0
  43. package/src/components/flexbox/flex.types.ts +224 -0
  44. package/src/components/link/link.scss +4 -10
  45. package/src/components/link/link.tsx +18 -3
  46. package/src/components/nav/nav.scss +1 -1
  47. package/src/index.scss +1 -0
  48. package/src/index.ts +19 -2
  49. package/src/patterns/page/page-header.tsx +1 -3
  50. package/src/styles/flexbox/flex.css +736 -0
  51. package/src/styles/flexbox/flex.css.map +1 -0
  52. package/src/styles/index.css +739 -9
  53. package/src/styles/index.css.map +1 -1
  54. package/src/styles/link/link.css +2 -6
  55. package/src/styles/link/link.css.map +1 -1
  56. package/src/styles/nav/nav.css +3 -3
  57. package/libs/chunk-5PJYLVFY.cjs +0 -17
  58. package/libs/chunk-5PJYLVFY.cjs.map +0 -1
  59. package/libs/chunk-NNTBIHSD.js +0 -8
  60. package/libs/chunk-NNTBIHSD.js.map +0 -1
  61. package/libs/components/alert/alert.min.min.css +0 -2
  62. package/libs/components/badge/badge.min.min.css +0 -2
  63. package/libs/components/breadcrumbs/breadcrumb.min.min.css +0 -2
  64. package/libs/components/buttons/button.min.min.css +0 -2
  65. package/libs/components/cards/card-style.min.min.css +0 -2
  66. package/libs/components/cards/card.min.min.css +0 -2
  67. package/libs/components/details/details.min.min.css +0 -2
  68. package/libs/components/dialog/dialog.min.min.css +0 -2
  69. package/libs/components/form/form.min.min.css +0 -2
  70. package/libs/components/icons/icon.min.min.css +0 -2
  71. package/libs/components/images/img.min.min.css +0 -2
  72. package/libs/components/layout/landmarks.min.min.css +0 -2
  73. package/libs/components/link/link.min.min.css +0 -2
  74. package/libs/components/list/list.min.min.css +0 -2
  75. package/libs/components/nav/nav.min.min.css +0 -2
  76. package/libs/components/progress/progress.min.min.css +0 -2
  77. package/libs/components/styles/index.min.min.css +0 -2
  78. package/libs/components/tag/tag.min.min.css +0 -2
  79. package/libs/components/text-to-speech/text-to-speech.min.min.css +0 -2
  80. /package/libs/{chunk-UJAQVHWC.js.map → chunk-CWRNJA4P.js.map} +0 -0
  81. /package/libs/{chunk-R7NLLZU2.cjs.map → chunk-DYFAUAB7.cjs.map} +0 -0
@@ -0,0 +1,996 @@
1
+ import { Meta } from "@storybook/addon-docs/blocks";
2
+
3
+ <Meta title="FP.REACT Components/Layout/Flex/Readme" />
4
+
5
+ # Flex Component
6
+
7
+ A powerful, type-safe flexbox layout component with compound pattern, responsive
8
+ props, and semantic element restrictions. Built for modern React applications
9
+ with accessibility-first design and full TypeScript support.
10
+
11
+ ## Summary
12
+
13
+ The `Flex` component provides a declarative React API for flexbox layouts,
14
+ converting props to utility classes for optimal performance. Features responsive
15
+ breakpoint props, preset layout variants, and enforced semantic HTML structure.
16
+
17
+ **Latest Version:** v3.0.0+ (Enhanced with type-safe semantic elements)
18
+
19
+ ## Features
20
+
21
+ - 🧩 **Compound component pattern** - Flex.Item and Flex.Spacer sub-components
22
+ - 📱 **Responsive props** - Different layouts at sm/md/lg/xl breakpoints
23
+ - 🎯 **Preset variants** - Common patterns like 'center', 'between', 'stack'
24
+ - 🔒 **Type-safe semantic elements** - Restricts `as` prop to valid container
25
+ elements
26
+ - ⚡ **Performance optimized** - Generates utility classes, not inline styles
27
+ - 🎨 **CSS custom properties** - Full theming via CSS variables
28
+ - 📦 **TypeScript support** - Comprehensive type definitions with autocomplete
29
+ - ♿ **Accessibility-first** - Semantic HTML by default
30
+ - 🧪 **100% test coverage** - 62 comprehensive tests
31
+
32
+ ## Accessibility
33
+
34
+ This component has been designed for WCAG 2.1 AA compliance:
35
+
36
+ - ✅ Uses semantic HTML container elements (section, article, nav, etc.)
37
+ - ✅ Type system enforces proper element usage (no inline/interactive elements)
38
+ - ✅ Forwards all ARIA attributes to rendered elements
39
+ - ✅ No interactive behavior by default (purely layout)
40
+ - ✅ Supports semantic list structures (ul/ol with li elements)
41
+ - ✅ Maintains logical tab order based on DOM structure
42
+ - ✅ Flexbox respects text spacing and zoom requirements
43
+
44
+ ### Semantic Element Restrictions
45
+
46
+ The `as` prop is restricted to semantic container elements to ensure proper HTML
47
+ structure:
48
+
49
+ **✅ Allowed Elements:**
50
+
51
+ - **Block containers**: `div` (default), `section`, `article`, `aside`, `main`,
52
+ `header`, `footer`
53
+ - **List containers**: `ul`, `ol`, `dl`, `nav`
54
+ - **Form containers**: `form`, `fieldset`
55
+ - **List items** (Flex.Item only): `li`, `dt`, `dd`
56
+
57
+ **❌ Not Allowed:**
58
+
59
+ - Inline elements: `span`, `a`, `strong`, `em`
60
+ - Interactive elements: `button`, `input`, `select`
61
+ - Void elements: `img`, `hr`, `br`
62
+
63
+ This restriction prevents common accessibility mistakes and ensures semantic
64
+ HTML structure.
65
+
66
+ ## Props
67
+
68
+ ### Flex (Main Component)
69
+
70
+ ```ts
71
+ interface FlexProps extends ResponsiveFlexProps {
72
+ /** Preset layout variant */
73
+ variant?: "center" | "between" | "around" | "stack" | "spread";
74
+
75
+ /** Use inline-flex instead of flex */
76
+ inline?: boolean;
77
+
78
+ /** Element type to render as (restricted to container elements) */
79
+ as?: FlexContainerElement;
80
+
81
+ /** Additional CSS class names */
82
+ className?: string;
83
+
84
+ /** Inline styles and CSS custom properties */
85
+ styles?: React.CSSProperties;
86
+
87
+ /** Children elements */
88
+ children?: React.ReactNode;
89
+
90
+ /** Responsive props for small screens (≥30rem / 480px) */
91
+ sm?: ResponsiveFlexProps;
92
+
93
+ /** Responsive props for medium screens (≥48rem / 768px) */
94
+ md?: ResponsiveFlexProps;
95
+
96
+ /** Responsive props for large screens (≥62rem / 992px) */
97
+ lg?: ResponsiveFlexProps;
98
+
99
+ /** Responsive props for extra large screens (≥80rem / 1280px) */
100
+ xl?: ResponsiveFlexProps;
101
+
102
+ /** Flex direction */
103
+ direction?: "row" | "row-reverse" | "column" | "column-reverse";
104
+
105
+ /** Flex wrap behavior */
106
+ wrap?: "wrap" | "nowrap" | "wrap-reverse";
107
+
108
+ /** Gap between flex items */
109
+ gap?: "0" | "xs" | "sm" | "md" | "lg" | "xl";
110
+
111
+ /** Row gap (vertical spacing) */
112
+ rowGap?: "0" | "xs" | "sm" | "md" | "lg" | "xl";
113
+
114
+ /** Column gap (horizontal spacing) */
115
+ colGap?: "0" | "xs" | "sm" | "md" | "lg" | "xl";
116
+
117
+ /** Justify content (main axis alignment) */
118
+ justify?: "start" | "end" | "center" | "between" | "around" | "evenly";
119
+
120
+ /** Align items (cross axis alignment) */
121
+ align?: "start" | "end" | "center" | "baseline" | "stretch";
122
+
123
+ /** Align content (multi-line alignment) */
124
+ alignContent?:
125
+ | "start"
126
+ | "end"
127
+ | "center"
128
+ | "between"
129
+ | "around"
130
+ | "evenly"
131
+ | "stretch";
132
+ }
133
+ ```
134
+
135
+ ### Flex.Item
136
+
137
+ ```ts
138
+ interface FlexItemProps {
139
+ /** Element type to render as (includes list items) */
140
+ as?: FlexItemElement;
141
+
142
+ /** Flex grow factor */
143
+ grow?: 0 | 1;
144
+
145
+ /** Flex shrink factor */
146
+ shrink?: 0 | 1;
147
+
148
+ /** Flex basis */
149
+ basis?: "auto" | "0" | "full";
150
+
151
+ /** Flex shorthand */
152
+ flex?: "1" | "auto" | "initial" | "none";
153
+
154
+ /** Align self (overrides parent align-items) */
155
+ alignSelf?: "auto" | "start" | "end" | "center" | "baseline" | "stretch";
156
+
157
+ /** Order of the flex item */
158
+ order?: "first" | "last" | "none";
159
+
160
+ /** Additional CSS class names */
161
+ className?: string;
162
+
163
+ /** Inline styles and CSS custom properties */
164
+ styles?: React.CSSProperties;
165
+
166
+ /** Children elements */
167
+ children?: React.ReactNode;
168
+
169
+ /** Responsive props for different breakpoints */
170
+ sm?: { flex?: "1" | "auto" | "none" };
171
+ md?: { flex?: "1" | "auto" | "none" };
172
+ lg?: { flex?: "1" | "auto" | "none" };
173
+ xl?: { flex?: "1" | "auto" | "none" };
174
+ }
175
+ ```
176
+
177
+ ### Flex.Spacer
178
+
179
+ ```ts
180
+ interface FlexSpacerProps {
181
+ /** Element type to render as (container elements only) */
182
+ as?: FlexContainerElement;
183
+
184
+ /** Additional CSS class names */
185
+ className?: string;
186
+
187
+ /** Inline styles and CSS custom properties */
188
+ styles?: React.CSSProperties;
189
+ }
190
+ ```
191
+
192
+ ### Default Values
193
+
194
+ | Prop | Default | Description |
195
+ | ----------- | ------- | ----------------------------------------- |
196
+ | `as` | `"div"` | Container element type |
197
+ | `inline` | `false` | Display mode (flex vs inline-flex) |
198
+ | `direction` | - | No default (uses CSS default: row) |
199
+ | `wrap` | - | No default (uses CSS default: nowrap) |
200
+ | `gap` | - | No gap by default |
201
+ | `justify` | - | No default (uses CSS default: flex-start) |
202
+ | `align` | - | No default (uses CSS default: stretch) |
203
+
204
+ ## Usage Examples
205
+
206
+ ### Basic Flex Container
207
+
208
+ ```tsx
209
+ import { Flex } from "@fpkit/acss";
210
+
211
+ function BasicLayout() {
212
+ return (
213
+ <Flex direction="row" gap="md" justify="between" align="center">
214
+ <div>Item 1</div>
215
+ <div>Item 2</div>
216
+ <div>Item 3</div>
217
+ </Flex>
218
+ );
219
+ }
220
+ ```
221
+
222
+ ### Responsive Layout
223
+
224
+ Column on mobile, row on medium+ screens:
225
+
226
+ ```tsx
227
+ import { Flex } from "@fpkit/acss";
228
+
229
+ function ResponsiveLayout() {
230
+ return (
231
+ <Flex direction="column" gap="sm" md={{ direction: "row", gap: "lg" }}>
232
+ <Flex.Item flex="none" md={{ flex: "1" }}>
233
+ <h2>Sidebar</h2>
234
+ <p>Navigation content</p>
235
+ </Flex.Item>
236
+
237
+ <Flex.Item flex="none" md={{ flex: "1" }}>
238
+ <h2>Main Content</h2>
239
+ <p>Primary content area</p>
240
+ </Flex.Item>
241
+ </Flex>
242
+ );
243
+ }
244
+ ```
245
+
246
+ ### Using Preset Variants
247
+
248
+ Quick layouts with common patterns:
249
+
250
+ ```tsx
251
+ import { Flex } from "@fpkit/acss";
252
+
253
+ function PresetVariants() {
254
+ return (
255
+ <>
256
+ {/* Center everything */}
257
+ <Flex variant="center">
258
+ <div>Centered content</div>
259
+ </Flex>
260
+
261
+ {/* Space between items */}
262
+ <Flex variant="between">
263
+ <div>Left</div>
264
+ <div>Right</div>
265
+ </Flex>
266
+
267
+ {/* Vertical stack */}
268
+ <Flex variant="stack" gap="md">
269
+ <div>Item 1</div>
270
+ <div>Item 2</div>
271
+ </Flex>
272
+ </>
273
+ );
274
+ }
275
+ ```
276
+
277
+ ### Flex.Spacer for Pushing Items Apart
278
+
279
+ ```tsx
280
+ import { Flex } from "@fpkit/acss";
281
+
282
+ function Header() {
283
+ return (
284
+ <Flex as="header" align="center" gap="md">
285
+ <div>Logo</div>
286
+ <nav>
287
+ <a href="/">Home</a>
288
+ <a href="/about">About</a>
289
+ </nav>
290
+ <Flex.Spacer />
291
+ <button>Sign In</button>
292
+ <button>Sign Up</button>
293
+ </Flex>
294
+ );
295
+ }
296
+ ```
297
+
298
+ ### Semantic Navigation with Flex
299
+
300
+ ```tsx
301
+ import { Flex } from "@fpkit/acss";
302
+
303
+ function Navigation() {
304
+ return (
305
+ <Flex as="nav" role="navigation" aria-label="Main navigation" gap="md">
306
+ <a href="/">Home</a>
307
+ <a href="/products">Products</a>
308
+ <a href="/about">About</a>
309
+ <a href="/contact">Contact</a>
310
+ </Flex>
311
+ );
312
+ }
313
+ ```
314
+
315
+ ### Semantic List Structure
316
+
317
+ ```tsx
318
+ import { Flex } from "@fpkit/acss";
319
+
320
+ function ProductList({ products }) {
321
+ return (
322
+ <Flex as="ul" direction="column" gap="md">
323
+ {products.map((product) => (
324
+ <Flex.Item as="li" key={product.id}>
325
+ <h3>{product.name}</h3>
326
+ <p>{product.description}</p>
327
+ <span>${product.price}</span>
328
+ </Flex.Item>
329
+ ))}
330
+ </Flex>
331
+ );
332
+ }
333
+ ```
334
+
335
+ ### Complex Responsive Grid
336
+
337
+ ```tsx
338
+ import { Flex } from "@fpkit/acss";
339
+
340
+ function ProductGrid({ products }) {
341
+ return (
342
+ <Flex
343
+ direction="column"
344
+ gap="sm"
345
+ sm={{ direction: "row", wrap: "wrap", gap: "md" }}
346
+ >
347
+ {products.map((product) => (
348
+ <Flex.Item
349
+ key={product.id}
350
+ flex="none"
351
+ sm={{ flex: "1" }}
352
+ styles={{ minWidth: "300px" }}
353
+ >
354
+ <article>
355
+ <img src={product.image} alt={product.name} />
356
+ <h3>{product.name}</h3>
357
+ <p>{product.description}</p>
358
+ <button>Add to Cart</button>
359
+ </article>
360
+ </Flex.Item>
361
+ ))}
362
+ </Flex>
363
+ );
364
+ }
365
+ ```
366
+
367
+ ### Form Layout with Flexbox
368
+
369
+ ```tsx
370
+ import { Flex } from "@fpkit/acss";
371
+
372
+ function LoginForm() {
373
+ return (
374
+ <Flex as="form" direction="column" gap="md">
375
+ <Flex direction="column" gap="xs">
376
+ <label htmlFor="email">Email</label>
377
+ <input id="email" type="email" />
378
+ </Flex>
379
+
380
+ <Flex direction="column" gap="xs">
381
+ <label htmlFor="password">Password</label>
382
+ <input id="password" type="password" />
383
+ </Flex>
384
+
385
+ <Flex gap="md" justify="between" align="center">
386
+ <label>
387
+ <input type="checkbox" /> Remember me
388
+ </label>
389
+ <button type="submit">Sign In</button>
390
+ </Flex>
391
+ </Flex>
392
+ );
393
+ }
394
+ ```
395
+
396
+ ### Flex.Item with Alignment
397
+
398
+ ```tsx
399
+ import { Flex } from "@fpkit/acss";
400
+
401
+ function AlignmentExample() {
402
+ return (
403
+ <Flex direction="row" gap="md" styles={{ minHeight: "200px" }}>
404
+ <Flex.Item alignSelf="start">
405
+ <div>Aligned to start</div>
406
+ </Flex.Item>
407
+
408
+ <Flex.Item alignSelf="center">
409
+ <div>Centered vertically</div>
410
+ </Flex.Item>
411
+
412
+ <Flex.Item alignSelf="end">
413
+ <div>Aligned to end</div>
414
+ </Flex.Item>
415
+
416
+ <Flex.Item alignSelf="stretch">
417
+ <div>Stretched to full height</div>
418
+ </Flex.Item>
419
+ </Flex>
420
+ );
421
+ }
422
+ ```
423
+
424
+ ### Visual Order Control
425
+
426
+ ```tsx
427
+ import { Flex } from "@fpkit/acss";
428
+
429
+ function OrderExample() {
430
+ return (
431
+ <Flex direction="row" gap="md">
432
+ <Flex.Item order="last">
433
+ <div>Renders first in HTML, displays last visually</div>
434
+ </Flex.Item>
435
+
436
+ <Flex.Item>
437
+ <div>Normal order (middle)</div>
438
+ </Flex.Item>
439
+
440
+ <Flex.Item order="first">
441
+ <div>Renders last in HTML, displays first visually</div>
442
+ </Flex.Item>
443
+ </Flex>
444
+ );
445
+ }
446
+ ```
447
+
448
+ ### Dashboard Layout
449
+
450
+ ```tsx
451
+ import { Flex } from "@fpkit/acss";
452
+
453
+ function Dashboard() {
454
+ return (
455
+ <Flex direction="column" gap="lg" styles={{ minHeight: "100vh" }}>
456
+ {/* Header */}
457
+ <Flex as="header" justify="between" align="center" gap="md">
458
+ <h1>Dashboard</h1>
459
+ <nav>
460
+ <Flex gap="md">
461
+ <a href="/profile">Profile</a>
462
+ <a href="/settings">Settings</a>
463
+ <button>Logout</button>
464
+ </Flex>
465
+ </nav>
466
+ </Flex>
467
+
468
+ {/* Main content area */}
469
+ <Flex as="main" flex="1" gap="lg">
470
+ {/* Sidebar */}
471
+ <Flex
472
+ as="aside"
473
+ direction="column"
474
+ gap="md"
475
+ styles={{ width: "250px" }}
476
+ >
477
+ <nav>
478
+ <Flex direction="column" gap="sm">
479
+ <a href="/dashboard">Overview</a>
480
+ <a href="/analytics">Analytics</a>
481
+ <a href="/reports">Reports</a>
482
+ </Flex>
483
+ </nav>
484
+ </Flex>
485
+
486
+ {/* Content */}
487
+ <Flex as="section" direction="column" gap="md" flex="1">
488
+ <h2>Overview</h2>
489
+ <Flex wrap="wrap" gap="md">
490
+ <Flex.Item flex="1" styles={{ minWidth: "300px" }}>
491
+ <article>Metric 1</article>
492
+ </Flex.Item>
493
+ <Flex.Item flex="1" styles={{ minWidth: "300px" }}>
494
+ <article>Metric 2</article>
495
+ </Flex.Item>
496
+ <Flex.Item flex="1" styles={{ minWidth: "300px" }}>
497
+ <article>Metric 3</article>
498
+ </Flex.Item>
499
+ </Flex>
500
+ </Flex>
501
+ </Flex>
502
+
503
+ {/* Footer */}
504
+ <Flex as="footer" justify="center" gap="md">
505
+ <a href="/privacy">Privacy</a>
506
+ <a href="/terms">Terms</a>
507
+ <a href="/contact">Contact</a>
508
+ </Flex>
509
+ </Flex>
510
+ );
511
+ }
512
+ ```
513
+
514
+ ## Styling
515
+
516
+ The Flex component uses CSS utility classes and custom properties for styling.
517
+
518
+ ### CSS Utility Classes Generated
519
+
520
+ The component automatically generates utility class names from props:
521
+
522
+ ```tsx
523
+ // These props:
524
+ <Flex direction="row" gap="md" justify="between" align="center">
525
+
526
+ // Generate these classes:
527
+ // "flex flex-row gap-md justify-between items-center"
528
+ ```
529
+
530
+ ### Responsive Classes
531
+
532
+ Responsive props generate breakpoint-prefixed classes:
533
+
534
+ ```tsx
535
+ // These props:
536
+ <Flex
537
+ direction="column"
538
+ md={{ direction: "row", gap: "lg" }}
539
+ >
540
+
541
+ // Generate these classes:
542
+ // "flex flex-col md:flex-row md:gap-lg"
543
+ ```
544
+
545
+ ### CSS Custom Properties
546
+
547
+ Override default spacing via CSS variables:
548
+
549
+ ```css
550
+ :root {
551
+ /* Gap sizes (in rem) */
552
+ --flex-gap-0: 0;
553
+ --flex-gap-xs: 0.25rem;
554
+ --flex-gap-sm: 0.5rem;
555
+ --flex-gap-md: 1rem;
556
+ --flex-gap-lg: 1.5rem;
557
+ --flex-gap-xl: 2rem;
558
+ }
559
+ ```
560
+
561
+ ### Custom Styling Examples
562
+
563
+ **Inline Styles:**
564
+
565
+ ```tsx
566
+ <Flex styles={{ backgroundColor: "#f5f5f5", padding: "2rem" }}>
567
+ <div>Custom styled flex</div>
568
+ </Flex>
569
+ ```
570
+
571
+ **CSS Classes:**
572
+
573
+ ```tsx
574
+ <Flex className="custom-layout shadow-lg">
575
+ <div>With custom classes</div>
576
+ </Flex>
577
+ ```
578
+
579
+ **CSS Variables:**
580
+
581
+ ```tsx
582
+ <Flex
583
+ gap="md"
584
+ styles={
585
+ {
586
+ "--flex-gap-md": "2rem",
587
+ } as React.CSSProperties
588
+ }
589
+ >
590
+ <div>Custom gap size</div>
591
+ </Flex>
592
+ ```
593
+
594
+ ## Breakpoints
595
+
596
+ The component supports four responsive breakpoints:
597
+
598
+ | Breakpoint | Minimum Width | Example Usage |
599
+ | ---------- | -------------- | ----------------------------- |
600
+ | `sm` | 30rem (480px) | `sm={{ direction: "row" }}` |
601
+ | `md` | 48rem (768px) | `md={{ gap: "lg" }}` |
602
+ | `lg` | 62rem (992px) | `lg={{ wrap: "wrap" }}` |
603
+ | `xl` | 80rem (1280px) | `xl={{ justify: "between" }}` |
604
+
605
+ ### Responsive Design Patterns
606
+
607
+ **Mobile-First Approach:**
608
+
609
+ ```tsx
610
+ <Flex
611
+ direction="column" // Default: column on mobile
612
+ sm={{ direction: "row" }} // Row on small+
613
+ lg={{ gap: "xl" }} // Larger gap on large+
614
+ >
615
+ {/* Content */}
616
+ </Flex>
617
+ ```
618
+
619
+ **Desktop-First Approach:**
620
+
621
+ ```tsx
622
+ <Flex
623
+ direction="row" // Default: row on desktop
624
+ lg={{ direction: "column" }} // Column on large screens only
625
+ >
626
+ {/* Content */}
627
+ </Flex>
628
+ ```
629
+
630
+ ## Type Safety
631
+
632
+ ### Semantic Element Enforcement
633
+
634
+ TypeScript prevents invalid element usage at compile-time:
635
+
636
+ ```tsx
637
+ // ✅ Valid - div is a container element
638
+ <Flex as="div">...</Flex>
639
+
640
+ // ✅ Valid - section is semantic
641
+ <Flex as="section">...</Flex>
642
+
643
+ // ✅ Valid - nav is a list container
644
+ <Flex as="nav">...</Flex>
645
+
646
+ // ❌ TypeScript Error - span is not a container element
647
+ <Flex as="span">...</Flex>
648
+
649
+ // ❌ TypeScript Error - button is interactive
650
+ <Flex as="button">...</Flex>
651
+
652
+ // ✅ Valid - li is allowed for Flex.Item
653
+ <Flex as="ul">
654
+ <Flex.Item as="li">List item</Flex.Item>
655
+ </Flex>
656
+
657
+ // ❌ TypeScript Error - li not allowed on main Flex
658
+ <Flex as="li">...</Flex>
659
+ ```
660
+
661
+ ### Type Exports
662
+
663
+ ```tsx
664
+ import type {
665
+ FlexProps,
666
+ FlexItemProps,
667
+ FlexSpacerProps,
668
+ FlexContainerElement,
669
+ FlexItemElement,
670
+ FlexDirection,
671
+ FlexWrap,
672
+ FlexJustify,
673
+ FlexAlign,
674
+ FlexGap,
675
+ FlexVariant,
676
+ ResponsiveFlexProps,
677
+ } from "@fpkit/acss";
678
+ ```
679
+
680
+ ## Performance
681
+
682
+ ### Utility Class Generation
683
+
684
+ The component generates utility class names instead of inline styles for better
685
+ performance:
686
+
687
+ **✅ Good (Utility Classes):**
688
+
689
+ ```tsx
690
+ // Generates: "flex flex-row gap-md"
691
+ <Flex direction="row" gap="md">
692
+ ```
693
+
694
+ **❌ Slower (Inline Styles):**
695
+
696
+ ```tsx
697
+ // Less efficient
698
+ <div style={{ display: 'flex', flexDirection: 'row', gap: '1rem' }}>
699
+ ```
700
+
701
+ **Benefits:**
702
+
703
+ - CSS caching by browser
704
+ - Smaller React updates
705
+ - Better performance in lists
706
+ - Easier to override with CSS
707
+
708
+ ### Responsive Performance
709
+
710
+ Responsive props use CSS media queries (not JavaScript):
711
+
712
+ ```tsx
713
+ // Generates: "flex flex-col md:flex-row"
714
+ // Media query handled by CSS, not JS
715
+ <Flex direction="column" md={{ direction: "row" }}>
716
+ ```
717
+
718
+ ## Best Practices
719
+
720
+ ### 1. Choose the Right Semantic Element
721
+
722
+ ```tsx
723
+ // ✅ Good - semantic header
724
+ <Flex as="header" justify="between">
725
+ <Logo />
726
+ <Nav />
727
+ </Flex>
728
+
729
+ // ✅ Good - semantic navigation
730
+ <Flex as="nav" gap="md">
731
+ <a href="/">Home</a>
732
+ <a href="/about">About</a>
733
+ </Flex>
734
+
735
+ // ❌ Bad - using div for everything
736
+ <Flex as="div">...</Flex>
737
+ ```
738
+
739
+ ### 2. Use Preset Variants for Common Patterns
740
+
741
+ ```tsx
742
+ // ✅ Good - use preset
743
+ <Flex variant="center">
744
+ <Logo />
745
+ </Flex>
746
+
747
+ // ❌ Unnecessary - manual props
748
+ <Flex justify="center" align="center" direction="column">
749
+ <Logo />
750
+ </Flex>
751
+ ```
752
+
753
+ ### 3. Leverage Responsive Props
754
+
755
+ ```tsx
756
+ // ✅ Good - mobile-first responsive
757
+ <Flex
758
+ direction="column"
759
+ gap="sm"
760
+ md={{ direction: "row", gap: "lg" }}
761
+ >
762
+ ```
763
+
764
+ ### 4. Use Flex.Item for Fine Control
765
+
766
+ ```tsx
767
+ // ✅ Good - explicit flex behavior
768
+ <Flex.Item flex="1">Grows to fill space</Flex.Item>
769
+ <Flex.Item flex="none">Fixed size</Flex.Item>
770
+
771
+ // ❌ Less clear - manual styles
772
+ <div style={{ flex: 1 }}>...</div>
773
+ ```
774
+
775
+ ### 5. Use Flex.Spacer to Push Items
776
+
777
+ ```tsx
778
+ // ✅ Good - semantic spacer
779
+ <Flex>
780
+ <div>Left</div>
781
+ <Flex.Spacer />
782
+ <div>Right</div>
783
+ </Flex>
784
+
785
+ // ❌ Less semantic
786
+ <Flex justify="between">
787
+ <div>Left</div>
788
+ <div>Right</div>
789
+ </Flex>
790
+ ```
791
+
792
+ ### 6. Maintain Semantic List Structures
793
+
794
+ ```tsx
795
+ // ✅ Good - proper list semantics
796
+ <Flex as="ul">
797
+ <Flex.Item as="li">Item 1</Flex.Item>
798
+ <Flex.Item as="li">Item 2</Flex.Item>
799
+ </Flex>
800
+
801
+ // ❌ Bad - invalid HTML (ul > div)
802
+ <Flex as="ul">
803
+ <div>Item 1</div>
804
+ <div>Item 2</div>
805
+ </Flex>
806
+ ```
807
+
808
+ ## Technical Implementation
809
+
810
+ ### Architecture
811
+
812
+ - **Hybrid Approach** - CSS utilities + React component API
813
+ - **Class Generation** - Props convert to utility class names
814
+ - **Responsive Design** - Breakpoint-prefixed classes for media queries
815
+ - **Type Safety** - Literal union types restrict valid options
816
+ - **Compound Pattern** - Sub-components attached as properties
817
+
818
+ ### Class Name Generation
819
+
820
+ ```tsx
821
+ // From flex.tsx
822
+ const generateFlexClasses = (
823
+ props: ResponsiveFlexProps,
824
+ prefix = ""
825
+ ): string[] => {
826
+ const classes: string[] = [];
827
+
828
+ if (props.direction) {
829
+ const dirMap = {
830
+ row: "flex-row",
831
+ "row-reverse": "flex-row-reverse",
832
+ column: "flex-col",
833
+ "column-reverse": "flex-col-reverse",
834
+ };
835
+ classes.push(`${prefix}${dirMap[props.direction]}`);
836
+ }
837
+
838
+ // ... more mappings
839
+
840
+ return classes;
841
+ };
842
+ ```
843
+
844
+ ### Responsive Class Generation
845
+
846
+ ```tsx
847
+ // Responsive breakpoint classes
848
+ if (sm) classes.push(...generateFlexClasses(sm, "sm:"));
849
+ if (md) classes.push(...generateFlexClasses(md, "md:"));
850
+ if (lg) classes.push(...generateFlexClasses(lg, "lg:"));
851
+ if (xl) classes.push(...generateFlexClasses(xl, "xl:"));
852
+ ```
853
+
854
+ ### Testing
855
+
856
+ The component has 100% test coverage with 62 tests:
857
+
858
+ - ✅ Basic rendering and props
859
+ - ✅ Direction, wrap, gap, justify, align props
860
+ - ✅ Preset variants
861
+ - ✅ Responsive breakpoint props
862
+ - ✅ Compound components (Flex.Item, Flex.Spacer)
863
+ - ✅ Flex.Item sizing and alignment
864
+ - ✅ Polymorphic rendering (`as` prop)
865
+ - ✅ Custom className and styles
866
+ - ✅ Display names
867
+
868
+ Run tests:
869
+
870
+ ```bash
871
+ cd packages/fpkit && npm test flex.test.tsx
872
+ ```
873
+
874
+ ## Comparison: Flex Component vs Direct Utility Classes
875
+
876
+ ### Using Flex Component (Recommended)
877
+
878
+ ```tsx
879
+ <Flex direction="row" gap="md" md={{ direction: "column" }}>
880
+ <Flex.Item flex="1">Content</Flex.Item>
881
+ </Flex>
882
+ ```
883
+
884
+ **Benefits:**
885
+
886
+ - ✅ TypeScript autocomplete and type safety
887
+ - ✅ Semantic element enforcement
888
+ - ✅ Cleaner JSX
889
+ - ✅ Easy responsive props
890
+ - ✅ Better refactoring
891
+
892
+ ### Using Direct Utility Classes
893
+
894
+ ```tsx
895
+ <div className="flex flex-row gap-md md:flex-col">
896
+ <div className="flex-1">Content</div>
897
+ </div>
898
+ ```
899
+
900
+ **Benefits:**
901
+
902
+ - ✅ Slightly less JavaScript
903
+ - ✅ Direct CSS control
904
+ - ✅ Familiar to Tailwind users
905
+
906
+ **Both approaches are valid** - the Flex component provides a React-friendly API
907
+ on top of the same utility classes.
908
+
909
+ ## Browser Support
910
+
911
+ - ✅ Modern browsers (Chrome, Firefox, Safari, Edge)
912
+ - ✅ Requires CSS flexbox support
913
+ - ✅ Requires React 18+
914
+ - ✅ TypeScript 5.0+ recommended for full type safety
915
+ - ✅ CSS custom properties support
916
+
917
+ ## API Reference
918
+
919
+ ### Exported Components
920
+
921
+ - `Flex` - Main flexbox container component
922
+ - `Flex.Item` - Individual flex item with sizing controls
923
+ - `Flex.Spacer` - Auto-expanding spacer element
924
+
925
+ ### Exported Types
926
+
927
+ - `FlexProps` - Main Flex component props
928
+ - `FlexItemProps` - Flex.Item component props
929
+ - `FlexSpacerProps` - Flex.Spacer component props
930
+ - `FlexContainerElement` - Valid container elements
931
+ - `FlexItemElement` - Valid item elements (includes list items)
932
+ - `FlexDirection` - Direction values
933
+ - `FlexWrap` - Wrap values
934
+ - `FlexJustify` - Justify content values
935
+ - `FlexAlign` - Align items values
936
+ - `FlexAlignContent` - Align content values
937
+ - `FlexAlignSelf` - Align self values
938
+ - `FlexGap` - Gap size values
939
+ - `FlexVariant` - Preset variant values
940
+ - `ResponsiveFlexProps` - Props for responsive breakpoints
941
+
942
+ ## Migration Guide
943
+
944
+ ### From Previous Versions
945
+
946
+ If migrating from direct utility classes or other flex systems:
947
+
948
+ **Before:**
949
+
950
+ ```tsx
951
+ <div className="flex flex-row gap-md">
952
+ <div className="flex-1">Content</div>
953
+ </div>
954
+ ```
955
+
956
+ **After:**
957
+
958
+ ```tsx
959
+ <Flex direction="row" gap="md">
960
+ <Flex.Item flex="1">Content</Flex.Item>
961
+ </Flex>
962
+ ```
963
+
964
+ ### Type Safety Updates (v3.0.0+)
965
+
966
+ Version 3.0.0 introduces semantic element restrictions:
967
+
968
+ ```tsx
969
+ // ✅ Valid in v3.0.0+
970
+ <Flex as="section">...</Flex>
971
+
972
+ // ❌ TypeScript error in v3.0.0+ (was allowed before)
973
+ <Flex as="span">...</Flex>
974
+ ```
975
+
976
+ Update code to use valid container elements only.
977
+
978
+ ## Resources
979
+
980
+ - [Storybook Documentation](http://localhost:6006/?path=/docs/fp-react-components-flex--docs)
981
+ - [GitHub Repository](https://github.com/yourusername/acss)
982
+ - [CSS Flexbox Guide](https://css-tricks.com/snippets/css/a-guide-to-flexbox/)
983
+ - [MDN Flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout)
984
+
985
+ ## Support
986
+
987
+ For issues, questions, or contributions:
988
+
989
+ - Open an issue on [GitHub](https://github.com/yourusername/acss/issues)
990
+ - Check existing [Storybook stories](http://localhost:6006) for examples
991
+ - Review the comprehensive test suite for usage patterns
992
+
993
+ ---
994
+
995
+ **Version:** v3.0.0+ **Last Updated:** December 2025 **Test Coverage:** 100% (62
996
+ tests) **Maintained by:** fpkit Team