@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.
- package/es/components/Table/interface.d.ts +2 -1
- package/es/components/Table/renderers/EmptyState.d.ts +2 -1
- package/es/components/Table/renderers/EmptyState.js +15 -8
- package/es/components/Table/style/Table.css +1 -1
- package/es/index.css +1 -1
- package/es/stories/docs/ComponentDocsPage.js +234 -0
- package/es/stories/docs/componentDocMeta.js +97 -0
- package/es/stories/docs/storybook-docs.css +79 -0
- package/lib/components/Table/interface.d.ts +2 -1
- package/lib/components/Table/renderers/EmptyState.d.ts +2 -1
- package/lib/components/Table/renderers/EmptyState.js +15 -7
- package/lib/components/Table/style/Table.css +1 -1
- package/lib/index.css +1 -1
- package/lib/stories/docs/ComponentDocsPage.js +244 -0
- package/lib/stories/docs/componentDocMeta.js +104 -0
- package/lib/stories/docs/storybook-docs.css +79 -0
- package/package.json +23 -8
- package/scripts/mcp-server/README.md +267 -0
- package/scripts/mcp-server/bin.mjs +2 -0
- package/scripts/mcp-server/drift.json +5 -0
- package/scripts/mcp-server/examples.generated.json +2651 -0
- package/scripts/mcp-server/index.generated.json +18098 -0
- package/scripts/mcp-server/index.mjs +308 -26
- package/scripts/mcp-server/tools/get-examples.mjs +125 -0
- package/scripts/mcp-server/tools/get-library-info.mjs +25 -0
- package/scripts/mcp-server/tools/get-symbol.mjs +232 -0
- package/scripts/mcp-server/tools/get-token.mjs +60 -0
- package/scripts/mcp-server/tools/list-icons.mjs +38 -0
- package/scripts/mcp-server/tools/list-symbols.mjs +46 -0
- package/scripts/mcp-server/tools/resolve-import.mjs +125 -0
- package/scripts/mcp-server/tools/search-symbols.mjs +79 -0
- package/.agents/skills/1money-component-dev/SKILL.md +0 -224
- package/.agents/skills/1money-component-dev/checklist.md +0 -159
- package/.agents/skills/1money-component-dev/references/ComponentPatterns.md +0 -478
- package/.agents/skills/1money-component-dev/references/FigmaExtractionChecklist.md +0 -144
- package/.agents/skills/1money-component-dev/references/HooksGuide.md +0 -360
- package/.agents/skills/1money-component-dev/references/SemanticColors.md +0 -215
- package/.agents/skills/1money-component-dev/references/StyleSystemAPI.md +0 -389
- package/.claude/settings.local.json +0 -120
- package/.claude/skills/1money-component-dev/SKILL.md +0 -229
- package/.claude/skills/1money-component-dev/checklist.md +0 -159
- package/.claude/skills/1money-component-dev/references/ComponentPatterns.md +0 -478
- package/.claude/skills/1money-component-dev/references/FigmaExtractionChecklist.md +0 -144
- package/.claude/skills/1money-component-dev/references/HooksGuide.md +0 -360
- package/.claude/skills/1money-component-dev/references/SemanticColors.md +0 -215
- package/.claude/skills/1money-component-dev/references/StyleSystemAPI.md +0 -389
- package/.claude/skills/1money-component-review/SKILL.md +0 -316
- package/.claude/skills/component-pipeline/SKILL.md +0 -116
- package/.claude/skills/component-pipeline/checklist.md +0 -125
- package/.hintrc +0 -13
- package/@types/global.d.ts +0 -28
- package/AGENTS.md +0 -546
- package/CLAUDE.md +0 -1
- package/jest.setup.d.ts +0 -1
- package/jest.setup.ts +0 -1
- package/patches/primereact.patch +0 -323
- package/patches/react-pro-sidebar.patch +0 -6421
- package/public/favicon.ico +0 -0
- package/public/fonts/Aeonik/Aeonik-Air.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-AirItalic.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-Black.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-BlackItalic.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-Bold.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-BoldItalic.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-Light.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-LightItalic.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-Medium.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-MediumItalic.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-Regular.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-RegularItalic.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-Thin.ttf +0 -0
- package/public/fonts/Aeonik/Aeonik-ThinItalic.ttf +0 -0
- package/public/fonts/Inter/Inter-Black.ttf +0 -0
- package/public/fonts/Inter/Inter-BlackItalic.ttf +0 -0
- package/public/fonts/Inter/Inter-Bold.ttf +0 -0
- package/public/fonts/Inter/Inter-BoldItalic.ttf +0 -0
- package/public/fonts/Inter/Inter-ExtraBold.ttf +0 -0
- package/public/fonts/Inter/Inter-ExtraBoldItalic.ttf +0 -0
- package/public/fonts/Inter/Inter-ExtraLight.ttf +0 -0
- package/public/fonts/Inter/Inter-ExtraLightItalic.ttf +0 -0
- package/public/fonts/Inter/Inter-Italic.ttf +0 -0
- package/public/fonts/Inter/Inter-Light.ttf +0 -0
- package/public/fonts/Inter/Inter-LightItalic.ttf +0 -0
- package/public/fonts/Inter/Inter-Medium.ttf +0 -0
- package/public/fonts/Inter/Inter-MediumItalic.ttf +0 -0
- package/public/fonts/Inter/Inter-Regular.ttf +0 -0
- package/public/fonts/Inter/Inter-SemiBold.ttf +0 -0
- package/public/fonts/Inter/Inter-SemiBoldItalic.ttf +0 -0
- package/public/fonts/Inter/Inter-Thin.ttf +0 -0
- package/public/fonts/Inter/Inter-ThinItalic.ttf +0 -0
- package/public/fonts/Outfit/Outfit-Black.ttf +0 -0
- package/public/fonts/Outfit/Outfit-Bold.ttf +0 -0
- package/public/fonts/Outfit/Outfit-ExtraBold.ttf +0 -0
- package/public/fonts/Outfit/Outfit-ExtraLight.ttf +0 -0
- package/public/fonts/Outfit/Outfit-Light.ttf +0 -0
- package/public/fonts/Outfit/Outfit-Medium.ttf +0 -0
- package/public/fonts/Outfit/Outfit-Regular.ttf +0 -0
- package/public/fonts/Outfit/Outfit-SemiBold.ttf +0 -0
- package/public/fonts/Outfit/Outfit-Thin.ttf +0 -0
- package/public/github-mark.svg +0 -3
- package/public/tokens/GYEN.svg +0 -9
- package/public/tokens/PYUSD.svg +0 -9
- package/public/tokens/USDT.svg +0 -6
- package/scripts/mcp-server/resources.d.mts +0 -1
- package/scripts/mcp-server/resources.mjs +0 -102
- package/test/jsdom-global-register.d.ts +0 -1
- 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
|
-
```
|