@godxjp/ui 19.1.0 → 19.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (436) hide show
  1. package/README.md +25 -128
  2. package/dist/app/theme-axes.d.ts +4 -15
  3. package/dist/app/timezones.d.ts +1 -4
  4. package/dist/components/charts/area-chart.d.ts +2 -3
  5. package/dist/components/charts/bar-chart.d.ts +2 -3
  6. package/dist/components/charts/chart-frame.d.ts +7 -16
  7. package/dist/components/charts/chart-summary.d.ts +2 -2
  8. package/dist/components/charts/compact-bar-trend.d.ts +9 -24
  9. package/dist/components/charts/index.d.ts +1 -6
  10. package/dist/components/data-display/badge.d.ts +2 -12
  11. package/dist/components/data-display/card.d.ts +21 -41
  12. package/dist/components/data-display/carousel.d.ts +1 -2
  13. package/dist/components/data-display/code-block.d.ts +4 -0
  14. package/dist/components/data-display/code-block.js +24 -0
  15. package/dist/components/data-display/data-table.d.ts +15 -37
  16. package/dist/components/data-display/data-table.js +1 -3
  17. package/dist/components/data-display/descriptions.d.ts +2 -6
  18. package/dist/components/data-display/descriptions.js +0 -2
  19. package/dist/components/data-display/index.d.ts +4 -0
  20. package/dist/components/data-display/index.js +4 -0
  21. package/dist/components/data-display/list-row.d.ts +3 -22
  22. package/dist/components/data-display/permission-matrix.d.ts +7 -20
  23. package/dist/components/data-display/progress.d.ts +1 -1
  24. package/dist/components/data-display/prose.d.ts +4 -0
  25. package/dist/components/data-display/prose.js +20 -0
  26. package/dist/components/data-display/service-launcher-card.d.ts +3 -10
  27. package/dist/components/data-display/table.d.ts +20 -80
  28. package/dist/components/data-display/table.js +0 -3
  29. package/dist/components/data-display/timeline.d.ts +3 -5
  30. package/dist/components/data-entry/branch-scope-picker.d.ts +2 -19
  31. package/dist/components/data-entry/branch-scope-picker.js +0 -1
  32. package/dist/components/data-entry/calendar.d.ts +3 -2
  33. package/dist/components/data-entry/calendar.js +58 -3
  34. package/dist/components/data-entry/command-palette.d.ts +8 -22
  35. package/dist/components/data-entry/date-picker.d.ts +4 -5
  36. package/dist/components/data-entry/date-picker.js +6 -1
  37. package/dist/components/data-entry/date-range-picker.d.ts +1 -1
  38. package/dist/components/data-entry/date-range-picker.js +8 -3
  39. package/dist/components/data-entry/form-errors.d.ts +7 -18
  40. package/dist/components/data-entry/form-field.js +1 -5
  41. package/dist/components/data-entry/form.d.ts +1 -9
  42. package/dist/components/data-entry/input.d.ts +16 -14
  43. package/dist/components/data-entry/input.js +3 -0
  44. package/dist/components/data-entry/month-picker.js +2 -2
  45. package/dist/components/data-entry/month-range-picker.d.ts +4 -6
  46. package/dist/components/data-entry/month-range-picker.js +2 -2
  47. package/dist/components/data-entry/number-input.d.ts +1 -5
  48. package/dist/components/data-entry/number-input.js +1 -0
  49. package/dist/components/data-entry/radio.js +0 -1
  50. package/dist/components/data-entry/search-select.d.ts +2 -4
  51. package/dist/components/data-entry/select.d.ts +11 -6
  52. package/dist/components/data-entry/select.js +4 -2
  53. package/dist/components/data-entry/switch.js +0 -1
  54. package/dist/components/data-entry/textarea.d.ts +10 -16
  55. package/dist/components/data-entry/time-picker.d.ts +3 -5
  56. package/dist/components/data-entry/upload-types.d.ts +1 -5
  57. package/dist/components/data-entry/use-upload-draft.d.ts +0 -4
  58. package/dist/components/feedback/dialog.d.ts +6 -15
  59. package/dist/components/feedback/overlay-header-tone.d.ts +1 -1
  60. package/dist/components/feedback/sheet.d.ts +3 -10
  61. package/dist/components/feedback/sheet.js +1 -1
  62. package/dist/components/feedback/sonner.js +2 -3
  63. package/dist/components/general/activity.d.ts +4 -30
  64. package/dist/components/general/button.js +1 -10
  65. package/dist/components/general/logo.d.ts +6 -28
  66. package/dist/components/general/reveal.d.ts +3 -9
  67. package/dist/components/general/typography.d.ts +1 -3
  68. package/dist/components/layout/account-chip.d.ts +8 -0
  69. package/dist/components/layout/account-chip.js +45 -0
  70. package/dist/components/layout/auth-divider.d.ts +2 -9
  71. package/dist/components/layout/auth-shell.d.ts +1 -14
  72. package/dist/components/layout/breadcrumb.d.ts +1 -5
  73. package/dist/components/layout/centered-shell.d.ts +4 -18
  74. package/dist/components/layout/error-surface.d.ts +11 -28
  75. package/dist/components/layout/error-surface.js +4 -1
  76. package/dist/components/layout/index.d.ts +2 -0
  77. package/dist/components/layout/index.js +2 -0
  78. package/dist/components/layout/legal-document-shell.d.ts +5 -28
  79. package/dist/components/layout/master-detail.d.ts +2 -18
  80. package/dist/components/layout/page-container.js +0 -1
  81. package/dist/components/layout/responsive-grid.d.ts +6 -1
  82. package/dist/components/layout/responsive-grid.js +9 -2
  83. package/dist/components/layout/service-role-panel.d.ts +7 -19
  84. package/dist/components/layout/sidebar.d.ts +5 -27
  85. package/dist/components/layout/sidebar.js +0 -1
  86. package/dist/components/layout/split-pane.d.ts +0 -7
  87. package/dist/components/layout/topbar.d.ts +1 -14
  88. package/dist/components/navigation/app-setting-picker.js +1 -3
  89. package/dist/components/navigation/filter-bar.d.ts +1 -6
  90. package/dist/components/navigation/pagination-utils.d.ts +2 -12
  91. package/dist/components/navigation/tabs-scroll.d.ts +2 -36
  92. package/dist/components/navigation/tabs.js +4 -8
  93. package/dist/components/query/data-state.d.ts +2 -2
  94. package/dist/components/ui/credential-reveal.d.ts +1 -4
  95. package/dist/components/ui/hover-card.d.ts +1 -2
  96. package/dist/components/ui/separator.d.ts +2 -15
  97. package/dist/components/ui/toggle-group.d.ts +1 -5
  98. package/dist/components/ui/toggle.d.ts +6 -31
  99. package/dist/email/brand-mark.d.ts +6 -34
  100. package/dist/email/color.d.ts +7 -17
  101. package/dist/email/geometry.d.ts +4 -8
  102. package/dist/email/index.d.ts +4 -48
  103. package/dist/email/inline-style.d.ts +3 -9
  104. package/dist/email/urgency.d.ts +2 -7
  105. package/dist/form/form-context.d.ts +2 -5
  106. package/dist/form/form-root.d.ts +1 -2
  107. package/dist/i18n/messages/en.json +4 -0
  108. package/dist/i18n/messages/ja.json +4 -0
  109. package/dist/i18n/messages/vi.json +4 -0
  110. package/dist/inertia/index.d.ts +2 -10
  111. package/dist/lib/control-styles.d.ts +10 -21
  112. package/dist/lib/control-styles.js +4 -6
  113. package/dist/lib/datetime/format-date.d.ts +1 -4
  114. package/dist/lib/field-a11y.d.ts +11 -68
  115. package/dist/lib/field-a11y.js +0 -1
  116. package/dist/lib/format.d.ts +4 -8
  117. package/dist/lib/hooks.d.ts +6 -12
  118. package/dist/lib/permission-grid.d.ts +3 -18
  119. package/dist/lib/query-error.d.ts +3 -3
  120. package/dist/props/components/app.prop.d.ts +15 -38
  121. package/dist/props/components/charts.prop.d.ts +2 -3
  122. package/dist/props/components/data-display.prop.d.ts +48 -72
  123. package/dist/props/components/data-entry.prop.d.ts +35 -40
  124. package/dist/props/components/form.prop.d.ts +2 -6
  125. package/dist/props/components/general.prop.d.ts +11 -27
  126. package/dist/props/components/layout.prop.d.ts +89 -260
  127. package/dist/props/components/navigation.prop.d.ts +27 -42
  128. package/dist/props/registry.d.ts +31 -0
  129. package/dist/props/registry.js +33 -0
  130. package/dist/props/vocabulary/data.prop.d.ts +18 -49
  131. package/dist/props/vocabulary/index.d.ts +1 -1
  132. package/dist/props/vocabulary/interaction.prop.d.ts +10 -12
  133. package/dist/props/vocabulary/layout.prop.d.ts +8 -30
  134. package/dist/props/vocabulary/shared.prop.d.ts +3 -2
  135. package/dist/styles/alert-layout.css +1 -32
  136. package/dist/styles/badge-layout.css +4 -18
  137. package/dist/styles/base.css +14 -113
  138. package/dist/styles/card-layout.css +6 -128
  139. package/dist/styles/chart-layout.css +2 -17
  140. package/dist/styles/control.css +380 -458
  141. package/dist/styles/core.css +21 -0
  142. package/dist/styles/data-display-layout.css +175 -94
  143. package/dist/styles/data-entry-layout.css +0 -45
  144. package/dist/styles/density.css +1 -30
  145. package/dist/styles/dialog-layout.css +5 -69
  146. package/dist/styles/focus-ring.css +13 -87
  147. package/dist/styles/fonts.css +1 -31
  148. package/dist/styles/form-layout.css +7 -91
  149. package/dist/styles/index.css +2 -20
  150. package/dist/styles/layout.css +38 -456
  151. package/dist/styles/logo-layout.css +1 -35
  152. package/dist/styles/motion.css +3 -42
  153. package/dist/styles/navigation-layout.css +3 -50
  154. package/dist/styles/shell-layout.css +37 -403
  155. package/dist/styles/table-layout.css +16 -274
  156. package/dist/styles/text-layout.css +7 -21
  157. package/dist/styles/toggle.css +1 -23
  158. package/dist/theme/dxs.canonical.css +1 -55
  159. package/dist/theme/example.service.css +1 -26
  160. package/dist/theme/famgia.service.css +5 -15
  161. package/dist/tokens/axes.css +3 -40
  162. package/dist/tokens/base.css +1 -4
  163. package/dist/tokens/components/activity.css +6 -42
  164. package/dist/tokens/components/badge.css +4 -13
  165. package/dist/tokens/components/banner.css +4 -9
  166. package/dist/tokens/components/card.css +32 -88
  167. package/dist/tokens/components/chart.css +9 -26
  168. package/dist/tokens/components/control.css +37 -222
  169. package/dist/tokens/components/data-display.css +28 -79
  170. package/dist/tokens/components/data-entry.css +5 -19
  171. package/dist/tokens/components/descriptions.css +7 -27
  172. package/dist/tokens/components/email.css +38 -84
  173. package/dist/tokens/components/error-surface.css +2 -18
  174. package/dist/tokens/components/feedback.css +27 -124
  175. package/dist/tokens/components/form.css +13 -45
  176. package/dist/tokens/components/legal-document.css +16 -41
  177. package/dist/tokens/components/list-row.css +11 -36
  178. package/dist/tokens/components/logo.css +2 -57
  179. package/dist/tokens/components/navigation.css +16 -94
  180. package/dist/tokens/components/scroll-area.css +2 -18
  181. package/dist/tokens/components/separator.css +8 -30
  182. package/dist/tokens/components/sheet.css +3 -14
  183. package/dist/tokens/components/shell.css +53 -307
  184. package/dist/tokens/components/sidebar.css +5 -22
  185. package/dist/tokens/components/table.css +19 -140
  186. package/dist/tokens/components/toggle.css +3 -65
  187. package/dist/tokens/components/upload.css +7 -43
  188. package/dist/tokens/foundation.css +108 -383
  189. package/dist/tokens/semantic/layout.css +33 -207
  190. package/docs/CANONICAL-CONTRACTS.md +206 -0
  191. package/docs/COMPONENTS.md +157 -0
  192. package/docs/COMPOSITION-VS-COMPONENT.md +105 -0
  193. package/docs/CONSUMER-RULES.md +14 -0
  194. package/docs/CUSTOMER-THEMING.md +162 -0
  195. package/docs/DATETIME.md +69 -0
  196. package/docs/DEVELOPMENT.md +173 -0
  197. package/docs/FORMS.md +143 -0
  198. package/docs/FRAME-A11Y-CI.md +267 -0
  199. package/docs/FRAME-COVERAGE-LEDGER.md +123 -0
  200. package/docs/FRAME-COVERAGE-REPORT.md +140 -0
  201. package/docs/FRAME-COVERAGE-STANDARD.md +65 -0
  202. package/docs/FRAME-COVERAGE.md +29 -0
  203. package/docs/PROPS-REGISTRY.md +61 -0
  204. package/docs/PROPS-VOCABULARY.md +100 -0
  205. package/docs/README.md +60 -0
  206. package/docs/REGISTRY.md +70 -0
  207. package/docs/SPACING.md +56 -0
  208. package/docs/STANDARDS-vocabulary-tokens.md +48 -0
  209. package/docs/TESTING.md +98 -0
  210. package/docs/TOKENS.md +347 -0
  211. package/docs/asset-modules.d.ts +46 -0
  212. package/docs/assets/cover-terrain.svg +6 -0
  213. package/docs/assets/portrait-amber.svg +5 -0
  214. package/docs/assets/portrait-clay.svg +5 -0
  215. package/docs/assets/portrait-indigo.svg +5 -0
  216. package/docs/assets/portrait-iris.svg +5 -0
  217. package/docs/assets/portrait-moss.svg +5 -0
  218. package/docs/assets/portrait-plum.svg +5 -0
  219. package/docs/assets/portrait-slate.svg +5 -0
  220. package/docs/charts/compact-bar-trend.tsx +328 -0
  221. package/docs/charts/size-tiers.tsx +192 -0
  222. package/docs/data-display/accordion.tsx +99 -0
  223. package/docs/data-display/avatar.tsx +355 -0
  224. package/docs/data-display/badge.tsx +247 -0
  225. package/docs/data-display/card/examples/detail-panel.tsx +106 -0
  226. package/docs/data-display/card/index.md +3 -0
  227. package/docs/data-display/card/index.tsx +285 -0
  228. package/docs/data-display/carousel.tsx +156 -0
  229. package/docs/data-display/charts.tsx +198 -0
  230. package/docs/data-display/code-block.tsx +90 -0
  231. package/docs/data-display/collapsible.tsx +162 -0
  232. package/docs/data-display/credential-reveal.tsx +145 -0
  233. package/docs/data-display/data-table/examples/approval-queue.tsx +212 -0
  234. package/docs/data-display/data-table/examples/grid-features.tsx +158 -0
  235. package/docs/data-display/data-table/examples/list-page.tsx +175 -0
  236. package/docs/data-display/data-table/index.md +5 -0
  237. package/docs/data-display/data-table/index.tsx +295 -0
  238. package/docs/data-display/descriptions.tsx +143 -0
  239. package/docs/data-display/empty-state.tsx +164 -0
  240. package/docs/data-display/hover-card.tsx +181 -0
  241. package/docs/data-display/list-row.tsx +420 -0
  242. package/docs/data-display/permission-matrix.tsx +184 -0
  243. package/docs/data-display/popover-touch.tsx +27 -0
  244. package/docs/data-display/popover.tsx +245 -0
  245. package/docs/data-display/progress.tsx +84 -0
  246. package/docs/data-display/prose.tsx +105 -0
  247. package/docs/data-display/qr-code.tsx +68 -0
  248. package/docs/data-display/scroll-area.tsx +271 -0
  249. package/docs/data-display/service-launcher-card.tsx +145 -0
  250. package/docs/data-display/stat-card.tsx +99 -0
  251. package/docs/data-display/table.tsx +251 -0
  252. package/docs/data-display/timeline.tsx +112 -0
  253. package/docs/data-display/touch-actions.tsx +36 -0
  254. package/docs/data-display/tree-list.tsx +107 -0
  255. package/docs/data-entry/branch-scope-picker.tsx +123 -0
  256. package/docs/data-entry/calendar.tsx +180 -0
  257. package/docs/data-entry/cascader.tsx +378 -0
  258. package/docs/data-entry/checkbox.tsx +256 -0
  259. package/docs/data-entry/color-picker.tsx +117 -0
  260. package/docs/data-entry/command-palette.tsx +179 -0
  261. package/docs/data-entry/command.tsx +262 -0
  262. package/docs/data-entry/country-picker-recipe.tsx +170 -0
  263. package/docs/data-entry/date-picker.tsx +191 -0
  264. package/docs/data-entry/date-range-picker.tsx +149 -0
  265. package/docs/data-entry/form/examples/employee-settings.tsx +267 -0
  266. package/docs/data-entry/form/examples/invoice-form.tsx +387 -0
  267. package/docs/data-entry/form-field/examples/a11y-contract.tsx +240 -0
  268. package/docs/data-entry/form-field/examples/create-form.tsx +105 -0
  269. package/docs/data-entry/form-field/index.md +8 -0
  270. package/docs/data-entry/form-field/index.tsx +326 -0
  271. package/docs/data-entry/form-inertia.tsx +80 -0
  272. package/docs/data-entry/form-root.tsx +102 -0
  273. package/docs/data-entry/form.tsx +724 -0
  274. package/docs/data-entry/input-otp.tsx +231 -0
  275. package/docs/data-entry/input.tsx +114 -0
  276. package/docs/data-entry/label.tsx +100 -0
  277. package/docs/data-entry/month-picker.tsx +101 -0
  278. package/docs/data-entry/month-range-picker.tsx +115 -0
  279. package/docs/data-entry/number-input.tsx +240 -0
  280. package/docs/data-entry/password-input.tsx +106 -0
  281. package/docs/data-entry/password-strength.tsx +97 -0
  282. package/docs/data-entry/radio-group.tsx +95 -0
  283. package/docs/data-entry/rating.tsx +87 -0
  284. package/docs/data-entry/search-input.tsx +120 -0
  285. package/docs/data-entry/select-async-contracts.tsx +108 -0
  286. package/docs/data-entry/select-matrix.tsx +204 -0
  287. package/docs/data-entry/select.tsx +369 -0
  288. package/docs/data-entry/slider.tsx +130 -0
  289. package/docs/data-entry/switch.tsx +67 -0
  290. package/docs/data-entry/tag-input.tsx +108 -0
  291. package/docs/data-entry/textarea.tsx +209 -0
  292. package/docs/data-entry/time-picker.tsx +99 -0
  293. package/docs/data-entry/toggle-count.tsx +293 -0
  294. package/docs/data-entry/toggle-group.tsx +225 -0
  295. package/docs/data-entry/toggle.tsx +127 -0
  296. package/docs/data-entry/transfer.tsx +97 -0
  297. package/docs/data-entry/tree-select.tsx +204 -0
  298. package/docs/data-entry/upload.tsx +184 -0
  299. package/docs/feedback/alert-dialog.tsx +270 -0
  300. package/docs/feedback/alert.tsx +248 -0
  301. package/docs/feedback/banner.tsx +183 -0
  302. package/docs/feedback/danger-confirm.tsx +88 -0
  303. package/docs/feedback/dialog-touch.tsx +24 -0
  304. package/docs/feedback/dialog.tsx +193 -0
  305. package/docs/feedback/sheet.tsx +410 -0
  306. package/docs/feedback/skeleton.tsx +111 -0
  307. package/docs/feedback/toast.tsx +135 -0
  308. package/docs/feedback/tooltip.tsx +171 -0
  309. package/docs/feedback/two-factor-setup.tsx +68 -0
  310. package/docs/foundation/_email-specimen.ts +274 -0
  311. package/docs/foundation/colors.tsx +202 -0
  312. package/docs/foundation/density.tsx +232 -0
  313. package/docs/foundation/email-tokens.tsx +306 -0
  314. package/docs/foundation/radius-shadow.tsx +152 -0
  315. package/docs/foundation/spacing.tsx +211 -0
  316. package/docs/foundation/typography.tsx +147 -0
  317. package/docs/general/activity.tsx +224 -0
  318. package/docs/general/button/examples/destructive-confirm.tsx +90 -0
  319. package/docs/general/button/examples/form-actions.tsx +85 -0
  320. package/docs/general/button/examples/toolbar.tsx +160 -0
  321. package/docs/general/button/index.md +12 -0
  322. package/docs/general/button/index.tsx +211 -0
  323. package/docs/general/logo.tsx +131 -0
  324. package/docs/general/reveal.tsx +41 -0
  325. package/docs/general/typography.tsx +152 -0
  326. package/docs/layout/account-chip.tsx +72 -0
  327. package/docs/layout/admin-collection.tsx +122 -0
  328. package/docs/layout/app-shell.tsx +374 -0
  329. package/docs/layout/aspect-ratio.tsx +119 -0
  330. package/docs/layout/auth-account-summary.tsx +103 -0
  331. package/docs/layout/auth-divider.tsx +28 -0
  332. package/docs/layout/auth-footer.tsx +37 -0
  333. package/docs/layout/auth-identity.tsx +36 -0
  334. package/docs/layout/auth-recovery/examples/mfa-challenge.md +41 -0
  335. package/docs/layout/auth-recovery/examples/mfa-challenge.tsx +254 -0
  336. package/docs/layout/auth-recovery/examples/mobile-390.md +25 -0
  337. package/docs/layout/auth-recovery/examples/mobile-390.tsx +82 -0
  338. package/docs/layout/auth-recovery/examples/password-recovery.md +24 -0
  339. package/docs/layout/auth-recovery/examples/password-recovery.tsx +197 -0
  340. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.md +27 -0
  341. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.tsx +156 -0
  342. package/docs/layout/auth-recovery/index.md +140 -0
  343. package/docs/layout/auth-recovery/index.tsx +96 -0
  344. package/docs/layout/auth-shell-context.tsx +103 -0
  345. package/docs/layout/auth-shell-device.tsx +112 -0
  346. package/docs/layout/auth-shell-registration.tsx +335 -0
  347. package/docs/layout/auth-shell-variants.tsx +139 -0
  348. package/docs/layout/auth-shell.tsx +59 -0
  349. package/docs/layout/auth-stack.tsx +40 -0
  350. package/docs/layout/centered-shell.tsx +102 -0
  351. package/docs/layout/error-surface/examples/application-403.tsx +84 -0
  352. package/docs/layout/error-surface/examples/application-404.tsx +77 -0
  353. package/docs/layout/error-surface/examples/system-500.tsx +47 -0
  354. package/docs/layout/error-surface/examples/system-503.tsx +48 -0
  355. package/docs/layout/error-surface/index.md +153 -0
  356. package/docs/layout/error-surface/index.tsx +239 -0
  357. package/docs/layout/flex.tsx +262 -0
  358. package/docs/layout/legal-document-shell/_data.ts +110 -0
  359. package/docs/layout/legal-document-shell/examples/desktop-1440.md +12 -0
  360. package/docs/layout/legal-document-shell/examples/desktop-1440.tsx +83 -0
  361. package/docs/layout/legal-document-shell/examples/mobile-390.md +22 -0
  362. package/docs/layout/legal-document-shell/examples/mobile-390.tsx +70 -0
  363. package/docs/layout/legal-document-shell/examples/tablet-1024.md +3 -0
  364. package/docs/layout/legal-document-shell/examples/tablet-1024.tsx +84 -0
  365. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.md +18 -0
  366. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.tsx +61 -0
  367. package/docs/layout/legal-document-shell/index.md +51 -0
  368. package/docs/layout/legal-document-shell/index.tsx +101 -0
  369. package/docs/layout/master-detail.tsx +387 -0
  370. package/docs/layout/org-switcher.tsx +131 -0
  371. package/docs/layout/page-container.tsx +946 -0
  372. package/docs/layout/resizable-panel.tsx +419 -0
  373. package/docs/layout/responsive-grid.tsx +235 -0
  374. package/docs/layout/separator.tsx +327 -0
  375. package/docs/layout/service-role-panel.tsx +144 -0
  376. package/docs/layout/sidebar.tsx +586 -0
  377. package/docs/layout/split-pane.tsx +451 -0
  378. package/docs/layout/topbar.tsx +347 -0
  379. package/docs/navigation/app-setting-picker.tsx +141 -0
  380. package/docs/navigation/breadcrumb.tsx +128 -0
  381. package/docs/navigation/context-menu.tsx +117 -0
  382. package/docs/navigation/dropdown-menu.tsx +213 -0
  383. package/docs/navigation/filter-bar.tsx +227 -0
  384. package/docs/navigation/menubar.tsx +141 -0
  385. package/docs/navigation/navigation-menu.tsx +165 -0
  386. package/docs/navigation/pagination.tsx +241 -0
  387. package/docs/navigation/steps.tsx +263 -0
  388. package/docs/navigation/tabs-rtl.tsx +28 -0
  389. package/docs/navigation/tabs.tsx +308 -0
  390. package/docs/navigation/toolbar.tsx +339 -0
  391. package/docs/providers/app-provider.tsx +191 -0
  392. package/docs/providers/format-date.tsx +230 -0
  393. package/docs/query/button-refetch.tsx +160 -0
  394. package/docs/query/data-state.tsx +192 -0
  395. package/docs/query/infinite-query-state.tsx +93 -0
  396. package/docs/query/mutation-feedback.tsx +70 -0
  397. package/docs/query/prefetch-link.tsx +262 -0
  398. package/docs/query/touch-actions.tsx +68 -0
  399. package/docs/showcase/acme-portal.tsx +441 -0
  400. package/docs/showcase/acme-website.tsx +455 -0
  401. package/docs/showcase/case1-warehouse-dashboard.tsx +343 -0
  402. package/docs/showcase/case2-employee-me.tsx +441 -0
  403. package/docs/showcase/case3-approval-workflow.tsx +527 -0
  404. package/docs/showcase/case4-login.tsx +307 -0
  405. package/docs/showcase/case5-shift-calendar.tsx +795 -0
  406. package/docs/showcase/case6-agency-handy.tsx +1072 -0
  407. package/docs/showcase/futurelastic-web.tsx +390 -0
  408. package/docs/showcase/org-switcher.tsx +313 -0
  409. package/docs/showcase/permission-matrix.tsx +343 -0
  410. package/docs/showcase/public-landing.tsx +210 -0
  411. package/docs/showcase/settings-account-sections.tsx +559 -0
  412. package/docs/showcase/settings-security-mfa.tsx +145 -0
  413. package/docs/showcase/table-approval-queue.tsx +199 -0
  414. package/docs/showcase/table-bulk-actions.tsx +460 -0
  415. package/docs/showcase/table-compact-kintone.tsx +438 -0
  416. package/docs/showcase/table-conditional-format.tsx +367 -0
  417. package/docs/showcase/table-crud-list.tsx +544 -0
  418. package/docs/showcase/table-density.tsx +340 -0
  419. package/docs/showcase/table-expandable-rows.tsx +471 -0
  420. package/docs/showcase/table-filter-chips.tsx +461 -0
  421. package/docs/showcase/table-footer-totals.tsx +311 -0
  422. package/docs/showcase/table-grouped-subtotals.tsx +388 -0
  423. package/docs/showcase/table-master-detail.tsx +479 -0
  424. package/docs/showcase/table-pagination.tsx +320 -0
  425. package/docs/showcase/table-states.tsx +363 -0
  426. package/docs/showcase/table-sticky-columns.tsx +373 -0
  427. package/docs/showcase/table-tree-rows.tsx +444 -0
  428. package/docs/showcase/table-view-tabs.tsx +488 -0
  429. package/package.json +9 -11
  430. package/scripts/_agent-setup.mjs +16 -2
  431. package/scripts/audit-hook.mjs +3 -13
  432. package/scripts/init-agent-kit.mjs +1 -14
  433. package/scripts/postinstall.mjs +12 -12
  434. package/scripts/ui-audit.mjs +93 -31
  435. package/scripts/visual-audit-rules.mjs +51 -7
  436. package/scripts/visual-audit.mjs +118 -47
@@ -1,259 +1,85 @@
1
- /* Layout primitive tokens: page, section, stack, inline. */
1
+
2
2
 
3
3
  :root {
4
- /* Semantic spacing — ONE coherent 4px grid (Tailwind/Material/Ant standard). All steps reference
5
- * the linear `--space-*` scale (NOT the golden φ scale — golden ratio is for modular SIZE scales
6
- * like type/radius, not the spacing grid; mixing the two left an incoherent density rhythm). The
7
- * φ tokens remain available as an optional golden-layout utility, just not the spacing baseline. */
8
- --space-page-x: var(--space-6); /* 24px — page gutter */
9
- --space-page-y: var(--space-6); /* 24px */
10
- --space-section: var(--space-4); /* 16px */
11
- --space-stack-xs: var(--space-1); /* 4px */
12
- --space-stack-sm: var(--space-2); /* 8px */
13
- --space-stack-md: var(--space-4); /* 16px */
14
- --space-stack-lg: var(--space-6); /* 24px */
15
- --space-stack-xl: var(--space-10); /* 40px */
16
- --space-inline-xs: var(--space-1); /* 4px */
17
- --space-inline-sm: var(--space-2); /* 8px */
18
- --space-inline-md: var(--space-3); /* 12px */
19
- --space-inline-lg: var(--space-4); /* 16px */
20
4
 
21
- /* OVERLAY STACKING — one system-level layer for every portaled surface (rule #44/#45).
22
- * Tooltip, Popover, Select, DropdownMenu and Sheet all hard-coded `z-50` independently, so a
23
- * host app that mounts @godxjp/ui under its own stacking context (a sticky masthead, a
24
- * third-party chat widget) had to fight five separate literals. Stacking is a SYSTEM decision,
25
- * not a per-primitive one: a service raises every overlay together by setting this once. */
5
+ --space-page-x: var(--space-6);
6
+ --space-page-y: var(--space-6);
7
+ --space-section: var(--space-4);
8
+ --space-stack-xs: var(--space-1);
9
+ --space-stack-sm: var(--space-2);
10
+ --space-stack-md: var(--space-4);
11
+ --space-stack-lg: var(--space-6);
12
+ --space-stack-xl: var(--space-10);
13
+ --space-inline-xs: var(--space-1);
14
+ --space-inline-sm: var(--space-2);
15
+ --space-inline-md: var(--space-3);
16
+ --space-inline-lg: var(--space-4);
17
+
26
18
  --overlay-z-index: 50;
27
19
 
28
- /* Master-detail geometry. Consumers choose a semantic rail preset; they never author grid tracks. */
29
- --master-detail-rail-compact: 18.75rem; /* 300px */
30
- --master-detail-rail-standard: 20rem; /* 320px */
20
+ --master-detail-rail-compact: 18.75rem;
21
+ --master-detail-rail-standard: 20rem;
31
22
  --master-detail-gap: var(--space-stack-md);
32
- /* The collapse threshold: MasterDetail keeps its two-track split while the composition's OWN
33
- * inline size is at least this wide, and stacks (master then detail) below it. A service theme
34
- * retunes it once globally; the `collapseBelow` prop overrides it per instance (rule #45).
35
- * This is a real knob — the layout reads it through the flex-basis threshold, NOT a media
36
- * query, precisely so a `var()` can drive it (see src/styles/layout.css · .ui-master-detail). */
37
- --master-detail-collapse-below: 40rem; /* 640px — the `sm` step */
38
23
 
39
- /* Bounded master viewport (gh#231). OPT-IN, chosen by the semantic `masterViewport` prop —
40
- * `auto` (the default) applies NO bound, so every existing composition is unchanged. A real
41
- * collection can be thousands of pixels tall; when the layout stacks, that pushes the detail
42
- * far below the fold. The presets cap the collection's BLOCK size and scroll it inside the
43
- * region instead. Sized as a whole number of nominal collection rows (2.5rem ≈ a compact list
44
- * row) so a service theme retunes them in the same semantic unit the design grid uses. */
45
- --master-detail-master-viewport-compact: 20rem; /* 320px — about 8 nominal rows */
46
- --master-detail-master-viewport-standard: 28rem; /* 448px — about 11 nominal rows */
47
- /* Focus-ring room INSIDE the bounded region: an overflow container clips both axes, so without
48
- * an inset the ring of a row at the edge would be cut off (WCAG 2.4.11/2.4.13). Doubles as the
49
- * scroll-padding so a row scrolled into view never sits flush against the clip edge. */
50
- --master-detail-master-viewport-inset: var(--space-1); /* 4px */
24
+ --master-detail-collapse-below: 40rem;
25
+
26
+ --master-detail-master-viewport-compact: 20rem;
27
+ --master-detail-master-viewport-standard: 28rem;
28
+
29
+ --master-detail-master-viewport-inset: var(--space-1);
51
30
 
52
31
  --space-page-active-x: var(--space-page-x);
53
32
  --space-page-active-y: var(--space-page-y);
54
33
  --space-section-active: var(--space-section);
55
- --space-page-compact-x: var(--space-4); /* 16px mobile page gutter */
34
+ --space-page-compact-x: var(--space-4);
56
35
  --space-page-compact-y: var(--space-4);
57
36
  --space-section-compact: var(--space-4);
58
37
 
59
- /* Modal scrim — the single backdrop colour shared by EVERY overlay (Dialog, AlertDialog, Sheet,
60
- * Drawer, AppShell mobile nav). Themeable (rule #44) so a service tints the wash to its brand
61
- * once, e.g. a navy `--overlay-background: rgb(12 26 49 / .55)`, instead of forking each overlay.
62
- *
63
- * HOW IT REACHES AN OVERLAY (gh#215 — it previously reached NOTHING): each surface declares its
64
- * own knob `initial` and resolves a SHARE of this colour at the call site,
65
- * `var(--dialog-overlay-background, color-mix(in srgb, var(--overlay-background)
66
- * var(--dialog-overlay-alpha), transparent))`. That keeps the calibrated per-surface depth — a
67
- * slide-in Sheet washes the page more lightly (40%) than a modal Dialog (60%) — while ONE
68
- * override here retints every backdrop. Per docs/TOKENS.md the knobs must stay `initial`: a
69
- * `:root` binding would freeze and a scoped `[data-tenant]`/`.dark` override of this token would
70
- * never reach the overlay. Overlays are portaled, so a tenant scope must also sit on the portal
71
- * container (see docs/CUSTOMER-THEMING.md). */
72
38
  --overlay-background: rgb(0 0 0 / 0.5);
73
39
 
74
- /* Full-bleed rule under the PageContainer header. OFF by default — the title/body
75
- * gap already separates them; a divider is a service-theme opt-in:
76
- * `--page-header-divider: 1px solid hsl(var(--border));` */
40
+ --page-footer-pad-block-end: var(--space-stack-md);
77
41
  --page-header-divider: none;
78
42
 
79
- /* PageContainer `toolbar` — the fixed chrome band between the header and the (scrolling) body.
80
- * ALL THREE knobs are quiet by default (rule #44):
81
- * background — `transparent`, i.e. the band shows the page ground exactly as it did before
82
- * the knob existed. It is bound at `:root` and NOT `initial`, unlike the
83
- * divider below, because the default is a plain CSS keyword rather than
84
- * another role token: there is nothing for a scoped [data-tenant]/.dark
85
- * override to re-resolve, so the `initial` + call-site-fallback dance would
86
- * buy nothing and only hide the default from anyone reading this file. A
87
- * service that wants the band to read as its own surface — the design that
88
- * asked for this knob puts a chat channel's workflow rail on the card ground —
89
- * sets `--page-toolbar-background: hsl(var(--card));` ONCE in its theme. Never
90
- * `className="bg-card"` at the call site: that is hand-laid page chrome, it
91
- * paints only under `variant="flush"` gutters correctly by accident, and it
92
- * cannot be re-themed per tenant.
93
- * pad-block 0 — the band's ONLY breathing room, and the only one it should ever have. The
94
- * band is chrome, so it sits FLUSH against the header above and the body
95
- * below (src/styles/layout.css cancels the container's --page-band-gap from
96
- * the band itself); there is deliberately no outside space to tune, because a
97
- * ruled, painted band floating in a void divides nothing. A service that opts
98
- * into the background or the divider gives the band its inset HERE
99
- * (`--page-toolbar-pad-block: var(--space-2)`) instead of padding the strip at
100
- * the call site. Still 0 by default: a transparent band is not a surface and
101
- * has no inside to breathe, and under `fill` every pixel of it comes straight
102
- * off the scroll viewport the slot exists to protect.
103
- * divider — declared `initial` so the CALL SITE can fall back to --page-header-divider
104
- * (`var(--page-toolbar-divider, var(--page-header-divider))`). One theme
105
- * declaration therefore rules the whole page chrome consistently, and a
106
- * scoped [data-tenant]/.dark override of the header divider still reaches the
107
- * band — a `:root` binding would freeze it at the :root value
108
- * (docs/TOKENS.md · "Role-mirror knobs MUST be `initial`"). Set
109
- * `--page-toolbar-divider: none` to silence just this band. */
110
43
  --page-toolbar-background: transparent;
111
44
  --page-toolbar-pad-block: 0px;
112
45
  --page-toolbar-divider: initial;
113
46
 
114
- /* Top rule of the PageContainer `footer` — the third page chrome band, brought onto the same
115
- * contract as the header and the toolbar (its rule used to be a hard literal in layout.css, so
116
- * a page could not turn it off at all). Declared `initial` like the toolbar's, so the CALL SITE
117
- * resolves it as `var(--page-footer-divider, 1px solid hsl(var(--border)))` and a scoped
118
- * [data-tenant]/.dark override still reaches it (docs/TOKENS.md · "Role-mirror knobs MUST be
119
- * `initial`").
120
- *
121
- * It is the ONE chrome knob whose default is a RULE rather than silence, and deliberately so:
122
- * `footer` is the shared slot a form's Save/Cancel bar lands in, where the line separating the
123
- * actions from the page content is the behaviour every existing page already depends on. The
124
- * old literal is the fallback verbatim, so unset is byte-identical. A page whose footer content
125
- * already carries its own frame — a chat composer is a bordered Card — silences the duplicate
126
- * with `--page-footer-divider: none`. */
127
47
  --page-footer-divider: initial;
128
48
 
129
- /* Bottom inset of the page header, sized so title→body distance (this pad + the
130
- * --space-section-active container gap) EQUALS the page's top padding — the title
131
- * band reads vertically balanced (24 above / 24 below by default), instead of the
132
- * old fixed 16px pad that left 24 above vs 32 below. A page that passes a `toolbar`
133
- * measures title→BAND instead (this pad alone, the gap being cancelled): the band is
134
- * chrome attached to the header, not the next section down. */
135
49
  --page-header-pad-bottom: calc(var(--space-page-active-y) - var(--space-section-active));
136
50
 
137
- /* Inline measure of the header `extra` region while the page header is in `responsive-inline`
138
- * arrangement (gh#231). Below the 640px step the default arrangement drops `extra` onto its own
139
- * full-width line under the subtitle; `headerLayout="responsive-inline"` keeps it beside the
140
- * title band at this measure instead, so a single compact control (a search field, one primary
141
- * action) stays on the title row at 390px. Unused by the default arrangement, so no existing
142
- * page moves. 11rem = 176px, i.e. the control ends flush with the compact page gutter. */
143
- --page-header-extra-measure: 11rem; /* 176px */
51
+ --page-header-extra-measure: 11rem;
144
52
 
145
- /* Gap between the page title and its status/meta band (PageContainer `status`,
146
- * godxjp-ui#255), and between the band's own items. One knob aligns the badge row
147
- * to a service's grid; a page that never passes `status` reads neither the token
148
- * nor the wrapping row. */
149
53
  --page-header-status-gap: var(--space-inline-sm);
150
54
 
151
- /* PageContainer `headerLoading` placeholders (gh#255). The title/subtitle elements wear the
152
- * shared `.ui-skeleton-block` skin, so they need only a MEASURE and a block size — a service
153
- * retunes the pending band's proportions here instead of per page. */
154
- --page-title-placeholder-measure: 14rem; /* 224px */
55
+ --page-title-placeholder-measure: 14rem;
155
56
  --page-title-placeholder-block-size: 1.5em;
156
- --page-subtitle-placeholder-measure: 22rem; /* 352px */
57
+ --page-subtitle-placeholder-measure: 22rem;
157
58
  --page-subtitle-placeholder-block-size: 1.25em;
158
59
 
159
- /* Bounded page MEASURE (gh#245 / gh#247) — the shared inline cap applied to the page HEADER and
160
- * BODY together, so the header `extra` action ends on the same edge as the body surface (the
161
- * `variant="narrow"` complaint: it caps only `.ui-page-body`, leaving the header action out at
162
- * the page edge). Selected by the semantic `measure` prop; `measure="default"` reads NEITHER
163
- * token, so an existing page is untouched.
164
- *
165
- * These are OUTER measures: the page gutters (--space-page-active-x, 24px each side by default)
166
- * live INSIDE the cap, so the VISIBLE surface is the measure minus both gutters:
167
- * narrow 42rem = 672px → 624px visible surface (the historical variant="narrow" body width)
168
- * medium 48rem = 768px → 720px visible surface (the canonical readable/feed measure)
169
- * Below the cap nothing binds, so a 390px viewport stays fluid at the 16px compact gutter
170
- * (358px surface). A service theme retunes both in ONE place; never a page-local max-width. */
171
- --page-measure-narrow: 42rem; /* 672px outer → 624px surface */
172
- --page-measure-medium: 48rem; /* 768px outer → 720px surface */
60
+ --page-measure-narrow: 42rem;
61
+ --page-measure-medium: 48rem;
173
62
 
174
- /* Responsive page typography is independent from density. Density changes information spacing;
175
- * these tokens change only page chrome so mobile keeps readable body text and touch targets. */
176
63
  --page-title-font-size: var(--heading-h1);
177
64
  --page-title-font-size-compact: var(--heading-h2);
178
65
  --page-subtitle-font-size: var(--font-size-base);
179
66
  --page-subtitle-font-size-compact: var(--font-size-sm);
180
67
 
181
- /* PageContainer `headerScale="chrome"` — the title step for a page whose top row IS CHROME
182
- * rather than a document title: a chat channel name, a mail subject line, an IDE tab. It is a
183
- * SEPARATE knob from the two above on purpose: those are ONE document title at two viewport
184
- * sizes (a responsive step), while this is a different KIND of page and holds at every width.
185
- * `--heading-h3` (= --font-size-base, 14px) is the body step, which is the point — the row
186
- * reads as a label ON the surface, not as the page's headline, and the header band collapses
187
- * from the measured 61px to ~40px once it stops carrying a 20px h1. Quiet by default: a page
188
- * that never passes `headerScale` never reads this token (rule #44). */
189
68
  --page-title-font-size-chrome: var(--heading-h3);
190
69
 
191
- /* The SUBTITLE step of the same fact. Measured against the reference chat screen, the chrome
192
- * title and the chrome subtitle were rendering at the SAME step (both --font-size-base), which
193
- * is not a hierarchy — a channel name and the channel's purpose line read as one undifferentiated
194
- * block. The design puts the purpose line two steps down (`Text size="2xs"`), and the size is
195
- * what carries the LINE BOX: at 14px/1.7 the subtitle line is 23.8px tall, at 11px/1.7 it is
196
- * 18.9px, so the whole header band loses ~5px it was spending on a caption. `--font-size-2xs`
197
- * (ratio⁻², ≈11px) is that step, and it is the same golden scale the title step reads — never a
198
- * literal. Quiet by default: a page that never passes `headerScale` never resolves it (#44). */
199
70
  --page-subtitle-font-size-chrome: var(--font-size-2xs);
200
71
 
201
- /* The page's TOP inset under `headerScale="chrome"`, the second half of the same fact: chrome
202
- * sits on the frame's edge. A document page opens with --space-page-active-y (24px, 16px below
203
- * the 720px step) because a title needs air above it; a chat channel head, a mail subject bar or
204
- * an IDE tab strip is the frame itself, and 24px of margin above it reads as a page floating
205
- * inside its own shell — measured on a consumer chat screen as 24px lost off the top of the
206
- * transcript viewport, against a design whose channel head starts at y=0. 0 is therefore the
207
- * quiet default (rule #44), and it is a knob rather than a literal so a service whose grid wants
208
- * its chrome inset (`--page-pad-block-start-chrome: var(--space-2)`) retunes it once instead of
209
- * forking the page shell. Read ONLY when the prop is passed, so no document page resolves it. */
210
72
  --page-pad-block-start-chrome: 0px;
211
73
 
212
- /* The BAND HEIGHT of the same fact (gh#331). A document header is content-height by definition —
213
- * a title is as tall as the title is. A chrome band is the opposite: it is furniture, and
214
- * furniture has a height that things centre INTO. `AppShell` has had `--app-shell-bar-height`
215
- * for exactly that since it shipped; `PageContainer` had no equivalent, so a `headerScale="chrome"`
216
- * band's vertical centre drifted with its own copy — measured in Chromium on
217
- * /isolate/layout-page-container, 42.02px with an `extra` control and 40.38px without, i.e. the
218
- * centre moves 0.8px for a change of content and there is no value a service can aim at.
219
- *
220
- * WHO OWNS THE BAND-HEIGHT AXIS (the question gh#331 defers to gh#330). `--app-shell-bar-height`
221
- * does: it is the system's one declared chrome-band height, and `--centered-shell-bar-height`
222
- * already reads it. A service that wants its page chrome to sit on the shell bar's band writes
223
- * ONE line — `--page-header-min-block-size-chrome: var(--app-shell-bar-height)` — and the two
224
- * bands are on one axis for good.
225
- *
226
- * It is NOT that value by DEFAULT, and the reason is not timidity: a `PageContainer` with a
227
- * chrome header is not necessarily inside an `AppShell` (the canonical chat composition renders
228
- * one inside a bordered region, a SplitPane pane, a Card), and a band that is not trying to line
229
- * up with a bar has no business inheriting that bar's height. `auto` is the quiet state (rule
230
- * #44): no floor, content-height, byte-identical to every page rendered before this token
231
- * existed — document AND chrome.
232
- *
233
- * A MIN, never a fixed height: a taller `extra` (an `lg` control, a wrapped JA/VI channel name)
234
- * must still fit rather than overflow its own band. The header centres its content in whatever
235
- * band it ends up with — see `justify-content` in styles/layout.css — so raising this knob
236
- * centres, it does not top-pack. The header's own `--page-header-pad-bottom` lives INSIDE the
237
- * band (border-box); under the canonical chrome composition (`variant="ghost"`) that pad is 0
238
- * and the centring is exact. */
239
74
  --page-header-min-block-size-chrome: auto;
240
75
 
241
- /* Section "chrome" padding — the SHARED inset for header / body / footer of every overlay-ish
242
- * surface (Dialog · Sheet · Drawer · Card). One global knob: a service sets these once instead of
243
- * per-component. Vertical is tightened (16 vs the old 24) and density-aware (see density.css);
244
- * horizontal stays 24 (Ant standard). Per-component tokens (--sheet-pad-*, --dialog-space-inset…)
245
- * default to these and only override when a surface genuinely needs to differ. */
246
- --space-chrome-x: var(--space-6); /* 24px — horizontal inset */
247
- --space-chrome-y: var(--space-4); /* 16px — vertical inset (header/footer/body) */
248
- --space-chrome-gap: var(--space-stack-sm); /* gap between header ↔ body ↔ footer */
76
+ --space-chrome-x: var(--space-6);
77
+ --space-chrome-y: var(--space-4);
78
+ --space-chrome-gap: var(--space-stack-sm);
249
79
 
250
- /* The ONE vertical gap between a field's LABEL and its CONTENT — same everywhere a label sits above
251
- * a control or a value (FormField, Descriptions, Form, any label-above stack). Single source so the
252
- * whole system stays in sync (gh feedback: Descriptions was ~0px while FormField was 8px). */
253
- --field-label-gap: var(--space-2); /* 8px */
80
+ --field-label-gap: var(--space-2);
254
81
  }
255
82
 
256
- /* Canonical admin collection composition. Services may retune these semantic knobs once. */
257
83
  :root {
258
84
  --admin-collection-control-height: var(--control-height-default);
259
85
  --admin-collection-section-gap: var(--space-stack-md);
@@ -0,0 +1,206 @@
1
+ # Canonical contracts — the answer to "does @godxjp/ui have an X?"
2
+
3
+ A consumer design spec names a component (`PageHeader`, `Banner`, `SocialLinks`, `OrganizationChoiceList`, `ServiceRolePanel`, `BranchScopePicker`, `PermissionMatrix`, `FilterBar`).
4
+
5
+ ---
6
+
7
+ ## 1. `PageHeader` — **`PageContainer`'s embedded header IS the DXS PageHeader** (gh#255)
8
+
9
+ ```ts
10
+ import { PageContainer, type PageContainerProps } from "@godxjp/ui/layout";
11
+ ```
12
+
13
+ There is **no standalone `PageHeader` export**. The canonical page title band — breadcrumbs · `<h1>` · subtitle · status/meta (`status`) · actions (`extra`) — lives on **one renderer**: `PageContainer`'s embedded header, with `headerLayout` (`stack` | `responsive-inline`), `breadcrumbLabel` (the landmark-unique override), `measure` and `headerLoading` (skeleton title band + `aria-busy`, keeping the `<h1>` in the document with an sr-only name so the heading outline never disappears mid-load).
14
+
15
+ **Why one renderer rather than a lifted export.** The band's geometry is token-owned (`.ui-page-header`, `--page-header-status-gap`, the placeholder measures) and every page mounts it through `PageContainer`, so a second mount point would be a second `<h1>` waiting to happen. A title band outside a full page shell (a Sheet detail, a `MasterDetail` pane, a tab body) is a COMPOSITION of `Breadcrumb` + heading text + `Flex` at section level — it should NOT be an `<h1>`.
16
+
17
+ | Situation | Use |
18
+ | -------------------------------------------- | ------------------------------------------------------------------------- |
19
+ | The surface **is a page** | `PageContainer` (`title`/`subtitle`/`status`/`extra`/`breadcrumb`) |
20
+ | A title band **inside** a pane/sheet/tab | Compose at section level — never a second `<h1>` / `PageContainer` header |
21
+ | The user **may not see the resource at all** | `ErrorSurface` — never a header that leaks the resource's name |
22
+
23
+ `denied` / `error` are deliberately **not** states of the band — see the table above.
24
+
25
+ ---
26
+
27
+ ## 2. `Banner` — **EXPORTED** as the page-level `Alert` (gh#255)
28
+
29
+ ```ts
30
+ import { Banner, type BannerProps } from "@godxjp/ui/feedback";
31
+ ```
32
+
33
+ Same tones, same icon defaults, same assertive/polite role split, same actions grid, same dismiss control. `Banner.Title` **is** `AlertTitle` — the same element, not a parallel family.
34
+
35
+ It is an alias, not a second implementation, for the same reason `FilterBar` is an alias of `Toolbar`: a banner and an inline alert are one object at two measures, and duplicating the tone mapping and dismiss behaviour is exactly what the no-duplication rule forbids.
36
+
37
+ | Scope of the message | Use |
38
+ | --------------------------------------------------------------------- | ------------------------------------------- |
39
+ | The page or the whole app (maintenance, trial expiry, read-only mode) | `Banner` above the header, or in `AppShell` |
40
+ | One section / card / form | `Alert` inside that section |
41
+ | One field | `FormField` `error` |
42
+ | Transient ("saved") | `toast()` |
43
+ | The user may not see the page at all | `ErrorSurface` |
44
+
45
+ Retheme through tokens, never a wrapper class: `--banner-radius`, `--banner-border-width`, `--banner-border-block-end-width`, `--banner-space-block`, `--banner-space-inline`, `--banner-dismiss-space-offset`. Never stack two banners.
46
+
47
+ ---
48
+
49
+ ## 3. `AuthShell preset="registration"` — **EXPORTED** (gh#256)
50
+
51
+ ```tsx
52
+ <AuthShell variant="canonical" preset="registration" brand={…} footer={…}>
53
+ ```
54
+
55
+ The 360px sign-up measure with a 15px inline gutter at 390px — the same page rhythm as `preset="login"`, so sign-in → sign-up never jumps on a phone. It carries the full password form **and** the pending-email confirmation state with no consumer geometry CSS.
56
+
57
+ Two things make it structurally distinct from every other preset, and both are load-bearing:
58
+
59
+ 1. **It is the only START-aligned preset.** A sign-up card is the tallest surface in the hosted-identity set (name · email · password · confirm · strength · consent · submit · providers). A vertically _centred_ tall card overflows **above the scroll origin** on a short viewport, putting its first field permanently out of reach. 2. **It is the only preset with its own footer-clearance knob**, so the legal/consent footer never sits flush against the submit button at the end of a long scroll.
60
+
61
+ Geometry knobs: `--auth-shell-registration-{card-max-width, main-padding-block-start, main-padding-block-start-mobile, main-padding-inline, main-padding-inline-mobile, main-padding-block-end, main-padding-block-end-mobile, card-stack-gap}`.
62
+
63
+ Worked screen: `docs/layout/auth-shell-registration.tsx`.
64
+
65
+ ---
66
+
67
+ ## 4. `SocialLinks` — **COMPOSE** (gh#256)
68
+
69
+ There is no `SocialLinks` component, and none is planned.
70
+
71
+ ```tsx
72
+ <AuthDivider label="または" />
73
+ <Flex direction="col" gap="sm">
74
+ {providers.map((p) => (
75
+ <Button key={p.id} variant="outline" disabled={submitting} onClick={p.start}>
76
+ <p.Icon aria-hidden="true" />
77
+ {p.label}
78
+ </Button>
79
+ ))}
80
+ </Flex>
81
+ ```
82
+
83
+ **Why.** It owns no behaviour: each provider is a plain action the app points at its own OAuth start URL. A framework component would have to invent _which_ providers a product offers, in what order, and what consent they imply — product decisions the package must not make. `disabled` and `loading` are the `Button`'s own props; there is no provider-specific API to learn.
84
+
85
+ ---
86
+
87
+ ## 5. `OrganizationChoiceList` — **COMPOSE** (gh#256)
88
+
89
+ ```tsx
90
+ <Card>
91
+ <CardHeader>…</CardHeader>
92
+ <CardContent flush>
93
+ <ul>
94
+ {orgs.map((org) => (
95
+ <ListRow
96
+ as="li"
97
+ key={org.id}
98
+ leading={<Avatar>…</Avatar>}
99
+ title={org.name}
100
+ description={org.role}
101
+ trailing={
102
+ <Button variant="ghost" size="sm">
103
+ 選択
104
+ </Button>
105
+ }
106
+ />
107
+ ))}
108
+ </ul>
109
+ </CardContent>
110
+ </Card>
111
+ ```
112
+
113
+ `CardContent flush` is what produces shared row dividers instead of a card outline per row.
114
+
115
+ States — all existing exports, no bespoke markup:
116
+
117
+ | State | Use |
118
+ | ----------------- | -------------------------------------------------------- |
119
+ | loading | `Skeleton` rows at the settled row height |
120
+ | empty | `EmptyState` |
121
+ | error | `Alert tone="destructive"` + a retry action |
122
+ | permission-denied | `Alert tone="warning"` (section) / `ErrorSurface` (page) |
123
+ | disabled row | the row's own `Button disabled` |
124
+
125
+ Worked screens: `docs/layout/auth-shell-context.tsx`, `docs/layout/auth-shell-registration.tsx`.
126
+
127
+ ---
128
+
129
+ ## 6. `ServiceRolePanel` · `BranchScopePicker` · `PermissionMatrix` — **EXPORTED** (gh#257)
130
+
131
+ All three compositions were promoted to public exports — the composition-first Gate 0 verdict was revisited when consumers kept re-authoring the same states and geometry:
132
+
133
+ ```ts
134
+ import { ServiceRolePanel } from "@godxjp/ui/layout";
135
+ import { BranchScopePicker } from "@godxjp/ui/data-entry";
136
+ import { PermissionMatrix } from "@godxjp/ui/data-display";
137
+ ```
138
+
139
+ ```ts
140
+ import {
141
+ grantKey,
142
+ hasGrant,
143
+ rolesDifferOnPermission,
144
+ visibleRows,
145
+ countGrants,
146
+ countDifferences,
147
+ } from "@godxjp/ui/lib/permission-grid";
148
+ ```
149
+
150
+ Layout the role list beside the editor with `MasterDetail` — it owns the tracks, the gap and the stacking threshold as tokens, so the page carries no `grid-template-columns` and no media query at 1440 / 1024 / 390. Destructive changes go through `AlertDialog variant="destructive"` (add `challenge` for type-to-confirm).
151
+
152
+ Worked screens: `docs/layout/service-role-panel.tsx`, `docs/data-entry/branch-scope-picker.tsx`, `docs/data-display/permission-matrix.tsx`, `docs/showcase/permission-matrix.tsx`.
153
+
154
+ ---
155
+
156
+ ## 7. `FilterBar` — **EXPORTED, and now typed** (gh#258)
157
+
158
+ `FilterBar` / `FilterBarGroup` remain the public domain-neutral names for the `Toolbar` primitives.
159
+
160
+ ```tsx
161
+ <FilterBar
162
+ search={{ value: q, onValueChange: setQ, placeholder: "Search records" }}
163
+ filters={[
164
+ {
165
+ value: "status",
166
+ label: "状態",
167
+ options: STATUS_OPTIONS,
168
+ selected: status,
169
+ onSelectedChange: setStatus,
170
+ },
171
+ ]}
172
+ chips={applied.map((f) => ({ value: f.value, label: f.label }))}
173
+ onChipRemove={lift}
174
+ resultCount={rows.length}
175
+ onClear={clearAll}
176
+ hasActiveFilters={applied.length > 0}
177
+ actions={
178
+ <Button variant="outline" size="sm">
179
+ エクスポート
180
+ </Button>
181
+ }
182
+ />
183
+ ```
184
+
185
+ **Order is the contract.** DOM order is tab order, and the **bar** decides it, not each page:
186
+
187
+ ```
188
+ search → typed filters → children (custom composition filters) → reset → actions
189
+ → applied-chips row → result-count / error line
190
+ ```
191
+
192
+ Reset sits before `actions` deliberately, so "clear filters" never lands at the end of the row beside an unrelated primary action.
193
+
194
+ What each prop buys that a plain child did not:
195
+
196
+ - **`search`** — the canonical `SearchInput` at one token-owned measure (`--filter-bar-search-width`) across every list page, full-width below the 640px step. Controlled through the `value`/`defaultValue`/`onValueChange` triad; `onSearch` mirrors the debounced-term callback. - **`filters`** — labelled, domain-neutral `Select` filters whose visible `label` is the control's real `<label htmlFor>` (WCAG 2.5.3 / 1.3.1), at the `--filter-bar-filter-width` measure. - **`chips`** — the chip lifecycle: a labelled row, a remove control named after _that specific_ filter (a row of buttons all called "Remove" is unusable from a screen-reader's control list), and no row at all when nothing is applied. Remove = `onChipRemove(value)`; clear-all = `onClear`. - **`resultCount`** — a polite live region formatted with `Intl.NumberFormat` + CLDR plurals.
197
+
198
+ The bar still owns **no filter state**. `search`/`filters`/`chips` are rendered consumer data, `resultCount` is a number you computed. It owns placement, measure, ordering, keyboard order and announcement — nothing else.
199
+
200
+ Worked screen: `docs/navigation/filter-bar.tsx`.
201
+
202
+ ---
203
+
204
+ ## Adding to this document
205
+
206
+ Any future "does the package have an X?" answer belongs here, with: the Gate 0 verdict, the public-route question, and — for a composition — the exact primitives, the token knobs, and the state table. If the honest answer is "the consumer cannot reach it publicly", that is a package gap: fix the library, never patch the consumer app.