@godxjp/ui 19.0.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 (445) hide show
  1. package/README.md +25 -128
  2. package/dist/app/app-provider.d.ts +1 -1
  3. package/dist/app/app-provider.js +3 -0
  4. package/dist/app/theme-axes.d.ts +4 -15
  5. package/dist/app/timezones.d.ts +1 -4
  6. package/dist/components/charts/area-chart.d.ts +2 -3
  7. package/dist/components/charts/bar-chart.d.ts +2 -3
  8. package/dist/components/charts/chart-frame.d.ts +7 -16
  9. package/dist/components/charts/chart-summary.d.ts +2 -2
  10. package/dist/components/charts/compact-bar-trend.d.ts +9 -24
  11. package/dist/components/charts/index.d.ts +1 -6
  12. package/dist/components/data-display/badge.d.ts +2 -12
  13. package/dist/components/data-display/card.d.ts +21 -41
  14. package/dist/components/data-display/carousel.d.ts +1 -2
  15. package/dist/components/data-display/code-block.d.ts +4 -0
  16. package/dist/components/data-display/code-block.js +24 -0
  17. package/dist/components/data-display/data-table.d.ts +15 -37
  18. package/dist/components/data-display/data-table.js +1 -3
  19. package/dist/components/data-display/descriptions.d.ts +2 -6
  20. package/dist/components/data-display/descriptions.js +0 -2
  21. package/dist/components/data-display/index.d.ts +4 -0
  22. package/dist/components/data-display/index.js +4 -0
  23. package/dist/components/data-display/list-row.d.ts +3 -22
  24. package/dist/components/data-display/permission-matrix.d.ts +7 -20
  25. package/dist/components/data-display/progress.d.ts +1 -1
  26. package/dist/components/data-display/prose.d.ts +4 -0
  27. package/dist/components/data-display/prose.js +20 -0
  28. package/dist/components/data-display/service-launcher-card.d.ts +3 -10
  29. package/dist/components/data-display/table.d.ts +20 -80
  30. package/dist/components/data-display/table.js +0 -3
  31. package/dist/components/data-display/timeline.d.ts +3 -5
  32. package/dist/components/data-entry/branch-scope-picker.d.ts +2 -19
  33. package/dist/components/data-entry/branch-scope-picker.js +0 -1
  34. package/dist/components/data-entry/calendar.d.ts +3 -2
  35. package/dist/components/data-entry/calendar.js +58 -3
  36. package/dist/components/data-entry/cascader.js +3 -1
  37. package/dist/components/data-entry/checkbox-group.js +12 -5
  38. package/dist/components/data-entry/checkbox.js +30 -21
  39. package/dist/components/data-entry/command-palette.d.ts +8 -22
  40. package/dist/components/data-entry/date-picker.d.ts +4 -5
  41. package/dist/components/data-entry/date-picker.js +12 -3
  42. package/dist/components/data-entry/date-range-picker.d.ts +1 -1
  43. package/dist/components/data-entry/date-range-picker.js +17 -6
  44. package/dist/components/data-entry/form-errors.d.ts +7 -18
  45. package/dist/components/data-entry/form-field.d.ts +1 -1
  46. package/dist/components/data-entry/form-field.js +15 -6
  47. package/dist/components/data-entry/form.d.ts +1 -9
  48. package/dist/components/data-entry/input.d.ts +16 -14
  49. package/dist/components/data-entry/input.js +13 -3
  50. package/dist/components/data-entry/month-picker.js +6 -4
  51. package/dist/components/data-entry/month-range-picker.d.ts +4 -6
  52. package/dist/components/data-entry/month-range-picker.js +11 -5
  53. package/dist/components/data-entry/number-input.d.ts +1 -5
  54. package/dist/components/data-entry/number-input.js +1 -0
  55. package/dist/components/data-entry/radio.js +19 -6
  56. package/dist/components/data-entry/search-select.d.ts +3 -5
  57. package/dist/components/data-entry/search-select.js +8 -2
  58. package/dist/components/data-entry/select.d.ts +15 -2
  59. package/dist/components/data-entry/select.js +57 -10
  60. package/dist/components/data-entry/switch.js +9 -2
  61. package/dist/components/data-entry/textarea.d.ts +10 -16
  62. package/dist/components/data-entry/textarea.js +8 -1
  63. package/dist/components/data-entry/time-picker.d.ts +3 -5
  64. package/dist/components/data-entry/tree-select.js +3 -1
  65. package/dist/components/data-entry/upload-types.d.ts +1 -5
  66. package/dist/components/data-entry/use-upload-draft.d.ts +0 -4
  67. package/dist/components/feedback/dialog.d.ts +6 -15
  68. package/dist/components/feedback/overlay-header-tone.d.ts +1 -1
  69. package/dist/components/feedback/sheet.d.ts +3 -10
  70. package/dist/components/feedback/sheet.js +1 -1
  71. package/dist/components/feedback/sonner.js +2 -3
  72. package/dist/components/general/activity.d.ts +4 -30
  73. package/dist/components/general/button.js +1 -10
  74. package/dist/components/general/logo.d.ts +6 -28
  75. package/dist/components/general/reveal.d.ts +3 -9
  76. package/dist/components/general/typography.d.ts +1 -3
  77. package/dist/components/layout/account-chip.d.ts +8 -0
  78. package/dist/components/layout/account-chip.js +45 -0
  79. package/dist/components/layout/auth-divider.d.ts +2 -9
  80. package/dist/components/layout/auth-shell.d.ts +1 -14
  81. package/dist/components/layout/breadcrumb.d.ts +1 -5
  82. package/dist/components/layout/centered-shell.d.ts +4 -18
  83. package/dist/components/layout/error-surface.d.ts +11 -28
  84. package/dist/components/layout/error-surface.js +4 -1
  85. package/dist/components/layout/index.d.ts +2 -0
  86. package/dist/components/layout/index.js +2 -0
  87. package/dist/components/layout/legal-document-shell.d.ts +5 -28
  88. package/dist/components/layout/master-detail.d.ts +2 -18
  89. package/dist/components/layout/page-container.js +0 -1
  90. package/dist/components/layout/responsive-grid.d.ts +6 -1
  91. package/dist/components/layout/responsive-grid.js +9 -2
  92. package/dist/components/layout/service-role-panel.d.ts +7 -19
  93. package/dist/components/layout/sidebar.d.ts +5 -27
  94. package/dist/components/layout/sidebar.js +0 -1
  95. package/dist/components/layout/split-pane.d.ts +0 -7
  96. package/dist/components/layout/topbar.d.ts +1 -14
  97. package/dist/components/navigation/app-setting-picker.js +1 -3
  98. package/dist/components/navigation/filter-bar.d.ts +1 -6
  99. package/dist/components/navigation/pagination-utils.d.ts +2 -12
  100. package/dist/components/navigation/tabs-scroll.d.ts +2 -36
  101. package/dist/components/navigation/tabs.js +4 -8
  102. package/dist/components/query/data-state.d.ts +2 -2
  103. package/dist/components/ui/credential-reveal.d.ts +1 -4
  104. package/dist/components/ui/hover-card.d.ts +1 -2
  105. package/dist/components/ui/separator.d.ts +2 -15
  106. package/dist/components/ui/toggle-group.d.ts +1 -5
  107. package/dist/components/ui/toggle.d.ts +6 -31
  108. package/dist/email/brand-mark.d.ts +6 -34
  109. package/dist/email/color.d.ts +7 -17
  110. package/dist/email/geometry.d.ts +4 -8
  111. package/dist/email/index.d.ts +4 -48
  112. package/dist/email/inline-style.d.ts +3 -9
  113. package/dist/email/urgency.d.ts +2 -7
  114. package/dist/form/form-context.d.ts +2 -5
  115. package/dist/form/form-root.d.ts +1 -2
  116. package/dist/i18n/messages/en.json +4 -0
  117. package/dist/i18n/messages/ja.json +4 -0
  118. package/dist/i18n/messages/vi.json +4 -0
  119. package/dist/inertia/index.d.ts +2 -10
  120. package/dist/lib/control-styles.d.ts +10 -21
  121. package/dist/lib/control-styles.js +4 -6
  122. package/dist/lib/datetime/format-date.d.ts +1 -4
  123. package/dist/lib/field-a11y.d.ts +31 -36
  124. package/dist/lib/field-a11y.js +16 -2
  125. package/dist/lib/format.d.ts +4 -8
  126. package/dist/lib/hooks.d.ts +6 -12
  127. package/dist/lib/permission-grid.d.ts +3 -18
  128. package/dist/lib/query-error.d.ts +3 -3
  129. package/dist/props/components/app.prop.d.ts +19 -27
  130. package/dist/props/components/charts.prop.d.ts +2 -3
  131. package/dist/props/components/data-display.prop.d.ts +48 -72
  132. package/dist/props/components/data-entry.prop.d.ts +41 -30
  133. package/dist/props/components/form.prop.d.ts +2 -6
  134. package/dist/props/components/general.prop.d.ts +11 -27
  135. package/dist/props/components/layout.prop.d.ts +89 -260
  136. package/dist/props/components/navigation.prop.d.ts +27 -42
  137. package/dist/props/registry.d.ts +31 -0
  138. package/dist/props/registry.js +33 -0
  139. package/dist/props/vocabulary/data.prop.d.ts +18 -49
  140. package/dist/props/vocabulary/index.d.ts +1 -1
  141. package/dist/props/vocabulary/interaction.prop.d.ts +10 -12
  142. package/dist/props/vocabulary/layout.prop.d.ts +8 -30
  143. package/dist/props/vocabulary/shared.prop.d.ts +3 -2
  144. package/dist/styles/alert-layout.css +1 -32
  145. package/dist/styles/badge-layout.css +4 -18
  146. package/dist/styles/base.css +14 -113
  147. package/dist/styles/card-layout.css +6 -128
  148. package/dist/styles/chart-layout.css +2 -17
  149. package/dist/styles/control.css +380 -458
  150. package/dist/styles/core.css +21 -0
  151. package/dist/styles/data-display-layout.css +175 -94
  152. package/dist/styles/data-entry-layout.css +0 -45
  153. package/dist/styles/density.css +1 -30
  154. package/dist/styles/dialog-layout.css +5 -69
  155. package/dist/styles/focus-ring.css +13 -87
  156. package/dist/styles/fonts.css +1 -31
  157. package/dist/styles/form-layout.css +7 -91
  158. package/dist/styles/index.css +2 -20
  159. package/dist/styles/layout.css +38 -456
  160. package/dist/styles/logo-layout.css +1 -35
  161. package/dist/styles/motion.css +3 -42
  162. package/dist/styles/navigation-layout.css +3 -50
  163. package/dist/styles/shell-layout.css +37 -403
  164. package/dist/styles/table-layout.css +16 -274
  165. package/dist/styles/text-layout.css +7 -21
  166. package/dist/styles/toggle.css +1 -23
  167. package/dist/theme/dxs.canonical.css +1 -55
  168. package/dist/theme/example.service.css +1 -26
  169. package/dist/theme/famgia.service.css +5 -15
  170. package/dist/tokens/axes.css +3 -40
  171. package/dist/tokens/base.css +1 -4
  172. package/dist/tokens/components/activity.css +6 -42
  173. package/dist/tokens/components/badge.css +4 -13
  174. package/dist/tokens/components/banner.css +4 -9
  175. package/dist/tokens/components/card.css +32 -88
  176. package/dist/tokens/components/chart.css +9 -26
  177. package/dist/tokens/components/control.css +37 -222
  178. package/dist/tokens/components/data-display.css +28 -79
  179. package/dist/tokens/components/data-entry.css +5 -19
  180. package/dist/tokens/components/descriptions.css +7 -27
  181. package/dist/tokens/components/email.css +38 -84
  182. package/dist/tokens/components/error-surface.css +2 -18
  183. package/dist/tokens/components/feedback.css +27 -124
  184. package/dist/tokens/components/form.css +13 -45
  185. package/dist/tokens/components/legal-document.css +16 -41
  186. package/dist/tokens/components/list-row.css +11 -36
  187. package/dist/tokens/components/logo.css +2 -57
  188. package/dist/tokens/components/navigation.css +16 -94
  189. package/dist/tokens/components/scroll-area.css +2 -18
  190. package/dist/tokens/components/separator.css +8 -30
  191. package/dist/tokens/components/sheet.css +3 -14
  192. package/dist/tokens/components/shell.css +53 -307
  193. package/dist/tokens/components/sidebar.css +5 -22
  194. package/dist/tokens/components/table.css +19 -140
  195. package/dist/tokens/components/toggle.css +3 -65
  196. package/dist/tokens/components/upload.css +7 -43
  197. package/dist/tokens/foundation.css +108 -383
  198. package/dist/tokens/semantic/layout.css +33 -207
  199. package/docs/CANONICAL-CONTRACTS.md +206 -0
  200. package/docs/COMPONENTS.md +157 -0
  201. package/docs/COMPOSITION-VS-COMPONENT.md +105 -0
  202. package/docs/CONSUMER-RULES.md +14 -0
  203. package/docs/CUSTOMER-THEMING.md +162 -0
  204. package/docs/DATETIME.md +69 -0
  205. package/docs/DEVELOPMENT.md +173 -0
  206. package/docs/FORMS.md +143 -0
  207. package/docs/FRAME-A11Y-CI.md +267 -0
  208. package/docs/FRAME-COVERAGE-LEDGER.md +123 -0
  209. package/docs/FRAME-COVERAGE-REPORT.md +140 -0
  210. package/docs/FRAME-COVERAGE-STANDARD.md +65 -0
  211. package/docs/FRAME-COVERAGE.md +29 -0
  212. package/docs/PROPS-REGISTRY.md +61 -0
  213. package/docs/PROPS-VOCABULARY.md +100 -0
  214. package/docs/README.md +60 -0
  215. package/docs/REGISTRY.md +70 -0
  216. package/docs/SPACING.md +56 -0
  217. package/docs/STANDARDS-vocabulary-tokens.md +48 -0
  218. package/docs/TESTING.md +98 -0
  219. package/docs/TOKENS.md +347 -0
  220. package/docs/asset-modules.d.ts +46 -0
  221. package/docs/assets/cover-terrain.svg +6 -0
  222. package/docs/assets/portrait-amber.svg +5 -0
  223. package/docs/assets/portrait-clay.svg +5 -0
  224. package/docs/assets/portrait-indigo.svg +5 -0
  225. package/docs/assets/portrait-iris.svg +5 -0
  226. package/docs/assets/portrait-moss.svg +5 -0
  227. package/docs/assets/portrait-plum.svg +5 -0
  228. package/docs/assets/portrait-slate.svg +5 -0
  229. package/docs/charts/compact-bar-trend.tsx +328 -0
  230. package/docs/charts/size-tiers.tsx +192 -0
  231. package/docs/data-display/accordion.tsx +99 -0
  232. package/docs/data-display/avatar.tsx +355 -0
  233. package/docs/data-display/badge.tsx +247 -0
  234. package/docs/data-display/card/examples/detail-panel.tsx +106 -0
  235. package/docs/data-display/card/index.md +3 -0
  236. package/docs/data-display/card/index.tsx +285 -0
  237. package/docs/data-display/carousel.tsx +156 -0
  238. package/docs/data-display/charts.tsx +198 -0
  239. package/docs/data-display/code-block.tsx +90 -0
  240. package/docs/data-display/collapsible.tsx +162 -0
  241. package/docs/data-display/credential-reveal.tsx +145 -0
  242. package/docs/data-display/data-table/examples/approval-queue.tsx +212 -0
  243. package/docs/data-display/data-table/examples/grid-features.tsx +158 -0
  244. package/docs/data-display/data-table/examples/list-page.tsx +175 -0
  245. package/docs/data-display/data-table/index.md +5 -0
  246. package/docs/data-display/data-table/index.tsx +295 -0
  247. package/docs/data-display/descriptions.tsx +143 -0
  248. package/docs/data-display/empty-state.tsx +164 -0
  249. package/docs/data-display/hover-card.tsx +181 -0
  250. package/docs/data-display/list-row.tsx +420 -0
  251. package/docs/data-display/permission-matrix.tsx +184 -0
  252. package/docs/data-display/popover-touch.tsx +27 -0
  253. package/docs/data-display/popover.tsx +245 -0
  254. package/docs/data-display/progress.tsx +84 -0
  255. package/docs/data-display/prose.tsx +105 -0
  256. package/docs/data-display/qr-code.tsx +68 -0
  257. package/docs/data-display/scroll-area.tsx +271 -0
  258. package/docs/data-display/service-launcher-card.tsx +145 -0
  259. package/docs/data-display/stat-card.tsx +99 -0
  260. package/docs/data-display/table.tsx +251 -0
  261. package/docs/data-display/timeline.tsx +112 -0
  262. package/docs/data-display/touch-actions.tsx +36 -0
  263. package/docs/data-display/tree-list.tsx +107 -0
  264. package/docs/data-entry/branch-scope-picker.tsx +123 -0
  265. package/docs/data-entry/calendar.tsx +180 -0
  266. package/docs/data-entry/cascader.tsx +378 -0
  267. package/docs/data-entry/checkbox.tsx +256 -0
  268. package/docs/data-entry/color-picker.tsx +117 -0
  269. package/docs/data-entry/command-palette.tsx +179 -0
  270. package/docs/data-entry/command.tsx +262 -0
  271. package/docs/data-entry/country-picker-recipe.tsx +170 -0
  272. package/docs/data-entry/date-picker.tsx +191 -0
  273. package/docs/data-entry/date-range-picker.tsx +149 -0
  274. package/docs/data-entry/form/examples/employee-settings.tsx +267 -0
  275. package/docs/data-entry/form/examples/invoice-form.tsx +387 -0
  276. package/docs/data-entry/form-field/examples/a11y-contract.tsx +240 -0
  277. package/docs/data-entry/form-field/examples/create-form.tsx +105 -0
  278. package/docs/data-entry/form-field/index.md +8 -0
  279. package/docs/data-entry/form-field/index.tsx +326 -0
  280. package/docs/data-entry/form-inertia.tsx +80 -0
  281. package/docs/data-entry/form-root.tsx +102 -0
  282. package/docs/data-entry/form.tsx +724 -0
  283. package/docs/data-entry/input-otp.tsx +231 -0
  284. package/docs/data-entry/input.tsx +114 -0
  285. package/docs/data-entry/label.tsx +100 -0
  286. package/docs/data-entry/month-picker.tsx +101 -0
  287. package/docs/data-entry/month-range-picker.tsx +115 -0
  288. package/docs/data-entry/number-input.tsx +240 -0
  289. package/docs/data-entry/password-input.tsx +106 -0
  290. package/docs/data-entry/password-strength.tsx +97 -0
  291. package/docs/data-entry/radio-group.tsx +95 -0
  292. package/docs/data-entry/rating.tsx +87 -0
  293. package/docs/data-entry/search-input.tsx +120 -0
  294. package/docs/data-entry/select-async-contracts.tsx +108 -0
  295. package/docs/data-entry/select-matrix.tsx +204 -0
  296. package/docs/data-entry/select.tsx +369 -0
  297. package/docs/data-entry/slider.tsx +130 -0
  298. package/docs/data-entry/switch.tsx +67 -0
  299. package/docs/data-entry/tag-input.tsx +108 -0
  300. package/docs/data-entry/textarea.tsx +209 -0
  301. package/docs/data-entry/time-picker.tsx +99 -0
  302. package/docs/data-entry/toggle-count.tsx +293 -0
  303. package/docs/data-entry/toggle-group.tsx +225 -0
  304. package/docs/data-entry/toggle.tsx +127 -0
  305. package/docs/data-entry/transfer.tsx +97 -0
  306. package/docs/data-entry/tree-select.tsx +204 -0
  307. package/docs/data-entry/upload.tsx +184 -0
  308. package/docs/feedback/alert-dialog.tsx +270 -0
  309. package/docs/feedback/alert.tsx +248 -0
  310. package/docs/feedback/banner.tsx +183 -0
  311. package/docs/feedback/danger-confirm.tsx +88 -0
  312. package/docs/feedback/dialog-touch.tsx +24 -0
  313. package/docs/feedback/dialog.tsx +193 -0
  314. package/docs/feedback/sheet.tsx +410 -0
  315. package/docs/feedback/skeleton.tsx +111 -0
  316. package/docs/feedback/toast.tsx +135 -0
  317. package/docs/feedback/tooltip.tsx +171 -0
  318. package/docs/feedback/two-factor-setup.tsx +68 -0
  319. package/docs/foundation/_email-specimen.ts +274 -0
  320. package/docs/foundation/colors.tsx +202 -0
  321. package/docs/foundation/density.tsx +232 -0
  322. package/docs/foundation/email-tokens.tsx +306 -0
  323. package/docs/foundation/radius-shadow.tsx +152 -0
  324. package/docs/foundation/spacing.tsx +211 -0
  325. package/docs/foundation/typography.tsx +147 -0
  326. package/docs/general/activity.tsx +224 -0
  327. package/docs/general/button/examples/destructive-confirm.tsx +90 -0
  328. package/docs/general/button/examples/form-actions.tsx +85 -0
  329. package/docs/general/button/examples/toolbar.tsx +160 -0
  330. package/docs/general/button/index.md +12 -0
  331. package/docs/general/button/index.tsx +211 -0
  332. package/docs/general/logo.tsx +131 -0
  333. package/docs/general/reveal.tsx +41 -0
  334. package/docs/general/typography.tsx +152 -0
  335. package/docs/layout/account-chip.tsx +72 -0
  336. package/docs/layout/admin-collection.tsx +122 -0
  337. package/docs/layout/app-shell.tsx +374 -0
  338. package/docs/layout/aspect-ratio.tsx +119 -0
  339. package/docs/layout/auth-account-summary.tsx +103 -0
  340. package/docs/layout/auth-divider.tsx +28 -0
  341. package/docs/layout/auth-footer.tsx +37 -0
  342. package/docs/layout/auth-identity.tsx +36 -0
  343. package/docs/layout/auth-recovery/examples/mfa-challenge.md +41 -0
  344. package/docs/layout/auth-recovery/examples/mfa-challenge.tsx +254 -0
  345. package/docs/layout/auth-recovery/examples/mobile-390.md +25 -0
  346. package/docs/layout/auth-recovery/examples/mobile-390.tsx +82 -0
  347. package/docs/layout/auth-recovery/examples/password-recovery.md +24 -0
  348. package/docs/layout/auth-recovery/examples/password-recovery.tsx +197 -0
  349. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.md +27 -0
  350. package/docs/layout/auth-recovery/examples/wrapping-ja-en-vi.tsx +156 -0
  351. package/docs/layout/auth-recovery/index.md +140 -0
  352. package/docs/layout/auth-recovery/index.tsx +96 -0
  353. package/docs/layout/auth-shell-context.tsx +103 -0
  354. package/docs/layout/auth-shell-device.tsx +112 -0
  355. package/docs/layout/auth-shell-registration.tsx +335 -0
  356. package/docs/layout/auth-shell-variants.tsx +139 -0
  357. package/docs/layout/auth-shell.tsx +59 -0
  358. package/docs/layout/auth-stack.tsx +40 -0
  359. package/docs/layout/centered-shell.tsx +102 -0
  360. package/docs/layout/error-surface/examples/application-403.tsx +84 -0
  361. package/docs/layout/error-surface/examples/application-404.tsx +77 -0
  362. package/docs/layout/error-surface/examples/system-500.tsx +47 -0
  363. package/docs/layout/error-surface/examples/system-503.tsx +48 -0
  364. package/docs/layout/error-surface/index.md +153 -0
  365. package/docs/layout/error-surface/index.tsx +239 -0
  366. package/docs/layout/flex.tsx +262 -0
  367. package/docs/layout/legal-document-shell/_data.ts +110 -0
  368. package/docs/layout/legal-document-shell/examples/desktop-1440.md +12 -0
  369. package/docs/layout/legal-document-shell/examples/desktop-1440.tsx +83 -0
  370. package/docs/layout/legal-document-shell/examples/mobile-390.md +22 -0
  371. package/docs/layout/legal-document-shell/examples/mobile-390.tsx +70 -0
  372. package/docs/layout/legal-document-shell/examples/tablet-1024.md +3 -0
  373. package/docs/layout/legal-document-shell/examples/tablet-1024.tsx +84 -0
  374. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.md +18 -0
  375. package/docs/layout/legal-document-shell/examples/wrapping-ja-en-vi.tsx +61 -0
  376. package/docs/layout/legal-document-shell/index.md +51 -0
  377. package/docs/layout/legal-document-shell/index.tsx +101 -0
  378. package/docs/layout/master-detail.tsx +387 -0
  379. package/docs/layout/org-switcher.tsx +131 -0
  380. package/docs/layout/page-container.tsx +946 -0
  381. package/docs/layout/resizable-panel.tsx +419 -0
  382. package/docs/layout/responsive-grid.tsx +235 -0
  383. package/docs/layout/separator.tsx +327 -0
  384. package/docs/layout/service-role-panel.tsx +144 -0
  385. package/docs/layout/sidebar.tsx +586 -0
  386. package/docs/layout/split-pane.tsx +451 -0
  387. package/docs/layout/topbar.tsx +347 -0
  388. package/docs/navigation/app-setting-picker.tsx +141 -0
  389. package/docs/navigation/breadcrumb.tsx +128 -0
  390. package/docs/navigation/context-menu.tsx +117 -0
  391. package/docs/navigation/dropdown-menu.tsx +213 -0
  392. package/docs/navigation/filter-bar.tsx +227 -0
  393. package/docs/navigation/menubar.tsx +141 -0
  394. package/docs/navigation/navigation-menu.tsx +165 -0
  395. package/docs/navigation/pagination.tsx +241 -0
  396. package/docs/navigation/steps.tsx +263 -0
  397. package/docs/navigation/tabs-rtl.tsx +28 -0
  398. package/docs/navigation/tabs.tsx +308 -0
  399. package/docs/navigation/toolbar.tsx +339 -0
  400. package/docs/providers/app-provider.tsx +191 -0
  401. package/docs/providers/format-date.tsx +230 -0
  402. package/docs/query/button-refetch.tsx +160 -0
  403. package/docs/query/data-state.tsx +192 -0
  404. package/docs/query/infinite-query-state.tsx +93 -0
  405. package/docs/query/mutation-feedback.tsx +70 -0
  406. package/docs/query/prefetch-link.tsx +262 -0
  407. package/docs/query/touch-actions.tsx +68 -0
  408. package/docs/showcase/acme-portal.tsx +441 -0
  409. package/docs/showcase/acme-website.tsx +455 -0
  410. package/docs/showcase/case1-warehouse-dashboard.tsx +343 -0
  411. package/docs/showcase/case2-employee-me.tsx +441 -0
  412. package/docs/showcase/case3-approval-workflow.tsx +527 -0
  413. package/docs/showcase/case4-login.tsx +307 -0
  414. package/docs/showcase/case5-shift-calendar.tsx +795 -0
  415. package/docs/showcase/case6-agency-handy.tsx +1072 -0
  416. package/docs/showcase/futurelastic-web.tsx +390 -0
  417. package/docs/showcase/org-switcher.tsx +313 -0
  418. package/docs/showcase/permission-matrix.tsx +343 -0
  419. package/docs/showcase/public-landing.tsx +210 -0
  420. package/docs/showcase/settings-account-sections.tsx +559 -0
  421. package/docs/showcase/settings-security-mfa.tsx +145 -0
  422. package/docs/showcase/table-approval-queue.tsx +199 -0
  423. package/docs/showcase/table-bulk-actions.tsx +460 -0
  424. package/docs/showcase/table-compact-kintone.tsx +438 -0
  425. package/docs/showcase/table-conditional-format.tsx +367 -0
  426. package/docs/showcase/table-crud-list.tsx +544 -0
  427. package/docs/showcase/table-density.tsx +340 -0
  428. package/docs/showcase/table-expandable-rows.tsx +471 -0
  429. package/docs/showcase/table-filter-chips.tsx +461 -0
  430. package/docs/showcase/table-footer-totals.tsx +311 -0
  431. package/docs/showcase/table-grouped-subtotals.tsx +388 -0
  432. package/docs/showcase/table-master-detail.tsx +479 -0
  433. package/docs/showcase/table-pagination.tsx +320 -0
  434. package/docs/showcase/table-states.tsx +363 -0
  435. package/docs/showcase/table-sticky-columns.tsx +373 -0
  436. package/docs/showcase/table-tree-rows.tsx +444 -0
  437. package/docs/showcase/table-view-tabs.tsx +488 -0
  438. package/package.json +10 -11
  439. package/scripts/_agent-setup.mjs +16 -2
  440. package/scripts/audit-hook.mjs +3 -13
  441. package/scripts/init-agent-kit.mjs +1 -14
  442. package/scripts/postinstall.mjs +12 -12
  443. package/scripts/ui-audit.mjs +93 -31
  444. package/scripts/visual-audit-rules.mjs +51 -7
  445. package/scripts/visual-audit.mjs +118 -47
@@ -1,24 +1,78 @@
1
1
  "use client";
2
- import { jsx } from "react/jsx-runtime";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
3
4
  import { ChevronLeft, ChevronRight } from "lucide-react";
4
- import { DayPicker } from "react-day-picker";
5
+ import { DayPicker, dateMatchModifiers } from "react-day-picker";
6
+ import { useTranslation } from "../../i18n/use-translation.js";
5
7
  import { cn } from "../../lib/utils.js";
6
8
  import { controlIconSmClass } from "../../lib/control-styles.js";
7
- import { buttonVariants } from "../general/button.js";
9
+ import { Button, buttonVariants } from "../general/button.js";
10
+ const startOfDay = (date) => new Date(date.getFullYear(), date.getMonth(), date.getDate());
11
+ const startOfMonth = (date) => new Date(date.getFullYear(), date.getMonth(), 1);
12
+ const endOfMonth = (date) => new Date(date.getFullYear(), date.getMonth() + 1, 0);
13
+ const sameDay = (a, b) => startOfDay(a).getTime() === startOfDay(b).getTime();
8
14
  function Calendar({
9
15
  className,
10
16
  classNames,
11
17
  showOutsideDays = true,
12
18
  "aria-label": ariaLabel,
13
19
  labels,
20
+ showToday = false,
21
+ showClose = false,
22
+ onClose,
23
+ footer,
24
+ month: monthProp,
25
+ onMonthChange,
14
26
  ...props
15
27
  }) {
28
+ const { t } = useTranslation();
29
+ const [month, setMonth] = React.useState(monthProp ?? props.defaultMonth);
30
+ const today = startOfDay(props.today ?? /* @__PURE__ */ new Date());
31
+ const todayDisabled = props.startMonth != null && today < startOfMonth(props.startMonth) || props.endMonth != null && today > endOfMonth(props.endMonth) || props.disabled != null && dateMatchModifiers(today, props.disabled);
32
+ const modifiers = { today: true };
33
+ const selectToday = (event) => {
34
+ setMonth(startOfMonth(today));
35
+ onMonthChange?.(startOfMonth(today));
36
+ if (props.mode === "single") {
37
+ props.onSelect?.(today, today, modifiers, event);
38
+ } else if (props.mode === "multiple") {
39
+ const current = props.selected ?? [];
40
+ const next = current.some((day) => sameDay(day, today)) ? current : [...current, today];
41
+ props.onSelect?.(next, today, modifiers, event);
42
+ } else if (props.mode === "range") {
43
+ const from = props.selected?.from;
44
+ const to = props.selected?.to;
45
+ const next = from && !to ? today < from ? { from: today, to: from } : { from, to: today } : { from: today, to: void 0 };
46
+ props.onSelect?.(next, today, modifiers, event);
47
+ }
48
+ };
49
+ const actions = showToday || showClose ? /* @__PURE__ */ jsxs(Fragment, { children: [
50
+ showToday ? /* @__PURE__ */ jsx(
51
+ Button,
52
+ {
53
+ type: "button",
54
+ variant: "ghost",
55
+ size: "sm",
56
+ className: "ui-calendar-footer-today",
57
+ disabled: todayDisabled,
58
+ onClick: selectToday,
59
+ children: t("dataEntry.calendar.today") ?? "Today"
60
+ }
61
+ ) : null,
62
+ showClose ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: onClose, children: t("dataEntry.calendar.close") ?? "Close" }) : null
63
+ ] }) : void 0;
16
64
  const rangeDefaults = props.mode === "range" ? { resetOnSelect: props.resetOnSelect ?? true } : null;
17
65
  return /* @__PURE__ */ jsx(
18
66
  DayPicker,
19
67
  {
20
68
  showOutsideDays,
21
69
  "aria-label": ariaLabel,
70
+ month: showToday ? monthProp ?? month : monthProp,
71
+ onMonthChange: (next) => {
72
+ setMonth(next);
73
+ onMonthChange?.(next);
74
+ },
75
+ footer: footer ?? actions,
22
76
  labels: {
23
77
  ...labels,
24
78
  labelNav: labels?.labelNav ?? (() => `${ariaLabel ?? "Calendar"} navigation`)
@@ -81,6 +135,7 @@ function Calendar({
81
135
  ),
82
136
  disabled: cn("ui-calendar-day-disabled", classNames?.disabled),
83
137
  hidden: cn("invisible", classNames?.hidden),
138
+ footer: cn("ui-calendar-footer", classNames?.footer),
84
139
  ...classNames
85
140
  },
86
141
  components: {
@@ -4,7 +4,7 @@ import * as React from "react";
4
4
  import { Check, ChevronRight, ChevronsUpDown, Minus, X } from "lucide-react";
5
5
  import { useTranslation } from "../../i18n/use-translation.js";
6
6
  import { cn } from "../../lib/utils.js";
7
- import { pickFieldA11y } from "../../lib/field-a11y.js";
7
+ import { pickFieldA11y, useFieldIdentity } from "../../lib/field-a11y.js";
8
8
  import { controlOpenRingClass } from "../../lib/control-styles.js";
9
9
  import { Button } from "../general/button.js";
10
10
  import { Popover, PopoverContent, PopoverTrigger } from "../data-display/popover.js";
@@ -86,6 +86,7 @@ function Cascader({
86
86
  }) {
87
87
  const { t } = useTranslation();
88
88
  const fieldA11y = pickFieldA11y(ariaProps);
89
+ const identity = useFieldIdentity({ id, "data-field": fieldA11y["data-field"] });
89
90
  const reactId = React.useId();
90
91
  const panelId = `${id ?? reactId}-panel`;
91
92
  const options = React.useMemo(
@@ -240,6 +241,7 @@ function Cascader({
240
241
  Button,
241
242
  {
242
243
  id,
244
+ "data-field": fieldA11y["data-field"] ?? identity["data-field"],
243
245
  type: "button",
244
246
  variant: "outline",
245
247
  role: "combobox",
@@ -2,7 +2,7 @@
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { cn } from "../../lib/utils.js";
5
- import { pickGroupFieldA11y } from "../../lib/field-a11y.js";
5
+ import { pickGroupFieldA11y, useFieldIdentity } from "../../lib/field-a11y.js";
6
6
  import { Checkbox } from "./checkbox.js";
7
7
  import { Field } from "./field.js";
8
8
  import { choiceGroupClassName } from "./choice-option.js";
@@ -33,6 +33,10 @@ function CheckboxGroup({
33
33
  const reactId = React.useId();
34
34
  const [value, setValue] = useControllableArray(controlledValue, defaultValue);
35
35
  const groupA11y = pickGroupFieldA11y(ariaProps);
36
+ const identity = useFieldIdentity({ id, name, "data-field": groupA11y["data-field"] });
37
+ const resolvedName = name ?? identity.name;
38
+ const resolvedField = groupA11y["data-field"] ?? identity["data-field"];
39
+ const optionDomId = (optionValue, index) => id ? `${id}-${optionValue}` : `${reactId}-${optionValue}-${index}`;
36
40
  const toggle = (optionValue) => {
37
41
  const next = value.includes(optionValue) ? value.filter((v) => v !== optionValue) : [...value, optionValue];
38
42
  setValue(next);
@@ -45,17 +49,19 @@ function CheckboxGroup({
45
49
  role: "group",
46
50
  id,
47
51
  ...groupA11y,
52
+ "data-field": resolvedField,
48
53
  "aria-disabled": disabled ? true : void 0,
49
54
  "data-orientation": orientation,
50
55
  className: choiceGroupClassName(orientation, className),
51
56
  children: options.map((opt, index) => {
52
- const id2 = `${reactId}-${opt.value}-${index}`;
57
+ const optionId = optionDomId(opt.value, index);
53
58
  const checked = value.includes(opt.value);
54
- return /* @__PURE__ */ jsx(Field, { id: id2, label: opt.label, description: opt.description, children: /* @__PURE__ */ jsx(
59
+ return /* @__PURE__ */ jsx(Field, { id: optionId, label: opt.label, description: opt.description, children: /* @__PURE__ */ jsx(
55
60
  Checkbox,
56
61
  {
57
- id: id2,
58
- name,
62
+ id: optionId,
63
+ name: resolvedName,
64
+ "data-field": resolvedField,
59
65
  value: opt.value,
60
66
  checked,
61
67
  disabled: Boolean(disabled) || Boolean(opt.disabled),
@@ -74,6 +80,7 @@ function CheckboxGroup({
74
80
  role: "group",
75
81
  id,
76
82
  ...groupA11y,
83
+ "data-field": resolvedField,
77
84
  "aria-disabled": disabled ? true : void 0,
78
85
  "data-orientation": orientation,
79
86
  className: cn(choiceGroupClassName(orientation), className),
@@ -4,28 +4,37 @@ import * as React from "react";
4
4
  import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
5
5
  import { Check } from "lucide-react";
6
6
  import { cn } from "../../lib/utils.js";
7
+ import { useFieldIdentity } from "../../lib/field-a11y.js";
7
8
  import { CheckboxGroup } from "./checkbox-group.js";
8
- const CheckboxRoot = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
9
- CheckboxPrimitive.Root,
10
- {
11
- ref,
12
- "data-slot": "checkbox",
13
- className: cn(
14
- // `disabled:cursor-not-allowed disabled:opacity-50` and the checked fill are DELETED, not
15
- // moved (#319): `.ui-checkbox:disabled, .ui-checkbox[data-disabled]` and
16
- // `.ui-checkbox[data-state="checked"]` in styles/control.css already declare both, reading
17
- // --disabled-opacity and --checkbox-checked-background. Utilities are layered AFTER
18
- // components in Tailwind v4, so these literals were silently OUTRANKING those knobs — a
19
- // service overriding --checkbox-checked-background got no fill change at all. Radix sets
20
- // `data-state`/`data-disabled` on the root, so the CSS rules match. Rendering is unchanged:
21
- // both knobs default to exactly the values these utilities hard-coded.
22
- "peer ui-checkbox aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=checked]:border-primary data-[state=checked]:text-primary-foreground shrink-0 shadow-xs transition-shadow outline-none",
23
- className
24
- ),
25
- ...props,
26
- children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, { "data-slot": "checkbox-indicator", className: "ui-choice-indicator", children: /* @__PURE__ */ jsx(Check, { className: "ui-checkbox-icon", "aria-hidden": "true" }) })
27
- }
28
- ));
9
+ const CheckboxRoot = React.forwardRef(({ className, ...props }, ref) => {
10
+ const identity = useFieldIdentity({
11
+ id: props.id,
12
+ name: props.name,
13
+ "data-field": props["data-field"]
14
+ });
15
+ return /* @__PURE__ */ jsx(
16
+ CheckboxPrimitive.Root,
17
+ {
18
+ ref,
19
+ "data-slot": "checkbox",
20
+ className: cn(
21
+ // `disabled:cursor-not-allowed disabled:opacity-50` and the checked fill are DELETED, not
22
+ // moved (#319): `.ui-checkbox:disabled, .ui-checkbox[data-disabled]` and
23
+ // `.ui-checkbox[data-state="checked"]` in styles/control.css already declare both, reading
24
+ // --disabled-opacity and --checkbox-checked-background. Utilities are layered AFTER
25
+ // components in Tailwind v4, so these literals were silently OUTRANKING those knobs — a
26
+ // service overriding --checkbox-checked-background got no fill change at all. Radix sets
27
+ // `data-state`/`data-disabled` on the root, so the CSS rules match. Rendering is unchanged:
28
+ // both knobs default to exactly the values these utilities hard-coded.
29
+ "peer ui-checkbox aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=checked]:border-primary data-[state=checked]:text-primary-foreground shrink-0 shadow-xs transition-shadow outline-none",
30
+ className
31
+ ),
32
+ ...props,
33
+ ...identity,
34
+ children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, { "data-slot": "checkbox-indicator", className: "ui-choice-indicator", children: /* @__PURE__ */ jsx(Check, { className: "ui-checkbox-icon", "aria-hidden": "true" }) })
35
+ }
36
+ );
37
+ });
29
38
  CheckboxRoot.displayName = CheckboxPrimitive.Root.displayName;
30
39
  const Checkbox = Object.assign(CheckboxRoot, {
31
40
  Group: CheckboxGroup
@@ -31,7 +31,7 @@ export type CommandPaletteProps = {
31
31
  onOpenChange?: (open: boolean) => void;
32
32
  /**
33
33
  * Controlled search-box query. Pairs with `onSearchChange`; leave it out for the uncontrolled
34
- * palette (seeded by `defaultSearch`). Same idiom as `SearchSelect`'s `search`.
34
+ * palette (seeded by `defaultSearch`).
35
35
  */
36
36
  search?: string;
37
37
  /** Initial uncontrolled query, and the value the palette resets to when it closes. Default `""`. */
@@ -45,8 +45,6 @@ export type CommandPaletteProps = {
45
45
  * Whether the palette filters `groups` itself (cmdk's client-side fuzzy match). Set `false` when
46
46
  * the QUERY is answered by a server and `groups` already holds the matches — otherwise every row
47
47
  * is scored a second time against the same string and late-arriving matches are dropped.
48
- *
49
- * It also decides who owns the empty node; see the component doc block. Default `true`.
50
48
  */
51
49
  shouldFilter?: boolean;
52
50
  loading?: boolean;
@@ -55,24 +53,12 @@ export type CommandPaletteProps = {
55
53
  shortcut?: boolean;
56
54
  };
57
55
  /**
58
- * CommandPalette — the ⌘K search dialog.
59
- *
60
- * ## The empty-state contract (gh#412)
61
- *
62
- * `labels.empty` renders under exactly one rule, and which mechanism decides follows `shouldFilter`:
63
- *
64
- * - **`shouldFilter` (default, client-side)** cmdk owns it: the palette holds items, the query
65
- * matches none of them. Unchanged.
66
- * - **`shouldFilter={false}` (server-side)** — the PALETTE owns it, derived synchronously from
67
- * props: the empty node renders when `groups` carries no items, and never while `loading` or
68
- * `error` is set. cmdk's own empty node cannot be trusted here, because it is driven by a
69
- * scheduled count of the items that have REGISTERED in the DOM, not by what the consumer knows —
70
- * so an async group that populates a frame late flips it on and off and any assertion over it
71
- * races. Reading `groups` instead makes "did we render the empty state?" a pure function of the
72
- * props at that render, which is what a contract test can assert.
73
- *
74
- * The practical consequence for search-as-you-type: hold `loading` true for the whole in-flight
75
- * window. While it is true the palette shows `labels.loading` and never claims "no results" —
76
- * a request that has not answered yet is not an empty result.
56
+ * Unchanged. - **`shouldFilter={false}` (server-side)** — the PALETTE owns it, derived
57
+ * synchronously from props: the empty node renders when `groups` carries no items, and never while
58
+ * `loading` or `error` is set. cmdk's own empty node cannot be trusted here, because it is driven
59
+ * by a scheduled count of the items that have REGISTERED in the DOM, not by what the consumer
60
+ * knows so an async group that populates a frame late flips it on and off and any assertion over
61
+ * it races. Reading `groups` instead makes "did we render the empty state?" a pure function of the
62
+ * props at that render, which is what a contract test can assert.
77
63
  */
78
64
  export declare function CommandPalette({ groups, labels, onSelect, open: controlledOpen, defaultOpen, onOpenChange, search: controlledSearch, defaultSearch, onSearchChange, shouldFilter, loading, error, trigger, shortcut, }: CommandPaletteProps): React.JSX.Element;
@@ -2,9 +2,8 @@ import * as React from "react";
2
2
  import type { DatePickerProp } from "../../props/components/data-entry.prop.js";
3
3
  export type { DatePickerProp, DatePickerProp as DatePickerProps, } from "../../props/components/data-entry.prop.js";
4
4
  /**
5
- * DatePicker — WAI-ARIA date combobox. A real, typeable `<input>` holds the value as an
6
- * ISO-8601 `yyyy-MM-dd` string (the international standard): it is form-submittable (give it a
7
- * `name`), screen-reader friendly, and e2e-testable by simply filling the input. The calendar
8
- * popover is the visual affordance; typing and the calendar stay in sync.
5
+ * DatePicker — WAI-ARIA date combobox. A real, typeable `<input>` holds the value as an ISO-8601
6
+ * `yyyy-MM-dd` string (the international standard): it is form-submittable (give it a `name`),
7
+ * screen-reader friendly, and e2e-testable by simply filling the input.
9
8
  */
10
- export declare function DatePicker({ value: valueProp, defaultValue, onValueChange, placeholder, disabled, className, id, name, locale: localeProp, fromDate, toDate, allowClear, ...ariaProps }: DatePickerProp): React.JSX.Element;
9
+ export declare function DatePicker({ value: valueProp, defaultValue, onValueChange, placeholder, disabled, className, id, name, locale: localeProp, showToday, showClose, fromDate, toDate, allowClear, ...ariaProps }: DatePickerProp): React.JSX.Element;
@@ -5,7 +5,7 @@ import { CalendarIcon, X } from "lucide-react";
5
5
  import { usePickerLocales, useTranslation } from "../../i18n/use-translation.js";
6
6
  import { parseDateInput, toIsoDate } from "../../lib/datetime/parse.js";
7
7
  import { useControlledLatch } from "../../lib/hooks.js";
8
- import { pickFieldA11y } from "../../lib/field-a11y.js";
8
+ import { pickFieldA11y, useFieldIdentity } from "../../lib/field-a11y.js";
9
9
  import { cn } from "../../lib/utils.js";
10
10
  import { Input } from "./input.js";
11
11
  import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from "../data-display/popover.js";
@@ -21,6 +21,8 @@ function DatePicker({
21
21
  id,
22
22
  name,
23
23
  locale: localeProp,
24
+ showToday,
25
+ showClose,
24
26
  fromDate,
25
27
  toDate,
26
28
  allowClear = true,
@@ -30,6 +32,9 @@ function DatePicker({
30
32
  const { dayPickerLocale } = usePickerLocales(localeProp);
31
33
  const [open, setOpen] = React.useState(false);
32
34
  const fieldA11y = pickFieldA11y(ariaProps);
35
+ const identity = useFieldIdentity({ id, name, "data-field": fieldA11y["data-field"] });
36
+ const resolvedName = name ?? identity.name;
37
+ const resolvedField = fieldA11y["data-field"] ?? identity["data-field"];
33
38
  const reactId = React.useId();
34
39
  const dialogId = `${id ?? reactId}-dialog`;
35
40
  const isControlled = useControlledLatch(valueProp !== void 0);
@@ -66,7 +71,8 @@ function DatePicker({
66
71
  Input,
67
72
  {
68
73
  id,
69
- name,
74
+ name: resolvedName,
75
+ "data-field": resolvedField,
70
76
  value: text,
71
77
  disabled,
72
78
  placeholder: resolvedPlaceholder,
@@ -149,7 +155,10 @@ function DatePicker({
149
155
  ...toDate ? [{ after: toDate }] : []
150
156
  ],
151
157
  startMonth: fromDate,
152
- endMonth: toDate
158
+ endMonth: toDate,
159
+ showToday,
160
+ showClose,
161
+ onClose: () => setOpen(false)
153
162
  }
154
163
  )
155
164
  }
@@ -8,4 +8,4 @@ export type { DateRangePickerProp, DateRangePickerProp as DateRangePickerProps,
8
8
  * `${name}_to`, screen-reader friendly, e2e-testable by filling either input); the
9
9
  * range calendar is the visual affordance.
10
10
  */
11
- export declare function DateRangePicker({ value: valueProp, defaultValue, onValueChange, placeholder, disabled, className, id, name, locale: localeProp, fromDate, toDate, allowClear, ...ariaProps }: DateRangePickerProp): React.JSX.Element;
11
+ export declare function DateRangePicker({ value: valueProp, defaultValue, onValueChange, placeholder, disabled, className, id, name, locale: localeProp, showToday, showClose, fromDate, toDate, allowClear, ...ariaProps }: DateRangePickerProp): React.JSX.Element;
@@ -5,7 +5,7 @@ import { ArrowRight, CalendarIcon, X } from "lucide-react";
5
5
  import { usePickerLocales, useTranslation } from "../../i18n/use-translation.js";
6
6
  import { parseDateInput, toIsoDate } from "../../lib/datetime/index.js";
7
7
  import { useControlledLatch } from "../../lib/hooks.js";
8
- import { pickGroupFieldA11y } from "../../lib/field-a11y.js";
8
+ import { pickGroupFieldA11y, useFieldIdentity } from "../../lib/field-a11y.js";
9
9
  import { cn } from "../../lib/utils.js";
10
10
  import { Popover, PopoverAnchor, PopoverContent, PopoverTrigger } from "../data-display/popover.js";
11
11
  import { Calendar } from "./calendar.js";
@@ -20,6 +20,8 @@ function DateRangePicker({
20
20
  id,
21
21
  name,
22
22
  locale: localeProp,
23
+ showToday,
24
+ showClose,
23
25
  fromDate,
24
26
  toDate,
25
27
  allowClear = true,
@@ -33,6 +35,9 @@ function DateRangePicker({
33
35
  const groupId = id ?? autoId;
34
36
  const fromId = `${groupId}-from`;
35
37
  const toId = `${groupId}-to`;
38
+ const identity = useFieldIdentity({ id: groupId, name, "data-field": groupA11y["data-field"] });
39
+ const rangeField = groupA11y["data-field"] ?? identity["data-field"];
40
+ const rangeName = name ?? identity.name;
36
41
  const isControlled = useControlledLatch(valueProp !== void 0);
37
42
  const [internalValue, setInternalValue] = React.useState(defaultValue);
38
43
  const value = isControlled ? valueProp : internalValue;
@@ -77,13 +82,14 @@ function DateRangePicker({
77
82
  role: "group",
78
83
  id: groupId,
79
84
  ...groupA11y,
85
+ "data-field": rangeField,
80
86
  "aria-disabled": disabled ? true : void 0,
87
+ "data-state": open ? "open" : "closed",
81
88
  className: cn(
82
89
  // One input-styled shell for the whole range — the shared composite-field box, so
83
90
  // this and the month range picker cannot drift into two slightly different fields.
84
91
  "ui-control ui-control-composite-field",
85
- "focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]",
86
- open && "border-ring ring-ring/50 ring-[3px]",
92
+ "aria-invalid:border-destructive",
87
93
  className
88
94
  ),
89
95
  onClick: () => {
@@ -94,7 +100,8 @@ function DateRangePicker({
94
100
  "input",
95
101
  {
96
102
  id: fromId,
97
- name: name ? `${name}_from` : void 0,
103
+ "data-field": rangeField ? `${rangeField}_from` : void 0,
104
+ name: rangeName ? `${rangeName}_from` : void 0,
98
105
  value: fromText,
99
106
  disabled,
100
107
  placeholder: resolvedPlaceholder,
@@ -118,7 +125,8 @@ function DateRangePicker({
118
125
  "input",
119
126
  {
120
127
  id: toId,
121
- name: name ? `${name}_to` : void 0,
128
+ "data-field": rangeField ? `${rangeField}_to` : void 0,
129
+ name: rangeName ? `${rangeName}_to` : void 0,
122
130
  value: toText,
123
131
  disabled,
124
132
  placeholder: resolvedPlaceholder,
@@ -186,7 +194,10 @@ function DateRangePicker({
186
194
  ...toDate ? [{ after: toDate }] : []
187
195
  ],
188
196
  startMonth: fromDate,
189
- endMonth: toDate
197
+ endMonth: toDate,
198
+ showToday,
199
+ showClose,
200
+ onClose: () => setOpen(false)
190
201
  }
191
202
  )
192
203
  }
@@ -3,10 +3,9 @@ import type { FormErrorsProp, FormErrorsProviderProp } from "../../props/compone
3
3
  import type { ErrorBagProp } from "../../props/vocabulary/index.js";
4
4
  export type { FormErrorsProp, FormErrorsProp as FormErrorsProps, FormErrorsProviderProp, FormErrorsProviderProp as FormErrorsProviderProps, } from "../../props/components/data-entry.prop.js";
5
5
  /**
6
- * Registry shared by a `Form` with its FormFields and `<FormErrors />`. Each mounted
7
- * `FormField name="…"` CLAIMS its error-bag key (it is the visible owner of that message);
8
- * `<FormErrors />` renders only the unclaimed remainder. Claims are reference-counted so
9
- * duplicate names and unmount order stay correct.
6
+ * Registry shared by a `Form` with its FormFields and `<FormErrors />`. Each mounted `FormField
7
+ * name="…"` CLAIMS its error-bag key (it is the visible owner of that message); `<FormErrors />`
8
+ * renders only the unclaimed remainder.
10
9
  */
11
10
  interface FormErrorsRegistryValue {
12
11
  errors: ErrorBagProp;
@@ -19,18 +18,9 @@ export declare function useFormErrorsRegistry(): FormErrorsRegistryValue | null;
19
18
  /** First message of a bag entry — Laravel arrays surface their first message on the field. */
20
19
  export declare function firstBagMessage(entry: string | string[] | undefined): string | undefined;
21
20
  /**
22
- * FormErrorsProvider — one shared error registry (error bag + claim set) over a region.
23
- * 兄弟 Form 群で 1 つのエラーバッグを共有するための公開プロバイダ。Two ways to get one:
24
- *
25
- * 1. `Form errors={…}` renders this provider itself (both `<form>` and `asChild` modes) —
26
- * the single-form case needs nothing else.
27
- * 2. An edit screen split into several sibling Card+Form sections (the standard exseli shape)
28
- * wraps the REGION in `<FormErrorsProvider errors={…}>` instead: Forms **without** their own
29
- * `errors` join the surrounding registry, every `FormField name="…"` inside claims into it,
30
- * and one `<FormErrors />` anywhere in the region renders the unclaimed remainder.
31
- *
32
- * A nested Form WITH its own `errors` starts a new registry that shadows this one — its claims
33
- * and messages stay inside it.
21
+ * FormErrorsProvider — one shared error registry (error bag + claim set) over a region. 兄弟 Form 群で
22
+ * 1 つのエラーバッグを共有するための公開プロバイダ。Two ways to get one: 1. `Form errors={…}` renders this provider itself
23
+ * (both `<form>` and `asChild` modes) — the single-form case needs nothing else. 2.
34
24
  */
35
25
  export declare function FormErrorsProvider({ errors, children }: FormErrorsProviderProp): React.JSX.Element;
36
26
  /** FormField calls this to claim its error-bag key while mounted (no-op outside a Form). */
@@ -39,7 +29,6 @@ export declare function useClaimErrorKey(name: string | undefined): void;
39
29
  * FormErrors — renders the error-bag entries no mounted `FormField name="…"` displays: server
40
30
  * validation errors attached to hidden/derived fields (an `action_mode`, a `page`, a source-record
41
31
  * id) that would otherwise fail silently. Place it inside a `Form errors={…}` — typically above
42
- * the fields; it renders nothing while every entry is claimed or the bag is empty. Composed on
43
- * `Alert tone="destructive"` (role="alert"), so appearing messages are announced assertively.
32
+ * the fields; it renders nothing while every entry is claimed or the bag is empty.
44
33
  */
45
34
  export declare function FormErrors({ errors: errorsProp, title, className }: FormErrorsProp): React.JSX.Element | null;
@@ -1,4 +1,4 @@
1
1
  import * as React from "react";
2
2
  import type { FormFieldProp } from "../../props/components/data-entry.prop.js";
3
3
  export type { FormFieldProp, FormFieldProp as FormFieldProps, } from "../../props/components/data-entry.prop.js";
4
- export declare function FormField({ id, name, label, required, helper, error: errorProp, labelAddon, layout: layoutProp, labelWidth: labelWidthProp, controlWidth: controlWidthProp, colSpan, className, children, staticText, }: FormFieldProp): React.JSX.Element;
4
+ export declare function FormField({ id, name, field, label, required, helper, error: errorProp, labelAddon, layout: layoutProp, labelWidth: labelWidthProp, controlWidth: controlWidthProp, colSpan, className, children, staticText, }: FormFieldProp): React.JSX.Element;
@@ -3,7 +3,8 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { Label } from "../data-entry/label.js";
5
5
  import { cn } from "../../lib/utils.js";
6
- import { FieldNameContext, mergeAriaIds } from "../../lib/field-a11y.js";
6
+ import { FieldIdentityContext, FieldNameContext, mergeAriaIds } from "../../lib/field-a11y.js";
7
+ import { useOptionalAppContext } from "../../app/app-provider.js";
7
8
  import { useFormLayout } from "./form.js";
8
9
  import { firstBagMessage, useClaimErrorKey, useFormErrorsRegistry } from "./form-errors.js";
9
10
  const toCssLength = (v) => typeof v === "number" ? `${v}px` : v;
@@ -11,6 +12,7 @@ const FOCUSABLE_SELECTOR = 'input:not([type="hidden"]), select, textarea, button
11
12
  function FormField({
12
13
  id,
13
14
  name,
15
+ field,
14
16
  label,
15
17
  required,
16
18
  helper,
@@ -38,6 +40,8 @@ function FormField({
38
40
  const labelId = `${resolvedId}-label`;
39
41
  const helperId = helper ? `${resolvedId}-helper` : void 0;
40
42
  const errorId = error ? `${resolvedId}-error` : void 0;
43
+ const fieldKey = field ?? name ?? id;
44
+ const emitFieldNames = useOptionalAppContext()?.emitFieldNames ?? false;
41
45
  const isStatic = staticText !== void 0;
42
46
  if (!isStatic && typeof process !== "undefined" && process.env?.NODE_ENV !== "production" && !React.isValidElement(children)) {
43
47
  console.warn(
@@ -48,21 +52,26 @@ function FormField({
48
52
  () => ({ labelId, label: typeof label === "string" ? label : void 0 }),
49
53
  [labelId, label]
50
54
  );
55
+ const fieldIdentityContext = React.useMemo(
56
+ () => fieldKey === void 0 ? null : { emitName: emitFieldNames },
57
+ [fieldKey, emitFieldNames]
58
+ );
51
59
  const childProps = React.isValidElement(children) ? children.props : void 0;
52
60
  const mergeIds = mergeAriaIds;
53
61
  const childWithA11y = isStatic ? (
54
- // Byte-for-byte the same value typography as `Descriptions.Item`'s `dd` (gh#294), so a
55
62
  // read-only FormField row and a Descriptions value are indistinguishable when mixed. That
56
- // used to be two copies of the literal `text-sm` kept in sync by this comment; both call sites
57
- // now read the SAME token pair (#319), so a service retunes both from one place and they
58
63
  // cannot drift. --descriptions-value-line-height is the mandatory companion: `text-sm` also
59
- // set Tailwind's `--text-sm--line-height`, which the theme never remaps (the gh#260 bug).
60
64
  /* @__PURE__ */ jsx("span", { className: "text-[length:var(--descriptions-value-font-size)] leading-[var(--descriptions-value-line-height)] break-all", children: staticText })
61
65
  ) : React.isValidElement(children) ? React.cloneElement(children, {
62
66
  // The label is associated via aria-labelledby (not <label for>): composite
63
67
  // controls (Radio.Group, checkbox lists, range pairs) have no labelable root,
64
68
  // and a dangling `for` triggers Chrome's "Incorrect use of <label>" issue.
65
69
  id: childProps?.id ?? resolvedId,
70
+ // Read the child's own value first in BOTH cases: cloneElement
71
+ // overwrites every key present in the config bag, `undefined` included, so a bare
72
+ // `"data-field": fieldKey` would erase a value the control set for itself.
73
+ "data-field": childProps?.["data-field"] ?? fieldKey,
74
+ ...emitFieldNames ? { name: childProps?.name ?? fieldKey } : void 0,
66
75
  "aria-labelledby": childProps?.["aria-labelledby"] ?? labelId,
67
76
  // Redundant `aria-label` fallback (belt-and-suspenders): the accessible name is the
68
77
  // SAME string as the visible label, just reachable even if an aria-labelledby lookup
@@ -125,7 +134,7 @@ function FormField({
125
134
  labelAddon
126
135
  ] }),
127
136
  /* @__PURE__ */ jsxs("div", { "data-slot": "form-field-control", className: "ui-form-field-control", children: [
128
- isStatic ? childWithA11y : /* @__PURE__ */ jsx(FieldNameContext.Provider, { value: fieldNameContext, children: childWithA11y }),
137
+ isStatic ? childWithA11y : /* @__PURE__ */ jsx(FieldNameContext.Provider, { value: fieldNameContext, children: /* @__PURE__ */ jsx(FieldIdentityContext.Provider, { value: fieldIdentityContext, children: childWithA11y }) }),
129
138
  helper ? /* @__PURE__ */ jsx("p", { id: helperId, className: "text-muted-foreground text-xs", children: helper }) : null,
130
139
  error ? /* @__PURE__ */ jsx("p", { id: errorId, role: "alert", className: "text-destructive text-xs", children: error }) : null
131
140
  ] })
@@ -14,15 +14,7 @@ export declare function useFormLayout(): FormLayoutContextValue | null;
14
14
  /**
15
15
  * Form — Ant-style layout container. Renders a `<form>` and provides layout (vertical/horizontal),
16
16
  * label/control width, label alignment, and a responsive collapse breakpoint to every FormField
17
- * inside it. A FormField may override any of these per-field. Optionally lays fields out in a
18
- * responsive multi-column grid via `columns` (reuses ResponsiveGrid — mobile-first, 1 col on small).
19
- *
20
- * `asChild` renders the caller's own element instead of a `<form>`, keeping only the layout
21
- * context. Routing libraries own the form element — Inertia's `<Form action method>` and
22
- * TanStack Form both render their own — so without this every such consumer has to choose
23
- * between the router's submission handling and the design system's field layout, and ends up
24
- * hand-rolling label columns per field. Two `<form>` elements cannot nest, so wrapping is not
25
- * an option: `<Form asChild layout="horizontal" labelWidth={174}><InertiaForm …/></Form>`.
17
+ * inside it.
26
18
  */
27
19
  export declare const Form: React.ForwardRefExoticComponent<React.FormHTMLAttributes<HTMLFormElement> & {
28
20
  layout?: FormLayoutProp;
@@ -1,37 +1,39 @@
1
1
  import * as React from "react";
2
- export type InputProps = React.InputHTMLAttributes<HTMLInputElement> & {
2
+ export type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> & {
3
+ /** Control height tier: `md` (default) or `sm`, the same tiers as SelectTrigger and NumberInput. */
4
+ size?: "sm" | "md";
3
5
  /** Show an inline ✕ that clears the field while it holds text (default false). */
4
6
  allowClear?: boolean;
5
7
  /** Called after the field is cleared via the inline ✕. */
6
8
  onClear?: () => void;
7
9
  /**
8
- * A leading affordance pinned inside the start of the field — e.g. a mail or
9
- * search icon (the common auth/search pattern). Decorative by default; the
10
- * input keeps the keyboard focus. Pairs with `trailingIcon`/`allowClear`.
10
+ * A leading affordance pinned inside the start of the field — e.g. a mail or search icon (the
11
+ * common auth/search pattern). Decorative by default; the input keeps the keyboard focus.
11
12
  */
12
13
  leadingIcon?: React.ReactNode;
13
14
  /**
14
- * A trailing affordance pinned inside the field — e.g. a calendar / clock popover
15
- * trigger button. ONE trailing icon shows at a time: when `allowClear` and the field
16
- * holds a value the clear ✕ REPLACES this icon; otherwise this icon shows. Never both.
15
+ * A trailing affordance pinned inside the field — e.g. a calendar / clock popover trigger
16
+ * button. ONE trailing icon shows at a time: when `allowClear` and the field holds a value the
17
+ * clear ✕ REPLACES this icon; otherwise this icon shows.
17
18
  */
18
19
  trailingIcon?: React.ReactNode;
19
20
  };
20
- export declare const Input: React.ForwardRefExoticComponent<React.InputHTMLAttributes<HTMLInputElement> & {
21
+ export declare const Input: React.ForwardRefExoticComponent<Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> & {
22
+ /** Control height tier: `md` (default) or `sm`, the same tiers as SelectTrigger and NumberInput. */
23
+ size?: "sm" | "md";
21
24
  /** Show an inline ✕ that clears the field while it holds text (default false). */
22
25
  allowClear?: boolean;
23
26
  /** Called after the field is cleared via the inline ✕. */
24
27
  onClear?: () => void;
25
28
  /**
26
- * A leading affordance pinned inside the start of the field — e.g. a mail or
27
- * search icon (the common auth/search pattern). Decorative by default; the
28
- * input keeps the keyboard focus. Pairs with `trailingIcon`/`allowClear`.
29
+ * A leading affordance pinned inside the start of the field — e.g. a mail or search icon (the
30
+ * common auth/search pattern). Decorative by default; the input keeps the keyboard focus.
29
31
  */
30
32
  leadingIcon?: React.ReactNode;
31
33
  /**
32
- * A trailing affordance pinned inside the field — e.g. a calendar / clock popover
33
- * trigger button. ONE trailing icon shows at a time: when `allowClear` and the field
34
- * holds a value the clear ✕ REPLACES this icon; otherwise this icon shows. Never both.
34
+ * A trailing affordance pinned inside the field — e.g. a calendar / clock popover trigger
35
+ * button. ONE trailing icon shows at a time: when `allowClear` and the field holds a value the
36
+ * clear ✕ REPLACES this icon; otherwise this icon shows.
35
37
  */
36
38
  trailingIcon?: React.ReactNode;
37
39
  } & React.RefAttributes<HTMLInputElement>>;