@1money/component-ui 0.0.23 → 0.0.25

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 (107) hide show
  1. package/es/components/Table/interface.d.ts +2 -1
  2. package/es/components/Table/renderers/EmptyState.d.ts +2 -1
  3. package/es/components/Table/renderers/EmptyState.js +15 -8
  4. package/es/components/Table/style/Table.css +1 -1
  5. package/es/index.css +1 -1
  6. package/es/stories/docs/ComponentDocsPage.js +234 -0
  7. package/es/stories/docs/componentDocMeta.js +97 -0
  8. package/es/stories/docs/storybook-docs.css +79 -0
  9. package/lib/components/Table/interface.d.ts +2 -1
  10. package/lib/components/Table/renderers/EmptyState.d.ts +2 -1
  11. package/lib/components/Table/renderers/EmptyState.js +15 -7
  12. package/lib/components/Table/style/Table.css +1 -1
  13. package/lib/index.css +1 -1
  14. package/lib/stories/docs/ComponentDocsPage.js +244 -0
  15. package/lib/stories/docs/componentDocMeta.js +104 -0
  16. package/lib/stories/docs/storybook-docs.css +79 -0
  17. package/package.json +23 -8
  18. package/scripts/mcp-server/README.md +267 -0
  19. package/scripts/mcp-server/bin.mjs +2 -0
  20. package/scripts/mcp-server/drift.json +5 -0
  21. package/scripts/mcp-server/examples.generated.json +2651 -0
  22. package/scripts/mcp-server/index.generated.json +18098 -0
  23. package/scripts/mcp-server/index.mjs +308 -26
  24. package/scripts/mcp-server/tools/get-examples.mjs +125 -0
  25. package/scripts/mcp-server/tools/get-library-info.mjs +25 -0
  26. package/scripts/mcp-server/tools/get-symbol.mjs +232 -0
  27. package/scripts/mcp-server/tools/get-token.mjs +60 -0
  28. package/scripts/mcp-server/tools/list-icons.mjs +38 -0
  29. package/scripts/mcp-server/tools/list-symbols.mjs +46 -0
  30. package/scripts/mcp-server/tools/resolve-import.mjs +125 -0
  31. package/scripts/mcp-server/tools/search-symbols.mjs +79 -0
  32. package/.agents/skills/1money-component-dev/SKILL.md +0 -224
  33. package/.agents/skills/1money-component-dev/checklist.md +0 -159
  34. package/.agents/skills/1money-component-dev/references/ComponentPatterns.md +0 -478
  35. package/.agents/skills/1money-component-dev/references/FigmaExtractionChecklist.md +0 -144
  36. package/.agents/skills/1money-component-dev/references/HooksGuide.md +0 -360
  37. package/.agents/skills/1money-component-dev/references/SemanticColors.md +0 -215
  38. package/.agents/skills/1money-component-dev/references/StyleSystemAPI.md +0 -389
  39. package/.claude/settings.local.json +0 -120
  40. package/.claude/skills/1money-component-dev/SKILL.md +0 -229
  41. package/.claude/skills/1money-component-dev/checklist.md +0 -159
  42. package/.claude/skills/1money-component-dev/references/ComponentPatterns.md +0 -478
  43. package/.claude/skills/1money-component-dev/references/FigmaExtractionChecklist.md +0 -144
  44. package/.claude/skills/1money-component-dev/references/HooksGuide.md +0 -360
  45. package/.claude/skills/1money-component-dev/references/SemanticColors.md +0 -215
  46. package/.claude/skills/1money-component-dev/references/StyleSystemAPI.md +0 -389
  47. package/.claude/skills/1money-component-review/SKILL.md +0 -316
  48. package/.claude/skills/component-pipeline/SKILL.md +0 -116
  49. package/.claude/skills/component-pipeline/checklist.md +0 -125
  50. package/.hintrc +0 -13
  51. package/@types/global.d.ts +0 -28
  52. package/AGENTS.md +0 -546
  53. package/CLAUDE.md +0 -1
  54. package/jest.setup.d.ts +0 -1
  55. package/jest.setup.ts +0 -1
  56. package/patches/primereact.patch +0 -323
  57. package/patches/react-pro-sidebar.patch +0 -6421
  58. package/public/favicon.ico +0 -0
  59. package/public/fonts/Aeonik/Aeonik-Air.ttf +0 -0
  60. package/public/fonts/Aeonik/Aeonik-AirItalic.ttf +0 -0
  61. package/public/fonts/Aeonik/Aeonik-Black.ttf +0 -0
  62. package/public/fonts/Aeonik/Aeonik-BlackItalic.ttf +0 -0
  63. package/public/fonts/Aeonik/Aeonik-Bold.ttf +0 -0
  64. package/public/fonts/Aeonik/Aeonik-BoldItalic.ttf +0 -0
  65. package/public/fonts/Aeonik/Aeonik-Light.ttf +0 -0
  66. package/public/fonts/Aeonik/Aeonik-LightItalic.ttf +0 -0
  67. package/public/fonts/Aeonik/Aeonik-Medium.ttf +0 -0
  68. package/public/fonts/Aeonik/Aeonik-MediumItalic.ttf +0 -0
  69. package/public/fonts/Aeonik/Aeonik-Regular.ttf +0 -0
  70. package/public/fonts/Aeonik/Aeonik-RegularItalic.ttf +0 -0
  71. package/public/fonts/Aeonik/Aeonik-Thin.ttf +0 -0
  72. package/public/fonts/Aeonik/Aeonik-ThinItalic.ttf +0 -0
  73. package/public/fonts/Inter/Inter-Black.ttf +0 -0
  74. package/public/fonts/Inter/Inter-BlackItalic.ttf +0 -0
  75. package/public/fonts/Inter/Inter-Bold.ttf +0 -0
  76. package/public/fonts/Inter/Inter-BoldItalic.ttf +0 -0
  77. package/public/fonts/Inter/Inter-ExtraBold.ttf +0 -0
  78. package/public/fonts/Inter/Inter-ExtraBoldItalic.ttf +0 -0
  79. package/public/fonts/Inter/Inter-ExtraLight.ttf +0 -0
  80. package/public/fonts/Inter/Inter-ExtraLightItalic.ttf +0 -0
  81. package/public/fonts/Inter/Inter-Italic.ttf +0 -0
  82. package/public/fonts/Inter/Inter-Light.ttf +0 -0
  83. package/public/fonts/Inter/Inter-LightItalic.ttf +0 -0
  84. package/public/fonts/Inter/Inter-Medium.ttf +0 -0
  85. package/public/fonts/Inter/Inter-MediumItalic.ttf +0 -0
  86. package/public/fonts/Inter/Inter-Regular.ttf +0 -0
  87. package/public/fonts/Inter/Inter-SemiBold.ttf +0 -0
  88. package/public/fonts/Inter/Inter-SemiBoldItalic.ttf +0 -0
  89. package/public/fonts/Inter/Inter-Thin.ttf +0 -0
  90. package/public/fonts/Inter/Inter-ThinItalic.ttf +0 -0
  91. package/public/fonts/Outfit/Outfit-Black.ttf +0 -0
  92. package/public/fonts/Outfit/Outfit-Bold.ttf +0 -0
  93. package/public/fonts/Outfit/Outfit-ExtraBold.ttf +0 -0
  94. package/public/fonts/Outfit/Outfit-ExtraLight.ttf +0 -0
  95. package/public/fonts/Outfit/Outfit-Light.ttf +0 -0
  96. package/public/fonts/Outfit/Outfit-Medium.ttf +0 -0
  97. package/public/fonts/Outfit/Outfit-Regular.ttf +0 -0
  98. package/public/fonts/Outfit/Outfit-SemiBold.ttf +0 -0
  99. package/public/fonts/Outfit/Outfit-Thin.ttf +0 -0
  100. package/public/github-mark.svg +0 -3
  101. package/public/tokens/GYEN.svg +0 -9
  102. package/public/tokens/PYUSD.svg +0 -9
  103. package/public/tokens/USDT.svg +0 -6
  104. package/scripts/mcp-server/resources.d.mts +0 -1
  105. package/scripts/mcp-server/resources.mjs +0 -102
  106. package/test/jsdom-global-register.d.ts +0 -1
  107. package/test/jsdom-global-register.js +0 -1
@@ -1,360 +0,0 @@
1
- # Hooks Guide
2
-
3
- Reference for using the library's custom hooks inside `@1money/components-ui` components.
4
-
5
- All hooks are provided by the `@1money/hooks` package and imported via `import { hookName } from '@1money/hooks'`.
6
-
7
- ---
8
-
9
- ## Import Convention
10
-
11
- ```tsx
12
- // Always import from @1money/hooks
13
- import { useControlledState } from '@1money/hooks';
14
- import { useEventCallback } from '@1money/hooks';
15
- import { useLatest } from '@1money/hooks';
16
- import { useLayoutEffect } from '@1money/hooks';
17
- import { useMemoizedFn } from '@1money/hooks';
18
- import { usePrevious } from '@1money/hooks';
19
- import { useSafeState } from '@1money/hooks';
20
- import { useSyncState } from '@1money/hooks';
21
- import { useUpdateEffect } from '@1money/hooks';
22
- import { useLayoutState, useTimeoutLock } from '@1money/hooks';
23
-
24
- // Or combine into a single import
25
- import { useControlledState, useEventCallback, useLatest } from '@1money/hooks';
26
- ```
27
-
28
- > **Never** import hooks from `@1money/components-ui` inside the library — that is the consumer-facing path.
29
-
30
- ---
31
-
32
- ## Hook Selection Guide
33
-
34
- | Scenario | Hook |
35
- |----------|------|
36
- | Controlled + uncontrolled input | `useControlledState` |
37
- | Stable callback for memoized children | `useEventCallback` or `useMemoizedFn` |
38
- | Access latest value without re-render | `useLatest` |
39
- | Different logic for mount vs update | `useLayoutEffect` |
40
- | Compare with previous value | `usePrevious` |
41
- | Async state updates (prevent unmount leak) | `useSafeState` |
42
- | Read latest state synchronously | `useSyncState` |
43
- | Skip effect on initial mount | `useUpdateEffect` |
44
- | Batch synchronous state updates | `useLayoutState` |
45
- | Short-lived lock with auto-reset | `useTimeoutLock` |
46
-
47
- ---
48
-
49
- ## Hook Details & In-Library Usage Patterns
50
-
51
- ### useControlledState
52
-
53
- **When to use**: Any component that supports both controlled (`value` prop) and uncontrolled (`defaultValue` prop) modes.
54
-
55
- ```tsx
56
- import { useControlledState } from '@1money/hooks';
57
-
58
- // Signature: useControlledState<T>(defaultValue: T, controlledValue?: T) => [T, (v: T) => void]
59
-
60
- const [val, setVal] = useControlledState(defaultValue ?? '', value);
61
- ```
62
-
63
- **Real usage** — `Input.tsx`:
64
- ```tsx
65
- const [val, setVal] = useControlledState(defaultValue ?? '', value);
66
- ```
67
-
68
- **Real usage** — `Select.tsx`:
69
- ```tsx
70
- const [selected, setSelected] = useControlledState<string | number | readonly string[] | null>(
71
- defaultValue ?? null, value
72
- );
73
- ```
74
-
75
- **Real usage** — `CheckboxGroup.tsx`:
76
- ```tsx
77
- const [checkedItems, setCheckedItems] = useControlledState<string[]>(
78
- normalValue ?? defaultChecked, normalValue
79
- );
80
- ```
81
-
82
- ---
83
-
84
- ### useEventCallback
85
-
86
- **When to use**: Event handlers that need a stable reference while always calling the latest function version. Preferred for simple event handlers (onChange, onClick, onHide, etc.).
87
-
88
- ```tsx
89
- import { useEventCallback } from '@1money/hooks';
90
-
91
- const handleChange = useEventCallback((e: ChangeEvent) => {
92
- setVal(e.target.value);
93
- onChange?.(e);
94
- });
95
- ```
96
-
97
- **Real usage** — `Input.tsx`:
98
- ```tsx
99
- const handleChange = useEventCallback((e: InputChangeEvent) => {
100
- if (loading || disabled) return;
101
- const _val = 'target' in e ? e.target.value : e.value;
102
- setVal((type === 'textarea' ? _val?.slice(0, maxLength) : _val) ?? '');
103
- onChange?.(e as any);
104
- });
105
- ```
106
-
107
- **Real usage** — `Select.tsx`:
108
- ```tsx
109
- const handleChange = useEventCallback<[SelectChangeEvent], void>((e) => {
110
- setSelected(e.value);
111
- emitChange?.(e);
112
- });
113
-
114
- const handleHide = useEventCallback(() => {
115
- setIsOpen(false);
116
- onHide?.();
117
- });
118
- ```
119
-
120
- ---
121
-
122
- ### useLatest
123
-
124
- **When to use**: Access the most recent value inside callbacks, timers, or imperative handles without adding the value to dependency arrays.
125
-
126
- ```tsx
127
- import { useLatest } from '@1money/hooks';
128
-
129
- const collapsedRef = useLatest(collapsed);
130
-
131
- // Later:
132
- const toggle = () => handleCollapse(!collapsedRef.current);
133
- ```
134
-
135
- **Real usage** — `Sidebar.tsx`:
136
- ```tsx
137
- const collapsedRef = useLatest(collapsed);
138
-
139
- useImperativeHandle(ref, () => ({
140
- toggle: () => handleCollapse(!collapsedRef.current),
141
- collapse: handleCollapse,
142
- }), [handleCollapse]);
143
- ```
144
-
145
- ---
146
-
147
- ### useMemoizedFn
148
-
149
- **When to use**: Render callbacks, complex handlers, or any function passed to children where you need a stable reference without a dependency array. Preferred over `useEventCallback` when the function is a render function or when you want zero dependency management.
150
-
151
- ```tsx
152
- import { useMemoizedFn } from '@1money/hooks';
153
-
154
- const renderIcon = useMemoizedFn(({ open }: { open: boolean }) =>
155
- collapsed ? null : <Icons name="chevronDown" />
156
- );
157
- ```
158
-
159
- **Real usage** — `Sidebar.tsx`:
160
- ```tsx
161
- const renderExpandIcon = useMemoizedFn(({ open }: { open: boolean }) =>
162
- collapsed ? null : <Icons name='chevronDown' size={20} />
163
- );
164
- ```
165
-
166
- **Real usage** — `CheckboxGroup.tsx`:
167
- ```tsx
168
- const handleNormalChange = useMemoizedFn((e: CheckboxChangeEvent, itemOnChange?: Callback) => {
169
- itemOnChange?.(!!e.checked);
170
- const next = e.checked
171
- ? [...checkedItems, e.value]
172
- : checkedItems.filter(k => k !== e.value);
173
- setCheckedItems(next);
174
- onChange?.(next);
175
- });
176
- ```
177
-
178
- ---
179
-
180
- ### useLayoutEffect (custom)
181
-
182
- **When to use**: When you need different logic for initial mount versus subsequent updates. The callback receives a `mount` boolean as its first argument.
183
-
184
- ```tsx
185
- import { useLayoutEffect } from '@1money/hooks';
186
-
187
- useLayoutEffect((mount) => {
188
- if (mount) {
189
- // setup without animation
190
- } else {
191
- // animate on update
192
- }
193
- }, [value]);
194
- ```
195
-
196
- > This is used internally by `useControlledState`. Use it directly only when mount/update distinction matters.
197
-
198
- ---
199
-
200
- ### usePrevious
201
-
202
- **When to use**: Comparing the current value with the value from the previous render.
203
-
204
- ```tsx
205
- import { usePrevious } from '@1money/hooks';
206
-
207
- const prevCount = usePrevious(count);
208
-
209
- useEffect(() => {
210
- if (prevCount !== undefined && count > prevCount) {
211
- // count increased
212
- }
213
- }, [count, prevCount]);
214
- ```
215
-
216
- ---
217
-
218
- ### useSafeState
219
-
220
- **When to use**: State that may be set in async callbacks (API calls, timers) where the component could unmount before the callback fires.
221
-
222
- ```tsx
223
- import { useSafeState } from '@1money/hooks';
224
-
225
- const [data, setData] = useSafeState<Data | null>(null);
226
-
227
- useEffect(() => {
228
- fetchData().then((result) => {
229
- setData(result); // no-op if unmounted
230
- });
231
- }, []);
232
- ```
233
-
234
- ---
235
-
236
- ### useSyncState
237
-
238
- **When to use**: When React batches updates but you need to read the very latest state synchronously (e.g., multiple `onTransitionEnd` events firing at once).
239
-
240
- ```tsx
241
- import { useSyncState } from '@1money/hooks';
242
-
243
- const [getCount, setCount] = useSyncState(0);
244
-
245
- const handleTransitionEnd = () => {
246
- setCount(getCount() + 1); // always reads latest
247
- };
248
- ```
249
-
250
- ---
251
-
252
- ### useUpdateEffect
253
-
254
- **When to use**: Run an effect only on updates, skipping the initial mount.
255
-
256
- ```tsx
257
- import { useUpdateEffect } from '@1money/hooks';
258
-
259
- useUpdateEffect(() => {
260
- onSearch(query); // only on query changes, not initial mount
261
- }, [query]);
262
- ```
263
-
264
- ---
265
-
266
- ### useLayoutState
267
-
268
- **When to use**: Batch multiple synchronous state updates into a single microtask render.
269
-
270
- ```tsx
271
- import { useLayoutState } from '@1money/hooks';
272
-
273
- const [widths, setWidths] = useLayoutState<Map<string, number>>(new Map());
274
-
275
- const handleResize = (key: string, width: number) => {
276
- setWidths(prev => new Map(prev).set(key, width));
277
- };
278
- ```
279
-
280
- ---
281
-
282
- ### useTimeoutLock
283
-
284
- **When to use**: Short-lived lock (100ms auto-reset) to prevent duplicate rapid actions.
285
-
286
- ```tsx
287
- import { useTimeoutLock } from '@1money/hooks';
288
-
289
- const [setLock, getLock] = useTimeoutLock<string>();
290
-
291
- const handleClick = () => {
292
- if (getLock()) return;
293
- setLock('submitting');
294
- submitForm();
295
- };
296
- ```
297
-
298
- ---
299
-
300
- ## Common Patterns
301
-
302
- ### Controlled/Uncontrolled + Event Handler (most common)
303
-
304
- ```tsx
305
- import { useControlledState, useEventCallback } from '@1money/hooks';
306
-
307
- export const MyComponent: FC<MyComponentProps> = props => {
308
- const { value, defaultValue, onChange, ...rest } = props;
309
-
310
- const [val, setVal] = useControlledState(defaultValue ?? '', value);
311
-
312
- const handleChange = useEventCallback((e: ChangeEvent<HTMLInputElement>) => {
313
- setVal(e.target.value);
314
- onChange?.(e);
315
- });
316
-
317
- return <input value={val} onChange={handleChange} {...rest} />;
318
- };
319
- ```
320
-
321
- ### Imperative Handle with Latest Ref
322
-
323
- ```tsx
324
- import { useLatest, useMemoizedFn } from '@1money/hooks';
325
-
326
- const stateRef = useLatest(someState);
327
-
328
- useImperativeHandle(ref, () => ({
329
- getValue: () => stateRef.current,
330
- doAction: useMemoizedFn(() => { /* uses stateRef.current */ }),
331
- }), []);
332
- ```
333
-
334
- ### Async Data Fetch with Safe State
335
-
336
- ```tsx
337
- import { useSafeState } from '@1money/hooks';
338
-
339
- const [loading, setLoading] = useSafeState(false);
340
- const [data, setData] = useSafeState<T | null>(null);
341
-
342
- useEffect(() => {
343
- setLoading(true);
344
- fetchData()
345
- .then(setData)
346
- .finally(() => setLoading(false));
347
- }, []);
348
- ```
349
-
350
- ---
351
-
352
- ## Hook Dependencies
353
-
354
- ```
355
- useEventCallback → uses useLatest
356
- useControlledState → uses useLayoutEffect (custom)
357
- useSyncState → uses useEventCallback
358
- ```
359
-
360
- Keep these dependencies in mind when debugging or testing components.
@@ -1,215 +0,0 @@
1
- # Semantic Colors Reference
2
-
3
- Complete key listing for all 4 semantic color domains accessed via `theme.palette()`. Source: `src/styles/tokens/color/_semantic-color.scss`.
4
-
5
- Usage: `theme.palette($domain, $token, $state?)` where `$domain` is one of `bg`, `text`, `icon`, `border`.
6
-
7
- Single-key calls like `theme.palette(bg, 'brand-hover')` and three-param calls like `theme.palette(bg, 'brand', 'hover')` are equivalent — the token and state are concatenated with a hyphen internally.
8
-
9
- ---
10
-
11
- ## `theme.palette(bg, ...)` — Background Colors (40 keys)
12
-
13
- | Key | Primitive | Group |
14
- |-----|-----------|-------|
15
- | `default` | white | Base |
16
- | `default-hover` | grey-100 | Base |
17
- | `default-secondary` | grey-50 | Base |
18
- | `default-secondary-hover` | grey-200 | Base |
19
- | `default-tertiary` | grey-200 | Base |
20
- | `default-tertiary-hover` | grey-300 | Base |
21
- | `disabled` | grey-100 | Disabled |
22
- | `disabled-brand` | blue-300 | Disabled |
23
- | `disabled-black` | black @ 10% | Disabled |
24
- | `brand` | blue-700 | Brand |
25
- | `brand-hover` | blue-800 | Brand |
26
- | `brand-secondary` | blue-100 | Brand |
27
- | `brand-secondary-hover` | blue-200 | Brand |
28
- | `brand-tertiary` | blue-50 | Brand |
29
- | `brand-tertiary-hover` | blue-100 | Brand |
30
- | `neutral` | grey-900 | Neutral |
31
- | `neutral-hover` | grey-800 | Neutral |
32
- | `neutral-secondary` | grey-200 | Neutral |
33
- | `neutral-secondary-hover` | grey-300 | Neutral |
34
- | `neutral-tertiary` | grey-100 | Neutral |
35
- | `neutral-tertiary-hover` | grey-200 | Neutral |
36
- | `positive` | green-700 | Positive |
37
- | `positive-hover` | green-800 | Positive |
38
- | `positive-secondary` | green-700 @ 10% | Positive |
39
- | `positive-secondary-hover` | green-700 @ 20% | Positive |
40
- | `positive-tertiary` | green-700 @ 5% | Positive |
41
- | `positive-tertiary-hover` | green-700 @ 10% | Positive |
42
- | `warning` | yellow-500 | Warning |
43
- | `warning-hover` | yellow-400 | Warning |
44
- | `warning-secondary` | yellow-500 @ 10% | Warning |
45
- | `warning-secondary-hover` | yellow-500 @ 20% | Warning |
46
- | `warning-tertiary` | yellow-500 @ 5% | Warning |
47
- | `warning-tertiary-hover` | yellow-500 @ 10% | Warning |
48
- | `danger` | red-600 | Danger |
49
- | `danger-hover` | red-700 | Danger |
50
- | `danger-secondary` | red-600 @ 10% | Danger |
51
- | `danger-secondary-hover` | red-600 @ 20% | Danger |
52
- | `danger-tertiary` | red-600 @ 5% | Danger |
53
- | `danger-tertiary-hover` | red-600 @ 10% | Danger |
54
-
55
- ---
56
-
57
- ## `theme.palette(text, ...)` — Text Colors (36 keys)
58
-
59
- | Key | Primitive | Group |
60
- |-----|-----------|-------|
61
- | `default` | grey-900 | Base |
62
- | `default-secondary` | grey-800 | Base |
63
- | `default-tertiary` | grey-700 | Base |
64
- | `disabled` | grey-400 | Disabled |
65
- | `disabled-black` | grey-400 | Disabled |
66
- | `disabled-white` | grey-50 | Disabled |
67
- | `brand` | blue-700 | Brand |
68
- | `brand-secondary` | blue-300 | Brand |
69
- | `brand-tertiary` | blue-200 | Brand |
70
- | `on-brand` | blue-100 | Brand (on) |
71
- | `on-brand-secondary` | blue-800 | Brand (on) |
72
- | `on-brand-tertiary` | blue-900 | Brand (on) |
73
- | `neutral` | grey-800 | Neutral |
74
- | `neutral-secondary` | grey-500 | Neutral |
75
- | `neutral-tertiary` | grey-400 | Neutral |
76
- | `on-neutral` | white | Neutral (on) |
77
- | `on-neutral-secondary` | grey-800 | Neutral (on) |
78
- | `on-neutral-tertiary` | grey-700 | Neutral (on) |
79
- | `positive` | green-700 | Positive |
80
- | `positive-secondary` | green-700 @ 20% | Positive |
81
- | `positive-tertiary` | green-700 @ 10% | Positive |
82
- | `on-positive` | green-700 @ 5% | Positive (on) |
83
- | `on-positive-secondary` | green-800 | Positive (on) |
84
- | `on-positive-tertiary` | green-900 | Positive (on) |
85
- | `warning` | yellow-700 | Warning |
86
- | `warning-secondary` | yellow-500 @ 20% | Warning |
87
- | `warning-tertiary` | yellow-500 @ 10% | Warning |
88
- | `on-warning` | yellow-500 @ 5% | Warning (on) |
89
- | `on-warning-secondary` | yellow-300 | Warning (on) |
90
- | `on-warning-tertiary` | yellow-700 | Warning (on) |
91
- | `danger` | red-600 | Danger |
92
- | `danger-secondary` | red-600 @ 20% | Danger |
93
- | `danger-tertiary` | red-600 @ 10% | Danger |
94
- | `on-danger` | red-600 @ 5% | Danger (on) |
95
- | `on-danger-secondary` | red-700 | Danger (on) |
96
- | `on-danger-tertiary` | red-800 | Danger (on) |
97
-
98
- ---
99
-
100
- ## `theme.palette(icon, ...)` — Icon Colors (36 keys)
101
-
102
- | Key | Primitive | Group |
103
- |-----|-----------|-------|
104
- | `default` | grey-900 | Base |
105
- | `default-secondary` | grey-800 | Base |
106
- | `default-tertiary` | grey-700 | Base |
107
- | `disabled` | grey-300 | Disabled |
108
- | `on-disabled` | grey-400 | Disabled |
109
- | `brand` | blue-700 | Brand |
110
- | `brand-secondary` | blue-300 | Brand |
111
- | `brand-tertiary` | blue-200 | Brand |
112
- | `on-brand` | blue-100 | Brand (on) |
113
- | `on-brand-secondary` | blue-800 | Brand (on) |
114
- | `on-brand-tertiary` | blue-900 | Brand (on) |
115
- | `neutral` | grey-800 | Neutral |
116
- | `neutral-secondary` | grey-500 | Neutral |
117
- | `neutral-tertiary` | grey-400 | Neutral |
118
- | `on-neutral` | white | Neutral (on) |
119
- | `on-neutral-secondary` | grey-800 | Neutral (on) |
120
- | `on-neutral-tertiary` | grey-700 | Neutral (on) |
121
- | `positive` | green-700 | Positive |
122
- | `positive-secondary` | green-700 @ 20% | Positive |
123
- | `positive-tertiary` | green-700 @ 10% | Positive |
124
- | `on-positive` | green-700 @ 5% | Positive (on) |
125
- | `on-positive-secondary` | green-800 | Positive (on) |
126
- | `on-positive-tertiary` | green-900 | Positive (on) |
127
- | `warning` | yellow-700 | Warning |
128
- | `warning-secondary` | yellow-500 | Warning |
129
- | `warning-tertiary` | yellow-500 @ 20% | Warning |
130
- | `on-warning` | yellow-500 @ 10% | Warning (on) |
131
- | `on-warning-secondary` | yellow-300 | Warning (on) |
132
- | `on-warning-tertiary` | yellow-700 | Warning (on) |
133
- | `danger` | red-600 | Danger |
134
- | `danger-secondary` | red-600 @ 20% | Danger |
135
- | `danger-tertiary` | red-600 @ 10% | Danger |
136
- | `on-danger` | red-600 @ 5% | Danger (on) |
137
- | `on-danger-secondary` | red-700 | Danger (on) |
138
- | `on-danger-tertiary` | red-800 | Danger (on) |
139
-
140
- ---
141
-
142
- ## `theme.palette(border, ...)` — Semantic Border Colors (19 keys)
143
-
144
- | Key | Primitive | Group |
145
- |-----|-----------|-------|
146
- | `default` | grey-300 | Base |
147
- | `default-secondary` | grey-500 | Base |
148
- | `default-tertiary` | grey-800 | Base |
149
- | `disabled` | grey-200 | Disabled |
150
- | `brand` | blue-700 | Brand |
151
- | `brand-secondary` | blue-300 | Brand |
152
- | `brand-tertiary` | blue-100 | Brand |
153
- | `neutral` | grey-200 | Neutral |
154
- | `neutral-secondary` | grey-100 | Neutral |
155
- | `neutral-tertiary` | grey-50 | Neutral |
156
- | `positive` | green-700 | Positive |
157
- | `positive-secondary` | green-700 @ 20% | Positive |
158
- | `positive-tertiary` | green-700 @ 10% | Positive |
159
- | `warning` | yellow-700 | Warning |
160
- | `warning-secondary` | yellow-500 | Warning |
161
- | `warning-tertiary` | yellow-500 @ 10% | Warning |
162
- | `danger` | red-600 | Danger |
163
- | `danger-secondary` | red-600 @ 10% | Danger |
164
- | `danger-tertiary` | red-600 @ 5% | Danger |
165
-
166
- ---
167
-
168
- ## Quick-Reference Tables
169
-
170
- For variant-specific token selection guidance (suffix rules, common component patterns, state pairing rules), see **`src/styles/README.md` → "Semantic Color Token Reference"** section. It provides lookup tables extracted from Button and Notification real-world usage.
171
-
172
- ---
173
-
174
- ## Common Patterns
175
-
176
- ### Button-like components
177
-
178
- ```scss
179
- // Primary variant
180
- color: theme.palette(text, 'on-neutral');
181
- background-color: theme.palette(bg, 'brand');
182
- &:hover:not(.p-disabled) { background-color: theme.palette(bg, 'brand-hover'); }
183
- &.p-disabled { color: theme.palette(text, 'disabled-white'); background-color: theme.palette(bg, 'disabled-brand'); }
184
-
185
- // Secondary variant
186
- color: theme.palette(text, 'brand');
187
- background-color: theme.palette(bg, 'brand-secondary');
188
- &:hover:not(.p-disabled) { background-color: theme.palette(bg, 'brand-secondary-hover'); }
189
-
190
- // Danger variant
191
- color: theme.palette(text, 'danger');
192
- background-color: theme.palette(bg, 'danger-secondary');
193
- &:hover:not(.p-disabled) { background-color: theme.palette(bg, 'danger-secondary-hover'); }
194
- ```
195
-
196
- ### Input-like components
197
-
198
- ```scss
199
- border-color: theme.palette(border, 'default');
200
- &:focus { border-color: theme.palette(border, 'brand'); }
201
- &.error { border-color: theme.palette(border, 'danger'); }
202
- &.p-disabled { border-color: theme.palette(border, 'disabled'); }
203
- ```
204
-
205
- ### Disabled states
206
-
207
- ```scss
208
- &.p-disabled {
209
- cursor: not-allowed;
210
- opacity: theme.opacity('disabled'); // if using opacity approach
211
- // OR use specific disabled color tokens:
212
- color: theme.palette(text, 'disabled');
213
- background-color: theme.palette(bg, 'disabled');
214
- }
215
- ```