@rovula/ui 0.1.6 → 0.1.8

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 (232) hide show
  1. package/dist/cjs/bundle.css +630 -467
  2. package/dist/cjs/bundle.js +1545 -1545
  3. package/dist/cjs/bundle.js.map +1 -1
  4. package/dist/cjs/types/components/AlertDialog/AlertDialog.stories.d.ts +3 -0
  5. package/dist/cjs/types/components/Dialog/Dialog.d.ts +7 -1
  6. package/dist/cjs/types/components/Dialog/Dialog.stories.d.ts +3 -0
  7. package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +2 -0
  8. package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +2 -0
  9. package/dist/cjs/types/components/Form/Field.d.ts +26 -0
  10. package/dist/cjs/types/components/Form/FieldMessage.d.ts +7 -0
  11. package/dist/cjs/types/components/Form/Form.d.ts +49 -11
  12. package/dist/cjs/types/components/Form/Form.stories.d.ts +23 -0
  13. package/dist/cjs/types/components/Form/ValidationHintList.d.ts +17 -0
  14. package/dist/cjs/types/components/Form/ValidationHintList.stories.d.ts +9 -0
  15. package/dist/cjs/types/components/Form/index.d.ts +10 -0
  16. package/dist/cjs/types/components/Form/useOptionBridge.d.ts +17 -0
  17. package/dist/cjs/types/components/OtpInput/OtpInput.d.ts +17 -0
  18. package/dist/cjs/types/components/OtpInput/OtpInput.stories.d.ts +15 -0
  19. package/dist/cjs/types/components/OtpInput/OtpInputGroup.d.ts +25 -0
  20. package/dist/cjs/types/components/OtpInput/index.d.ts +5 -0
  21. package/dist/cjs/types/components/TextInput/TextInput.styles.d.ts +3 -0
  22. package/dist/cjs/types/index.d.ts +5 -0
  23. package/dist/cjs/types/theme/ThemeColorCoverageRuntime.stories.d.ts +10 -0
  24. package/dist/cjs/types/utils/colors.d.ts +351 -267
  25. package/dist/components/ActionButton/ActionButton.stories.js +2 -2
  26. package/dist/components/ActionButton/ActionButton.styles.js +1 -1
  27. package/dist/components/AlertDialog/AlertDialog.js +6 -6
  28. package/dist/components/AlertDialog/AlertDialog.stories.js +3 -0
  29. package/dist/components/Avatar/Avatar.stories.js +1 -1
  30. package/dist/components/Avatar/Avatar.styles.js +1 -1
  31. package/dist/components/Avatar/AvatarBase.js +1 -1
  32. package/dist/components/Avatar/AvatarGroup.stories.js +1 -1
  33. package/dist/components/Button/Buttons.stories.js +2 -2
  34. package/dist/components/Calendar/Calendar.js +1 -1
  35. package/dist/components/Checkbox/Checkbox.js +1 -1
  36. package/dist/components/Checkbox/Checkbox.stories.js +17 -7
  37. package/dist/components/Collapsible/Collapsible.styles.js +1 -1
  38. package/dist/components/DataTable/DataTable.js +2 -2
  39. package/dist/components/Dialog/Dialog.js +12 -7
  40. package/dist/components/Dialog/Dialog.stories.js +90 -2
  41. package/dist/components/Dropdown/Dropdown.js +2 -2
  42. package/dist/components/DropdownMenu/DropdownMenu.js +3 -3
  43. package/dist/components/FocusedScrollView/FocusedScrollView.stories.js +6 -6
  44. package/dist/components/Form/Field.js +60 -0
  45. package/dist/components/Form/FieldMessage.js +24 -0
  46. package/dist/components/Form/Form.js +73 -41
  47. package/dist/components/Form/Form.stories.js +221 -0
  48. package/dist/components/Form/ValidationHintList.js +30 -0
  49. package/dist/components/Form/ValidationHintList.stories.js +50 -0
  50. package/dist/components/Form/index.js +5 -0
  51. package/dist/components/Form/useOptionBridge.js +27 -0
  52. package/dist/components/InputFilter/InputFilter.js +5 -4
  53. package/dist/components/InputFilter/InputFilter.stories.js +1 -1
  54. package/dist/components/InputFilter/InputFilter.styles.js +14 -1
  55. package/dist/components/Label/Label.styles.js +1 -1
  56. package/dist/components/Menu/Menu.js +2 -2
  57. package/dist/components/NumberInput/NumberInput.stories.js +1 -1
  58. package/dist/components/OtpInput/OtpInput.js +118 -0
  59. package/dist/components/OtpInput/OtpInput.stories.js +60 -0
  60. package/dist/components/OtpInput/OtpInputGroup.js +23 -0
  61. package/dist/components/OtpInput/index.js +3 -0
  62. package/dist/components/PasswordInput/PasswordInput.stories.js +1 -1
  63. package/dist/components/Popover/Popover.js +1 -1
  64. package/dist/components/RadioGroup/RadioGroup.js +1 -1
  65. package/dist/components/RadioGroup/RadioGroup.stories.js +2 -2
  66. package/dist/components/Search/Search.js +13 -1
  67. package/dist/components/Search/Search.stories.js +1 -1
  68. package/dist/components/Slider/Slider.js +1 -1
  69. package/dist/components/Slider/Slider.stories.js +5 -5
  70. package/dist/components/Switch/Switch.stories.js +2 -2
  71. package/dist/components/Switch/Switch.styles.js +1 -1
  72. package/dist/components/Table/Table.js +5 -5
  73. package/dist/components/Tabs/Tabs.js +12 -9
  74. package/dist/components/Tabs/Tabs.stories.js +1 -1
  75. package/dist/components/Text/Text.js +1 -1
  76. package/dist/components/Text/Text.stories.js +1 -1
  77. package/dist/components/TextArea/TextArea.stories.js +1 -1
  78. package/dist/components/TextArea/TextArea.styles.js +3 -3
  79. package/dist/components/TextInput/TextInput.js +3 -2
  80. package/dist/components/TextInput/TextInput.stories.js +3 -3
  81. package/dist/components/TextInput/TextInput.styles.js +41 -19
  82. package/dist/components/Toast/Toast.js +4 -2
  83. package/dist/components/Toast/Toast.stories.js +1 -1
  84. package/dist/components/Toast/Toast.styles.js +4 -4
  85. package/dist/components/Toast/Toaster.js +2 -2
  86. package/dist/components/Tree/Tree.stories.js +1 -1
  87. package/dist/components/Tree/TreeItem.js +1 -1
  88. package/dist/esm/bundle.css +630 -467
  89. package/dist/esm/bundle.js +1545 -1545
  90. package/dist/esm/bundle.js.map +1 -1
  91. package/dist/esm/types/components/AlertDialog/AlertDialog.stories.d.ts +3 -0
  92. package/dist/esm/types/components/Dialog/Dialog.d.ts +7 -1
  93. package/dist/esm/types/components/Dialog/Dialog.stories.d.ts +3 -0
  94. package/dist/esm/types/components/Dropdown/Dropdown.d.ts +2 -0
  95. package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +2 -0
  96. package/dist/esm/types/components/Form/Field.d.ts +26 -0
  97. package/dist/esm/types/components/Form/FieldMessage.d.ts +7 -0
  98. package/dist/esm/types/components/Form/Form.d.ts +49 -11
  99. package/dist/esm/types/components/Form/Form.stories.d.ts +23 -0
  100. package/dist/esm/types/components/Form/ValidationHintList.d.ts +17 -0
  101. package/dist/esm/types/components/Form/ValidationHintList.stories.d.ts +9 -0
  102. package/dist/esm/types/components/Form/index.d.ts +10 -0
  103. package/dist/esm/types/components/Form/useOptionBridge.d.ts +17 -0
  104. package/dist/esm/types/components/OtpInput/OtpInput.d.ts +17 -0
  105. package/dist/esm/types/components/OtpInput/OtpInput.stories.d.ts +15 -0
  106. package/dist/esm/types/components/OtpInput/OtpInputGroup.d.ts +25 -0
  107. package/dist/esm/types/components/OtpInput/index.d.ts +5 -0
  108. package/dist/esm/types/components/TextInput/TextInput.styles.d.ts +3 -0
  109. package/dist/esm/types/index.d.ts +5 -0
  110. package/dist/esm/types/theme/ThemeColorCoverageRuntime.stories.d.ts +10 -0
  111. package/dist/esm/types/utils/colors.d.ts +351 -267
  112. package/dist/index.d.ts +512 -269
  113. package/dist/index.js +3 -0
  114. package/dist/src/theme/global.css +2739 -2681
  115. package/dist/theme/ThemeColorCoverageRuntime.stories.js +91 -0
  116. package/dist/utils/colors.js +359 -267
  117. package/package.json +4 -2
  118. package/src/components/ActionButton/ActionButton.stories.tsx +6 -6
  119. package/src/components/ActionButton/ActionButton.styles.ts +1 -1
  120. package/src/components/AlertDialog/AlertDialog.stories.tsx +22 -0
  121. package/src/components/AlertDialog/AlertDialog.tsx +6 -6
  122. package/src/components/Avatar/Avatar.stories.tsx +1 -1
  123. package/src/components/Avatar/Avatar.styles.ts +1 -1
  124. package/src/components/Avatar/AvatarBase.tsx +1 -1
  125. package/src/components/Avatar/AvatarGroup.stories.tsx +1 -1
  126. package/src/components/Button/Buttons.stories.tsx +25 -17
  127. package/src/components/Calendar/Calendar.tsx +3 -3
  128. package/src/components/Checkbox/Checkbox.stories.tsx +35 -12
  129. package/src/components/Checkbox/Checkbox.tsx +7 -5
  130. package/src/components/Collapsible/Collapsible.styles.ts +1 -1
  131. package/src/components/DataTable/DataTable.tsx +2 -2
  132. package/src/components/Dialog/Dialog.stories.tsx +173 -0
  133. package/src/components/Dialog/Dialog.tsx +32 -15
  134. package/src/components/Dropdown/Dropdown.styles.ts +1 -1
  135. package/src/components/Dropdown/Dropdown.tsx +16 -14
  136. package/src/components/DropdownMenu/DropdownMenu.tsx +3 -3
  137. package/src/components/FocusedScrollView/FocusedScrollView.stories.tsx +10 -10
  138. package/src/components/Form/Field.tsx +160 -0
  139. package/src/components/Form/FieldMessage.tsx +38 -0
  140. package/src/components/Form/Form.docs.mdx +67 -0
  141. package/src/components/Form/Form.stories.tsx +490 -0
  142. package/src/components/Form/Form.tsx +185 -87
  143. package/src/components/Form/README.md +284 -0
  144. package/src/components/Form/ValidationHintList.stories.tsx +118 -0
  145. package/src/components/Form/ValidationHintList.tsx +82 -0
  146. package/src/components/Form/index.ts +28 -0
  147. package/src/components/Form/useOptionBridge.ts +55 -0
  148. package/src/components/InputFilter/InputFilter.stories.tsx +1 -1
  149. package/src/components/InputFilter/InputFilter.styles.ts +14 -1
  150. package/src/components/InputFilter/InputFilter.tsx +33 -28
  151. package/src/components/Label/Label.styles.ts +2 -2
  152. package/src/components/Label/Label.tsx +1 -1
  153. package/src/components/Menu/Menu.tsx +12 -12
  154. package/src/components/NumberInput/NumberInput.stories.tsx +1 -1
  155. package/src/components/OtpInput/OtpInput.stories.tsx +168 -0
  156. package/src/components/OtpInput/OtpInput.tsx +210 -0
  157. package/src/components/OtpInput/OtpInputGroup.tsx +74 -0
  158. package/src/components/OtpInput/index.ts +5 -0
  159. package/src/components/PasswordInput/PasswordInput.stories.tsx +1 -1
  160. package/src/components/Popover/Popover.tsx +1 -1
  161. package/src/components/RadioGroup/RadioGroup.stories.tsx +4 -4
  162. package/src/components/RadioGroup/RadioGroup.tsx +2 -1
  163. package/src/components/Search/Search.stories.tsx +1 -1
  164. package/src/components/Search/Search.tsx +6 -2
  165. package/src/components/Slider/Slider.stories.tsx +7 -7
  166. package/src/components/Slider/Slider.tsx +1 -1
  167. package/src/components/Switch/Switch.stories.tsx +4 -4
  168. package/src/components/Switch/Switch.styles.ts +1 -1
  169. package/src/components/Table/Table.tsx +5 -5
  170. package/src/components/Tabs/Tabs.stories.tsx +1 -1
  171. package/src/components/Tabs/Tabs.tsx +29 -18
  172. package/src/components/Text/Text.stories.tsx +1 -1
  173. package/src/components/Text/Text.tsx +1 -1
  174. package/src/components/TextArea/TextArea.stories.tsx +1 -1
  175. package/src/components/TextArea/TextArea.styles.ts +3 -3
  176. package/src/components/TextInput/TextInput.stories.tsx +7 -7
  177. package/src/components/TextInput/TextInput.styles.ts +42 -19
  178. package/src/components/TextInput/TextInput.tsx +3 -1
  179. package/src/components/Toast/Toast.stories.tsx +1 -1
  180. package/src/components/Toast/Toast.styles.tsx +7 -7
  181. package/src/components/Toast/Toast.tsx +5 -4
  182. package/src/components/Toast/Toaster.tsx +17 -20
  183. package/src/components/Tree/Tree.stories.tsx +1 -1
  184. package/src/components/Tree/TreeItem.tsx +1 -1
  185. package/src/index.ts +5 -0
  186. package/src/theme/THEME_MAPPING.md +36 -37
  187. package/src/theme/ThemeColorCoverageRuntime.stories.tsx +236 -0
  188. package/src/theme/direct-token-migration-plan.md +121 -0
  189. package/src/theme/figma-mcp-check-report.md +225 -0
  190. package/src/theme/figma-mcp-component-checklist.json +1250 -0
  191. package/src/theme/global.css +7 -3
  192. package/src/theme/presets/colors.js +173 -64
  193. package/src/theme/themes/skyller/baseline.css +0 -4
  194. package/src/theme/themes/variable-mapping.css +1064 -0
  195. package/src/theme/themes/variable.css +248 -230
  196. package/src/theme/themes/xspector/baseline.css +0 -4
  197. package/src/theme/themes/xspector/components/dropdown-menu.css +4 -4
  198. package/src/theme/themes/xspector/components/loading.css +2 -2
  199. package/src/theme/tokens/baseline.css +0 -3
  200. package/src/theme/tokens/color.css +36 -65
  201. package/src/theme/tokens/components/action-button.css +6 -6
  202. package/src/theme/tokens/components/button.css +189 -189
  203. package/src/theme/tokens/components/dropdown-menu.css +5 -5
  204. package/src/theme/tokens/components/footer.css +1 -1
  205. package/src/theme/tokens/components/loading.css +2 -2
  206. package/src/theme/tokens/components/switch.css +11 -11
  207. package/src/theme/tokens/typography.css +28 -28
  208. package/src/theme/tokens_old/baseline.css +13 -0
  209. package/src/theme/tokens_old/color.css +78 -0
  210. package/src/theme/tokens_old/components/action-button.css +127 -0
  211. package/src/theme/tokens_old/components/button.css +512 -0
  212. package/src/theme/tokens_old/components/dropdown-menu.css +27 -0
  213. package/src/theme/tokens_old/components/footer.css +9 -0
  214. package/src/theme/tokens_old/components/loading.css +11 -0
  215. package/src/theme/tokens_old/components/navbar.css +9 -0
  216. package/src/theme/tokens_old/components/progress-bar.css +8 -0
  217. package/src/theme/tokens_old/components/switch.css +29 -0
  218. package/src/theme/tokens_old/typography.css +199 -0
  219. package/src/theme/tokens_old/variables.css +28 -0
  220. package/src/theme/utils.js +172 -33
  221. package/src/utils/colors.ts +367 -278
  222. package/src/theme/themes/skyller/color.css +0 -79
  223. package/src/theme/themes/skyller/palette.css +0 -143
  224. package/src/theme/themes/skyller/state.css +0 -94
  225. package/src/theme/themes/skyller/transparent.css +0 -94
  226. package/src/theme/themes/xspector/color.css +0 -83
  227. package/src/theme/themes/xspector/palette.css +0 -142
  228. package/src/theme/themes/xspector/state.css +0 -94
  229. package/src/theme/themes/xspector/transparent.css +0 -93
  230. /package/src/theme/{tokens → tokens_old}/palette.css +0 -0
  231. /package/src/theme/{tokens → tokens_old}/state.css +0 -0
  232. /package/src/theme/{tokens → tokens_old}/transparent.css +0 -0
@@ -0,0 +1,236 @@
1
+ import React, { useMemo } from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+
4
+ import { THEME_COLOR_KEYS, getThemeColor } from "../utils/colors";
5
+
6
+ const meta = {
7
+ title: "Theme/Color Coverage Runtime",
8
+ parameters: {
9
+ layout: "fullscreen",
10
+ },
11
+ } satisfies Meta;
12
+
13
+ export default meta;
14
+
15
+ type CoverageRow = {
16
+ key: string;
17
+ variableName: string;
18
+ runtimeValue: string;
19
+ hasRuntimeValue: boolean;
20
+ canonicalKey: string;
21
+ isMappedAlias: boolean;
22
+ isDeprecated: boolean;
23
+ };
24
+
25
+ const DEPRECATED_KEYS = new Set([
26
+ "text-dark",
27
+ "text-medium",
28
+ "text-light",
29
+ "text-grey-dark",
30
+ "text-grey-medium",
31
+ "text-grey-light",
32
+ "base-bg",
33
+ "base-bg2",
34
+ "base-bg3",
35
+ "base-workspace-stroke",
36
+ "base-guideline-stroke",
37
+ "base-popup",
38
+ "base-popup-highlight",
39
+ "base-popup-curtain",
40
+ "base-popup-foreground",
41
+ "background",
42
+ "foreground",
43
+ "surface",
44
+ "surface-foreground",
45
+ "primary-foreground",
46
+ "secondary-foreground",
47
+ "tertiary-foreground",
48
+ "info-foreground",
49
+ "success-foreground",
50
+ "warning-foreground",
51
+ "error-foreground",
52
+ "grey-foreground",
53
+ "grey2-foreground",
54
+ "function-default-outline",
55
+ ]);
56
+ const RuntimeCoveragePanel = () => {
57
+ const rows = useMemo<CoverageRow[]>(() => {
58
+ const baseRows = Object.entries(THEME_COLOR_KEYS)
59
+ .map(([key, variableName]) => {
60
+ const runtimeValue = getThemeColor(variableName);
61
+ const hasRuntimeValue = runtimeValue.length > 0;
62
+ const canonicalKey = variableName.replace(/^--/, "");
63
+
64
+ return {
65
+ key,
66
+ variableName,
67
+ runtimeValue,
68
+ hasRuntimeValue,
69
+ canonicalKey,
70
+ isMappedAlias: key !== canonicalKey,
71
+ isDeprecated: DEPRECATED_KEYS.has(key),
72
+ };
73
+ })
74
+ .sort((a, b) => a.key.localeCompare(b.key));
75
+
76
+ const existingKeys = new Set(baseRows.map((row) => row.key));
77
+ const generatedDirectRows = baseRows
78
+ .filter((row) => row.isMappedAlias)
79
+ .map((row) => {
80
+ return {
81
+ key: row.canonicalKey,
82
+ variableName: row.variableName,
83
+ runtimeValue: row.runtimeValue,
84
+ hasRuntimeValue: row.hasRuntimeValue,
85
+ canonicalKey: row.canonicalKey,
86
+ isMappedAlias: false,
87
+ isDeprecated: false,
88
+ } satisfies CoverageRow;
89
+ })
90
+ .filter((row) => !existingKeys.has(row.key));
91
+
92
+ return [...baseRows, ...generatedDirectRows].sort((a, b) =>
93
+ a.key.localeCompare(b.key),
94
+ );
95
+ }, []);
96
+
97
+ const activeRows = rows.filter(
98
+ (row) => !row.isDeprecated && !row.isMappedAlias,
99
+ );
100
+ const mappedRows = rows.filter(
101
+ (row) => !row.isDeprecated && row.isMappedAlias,
102
+ );
103
+ const deprecatedRows = rows.filter((row) => row.isDeprecated);
104
+
105
+ const missingRuntimeValue = rows.filter((row) => !row.hasRuntimeValue);
106
+ const activeMissingRuntimeValue = activeRows.filter(
107
+ (row) => !row.hasRuntimeValue,
108
+ );
109
+ const mappedMissingRuntimeValue = mappedRows.filter(
110
+ (row) => !row.hasRuntimeValue,
111
+ );
112
+ const deprecatedMissingRuntimeValue = deprecatedRows.filter(
113
+ (row) => !row.hasRuntimeValue,
114
+ );
115
+ const stateRows = rows.filter((row) =>
116
+ row.variableName.startsWith("--state-"),
117
+ );
118
+ const stateRuntimeMissing = stateRows.filter((row) => !row.hasRuntimeValue);
119
+
120
+ const renderTable = (tableRows: CoverageRow[]) => (
121
+ <div className="rounded-md border border-bg-stroke2 bg-bg-bg2 overflow-auto">
122
+ <table className="w-full text-small3">
123
+ <thead className="sticky top-0 bg-bg-bg3">
124
+ <tr>
125
+ <th className="text-left p-2">Key</th>
126
+ <th className="text-left p-2">CSS Variable</th>
127
+ <th className="text-left p-2">Runtime</th>
128
+ <th className="text-left p-2">Preview</th>
129
+ </tr>
130
+ </thead>
131
+ <tbody>
132
+ {tableRows.map((row) => (
133
+ <tr key={row.key} className="border-t border-bg-stroke2">
134
+ <td className="p-2">{row.key}</td>
135
+ <td className="p-2">{row.variableName}</td>
136
+ <td className="p-2">
137
+ {row.hasRuntimeValue ? row.runtimeValue : "missing"}
138
+ </td>
139
+ <td className="p-2">
140
+ {row.hasRuntimeValue ? (
141
+ <span
142
+ className="inline-block w-6 h-4 rounded border border-bg-stroke2"
143
+ style={{ backgroundColor: `var(${row.variableName})` }}
144
+ />
145
+ ) : (
146
+ "-"
147
+ )}
148
+ </td>
149
+ </tr>
150
+ ))}
151
+ </tbody>
152
+ </table>
153
+ </div>
154
+ );
155
+
156
+ return (
157
+ <div className="p-6 space-y-4 bg-bg-bg2 text-text-g-contrast-high min-h-screen text-text-black">
158
+ <h2 className="text-h5">Theme Color Runtime Coverage</h2>
159
+
160
+ <div className="grid grid-cols-2 gap-3 max-w-3xl">
161
+ <div className="rounded-md border border-bg-stroke2 p-3 bg-bg-bg2">
162
+ <div className="text-small3">Total keys</div>
163
+ <div className="text-h6">{rows.length}</div>
164
+ </div>
165
+ <div className="rounded-md border border-bg-stroke2 p-3 bg-bg-bg2">
166
+ <div className="text-small3">Missing runtime values</div>
167
+ <div className="text-h6">{missingRuntimeValue.length}</div>
168
+ </div>
169
+ <div className="rounded-md border border-bg-stroke2 p-3 bg-bg-bg2">
170
+ <div className="text-small3">State runtime coverage</div>
171
+ <div className="text-h6">
172
+ {stateRows.length - stateRuntimeMissing.length}/{stateRows.length}
173
+ </div>
174
+ </div>
175
+ <div className="rounded-md border border-bg-stroke2 p-3 bg-bg-bg2">
176
+ <div className="text-small3">Runtime coverage</div>
177
+ <div className="text-h6">
178
+ {rows.length - missingRuntimeValue.length}/{rows.length}
179
+ </div>
180
+ </div>
181
+ </div>
182
+
183
+ <div className="grid grid-cols-3 gap-3 max-w-4xl">
184
+ <div className="rounded-md border border-bg-stroke2 p-3 bg-bg-bg2">
185
+ <div className="text-small3">Active keys</div>
186
+ <div className="text-h6">
187
+ {activeRows.length - activeMissingRuntimeValue.length}/
188
+ {activeRows.length}
189
+ </div>
190
+ </div>
191
+ <div className="rounded-md border border-bg-stroke2 p-3 bg-bg-bg2">
192
+ <div className="text-small3">Mapped keys (alias to canonical)</div>
193
+ <div className="text-h6">
194
+ {mappedRows.length - mappedMissingRuntimeValue.length}/
195
+ {mappedRows.length}
196
+ </div>
197
+ </div>
198
+ <div className="rounded-md border border-bg-stroke2 p-3 bg-bg-bg2">
199
+ <div className="text-small3">Deprecated keys</div>
200
+ <div className="text-h6">
201
+ {deprecatedRows.length - deprecatedMissingRuntimeValue.length}/
202
+ {deprecatedRows.length}
203
+ </div>
204
+ </div>
205
+ </div>
206
+
207
+ {missingRuntimeValue.length > 0 ? (
208
+ <div className="rounded-md border border-warning p-3 bg-warning-transparent-8">
209
+ <div className="text-small2 text-warning">Missing runtime values</div>
210
+ <div className="text-small3 mt-1">
211
+ {missingRuntimeValue.map((item) => item.variableName).join(", ")}
212
+ </div>
213
+ </div>
214
+ ) : null}
215
+
216
+ <div className="space-y-2">
217
+ <h3 className="text-subtitle3">Active Tokens</h3>
218
+ {renderTable(activeRows)}
219
+ </div>
220
+
221
+ <div className="space-y-2">
222
+ <h3 className="text-subtitle3">Mapped Tokens (Alias)</h3>
223
+ {renderTable(mappedRows)}
224
+ </div>
225
+
226
+ <div className="space-y-2">
227
+ <h3 className="text-subtitle3">Deprecated Aliases</h3>
228
+ {renderTable(deprecatedRows)}
229
+ </div>
230
+ </div>
231
+ );
232
+ };
233
+
234
+ export const RuntimeCoverage = {
235
+ render: () => <RuntimeCoveragePanel />,
236
+ } satisfies StoryObj;
@@ -0,0 +1,121 @@
1
+ # Direct Token Migration Plan
2
+
3
+ Status: draft (no code changes applied from this plan yet)
4
+
5
+ ## Goal
6
+
7
+ Migrate color class usage from mapped aliases to direct token classes:
8
+
9
+ - Ramps: `{base}-{step}` -> `ramps-{base}-{step}`
10
+ - Transparent: `{base}-transparent-{alpha}` -> `transparent-{base}-{alpha}`
11
+
12
+ Examples:
13
+
14
+ - `error-100` -> `ramps-error-100`
15
+ - `black-transparent-12` -> `transparent-black-12`
16
+ - `grey-transparent-24` -> `transparent-grey-24`
17
+
18
+ ## Current Scan Snapshot
19
+
20
+ Estimated touch points (from latest scan):
21
+
22
+ - Runtime components: ~17
23
+ - Component stories: ~11
24
+ - `src/stories/ColorGroupPreview.tsx`: ~100
25
+
26
+ Total estimated class replacements: ~128
27
+
28
+ ## Migration Rule
29
+
30
+ Active/canonical class names should match CSS variable naming:
31
+
32
+ - Canonical ramps key: `ramps-*`
33
+ - Canonical transparent key: `transparent-*`
34
+ - Non-canonical aliases are treated as mapped/compat aliases.
35
+
36
+ ## Recommended Phases
37
+
38
+ ### Phase 1 - Runtime Components First
39
+
40
+ Targets:
41
+
42
+ - `src/components/Tree/TreeItem.tsx`
43
+ - `src/components/Table/Table.tsx`
44
+ - `src/components/DataTable/DataTable.tsx`
45
+ - `src/components/Toast/Toast.styles.tsx`
46
+ - `src/components/Avatar/Avatar.styles.ts`
47
+ - `src/components/ProgressBar/ProgressBar.tsx`
48
+
49
+ Reason:
50
+
51
+ - Highest product impact
52
+ - Lower volume than stories
53
+ - Easier regression validation
54
+
55
+ ### Phase 2 - Component Stories
56
+
57
+ Targets:
58
+
59
+ - `src/components/Slider/Slider.stories.tsx`
60
+ - `src/components/Navbar/Navbar.stories.tsx`
61
+ - `src/components/Toast/Toast.stories.tsx`
62
+ - `src/components/FocusedScrollView/FocusedScrollView.stories.tsx`
63
+
64
+ Reason:
65
+
66
+ - Keeps docs/demo aligned with production naming
67
+
68
+ ### Phase 3 - Color Preview Story
69
+
70
+ Target:
71
+
72
+ - `src/stories/ColorGroupPreview.tsx` (~100 replacements)
73
+
74
+ Reason:
75
+
76
+ - Largest single-file conversion
77
+ - Safe to batch once phases 1-2 are stable
78
+
79
+ ### Phase 4 - Optional Infra Cleanup (Later)
80
+
81
+ Potential scope (if deprecating mapped aliases from system, not just usage):
82
+
83
+ - `src/utils/colors.ts`
84
+ - `src/theme/presets/colors.js`
85
+ - `src/theme/ThemeColorCoverageRuntime.stories.tsx`
86
+ - `src/theme/themes/variable-mapping.css`
87
+ - `src/theme/THEME_MAPPING.md`
88
+
89
+ Note:
90
+
91
+ - This phase is broader and should happen only after all usage migration is complete.
92
+
93
+ ## Validation Checklist Per Phase
94
+
95
+ - Run lints on edited files
96
+ - Build or run Storybook checks for touched stories
97
+ - Spot-check critical components visually (Toast, Table, Tree, DataTable)
98
+ - Re-open `Theme/Color Coverage Runtime` and verify:
99
+ - Direct keys appear in Active
100
+ - Alias keys are only in Mapped
101
+
102
+ ## Suggested Replace Pattern
103
+
104
+ For ramps:
105
+
106
+ - `bg-{base}-{step}` -> `bg-ramps-{base}-{step}`
107
+ - `text-{base}-{step}` -> `text-ramps-{base}-{step}`
108
+ - `border-{base}-{step}` -> `border-ramps-{base}-{step}`
109
+
110
+ For transparent:
111
+
112
+ - `bg-{base}-transparent-{alpha}` -> `bg-transparent-{base}-{alpha}`
113
+ - `text-{base}-transparent-{alpha}` -> `text-transparent-{base}-{alpha}`
114
+ - `border-{base}-transparent-{alpha}` -> `border-transparent-{base}-{alpha}`
115
+
116
+ ## Risk Notes
117
+
118
+ - Some names may look like ramps but are semantic state tokens (do not convert):
119
+ - `primary`, `primary-hover`, `state-*`, `function-*`, `input-*`
120
+ - Gradient literals and hex colors are separate cleanup work and should not be auto-converted in this pass.
121
+
@@ -0,0 +1,225 @@
1
+ # Figma MCP Mapping Check Report
2
+
3
+ Source checklist: `src/theme/figma-mcp-component-checklist.json`
4
+ Coverage mode: `representative-minimum` (22 button nodes + 9 action-button nodes + 8 text-input nodes + 6 input-filter nodes)
5
+
6
+ ## Checked
7
+
8
+ ### Button/Primary/Solid/Default/L/NoIcon (`9044:17724`)
9
+
10
+ - `color` -> pass
11
+ - Figma expects primary solid default surface/text.
12
+ - `src/components/Button/Button.styles.ts` uses `bg-button-primary-solid-default`, `border-button-primary-solid-default`, `text-button-primary-solid-default`.
13
+ - `src/theme/tokens/components/button.css` maps these tokens to `--state-primary-default` and `--state-primary-text-solid`.
14
+ - `state` -> pass
15
+ - `default` mapping is present for `solid` state class chain and token variables.
16
+ - `size` -> pass
17
+ - Figma expects L with `px:24`, `py:16`, font `16/24 bold`.
18
+ - `src/components/Button/Button.styles.ts` size `lg` is `px-[24px] py-[16px] typography-buttonL`.
19
+ - `src/theme/main-preset.js` defines `text-buttonL` as `16px/24px` with weight `700`.
20
+ - `icon` -> pass
21
+ - Figma variant is no start/end icon.
22
+ - `src/components/Button/Button.tsx` only renders icons when `startIcon` or `endIcon` is provided.
23
+
24
+ Overall: `pass`
25
+
26
+ ### Button/Primary/Solid/Default/L/NoIcon/Capsule (`9057:12622`)
27
+
28
+ - `shape` -> pass
29
+ - Figma capsule corner for L is `56px`.
30
+ - `src/components/Button/Button.styles.ts` uses `shape="capsule"` + `size="lg"` -> `rounded-[var(--button-l-capsule)]`.
31
+ - `src/theme/themes/variable.css` defines `--button-l-capsule: 56px`.
32
+ - `color` -> pass
33
+ - Uses same primary solid default token chain as regular button (`--state-primary-default` / `--state-primary-text-solid`).
34
+ - `size` -> pass
35
+ - Matches L spacing and typography (`px 24`, `py 16`, `16/24 bold`).
36
+
37
+ Overall: `pass`
38
+
39
+ ### Capsule minimum set (additional checks)
40
+
41
+ - `Button/Primary/Outline/Default/L/NoIcon/Capsule` (`9057:12630`) -> `pass`
42
+ - `Button/Primary/Text/Default/L/NoIcon/Capsule` (`9057:12638`) -> `pass`
43
+ - `Button/Primary/Solid/Default/M/NoIcon/Capsule` (`9057:12673`) -> `pass`
44
+ - `Button/Primary/Outline/Pressed/M/NoIcon/Capsule` (`9057:12698`) -> `pass`
45
+ - `Button/Primary/Solid/Pressed/S/IconEnd/Capsule` (`9057:12614`) -> `pass`
46
+ - `Button/Primary/Outline/Disable/S/IconEnd/Capsule` (`9057:12586`) -> `pass`
47
+
48
+ ### Action button (function) check
49
+
50
+ ### ActionButton/Function/Solid/Default/L/Round (`9044:18043`)
51
+
52
+ - `color` -> pass
53
+ - Figma default surface uses `--function-default-solid`.
54
+ - `src/theme/tokens/components/action-button.css` maps `--action-button-solid-default-bg/border` to `--function-default-solid`.
55
+ - `state` -> pass
56
+ - Figma state is `Default`; `ActionButton` variant `solid` default class chain maps correctly.
57
+ - `size` -> pass
58
+ - Figma spacing is `p-12` with `32px` icon.
59
+ - `src/components/ActionButton/ActionButton.styles.ts` (`size=lg`) uses `px-[12px] py-[12px] [&_svg]:size-[32px]`.
60
+ - `shape` -> pass
61
+ - Figma radius for L round is `8px`.
62
+ - `src/components/ActionButton/ActionButton.styles.ts` uses `rounded-[var(--function-button-l-round)]`; `variable.css` sets `--function-button-l-round: 8px`.
63
+ - `icon` -> pass
64
+ - Design is icon-only and component supports icon-only content via `children`.
65
+
66
+ ### ActionButton minimum set (additional checks)
67
+
68
+ - `ActionButton/Function/Outline/Default/L/Round` (`9044:18045`) -> `pass`
69
+ - `ActionButton/Function/Icon/Default/L/Round` (`9044:18047`) -> `pass`
70
+ - `ActionButton/Function/Solid/Hover/L/Round` (`9044:18065`) -> `pass`
71
+ - `ActionButton/Function/Outline/Active/L/Round` (`9044:18089`) -> `pass`
72
+ - `ActionButton/Function/Outline/Active-Hover/L/Round` (`9044:18111`) -> `pass`
73
+ - `ActionButton/Function/Outline/Disable/L/Round` (`9044:18133`) -> `pass`
74
+ - `ActionButton/Function/Icon/Default/XXS/Round` (`9044:18063`) -> `pass`
75
+
76
+ ### Input field check
77
+
78
+ ### TextInput/Default/Outline/L/Required (`42037:209129`)
79
+
80
+ - `color` -> pass
81
+ - Figma uses `--input-default-stroke`, `--input-default-text`, and `--input-error` (for required `*`).
82
+ - `TextInput` styles use `ring-input-default-stroke`, `text-input-default-text`, and required mark `text-input-error`.
83
+ - `state` -> pass
84
+ - Node is default state; outline/default path is present in `inputVariant`.
85
+ - `size` -> pass
86
+ - Figma uses `p-16` and subtitle1 typography (`16/24` regular).
87
+ - `size="lg"` in `TextInput` maps to `p-4 typography-subtitle1`.
88
+ - `shape` -> pass
89
+ - Figma corner radius is `8px`.
90
+ - `TextInput` default `rounded="normal"` maps to `rounded-md` (radius-m = 8px).
91
+ - `required` -> pass
92
+ - Required star is rendered by default in `TextInput` (`required=true`) with error color.
93
+
94
+ ### TextInput minimum set (additional checks)
95
+
96
+ - `TextInput/Default/Outline/M/Required` (`40388:258895`) -> `pass`
97
+ - `TextInput/Default/Outline/S/Required` (`40388:258903`) -> `pass` (after radius fix for size S)
98
+ - `TextInput/FocusTyping/Outline/L/Required` (`40388:259075`) -> `pass`
99
+ - `TextInput/Filled/Outline/L/Required` (`40388:259093`) -> `pass`
100
+ - `TextInput/Disable/Outline/L/Required` (`40388:258911`) -> `pass`
101
+ - `TextInput/Error/Outline/L/Required` (`40388:259165`) -> `pass`
102
+ - `TextInput/ErrorFilled/Outline/L/Required` (`40388:259135`) -> `pass`
103
+
104
+ ### InputFilter minimum set
105
+
106
+ - `InputFilter/Default/NotFilled/L` (`3150:80315`) -> `pass`
107
+ - `InputFilter/Default/Filled/L` (`3150:80299`) -> `pass`
108
+ - `InputFilter/Active/Filled/L` (`3150:80310`) -> `pass`
109
+ - `InputFilter/Disable/NotFilled/L` (`3150:80302`) -> `pass`
110
+ - `InputFilter/Default/NotFilled/S` (`3150:80305`) -> `pass` (after size-aware right-corner tuning)
111
+ - `InputFilter/InputSegment/Default/L` (`3150:80013`) -> `pass` (rechecked, left segment border/shape aligned)
112
+
113
+ ### Search minimum set
114
+
115
+ - `Search/Default-Focus-Filled-Disable/S-M-L` (`40388:259223`) -> `pass` (after removing segmented input style in `Search`, and aligning search icon size/offset to `24/20/14` with size-aware left spacing)
116
+
117
+ ### Tabs minimum set
118
+
119
+ - `Tabs/Text-Icon-Loading/Default-Hover-Active-Disable` (`9478:6430`) -> `pass` (after aligning active/disabled text token, hover and active indicator colors, icon/loading size to `12px`, and default icon-space behavior)
120
+ - Detailed node recheck (`pass`):
121
+ - `Tabs/Text/Active/NoHover/NoDisable/NoIcon` (`9478:6452`)
122
+ - `Tabs/Text/Active/Hover/NoDisable/NoIcon` (`9482:10539`)
123
+ - `Tabs/Text/Inactive/NoHover/NoDisable/NoIcon` (`9478:6499`)
124
+ - `Tabs/Text/Inactive/NoHover/Disable/NoIcon` (`9478:6530`)
125
+ - `Tabs/IconLeft/Inactive/NoHover/NoDisable` (`9478:6471`)
126
+ - `Tabs/IconRight/Inactive/Hover/NoDisable` (`9478:6492`)
127
+ - `Tabs/LoadingLeft/Inactive/NoHover/NoDisable` (`9478:6457`)
128
+ - `Tabs/LoadingLeft/Inactive/NoHover/Disable` (`9478:6509`)
129
+
130
+ ### Loading minimum set
131
+
132
+ - `Loading/Icon/Default/16` (`42096:153887`) -> `pass`
133
+ - Figma is a 16x16 circular loading icon with a grey track and brand yellow progress arc.
134
+ - `src/components/Loading/Loading.tsx` defaults match: `size=16`, `strokeWidth=2`, circular path with rounded progress cap.
135
+ - Color mapping is tokenized via `--loading-track-color` and `--loading-process-color` from `src/theme/tokens/components/loading.css`.
136
+ - Updated token mapping to match Figma exactly: `--loading-track-color -> --transparent-grey-32` and `--loading-process-color -> --brand-rvl-yellow` (including xspector theme override).
137
+
138
+ ### Checkbox + Radio minimum set
139
+
140
+ - `Checkbox/StateMatrix/Default-Hover-Disable-Checked-Indeterminate` (`40388:258859`) -> `pass`
141
+ - Rechecked checkbox matrix nodes in Figma section `9112:22335`.
142
+ - Fix applied: unchecked + disabled border now maps to `state-disable-outline` in `src/components/Checkbox/Checkbox.tsx`.
143
+ - Checked/indeterminate + disabled still map to `state-disable-solid` background/border, matching Figma.
144
+ - `Radio/StateMatrix/Default-Hover-Disable-Checked` (`40388:258859`) -> `pass`
145
+ - Rechecked radio matrix nodes in the same Figma section.
146
+ - Disabled styling now distinguishes unchecked (`state-disable-outline`) and checked (`state-disable-solid`) in `src/components/RadioGroup/RadioGroup.tsx`.
147
+
148
+ ### Switch minimum set
149
+
150
+ - `Switch/Toggle/On-Off/Default-Hover-Disable` (`2112:6315`) -> `pass`
151
+ - Rechecked all six states from Figma matrix (`2112:6314`, `2112:6312`, `2112:6310`, `2112:6313`, `2112:6311`, `2112:6309`).
152
+ - Existing state mapping in `src/components/Switch/Switch.styles.ts` already matches track/thumb color and opacity model.
153
+ - Fix applied for thumb shadow parity: `--switch-thumb-filter` updated to `drop-shadow(0 8px 16px #00000014)` in `src/theme/tokens/components/switch.css`.
154
+
155
+ ### Toast minimum set
156
+
157
+ - `Toast/Success-Warning-Error/Action-TextModes` (`9171:21362`) -> `pass`
158
+ - Rechecked representative nodes: success (`9171:21363`, `9171:21370`, `9171:21379`), warning (`9171:21395`), error (`9171:21434`, `9171:21442`).
159
+ - Updated toast card shadow to Figma value (`0 8 16 #00000014` -> `rgba(0,0,0,0.08)`).
160
+ - Final spacing model uses root `gap-1` with icon wrapper `mr-2` (icon-to-text effective `12px`) and action wrapper `mx-5` (effective `24px` around action block).
161
+ - Vertical content mode remains `items-start` with no extra gap for two-line layout parity.
162
+ - Action wrapper renders only when action exists; close action offset is normalized.
163
+
164
+ ### Batch run from checklist
165
+
166
+ - `Button/Primary/Outline/Default/L/NoIcon` (`9044:17740`) -> `pass`
167
+ - `Button/Primary/Text/Default/L/NoIcon` (`9044:17756`) -> `pass` (mapped via `text` variant -> `flat` token family)
168
+ - `Button/Primary/Solid/Hover/L/NoIcon` (`9044:17810`) -> `pass`
169
+ - `Button/Primary/Outline/Pressed/L/NoIcon` (`9044:17774`) -> `pass` (`Pressed` mapped to `active` token/state in code)
170
+ - `Button/Primary/Text/Loading/L/NoIcon` (`9044:17795`) -> `pass` (`Loading` mapped via `data-[loading=true]` to `active` token/state)
171
+ - `Button/Primary/Solid/Disable/L/NoIcon` (`9044:17738`) -> `pass`
172
+ - `Button/Primary/Solid/Default/M/NoIcon` (`9044:17829`) -> `pass`
173
+ - `Button/Primary/Solid/Default/S/NoIcon` (`9044:17934`) -> `pass`
174
+ - `Button/Primary/Solid/Default/L/IconStart` (`9044:16788`) -> `pass`
175
+ - `Button/Primary/Solid/Default/L/IconEnd` (`9044:17256`) -> `pass`
176
+ - `Button/Secondary/Solid/Default/L/NoIcon` (`9044:17726`) -> `pass`
177
+ - `Button/Specific-Warning/Outline/Hover/L/NoIcon` (`9044:17785`) -> `pass` (`Specific-Warning` mapped to `warning`)
178
+ - `Button/Specific-Success/Text/Default/M/NoIcon` (`9044:17871`) -> `pass` (`Specific-Success` mapped to `success`)
179
+ - `Button/Specific-Error/Solid/Default/L/NoIcon` (`9044:17736`) -> `pass` (`Specific-Error` mapped to `error`)
180
+
181
+ ## Result
182
+
183
+ - Checked components: `60/60`
184
+ - Failed: `0`
185
+ - Pending: `0`
186
+ - Coverage confirmed for style/state/size/icon/color representative set in checklist
187
+
188
+ ## Mapping notes
189
+
190
+ - Figma `Text` style is represented in code by `variant="text"` but uses the `flat` token namespace (`button-*-flat-*`), which is expected in this codebase.
191
+ - Figma `Pressed` and `Loading` are represented by code `active`/`data-loading` styling paths, which match the token model currently used by `Button`.
192
+ - Capsule minimum currently covers icon-end path; add one icon-start capsule node if you want full icon-direction parity.
193
+ - ActionButton alignment fixes applied from this run:
194
+ - `icon + xxs` now uses `10px` icon size in `src/components/ActionButton/ActionButton.styles.ts` to match Figma node set.
195
+ - `outline + disabled` border token now uses `--state-disable-solid` in `src/theme/tokens/components/action-button.css` to match Figma node set.
196
+ - ActionButton nodes under `9044:18042` are round variants; no capsule nodes were discovered from this design group.
197
+ - TextInput alignment fixes applied from this run:
198
+ - `size=sm + rounded=normal` now maps to `rounded-sm` (`6px`) in `src/components/TextInput/TextInput.styles.ts` to match Figma size S.
199
+ - InputFilter alignment fixes applied from this run:
200
+ - Filter icon glyph now scales by input size (`32/22/18`) in `src/components/InputFilter/InputFilter.tsx`.
201
+ - Right segmented function corner now uses size-aware rounding (`8px` for L/M, `6px` for S) in `src/components/InputFilter/InputFilter.styles.ts`.
202
+ - Left input segment now uses segmented border model (no right border, left-only radius, state-aware stroke) via `customInputVariant` in `src/components/Dropdown/Dropdown.styles.ts`.
203
+ - Search alignment fixes applied from this run:
204
+ - `Search` now opts out of dropdown segmented input styling (`segmentedInput={false}`) in `src/components/Search/Search.tsx`, so default state border/shape follows standalone input design.
205
+ - Built-in search icon now uses size-aware glyphs `14/20/24` and matching left spacing offsets in `src/components/TextInput/TextInput.styles.ts`.
206
+ - Tabs alignment fixes applied from this run:
207
+ - `Tabs` active text now uses `text-contrast-max` and disabled state uses `state-disable-outline` in `src/components/Tabs/Tabs.tsx`.
208
+ - Active indicator now uses `function-active-solid`, switches to `function-active-hover` on active hover, and non-active hover indicator uses `function-default-hover`.
209
+ - Tab icon/loading area now normalizes to `12px` and follows state color tokens; default `keepIconSpace` changed to `false` for closer text-only layout parity with Figma matrix.
210
+ - Loading mapping check from this run:
211
+ - `Loading` default (`16px`) matches Figma node `42096:153887` after remapping loading tokens to `transparent/grey/32%` and `brand/RVL yellow`.
212
+ - Checkbox/Radio alignment fixes applied from this run:
213
+ - `Checkbox`: disabled unchecked border changed to `state-disable-outline`; checked/indeterminate disabled remain `state-disable-solid`.
214
+ - `Radio`: disabled unchecked uses `state-disable-outline`, while disabled checked uses `state-disable-solid`.
215
+ - Switch alignment fixes applied from this run:
216
+ - Thumb shadow token updated to match Figma toggle effect (`0 8 16 #00000014`) in `src/theme/tokens/components/switch.css`.
217
+ - Toast alignment fixes applied from this run:
218
+ - `Toast` card shadow updated to `0 8 16 / 0.08`; spacing now uses icon `mr-2` + action `mx-5` model to match `12px` (icon-text) and `24px` (around action).
219
+ - `Toaster` renders action wrapper only when an action is provided; close button offset normalized.
220
+
221
+ ## How to use
222
+
223
+ 1. Add MCP node entries in `src/theme/figma-mcp-component-checklist.json`.
224
+ 2. Ask the agent to "run mapping check from checklist".
225
+ 3. Update this report with pass/fail and mismatches per component.