@godxjp/ui 31.31.7 → 32.0.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 (728) hide show
  1. package/README.md +102 -121
  2. package/agent/START-HERE.md +10 -10
  3. package/agent/components/Accordion.json +2 -2
  4. package/agent/components/AccountChip.json +1 -1
  5. package/agent/components/Actions.json +1 -1
  6. package/agent/components/Activity.json +2 -2
  7. package/agent/components/Affix.json +1 -1
  8. package/agent/components/Alert.json +22 -6
  9. package/agent/components/AlertDialog.json +8 -1
  10. package/agent/components/Anchor.json +4 -3
  11. package/agent/components/AppLauncher.json +2 -2
  12. package/agent/components/AppProvider.json +19 -11
  13. package/agent/components/AppSettingPicker.json +18 -2
  14. package/agent/components/AppShell.json +4 -5
  15. package/agent/components/AreaChart.json +0 -1
  16. package/agent/components/AspectRatio.json +2 -2
  17. package/agent/components/Attachments.json +3 -3
  18. package/agent/components/AuthAccountSummary.json +1 -1
  19. package/agent/components/AuthDivider.json +1 -1
  20. package/agent/components/AuthExpiryProvider.json +0 -1
  21. package/agent/components/AuthFooter.json +2 -2
  22. package/agent/components/AuthIdentity.json +3 -3
  23. package/agent/components/AuthStack.json +1 -1
  24. package/agent/components/Avatar.json +2 -12
  25. package/agent/components/Badge.json +1 -1
  26. package/agent/components/BarChart.json +0 -1
  27. package/agent/components/BranchScopePicker.json +1 -1
  28. package/agent/components/Breadcrumb.json +1 -1
  29. package/agent/components/Button.json +3 -3
  30. package/agent/components/Calendar.json +1 -1
  31. package/agent/components/Card.json +2 -2
  32. package/agent/components/CardBar.json +0 -1
  33. package/agent/components/CardContent.json +0 -1
  34. package/agent/components/Carousel.json +4 -3
  35. package/agent/components/Cascader.json +1 -1
  36. package/agent/components/CenteredShell.json +78 -17
  37. package/agent/components/ChatBubble.json +3 -3
  38. package/agent/components/ChatBubbleList.json +3 -3
  39. package/agent/components/ChatComposer.json +3 -3
  40. package/agent/components/ChatSuggestion.json +3 -3
  41. package/agent/components/Checkbox.json +1 -1
  42. package/agent/components/CheckboxGroup.json +0 -1
  43. package/agent/components/CodeBlock.json +1 -1
  44. package/agent/components/Collapsible.json +4 -4
  45. package/agent/components/ColorPicker.json +1 -1
  46. package/agent/components/Command.json +5 -5
  47. package/agent/components/CommandPalette.json +1 -1
  48. package/agent/components/CompactBarTrend.json +1 -1
  49. package/agent/components/Conversations.json +3 -3
  50. package/agent/components/CredentialReveal.json +1 -1
  51. package/agent/components/DataState.json +2 -2
  52. package/agent/components/DataTable.json +1 -1
  53. package/agent/components/DatePicker.json +1 -1
  54. package/agent/components/Descriptions.json +1 -1
  55. package/agent/components/Dialog.json +2 -2
  56. package/agent/components/DraggablePanel.json +5 -4
  57. package/agent/components/DropdownMenu.json +1 -1
  58. package/agent/components/EmojiPicker.json +3 -2
  59. package/agent/components/EmptyState.json +1 -1
  60. package/agent/components/ErrorSurface.json +3 -3
  61. package/agent/components/FeatureList.json +1 -1
  62. package/agent/components/Field.json +0 -1
  63. package/agent/components/Flex.json +34 -4
  64. package/agent/components/FloatButton.json +6 -5
  65. package/agent/components/Form.json +1 -1
  66. package/agent/components/FormErrors.json +0 -1
  67. package/agent/components/FormField.json +6 -6
  68. package/agent/components/FormFieldArray.json +0 -1
  69. package/agent/components/FormFieldControl.json +0 -1
  70. package/agent/components/FormRoot.json +1 -1
  71. package/agent/components/Heading.json +3 -0
  72. package/agent/components/Icon.json +1 -1
  73. package/agent/components/Image.json +7 -4
  74. package/agent/components/InfiniteQueryState.json +1 -1
  75. package/agent/components/Input.json +1 -1
  76. package/agent/components/InputOTP.json +2 -2
  77. package/agent/components/Label.json +3 -3
  78. package/agent/components/LegalDocumentShell.json +5 -4
  79. package/agent/components/Legend.json +1 -1
  80. package/agent/components/LineChart.json +0 -1
  81. package/agent/components/Link.json +0 -1
  82. package/agent/components/ListRow.json +1 -1
  83. package/agent/components/Logo.json +5 -4
  84. package/agent/components/Marquee.json +4 -3
  85. package/agent/components/Masonry.json +4 -3
  86. package/agent/components/MasterDetail.json +1 -1
  87. package/agent/components/MegaMenu.json +4 -3
  88. package/agent/components/MobileShell.json +4 -4
  89. package/agent/components/NavList.json +1 -1
  90. package/agent/components/NumberInput.json +1 -1
  91. package/agent/components/OrgChart.json +4 -3
  92. package/agent/components/OrgSwitcher.json +1 -1
  93. package/agent/components/OverlayPortalProvider.json +0 -1
  94. package/agent/components/PageContainer.json +3 -3
  95. package/agent/components/PageCover.json +3 -2
  96. package/agent/components/Pagination.json +1 -1
  97. package/agent/components/PasswordInput.json +1 -1
  98. package/agent/components/PasswordStrength.json +1 -1
  99. package/agent/components/PermissionMatrix.json +1 -1
  100. package/agent/components/PieChart.json +0 -1
  101. package/agent/components/Popover.json +31 -6
  102. package/agent/components/PrefetchLink.json +1 -1
  103. package/agent/components/Progress.json +1 -1
  104. package/agent/components/Prose.json +1 -1
  105. package/agent/components/QrCode.json +1 -1
  106. package/agent/components/Radio.json +0 -1
  107. package/agent/components/RadioGroup.json +2 -2
  108. package/agent/components/RangeTimeline.json +2 -1
  109. package/agent/components/Rating.json +1 -1
  110. package/agent/components/RecordPicker.json +1 -1
  111. package/agent/components/ResizablePanel.json +1 -1
  112. package/agent/components/ResponsiveGrid.json +2 -2
  113. package/agent/components/Reveal.json +3 -3
  114. package/agent/components/ScrollArea.json +2 -2
  115. package/agent/components/SearchInput.json +1 -1
  116. package/agent/components/Segmented.json +1 -1
  117. package/agent/components/Select.json +7 -5
  118. package/agent/components/Separator.json +1 -1
  119. package/agent/components/ServiceCatalogCta.json +0 -1
  120. package/agent/components/ServiceLauncherCard.json +1 -1
  121. package/agent/components/ServiceRolePanel.json +1 -1
  122. package/agent/components/Sheet.json +5 -5
  123. package/agent/components/Sidebar.json +1 -1
  124. package/agent/components/Skeleton.json +26 -12
  125. package/agent/components/Slider.json +2 -2
  126. package/agent/components/SortableList.json +3 -2
  127. package/agent/components/SplitPane.json +1 -1
  128. package/agent/components/StatCard.json +1 -1
  129. package/agent/components/Steps.json +1 -1
  130. package/agent/components/Swatch.json +1 -1
  131. package/agent/components/Switch.json +1 -1
  132. package/agent/components/Table.json +1 -1
  133. package/agent/components/Tabs.json +3 -3
  134. package/agent/components/Text.json +5 -1
  135. package/agent/components/TextDiff.json +5 -4
  136. package/agent/components/Textarea.json +1 -1
  137. package/agent/components/ThemeScope.json +1 -1
  138. package/agent/components/ThoughtChain.json +3 -3
  139. package/agent/components/TimePicker.json +1 -1
  140. package/agent/components/Timeline.json +1 -1
  141. package/agent/components/TimelineGrid.json +5 -4
  142. package/agent/components/Toaster.json +0 -1
  143. package/agent/components/Toggle.json +3 -3
  144. package/agent/components/ToggleGroup.json +1 -1
  145. package/agent/components/Toolbar.json +10 -3
  146. package/agent/components/Tooltip.json +9 -9
  147. package/agent/components/Topbar.json +1 -1
  148. package/agent/components/TopbarItem.json +1 -1
  149. package/agent/components/Transfer.json +2 -2
  150. package/agent/components/Tree.json +1 -1
  151. package/agent/components/TreeSelect.json +1 -1
  152. package/agent/components/TwoFactorSetup.json +1 -1
  153. package/agent/components/Upload.json +1 -1
  154. package/agent/components/UploadCropDialog.json +1 -1
  155. package/agent/components/Welcome.json +3 -3
  156. package/agent/components/formatDate.json +2 -2
  157. package/agent/components/inertiaUpload.json +0 -1
  158. package/agent/components/useZodForm.json +0 -1
  159. package/agent/components-index.json +80 -154
  160. package/agent/components.json +541 -1737
  161. package/agent/index.json +10 -10
  162. package/agent/llms.txt +9 -9
  163. package/agent/patterns/account-recovery-settings.json +1 -1
  164. package/agent/patterns/auth-recovery-panels.json +2 -2
  165. package/agent/patterns/error-pages.json +1 -1
  166. package/agent/patterns/pricing-plans.json +17 -0
  167. package/agent/patterns-index.json +17 -1
  168. package/agent/patterns.json +21 -4
  169. package/agent/rules.json +30 -65
  170. package/agent/tokens.json +27 -57
  171. package/agent/vocabulary.json +3 -3
  172. package/dist/app/app-provider.d.ts +5 -3
  173. package/dist/app/app-provider.js +47 -12
  174. package/dist/app/date-format-labels.d.ts +3 -1
  175. package/dist/app/date-format-labels.js +2 -4
  176. package/dist/app/date-formats.d.ts +21 -2
  177. package/dist/app/date-formats.js +51 -2
  178. package/dist/app/index.d.ts +3 -1
  179. package/dist/app/index.js +5 -0
  180. package/dist/app/locales.d.ts +58 -3
  181. package/dist/app/locales.js +134 -8
  182. package/dist/app/preset.d.ts +25 -0
  183. package/dist/app/preset.js +10 -0
  184. package/dist/app/request-headers.d.ts +3 -3
  185. package/dist/app/request-headers.js +19 -10
  186. package/dist/app/settings-scope.d.ts +54 -0
  187. package/dist/app/settings-scope.js +46 -0
  188. package/dist/app/tenant-theme.js +8 -3
  189. package/dist/app/time-format-labels.d.ts +4 -1
  190. package/dist/app/time-format-labels.js +7 -1
  191. package/dist/app/types.d.ts +10 -2
  192. package/dist/app/use-formatting.d.ts +1 -1
  193. package/dist/components/admin/index.d.ts +1 -1
  194. package/dist/components/admin/index.js +1 -1
  195. package/dist/components/data-display/accordion.d.ts +51 -1
  196. package/dist/components/data-display/accordion.js +247 -1
  197. package/dist/components/data-display/avatar.d.ts +16 -1
  198. package/dist/components/data-display/avatar.js +109 -1
  199. package/dist/components/data-display/credential-reveal.d.ts +9 -2
  200. package/dist/components/data-display/credential-reveal.js +156 -1
  201. package/dist/components/data-display/image.js +5 -3
  202. package/dist/components/data-display/index.d.ts +0 -21
  203. package/dist/components/data-display/index.js +1 -43
  204. package/dist/components/data-display/popover.d.ts +15 -3
  205. package/dist/components/data-display/popover.js +168 -2
  206. package/dist/components/data-entry/branch-scope-picker.d.ts +1 -1
  207. package/dist/components/data-entry/index.d.ts +5 -12
  208. package/dist/components/data-entry/index.js +11 -12
  209. package/dist/components/data-entry/input-otp.d.ts +48 -2
  210. package/dist/components/data-entry/input-otp.js +94 -1
  211. package/dist/components/data-entry/number-input.d.ts +1 -1
  212. package/dist/components/data-entry/password-input.d.ts +38 -2
  213. package/dist/components/data-entry/password-input.js +56 -1
  214. package/dist/components/data-entry/rating.d.ts +38 -2
  215. package/dist/components/data-entry/rating.js +127 -1
  216. package/dist/components/data-entry/segmented.d.ts +94 -2
  217. package/dist/components/data-entry/segmented.js +104 -1
  218. package/dist/components/{ui/tag-input.d.ts → data-entry/select-tags-inline.d.ts} +7 -4
  219. package/dist/components/{ui/tag-input.js → data-entry/select-tags-inline.js} +4 -4
  220. package/dist/components/data-entry/select.js +4 -0
  221. package/dist/components/data-entry/toggle-group.d.ts +108 -2
  222. package/dist/components/data-entry/toggle-group.js +189 -1
  223. package/dist/components/data-entry/toggle.d.ts +86 -2
  224. package/dist/components/data-entry/toggle.js +153 -2
  225. package/dist/components/feedback/alert.d.ts +5 -3
  226. package/dist/components/feedback/alert.js +14 -2
  227. package/dist/components/feedback/index.d.ts +2 -6
  228. package/dist/components/feedback/index.js +1 -13
  229. package/dist/components/feedback/skeleton.d.ts +4 -17
  230. package/dist/components/feedback/skeleton.js +3 -40
  231. package/dist/components/general/index.d.ts +2 -4
  232. package/dist/components/general/index.js +1 -6
  233. package/dist/components/general/typography.d.ts +4 -58
  234. package/dist/components/general/typography.js +7 -141
  235. package/dist/components/layout/aspect-ratio.d.ts +24 -1
  236. package/dist/components/layout/aspect-ratio.js +18 -1
  237. package/dist/components/layout/auth-divider.js +1 -1
  238. package/dist/components/layout/auth-identity.js +6 -2
  239. package/dist/components/layout/centered-shell.d.ts +13 -8
  240. package/dist/components/layout/centered-shell.js +43 -1
  241. package/dist/components/layout/flex.d.ts +1 -1
  242. package/dist/components/layout/flex.js +73 -1
  243. package/dist/components/layout/index.d.ts +1 -13
  244. package/dist/components/layout/index.js +0 -12
  245. package/dist/components/layout/separator.d.ts +25 -2
  246. package/dist/components/layout/separator.js +71 -1
  247. package/dist/components/navigation/{app-setting-toggle.d.ts → app-setting-cycle.d.ts} +3 -4
  248. package/dist/components/navigation/{app-setting-toggle.js → app-setting-cycle.js} +3 -3
  249. package/dist/components/navigation/app-setting-picker.d.ts +6 -2
  250. package/dist/components/navigation/app-setting-picker.js +20 -2
  251. package/dist/components/navigation/index.d.ts +3 -11
  252. package/dist/components/navigation/index.js +1 -9
  253. package/dist/components/navigation/tabs.js +1 -1
  254. package/dist/components/ui/carousel.d.ts +1 -1
  255. package/dist/components/ui/carousel.js +1 -1
  256. package/dist/components/ui/index.d.ts +11 -5
  257. package/dist/components/ui/index.js +5 -5
  258. package/dist/contracts/measurement.json +2 -2
  259. package/dist/email/brand-mark.d.ts +3 -2
  260. package/dist/email/brand-mark.js +1 -1
  261. package/dist/email/tokens.generated.d.ts +6 -6
  262. package/dist/email/tokens.generated.js +6 -6
  263. package/dist/i18n/locale-tags.d.ts +25 -0
  264. package/dist/i18n/locale-tags.js +59 -0
  265. package/dist/i18n/translate.d.ts +20 -3
  266. package/dist/i18n/translate.js +25 -14
  267. package/dist/i18n/use-translation.d.ts +3 -3
  268. package/dist/i18n/use-translation.js +4 -2
  269. package/dist/{components/navigation → lab}/anchor.d.ts +2 -2
  270. package/dist/{components/navigation → lab}/anchor.js +5 -5
  271. package/dist/{components/data-display → lab}/carousel.js +2 -2
  272. package/dist/{components/layout → lab}/draggable-panel.d.ts +8 -8
  273. package/dist/{components/layout → lab}/draggable-panel.js +2 -2
  274. package/dist/{components/data-entry → lab}/emoji-picker.d.ts +2 -2
  275. package/dist/{components/data-entry → lab}/emoji-picker.js +6 -6
  276. package/dist/{components/general → lab}/float-button.d.ts +8 -8
  277. package/dist/{components/general → lab}/float-button.js +7 -7
  278. package/dist/lab/index.d.ts +39 -0
  279. package/dist/lab/index.js +48 -0
  280. package/dist/{components/layout → lab}/legal-document-shell.d.ts +2 -2
  281. package/dist/{components/layout → lab}/legal-document-shell.js +4 -4
  282. package/dist/{components/data-display → lab}/marquee.d.ts +5 -5
  283. package/dist/{components/data-display → lab}/marquee.js +5 -5
  284. package/dist/{components/layout → lab}/masonry.d.ts +2 -2
  285. package/dist/{components/layout → lab}/masonry.js +3 -3
  286. package/dist/{components/navigation → lab}/mega-menu.d.ts +4 -4
  287. package/dist/{components/navigation → lab}/mega-menu.js +2 -2
  288. package/dist/{components/data-display → lab}/org-chart.d.ts +2 -2
  289. package/dist/{components/data-display → lab}/org-chart.js +4 -4
  290. package/dist/{components/layout → lab}/page-cover.d.ts +2 -2
  291. package/dist/{components/layout → lab}/page-cover.js +2 -2
  292. package/dist/{components/data-display → lab}/range-timeline.d.ts +1 -1
  293. package/dist/{components/data-display → lab}/range-timeline.js +6 -6
  294. package/dist/{components/data-entry → lab}/sortable-list.d.ts +2 -2
  295. package/dist/{components/data-entry → lab}/sortable-list.js +3 -3
  296. package/dist/{components/data-display → lab}/text-diff.d.ts +3 -3
  297. package/dist/{components/data-display → lab}/text-diff.js +4 -4
  298. package/dist/{components/data-display → lab}/timeline-grid.d.ts +2 -2
  299. package/dist/{components/data-display → lab}/timeline-grid.js +1 -1
  300. package/dist/lib/control-styles.js +1 -1
  301. package/dist/lib/datetime/format.js +20 -6
  302. package/dist/lib/datetime/sync.d.ts +6 -2
  303. package/dist/lib/datetime/sync.js +14 -18
  304. package/dist/lib/platform.d.ts +1 -1
  305. package/dist/props/components/app.prop.d.ts +28 -13
  306. package/dist/props/components/data-display.prop.d.ts +19 -29
  307. package/dist/props/components/feedback.prop.d.ts +15 -44
  308. package/dist/props/components/general.prop.d.ts +2 -64
  309. package/dist/props/components/index.d.ts +9 -1
  310. package/dist/props/components/layout.prop.d.ts +41 -57
  311. package/dist/props/registry.d.ts +48 -101
  312. package/dist/props/registry.js +45 -129
  313. package/dist/props/vocabulary/index.d.ts +1 -1
  314. package/dist/props/vocabulary/interaction.prop.d.ts +3 -12
  315. package/dist/styles/alert-layout.css +0 -29
  316. package/dist/styles/data-display-layout.css +14 -22
  317. package/dist/styles/dialog-layout.css +4 -0
  318. package/dist/styles/fonts/OFL.txt +93 -0
  319. package/dist/styles/form-layout.css +4 -0
  320. package/dist/styles/index.css +0 -2
  321. package/dist/styles/layers.json +44 -179
  322. package/dist/styles/text-layout.css +0 -15
  323. package/dist/styles.css +2 -0
  324. package/dist/themes/godx.css +43 -0
  325. package/dist/themes/godx.d.ts +13 -0
  326. package/dist/themes/godx.js +12 -0
  327. package/dist/tokens/components/feedback.css +0 -6
  328. package/dist/tokens/derived.css +23 -22
  329. package/dist/tokens/foundation.css +4 -6
  330. package/docs/COMPOSITION-VS-COMPONENT.md +58 -33
  331. package/docs/CONSUMER-RULES.md +1 -1
  332. package/docs/CUSTOMER-THEMING.md +17 -53
  333. package/docs/migrations/v32.md +98 -0
  334. package/package.json +58 -19
  335. package/scripts/_agent-setup.mjs +54 -3
  336. package/scripts/brand-accent.generated.mjs +15 -2
  337. package/scripts/cli.mjs +36 -11
  338. package/scripts/codemod.mjs +522 -0
  339. package/scripts/consumer-rule.md +21 -43
  340. package/scripts/postinstall.mjs +10 -47
  341. package/scripts/prune-css.mjs +1 -1
  342. package/scripts/ui-audit.mjs +5 -2
  343. package/dist/components/data-display/chat-bubble.d.ts +0 -30
  344. package/dist/components/data-display/chat-bubble.js +0 -229
  345. package/dist/components/data-display/hover-card.d.ts +0 -1
  346. package/dist/components/data-display/hover-card.js +0 -7
  347. package/dist/components/data-display/thought-chain.d.ts +0 -42
  348. package/dist/components/data-display/thought-chain.js +0 -177
  349. package/dist/components/data-display/thumbnail.d.ts +0 -37
  350. package/dist/components/data-display/thumbnail.js +0 -20
  351. package/dist/components/data-display/welcome.d.ts +0 -26
  352. package/dist/components/data-display/welcome.js +0 -37
  353. package/dist/components/data-entry/attachments.d.ts +0 -19
  354. package/dist/components/data-entry/attachments.js +0 -366
  355. package/dist/components/data-entry/chat-composer.d.ts +0 -51
  356. package/dist/components/data-entry/chat-composer.js +0 -200
  357. package/dist/components/data-entry/chat-suggestion.d.ts +0 -28
  358. package/dist/components/data-entry/chat-suggestion.js +0 -309
  359. package/dist/components/data-entry/tag-input.d.ts +0 -2
  360. package/dist/components/data-entry/tag-input.js +0 -5
  361. package/dist/components/feedback/banner.d.ts +0 -21
  362. package/dist/components/feedback/banner.js +0 -19
  363. package/dist/components/feedback/callout.d.ts +0 -23
  364. package/dist/components/feedback/callout.js +0 -42
  365. package/dist/components/layout/auth-shell.d.ts +0 -10
  366. package/dist/components/layout/auth-shell.js +0 -42
  367. package/dist/components/layout/space-compact.d.ts +0 -65
  368. package/dist/components/layout/space-compact.js +0 -52
  369. package/dist/components/navigation/conversations.d.ts +0 -39
  370. package/dist/components/navigation/conversations.js +0 -371
  371. package/dist/components/ui/accordion.d.ts +0 -51
  372. package/dist/components/ui/accordion.js +0 -254
  373. package/dist/components/ui/aspect-ratio.d.ts +0 -24
  374. package/dist/components/ui/aspect-ratio.js +0 -21
  375. package/dist/components/ui/avatar.d.ts +0 -16
  376. package/dist/components/ui/avatar.js +0 -115
  377. package/dist/components/ui/credential-reveal.d.ts +0 -9
  378. package/dist/components/ui/credential-reveal.js +0 -160
  379. package/dist/components/ui/hover-card.d.ts +0 -47
  380. package/dist/components/ui/hover-card.js +0 -205
  381. package/dist/components/ui/input-otp.d.ts +0 -48
  382. package/dist/components/ui/input-otp.js +0 -101
  383. package/dist/components/ui/password-input.d.ts +0 -38
  384. package/dist/components/ui/password-input.js +0 -60
  385. package/dist/components/ui/rating.d.ts +0 -38
  386. package/dist/components/ui/rating.js +0 -131
  387. package/dist/components/ui/segmented.d.ts +0 -94
  388. package/dist/components/ui/segmented.js +0 -108
  389. package/dist/components/ui/separator.d.ts +0 -25
  390. package/dist/components/ui/separator.js +0 -74
  391. package/dist/components/ui/toggle-group.d.ts +0 -108
  392. package/dist/components/ui/toggle-group.js +0 -194
  393. package/dist/components/ui/toggle.d.ts +0 -86
  394. package/dist/components/ui/toggle.js +0 -156
  395. package/docs/CANONICAL-CONTRACTS.md +0 -206
  396. package/docs/COMPONENTS.md +0 -163
  397. package/docs/DATETIME.md +0 -78
  398. package/docs/DEVELOPMENT.md +0 -269
  399. package/docs/FRAME-A11Y-CI.md +0 -287
  400. package/docs/FRAME-COVERAGE-LEDGER.md +0 -123
  401. package/docs/FRAME-COVERAGE-REPORT.md +0 -228
  402. package/docs/FRAME-COVERAGE-STANDARD.md +0 -65
  403. package/docs/FRAME-COVERAGE.md +0 -29
  404. package/docs/MEASUREMENT-CONTRACT.md +0 -109
  405. package/docs/PROPS-REGISTRY.md +0 -61
  406. package/docs/PROPS-VOCABULARY.md +0 -100
  407. package/docs/REGISTRY.md +0 -70
  408. package/docs/TESTING.md +0 -107
  409. package/docs/THEME-API-COVERAGE.md +0 -538
  410. package/docs/WHAT-BELONGS-HERE.md +0 -179
  411. package/docs/asset-modules.d.ts +0 -53
  412. package/docs/assets/cover-terrain.svg +0 -6
  413. package/docs/assets/portrait-amber.svg +0 -5
  414. package/docs/assets/portrait-clay.svg +0 -5
  415. package/docs/assets/portrait-indigo.svg +0 -5
  416. package/docs/assets/portrait-iris.svg +0 -5
  417. package/docs/assets/portrait-moss.svg +0 -5
  418. package/docs/assets/portrait-plum.svg +0 -5
  419. package/docs/assets/portrait-slate.svg +0 -5
  420. package/docs/assets/service-mark-rose.svg +0 -6
  421. package/docs/assets/service-mark-teal.svg +0 -5
  422. package/docs/assets/shot-landscape.svg +0 -12
  423. package/docs/assets/shot-portrait.svg +0 -10
  424. package/docs/assets/tcgm/card-1.svg +0 -1
  425. package/docs/assets/tcgm/card-2.svg +0 -1
  426. package/docs/assets/tcgm/card-3.svg +0 -1
  427. package/docs/assets/tcgm/card-4.svg +0 -1
  428. package/docs/assets/tcgm/card-5.svg +0 -1
  429. package/docs/assets/tcgm/card-6.svg +0 -1
  430. package/docs/assets/tcgm/hero-prism.svg +0 -1
  431. package/docs/assets/tcgm/scene-1.svg +0 -1
  432. package/docs/assets/tcgm/scene-2.svg +0 -1
  433. package/docs/assets/tcgm/scene-3.svg +0 -1
  434. package/docs/assets/tcgm/scene-4.svg +0 -1
  435. package/docs/assets/tcgm/scene-5.svg +0 -1
  436. package/docs/assets/tcgm/tcgm-lockup-color.svg +0 -1
  437. package/docs/assets/tcgm/tcgm-symbol-color.svg +0 -1
  438. package/docs/charts/cjk-category-axis.tsx +0 -81
  439. package/docs/charts/compact-bar-trend.tsx +0 -327
  440. package/docs/charts/size-tiers.tsx +0 -192
  441. package/docs/data-display/accordion.tsx +0 -99
  442. package/docs/data-display/avatar.tsx +0 -502
  443. package/docs/data-display/badge.tsx +0 -335
  444. package/docs/data-display/card/examples/detail-panel.tsx +0 -106
  445. package/docs/data-display/card/examples/tab-list.tsx +0 -97
  446. package/docs/data-display/card/index.md +0 -3
  447. package/docs/data-display/card/index.tsx +0 -390
  448. package/docs/data-display/carousel.tsx +0 -160
  449. package/docs/data-display/charts.tsx +0 -278
  450. package/docs/data-display/chat-bubble.tsx +0 -397
  451. package/docs/data-display/code-block.tsx +0 -188
  452. package/docs/data-display/collapsible.tsx +0 -162
  453. package/docs/data-display/credential-reveal.tsx +0 -148
  454. package/docs/data-display/data-table/examples/antd-parity.tsx +0 -257
  455. package/docs/data-display/data-table/examples/approval-queue.tsx +0 -212
  456. package/docs/data-display/data-table/examples/grid-features.tsx +0 -158
  457. package/docs/data-display/data-table/examples/list-page.tsx +0 -175
  458. package/docs/data-display/data-table/examples/selectable-inbox.tsx +0 -113
  459. package/docs/data-display/data-table/examples/server-paged.tsx +0 -179
  460. package/docs/data-display/data-table/examples/striped-list.tsx +0 -173
  461. package/docs/data-display/data-table/index.md +0 -9
  462. package/docs/data-display/data-table/index.tsx +0 -407
  463. package/docs/data-display/descriptions.tsx +0 -263
  464. package/docs/data-display/empty-state.tsx +0 -164
  465. package/docs/data-display/feature-list.tsx +0 -159
  466. package/docs/data-display/hover-card.tsx +0 -181
  467. package/docs/data-display/image.tsx +0 -170
  468. package/docs/data-display/legend.tsx +0 -158
  469. package/docs/data-display/list-row.tsx +0 -441
  470. package/docs/data-display/markdown.tsx +0 -86
  471. package/docs/data-display/marquee.tsx +0 -254
  472. package/docs/data-display/org-chart.tsx +0 -165
  473. package/docs/data-display/permission-matrix.tsx +0 -188
  474. package/docs/data-display/popover-touch.tsx +0 -27
  475. package/docs/data-display/popover.tsx +0 -331
  476. package/docs/data-display/progress.tsx +0 -162
  477. package/docs/data-display/prose.tsx +0 -169
  478. package/docs/data-display/qr-code.tsx +0 -68
  479. package/docs/data-display/scroll-area.tsx +0 -420
  480. package/docs/data-display/service-launcher-card.tsx +0 -445
  481. package/docs/data-display/stat-card.tsx +0 -354
  482. package/docs/data-display/swatch.tsx +0 -107
  483. package/docs/data-display/table.tsx +0 -362
  484. package/docs/data-display/text-diff.tsx +0 -89
  485. package/docs/data-display/thought-chain.tsx +0 -176
  486. package/docs/data-display/thumbnail.tsx +0 -128
  487. package/docs/data-display/timeline-grid.tsx +0 -119
  488. package/docs/data-display/timeline.tsx +0 -671
  489. package/docs/data-display/touch-actions.tsx +0 -36
  490. package/docs/data-display/tree.tsx +0 -724
  491. package/docs/data-display/welcome.tsx +0 -115
  492. package/docs/data-entry/attachments.tsx +0 -160
  493. package/docs/data-entry/block-editor.tsx +0 -105
  494. package/docs/data-entry/branch-scope-picker.tsx +0 -128
  495. package/docs/data-entry/calendar.tsx +0 -226
  496. package/docs/data-entry/cascader.tsx +0 -380
  497. package/docs/data-entry/chat-composer.tsx +0 -619
  498. package/docs/data-entry/chat-suggestion.tsx +0 -301
  499. package/docs/data-entry/checkbox.tsx +0 -256
  500. package/docs/data-entry/color-picker.tsx +0 -189
  501. package/docs/data-entry/command-palette.tsx +0 -179
  502. package/docs/data-entry/command.tsx +0 -341
  503. package/docs/data-entry/country-picker-recipe.tsx +0 -175
  504. package/docs/data-entry/date-picker.tsx +0 -452
  505. package/docs/data-entry/emoji-picker.tsx +0 -35
  506. package/docs/data-entry/form/examples/employee-settings.tsx +0 -267
  507. package/docs/data-entry/form/examples/invoice-form.tsx +0 -387
  508. package/docs/data-entry/form-dynamic-fields.tsx +0 -199
  509. package/docs/data-entry/form-field/examples/a11y-contract.tsx +0 -242
  510. package/docs/data-entry/form-field/examples/create-form.tsx +0 -107
  511. package/docs/data-entry/form-field/index.md +0 -8
  512. package/docs/data-entry/form-field/index.tsx +0 -337
  513. package/docs/data-entry/form-inertia.tsx +0 -80
  514. package/docs/data-entry/form-root.tsx +0 -112
  515. package/docs/data-entry/form.tsx +0 -1498
  516. package/docs/data-entry/input-otp.tsx +0 -258
  517. package/docs/data-entry/input.tsx +0 -796
  518. package/docs/data-entry/label.tsx +0 -102
  519. package/docs/data-entry/markdown-editor.tsx +0 -69
  520. package/docs/data-entry/number-input.tsx +0 -279
  521. package/docs/data-entry/password-input.tsx +0 -102
  522. package/docs/data-entry/password-strength.tsx +0 -99
  523. package/docs/data-entry/radio-group.tsx +0 -316
  524. package/docs/data-entry/rating.tsx +0 -91
  525. package/docs/data-entry/record-picker.tsx +0 -209
  526. package/docs/data-entry/search-input.tsx +0 -121
  527. package/docs/data-entry/segmented-in-filter-row.tsx +0 -60
  528. package/docs/data-entry/segmented.tsx +0 -300
  529. package/docs/data-entry/select-async-contracts.tsx +0 -108
  530. package/docs/data-entry/select-matrix.tsx +0 -209
  531. package/docs/data-entry/select.tsx +0 -547
  532. package/docs/data-entry/slider.tsx +0 -212
  533. package/docs/data-entry/sortable-list.tsx +0 -76
  534. package/docs/data-entry/switch.tsx +0 -314
  535. package/docs/data-entry/tag-input.tsx +0 -145
  536. package/docs/data-entry/textarea.tsx +0 -249
  537. package/docs/data-entry/time-picker.tsx +0 -187
  538. package/docs/data-entry/time-range-picker.tsx +0 -55
  539. package/docs/data-entry/toggle-count.tsx +0 -348
  540. package/docs/data-entry/toggle-group.tsx +0 -438
  541. package/docs/data-entry/toggle.tsx +0 -217
  542. package/docs/data-entry/transfer.tsx +0 -115
  543. package/docs/data-entry/tree-select.tsx +0 -204
  544. package/docs/data-entry/upload-crop-dialog.tsx +0 -109
  545. package/docs/data-entry/upload.tsx +0 -310
  546. package/docs/feedback/alert-dialog.tsx +0 -270
  547. package/docs/feedback/alert.tsx +0 -248
  548. package/docs/feedback/auth-expiry.tsx +0 -104
  549. package/docs/feedback/banner.tsx +0 -183
  550. package/docs/feedback/callout.tsx +0 -220
  551. package/docs/feedback/danger-confirm.tsx +0 -91
  552. package/docs/feedback/dialog-touch.tsx +0 -24
  553. package/docs/feedback/dialog.tsx +0 -373
  554. package/docs/feedback/sheet.tsx +0 -510
  555. package/docs/feedback/skeleton.tsx +0 -168
  556. package/docs/feedback/toast.tsx +0 -135
  557. package/docs/feedback/tooltip.tsx +0 -171
  558. package/docs/feedback/two-factor-setup.tsx +0 -68
  559. package/docs/foundation/_email-specimen.ts +0 -274
  560. package/docs/foundation/_theme-editor-scope.ts +0 -222
  561. package/docs/foundation/colors.tsx +0 -207
  562. package/docs/foundation/density.tsx +0 -242
  563. package/docs/foundation/email-tokens.tsx +0 -323
  564. package/docs/foundation/radius-shadow.tsx +0 -154
  565. package/docs/foundation/spacing.tsx +0 -216
  566. package/docs/foundation/theme-editor.tsx +0 -654
  567. package/docs/foundation/typography.tsx +0 -147
  568. package/docs/general/actions.tsx +0 -175
  569. package/docs/general/activity.tsx +0 -289
  570. package/docs/general/button/examples/destructive-confirm.tsx +0 -90
  571. package/docs/general/button/examples/form-actions.tsx +0 -87
  572. package/docs/general/button/examples/toolbar.tsx +0 -160
  573. package/docs/general/button/index.md +0 -16
  574. package/docs/general/button/index.tsx +0 -236
  575. package/docs/general/float-button.tsx +0 -133
  576. package/docs/general/icon.tsx +0 -217
  577. package/docs/general/logo.tsx +0 -194
  578. package/docs/general/reveal.tsx +0 -309
  579. package/docs/general/typography.tsx +0 -542
  580. package/docs/i18n/messages/en.json +0 -1715
  581. package/docs/i18n/messages/ja.json +0 -1708
  582. package/docs/i18n/messages/vi.json +0 -1708
  583. package/docs/layout/account-chip.tsx +0 -72
  584. package/docs/layout/admin-collection.tsx +0 -122
  585. package/docs/layout/affix.tsx +0 -209
  586. package/docs/layout/app-launcher.tsx +0 -211
  587. package/docs/layout/app-shell-arrangements.tsx +0 -225
  588. package/docs/layout/app-shell-narrow-bar.tsx +0 -205
  589. package/docs/layout/app-shell-states.tsx +0 -171
  590. package/docs/layout/app-shell.tsx +0 -395
  591. package/docs/layout/aspect-ratio.tsx +0 -135
  592. package/docs/layout/auth-account-summary.tsx +0 -103
  593. package/docs/layout/auth-divider.tsx +0 -28
  594. package/docs/layout/auth-footer.tsx +0 -37
  595. package/docs/layout/auth-identity.tsx +0 -70
  596. package/docs/layout/auth-recovery/examples/mfa-challenge.md +0 -41
  597. package/docs/layout/auth-recovery/examples/mfa-challenge.tsx +0 -254
  598. package/docs/layout/auth-recovery/examples/mobile-390.md +0 -25
  599. package/docs/layout/auth-recovery/examples/mobile-390.tsx +0 -82
  600. package/docs/layout/auth-recovery/examples/password-recovery.md +0 -24
  601. package/docs/layout/auth-recovery/examples/password-recovery.tsx +0 -197
  602. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.md +0 -27
  603. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.tsx +0 -156
  604. package/docs/layout/auth-recovery/index.md +0 -140
  605. package/docs/layout/auth-recovery/index.tsx +0 -96
  606. package/docs/layout/auth-shell-context.tsx +0 -103
  607. package/docs/layout/auth-shell-device.tsx +0 -112
  608. package/docs/layout/auth-shell-registration.tsx +0 -338
  609. package/docs/layout/auth-shell-variants.tsx +0 -143
  610. package/docs/layout/auth-shell.tsx +0 -59
  611. package/docs/layout/auth-stack.tsx +0 -40
  612. package/docs/layout/centered-shell.tsx +0 -102
  613. package/docs/layout/draggable-panel.tsx +0 -127
  614. package/docs/layout/error-surface/examples/application-403.tsx +0 -84
  615. package/docs/layout/error-surface/examples/application-404.tsx +0 -77
  616. package/docs/layout/error-surface/examples/system-500.tsx +0 -47
  617. package/docs/layout/error-surface/examples/system-503.tsx +0 -48
  618. package/docs/layout/error-surface/index.md +0 -153
  619. package/docs/layout/error-surface/index.tsx +0 -239
  620. package/docs/layout/flex.tsx +0 -444
  621. package/docs/layout/legal-document-shell/_data.ts +0 -110
  622. package/docs/layout/legal-document-shell/examples/desktop-1440.md +0 -12
  623. package/docs/layout/legal-document-shell/examples/desktop-1440.tsx +0 -83
  624. package/docs/layout/legal-document-shell/examples/mobile-390.md +0 -22
  625. package/docs/layout/legal-document-shell/examples/mobile-390.tsx +0 -70
  626. package/docs/layout/legal-document-shell/examples/tablet-1024.md +0 -3
  627. package/docs/layout/legal-document-shell/examples/tablet-1024.tsx +0 -84
  628. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.md +0 -18
  629. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.tsx +0 -61
  630. package/docs/layout/legal-document-shell/index.md +0 -51
  631. package/docs/layout/legal-document-shell/index.tsx +0 -101
  632. package/docs/layout/masonry.tsx +0 -291
  633. package/docs/layout/master-detail.tsx +0 -390
  634. package/docs/layout/mobile-shell.tsx +0 -106
  635. package/docs/layout/nav-list.tsx +0 -584
  636. package/docs/layout/org-switcher.tsx +0 -131
  637. package/docs/layout/page-container.tsx +0 -1020
  638. package/docs/layout/page-cover.tsx +0 -56
  639. package/docs/layout/resizable-panel.tsx +0 -419
  640. package/docs/layout/responsive-grid.tsx +0 -403
  641. package/docs/layout/separator.tsx +0 -327
  642. package/docs/layout/service-role-panel.tsx +0 -144
  643. package/docs/layout/sidebar.tsx +0 -689
  644. package/docs/layout/space-compact.tsx +0 -202
  645. package/docs/layout/split-pane.tsx +0 -532
  646. package/docs/layout/topbar-item.tsx +0 -233
  647. package/docs/layout/topbar.tsx +0 -360
  648. package/docs/navigation/anchor.tsx +0 -295
  649. package/docs/navigation/app-setting-picker.tsx +0 -178
  650. package/docs/navigation/app-setting-toggle.tsx +0 -111
  651. package/docs/navigation/breadcrumb.tsx +0 -207
  652. package/docs/navigation/card-tabs.tsx +0 -344
  653. package/docs/navigation/conversations.tsx +0 -176
  654. package/docs/navigation/dropdown-menu.tsx +0 -345
  655. package/docs/navigation/filter-bar.tsx +0 -247
  656. package/docs/navigation/mega-menu-panel.tsx +0 -86
  657. package/docs/navigation/mega-menu.tsx +0 -254
  658. package/docs/navigation/pagination.tsx +0 -293
  659. package/docs/navigation/steps.tsx +0 -315
  660. package/docs/navigation/tabs-rtl.tsx +0 -28
  661. package/docs/navigation/tabs.tsx +0 -755
  662. package/docs/navigation/toolbar.tsx +0 -347
  663. package/docs/providers/app-provider.tsx +0 -191
  664. package/docs/providers/format-date.tsx +0 -230
  665. package/docs/providers/theme-scope.tsx +0 -186
  666. package/docs/query/button-refetch.tsx +0 -161
  667. package/docs/query/data-state.tsx +0 -262
  668. package/docs/query/infinite-query-state.tsx +0 -97
  669. package/docs/query/mutation-feedback.tsx +0 -128
  670. package/docs/query/touch-actions.tsx +0 -68
  671. package/docs/react-router/prefetch-link.tsx +0 -262
  672. package/docs/roadmap/ai-chat-components.md +0 -206
  673. package/docs/roadmap/antd-parity.md +0 -155
  674. package/docs/roadmap/badge-tag-chip-count.md +0 -172
  675. package/docs/roadmap/list-masonry.md +0 -159
  676. package/docs/roadmap/parity-audit-data-display-feedback.md +0 -567
  677. package/docs/roadmap/parity-audit-data-entry.md +0 -368
  678. package/docs/roadmap/parity-audit-layout-navigation-general.md +0 -459
  679. package/docs/roadmap/parity-backlog.md +0 -77
  680. package/docs/roadmap/tree-components.md +0 -151
  681. package/docs/roadmap/website-components.md +0 -813
  682. package/docs/showcase/acme-portal.tsx +0 -461
  683. package/docs/showcase/acme-website.tsx +0 -499
  684. package/docs/showcase/caimono-price-comparison.tsx +0 -919
  685. package/docs/showcase/case1-warehouse-dashboard.tsx +0 -358
  686. package/docs/showcase/case2-employee-me.tsx +0 -438
  687. package/docs/showcase/case3-approval-workflow.tsx +0 -531
  688. package/docs/showcase/case4-login.tsx +0 -312
  689. package/docs/showcase/case5-shift-calendar.tsx +0 -702
  690. package/docs/showcase/case6-agency-handy.tsx +0 -1120
  691. package/docs/showcase/futurelastic-web.tsx +0 -441
  692. package/docs/showcase/marketing-page.tsx +0 -895
  693. package/docs/showcase/org-switcher.tsx +0 -320
  694. package/docs/showcase/permission-matrix.tsx +0 -354
  695. package/docs/showcase/public-landing.tsx +0 -210
  696. package/docs/showcase/settings-account-sections.tsx +0 -559
  697. package/docs/showcase/settings-security-mfa.tsx +0 -145
  698. package/docs/showcase/table-approval-queue.tsx +0 -199
  699. package/docs/showcase/table-bulk-actions.tsx +0 -468
  700. package/docs/showcase/table-compact-kintone.tsx +0 -438
  701. package/docs/showcase/table-conditional-format.tsx +0 -367
  702. package/docs/showcase/table-crud-list.tsx +0 -544
  703. package/docs/showcase/table-density.tsx +0 -349
  704. package/docs/showcase/table-expandable-rows.tsx +0 -496
  705. package/docs/showcase/table-filter-chips.tsx +0 -468
  706. package/docs/showcase/table-footer-totals.tsx +0 -328
  707. package/docs/showcase/table-grouped-subtotals.tsx +0 -398
  708. package/docs/showcase/table-master-detail.tsx +0 -482
  709. package/docs/showcase/table-pagination.tsx +0 -409
  710. package/docs/showcase/table-states.tsx +0 -371
  711. package/docs/showcase/table-sticky-columns.tsx +0 -377
  712. package/docs/showcase/table-tree-rows.tsx +0 -451
  713. package/docs/showcase/table-view-tabs.tsx +0 -488
  714. package/docs/showcase/tcgm-website.tsx +0 -1047
  715. package/docs/showcase/tenant-brand-color.tsx +0 -338
  716. package/docs/showcase/theme-customization.tsx +0 -1292
  717. package/docs/showcase/theme-lab.tsx +0 -2125
  718. package/docs/themes/flat.css +0 -466
  719. package/docs/themes/glassmorphism.css +0 -960
  720. package/docs/themes/index.ts +0 -219
  721. package/docs/themes/neubrutalism.css +0 -481
  722. /package/dist/components/navigation/{filter-bar.d.ts → toolbar.d.ts} +0 -0
  723. /package/dist/components/navigation/{filter-bar.js → toolbar.js} +0 -0
  724. /package/dist/{components/data-display → lab}/carousel.d.ts +0 -0
  725. /package/dist/{components/data-entry → lab}/emoji-data.d.ts +0 -0
  726. /package/dist/{components/data-entry → lab}/emoji-data.js +0 -0
  727. /package/dist/{components/data-display → lab}/marquee-reveal.d.ts +0 -0
  728. /package/dist/{components/data-display → lab}/marquee-reveal.js +0 -0
@@ -1,567 +0,0 @@
1
- # Ant Design parity audit — `data-display` + `feedback`
2
-
3
- > Method and ground rules: `docs/roadmap/antd-parity.md` §0/§2. This is a **read-only audit pass**
4
- > (§4.5): no source, token, test, i18n or catalog file was touched. Ant Design reference = **v5**
5
- > (`5.x-stable` `components/<slug>/index.en-US.md`); `ant.design/components/*` now serves v6, and v6
6
- > deltas are cited only where they change the *right* answer for this library (v6 moved `fixed`,
7
- > `gapPosition`, `dotPosition`, `expandIconPosition`, `Timeline.mode` and `Drawer.closable.placement`
8
- > to logical `start`/`end` — the spelling this repo already uses).
9
- >
10
- > Audited: **2026-09-10**. Out of scope by instruction (already specced or being built concurrently):
11
- > `Badge` / `CountBadge` / `Tree` / `TreeList`, `ChatBubble` / `ChatBubbleList`, `List` / `Masonry`,
12
- > `Tabs`, `Steps`, `Segmented`.
13
-
14
- ---
15
-
16
- ## 1. Summary
17
-
18
- These two groups are **far more Ant-aligned than the "missing features" complaint implies — but the
19
- alignment is extremely uneven.** `DataTable` is the strongest component in the library and already
20
- carries a deliberate, documented antd parity surface (`rowSelection`, `expandable`, `summary`,
21
- `scroll`, `sticky`, `onRow`, `bordered`, `sortDirections`, per-column `fixed`/`ellipsis`/`sorter`/
22
- `filters`/`filteredValue`, plus pagination in three accepted shapes — `src/props/vocabulary/data.prop.ts:16-134`).
23
- `Descriptions` matches antd's `column`/`span`/`layout`/`labelAlign`/`bordered`/`items` including the
24
- responsive object and `span="filled"`. `ErrorSurface` **exceeds** antd's `Result` (request-id,
25
- missing-permission, tenant, maintenance window, shell-mode contract). `Rating` already mirrors `Rate`
26
- (`count`/`allowHalf`/`character`/`tooltips`/`readOnly`). Nothing here needs a rewrite.
27
-
28
- The weakness is concentrated in the **small display primitives and the whole toast surface**, and the
29
- five gaps that actually matter are not cosmetic:
30
-
31
- 1. **`Timeline` ships hardcoded English screen-reader text** (`"Completed: "` / `"Current: "` /
32
- `"Upcoming: "`, `src/components/data-display/timeline.tsx:31-35`, with a comment calling it
33
- "localize-agnostic English"). There are **zero `timeline` keys in `src/i18n/messages/en.json`**.
34
- A Japanese product announces English status words. This is the single worst finding in the audit.
35
- 2. **`Toaster` is not a design-system component at all.** The catalog itself tells consumers to
36
- `import { toast } from "sonner"` (`mcp/src/data/components.ts:7302`), so the entire imperative
37
- feedback API — the most-used feedback surface in any admin app — sits outside the house
38
- vocabulary, outside `t()`, and outside the token contract. `position` is sonner's physical
39
- `"bottom-right"` (`src/components/feedback/sonner.tsx:118`) and never flips under RTL.
40
- 3. **`Avatar` has no `size`.** `AvatarProp` exposes only `shape`/`appearance`/`presence`
41
- (`src/props/components/data-display.prop.ts:172-199`), and the token file *admits* the workaround:
42
- "a `size-12` call site" (`src/tokens/components/data-display.css:89`). Every consumer hand-writes
43
- a Tailwind size class — the exact thing cardinal rule #22 / `check:control-sizing` exists to stop.
44
- There is also **no `Avatar.Group`** (grep for `AvatarGroup|Avatar.Group` across `src/` + the MCP
45
- catalog: 0 hits), so every assignee stack is hand-rolled.
46
- 4. **`StatCard` does no number formatting and parses its own delta sign with a regex.** `value` is a
47
- bare `ReactNode` and `getDeltaTone` matches `/^[+\-−]/` on a stringified delta
48
- (`src/components/data-display/card.tsx:233-246`). antd's `Statistic` owns `precision`,
49
- `groupSeparator`, `decimalSeparator`, `prefix`/`suffix` and `formatter`. Here every KPI tile
50
- formats its own numbers, which is how a dashboard ends up with `1,234` next to `1 234`.
51
- 5. **`Accordion` hardcodes `<h3>`** (`src/components/ui/accordion.tsx:314`) and offers no `extra`
52
- slot outside the trigger button. A settings accordion whose header carries a `Switch` cannot be
53
- built without nesting a control inside a `<button>` — invalid HTML and a real keyboard trap.
54
-
55
- Everything else is either genuinely `PRESENT`, correctly `COVERED-ELSEWHERE` (antd `Spin` →
56
- `Activity` + `Skeleton` + `DataState`; antd `Empty` → `EmptyState`; antd `Popconfirm` → `AlertDialog`
57
- or `Popover` + `Button`s; antd `Result` → `ErrorSurface`), or a deliberate `WONT-PORT`
58
- (`classNames`/`styles` semantic-DOM maps, `getPopupContainer`, `components`, `filterDropdown`,
59
- `renderCell`, `valueStyle`, `strokeColor` gradients, `imageStyle`).
60
-
61
- ---
62
-
63
- ## 2. Ledgers
64
-
65
- ### 2.1 `DataTable` vs antd `Table`
66
-
67
- Sources: `src/props/components/data-display.prop.ts:337-375`, `src/props/vocabulary/data.prop.ts:16-134`,
68
- `src/components/data-display/data-table.tsx`.
69
-
70
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
71
- | --- | --- | --- | --- |
72
- | `dataSource` — rows | `RENAMED` | `data` — `data-display.prop.ts:338` | — |
73
- | `columns` | `PRESENT` | `data-display.prop.ts:339` | — |
74
- | `rowKey` | `RENAMED` | `getRowId` — `data-display.prop.ts:340`, `vocabulary/data.prop.ts` `GetRowIdProp` | — |
75
- | `rowSelection` (`type`, `selectedRowKeys`, `onChange`, `getCheckboxProps`, `preserveSelectedRowKeys`, `selections`, `hideSelectAll`, `columnTitle`) | `PRESENT` | `vocabulary/data.prop.ts:58-71`; `data-table.tsx:545` | — |
76
- | `rowSelection.renderCell` | `WONT-PORT` | not in `TableRowSelectionProp` (`vocabulary/data.prop.ts:58-71`) | Render-prop over the checkbox cell bypasses the a11y contract. |
77
- | `rowSelection.align` / `fixed` / `columnWidth` | `MISSING` | grep `align`/`columnWidth` in `TableRowSelectionProp`: absent | P2 — add `columnWidth`; alignment is a token. |
78
- | `expandable` (`expandedRowRender`, `rowExpandable`, `defaultExpandAllRows`, `expandedRowKeys`, `onExpandedRowsChange`, `expandRowByClick`, `columnTitle`) | `PRESENT` | `vocabulary/data.prop.ts:75-86` | — |
79
- | `expandable.childrenColumnName` — **tree/nested rows** | `MISSING` | `grep -n childrenColumnName src/components/data-display/data-table.tsx src/props/vocabulary/data.prop.ts` → 0 hits | **P1** — add `childrenColumnName` + `indentSize`; nested rows are otherwise impossible. `TableCellIndentProp` already exists (`vocabulary/data.prop.ts`) and is the intended measure. |
80
- | `expandable.expandIcon` / `showExpandColumn` / `columnWidth` | `MISSING` | grep `expandIcon` → 0 hits in `data-table.tsx` | P2 — `showExpandColumn` only; the icon is a token. |
81
- | `summary` (+ `Table.Summary.Cell colSpan/rowSpan`) | `PRESENT` | `vocabulary/data.prop.ts:89`; real `<tfoot>` per `data-display.prop.ts:366` | — |
82
- | `scroll: { x, y }` | `PRESENT` | `vocabulary/data.prop.ts:97` | — |
83
- | `scroll.scrollToFirstRowOnChange` | `MISSING` | `TableScrollProp` has `x`/`y` only | P2 |
84
- | `sticky` (+ `offsetHeader`) | `PRESENT` | `vocabulary/data.prop.ts:103` | — |
85
- | `sticky.offsetScroll` / `getContainer` | `MISSING` | `TableStickyProp` = `boolean \| { offsetHeader }` | P2 |
86
- | `onRow` | `PRESENT` | `vocabulary/data.prop.ts:110`; `data-table.tsx:358` | — |
87
- | `onHeaderRow` | `MISSING` | grep `onHeaderRow` → 0 hits | P2 |
88
- | `column.onCell` / `onHeaderCell` — per-cell props, `colSpan`/`rowSpan` merges | `MISSING` | grep `onCell` / `rowSpan` in `data-table.tsx` → 0 hits | **P1** — merged cells are unreachable from `DataTable`; today the escape is dropping to the raw `Table` primitive, which loses sort/filter/selection. Add `onCell` returning `{ colSpan, rowSpan }` only (not arbitrary DOM). |
89
- | `bordered` | `PRESENT` | `data-display.prop.ts:368` | — |
90
- | `sortDirections` (table + column) | `PRESENT` | `data-display.prop.ts:372`, `vocabulary/data.prop.ts` `sortDirections` | Values are `asc`/`desc`, not antd's `ascend`/`descend` — correct per §0.1. |
91
- | `showSorterTooltip` | `PRESENT` | `data-display.prop.ts:370` | — |
92
- | `column.sorter` incl. `{ compare, multiple }` multi-sort | `PRESENT` | `data-table.tsx:196-212` | — |
93
- | `column.filters` / `filteredValue` / `defaultFilteredValue` / `filterMultiple` / `onFilter` | `PRESENT` | `vocabulary/data.prop.ts` `ColumnDefProp` | — |
94
- | `column.filterSearch` / `filterMode: 'tree'` / `filterResetToDefaultFilteredValue` | `MISSING` | grep `filterSearch` → 0 hits | P2 — `filterSearch` is real for a 40-value status filter. |
95
- | `column.filterDropdown` / `filterIcon` / `sortIcon` | `WONT-PORT` | absent from `ColumnDefProp` | Render-prop escape hatches over the filter menu's ARIA. |
96
- | `column.fixed: 'left'\|'right'` | `RENAMED` | `fixed?: ColumnFixedProp` = `"start" \| "end"` — `vocabulary/data.prop.ts:15` | Logical, matching antd v6. |
97
- | `column.ellipsis` | `PRESENT` | `ColumnDefProp.ellipsis` | — |
98
- | `column.width` / `minWidth` | `PRESENT` (`width`) / `MISSING` (`minWidth`) | `ColumnDefProp.width`; grep `minWidth` → 0 hits | P2 |
99
- | `column.hidden` | `RENAMED` | `enableHiding` + `hiddenOnMobile` + `priority` — `ColumnDefProp` | Richer than antd's boolean. |
100
- | `column.responsive: Breakpoint[]` | `COVERED-ELSEWHERE` | `priority` + `preset="action-collection"` + `collapseBelow` — `data-display.prop.ts:355-361` | Cross-link `preset` ↔ `responsive` in the catalog. |
101
- | `column.rowScope` | `MISSING` | grep `rowScope` → 0 hits | **P1 (a11y)** — a row-header column (`scope="row"`) is how a screen reader names each cell. Add `rowHeader?: boolean` on `ColumnDefProp`. |
102
- | `column.shouldCellUpdate` | `WONT-PORT` | absent | A memoization escape hatch; `React.memo` in `render` is the consumer's tool. |
103
- | `column.colSpan` (header grouping) / `ColumnGroup` | `MISSING` | grep `ColumnGroup` → 0 hits | P2 — grouped header rows. |
104
- | `pagination` (object / `false` / controlled) | `PRESENT` | `data-table.tsx:406-412, 565-620`; `TablePaginationProp` — `vocabulary/data.prop.ts:124-133` | — |
105
- | `pagination.position` | `MISSING` | `TablePaginationProp` has no `position` | P2 — if added, use logical `bottomEnd` (antd v6 spelling), never `bottomRight`. |
106
- | `loading` | `PRESENT` | `data-display.prop.ts:346`; renders `SkeletonTable` | Better than antd's `Spin` overlay. |
107
- | `locale` (empty text, filter labels) | `COVERED-ELSEWHERE` | `empty` / `error` / `denied` props + `useTranslation` | — |
108
- | `title` / `footer` renderers | `COVERED-ELSEWHERE` | `Card` + `CardHeader` / `CardFooter` / `CardBar` — `card.tsx:78, 151, 181` | Cross-link both sides. |
109
- | `showHeader` | `MISSING` | grep `showHeader` → 0 hits | P2 |
110
- | `tableLayout` | `MISSING` | grep `tableLayout` → 0 hits | P2 — antd forces `fixed` when `ellipsis`/`fixed` is used; this library should decide it internally, not expose it. |
111
- | `size: large\|middle\|small` | `RENAMED` | `density?: TableDensityProp` (`compact \| comfortable`) — `data-display.prop.ts:344` | — |
112
- | `virtual` | `MISSING` | grep `virtual` in `data-table.tsx` → 0 hits | **P1** — a 5 000-row grid has no answer today. Same gap `list-masonry.md` records for `List`; solve once. |
113
- | `ref.scrollTo({ index, key, top })` | `MISSING` | no `scrollTo` on the DataTable ref | P2 — pairs with `virtual`. |
114
- | `rowClassName` | `PRESENT` | `data-table.tsx:353, 461` | — |
115
- | `rowHoverable` | `PRESENT` | `data-table.tsx:445` (`Highlight a row on hover even when it is not clickable`) | — |
116
- | `components` / `getPopupContainer` | `WONT-PORT` | absent | Element-substitution + portal-container escape hatches. |
117
- | `onChange(pagination, filters, sorter, extra)` | `RENAMED` | split into `onSortChange` / `onFilterChange` / `onPaginationChange` / `onSelectChange` | Event-specific names per STANDARDS #12. |
118
-
119
- ### 2.2 `Table` (the primitive) vs antd `Table`
120
-
121
- `src/components/data-display/table.tsx:13-63`. `Table` is **not** antd's `Table` — it is the styled
122
- `<table>`/`<thead>`/`<tr>` set that `DataTable` and hand-composed grids build on
123
- (`namethatui.com` classifies this shape as "table primitive", not "data grid").
124
-
125
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
126
- | --- | --- | --- | --- |
127
- | everything data-grid (sort/filter/select/paginate) | `COVERED-ELSEWHERE` | `DataTable` — `data-table.tsx` | Catalog already says so. |
128
- | `bordered` | `PRESENT` | `table.tsx:25` | — |
129
- | horizontal scroll region, keyboard reachable | `PRESENT` | `table.tsx:19, 84-103` (`tabIndex={0}`, WCAG 2.1.1) | Ahead of antd. |
130
- | `caption` | `MISSING` | grep `caption` → only `caption-bottom` utility (`table.tsx:109`) | P2 — a `<caption>` is the cheapest accessible name for a hand-composed table. |
131
-
132
- ### 2.3 `Descriptions` vs antd `Descriptions`
133
-
134
- `src/components/data-display/descriptions.tsx:48-224`.
135
-
136
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
137
- | --- | --- | --- | --- |
138
- | `column` (number **and** responsive object) | `RENAMED` | `columns?: DescriptionsColumnProp` — `descriptions.tsx:54`, `vocabulary/data.prop.ts:141` | — |
139
- | `layout: horizontal\|vertical` | `PRESENT` | `descriptions.tsx:56` | Default is `vertical` here vs antd's `horizontal` — deliberate. |
140
- | `labelAlign` | `PRESENT` | `descriptions.tsx:61`, guarded to horizontal at `:173` | Logical `start`/`end`, not antd's `left`/`right`. Correct. |
141
- | `bordered` | `PRESENT` | `descriptions.tsx:66` | — |
142
- | `items` | `PRESENT` | `descriptions.tsx:71, 125-135` | — |
143
- | `Item.span` incl. `"filled"` + responsive | `PRESENT` | `descriptions.tsx:151, 164-170` | — |
144
- | `Item.key` | `PRESENT` | `DescriptionsItemsProp.key` — `vocabulary/data.prop.ts:151` | — |
145
- | `title` / `extra` (block header) | `COVERED-ELSEWHERE` | `CardHeader` + `CardTitle` + `CardAction` — `card.tsx:78, 102, 307` | Add the `related` cross-link both ways. |
146
- | `size: default\|middle\|small` | `MISSING` | grep `size` in `descriptions.tsx` → 0 hits | P2 — add `size ∈ sm\|md\|lg` (never `"default"`/`"middle"`). |
147
- | `colon` | `WONT-PORT` | absent | A CJK/Latin punctuation decision belongs in the token/CSS layer, not a prop. |
148
- | `labelStyle` / `contentStyle` / `classNames` / `styles` | `WONT-PORT` | absent | §0.4 — inline-style twins. `--descriptions-*` tokens already cover it (`descriptions.tsx:120, 190`). |
149
-
150
- ### 2.4 `StatCard` vs antd `Statistic` (+ `Statistic.Timer`)
151
-
152
- `src/components/data-display/card.tsx:210-304`.
153
-
154
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
155
- | --- | --- | --- | --- |
156
- | `title` | `RENAMED` | `label` — `card.tsx:211` | — |
157
- | `value` | `PRESENT` | `card.tsx:212` (`React.ReactNode`) | — |
158
- | `precision` | `MISSING` | no formatting anywhere in `card.tsx:249-304` | **P1** — every KPI tile formats its own number. |
159
- | `groupSeparator` / `decimalSeparator` | `MISSING` | ditto | **P1** — but do **not** port antd's spelling: the correct fix is `numberFormat?: Intl.NumberFormatOptions`, the vocabulary `CompactBarTrend` already uses (`charts.prop.ts:106`) and the only one that is CLDR-correct. |
160
- | `formatter` | `COVERED-ELSEWHERE` | `value: ReactNode` accepts a pre-formatted node | — |
161
- | `prefix` / `suffix` | `MISSING` | `card.tsx:210-231` has `icon`/`delta`/`hint` only | P2 — a `¥`/`%`/`件` affix currently has to be baked into `value`, which breaks `tabular-nums` alignment across a KPI row. |
162
- | `loading` | `COVERED-ELSEWHERE` | `SkeletonStat` — `src/components/feedback/skeleton.tsx:92-99` | Cross-link. |
163
- | `valueStyle` | `WONT-PORT` | absent | §0.4 — `--stat-card-*` tokens. |
164
- | `Statistic.Timer` (`type: countdown\|countup`, `format`, `onFinish`, `onChange`) | `MISSING` | `grep -rn "Countdown\|Statistic.Timer" src/` → 0 hits | P2 — real for maintenance windows and OTP expiry; `ErrorSurface.maintenance` already formats a window with `Intl` (`layout.prop.ts:801`), so the arithmetic exists. If added, format with `Intl.RelativeTimeFormat`/`Intl.DurationFormat`, never a `dayjs` `"HH:mm:ss"` template. |
165
- | delta sign → tone | `PRESENT` **but defective** | `getDeltaTone` regex `/^[+\-−]/` on a stringified node — `card.tsx:233-246` | **P1 (i18n)** — a delta formatted with `Intl.NumberFormat(locale, { signDisplay: "always" })` in `ar`/`fa` (Arabic-Indic digits, RTL sign placement) or any locale using U+2212 vs U+002D inconsistently is silently untoned. A `delta: number` + `numberFormat` pair removes the parse entirely. |
166
-
167
- ### 2.5 `Card` / `CardBar` / `CardContent` vs antd `Card`
168
-
169
- `src/components/data-display/card.tsx:34-312`.
170
-
171
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
172
- | --- | --- | --- | --- |
173
- | `title` / `extra` | `COVERED-ELSEWHERE` | `CardHeader` + `CardTitle` (+ `level`/`as`) + `CardAction` — `card.tsx:78, 91-110, 307` | Composition beats antd's flat props; `CardTitle.level` is *ahead* of antd (which emits no heading at all). |
174
- | `cover` | `PRESENT` | `CardCover` — `card.tsx:66` | — |
175
- | `actions` (equal-width bottom bar) | `COVERED-ELSEWHERE` | `CardFooter separated`/`flush` — `card.tsx:144-163` | — |
176
- | `bordered` → v5.24 `variant: outlined\|borderless` | `PRESENT` | `variant: "default" \| "muted" \| "outline" \| "featured"` — `card.tsx:21, 41` | Superset. |
177
- | `hoverable` | `MISSING` | grep `hoverable` in `card.tsx` → 0 hits | P2 — but check first whether `ServiceLauncherCard` (`service-launcher-card.tsx`) already owns the interactive-card case; if so this is `COVERED-ELSEWHERE`. |
178
- | `loading` | `COVERED-ELSEWHERE` | `SkeletonDetail` / `SkeletonStat` — `skeleton.tsx:74, 92` | — |
179
- | `size: default\|small` | `RENAMED` | `density: "tight" \| "cozy"` — `card.tsx:23, 42`; the file explicitly records that a `size` prop was removed 2026-08-24 (`card.tsx:29-32`) | Deliberate; do not re-add. |
180
- | `type="inner"` | `COVERED-ELSEWHERE` | `variant="muted"` | — |
181
- | `tabList` / `activeTabKey` / `onTabChange` / `tabBarExtraContent` | `COVERED-ELSEWHERE` | `CardBar` + `Tabs`; `CardBar.extra` is documented as the `tabBarExtraContent` equivalent — `card.tsx:171` | — |
182
- | `Card.Grid` | `COVERED-ELSEWHERE` | `ResponsiveGrid` (layout group) | Cross-link. |
183
- | `Card.Meta` (`avatar`/`title`/`description`) | `COVERED-ELSEWHERE` | `ListRow` (`leading`/`title`/`description`/`trailing`) — `list-row.tsx:22-58` | Cross-link both sides. |
184
- | `classNames` / `styles` / `bodyStyle` / `headStyle` | `WONT-PORT` | absent | §0.4 — `--card-*` tokens. |
185
- | `accent` + `accentPlacement` | *beyond antd* | `card.tsx:9-19, 35-40` | — |
186
-
187
- ### 2.6 `Avatar` vs antd `Avatar` + `Avatar.Group`
188
-
189
- `src/props/components/data-display.prop.ts:172-199`, `src/components/ui/avatar.tsx`.
190
-
191
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
192
- | --- | --- | --- | --- |
193
- | `src` / `srcSet` / `crossOrigin` / image-load fallback | `PRESENT` | `AvatarImage` + `useImageLoadingStatus` — `ui/avatar.tsx:50-95` | Ahead of antd: a broken `<img>` is never mounted (`ui/avatar.tsx:19-23`). |
194
- | `alt` | `PRESENT` | `AvatarImage` spreads `<img>` props | — |
195
- | `icon` / `children` fallback | `PRESENT` | `AvatarFallback` | — |
196
- | `shape: circle\|square` | `PRESENT` | `AvatarProp.shape` — `data-display.prop.ts:173` | — |
197
- | **`size`** | `MISSING` | `AvatarProp` (`data-display.prop.ts:172-199`) has no `size`; `src/tokens/components/data-display.css:89` names "a `size-12` call site" as an existing pattern | **P1** — add `size ∈ xs\|sm\|md\|lg` resolving from `--control-height` (STANDARDS #22). Every consumer currently hand-writes a Tailwind size utility, which is precisely what `check:control-sizing` forbids inside the package and cannot detect outside it. |
198
- | `gap` (initials inset) | `WONT-PORT` | absent | A pixel knob; `--avatar-*` tokens own it. |
199
- | `onError` returning `false` | `MISSING` | no `onError` hook on the status machine | P2 |
200
- | **`Avatar.Group`** (`max.count`, `max.popover`, shared `size`/`shape`) | `MISSING` | `grep -rn "AvatarGroup\|Avatar.Group" src/ mcp/src/data/components.ts` → 0 hits | **P1** — assignee/attendee stacks are hand-rolled today (overlap offset, the `+N` tile, and the accessible name for "3 more" all re-derived per screen). See GATE-0 §4.1. |
201
- | `presence` (4-state, shape-encoded, `sr-only` label) | *beyond antd* | `data-display.prop.ts:200-216` | — |
202
- | `appearance: tinted` (capability medallion) | *beyond antd* | `data-display.prop.ts:218-238` | — |
203
-
204
- ### 2.7 `Timeline` vs antd `Timeline`
205
-
206
- `src/components/data-display/timeline.tsx`.
207
-
208
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
209
- | --- | --- | --- | --- |
210
- | `items` | `PRESENT` | `timeline.tsx:21-28` | — |
211
- | `item.children` (content) | `RENAMED` | `title` + `location` + `time` + `note` — `timeline.tsx:8-19` | Richer, but see `mode` below. |
212
- | `item.dot` / `icon` | `PRESENT` | `item.icon?: LucideIcon` — `timeline.tsx:18` | — |
213
- | `item.label` | `RENAMED` | `time` — `timeline.tsx:11` | — |
214
- | `item.color` (`blue\|red\|green\|gray` or custom) | `MISSING` | only `status: done\|current\|pending` — `timeline.tsx:4, 16` | P2 — add `tone?: ToneProp` (never antd's colour names), plus the `color?: string` data-colour wash `Badge`/`TimelineGrid` already define (`data-display.prop.ts` `BadgeProp.color`). |
215
- | `mode: left\|alternate\|right` (v6: `start\|alternate\|end`) | `MISSING` | single layout; grep `mode`/`alternate` → 0 hits | P2 — add `placement?: "start" \| "end" \| "alternate"`, logical. |
216
- | `item.position` | `MISSING` | ditto | P2 — pairs with `placement`. |
217
- | `pending` / `pendingDot` (trailing ghost node) | `MISSING` | `status: "pending"` is a *per-item* state, not antd's trailing loader — `timeline.tsx:37-46` | P2 — the name collision is a documentation hazard; record it in the catalog. |
218
- | `reverse` | `MISSING` | grep `reverse` → 0 hits | P2 |
219
- | **screen-reader status prefix** | `MISSING`/**defective** | `SR_PREFIX = { done: "Completed: ", current: "Current: ", pending: "Upcoming: " }` — `timeline.tsx:31-35`, injected at `:107`; `grep -n timeline src/i18n/messages/en.json` → **0 hits** | **P0 (i18n/a11y)** — hardcoded English SR text in a ja/vi product, with a source comment declaring it intentional. Move to `t("dataDisplay.timeline.status.*")` across `en`/`ja`/`vi`. |
220
- | stable item identity | `MISSING` | `key={index}` — `timeline.tsx:84` | P2 — add `id` to `TimelineItem`; index keys break on reorder/prepend. |
221
- | `orientation: horizontal` (v6) | `MISSING` | — | P2 — `TimelineGrid` covers the 2-D case; a horizontal single-axis timeline does not exist. |
222
-
223
- ### 2.8 `Accordion` / `Collapsible` vs antd `Collapse`
224
-
225
- `src/components/ui/accordion.tsx`, `src/components/data-display/collapsible.tsx`.
226
-
227
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
228
- | --- | --- | --- | --- |
229
- | `accordion` (one panel open) | `RENAMED` | `type: "single" \| "multiple"` + `collapsible` — `ui/accordion.tsx:92-116` | — |
230
- | `activeKey` / `defaultActiveKey` / `onChange` | `RENAMED` | `value` / `defaultValue` / `onValueChange` — `ui/accordion.tsx:95-113` | Correct controlled triad. |
231
- | `destroyInactivePanel` → v5.25 `destroyOnHidden` | `PRESENT` (inverted) | children unmount by default; `forceMount` opts out — `ui/accordion.tsx:346-349, 382` | — |
232
- | arrow-key roving, `Home`/`End`, wrap, skip-disabled | `PRESENT` | `moveFocus` — `ui/accordion.tsx:169-200` | Ahead of antd (rc-collapse has none). |
233
- | `bordered` / `ghost` | `COVERED-ELSEWHERE` | `.ui-accordion-*` + tokens | — |
234
- | `size: large\|middle\|small` | `MISSING` | grep `size` in `ui/accordion.tsx` → 0 hits | P2 — `size ∈ sm\|md\|lg`. |
235
- | `expandIconPosition` (v6 `expandIconPlacement: start\|end`) | `MISSING` | chevron is appended unconditionally — `ui/accordion.tsx:340` | P2 — a token (`--accordion-chevron-*`) per cardinal rule #44, not a prop. |
236
- | `item.showArrow: false` | `MISSING` | ditto | P2 |
237
- | **`item.extra`** (corner slot outside the trigger) | `MISSING` | `AccordionTrigger` renders `children` + chevron inside one `<button>` — `ui/accordion.tsx:320-341` | **P1 (a11y)** — a header carrying a `Switch`/`Button`/`Badge` action cannot be expressed without nesting an interactive element inside a `<button>`. Add an `extra` slot rendered as a sibling of the trigger inside the header. |
238
- | **`collapsible: 'header'\|'icon'\|'disabled'`** | `PARTIAL` (`disabled` only) | `AccordionItem.disabled` — `ui/accordion.tsx:243`; no `icon` mode | **P1** — the companion to `extra`: `collapsible="icon"` shrinks the trigger to the chevron so the rest of the header can hold real controls. |
239
- | **heading level of the trigger** | `MISSING` | `<h3>` hardcoded — `ui/accordion.tsx:314` | **P1 (a11y)** — WAI-ARIA APG requires the button be wrapped in a heading *of the correct level*. An accordion under an `<h4>` section skips/inverts the outline. `CardTitle.level` (`card.tsx:93`) and `EmptyState.titleLevel` (`data-display.prop.ts:122`) already ship this exact vocabulary; Accordion is the odd one out. |
240
- | `items` (declarative array) | `MISSING` | children-composed only — `ui/accordion.tsx:134-239` | P2 — `Tabs`, `Steps` and `Descriptions` all take `items`; Accordion is inconsistent. |
241
- | `expandIcon` render prop | `WONT-PORT` | absent | Token, not a render prop. |
242
- | `Collapsible` (single disclosure) | `PRESENT` | `collapsible.tsx:60-200`, `open`/`defaultOpen`/`onOpenChange`/`disabled` | antd has no single-disclosure primitive; this is a superset. |
243
-
244
- ### 2.9 `Carousel` vs antd `Carousel`
245
-
246
- `src/components/data-display/carousel.tsx`.
247
-
248
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
249
- | --- | --- | --- | --- |
250
- | `infinite` | `COVERED-ELSEWHERE` | `opts.loop` (embla) — `carousel.tsx:38` | — |
251
- | `dots` | `PRESENT` | `CarouselDots` — `carousel.tsx:238-274` | Opt-in child rather than a boolean. |
252
- | `arrows` | `PRESENT` | `CarouselPrevious` / `CarouselNext` — `carousel.tsx:187-231` | — |
253
- | `goTo` / `next` / `prev` (imperative) | `PRESENT` | `setApi` + `useCarousel()` — `carousel.tsx:40, 27-33` | — |
254
- | `beforeChange` / `afterChange` | `COVERED-ELSEWHERE` | `api.on("select", …)` via `setApi` | P2 — a first-class `onValueChange(index)` would be the house spelling; the raw embla event bus is an escape hatch. |
255
- | `autoplay` / `autoplaySpeed` | `MISSING` | `plugins` passthrough only — `carousel.tsx:39` | P2 — **but** if added it MUST ship a pause control (WCAG 2.2.2 SC "Pause, Stop, Hide") and honour `prefers-reduced-motion`. A consumer bolting `embla-carousel-autoplay` onto `plugins` today gets a silent WCAG failure with no affordance. Record that in the catalog either way. |
256
- | `effect: fade` | `MISSING` | grep `fade` → 0 hits | P2 |
257
- | `adaptiveHeight` | `MISSING` | grep `adaptiveHeight` → 0 hits | P2 |
258
- | `dotPosition` (v6 `dotPlacement: top\|bottom\|start\|end`) | `COVERED-ELSEWHERE` | CSS placement of `CarouselDots` | Composition. |
259
- | `draggable` / `speed` / `easing` / `waitForAnimate` | `COVERED-ELSEWHERE` | `opts` (embla) — `carousel.tsx:38` | Raw-library passthrough; note it in the catalog as the documented escape hatch. |
260
- | **dots ARIA** | *defect* | `role="tablist"` + `role="tab"` + `aria-selected` with **no `aria-controls`** and slides that are `role="group"`, not `tabpanel` — `carousel.tsx:249-269` vs `:178-179` | **P1 (a11y)** — tabs that control nothing. APG's carousel pattern wants either (a) real tabs wired `aria-controls` → `role="tabpanel"` slides, or (b) plain buttons in a `role="group"`. Pick one. |
261
- | **arrow direction under RTL** | *defect* | `ChevronLeft`/`ChevronRight` hardcoded — `carousel.tsx:203, 226`; `grep carousel-arrow src/styles/data-display-layout.css` shows no `[dir="rtl"]`/`scale(-1)` rule | **P1 (RTL)** — "previous" points left in `ar`/`he`, where previous is to the right. |
262
- | slide "N of M" announcement | `PRESENT` | `carousel.tsx:143-156` via `t()` | Ahead of antd. |
263
-
264
- ### 2.10 `EmptyState` vs antd `Empty`
265
-
266
- `src/components/data-display/empty-state.tsx`, `src/props/components/data-display.prop.ts:110-128`.
267
-
268
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
269
- | --- | --- | --- | --- |
270
- | `description` | `PRESENT` | `data-display.prop.ts:113` | — |
271
- | `children` (a CTA under the description) | `RENAMED` | `action?: ActionProp` — `data-display.prop.ts:114` | — |
272
- | `image` (`ReactNode`, a URL string, or `PRESENTED_IMAGE_SIMPLE/DEFAULT`) | `MISSING` | `icon?: IconProp` is a **`LucideIcon` component type** only — `data-display.prop.ts:111`; rendered at `empty-state.tsx:34-42` | P2 — a brand illustration or an `<img>` cannot be passed. Add `media?: ReactNode` beside `icon` (do not widen `icon`, which is a typed Lucide slot everywhere else). |
273
- | `imageStyle` | `WONT-PORT` | absent | §0.4 — `--empty-state-icon-*` tokens. |
274
- | `variant` (page/section/compact), `tone`, `titleLevel`, `titleAs` | *beyond antd* | `data-display.prop.ts:116-127` | — |
275
- | `role="status"` | `PRESENT` | `empty-state.tsx:31` | Ahead of antd. |
276
- | icon dropped in `compact` | *documented* | `empty-state.tsx:34` (`variant !== "compact"`) | Worth stating in the catalog. |
277
-
278
- ### 2.11 `ErrorSurface` / `DataState` vs antd `Result`
279
-
280
- `src/props/components/layout.prop.ts:759-816`, `src/props/vocabulary/layout.prop.ts:49`, `src/props/components/query.prop.ts:15-31`.
281
-
282
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
283
- | --- | --- | --- | --- |
284
- | `status: 404\|403\|500` | `PRESENT` | `ErrorSurfaceStatusProp = 400 \| 403 \| 404 \| 500 \| 503 \| (number & {})` — `vocabulary/layout.prop.ts:49` | Superset (400/503). |
285
- | `status: success\|error\|info\|warning` (non-HTTP outcome pages) | `MISSING` | the union is numeric-only — `vocabulary/layout.prop.ts:49` | P2 — antd's `Result status="success"` is the "submission complete" page. Today that is `EmptyState tone="success"` + `action`, which is a reasonable `COVERED-ELSEWHERE`; cross-link it rather than widening the status union. |
286
- | `title` / `subTitle` | `PRESENT` | `title` / `description` — `layout.prop.ts:765, 767` | — |
287
- | `extra` (actions) | `RENAMED`, narrowed | `action: ActionProp` — exactly one, structurally enforced (`layout.prop.ts:772`) | Deliberate; keep. |
288
- | `icon` | `PRESENT` | `layout.prop.ts:777` | — |
289
- | `children` (content block) | `MISSING` | single `description` slot | P2 |
290
- | `requestId` / `permission` / `organization` / `maintenance` / `mode` / `brand` / `footer` | *beyond antd* | `layout.prop.ts:786-812` | — |
291
- | antd `Table.locale.emptyText` + `Spin` lifecycle | `COVERED-ELSEWHERE` | `DataState` — `query.prop.ts:15-31` (skeleton → prerequisite → empty → error, cause-aware retry) | Cross-link. |
292
-
293
- ### 2.12 `Skeleton` / `SkeletonTable` vs antd `Skeleton`
294
-
295
- `src/components/feedback/skeleton.tsx`.
296
-
297
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
298
- | --- | --- | --- | --- |
299
- | `loading` (render children when false) | `MISSING` | `SkeletonProps = React.HTMLAttributes<HTMLDivElement>` — `skeleton.tsx:8` | `COVERED-ELSEWHERE` by `DataState.skeleton` (`query.prop.ts:16`); no work. |
300
- | `active` (shimmer) | `MISSING` | no props at all — `skeleton.tsx:8-19` | P2 — and it must be inert under `prefers-reduced-motion`. |
301
- | `paragraph: { rows, width }` | `PARTIAL` | `SkeletonRows({ rows, columns })` — `skeleton.tsx:21-46`; widths are baked (`w-1/4`, `w-1/6`, `flex-1` at `:38`) | P2 — per-row width is not reachable. |
302
- | `title: { width }` | `MISSING` | `SkeletonDetail` bakes `w-1/3` — `skeleton.tsx:77` | P2 |
303
- | `avatar: { shape, size }` | `MISSING` | no avatar preset | P2 |
304
- | `round` | `WONT-PORT` | absent | Token (`--radius`). |
305
- | `Skeleton.Button` / `.Input` / `.Image` / `.Node` | `MISSING` | grep → only `Skeleton`, `SkeletonRows`, `SkeletonTable`, `SkeletonDetail`, `SkeletonStat` | P2 — the house presets (`Table`/`Detail`/`Stat`) are a *better* answer than antd's shape primitives for this product; record that as the deliberate design and add only `Skeleton.Node`-equivalent freedom (already available: `Skeleton` takes `className`). |
306
- | `size` | `MISSING` | — | P2 |
307
- | **live-region hygiene** | *defect* | every `Skeleton` block carries `aria-busy="true"` **and** `aria-live="polite"` — `skeleton.tsx:13-14`; `SkeletonTable` renders 40+ of them (`:49-70`) | **P1 (a11y)** — dozens of nested polite live regions on decorative placeholders. Correct shape: **one** `aria-busy` container with a localized `aria-label`, and the blocks themselves `aria-hidden`. There is no shared `common.loading` key today — the nearest is `dataTable.loading` (`src/i18n/messages/en.json:461`), so a `feedback.skeleton.loading` key has to be added in `en`/`ja`/`vi`. `Activity` already documents the right rule ("`aria-busy` + an unconditional live region" is *its* stated anti-pattern — `general.prop.ts:213` docblock). |
308
-
309
- ### 2.13 `Alert` / `Banner` vs antd `Alert`
310
-
311
- `src/components/feedback/alert.tsx`, `src/props/components/feedback.prop.ts:41-93`.
312
-
313
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
314
- | --- | --- | --- | --- |
315
- | `type: success\|info\|warning\|error` | `RENAMED` | `tone?: ToneProp` — `feedback.prop.ts:56` | STANDARDS #9. |
316
- | `message` (v6 `title`) / `description` | `RENAMED` | `Alert.Title` / `Alert.Description` children — `alert.tsx:104-128` | Composition. |
317
- | `showIcon` / `icon` | `PRESENT` | `icon?: IconProp \| false` — `feedback.prop.ts:58`; defaults per tone at `alert.tsx:48-56` | Better default (`showIcon` defaults `false` in antd — an icon-less error). |
318
- | `closable` / `onClose` / `closeIcon` | `RENAMED` | `onDismiss` — `feedback.prop.ts:59`, rendered with a `t()` label at `alert.tsx:82-96` | — |
319
- | `afterClose` | `MISSING` | grep `afterClose` → 0 hits | P2 |
320
- | `banner` | `RENAMED` | `Banner` component with `variant` fixed — `banner.tsx:14-26` | — |
321
- | `action` | `RENAMED` | `Alert.Actions` — `alert.tsx:130-135` | — |
322
- | `variant: outlined\|filled` (v6.4) | `PRESENT` | `AlertVariantProp` — `feedback.prop.ts:55` | — |
323
- | `Alert.ErrorBoundary` | `MISSING` | `grep -rln ErrorBoundary src/` → **0 hits** | P2 — `ErrorSurface` is the *page*-level answer; a component-level boundary that renders an `Alert` has no equivalent. Note: a React error boundary is a class component, which is why antd ships it. |
324
- | assertive vs polite live region derived from tone | `PRESENT` | `ASSERTIVE_TONES` → `role="alert"` else `role="status"` — `alert.tsx:46, 70` | Ahead of antd. |
325
- | `Alert.QueryError` (cause-aware, never leaks backend text) | *beyond antd* | `alert.tsx:181-225` | — |
326
-
327
- ### 2.14 `Toaster` vs antd `notification` + `message`
328
-
329
- `src/components/feedback/sonner.tsx`, `src/components/feedback/use-toast.ts`, catalog entry `mcp/src/data/components.ts:7299-7345`.
330
-
331
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
332
- | --- | --- | --- | --- |
333
- | `message.success/error/info/warning/loading` | `COVERED-ELSEWHERE` | sonner `toast.*` — `use-toast.ts:1-11` | — |
334
- | `message.promise`-style flow | `PRESENT` | `toast.promise` — `use-toast.ts:4` | — |
335
- | `notification` (title + description + actions) | `COVERED-ELSEWHERE` | sonner's `ExternalToast` (`description`, `action`) — re-exported at `use-toast.ts:10` | — |
336
- | `duration`, `pauseOnHover`, `showProgress` | `COVERED-ELSEWHERE` | sonner options | — |
337
- | `maxCount` / `stack` | `COVERED-ELSEWHERE` | sonner `visibleToasts` | — |
338
- | `key` → update a live toast in place | `COVERED-ELSEWHERE` | sonner returns an id accepted by `toast(…, { id })` | — |
339
- | `placement` (`topRight` …) | `MISSING` (house vocabulary) | `position="bottom-right"` — `sonner.tsx:118`; the catalog documents the physical union — `components.ts:7307-7310` | **P1 (RTL)** — physical `left`/`right` corners contradict §0.4 and never flip under `dir="rtl"`. The house spelling is `placement ∈ top-start \| top-center \| top-end \| bottom-*`. |
340
- | `role: 'alert' \| 'status'` (5.6.0) | `MISSING` | not exposed | P2 — a destructive toast should be assertive; `Alert` already derives this from tone (`alert.tsx:46`). |
341
- | close-button label localization | `MISSING` | no `closeButton`/`t()` wiring in `sonner.tsx:84-128`; sonner's own default label is English | **P1 (i18n)** — verify against a live render; if sonner's default label ships untranslated, the toast has an English control in a ja/vi app. |
342
- | **the whole imperative surface is un-owned** | *systemic* | catalog tagline: "trigger toasts via `import { toast } from \"sonner\"` — **NOT** from @godxjp/ui" (`components.ts:7302`); `use-toast.ts` re-exports sonner verbatim | **P1** — consumers call a third-party API directly, so nothing in the vocabulary check, the prop registry, the a11y contract or `t()` covers the most-used feedback path in the product. Wrap it: `toast()` exported from `@godxjp/ui/feedback` with house options (`tone`, `placement`, `duration`, `action`), delegating to sonner. This is the same argument that produced `Alert.QueryError`. |
343
-
344
- ### 2.15 `Tooltip` / `Popover` / `HoverCard` vs antd `Tooltip` / `Popover` / `Popconfirm`
345
-
346
- `src/components/feedback/tooltip.tsx`, `src/components/data-display/popover.tsx`, `src/components/ui/hover-card.tsx`.
347
-
348
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
349
- | --- | --- | --- | --- |
350
- | `title` / `content` shorthand | `RENAMED` | `TooltipContent` / `PopoverContent` children | — |
351
- | `open` / `defaultOpen` / `onOpenChange` | `PRESENT` | `tooltip.tsx:100-111`; `popover.tsx` root | Correct disclosure triad. |
352
- | `placement` (12 values) | `RENAMED` | `side` + `align` → `placement` internally — `tooltip.tsx:51-62`, `popover.tsx:322-325` | Radix vocabulary. |
353
- | `side: 'left' \| 'right'` | *physical* | `type Side = "top" \| "right" \| "bottom" \| "left"` — `tooltip.tsx:51` | P2 — §0.4 argues for logical `inline-start`/`inline-end`. Radix/RAC flip physical sides automatically under `dir`, so this is **not** an RTL bug; it is a vocabulary inconsistency. Document, don't churn. |
354
- | `mouseEnterDelay` / `mouseLeaveDelay` | `PARTIAL` | `delayDuration` (open only) + `TooltipProvider` — `tooltip.tsx:79-98, 108` | P2 — no close delay. |
355
- | **`arrow`** (default `true` in antd) | `MISSING` | `grep -rln "PopoverArrow\|TooltipArrow\|ui-tooltip-arrow\|ui-popover-arrow" src/` → **0 hits** | P2 — with several triggers in a row (a toolbar), a tooltip with no arrow does not say which control it belongs to. Add as an opt-in part + token, not a boolean twin. |
356
- | `trigger: click \| hover \| focus \| contextMenu` | `COVERED-ELSEWHERE` | `Tooltip` = hover/focus (RAC, correct per APG); `Popover` = click; `HoverCard` = hover-rich | Three components, one axis. Cross-link all three. |
357
- | `color` (background preset) | `WONT-PORT` | absent | §0.4 — tokens. |
358
- | `fresh` / `destroyOnHidden` | `MISSING` | `forceMount` is inert on RAC — `tooltip.tsx:177`, `popover.tsx:339` | P2 — the *inert-but-kept* Radix props (`sticky`, `hideWhenDetached`, `forceMount`) are documented dead weight (`tooltip.tsx:172-177`); flag them in the catalog so consumers stop passing them. |
359
- | `getPopupContainer` / `zIndex` / `align` (dom-align) | `WONT-PORT` | absent | Escape hatches / pixel knobs. |
360
- | `Popconfirm` (title + description + OK/Cancel on a trigger) | `COVERED-ELSEWHERE` | `AlertDialog` (`feedback.prop.ts:22-39`, incl. `confirmPhrase`/`challenge`/`stepUp`) for consequential actions; `Popover` + two `Button`s for light ones | No new component. Add the `related` cross-link on both sides — the catalog currently names neither as antd's `Popconfirm`. |
361
-
362
- ### 2.16 `Dialog` / `AlertDialog` / `Sheet` vs antd `Modal` / `Drawer`
363
-
364
- `src/components/feedback/dialog.tsx`, `src/components/feedback/sheet.tsx`.
365
-
366
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
367
- | --- | --- | --- | --- |
368
- | `open` / `onCancel` / `onOk` / `okText` / `cancelText` / `okType` | `PRESENT` | `AlertDialogProp` — `feedback.prop.ts:22-39`; `Dialog.Action` / `Dialog.Cancel` — `dialog.tsx:724-725` | — |
369
- | `confirmLoading` | `RENAMED` | `pending` — `feedback.prop.ts:38`, `dialog.tsx:602` | STANDARDS forbidden-alias table. |
370
- | `closable` / `closeIcon` | `PRESENT` | `showClose` / `showCloseButton` — `dialog.tsx:288-289` | — |
371
- | `maskClosable` (v6 `mask.closable`) | `PRESENT` | `isDismissable` — `dialog.tsx:148`; `false` for `alertdialog` — `dialog.tsx:478` | Correct APG behaviour. |
372
- | `keyboard` (Esc) | `PRESENT` | `dialog.tsx:37-38` (Escape closes alert-dialog too, matching Radix) | — |
373
- | `destroyOnHidden` / `forceRender` | `PRESENT` | `forceMount` — `dialog.tsx:244, 292` | — |
374
- | `focusTriggerAfterClose` | `PRESENT` | `onCloseAutoFocus` + `useOverlayCloseFocus` — `dialog.tsx:294` | — |
375
- | `title` / `footer` / `extra` (Drawer) | `PRESENT` | `SheetHeader({ title, extra })` — `sheet.tsx:362-368`; `SheetFooter` — `sheet.tsx:426` | — |
376
- | `loading` (skeleton body, 5.17/5.18) | `MISSING` | grep `loading` in `dialog.tsx`/`sheet.tsx` → only `pending` on the confirm button | P2 — an async-loaded dialog body has no built-in placeholder. |
377
- | `width` / `size: default\|large` | `MISSING` (Sheet) | `--sheet-width-default` token only — `sheet.tsx:242` | P2 — a token exists, a per-instance `size` does not. |
378
- | `Drawer.placement` (v6 logical) | *physical, deliberate* | `side` with an explicit `/* rtl-ignore: named physical side */` — `sheet.tsx:241-243`; `SheetResponsiveProp` (`auto`/`side`/`bottom`) — `feedback.prop.ts:104` | `WONT-PORT` as written **but record the reason in the catalog** so it is not re-litigated. antd v6 moved to `start`/`end`; the responsive `auto` mode is a better answer than either. |
379
- | `Drawer.push` (nested drawers) / `resizable` / `maxSize` (v6) | `MISSING` | grep → 0 hits | P2 |
380
- | `Modal.confirm()` / `useModal()` returning a promise | `MISSING` | no imperative helper; `grep -rn "useModal\|modal.confirm" src/` → 0 hits | P2 — `AlertDialog` is the declarative answer and is better for a11y (the context-holder problem antd documents does not exist here). Record as a deliberate refusal rather than a gap. |
381
- | `modalRender` / `drawerRender` / `classNames` / `styles` / `getContainer` / `zIndex` | `WONT-PORT` | absent | §0.4. |
382
-
383
- ### 2.17 `Progress` vs antd `Progress`
384
-
385
- `src/components/data-display/progress.tsx`.
386
-
387
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
388
- | --- | --- | --- | --- |
389
- | `percent` | `RENAMED` | `value` — `progress.tsx:36` | — |
390
- | `status: success\|exception\|normal` | `RENAMED` | `tone: "success" \| "warning" \| "destructive"` — `progress.tsx:6, 37` | — |
391
- | `status="active"` (indeterminate stripe) | `COVERED-ELSEWHERE` | `Activity` (`general.prop.ts:213`) / `Skeleton` | Cross-link. |
392
- | `showInfo` / `format(percent)` | `MISSING` | `label` is a caption, not the value — `progress.tsx:31, 108-113`; the percentage exists only in `aria-valuetext` (`:174`) | **P1** — the number is announced but never *shown*. A capacity meter that shows no figure is the commonest complaint against this component. Add `showValue?: boolean` + `numberFormat?: Intl.NumberFormatOptions`. |
393
- | **percentage formatting** | *defect* | `aria-valuetext={`${boundedValue}%`}` — `progress.tsx:174` | **P1 (i18n)** — a hand-built percent string. `Intl.NumberFormat(locale, { style: "percent" })` places the sign correctly for `tr` (`%50`), `fr` (`50 %`) and uses locale digits. Same fix as `showValue`. |
394
- | `type: circle` / `dashboard` | `MISSING` | grep `circle`/`dashboard` in `progress.tsx` → 0 hits | **P1** — a ring gauge is standard on any KPI dashboard; today it is hand-rolled SVG in the consumer. Extend `Progress` with `variant?: "bar" \| "circle" \| "gauge"` (reusing the existing role/ARIA machinery), **not** a new component. |
395
- | `steps` (discrete segments) | `MISSING` | `segments` is a *breakdown partition* (`progress.tsx:66-71`), a different concept | P2 — record the name collision in the catalog. |
396
- | `size` | `MISSING` | grep `size` in `progress.tsx` → 0 hits | P2 — `size ∈ xs\|sm\|md\|lg`. |
397
- | `success: { percent }` (sub-bar) | `COVERED-ELSEWHERE` | `segments` — `progress.tsx:66` | — |
398
- | `strokeColor` (incl. gradients) / `trailColor` / `strokeLinecap` / `gapDegree` | `WONT-PORT` | absent | §0.4 — `--progress-*` tokens. |
399
- | `over` (>100 %, striped over-capacity fill, real ratio in `aria-valuetext`) | *beyond antd* | `progress.tsx:38-45, 160-174` | — |
400
- | breakdown as `role="img"` with every slice spoken, labels required | *beyond antd* | `progress.tsx:48-64, 115-154` | Exemplary; keep. |
401
-
402
- ### 2.18 `QrCode` vs antd `QRCode`
403
-
404
- `src/components/data-display/qr-code.tsx`.
405
-
406
- | Ant Design prop / behaviour | Status | Evidence | Verdict |
407
- | --- | --- | --- | --- |
408
- | `value` | `PRESENT` | `qr-code.tsx:20` | — |
409
- | `size` | `PARTIAL` | `size?: SizeProp` → `data-size` attribute; the SVG is fixed at 256 (`QR_INTRINSIC_SIZE`, `qr-code.tsx:13, 27`) and scaled by CSS | Correct house design (tier, not px). No work. |
410
- | `type: canvas\|svg` | `WONT-PORT` | SVG only — `qr-code.tsx:22` | SVG is the right choice (scales, prints, no DPR bug). State it in the catalog. |
411
- | `errorLevel: L\|M\|Q\|H` | `MISSING` | hardcoded `level="M"` — `qr-code.tsx:28` | P2 — `H` is needed whenever an `icon` overlays the modules, and for printed codes. |
412
- | `boostLevel` | `PRESENT` (forced on) | `qr-code.tsx:29` | — |
413
- | `icon` / `iconSize` (centre logo) | `MISSING` | grep → 0 hits | P2 — depends on `errorLevel="H"`; ship the pair or neither. |
414
- | `bordered` | `MISSING` | grep → 0 hits | P2 — token, not a prop. |
415
- | `color` / `bgColor` | `WONT-PORT` | `hsl(var(--qr-code-*))` — `qr-code.tsx:31-32` | §0.4 — already tokens. Note: token-driven colours mean a theme *can* produce a sub-threshold contrast ratio and break scanning; a documented contrast floor would be worth a catalog rule. |
416
- | `status: active\|expired\|loading\|scanned` + `onRefresh` + `statusRender` | `MISSING` | grep `status` in `qr-code.tsx` → 0 hits | **P1** — an expired-code overlay with a refresh button is the whole UX of a device-pairing / 2FA-enrolment screen, and `TwoFactorSetup` (`src/components/feedback/two-factor-setup.tsx`) is exactly that screen. Without it every consumer hand-rolls an absolutely-positioned overlay with no live-region announcement of the state change. |
417
- | `marginSize` (quiet zone) | `PRESENT` (fixed) | `marginSize={4}` — `qr-code.tsx:30` | Correct — 4 modules is the spec minimum. |
418
- | accessible name never leaks the encoded value | *beyond antd* | `qr-code.tsx:16-17, 33-34` | — |
419
-
420
- ### 2.19 `ScrollArea`, `CodeBlock`, `Prose`, `ListRow`, `TimelineGrid`, `RangeTimeline`, `CompactBarTrend`, `Legend`, `CredentialReveal`, `PermissionMatrix`, `ServiceLauncherCard`, `PrefetchLink`, `InfiniteQueryState`, `TwoFactorSetup`
421
-
422
- **No antd counterpart exists** for these; they are this library's own vocabulary, and
423
- `namethatui.com/?platform=web` returns no matching web pattern for `RangeTimeline`, `TimelineGrid`,
424
- `PermissionMatrix`, `CredentialReveal` or `ServiceLauncherCard`. Checked and **fully aligned / out of
425
- antd's scope**:
426
-
427
- - `ScrollArea` (`data-display.prop.ts:477-503`) — `orientation`, `anchor: "bottom"` for live streams,
428
- `anchorOffset` from a token, `onAnchoredChange` so "jump to newest" is never motion-only. No antd
429
- equivalent; ahead of it.
430
- - `CodeBlock` (`code-block.tsx:8-39`) — `wrap`, `maxHeight`, `tabIndex` when it scrolls (WCAG 2.1.1).
431
- Nearest antd is `Typography.Text code`, which is inline only.
432
- - `Prose` (`prose.tsx:8-23`) — antd's `Typography` has no rendered-HTML container.
433
- - `ListRow` (`list-row.tsx:22-58`, `data-display.prop.ts:374-397`) — see §2.5, covers `Card.Meta` and `List.Item.Meta`.
434
- - `TimelineGrid` / `RangeTimeline` (`data-display.prop.ts:546-570`, `range-timeline.tsx`) — 2-D
435
- resource timelines; antd has nothing comparable.
436
- - `CompactBarTrend` (`charts.prop.ts:83-121`) — the sparkline. Already takes
437
- `numberFormat?: Intl.NumberFormatOptions` and requires a `label` for `role="img"`. **This is the
438
- formatting vocabulary `StatCard` should adopt** (§2.4).
439
- - `Legend`, `CredentialReveal`, `PermissionMatrix`, `ServiceLauncherCard`, `PrefetchLink`,
440
- `InfiniteQueryState`, `TwoFactorSetup`, `DataState`, `AlertDialogRoot` — house-specific.
441
-
442
- ### 2.20 Ant Design components with **no** counterpart here
443
-
444
- | Ant component | Status | Evidence | Verdict |
445
- | --- | --- | --- | --- |
446
- | `Spin` | `COVERED-ELSEWHERE` | `Activity` (`general.prop.ts:213-240`), `Skeleton`, `DataState`, `Button pending` | No work. The `Activity` docblock already draws the three-way distinction correctly. |
447
- | `Empty` | `COVERED-ELSEWHERE` | `EmptyState` — §2.10 | — |
448
- | `Result` | `COVERED-ELSEWHERE` | `ErrorSurface` — §2.11 | — |
449
- | `Popconfirm` | `COVERED-ELSEWHERE` | `AlertDialog` / `Popover` + `Button`s — §2.15 | — |
450
- | `notification` / `message` | `COVERED-ELSEWHERE` | `Toaster` — §2.14 (but the wrapper gap there is P1) | — |
451
- | `Rate` | `COVERED-ELSEWHERE` | `Rating` (data-entry) — `src/components/ui/rating.tsx:11-38`: `count`, `allowHalf`, `character`, `tooltips`, `readOnly`, `disabled` | Full parity, including read-only display. Cross-link from `data-display`. |
452
- | `Statistic.Timer` | `MISSING` | `grep -rn "Countdown\|Statistic.Timer" src/` → 0 hits | P2 — extend `StatCard` (§2.4), not a new component. |
453
- | `Image` (+ `PreviewGroup`) | `MISSING` | `grep -rn "ImagePreview\|Lightbox" src/` → 0 hits; only `upload-crop-dialog.tsx` handles images | P2 — see GATE-0 §4.2. |
454
- | `Watermark` | `MISSING` | `grep -rn Watermark src/` → 0 hits | P2 — see GATE-0 §4.3. |
455
- | `Tour` | `MISSING` | `grep -rn Tour src/` → 0 hits | P2 — see GATE-0 §4.4. |
456
- | `Splitter` | `PARTIAL` | `SplitPane` (layout group) — `src/components/layout/split-pane.tsx:3-31`: `aside`, `asideWidth: sm\|md\|lg`, `asideLabel`, `fill`. **No draggable divider, no `min`/`max`, no collapse, no `onResize`** | **P1**, but it belongs to the `layout` group's audit — flagged here because the brief asked for the comparison. antd's separator is keyboard-operable (`role="separator"` + arrow keys); a fixed three-tier width is not the same component. |
457
-
458
- ---
459
-
460
- ## 3. Consolidated priority list
461
-
462
- Every `MISSING`/defective row, most severe first. **P0** = breaks a real screen · **P1** = a
463
- workaround exists but is hand-rolled and a11y-risky · **P2** = nice to have.
464
-
465
- ### P0
466
-
467
- | # | Component | Gap | Evidence |
468
- | --- | --- | --- | --- |
469
- | 1 | `Timeline` | Screen-reader status prefixes are **hardcoded English** (`"Completed: "` / `"Current: "` / `"Upcoming: "`) with no i18n keys in any locale file. Every ja/vi screen using `Timeline` announces English. | `src/components/data-display/timeline.tsx:31-35, 107`; `grep -n timeline src/i18n/messages/en.json` → 0 hits |
470
-
471
- ### P1
472
-
473
- | # | Component | Gap | Evidence |
474
- | --- | --- | --- | --- |
475
- | 2 | `Skeleton` | `aria-live="polite"` on **every** placeholder block — a `SkeletonTable` mounts 40+ nested live regions, and none has a localized name. Should be one `aria-busy` container with a localized label and `aria-hidden` blocks; no shared `common.loading` key exists yet (nearest: `dataTable.loading`). | `skeleton.tsx:13-14, 49-70`; `src/i18n/messages/en.json:461` |
476
- | 3 | `Accordion` | Trigger heading level hardcoded to `<h3>`; breaks the document outline wherever the accordion is not a level-3 section. `CardTitle.level` / `EmptyState.titleLevel` already ship the vocabulary. | `src/components/ui/accordion.tsx:314`; cf. `card.tsx:93`, `data-display.prop.ts:122` |
477
- | 4 | `Accordion` | No `extra` slot and no `collapsible="icon"`: a header carrying a `Switch`/`Button` must nest an interactive element inside the trigger `<button>`. | `ui/accordion.tsx:320-341` |
478
- | 5 | `Carousel` | Dots are `role="tab"`/`aria-selected` with **no `aria-controls`**, over slides that are `role="group"` — tabs that control nothing. | `carousel.tsx:249-269` vs `:178-179` |
479
- | 6 | `Carousel` | Prev/next arrows are hardcoded `ChevronLeft`/`ChevronRight` with no RTL flip in the stylesheet. | `carousel.tsx:203, 226`; `src/styles/data-display-layout.css:547-580` (no `[dir="rtl"]` rule) |
480
- | 7 | `Toaster` | The imperative API is un-owned: the catalog instructs consumers to import `toast` from `sonner` directly, so no house vocabulary, no `t()`, no tone→politeness mapping, no prop registry coverage. | `mcp/src/data/components.ts:7302`; `src/components/feedback/use-toast.ts:1-11` |
481
- | 8 | `Toaster` | `position` is sonner's physical `"bottom-right"`; never flips under `dir="rtl"`. Close-button label localization unverified (sonner's default is English). | `sonner.tsx:118, 84-128`; `components.ts:7307-7310` |
482
- | 9 | `Avatar` | No `size` prop — consumers hand-write `size-12` Tailwind classes, which `check:control-sizing` cannot see outside the package. | `data-display.prop.ts:172-199`; `src/tokens/components/data-display.css:89` |
483
- | 10 | `Avatar` | No `Avatar.Group` — every assignee/attendee stack re-derives overlap, the `+N` tile and its accessible name. | `grep -rn "AvatarGroup\|Avatar.Group" src/ mcp/src/data/components.ts` → 0 hits |
484
- | 11 | `Progress` | The percentage is announced but never displayed (no `showValue`/`format`), and `aria-valuetext` builds the percent string by hand instead of `Intl.NumberFormat(style:"percent")`. | `progress.tsx:174, 108-113` |
485
- | 12 | `Progress` | No circular / gauge form; KPI ring gauges are hand-rolled SVG in consumers. | `grep -n "circle\|dashboard" src/components/data-display/progress.tsx` → 0 hits |
486
- | 13 | `StatCard` | No number formatting (`precision`/separators/affixes) and a locale-fragile regex sign parse for the delta tone. | `card.tsx:210-231, 233-246` |
487
- | 14 | `QrCode` | No `status` (`expired`/`scanned`/`loading`) + `onRefresh`; the 2FA-enrolment screen that needs it ships in this very group. | `qr-code.tsx:19-42`; `src/components/feedback/two-factor-setup.tsx` |
488
- | 15 | `DataTable` | No `virtual` list — no answer for a 5 000-row grid. Same gap `docs/roadmap/list-masonry.md` records for `List`; solve once, share the primitive. | `grep -n virtual src/components/data-display/data-table.tsx` → 0 hits |
489
- | 16 | `DataTable` | No `onCell` → no `colSpan`/`rowSpan` merged cells; the only escape is the raw `Table` primitive, which forfeits sort/filter/selection. | `grep -n "onCell\|rowSpan" src/components/data-display/data-table.tsx` → 0 hits |
490
- | 17 | `DataTable` | No `column.rowScope` → no row-header column, so a screen reader cannot name each cell by its row. | `grep -n rowScope src/props/vocabulary/data.prop.ts` → 0 hits |
491
- | 18 | `DataTable` | No `childrenColumnName`/`indentSize` → nested (tree) rows are impossible, although `TableCellIndentProp` already exists for exactly this. | `grep -n childrenColumnName …` → 0 hits; `vocabulary/data.prop.ts` `TableCellIndentProp` |
492
- | 19 | `SplitPane` *(layout group — flagged, not owned)* | No draggable, keyboard-operable separator; `asideWidth` is a fixed three-tier union. | `src/components/layout/split-pane.tsx:3-31` |
493
-
494
- ### P2
495
-
496
- `Descriptions.size` · `Descriptions` `children` block · `Table` `<caption>` · `Card.hoverable`
497
- (check `ServiceLauncherCard` first) · `Avatar.onError` · `Timeline` `tone`/`color`, `placement`
498
- (`start`/`end`/`alternate`), `reverse`, trailing `pending`, stable item `id` · `Accordion` `items`,
499
- `size`, `expandIconPlacement` (token), `showArrow` · `Carousel` `autoplay` (**with** a pause control,
500
- WCAG 2.2.2), `effect="fade"`, `adaptiveHeight`, first-class `onValueChange(index)` · `EmptyState`
501
- `media?: ReactNode` · `ErrorSurface` non-HTTP outcome statuses (or a documented `EmptyState`
502
- cross-link) + `children` · `Skeleton` `active`, per-row widths, `avatar`/`title` presets, `size` ·
503
- `Alert` `afterClose`, an `ErrorBoundary` recipe · `Toaster` `role` (assertive for destructive) ·
504
- `Tooltip`/`Popover` `arrow`, `mouseLeaveDelay`, catalog note on the inert Radix props · `Dialog`/
505
- `Sheet` `loading` body, `Sheet` `size`, `push`, `resizable` · `Progress` `size`, catalog note on the
506
- `steps`↔`segments` name collision · `QrCode` `errorLevel`, `icon`+`iconSize`, `bordered` token ·
507
- `StatCard` `prefix`/`suffix`, `Statistic.Timer` equivalent · `DataTable` `filterSearch`, `showHeader`,
508
- `tableLayout`, `onHeaderRow`, `ColumnGroup`, `column.minWidth`, `pagination.position` (logical
509
- spelling), `scroll.scrollToFirstRowOnChange`, `sticky.offsetScroll`, `ref.scrollTo`,
510
- `rowSelection.columnWidth`, `expandable.showExpandColumn` · new components `Image` preview,
511
- `Watermark`, `Tour` (see §4).
512
-
513
- ### Catalog-only follow-ups (no code)
514
-
515
- `related` cross-links are one-sided or absent for: `Descriptions` ↔ `Card`/`CardHeader`; `Card.Meta`
516
- ↔ `ListRow`; `Card.Grid` ↔ `ResponsiveGrid`; `Spin` → `Activity`/`Skeleton`/`DataState`;
517
- `Popconfirm` → `AlertDialog`/`Popover`; `Rate` → `Rating`; `StatCard` ↔ `SkeletonStat`; `Progress`
518
- `segments` vs antd `steps`; `Timeline` per-item `pending` vs antd's trailing `pending`. Per §0's
519
- `COVERED-ELSEWHERE` rule these must be added **on both sides** (the one-sided-claim mistake fixed in
520
- `8365bf05`). Also record the `WONT-PORT` reasons in the entries themselves: `Sheet.side` physical
521
- spelling, `QrCode` SVG-only, `Card` deliberate absence of `size`, the inert Radix overlay props.
522
-
523
- ---
524
-
525
- ## 4. GATE-0 ledgers for anything proposed as **new**
526
-
527
- Per `docs/COMPOSITION-VS-COMPONENT.md` §2, all seven must PASS. **Every P0/P1 gap above closes by
528
- extending an existing component — none of them proposes a new one.** Four candidates were tested
529
- anyway; three fail.
530
-
531
- ### 4.1 `Avatar.Group` — **sub-component of `Avatar`, not a new top-level component**
532
-
533
- | C1 | C2 | C3 | C4 | C5 | C6 | C7 | Verdict |
534
- | --- | --- | --- | --- | --- | --- | --- | --- |
535
- | ✅ universal (assignees, attendees, reviewers) | ➖ owns overflow arithmetic + the `+N` accessible name + an optional `Popover` of the remainder; no keyboard model of its own | ❌ **you can build the stack today** from `Avatar` + `Flex` + negative-inset tokens | ✅ `max`, `size`, `shape` | ✅ `--avatar-*` | ➖ | ✅ | **Extend `Avatar`** — ship as `Avatar.Group`, exactly as antd does. C3 fails for a *new component*, which is the correct answer: the value is the shared `size`/`shape` context and the overflow naming, both of which belong to `Avatar`. |
536
-
537
- Blocked on the P1 `Avatar.size` gap (#9) — the group's `size` prop has nothing to propagate until
538
- `Avatar` has one. Do #9 first.
539
-
540
- ### 4.2 `Image` / preview lightbox — **defer; passes on merit, fails on demand**
541
-
542
- | C1 | C2 | C3 | C4 | C5 | C6 | C7 | Verdict |
543
- | --- | --- | --- | --- | --- | --- | --- | --- |
544
- | ➖ | ✅ focus trap, Escape, arrow-key paging, zoom/rotate state, `prefers-reduced-motion` | ✅ not expressible from primitives | ✅ `open`/`onOpenChange`, `value`/`onValueChange` for the group index | ✅ | ✅ (a hand-rolled lightbox is *always* an a11y failure) | ❌ no consumer in this repo asks for it today | **Not now.** Re-run GATE-0 when a real screen needs it. Record in the catalog that a hand-rolled `<div>` lightbox is forbidden, so the gap surfaces as an issue rather than as consumer code. |
545
-
546
- ### 4.3 `Watermark` — **fails**
547
-
548
- | C1 | C2 | C3 | C4 | C5 | C6 | C7 | Verdict |
549
- | --- | --- | --- | --- | --- | --- | --- | --- |
550
- | ❌ one compliance scenario, not many domains | ➖ canvas tiling + anti-tamper `MutationObserver` | ✅ | ➖ | ➖ (`font.color` is inherently a raw value) | ❌ no interaction, no ARIA — a decorative overlay | ❌ | **Composition.** A tiled `background-image` from a token, applied by the consumer. Do not add. |
551
-
552
- ### 4.4 `Tour` — **fails today**
553
-
554
- | C1 | C2 | C3 | C4 | C5 | C6 | C7 | Verdict |
555
- | --- | --- | --- | --- | --- | --- | --- | --- |
556
- | ➖ onboarding is common but the *content* is entirely product-specific | ✅ spotlight mask, focus management, step state, `scrollIntoView` | ✅ | ✅ `open`, `current`/`onValueChange`, `steps` | ✅ | ✅ | ❌ nothing consumes it | **Not now.** Same disposition as §4.2 — a real onboarding requirement re-opens the gate. |
557
-
558
- ### 4.5 Explicitly rejected as new components
559
-
560
- - **`Popconfirm`** — `AlertDialog` (consequential) and `Popover` + `Button`s (light) already cover
561
- it. Adding it would be the third dialect §0.1 warns about. **Instant reject.**
562
- - **`CircularProgress` / `Gauge`** — extend `Progress` with a `variant`; the ARIA, tone and
563
- over-capacity machinery already exist (`progress.tsx:160-190`).
564
- - **`Statistic` / `Countdown`** — extend `StatCard`.
565
- - **`Notification`** — the gap is a *wrapper* around sonner, not a second toast component.
566
- - **`Empty`**, **`Result`**, **`Spin`**, **`Rate`** — `EmptyState`, `ErrorSurface`,
567
- `Activity`/`Skeleton`/`DataState`, `Rating`. **Instant reject.**