@godxjp/ui 20.0.0 → 20.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/README.md +8 -2
  2. package/dist/app/app-provider.js +37 -21
  3. package/dist/app/index.d.ts +2 -0
  4. package/dist/app/index.js +2 -0
  5. package/dist/app/storage.d.ts +17 -0
  6. package/dist/app/storage.js +28 -0
  7. package/dist/app/theme-axes.d.ts +2 -0
  8. package/dist/app/theme-axes.js +45 -0
  9. package/dist/components/charts/chart-cartesian.d.ts +2 -1
  10. package/dist/components/charts/chart-cartesian.js +52 -3
  11. package/dist/components/charts/chart-category-axis.d.ts +55 -0
  12. package/dist/components/charts/chart-category-axis.js +93 -0
  13. package/dist/components/charts/chart-frame.d.ts +10 -1
  14. package/dist/components/charts/chart-frame.js +19 -3
  15. package/dist/components/charts/compact-bar-trend.d.ts +1 -1
  16. package/dist/components/charts/compact-bar-trend.js +2 -0
  17. package/dist/components/charts/pie-chart.d.ts +1 -1
  18. package/dist/components/charts/pie-chart.js +12 -1
  19. package/dist/components/charts/recharts-peer.d.ts +49 -0
  20. package/dist/components/charts/recharts-peer.js +45 -0
  21. package/dist/components/data-display/card.d.ts +12 -1
  22. package/dist/components/data-display/card.js +22 -4
  23. package/dist/components/data-display/code-block.js +6 -2
  24. package/dist/components/data-display/data-table.d.ts +39 -4
  25. package/dist/components/data-display/data-table.js +802 -270
  26. package/dist/components/data-display/descriptions.d.ts +27 -6
  27. package/dist/components/data-display/descriptions.js +58 -17
  28. package/dist/components/data-display/index.d.ts +2 -0
  29. package/dist/components/data-display/index.js +2 -0
  30. package/dist/components/data-display/list-row.d.ts +10 -1
  31. package/dist/components/data-display/list-row.js +7 -1
  32. package/dist/components/data-display/popover.d.ts +9 -3
  33. package/dist/components/data-display/popover.js +65 -11
  34. package/dist/components/data-display/range-timeline.d.ts +38 -0
  35. package/dist/components/data-display/range-timeline.js +161 -0
  36. package/dist/components/data-display/scroll-area.js +13 -2
  37. package/dist/components/data-display/service-launcher-card.js +14 -12
  38. package/dist/components/data-display/table.d.ts +71 -3
  39. package/dist/components/data-display/table.js +56 -18
  40. package/dist/components/data-display/tree-list.js +4 -9
  41. package/dist/components/data-entry/calendar.d.ts +2 -2
  42. package/dist/components/data-entry/calendar.js +23 -3
  43. package/dist/components/data-entry/cascader.d.ts +1 -1
  44. package/dist/components/data-entry/cascader.js +188 -24
  45. package/dist/components/data-entry/color-picker.d.ts +1 -1
  46. package/dist/components/data-entry/color-picker.js +17 -5
  47. package/dist/components/data-entry/control-appearance.d.ts +64 -0
  48. package/dist/components/data-entry/control-appearance.js +39 -0
  49. package/dist/components/data-entry/control-surface.d.ts +61 -0
  50. package/dist/components/data-entry/control-surface.js +39 -0
  51. package/dist/components/data-entry/date-picker.d.ts +1 -1
  52. package/dist/components/data-entry/date-picker.js +344 -113
  53. package/dist/components/data-entry/date-range-picker.d.ts +1 -1
  54. package/dist/components/data-entry/date-range-picker.js +278 -140
  55. package/dist/components/data-entry/form-field.d.ts +1 -1
  56. package/dist/components/data-entry/form-field.js +39 -4
  57. package/dist/components/data-entry/form.d.ts +4 -0
  58. package/dist/components/data-entry/form.js +4 -2
  59. package/dist/components/data-entry/index.d.ts +7 -3
  60. package/dist/components/data-entry/index.js +10 -1
  61. package/dist/components/data-entry/input-otp.d.ts +1 -1
  62. package/dist/components/data-entry/input.d.ts +12 -34
  63. package/dist/components/data-entry/input.js +92 -24
  64. package/dist/components/data-entry/month-picker.d.ts +1 -1
  65. package/dist/components/data-entry/month-picker.js +47 -10
  66. package/dist/components/data-entry/month-range-picker.d.ts +1 -1
  67. package/dist/components/data-entry/month-range-picker.js +51 -11
  68. package/dist/components/data-entry/number-input.d.ts +7 -0
  69. package/dist/components/data-entry/number-input.js +147 -98
  70. package/dist/components/data-entry/password-input.d.ts +1 -1
  71. package/dist/components/data-entry/radio.d.ts +1 -1
  72. package/dist/components/data-entry/radio.js +61 -13
  73. package/dist/components/data-entry/search-input.d.ts +1 -1
  74. package/dist/components/data-entry/search-input.js +16 -2
  75. package/dist/components/data-entry/search-select.d.ts +2 -2
  76. package/dist/components/data-entry/search-select.js +209 -78
  77. package/dist/components/data-entry/select.d.ts +22 -4
  78. package/dist/components/data-entry/select.js +215 -163
  79. package/dist/components/data-entry/slider.d.ts +9 -1
  80. package/dist/components/data-entry/slider.js +87 -9
  81. package/dist/components/data-entry/switch.d.ts +3 -0
  82. package/dist/components/data-entry/switch.js +29 -3
  83. package/dist/components/data-entry/textarea.d.ts +14 -56
  84. package/dist/components/data-entry/textarea.js +80 -33
  85. package/dist/components/data-entry/time-picker.d.ts +2 -2
  86. package/dist/components/data-entry/time-picker.js +333 -109
  87. package/dist/components/data-entry/time-range-picker.d.ts +5 -0
  88. package/dist/components/data-entry/time-range-picker.js +89 -0
  89. package/dist/components/data-entry/transfer.d.ts +1 -1
  90. package/dist/components/data-entry/transfer.js +86 -28
  91. package/dist/components/data-entry/tree-select.d.ts +1 -1
  92. package/dist/components/data-entry/tree-select.js +201 -113
  93. package/dist/components/data-entry/tree-utils.js +7 -14
  94. package/dist/components/data-entry/upload-files.d.ts +2 -0
  95. package/dist/components/data-entry/upload-files.js +31 -0
  96. package/dist/components/data-entry/upload-request.d.ts +4 -0
  97. package/dist/components/data-entry/upload-request.js +53 -0
  98. package/dist/components/data-entry/upload-types.d.ts +28 -0
  99. package/dist/components/data-entry/upload-types.js +2 -0
  100. package/dist/components/data-entry/upload.d.ts +2 -2
  101. package/dist/components/data-entry/upload.js +475 -115
  102. package/dist/components/feedback/dialog.js +19 -19
  103. package/dist/components/feedback/sheet.js +3 -0
  104. package/dist/components/feedback/tooltip.js +3 -0
  105. package/dist/components/general/button.d.ts +2 -1
  106. package/dist/components/general/button.js +7 -1
  107. package/dist/components/general/index.d.ts +1 -0
  108. package/dist/components/general/index.js +2 -0
  109. package/dist/components/general/typography.d.ts +3 -0
  110. package/dist/components/general/typography.js +15 -1
  111. package/dist/components/general/visually-hidden.d.ts +3 -0
  112. package/dist/components/general/visually-hidden.js +9 -0
  113. package/dist/components/layout/app-launcher.d.ts +34 -0
  114. package/dist/components/layout/app-launcher.js +261 -0
  115. package/dist/components/layout/app-shell.d.ts +3 -1
  116. package/dist/components/layout/app-shell.js +34 -14
  117. package/dist/components/layout/auth-shell.d.ts +1 -1
  118. package/dist/components/layout/auth-shell.js +2 -0
  119. package/dist/components/layout/breadcrumb.d.ts +14 -2
  120. package/dist/components/layout/breadcrumb.js +46 -4
  121. package/dist/components/layout/flex.d.ts +1 -1
  122. package/dist/components/layout/flex.js +23 -2
  123. package/dist/components/layout/index.d.ts +3 -0
  124. package/dist/components/layout/index.js +5 -1
  125. package/dist/components/layout/org-switcher.js +20 -1
  126. package/dist/components/layout/page-container.d.ts +1 -1
  127. package/dist/components/layout/page-container.js +5 -3
  128. package/dist/components/layout/responsive-grid.d.ts +16 -2
  129. package/dist/components/layout/responsive-grid.js +29 -2
  130. package/dist/components/layout/sidebar.js +2 -1
  131. package/dist/components/layout/topbar-item.d.ts +3 -0
  132. package/dist/components/layout/topbar-item.js +18 -3
  133. package/dist/components/layout/topbar.d.ts +1 -1
  134. package/dist/components/layout/topbar.js +27 -6
  135. package/dist/components/navigation/dropdown-menu.d.ts +30 -2
  136. package/dist/components/navigation/dropdown-menu.js +73 -11
  137. package/dist/components/navigation/pagination.d.ts +2 -2
  138. package/dist/components/navigation/pagination.js +155 -83
  139. package/dist/components/navigation/steps.d.ts +2 -2
  140. package/dist/components/navigation/steps.js +29 -4
  141. package/dist/components/navigation/tabs.d.ts +5 -33
  142. package/dist/components/navigation/tabs.js +232 -64
  143. package/dist/components/ui/hover-card.js +3 -0
  144. package/dist/components/ui/input-otp.d.ts +26 -28
  145. package/dist/components/ui/input-otp.js +50 -7
  146. package/dist/components/ui/password-input.d.ts +36 -2
  147. package/dist/components/ui/password-input.js +27 -7
  148. package/dist/components/ui/rating.d.ts +25 -0
  149. package/dist/components/ui/rating.js +67 -27
  150. package/dist/components/ui/segmented.d.ts +9 -0
  151. package/dist/components/ui/segmented.js +17 -2
  152. package/dist/components/ui/separator.d.ts +4 -0
  153. package/dist/components/ui/separator.js +13 -0
  154. package/dist/components/ui/tag-input.d.ts +45 -0
  155. package/dist/components/ui/tag-input.js +109 -27
  156. package/dist/form/form-context.d.ts +29 -0
  157. package/dist/form/form-context.js +44 -4
  158. package/dist/form/form-field-array.d.ts +22 -0
  159. package/dist/form/form-field-array.js +50 -0
  160. package/dist/form/form-field-control.d.ts +2 -1
  161. package/dist/form/form-field-control.js +116 -40
  162. package/dist/form/form-root.d.ts +2 -1
  163. package/dist/form/form-root.js +142 -23
  164. package/dist/form/index.d.ts +3 -1
  165. package/dist/form/index.js +12 -1
  166. package/dist/i18n/index.d.ts +1 -1
  167. package/dist/i18n/index.js +3 -1
  168. package/dist/i18n/messages/en.json +59 -6
  169. package/dist/i18n/messages/ja.json +59 -6
  170. package/dist/i18n/messages/vi.json +59 -6
  171. package/dist/i18n/translate.d.ts +19 -0
  172. package/dist/i18n/translate.js +24 -0
  173. package/dist/inertia/index.d.ts +20 -0
  174. package/dist/inertia/index.js +60 -1
  175. package/dist/lib/control-styles.d.ts +25 -3
  176. package/dist/lib/control-styles.js +9 -3
  177. package/dist/lib/datetime/picker-format.d.ts +8 -0
  178. package/dist/lib/datetime/picker-format.js +54 -0
  179. package/dist/lib/overlay-portal.d.ts +18 -0
  180. package/dist/lib/overlay-portal.js +17 -0
  181. package/dist/props/components/app.prop.d.ts +13 -2
  182. package/dist/props/components/charts.prop.d.ts +21 -0
  183. package/dist/props/components/data-display.prop.d.ts +55 -4
  184. package/dist/props/components/data-entry.prop.d.ts +687 -43
  185. package/dist/props/components/form.prop.d.ts +142 -4
  186. package/dist/props/components/general.prop.d.ts +30 -1
  187. package/dist/props/components/index.d.ts +2 -2
  188. package/dist/props/components/layout.prop.d.ts +255 -8
  189. package/dist/props/components/navigation.prop.d.ts +113 -3
  190. package/dist/props/registry.d.ts +376 -10
  191. package/dist/props/registry.js +493 -9
  192. package/dist/props/vocabulary/data.prop.d.ts +179 -1
  193. package/dist/props/vocabulary/index.d.ts +4 -4
  194. package/dist/props/vocabulary/interaction.prop.d.ts +51 -2
  195. package/dist/props/vocabulary/navigation.prop.d.ts +40 -0
  196. package/dist/props/vocabulary/shared.prop.d.ts +33 -0
  197. package/dist/styles/badge-layout.css +2 -1
  198. package/dist/styles/card-layout.css +36 -5
  199. package/dist/styles/chart-layout.css +17 -1
  200. package/dist/styles/control.css +520 -14
  201. package/dist/styles/data-display-layout.css +248 -7
  202. package/dist/styles/data-entry-layout.css +13 -0
  203. package/dist/styles/layout.css +221 -4
  204. package/dist/styles/navigation-layout.css +230 -1
  205. package/dist/styles/shell-layout.css +690 -21
  206. package/dist/styles/table-layout.css +95 -6
  207. package/dist/styles/text-layout.css +5 -0
  208. package/dist/tokens/base.css +1 -0
  209. package/dist/tokens/components/badge.css +1 -0
  210. package/dist/tokens/components/chart.css +6 -0
  211. package/dist/tokens/components/control.css +81 -3
  212. package/dist/tokens/components/data-display.css +9 -0
  213. package/dist/tokens/components/descriptions.css +11 -0
  214. package/dist/tokens/components/flex.css +8 -0
  215. package/dist/tokens/components/navigation.css +55 -0
  216. package/dist/tokens/components/shell.css +100 -5
  217. package/dist/tokens/components/table.css +14 -0
  218. package/dist/tokens/foundation.css +2 -0
  219. package/dist/tokens/semantic/layout.css +9 -0
  220. package/docs/CONSUMER-RULES.md +13 -0
  221. package/docs/DESIGN-AUTHORITY.md +43 -6
  222. package/docs/DEVELOPMENT.md +4 -3
  223. package/docs/FORMS.md +151 -6
  224. package/docs/FRAME-COVERAGE-REPORT.md +29 -16
  225. package/docs/README.md +1 -1
  226. package/docs/STANDARDS-vocabulary-tokens.md +1 -1
  227. package/docs/TESTING.md +15 -6
  228. package/docs/charts/cjk-category-axis.tsx +81 -0
  229. package/docs/data-display/card/index.tsx +22 -0
  230. package/docs/data-display/data-table/examples/antd-parity.tsx +257 -0
  231. package/docs/data-display/data-table/index.tsx +23 -0
  232. package/docs/data-display/descriptions.tsx +41 -0
  233. package/docs/data-display/list-row.tsx +6 -6
  234. package/docs/data-display/scroll-area.tsx +31 -25
  235. package/docs/data-display/table.tsx +104 -45
  236. package/docs/data-display/timeline.tsx +41 -0
  237. package/docs/data-entry/date-picker.tsx +85 -0
  238. package/docs/data-entry/date-range-picker.tsx +26 -0
  239. package/docs/data-entry/form-dynamic-fields.tsx +199 -0
  240. package/docs/data-entry/form.tsx +74 -4
  241. package/docs/data-entry/input-otp.tsx +24 -0
  242. package/docs/data-entry/input.tsx +46 -1
  243. package/docs/data-entry/month-range-picker.tsx +1 -1
  244. package/docs/data-entry/select.tsx +27 -0
  245. package/docs/data-entry/switch.tsx +41 -0
  246. package/docs/data-entry/textarea.tsx +38 -0
  247. package/docs/data-entry/time-picker.tsx +85 -1
  248. package/docs/data-entry/time-range-picker.tsx +55 -0
  249. package/docs/data-entry/transfer.tsx +17 -0
  250. package/docs/data-entry/upload.tsx +56 -12
  251. package/docs/feedback/tooltip.tsx +1 -1
  252. package/docs/general/activity.tsx +2 -2
  253. package/docs/general/button/index.tsx +14 -1
  254. package/docs/general/typography.tsx +14 -1
  255. package/docs/layout/app-launcher.tsx +195 -0
  256. package/docs/layout/app-shell-arrangements.tsx +5 -5
  257. package/docs/layout/app-shell.tsx +11 -0
  258. package/docs/layout/flex.tsx +50 -0
  259. package/docs/layout/responsive-grid.tsx +21 -1
  260. package/docs/layout/topbar.tsx +5 -9
  261. package/docs/navigation/app-setting-picker.tsx +11 -0
  262. package/docs/navigation/breadcrumb.tsx +48 -0
  263. package/docs/navigation/dropdown-menu.tsx +21 -0
  264. package/docs/navigation/pagination.tsx +52 -0
  265. package/docs/navigation/steps.tsx +37 -0
  266. package/docs/navigation/tabs.tsx +97 -1
  267. package/docs/query/button-refetch.tsx +1 -0
  268. package/docs/showcase/settings-security-mfa.tsx +3 -3
  269. package/package.json +24 -4
  270. package/scripts/_agent-setup.mjs +76 -9
  271. package/scripts/init-guinea-pig.mjs +26 -4
  272. package/scripts/ui-audit.mjs +243 -30
  273. package/scripts/visual-audit.mjs +45 -7
@@ -46,6 +46,17 @@ const journalItems = [
46
46
 
47
47
  export default function Demo() {
48
48
  const [activeTab, setActiveTab] = useState("pending");
49
+ const [editableTabs, setEditableTabs] = useState([
50
+ { value: "je-0042", label: "JE-0042", content: <Text as="p">売上計上 ¥480,000</Text> },
51
+ { value: "je-0043", label: "JE-0043", content: <Text as="p">仕入計上 ¥120,000</Text> },
52
+ {
53
+ value: "je-0040",
54
+ label: "JE-0040 (固定)",
55
+ content: <Text as="p">給与支払 ¥2,800,000</Text>,
56
+ closable: false,
57
+ },
58
+ ]);
59
+ const [editableTab, setEditableTab] = useState("je-0042");
49
60
 
50
61
  return (
51
62
  <PageContainer
@@ -106,7 +117,7 @@ export default function Demo() {
106
117
  <CardTitle level={2}>320px stress · 長いローカライズラベル</CardTitle>
107
118
  <CardDescription>
108
119
  狭いコンテナでも長いラベルはクリップされず、水平タブリストが自身でスクロールする
109
- 。compact navigation への変換は Tabs API に存在しないため擬似実装しない
120
+ 。compact navigation への変換は Tabs API に存在しないため擬似実装しない ·
110
121
  スクロールが意図した縮退動作。
111
122
  </CardDescription>
112
123
  </CardHeader>
@@ -308,6 +319,91 @@ export default function Demo() {
308
319
  </Flex>
309
320
  </CardContent>
310
321
  </Card>
322
+
323
+ {/* Ant Design parity surface — editable-card + extra + centered + placement + size */}
324
+ <Card>
325
+ <CardHeader>
326
+ <CardTitle level={2}>Editable card · onEdit / extra / hideAdd</CardTitle>
327
+ <CardDescription>
328
+ variant=&quot;editable-card&quot; は Ant Design の editable-card。タブ内の ×
329
+ はポインタ用ショートカット(aria-hidden)で、キーボードでは Delete /
330
+ Backspace(aria-keyshortcuts)。追加ボタンは tablist の外にある本物の button。extra は
331
+ antd の tabBarExtraContent を論理軸(start / end)にしたもの。
332
+ </CardDescription>
333
+ </CardHeader>
334
+ <CardContent>
335
+ <Tabs
336
+ id="antd-editable-card"
337
+ variant="editable-card"
338
+ value={editableTab}
339
+ onValueChange={setEditableTab}
340
+ onEdit={(target, action) => {
341
+ if (action === "add") {
342
+ const next = `tab-${editableTabs.length + 1}`;
343
+ setEditableTabs([
344
+ ...editableTabs,
345
+ {
346
+ value: next,
347
+ label: `新規 ${editableTabs.length + 1}`,
348
+ content: <Text as="p">新規タブ {next}</Text>,
349
+ },
350
+ ]);
351
+ setEditableTab(next);
352
+ return;
353
+ }
354
+ const rest = editableTabs.filter((item) => item.value !== target);
355
+ setEditableTabs(rest);
356
+ if (target === editableTab && rest[0]) setEditableTab(rest[0].value);
357
+ }}
358
+ extra={{
359
+ end: (
360
+ <Button size="sm" variant="outline">
361
+ 一括操作
362
+ </Button>
363
+ ),
364
+ }}
365
+ items={editableTabs}
366
+ />
367
+ </CardContent>
368
+ </Card>
369
+
370
+ <Card>
371
+ <CardHeader>
372
+ <CardTitle level={2}>tabPlacement · size · centered</CardTitle>
373
+ <CardDescription>
374
+ tabPlacement は antd 6.6.2 の名前で、値は論理軸(top / bottom / start / end)。start /
375
+ end は tablist を縦方向のロービングフォーカスに切り替える。size はライブラリの control
376
+ band(sm / md / lg)に対応。
377
+ </CardDescription>
378
+ </CardHeader>
379
+ <CardContent>
380
+ <Flex direction="col" gap="lg">
381
+ <Tabs
382
+ id="antd-centered"
383
+ defaultValue="pending"
384
+ variant="line"
385
+ centered
386
+ items={journalItems}
387
+ />
388
+ <Tabs
389
+ id="antd-bottom"
390
+ defaultValue="pending"
391
+ variant="card"
392
+ tabPlacement="bottom"
393
+ size="sm"
394
+ items={journalItems}
395
+ />
396
+ <Tabs
397
+ id="antd-start"
398
+ defaultValue="pending"
399
+ variant="line"
400
+ tabPlacement="start"
401
+ size="lg"
402
+ items={journalItems}
403
+ />
404
+ </Flex>
405
+ </CardContent>
406
+ </Card>
311
407
  </Flex>
312
408
  </PageContainer>
313
409
  );
@@ -81,6 +81,7 @@ function VariantBlock() {
81
81
  <ButtonRefetch query={query} variant="ghost" label="ghost" />
82
82
  <ButtonRefetch query={query} variant="destructive" label="destructive" />
83
83
  <ButtonRefetch query={query} variant="link" label="link" />
84
+ <ButtonRefetch query={query} variant="bare" label="bare" />
84
85
  </Flex>
85
86
  </CardContent>
86
87
  </Card>
@@ -78,7 +78,7 @@ export default function SecurityMfaShowcase() {
78
78
  </CardHeader>
79
79
  <CardContent flush>
80
80
  <ListRow
81
- leading={<Mail aria-hidden="true" className="size-4" />}
81
+ leading={<Mail aria-hidden="true" />}
82
82
  title="OTP qua email"
83
83
  description="Gửi mã tới t•••@famgia.com"
84
84
  trailing={
@@ -91,7 +91,7 @@ export default function SecurityMfaShowcase() {
91
91
  }
92
92
  />
93
93
  <ListRow
94
- leading={<Smartphone aria-hidden="true" className="size-4" />}
94
+ leading={<Smartphone aria-hidden="true" />}
95
95
  title="Ứng dụng xác thực"
96
96
  description="Chưa thiết lập"
97
97
  trailing={
@@ -101,7 +101,7 @@ export default function SecurityMfaShowcase() {
101
101
  }
102
102
  />
103
103
  <ListRow
104
- leading={<KeyRound aria-hidden="true" className="size-4" />}
104
+ leading={<KeyRound aria-hidden="true" />}
105
105
  title="Passkey"
106
106
  description="1 thiết bị · MacBook Pro"
107
107
  trailing={
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@godxjp/ui",
3
- "version": "20.0.0",
4
- "godxUiMcp": "20.0.0",
3
+ "version": "20.2.0",
4
+ "godxUiMcp": "20.2.0",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -85,6 +85,22 @@
85
85
  "types": "./dist/components/charts/compact-bar-trend.d.ts",
86
86
  "import": "./dist/components/charts/compact-bar-trend.js"
87
87
  },
88
+ "./charts/line-chart": {
89
+ "types": "./dist/components/charts/line-chart.d.ts",
90
+ "import": "./dist/components/charts/line-chart.js"
91
+ },
92
+ "./charts/bar-chart": {
93
+ "types": "./dist/components/charts/bar-chart.d.ts",
94
+ "import": "./dist/components/charts/bar-chart.js"
95
+ },
96
+ "./charts/area-chart": {
97
+ "types": "./dist/components/charts/area-chart.d.ts",
98
+ "import": "./dist/components/charts/area-chart.js"
99
+ },
100
+ "./charts/pie-chart": {
101
+ "types": "./dist/components/charts/pie-chart.d.ts",
102
+ "import": "./dist/components/charts/pie-chart.js"
103
+ },
88
104
  "./ui": {
89
105
  "types": "./dist/components/ui/index.d.ts",
90
106
  "import": "./dist/components/ui/index.js"
@@ -316,6 +332,7 @@
316
332
  "test:visual:auth-registration": "node scripts/auth-shell-registration-visual.mjs",
317
333
  "test:visual:topbar-collision": "node scripts/topbar-collision-visual.mjs",
318
334
  "test:visual:table-collection-cjk": "node scripts/table-collection-cjk-visual.mjs",
335
+ "test:visual:chart-cjk-axis": "node scripts/chart-cjk-axis-visual.mjs",
319
336
  "test:watch": "vitest",
320
337
  "test:coverage": "vitest run --coverage",
321
338
  "check:example-imports": "node scripts/check-example-imports.mjs",
@@ -340,8 +357,8 @@
340
357
  "verify": "pnpm typecheck && pnpm lint && pnpm format && pnpm build && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:frame-coverage && pnpm test",
341
358
  "verify:static": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:token-scale-bypass && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:mcp-prop-sync && pnpm check:contrast && pnpm check:visual-audit && pnpm test",
342
359
  "verify:ci": "pnpm verify:ci:static && pnpm check:frame-contracts && pnpm test",
343
- "verify:ci:static": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:registry && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:no-antd-runtime && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:gate-coverage && pnpm check:mcp-prop-sync",
344
- "verify:browser": "pnpm check:contrast && pnpm check:visual-audit",
360
+ "verify:ci:static": "pnpm build && pnpm check:packed-public-contract && pnpm typecheck && pnpm typecheck:docs && pnpm lint && pnpm preview:build && pnpm check:registry && pnpm check:example-imports && pnpm check:core-isolation && pnpm check:no-consumer-coupling && pnpm check:use-client && pnpm check:prop-vocabulary && pnpm check:token-tiers && pnpm check:no-external-assets && pnpm check:token-scale-bypass && pnpm check:no-antd-runtime && pnpm check:dist-tokens-resolve && pnpm check:no-hardcoded-geometry && pnpm check:no-hardcoded-css-values && pnpm check:no-inline-magic-numbers && pnpm check:no-tailwind-class-assertions && pnpm check:control-sizing && pnpm check:rtl && pnpm check:typography && pnpm check:mcp-lockstep && pnpm check:mcp-sync && pnpm check:doc-prop-existence && pnpm check:mcp-catalog-coverage && pnpm check:mcp-orphans && pnpm check:mcp-pattern-imports && pnpm check:audit-sync && pnpm check:gate-coverage && pnpm check:mcp-prop-sync && pnpm check:catalog-contradictions",
361
+ "verify:browser": "pnpm check:contrast && pnpm check:text-ink-clip && pnpm check:visual-audit",
345
362
  "verify:release": "pnpm verify:static && pnpm check:frame-contracts && pnpm check:frame-coverage && pnpm check:frame-axe",
346
363
  "verify:publish-tree": "pnpm build && pnpm check:packed-public-contract && pnpm check:use-client && pnpm check:dist-tokens-resolve",
347
364
  "check:release-plan": "node scripts/check-release-command-plan.mjs",
@@ -351,6 +368,7 @@
351
368
  "check:mcp-sync": "node scripts/check-mcp-sync.mjs",
352
369
  "check:mcp-catalog-coverage": "node scripts/check-mcp-catalog-coverage.mjs",
353
370
  "check:mcp-orphans": "node scripts/check-mcp-orphans.mjs",
371
+ "check:catalog-contradictions": "node scripts/check-catalog-contradictions.mjs",
354
372
  "check:mcp-prop-sync": "node scripts/check-mcp-prop-sync.mjs",
355
373
  "check:doc-prop-existence": "node scripts/check-doc-prop-existence.mjs",
356
374
  "gen:component-api-manifest": "node scripts/gen-component-api-manifest.mjs",
@@ -387,6 +405,7 @@
387
405
  "check:audit-sync": "node scripts/check-audit-sync.mjs",
388
406
  "check:gate-coverage": "node scripts/check-gate-coverage.mjs",
389
407
  "check:contrast": "node scripts/check-contrast.mjs",
408
+ "check:text-ink-clip": "node scripts/check-text-ink-clip.mjs",
390
409
  "visual-audit": "node scripts/visual-audit.mjs",
391
410
  "check:visual-audit": "node scripts/visual-audit-smoke.mjs",
392
411
  "check:frame-axe": "node scripts/check-frame-axe.mjs",
@@ -466,6 +485,7 @@
466
485
  "react-aria-components": "^1.21.1",
467
486
  "react-day-picker": "^10.0.1",
468
487
  "react-resizable-panels": "^4.12.3",
488
+ "react-stately": "3.50.0",
469
489
  "sonner": "^2.0.8",
470
490
  "tailwind-merge": "^3.5.0",
471
491
  "tailwindcss-animate": "^1.0.7",
@@ -74,8 +74,21 @@ or change a component, page, or form — no exceptions.
74
74
  \`rounded border\` div. Text is \`<Text tone size weight truncate>\`, never utility classes.
75
75
 
76
76
  ## Before writing UI
77
- 1. **MCP-first.** Consult the godx-ui MCP: \`get_component <Name>\`, \`search_components\`,
78
- \`list_audit_rules\`, \`list_visual_checks\`. Never guess a prop; never hand-roll what a
77
+ 1. **DISCOVERY BEFORE LOOKUP in this order, every time.**
78
+ 1. \`search_components "<the area you are about to build>"\` FIRST. This is the only call that
79
+ answers "what already exists here". Ask it before the first line of JSX, not after.
80
+ 2. \`get_component <Name>\` second, once you know the name.
81
+ \`get_component\` answers "how do I use X" and is USELESS for finding X — you can only look up a
82
+ name you already have. Skipping step 1 is how a consumer hand-rolled an organization switcher
83
+ the package ships (\`OrgSwitcher\`) and built three topbar cells out of Buttons instead of
84
+ \`TopbarItem\`: both were one \`search_components\` call away, and neither was ever searched for.
85
+ **Existing code in this repo is NOT the authority.** Reading a neighbouring file and copying it
86
+ is the most common way this rule gets skipped — measured: of four fresh agents given a vague UI
87
+ task, all four answered correctly but two never called the MCP at all, saying the answer was
88
+ already in the code. They were only right because that code had just been fixed; a week earlier
89
+ the same files hand-rolled a switcher and put Buttons in topbar slots, and both agents would
90
+ have copied it. Search the catalog even when a local file looks like it already answers you.
91
+ Also \`list_audit_rules\`, \`list_visual_checks\`. Never guess a prop; never hand-roll what a
79
92
  primitive already does.
80
93
  2. **Real primitives only.** No raw \`<input>/<select>/<button>/<textarea>/<table>\`, no
81
94
  styled-div fakes. A labelled control ALWAYS goes in \`<FormField label=…>\` (it owns the
@@ -105,8 +118,21 @@ This app uses @godxjp/ui. EVERY time you build or change UI:
105
118
  \`PageContainer\`; siblings go in \`<Flex direction="col" gap>\` / \`<ResponsiveGrid>\`; no
106
119
  \`flex\`/\`grid\`/\`gap-*\`/\`p-*\`/\`m-*\` on your own elements; boxes are \`Card\`/\`Badge\`/
107
120
  \`ListRow\`/\`Descriptions\`, never a \`rounded border\` div; text is \`<Text tone size weight>\`.
108
- 1. **MCP-first.** Consult the \`godx-ui\` MCP \`get_component\`, \`search_components\`,
109
- \`list_audit_rules\`, \`list_visual_checks\`. Never guess a prop; never hand-roll what a
121
+ 1. **DISCOVERY BEFORE LOOKUP in this order, every time.**
122
+ 1. \`search_components "<the area you are about to build>"\` FIRST. This is the only call that
123
+ answers "what already exists here". Ask it before the first line of JSX, not after.
124
+ 2. \`get_component <Name>\` second, once you know the name.
125
+ \`get_component\` answers "how do I use X" and is USELESS for finding X — you can only look up a
126
+ name you already have. Skipping step 1 is how a consumer hand-rolled an organization switcher
127
+ the package ships (\`OrgSwitcher\`) and built three topbar cells out of Buttons instead of
128
+ \`TopbarItem\`: both were one \`search_components\` call away, and neither was ever searched for.
129
+ **Existing code in this repo is NOT the authority.** Reading a neighbouring file and copying it
130
+ is the most common way this rule gets skipped — measured: of four fresh agents given a vague UI
131
+ task, all four answered correctly but two never called the MCP at all, saying the answer was
132
+ already in the code. They were only right because that code had just been fixed; a week earlier
133
+ the same files hand-rolled a switcher and put Buttons in topbar slots, and both agents would
134
+ have copied it. Search the catalog even when a local file looks like it already answers you.
135
+ Also \`list_audit_rules\`, \`list_visual_checks\`. Never guess a prop; never hand-roll what a
110
136
  primitive already does.
111
137
  2. **Real primitives only.** No raw \`<input>/<select>/<button>/<textarea>/<table>\`. A labelled
112
138
  control ALWAYS goes in \`<FormField label=…>\` — never a bare \`<Label>\`+\`<Input>\`. Semantic
@@ -192,10 +218,13 @@ export function writeWorkflowMd(root) {
192
218
  const path = join(root, ".claude", "godxjp-ui-workflow.md");
193
219
  mkdirSync(dirname(path), { recursive: true });
194
220
  // This file is owned entirely by the package — the CLAUDE.md block tells the consumer to edit
195
- // it, but nothing else reads from it, so a stale copy is pure loss. Rewrite when the stamp moves.
221
+ // it, but nothing else reads from it, so a stale copy is pure loss. It is package-owned end to
222
+ // end, so the comparison is the BODY: a version check froze every consumer whose stamp already
223
+ // matched, which meant guidance edited between releases reached nobody while still reading as
224
+ // current. Same defect as ensureClaudeMd carried, same fix.
196
225
  if (existsSync(path)) {
197
226
  const cur = readFileSync(path, "utf8");
198
- if (stampedVersion(cur) === KIT_VERSION) return false;
227
+ if (cur.trim() === WORKFLOW_MD.trim()) return false;
199
228
  writeFileSync(path, WORKFLOW_MD);
200
229
  return "refreshed";
201
230
  }
@@ -207,13 +236,34 @@ export function writeWorkflowMd(root) {
207
236
  * Append the godxjp-ui mandate to the consumer's CLAUDE.md (created if absent). Idempotent via the
208
237
  * markers.
209
238
  */
239
+
240
+ /**
241
+ * Is the managed region in `existing` already byte-identical to what we would write?
242
+ *
243
+ * Digest first (cheap, and survives whitespace-only rewrites of the surrounding file). When the
244
+ * stamp predates digest stamping there is nothing to compare, so fall back to the region body
245
+ * itself rather than assuming current — assuming current is the bug this replaced.
246
+ */
247
+ function blockIsCurrent(existing, block) {
248
+ const wanted = stampedDigest(block);
249
+ const have = stampedDigest(existing);
250
+ if (wanted && have) return wanted === have;
251
+ const region = (text) => text.slice(text.indexOf("<!-- godxjp-ui:start"), text.indexOf("<!-- godxjp-ui:end -->"));
252
+ return region(existing).trim() === region(block).trim();
253
+ }
254
+
210
255
  export function ensureClaudeMd(root) {
211
256
  const path = join(root, "CLAUDE.md");
212
257
  const existing = existsSync(path) ? readFileSync(path, "utf8") : null;
213
258
  if (existing?.includes("godxjp-ui:start")) {
214
259
  // Present — but at WHICH version? Refresh only the delimited block; anything the consumer
215
260
  // wrote around it is untouched.
216
- if (stampedVersion(existing) === KIT_VERSION) return "present";
261
+ // Compare the DIGEST, not the version — which is what the note above already promised and
262
+ // what this line did not do. Guidance is edited far more often than the package version moves,
263
+ // so a version check freezes every consumer whose stamp already matches: a rewritten mandate
264
+ // reached nobody, and the block still read as current. A file written before digest stamping
265
+ // has no digest at all, so fall back to comparing the rendered body.
266
+ if (blockIsCurrent(existing, CLAUDE_MD_BLOCK)) return "present";
217
267
  writeFileSync(
218
268
  path,
219
269
  refreshBlock(existing, CLAUDE_MD_BLOCK, "<!-- godxjp-ui:start", "<!-- godxjp-ui:end -->"),
@@ -255,17 +305,34 @@ export function refreshGuineaPigSkill(root) {
255
305
  const target = join(dir, "SKILL.md");
256
306
  const optin = join(dir, ".guinea-pig-optin");
257
307
  if (!existsSync(optin) || !existsSync(target)) return false;
258
- if (readFileSync(optin, "utf8").trim() === KIT_VERSION) return false;
259
308
 
260
309
  const base = readFileSync(join(SELF_ROOT, "scripts", "guinea-pig-skill.md"), "utf8");
310
+ /*
311
+ * The marker tracks the BASE TEXT, not the release — the same correction the consumer rule file
312
+ * needed, for the same reason. A version marker means editing this skill without cutting a
313
+ * release reaches nobody, and the skill is edited far more often than the version moves. The
314
+ * digest covers only the base: everything from the `# 8.` marker down belongs to the repo and
315
+ * must not make the package's own content look changed.
316
+ *
317
+ * `<version>:<digest>` rather than a bare digest, so the file still says which release wrote it
318
+ * to anyone reading it. Only the digest half is compared.
319
+ */
320
+ const stamp = `${KIT_VERSION}:${digestOf(base)}`;
321
+ if (readFileSync(optin, "utf8").trim().split(":").pop() === digestOf(base)) return false;
322
+
261
323
  const current = readFileSync(target, "utf8");
262
324
  const marker = "\n---\n\n# 8. ";
263
325
  const i = current.indexOf(marker);
264
326
  writeFileSync(target, base.replace(/\s*$/, "") + "\n" + (i < 0 ? "" : current.slice(i)));
265
- writeFileSync(optin, `${KIT_VERSION}\n`);
327
+ writeFileSync(optin, `${stamp}\n`);
266
328
  return true;
267
329
  }
268
330
 
331
+ /** The stamp `init-guinea-pig` writes on a fresh install, so the first refresh is a no-op. */
332
+ export function guineaPigStamp() {
333
+ return `${KIT_VERSION}:${digestOf(readFileSync(join(SELF_ROOT, "scripts", "guinea-pig-skill.md"), "utf8"))}`;
334
+ }
335
+
269
336
  /**
270
337
  * Install the common consumer rules as a PATH-TRIGGERED file, and wire them into `.ai/rules`.
271
338
  *
@@ -11,7 +11,7 @@ import { copyFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
11
11
  import { dirname, join } from "node:path";
12
12
  import { fileURLToPath } from "node:url";
13
13
 
14
- import { KIT_VERSION, shouldSkip } from "./_agent-setup.mjs";
14
+ import { KIT_VERSION, guineaPigStamp, shouldSkip } from "./_agent-setup.mjs";
15
15
 
16
16
  const root = process.env.INIT_CWD || process.cwd();
17
17
  const skip = shouldSkip(root);
@@ -28,10 +28,32 @@ if (skip === "no-package") {
28
28
  const source = join(dirname(fileURLToPath(import.meta.url)), "guinea-pig-skill.md");
29
29
  const target = join(root, ".claude", "skills", "godx-ui-guinea-pig", "SKILL.md");
30
30
 
31
+ const optin = join(dirname(target), ".guinea-pig-optin");
32
+
31
33
  if (existsSync(target)) {
32
- console.log(` guinea-pig skill already present:\n ${target}`);
34
+ /*
35
+ * PRESENT IS NOT THE SAME AS OPTED IN, and this used to exit here regardless — printing "its
36
+ * BASE sections now refresh on `npm update`" at a repo where they never would.
37
+ *
38
+ * `refreshGuineaPigSkill` keys entirely off the marker: no marker, no refresh, ever, and no
39
+ * report of it either. Measured across the three guinea pigs: one carried the marker and kept
40
+ * up; two had SKILL.md copied by an older path and had been reading whatever guidance was
41
+ * current the day it landed. Re-running is exactly how someone would try to fix that, so
42
+ * re-running has to actually fix it.
43
+ */
44
+ if (!existsSync(optin)) {
45
+ writeFileSync(optin, `${guineaPigStamp()}\n`);
46
+ console.log(`
47
+ guinea-pig skill was present but NOT opted in — its base sections would never have refreshed.
48
+ Marker written; it now tracks @godxjp/ui@${KIT_VERSION}:
49
+ • ${target}
50
+ `);
51
+ process.exit(0);
52
+ }
53
+
54
+ console.log(` guinea-pig skill already present and opted in:\n ${target}`);
33
55
  console.log(
34
- "\n Its BASE sections now refresh on `npm update @godxjp/ui`; anything you appended below\n" +
56
+ "\n Its BASE sections refresh on `npm update @godxjp/ui`; anything you appended below\n" +
35
57
  " the `# 8.` marker is preserved. Re-running this command changes nothing.\n",
36
58
  );
37
59
  process.exit(0);
@@ -48,7 +70,7 @@ copyFileSync(source, target);
48
70
  * exact staleness this whole change exists to remove. The marker lives next to the skill rather
49
71
  * than in package.json so it travels with the thing it describes.
50
72
  */
51
- writeFileSync(join(dirname(target), ".guinea-pig-optin"), `${KIT_VERSION}\n`);
73
+ writeFileSync(optin, `${guineaPigStamp()}\n`);
52
74
 
53
75
  console.log(`
54
76
  guinea-pig skill installed: