@fpkit/acss 3.3.0 → 3.5.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 (99) hide show
  1. package/libs/index.cjs +22 -20
  2. package/libs/index.cjs.map +1 -1
  3. package/libs/index.d.cts +309 -1
  4. package/libs/index.d.ts +309 -1
  5. package/libs/index.js +9 -9
  6. package/libs/index.js.map +1 -1
  7. package/package.json +2 -2
  8. package/src/components/col/README.mdx +661 -0
  9. package/src/components/col/col.stories.tsx +527 -0
  10. package/src/components/col/col.test.tsx +366 -0
  11. package/src/components/col/col.tsx +107 -0
  12. package/src/components/col/col.types.ts +90 -0
  13. package/src/components/row/README.mdx +324 -0
  14. package/src/components/row/row.stories.tsx +595 -0
  15. package/src/components/row/row.test.tsx +358 -0
  16. package/src/components/row/row.tsx +121 -0
  17. package/src/components/row/row.types.ts +93 -0
  18. package/src/index.scss +1 -0
  19. package/src/index.ts +2 -0
  20. package/src/sass/README.mdx +597 -0
  21. package/src/sass/_columns.scss +394 -0
  22. package/src/sass/columns.stories.tsx +456 -0
  23. package/src/styles/index.css +392 -0
  24. package/src/styles/index.css.map +1 -1
  25. package/src/types/layout-primitives.ts +81 -0
  26. package/libs/components/alert/alert.css +0 -1
  27. package/libs/components/alert/alert.css.map +0 -1
  28. package/libs/components/alert/alert.min.css +0 -3
  29. package/libs/components/badge/badge.css +0 -1
  30. package/libs/components/badge/badge.css.map +0 -1
  31. package/libs/components/badge/badge.min.css +0 -3
  32. package/libs/components/box/box.css +0 -1
  33. package/libs/components/box/box.css.map +0 -1
  34. package/libs/components/box/box.min.css +0 -3
  35. package/libs/components/breadcrumbs/breadcrumb.css +0 -1
  36. package/libs/components/breadcrumbs/breadcrumb.css.map +0 -1
  37. package/libs/components/breadcrumbs/breadcrumb.min.css +0 -3
  38. package/libs/components/buttons/button.css +0 -1
  39. package/libs/components/buttons/button.css.map +0 -1
  40. package/libs/components/buttons/button.min.css +0 -3
  41. package/libs/components/cards/card-style.css +0 -1
  42. package/libs/components/cards/card-style.css.map +0 -1
  43. package/libs/components/cards/card-style.min.css +0 -3
  44. package/libs/components/cards/card.css +0 -1
  45. package/libs/components/cards/card.css.map +0 -1
  46. package/libs/components/cards/card.min.css +0 -3
  47. package/libs/components/cluster/cluster.css +0 -1
  48. package/libs/components/cluster/cluster.css.map +0 -1
  49. package/libs/components/cluster/cluster.min.css +0 -3
  50. package/libs/components/details/details.css +0 -1
  51. package/libs/components/details/details.css.map +0 -1
  52. package/libs/components/details/details.min.css +0 -3
  53. package/libs/components/dialog/dialog.css +0 -1
  54. package/libs/components/dialog/dialog.css.map +0 -1
  55. package/libs/components/dialog/dialog.min.css +0 -3
  56. package/libs/components/flexbox/flex.css +0 -1
  57. package/libs/components/flexbox/flex.css.map +0 -1
  58. package/libs/components/flexbox/flex.min.css +0 -3
  59. package/libs/components/form/form.css +0 -1
  60. package/libs/components/form/form.css.map +0 -1
  61. package/libs/components/form/form.min.css +0 -3
  62. package/libs/components/grid/grid.css +0 -1
  63. package/libs/components/grid/grid.css.map +0 -1
  64. package/libs/components/grid/grid.min.css +0 -3
  65. package/libs/components/icons/icon.css +0 -1
  66. package/libs/components/icons/icon.css.map +0 -1
  67. package/libs/components/icons/icon.min.css +0 -3
  68. package/libs/components/images/img.css +0 -1
  69. package/libs/components/images/img.css.map +0 -1
  70. package/libs/components/images/img.min.css +0 -3
  71. package/libs/components/layout/landmarks.css +0 -1
  72. package/libs/components/layout/landmarks.css.map +0 -1
  73. package/libs/components/layout/landmarks.min.css +0 -3
  74. package/libs/components/link/link.css +0 -1
  75. package/libs/components/link/link.css.map +0 -1
  76. package/libs/components/link/link.min.css +0 -3
  77. package/libs/components/list/list.css +0 -1
  78. package/libs/components/list/list.css.map +0 -1
  79. package/libs/components/list/list.min.css +0 -3
  80. package/libs/components/nav/nav.css +0 -1
  81. package/libs/components/nav/nav.css.map +0 -1
  82. package/libs/components/nav/nav.min.css +0 -3
  83. package/libs/components/progress/progress.css +0 -1
  84. package/libs/components/progress/progress.css.map +0 -1
  85. package/libs/components/progress/progress.min.css +0 -3
  86. package/libs/components/stack/stack.css +0 -1
  87. package/libs/components/stack/stack.css.map +0 -1
  88. package/libs/components/stack/stack.min.css +0 -3
  89. package/libs/components/styles/index.css +0 -1
  90. package/libs/components/styles/index.css.map +0 -1
  91. package/libs/components/styles/index.min.css +0 -3
  92. package/libs/components/tag/tag.css +0 -1
  93. package/libs/components/tag/tag.css.map +0 -1
  94. package/libs/components/tag/tag.min.css +0 -3
  95. package/libs/components/text-to-speech/text-to-speech.css +0 -1
  96. package/libs/components/text-to-speech/text-to-speech.css.map +0 -1
  97. package/libs/components/text-to-speech/text-to-speech.min.css +0 -3
  98. package/libs/index.css +0 -1
  99. package/libs/index.css.map +0 -1
@@ -0,0 +1,456 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import { within, expect } from "storybook/test";
3
+
4
+ import "./_columns.scss";
5
+
6
+ const meta: Meta = {
7
+ title: "FP.React Components/Utilities/Columns",
8
+ tags: ["autodocs"],
9
+ parameters: {
10
+ docs: {
11
+ description: {
12
+ component: `
13
+ ## 12-Column Utility System
14
+
15
+ Bootstrap/Foundation-compatible column utilities for Flexbox layouts. Provides \`.col-1\` through \`.col-12\` classes with mobile-first responsive behavior.
16
+
17
+ ### Key Features
18
+ - **12-column grid**: \`.col-1\` (8.333%) through \`.col-12\` (100%)
19
+ - **Mobile-first**: 100% width on mobile (< 768px), percentage widths on desktop
20
+ - **Flexbox-only**: Works with Flex component or \`.col-row\` utility (NOT with Grid component)
21
+ - **Optional utilities**: Offsets, auto-width, and ordering
22
+
23
+ ### Container Requirements
24
+ Column utilities require a flex container with \`flex-wrap: wrap\`:
25
+
26
+ **Option 1: Use \`.col-row\` utility (recommended for simple layouts)**
27
+ \`\`\`jsx
28
+ <div className="col-row">
29
+ <div className="col-6">Column</div>
30
+ </div>
31
+ \`\`\`
32
+
33
+ **Option 2: Use Flex component (recommended for complex layouts)**
34
+ \`\`\`jsx
35
+ <Flex wrap="wrap" gap="md">
36
+ <div className="col-6">Column</div>
37
+ </Flex>
38
+ \`\`\`
39
+ `,
40
+ },
41
+ },
42
+ },
43
+ };
44
+
45
+ export default meta;
46
+ type Story = StoryObj<typeof meta>;
47
+
48
+ // Demo card styling
49
+ const demoCardStyle = {
50
+ padding: "1rem",
51
+ backgroundColor: "#e0e7ff",
52
+ border: "2px solid #6366f1",
53
+ borderRadius: "0.5rem",
54
+ textAlign: "center" as const,
55
+ fontWeight: "600",
56
+ };
57
+
58
+ /**
59
+ * Demonstrates all 12 column sizes stacked vertically.
60
+ * Shows the percentage width each column class represents.
61
+ */
62
+ export const AllColumnSizes: Story = {
63
+ render: () => (
64
+ <div style={{ maxWidth: "1200px", margin: "0 auto" }}>
65
+ <div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
66
+ <div className="col-1" style={demoCardStyle}>
67
+ .col-1
68
+ <br />
69
+ 8.333%
70
+ </div>
71
+ </div>
72
+ <div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
73
+ <div className="col-2" style={demoCardStyle}>
74
+ .col-2
75
+ <br />
76
+ 16.667%
77
+ </div>
78
+ </div>
79
+ <div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
80
+ <div className="col-3" style={demoCardStyle}>
81
+ .col-3
82
+ <br />
83
+ 25%
84
+ </div>
85
+ </div>
86
+ <div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
87
+ <div className="col-4" style={demoCardStyle}>
88
+ .col-4
89
+ <br />
90
+ 33.333%
91
+ </div>
92
+ </div>
93
+ <div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
94
+ <div className="col-5" style={demoCardStyle}>
95
+ .col-5
96
+ <br />
97
+ 41.667%
98
+ </div>
99
+ </div>
100
+ <div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
101
+ <div className="col-6" style={demoCardStyle}>
102
+ .col-6
103
+ <br />
104
+ 50%
105
+ </div>
106
+ </div>
107
+ <div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
108
+ <div className="col-7" style={demoCardStyle}>
109
+ .col-7
110
+ <br />
111
+ 58.333%
112
+ </div>
113
+ </div>
114
+ <div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
115
+ <div className="col-8" style={demoCardStyle}>
116
+ .col-8
117
+ <br />
118
+ 66.667%
119
+ </div>
120
+ </div>
121
+ <div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
122
+ <div className="col-9" style={demoCardStyle}>
123
+ .col-9
124
+ <br />
125
+ 75%
126
+ </div>
127
+ </div>
128
+ <div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
129
+ <div className="col-10" style={demoCardStyle}>
130
+ .col-10
131
+ <br />
132
+ 83.333%
133
+ </div>
134
+ </div>
135
+ <div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
136
+ <div className="col-11" style={demoCardStyle}>
137
+ .col-11
138
+ <br />
139
+ 91.667%
140
+ </div>
141
+ </div>
142
+ <div className="col-row" style={{ gap: "1rem", marginBottom: "1rem" }}>
143
+ <div className="col-12" style={demoCardStyle}>
144
+ .col-12
145
+ <br />
146
+ 100%
147
+ </div>
148
+ </div>
149
+ </div>
150
+ ),
151
+ play: async ({ canvasElement, step }) => {
152
+ const canvas = within(canvasElement);
153
+
154
+ await step("All column sizes render correctly", async () => {
155
+ expect(canvas.getByText(".col-1")).toBeInTheDocument();
156
+ expect(canvas.getByText(".col-6")).toBeInTheDocument();
157
+ expect(canvas.getByText(".col-12")).toBeInTheDocument();
158
+ });
159
+ },
160
+ };
161
+
162
+ /**
163
+ * Two-column layout (50/50 split).
164
+ * Common pattern for side-by-side content.
165
+ */
166
+ export const TwoColumns: Story = {
167
+ render: () => (
168
+ <div className="col-row">
169
+ <div className="col-6" style={demoCardStyle}>
170
+ Left Column
171
+ <br />
172
+ .col-6
173
+ </div>
174
+ <div className="col-6" style={demoCardStyle}>
175
+ Right Column
176
+ <br />
177
+ .col-6
178
+ </div>
179
+ </div>
180
+ ),
181
+ play: async ({ canvasElement, step }) => {
182
+ const canvas = within(canvasElement);
183
+
184
+ await step("Two columns render side by side", async () => {
185
+ expect(canvas.getByText("Left Column")).toBeInTheDocument();
186
+ expect(canvas.getByText("Right Column")).toBeInTheDocument();
187
+ });
188
+ },
189
+ };
190
+
191
+ /**
192
+ * Three-column layout (equal widths).
193
+ * Perfect for feature lists, card grids, etc.
194
+ */
195
+ export const ThreeColumns: Story = {
196
+ render: () => (
197
+ <div className="col-row">
198
+ <div className="col-4" style={demoCardStyle}>
199
+ Column 1<br />.col-4
200
+ </div>
201
+ <div className="col-4" style={demoCardStyle}>
202
+ Column 2<br />.col-4
203
+ </div>
204
+ <div className="col-4" style={demoCardStyle}>
205
+ Column 3<br />.col-4
206
+ </div>
207
+ </div>
208
+ ),
209
+ };
210
+
211
+ /**
212
+ * Four-column layout (equal widths).
213
+ * Great for dashboard cards or product grids.
214
+ */
215
+ export const FourColumns: Story = {
216
+ render: () => (
217
+ <div className="col-row">
218
+ <div className="col-3" style={demoCardStyle}>
219
+ Col 1<br />.col-3
220
+ </div>
221
+ <div className="col-3" style={demoCardStyle}>
222
+ Col 2<br />.col-3
223
+ </div>
224
+ <div className="col-3" style={demoCardStyle}>
225
+ Col 3<br />.col-3
226
+ </div>
227
+ <div className="col-3" style={demoCardStyle}>
228
+ Col 4<br />.col-3
229
+ </div>
230
+ </div>
231
+ ),
232
+ };
233
+
234
+ /**
235
+ * Sidebar layout with asymmetric columns.
236
+ * Common pattern: narrow sidebar + wide main content area.
237
+ */
238
+ export const SidebarLayout: Story = {
239
+ render: () => (
240
+ <div className="col-row">
241
+ <div className="col-3" style={{ ...demoCardStyle, backgroundColor: "#fef3c7" }}>
242
+ Sidebar
243
+ <br />
244
+ .col-3
245
+ </div>
246
+ <div className="col-9" style={{ ...demoCardStyle, backgroundColor: "#dbeafe" }}>
247
+ Main Content
248
+ <br />
249
+ .col-9
250
+ </div>
251
+ </div>
252
+ ),
253
+ };
254
+
255
+ /**
256
+ * Mixed column widths demonstrating flexible layouts.
257
+ * Shows how columns automatically wrap to new rows.
258
+ */
259
+ export const MixedWidths: Story = {
260
+ render: () => (
261
+ <div className="col-row">
262
+ <div className="col-8" style={demoCardStyle}>
263
+ Wide (.col-8)
264
+ </div>
265
+ <div className="col-4" style={demoCardStyle}>
266
+ Narrow (.col-4)
267
+ </div>
268
+ <div className="col-6" style={demoCardStyle}>
269
+ Half (.col-6)
270
+ </div>
271
+ <div className="col-6" style={demoCardStyle}>
272
+ Half (.col-6)
273
+ </div>
274
+ <div className="col-12" style={demoCardStyle}>
275
+ Full Width (.col-12)
276
+ </div>
277
+ </div>
278
+ ),
279
+ };
280
+
281
+ /**
282
+ * Column offset utilities for centering or creating asymmetric layouts.
283
+ * Offsets push columns to the right using margin-inline-start.
284
+ */
285
+ export const ColumnOffsets: Story = {
286
+ render: () => (
287
+ <div style={{ maxWidth: "1200px", margin: "0 auto" }}>
288
+ <div className="col-row" style={{ marginBottom: "1rem" }}>
289
+ <div className="col-6 col-offset-3" style={demoCardStyle}>
290
+ Centered
291
+ <br />
292
+ .col-6.col-offset-3
293
+ </div>
294
+ </div>
295
+ <div className="col-row" style={{ marginBottom: "1rem" }}>
296
+ <div className="col-4 col-offset-4" style={demoCardStyle}>
297
+ Centered
298
+ <br />
299
+ .col-4.col-offset-4
300
+ </div>
301
+ </div>
302
+ <div className="col-row">
303
+ <div className="col-3 col-offset-2" style={demoCardStyle}>
304
+ Offset Left
305
+ <br />
306
+ .col-3.col-offset-2
307
+ </div>
308
+ <div className="col-4 col-offset-1" style={demoCardStyle}>
309
+ Offset Left
310
+ <br />
311
+ .col-4.col-offset-1
312
+ </div>
313
+ </div>
314
+ </div>
315
+ ),
316
+ };
317
+
318
+ /**
319
+ * Auto-width column that sizes based on content.
320
+ * Useful for buttons, labels, or dynamic content widths.
321
+ */
322
+ export const AutoWidth: Story = {
323
+ render: () => (
324
+ <div className="col-row">
325
+ <div className="col-auto" style={{ ...demoCardStyle, whiteSpace: "nowrap" }}>
326
+ Auto Width (.col-auto)
327
+ </div>
328
+ <div className="col-6" style={demoCardStyle}>
329
+ Fixed Width (.col-6)
330
+ </div>
331
+ <div className="col-auto" style={{ ...demoCardStyle, whiteSpace: "nowrap" }}>
332
+ Auto (.col-auto)
333
+ </div>
334
+ </div>
335
+ ),
336
+ };
337
+
338
+ /**
339
+ * Column ordering utilities for visual reordering without changing HTML.
340
+ * Useful for responsive layouts where order changes at breakpoints.
341
+ */
342
+ export const ColumnOrdering: Story = {
343
+ render: () => (
344
+ <div style={{ maxWidth: "1200px", margin: "0 auto" }}>
345
+ <p style={{ marginBottom: "1rem", fontSize: "0.875rem", color: "#6b7280" }}>
346
+ Visual order: Second → First → Third (using .col-order-* classes)
347
+ </p>
348
+ <div className="col-row">
349
+ <div className="col-4 col-order-2" style={{ ...demoCardStyle, backgroundColor: "#fecaca" }}>
350
+ HTML Order: 1<br />
351
+ Visual Order: 2<br />
352
+ .col-order-2
353
+ </div>
354
+ <div className="col-4 col-order-first" style={{ ...demoCardStyle, backgroundColor: "#bbf7d0" }}>
355
+ HTML Order: 2<br />
356
+ Visual Order: 1<br />
357
+ .col-order-first
358
+ </div>
359
+ <div className="col-4 col-order-last" style={{ ...demoCardStyle, backgroundColor: "#bfdbfe" }}>
360
+ HTML Order: 3<br />
361
+ Visual Order: 3<br />
362
+ .col-order-last
363
+ </div>
364
+ </div>
365
+ </div>
366
+ ),
367
+ };
368
+
369
+ /**
370
+ * Custom gap spacing using gap utility classes.
371
+ * Shows how to control spacing between columns.
372
+ */
373
+ export const CustomGapSpacing: Story = {
374
+ render: () => (
375
+ <div style={{ maxWidth: "1200px", margin: "0 auto" }}>
376
+ <h3 style={{ marginBottom: "1rem", fontSize: "1rem" }}>No Gap</h3>
377
+ <div className="col-row" style={{ gap: 0, marginBottom: "2rem" }}>
378
+ <div className="col-4" style={demoCardStyle}>
379
+ Column 1
380
+ </div>
381
+ <div className="col-4" style={demoCardStyle}>
382
+ Column 2
383
+ </div>
384
+ <div className="col-4" style={demoCardStyle}>
385
+ Column 3
386
+ </div>
387
+ </div>
388
+
389
+ <h3 style={{ marginBottom: "1rem", fontSize: "1rem" }}>Small Gap (0.5rem)</h3>
390
+ <div className="col-row" style={{ gap: "0.5rem", marginBottom: "2rem" }}>
391
+ <div className="col-4" style={demoCardStyle}>
392
+ Column 1
393
+ </div>
394
+ <div className="col-4" style={demoCardStyle}>
395
+ Column 2
396
+ </div>
397
+ <div className="col-4" style={demoCardStyle}>
398
+ Column 3
399
+ </div>
400
+ </div>
401
+
402
+ <h3 style={{ marginBottom: "1rem", fontSize: "1rem" }}>Large Gap (2rem)</h3>
403
+ <div className="col-row" style={{ gap: "2rem" }}>
404
+ <div className="col-4" style={demoCardStyle}>
405
+ Column 1
406
+ </div>
407
+ <div className="col-4" style={demoCardStyle}>
408
+ Column 2
409
+ </div>
410
+ <div className="col-4" style={demoCardStyle}>
411
+ Column 3
412
+ </div>
413
+ </div>
414
+ </div>
415
+ ),
416
+ };
417
+
418
+ /**
419
+ * Responsive behavior demonstration.
420
+ * Resize browser to see columns stack on mobile (< 768px) and spread on desktop.
421
+ */
422
+ export const ResponsiveBehavior: Story = {
423
+ render: () => (
424
+ <div style={{ maxWidth: "1200px", margin: "0 auto" }}>
425
+ <div
426
+ style={{
427
+ padding: "1rem",
428
+ backgroundColor: "#fef3c7",
429
+ borderRadius: "0.5rem",
430
+ marginBottom: "1rem",
431
+ fontSize: "0.875rem",
432
+ }}
433
+ >
434
+ <strong>💡 Try this:</strong> Resize your browser or use DevTools responsive mode.
435
+ <br />• <strong>Mobile (&lt; 768px):</strong> All columns stack to 100% width
436
+ <br />• <strong>Desktop (≥ 768px):</strong> Columns use percentage widths
437
+ </div>
438
+ <div className="col-row">
439
+ <div className="col-4" style={demoCardStyle}>
440
+ Column 1<br />.col-4
441
+ </div>
442
+ <div className="col-4" style={demoCardStyle}>
443
+ Column 2<br />.col-4
444
+ </div>
445
+ <div className="col-4" style={demoCardStyle}>
446
+ Column 3<br />.col-4
447
+ </div>
448
+ </div>
449
+ </div>
450
+ ),
451
+ parameters: {
452
+ viewport: {
453
+ defaultViewport: "md",
454
+ },
455
+ },
456
+ };