@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.
Files changed (202) hide show
  1. package/libs/{chunk-2NRIP6RB.cjs → chunk-2C3YLBWP.cjs} +3 -3
  2. package/libs/{chunk-NWJDAHP6.cjs → chunk-2GJHKWEK.cjs} +3 -3
  3. package/libs/{chunk-FVROL3V5.js → chunk-2JCDEC32.js} +3 -3
  4. package/libs/{chunk-IRLFZ3OL.js → chunk-3XJC4XUG.js} +2 -2
  5. package/libs/{chunk-L6PRDL6F.cjs → chunk-5CJPTDK3.cjs} +3 -3
  6. package/libs/{chunk-E4OSROCA.cjs → chunk-5QSNJQVH.cjs} +3 -3
  7. package/libs/{chunk-O3JIHC5M.cjs → chunk-6BUJZ4DJ.cjs} +3 -3
  8. package/libs/{chunk-WXBFBWYF.cjs → chunk-AFINOD2L.cjs} +3 -3
  9. package/libs/{chunk-HRRHPLER.js → chunk-AWZLSWDO.js} +2 -2
  10. package/libs/chunk-DDSXKOUB.js +7 -0
  11. package/libs/chunk-DDSXKOUB.js.map +1 -0
  12. package/libs/{chunk-CWRNJA4P.js → chunk-DIJBIOFE.js} +3 -3
  13. package/libs/chunk-EJ6KYBFE.cjs +13 -0
  14. package/libs/chunk-EJ6KYBFE.cjs.map +1 -0
  15. package/libs/{chunk-GUJSMQ3V.cjs → chunk-EKJYOCLY.cjs} +3 -3
  16. package/libs/{chunk-X5RKCLDC.cjs → chunk-F64GE6RG.cjs} +4 -4
  17. package/libs/{chunk-5RAWNUVD.js → chunk-IBUTNPTQ.js} +2 -2
  18. package/libs/chunk-IWP4VJEP.cjs +18 -0
  19. package/libs/chunk-IWP4VJEP.cjs.map +1 -0
  20. package/libs/{chunk-ZFJ4U45S.js → chunk-KDMX3FAW.js} +2 -2
  21. package/libs/{chunk-DYFAUAB7.cjs → chunk-LXODKKA3.cjs} +4 -4
  22. package/libs/{chunk-MPTMPBFT.js → chunk-M7JLT62Q.js} +2 -2
  23. package/libs/{chunk-IQ76HGVP.js → chunk-MBWI67UT.js} +2 -2
  24. package/libs/{chunk-O5XAJ7BY.cjs → chunk-NCGVF2QS.cjs} +4 -4
  25. package/libs/{chunk-W2UIN7EV.cjs → chunk-NPWHQVYB.cjs} +3 -3
  26. package/libs/{chunk-43TK2ICH.js → chunk-PMWL5XZ4.js} +3 -3
  27. package/libs/{chunk-KVKQLRJG.js → chunk-TF3GQKOY.js} +2 -2
  28. package/libs/{chunk-IEB64SWY.js → chunk-U5VA34SU.js} +2 -2
  29. package/libs/chunk-UGMP72J2.js +8 -0
  30. package/libs/chunk-UGMP72J2.js.map +1 -0
  31. package/libs/{chunk-EE3ZWSBY.cjs → chunk-URBGDUFN.cjs} +6 -6
  32. package/libs/{chunk-TPIB3RQP.js → chunk-ZF6Y7W57.js} +5 -5
  33. package/libs/component-props-50e69975.d.ts +66 -0
  34. package/libs/components/box/box.css +1 -0
  35. package/libs/components/box/box.css.map +1 -0
  36. package/libs/components/box/box.min.css +3 -0
  37. package/libs/components/breadcrumbs/breadcrumb.cjs +6 -6
  38. package/libs/components/breadcrumbs/breadcrumb.js +3 -3
  39. package/libs/components/button.cjs +4 -4
  40. package/libs/components/button.d.cts +10 -3
  41. package/libs/components/button.d.ts +10 -3
  42. package/libs/components/button.js +2 -2
  43. package/libs/components/card.cjs +7 -7
  44. package/libs/components/card.d.cts +13 -85
  45. package/libs/components/card.d.ts +13 -85
  46. package/libs/components/card.js +2 -2
  47. package/libs/components/cards/card.css +1 -1
  48. package/libs/components/cards/card.css.map +1 -1
  49. package/libs/components/cards/card.min.css +2 -2
  50. package/libs/components/cluster/cluster.css +1 -0
  51. package/libs/components/cluster/cluster.css.map +1 -0
  52. package/libs/components/cluster/cluster.min.css +3 -0
  53. package/libs/components/dialog/dialog.cjs +7 -7
  54. package/libs/components/dialog/dialog.js +5 -5
  55. package/libs/components/form/fields.cjs +4 -4
  56. package/libs/components/form/fields.js +2 -2
  57. package/libs/components/form/textarea.cjs +4 -4
  58. package/libs/components/form/textarea.js +2 -2
  59. package/libs/components/grid/grid.css +1 -0
  60. package/libs/components/grid/grid.css.map +1 -0
  61. package/libs/components/grid/grid.min.css +3 -0
  62. package/libs/components/heading/heading.cjs +3 -3
  63. package/libs/components/heading/heading.js +2 -2
  64. package/libs/components/icons/icon.cjs +4 -4
  65. package/libs/components/icons/icon.d.cts +2 -2
  66. package/libs/components/icons/icon.d.ts +2 -2
  67. package/libs/components/icons/icon.js +2 -2
  68. package/libs/components/link/link.cjs +6 -6
  69. package/libs/components/link/link.js +2 -2
  70. package/libs/components/list/list.cjs +5 -5
  71. package/libs/components/list/list.js +2 -2
  72. package/libs/components/modal.cjs +4 -4
  73. package/libs/components/modal.d.cts +1 -1
  74. package/libs/components/modal.d.ts +1 -1
  75. package/libs/components/modal.js +3 -3
  76. package/libs/components/nav/nav.cjs +7 -7
  77. package/libs/components/nav/nav.js +3 -3
  78. package/libs/components/stack/stack.css +1 -0
  79. package/libs/components/stack/stack.css.map +1 -0
  80. package/libs/components/stack/stack.min.css +3 -0
  81. package/libs/components/tables/table.d.cts +1 -1
  82. package/libs/components/tables/table.d.ts +1 -1
  83. package/libs/components/text/text.cjs +5 -5
  84. package/libs/components/text/text.js +2 -2
  85. package/libs/hooks.cjs +4 -4
  86. package/libs/hooks.js +3 -3
  87. package/libs/{icons-287fce3a.d.ts → icons-df8e744f.d.ts} +1 -1
  88. package/libs/icons.cjs +3 -3
  89. package/libs/icons.d.cts +2 -2
  90. package/libs/icons.d.ts +2 -2
  91. package/libs/icons.js +2 -2
  92. package/libs/index.cjs +64 -63
  93. package/libs/index.cjs.map +1 -1
  94. package/libs/index.css +1 -1
  95. package/libs/index.css.map +1 -1
  96. package/libs/index.d.cts +923 -4
  97. package/libs/index.d.ts +923 -4
  98. package/libs/index.js +28 -28
  99. package/libs/index.js.map +1 -1
  100. package/package.json +2 -2
  101. package/src/components/alert/STYLES.mdx +790 -0
  102. package/src/components/badge/STYLES.mdx +610 -0
  103. package/src/components/box/README.mdx +401 -0
  104. package/src/components/box/STYLES.mdx +360 -0
  105. package/src/components/box/box.scss +245 -0
  106. package/src/components/box/box.stories.tsx +395 -0
  107. package/src/components/box/box.test.tsx +425 -0
  108. package/src/components/box/box.tsx +170 -0
  109. package/src/components/box/box.types.ts +166 -0
  110. package/src/components/breadcrumbs/STYLES.mdx +99 -0
  111. package/src/components/buttons/STYLES.mdx +766 -0
  112. package/src/components/cards/STYLES.mdx +835 -0
  113. package/src/components/cards/card.scss +29 -21
  114. package/src/components/cards/card.tsx +13 -3
  115. package/src/components/cards/card.types.ts +13 -0
  116. package/src/components/cluster/README.mdx +595 -0
  117. package/src/components/cluster/STYLES.mdx +626 -0
  118. package/src/components/cluster/cluster.scss +86 -0
  119. package/src/components/cluster/cluster.stories.tsx +385 -0
  120. package/src/components/cluster/cluster.test.tsx +655 -0
  121. package/src/components/cluster/cluster.tsx +94 -0
  122. package/src/components/cluster/cluster.types.ts +75 -0
  123. package/src/components/details/STYLES.mdx +445 -0
  124. package/src/components/dialog/STYLES.mdx +888 -0
  125. package/src/components/flexbox/STYLES.mdx +1 -1
  126. package/src/components/form/STYLES.mdx +821 -0
  127. package/src/components/grid/README.mdx +709 -0
  128. package/src/components/grid/STYLES.mdx +785 -0
  129. package/src/components/grid/grid.scss +287 -0
  130. package/src/components/grid/grid.stories.tsx +486 -0
  131. package/src/components/grid/grid.test.tsx +981 -0
  132. package/src/components/grid/grid.tsx +222 -0
  133. package/src/components/grid/grid.types.ts +344 -0
  134. package/src/components/icons/STYLES.mdx +56 -0
  135. package/src/components/images/STYLES.mdx +75 -0
  136. package/src/components/layout/STYLES.mdx +556 -0
  137. package/src/components/link/STYLES.mdx +75 -0
  138. package/src/components/list/STYLES.mdx +631 -0
  139. package/src/components/nav/STYLES.mdx +460 -0
  140. package/src/components/progress/STYLES.mdx +64 -0
  141. package/src/components/stack/README.mdx +400 -0
  142. package/src/components/stack/STYLES.mdx +414 -0
  143. package/src/components/stack/stack.scss +109 -0
  144. package/src/components/stack/stack.stories.tsx +559 -0
  145. package/src/components/stack/stack.test.tsx +426 -0
  146. package/src/components/stack/stack.tsx +141 -0
  147. package/src/components/stack/stack.types.ts +133 -0
  148. package/src/components/tag/STYLES.mdx +105 -0
  149. package/src/components/text-to-speech/STYLES.mdx +80 -0
  150. package/src/components/ui.tsx +3 -3
  151. package/src/index.scss +5 -1
  152. package/src/index.ts +305 -12
  153. package/src/sass/GLOBALS-STYLES.md +631 -0
  154. package/src/sass/_globals.scss +45 -24
  155. package/src/styles/box/box.css +220 -0
  156. package/src/styles/box/box.css.map +1 -0
  157. package/src/styles/cards/card.css +22 -17
  158. package/src/styles/cards/card.css.map +1 -1
  159. package/src/styles/cluster/cluster.css +71 -0
  160. package/src/styles/cluster/cluster.css.map +1 -0
  161. package/src/styles/grid/grid.css +238 -0
  162. package/src/styles/grid/grid.css.map +1 -0
  163. package/src/styles/index.css +667 -49
  164. package/src/styles/index.css.map +1 -1
  165. package/src/styles/stack/stack.css +86 -0
  166. package/src/styles/stack/stack.css.map +1 -0
  167. package/src/types/component-props.ts +42 -14
  168. package/src/types/layout-primitives.ts +48 -0
  169. package/src/types/shared.ts +10 -26
  170. package/libs/chunk-ENTCUJ3A.cjs +0 -13
  171. package/libs/chunk-ENTCUJ3A.cjs.map +0 -1
  172. package/libs/chunk-HHLNOC5T.js +0 -7
  173. package/libs/chunk-HHLNOC5T.js.map +0 -1
  174. package/libs/chunk-KK47SYZI.js +0 -8
  175. package/libs/chunk-KK47SYZI.js.map +0 -1
  176. package/libs/chunk-W5TKWBFC.cjs +0 -18
  177. package/libs/chunk-W5TKWBFC.cjs.map +0 -1
  178. package/libs/component-props-67d978a2.d.ts +0 -38
  179. /package/libs/{chunk-2NRIP6RB.cjs.map → chunk-2C3YLBWP.cjs.map} +0 -0
  180. /package/libs/{chunk-NWJDAHP6.cjs.map → chunk-2GJHKWEK.cjs.map} +0 -0
  181. /package/libs/{chunk-FVROL3V5.js.map → chunk-2JCDEC32.js.map} +0 -0
  182. /package/libs/{chunk-IRLFZ3OL.js.map → chunk-3XJC4XUG.js.map} +0 -0
  183. /package/libs/{chunk-L6PRDL6F.cjs.map → chunk-5CJPTDK3.cjs.map} +0 -0
  184. /package/libs/{chunk-E4OSROCA.cjs.map → chunk-5QSNJQVH.cjs.map} +0 -0
  185. /package/libs/{chunk-O3JIHC5M.cjs.map → chunk-6BUJZ4DJ.cjs.map} +0 -0
  186. /package/libs/{chunk-WXBFBWYF.cjs.map → chunk-AFINOD2L.cjs.map} +0 -0
  187. /package/libs/{chunk-HRRHPLER.js.map → chunk-AWZLSWDO.js.map} +0 -0
  188. /package/libs/{chunk-CWRNJA4P.js.map → chunk-DIJBIOFE.js.map} +0 -0
  189. /package/libs/{chunk-GUJSMQ3V.cjs.map → chunk-EKJYOCLY.cjs.map} +0 -0
  190. /package/libs/{chunk-X5RKCLDC.cjs.map → chunk-F64GE6RG.cjs.map} +0 -0
  191. /package/libs/{chunk-5RAWNUVD.js.map → chunk-IBUTNPTQ.js.map} +0 -0
  192. /package/libs/{chunk-ZFJ4U45S.js.map → chunk-KDMX3FAW.js.map} +0 -0
  193. /package/libs/{chunk-DYFAUAB7.cjs.map → chunk-LXODKKA3.cjs.map} +0 -0
  194. /package/libs/{chunk-MPTMPBFT.js.map → chunk-M7JLT62Q.js.map} +0 -0
  195. /package/libs/{chunk-IQ76HGVP.js.map → chunk-MBWI67UT.js.map} +0 -0
  196. /package/libs/{chunk-O5XAJ7BY.cjs.map → chunk-NCGVF2QS.cjs.map} +0 -0
  197. /package/libs/{chunk-W2UIN7EV.cjs.map → chunk-NPWHQVYB.cjs.map} +0 -0
  198. /package/libs/{chunk-43TK2ICH.js.map → chunk-PMWL5XZ4.js.map} +0 -0
  199. /package/libs/{chunk-KVKQLRJG.js.map → chunk-TF3GQKOY.js.map} +0 -0
  200. /package/libs/{chunk-IEB64SWY.js.map → chunk-U5VA34SU.js.map} +0 -0
  201. /package/libs/{chunk-EE3ZWSBY.cjs.map → chunk-URBGDUFN.cjs.map} +0 -0
  202. /package/libs/{chunk-TPIB3RQP.js.map → chunk-ZF6Y7W57.js.map} +0 -0
@@ -0,0 +1,385 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import { within, expect } from "storybook/test";
3
+
4
+ import { Cluster } from "./cluster";
5
+ import "./cluster.scss";
6
+
7
+ const meta: Meta<typeof Cluster> = {
8
+ title: "FP.React Components/Layout/Cluster",
9
+ component: Cluster,
10
+ tags: ["autodocs", "rc", "layout"],
11
+ parameters: {
12
+ docs: {
13
+ description: {
14
+ component: `
15
+ # Cluster - Layout Primitive
16
+
17
+ A wrapping flex layout for inline groups that need to flow and wrap naturally.
18
+
19
+ ## Features
20
+
21
+ - **Auto-Wrapping**: Items wrap to next line when container is full
22
+ - **Fluid Spacing**: Responsive gap using CSS clamp()
23
+ - **Semantic**: Clear intent for inline grouped content
24
+ - **Polymorphic**: Render as any semantic HTML element
25
+ - **Type-Safe**: Full TypeScript support
26
+
27
+ ## When to Use
28
+
29
+ - **Cluster**: Inline content that wraps (tags, badges, buttons)
30
+ - **Stack**: Vertical/horizontal layouts without wrapping
31
+ - **Box**: Padding/margin on containers (no gap)
32
+
33
+ [View Full Documentation →](https://github.com/anthropics/fpkit/blob/main/packages/fpkit/src/components/cluster/README.mdx)
34
+ `,
35
+ },
36
+ },
37
+ },
38
+ };
39
+
40
+ export default meta;
41
+ type Story = StoryObj<typeof meta>;
42
+
43
+ /**
44
+ * Default Cluster with small gap.
45
+ * Perfect for tag clouds and inline groups.
46
+ */
47
+ export const Default: Story = {
48
+ args: {
49
+ gap: "sm",
50
+ children: (
51
+ <>
52
+ {["React", "TypeScript", "CSS", "Accessibility", "Performance"].map((tag) => (
53
+ <span
54
+ key={tag}
55
+ style={{
56
+ padding: "0.25rem 0.75rem",
57
+ backgroundColor: "#f0f0f0",
58
+ borderRadius: "0.25rem",
59
+ fontSize: "0.875rem",
60
+ }}
61
+ >
62
+ {tag}
63
+ </span>
64
+ ))}
65
+ </>
66
+ ),
67
+ },
68
+ play: async ({ canvasElement, step }) => {
69
+ const canvas = within(canvasElement);
70
+
71
+ await step("Cluster renders correctly", async () => {
72
+ expect(canvas.getByText("React")).toBeInTheDocument();
73
+ });
74
+
75
+ await step("Cluster has correct classes", async () => {
76
+ const cluster = canvas.getByText("React").parentElement;
77
+ expect(cluster).toHaveClass("cluster");
78
+ expect(cluster).toHaveClass("cluster-gap-sm");
79
+ });
80
+ },
81
+ };
82
+
83
+ /**
84
+ * Button group with wrapping.
85
+ * Buttons wrap to next line when they exceed container width.
86
+ */
87
+ export const ButtonGroup: Story = {
88
+ args: {
89
+ gap: "md",
90
+ styles: { maxWidth: "400px" },
91
+ children: (
92
+ <>
93
+ {[...Array(8)].map((_, i) => (
94
+ <button
95
+ key={i}
96
+ type="button"
97
+ style={{
98
+ padding: "0.5rem 1rem",
99
+ backgroundColor: "#0066cc",
100
+ color: "#fff",
101
+ border: "none",
102
+ borderRadius: "0.25rem",
103
+ cursor: "pointer",
104
+ }}
105
+ >
106
+ Action {i + 1}
107
+ </button>
108
+ ))}
109
+ </>
110
+ ),
111
+ },
112
+ };
113
+
114
+ /**
115
+ * Centered tag cloud.
116
+ * Tags centered horizontally with wrapping.
117
+ */
118
+ export const CenteredTags: Story = {
119
+ args: {
120
+ gap: "sm",
121
+ justify: "center",
122
+ children: (
123
+ <>
124
+ {["HTML", "CSS", "JavaScript", "React", "Vue", "Angular", "Svelte", "TypeScript"].map(
125
+ (tech) => (
126
+ <span
127
+ key={tech}
128
+ style={{
129
+ padding: "0.375rem 1rem",
130
+ backgroundColor: "#e8f4f8",
131
+ color: "#0066cc",
132
+ borderRadius: "1rem",
133
+ fontSize: "0.875rem",
134
+ fontWeight: "500",
135
+ }}
136
+ >
137
+ {tech}
138
+ </span>
139
+ )
140
+ )}
141
+ </>
142
+ ),
143
+ },
144
+ };
145
+
146
+ /**
147
+ * Badge cluster.
148
+ * Multiple badges with different colors and sizes.
149
+ */
150
+ export const Badges: Story = {
151
+ render: () => (
152
+ <Cluster gap="xs">
153
+ <span
154
+ style={{
155
+ padding: "0.25rem 0.5rem",
156
+ backgroundColor: "#d4edda",
157
+ color: "#155724",
158
+ borderRadius: "0.25rem",
159
+ fontSize: "0.75rem",
160
+ fontWeight: "500",
161
+ }}
162
+ >
163
+ Active
164
+ </span>
165
+ <span
166
+ style={{
167
+ padding: "0.25rem 0.5rem",
168
+ backgroundColor: "#d1ecf1",
169
+ color: "#0c5460",
170
+ borderRadius: "0.25rem",
171
+ fontSize: "0.75rem",
172
+ fontWeight: "500",
173
+ }}
174
+ >
175
+ New
176
+ </span>
177
+ <span
178
+ style={{
179
+ padding: "0.25rem 0.5rem",
180
+ backgroundColor: "#fff3cd",
181
+ color: "#856404",
182
+ borderRadius: "0.25rem",
183
+ fontSize: "0.75rem",
184
+ fontWeight: "500",
185
+ }}
186
+ >
187
+ Beta
188
+ </span>
189
+ <span
190
+ style={{
191
+ padding: "0.25rem 0.5rem",
192
+ backgroundColor: "#f8d7da",
193
+ color: "#721c24",
194
+ borderRadius: "0.25rem",
195
+ fontSize: "0.75rem",
196
+ fontWeight: "500",
197
+ }}
198
+ >
199
+ Deprecated
200
+ </span>
201
+ </Cluster>
202
+ ),
203
+ };
204
+
205
+ /**
206
+ * Navigation links with baseline alignment.
207
+ * Links aligned by baseline for consistent text alignment.
208
+ */
209
+ export const Navigation: Story = {
210
+ args: {
211
+ as: "nav",
212
+ gap: "lg",
213
+ align: "baseline",
214
+ justify: "center",
215
+ styles: {
216
+ padding: "1rem",
217
+ backgroundColor: "#f8f9fa",
218
+ border: "1px solid #e0e0e0",
219
+ },
220
+ children: (
221
+ <>
222
+ <a href="#home" style={{ textDecoration: "none", color: "#0066cc", fontSize: "1rem" }}>
223
+ Home
224
+ </a>
225
+ <a href="#products" style={{ textDecoration: "none", color: "#0066cc", fontSize: "1rem" }}>
226
+ Products
227
+ </a>
228
+ <a href="#about" style={{ textDecoration: "none", color: "#0066cc", fontSize: "1rem" }}>
229
+ About
230
+ </a>
231
+ <a href="#contact" style={{ textDecoration: "none", color: "#0066cc", fontSize: "1rem" }}>
232
+ Contact
233
+ </a>
234
+ </>
235
+ ),
236
+ },
237
+ };
238
+
239
+ /**
240
+ * Different gap sizes.
241
+ * Demonstrates the unified spacing scale from xs to xl.
242
+ */
243
+ export const GapSizes: Story = {
244
+ render: () => (
245
+ <div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
246
+ {["xs", "sm", "md", "lg", "xl"].map((size) => (
247
+ <div key={size}>
248
+ <h4 style={{ margin: 0, marginBottom: "0.5rem" }}>Gap {size.toUpperCase()}</h4>
249
+ <Cluster gap={size as SpacingScale} styles={{ border: "2px dashed #ccc", padding: "1rem" }}>
250
+ {[...Array(6)].map((_, i) => (
251
+ <span
252
+ key={i}
253
+ style={{
254
+ padding: "0.5rem",
255
+ backgroundColor: "#f0f0f0",
256
+ border: "1px solid #ccc",
257
+ }}
258
+ >
259
+ Item {i + 1}
260
+ </span>
261
+ ))}
262
+ </Cluster>
263
+ </div>
264
+ ))}
265
+ </div>
266
+ ),
267
+ };
268
+
269
+ /**
270
+ * Alignment variations.
271
+ * Demonstrates different vertical alignment options.
272
+ */
273
+ export const Alignments: Story = {
274
+ render: () => (
275
+ <div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
276
+ {["start", "center", "end", "baseline"].map((alignment) => (
277
+ <div key={alignment}>
278
+ <h4 style={{ margin: 0, marginBottom: "0.5rem" }}>Align {alignment}</h4>
279
+ <Cluster
280
+ gap="md"
281
+ align={alignment as "start" | "center" | "end"}
282
+ styles={{ border: "2px dashed #ccc", padding: "1rem", minHeight: "80px" }}
283
+ >
284
+ <span style={{ padding: "0.5rem", backgroundColor: "#f0f0f0", fontSize: "0.875rem" }}>
285
+ Small
286
+ </span>
287
+ <span style={{ padding: "1rem", backgroundColor: "#e0e0e0", fontSize: "1rem" }}>
288
+ Medium
289
+ </span>
290
+ <span style={{ padding: "1.5rem", backgroundColor: "#d0d0d0", fontSize: "1.25rem" }}>
291
+ Large
292
+ </span>
293
+ </Cluster>
294
+ </div>
295
+ ))}
296
+ </div>
297
+ ),
298
+ };
299
+
300
+ /**
301
+ * Justification variations.
302
+ * Demonstrates different horizontal alignment options.
303
+ */
304
+ export const Justifications: Story = {
305
+ render: () => (
306
+ <div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
307
+ {["start", "center", "end", "between"].map((justification) => (
308
+ <div key={justification}>
309
+ <h4 style={{ margin: 0, marginBottom: "0.5rem" }}>Justify {justification}</h4>
310
+ <Cluster
311
+ gap="sm"
312
+ justify={justification as "start" | "center" | "end" | "between"}
313
+ styles={{ border: "2px dashed #ccc", padding: "1rem" }}
314
+ >
315
+ {[...Array(4)].map((_, i) => (
316
+ <span
317
+ key={i}
318
+ style={{ padding: "0.5rem 1rem", backgroundColor: "#f0f0f0", border: "1px solid #ccc" }}
319
+ >
320
+ Item {i + 1}
321
+ </span>
322
+ ))}
323
+ </Cluster>
324
+ </div>
325
+ ))}
326
+ </div>
327
+ ),
328
+ };
329
+
330
+ /**
331
+ * Filter pills.
332
+ * Interactive filter tags that wrap naturally.
333
+ */
334
+ export const FilterPills: Story = {
335
+ render: () => (
336
+ <Cluster gap="sm" styles={{ maxWidth: "500px" }}>
337
+ {["All", "Active", "Completed", "In Progress", "Pending", "Cancelled"].map((filter) => (
338
+ <button
339
+ key={filter}
340
+ type="button"
341
+ style={{
342
+ padding: "0.5rem 1rem",
343
+ backgroundColor: filter === "All" ? "#0066cc" : "#fff",
344
+ color: filter === "All" ? "#fff" : "#333",
345
+ border: "1px solid #ccc",
346
+ borderRadius: "1.5rem",
347
+ cursor: "pointer",
348
+ fontSize: "0.875rem",
349
+ }}
350
+ >
351
+ {filter}
352
+ </button>
353
+ ))}
354
+ </Cluster>
355
+ ),
356
+ };
357
+
358
+ /**
359
+ * Semantic list.
360
+ * Using ul element for semantic list of items.
361
+ */
362
+ export const SemanticList: Story = {
363
+ args: {
364
+ as: "ul",
365
+ gap: "md",
366
+ styles: { listStyle: "none", padding: 0 },
367
+ children: (
368
+ <>
369
+ {["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"].map((item) => (
370
+ <li
371
+ key={item}
372
+ style={{
373
+ padding: "0.75rem 1rem",
374
+ backgroundColor: "#f8f9fa",
375
+ border: "1px solid #e0e0e0",
376
+ borderRadius: "0.25rem",
377
+ }}
378
+ >
379
+ {item}
380
+ </li>
381
+ ))}
382
+ </>
383
+ ),
384
+ },
385
+ };