@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,389 +0,0 @@
1
- # Style System API Reference
2
-
3
- Internal SCSS authoring reference for `@1money/components-ui` component development.
4
-
5
- ## Import
6
-
7
- ```scss
8
- @use '@/styles/api' as theme;
9
- @use '@/styles/recipes/variants' as variants;
10
- ```
11
-
12
- Components use **namespaced** imports:
13
- - `theme.*` for all token functions, semantic helpers, typography mixins, and responsive mixins
14
- - `variants.*` for the Variant DSL helpers
15
- - `theme.$prefix` for the BEM prefix (`om-react-ui`)
16
-
17
- ---
18
-
19
- ## Token Functions
20
-
21
- ### `theme.spacing($domain, $key)` — Spacing
22
-
23
- Domain determines the spacing group. Available domains: `scale`, `gap`, `component-padding`, `section-padding`.
24
-
25
- #### `theme.spacing(scale, $key)` — Raw Spacing Scale
26
-
27
- | Key | Value |
28
- |-----|-------|
29
- | `0` | 0 |
30
- | `100` | 4px |
31
- | `200` | 8px |
32
- | `300` | 12px |
33
- | `400` | 16px |
34
- | `500` | 20px |
35
- | `600` | 24px |
36
- | `800` | 32px |
37
- | `1000` | 40px |
38
- | `1200` | 48px |
39
- | `1400` | 56px |
40
- | `1600` | 64px |
41
- | `2000` | 80px |
42
- | `2400` | 96px |
43
- | `3200` | 128px |
44
- | `4000` | 160px |
45
-
46
- ```scss
47
- .element { padding: theme.spacing(scale, 400); } // 16px
48
- ```
49
-
50
- #### `theme.spacing(gap, $key)` — Gap Spacing
51
-
52
- Allowed keys: `050`, `100`, `200`, `300`, `400`, `600`, `1600`
53
-
54
- ```scss
55
- .stack { gap: theme.spacing(gap, 400); } // 16px
56
- ```
57
-
58
- #### `theme.spacing(component-padding, $key)` — Component Internal Padding
59
-
60
- Allowed keys: `050`, `100`, `200`, `300`, `400`, `600`, `800`
61
-
62
- ```scss
63
- .button { padding: theme.spacing(component-padding, 400); }
64
- ```
65
-
66
- #### `theme.spacing(section-padding, $key)` — Page Section Padding
67
-
68
- Allowed keys: `800`, `1600`, `2400`, `4000`
69
-
70
- ```scss
71
- .section { padding: theme.spacing(section-padding, 1600); }
72
- ```
73
-
74
- ### `theme.shape($key)` — Border Radius
75
-
76
- | Key | Value |
77
- |-----|-------|
78
- | `0` | 0 |
79
- | `100` | 4px |
80
- | `200` | 8px |
81
- | `300` | 12px |
82
- | `400` | 16px |
83
- | `600` | 24px |
84
- | `full` | 9999px |
85
-
86
- ```scss
87
- .element { border-radius: theme.shape(300); } // 12px
88
- .pill { border-radius: theme.shape('full'); } // 9999px
89
- ```
90
-
91
- ### `theme.shadows($key)` — Box Shadow
92
-
93
- | Key | Value |
94
- |-----|-------|
95
- | `0` | none |
96
- | `100` | `0 4px 8px rgba(65, 91, 130, 12%)` |
97
- | `200` | `0 10px 22px rgba(0, 0, 0, 10%)` |
98
-
99
- ```scss
100
- .element { box-shadow: theme.shadows(100); }
101
- ```
102
-
103
- ### `theme.sizing($domain, $key)` — Sizing
104
-
105
- Domain determines the sizing group. Available domains: `scale`, `component-height`.
106
-
107
- #### `theme.sizing(scale, $key)` — Percentage Sizing
108
-
109
- | Key | Value |
110
- |-----|-------|
111
- | `25` | 25% |
112
- | `33` | 33.333% |
113
- | `50` | 50% |
114
- | `66` | 66.667% |
115
- | `75` | 75% |
116
- | `100` | 100% |
117
- | `auto` | auto |
118
-
119
- #### `theme.sizing(component-height, $key)` — Component Heights
120
-
121
- Standardized heights for interactive elements.
122
-
123
- | Key | Value | Use case |
124
- |-----|-------|----------|
125
- | `xs` | 24px | Badge, small chips |
126
- | `sm` | 32px | Small button, icon button |
127
- | `md` | 40px | Medium button, sidebar items |
128
- | `lg` | 44px | Small input/select |
129
- | `xl` | 48px | Cell, stepper step |
130
- | `2xl` | 52px | Default button |
131
- | `3xl` | 56px | Default input/select |
132
-
133
- ```scss
134
- .button { height: theme.sizing(component-height, 'md'); } // 40px
135
- .icon-circle { width: theme.sizing(component-height, 'sm'); height: theme.sizing(component-height, 'sm'); } // 32px
136
- ```
137
-
138
- ### `theme.opacity($key)` — Opacity
139
-
140
- | Key | Value |
141
- |-----|-------|
142
- | `subtle` | 0.05 |
143
- | `light` | 0.1 |
144
- | `medium` | 0.2 |
145
- | `disabled-light` | 0.3 |
146
- | `overlay` | 0.4 |
147
- | `disabled` | 0.5 |
148
- | `disabled-heavy` | 0.6 |
149
-
150
- ```scss
151
- .disabled { opacity: theme.opacity('disabled'); } // 0.5
152
- ```
153
-
154
- ---
155
-
156
- ## Semantic Color Functions
157
-
158
- ### `theme.palette($domain, $token, $state?)` — All Color Domains
159
-
160
- A single function handles all four color domains: `bg`, `text`, `icon`, `border`.
161
-
162
- When called with three arguments, `$token` and `$state` are concatenated with a hyphen (e.g., `theme.palette(bg, 'brand', 'hover')` → resolves key `'brand-hover'`). When called with two arguments, `$token` is used as the key directly.
163
-
164
- ```scss
165
- // Background colors
166
- .card { background-color: theme.palette(bg, 'brand'); }
167
- .card:hover { background-color: theme.palette(bg, 'brand-hover'); }
168
- .card:hover { background-color: theme.palette(bg, 'brand', 'hover'); } // equivalent
169
-
170
- // Text colors
171
- .label { color: theme.palette(text, 'default'); }
172
- .label-muted { color: theme.palette(text, 'default-tertiary'); }
173
- .on-dark { color: theme.palette(text, 'on-neutral'); }
174
-
175
- // Icon colors
176
- .icon { color: theme.palette(icon, 'default'); }
177
- .icon-brand { color: theme.palette(icon, 'brand'); }
178
-
179
- // Border colors
180
- .input { border-color: theme.palette(border, 'default'); }
181
- .input:focus { border-color: theme.palette(border, 'brand'); }
182
- .input.error { border-color: theme.palette(border, 'danger'); }
183
- ```
184
-
185
- See `SemanticColors.md` for the complete key list for each domain.
186
-
187
- ---
188
-
189
- ## Typography
190
-
191
- All typography tokens are emitted as CSS custom properties under `:root`, enabling runtime theme overrides:
192
-
193
- ```css
194
- --om-body-md-font-size: 14px;
195
- --om-body-md-line-height: 19.6px;
196
- --om-body-md-font-weight: 400;
197
- --om-body-md-strong-font-weight: 500;
198
- --om-link-md-text-decoration: underline;
199
- ```
200
-
201
- Variable naming: `--om-{category}-{size}-{property}`
202
-
203
- ### `@include theme.typography($category, $size, [$strong: false])`
204
-
205
- Emits all CSS properties as `var()` references: `font-family`, `font-size`, `line-height`, `letter-spacing`, `font-weight`.
206
-
207
- ```scss
208
- .body { @include theme.typography(body, md); }
209
- // Compiles to:
210
- // font-size: var(--om-body-md-font-size);
211
- // font-family: var(--om-body-md-font-family);
212
- // line-height: var(--om-body-md-line-height);
213
- // letter-spacing: var(--om-body-md-letter-spacing);
214
- // font-weight: var(--om-body-md-font-weight);
215
-
216
- .body-bold { @include theme.typography(body, md, $strong: true); }
217
- // font-weight: var(--om-body-md-strong-font-weight);
218
-
219
- .link { @include theme.typography(link, md); }
220
- // Also emits: text-decoration: var(--om-link-md-text-decoration);
221
- ```
222
-
223
- ### Categories & Sizes
224
-
225
- | Category | Sizes | Font | Strong weight |
226
- |----------|-------|------|---------------|
227
- | `display` | `xl`, `lg`, `md`, `sm`, `xs` | Aeonik | -- |
228
- | `headline` | `lg`, `md`, `sm`, `xs` | Aeonik | -- |
229
- | `title` | `lg`, `md`, `sm` | Inter | 700 |
230
- | `body` | `lg`, `md`, `sm` | Inter | 500 |
231
- | `link` | `md`, `sm` | Inter | -- |
232
- | `label` | `xl`, `lg`, `md`, `sm`, `xs` | Inter | 600-700 |
233
-
234
- ---
235
-
236
- ## Responsive Mixins
237
-
238
- Mobile-first breakpoint helpers using `max-width` media queries.
239
-
240
- ### `@include theme.down($breakpoint)`
241
-
242
- | Breakpoint | Max-width |
243
- |------------|-----------|
244
- | `lg` | 1279.98px |
245
- | `md` | 1023.98px |
246
- | `sm` | 767.98px |
247
-
248
- ```scss
249
- .sidebar {
250
- width: 280px;
251
- @include theme.down(md) { width: 200px; }
252
- @include theme.down(sm) { display: none; }
253
- }
254
- ```
255
-
256
- ### Other Responsive Mixins
257
-
258
- ```scss
259
- @include theme.up($bp) // min-width
260
- @include theme.between($lo, $hi) // min-width and max-width
261
- @include theme.only($bp) // exact range for one breakpoint
262
- @include theme.respond($bp) // alias for theme.down
263
- ```
264
-
265
- ---
266
-
267
- ## Variant DSL
268
-
269
- Use the variant helpers when a component has multiple color/status modifiers that differ only by a set of token values. The DSL eliminates repetitive `&-{variant}` blocks by declaring a schema once and generating all modifier classes automatically.
270
-
271
- **Import**: `@use '@/styles/recipes/variants' as variants;`
272
-
273
- ### Concepts
274
-
275
- 1. **Schema** — maps CSS custom property names to token keys inside each variant payload. Use `variants.om-variant-schema($component, $keys...)` to auto-generate this from the component name and key list.
276
- 2. **Variants map** — keyed by string variant names, each value is a token map matching the schema
277
- 3. **Mixins** — `variants.om-variant-default` sets the base, `variants.om-variant-classes` generates all modifier classes
278
-
279
- ### Basic Example
280
-
281
- ```scss
282
- @use '@/styles/api' as theme;
283
- @use '@/styles/recipes/variants' as variants;
284
-
285
- $component: 'badge';
286
- // Auto-generates: (--om-badge-text: text, --om-badge-bg: bg)
287
- $badge-variant-schema: variants.om-variant-schema($component, text, bg);
288
-
289
- $badge-variants: (
290
- 'info': (
291
- text: theme.palette(text, 'brand'),
292
- bg: theme.palette(bg, 'brand-secondary'),
293
- ),
294
- 'danger': (
295
- text: theme.palette(text, 'danger'),
296
- bg: theme.palette(bg, 'danger-secondary'),
297
- ),
298
- );
299
-
300
- .#{theme.$prefix}-#{$component} {
301
- // Set default variant values + validate all variants against schema
302
- @include variants.om-variant-default($badge-variants, 'info', $badge-variant-schema);
303
-
304
- color: var(--om-badge-text);
305
- background-color: var(--om-badge-bg);
306
-
307
- // Generate modifier classes, skipping 'info' (already set as default)
308
- @include variants.om-variant-classes($badge-variants, $badge-variant-schema, $default: 'info');
309
- }
310
- ```
311
-
312
- ### Extending a Base Variant
313
-
314
- Use `variants.om-variant-extend` when variants share a common base:
315
-
316
- ```scss
317
- $base: (
318
- text: theme.palette(text, 'default'),
319
- bg: theme.palette(bg, 'default'),
320
- hover-bg: theme.palette(bg, 'default-hover'),
321
- );
322
-
323
- $variants: (
324
- 'default': $base,
325
- 'active': variants.om-variant-extend($base, (
326
- bg: theme.palette(bg, 'brand'),
327
- hover-bg: theme.palette(bg, 'brand-hover'),
328
- )),
329
- );
330
- ```
331
-
332
- ### Available Helpers
333
-
334
- | Helper | Description |
335
- |--------|-------------|
336
- | `variants.om-variant-schema($component, $keys...)` | Auto-generates a schema map from component name + token key list |
337
- | `variants.om-variant($variants, $name)` | Returns a variant token map; errors on unknown names |
338
- | `variants.om-variant-value($tokens, $key)` | Returns a token value; errors on missing keys |
339
- | `variants.om-variant-extend($base, $overrides)` | Creates a new variant by merging overrides into a base |
340
- | `@include variants.om-variant-apply($schema, $tokens)` | Emits CSS declarations for one variant payload |
341
- | `@include variants.om-variant-default($variants, $name, $schema)` | Validates all variants against schema, then applies the default |
342
- | `@include variants.om-variant-classes($variants, $schema, $default, $selector-prefix)` | Validates and generates modifier classes; `$default` skips the default variant |
343
-
344
- ### Compile-Time Safety
345
-
346
- Both `variants.om-variant-default` and `variants.om-variant-classes` validate that every variant contains all token keys required by the schema. A missing key triggers a Sass `@error` at build time.
347
-
348
- ### Naming Conventions
349
-
350
- - Schema variable: `$component-variant-schema`
351
- - Variants map: `$component-variants`
352
- - Individual variant (if extracted): `$component-{name}-variant`
353
- - Always quote variant names: `'white'`, `'black'`, `'grey'` (prevents Sass color literal issues)
354
-
355
- ---
356
-
357
- ## Architecture
358
-
359
- The style system has three layers:
360
-
361
- 1. **Tokens** (`src/styles/tokens/`): Raw primitives — colors, spacing multipliers, font sizes, scale maps
362
- 2. **Theme** (`src/styles/theme/`): Functions that resolve tokens to CSS variables or raw values, breakpoint mixins, typography mixin
363
- 3. **System** (`src/styles/system/`): The `om-sx` mixin — a compact shorthand API for layout (used in business code, **not** in component SCSS)
364
-
365
- All three layers are exposed through the `@use '@/styles/api' as theme;` import (namespaced under `theme`).
366
-
367
- The Variant DSL lives in `src/styles/recipes/` and is imported separately: `@use '@/styles/recipes/variants' as variants;`.
368
-
369
- ---
370
-
371
- ## Quick Decision Table
372
-
373
- | Figma concept | SCSS function |
374
- |---------------|---------------|
375
- | Background fill | `theme.palette(bg, 'key')` |
376
- | Text color | `theme.palette(text, 'key')` |
377
- | Icon color | `theme.palette(icon, 'key')` |
378
- | Border color | `theme.palette(border, 'key')` |
379
- | Padding/margin | `theme.spacing(scale, key)` or `theme.spacing(component-padding, key)` |
380
- | Gap between items | `theme.spacing(gap, key)` |
381
- | Section padding | `theme.spacing(section-padding, key)` |
382
- | Corner radius | `theme.shape(key)` |
383
- | Box shadow/elevation | `theme.shadows(key)` |
384
- | Component height | `theme.sizing(component-height, key)` |
385
- | Font styles | `@include theme.typography(cat, size)` |
386
- | Opacity/disabled | `theme.opacity(key)` |
387
- | Width/height % | `theme.sizing(scale, key)` |
388
- | Responsive breakpoint | `@include theme.down(bp)` |
389
- | Multi-variant color scheme | Variant DSL: `variants.om-variant-default` + `variants.om-variant-classes` |
@@ -1,316 +0,0 @@
1
- ---
2
- name: 1money-component-review
3
- description: Review an existing component against its Figma design for pixel-perfect fidelity. Takes a Figma URL and component name, performs a property-by-property comparison, and outputs a detailed checklist table.
4
- metadata:
5
- short-description: Review component design fidelity against Figma
6
- ---
7
-
8
- # 1money-component-review
9
-
10
- ## Activation
11
-
12
- **Act when**: User invokes `/1money-component-review` with a Figma URL and component name to verify design fidelity.
13
- **Goal**: Compare the implemented component against the Figma design source-of-truth, checking every visual property, and output a structured table showing pass/fail status for each item.
14
-
15
- ## Inputs
16
-
17
- - **Figma URL** (required): The Figma design link for the component to review.
18
- - **Component Name** (required): PascalCase name of the existing component in `src/components/`.
19
-
20
- ## Workflow
21
-
22
- ```dot
23
- digraph review {
24
- "Phase 1:\nValidate Inputs" -> "Phase 2:\nExtract Figma Design";
25
- "Phase 2:\nExtract Figma Design" -> "Phase 3:\nRead Component Code";
26
- "Phase 3:\nRead Component Code" -> "Phase 4:\nProperty-by-Property Comparison";
27
- "Phase 4:\nProperty-by-Property Comparison" -> "Phase 5:\nOutput Review Table";
28
- "Phase 5:\nOutput Review Table" -> "Phase 6:\nSummary & Recommendations";
29
- }
30
- ```
31
-
32
- ### Phase 1 — Validate Inputs
33
-
34
- 1. Confirm the component exists at `src/components/{Name}/`.
35
- 2. Parse the Figma URL to extract `fileKey` and `nodeId`.
36
- 3. If either input is missing, ask the user before proceeding.
37
-
38
- ### Phase 2 — Extract Figma Design
39
-
40
- Extract all design data from Figma using MCP tools:
41
-
42
- 1. **`mcp__figma__get_design_context(nodeId, fileKey)`** — Get code hints and structure.
43
- 2. **`mcp__figma__get_screenshot(nodeId, fileKey)`** — Get visual screenshot for layout/spacing reference.
44
- 3. **`mcp__figma__get_variable_defs(nodeId, fileKey)`** — Get design tokens (colors, spacing, radii, typography).
45
-
46
- From the extracted data, build a **Design Spec** covering:
47
- - All color values (background, text, icon, border) per variant and state
48
- - Spacing values (padding, gap, margin)
49
- - Typography (font family, size, weight, line-height)
50
- - Border radius
51
- - Shadows
52
- - Component heights/widths
53
- - Icon usage and sizes
54
- - All variants (color, size, state)
55
- - Layout structure (flex direction, alignment, gap)
56
-
57
- ### Phase 3 — Read Component Code
58
-
59
- Read all component files:
60
-
61
- 1. `src/components/{Name}/{Name}.tsx` — Component logic and structure
62
- 2. `src/components/{Name}/interface.ts` — Props interface
63
- 3. `src/components/{Name}/style/{Name}.scss` — Styles
64
- 4. `src/components/{Name}/{Name}.stories.tsx` — Stories (if exists)
65
-
66
- Also read the token source files for color verification:
67
-
68
- 5. `src/styles/tokens/color/_semantic-color.scss` — Semantic token → primitive mapping
69
- 6. `src/styles/tokens/color/_primitives.scss` — Primitive → hex value definitions
70
-
71
- Extract the **Implementation Spec**:
72
- - All token function calls (`theme.palette()`, `theme.spacing()`, `theme.shape()`, `theme.typography()`, `theme.sizing()`, `theme.shadows()`)
73
- - CSS custom properties and variant DSL values
74
- - Variant names and their token mappings
75
- - State handling (hover, disabled, active, focus)
76
- - Layout properties (display, flex, gap, alignment)
77
- - Icon components used and their props
78
-
79
- ### Phase 4 — Property-by-Property Comparison
80
-
81
- Compare each design property against the implementation. Check every item in these categories:
82
-
83
- #### 4.1 Colors (per variant, per state)
84
-
85
- **CRITICAL: Token-to-Hex Verification**
86
-
87
- Never mark a color as ✅ or ⚠️ based on token name alone. For every color comparison, you MUST complete the full verification chain:
88
-
89
- 1. Get the Figma hex value (from `get_variable_defs` or design context CSS variables)
90
- 2. Identify the SCSS token used in code (e.g., `theme.palette(icon, 'neutral-secondary')`)
91
- 3. Trace the token through `src/styles/tokens/color/_semantic-color.scss` to find the primitive reference (e.g., `p.$grey-500`)
92
- 4. Resolve the primitive in `src/styles/tokens/color/_primitives.scss` to get the actual hex value (e.g., `$grey-500: #9fa3a3`)
93
- 5. Compare the resolved hex against the Figma hex — mark ✅ if they match, ❌ if they don't
94
-
95
- In the review table, always include the resolved hex value:
96
- ```
97
- | Icon color | info | #073387 | `theme.palette(icon, 'brand')` → `$blue-700` → #073387 | ✅ |
98
- | Close icon | all | #646465 | `theme.palette(icon, 'neutral-secondary')` → `$grey-500` → #9fa3a3 | ❌ |
99
- ```
100
-
101
- For each variant × state combination:
102
- - [ ] Background color matches Figma (verified via hex)
103
- - [ ] Text color matches Figma (verified via hex)
104
- - [ ] Icon color matches Figma (verified via hex)
105
- - [ ] Border color matches Figma (verified via hex, if applicable)
106
-
107
- #### 4.2 Typography
108
-
109
- Check in two steps:
110
-
111
- **Step 1 — Extract Figma text style name** (e.g., `Headline(Beta)/Small`, `Body(Beta)/Large`, `Title(Beta)/Medium Strong`)
112
-
113
- **Step 2 — Verify `<Typography>` component usage and mapping**
114
-
115
- All text rendering MUST use the `Typography` compound component (`@/components/Typography`). The component exposes sub-components per category: `Typography.Display`, `Typography.Headline`, `Typography.Title`, `Typography.Body`, `Typography.Label`, `Typography.Link`.
116
-
117
- If the Figma text style maps correctly to the right `Typography.*` sub-component + `size` prop, the font properties (family, size, weight, line-height) are automatically correct — no need to check pixel values individually.
118
-
119
- Figma style → Typography component mapping:
120
-
121
- | Figma Text Style | Typography Component | Props |
122
- |---|---|---|
123
- | `Display(Beta)/XL` | `<Typography.Display size="xl">` | |
124
- | `Display(Beta)/Large` | `<Typography.Display size="lg">` | |
125
- | `Display(Beta)/Medium` | `<Typography.Display size="md">` | |
126
- | `Display(Beta)/Small` | `<Typography.Display size="sm">` | |
127
- | `Display(Beta)/XS` | `<Typography.Display size="xs">` | |
128
- | `Headline(Beta)/Large` | `<Typography.Headline size="lg">` | |
129
- | `Headline(Beta)/Medium` | `<Typography.Headline size="md">` | |
130
- | `Headline(Beta)/Small` | `<Typography.Headline size="sm">` | |
131
- | `Headline(Beta)/XS` | `<Typography.Headline size="xs">` | |
132
- | `Title(Beta)/Large` | `<Typography.Title size="lg">` | |
133
- | `Title(Beta)/Medium` | `<Typography.Title size="md">` | |
134
- | `Title(Beta)/Medium Strong` | `<Typography.Title size="md" strong>` | `strong` |
135
- | `Title(Beta)/Small` | `<Typography.Title size="sm">` | |
136
- | `Body(Beta)/Large` | `<Typography.Body size="lg">` | |
137
- | `Body(Beta)/Medium` | `<Typography.Body size="md">` | |
138
- | `Body(Beta)/Small` | `<Typography.Body size="sm">` | |
139
- | `Label(Beta)/XL` | `<Typography.Label size="xl">` | |
140
- | `Label(Beta)/Large` | `<Typography.Label size="lg">` | |
141
- | `Label(Beta)/Medium` | `<Typography.Label size="md">` | |
142
- | `Label(Beta)/Small` | `<Typography.Label size="sm">` | |
143
- | `Label(Beta)/XS` | `<Typography.Label size="xs">` | |
144
- | `Link(Beta)/Medium` | `<Typography.Link size="md">` | |
145
- | `Link(Beta)/Small` | `<Typography.Link size="sm">` | |
146
-
147
- Additional Typography props to check:
148
-
149
- - `color` — maps to `TypographyColor` (e.g., `"default"`, `"default-secondary"`, `"brand"`, `"disabled"`)
150
- - `strong` — only available on `Typography.Title`, `Typography.Body`, `Typography.Label`
151
- - `as` — override the HTML tag (e.g., `as="h2"` for semantic heading)
152
-
153
- Checklist:
154
-
155
- - [ ] All text elements use `Typography.*` sub-components — no raw `<p>`, `<span>`, `<h1>`–`<h6>`, or `<div>` for text rendering
156
- - [ ] No SCSS `@include theme.typography(...)` used directly — typography is handled by `Typography.*` components, not SCSS
157
- - [ ] Each text element uses the correct `Typography.*` sub-component matching the Figma text style category (Display/Headline/Title/Body/Label/Link)
158
- - [ ] Each `size` prop matches the corresponding Figma text style size
159
- - [ ] `strong` prop is set when Figma uses a Strong/Bold variant (e.g., `Title(Beta)/Medium Strong`)
160
- - [ ] `color` prop matches the Figma text color token (e.g., Text/Default/Default → `color="default"`)
161
- - [ ] If Figma text style cannot be mapped to a known Typography variant, flag as ❌
162
-
163
- #### 4.3 Spacing
164
-
165
- - [ ] Padding top/right/bottom/left matches
166
- - [ ] Gap between children matches
167
- - [ ] Margin matches (if applicable)
168
-
169
- #### 4.4 Visual Properties
170
-
171
- - [ ] Border radius matches
172
- - [ ] Box shadow matches
173
- - [ ] Opacity matches (if applicable)
174
- - [ ] Border width and style matches (if applicable)
175
-
176
- #### 4.5 Sizing
177
-
178
- - [ ] Component height matches (per size variant)
179
- - [ ] Component width matches (if fixed)
180
- - [ ] Icon size matches
181
- - [ ] Min/max constraints match
182
-
183
- #### 4.6 Layout
184
-
185
- - [ ] Flex direction matches
186
- - [ ] Alignment (align-items, justify-content) matches
187
- - [ ] Element ordering matches
188
-
189
- #### 4.7 States
190
-
191
- - [ ] Default state matches
192
- - [ ] Hover state matches
193
- - [ ] Disabled state matches
194
- - [ ] Active/pressed state matches (if applicable)
195
- - [ ] Focus state matches (if applicable)
196
- - [ ] Selected/checked state matches (if applicable)
197
-
198
- #### 4.8 Variants Coverage
199
-
200
- - [ ] All Figma variants are implemented
201
- - [ ] No extra variants exist that aren't in Figma
202
- - [ ] Default variant matches Figma default
203
-
204
- #### 4.9 Icons
205
-
206
- - [ ] Correct icon names used
207
- - [ ] Icon sizes match Figma
208
- - [ ] Icon colors match per variant/state
209
-
210
- ### Phase 5 — Output Review Table
211
-
212
- Present results as a detailed Markdown table. Use these status markers:
213
-
214
- | Marker | Meaning |
215
- |--------|---------|
216
- | ✅ | Matches Figma exactly |
217
- | ⚠️ | Close but has minor deviation |
218
- | ❌ | Does not match / missing |
219
- | ➖ | Not applicable |
220
-
221
- **Output format:**
222
-
223
- ```markdown
224
- ## Design Review: {ComponentName}
225
-
226
- ### Colors
227
-
228
- | Property | Variant | State | Figma Value | Implementation | Token Used | Status |
229
- |----------|---------|-------|-------------|----------------|------------|--------|
230
- | Background | primary | default | #1D4ED8 | `theme.palette(bg, 'brand')` → blue-700 | `bg-brand` | ✅ |
231
- | Background | primary | hover | #1E40AF | `theme.palette(bg, 'brand-hover')` → blue-800 | `bg-brand-hover` | ✅ |
232
- | Text | primary | default | #FFFFFF | `theme.palette(text, 'on-brand')` | `text-on-brand` | ✅ |
233
-
234
- ### Typography
235
-
236
- | 文本元素 | Figma 样式 | 期望组件 | 实际实现 | 使用 Typography | 状态 |
237
- |----------|-----------|---------|----------|----------------|------|
238
- | 标题 | `Headline(Beta)/Small` | `<Typography.Headline size="sm">` | `<Typography.Headline size="sm">` | ✅ | ✅ |
239
- | 内容 | `Body(Beta)/Large` | `<Typography.Body size="lg">` | `<span>` (原生标签) | ❌ | ❌ |
240
-
241
- ### Spacing
242
-
243
- | Property | Variant/Size | Figma Value | Implementation | Token Used | Status |
244
- |----------|-------------|-------------|----------------|------------|--------|
245
- | Padding H | medium | 16px | `theme.spacing(component-padding, 400)` | `cp-400` | ✅ |
246
- | Gap | all | 8px | `theme.spacing(gap, 200)` | `gap-200` | ✅ |
247
-
248
- ### Visual Properties
249
-
250
- | Property | Figma Value | Implementation | Token Used | Status |
251
- |----------|-------------|----------------|------------|--------|
252
- | Border Radius | 12px | `theme.shape(300)` | `shape-300` | ✅ |
253
- | Shadow | none | none | — | ✅ |
254
-
255
- ### Sizing
256
-
257
- | Property | Variant/Size | Figma Value | Implementation | Token Used | Status |
258
- |----------|-------------|-------------|----------------|------------|--------|
259
- | Height | medium | 40px | `theme.sizing(component-height, md)` | `ch-md` | ✅ |
260
-
261
- ### States
262
-
263
- | State | Variant | Property | Figma | Implementation | Status |
264
- |-------|---------|----------|-------|----------------|--------|
265
- | hover | primary | bg | blue-800 | `bg-brand-hover` | ✅ |
266
- | disabled | primary | bg | grey-100 | `bg-disabled` | ✅ |
267
- | disabled | primary | cursor | not-allowed | `cursor: not-allowed` | ✅ |
268
-
269
- ### Variants Coverage
270
-
271
- | Figma Variant | Implemented | Status |
272
- |---------------|------------|--------|
273
- | primary | yes | ✅ |
274
- | secondary | yes | ✅ |
275
- | ghost | no | ❌ |
276
-
277
- ### Icons
278
-
279
- | Icon Slot | Figma Icon | Implementation | Size Match | Color Match | Status |
280
- |-----------|-----------|----------------|------------|-------------|--------|
281
- | iconStart | arrow-left | `<Icons name="arrow-left" />` | ✅ | ✅ | ✅ |
282
- ```
283
-
284
- ### Phase 6 — Summary & Recommendations
285
-
286
- After the table, provide:
287
-
288
- 1. **Score**: `{passed}/{total}` items matching (`{percentage}%`)
289
- 2. **Critical Issues** (❌): List each mismatch with the fix needed
290
- 3. **Minor Issues** (⚠️): List deviations that may be acceptable
291
- 4. **Missing Features**: Variants/states in Figma not implemented
292
-
293
- Example:
294
- ```markdown
295
- ### Summary
296
-
297
- **Score: 28/32 (87.5%)**
298
-
299
- #### Critical Issues (❌)
300
- 1. `ghost` variant exists in Figma but is not implemented
301
- 2. Disabled background for `secondary` uses `bg-disabled` but Figma shows `bg-default-secondary`
302
-
303
- #### Minor Issues (⚠️)
304
- 1. Hover transition duration is 200ms in code but 150ms in Figma
305
-
306
- #### Missing Features
307
- - `ghost` variant (3 states: default, hover, disabled)
308
- ```
309
-
310
- ## Constraints
311
-
312
- - **Do NOT modify any code** — this skill is read-only review. Report findings only.
313
- - **Do NOT guess values** — if a Figma value cannot be determined from MCP data, mark as `⚠️ Unable to verify` and note why.
314
- - **Compare against Figma as source of truth** — if code differs from Figma, it is a mismatch regardless of whether the code "looks right."
315
- - **Check ALL variants and states** — do not skip any variant × state combination visible in Figma.
316
- - **Use the style system references** — consult `SemanticColors.md` and `StyleSystemAPI.md` from the `1money-component-dev` skill to verify token mappings are correct.