@godxjp/ui 31.31.8 → 32.0.1

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 (732) 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/color.d.ts +7 -0
  262. package/dist/email/color.js +14 -1
  263. package/dist/email/index.d.ts +10 -2
  264. package/dist/email/index.js +23 -2
  265. package/dist/email/tokens.generated.d.ts +120 -2
  266. package/dist/email/tokens.generated.js +119 -1
  267. package/dist/i18n/locale-tags.d.ts +25 -0
  268. package/dist/i18n/locale-tags.js +59 -0
  269. package/dist/i18n/translate.d.ts +20 -3
  270. package/dist/i18n/translate.js +25 -14
  271. package/dist/i18n/use-translation.d.ts +3 -3
  272. package/dist/i18n/use-translation.js +4 -2
  273. package/dist/{components/navigation → lab}/anchor.d.ts +2 -2
  274. package/dist/{components/navigation → lab}/anchor.js +5 -5
  275. package/dist/{components/data-display → lab}/carousel.js +2 -2
  276. package/dist/{components/layout → lab}/draggable-panel.d.ts +8 -8
  277. package/dist/{components/layout → lab}/draggable-panel.js +2 -2
  278. package/dist/{components/data-entry → lab}/emoji-picker.d.ts +2 -2
  279. package/dist/{components/data-entry → lab}/emoji-picker.js +6 -6
  280. package/dist/{components/general → lab}/float-button.d.ts +8 -8
  281. package/dist/{components/general → lab}/float-button.js +7 -7
  282. package/dist/lab/index.d.ts +39 -0
  283. package/dist/lab/index.js +48 -0
  284. package/dist/{components/layout → lab}/legal-document-shell.d.ts +2 -2
  285. package/dist/{components/layout → lab}/legal-document-shell.js +4 -4
  286. package/dist/{components/data-display → lab}/marquee.d.ts +5 -5
  287. package/dist/{components/data-display → lab}/marquee.js +5 -5
  288. package/dist/{components/layout → lab}/masonry.d.ts +2 -2
  289. package/dist/{components/layout → lab}/masonry.js +3 -3
  290. package/dist/{components/navigation → lab}/mega-menu.d.ts +4 -4
  291. package/dist/{components/navigation → lab}/mega-menu.js +2 -2
  292. package/dist/{components/data-display → lab}/org-chart.d.ts +2 -2
  293. package/dist/{components/data-display → lab}/org-chart.js +4 -4
  294. package/dist/{components/layout → lab}/page-cover.d.ts +2 -2
  295. package/dist/{components/layout → lab}/page-cover.js +2 -2
  296. package/dist/{components/data-display → lab}/range-timeline.d.ts +1 -1
  297. package/dist/{components/data-display → lab}/range-timeline.js +6 -6
  298. package/dist/{components/data-entry → lab}/sortable-list.d.ts +2 -2
  299. package/dist/{components/data-entry → lab}/sortable-list.js +3 -3
  300. package/dist/{components/data-display → lab}/text-diff.d.ts +3 -3
  301. package/dist/{components/data-display → lab}/text-diff.js +4 -4
  302. package/dist/{components/data-display → lab}/timeline-grid.d.ts +2 -2
  303. package/dist/{components/data-display → lab}/timeline-grid.js +1 -1
  304. package/dist/lib/control-styles.js +1 -1
  305. package/dist/lib/datetime/format.js +20 -6
  306. package/dist/lib/datetime/sync.d.ts +6 -2
  307. package/dist/lib/datetime/sync.js +14 -18
  308. package/dist/lib/platform.d.ts +1 -1
  309. package/dist/props/components/app.prop.d.ts +28 -13
  310. package/dist/props/components/data-display.prop.d.ts +19 -29
  311. package/dist/props/components/feedback.prop.d.ts +15 -44
  312. package/dist/props/components/general.prop.d.ts +2 -64
  313. package/dist/props/components/index.d.ts +9 -1
  314. package/dist/props/components/layout.prop.d.ts +41 -57
  315. package/dist/props/registry.d.ts +48 -101
  316. package/dist/props/registry.js +45 -129
  317. package/dist/props/vocabulary/index.d.ts +1 -1
  318. package/dist/props/vocabulary/interaction.prop.d.ts +3 -12
  319. package/dist/styles/alert-layout.css +0 -29
  320. package/dist/styles/data-display-layout.css +14 -22
  321. package/dist/styles/fonts/OFL.txt +93 -0
  322. package/dist/styles/form-layout.css +4 -0
  323. package/dist/styles/index.css +0 -2
  324. package/dist/styles/layers.json +44 -179
  325. package/dist/styles/text-layout.css +0 -15
  326. package/dist/styles.css +2 -0
  327. package/dist/themes/godx-tokens.css +41 -0
  328. package/dist/themes/godx.css +3 -0
  329. package/dist/themes/godx.d.ts +16 -0
  330. package/dist/themes/godx.js +12 -0
  331. package/dist/tokens/components/feedback.css +0 -6
  332. package/dist/tokens/derived.css +23 -22
  333. package/dist/tokens/foundation.css +4 -6
  334. package/docs/COMPOSITION-VS-COMPONENT.md +58 -33
  335. package/docs/CONSUMER-RULES.md +1 -1
  336. package/docs/CUSTOMER-THEMING.md +17 -53
  337. package/docs/migrations/v32.md +105 -0
  338. package/package.json +59 -19
  339. package/scripts/_agent-setup.mjs +54 -3
  340. package/scripts/brand-accent.generated.mjs +15 -2
  341. package/scripts/cli.mjs +36 -11
  342. package/scripts/codemod.mjs +542 -0
  343. package/scripts/consumer-rule.md +21 -43
  344. package/scripts/postinstall.mjs +10 -47
  345. package/scripts/prune-css.mjs +1 -1
  346. package/scripts/ui-audit.mjs +5 -2
  347. package/dist/components/data-display/chat-bubble.d.ts +0 -30
  348. package/dist/components/data-display/chat-bubble.js +0 -229
  349. package/dist/components/data-display/hover-card.d.ts +0 -1
  350. package/dist/components/data-display/hover-card.js +0 -7
  351. package/dist/components/data-display/thought-chain.d.ts +0 -42
  352. package/dist/components/data-display/thought-chain.js +0 -177
  353. package/dist/components/data-display/thumbnail.d.ts +0 -37
  354. package/dist/components/data-display/thumbnail.js +0 -20
  355. package/dist/components/data-display/welcome.d.ts +0 -26
  356. package/dist/components/data-display/welcome.js +0 -37
  357. package/dist/components/data-entry/attachments.d.ts +0 -19
  358. package/dist/components/data-entry/attachments.js +0 -366
  359. package/dist/components/data-entry/chat-composer.d.ts +0 -51
  360. package/dist/components/data-entry/chat-composer.js +0 -200
  361. package/dist/components/data-entry/chat-suggestion.d.ts +0 -28
  362. package/dist/components/data-entry/chat-suggestion.js +0 -309
  363. package/dist/components/data-entry/tag-input.d.ts +0 -2
  364. package/dist/components/data-entry/tag-input.js +0 -5
  365. package/dist/components/feedback/banner.d.ts +0 -21
  366. package/dist/components/feedback/banner.js +0 -19
  367. package/dist/components/feedback/callout.d.ts +0 -23
  368. package/dist/components/feedback/callout.js +0 -42
  369. package/dist/components/layout/auth-shell.d.ts +0 -10
  370. package/dist/components/layout/auth-shell.js +0 -42
  371. package/dist/components/layout/space-compact.d.ts +0 -65
  372. package/dist/components/layout/space-compact.js +0 -52
  373. package/dist/components/navigation/conversations.d.ts +0 -39
  374. package/dist/components/navigation/conversations.js +0 -371
  375. package/dist/components/ui/accordion.d.ts +0 -51
  376. package/dist/components/ui/accordion.js +0 -254
  377. package/dist/components/ui/aspect-ratio.d.ts +0 -24
  378. package/dist/components/ui/aspect-ratio.js +0 -21
  379. package/dist/components/ui/avatar.d.ts +0 -16
  380. package/dist/components/ui/avatar.js +0 -115
  381. package/dist/components/ui/credential-reveal.d.ts +0 -9
  382. package/dist/components/ui/credential-reveal.js +0 -160
  383. package/dist/components/ui/hover-card.d.ts +0 -47
  384. package/dist/components/ui/hover-card.js +0 -205
  385. package/dist/components/ui/input-otp.d.ts +0 -48
  386. package/dist/components/ui/input-otp.js +0 -101
  387. package/dist/components/ui/password-input.d.ts +0 -38
  388. package/dist/components/ui/password-input.js +0 -60
  389. package/dist/components/ui/rating.d.ts +0 -38
  390. package/dist/components/ui/rating.js +0 -131
  391. package/dist/components/ui/segmented.d.ts +0 -94
  392. package/dist/components/ui/segmented.js +0 -108
  393. package/dist/components/ui/separator.d.ts +0 -25
  394. package/dist/components/ui/separator.js +0 -74
  395. package/dist/components/ui/toggle-group.d.ts +0 -108
  396. package/dist/components/ui/toggle-group.js +0 -194
  397. package/dist/components/ui/toggle.d.ts +0 -86
  398. package/dist/components/ui/toggle.js +0 -156
  399. package/docs/CANONICAL-CONTRACTS.md +0 -206
  400. package/docs/COMPONENTS.md +0 -163
  401. package/docs/DATETIME.md +0 -78
  402. package/docs/DEVELOPMENT.md +0 -269
  403. package/docs/FRAME-A11Y-CI.md +0 -287
  404. package/docs/FRAME-COVERAGE-LEDGER.md +0 -123
  405. package/docs/FRAME-COVERAGE-REPORT.md +0 -228
  406. package/docs/FRAME-COVERAGE-STANDARD.md +0 -65
  407. package/docs/FRAME-COVERAGE.md +0 -29
  408. package/docs/MEASUREMENT-CONTRACT.md +0 -109
  409. package/docs/PROPS-REGISTRY.md +0 -61
  410. package/docs/PROPS-VOCABULARY.md +0 -100
  411. package/docs/REGISTRY.md +0 -70
  412. package/docs/TESTING.md +0 -107
  413. package/docs/THEME-API-COVERAGE.md +0 -538
  414. package/docs/WHAT-BELONGS-HERE.md +0 -179
  415. package/docs/asset-modules.d.ts +0 -53
  416. package/docs/assets/cover-terrain.svg +0 -6
  417. package/docs/assets/portrait-amber.svg +0 -5
  418. package/docs/assets/portrait-clay.svg +0 -5
  419. package/docs/assets/portrait-indigo.svg +0 -5
  420. package/docs/assets/portrait-iris.svg +0 -5
  421. package/docs/assets/portrait-moss.svg +0 -5
  422. package/docs/assets/portrait-plum.svg +0 -5
  423. package/docs/assets/portrait-slate.svg +0 -5
  424. package/docs/assets/service-mark-rose.svg +0 -6
  425. package/docs/assets/service-mark-teal.svg +0 -5
  426. package/docs/assets/shot-landscape.svg +0 -12
  427. package/docs/assets/shot-portrait.svg +0 -10
  428. package/docs/assets/tcgm/card-1.svg +0 -1
  429. package/docs/assets/tcgm/card-2.svg +0 -1
  430. package/docs/assets/tcgm/card-3.svg +0 -1
  431. package/docs/assets/tcgm/card-4.svg +0 -1
  432. package/docs/assets/tcgm/card-5.svg +0 -1
  433. package/docs/assets/tcgm/card-6.svg +0 -1
  434. package/docs/assets/tcgm/hero-prism.svg +0 -1
  435. package/docs/assets/tcgm/scene-1.svg +0 -1
  436. package/docs/assets/tcgm/scene-2.svg +0 -1
  437. package/docs/assets/tcgm/scene-3.svg +0 -1
  438. package/docs/assets/tcgm/scene-4.svg +0 -1
  439. package/docs/assets/tcgm/scene-5.svg +0 -1
  440. package/docs/assets/tcgm/tcgm-lockup-color.svg +0 -1
  441. package/docs/assets/tcgm/tcgm-symbol-color.svg +0 -1
  442. package/docs/charts/cjk-category-axis.tsx +0 -81
  443. package/docs/charts/compact-bar-trend.tsx +0 -327
  444. package/docs/charts/size-tiers.tsx +0 -192
  445. package/docs/data-display/accordion.tsx +0 -99
  446. package/docs/data-display/avatar.tsx +0 -502
  447. package/docs/data-display/badge.tsx +0 -335
  448. package/docs/data-display/card/examples/detail-panel.tsx +0 -106
  449. package/docs/data-display/card/examples/tab-list.tsx +0 -97
  450. package/docs/data-display/card/index.md +0 -3
  451. package/docs/data-display/card/index.tsx +0 -390
  452. package/docs/data-display/carousel.tsx +0 -160
  453. package/docs/data-display/charts.tsx +0 -278
  454. package/docs/data-display/chat-bubble.tsx +0 -397
  455. package/docs/data-display/code-block.tsx +0 -188
  456. package/docs/data-display/collapsible.tsx +0 -162
  457. package/docs/data-display/credential-reveal.tsx +0 -148
  458. package/docs/data-display/data-table/examples/antd-parity.tsx +0 -257
  459. package/docs/data-display/data-table/examples/approval-queue.tsx +0 -212
  460. package/docs/data-display/data-table/examples/grid-features.tsx +0 -158
  461. package/docs/data-display/data-table/examples/list-page.tsx +0 -175
  462. package/docs/data-display/data-table/examples/selectable-inbox.tsx +0 -113
  463. package/docs/data-display/data-table/examples/server-paged.tsx +0 -179
  464. package/docs/data-display/data-table/examples/striped-list.tsx +0 -173
  465. package/docs/data-display/data-table/index.md +0 -9
  466. package/docs/data-display/data-table/index.tsx +0 -407
  467. package/docs/data-display/descriptions.tsx +0 -263
  468. package/docs/data-display/empty-state.tsx +0 -164
  469. package/docs/data-display/feature-list.tsx +0 -159
  470. package/docs/data-display/hover-card.tsx +0 -181
  471. package/docs/data-display/image.tsx +0 -170
  472. package/docs/data-display/legend.tsx +0 -158
  473. package/docs/data-display/list-row.tsx +0 -441
  474. package/docs/data-display/markdown.tsx +0 -86
  475. package/docs/data-display/marquee.tsx +0 -254
  476. package/docs/data-display/org-chart.tsx +0 -165
  477. package/docs/data-display/permission-matrix.tsx +0 -188
  478. package/docs/data-display/popover-touch.tsx +0 -27
  479. package/docs/data-display/popover.tsx +0 -331
  480. package/docs/data-display/progress.tsx +0 -162
  481. package/docs/data-display/prose.tsx +0 -169
  482. package/docs/data-display/qr-code.tsx +0 -68
  483. package/docs/data-display/scroll-area.tsx +0 -420
  484. package/docs/data-display/service-launcher-card.tsx +0 -445
  485. package/docs/data-display/stat-card.tsx +0 -354
  486. package/docs/data-display/swatch.tsx +0 -107
  487. package/docs/data-display/table.tsx +0 -362
  488. package/docs/data-display/text-diff.tsx +0 -89
  489. package/docs/data-display/thought-chain.tsx +0 -176
  490. package/docs/data-display/thumbnail.tsx +0 -128
  491. package/docs/data-display/timeline-grid.tsx +0 -119
  492. package/docs/data-display/timeline.tsx +0 -671
  493. package/docs/data-display/touch-actions.tsx +0 -36
  494. package/docs/data-display/tree.tsx +0 -724
  495. package/docs/data-display/welcome.tsx +0 -115
  496. package/docs/data-entry/attachments.tsx +0 -160
  497. package/docs/data-entry/block-editor.tsx +0 -105
  498. package/docs/data-entry/branch-scope-picker.tsx +0 -128
  499. package/docs/data-entry/calendar.tsx +0 -226
  500. package/docs/data-entry/cascader.tsx +0 -380
  501. package/docs/data-entry/chat-composer.tsx +0 -619
  502. package/docs/data-entry/chat-suggestion.tsx +0 -301
  503. package/docs/data-entry/checkbox.tsx +0 -256
  504. package/docs/data-entry/color-picker.tsx +0 -189
  505. package/docs/data-entry/command-palette.tsx +0 -179
  506. package/docs/data-entry/command.tsx +0 -341
  507. package/docs/data-entry/country-picker-recipe.tsx +0 -175
  508. package/docs/data-entry/date-picker.tsx +0 -452
  509. package/docs/data-entry/emoji-picker.tsx +0 -35
  510. package/docs/data-entry/form/examples/employee-settings.tsx +0 -267
  511. package/docs/data-entry/form/examples/invoice-form.tsx +0 -387
  512. package/docs/data-entry/form-dynamic-fields.tsx +0 -199
  513. package/docs/data-entry/form-field/examples/a11y-contract.tsx +0 -242
  514. package/docs/data-entry/form-field/examples/create-form.tsx +0 -107
  515. package/docs/data-entry/form-field/index.md +0 -8
  516. package/docs/data-entry/form-field/index.tsx +0 -337
  517. package/docs/data-entry/form-inertia.tsx +0 -80
  518. package/docs/data-entry/form-root.tsx +0 -112
  519. package/docs/data-entry/form.tsx +0 -1498
  520. package/docs/data-entry/input-otp.tsx +0 -258
  521. package/docs/data-entry/input.tsx +0 -796
  522. package/docs/data-entry/label.tsx +0 -102
  523. package/docs/data-entry/markdown-editor.tsx +0 -69
  524. package/docs/data-entry/number-input.tsx +0 -279
  525. package/docs/data-entry/password-input.tsx +0 -102
  526. package/docs/data-entry/password-strength.tsx +0 -99
  527. package/docs/data-entry/radio-group.tsx +0 -316
  528. package/docs/data-entry/rating.tsx +0 -91
  529. package/docs/data-entry/record-picker.tsx +0 -209
  530. package/docs/data-entry/search-input.tsx +0 -121
  531. package/docs/data-entry/segmented-in-filter-row.tsx +0 -60
  532. package/docs/data-entry/segmented.tsx +0 -300
  533. package/docs/data-entry/select-async-contracts.tsx +0 -108
  534. package/docs/data-entry/select-matrix.tsx +0 -209
  535. package/docs/data-entry/select.tsx +0 -547
  536. package/docs/data-entry/slider.tsx +0 -212
  537. package/docs/data-entry/sortable-list.tsx +0 -76
  538. package/docs/data-entry/switch.tsx +0 -314
  539. package/docs/data-entry/tag-input.tsx +0 -145
  540. package/docs/data-entry/textarea.tsx +0 -249
  541. package/docs/data-entry/time-picker.tsx +0 -187
  542. package/docs/data-entry/time-range-picker.tsx +0 -55
  543. package/docs/data-entry/toggle-count.tsx +0 -348
  544. package/docs/data-entry/toggle-group.tsx +0 -438
  545. package/docs/data-entry/toggle.tsx +0 -217
  546. package/docs/data-entry/transfer.tsx +0 -115
  547. package/docs/data-entry/tree-select.tsx +0 -204
  548. package/docs/data-entry/upload-crop-dialog.tsx +0 -109
  549. package/docs/data-entry/upload.tsx +0 -310
  550. package/docs/feedback/alert-dialog.tsx +0 -270
  551. package/docs/feedback/alert.tsx +0 -248
  552. package/docs/feedback/auth-expiry.tsx +0 -104
  553. package/docs/feedback/banner.tsx +0 -183
  554. package/docs/feedback/callout.tsx +0 -220
  555. package/docs/feedback/danger-confirm.tsx +0 -91
  556. package/docs/feedback/dialog-touch.tsx +0 -24
  557. package/docs/feedback/dialog.tsx +0 -373
  558. package/docs/feedback/sheet.tsx +0 -510
  559. package/docs/feedback/skeleton.tsx +0 -168
  560. package/docs/feedback/toast.tsx +0 -135
  561. package/docs/feedback/tooltip.tsx +0 -171
  562. package/docs/feedback/two-factor-setup.tsx +0 -68
  563. package/docs/foundation/_email-specimen.ts +0 -274
  564. package/docs/foundation/_theme-editor-scope.ts +0 -222
  565. package/docs/foundation/colors.tsx +0 -207
  566. package/docs/foundation/density.tsx +0 -242
  567. package/docs/foundation/email-tokens.tsx +0 -323
  568. package/docs/foundation/radius-shadow.tsx +0 -154
  569. package/docs/foundation/spacing.tsx +0 -216
  570. package/docs/foundation/theme-editor.tsx +0 -654
  571. package/docs/foundation/typography.tsx +0 -147
  572. package/docs/general/actions.tsx +0 -175
  573. package/docs/general/activity.tsx +0 -289
  574. package/docs/general/button/examples/destructive-confirm.tsx +0 -90
  575. package/docs/general/button/examples/form-actions.tsx +0 -87
  576. package/docs/general/button/examples/toolbar.tsx +0 -160
  577. package/docs/general/button/index.md +0 -16
  578. package/docs/general/button/index.tsx +0 -236
  579. package/docs/general/float-button.tsx +0 -133
  580. package/docs/general/icon.tsx +0 -217
  581. package/docs/general/logo.tsx +0 -194
  582. package/docs/general/reveal.tsx +0 -309
  583. package/docs/general/typography.tsx +0 -542
  584. package/docs/i18n/messages/en.json +0 -1715
  585. package/docs/i18n/messages/ja.json +0 -1708
  586. package/docs/i18n/messages/vi.json +0 -1708
  587. package/docs/layout/account-chip.tsx +0 -72
  588. package/docs/layout/admin-collection.tsx +0 -122
  589. package/docs/layout/affix.tsx +0 -209
  590. package/docs/layout/app-launcher.tsx +0 -211
  591. package/docs/layout/app-shell-arrangements.tsx +0 -225
  592. package/docs/layout/app-shell-narrow-bar.tsx +0 -205
  593. package/docs/layout/app-shell-states.tsx +0 -171
  594. package/docs/layout/app-shell.tsx +0 -395
  595. package/docs/layout/aspect-ratio.tsx +0 -135
  596. package/docs/layout/auth-account-summary.tsx +0 -103
  597. package/docs/layout/auth-divider.tsx +0 -28
  598. package/docs/layout/auth-footer.tsx +0 -37
  599. package/docs/layout/auth-identity.tsx +0 -70
  600. package/docs/layout/auth-recovery/examples/mfa-challenge.md +0 -41
  601. package/docs/layout/auth-recovery/examples/mfa-challenge.tsx +0 -254
  602. package/docs/layout/auth-recovery/examples/mobile-390.md +0 -25
  603. package/docs/layout/auth-recovery/examples/mobile-390.tsx +0 -82
  604. package/docs/layout/auth-recovery/examples/password-recovery.md +0 -24
  605. package/docs/layout/auth-recovery/examples/password-recovery.tsx +0 -197
  606. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.md +0 -27
  607. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.tsx +0 -156
  608. package/docs/layout/auth-recovery/index.md +0 -140
  609. package/docs/layout/auth-recovery/index.tsx +0 -96
  610. package/docs/layout/auth-shell-context.tsx +0 -103
  611. package/docs/layout/auth-shell-device.tsx +0 -112
  612. package/docs/layout/auth-shell-registration.tsx +0 -338
  613. package/docs/layout/auth-shell-variants.tsx +0 -143
  614. package/docs/layout/auth-shell.tsx +0 -59
  615. package/docs/layout/auth-stack.tsx +0 -40
  616. package/docs/layout/centered-shell.tsx +0 -102
  617. package/docs/layout/draggable-panel.tsx +0 -127
  618. package/docs/layout/error-surface/examples/application-403.tsx +0 -84
  619. package/docs/layout/error-surface/examples/application-404.tsx +0 -77
  620. package/docs/layout/error-surface/examples/system-500.tsx +0 -47
  621. package/docs/layout/error-surface/examples/system-503.tsx +0 -48
  622. package/docs/layout/error-surface/index.md +0 -153
  623. package/docs/layout/error-surface/index.tsx +0 -239
  624. package/docs/layout/flex.tsx +0 -444
  625. package/docs/layout/legal-document-shell/_data.ts +0 -110
  626. package/docs/layout/legal-document-shell/examples/desktop-1440.md +0 -12
  627. package/docs/layout/legal-document-shell/examples/desktop-1440.tsx +0 -83
  628. package/docs/layout/legal-document-shell/examples/mobile-390.md +0 -22
  629. package/docs/layout/legal-document-shell/examples/mobile-390.tsx +0 -70
  630. package/docs/layout/legal-document-shell/examples/tablet-1024.md +0 -3
  631. package/docs/layout/legal-document-shell/examples/tablet-1024.tsx +0 -84
  632. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.md +0 -18
  633. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.tsx +0 -61
  634. package/docs/layout/legal-document-shell/index.md +0 -51
  635. package/docs/layout/legal-document-shell/index.tsx +0 -101
  636. package/docs/layout/masonry.tsx +0 -291
  637. package/docs/layout/master-detail.tsx +0 -390
  638. package/docs/layout/mobile-shell.tsx +0 -106
  639. package/docs/layout/nav-list.tsx +0 -584
  640. package/docs/layout/org-switcher.tsx +0 -131
  641. package/docs/layout/page-container.tsx +0 -1020
  642. package/docs/layout/page-cover.tsx +0 -56
  643. package/docs/layout/resizable-panel.tsx +0 -419
  644. package/docs/layout/responsive-grid.tsx +0 -403
  645. package/docs/layout/separator.tsx +0 -327
  646. package/docs/layout/service-role-panel.tsx +0 -144
  647. package/docs/layout/sidebar.tsx +0 -689
  648. package/docs/layout/space-compact.tsx +0 -202
  649. package/docs/layout/split-pane.tsx +0 -532
  650. package/docs/layout/topbar-item.tsx +0 -233
  651. package/docs/layout/topbar.tsx +0 -360
  652. package/docs/navigation/anchor.tsx +0 -295
  653. package/docs/navigation/app-setting-picker.tsx +0 -178
  654. package/docs/navigation/app-setting-toggle.tsx +0 -111
  655. package/docs/navigation/breadcrumb.tsx +0 -207
  656. package/docs/navigation/card-tabs.tsx +0 -344
  657. package/docs/navigation/conversations.tsx +0 -176
  658. package/docs/navigation/dropdown-menu.tsx +0 -345
  659. package/docs/navigation/filter-bar.tsx +0 -247
  660. package/docs/navigation/mega-menu-panel.tsx +0 -86
  661. package/docs/navigation/mega-menu.tsx +0 -254
  662. package/docs/navigation/pagination.tsx +0 -293
  663. package/docs/navigation/steps.tsx +0 -315
  664. package/docs/navigation/tabs-rtl.tsx +0 -28
  665. package/docs/navigation/tabs.tsx +0 -755
  666. package/docs/navigation/toolbar.tsx +0 -347
  667. package/docs/providers/app-provider.tsx +0 -191
  668. package/docs/providers/format-date.tsx +0 -230
  669. package/docs/providers/theme-scope.tsx +0 -186
  670. package/docs/query/button-refetch.tsx +0 -161
  671. package/docs/query/data-state.tsx +0 -262
  672. package/docs/query/infinite-query-state.tsx +0 -97
  673. package/docs/query/mutation-feedback.tsx +0 -128
  674. package/docs/query/touch-actions.tsx +0 -68
  675. package/docs/react-router/prefetch-link.tsx +0 -262
  676. package/docs/roadmap/ai-chat-components.md +0 -206
  677. package/docs/roadmap/antd-parity.md +0 -155
  678. package/docs/roadmap/badge-tag-chip-count.md +0 -172
  679. package/docs/roadmap/list-masonry.md +0 -159
  680. package/docs/roadmap/parity-audit-data-display-feedback.md +0 -567
  681. package/docs/roadmap/parity-audit-data-entry.md +0 -368
  682. package/docs/roadmap/parity-audit-layout-navigation-general.md +0 -459
  683. package/docs/roadmap/parity-backlog.md +0 -77
  684. package/docs/roadmap/tree-components.md +0 -151
  685. package/docs/roadmap/website-components.md +0 -813
  686. package/docs/showcase/acme-portal.tsx +0 -461
  687. package/docs/showcase/acme-website.tsx +0 -499
  688. package/docs/showcase/caimono-price-comparison.tsx +0 -919
  689. package/docs/showcase/case1-warehouse-dashboard.tsx +0 -358
  690. package/docs/showcase/case2-employee-me.tsx +0 -438
  691. package/docs/showcase/case3-approval-workflow.tsx +0 -531
  692. package/docs/showcase/case4-login.tsx +0 -312
  693. package/docs/showcase/case5-shift-calendar.tsx +0 -702
  694. package/docs/showcase/case6-agency-handy.tsx +0 -1120
  695. package/docs/showcase/futurelastic-web.tsx +0 -441
  696. package/docs/showcase/marketing-page.tsx +0 -895
  697. package/docs/showcase/org-switcher.tsx +0 -320
  698. package/docs/showcase/permission-matrix.tsx +0 -354
  699. package/docs/showcase/public-landing.tsx +0 -210
  700. package/docs/showcase/settings-account-sections.tsx +0 -559
  701. package/docs/showcase/settings-security-mfa.tsx +0 -145
  702. package/docs/showcase/table-approval-queue.tsx +0 -199
  703. package/docs/showcase/table-bulk-actions.tsx +0 -468
  704. package/docs/showcase/table-compact-kintone.tsx +0 -438
  705. package/docs/showcase/table-conditional-format.tsx +0 -367
  706. package/docs/showcase/table-crud-list.tsx +0 -544
  707. package/docs/showcase/table-density.tsx +0 -349
  708. package/docs/showcase/table-expandable-rows.tsx +0 -496
  709. package/docs/showcase/table-filter-chips.tsx +0 -468
  710. package/docs/showcase/table-footer-totals.tsx +0 -328
  711. package/docs/showcase/table-grouped-subtotals.tsx +0 -398
  712. package/docs/showcase/table-master-detail.tsx +0 -482
  713. package/docs/showcase/table-pagination.tsx +0 -409
  714. package/docs/showcase/table-states.tsx +0 -371
  715. package/docs/showcase/table-sticky-columns.tsx +0 -377
  716. package/docs/showcase/table-tree-rows.tsx +0 -451
  717. package/docs/showcase/table-view-tabs.tsx +0 -488
  718. package/docs/showcase/tcgm-website.tsx +0 -1047
  719. package/docs/showcase/tenant-brand-color.tsx +0 -338
  720. package/docs/showcase/theme-customization.tsx +0 -1292
  721. package/docs/showcase/theme-lab.tsx +0 -2125
  722. package/docs/themes/flat.css +0 -466
  723. package/docs/themes/glassmorphism.css +0 -960
  724. package/docs/themes/index.ts +0 -219
  725. package/docs/themes/neubrutalism.css +0 -481
  726. /package/dist/components/navigation/{filter-bar.d.ts → toolbar.d.ts} +0 -0
  727. /package/dist/components/navigation/{filter-bar.js → toolbar.js} +0 -0
  728. /package/dist/{components/data-display → lab}/carousel.d.ts +0 -0
  729. /package/dist/{components/data-entry → lab}/emoji-data.d.ts +0 -0
  730. /package/dist/{components/data-entry → lab}/emoji-data.js +0 -0
  731. /package/dist/{components/data-display → lab}/marquee-reveal.d.ts +0 -0
  732. /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.**