@godxjp/ui 19.6.0 → 20.1.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 (326) hide show
  1. package/README.md +8 -2
  2. package/dist/app/theme-axes.d.ts +2 -0
  3. package/dist/app/theme-axes.js +45 -0
  4. package/dist/components/charts/chart-cartesian.d.ts +2 -1
  5. package/dist/components/charts/chart-cartesian.js +52 -3
  6. package/dist/components/charts/chart-category-axis.d.ts +55 -0
  7. package/dist/components/charts/chart-category-axis.js +93 -0
  8. package/dist/components/charts/chart-frame.d.ts +10 -1
  9. package/dist/components/charts/chart-frame.js +19 -3
  10. package/dist/components/charts/compact-bar-trend.d.ts +1 -1
  11. package/dist/components/charts/compact-bar-trend.js +2 -0
  12. package/dist/components/charts/pie-chart.d.ts +1 -1
  13. package/dist/components/charts/pie-chart.js +12 -1
  14. package/dist/components/charts/recharts-peer.d.ts +49 -0
  15. package/dist/components/charts/recharts-peer.js +45 -0
  16. package/dist/components/data-display/card.d.ts +14 -3
  17. package/dist/components/data-display/card.js +22 -4
  18. package/dist/components/data-display/code-block.js +6 -2
  19. package/dist/components/data-display/collapsible.d.ts +23 -4
  20. package/dist/components/data-display/collapsible.js +119 -4
  21. package/dist/components/data-display/data-table.d.ts +39 -4
  22. package/dist/components/data-display/data-table.js +802 -270
  23. package/dist/components/data-display/descriptions.d.ts +27 -6
  24. package/dist/components/data-display/descriptions.js +58 -17
  25. package/dist/components/data-display/index.d.ts +5 -1
  26. package/dist/components/data-display/index.js +4 -0
  27. package/dist/components/data-display/legend.d.ts +15 -0
  28. package/dist/components/data-display/legend.js +11 -0
  29. package/dist/components/data-display/list-row.d.ts +10 -1
  30. package/dist/components/data-display/list-row.js +8 -2
  31. package/dist/components/data-display/popover.d.ts +60 -7
  32. package/dist/components/data-display/popover.js +268 -39
  33. package/dist/components/data-display/progress.d.ts +50 -2
  34. package/dist/components/data-display/progress.js +57 -9
  35. package/dist/components/data-display/range-timeline.d.ts +38 -0
  36. package/dist/components/data-display/range-timeline.js +161 -0
  37. package/dist/components/data-display/scroll-area.js +13 -2
  38. package/dist/components/data-display/service-launcher-card.js +10 -10
  39. package/dist/components/data-display/table.d.ts +11 -3
  40. package/dist/components/data-display/table.js +48 -18
  41. package/dist/components/data-display/tree-list.js +4 -9
  42. package/dist/components/data-entry/calendar.d.ts +2 -2
  43. package/dist/components/data-entry/calendar.js +79 -33
  44. package/dist/components/data-entry/cascader.d.ts +1 -1
  45. package/dist/components/data-entry/cascader.js +188 -24
  46. package/dist/components/data-entry/checkbox.d.ts +19 -6
  47. package/dist/components/data-entry/checkbox.js +55 -16
  48. package/dist/components/data-entry/choice-option.d.ts +1 -1
  49. package/dist/components/data-entry/color-picker.d.ts +1 -1
  50. package/dist/components/data-entry/color-picker.js +17 -5
  51. package/dist/components/data-entry/control-appearance.d.ts +64 -0
  52. package/dist/components/data-entry/control-appearance.js +39 -0
  53. package/dist/components/data-entry/control-surface.d.ts +61 -0
  54. package/dist/components/data-entry/control-surface.js +39 -0
  55. package/dist/components/data-entry/date-picker.d.ts +1 -1
  56. package/dist/components/data-entry/date-picker.js +344 -113
  57. package/dist/components/data-entry/date-range-picker.d.ts +2 -2
  58. package/dist/components/data-entry/date-range-picker.js +278 -140
  59. package/dist/components/data-entry/field.js +0 -1
  60. package/dist/components/data-entry/form-field.d.ts +1 -1
  61. package/dist/components/data-entry/form-field.js +39 -4
  62. package/dist/components/data-entry/form.d.ts +4 -0
  63. package/dist/components/data-entry/form.js +5 -3
  64. package/dist/components/data-entry/index.d.ts +7 -3
  65. package/dist/components/data-entry/index.js +10 -1
  66. package/dist/components/data-entry/input-otp.d.ts +1 -1
  67. package/dist/components/data-entry/input.d.ts +12 -34
  68. package/dist/components/data-entry/input.js +92 -24
  69. package/dist/components/data-entry/label.d.ts +3 -2
  70. package/dist/components/data-entry/label.js +23 -10
  71. package/dist/components/data-entry/month-picker.d.ts +2 -2
  72. package/dist/components/data-entry/month-picker.js +47 -10
  73. package/dist/components/data-entry/month-range-picker.d.ts +2 -2
  74. package/dist/components/data-entry/month-range-picker.js +51 -11
  75. package/dist/components/data-entry/number-input.d.ts +7 -0
  76. package/dist/components/data-entry/number-input.js +147 -98
  77. package/dist/components/data-entry/password-input.d.ts +1 -1
  78. package/dist/components/data-entry/radio.d.ts +1 -1
  79. package/dist/components/data-entry/radio.js +61 -13
  80. package/dist/components/data-entry/search-input.d.ts +1 -1
  81. package/dist/components/data-entry/search-input.js +16 -2
  82. package/dist/components/data-entry/search-select.d.ts +2 -2
  83. package/dist/components/data-entry/search-select.js +209 -78
  84. package/dist/components/data-entry/select.d.ts +22 -4
  85. package/dist/components/data-entry/select.js +215 -163
  86. package/dist/components/data-entry/slider.d.ts +9 -1
  87. package/dist/components/data-entry/slider.js +87 -9
  88. package/dist/components/data-entry/switch.d.ts +3 -0
  89. package/dist/components/data-entry/switch.js +29 -3
  90. package/dist/components/data-entry/textarea.d.ts +14 -56
  91. package/dist/components/data-entry/textarea.js +80 -33
  92. package/dist/components/data-entry/time-picker.d.ts +2 -2
  93. package/dist/components/data-entry/time-picker.js +333 -109
  94. package/dist/components/data-entry/time-range-picker.d.ts +5 -0
  95. package/dist/components/data-entry/time-range-picker.js +89 -0
  96. package/dist/components/data-entry/transfer.d.ts +1 -1
  97. package/dist/components/data-entry/transfer.js +99 -31
  98. package/dist/components/data-entry/tree-select-strategy.d.ts +1 -1
  99. package/dist/components/data-entry/tree-select.d.ts +1 -1
  100. package/dist/components/data-entry/tree-select.js +197 -92
  101. package/dist/components/data-entry/tree-utils.d.ts +1 -1
  102. package/dist/components/data-entry/tree-utils.js +7 -14
  103. package/dist/components/data-entry/upload-files.d.ts +2 -0
  104. package/dist/components/data-entry/upload-files.js +31 -0
  105. package/dist/components/data-entry/upload-request.d.ts +4 -0
  106. package/dist/components/data-entry/upload-request.js +53 -0
  107. package/dist/components/data-entry/upload-types.d.ts +28 -0
  108. package/dist/components/data-entry/upload-types.js +2 -0
  109. package/dist/components/data-entry/upload.d.ts +2 -2
  110. package/dist/components/data-entry/upload.js +482 -117
  111. package/dist/components/feedback/dialog.d.ts +105 -38
  112. package/dist/components/feedback/dialog.js +268 -193
  113. package/dist/components/feedback/overlay-close-focus.d.ts +31 -0
  114. package/dist/components/feedback/overlay-close-focus.js +31 -0
  115. package/dist/components/feedback/overlay-header-tone.d.ts +1 -1
  116. package/dist/components/feedback/sheet.d.ts +53 -11
  117. package/dist/components/feedback/sheet.js +150 -81
  118. package/dist/components/feedback/tooltip.d.ts +51 -7
  119. package/dist/components/feedback/tooltip.js +107 -25
  120. package/dist/components/general/button.d.ts +1 -1
  121. package/dist/components/general/button.js +7 -3
  122. package/dist/components/general/index.d.ts +1 -0
  123. package/dist/components/general/index.js +2 -0
  124. package/dist/components/general/logo.d.ts +17 -0
  125. package/dist/components/general/logo.js +22 -16
  126. package/dist/components/general/typography.d.ts +3 -0
  127. package/dist/components/general/typography.js +15 -1
  128. package/dist/components/general/visually-hidden.d.ts +3 -0
  129. package/dist/components/general/visually-hidden.js +9 -0
  130. package/dist/components/layout/app-launcher.d.ts +34 -0
  131. package/dist/components/layout/app-launcher.js +228 -0
  132. package/dist/components/layout/app-shell.d.ts +3 -1
  133. package/dist/components/layout/app-shell.js +69 -12
  134. package/dist/components/layout/aspect-ratio.js +0 -1
  135. package/dist/components/layout/auth-divider.js +0 -1
  136. package/dist/components/layout/breadcrumb.d.ts +14 -2
  137. package/dist/components/layout/breadcrumb.js +46 -4
  138. package/dist/components/layout/flex.d.ts +1 -1
  139. package/dist/components/layout/flex.js +41 -3
  140. package/dist/components/layout/index.d.ts +3 -0
  141. package/dist/components/layout/index.js +5 -1
  142. package/dist/components/layout/nav-surface.d.ts +26 -0
  143. package/dist/components/layout/nav-surface.js +17 -0
  144. package/dist/components/layout/org-switcher.d.ts +5 -1
  145. package/dist/components/layout/org-switcher.js +25 -4
  146. package/dist/components/layout/page-container.d.ts +1 -1
  147. package/dist/components/layout/page-container.js +5 -3
  148. package/dist/components/layout/responsive-grid.d.ts +16 -2
  149. package/dist/components/layout/responsive-grid.js +29 -2
  150. package/dist/components/layout/separator.js +0 -1
  151. package/dist/components/layout/sidebar.js +4 -1
  152. package/dist/components/layout/split-pane.d.ts +14 -1
  153. package/dist/components/layout/split-pane.js +26 -13
  154. package/dist/components/layout/topbar-item.d.ts +3 -0
  155. package/dist/components/layout/topbar-item.js +19 -5
  156. package/dist/components/layout/topbar.d.ts +1 -1
  157. package/dist/components/layout/topbar.js +27 -6
  158. package/dist/components/navigation/app-setting-picker.js +21 -2
  159. package/dist/components/navigation/app-setting-toggle.d.ts +16 -0
  160. package/dist/components/navigation/app-setting-toggle.js +96 -0
  161. package/dist/components/navigation/dropdown-menu.d.ts +227 -18
  162. package/dist/components/navigation/dropdown-menu.js +402 -118
  163. package/dist/components/navigation/index.d.ts +2 -0
  164. package/dist/components/navigation/index.js +2 -0
  165. package/dist/components/navigation/pagination-utils.d.ts +2 -1
  166. package/dist/components/navigation/pagination.d.ts +2 -2
  167. package/dist/components/navigation/pagination.js +155 -83
  168. package/dist/components/navigation/steps.d.ts +2 -2
  169. package/dist/components/navigation/steps.js +29 -4
  170. package/dist/components/navigation/tabs.d.ts +29 -16
  171. package/dist/components/navigation/tabs.js +374 -144
  172. package/dist/components/ui/accordion.d.ts +50 -5
  173. package/dist/components/ui/accordion.js +239 -33
  174. package/dist/components/ui/aspect-ratio.d.ts +23 -2
  175. package/dist/components/ui/aspect-ratio.js +15 -13
  176. package/dist/components/ui/avatar.d.ts +29 -4
  177. package/dist/components/ui/avatar.js +111 -25
  178. package/dist/components/ui/hover-card.d.ts +42 -4
  179. package/dist/components/ui/hover-card.js +183 -27
  180. package/dist/components/ui/input-otp.d.ts +26 -28
  181. package/dist/components/ui/input-otp.js +50 -7
  182. package/dist/components/ui/label.js +0 -1
  183. package/dist/components/ui/password-input.d.ts +36 -2
  184. package/dist/components/ui/password-input.js +27 -7
  185. package/dist/components/ui/rating.d.ts +25 -0
  186. package/dist/components/ui/rating.js +67 -27
  187. package/dist/components/ui/segmented.d.ts +12 -3
  188. package/dist/components/ui/segmented.js +17 -2
  189. package/dist/components/ui/separator.d.ts +12 -2
  190. package/dist/components/ui/separator.js +30 -9
  191. package/dist/components/ui/tag-input.d.ts +45 -0
  192. package/dist/components/ui/tag-input.js +109 -27
  193. package/dist/components/ui/toggle-group.d.ts +50 -5
  194. package/dist/components/ui/toggle-group.js +79 -20
  195. package/dist/components/ui/toggle.d.ts +31 -5
  196. package/dist/components/ui/toggle.js +42 -3
  197. package/dist/form/form-context.d.ts +29 -0
  198. package/dist/form/form-context.js +44 -4
  199. package/dist/form/form-field-array.d.ts +22 -0
  200. package/dist/form/form-field-array.js +50 -0
  201. package/dist/form/form-field-control.d.ts +2 -1
  202. package/dist/form/form-field-control.js +116 -40
  203. package/dist/form/form-root.d.ts +2 -1
  204. package/dist/form/form-root.js +142 -23
  205. package/dist/form/index.d.ts +3 -1
  206. package/dist/form/index.js +12 -1
  207. package/dist/i18n/messages/en.json +64 -5
  208. package/dist/i18n/messages/ja.json +64 -5
  209. package/dist/i18n/messages/vi.json +64 -5
  210. package/dist/inertia/index.d.ts +20 -0
  211. package/dist/inertia/index.js +60 -1
  212. package/dist/lib/control-styles.d.ts +25 -3
  213. package/dist/lib/control-styles.js +9 -3
  214. package/dist/lib/datetime/picker-format.d.ts +8 -0
  215. package/dist/lib/datetime/picker-format.js +54 -0
  216. package/dist/lib/slot.d.ts +32 -0
  217. package/dist/lib/slot.js +22 -0
  218. package/dist/lib/variants.d.ts +22 -3
  219. package/dist/lib/variants.js +56 -1
  220. package/dist/props/components/app.prop.d.ts +25 -1
  221. package/dist/props/components/charts.prop.d.ts +21 -0
  222. package/dist/props/components/data-display.prop.d.ts +72 -4
  223. package/dist/props/components/data-entry.prop.d.ts +718 -46
  224. package/dist/props/components/form.prop.d.ts +142 -4
  225. package/dist/props/components/general.prop.d.ts +17 -1
  226. package/dist/props/components/index.d.ts +3 -3
  227. package/dist/props/components/layout.prop.d.ts +281 -11
  228. package/dist/props/components/navigation.prop.d.ts +114 -4
  229. package/dist/props/registry.d.ts +397 -11
  230. package/dist/props/registry.js +526 -11
  231. package/dist/props/vocabulary/content.prop.d.ts +1 -1
  232. package/dist/props/vocabulary/data.prop.d.ts +179 -1
  233. package/dist/props/vocabulary/index.d.ts +5 -5
  234. package/dist/props/vocabulary/interaction.prop.d.ts +68 -3
  235. package/dist/props/vocabulary/layout.prop.d.ts +57 -1
  236. package/dist/props/vocabulary/navigation.prop.d.ts +40 -0
  237. package/dist/props/vocabulary/shared.prop.d.ts +33 -0
  238. package/dist/styles/badge-layout.css +2 -1
  239. package/dist/styles/card-layout.css +26 -4
  240. package/dist/styles/chart-layout.css +15 -0
  241. package/dist/styles/control.css +657 -15
  242. package/dist/styles/core.css +5 -2
  243. package/dist/styles/data-display-layout.css +313 -6
  244. package/dist/styles/data-entry-layout.css +13 -0
  245. package/dist/styles/focus-ring.css +4 -0
  246. package/dist/styles/index.css +5 -2
  247. package/dist/styles/layout.css +327 -4
  248. package/dist/styles/navigation-layout.css +227 -0
  249. package/dist/styles/shell-layout.css +369 -13
  250. package/dist/styles/table-layout.css +95 -6
  251. package/dist/styles/text-layout.css +10 -4
  252. package/dist/tokens/base.css +2 -1
  253. package/dist/tokens/components/badge.css +1 -0
  254. package/dist/tokens/components/chart.css +6 -0
  255. package/dist/tokens/components/control.css +79 -2
  256. package/dist/tokens/components/data-display.css +20 -0
  257. package/dist/tokens/components/descriptions.css +11 -0
  258. package/dist/tokens/components/flex.css +8 -0
  259. package/dist/tokens/components/navigation.css +55 -0
  260. package/dist/tokens/components/shell.css +53 -3
  261. package/dist/tokens/components/table.css +14 -0
  262. package/dist/tokens/foundation.css +2 -0
  263. package/dist/tokens/semantic/layout.css +9 -0
  264. package/docs/COMPONENTS.md +9 -3
  265. package/docs/CONSUMER-RULES.md +13 -0
  266. package/docs/DESIGN-AUTHORITY.md +145 -83
  267. package/docs/DEVELOPMENT.md +4 -3
  268. package/docs/FORMS.md +151 -6
  269. package/docs/FRAME-COVERAGE-REPORT.md +32 -17
  270. package/docs/README.md +15 -15
  271. package/docs/STANDARDS-vocabulary-tokens.md +1 -1
  272. package/docs/TESTING.md +15 -6
  273. package/docs/WHAT-BELONGS-HERE.md +179 -0
  274. package/docs/charts/cjk-category-axis.tsx +81 -0
  275. package/docs/data-display/card/index.tsx +22 -0
  276. package/docs/data-display/data-table/examples/antd-parity.tsx +257 -0
  277. package/docs/data-display/data-table/index.tsx +23 -0
  278. package/docs/data-display/descriptions.tsx +41 -0
  279. package/docs/data-display/legend.tsx +145 -0
  280. package/docs/data-display/progress.tsx +32 -0
  281. package/docs/data-display/scroll-area.tsx +31 -25
  282. package/docs/data-display/table.tsx +104 -45
  283. package/docs/data-display/timeline.tsx +41 -0
  284. package/docs/data-entry/date-picker.tsx +85 -0
  285. package/docs/data-entry/date-range-picker.tsx +26 -0
  286. package/docs/data-entry/form-dynamic-fields.tsx +199 -0
  287. package/docs/data-entry/form.tsx +74 -4
  288. package/docs/data-entry/input-otp.tsx +24 -0
  289. package/docs/data-entry/input.tsx +46 -1
  290. package/docs/data-entry/month-range-picker.tsx +1 -1
  291. package/docs/data-entry/segmented.tsx +1 -1
  292. package/docs/data-entry/select.tsx +29 -2
  293. package/docs/data-entry/switch.tsx +41 -0
  294. package/docs/data-entry/textarea.tsx +38 -0
  295. package/docs/data-entry/time-picker.tsx +85 -1
  296. package/docs/data-entry/time-range-picker.tsx +55 -0
  297. package/docs/data-entry/transfer.tsx +17 -0
  298. package/docs/data-entry/upload.tsx +56 -12
  299. package/docs/feedback/sheet.tsx +1 -1
  300. package/docs/feedback/tooltip.tsx +1 -1
  301. package/docs/general/activity.tsx +2 -2
  302. package/docs/general/button/index.tsx +14 -1
  303. package/docs/general/typography.tsx +14 -1
  304. package/docs/layout/app-launcher.tsx +151 -0
  305. package/docs/layout/app-shell-arrangements.tsx +225 -0
  306. package/docs/layout/app-shell.tsx +11 -0
  307. package/docs/layout/aspect-ratio.tsx +1 -1
  308. package/docs/layout/flex.tsx +50 -0
  309. package/docs/layout/responsive-grid.tsx +21 -1
  310. package/docs/layout/topbar.tsx +5 -9
  311. package/docs/navigation/app-setting-picker.tsx +37 -1
  312. package/docs/navigation/app-setting-toggle.tsx +111 -0
  313. package/docs/navigation/breadcrumb.tsx +48 -0
  314. package/docs/navigation/dropdown-menu.tsx +21 -0
  315. package/docs/navigation/pagination.tsx +52 -0
  316. package/docs/navigation/steps.tsx +37 -0
  317. package/docs/navigation/tabs.tsx +97 -1
  318. package/docs/query/button-refetch.tsx +1 -0
  319. package/package.json +28 -8
  320. package/scripts/_agent-setup.mjs +182 -3
  321. package/scripts/consumer-rule.md +98 -0
  322. package/scripts/guinea-pig-skill.md +322 -0
  323. package/scripts/init-guinea-pig.mjs +84 -0
  324. package/scripts/postinstall.mjs +13 -2
  325. package/scripts/ui-audit.mjs +351 -37
  326. /package/dist/tokens/{antd.generated.css → derived.css} +0 -0
@@ -23,7 +23,8 @@
23
23
  },
24
24
  "datePicker": {
25
25
  "placeholder": "Chọn ngày",
26
- "openCalendar": "Mở lịch"
26
+ "openCalendar": "Mở lịch",
27
+ "quarter": "Quý {quarter}"
27
28
  },
28
29
  "dateRangePicker": {
29
30
  "placeholder": "Chọn khoảng ngày",
@@ -39,7 +40,10 @@
39
40
  "openPicker": "Mở chọn giờ",
40
41
  "meridiem": "Buổi",
41
42
  "am": "SA",
42
- "pm": "CH"
43
+ "pm": "CH",
44
+ "now": "Bây giờ",
45
+ "confirm": "Chọn",
46
+ "second": "Giây"
43
47
  },
44
48
  "searchInput": {
45
49
  "placeholder": "Tìm kiếm…"
@@ -55,7 +59,7 @@
55
59
  "upload": {
56
60
  "dropzoneLabel": "Tải file lên",
57
61
  "dropzoneHint": "Kéo thả file vào đây, hoặc bấm để chọn",
58
- "dropzoneMeta": "Upload vào temp promote khi lưu form",
62
+ "dropzoneMeta": "Tệp đã chọn sẽ hiển thị tại đây.",
59
63
  "buttonLabel": "Chọn file",
60
64
  "addImage": "Thêm ảnh",
61
65
  "uploading": "Đang tải lên…",
@@ -75,7 +79,17 @@
75
79
  "statusFailed": "{count} tệp tải lên thất bại",
76
80
  "removeImage": "Xóa ảnh",
77
81
  "removeFile": "Xóa {name}",
78
- "cropDescription": "Kéo thanh thu phóng rồi lưu để cắt ảnh thành hình vuông."
82
+ "cropDescription": "Kéo thanh thu phóng rồi lưu để cắt ảnh thành hình vuông.",
83
+ "preview": "Xem trước",
84
+ "download": "Tải xuống",
85
+ "retry": "Thử lại",
86
+ "start": "Tải lên",
87
+ "cancel": "Huỷ",
88
+ "rejectAccept": "{name}: loại tệp không được phép.",
89
+ "rejectSize": "{name}: tệp quá lớn.",
90
+ "rejectCount": "{name}: đã đủ số lượng tệp.",
91
+ "rejectBeforeUpload": "{name}: kiểm tra tệp thất bại.",
92
+ "readFailed": "Không thể đọc thư mục đã chọn."
79
93
  },
80
94
  "cascader": {
81
95
  "placeholder": "Chọn…",
@@ -109,6 +123,9 @@
109
123
  "empty": "Không có kết quả",
110
124
  "error": "Không tải được lựa chọn"
111
125
  },
126
+ "selection": {
127
+ "overflow": "+{count}"
128
+ },
112
129
  "monthPicker": {
113
130
  "openGrid": "Mở chọn tháng",
114
131
  "previousYear": "Năm trước",
@@ -132,6 +149,14 @@
132
149
  },
133
150
  "formErrors": {
134
151
  "title": "Dữ liệu nhập có lỗi, vui lòng kiểm tra"
152
+ },
153
+ "form": {
154
+ "optional": "(không bắt buộc)",
155
+ "success": "Hợp lệ",
156
+ "warning": "Cần kiểm tra",
157
+ "error": "Không hợp lệ",
158
+ "validating": "Đang kiểm tra",
159
+ "submitFailed": "Không thể gửi biểu mẫu. Vui lòng thử lại."
135
160
  }
136
161
  },
137
162
  "feedback": {
@@ -154,6 +179,7 @@
154
179
  },
155
180
  "appShell": {
156
181
  "sidebarLabel": "Thanh bên",
182
+ "navRailLabel": "Không gian làm việc",
157
183
  "headerLabel": "Đầu trang",
158
184
  "mainLabel": "Nội dung chính",
159
185
  "footerLabel": "Chân trang",
@@ -246,6 +272,10 @@
246
272
  "denied": "Bạn không có quyền xem ma trận này",
247
273
  "deniedDescription": "Hãy đề nghị quản trị viên cấp quyền truy cập.",
248
274
  "loading": "Đang tải quyền…"
275
+ },
276
+ "progress": {
277
+ "ariaLabel": "Tiến độ",
278
+ "breakdownSeparator": ", "
249
279
  }
250
280
  },
251
281
  "ui": {
@@ -279,8 +309,13 @@
279
309
  }
280
310
  },
281
311
  "navigation": {
312
+ "tabs": {
313
+ "addTab": "Thêm tab",
314
+ "removeTab": "Đóng tab"
315
+ },
282
316
  "steps": {
283
317
  "ariaLabel": "Tiến trình",
318
+ "percentLabel": "Tiến độ bước hiện tại",
284
319
  "status": {
285
320
  "wait": "Đang chờ",
286
321
  "process": "Bước hiện tại",
@@ -318,6 +353,7 @@
318
353
  "page": "Trang {page}",
319
354
  "pageSize": "Số dòng mỗi trang",
320
355
  "pageSizeTrigger": "{size} / trang",
356
+ "jumpTo": "Tới trang",
321
357
  "pageSizeOption": "{size} / trang",
322
358
  "total": "Tổng {total} mục"
323
359
  },
@@ -347,6 +383,9 @@
347
383
  "logistics": "Logistics Teal",
348
384
  "partner": "Partner Orange",
349
385
  "slate": "HQ Slate"
386
+ },
387
+ "settingToggle": {
388
+ "label": "{setting}: {value}"
350
389
  }
351
390
  },
352
391
  "locale": {
@@ -390,7 +429,19 @@
390
429
  "error": "Không tải được danh sách này",
391
430
  "errorDescription": "Không lấy được dữ liệu. Vui lòng thử lại sau giây lát.",
392
431
  "denied": "Bạn không có quyền xem danh sách này",
393
- "deniedDescription": "Hãy đề nghị quản trị viên cấp quyền xem các bản ghi này."
432
+ "deniedDescription": "Hãy đề nghị quản trị viên cấp quyền xem các bản ghi này.",
433
+ "selectInvert": "Đảo lựa chọn",
434
+ "selectNone": "Bỏ chọn tất cả",
435
+ "selectionMenu": "Tuỳ chọn lựa chọn",
436
+ "filterColumn": "Lọc",
437
+ "filterReset": "Bỏ lọc",
438
+ "expandColumn": "Mở rộng",
439
+ "expandRow": "Mở rộng hàng",
440
+ "collapseRow": "Thu gọn hàng",
441
+ "sortAscending": "Sắp xếp tăng dần",
442
+ "sortDescending": "Sắp xếp giảm dần",
443
+ "sortCancel": "Bỏ sắp xếp",
444
+ "selectColumn": "Chọn"
394
445
  },
395
446
  "dataGrid": {
396
447
  "search": "Tìm kiếm",
@@ -458,5 +509,13 @@
458
509
  "summaryPie": "Biểu đồ tròn gồm {slices} phần",
459
510
  "summaryTrend": "Biểu đồ cột xu hướng gồm {points} điểm dữ liệu",
460
511
  "trendCurrent": "hiện tại"
512
+ },
513
+ "rangeTimeline": {
514
+ "outsideRange": "Ngoài khoảng đang xem",
515
+ "schedule": "Lịch công việc"
516
+ },
517
+ "textExamples": {
518
+ "preservedText": "Văn bản thuần",
519
+ "sampleText": "Dòng đầu\n Dòng thụt vào\n\nDòng cuối"
461
520
  }
462
521
  }
@@ -11,6 +11,7 @@ export interface InertiaFormLike<TData extends Record<string, unknown> = Record<
11
11
  errors: Partial<Record<string, string>>;
12
12
  /** True while a submit request is in flight. */
13
13
  processing: boolean;
14
+ reset?(): void;
14
15
  }
15
16
  /**
16
17
  * Wrap an Inertia `useForm()` object as a framework-agnostic {@link FormStateAdapter} so it drives
@@ -105,3 +106,22 @@ export interface InertiaLinkLike {
105
106
  * ```
106
107
  */
107
108
  export declare function inertiaSidebarLink<P extends InertiaLinkLike>(Link: ComponentType<P>): SidebarLinkComponentProp;
109
+ /** Visit callbacks needed to connect Upload to an Inertia multipart endpoint. */
110
+ export interface InertiaUploadCallbacks {
111
+ forceFormData: true;
112
+ async: true;
113
+ onProgress: (progress: {
114
+ percentage?: number;
115
+ } | undefined) => void;
116
+ onSuccess: () => void;
117
+ onError: (errors: Record<string, string>) => void;
118
+ onCancelToken: (token: {
119
+ cancel: () => void;
120
+ }) => void;
121
+ onCancel: () => void;
122
+ onNetworkError: (error: Error) => boolean;
123
+ onHttpException: () => boolean;
124
+ onFinish: () => void;
125
+ }
126
+ /** Bridge redirect-based Inertia uploads to Upload's progress/abort/retry lifecycle. */
127
+ export declare function inertiaUpload(send: (file: File, callbacks: InertiaUploadCallbacks) => void, errorMessage: string): NonNullable<import("../props/components/data-entry.prop.js").UploadProp["onUpload"]>;
@@ -6,7 +6,8 @@ function inertiaAdapter(form) {
6
6
  setValue: (name, value) => form.setData(name, value),
7
7
  getError: (name) => form.errors[name],
8
8
  isSubmitting: form.processing,
9
- getValues: () => form.data
9
+ getValues: () => form.data,
10
+ reset: form.reset ? () => form.reset?.() : void 0
10
11
  };
11
12
  }
12
13
  function useInertiaField(form, name) {
@@ -20,8 +21,66 @@ function useInertiaField(form, name) {
20
21
  function inertiaSidebarLink(Link) {
21
22
  return createSidebarLink(Link, "href");
22
23
  }
24
+ function inertiaUpload(send, errorMessage) {
25
+ return (file, _item, context) => new Promise((resolve, reject) => {
26
+ let cancel;
27
+ let settled = false;
28
+ const abort = () => {
29
+ cancel?.();
30
+ fail(new DOMException("Upload aborted", "AbortError"));
31
+ };
32
+ const cleanup = () => context.signal.removeEventListener("abort", abort);
33
+ const fail = (error) => {
34
+ if (settled) return;
35
+ settled = true;
36
+ cleanup();
37
+ reject(error);
38
+ };
39
+ if (context.signal.aborted) {
40
+ abort();
41
+ return;
42
+ }
43
+ context.signal.addEventListener("abort", abort, { once: true });
44
+ try {
45
+ send(file, {
46
+ forceFormData: true,
47
+ async: true,
48
+ onProgress: (progress) => {
49
+ if (!settled) context.onProgress(progress?.percentage ?? 0);
50
+ },
51
+ onSuccess: () => {
52
+ if (!settled) {
53
+ settled = true;
54
+ cleanup();
55
+ resolve({});
56
+ }
57
+ },
58
+ onError: (errors) => fail(new Error(Object.values(errors)[0] ?? errorMessage)),
59
+ onCancelToken: (token) => {
60
+ cancel = token.cancel;
61
+ if (context.signal.aborted) token.cancel();
62
+ },
63
+ onCancel: () => fail(new DOMException("Upload aborted", "AbortError")),
64
+ onNetworkError: () => {
65
+ fail(new Error(errorMessage));
66
+ return false;
67
+ },
68
+ onHttpException: () => {
69
+ fail(new Error(errorMessage));
70
+ return false;
71
+ },
72
+ onFinish: () => {
73
+ if (!settled) fail(new Error(errorMessage));
74
+ }
75
+ });
76
+ } catch (error) {
77
+ fail(error);
78
+ }
79
+ });
80
+ }
23
81
  export {
24
82
  inertiaAdapter,
25
83
  inertiaSidebarLink,
84
+ inertiaUpload,
26
85
  useInertiaField
27
86
  };
@@ -1,18 +1,40 @@
1
1
  /** Shared control sizing — reads `--control-height`, `--font-size-*` from density / theme. */
2
- export declare const controlMultilineClass = "ui-control-multiline aria-invalid:border-destructive w-full rounded-[var(--control-radius)] border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none";
2
+ export declare const controlMultilineClass = "ui-control-multiline aria-invalid:border-destructive data-[status=error]:border-destructive data-[status=warning]:border-warning w-full rounded-[var(--control-radius)] border-input bg-background ring-offset-background placeholder:text-muted-foreground";
3
3
  /**
4
4
  * Multiline control with its own chrome removed, for a textarea EMBEDDED in a surface that already
5
5
  * draws the box — a chat composer inside a Card, an inline edit cell, a comment box in a panel.
6
6
  * Two nested rounded borders is the tell that this was missing.
7
7
  */
8
- export declare const controlMultilineGhostClass = "ui-control-multiline w-full min-h-0 border-0 bg-transparent shadow-none placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0";
8
+ export declare const controlMultilineGhostClass = "ui-control-multiline data-[status=error]:border-destructive data-[status=warning]:border-warning w-full min-h-0 border-0 bg-transparent shadow-none placeholder:text-muted-foreground focus-visible:ring-0";
9
+ /**
10
+ * Multiline control drawn as antd's `filled` variant — a tinted surface instead of a boundary.
11
+ *
12
+ * It is a SEPARATE string rather than `controlMultilineClass` plus a modifier because
13
+ * `bg-background` lives in `@layer utilities`, which outranks every component-layer rule: a
14
+ * `.ui-control--filled` appended to the outlined list would be silently overpainted and no gate
15
+ * would catch it. The two lists differ only in which chrome utilities they carry.
16
+ */
17
+ export declare const controlMultilineFilledClass = "ui-control-multiline ui-control--filled aria-invalid:border-destructive data-[status=error]:border-destructive data-[status=warning]:border-warning w-full rounded-[var(--control-radius)] ring-offset-background placeholder:text-muted-foreground";
9
18
  /**
10
19
  * Open-state ring for popup-style triggers (Select / Cascader / TreeSelect / SearchSelect). Radix
11
20
  * moves focus INTO the popup on open, so the trigger loses `:focus-visible` and — without this —
12
21
  * an open popover shows only a border change (no ring), inconsistent with a focused Input.
13
22
  */
14
23
  export declare const controlOpenRingClass = "ui-control-trigger";
15
- export declare const controlTriggerClass = "ui-control ui-control-trigger flex items-center justify-between gap-2 whitespace-nowrap rounded-[var(--control-radius)] border-input bg-background transition-[color,box-shadow] focus-visible:outline-none [&>span]:line-clamp-1";
24
+ /**
25
+ * The trigger WITHOUT a surface — no `border-input`, no `bg-background`.
26
+ *
27
+ * Those two are Tailwind utilities, and `@layer utilities` beats `@layer components`, so a
28
+ * `[data-variant]` / `[data-status]` rule in control.css can never recolour a trigger that carries
29
+ * them (the same trap that killed `.ui-app-setting-picker-icon` in gh#366 and
30
+ * `--control-bounded-width` in gh#375). A control that wants the antd `variant` × `status` matrix
31
+ * therefore composes THIS class plus `ui-control-surface`, which supplies the identical resting
32
+ * border and fill from `--control-surface-*`.
33
+ */
34
+ export declare const controlTriggerBaseClass = "ui-control ui-control-trigger flex items-center justify-between gap-2 whitespace-nowrap rounded-[var(--control-radius)] transition-[color,box-shadow] [&>[data-slot=select-value]]:line-clamp-1";
35
+ export declare const controlTriggerClass = "ui-control ui-control-trigger flex items-center justify-between gap-2 whitespace-nowrap rounded-[var(--control-radius)] transition-[color,box-shadow] [&>[data-slot=select-value]]:line-clamp-1 border-input bg-background";
36
+ /** `controlTriggerBaseClass` + the token-driven surface — the select-family trigger. */
37
+ export declare const controlSurfaceTriggerClass = "ui-control ui-control-trigger flex items-center justify-between gap-2 whitespace-nowrap rounded-[var(--control-radius)] transition-[color,box-shadow] [&>[data-slot=select-value]]:line-clamp-1 ui-control-surface";
16
38
  export declare const controlIconClass = "size-[length:var(--control-height)] shrink-0";
17
39
  export declare const controlIconSmClass = "size-[calc(var(--control-height)-0.5rem)] shrink-0";
18
40
  /** Leading/affix icon inside an input row (search, command) — sized to `--control-icon-size`. */
@@ -1,7 +1,10 @@
1
- const controlMultilineClass = "ui-control-multiline aria-invalid:border-destructive w-full rounded-[var(--control-radius)] border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none";
2
- const controlMultilineGhostClass = "ui-control-multiline w-full min-h-0 border-0 bg-transparent shadow-none placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0";
1
+ const controlMultilineClass = "ui-control-multiline aria-invalid:border-destructive data-[status=error]:border-destructive data-[status=warning]:border-warning w-full rounded-[var(--control-radius)] border-input bg-background ring-offset-background placeholder:text-muted-foreground";
2
+ const controlMultilineGhostClass = "ui-control-multiline data-[status=error]:border-destructive data-[status=warning]:border-warning w-full min-h-0 border-0 bg-transparent shadow-none placeholder:text-muted-foreground focus-visible:ring-0";
3
+ const controlMultilineFilledClass = "ui-control-multiline ui-control--filled aria-invalid:border-destructive data-[status=error]:border-destructive data-[status=warning]:border-warning w-full rounded-[var(--control-radius)] ring-offset-background placeholder:text-muted-foreground";
3
4
  const controlOpenRingClass = "ui-control-trigger";
4
- const controlTriggerClass = "ui-control ui-control-trigger flex items-center justify-between gap-2 whitespace-nowrap rounded-[var(--control-radius)] border-input bg-background transition-[color,box-shadow] focus-visible:outline-none [&>span]:line-clamp-1";
5
+ const controlTriggerBaseClass = "ui-control ui-control-trigger flex items-center justify-between gap-2 whitespace-nowrap rounded-[var(--control-radius)] transition-[color,box-shadow] [&>[data-slot=select-value]]:line-clamp-1";
6
+ const controlTriggerClass = `${controlTriggerBaseClass} border-input bg-background`;
7
+ const controlSurfaceTriggerClass = `${controlTriggerBaseClass} ui-control-surface`;
5
8
  const controlIconClass = "size-[length:var(--control-height)] shrink-0";
6
9
  const controlIconSmClass = "size-[calc(var(--control-height)-0.5rem)] shrink-0";
7
10
  const controlIconLeadingClass = "size-[length:var(--control-icon-size)] shrink-0";
@@ -20,8 +23,11 @@ export {
20
23
  controlIconLeadingClass,
21
24
  controlIconSmClass,
22
25
  controlMultilineClass,
26
+ controlMultilineFilledClass,
23
27
  controlMultilineGhostClass,
24
28
  controlOpenRingClass,
29
+ controlSurfaceTriggerClass,
30
+ controlTriggerBaseClass,
25
31
  controlTriggerClass,
26
32
  tableCellPaddingClass,
27
33
  tableHeadHeightClass,
@@ -0,0 +1,8 @@
1
+ import { type Locale } from "date-fns";
2
+ import type { DatePickerBaseProp, PickerDateFormatProp } from "../../props/components/data-entry.prop.js";
3
+ /** Display is independent from the canonical value submitted by the field. */
4
+ export declare function formatPickerDate(date: Date | undefined, format: PickerDateFormatProp | undefined, locale: string, withTime?: boolean): string;
5
+ export declare function parsePickerDate(text: string, format: PickerDateFormatProp | undefined, parser?: (text: string) => Date | undefined, withTime?: boolean): Date | undefined;
6
+ export declare function pickerDateAllowed(date: Date, min: Date | undefined, max: Date | undefined, disabled?: (date: Date) => boolean): boolean;
7
+ /** Normalize a reporting period with the active calendar's week convention. */
8
+ export declare function pickerPeriodStart(date: Date, picker: DatePickerBaseProp["picker"], locale: Pick<Locale, "options">): Date;
@@ -0,0 +1,54 @@
1
+ import {
2
+ format as formatDate,
3
+ isValid,
4
+ parse,
5
+ startOfDay,
6
+ startOfWeek,
7
+ startOfMonth,
8
+ startOfQuarter,
9
+ startOfYear
10
+ } from "date-fns";
11
+ import { parseDateInput, toIsoDate } from "./parse.js";
12
+ function formatPickerDate(date, format, locale, withTime = false) {
13
+ if (!date || !isValid(date)) return "";
14
+ if (typeof format === "function") return format(date);
15
+ if (typeof format === "object") return new Intl.DateTimeFormat(locale, format).format(date);
16
+ if (typeof format === "string") return formatDate(date, format);
17
+ return withTime ? formatDate(date, "yyyy-MM-dd HH:mm") : toIsoDate(date);
18
+ }
19
+ function parsePickerDate(text, format, parser, withTime = false) {
20
+ const raw = text.trim();
21
+ if (!raw) return void 0;
22
+ const custom = parser?.(raw);
23
+ if (custom && isValid(custom)) return custom;
24
+ const pattern = typeof format === "string" ? format : withTime ? "yyyy-MM-dd HH:mm" : void 0;
25
+ if (pattern) {
26
+ const parsed = parse(raw, pattern, new Date(2e3, 0, 1));
27
+ if (isValid(parsed) && formatDate(parsed, pattern) === raw) return parsed;
28
+ }
29
+ if (withTime || !/^\d{4}-\d{2}-\d{2}$/.test(raw)) return void 0;
30
+ return parseDateInput(raw) ?? void 0;
31
+ }
32
+ function pickerDateAllowed(date, min, max, disabled) {
33
+ return isValid(date) && (!min || startOfDay(date) >= startOfDay(min)) && (!max || startOfDay(date) <= startOfDay(max)) && !disabled?.(date);
34
+ }
35
+ function pickerPeriodStart(date, picker, locale) {
36
+ switch (picker) {
37
+ case "week":
38
+ return startOfWeek(date, { locale });
39
+ case "month":
40
+ return startOfMonth(date);
41
+ case "quarter":
42
+ return startOfQuarter(date);
43
+ case "year":
44
+ return startOfYear(date);
45
+ default:
46
+ return date;
47
+ }
48
+ }
49
+ export {
50
+ formatPickerDate,
51
+ parsePickerDate,
52
+ pickerDateAllowed,
53
+ pickerPeriodStart
54
+ };
@@ -0,0 +1,32 @@
1
+ import * as React from "react";
2
+ /**
3
+ * `Slot` — nền của `asChild`, và từ v20 là của CHÍNH kho này.
4
+ *
5
+ * ## Vì sao tự dựng
6
+ *
7
+ * `asChild` là API công khai của @godxjp/ui: 171 chỗ trong thư viện và mọi
8
+ * consumer đều dùng. React Aria KHÔNG có mô hình đó — nó dùng prop `render`.
9
+ * Nếu để nền quyết định API thì đợt đổi nền sẽ phá mọi consumer; nếu tự giữ
10
+ * `Slot` thì đổi nền là chuyện nội bộ. Ba mươi dòng ở đây mua lấy điều đó.
11
+ *
12
+ * ## Ngữ nghĩa, và một chỗ KHÁC `mergeProps`
13
+ *
14
+ * Gộp prop đi qua `mergeProps` của React Aria — cùng luật mà chính các
15
+ * component React Aria dùng bên trong, nên `Slot` cư xử nhất quán với phần còn
16
+ * lại của hệ. Nó cho: `className` nối chuỗi, handler CHAIN (cha chạy rồi tới
17
+ * con, không ghi đè), prop thường thì CON thắng.
18
+ *
19
+ * Nhưng `mergeProps` để `style` của con GHI ĐÈ HẲN style của cha — đo được:
20
+ * cha `{color:'red'}` + con `{margin:1}` ra `{margin:1}`, mất màu. Slot của
21
+ * Radix thì gộp nông hai object, và 171 call site đang dựa vào hành vi ấy. Nên
22
+ * `style` được gộp riêng ở đây, sau `mergeProps`.
23
+ *
24
+ * ## Đúng MỘT con
25
+ *
26
+ * `asChild` nghĩa là "đừng dựng thẻ của mình, mượn thẻ của con". Hai con thì
27
+ * không có thẻ nào để mượn, nên `Children.only` ném lỗi — sớm và rõ, thay vì
28
+ * lặng lẽ dựng ra một cây DOM không ai định.
29
+ */
30
+ export declare function Slot({ children, ...slotProps }: React.HTMLAttributes<HTMLElement> & React.RefAttributes<HTMLElement> & {
31
+ children?: React.ReactNode;
32
+ }): React.ReactElement<React.HTMLAttributes<HTMLElement>, string | React.JSXElementConstructor<any>>;
@@ -0,0 +1,22 @@
1
+ "use client";
2
+ import { mergeProps } from "@react-aria/utils";
3
+ import * as React from "react";
4
+ function Slot({
5
+ children,
6
+ ...slotProps
7
+ }) {
8
+ const child = React.Children.only(children);
9
+ const merged = mergeProps(
10
+ slotProps,
11
+ child.props
12
+ );
13
+ const slotStyle = slotProps.style;
14
+ const childStyle = child.props.style;
15
+ return React.cloneElement(child, {
16
+ ...merged,
17
+ style: slotStyle === void 0 && childStyle === void 0 ? void 0 : { ...slotStyle, ...childStyle }
18
+ });
19
+ }
20
+ export {
21
+ Slot
22
+ };
@@ -1,12 +1,31 @@
1
1
  /** Prop → internal class maps. Apps use component props, never these classes directly. */
2
- import type { GapProp, PageContainerVariantProp, PageDensityProp } from "../props/vocabulary/index.js";
2
+ import type * as React from "react";
3
+ import type { GapNameProp, GapProp, PadProp, PadRawProp, PageContainerVariantProp, PageDensityProp } from "../props/vocabulary/index.js";
3
4
  export type Density = PageDensityProp;
4
5
  export type StackGap = GapProp;
5
6
  export type FlexGap = GapProp;
6
- export type InlineGap = Exclude<GapProp, "xl" | "none">;
7
+ export type InlineGap = Exclude<GapNameProp, "xl" | "none">;
7
8
  export type PageContainerVariant = PageContainerVariantProp;
8
9
  export declare const densityClass: Record<PageDensityProp, string>;
9
10
  export declare const pageContainerVariantClass: Record<PageContainerVariantProp, string | undefined>;
10
- export declare const stackGapClass: Record<Exclude<GapProp, "none">, string>;
11
+ export declare const stackGapClass: Record<Exclude<GapNameProp, "none">, string>;
11
12
  export declare const inlineGapClass: Record<InlineGap, string>;
12
13
  export declare const flexGapClass: Record<GapProp, string>;
14
+ /**
15
+ * Bậc thang → giá trị CSS cho đệm.
16
+ *
17
+ * Bậc TÊN ánh xạ vào thang dọc (`--space-stack-*`) chứ không theo trục như
18
+ * `gap`: đệm bao quanh một khối, nó không có "trục viết" để chặt hơn. Bậc SỐ
19
+ * đi thẳng vào `--space-{n}` của thang gốc, giống hệt `gap={n}`.
20
+ */
21
+ export declare function padStepToken(step: GapProp): string;
22
+ /**
23
+ * `pad` / `padRaw` → style đệm theo tên cạnh LOGIC.
24
+ *
25
+ * Trả về `undefined` khi không có gì để đặt, để `Flex` không phát một thuộc
26
+ * tính `style` rỗng (và phép so với bản Radix không lệch vì một chuỗi thừa).
27
+ *
28
+ * `padRaw` thắng `pad` ở TỪNG CẠNH, không phải cả cụm: một thiết kế có thể cần
29
+ * `blockStart` đúng 10px trong khi ba cạnh còn lại vẫn theo thang.
30
+ */
31
+ export declare function padStyle(pad: PadProp | undefined, padRaw: PadRawProp | undefined): React.CSSProperties | undefined;
@@ -28,12 +28,67 @@ const flexGapClass = {
28
28
  sm: "ui-flex-gap-sm",
29
29
  md: "ui-flex-gap-md",
30
30
  lg: "ui-flex-gap-lg",
31
- xl: "ui-flex-gap-xl"
31
+ xl: "ui-flex-gap-xl",
32
+ // Bậc SỐ: thang gốc `--space-{n}`, không theo trục. Xem GapStepProp.
33
+ 0: "ui-flex-gap-none",
34
+ 1: "ui-flex-gap-1",
35
+ 2: "ui-flex-gap-2",
36
+ 3: "ui-flex-gap-3",
37
+ 4: "ui-flex-gap-4",
38
+ 5: "ui-flex-gap-5",
39
+ 6: "ui-flex-gap-6",
40
+ 8: "ui-flex-gap-8",
41
+ 10: "ui-flex-gap-10",
42
+ 12: "ui-flex-gap-12"
32
43
  };
44
+ function padStepToken(step) {
45
+ if (step === "none" || step === 0) {
46
+ return "0";
47
+ }
48
+ return typeof step === "number" ? `var(--space-${step})` : `var(--space-stack-${step})`;
49
+ }
50
+ function padStyle(pad, padRaw) {
51
+ const scalar = (v) => v !== void 0 && (typeof v !== "object" || v === null) ? v : void 0;
52
+ const sides = (v) => v !== void 0 && typeof v === "object" && v !== null ? v : {};
53
+ const allStep = scalar(pad);
54
+ const allRaw = scalar(padRaw);
55
+ const stepSides = sides(pad);
56
+ const rawSides = sides(padRaw);
57
+ const AXES = {
58
+ inline: ["paddingInlineStart", "paddingInlineEnd"],
59
+ block: ["paddingBlockStart", "paddingBlockEnd"],
60
+ inlineStart: ["paddingInlineStart"],
61
+ inlineEnd: ["paddingInlineEnd"],
62
+ blockStart: ["paddingBlockStart"],
63
+ blockEnd: ["paddingBlockEnd"]
64
+ };
65
+ const out = {};
66
+ if (allStep !== void 0) {
67
+ out.padding = padStepToken(allStep);
68
+ }
69
+ if (allRaw !== void 0) {
70
+ out.padding = `${allRaw}px`;
71
+ }
72
+ for (const [key, props] of Object.entries(AXES)) {
73
+ const step = stepSides[key];
74
+ if (step !== void 0) {
75
+ for (const prop of props) out[prop] = padStepToken(step);
76
+ }
77
+ }
78
+ for (const [key, props] of Object.entries(AXES)) {
79
+ const raw = rawSides[key];
80
+ if (raw !== void 0) {
81
+ for (const prop of props) out[prop] = `${raw}px`;
82
+ }
83
+ }
84
+ return Object.keys(out).length > 0 ? out : void 0;
85
+ }
33
86
  export {
34
87
  densityClass,
35
88
  flexGapClass,
36
89
  inlineGapClass,
90
+ padStepToken,
91
+ padStyle,
37
92
  pageContainerVariantClass,
38
93
  stackGapClass
39
94
  };
@@ -3,7 +3,7 @@ import type { Locale } from "date-fns";
3
3
  import type { DayPickerProps } from "react-day-picker";
4
4
  import type { AppLocale, AppRequestHeaders, AppTimeFormat, AppTimezone, AppTimezoneDefault, AppDateFormat } from "../../app/types.js";
5
5
  import type { AppBrand, AppDensity, AppFontSize, AppTheme } from "../../app/theme-axes.js";
6
- import type { AppSettingPickerAppearanceProp, ChildrenProp, ClassNameProp, DisabledProp, IdProp, NameProp, OnValueChangeProp, ValueProp } from "../vocabulary/index.js";
6
+ import type { AppSettingPickerAppearanceProp, AppSettingToggleAppearanceProp, ChildrenProp, ClassNameProp, DisabledProp, IdProp, NameProp, OnValueChangeProp, ValueProp } from "../vocabulary/index.js";
7
7
  /** @see AppProvider */
8
8
  export type AppProviderProp = {
9
9
  children: ChildrenProp;
@@ -93,6 +93,30 @@ export type AppSettingPickerProp = {
93
93
  value?: ValueProp<string>;
94
94
  onValueChange?: OnValueChangeProp<string>;
95
95
  };
96
+ /**
97
+ * The {@link AppSettingToggle} subset of {@link AppSettingKind} — the settings whose value set is
98
+ * CLOSED and short enough to cycle by tapping. `locale`, `timezone`, `dateFormat` and `brand` are
99
+ * deliberately absent: a 400-entry IANA list (or a palette a service extends) is a menu, not a
100
+ * cycle, and tapping through it is not a control anyone can use.
101
+ */
102
+ export type AppSettingToggleKind = Extract<AppSettingKind, "theme" | "density" | "fontSize" | "timeFormat">;
103
+ /**
104
+ * @see AppSettingToggle — one BUTTON that steps a single AppProvider setting to its next value and
105
+ * shows that value as its glyph. The no-menu counterpart to {@link AppSettingPickerProp}: same
106
+ * binding contract (context-bound by default, controlled via value + onValueChange), same option
107
+ * order, one tap instead of open-then-choose.
108
+ */
109
+ export type AppSettingToggleProp = {
110
+ kind: AppSettingToggleKind;
111
+ /** Box the button takes. Default: `"bar"` — a toggle exists for a top bar. */
112
+ appearance?: AppSettingToggleAppearanceProp;
113
+ className?: ClassNameProp;
114
+ disabled?: DisabledProp;
115
+ id?: IdProp;
116
+ /** Controlled value; default reads/writes the matching AppProvider context. */
117
+ value?: ValueProp<string>;
118
+ onValueChange?: OnValueChangeProp<string>;
119
+ };
96
120
  /** Value exposed by `useAppContext`. */
97
121
  export type AppContextValue = {
98
122
  locale: AppLocale;
@@ -22,6 +22,13 @@ type ChartCartesianBase = {
22
22
  categoryKey: string;
23
23
  /** Accessible name + visible caption for the chart. REQUIRED (role="img" needs a name). */
24
24
  label: LabelProp;
25
+ /**
26
+ * Paint `label` as a visible caption above the plot. Set `false` when the chart already sits
27
+ * under a heading that says the same thing (a `CardTitle`, a section `<h2>`): the caption stays
28
+ * in the DOM as `sr-only`, so `role="img"` keeps its accessible name and only the duplicated
29
+ * visible title goes away.
30
+ */
31
+ showCaption?: boolean;
25
32
  /** Extra context appended to the screen-reader description. */
26
33
  description?: DescriptionProp;
27
34
  /** Canvas height preset — `xs|sm|md|lg`. Ignored when `height` is set. */
@@ -67,6 +74,13 @@ export type CompactBarTrendProp = {
67
74
  valueKey: string;
68
75
  /** Accessible name + visible caption for the chart. REQUIRED (role="img" needs a name). */
69
76
  label: LabelProp;
77
+ /**
78
+ * Paint `label` as a visible caption above the plot. Set `false` when the chart already sits
79
+ * under a heading that says the same thing (a `CardTitle`, a section `<h2>`): the caption stays
80
+ * in the DOM as `sr-only`, so `role="img"` keeps its accessible name and only the duplicated
81
+ * visible title goes away.
82
+ */
83
+ showCaption?: boolean;
70
84
  /** Extra context appended to the screen-reader description. */
71
85
  description?: DescriptionProp;
72
86
  /** Plot-height tier — `xs|sm|md|lg`. Defaults to `xs` (dashboard summary-card density). */
@@ -107,6 +121,13 @@ export type PieChartProp = {
107
121
  colors?: string[];
108
122
  /** Accessible name + visible caption for the chart. REQUIRED. */
109
123
  label: LabelProp;
124
+ /**
125
+ * Paint `label` as a visible caption above the plot. Set `false` when the chart already sits
126
+ * under a heading that says the same thing (a `CardTitle`, a section `<h2>`): the caption stays
127
+ * in the DOM as `sr-only`, so `role="img"` keeps its accessible name and only the duplicated
128
+ * visible title goes away.
129
+ */
130
+ showCaption?: boolean;
110
131
  /** Extra context appended to the screen-reader description. */
111
132
  description?: DescriptionProp;
112
133
  /** Canvas height preset — `xs|sm|md|lg`. Ignored when `height` is set. */