@fpkit/acss 4.0.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/libs/components/alert/alert.css +1 -1
- package/libs/components/alert/alert.css.map +1 -1
- package/libs/components/alert/alert.min.css +2 -2
- package/libs/components/badge/badge.css +1 -1
- package/libs/components/badge/badge.css.map +1 -1
- package/libs/components/badge/badge.min.css +2 -2
- package/libs/components/buttons/button.css +1 -1
- package/libs/components/buttons/button.css.map +1 -1
- package/libs/components/buttons/button.min.css +2 -2
- package/libs/components/cards/card.css +1 -1
- package/libs/components/cards/card.css.map +1 -1
- package/libs/components/cards/card.min.css +2 -2
- package/libs/components/details/details.css +1 -1
- package/libs/components/details/details.css.map +1 -1
- package/libs/components/details/details.min.css +2 -2
- package/libs/components/dialog/dialog.css +1 -1
- package/libs/components/dialog/dialog.css.map +1 -1
- package/libs/components/dialog/dialog.min.css +2 -2
- package/libs/components/form/checkbox.css +1 -1
- package/libs/components/form/checkbox.css.map +1 -1
- package/libs/components/form/checkbox.min.css +2 -2
- package/libs/components/form/form.css +1 -1
- package/libs/components/form/form.css.map +1 -1
- package/libs/components/form/form.min.css +2 -2
- package/libs/components/link/link.css +1 -1
- package/libs/components/link/link.css.map +1 -1
- package/libs/components/link/link.min.css +2 -2
- package/libs/components/nav/nav.css +1 -1
- package/libs/components/nav/nav.css.map +1 -1
- package/libs/components/nav/nav.min.css +2 -2
- package/libs/components/progress/progress.css +1 -1
- package/libs/components/progress/progress.css.map +1 -1
- package/libs/components/progress/progress.min.css +2 -2
- package/libs/components/tag/tag.css +1 -1
- package/libs/components/tag/tag.css.map +1 -1
- package/libs/components/tag/tag.min.css +2 -2
- package/libs/components/text-to-speech/text-to-speech.css +1 -1
- package/libs/components/text-to-speech/text-to-speech.css.map +1 -1
- package/libs/components/text-to-speech/text-to-speech.min.css +2 -2
- package/libs/components/title/title.css +1 -1
- package/libs/components/title/title.css.map +1 -1
- package/libs/components/title/title.min.css +2 -2
- package/libs/index.cjs +1 -1
- package/libs/index.cjs.map +1 -1
- package/libs/index.css +1 -1
- package/libs/index.css.map +1 -1
- package/libs/index.js +1 -1
- package/libs/index.js.map +1 -1
- package/package.json +2 -2
- package/src/components/alert/alert.scss +22 -22
- package/src/components/alert/views/alert-view.tsx +6 -2
- package/src/components/badge/badge.scss +1 -1
- package/src/components/buttons/button.scss +8 -8
- package/src/components/cards/card.scss +7 -7
- package/src/components/details/details.scss +2 -3
- package/src/components/dialog/dialog.scss +4 -4
- package/src/components/form/checkbox.scss +8 -8
- package/src/components/form/form.scss +10 -10
- package/src/components/form/input.stories.tsx +17 -4
- package/src/components/link/link.scss +1 -1
- package/src/components/nav/nav.scss +1 -1
- package/src/components/progress/progress.scss +2 -2
- package/src/components/tag/tag.scss +7 -7
- package/src/components/text-to-speech/text-to-speech.scss +1 -1
- package/src/components/title/title.scss +4 -4
- package/src/index.scss +15 -1
- package/src/sass/_globals.scss +3 -3
- package/src/sass/styles/_colors.scss +16 -0
- package/src/sass/tokens/_color-primitives.scss +112 -0
- package/src/sass/tokens/_color-semantic.scss +144 -0
- package/src/sass/tokens/_index.scss +15 -0
- package/src/sass/utilities/_color-bg.scss +62 -0
- package/src/sass/utilities/_color-border.scss +61 -0
- package/src/sass/utilities/_color-text.scss +58 -0
- package/src/sass/utilities/_index.scss +17 -0
- package/src/sass/utilities/color-utilities.stories.tsx +608 -0
- package/src/styles/alert/alert.css +19 -19
- package/src/styles/badge/badge.css +1 -1
- package/src/styles/buttons/button.css +8 -8
- package/src/styles/cards/card.css +7 -7
- package/src/styles/details/details.css +2 -3
- package/src/styles/details/details.css.map +1 -1
- package/src/styles/dialog/dialog.css +4 -4
- package/src/styles/form/checkbox.css +11 -11
- package/src/styles/form/form.css +26 -21
- package/src/styles/form/form.css.map +1 -1
- package/src/styles/index.css +516 -82
- package/src/styles/index.css.map +1 -1
- package/src/styles/link/link.css +1 -1
- package/src/styles/nav/nav.css +1 -1
- package/src/styles/progress/progress.css +2 -2
- package/src/styles/tag/tag.css +7 -7
- package/src/styles/text-to-speech/text-to-speech.css +1 -1
- package/src/styles/title/title.css +4 -4
- package/src/styles/title/title.css.map +1 -1
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Color Utilities
|
|
5
|
+
*
|
|
6
|
+
* Semantic color utility classes for quick styling. All utilities reference
|
|
7
|
+
* semantic tokens from the 3-tier color system, ensuring WCAG AA compliance
|
|
8
|
+
* and consistent theming across the application.
|
|
9
|
+
*
|
|
10
|
+
* ## Three Utility Categories
|
|
11
|
+
*
|
|
12
|
+
* 1. **Text Colors** - `.text-*` classes for typography
|
|
13
|
+
* 2. **Background Colors** - `.bg-*` classes for surfaces
|
|
14
|
+
* 3. **Border Colors** - `.border-*` classes (requires border-width and border-style)
|
|
15
|
+
*
|
|
16
|
+
* ## Token Architecture
|
|
17
|
+
*
|
|
18
|
+
* All utilities reference **semantic tokens** (Tier 2), not primitive colors:
|
|
19
|
+
* ```
|
|
20
|
+
* Primitives (Tier 1) → Semantic (Tier 2) → Utilities
|
|
21
|
+
* --color-blue-600 → --color-primary → .text-primary
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* This ensures:
|
|
25
|
+
* - Easy theming via token overrides
|
|
26
|
+
* - Consistent color usage across components
|
|
27
|
+
* - WCAG AA accessibility compliance (4.5:1 text, 3:1 UI)
|
|
28
|
+
*/
|
|
29
|
+
const meta = {
|
|
30
|
+
title: "FP.React Components/Utilities/Colors",
|
|
31
|
+
tags: ["autodocs"],
|
|
32
|
+
parameters: {
|
|
33
|
+
docs: {
|
|
34
|
+
description: {
|
|
35
|
+
component:
|
|
36
|
+
"Semantic color utility classes for rapid development. All utilities maintain WCAG AA contrast ratios and reference the centralized token system.",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
} satisfies Meta;
|
|
41
|
+
|
|
42
|
+
export default meta;
|
|
43
|
+
type Story = StoryObj<typeof meta>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Text Color Utilities
|
|
47
|
+
*
|
|
48
|
+
* Use `.text-*` classes to apply semantic text colors. All colors meet
|
|
49
|
+
* WCAG AA contrast requirements (4.5:1 minimum) when used on appropriate backgrounds.
|
|
50
|
+
*/
|
|
51
|
+
export const TextColors: Story = {
|
|
52
|
+
render: () => (
|
|
53
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
|
|
54
|
+
<div>
|
|
55
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>Brand Colors</h3>
|
|
56
|
+
<p className="text-primary">
|
|
57
|
+
.text-primary - Primary brand color for emphasis
|
|
58
|
+
</p>
|
|
59
|
+
<p className="text-secondary">
|
|
60
|
+
.text-secondary - Secondary text for less emphasis
|
|
61
|
+
</p>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<div>
|
|
65
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>State Colors</h3>
|
|
66
|
+
<p className="text-success">
|
|
67
|
+
.text-success - Success messages and positive feedback
|
|
68
|
+
</p>
|
|
69
|
+
<p className="text-error">
|
|
70
|
+
.text-error - Error messages and validation failures
|
|
71
|
+
</p>
|
|
72
|
+
<p className="text-warning">
|
|
73
|
+
.text-warning - Warning messages and cautionary information
|
|
74
|
+
</p>
|
|
75
|
+
<p className="text-info">.text-info - Informational messages</p>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<div>
|
|
79
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>Text Hierarchy</h3>
|
|
80
|
+
<p className="text-muted">
|
|
81
|
+
.text-muted - Muted text for de-emphasized content
|
|
82
|
+
</p>
|
|
83
|
+
<p className="text-disabled">.text-disabled - Disabled state text</p>
|
|
84
|
+
<p className="text-inverse" style={{ backgroundColor: "#262626" }}>
|
|
85
|
+
.text-inverse - Inverse text (white) for dark backgrounds
|
|
86
|
+
</p>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
),
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Background Color Utilities
|
|
94
|
+
*
|
|
95
|
+
* Use `.bg-*` classes to apply semantic background colors. Combines with
|
|
96
|
+
* text utilities for accessible color combinations.
|
|
97
|
+
*/
|
|
98
|
+
export const BackgroundColors: Story = {
|
|
99
|
+
render: () => (
|
|
100
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
|
|
101
|
+
<div>
|
|
102
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>Brand Backgrounds</h3>
|
|
103
|
+
<div
|
|
104
|
+
className="bg-primary"
|
|
105
|
+
style={{ padding: "1rem", color: "white", marginBlockEnd: "0.5rem" }}
|
|
106
|
+
>
|
|
107
|
+
.bg-primary - Primary brand background
|
|
108
|
+
</div>
|
|
109
|
+
<div
|
|
110
|
+
className="bg-primary-light"
|
|
111
|
+
style={{ padding: "1rem", marginBlockEnd: "0.5rem" }}
|
|
112
|
+
>
|
|
113
|
+
.bg-primary-light - Light primary background
|
|
114
|
+
</div>
|
|
115
|
+
<div
|
|
116
|
+
className="bg-secondary"
|
|
117
|
+
style={{ padding: "1rem", marginBlockEnd: "0.5rem" }}
|
|
118
|
+
>
|
|
119
|
+
.bg-secondary - Secondary background
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<div>
|
|
124
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>State Backgrounds</h3>
|
|
125
|
+
<div
|
|
126
|
+
className="bg-success"
|
|
127
|
+
style={{ padding: "1rem", marginBlockEnd: "0.5rem" }}
|
|
128
|
+
>
|
|
129
|
+
.bg-success - Success background for positive feedback
|
|
130
|
+
</div>
|
|
131
|
+
<div
|
|
132
|
+
className="bg-error"
|
|
133
|
+
style={{ padding: "1rem", marginBlockEnd: "0.5rem" }}
|
|
134
|
+
>
|
|
135
|
+
.bg-error - Error background for validation failures
|
|
136
|
+
</div>
|
|
137
|
+
<div
|
|
138
|
+
className="bg-warning"
|
|
139
|
+
style={{ padding: "1rem", marginBlockEnd: "0.5rem" }}
|
|
140
|
+
>
|
|
141
|
+
.bg-warning - Warning background for caution
|
|
142
|
+
</div>
|
|
143
|
+
<div
|
|
144
|
+
className="bg-info"
|
|
145
|
+
style={{ padding: "1rem", marginBlockEnd: "0.5rem" }}
|
|
146
|
+
>
|
|
147
|
+
.bg-info - Info background for informational content
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
<div>
|
|
152
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>Surface Backgrounds</h3>
|
|
153
|
+
<div
|
|
154
|
+
className="bg-surface"
|
|
155
|
+
style={{
|
|
156
|
+
padding: "1rem",
|
|
157
|
+
border: "1px solid #d4d4d4",
|
|
158
|
+
marginBlockEnd: "0.5rem",
|
|
159
|
+
}}
|
|
160
|
+
>
|
|
161
|
+
.bg-surface - Primary surface background (usually white)
|
|
162
|
+
</div>
|
|
163
|
+
<div
|
|
164
|
+
className="bg-surface-secondary"
|
|
165
|
+
style={{
|
|
166
|
+
padding: "1rem",
|
|
167
|
+
border: "1px solid #d4d4d4",
|
|
168
|
+
marginBlockEnd: "0.5rem",
|
|
169
|
+
}}
|
|
170
|
+
>
|
|
171
|
+
.bg-surface-secondary - Secondary surface background
|
|
172
|
+
</div>
|
|
173
|
+
<div
|
|
174
|
+
className="bg-transparent"
|
|
175
|
+
style={{
|
|
176
|
+
padding: "1rem",
|
|
177
|
+
border: "1px solid #d4d4d4",
|
|
178
|
+
marginBlockEnd: "0.5rem",
|
|
179
|
+
}}
|
|
180
|
+
>
|
|
181
|
+
.bg-transparent - Transparent background
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
</div>
|
|
185
|
+
),
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Border Color Utilities
|
|
190
|
+
*
|
|
191
|
+
* Use `.border-*` classes to apply semantic border colors. You must also
|
|
192
|
+
* set `border-width` and `border-style` for borders to be visible.
|
|
193
|
+
*
|
|
194
|
+
* Example: `className="border-primary" style={{ border: "2px solid" }}`
|
|
195
|
+
*/
|
|
196
|
+
export const BorderColors: Story = {
|
|
197
|
+
render: () => (
|
|
198
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
|
|
199
|
+
<div>
|
|
200
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>Brand Borders</h3>
|
|
201
|
+
<div
|
|
202
|
+
className="border-primary"
|
|
203
|
+
style={{
|
|
204
|
+
padding: "1rem",
|
|
205
|
+
border: "2px solid",
|
|
206
|
+
marginBlockEnd: "0.5rem",
|
|
207
|
+
}}
|
|
208
|
+
>
|
|
209
|
+
.border-primary - Primary brand border
|
|
210
|
+
</div>
|
|
211
|
+
<div
|
|
212
|
+
className="border-secondary"
|
|
213
|
+
style={{
|
|
214
|
+
padding: "1rem",
|
|
215
|
+
border: "2px solid",
|
|
216
|
+
marginBlockEnd: "0.5rem",
|
|
217
|
+
}}
|
|
218
|
+
>
|
|
219
|
+
.border-secondary - Secondary border
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
<div>
|
|
224
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>State Borders</h3>
|
|
225
|
+
<div
|
|
226
|
+
className="border-success"
|
|
227
|
+
style={{
|
|
228
|
+
padding: "1rem",
|
|
229
|
+
border: "2px solid",
|
|
230
|
+
marginBlockEnd: "0.5rem",
|
|
231
|
+
}}
|
|
232
|
+
>
|
|
233
|
+
.border-success - Success border for valid states
|
|
234
|
+
</div>
|
|
235
|
+
<div
|
|
236
|
+
className="border-error"
|
|
237
|
+
style={{
|
|
238
|
+
padding: "1rem",
|
|
239
|
+
border: "2px solid",
|
|
240
|
+
marginBlockEnd: "0.5rem",
|
|
241
|
+
}}
|
|
242
|
+
>
|
|
243
|
+
.border-error - Error border for invalid states
|
|
244
|
+
</div>
|
|
245
|
+
<div
|
|
246
|
+
className="border-warning"
|
|
247
|
+
style={{
|
|
248
|
+
padding: "1rem",
|
|
249
|
+
border: "2px solid",
|
|
250
|
+
marginBlockEnd: "0.5rem",
|
|
251
|
+
}}
|
|
252
|
+
>
|
|
253
|
+
.border-warning - Warning border for caution
|
|
254
|
+
</div>
|
|
255
|
+
<div
|
|
256
|
+
className="border-info"
|
|
257
|
+
style={{
|
|
258
|
+
padding: "1rem",
|
|
259
|
+
border: "2px solid",
|
|
260
|
+
marginBlockEnd: "0.5rem",
|
|
261
|
+
}}
|
|
262
|
+
>
|
|
263
|
+
.border-info - Info border for informational content
|
|
264
|
+
</div>
|
|
265
|
+
</div>
|
|
266
|
+
|
|
267
|
+
<div>
|
|
268
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>UI Borders</h3>
|
|
269
|
+
<div
|
|
270
|
+
className="border-default"
|
|
271
|
+
style={{
|
|
272
|
+
padding: "1rem",
|
|
273
|
+
border: "2px solid",
|
|
274
|
+
marginBlockEnd: "0.5rem",
|
|
275
|
+
}}
|
|
276
|
+
>
|
|
277
|
+
.border-default - Default UI border
|
|
278
|
+
</div>
|
|
279
|
+
<div
|
|
280
|
+
className="border-subtle"
|
|
281
|
+
style={{
|
|
282
|
+
padding: "1rem",
|
|
283
|
+
border: "2px solid",
|
|
284
|
+
marginBlockEnd: "0.5rem",
|
|
285
|
+
}}
|
|
286
|
+
>
|
|
287
|
+
.border-subtle - Subtle border for less emphasis
|
|
288
|
+
</div>
|
|
289
|
+
<div
|
|
290
|
+
className="border-transparent"
|
|
291
|
+
style={{
|
|
292
|
+
padding: "1rem",
|
|
293
|
+
border: "2px solid",
|
|
294
|
+
backgroundColor: "#f5f5f5",
|
|
295
|
+
marginBlockEnd: "0.5rem",
|
|
296
|
+
}}
|
|
297
|
+
>
|
|
298
|
+
.border-transparent - Transparent border
|
|
299
|
+
</div>
|
|
300
|
+
</div>
|
|
301
|
+
</div>
|
|
302
|
+
),
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Combined Utilities
|
|
307
|
+
*
|
|
308
|
+
* Demonstrates combining text, background, and border utilities for
|
|
309
|
+
* common design patterns. All combinations maintain WCAG AA contrast ratios.
|
|
310
|
+
*/
|
|
311
|
+
export const CombinedUtilities: Story = {
|
|
312
|
+
render: () => (
|
|
313
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
|
|
314
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>Alert-style Messages</h3>
|
|
315
|
+
|
|
316
|
+
<div
|
|
317
|
+
className="bg-success text-success border-success"
|
|
318
|
+
style={{
|
|
319
|
+
padding: "1rem",
|
|
320
|
+
border: "2px solid",
|
|
321
|
+
borderRadius: "0.25rem",
|
|
322
|
+
}}
|
|
323
|
+
>
|
|
324
|
+
<strong>Success!</strong> Your changes have been saved successfully.
|
|
325
|
+
</div>
|
|
326
|
+
|
|
327
|
+
<div
|
|
328
|
+
className="bg-error text-error border-error"
|
|
329
|
+
style={{
|
|
330
|
+
padding: "1rem",
|
|
331
|
+
border: "2px solid",
|
|
332
|
+
borderRadius: "0.25rem",
|
|
333
|
+
}}
|
|
334
|
+
>
|
|
335
|
+
<strong>Error:</strong> Please correct the validation errors below.
|
|
336
|
+
</div>
|
|
337
|
+
|
|
338
|
+
<div
|
|
339
|
+
className="bg-warning text-warning border-warning"
|
|
340
|
+
style={{
|
|
341
|
+
padding: "1rem",
|
|
342
|
+
border: "2px solid",
|
|
343
|
+
borderRadius: "0.25rem",
|
|
344
|
+
}}
|
|
345
|
+
>
|
|
346
|
+
<strong>Warning:</strong> This action cannot be undone.
|
|
347
|
+
</div>
|
|
348
|
+
|
|
349
|
+
<div
|
|
350
|
+
className="bg-info text-info border-info"
|
|
351
|
+
style={{
|
|
352
|
+
padding: "1rem",
|
|
353
|
+
border: "2px solid",
|
|
354
|
+
borderRadius: "0.25rem",
|
|
355
|
+
}}
|
|
356
|
+
>
|
|
357
|
+
<strong>Info:</strong> You have 3 unread notifications.
|
|
358
|
+
</div>
|
|
359
|
+
|
|
360
|
+
<h3 style={{ marginBlockEnd: "0.5rem", marginBlockStart: "1rem" }}>
|
|
361
|
+
Card-style Containers
|
|
362
|
+
</h3>
|
|
363
|
+
|
|
364
|
+
<div
|
|
365
|
+
className="bg-surface border-default"
|
|
366
|
+
style={{
|
|
367
|
+
padding: "1.5rem",
|
|
368
|
+
border: "1px solid",
|
|
369
|
+
borderRadius: "0.5rem",
|
|
370
|
+
}}
|
|
371
|
+
>
|
|
372
|
+
<h4 className="text-primary" style={{ marginBlockStart: 0 }}>
|
|
373
|
+
Primary Heading
|
|
374
|
+
</h4>
|
|
375
|
+
<p className="text-secondary" style={{ marginBlockEnd: 0 }}>
|
|
376
|
+
This card uses semantic utilities for consistent styling.
|
|
377
|
+
</p>
|
|
378
|
+
</div>
|
|
379
|
+
|
|
380
|
+
<div
|
|
381
|
+
className="bg-primary-light border-primary"
|
|
382
|
+
style={{
|
|
383
|
+
padding: "1.5rem",
|
|
384
|
+
border: "2px solid",
|
|
385
|
+
borderRadius: "0.5rem",
|
|
386
|
+
}}
|
|
387
|
+
>
|
|
388
|
+
<h4 className="text-primary" style={{ marginBlockStart: 0 }}>
|
|
389
|
+
Highlighted Card
|
|
390
|
+
</h4>
|
|
391
|
+
<p style={{ marginBlockEnd: 0 }}>
|
|
392
|
+
Combines light background with primary border for emphasis.
|
|
393
|
+
</p>
|
|
394
|
+
</div>
|
|
395
|
+
</div>
|
|
396
|
+
),
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Theming Example
|
|
401
|
+
*
|
|
402
|
+
* Demonstrates how utilities adapt when semantic tokens are overridden.
|
|
403
|
+
* This example uses inline CSS variables to simulate theme customization.
|
|
404
|
+
*/
|
|
405
|
+
export const ThemingExample: Story = {
|
|
406
|
+
render: () => (
|
|
407
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
|
|
408
|
+
<div>
|
|
409
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>Default Theme</h3>
|
|
410
|
+
<p className="text-primary">
|
|
411
|
+
Primary text uses default blue from token system
|
|
412
|
+
</p>
|
|
413
|
+
<div className="bg-primary" style={{ padding: "1rem", color: "white" }}>
|
|
414
|
+
Primary background uses default blue
|
|
415
|
+
</div>
|
|
416
|
+
</div>
|
|
417
|
+
|
|
418
|
+
<div
|
|
419
|
+
style={
|
|
420
|
+
{
|
|
421
|
+
"--color-primary": "#7c3aed",
|
|
422
|
+
"--color-primary-light": "#ede9fe",
|
|
423
|
+
} as React.CSSProperties
|
|
424
|
+
}
|
|
425
|
+
>
|
|
426
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>Custom Theme (Purple)</h3>
|
|
427
|
+
<p className="text-primary">
|
|
428
|
+
Primary text now uses purple via token override
|
|
429
|
+
</p>
|
|
430
|
+
<div className="bg-primary" style={{ padding: "1rem", color: "white" }}>
|
|
431
|
+
Primary background now uses purple
|
|
432
|
+
</div>
|
|
433
|
+
<div className="bg-primary-light" style={{ padding: "1rem" }}>
|
|
434
|
+
Light background adapts to purple theme
|
|
435
|
+
</div>
|
|
436
|
+
</div>
|
|
437
|
+
|
|
438
|
+
<div
|
|
439
|
+
style={
|
|
440
|
+
{
|
|
441
|
+
"--color-primary": "#dc2626",
|
|
442
|
+
"--color-primary-light": "#fee2e2",
|
|
443
|
+
} as React.CSSProperties
|
|
444
|
+
}
|
|
445
|
+
>
|
|
446
|
+
<h3 style={{ marginBlockEnd: "0.5rem" }}>Custom Theme (Red)</h3>
|
|
447
|
+
<p className="text-primary">
|
|
448
|
+
Primary text now uses red via token override
|
|
449
|
+
</p>
|
|
450
|
+
<div className="bg-primary" style={{ padding: "1rem", color: "white" }}>
|
|
451
|
+
Primary background now uses red
|
|
452
|
+
</div>
|
|
453
|
+
<div className="bg-primary-light" style={{ padding: "1rem" }}>
|
|
454
|
+
Light background adapts to red theme
|
|
455
|
+
</div>
|
|
456
|
+
</div>
|
|
457
|
+
|
|
458
|
+
<div
|
|
459
|
+
style={{
|
|
460
|
+
marginBlockStart: "1rem",
|
|
461
|
+
padding: "1rem",
|
|
462
|
+
backgroundColor: "#f5f5f5",
|
|
463
|
+
borderRadius: "0.25rem",
|
|
464
|
+
}}
|
|
465
|
+
>
|
|
466
|
+
<p style={{ marginBlockStart: 0, fontSize: "0.875rem" }}>
|
|
467
|
+
<strong>💡 Theming Tip:</strong> Override semantic tokens (
|
|
468
|
+
<code>--color-primary</code>, <code>--color-success</code>, etc.) to
|
|
469
|
+
theme your entire application. All utilities automatically adapt!
|
|
470
|
+
</p>
|
|
471
|
+
</div>
|
|
472
|
+
</div>
|
|
473
|
+
),
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Usage Guidelines
|
|
478
|
+
*
|
|
479
|
+
* Best practices for using color utilities in your application.
|
|
480
|
+
*/
|
|
481
|
+
export const UsageGuidelines: Story = {
|
|
482
|
+
render: () => (
|
|
483
|
+
<div style={{ maxWidth: "75ch" }}>
|
|
484
|
+
<h3>Best Practices</h3>
|
|
485
|
+
|
|
486
|
+
<h4>✅ Do</h4>
|
|
487
|
+
<ul style={{ lineHeight: 1.6 }}>
|
|
488
|
+
<li>
|
|
489
|
+
Use semantic utilities (<code>.text-primary</code>,{" "}
|
|
490
|
+
<code>.bg-success</code>) for consistent theming
|
|
491
|
+
</li>
|
|
492
|
+
<li>
|
|
493
|
+
Combine utilities for common patterns (<code>.bg-error</code> +{" "}
|
|
494
|
+
<code>.text-error</code>)
|
|
495
|
+
</li>
|
|
496
|
+
<li>Ensure sufficient contrast for accessibility (4.5:1 for text)</li>
|
|
497
|
+
<li>
|
|
498
|
+
Use <code>.text-inverse</code> on dark backgrounds for readability
|
|
499
|
+
</li>
|
|
500
|
+
<li>
|
|
501
|
+
Override semantic tokens (<code>--color-primary</code>) for
|
|
502
|
+
application-wide theming
|
|
503
|
+
</li>
|
|
504
|
+
</ul>
|
|
505
|
+
|
|
506
|
+
<h4>❌ Don't</h4>
|
|
507
|
+
<ul style={{ lineHeight: 1.6 }}>
|
|
508
|
+
<li>
|
|
509
|
+
Don't use utilities on elements with component-level tokens (they may
|
|
510
|
+
conflict)
|
|
511
|
+
</li>
|
|
512
|
+
<li>
|
|
513
|
+
Don't reference primitive tokens directly (
|
|
514
|
+
<code>--color-blue-600</code>) - use semantic tokens instead
|
|
515
|
+
</li>
|
|
516
|
+
<li>Don't create custom color utilities outside the token system</li>
|
|
517
|
+
<li>
|
|
518
|
+
Don't forget to set <code>border-width</code> and{" "}
|
|
519
|
+
<code>border-style</code> when using border utilities
|
|
520
|
+
</li>
|
|
521
|
+
<li>
|
|
522
|
+
Don't use utilities for complex component styling - use
|
|
523
|
+
component-level tokens instead
|
|
524
|
+
</li>
|
|
525
|
+
</ul>
|
|
526
|
+
|
|
527
|
+
<h4>Code Examples</h4>
|
|
528
|
+
|
|
529
|
+
<div
|
|
530
|
+
style={{
|
|
531
|
+
backgroundColor: "#f5f5f5",
|
|
532
|
+
padding: "1rem",
|
|
533
|
+
borderRadius: "0.25rem",
|
|
534
|
+
marginBlockEnd: "1rem",
|
|
535
|
+
}}
|
|
536
|
+
>
|
|
537
|
+
<p style={{ marginBlockStart: 0, fontSize: "0.875rem" }}>
|
|
538
|
+
<strong>HTML:</strong>
|
|
539
|
+
</p>
|
|
540
|
+
<pre style={{ marginBlockEnd: 0, overflow: "auto" }}>
|
|
541
|
+
<code>{`<!-- Alert-style message -->
|
|
542
|
+
<div class="bg-success text-success border-success" style="padding: 1rem; border: 2px solid;">
|
|
543
|
+
Success! Your changes have been saved.
|
|
544
|
+
</div>
|
|
545
|
+
|
|
546
|
+
<!-- Primary button-style link -->
|
|
547
|
+
<a href="#" class="bg-primary text-inverse" style="padding: 0.5rem 1rem; display: inline-block;">
|
|
548
|
+
Get Started
|
|
549
|
+
</a>`}</code>
|
|
550
|
+
</pre>
|
|
551
|
+
</div>
|
|
552
|
+
|
|
553
|
+
<div
|
|
554
|
+
style={{
|
|
555
|
+
backgroundColor: "#f5f5f5",
|
|
556
|
+
padding: "1rem",
|
|
557
|
+
borderRadius: "0.25rem",
|
|
558
|
+
}}
|
|
559
|
+
>
|
|
560
|
+
<p style={{ marginBlockStart: 0, fontSize: "0.875rem" }}>
|
|
561
|
+
<strong>Theming (CSS):</strong>
|
|
562
|
+
</p>
|
|
563
|
+
<pre style={{ marginBlockEnd: 0, overflow: "auto" }}>
|
|
564
|
+
<code>{`:root {
|
|
565
|
+
/* Override semantic tokens for custom branding */
|
|
566
|
+
--color-primary: #7c3aed; /* Purple instead of blue */
|
|
567
|
+
--color-primary-light: #ede9fe; /* Light purple */
|
|
568
|
+
--color-success: #059669; /* Teal instead of green */
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/* All .text-primary, .bg-primary utilities now use purple! */`}</code>
|
|
572
|
+
</pre>
|
|
573
|
+
</div>
|
|
574
|
+
|
|
575
|
+
<h4 style={{ marginBlockStart: "1.5rem" }}>Accessibility</h4>
|
|
576
|
+
<p>All color utilities meet WCAG AA standards when used appropriately:</p>
|
|
577
|
+
<ul style={{ lineHeight: 1.6 }}>
|
|
578
|
+
<li>
|
|
579
|
+
<strong>Text colors:</strong> 4.5:1 contrast minimum on white
|
|
580
|
+
backgrounds
|
|
581
|
+
</li>
|
|
582
|
+
<li>
|
|
583
|
+
<strong>State backgrounds:</strong> Paired with matching text colors
|
|
584
|
+
for sufficient contrast
|
|
585
|
+
</li>
|
|
586
|
+
<li>
|
|
587
|
+
<strong>Borders:</strong> 3:1 contrast minimum for UI components
|
|
588
|
+
</li>
|
|
589
|
+
<li>
|
|
590
|
+
<strong>Focus indicators:</strong> Use semantic tokens that meet
|
|
591
|
+
contrast requirements
|
|
592
|
+
</li>
|
|
593
|
+
</ul>
|
|
594
|
+
|
|
595
|
+
<p>
|
|
596
|
+
Always test color combinations with tools like the{" "}
|
|
597
|
+
<a
|
|
598
|
+
href="https://webaim.org/resources/contrastchecker/"
|
|
599
|
+
target="_blank"
|
|
600
|
+
rel="noopener noreferrer"
|
|
601
|
+
>
|
|
602
|
+
WebAIM Contrast Checker
|
|
603
|
+
</a>{" "}
|
|
604
|
+
or browser DevTools.
|
|
605
|
+
</p>
|
|
606
|
+
</div>
|
|
607
|
+
),
|
|
608
|
+
};
|
|
@@ -12,28 +12,28 @@
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
[role=alert] {
|
|
15
|
-
/* Success colors */
|
|
16
|
-
--alert-success-bg:
|
|
17
|
-
--alert-success-border:
|
|
18
|
-
--alert-success-text:
|
|
19
|
-
/* Error colors */
|
|
20
|
-
--alert-error-bg:
|
|
21
|
-
--alert-error-border:
|
|
22
|
-
--alert-error-text:
|
|
23
|
-
/* Warning colors */
|
|
24
|
-
--alert-warning-bg:
|
|
25
|
-
--alert-warning-border:
|
|
26
|
-
--alert-warning-text:
|
|
27
|
-
/* Info colors */
|
|
28
|
-
--alert-info-bg:
|
|
29
|
-
--alert-info-border:
|
|
30
|
-
--alert-info-text:
|
|
15
|
+
/* Success colors - WCAG AA compliant (mapped to semantic tokens) */
|
|
16
|
+
--alert-success-bg: var(--color-success-bg);
|
|
17
|
+
--alert-success-border: var(--color-success-border);
|
|
18
|
+
--alert-success-text: var(--color-success-text);
|
|
19
|
+
/* Error colors - WCAG AA compliant (mapped to semantic tokens) */
|
|
20
|
+
--alert-error-bg: var(--color-error-bg);
|
|
21
|
+
--alert-error-border: var(--color-error-border);
|
|
22
|
+
--alert-error-text: var(--color-error-text);
|
|
23
|
+
/* Warning colors - WCAG AA compliant (mapped to semantic tokens) */
|
|
24
|
+
--alert-warning-bg: var(--color-warning-bg);
|
|
25
|
+
--alert-warning-border: var(--color-warning-border);
|
|
26
|
+
--alert-warning-text: var(--color-warning-text);
|
|
27
|
+
/* Info colors - WCAG AA compliant (mapped to semantic tokens) */
|
|
28
|
+
--alert-info-bg: var(--color-info-bg);
|
|
29
|
+
--alert-info-border: var(--color-info-border);
|
|
30
|
+
--alert-info-text: var(--color-info-text);
|
|
31
31
|
/* Animation */
|
|
32
32
|
--alert-transition-duration: 0.3s;
|
|
33
33
|
--alert-border: thin solid currentColor;
|
|
34
|
-
background-color: var(--alert-bg,
|
|
35
|
-
border: var(--alert-border,
|
|
36
|
-
color: var(--alert-color,
|
|
34
|
+
background-color: var(--alert-bg, var(--color-surface));
|
|
35
|
+
border: var(--alert-border, var(--color-border));
|
|
36
|
+
color: var(--alert-color, var(--color-text));
|
|
37
37
|
padding: var(--alert-padding, var(--spc-4));
|
|
38
38
|
margin-block-end: var(--alert-margin-block-end);
|
|
39
39
|
font-size: var(--fs-0);
|
|
@@ -6,7 +6,7 @@ button {
|
|
|
6
6
|
--btn-pill: 100rem;
|
|
7
7
|
--btn-fs: var(--btn-size-md);
|
|
8
8
|
--btn-height: calc(var(--btn-fs) * 2.25);
|
|
9
|
-
--btn-bg:
|
|
9
|
+
--btn-bg: var(--color-neutral-300);
|
|
10
10
|
--btn-width: max-content;
|
|
11
11
|
font-size: var(--btn-fs);
|
|
12
12
|
font-weight: var(--btn-fw, 500);
|
|
@@ -31,12 +31,12 @@ button {
|
|
|
31
31
|
line-height: 0cap;
|
|
32
32
|
}
|
|
33
33
|
button[type] {
|
|
34
|
-
background-color: var(--btn-bg, var(--neutral-300));
|
|
34
|
+
background-color: var(--btn-bg, var(--color-neutral-300));
|
|
35
35
|
--btn-border: solid var(--btn-sg);
|
|
36
36
|
}
|
|
37
37
|
button[type=submit], button[style*=submit] {
|
|
38
|
-
--btn-bg: var(--primary
|
|
39
|
-
--btn-color:
|
|
38
|
+
--btn-bg: var(--color-primary);
|
|
39
|
+
--btn-color: var(--color-text-inverse);
|
|
40
40
|
}
|
|
41
41
|
button[disabled], button[aria-disabled=true] {
|
|
42
42
|
cursor: var(--btn-cursor, not-allowed);
|
|
@@ -61,12 +61,12 @@ button:focus-visible {
|
|
|
61
61
|
}
|
|
62
62
|
button[type=reset] {
|
|
63
63
|
--btn-bg: transparent;
|
|
64
|
-
--btn-color:
|
|
65
|
-
--btn-border:
|
|
64
|
+
--btn-color: var(--color-text-secondary);
|
|
65
|
+
--btn-border: var(--color-border) thin solid;
|
|
66
66
|
}
|
|
67
67
|
button[type=submit] {
|
|
68
|
-
--btn-bg: var(--primary
|
|
69
|
-
--btn-color:
|
|
68
|
+
--btn-bg: var(--color-primary);
|
|
69
|
+
--btn-color: var(--color-text-inverse);
|
|
70
70
|
--btn-border: none;
|
|
71
71
|
}
|
|
72
72
|
button[data-fp-btn~=pill], button[data-btn~=pill], button[data-style~=pill] {
|