@godxjp/ui 6.0.0 → 6.0.1

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 (434) hide show
  1. package/dist/app/index.d.ts +140 -0
  2. package/dist/app/index.js +38 -0
  3. package/dist/app.prop-IobwLwaM.d.ts +90 -0
  4. package/dist/checkbox-NkFkqsQ8.d.ts +13 -0
  5. package/dist/chunk-2XW7J3EI.js +226 -0
  6. package/dist/chunk-3F2AKYRD.js +416 -0
  7. package/dist/chunk-3KPEZ5CF.js +37 -0
  8. package/dist/chunk-3UGU5TYP.js +89 -0
  9. package/{src/props/registry.ts → dist/chunk-6RA3KSVK.js} +118 -133
  10. package/dist/chunk-7NZFVD24.js +122 -0
  11. package/dist/chunk-7PWBC4BY.js +25 -0
  12. package/dist/chunk-7S7MYFXE.js +61 -0
  13. package/dist/chunk-7WRZG2IG.js +71 -0
  14. package/dist/chunk-B775Y6BE.js +1 -0
  15. package/dist/chunk-BHV2FUOA.js +111 -0
  16. package/dist/chunk-BI3HERR7.js +70 -0
  17. package/dist/chunk-BPSKQUL2.js +68 -0
  18. package/dist/chunk-CDWPQ5RP.js +187 -0
  19. package/dist/chunk-CP2LET6N.js +244 -0
  20. package/dist/chunk-CQBADMFG.js +20 -0
  21. package/dist/chunk-CRERCLIZ.js +33 -0
  22. package/dist/chunk-DU6ZYZRP.js +238 -0
  23. package/dist/chunk-DY5C44UP.js +55 -0
  24. package/dist/chunk-E4HJNQ62.js +117 -0
  25. package/dist/chunk-E76QIYSY.js +93 -0
  26. package/dist/chunk-F7PG4OEV.js +37 -0
  27. package/dist/chunk-GDSVW62T.js +171 -0
  28. package/dist/chunk-H2FHJOLU.js +178 -0
  29. package/dist/chunk-HJEBRCXL.js +55 -0
  30. package/dist/chunk-ICM6XBST.js +16 -0
  31. package/{src/components/data-entry/calendar.tsx → dist/chunk-IK7I3ABN.js} +33 -35
  32. package/dist/chunk-L6J44O74.js +144 -0
  33. package/dist/chunk-LDSLS6HE.js +1 -0
  34. package/dist/chunk-LVNUHUEZ.js +191 -0
  35. package/dist/chunk-M64MVRLS.js +92 -0
  36. package/dist/chunk-NGQW3KEM.js +402 -0
  37. package/dist/chunk-NZ4FOC5N.js +559 -0
  38. package/dist/chunk-PIIRNAXA.js +26 -0
  39. package/dist/chunk-S66TJXJU.js +33 -0
  40. package/dist/chunk-SMLKNECP.js +133 -0
  41. package/dist/chunk-TAHBM3F2.js +66 -0
  42. package/dist/chunk-TO33OY4L.js +150 -0
  43. package/dist/chunk-TO7URV7U.js +51 -0
  44. package/dist/chunk-TOO5AEKL.js +81 -0
  45. package/dist/chunk-U3GHAOIJ.js +299 -0
  46. package/dist/chunk-U7N2A7A3.js +9 -0
  47. package/dist/chunk-UX634MYF.js +123 -0
  48. package/dist/chunk-V6UWJKZF.js +28 -0
  49. package/{src/components/data-entry/input.tsx → dist/chunk-VOHTRR5X.js} +18 -16
  50. package/dist/chunk-WRFKVUPW.js +332 -0
  51. package/dist/chunk-WXW43RK5.js +24 -0
  52. package/{src/components/navigation/tabs.tsx → dist/chunk-XG7XDYIM.js} +46 -53
  53. package/dist/chunk-YFCQKO3B.js +842 -0
  54. package/dist/chunk-ZDWXGWLY.js +73 -0
  55. package/dist/chunk-ZLK5SPT6.js +11 -0
  56. package/dist/chunk-ZS6DTAM2.js +31 -0
  57. package/dist/chunk-ZT5UEUBO.js +1 -0
  58. package/dist/components/admin/index.d.ts +80 -0
  59. package/dist/components/admin/index.js +38 -0
  60. package/dist/components/data-display/badge.d.ts +12 -0
  61. package/dist/components/data-display/badge.js +3 -0
  62. package/dist/components/data-display/card.d.ts +87 -0
  63. package/dist/components/data-display/card.js +2 -0
  64. package/dist/components/data-display/index.d.ts +72 -0
  65. package/dist/components/data-display/index.js +89 -0
  66. package/dist/components/data-display/popover.d.ts +13 -0
  67. package/dist/components/data-display/popover.js +2 -0
  68. package/dist/components/data-display/scroll-area.d.ts +7 -0
  69. package/dist/components/data-display/scroll-area.js +2 -0
  70. package/dist/components/data-display/table.d.ts +10 -0
  71. package/dist/components/data-display/table.js +3 -0
  72. package/dist/components/data-entry/autocomplete.d.ts +16 -0
  73. package/dist/components/data-entry/autocomplete.js +8 -0
  74. package/dist/components/data-entry/calendar.d.ts +16 -0
  75. package/dist/components/data-entry/calendar.js +4 -0
  76. package/dist/components/data-entry/cascader.d.ts +32 -0
  77. package/dist/components/data-entry/cascader.js +13 -0
  78. package/dist/components/data-entry/checkbox.d.ts +13 -0
  79. package/dist/components/data-entry/checkbox.js +4 -0
  80. package/dist/components/data-entry/color-picker.d.ts +16 -0
  81. package/dist/components/data-entry/color-picker.js +6 -0
  82. package/dist/components/data-entry/command.d.ts +69 -0
  83. package/dist/components/data-entry/command.js +3 -0
  84. package/dist/components/data-entry/date-picker.d.ts +16 -0
  85. package/dist/components/data-entry/date-picker.js +8 -0
  86. package/dist/components/data-entry/date-range-picker.d.ts +16 -0
  87. package/dist/components/data-entry/date-range-picker.js +8 -0
  88. package/dist/components/data-entry/index.d.ts +53 -0
  89. package/dist/components/data-entry/index.js +152 -0
  90. package/dist/components/data-entry/input.d.ts +6 -0
  91. package/dist/components/data-entry/input.js +2 -0
  92. package/dist/components/data-entry/label.d.ts +8 -0
  93. package/dist/components/data-entry/label.js +2 -0
  94. package/dist/components/data-entry/radio.d.ts +24 -0
  95. package/dist/components/data-entry/radio.js +4 -0
  96. package/dist/components/data-entry/select.d.ts +18 -0
  97. package/dist/components/data-entry/select.js +3 -0
  98. package/dist/components/data-entry/slider.d.ts +16 -0
  99. package/dist/components/data-entry/slider.js +2 -0
  100. package/dist/components/data-entry/switch.d.ts +17 -0
  101. package/dist/components/data-entry/switch.js +2 -0
  102. package/dist/components/data-entry/textarea.d.ts +6 -0
  103. package/dist/components/data-entry/textarea.js +3 -0
  104. package/dist/components/data-entry/time-picker.d.ts +16 -0
  105. package/dist/components/data-entry/time-picker.js +7 -0
  106. package/dist/components/data-entry/transfer.d.ts +17 -0
  107. package/dist/components/data-entry/transfer.js +11 -0
  108. package/dist/components/data-entry/tree-select.d.ts +26 -0
  109. package/dist/components/data-entry/tree-select.js +13 -0
  110. package/dist/components/data-entry/upload.d.ts +42 -0
  111. package/dist/components/data-entry/upload.js +11 -0
  112. package/dist/components/feedback/alert.d.ts +60 -0
  113. package/dist/components/feedback/alert.js +7 -0
  114. package/dist/components/feedback/dialog.d.ts +64 -0
  115. package/dist/components/feedback/dialog.js +7 -0
  116. package/dist/components/feedback/index.d.ts +16 -0
  117. package/dist/components/feedback/index.js +14 -0
  118. package/dist/components/feedback/sheet.d.ts +24 -0
  119. package/dist/components/feedback/sheet.js +2 -0
  120. package/dist/components/feedback/sonner.d.ts +6 -0
  121. package/dist/components/feedback/sonner.js +1 -0
  122. package/dist/components/general/button.d.ts +20 -0
  123. package/dist/components/general/button.js +2 -0
  124. package/dist/components/general/index.d.ts +6 -0
  125. package/dist/components/general/index.js +2 -0
  126. package/dist/components/layout/index.d.ts +71 -0
  127. package/dist/components/layout/index.js +5 -0
  128. package/dist/components/navigation/dropdown-menu.d.ts +28 -0
  129. package/dist/components/navigation/dropdown-menu.js +2 -0
  130. package/dist/components/navigation/index.d.ts +32 -0
  131. package/dist/components/navigation/index.js +12 -0
  132. package/dist/components/navigation/pagination.d.ts +11 -0
  133. package/dist/components/navigation/pagination.js +7 -0
  134. package/dist/components/navigation/steps.d.ts +12 -0
  135. package/dist/components/navigation/steps.js +3 -0
  136. package/dist/components/navigation/tabs-items.d.ts +12 -0
  137. package/dist/components/navigation/tabs-items.js +3 -0
  138. package/dist/components/navigation/tabs.d.ts +12 -0
  139. package/dist/components/navigation/tabs.js +2 -0
  140. package/dist/components/query/index.d.ts +43 -0
  141. package/dist/components/query/index.js +8 -0
  142. package/dist/components/ui/index.d.ts +57 -0
  143. package/dist/components/ui/index.js +37 -0
  144. package/{src/props/vocabulary/content.prop.ts → dist/content.prop-D1Dd3TAc.d.ts} +16 -20
  145. package/dist/data-display.prop-DNTAzmDy.d.ts +58 -0
  146. package/dist/data-entry.prop-BEGA1lTq.d.ts +323 -0
  147. package/dist/data-table-D1u_rKLK.d.ts +83 -0
  148. package/dist/data.prop-BVvfKC_g.d.ts +41 -0
  149. package/dist/feedback.prop-BmxUlpAW.d.ts +64 -0
  150. package/dist/filter-bar-B7OGFO9S.d.ts +10 -0
  151. package/dist/form/index.d.ts +21 -0
  152. package/dist/form/index.js +4 -0
  153. package/dist/form.prop-BHgpuFFm.d.ts +41 -0
  154. package/dist/format-date-ByyZoqI5.d.ts +51 -0
  155. package/dist/general.prop-D7brMPNL.d.ts +16 -0
  156. package/dist/i18n/index.d.ts +217 -0
  157. package/dist/i18n/index.js +2 -0
  158. package/dist/index.d.ts +53 -0
  159. package/dist/index.js +39 -0
  160. package/dist/inline-C5u6ptJV.d.ts +10 -0
  161. package/dist/interaction.prop-Cdn7wOtq.d.ts +25 -0
  162. package/{src/props/vocabulary/layout.prop.ts → dist/layout.prop-4TCNvyQZ.d.ts} +9 -14
  163. package/dist/layout.prop-C795F0qg.d.ts +112 -0
  164. package/dist/lib/datetime/index.d.ts +31 -0
  165. package/dist/lib/datetime/index.js +1 -0
  166. package/dist/lib/utils.d.ts +5 -0
  167. package/dist/lib/utils.js +1 -0
  168. package/dist/navigation.prop-DpZqcXey.d.ts +78 -0
  169. package/dist/navigation.prop-DxBiClEH.d.ts +20 -0
  170. package/dist/props/components/index.d.ts +27 -0
  171. package/dist/props/components/index.js +1 -0
  172. package/dist/props/index.d.ts +28 -0
  173. package/dist/props/index.js +3 -0
  174. package/dist/props/registry.d.ts +649 -0
  175. package/dist/props/registry.js +1 -0
  176. package/dist/props/vocabulary/index.d.ts +7 -0
  177. package/dist/props/vocabulary/index.js +1 -0
  178. package/dist/query.prop-hIPrk2zI.d.ts +71 -0
  179. package/dist/search-input-uP01rY1L.d.ts +22 -0
  180. package/dist/shared.prop-BNRJc9K0.d.ts +45 -0
  181. package/dist/types-mvzYGrma.d.ts +37 -0
  182. package/dist/use-toast-Dol5bdY3.d.ts +34 -0
  183. package/package.json +233 -67
  184. package/src/app/__tests__/app-provider.test.tsx +0 -232
  185. package/src/app/__tests__/date-format-labels.test.ts +0 -36
  186. package/src/app/__tests__/date-formats.test.ts +0 -44
  187. package/src/app/__tests__/timezones.test.ts +0 -65
  188. package/src/app/app-provider.tsx +0 -227
  189. package/src/app/date-format-labels.ts +0 -21
  190. package/src/app/date-formats.ts +0 -30
  191. package/src/app/index.ts +0 -40
  192. package/src/app/locales.ts +0 -32
  193. package/src/app/request-headers.ts +0 -31
  194. package/src/app/storage.ts +0 -44
  195. package/src/app/time-format-labels.ts +0 -19
  196. package/src/app/time-formats.ts +0 -15
  197. package/src/app/timezones.ts +0 -208
  198. package/src/app/types.ts +0 -39
  199. package/src/app/use-formatting.ts +0 -47
  200. package/src/components/__tests__/accessibility-primitives.test.tsx +0 -65
  201. package/src/components/__tests__/docs-parity.test.ts +0 -41
  202. package/src/components/__tests__/shadcn-release-guardrails.test.ts +0 -71
  203. package/src/components/__tests__/theme-axes-integration.test.tsx +0 -242
  204. package/src/components/admin/index.ts +0 -76
  205. package/src/components/data-display/__tests__/card-table.test.tsx +0 -328
  206. package/src/components/data-display/__tests__/data-display.test.tsx +0 -73
  207. package/src/components/data-display/__tests__/data-table.test.tsx +0 -84
  208. package/src/components/data-display/__tests__/popover.test.tsx +0 -92
  209. package/src/components/data-display/__tests__/scroll-area-collapsible.test.tsx +0 -66
  210. package/src/components/data-display/badge.tsx +0 -27
  211. package/src/components/data-display/card.tsx +0 -194
  212. package/src/components/data-display/code-badge.tsx +0 -28
  213. package/src/components/data-display/collapsible.tsx +0 -5
  214. package/src/components/data-display/data-table.tsx +0 -476
  215. package/src/components/data-display/empty-state.tsx +0 -22
  216. package/src/components/data-display/index.ts +0 -41
  217. package/src/components/data-display/key-value-grid.tsx +0 -46
  218. package/src/components/data-display/popover.tsx +0 -62
  219. package/src/components/data-display/progress-meter.tsx +0 -20
  220. package/src/components/data-display/scan-panel.tsx +0 -16
  221. package/src/components/data-display/scroll-area.tsx +0 -42
  222. package/src/components/data-display/status-badge.tsx +0 -83
  223. package/src/components/data-display/table.tsx +0 -59
  224. package/src/components/data-display/timeline.tsx +0 -42
  225. package/src/components/data-display/tree-list.tsx +0 -42
  226. package/src/components/data-entry/__fixtures__/tree-options.ts +0 -80
  227. package/src/components/data-entry/__tests__/cascader-tree-transfer.test.tsx +0 -417
  228. package/src/components/data-entry/__tests__/checkbox-group.test.tsx +0 -40
  229. package/src/components/data-entry/__tests__/checkbox.test.tsx +0 -20
  230. package/src/components/data-entry/__tests__/date-autocomplete.test.tsx +0 -94
  231. package/src/components/data-entry/__tests__/form-field.test.tsx +0 -49
  232. package/src/components/data-entry/__tests__/input-textarea.test.tsx +0 -38
  233. package/src/components/data-entry/__tests__/label-select.test.tsx +0 -62
  234. package/src/components/data-entry/__tests__/pickers.test.tsx +0 -74
  235. package/src/components/data-entry/__tests__/radio.test.tsx +0 -46
  236. package/src/components/data-entry/__tests__/search-input.test.tsx +0 -32
  237. package/src/components/data-entry/__tests__/switch-field.test.tsx +0 -52
  238. package/src/components/data-entry/__tests__/upload.test.tsx +0 -125
  239. package/src/components/data-entry/autocomplete.tsx +0 -91
  240. package/src/components/data-entry/cascader.tsx +0 -305
  241. package/src/components/data-entry/checkbox-group.tsx +0 -90
  242. package/src/components/data-entry/checkbox.tsx +0 -30
  243. package/src/components/data-entry/choice-field.tsx +0 -27
  244. package/src/components/data-entry/choice-option.ts +0 -20
  245. package/src/components/data-entry/color-picker.tsx +0 -75
  246. package/src/components/data-entry/command.tsx +0 -56
  247. package/src/components/data-entry/country-select.tsx +0 -88
  248. package/src/components/data-entry/date-picker.tsx +0 -69
  249. package/src/components/data-entry/date-range-picker.tsx +0 -75
  250. package/src/components/data-entry/form-field.tsx +0 -59
  251. package/src/components/data-entry/index.ts +0 -62
  252. package/src/components/data-entry/label.tsx +0 -25
  253. package/src/components/data-entry/radio.tsx +0 -109
  254. package/src/components/data-entry/search-input.tsx +0 -103
  255. package/src/components/data-entry/select.tsx +0 -149
  256. package/src/components/data-entry/slider.tsx +0 -38
  257. package/src/components/data-entry/switch-field.tsx +0 -91
  258. package/src/components/data-entry/switch.tsx +0 -24
  259. package/src/components/data-entry/textarea.tsx +0 -12
  260. package/src/components/data-entry/time-picker.tsx +0 -214
  261. package/src/components/data-entry/transfer.tsx +0 -231
  262. package/src/components/data-entry/tree-select-strategy.ts +0 -6
  263. package/src/components/data-entry/tree-select.tsx +0 -279
  264. package/src/components/data-entry/tree-utils.ts +0 -221
  265. package/src/components/data-entry/upload-crop-dialog.tsx +0 -109
  266. package/src/components/data-entry/upload-types.ts +0 -86
  267. package/src/components/data-entry/upload.tsx +0 -498
  268. package/src/components/data-entry/use-upload-draft.ts +0 -93
  269. package/src/components/feedback/__tests__/alert.test.tsx +0 -127
  270. package/src/components/feedback/__tests__/dialog.test.tsx +0 -290
  271. package/src/components/feedback/__tests__/sheet.test.tsx +0 -94
  272. package/src/components/feedback/__tests__/skeleton.test.tsx +0 -25
  273. package/src/components/feedback/__tests__/toast.test.tsx +0 -52
  274. package/src/components/feedback/alert.tsx +0 -167
  275. package/src/components/feedback/dialog.tsx +0 -325
  276. package/src/components/feedback/index.ts +0 -53
  277. package/src/components/feedback/sheet.tsx +0 -130
  278. package/src/components/feedback/skeleton.tsx +0 -95
  279. package/src/components/feedback/sonner.tsx +0 -54
  280. package/src/components/feedback/toaster.tsx +0 -1
  281. package/src/components/feedback/use-toast.ts +0 -62
  282. package/src/components/general/__tests__/button.test.tsx +0 -71
  283. package/src/components/general/button.tsx +0 -61
  284. package/src/components/general/index.ts +0 -2
  285. package/src/components/layout/__tests__/page-container.test.tsx +0 -69
  286. package/src/components/layout/__tests__/page-inset.test.tsx +0 -14
  287. package/src/components/layout/__tests__/stack-inline.test.tsx +0 -39
  288. package/src/components/layout/app-shell.tsx +0 -42
  289. package/src/components/layout/breadcrumb.tsx +0 -35
  290. package/src/components/layout/index.ts +0 -31
  291. package/src/components/layout/inline.tsx +0 -13
  292. package/src/components/layout/menu.tsx +0 -34
  293. package/src/components/layout/mobile-frame.tsx +0 -57
  294. package/src/components/layout/page-container.tsx +0 -81
  295. package/src/components/layout/page-inset.tsx +0 -16
  296. package/src/components/layout/responsive-grid.tsx +0 -14
  297. package/src/components/layout/shell-app.tsx +0 -30
  298. package/src/components/layout/sidebar.tsx +0 -98
  299. package/src/components/layout/split-pane.tsx +0 -16
  300. package/src/components/layout/stack.tsx +0 -13
  301. package/src/components/layout/topbar.tsx +0 -108
  302. package/src/components/navigation/__tests__/app-pickers.test.tsx +0 -118
  303. package/src/components/navigation/__tests__/dropdown-menu.test.tsx +0 -104
  304. package/src/components/navigation/__tests__/navigation.test.tsx +0 -61
  305. package/src/components/navigation/__tests__/pagination-steps-tabs.test.tsx +0 -76
  306. package/src/components/navigation/date-format-picker.tsx +0 -55
  307. package/src/components/navigation/dropdown-menu.tsx +0 -190
  308. package/src/components/navigation/filter-bar.tsx +0 -38
  309. package/src/components/navigation/index.ts +0 -28
  310. package/src/components/navigation/locale-picker.tsx +0 -49
  311. package/src/components/navigation/page-header.tsx +0 -50
  312. package/src/components/navigation/pagination-utils.ts +0 -35
  313. package/src/components/navigation/pagination.tsx +0 -168
  314. package/src/components/navigation/steps.tsx +0 -163
  315. package/src/components/navigation/tabs-items.tsx +0 -69
  316. package/src/components/navigation/time-format-picker.tsx +0 -55
  317. package/src/components/navigation/timezone-picker.tsx +0 -63
  318. package/src/components/query/__tests__/data-state.test.tsx +0 -214
  319. package/src/components/query/__tests__/infinite-prefetch.test.tsx +0 -105
  320. package/src/components/query/__tests__/query-helpers.test.tsx +0 -61
  321. package/src/components/query/data-state.tsx +0 -58
  322. package/src/components/query/index.ts +0 -10
  323. package/src/components/query/infinite-query-state.tsx +0 -99
  324. package/src/components/query/mutation-feedback.tsx +0 -31
  325. package/src/components/query/prefetch-link.tsx +0 -45
  326. package/src/components/query/query-refetch-button.tsx +0 -41
  327. package/src/components/ui/alert-dialog.tsx +0 -1
  328. package/src/components/ui/alert.tsx +0 -1
  329. package/src/components/ui/autocomplete.tsx +0 -1
  330. package/src/components/ui/badge.tsx +0 -1
  331. package/src/components/ui/button.tsx +0 -1
  332. package/src/components/ui/calendar.tsx +0 -1
  333. package/src/components/ui/card.tsx +0 -1
  334. package/src/components/ui/checkbox.tsx +0 -1
  335. package/src/components/ui/color-picker.tsx +0 -1
  336. package/src/components/ui/command.tsx +0 -1
  337. package/src/components/ui/date-picker.tsx +0 -1
  338. package/src/components/ui/date-range-picker.tsx +0 -1
  339. package/src/components/ui/dialog.tsx +0 -1
  340. package/src/components/ui/dropdown-menu.tsx +0 -1
  341. package/src/components/ui/index.tsx +0 -31
  342. package/src/components/ui/input.tsx +0 -1
  343. package/src/components/ui/label.tsx +0 -1
  344. package/src/components/ui/pagination.tsx +0 -1
  345. package/src/components/ui/popover.tsx +0 -1
  346. package/src/components/ui/radio.tsx +0 -1
  347. package/src/components/ui/scroll-area.tsx +0 -1
  348. package/src/components/ui/select.tsx +0 -1
  349. package/src/components/ui/sheet.tsx +0 -1
  350. package/src/components/ui/slider.tsx +0 -1
  351. package/src/components/ui/sonner.tsx +0 -1
  352. package/src/components/ui/switch.tsx +0 -1
  353. package/src/components/ui/table.tsx +0 -1
  354. package/src/components/ui/tabs-items.tsx +0 -1
  355. package/src/components/ui/tabs.tsx +0 -1
  356. package/src/components/ui/textarea.tsx +0 -1
  357. package/src/components/ui/time-picker.tsx +0 -1
  358. package/src/components/ui/upload.tsx +0 -1
  359. package/src/form/__tests__/use-zod-form.test.tsx +0 -97
  360. package/src/form/form-field-control.tsx +0 -44
  361. package/src/form/form-root.tsx +0 -29
  362. package/src/form/index.ts +0 -7
  363. package/src/form/use-zod-form.ts +0 -29
  364. package/src/i18n/__tests__/translate.test.ts +0 -23
  365. package/src/i18n/index.ts +0 -9
  366. package/src/i18n/messages/en.json +0 -171
  367. package/src/i18n/messages/ja.json +0 -171
  368. package/src/i18n/messages/vi.json +0 -171
  369. package/src/i18n/translate.ts +0 -74
  370. package/src/i18n/use-translation.ts +0 -53
  371. package/src/index.ts +0 -3
  372. package/src/lib/__tests__/control-styles.test.ts +0 -78
  373. package/src/lib/__tests__/datetime.test.ts +0 -77
  374. package/src/lib/__tests__/format-date.test.ts +0 -97
  375. package/src/lib/__tests__/format.test.ts +0 -62
  376. package/src/lib/__tests__/theme-tokens-audit.test.ts +0 -176
  377. package/src/lib/__tests__/theme-tokens-css.test.ts +0 -118
  378. package/src/lib/__tests__/token-governance.test.ts +0 -191
  379. package/src/lib/__tests__/variants.test.ts +0 -18
  380. package/src/lib/control-styles.ts +0 -33
  381. package/src/lib/datetime/detect.ts +0 -25
  382. package/src/lib/datetime/format-date.ts +0 -100
  383. package/src/lib/datetime/format.ts +0 -140
  384. package/src/lib/datetime/index.ts +0 -25
  385. package/src/lib/datetime/parse.ts +0 -51
  386. package/src/lib/datetime/sync.ts +0 -48
  387. package/src/lib/format.ts +0 -114
  388. package/src/lib/hooks.ts +0 -54
  389. package/src/lib/utils.ts +0 -6
  390. package/src/lib/variants.ts +0 -40
  391. package/src/props/components/app.prop.ts +0 -99
  392. package/src/props/components/data-display.prop.ts +0 -73
  393. package/src/props/components/data-entry.prop.ts +0 -334
  394. package/src/props/components/feedback.prop.ts +0 -80
  395. package/src/props/components/form.prop.ts +0 -46
  396. package/src/props/components/general.prop.ts +0 -18
  397. package/src/props/components/index.ts +0 -99
  398. package/src/props/components/layout.prop.ts +0 -130
  399. package/src/props/components/navigation.prop.ts +0 -88
  400. package/src/props/components/query.prop.ts +0 -94
  401. package/src/props/index.ts +0 -17
  402. package/src/props/vocabulary/data.prop.ts +0 -46
  403. package/src/props/vocabulary/index.ts +0 -73
  404. package/src/props/vocabulary/interaction.prop.ts +0 -42
  405. package/src/props/vocabulary/navigation.prop.ts +0 -19
  406. package/src/props/vocabulary/shared.prop.ts +0 -59
  407. package/src/test/__tests__/render-loop-guard.test.tsx +0 -38
  408. package/src/test/jest-dom.d.ts +0 -4
  409. package/src/test/render-loop-guard.tsx +0 -50
  410. package/src/test/render.tsx +0 -29
  411. package/src/test/theme-globals.test.ts +0 -77
  412. package/src/test/theme-globals.ts +0 -134
  413. package/src/test/theme-test-utils.tsx +0 -67
  414. /package/{src → dist}/styles/alert-layout.css +0 -0
  415. /package/{src → dist}/styles/badge-layout.css +0 -0
  416. /package/{src → dist}/styles/card-layout.css +0 -0
  417. /package/{src → dist}/styles/control.css +0 -0
  418. /package/{src → dist}/styles/data-display-layout.css +0 -0
  419. /package/{src → dist}/styles/density.css +0 -0
  420. /package/{src → dist}/styles/dialog-layout.css +0 -0
  421. /package/{src → dist}/styles/index.css +0 -0
  422. /package/{src → dist}/styles/layout.css +0 -0
  423. /package/{src → dist}/styles/shell-layout.css +0 -0
  424. /package/{src → dist}/styles/table-layout.css +0 -0
  425. /package/{src → dist}/theme/example.service.css +0 -0
  426. /package/{src → dist}/tokens/base.css +0 -0
  427. /package/{src → dist}/tokens/foundation.css +0 -0
  428. /package/{src → dist}/tokens/primitives/badge.css +0 -0
  429. /package/{src → dist}/tokens/primitives/card.css +0 -0
  430. /package/{src → dist}/tokens/primitives/control.css +0 -0
  431. /package/{src → dist}/tokens/primitives/feedback.css +0 -0
  432. /package/{src → dist}/tokens/primitives/layout.css +0 -0
  433. /package/{src → dist}/tokens/primitives/navigation.css +0 -0
  434. /package/{src → dist}/tokens/primitives/table.css +0 -0
@@ -1,33 +0,0 @@
1
- /** Shared control sizing — reads `--control-height`, `--font-size-*` from density / theme. */
2
- export const controlFieldClass =
3
- "ui-control w-full rounded-lg border border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/25 disabled:cursor-not-allowed disabled:opacity-50";
4
-
5
- export const controlMultilineClass =
6
- "ui-control-multiline w-full rounded-lg border border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/25 disabled:cursor-not-allowed disabled:opacity-50";
7
-
8
- export const controlTriggerClass =
9
- "ui-control flex w-full items-center justify-between gap-2 whitespace-nowrap rounded-lg border border-input bg-background shadow-sm focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/25 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1";
10
-
11
- export const controlIconClass = "size-[length:var(--control-height)] shrink-0";
12
-
13
- export const controlIconSmClass = "size-[calc(var(--control-height)-0.5rem)] shrink-0";
14
-
15
- /** Leading/affix icon inside an input row (search, command) — sized to `--control-icon-size`. */
16
- export const controlIconLeadingClass = "size-[length:var(--control-icon-size)] shrink-0";
17
-
18
- export const tableRowHeightClass = "h-[length:var(--table-row-height)]";
19
-
20
- export const tableHeadHeightClass = "h-[length:var(--table-row-height)]";
21
-
22
- export const tableCellPaddingClass = "py-[length:var(--table-cell-padding-y)]";
23
-
24
- /** Semantic status / badge tones — always use tokens, never raw Tailwind palette. */
25
- export const toneSuccessClass = "border-success/30 bg-success/10 text-success";
26
-
27
- export const toneWarningClass = "border-warning/30 bg-warning/10 text-warning-foreground";
28
-
29
- export const toneInfoClass = "border-info/30 bg-info/10 text-info";
30
-
31
- export const toneDestructiveClass = "border-destructive/30 bg-destructive/10 text-destructive";
32
-
33
- export const toneNeutralClass = "border-border bg-muted text-muted-foreground";
@@ -1,25 +0,0 @@
1
- import { isValidHhmm } from "./parse";
2
-
3
- export type FormatDateKind =
4
- | "auto"
5
- | "date"
6
- | "datetime"
7
- | "time"
8
- | "long"
9
- | "relative"
10
- | "calendar";
11
-
12
- const DATE_ONLY_RE = /^\d{4}-\d{2}-\d{2}$/;
13
-
14
- /** Infer display kind from raw value — ISO date, HH:mm, or instant. */
15
- export function detectFormatDateKind(value: string | Date): Exclude<FormatDateKind, "auto"> {
16
- if (value instanceof Date) return "datetime";
17
- const trimmed = value.trim();
18
- if (isValidHhmm(trimmed)) return "time";
19
- if (DATE_ONLY_RE.test(trimmed)) return "date";
20
- return "datetime";
21
- }
22
-
23
- export function isDateOnlyString(value: string): boolean {
24
- return DATE_ONLY_RE.test(value.trim());
25
- }
@@ -1,100 +0,0 @@
1
- import {
2
- formatAppDate,
3
- formatAppDateLong,
4
- formatAppDateTime,
5
- formatAppRelative,
6
- formatAppTime,
7
- formatCalendarDate,
8
- formatTimeOfDay,
9
- type FormatDatetimeOptions,
10
- } from "./format";
11
- import { detectFormatDateKind, type FormatDateKind } from "./detect";
12
- import { isValidHhmm, parseDateInput } from "./parse";
13
-
14
- const EMPTY = "—";
15
-
16
- export type FormatDateOptions = FormatDatetimeOptions & {
17
- /**
18
- * Output preset. Default `auto` detects ISO date / HH:mm / instant.
19
- * Locale, timezone, and 12h|24h fall back to AppProvider when omitted.
20
- */
21
- kind?: FormatDateKind;
22
- /** Treat `Date` as calendar pick (react-day-picker) — not an instant. */
23
- calendar?: boolean;
24
- };
25
-
26
- function resolveKind(
27
- value: string | Date,
28
- options?: FormatDateOptions,
29
- ): Exclude<FormatDateKind, "auto"> {
30
- if (options?.kind && options.kind !== "auto") return options.kind;
31
- if (options?.calendar && value instanceof Date) return "calendar";
32
- return detectFormatDateKind(value);
33
- }
34
-
35
- /**
36
- * **Single entry point** for all date/time display in GX apps.
37
- *
38
- * - Defaults: locale, timezone, timeFormat from AppProvider (`syncDatetimeContext`)
39
- * - Optional overrides: `{ timezone: "Asia/Tokyo" }` per call
40
- * - Auto-detect: `"2026-05-01"` → date, `"14:30"` → time, ISO instant → datetime
41
- * - International patterns: ISO 8601 date (`yyyy-MM-dd`) + ISO datetime (`yyyy-MM-dd HH:mm`)
42
- */
43
- export function formatDate(
44
- value: string | Date | null | undefined,
45
- options?: FormatDateOptions,
46
- ): string {
47
- if (value == null || value === "") return EMPTY;
48
-
49
- if (typeof value === "string") {
50
- const trimmed = value.trim();
51
- if (!trimmed) return EMPTY;
52
-
53
- const kind = resolveKind(trimmed, options);
54
- switch (kind) {
55
- case "time":
56
- return isValidHhmm(trimmed)
57
- ? formatTimeOfDay(trimmed, options)
58
- : formatAppTime(trimmed, options);
59
- case "date":
60
- return formatAppDate(trimmed, options);
61
- case "long":
62
- return formatAppDateLong(trimmed, options);
63
- case "relative":
64
- return formatAppRelative(trimmed, options);
65
- case "calendar":
66
- case "datetime":
67
- default:
68
- return formatAppDateTime(trimmed, options);
69
- }
70
- }
71
-
72
- if (!(value instanceof Date) || Number.isNaN(value.getTime())) return EMPTY;
73
-
74
- const kind = resolveKind(value, options);
75
- switch (kind) {
76
- case "calendar":
77
- return formatCalendarDate(value, options);
78
- case "date":
79
- return formatCalendarDate(value, options);
80
- case "time":
81
- return formatAppTime(value, options);
82
- case "long":
83
- return formatAppDateLong(value, options);
84
- case "relative":
85
- return formatAppRelative(value, options);
86
- case "datetime":
87
- default:
88
- return formatAppDateTime(value, options);
89
- }
90
- }
91
-
92
- /** True when value looks like a displayable date/time (string or valid Date). */
93
- export function isFormatDateValue(value: unknown): value is string | Date {
94
- if (value instanceof Date) return !Number.isNaN(value.getTime());
95
- if (typeof value !== "string") return false;
96
- const trimmed = value.trim();
97
- if (!trimmed) return false;
98
- if (isValidHhmm(trimmed)) return true;
99
- return parseDateInput(trimmed) != null;
100
- }
@@ -1,140 +0,0 @@
1
- import { TZDate } from "@date-fns/tz";
2
- import { format, formatDistanceToNow, type Locale } from "date-fns";
3
- import { getDateFnsLocale } from "../../app/locales";
4
- import { getDatePattern, getDateTimePattern } from "../../app/date-formats";
5
- import { getTimePattern, type AppTimeFormat } from "../../app/time-formats";
6
- import type { AppLocale, AppDateFormat } from "../../app/types";
7
- import { calendarDateToTZDate, hhmmToTZDate, parseDateInput } from "./parse";
8
- import { isDateOnlyString } from "./detect";
9
- import { getDatetimeContext } from "./sync";
10
-
11
- export type FormatDatetimeOptions = {
12
- locale?: Locale | AppLocale;
13
- timezone?: string;
14
- timeFormat?: AppTimeFormat;
15
- dateFormat?: AppDateFormat;
16
- };
17
-
18
- type ResolvedFormatOptions = {
19
- locale: Locale;
20
- timezone: string;
21
- timeFormat: AppTimeFormat;
22
- dateFormat: AppDateFormat;
23
- };
24
-
25
- function resolveLocale(locale?: Locale | AppLocale): Locale {
26
- if (!locale) return getDatetimeContext().dateFnsLocale;
27
- if (typeof locale === "string") return getDateFnsLocale(locale);
28
- return locale;
29
- }
30
-
31
- function resolveOptions(options?: FormatDatetimeOptions): ResolvedFormatOptions {
32
- const ctx = getDatetimeContext();
33
- return {
34
- locale: resolveLocale(options?.locale),
35
- timezone: options?.timezone ?? ctx.timezone,
36
- timeFormat: options?.timeFormat ?? ctx.timeFormat,
37
- dateFormat: options?.dateFormat ?? ctx.dateFormat,
38
- };
39
- }
40
-
41
- function formatTZDate(zoned: TZDate, pattern: string, options: ResolvedFormatOptions): string {
42
- return format(zoned, pattern, { locale: options.locale });
43
- }
44
-
45
- function instantToTZDate(value: Date, timezone: string): TZDate {
46
- return new TZDate(value, timezone);
47
- }
48
-
49
- const EMPTY = "—";
50
-
51
- /** Date-only from calendar picker — uses Y/M/D in app timezone. */
52
- export function formatCalendarDate(
53
- value: Date | null | undefined,
54
- options?: FormatDatetimeOptions,
55
- ): string {
56
- if (!value) return EMPTY;
57
- const resolved = resolveOptions(options);
58
- const zoned = calendarDateToTZDate(value, resolved.timezone);
59
- return formatTZDate(zoned, getDatePattern(resolved.dateFormat), resolved);
60
- }
61
-
62
- /** Date-only from ISO instant or `yyyy-MM-dd` string — date part in app timezone. */
63
- export function formatAppDate(
64
- value: string | Date | null | undefined,
65
- options?: FormatDatetimeOptions,
66
- ): string {
67
- const resolved = resolveOptions(options);
68
- if (typeof value === "string" && isDateOnlyString(value)) {
69
- const [year, month, day] = value.split("-").map(Number);
70
- const zoned = new TZDate(year, month - 1, day, resolved.timezone);
71
- return formatTZDate(zoned, getDatePattern(resolved.dateFormat), resolved);
72
- }
73
- const parsed = parseDateInput(value);
74
- if (!parsed) return EMPTY;
75
- const zoned = instantToTZDate(parsed, resolved.timezone);
76
- return formatTZDate(zoned, getDatePattern(resolved.dateFormat), resolved);
77
- }
78
-
79
- /** Date + time in app timezone. */
80
- export function formatAppDateTime(
81
- value: string | Date | null | undefined,
82
- options?: FormatDatetimeOptions,
83
- ): string {
84
- const parsed = parseDateInput(value);
85
- if (!parsed) return EMPTY;
86
- const resolved = resolveOptions(options);
87
- const zoned = instantToTZDate(parsed, resolved.timezone);
88
- return formatTZDate(
89
- zoned,
90
- getDateTimePattern(resolved.timeFormat, resolved.dateFormat),
91
- resolved,
92
- );
93
- }
94
-
95
- /** Time from ISO instant in app timezone. */
96
- export function formatAppTime(
97
- value: string | Date | null | undefined,
98
- options?: FormatDatetimeOptions,
99
- ): string {
100
- const parsed = parseDateInput(value);
101
- if (!parsed) return EMPTY;
102
- const resolved = resolveOptions(options);
103
- const zoned = instantToTZDate(parsed, resolved.timezone);
104
- return formatTZDate(zoned, getTimePattern(resolved.timeFormat), resolved);
105
- }
106
-
107
- /** Long date (PPP) in app timezone. */
108
- export function formatAppDateLong(
109
- value: string | Date | null | undefined,
110
- options?: FormatDatetimeOptions,
111
- ): string {
112
- const parsed = parseDateInput(value);
113
- if (!parsed) return EMPTY;
114
- const resolved = resolveOptions(options);
115
- const zoned = instantToTZDate(parsed, resolved.timezone);
116
- return formatTZDate(zoned, "PPP", resolved);
117
- }
118
-
119
- /** Relative time — instant-based; locale from context. */
120
- export function formatAppRelative(
121
- value: string | Date | null | undefined,
122
- options?: Pick<FormatDatetimeOptions, "locale">,
123
- ): string {
124
- const parsed = parseDateInput(value);
125
- if (!parsed) return EMPTY;
126
- const locale = resolveLocale(options?.locale);
127
- return formatDistanceToNow(parsed, { addSuffix: true, locale });
128
- }
129
-
130
- /** Format canonical HH:mm (24h storage) for display per timeFormat + locale. */
131
- export function formatTimeOfDay(
132
- hhmm: string | null | undefined,
133
- options?: FormatDatetimeOptions,
134
- ): string {
135
- if (!hhmm) return EMPTY;
136
- const resolved = resolveOptions(options);
137
- const zoned = hhmmToTZDate(hhmm, resolved.timezone);
138
- if (!zoned) return hhmm;
139
- return formatTZDate(zoned, getTimePattern(resolved.timeFormat), resolved);
140
- }
@@ -1,25 +0,0 @@
1
- export {
2
- syncDatetimeContext,
3
- getDatetimeContext,
4
- resetDatetimeContextForTests,
5
- type DatetimeContext,
6
- } from "./sync";
7
- export {
8
- parseDateInput,
9
- calendarDateToTZDate,
10
- isValidHhmm,
11
- normalizeHhmm,
12
- hhmmToTZDate,
13
- } from "./parse";
14
- export {
15
- formatCalendarDate,
16
- formatAppDate,
17
- formatAppDateTime,
18
- formatAppTime,
19
- formatAppDateLong,
20
- formatAppRelative,
21
- formatTimeOfDay,
22
- type FormatDatetimeOptions,
23
- } from "./format";
24
- export { formatDate, isFormatDateValue, type FormatDateOptions } from "./format-date";
25
- export { detectFormatDateKind, isDateOnlyString, type FormatDateKind } from "./detect";
@@ -1,51 +0,0 @@
1
- import { TZDate } from "@date-fns/tz";
2
- import { parseISO } from "date-fns";
3
- import { isDateOnlyString } from "./detect";
4
-
5
- /** Parse ISO string or Date — returns null for invalid values. */
6
- export function parseDateInput(value: string | Date | null | undefined): Date | null {
7
- if (value == null) return null;
8
- if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value;
9
- const trimmed = value.trim();
10
- if (isDateOnlyString(trimmed)) {
11
- const [year, month, day] = trimmed.split("-").map(Number);
12
- return new Date(year, month - 1, day);
13
- }
14
- const parsed = parseISO(trimmed);
15
- return Number.isNaN(parsed.getTime()) ? null : parsed;
16
- }
17
-
18
- /** Calendar date from react-day-picker — interpret Y/M/D in app timezone, not browser local. */
19
- export function calendarDateToTZDate(date: Date, timezone: string): TZDate {
20
- return new TZDate(date.getFullYear(), date.getMonth(), date.getDate(), timezone);
21
- }
22
-
23
- const HHMM_RE = /^([01]?\d|2[0-3]):([0-5]\d)$/;
24
-
25
- export function isValidHhmm(value: string): boolean {
26
- return HHMM_RE.test(value.trim());
27
- }
28
-
29
- /** Normalize loose input ("9:30") to canonical 24h "09:30". */
30
- export function normalizeHhmm(value: string): string | null {
31
- const trimmed = value.trim();
32
- if (isValidHhmm(trimmed)) {
33
- const [h, m] = trimmed.split(":");
34
- return `${h.padStart(2, "0")}:${m}`;
35
- }
36
- const loose = /^(\d{1,2}):(\d{2})$/.exec(trimmed);
37
- if (!loose) return null;
38
- const hours = Number(loose[1]);
39
- const minutes = Number(loose[2]);
40
- if (hours > 23 || minutes > 59) return null;
41
- return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
42
- }
43
-
44
- /** Map canonical HH:mm to a TZDate on today's calendar date in the given timezone. */
45
- export function hhmmToTZDate(hhmm: string, timezone: string): TZDate | null {
46
- const normalized = normalizeHhmm(hhmm);
47
- if (!normalized) return null;
48
- const [h, m] = normalized.split(":").map(Number);
49
- const today = TZDate.tz(timezone);
50
- return new TZDate(today.getFullYear(), today.getMonth(), today.getDate(), h, m, 0, 0, timezone);
51
- }
@@ -1,48 +0,0 @@
1
- import type { Locale } from "date-fns";
2
- import { getDateFnsLocale } from "../../app/locales";
3
- import { resolveDefaultDateFormat } from "../../app/date-format-labels";
4
- import type { AppLocale, AppTimeFormat, AppDateFormat } from "../../app/types";
5
-
6
- export type DatetimeContext = {
7
- locale: AppLocale;
8
- dateFnsLocale: Locale;
9
- timezone: string;
10
- timeFormat: AppTimeFormat;
11
- dateFormat: AppDateFormat;
12
- };
13
-
14
- const DEFAULT_LOCALE: AppLocale = "vi";
15
-
16
- const defaultContext = (): DatetimeContext => ({
17
- locale: DEFAULT_LOCALE,
18
- dateFnsLocale: getDateFnsLocale(DEFAULT_LOCALE),
19
- timezone: "Asia/Ho_Chi_Minh",
20
- timeFormat: "24h",
21
- dateFormat: resolveDefaultDateFormat(DEFAULT_LOCALE),
22
- });
23
-
24
- let syncedContext: DatetimeContext = defaultContext();
25
-
26
- /** Sync module-level datetime prefs from AppProvider (mirrors syncI18nLocale). */
27
- export function syncDatetimeContext(
28
- partial: Pick<DatetimeContext, "locale" | "timezone" | "timeFormat" | "dateFormat"> & {
29
- dateFnsLocale?: Locale;
30
- },
31
- ): void {
32
- syncedContext = {
33
- locale: partial.locale,
34
- timezone: partial.timezone,
35
- timeFormat: partial.timeFormat,
36
- dateFormat: partial.dateFormat,
37
- dateFnsLocale: partial.dateFnsLocale ?? getDateFnsLocale(partial.locale),
38
- };
39
- }
40
-
41
- export function getDatetimeContext(): Readonly<DatetimeContext> {
42
- return syncedContext;
43
- }
44
-
45
- /** Vitest only — reset to defaults between cases. */
46
- export function resetDatetimeContextForTests(): void {
47
- syncedContext = defaultContext();
48
- }
package/src/lib/format.ts DELETED
@@ -1,114 +0,0 @@
1
- // Shared formatting helpers — every admin component uses these instead of
2
- // inline string templates so the platform speaks one language for dates,
3
- // sizes, money, IDs.
4
- import { formatDate, type FormatDateOptions, type FormatDatetimeOptions } from "./datetime";
5
- import { translateCurrent } from "../i18n/translate";
6
-
7
- export type FormatOptions = FormatDatetimeOptions & FormatDateOptions;
8
-
9
- /** @deprecated Prefer `formatDate(value, { kind: "datetime" })` — delegates to unified formatter. */
10
- export function formatTime(
11
- value: string | Date | null | undefined,
12
- options?: FormatOptions,
13
- ): string {
14
- return formatDate(value, { ...options, kind: "time" });
15
- }
16
-
17
- /** @deprecated Prefer `formatDate(value, { kind: "datetime" })`. */
18
- export function formatDateTime(
19
- value: string | Date | null | undefined,
20
- options?: FormatOptions,
21
- ): string {
22
- return formatDate(value, { ...options, kind: "datetime" });
23
- }
24
-
25
- /** @deprecated Prefer `formatDate(value, { kind: "long" })`. */
26
- export function formatDateLong(
27
- value: string | Date | null | undefined,
28
- options?: FormatOptions,
29
- ): string {
30
- return formatDate(value, { ...options, kind: "long" });
31
- }
32
-
33
- /** @deprecated Prefer `formatDate(value, { kind: "relative" })`. */
34
- export function formatRelative(
35
- value: string | Date | null | undefined,
36
- options?: Pick<FormatOptions, "locale">,
37
- ): string {
38
- return formatDate(value, { ...options, kind: "relative" });
39
- }
40
-
41
- /** Bytes → "1.2 MB". */
42
- export function formatBytes(n: number | null | undefined): string {
43
- if (n == null) return "—";
44
- if (n < 1024) return `${n} B`;
45
- if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
46
- if (n < 1024 * 1024 * 1024) return `${(n / 1024 / 1024).toFixed(1)} MB`;
47
- return `${(n / 1024 / 1024 / 1024).toFixed(2)} GB`;
48
- }
49
-
50
- /** ISO 4217 minor units → display string. e.g. (1995, "USD") → "$19.95". */
51
- export function formatCurrency(amountMinor: number | null | undefined, currency: string): string {
52
- if (amountMinor == null || !currency) return "—";
53
- // Most ISO 4217 currencies use 2 decimal places; JPY/VND/KRW use 0.
54
- const zeroDecimal = [
55
- "JPY",
56
- "VND",
57
- "KRW",
58
- "CLP",
59
- "ISK",
60
- "BIF",
61
- "DJF",
62
- "GNF",
63
- "KMF",
64
- "RWF",
65
- "XAF",
66
- "XOF",
67
- "XPF",
68
- ];
69
- const minorUnitDigits = zeroDecimal.includes(currency.toUpperCase()) ? 0 : 2;
70
- const major = amountMinor / Math.pow(10, minorUnitDigits);
71
- return new Intl.NumberFormat("en-US", {
72
- style: "currency",
73
- currency,
74
- minimumFractionDigits: minorUnitDigits,
75
- maximumFractionDigits: minorUnitDigits,
76
- }).format(major);
77
- }
78
-
79
- /** UUIDv7 / UUIDv4 → first 8 chars + ellipsis. Pair with a Tooltip showing full. */
80
- export function shortId(id: string | null | undefined): string {
81
- if (!id) return "—";
82
- if (id.length <= 12) return id;
83
- return id.slice(0, 8) + "…";
84
- }
85
-
86
- /** Translate any backend error into something a user can act on. Falls back
87
- * to a generic message for non-Error objects (avoids dumping stack traces). */
88
- export function humanError(err: unknown): string {
89
- if (err instanceof Error) {
90
- const msg = err.message;
91
- const cleaned = msg.replace(/^\d{3}[^:]*:\s*/, "");
92
- if (cleaned && cleaned !== "(empty)") return cleaned;
93
- return translateCurrent("feedback.genericError");
94
- }
95
- return translateCurrent("feedback.genericError");
96
- }
97
-
98
- // Re-export datetime utilities for apps that import from lib/format.
99
- export {
100
- formatDate,
101
- isFormatDateValue,
102
- formatCalendarDate,
103
- formatAppDate,
104
- formatAppDateTime,
105
- formatAppTime,
106
- formatAppDateLong,
107
- formatAppRelative,
108
- formatTimeOfDay,
109
- parseDateInput,
110
- normalizeHhmm,
111
- isValidHhmm,
112
- detectFormatDateKind,
113
- } from "./datetime";
114
- export type { FormatDateOptions, FormatDatetimeOptions, FormatDateKind } from "./datetime";
package/src/lib/hooks.ts DELETED
@@ -1,54 +0,0 @@
1
- // Shared hooks for admin components.
2
- import { useEffect, useState } from "react";
3
-
4
- /**
5
- * Returns a debounced view of `value`, updated only after `delay` ms of no
6
- * change. Use for search inputs to avoid querying on every keystroke.
7
- *
8
- * setState runs only inside setTimeout (async) — compliant with
9
- * react-hooks/set-state-in-effect.
10
- */
11
- export function useDebouncedValue<T>(value: T, delay = 250): T {
12
- const [debounced, setDebounced] = useState(value);
13
- useEffect(() => {
14
- const t = setTimeout(() => {
15
- setDebounced(value);
16
- }, delay);
17
- return () => {
18
- clearTimeout(t);
19
- };
20
- }, [value, delay]);
21
- return debounced;
22
- }
23
-
24
- /**
25
- * Returns true while `ms` haven't elapsed since `signal` last flipped truthy.
26
- * setState is scheduled asynchronously (setTimeout 0 / ms) — Rules of React safe.
27
- */
28
- export function useTimeoutFlag(signal: unknown, ms = 2_000): boolean {
29
- const [active, setActive] = useState(false);
30
-
31
- useEffect(() => {
32
- if (!signal) {
33
- const id = window.setTimeout(() => {
34
- setActive(false);
35
- }, 0);
36
- return () => {
37
- clearTimeout(id);
38
- };
39
- }
40
-
41
- const showId = window.setTimeout(() => {
42
- setActive(true);
43
- }, 0);
44
- const hideId = window.setTimeout(() => {
45
- setActive(false);
46
- }, ms);
47
- return () => {
48
- clearTimeout(showId);
49
- clearTimeout(hideId);
50
- };
51
- }, [signal, ms]);
52
-
53
- return Boolean(signal) && active;
54
- }
package/src/lib/utils.ts DELETED
@@ -1,6 +0,0 @@
1
- import { clsx, type ClassValue } from "clsx";
2
- import { twMerge } from "tailwind-merge";
3
-
4
- export function cn(...inputs: ClassValue[]) {
5
- return twMerge(clsx(inputs));
6
- }
@@ -1,40 +0,0 @@
1
- /** Prop → internal class maps. Apps use component props, never these classes directly. */
2
- import type {
3
- InlineGapProp,
4
- PageContainerVariantProp,
5
- PageDensityProp,
6
- StackGapProp,
7
- } from "../props/vocabulary";
8
-
9
- export type Density = PageDensityProp;
10
- export type StackGap = StackGapProp;
11
- export type InlineGap = InlineGapProp;
12
- export type PageContainerVariant = PageContainerVariantProp;
13
-
14
- export const densityClass: Record<PageDensityProp, string> = {
15
- compact: "ui-density-compact",
16
- default: "ui-density-default",
17
- comfortable: "ui-density-comfortable",
18
- };
19
-
20
- export const pageContainerVariantClass: Record<PageContainerVariantProp, string | undefined> = {
21
- default: undefined,
22
- narrow: "ui-page-container--narrow",
23
- flush: "ui-page-container--flush",
24
- ghost: "ui-page-container--ghost",
25
- };
26
-
27
- export const stackGapClass: Record<StackGapProp, string> = {
28
- xs: "ui-stack-xs",
29
- sm: "ui-stack-sm",
30
- md: "ui-stack-md",
31
- lg: "ui-stack-lg",
32
- xl: "ui-stack-xl",
33
- };
34
-
35
- export const inlineGapClass: Record<InlineGapProp, string> = {
36
- xs: "ui-inline-xs",
37
- sm: "ui-inline-sm",
38
- md: "ui-inline-md",
39
- lg: "ui-inline-lg",
40
- };