@godxjp/ui 31.31.8 → 32.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (727) hide show
  1. package/README.md +102 -121
  2. package/agent/START-HERE.md +10 -10
  3. package/agent/components/Accordion.json +2 -2
  4. package/agent/components/AccountChip.json +1 -1
  5. package/agent/components/Actions.json +1 -1
  6. package/agent/components/Activity.json +2 -2
  7. package/agent/components/Affix.json +1 -1
  8. package/agent/components/Alert.json +22 -6
  9. package/agent/components/AlertDialog.json +8 -1
  10. package/agent/components/Anchor.json +4 -3
  11. package/agent/components/AppLauncher.json +2 -2
  12. package/agent/components/AppProvider.json +19 -11
  13. package/agent/components/AppSettingPicker.json +18 -2
  14. package/agent/components/AppShell.json +4 -5
  15. package/agent/components/AreaChart.json +0 -1
  16. package/agent/components/AspectRatio.json +2 -2
  17. package/agent/components/Attachments.json +3 -3
  18. package/agent/components/AuthAccountSummary.json +1 -1
  19. package/agent/components/AuthDivider.json +1 -1
  20. package/agent/components/AuthExpiryProvider.json +0 -1
  21. package/agent/components/AuthFooter.json +2 -2
  22. package/agent/components/AuthIdentity.json +3 -3
  23. package/agent/components/AuthStack.json +1 -1
  24. package/agent/components/Avatar.json +2 -12
  25. package/agent/components/Badge.json +1 -1
  26. package/agent/components/BarChart.json +0 -1
  27. package/agent/components/BranchScopePicker.json +1 -1
  28. package/agent/components/Breadcrumb.json +1 -1
  29. package/agent/components/Button.json +3 -3
  30. package/agent/components/Calendar.json +1 -1
  31. package/agent/components/Card.json +2 -2
  32. package/agent/components/CardBar.json +0 -1
  33. package/agent/components/CardContent.json +0 -1
  34. package/agent/components/Carousel.json +4 -3
  35. package/agent/components/Cascader.json +1 -1
  36. package/agent/components/CenteredShell.json +78 -17
  37. package/agent/components/ChatBubble.json +3 -3
  38. package/agent/components/ChatBubbleList.json +3 -3
  39. package/agent/components/ChatComposer.json +3 -3
  40. package/agent/components/ChatSuggestion.json +3 -3
  41. package/agent/components/Checkbox.json +1 -1
  42. package/agent/components/CheckboxGroup.json +0 -1
  43. package/agent/components/CodeBlock.json +1 -1
  44. package/agent/components/Collapsible.json +4 -4
  45. package/agent/components/ColorPicker.json +1 -1
  46. package/agent/components/Command.json +5 -5
  47. package/agent/components/CommandPalette.json +1 -1
  48. package/agent/components/CompactBarTrend.json +1 -1
  49. package/agent/components/Conversations.json +3 -3
  50. package/agent/components/CredentialReveal.json +1 -1
  51. package/agent/components/DataState.json +2 -2
  52. package/agent/components/DataTable.json +1 -1
  53. package/agent/components/DatePicker.json +1 -1
  54. package/agent/components/Descriptions.json +1 -1
  55. package/agent/components/Dialog.json +2 -2
  56. package/agent/components/DraggablePanel.json +5 -4
  57. package/agent/components/DropdownMenu.json +1 -1
  58. package/agent/components/EmojiPicker.json +3 -2
  59. package/agent/components/EmptyState.json +1 -1
  60. package/agent/components/ErrorSurface.json +3 -3
  61. package/agent/components/FeatureList.json +1 -1
  62. package/agent/components/Field.json +0 -1
  63. package/agent/components/Flex.json +34 -4
  64. package/agent/components/FloatButton.json +6 -5
  65. package/agent/components/Form.json +1 -1
  66. package/agent/components/FormErrors.json +0 -1
  67. package/agent/components/FormField.json +6 -6
  68. package/agent/components/FormFieldArray.json +0 -1
  69. package/agent/components/FormFieldControl.json +0 -1
  70. package/agent/components/FormRoot.json +1 -1
  71. package/agent/components/Heading.json +3 -0
  72. package/agent/components/Icon.json +1 -1
  73. package/agent/components/Image.json +7 -4
  74. package/agent/components/InfiniteQueryState.json +1 -1
  75. package/agent/components/Input.json +1 -1
  76. package/agent/components/InputOTP.json +2 -2
  77. package/agent/components/Label.json +3 -3
  78. package/agent/components/LegalDocumentShell.json +5 -4
  79. package/agent/components/Legend.json +1 -1
  80. package/agent/components/LineChart.json +0 -1
  81. package/agent/components/Link.json +0 -1
  82. package/agent/components/ListRow.json +1 -1
  83. package/agent/components/Logo.json +5 -4
  84. package/agent/components/Marquee.json +4 -3
  85. package/agent/components/Masonry.json +4 -3
  86. package/agent/components/MasterDetail.json +1 -1
  87. package/agent/components/MegaMenu.json +4 -3
  88. package/agent/components/MobileShell.json +4 -4
  89. package/agent/components/NavList.json +1 -1
  90. package/agent/components/NumberInput.json +1 -1
  91. package/agent/components/OrgChart.json +4 -3
  92. package/agent/components/OrgSwitcher.json +1 -1
  93. package/agent/components/OverlayPortalProvider.json +0 -1
  94. package/agent/components/PageContainer.json +3 -3
  95. package/agent/components/PageCover.json +3 -2
  96. package/agent/components/Pagination.json +1 -1
  97. package/agent/components/PasswordInput.json +1 -1
  98. package/agent/components/PasswordStrength.json +1 -1
  99. package/agent/components/PermissionMatrix.json +1 -1
  100. package/agent/components/PieChart.json +0 -1
  101. package/agent/components/Popover.json +31 -6
  102. package/agent/components/PrefetchLink.json +1 -1
  103. package/agent/components/Progress.json +1 -1
  104. package/agent/components/Prose.json +1 -1
  105. package/agent/components/QrCode.json +1 -1
  106. package/agent/components/Radio.json +0 -1
  107. package/agent/components/RadioGroup.json +2 -2
  108. package/agent/components/RangeTimeline.json +2 -1
  109. package/agent/components/Rating.json +1 -1
  110. package/agent/components/RecordPicker.json +1 -1
  111. package/agent/components/ResizablePanel.json +1 -1
  112. package/agent/components/ResponsiveGrid.json +2 -2
  113. package/agent/components/Reveal.json +3 -3
  114. package/agent/components/ScrollArea.json +2 -2
  115. package/agent/components/SearchInput.json +1 -1
  116. package/agent/components/Segmented.json +1 -1
  117. package/agent/components/Select.json +7 -5
  118. package/agent/components/Separator.json +1 -1
  119. package/agent/components/ServiceCatalogCta.json +0 -1
  120. package/agent/components/ServiceLauncherCard.json +1 -1
  121. package/agent/components/ServiceRolePanel.json +1 -1
  122. package/agent/components/Sheet.json +5 -5
  123. package/agent/components/Sidebar.json +1 -1
  124. package/agent/components/Skeleton.json +26 -12
  125. package/agent/components/Slider.json +2 -2
  126. package/agent/components/SortableList.json +3 -2
  127. package/agent/components/SplitPane.json +1 -1
  128. package/agent/components/StatCard.json +1 -1
  129. package/agent/components/Steps.json +1 -1
  130. package/agent/components/Swatch.json +1 -1
  131. package/agent/components/Switch.json +1 -1
  132. package/agent/components/Table.json +1 -1
  133. package/agent/components/Tabs.json +3 -3
  134. package/agent/components/Text.json +5 -1
  135. package/agent/components/TextDiff.json +5 -4
  136. package/agent/components/Textarea.json +1 -1
  137. package/agent/components/ThemeScope.json +1 -1
  138. package/agent/components/ThoughtChain.json +3 -3
  139. package/agent/components/TimePicker.json +1 -1
  140. package/agent/components/Timeline.json +1 -1
  141. package/agent/components/TimelineGrid.json +5 -4
  142. package/agent/components/Toaster.json +0 -1
  143. package/agent/components/Toggle.json +3 -3
  144. package/agent/components/ToggleGroup.json +1 -1
  145. package/agent/components/Toolbar.json +10 -3
  146. package/agent/components/Tooltip.json +9 -9
  147. package/agent/components/Topbar.json +1 -1
  148. package/agent/components/TopbarItem.json +1 -1
  149. package/agent/components/Transfer.json +2 -2
  150. package/agent/components/Tree.json +1 -1
  151. package/agent/components/TreeSelect.json +1 -1
  152. package/agent/components/TwoFactorSetup.json +1 -1
  153. package/agent/components/Upload.json +1 -1
  154. package/agent/components/UploadCropDialog.json +1 -1
  155. package/agent/components/Welcome.json +3 -3
  156. package/agent/components/formatDate.json +2 -2
  157. package/agent/components/inertiaUpload.json +0 -1
  158. package/agent/components/useZodForm.json +0 -1
  159. package/agent/components-index.json +80 -154
  160. package/agent/components.json +541 -1737
  161. package/agent/index.json +10 -10
  162. package/agent/llms.txt +9 -9
  163. package/agent/patterns/account-recovery-settings.json +1 -1
  164. package/agent/patterns/auth-recovery-panels.json +2 -2
  165. package/agent/patterns/error-pages.json +1 -1
  166. package/agent/patterns/pricing-plans.json +17 -0
  167. package/agent/patterns-index.json +17 -1
  168. package/agent/patterns.json +21 -4
  169. package/agent/rules.json +30 -65
  170. package/agent/tokens.json +27 -57
  171. package/agent/vocabulary.json +3 -3
  172. package/dist/app/app-provider.d.ts +5 -3
  173. package/dist/app/app-provider.js +47 -12
  174. package/dist/app/date-format-labels.d.ts +3 -1
  175. package/dist/app/date-format-labels.js +2 -4
  176. package/dist/app/date-formats.d.ts +21 -2
  177. package/dist/app/date-formats.js +51 -2
  178. package/dist/app/index.d.ts +3 -1
  179. package/dist/app/index.js +5 -0
  180. package/dist/app/locales.d.ts +58 -3
  181. package/dist/app/locales.js +134 -8
  182. package/dist/app/preset.d.ts +25 -0
  183. package/dist/app/preset.js +10 -0
  184. package/dist/app/request-headers.d.ts +3 -3
  185. package/dist/app/request-headers.js +19 -10
  186. package/dist/app/settings-scope.d.ts +54 -0
  187. package/dist/app/settings-scope.js +46 -0
  188. package/dist/app/tenant-theme.js +8 -3
  189. package/dist/app/time-format-labels.d.ts +4 -1
  190. package/dist/app/time-format-labels.js +7 -1
  191. package/dist/app/types.d.ts +10 -2
  192. package/dist/app/use-formatting.d.ts +1 -1
  193. package/dist/components/admin/index.d.ts +1 -1
  194. package/dist/components/admin/index.js +1 -1
  195. package/dist/components/data-display/accordion.d.ts +51 -1
  196. package/dist/components/data-display/accordion.js +247 -1
  197. package/dist/components/data-display/avatar.d.ts +16 -1
  198. package/dist/components/data-display/avatar.js +109 -1
  199. package/dist/components/data-display/credential-reveal.d.ts +9 -2
  200. package/dist/components/data-display/credential-reveal.js +156 -1
  201. package/dist/components/data-display/image.js +5 -3
  202. package/dist/components/data-display/index.d.ts +0 -21
  203. package/dist/components/data-display/index.js +1 -43
  204. package/dist/components/data-display/popover.d.ts +15 -3
  205. package/dist/components/data-display/popover.js +168 -2
  206. package/dist/components/data-entry/branch-scope-picker.d.ts +1 -1
  207. package/dist/components/data-entry/index.d.ts +5 -12
  208. package/dist/components/data-entry/index.js +11 -12
  209. package/dist/components/data-entry/input-otp.d.ts +48 -2
  210. package/dist/components/data-entry/input-otp.js +94 -1
  211. package/dist/components/data-entry/number-input.d.ts +1 -1
  212. package/dist/components/data-entry/password-input.d.ts +38 -2
  213. package/dist/components/data-entry/password-input.js +56 -1
  214. package/dist/components/data-entry/rating.d.ts +38 -2
  215. package/dist/components/data-entry/rating.js +127 -1
  216. package/dist/components/data-entry/segmented.d.ts +94 -2
  217. package/dist/components/data-entry/segmented.js +104 -1
  218. package/dist/components/{ui/tag-input.d.ts → data-entry/select-tags-inline.d.ts} +7 -4
  219. package/dist/components/{ui/tag-input.js → data-entry/select-tags-inline.js} +4 -4
  220. package/dist/components/data-entry/select.js +4 -0
  221. package/dist/components/data-entry/toggle-group.d.ts +108 -2
  222. package/dist/components/data-entry/toggle-group.js +189 -1
  223. package/dist/components/data-entry/toggle.d.ts +86 -2
  224. package/dist/components/data-entry/toggle.js +153 -2
  225. package/dist/components/feedback/alert.d.ts +5 -3
  226. package/dist/components/feedback/alert.js +14 -2
  227. package/dist/components/feedback/index.d.ts +2 -6
  228. package/dist/components/feedback/index.js +1 -13
  229. package/dist/components/feedback/skeleton.d.ts +4 -17
  230. package/dist/components/feedback/skeleton.js +3 -40
  231. package/dist/components/general/index.d.ts +2 -4
  232. package/dist/components/general/index.js +1 -6
  233. package/dist/components/general/typography.d.ts +4 -58
  234. package/dist/components/general/typography.js +7 -141
  235. package/dist/components/layout/aspect-ratio.d.ts +24 -1
  236. package/dist/components/layout/aspect-ratio.js +18 -1
  237. package/dist/components/layout/auth-divider.js +1 -1
  238. package/dist/components/layout/auth-identity.js +6 -2
  239. package/dist/components/layout/centered-shell.d.ts +13 -8
  240. package/dist/components/layout/centered-shell.js +43 -1
  241. package/dist/components/layout/flex.d.ts +1 -1
  242. package/dist/components/layout/flex.js +73 -1
  243. package/dist/components/layout/index.d.ts +1 -13
  244. package/dist/components/layout/index.js +0 -12
  245. package/dist/components/layout/separator.d.ts +25 -2
  246. package/dist/components/layout/separator.js +71 -1
  247. package/dist/components/navigation/{app-setting-toggle.d.ts → app-setting-cycle.d.ts} +3 -4
  248. package/dist/components/navigation/{app-setting-toggle.js → app-setting-cycle.js} +3 -3
  249. package/dist/components/navigation/app-setting-picker.d.ts +6 -2
  250. package/dist/components/navigation/app-setting-picker.js +20 -2
  251. package/dist/components/navigation/index.d.ts +3 -11
  252. package/dist/components/navigation/index.js +1 -9
  253. package/dist/components/navigation/tabs.js +1 -1
  254. package/dist/components/ui/carousel.d.ts +1 -1
  255. package/dist/components/ui/carousel.js +1 -1
  256. package/dist/components/ui/index.d.ts +11 -5
  257. package/dist/components/ui/index.js +5 -5
  258. package/dist/contracts/measurement.json +2 -2
  259. package/dist/email/brand-mark.d.ts +3 -2
  260. package/dist/email/brand-mark.js +1 -1
  261. package/dist/email/tokens.generated.d.ts +6 -6
  262. package/dist/email/tokens.generated.js +6 -6
  263. package/dist/i18n/locale-tags.d.ts +25 -0
  264. package/dist/i18n/locale-tags.js +59 -0
  265. package/dist/i18n/translate.d.ts +20 -3
  266. package/dist/i18n/translate.js +25 -14
  267. package/dist/i18n/use-translation.d.ts +3 -3
  268. package/dist/i18n/use-translation.js +4 -2
  269. package/dist/{components/navigation → lab}/anchor.d.ts +2 -2
  270. package/dist/{components/navigation → lab}/anchor.js +5 -5
  271. package/dist/{components/data-display → lab}/carousel.js +2 -2
  272. package/dist/{components/layout → lab}/draggable-panel.d.ts +8 -8
  273. package/dist/{components/layout → lab}/draggable-panel.js +2 -2
  274. package/dist/{components/data-entry → lab}/emoji-picker.d.ts +2 -2
  275. package/dist/{components/data-entry → lab}/emoji-picker.js +6 -6
  276. package/dist/{components/general → lab}/float-button.d.ts +8 -8
  277. package/dist/{components/general → lab}/float-button.js +7 -7
  278. package/dist/lab/index.d.ts +39 -0
  279. package/dist/lab/index.js +48 -0
  280. package/dist/{components/layout → lab}/legal-document-shell.d.ts +2 -2
  281. package/dist/{components/layout → lab}/legal-document-shell.js +4 -4
  282. package/dist/{components/data-display → lab}/marquee.d.ts +5 -5
  283. package/dist/{components/data-display → lab}/marquee.js +5 -5
  284. package/dist/{components/layout → lab}/masonry.d.ts +2 -2
  285. package/dist/{components/layout → lab}/masonry.js +3 -3
  286. package/dist/{components/navigation → lab}/mega-menu.d.ts +4 -4
  287. package/dist/{components/navigation → lab}/mega-menu.js +2 -2
  288. package/dist/{components/data-display → lab}/org-chart.d.ts +2 -2
  289. package/dist/{components/data-display → lab}/org-chart.js +4 -4
  290. package/dist/{components/layout → lab}/page-cover.d.ts +2 -2
  291. package/dist/{components/layout → lab}/page-cover.js +2 -2
  292. package/dist/{components/data-display → lab}/range-timeline.d.ts +1 -1
  293. package/dist/{components/data-display → lab}/range-timeline.js +6 -6
  294. package/dist/{components/data-entry → lab}/sortable-list.d.ts +2 -2
  295. package/dist/{components/data-entry → lab}/sortable-list.js +3 -3
  296. package/dist/{components/data-display → lab}/text-diff.d.ts +3 -3
  297. package/dist/{components/data-display → lab}/text-diff.js +4 -4
  298. package/dist/{components/data-display → lab}/timeline-grid.d.ts +2 -2
  299. package/dist/{components/data-display → lab}/timeline-grid.js +1 -1
  300. package/dist/lib/control-styles.js +1 -1
  301. package/dist/lib/datetime/format.js +20 -6
  302. package/dist/lib/datetime/sync.d.ts +6 -2
  303. package/dist/lib/datetime/sync.js +14 -18
  304. package/dist/lib/platform.d.ts +1 -1
  305. package/dist/props/components/app.prop.d.ts +28 -13
  306. package/dist/props/components/data-display.prop.d.ts +19 -29
  307. package/dist/props/components/feedback.prop.d.ts +15 -44
  308. package/dist/props/components/general.prop.d.ts +2 -64
  309. package/dist/props/components/index.d.ts +9 -1
  310. package/dist/props/components/layout.prop.d.ts +41 -57
  311. package/dist/props/registry.d.ts +48 -101
  312. package/dist/props/registry.js +45 -129
  313. package/dist/props/vocabulary/index.d.ts +1 -1
  314. package/dist/props/vocabulary/interaction.prop.d.ts +3 -12
  315. package/dist/styles/alert-layout.css +0 -29
  316. package/dist/styles/data-display-layout.css +14 -22
  317. package/dist/styles/fonts/OFL.txt +93 -0
  318. package/dist/styles/form-layout.css +4 -0
  319. package/dist/styles/index.css +0 -2
  320. package/dist/styles/layers.json +44 -179
  321. package/dist/styles/text-layout.css +0 -15
  322. package/dist/styles.css +2 -0
  323. package/dist/themes/godx.css +43 -0
  324. package/dist/themes/godx.d.ts +13 -0
  325. package/dist/themes/godx.js +12 -0
  326. package/dist/tokens/components/feedback.css +0 -6
  327. package/dist/tokens/derived.css +23 -22
  328. package/dist/tokens/foundation.css +4 -6
  329. package/docs/COMPOSITION-VS-COMPONENT.md +58 -33
  330. package/docs/CONSUMER-RULES.md +1 -1
  331. package/docs/CUSTOMER-THEMING.md +17 -53
  332. package/docs/migrations/v32.md +98 -0
  333. package/package.json +58 -19
  334. package/scripts/_agent-setup.mjs +54 -3
  335. package/scripts/brand-accent.generated.mjs +15 -2
  336. package/scripts/cli.mjs +36 -11
  337. package/scripts/codemod.mjs +522 -0
  338. package/scripts/consumer-rule.md +21 -43
  339. package/scripts/postinstall.mjs +10 -47
  340. package/scripts/prune-css.mjs +1 -1
  341. package/scripts/ui-audit.mjs +5 -2
  342. package/dist/components/data-display/chat-bubble.d.ts +0 -30
  343. package/dist/components/data-display/chat-bubble.js +0 -229
  344. package/dist/components/data-display/hover-card.d.ts +0 -1
  345. package/dist/components/data-display/hover-card.js +0 -7
  346. package/dist/components/data-display/thought-chain.d.ts +0 -42
  347. package/dist/components/data-display/thought-chain.js +0 -177
  348. package/dist/components/data-display/thumbnail.d.ts +0 -37
  349. package/dist/components/data-display/thumbnail.js +0 -20
  350. package/dist/components/data-display/welcome.d.ts +0 -26
  351. package/dist/components/data-display/welcome.js +0 -37
  352. package/dist/components/data-entry/attachments.d.ts +0 -19
  353. package/dist/components/data-entry/attachments.js +0 -366
  354. package/dist/components/data-entry/chat-composer.d.ts +0 -51
  355. package/dist/components/data-entry/chat-composer.js +0 -200
  356. package/dist/components/data-entry/chat-suggestion.d.ts +0 -28
  357. package/dist/components/data-entry/chat-suggestion.js +0 -309
  358. package/dist/components/data-entry/tag-input.d.ts +0 -2
  359. package/dist/components/data-entry/tag-input.js +0 -5
  360. package/dist/components/feedback/banner.d.ts +0 -21
  361. package/dist/components/feedback/banner.js +0 -19
  362. package/dist/components/feedback/callout.d.ts +0 -23
  363. package/dist/components/feedback/callout.js +0 -42
  364. package/dist/components/layout/auth-shell.d.ts +0 -10
  365. package/dist/components/layout/auth-shell.js +0 -42
  366. package/dist/components/layout/space-compact.d.ts +0 -65
  367. package/dist/components/layout/space-compact.js +0 -52
  368. package/dist/components/navigation/conversations.d.ts +0 -39
  369. package/dist/components/navigation/conversations.js +0 -371
  370. package/dist/components/ui/accordion.d.ts +0 -51
  371. package/dist/components/ui/accordion.js +0 -254
  372. package/dist/components/ui/aspect-ratio.d.ts +0 -24
  373. package/dist/components/ui/aspect-ratio.js +0 -21
  374. package/dist/components/ui/avatar.d.ts +0 -16
  375. package/dist/components/ui/avatar.js +0 -115
  376. package/dist/components/ui/credential-reveal.d.ts +0 -9
  377. package/dist/components/ui/credential-reveal.js +0 -160
  378. package/dist/components/ui/hover-card.d.ts +0 -47
  379. package/dist/components/ui/hover-card.js +0 -205
  380. package/dist/components/ui/input-otp.d.ts +0 -48
  381. package/dist/components/ui/input-otp.js +0 -101
  382. package/dist/components/ui/password-input.d.ts +0 -38
  383. package/dist/components/ui/password-input.js +0 -60
  384. package/dist/components/ui/rating.d.ts +0 -38
  385. package/dist/components/ui/rating.js +0 -131
  386. package/dist/components/ui/segmented.d.ts +0 -94
  387. package/dist/components/ui/segmented.js +0 -108
  388. package/dist/components/ui/separator.d.ts +0 -25
  389. package/dist/components/ui/separator.js +0 -74
  390. package/dist/components/ui/toggle-group.d.ts +0 -108
  391. package/dist/components/ui/toggle-group.js +0 -194
  392. package/dist/components/ui/toggle.d.ts +0 -86
  393. package/dist/components/ui/toggle.js +0 -156
  394. package/docs/CANONICAL-CONTRACTS.md +0 -206
  395. package/docs/COMPONENTS.md +0 -163
  396. package/docs/DATETIME.md +0 -78
  397. package/docs/DEVELOPMENT.md +0 -269
  398. package/docs/FRAME-A11Y-CI.md +0 -287
  399. package/docs/FRAME-COVERAGE-LEDGER.md +0 -123
  400. package/docs/FRAME-COVERAGE-REPORT.md +0 -228
  401. package/docs/FRAME-COVERAGE-STANDARD.md +0 -65
  402. package/docs/FRAME-COVERAGE.md +0 -29
  403. package/docs/MEASUREMENT-CONTRACT.md +0 -109
  404. package/docs/PROPS-REGISTRY.md +0 -61
  405. package/docs/PROPS-VOCABULARY.md +0 -100
  406. package/docs/REGISTRY.md +0 -70
  407. package/docs/TESTING.md +0 -107
  408. package/docs/THEME-API-COVERAGE.md +0 -538
  409. package/docs/WHAT-BELONGS-HERE.md +0 -179
  410. package/docs/asset-modules.d.ts +0 -53
  411. package/docs/assets/cover-terrain.svg +0 -6
  412. package/docs/assets/portrait-amber.svg +0 -5
  413. package/docs/assets/portrait-clay.svg +0 -5
  414. package/docs/assets/portrait-indigo.svg +0 -5
  415. package/docs/assets/portrait-iris.svg +0 -5
  416. package/docs/assets/portrait-moss.svg +0 -5
  417. package/docs/assets/portrait-plum.svg +0 -5
  418. package/docs/assets/portrait-slate.svg +0 -5
  419. package/docs/assets/service-mark-rose.svg +0 -6
  420. package/docs/assets/service-mark-teal.svg +0 -5
  421. package/docs/assets/shot-landscape.svg +0 -12
  422. package/docs/assets/shot-portrait.svg +0 -10
  423. package/docs/assets/tcgm/card-1.svg +0 -1
  424. package/docs/assets/tcgm/card-2.svg +0 -1
  425. package/docs/assets/tcgm/card-3.svg +0 -1
  426. package/docs/assets/tcgm/card-4.svg +0 -1
  427. package/docs/assets/tcgm/card-5.svg +0 -1
  428. package/docs/assets/tcgm/card-6.svg +0 -1
  429. package/docs/assets/tcgm/hero-prism.svg +0 -1
  430. package/docs/assets/tcgm/scene-1.svg +0 -1
  431. package/docs/assets/tcgm/scene-2.svg +0 -1
  432. package/docs/assets/tcgm/scene-3.svg +0 -1
  433. package/docs/assets/tcgm/scene-4.svg +0 -1
  434. package/docs/assets/tcgm/scene-5.svg +0 -1
  435. package/docs/assets/tcgm/tcgm-lockup-color.svg +0 -1
  436. package/docs/assets/tcgm/tcgm-symbol-color.svg +0 -1
  437. package/docs/charts/cjk-category-axis.tsx +0 -81
  438. package/docs/charts/compact-bar-trend.tsx +0 -327
  439. package/docs/charts/size-tiers.tsx +0 -192
  440. package/docs/data-display/accordion.tsx +0 -99
  441. package/docs/data-display/avatar.tsx +0 -502
  442. package/docs/data-display/badge.tsx +0 -335
  443. package/docs/data-display/card/examples/detail-panel.tsx +0 -106
  444. package/docs/data-display/card/examples/tab-list.tsx +0 -97
  445. package/docs/data-display/card/index.md +0 -3
  446. package/docs/data-display/card/index.tsx +0 -390
  447. package/docs/data-display/carousel.tsx +0 -160
  448. package/docs/data-display/charts.tsx +0 -278
  449. package/docs/data-display/chat-bubble.tsx +0 -397
  450. package/docs/data-display/code-block.tsx +0 -188
  451. package/docs/data-display/collapsible.tsx +0 -162
  452. package/docs/data-display/credential-reveal.tsx +0 -148
  453. package/docs/data-display/data-table/examples/antd-parity.tsx +0 -257
  454. package/docs/data-display/data-table/examples/approval-queue.tsx +0 -212
  455. package/docs/data-display/data-table/examples/grid-features.tsx +0 -158
  456. package/docs/data-display/data-table/examples/list-page.tsx +0 -175
  457. package/docs/data-display/data-table/examples/selectable-inbox.tsx +0 -113
  458. package/docs/data-display/data-table/examples/server-paged.tsx +0 -179
  459. package/docs/data-display/data-table/examples/striped-list.tsx +0 -173
  460. package/docs/data-display/data-table/index.md +0 -9
  461. package/docs/data-display/data-table/index.tsx +0 -407
  462. package/docs/data-display/descriptions.tsx +0 -263
  463. package/docs/data-display/empty-state.tsx +0 -164
  464. package/docs/data-display/feature-list.tsx +0 -159
  465. package/docs/data-display/hover-card.tsx +0 -181
  466. package/docs/data-display/image.tsx +0 -170
  467. package/docs/data-display/legend.tsx +0 -158
  468. package/docs/data-display/list-row.tsx +0 -441
  469. package/docs/data-display/markdown.tsx +0 -86
  470. package/docs/data-display/marquee.tsx +0 -254
  471. package/docs/data-display/org-chart.tsx +0 -165
  472. package/docs/data-display/permission-matrix.tsx +0 -188
  473. package/docs/data-display/popover-touch.tsx +0 -27
  474. package/docs/data-display/popover.tsx +0 -331
  475. package/docs/data-display/progress.tsx +0 -162
  476. package/docs/data-display/prose.tsx +0 -169
  477. package/docs/data-display/qr-code.tsx +0 -68
  478. package/docs/data-display/scroll-area.tsx +0 -420
  479. package/docs/data-display/service-launcher-card.tsx +0 -445
  480. package/docs/data-display/stat-card.tsx +0 -354
  481. package/docs/data-display/swatch.tsx +0 -107
  482. package/docs/data-display/table.tsx +0 -362
  483. package/docs/data-display/text-diff.tsx +0 -89
  484. package/docs/data-display/thought-chain.tsx +0 -176
  485. package/docs/data-display/thumbnail.tsx +0 -128
  486. package/docs/data-display/timeline-grid.tsx +0 -119
  487. package/docs/data-display/timeline.tsx +0 -671
  488. package/docs/data-display/touch-actions.tsx +0 -36
  489. package/docs/data-display/tree.tsx +0 -724
  490. package/docs/data-display/welcome.tsx +0 -115
  491. package/docs/data-entry/attachments.tsx +0 -160
  492. package/docs/data-entry/block-editor.tsx +0 -105
  493. package/docs/data-entry/branch-scope-picker.tsx +0 -128
  494. package/docs/data-entry/calendar.tsx +0 -226
  495. package/docs/data-entry/cascader.tsx +0 -380
  496. package/docs/data-entry/chat-composer.tsx +0 -619
  497. package/docs/data-entry/chat-suggestion.tsx +0 -301
  498. package/docs/data-entry/checkbox.tsx +0 -256
  499. package/docs/data-entry/color-picker.tsx +0 -189
  500. package/docs/data-entry/command-palette.tsx +0 -179
  501. package/docs/data-entry/command.tsx +0 -341
  502. package/docs/data-entry/country-picker-recipe.tsx +0 -175
  503. package/docs/data-entry/date-picker.tsx +0 -452
  504. package/docs/data-entry/emoji-picker.tsx +0 -35
  505. package/docs/data-entry/form/examples/employee-settings.tsx +0 -267
  506. package/docs/data-entry/form/examples/invoice-form.tsx +0 -387
  507. package/docs/data-entry/form-dynamic-fields.tsx +0 -199
  508. package/docs/data-entry/form-field/examples/a11y-contract.tsx +0 -242
  509. package/docs/data-entry/form-field/examples/create-form.tsx +0 -107
  510. package/docs/data-entry/form-field/index.md +0 -8
  511. package/docs/data-entry/form-field/index.tsx +0 -337
  512. package/docs/data-entry/form-inertia.tsx +0 -80
  513. package/docs/data-entry/form-root.tsx +0 -112
  514. package/docs/data-entry/form.tsx +0 -1498
  515. package/docs/data-entry/input-otp.tsx +0 -258
  516. package/docs/data-entry/input.tsx +0 -796
  517. package/docs/data-entry/label.tsx +0 -102
  518. package/docs/data-entry/markdown-editor.tsx +0 -69
  519. package/docs/data-entry/number-input.tsx +0 -279
  520. package/docs/data-entry/password-input.tsx +0 -102
  521. package/docs/data-entry/password-strength.tsx +0 -99
  522. package/docs/data-entry/radio-group.tsx +0 -316
  523. package/docs/data-entry/rating.tsx +0 -91
  524. package/docs/data-entry/record-picker.tsx +0 -209
  525. package/docs/data-entry/search-input.tsx +0 -121
  526. package/docs/data-entry/segmented-in-filter-row.tsx +0 -60
  527. package/docs/data-entry/segmented.tsx +0 -300
  528. package/docs/data-entry/select-async-contracts.tsx +0 -108
  529. package/docs/data-entry/select-matrix.tsx +0 -209
  530. package/docs/data-entry/select.tsx +0 -547
  531. package/docs/data-entry/slider.tsx +0 -212
  532. package/docs/data-entry/sortable-list.tsx +0 -76
  533. package/docs/data-entry/switch.tsx +0 -314
  534. package/docs/data-entry/tag-input.tsx +0 -145
  535. package/docs/data-entry/textarea.tsx +0 -249
  536. package/docs/data-entry/time-picker.tsx +0 -187
  537. package/docs/data-entry/time-range-picker.tsx +0 -55
  538. package/docs/data-entry/toggle-count.tsx +0 -348
  539. package/docs/data-entry/toggle-group.tsx +0 -438
  540. package/docs/data-entry/toggle.tsx +0 -217
  541. package/docs/data-entry/transfer.tsx +0 -115
  542. package/docs/data-entry/tree-select.tsx +0 -204
  543. package/docs/data-entry/upload-crop-dialog.tsx +0 -109
  544. package/docs/data-entry/upload.tsx +0 -310
  545. package/docs/feedback/alert-dialog.tsx +0 -270
  546. package/docs/feedback/alert.tsx +0 -248
  547. package/docs/feedback/auth-expiry.tsx +0 -104
  548. package/docs/feedback/banner.tsx +0 -183
  549. package/docs/feedback/callout.tsx +0 -220
  550. package/docs/feedback/danger-confirm.tsx +0 -91
  551. package/docs/feedback/dialog-touch.tsx +0 -24
  552. package/docs/feedback/dialog.tsx +0 -373
  553. package/docs/feedback/sheet.tsx +0 -510
  554. package/docs/feedback/skeleton.tsx +0 -168
  555. package/docs/feedback/toast.tsx +0 -135
  556. package/docs/feedback/tooltip.tsx +0 -171
  557. package/docs/feedback/two-factor-setup.tsx +0 -68
  558. package/docs/foundation/_email-specimen.ts +0 -274
  559. package/docs/foundation/_theme-editor-scope.ts +0 -222
  560. package/docs/foundation/colors.tsx +0 -207
  561. package/docs/foundation/density.tsx +0 -242
  562. package/docs/foundation/email-tokens.tsx +0 -323
  563. package/docs/foundation/radius-shadow.tsx +0 -154
  564. package/docs/foundation/spacing.tsx +0 -216
  565. package/docs/foundation/theme-editor.tsx +0 -654
  566. package/docs/foundation/typography.tsx +0 -147
  567. package/docs/general/actions.tsx +0 -175
  568. package/docs/general/activity.tsx +0 -289
  569. package/docs/general/button/examples/destructive-confirm.tsx +0 -90
  570. package/docs/general/button/examples/form-actions.tsx +0 -87
  571. package/docs/general/button/examples/toolbar.tsx +0 -160
  572. package/docs/general/button/index.md +0 -16
  573. package/docs/general/button/index.tsx +0 -236
  574. package/docs/general/float-button.tsx +0 -133
  575. package/docs/general/icon.tsx +0 -217
  576. package/docs/general/logo.tsx +0 -194
  577. package/docs/general/reveal.tsx +0 -309
  578. package/docs/general/typography.tsx +0 -542
  579. package/docs/i18n/messages/en.json +0 -1715
  580. package/docs/i18n/messages/ja.json +0 -1708
  581. package/docs/i18n/messages/vi.json +0 -1708
  582. package/docs/layout/account-chip.tsx +0 -72
  583. package/docs/layout/admin-collection.tsx +0 -122
  584. package/docs/layout/affix.tsx +0 -209
  585. package/docs/layout/app-launcher.tsx +0 -211
  586. package/docs/layout/app-shell-arrangements.tsx +0 -225
  587. package/docs/layout/app-shell-narrow-bar.tsx +0 -205
  588. package/docs/layout/app-shell-states.tsx +0 -171
  589. package/docs/layout/app-shell.tsx +0 -395
  590. package/docs/layout/aspect-ratio.tsx +0 -135
  591. package/docs/layout/auth-account-summary.tsx +0 -103
  592. package/docs/layout/auth-divider.tsx +0 -28
  593. package/docs/layout/auth-footer.tsx +0 -37
  594. package/docs/layout/auth-identity.tsx +0 -70
  595. package/docs/layout/auth-recovery/examples/mfa-challenge.md +0 -41
  596. package/docs/layout/auth-recovery/examples/mfa-challenge.tsx +0 -254
  597. package/docs/layout/auth-recovery/examples/mobile-390.md +0 -25
  598. package/docs/layout/auth-recovery/examples/mobile-390.tsx +0 -82
  599. package/docs/layout/auth-recovery/examples/password-recovery.md +0 -24
  600. package/docs/layout/auth-recovery/examples/password-recovery.tsx +0 -197
  601. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.md +0 -27
  602. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.tsx +0 -156
  603. package/docs/layout/auth-recovery/index.md +0 -140
  604. package/docs/layout/auth-recovery/index.tsx +0 -96
  605. package/docs/layout/auth-shell-context.tsx +0 -103
  606. package/docs/layout/auth-shell-device.tsx +0 -112
  607. package/docs/layout/auth-shell-registration.tsx +0 -338
  608. package/docs/layout/auth-shell-variants.tsx +0 -143
  609. package/docs/layout/auth-shell.tsx +0 -59
  610. package/docs/layout/auth-stack.tsx +0 -40
  611. package/docs/layout/centered-shell.tsx +0 -102
  612. package/docs/layout/draggable-panel.tsx +0 -127
  613. package/docs/layout/error-surface/examples/application-403.tsx +0 -84
  614. package/docs/layout/error-surface/examples/application-404.tsx +0 -77
  615. package/docs/layout/error-surface/examples/system-500.tsx +0 -47
  616. package/docs/layout/error-surface/examples/system-503.tsx +0 -48
  617. package/docs/layout/error-surface/index.md +0 -153
  618. package/docs/layout/error-surface/index.tsx +0 -239
  619. package/docs/layout/flex.tsx +0 -444
  620. package/docs/layout/legal-document-shell/_data.ts +0 -110
  621. package/docs/layout/legal-document-shell/examples/desktop-1440.md +0 -12
  622. package/docs/layout/legal-document-shell/examples/desktop-1440.tsx +0 -83
  623. package/docs/layout/legal-document-shell/examples/mobile-390.md +0 -22
  624. package/docs/layout/legal-document-shell/examples/mobile-390.tsx +0 -70
  625. package/docs/layout/legal-document-shell/examples/tablet-1024.md +0 -3
  626. package/docs/layout/legal-document-shell/examples/tablet-1024.tsx +0 -84
  627. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.md +0 -18
  628. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.tsx +0 -61
  629. package/docs/layout/legal-document-shell/index.md +0 -51
  630. package/docs/layout/legal-document-shell/index.tsx +0 -101
  631. package/docs/layout/masonry.tsx +0 -291
  632. package/docs/layout/master-detail.tsx +0 -390
  633. package/docs/layout/mobile-shell.tsx +0 -106
  634. package/docs/layout/nav-list.tsx +0 -584
  635. package/docs/layout/org-switcher.tsx +0 -131
  636. package/docs/layout/page-container.tsx +0 -1020
  637. package/docs/layout/page-cover.tsx +0 -56
  638. package/docs/layout/resizable-panel.tsx +0 -419
  639. package/docs/layout/responsive-grid.tsx +0 -403
  640. package/docs/layout/separator.tsx +0 -327
  641. package/docs/layout/service-role-panel.tsx +0 -144
  642. package/docs/layout/sidebar.tsx +0 -689
  643. package/docs/layout/space-compact.tsx +0 -202
  644. package/docs/layout/split-pane.tsx +0 -532
  645. package/docs/layout/topbar-item.tsx +0 -233
  646. package/docs/layout/topbar.tsx +0 -360
  647. package/docs/navigation/anchor.tsx +0 -295
  648. package/docs/navigation/app-setting-picker.tsx +0 -178
  649. package/docs/navigation/app-setting-toggle.tsx +0 -111
  650. package/docs/navigation/breadcrumb.tsx +0 -207
  651. package/docs/navigation/card-tabs.tsx +0 -344
  652. package/docs/navigation/conversations.tsx +0 -176
  653. package/docs/navigation/dropdown-menu.tsx +0 -345
  654. package/docs/navigation/filter-bar.tsx +0 -247
  655. package/docs/navigation/mega-menu-panel.tsx +0 -86
  656. package/docs/navigation/mega-menu.tsx +0 -254
  657. package/docs/navigation/pagination.tsx +0 -293
  658. package/docs/navigation/steps.tsx +0 -315
  659. package/docs/navigation/tabs-rtl.tsx +0 -28
  660. package/docs/navigation/tabs.tsx +0 -755
  661. package/docs/navigation/toolbar.tsx +0 -347
  662. package/docs/providers/app-provider.tsx +0 -191
  663. package/docs/providers/format-date.tsx +0 -230
  664. package/docs/providers/theme-scope.tsx +0 -186
  665. package/docs/query/button-refetch.tsx +0 -161
  666. package/docs/query/data-state.tsx +0 -262
  667. package/docs/query/infinite-query-state.tsx +0 -97
  668. package/docs/query/mutation-feedback.tsx +0 -128
  669. package/docs/query/touch-actions.tsx +0 -68
  670. package/docs/react-router/prefetch-link.tsx +0 -262
  671. package/docs/roadmap/ai-chat-components.md +0 -206
  672. package/docs/roadmap/antd-parity.md +0 -155
  673. package/docs/roadmap/badge-tag-chip-count.md +0 -172
  674. package/docs/roadmap/list-masonry.md +0 -159
  675. package/docs/roadmap/parity-audit-data-display-feedback.md +0 -567
  676. package/docs/roadmap/parity-audit-data-entry.md +0 -368
  677. package/docs/roadmap/parity-audit-layout-navigation-general.md +0 -459
  678. package/docs/roadmap/parity-backlog.md +0 -77
  679. package/docs/roadmap/tree-components.md +0 -151
  680. package/docs/roadmap/website-components.md +0 -813
  681. package/docs/showcase/acme-portal.tsx +0 -461
  682. package/docs/showcase/acme-website.tsx +0 -499
  683. package/docs/showcase/caimono-price-comparison.tsx +0 -919
  684. package/docs/showcase/case1-warehouse-dashboard.tsx +0 -358
  685. package/docs/showcase/case2-employee-me.tsx +0 -438
  686. package/docs/showcase/case3-approval-workflow.tsx +0 -531
  687. package/docs/showcase/case4-login.tsx +0 -312
  688. package/docs/showcase/case5-shift-calendar.tsx +0 -702
  689. package/docs/showcase/case6-agency-handy.tsx +0 -1120
  690. package/docs/showcase/futurelastic-web.tsx +0 -441
  691. package/docs/showcase/marketing-page.tsx +0 -895
  692. package/docs/showcase/org-switcher.tsx +0 -320
  693. package/docs/showcase/permission-matrix.tsx +0 -354
  694. package/docs/showcase/public-landing.tsx +0 -210
  695. package/docs/showcase/settings-account-sections.tsx +0 -559
  696. package/docs/showcase/settings-security-mfa.tsx +0 -145
  697. package/docs/showcase/table-approval-queue.tsx +0 -199
  698. package/docs/showcase/table-bulk-actions.tsx +0 -468
  699. package/docs/showcase/table-compact-kintone.tsx +0 -438
  700. package/docs/showcase/table-conditional-format.tsx +0 -367
  701. package/docs/showcase/table-crud-list.tsx +0 -544
  702. package/docs/showcase/table-density.tsx +0 -349
  703. package/docs/showcase/table-expandable-rows.tsx +0 -496
  704. package/docs/showcase/table-filter-chips.tsx +0 -468
  705. package/docs/showcase/table-footer-totals.tsx +0 -328
  706. package/docs/showcase/table-grouped-subtotals.tsx +0 -398
  707. package/docs/showcase/table-master-detail.tsx +0 -482
  708. package/docs/showcase/table-pagination.tsx +0 -409
  709. package/docs/showcase/table-states.tsx +0 -371
  710. package/docs/showcase/table-sticky-columns.tsx +0 -377
  711. package/docs/showcase/table-tree-rows.tsx +0 -451
  712. package/docs/showcase/table-view-tabs.tsx +0 -488
  713. package/docs/showcase/tcgm-website.tsx +0 -1047
  714. package/docs/showcase/tenant-brand-color.tsx +0 -338
  715. package/docs/showcase/theme-customization.tsx +0 -1292
  716. package/docs/showcase/theme-lab.tsx +0 -2125
  717. package/docs/themes/flat.css +0 -466
  718. package/docs/themes/glassmorphism.css +0 -960
  719. package/docs/themes/index.ts +0 -219
  720. package/docs/themes/neubrutalism.css +0 -481
  721. /package/dist/components/navigation/{filter-bar.d.ts → toolbar.d.ts} +0 -0
  722. /package/dist/components/navigation/{filter-bar.js → toolbar.js} +0 -0
  723. /package/dist/{components/data-display → lab}/carousel.d.ts +0 -0
  724. /package/dist/{components/data-entry → lab}/emoji-data.d.ts +0 -0
  725. /package/dist/{components/data-entry → lab}/emoji-data.js +0 -0
  726. /package/dist/{components/data-display → lab}/marquee-reveal.d.ts +0 -0
  727. /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.**