@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,18 +1,12 @@
1
- /*
2
- * DIALOG — overlay content shell (form + confirm modes share tokens).
3
- */
1
+
4
2
 
5
3
  @layer components {
6
- /* Sheet (side-panel, Radix Dialog) chrome padding — defaults to the shared global chrome tokens.
7
- * A service overrides --space-chrome-* once (whole system) or --sheet-pad-* for the Sheet only.
8
- * (Lives here because Sheet is Dialog-based and dialog-layout.css is in the main bundle.) */
4
+
9
5
  [data-slot="sheet-content"] {
10
6
  --sheet-pad-x: var(--space-chrome-x);
11
7
  --sheet-pad-y: var(--space-chrome-y);
12
8
  }
13
9
 
14
- /* Sheet header/footer dividers appear ONLY when a SheetBody is present (mirrors the dialog rule) —
15
- * a body-less sheet never shows a doubled header-bottom + footer-top line. */
16
10
  [data-slot="sheet-content"]:has([data-slot="sheet-body"]) [data-slot="sheet-header"] {
17
11
  border-bottom: 1px solid hsl(var(--border));
18
12
  }
@@ -21,10 +15,6 @@
21
15
  border-top: 1px solid hsl(var(--border));
22
16
  }
23
17
 
24
- /* Scrim = a SHARE of the ONE shared semantic scrim (--overlay-background), resolved here at the
25
- * call site so a scoped [data-tenant]/.dark override of --overlay-background actually reaches the
26
- * portaled overlay (docs/TOKENS.md · "Role-mirror knobs MUST be `initial`"). Setting
27
- * --dialog-overlay-background / --sheet-overlay-background still wins outright. */
28
18
  .ui-dialog-overlay {
29
19
  background-color: var(
30
20
  --dialog-overlay-background,
@@ -39,10 +29,6 @@
39
29
  );
40
30
  }
41
31
 
42
- /* Stacking joins the ONE system layer (--overlay-z-index) instead of a private z-50 — Sheet,
43
- * Tooltip and Popover already do, so a service that lifts its overlays above an app-owned
44
- * fixed element no longer has to fork the dialog to bring it along. Default is 50, the literal
45
- * this replaces. */
46
32
  .ui-dialog-overlay {
47
33
  position: fixed;
48
34
  inset: 0;
@@ -62,7 +48,7 @@
62
48
  border: 1px solid hsl(var(--border));
63
49
  background-color: hsl(var(--background));
64
50
  padding: var(--dialog-space-inset);
65
- /* clip so the full-bleed header/footer bands round with the dialog corners (Ant Modal). */
51
+
66
52
  overflow: hidden;
67
53
  box-shadow: var(--shadow-lg, 0 10px 15px -3px rgb(0 0 0 / 0.1)), var(--dialog-content-glow);
68
54
  }
@@ -73,9 +59,6 @@
73
59
  }
74
60
  }
75
61
 
76
- /* Ring-safe scrollable body for a tall dialog. Full-bleed inset (matches the dialog padding) so a
77
- * full-width control's 3px focus ring never clips against the scroll container's computed
78
- * overflow-x; padding-block keeps the ring visible at the scroll edges. Mirrors SheetBody. */
79
62
  [data-slot="dialog-body"] {
80
63
  min-height: 0;
81
64
  max-height: min(60vh, 32rem);
@@ -86,9 +69,6 @@
86
69
  scroll-padding-block: var(--space-1);
87
70
  }
88
71
 
89
- /* Header & footer are PLAIN stacked sections by default — the dialog padding gives the inset and the
90
- * content `gap` gives the header↔footer spacing. No border band here, so a simple confirm dialog
91
- * (header + footer, NO body) never shows an internal divider or a doubled line + padding. */
92
72
  [data-slot="dialog-header"] {
93
73
  display: flex;
94
74
  flex-direction: column;
@@ -96,17 +76,12 @@
96
76
  text-align: start;
97
77
  }
98
78
 
99
- /* DIALOG chrome rhythm — the exact mirror of the `.ui-sheet-*` set at the foot of this file.
100
- * Dialog's default header markup is byte-identical to Sheet's, but its gaps were literal on the
101
- * component (`gap-[var(--space-3)] pe-[var(--space-8)]`, `min-w-0 flex-col gap-[var(--space-1)]`,
102
- * `shrink-0 gap-[var(--space-2)]`), so the two siblings could not be retuned together (#319). */
103
79
  .ui-dialog-title-row {
104
80
  display: flex;
105
81
  align-items: flex-start;
106
82
  justify-content: space-between;
107
83
  gap: var(--dialog-title-row-space-gap);
108
- /* Reserves inline room for the absolutely-positioned close button so a long title or the extra
109
- * slot never runs under it. Moves with --dialog-close-space-offset. */
84
+
110
85
  padding-inline-end: var(--dialog-header-close-space-inline-end);
111
86
  }
112
87
 
@@ -125,14 +100,11 @@
125
100
  white-space: nowrap;
126
101
  }
127
102
 
128
- /* Close glyph — mirrors `.ui-sheet-close-icon`, so both overlay ✕ marks follow the one control
129
- * affix size instead of a per-component `size-4`. */
130
103
  .ui-dialog-close-icon {
131
104
  inline-size: var(--control-affix-icon-size);
132
105
  block-size: var(--control-affix-icon-size);
133
106
  }
134
107
 
135
- /* Type-to-confirm challenge: the step-up failure line under the input. */
136
108
  .ui-dialog-step-up-error {
137
109
  font-size: var(--dialog-step-up-error-font-size);
138
110
  color: hsl(var(--destructive));
@@ -151,9 +123,6 @@
151
123
  }
152
124
  }
153
125
 
154
- /* Scrollable-body layout (Ant Modal): ONLY when a body is present do header & footer become
155
- * full-bleed pinned bands with a divider, so the body scrolls between two fixed bars. Without a
156
- * body the dividers (and their band padding) collapse — fixes the double-border + oversized gap. */
157
126
  [data-slot="dialog-content"]:has([data-slot="dialog-body"]) [data-slot="dialog-header"] {
158
127
  margin-inline: calc(-1 * var(--dialog-space-x));
159
128
  margin-block-start: calc(-1 * var(--dialog-space-y));
@@ -197,10 +166,6 @@
197
166
  max-width: 27.5rem;
198
167
  }
199
168
 
200
- /* No scrim override here: the two-factor dialog's backdrop is the SHARED overlay scrim
201
- * (.ui-dialog-overlay above). The old literal `rgb(0 0 0 / 0.3)` re-stated the dialog default at a
202
- * higher specificity and silently opted this one dialog out of --overlay-background theming. */
203
-
204
169
  .ui-two-factor-setup-enrollment,
205
170
  .ui-two-factor-setup-recovery {
206
171
  display: flex;
@@ -259,19 +224,6 @@
259
224
  }
260
225
  }
261
226
 
262
- /*
263
- * REDUCED MOTION — every overlay enter/exit animation is gated (WCAG 2.3.3 Animation from
264
- * Interactions / 2.2.2 Pause-Stop-Hide). Dialog, AlertDialog, CommandPalette (a Dialog), Sheet /
265
- * mobile drawer and Popover all animate via Tailwind `data-[state]:animate-in|animate-out`
266
- * utilities plus a `transition`; the content additionally zooms/slides, which is exactly the
267
- * vestibular trigger the media query exists for. The overlay still fades in/out INSTANTLY, so the
268
- * open/closed state is never ambiguous — only the motion is removed, never the affordance.
269
- *
270
- * DELIBERATELY UNLAYERED. Tailwind v4 emits `animate-in` / `slide-in-from-*` into `@layer
271
- * utilities`, which beats ANY rule inside `@layer components` regardless of specificity — a gate
272
- * written inside the components layer above would be dead code. Unlayered author declarations win
273
- * over every layered one, so this block (and only this block) actually stops the animation.
274
- */
275
227
  @media (prefers-reduced-motion: reduce) {
276
228
  [data-slot="dialog-overlay"],
277
229
  [data-slot="dialog-content"],
@@ -286,16 +238,7 @@
286
238
  }
287
239
 
288
240
  @layer components {
289
- /* TOOLTIP / POPOVER — the two portaled overlay surfaces.
290
- *
291
- * Both shipped their entire box as Tailwind literals on the component
292
- * (`z-50 max-w-xs px-2 py-1 rounded-md text-xs shadow-md`, `w-72 p-4`), so a service
293
- * theme could not retune tooltip density, popover width, or overlay stacking without
294
- * forking the component — exactly the gap cardinal rule #45 exists to close.
295
- *
296
- * Colours read the popover ROLE at the call site (not bound at :root) so a scoped
297
- * [data-tenant]/.dark override still reaches the portaled node — docs/TOKENS.md ·
298
- * "Role-mirror knobs MUST be `initial`". */
241
+
299
242
  .ui-tooltip-content {
300
243
  z-index: var(--overlay-z-index);
301
244
  width: fit-content;
@@ -332,16 +275,12 @@
332
275
  }
333
276
 
334
277
  @layer components {
335
- /* SHEET chrome rhythm — --sheet-pad-x/-y already governed the panel inset; these are the gaps
336
- * INSIDE that chrome, which were literal on the component (#319). */
337
278
  .ui-sheet-header {
338
279
  display: flex;
339
280
  flex-direction: column;
340
281
  gap: var(--sheet-header-space-gap);
341
282
  }
342
283
 
343
- /* Reserves inline room for the absolutely-positioned close button so a long title or the
344
- * extra slot never runs under it. Moves with --sheet-close-offset. */
345
284
  .ui-sheet-title-row {
346
285
  display: flex;
347
286
  align-items: flex-start;
@@ -407,7 +346,6 @@
407
346
  block-size: var(--control-affix-icon-size);
408
347
  }
409
348
 
410
- /* Overlay + panel stacking joins the one system layer instead of a private z-50. */
411
349
  .ui-sheet-overlay,
412
350
  .ui-sheet-panel {
413
351
  z-index: var(--overlay-z-index);
@@ -431,8 +369,6 @@
431
369
  border-block-start: 1px solid hsl(var(--border));
432
370
  }
433
371
 
434
- /* The scroll region must be allowed to shrink inside the flex column, or it grows past the
435
- * panel and the footer is pushed out of view. */
436
372
  .ui-sheet-body-space {
437
373
  min-block-size: 0;
438
374
  }
@@ -1,93 +1,37 @@
1
- /* ─────────────────────────────────────────────────────────────────────────
2
- * FOCUS RING — the ONE place the keyboard-focus affordance is drawn.
3
- *
4
- * WHY THIS FILE EXISTS: the ring used to be re-written by hand in every layout
5
- * file, and it drifted into four incompatible shapes — the token pair
6
- * (`0 0 0 var(--focus-ring-width) hsl(var(--focus-ring-color, var(--ring)))`),
7
- * the same with an ad-hoc `/ 0.45`, and two that hardcoded `3px` with `/ 0.35`
8
- * and `/ 0.3`, bypassing `--focus-ring-width` entirely. Same state, four
9
- * thicknesses and opacities, and no way for a service to retune them together.
10
- * A component that forgot the rule got the UA default instead (Chrome paints
11
- * `rgb(0,95,204)` — a blue belonging to no theme; that is exactly how the
12
- * pagination defect was found).
13
- *
14
- * THE API — three layers, each overriding the one above:
15
- *
16
- * 1. GLOBAL (`:root`, tokens/foundation.css)
17
- * --focus-ring-width thickness (default 2px)
18
- * --focus-ring-color hue, HSL components (default = live --ring)
19
- * --focus-ring-opacity alpha (default 1)
20
- * --focus-ring-offset gap, outline form (default 0px)
21
- * Set any of these ONCE — even scoped under `[data-tenant]` — and EVERY
22
- * ring in the system follows.
23
- *
24
- * 2. PER COMPONENT (tokens/components/*.css)
25
- * A component that genuinely needs a different ring publishes its own
26
- * knob and rebinds the local value, e.g.
27
- * --toggle-focus-ring-alpha: 0.35; (public knob)
28
- * .ui-toggle { --focus-ring-opacity: var(--toggle-focus-ring-alpha); }
29
- * Custom properties inherit, so the rule below picks up the local value at
30
- * the element that paints — one formula, per-component tuning, and the
31
- * knob stays discoverable in the token file rather than buried in a
32
- * hand-written box-shadow.
33
- *
34
- * 3. PER INSTANCE (consumer)
35
- * `style={{ "--focus-ring-color": "0 84% 60%" }}` on any subtree.
36
- *
37
- * TURNING IT OFF: `--focus-ring-width: 0` — globally at `:root`, on one
38
- * component, or on one instance. A zero-width ring paints nothing.
39
- * A11y note: the default is ALWAYS ON (WCAG 2.4.7 / 2.4.11); switching it off
40
- * is a deliberate consumer act, never a default of this package. The one
41
- * exception that ships off is the REGION ring (`.app-main`,
42
- * `--region-focus-ring-width: 0`) — a documented product-owner tradeoff (see
43
- * tokens/foundation.css), because a control-strength frame around the whole
44
- * content area reads as a glitch to mouse-first users.
45
- *
46
- * TWO FORMS, one API: `box-shadow` hugs the border-radius and never shifts
47
- * layout, so it is the default. `outline` + `outline-offset` is for marks that
48
- * need a visible GAP (a star, a dot, a heading anchor) where a hugging ring
49
- * would touch the glyph. Both read the same four tokens.
50
- *
51
- * ADDING A COMPONENT: put its class in the matching `:is()` list below, or
52
- * give the element `ui-focus-ring` / `ui-focus-ring-outline`. Do NOT write a
53
- * `:focus-visible` box-shadow/outline anywhere else — a test enforces this
54
- * (`src/styles/__tests__/focus-ring-single-source.test.ts`).
55
- * ───────────────────────────────────────────────────────────────────────── */
1
+
56
2
  @layer components {
57
- /* Shadow form — the default. Hugs the radius, no layout shift. */
3
+
58
4
  :is(
59
5
  .ui-focus-ring,
60
6
  .ui-button,
7
+ .ui-control,
8
+ .ui-input,
9
+ .ui-control-multiline,
10
+ .ui-control-trigger,
61
11
  .ui-toggle,
62
12
  .ui-checkbox,
63
13
  .ui-radio,
64
14
  .ui-slider-thumb,
65
15
  .ui-switch,
66
- .ui-time-input,
67
16
  .ui-steps-inline-control,
68
17
  .ui-pagination-link,
69
18
  .ui-legal-document-toc-link,
19
+ .ui-code-block,
70
20
  .sb-user,
71
21
  .tb-icon-btn
72
- ):focus-visible {
22
+ ):focus-visible,
23
+ .ui-control-trigger[data-state="open"],
24
+ .ui-tag-input:focus-within,
25
+ .ui-control-composite-field:focus-within,
26
+ .ui-control-composite-field[data-state="open"] {
73
27
  outline: none;
74
- /* TWO declarations, one ring — because a control may also carry a Tailwind
75
- * shadow/ring utility (`shadow-xs` on Checkbox, Radio, Switch, Input …).
76
- * Those live in the UTILITIES layer, which outranks `components`, and they
77
- * set `box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow),
78
- * var(--tw-shadow)` — so a plain `box-shadow` here loses and the ring never
79
- * paints. Measured before this fix: Checkbox focus-visible resolved to
80
- * `rgba(0,0,0,0) 0 0 0 0`, i.e. NO visible ring at all.
81
- * Feeding `--tw-ring-shadow` makes the utility's own composite paint our
82
- * ring (and keeps the element's resting shadow); the plain `box-shadow`
83
- * covers elements that carry no such utility. */
28
+
84
29
  --tw-ring-shadow: 0 0 0 var(--focus-ring-width)
85
30
  hsl(var(--focus-ring-color, var(--ring)) / var(--focus-ring-opacity, 1));
86
31
  box-shadow: 0 0 0 var(--focus-ring-width)
87
32
  hsl(var(--focus-ring-color, var(--ring)) / var(--focus-ring-opacity, 1));
88
33
  }
89
34
 
90
- /* Outline form — for marks that need a gap between glyph and ring. */
91
35
  :is(
92
36
  .ui-focus-ring-outline,
93
37
  .ui-accordion-trigger,
@@ -100,26 +44,11 @@
100
44
  outline-offset: var(--focus-ring-offset, 0px);
101
45
  }
102
46
 
103
- /* ── Per-component rebinds ────────────────────────────────────────────────
104
- * Each line maps a PUBLIC knob (declared in tokens/components/*.css) onto the
105
- * local value the rules above read. The historical look is preserved: these
106
- * are the components that used to hand-write a different ring. */
107
-
108
- /* Toggle: a heavier, softer ring — the control is a filled surface, so a
109
- * hard 2px reads as a second border rather than a focus mark. */
110
47
  .ui-toggle {
111
48
  --focus-ring-width: var(--toggle-focus-ring-width);
112
49
  --focus-ring-opacity: var(--toggle-focus-ring-alpha);
113
50
  }
114
51
 
115
- /* Time input: same reasoning as Toggle — sits inside a bordered field. */
116
- .ui-time-input {
117
- --focus-ring-width: var(--time-input-focus-ring-width);
118
- --focus-ring-opacity: var(--time-input-focus-ring-alpha);
119
- }
120
-
121
- /* Shell chrome: softened so the ring reads as focus, not as a selected item,
122
- * on the tinted sidebar/topbar grounds. */
123
52
  .sb-user {
124
53
  --focus-ring-opacity: var(--sidebar-user-focus-ring-alpha);
125
54
  }
@@ -128,7 +57,6 @@
128
57
  --focus-ring-opacity: var(--topbar-icon-focus-ring-alpha);
129
58
  }
130
59
 
131
- /* Outline-form offsets — the gap each mark needs. */
132
60
  .ui-accordion-trigger {
133
61
  --focus-ring-offset: var(--accordion-focus-ring-offset);
134
62
  }
@@ -145,8 +73,6 @@
145
73
  --focus-ring-offset: var(--legal-document-section-focus-ring-offset);
146
74
  }
147
75
 
148
- /* Opt OUT — the command palette input sits inside an already-focused dialog
149
- * frame, so its own ring would double up (historical behaviour, kept). */
150
76
  .ui-command-input:focus-visible {
151
77
  --focus-ring-width: 0;
152
78
  outline: none;
@@ -1,29 +1,4 @@
1
- /* ─────────────────────────────────────────────────────────────────────────
2
- * BUNDLED FONTS — opt-in.
3
- *
4
- * Self-contained so consumers need no font config. The browser only downloads
5
- * the subset files matching the rendered text:
6
- * · Noto Sans JP — the DXS DEFAULT face for Japanese and Latin, including the
7
- * Vietnamese glyph coverage used by the product locales
8
- * (product override, direct instruction).
9
- * · M PLUS 2 — retained as the fallback after Noto Sans JP.
10
- *
11
- * IMPORT ORDER IS LOAD-BEARING — this file MUST be imported AFTER
12
- * `@godxjp/ui/styles/base`:
13
- *
14
- * @import "@godxjp/ui/styles/base"; /· tokens: --font-sans-base = system stack ·/
15
- * @import "@godxjp/ui/styles/fonts"; /· THEN the bundled faces overwrite it ·/
16
- *
17
- * The token fills below and foundation.css's font-agnostic default both target
18
- * `:root` at identical specificity (0,1,0), so whichever is parsed LAST wins.
19
- * Imported first, this file is silently dead — the system stack renders and the
20
- * ~800 KB of @font-face is downloaded for nothing (issue #210).
21
- *
22
- * The all-in-one `@godxjp/ui/styles` entry pulls this in automatically, in the
23
- * correct position. If you manage fonts yourself (e.g. next/font), DON'T import
24
- * this — import `@godxjp/ui/styles/base` + the layout layers you use and supply
25
- * your own faces via the --font-family-* tokens.
26
- * ───────────────────────────────────────────────────────────────────────── */
1
+
27
2
  @import "@fontsource/m-plus-2/400.css";
28
3
  @import "@fontsource/m-plus-2/500.css";
29
4
  @import "@fontsource/m-plus-2/700.css";
@@ -31,11 +6,6 @@
31
6
  @import "@fontsource/noto-sans-jp/500.css";
32
7
  @import "@fontsource/noto-sans-jp/700.css";
33
8
 
34
- /* Fill the font-token slots (see tokens/foundation.css + styles/base.css) with
35
- * the bundled faces, so the all-in-one `@godxjp/ui/styles` entry stays
36
- * zero-config: Noto Sans JP is the DXS default face for every supported locale
37
- * and M PLUS 2 remains its fallback. Consumers on the per-layer setup who
38
- * supply their own faces simply DON'T import this file and set the slots. */
39
9
  :root {
40
10
  --font-sans-base:
41
11
  "Noto Sans JP", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic Medium", YuGothic,
@@ -1,12 +1,4 @@
1
- /*
2
- * FORM — Ant-style layout. Vertical by default (label above control, LEFT-aligned). Horizontal lays
3
- * the label beside the control from the `collapseBelow` breakpoint UP (mobile-first): below it the
4
- * field collapses back to vertical. `--form-label-width` / `--form-control-width` come from the Form
5
- * (or a per-field override). RTL-safe: logical inline axis throughout.
6
- *
7
- * IMPORTANT: label alignment (justify/text-align: end) applies ONLY in horizontal/inline mode — never
8
- * to a vertical field (a right-aligned label above a full-width control is wrong, gh feedback).
9
- */
1
+
10
2
 
11
3
  @layer components {
12
4
  .ui-form {
@@ -14,70 +6,23 @@
14
6
  flex-direction: column;
15
7
  }
16
8
 
17
- /* Row rhythm between a Form's own top-level blocks (gh#295) — e.g. the field group's
18
- * CardContent and its CardFooter action row. MARGIN, not flex `gap`: `gap` only reaches DIRECT
19
- * children, which is dead the moment a consumer needs a CardFooter Save button to actually
20
- * submit (it must stay a `<form>` descendant, so Form has to wrap CardContent — the FormFields
21
- * become grandchildren, past flex `gap`'s reach). Margin-based sibling spacing works at any
22
- * depth as long as the elements are literal siblings. */
23
9
  .ui-form > * + * {
24
10
  margin-block-start: var(--form-block-gap);
25
11
  }
26
12
 
27
- /* Field-to-field row rhythm (gh#295) — MORE SPECIFIC than the rule above (two class selectors
28
- * beat one), so it wins rather than stacking with it whenever two FormFields are adjacent
29
- * siblings: Form's own direct children (a plain field list, no Card framing) or nested one
30
- * level through CardContent (the common Card-framed, Save-button-capable case). This is what
31
- * makes the rhythm hold regardless of DOM depth — the actual fix for gh#295. */
32
13
  .ui-form-field + .ui-form-field {
33
14
  margin-block-start: var(--form-field-row-gap);
34
15
  }
35
16
 
36
- /* …except when the fields are ResponsiveGrid ITEMS (Form columns={n}): there the grid's own
37
- * `row-gap` owns the rhythm (see the rule below), and a per-item margin double-spaces every row
38
- * AND breaks column alignment — the FIRST field has no preceding sibling so no margin, while its
39
- * row-mate does, shifting row 1's columns apart by exactly --form-field-row-gap and inflating
40
- * every grid track by the same amount (gh#304: measured 0 / +12px tops on row 1, 89px pitch
41
- * against a 77px track). Fields merely NESTED somewhere inside a grid cell (a stacked pair in one
42
- * cell) are not direct children, keep the margin, and are unaffected. */
43
17
  .ui-responsive-grid > .ui-form-field + .ui-form-field {
44
18
  margin-block-start: 0;
45
19
  }
46
20
 
47
- /* …and the rhythm the grid takes over is the FORM'S, not ResponsiveGrid's generic 16px stack gap
48
- * (gh#304). Handing the rows to the grid fixed the alignment but silently re-tuned the spacing:
49
- * a `columns={1}` form — and every `columns={n}` form once a narrow container collapses it to one
50
- * column, i.e. every phone — laid its rows out 16px apart where the SAME fields without `columns`
51
- * sat 12px apart. One canonical field rhythm on both paths: --form-grid-row-gap defaults to
52
- * --form-field-row-gap, and the gutter becomes a knob at the same time (rule #45, 16px default).
53
- *
54
- * `:has(> .ui-form-field)` — a grid whose ITEMS are FormFields is a field grid, and that is the
55
- * exact condition the margin reset above tests, so the two rules can never disagree about which
56
- * mechanism owns a row. Deliberately NOT `.ui-form > …`: `columns={n}` is only one way to write
57
- * this layout, and the Card-framed hand-written one (`Form > Card > CardContent > ResponsiveGrid
58
- * > FormField*` — what a form with several titled sections must do, and what docs' invoice-form
59
- * does) is the other. Keying on ancestry would give the two identical-looking layouts different
60
- * row rhythms, which is the depth-dependence gh#295 removed from this file in the first place.
61
- * A card/tile grid inside a form has no FormField items and keeps ResponsiveGrid's stack gap. */
62
21
  .ui-responsive-grid:has(> .ui-form-field) {
63
22
  row-gap: var(--form-grid-row-gap);
64
23
  column-gap: var(--form-grid-column-gap);
65
24
  }
66
25
 
67
- /* colSpan is honoured only where the grid ACTUALLY HAS more than one column.
68
- *
69
- * `grid-column: span 2` on a one-column grid does not quietly degrade to one column: per spec it
70
- * FABRICATES an implicit second track, that track auto-sizes to its content, and the real
71
- * `minmax(0, 1fr)` track is left with the remainder — which at 320px is 0px. The field in it
72
- * collapsed to zero width, and its Input's absolutely-positioned trailing affix (the clear
73
- * button, `inset-inline-end: 8px` off a zero-width box) landed outside the frame with no
74
- * scrollable ancestor between them: a control the keyboard could focus and the user could never
75
- * see. That is a WCAG 2.1.1 failure, and a resting screenshot cannot show it because the field
76
- * does not overflow — it disappears.
77
- *
78
- * The breakpoint mirrors ResponsiveGrid's own 2-column container query in layout.css, so the
79
- * span turns on exactly when the second column does. Below it, `auto` puts the field in the
80
- * single real track like every other field. */
81
26
  .ui-responsive-grid > .ui-form-field {
82
27
  grid-column: auto;
83
28
  }
@@ -88,31 +33,15 @@
88
33
  }
89
34
  }
90
35
 
91
- /* Vertical (default + collapsed state): label stacked above the control column, LEFT-aligned.
92
- * Gap = the shared --field-label-gap so FormField matches Descriptions and every label-above stack. */
93
36
  .ui-form-field {
94
37
  display: grid;
95
38
  gap: var(--field-label-gap);
96
- /* Fill the container's inline (horizontal) axis in ANY parent — a Form's
97
- * flex column (.ui-form), a ResponsiveGrid cell, or a bare flex column /
98
- * block — instead of collapsing to the content's max-content width. This
99
- * mirrors Ant Design's Form.Item, which sets the item/control to width:100%
100
- * in vertical layout rather than relying on the parent to stretch it. Without
101
- * this, a flex-column parent maps `align-self:start` onto the inline axis and
102
- * the field shrinks to its widest content (a helper-less input collapses to
103
- * its default ~20ch). Inline layout opts out below (Ant: compact, content-width). */
39
+
104
40
  inline-size: 100%;
105
- /* Never stretch to a taller grid-row sibling (e.g. a field carrying a
106
- * helper/error). Stretching would let .ui-form-field-control's
107
- * align-content:center vertically centre the control, so a field WITHOUT a
108
- * helper sits lower than one WITH a helper in the same ResponsiveGrid row.
109
- * Hugging content keeps every control top-aligned across the row. This is the
110
- * BLOCK (vertical) axis only — width is pinned by inline-size:100% above. */
41
+
111
42
  align-self: start;
112
43
  }
113
44
 
114
- /* Inline layout is intentionally compact (Ant: layout="inline"): the field
115
- * hugs its content so a row of inline fields can sit side by side. */
116
45
  .ui-form-field[data-layout="inline"] {
117
46
  inline-size: auto;
118
47
  }
@@ -126,34 +55,21 @@
126
55
 
127
56
  .ui-form-field-control {
128
57
  display: grid;
129
- /* Single column capped to the field width. Without an explicit track the
130
- * implicit column sizes to content (max-content), so a wide control (e.g. a
131
- * Select with a long value) overflows its grid cell and overlaps siblings. */
58
+
132
59
  grid-template-columns: minmax(0, 1fr);
133
- gap: var(--space-stack-xs); /* 4px between control and helper/error */
60
+ gap: var(--space-stack-xs);
134
61
  min-width: 0;
135
- /* Cap the control width when a controlWidth is set; otherwise fill the column. */
62
+
136
63
  max-inline-size: var(--form-control-width, none);
137
- /* Reserve the control-row height and centre the content so a SHORT control
138
- * (switch, slider, rating, a bare checkbox/radio — anything thinner than an
139
- * input) lines up with the label in a horizontal field instead of sitting
140
- * high. `align-content: center` centres the content row without stretching
141
- * the control; full-width inputs still fill via the 1fr column, and taller
142
- * controls (textarea) simply grow past the floor. */
64
+
143
65
  min-height: var(--control-height);
144
66
  align-content: center;
145
67
  }
146
68
 
147
- /* Let controls (and helper/error) shrink within the cell instead of forcing
148
- * the column to their intrinsic width. */
149
69
  .ui-form-field-control > * {
150
70
  min-width: 0;
151
71
  }
152
72
 
153
- /* ── Horizontal — label beside control. Each block is scoped to [data-layout=horizontal|inline]
154
- * so it NEVER affects a vertical field. Applies from the collapse breakpoint up (mobile-first). */
155
-
156
- /* collapseBelow=false → always horizontal (all widths). */
157
73
  .ui-form-field[data-collapse-below="false"]:is(
158
74
  [data-layout="horizontal"],
159
75
  [data-layout="inline"]
@@ -1,26 +1,8 @@
1
- /* ─────────────────────────────────────────────────────────────────────────
2
- * ALL-IN-ONE stylesheet — fonts + foundation + EVERY component layout layer.
3
- * Zero-config: `@import "@godxjp/ui/styles";` and everything is styled.
4
- *
5
- * For a smaller build that ships only what you render, DON'T use this. Instead:
6
- * @import "@godxjp/ui/styles/base"; // required foundation
7
- * @import "@godxjp/ui/styles/control"; // + only the layout layers you use
8
- * @import "@godxjp/ui/styles/dialog-layout";
9
- * ...
10
- * and add `@godxjp/ui/styles/fonts` AFTER `styles/base` if you want the bundled
11
- * faces. See src/styles/base.css for the full list and rules.
12
- *
13
- * ORDER IS LOAD-BEARING — `fonts.css` MUST come AFTER `base.css`.
14
- * `base.css` pulls in `tokens/base.css` → `tokens/foundation.css`, which declares
15
- * the font-agnostic `:root { --font-sans-base: <system stack> }` default. Both
16
- * declarations sit on `:root` at identical specificity (0,1,0), so the LATER one
17
- * wins. With `fonts.css` first the bundled faces could never apply and every
18
- * consumer downloaded ~800 KB of dead @font-face (issue #210).
19
- * ───────────────────────────────────────────────────────────────────────── */
1
+
20
2
  @import "sonner/dist/styles.css";
21
3
  @import "react-day-picker/style.css";
22
4
  @import "./base.css";
23
- /* AFTER the token layers — see the ORDER IS LOAD-BEARING note above. */
5
+
24
6
  @import "./fonts.css";
25
7
  @import "./shell-layout.css";
26
8
  @import "./motion.css";