@lerianstudio/sindarian-ui 2.0.0-beta.24 → 2.0.0-beta.26

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 (337) hide show
  1. package/dist/charts/chart.js +4 -231
  2. package/dist/charts/index.js +1 -11
  3. package/dist/components/breadcrumb/get-breadcrumb-paths.js +1 -18
  4. package/dist/components/breadcrumb/index.js +1 -37
  5. package/dist/components/card/account-card/index.js +1 -69
  6. package/dist/components/card/basic-card/index.js +1 -20
  7. package/dist/components/card/dashboard-card/index.js +1 -20
  8. package/dist/components/card/entity-card/index.js +1 -68
  9. package/dist/components/card/index.js +1 -20
  10. package/dist/components/dialog/confirmation-dialog/index.d.ts.map +1 -1
  11. package/dist/components/dialog/confirmation-dialog/index.js +1 -96
  12. package/dist/components/dialog/confirmation-dialog/use-confirm-dialog.js +1 -55
  13. package/dist/components/dialog/index.js +1 -19
  14. package/dist/components/dialog/large-dialog/index.d.ts +2 -2
  15. package/dist/components/dialog/large-dialog/index.d.ts.map +1 -1
  16. package/dist/components/dialog/large-dialog/index.js +1 -21
  17. package/dist/components/entity-box/index.js +1 -67
  18. package/dist/components/entity-data-table/index.js +1 -20
  19. package/dist/components/form/combo-box-field/index.js +1 -35
  20. package/dist/components/form/country-field/index.js +1 -11
  21. package/dist/components/form/date-picker-field/index.js +1 -83
  22. package/dist/components/form/date-range-field/index.js +1 -58
  23. package/dist/components/form/date-time-picker-field/index.js +1 -114
  24. package/dist/components/form/file-upload-field/index.js +1 -69
  25. package/dist/components/form/index.js +1 -31
  26. package/dist/components/form/input-field/index.js +1 -96
  27. package/dist/components/form/otp-field/index.js +1 -19
  28. package/dist/components/form/pagination-limit-field/index.js +1 -10
  29. package/dist/components/form/password-field/index.d.ts.map +1 -1
  30. package/dist/components/form/password-field/index.js +1 -16
  31. package/dist/components/form/radio-group-field/index.js +1 -36
  32. package/dist/components/form/renderable-label.js +1 -57
  33. package/dist/components/form/select-field/index.js +1 -68
  34. package/dist/components/form/state-field/index.js +1 -42
  35. package/dist/components/form/switch-field/index.js +1 -16
  36. package/dist/components/form/textarea-field/index.js +1 -23
  37. package/dist/components/page/index.js +1 -20
  38. package/dist/components/page-header/index.js +1 -80
  39. package/dist/components/pagination/index.js +1 -10
  40. package/dist/components/table/id-table-cell.js +1 -109
  41. package/dist/components/table/index.js +1 -19
  42. package/dist/components/table/locked-table-actions.js +1 -41
  43. package/dist/components/table/name-table-cell.js +1 -58
  44. package/dist/components/ui/accordion/index.js +1 -62
  45. package/dist/components/ui/alert/index.js +1 -45
  46. package/dist/components/ui/alert-dialog/index.js +1 -84
  47. package/dist/components/ui/autocomplete/index.js +1 -440
  48. package/dist/components/ui/autosize-textarea/index.js +1 -89
  49. package/dist/components/ui/avatar/index.js +1 -51
  50. package/dist/components/ui/badge/index.js +1 -83
  51. package/dist/components/ui/breadcrumb/index.js +1 -35
  52. package/dist/components/ui/button/index.js +1 -65
  53. package/dist/components/ui/button/styles.css +2 -1
  54. package/dist/components/ui/calendar/index.js +1 -118
  55. package/dist/components/ui/card/index.js +1 -32
  56. package/dist/components/ui/checkbox/index.js +1 -44
  57. package/dist/components/ui/collapsible/index.js +1 -50
  58. package/dist/components/ui/command/index.js +1 -95
  59. package/dist/components/ui/copy-field/index.js +1 -163
  60. package/dist/components/ui/dialog/index.d.ts +4 -1
  61. package/dist/components/ui/dialog/index.d.ts.map +1 -1
  62. package/dist/components/ui/dialog/index.js +1 -80
  63. package/dist/components/ui/dialog/styles.css +2 -1
  64. package/dist/components/ui/dropdown-menu/index.js +1 -110
  65. package/dist/components/ui/field/index.js +1 -82
  66. package/dist/components/ui/file-upload/index.js +1 -574
  67. package/dist/components/ui/form.js +1 -162
  68. package/dist/components/ui/hover-card/index.js +1 -51
  69. package/dist/components/ui/icon-button/index.js +1 -35
  70. package/dist/components/ui/input/adornment.js +1 -21
  71. package/dist/components/ui/input/index.js +1 -99
  72. package/dist/components/ui/input/styles.css +29 -12
  73. package/dist/components/ui/label/index.js +1 -45
  74. package/dist/components/ui/lerian-wordmark/index.js +1 -7
  75. package/dist/components/ui/loading-button/index.js +1 -9
  76. package/dist/components/ui/multiple-select/index.js +1 -235
  77. package/dist/components/ui/otp-input/index.js +1 -62
  78. package/dist/components/ui/paper/index.js +1 -8
  79. package/dist/components/ui/paper-collapsible/index.js +1 -24
  80. package/dist/components/ui/popover/index.js +1 -55
  81. package/dist/components/ui/progress/index.js +1 -66
  82. package/dist/components/ui/qr-code/index.js +1 -27
  83. package/dist/components/ui/radio-group/index.js +1 -48
  84. package/dist/components/ui/scroll-area/index.js +1 -49
  85. package/dist/components/ui/select/index.js +1 -119
  86. package/dist/components/ui/select/styles.css +6 -3
  87. package/dist/components/ui/separator/index.js +1 -43
  88. package/dist/components/ui/sheet/index.d.ts +7 -2
  89. package/dist/components/ui/sheet/index.d.ts.map +1 -1
  90. package/dist/components/ui/sheet/index.js +1 -136
  91. package/dist/components/ui/sidebar/index.js +1 -27
  92. package/dist/components/ui/sidebar/next-router.cjs +1 -119
  93. package/dist/components/ui/sidebar/sidebar-back-button.js +1 -8
  94. package/dist/components/ui/sidebar/sidebar-components.js +1 -23
  95. package/dist/components/ui/sidebar/sidebar-expand-button.js +1 -49
  96. package/dist/components/ui/sidebar/sidebar-item-button.js +1 -21
  97. package/dist/components/ui/sidebar/sidebar-item-collapsible.js +1 -52
  98. package/dist/components/ui/sidebar/sidebar-item-icon-button.js +1 -18
  99. package/dist/components/ui/sidebar/sidebar-item.js +1 -44
  100. package/dist/components/ui/sidebar/sidebar-provider.js +1 -201
  101. package/dist/components/ui/sidebar/sidebar-root.d.ts +3 -1
  102. package/dist/components/ui/sidebar/sidebar-root.d.ts.map +1 -1
  103. package/dist/components/ui/sidebar/sidebar-root.js +1 -130
  104. package/dist/components/ui/sidebar/sidebar-router.js +1 -126
  105. package/dist/components/ui/sidebar/sidebar-trigger.js +1 -57
  106. package/dist/components/ui/skeleton/index.js +1 -8
  107. package/dist/components/ui/stepper/index.js +1 -29
  108. package/dist/components/ui/switch/index.js +1 -43
  109. package/dist/components/ui/table/index.js +1 -56
  110. package/dist/components/ui/tabs/index.js +1 -55
  111. package/dist/components/ui/textarea/index.js +1 -8
  112. package/dist/components/ui/time-picker/index.js +1 -85
  113. package/dist/components/ui/toast/index.js +1 -3
  114. package/dist/components/ui/toast/toaster.js +1 -16
  115. package/dist/components/ui/toggle-group/index.js +1 -156
  116. package/dist/components/ui/tooltip/index.js +1 -81
  117. package/dist/domain/blotter/index.js +1 -20
  118. package/dist/domain/delinquency-aging/aging-buckets.js +1 -120
  119. package/dist/domain/delinquency-aging/index.js +1 -222
  120. package/dist/domain/figure/index.js +1 -19
  121. package/dist/domain/format.js +1 -137
  122. package/dist/domain/index.js +1 -43
  123. package/dist/domain/key-id/index.js +1 -174
  124. package/dist/domain/ledger-sheet/index.js +1 -28
  125. package/dist/domain/money-diff.js +1 -48
  126. package/dist/domain/money-math.js +1 -104
  127. package/dist/domain/money-text/index.js +1 -123
  128. package/dist/domain/section-label/index.js +1 -17
  129. package/dist/domain/status-rail/index.js +1 -76
  130. package/dist/domain/threshold-gauge/index.js +1 -161
  131. package/dist/enterprise/alert-banner/index.js +1 -24
  132. package/dist/enterprise/app-shell/index.js +1 -87
  133. package/dist/enterprise/cursor-pager/index.js +1 -26
  134. package/dist/enterprise/data-table/column-size.js +1 -103
  135. package/dist/enterprise/data-table/index.d.ts.map +1 -1
  136. package/dist/enterprise/data-table/index.js +1 -345
  137. package/dist/enterprise/date-range-picker/index.js +1 -115
  138. package/dist/enterprise/detail-panel/index.js +1 -20
  139. package/dist/enterprise/empty-state/index.d.ts +6 -1
  140. package/dist/enterprise/empty-state/index.d.ts.map +1 -1
  141. package/dist/enterprise/empty-state/index.js +1 -13
  142. package/dist/enterprise/index.js +1 -39
  143. package/dist/enterprise/number-input/index.js +1 -252
  144. package/dist/enterprise/search-input/index.js +1 -121
  145. package/dist/enterprise/stat-card/index.js +1 -75
  146. package/dist/enterprise/status-badge/index.js +1 -120
  147. package/dist/enterprise/use-is-mobile.js +1 -68
  148. package/dist/enterprise/virtualized-table/index.js +1 -141
  149. package/dist/esm/charts/chart.js +4 -190
  150. package/dist/esm/charts/index.js +1 -3
  151. package/dist/esm/components/breadcrumb/get-breadcrumb-paths.js +1 -12
  152. package/dist/esm/components/breadcrumb/index.js +1 -30
  153. package/dist/esm/components/card/account-card/index.js +1 -53
  154. package/dist/esm/components/card/basic-card/index.js +1 -14
  155. package/dist/esm/components/card/dashboard-card/index.js +1 -14
  156. package/dist/esm/components/card/entity-card/index.js +1 -52
  157. package/dist/esm/components/card/index.js +1 -4
  158. package/dist/esm/components/dialog/confirmation-dialog/index.d.ts.map +1 -1
  159. package/dist/esm/components/dialog/confirmation-dialog/index.js +1 -60
  160. package/dist/esm/components/dialog/confirmation-dialog/use-confirm-dialog.js +1 -49
  161. package/dist/esm/components/dialog/index.js +1 -3
  162. package/dist/esm/components/dialog/large-dialog/index.d.ts +2 -2
  163. package/dist/esm/components/dialog/large-dialog/index.d.ts.map +1 -1
  164. package/dist/esm/components/dialog/large-dialog/index.js +1 -16
  165. package/dist/esm/components/entity-box/index.js +1 -56
  166. package/dist/esm/components/entity-data-table/index.js +1 -17
  167. package/dist/esm/components/form/combo-box-field/index.js +1 -28
  168. package/dist/esm/components/form/country-field/index.js +1 -7
  169. package/dist/esm/components/form/date-picker-field/index.js +1 -43
  170. package/dist/esm/components/form/date-range-field/index.js +1 -18
  171. package/dist/esm/components/form/date-time-picker-field/index.js +1 -74
  172. package/dist/esm/components/form/file-upload-field/index.js +1 -65
  173. package/dist/esm/components/form/index.js +1 -15
  174. package/dist/esm/components/form/input-field/index.js +1 -92
  175. package/dist/esm/components/form/otp-field/index.js +1 -15
  176. package/dist/esm/components/form/pagination-limit-field/index.js +1 -6
  177. package/dist/esm/components/form/password-field/index.d.ts.map +1 -1
  178. package/dist/esm/components/form/password-field/index.js +1 -10
  179. package/dist/esm/components/form/radio-group-field/index.js +1 -32
  180. package/dist/esm/components/form/renderable-label.js +1 -54
  181. package/dist/esm/components/form/select-field/index.js +1 -64
  182. package/dist/esm/components/form/state-field/index.js +1 -35
  183. package/dist/esm/components/form/switch-field/index.js +1 -12
  184. package/dist/esm/components/form/textarea-field/index.js +1 -19
  185. package/dist/esm/components/page/index.js +1 -15
  186. package/dist/esm/components/page-header/index.js +1 -71
  187. package/dist/esm/components/pagination/index.js +1 -6
  188. package/dist/esm/components/table/id-table-cell.js +1 -105
  189. package/dist/esm/components/table/index.js +1 -3
  190. package/dist/esm/components/table/locked-table-actions.js +1 -37
  191. package/dist/esm/components/table/name-table-cell.js +1 -54
  192. package/dist/esm/components/ui/accordion/index.js +1 -24
  193. package/dist/esm/components/ui/alert/index.js +1 -38
  194. package/dist/esm/components/ui/alert-dialog/index.js +1 -39
  195. package/dist/esm/components/ui/autocomplete/index.js +1 -392
  196. package/dist/esm/components/ui/autosize-textarea/index.js +1 -51
  197. package/dist/esm/components/ui/avatar/index.js +1 -14
  198. package/dist/esm/components/ui/badge/index.js +1 -79
  199. package/dist/esm/components/ui/breadcrumb/index.js +1 -27
  200. package/dist/esm/components/ui/button/index.js +1 -60
  201. package/dist/esm/components/ui/calendar/index.js +1 -82
  202. package/dist/esm/components/ui/card/index.js +1 -24
  203. package/dist/esm/components/ui/checkbox/index.js +1 -9
  204. package/dist/esm/components/ui/collapsible/index.js +1 -13
  205. package/dist/esm/components/ui/command/index.js +1 -51
  206. package/dist/esm/components/ui/copy-field/index.js +1 -127
  207. package/dist/esm/components/ui/dialog/index.d.ts +4 -1
  208. package/dist/esm/components/ui/dialog/index.d.ts.map +1 -1
  209. package/dist/esm/components/ui/dialog/index.js +1 -36
  210. package/dist/esm/components/ui/dropdown-menu/index.js +1 -60
  211. package/dist/esm/components/ui/field/index.js +1 -71
  212. package/dist/esm/components/ui/file-upload/index.js +1 -536
  213. package/dist/esm/components/ui/form.js +1 -118
  214. package/dist/esm/components/ui/hover-card/index.js +1 -14
  215. package/dist/esm/components/ui/icon-button/index.js +1 -31
  216. package/dist/esm/components/ui/input/adornment.js +1 -17
  217. package/dist/esm/components/ui/input/index.js +1 -60
  218. package/dist/esm/components/ui/label/index.js +1 -10
  219. package/dist/esm/components/ui/lerian-wordmark/index.js +1 -4
  220. package/dist/esm/components/ui/loading-button/index.js +1 -7
  221. package/dist/esm/components/ui/multiple-select/index.js +1 -196
  222. package/dist/esm/components/ui/otp-input/index.js +1 -21
  223. package/dist/esm/components/ui/paper/index.js +1 -5
  224. package/dist/esm/components/ui/paper-collapsible/index.js +1 -19
  225. package/dist/esm/components/ui/popover/index.js +1 -17
  226. package/dist/esm/components/ui/progress/index.js +1 -31
  227. package/dist/esm/components/ui/qr-code/index.js +1 -24
  228. package/dist/esm/components/ui/radio-group/index.js +1 -12
  229. package/dist/esm/components/ui/scroll-area/index.js +1 -13
  230. package/dist/esm/components/ui/select/index.js +1 -74
  231. package/dist/esm/components/ui/separator/index.js +1 -8
  232. package/dist/esm/components/ui/sheet/index.d.ts +7 -2
  233. package/dist/esm/components/ui/sheet/index.d.ts.map +1 -1
  234. package/dist/esm/components/ui/sheet/index.js +1 -92
  235. package/dist/esm/components/ui/sidebar/index.js +1 -11
  236. package/dist/esm/components/ui/sidebar/next-router.cjs +1 -119
  237. package/dist/esm/components/ui/sidebar/sidebar-back-button.js +1 -5
  238. package/dist/esm/components/ui/sidebar/sidebar-components.js +1 -15
  239. package/dist/esm/components/ui/sidebar/sidebar-expand-button.js +1 -42
  240. package/dist/esm/components/ui/sidebar/sidebar-item-button.js +1 -18
  241. package/dist/esm/components/ui/sidebar/sidebar-item-collapsible.js +1 -44
  242. package/dist/esm/components/ui/sidebar/sidebar-item-icon-button.js +1 -14
  243. package/dist/esm/components/ui/sidebar/sidebar-item.js +1 -40
  244. package/dist/esm/components/ui/sidebar/sidebar-provider.js +1 -193
  245. package/dist/esm/components/ui/sidebar/sidebar-root.d.ts +3 -1
  246. package/dist/esm/components/ui/sidebar/sidebar-root.d.ts.map +1 -1
  247. package/dist/esm/components/ui/sidebar/sidebar-root.js +1 -126
  248. package/dist/esm/components/ui/sidebar/sidebar-router.js +1 -89
  249. package/dist/esm/components/ui/sidebar/sidebar-trigger.js +1 -53
  250. package/dist/esm/components/ui/skeleton/index.js +1 -6
  251. package/dist/esm/components/ui/stepper/index.js +1 -20
  252. package/dist/esm/components/ui/switch/index.js +1 -8
  253. package/dist/esm/components/ui/table/index.js +1 -44
  254. package/dist/esm/components/ui/tabs/index.js +1 -17
  255. package/dist/esm/components/ui/textarea/index.js +1 -6
  256. package/dist/esm/components/ui/time-picker/index.js +1 -49
  257. package/dist/esm/components/ui/toast/index.js +1 -2
  258. package/dist/esm/components/ui/toast/toaster.js +1 -13
  259. package/dist/esm/components/ui/toggle-group/index.js +1 -120
  260. package/dist/esm/components/ui/tooltip/index.js +1 -43
  261. package/dist/esm/domain/blotter/index.js +1 -16
  262. package/dist/esm/domain/delinquency-aging/aging-buckets.js +1 -115
  263. package/dist/esm/domain/delinquency-aging/index.js +1 -218
  264. package/dist/esm/domain/figure/index.js +1 -15
  265. package/dist/esm/domain/format.js +1 -128
  266. package/dist/esm/domain/index.js +1 -19
  267. package/dist/esm/domain/key-id/index.js +1 -169
  268. package/dist/esm/domain/ledger-sheet/index.js +1 -24
  269. package/dist/esm/domain/money-diff.js +1 -45
  270. package/dist/esm/domain/money-math.js +1 -98
  271. package/dist/esm/domain/money-text/index.js +1 -118
  272. package/dist/esm/domain/section-label/index.js +1 -14
  273. package/dist/esm/domain/status-rail/index.js +1 -71
  274. package/dist/esm/domain/threshold-gauge/index.js +1 -157
  275. package/dist/esm/enterprise/alert-banner/index.js +1 -21
  276. package/dist/esm/enterprise/app-shell/index.js +1 -51
  277. package/dist/esm/enterprise/cursor-pager/index.js +1 -23
  278. package/dist/esm/enterprise/data-table/column-size.js +1 -97
  279. package/dist/esm/enterprise/data-table/index.d.ts.map +1 -1
  280. package/dist/esm/enterprise/data-table/index.js +1 -342
  281. package/dist/esm/enterprise/date-range-picker/index.js +1 -112
  282. package/dist/esm/enterprise/detail-panel/index.js +1 -17
  283. package/dist/esm/enterprise/empty-state/index.d.ts +6 -1
  284. package/dist/esm/enterprise/empty-state/index.d.ts.map +1 -1
  285. package/dist/esm/enterprise/empty-state/index.js +1 -10
  286. package/dist/esm/enterprise/index.js +1 -22
  287. package/dist/esm/enterprise/number-input/index.js +1 -214
  288. package/dist/esm/enterprise/search-input/index.js +1 -85
  289. package/dist/esm/enterprise/stat-card/index.js +1 -72
  290. package/dist/esm/enterprise/status-badge/index.js +1 -116
  291. package/dist/esm/enterprise/use-is-mobile.js +1 -31
  292. package/dist/esm/enterprise/virtualized-table/index.js +1 -138
  293. package/dist/esm/hooks/use-click-away.js +1 -22
  294. package/dist/esm/hooks/use-pagination.js +1 -38
  295. package/dist/esm/hooks/use-stepper.js +1 -22
  296. package/dist/esm/hooks/use-time.js +1 -13
  297. package/dist/esm/hooks/use-toast.js +1 -107
  298. package/dist/esm/index.js +1 -77
  299. package/dist/esm/lib/storage/get-storage-object.js +1 -17
  300. package/dist/esm/lib/storage/get-storage.js +1 -14
  301. package/dist/esm/lib/storage/index.js +1 -2
  302. package/dist/esm/lib/typography.js +1 -31
  303. package/dist/esm/lib/utils.js +1 -41
  304. package/dist/esm/theme/get-theme-script.js +1 -41
  305. package/dist/esm/theme/index.js +1 -4
  306. package/dist/esm/theme/mode-toggle.js +1 -45
  307. package/dist/esm/theme/theme-provider.js +1 -122
  308. package/dist/esm/toast/helpers.js +1 -36
  309. package/dist/esm/toast/index.js +1 -4
  310. package/dist/esm/types/metadata-type.js +1 -1
  311. package/dist/esm/utils/countries.cjs +1 -17
  312. package/dist/esm/utils/country-utils.js +1 -18
  313. package/dist/esm/utils/currency-codes.js +1 -181
  314. package/dist/globals.css +1 -0
  315. package/dist/hooks/use-click-away.js +1 -29
  316. package/dist/hooks/use-pagination.js +1 -41
  317. package/dist/hooks/use-stepper.js +1 -26
  318. package/dist/hooks/use-time.js +1 -20
  319. package/dist/hooks/use-toast.js +1 -111
  320. package/dist/index.js +1 -96
  321. package/dist/lib/storage/get-storage-object.js +1 -23
  322. package/dist/lib/storage/get-storage.js +1 -17
  323. package/dist/lib/storage/index.js +1 -18
  324. package/dist/lib/typography.js +1 -34
  325. package/dist/lib/utils.js +1 -45
  326. package/dist/theme/get-theme-script.js +1 -44
  327. package/dist/theme/index.js +1 -11
  328. package/dist/theme/mode-toggle.js +1 -48
  329. package/dist/theme/theme-provider.js +1 -160
  330. package/dist/toast/helpers.js +1 -41
  331. package/dist/toast/index.js +1 -10
  332. package/dist/tokens.css +7 -4
  333. package/dist/types/metadata-type.js +1 -2
  334. package/dist/utils/countries.cjs +1 -17
  335. package/dist/utils/country-utils.js +1 -25
  336. package/dist/utils/currency-codes.js +1 -184
  337. package/package.json +4 -3
@@ -1,103 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UNSIZED_DEFAULT_COLUMN = void 0;
4
- exports.readDeclaredColumnSize = readDeclaredColumnSize;
5
- exports.readDeclaredGroupSize = readDeclaredGroupSize;
6
- exports.readPreferredColumnSize = readPreferredColumnSize;
7
- /**
8
- * The column sizing a ColumnDef actually DECLARED, or `undefined` when it
9
- * declared none. This is VirtualizedTable's reading: flex rows honour all
10
- * three, so `size`, `minSize` and `maxSize` all PIN. DataTable's `<th>`/`<td>`
11
- * path reads the same declaration through {@link readPreferredColumnSize},
12
- * which drops the ceiling CSS auto table layout cannot enforce.
13
- *
14
- * Reading the raw `columnDef` is only honest because both tables pass
15
- * `defaultColumn: { size: undefined, minSize: undefined, maxSize: undefined }`
16
- * to `useReactTable`. TanStack builds every columnDef as
17
- * `{ ...featureDefaults, ...table.options.defaultColumn, ...userDef }`, so
18
- * those three overrides blank out the `defaultColumnSizing` the ColumnSizing
19
- * feature would otherwise stamp on every column (150 / 20 / MAX_SAFE_INTEGER).
20
- * Without them a column asking for nothing reports `size: 150` and a column
21
- * asking for exactly 150 is indistinguishable from it. `column.getSize()` is
22
- * unaffected: it falls back to `defaultColumnSizing` with `??`, so column
23
- * offsets and the table's total size are byte-identical either way.
24
- *
25
- * Width comes from `getSize()` rather than the raw `size` so it lands already
26
- * clamped by the column's own min/max.
27
- */
28
- function readDeclaredColumnSize(column) {
29
- const { size, minSize, maxSize } = column.columnDef;
30
- const width = size === undefined ? undefined : column.getSize();
31
- if (width === undefined && minSize === undefined && maxSize === undefined) {
32
- return undefined;
33
- }
34
- return { width, minWidth: minSize, maxWidth: maxSize };
35
- }
36
- /**
37
- * A GROUP header cell is exactly as wide as the leaf columns it spans, so it
38
- * can only be pinned when every one of them is: a group whose leaves are
39
- * partly sized has no honest fixed width, and keeps its colSpan flex share so
40
- * the header rule still tracks the cells beneath it. Reading the group's own
41
- * ColumnDef instead would size the header against a declaration its body cells
42
- * never see.
43
- *
44
- * Every dimension the leaves agree on carries up, CEILING INCLUDED. This is
45
- * VirtualizedTable's path, where flex rows honour `maxSize` on a leaf — so a
46
- * group of capped leaves whose header carried no `maxWidth` was free to grow
47
- * past every column it names, which is the same header-vs-cells drift the
48
- * width sum exists to prevent. Each dimension is decided on its own: a group
49
- * can be uncapped and still have a floor.
50
- */
51
- function readDeclaredGroupSize(leaves) {
52
- if (leaves.length === 0)
53
- return undefined;
54
- const sizes = leaves.map(readDeclaredColumnSize);
55
- const width = sum(sizes, 'width');
56
- const minWidth = sum(sizes, 'minWidth');
57
- const maxWidth = sum(sizes, 'maxWidth');
58
- if (width === undefined && minWidth === undefined && maxWidth === undefined) {
59
- return undefined;
60
- }
61
- return { width, minWidth, maxWidth };
62
- }
63
- /**
64
- * The total of one dimension, or `undefined` unless EVERY leaf declared it. One
65
- * leaf short and the group has no honest total: an unsized leaf flexes, an
66
- * unfloored one can shrink, and an uncapped one grows without limit.
67
- */
68
- function sum(sizes, key) {
69
- let total = 0;
70
- for (const size of sizes) {
71
- const value = size?.[key];
72
- if (value === undefined)
73
- return undefined;
74
- total += value;
75
- }
76
- return total;
77
- }
78
- /**
79
- * The same declaration as {@link readDeclaredColumnSize}, minus `maxWidth`.
80
- *
81
- * DataTable renders real `<th>`/`<td>` under CSS AUTO table layout, where
82
- * Chrome and Firefox ignore `max-width` on a cell. Emitting it would advertise
83
- * a ceiling that never holds, so this path keeps only what the layout obeys:
84
- * `size` as a PREFERRED width and `minSize` as a floor. A column that must not
85
- * grow past a width belongs in VirtualizedTable.
86
- */
87
- function readPreferredColumnSize(column) {
88
- const { width, minWidth } = readDeclaredColumnSize(column) ?? {};
89
- if (width === undefined && minWidth === undefined) {
90
- return undefined;
91
- }
92
- return { width, minWidth };
93
- }
94
- /**
95
- * Blanks out the `defaultColumnSizing` TanStack stamps onto every ColumnDef, so
96
- * `columnDef.size` / `minSize` / `maxSize` mean "the consumer asked for this"
97
- * and nothing else. Both tables pass it to `useReactTable`.
98
- */
99
- exports.UNSIZED_DEFAULT_COLUMN = {
100
- size: undefined,
101
- minSize: undefined,
102
- maxSize: undefined
103
- };
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.UNSIZED_DEFAULT_COLUMN=void 0;exports.readDeclaredColumnSize=readDeclaredColumnSize;exports.readDeclaredGroupSize=readDeclaredGroupSize;exports.readPreferredColumnSize=readPreferredColumnSize;function readDeclaredColumnSize(d){const{size:n,minSize:e,maxSize:t}=d.columnDef;const i=n===void 0?void 0:d.getSize();if(i===void 0&&e===void 0&&t===void 0){return void 0}return{width:i,minWidth:e,maxWidth:t}}function readDeclaredGroupSize(d){if(d.length===0)return void 0;const n=d.map(readDeclaredColumnSize);const e=sum(n,"width");const t=sum(n,"minWidth");const i=sum(n,"maxWidth");if(e===void 0&&t===void 0&&i===void 0){return void 0}return{width:e,minWidth:t,maxWidth:i}}function sum(d,n){let e=0;for(const t of d){const i=t?.[n];if(i===void 0)return void 0;e+=i}return e}function readPreferredColumnSize(d){const{width:n,minWidth:e}=readDeclaredColumnSize(d)??{};if(n===void 0&&e===void 0){return void 0}return{width:n,minWidth:e}}exports.UNSIZED_DEFAULT_COLUMN={size:void 0,minSize:void 0,maxSize:void 0};
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/enterprise/data-table/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/enterprise/data-table/index.tsx"],"names":[],"mappings":"AAuDA,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,UAAU,EAEf,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAEjB,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAA;AAc9B,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAGjE;;;;;GAKG;AACH,OAAO,QAAQ,uBAAuB,CAAC;IAIrC,UAAU,UAAU,CAAC,KAAK,SAAS,OAAO,EAAE,MAAM;QAChD;;;;WAIG;QACH,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB;;;;;WAKG;QACH,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAA;QACnC;;;WAGG;QACH,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB;;;;;WAKG;QACH,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB;;;;;;;;;;;;;WAaG;QACH,aAAa,CAAC,EAAE,OAAO,CAAA;KACxB;CACF;AAED;;;;;;;;GAQG;AACH,KAAK,iBAAiB,CAAC,KAAK,IACxB;IACE,kBAAkB,CAAC,EAAE,KAAK,CAAA;IAC1B,YAAY,CAAC,EAAE,KAAK,CAAA;IACpB,oBAAoB,CAAC,EAAE,KAAK,CAAA;IAC5B,oBAAoB,CAAC,EAAE,KAAK,CAAA;CAC7B,GACD;IACE,kBAAkB,EAAE,IAAI,CAAA;IACxB,kFAAkF;IAClF,YAAY,EAAE,iBAAiB,CAAA;IAC/B,4DAA4D;IAC5D,oBAAoB,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAA;IACnD;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,MAAM,CAAA;CAC9C,CAAA;AAEL;;;;;;;;;;;;;;;;GAgBG;AACH,KAAK,YAAY,GACb;IACE,aAAa,CAAC,EAAE,KAAK,CAAA;IACrB,OAAO,CAAC,EAAE,KAAK,CAAA;IACf,eAAe,CAAC,EAAE,KAAK,CAAA;CACxB,GACD;IACE,aAAa,EAAE,IAAI,CAAA;IACnB;;;;;OAKG;IACH,OAAO,EAAE,YAAY,CAAA;IACrB,uDAAuD;IACvD,eAAe,EAAE,UAAU,CAAC,YAAY,CAAC,CAAA;CAC1C,CAAA;AAEL;;;;;;;;;;;;;;;;GAgBG;AACH,KAAK,qBAAqB,GACtB;IACE,uEAAuE;IACvE,gBAAgB,EAAE,eAAe,CAAA;IACjC;;;OAGG;IACH,wBAAwB,CAAC,EAAE,UAAU,CAAC,eAAe,CAAC,CAAA;CACvD,GACD;IAAE,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAAC,wBAAwB,CAAC,EAAE,SAAS,CAAA;CAAE,CAAA;AAE1E,KAAK,kBAAkB,CAAC,KAAK,IAAI;IAC/B,OAAO,EAAE,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAA;IACpC,IAAI,EAAE,KAAK,EAAE,CAAA;IACb,sDAAsD;IACtD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iGAAiG;IACjG,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,eAAe,CAAA;IACvB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAChD;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAA;IACnC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAA;IACpC;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,MAAM,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,cAAc,CAAC,KAAK,IAAI,kBAAkB,CAAC,KAAK,CAAC,GAC3D,iBAAiB,CAAC,KAAK,CAAC,GACxB,YAAY,GACZ,qBAAqB,CAAA;AA4GvB,wBAAgB,SAAS,CAAC,KAAK,EAAE,EAC/B,OAAO,EACP,IAAI,EACJ,OAAe,EACf,YAAgB,EAChB,YAAmC,EACnC,KAAK,EACL,QAAQ,EACR,KAAa,EACb,OAAuB,EACvB,kBAA0B,EAC1B,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,aAAqB,EACrB,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,OAAO,EACP,SAAS,EACT,aAAa,EACb,MAAM,EACP,EAAE,cAAc,CAAC,KAAK,CAAC,+BAiWvB"}
@@ -1,345 +1 @@
1
- 'use client';
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.DataTable = DataTable;
5
- const jsx_runtime_1 = require("react/jsx-runtime");
6
- /**
7
- * DataTable — a typed, generic wrapper over TanStack Table v8.
8
- *
9
- * Pairs with CursorPager (server-driven pagination): pass the page's `items`
10
- * as `data`; this component does no client-side paging or sorting by default.
11
- * It owns the three render states the list screens need:
12
- * - loading → header + skeleton rows
13
- * - empty → EmptyState (data resolved, zero rows)
14
- * - data → semantic table rows; cells own any links/actions
15
- *
16
- * Column heads speak the kit's LABEL_VOICE_CLASS; `headClassName` overrides it
17
- * per table. An optional `footer` node renders in a `tfoot` for footed totals.
18
- *
19
- * Columns are standard TanStack `ColumnDef<T>`; cells receive the row's
20
- * `original` value, so screens compose money / date / status cells directly in
21
- * their column `cell` renderers.
22
- *
23
- * Declared column sizing (see `./column-size`) does NOT mean the same thing in
24
- * the kit's two table paths, because their layouts differ:
25
- * - DataTable renders real `<th>`/`<td>` under CSS AUTO table layout (the
26
- * `Table` primitive sets no `table-fixed`). There, `size` is a PREFERRED
27
- * width the browser may exceed to fit content, `minSize` acts as a floor,
28
- * and `maxSize` is ignored outright — Chrome and Firefox do not apply
29
- * `max-width` to table cells. A column declaring none keeps auto width.
30
- * - VirtualizedTable renders flex rows, where all three PIN: `size`,
31
- * `minSize` and `maxSize` are honoured exactly as declared.
32
- * So a column that must not grow past a width belongs in VirtualizedTable, or
33
- * in a cell renderer that truncates its own content.
34
- *
35
- * Row selection is opt-in and controlled: pass `enableRowSelection` plus
36
- * `rowSelection` / `onRowSelectionChange` (TanStack-native types). When
37
- * enabled, a checkbox column is prepended — header checkbox selects the
38
- * page (indeterminate for partial), checkbox-cell clicks never bubble to
39
- * row-level handlers. With the flag off (the default), nothing changes.
40
- *
41
- * Sorting is opt-in and controlled too: pass `enableSorting` plus `sorting` /
42
- * `onSortingChange`. Rows are never reordered client-side (`manualSorting`, no
43
- * sorted row model); what the flag buys is `aria-sort` on each sortable `th`.
44
- * With the flag off (the default), no header carries the attribute.
45
- *
46
- * Keyboard navigation is opt-in via `onRowActivate`: when present, rows get
47
- * a roving tabindex (Tab enters the table once at the anchor row; the next
48
- * Tab moves to the row's first tabbable child if it has one, otherwise out
49
- * of the table — no trap), ArrowUp/Down move row focus clamped to the page,
50
- * Home/End jump to the page edges, Enter activates the row through the
51
- * callback, and Space toggles selection when `enableRowSelection` is on.
52
- * Cmd/Ctrl+Enter opens the row's destination in a new tab when the optional
53
- * `rowHref` builder is provided (window.open with noopener,noreferrer);
54
- * without it, modified Enter stays a deliberate no-op — never a same-tab
55
- * activation. Keydown events originating from interactive children (links,
56
- * buttons, checkboxes, form fields) are never hijacked.
57
- */
58
- const react_1 = require("react");
59
- const react_table_1 = require("@tanstack/react-table");
60
- const table_1 = require("../../components/ui/table");
61
- const skeleton_1 = require("../../components/ui/skeleton");
62
- const typography_1 = require("../../lib/typography");
63
- const utils_1 = require("../../lib/utils");
64
- const empty_state_1 = require("../empty-state");
65
- const column_size_1 = require("./column-size");
66
- const SELECTION_COLUMN_ID = '__select__';
67
- const CHECKBOX_CLASS = 'accent-primary block size-4';
68
- /** Figure treatment for `meta: { numeric: true }` columns; the alignment half
69
- * lives in ALIGN_CELL_CLASS so `meta.align` can override one without the other. */
70
- const NUMERIC_FIGURE_CLASS = 'font-mono tabular-nums';
71
- /**
72
- * Body-cell alignment, one class per direction rather than a single string with
73
- * `text-right` baked in: an explicit `meta.align` has to beat `numeric` by
74
- * choosing the class, not by out-ordering it — tailwind-merge resolving two
75
- * conflicting alignment utilities by source order is not a contract worth
76
- * relying on.
77
- */
78
- const ALIGN_CELL_CLASS = {
79
- left: 'text-left',
80
- center: 'text-center',
81
- right: 'text-right'
82
- };
83
- /**
84
- * Keydown events whose target sits inside one of these are never hijacked
85
- * by the row-level keyboard handler — Space in a checkbox and Enter on an
86
- * in-cell link keep their native behavior.
87
- */
88
- const INTERACTIVE_CHILD_SELECTOR = 'a, button, input, select, textarea, [role="checkbox"]';
89
- /**
90
- * Inset focus outline for keyboard-navigable rows. Outline, not Tailwind
91
- * ring: ring is box-shadow, which renders unreliably on display: table-row.
92
- * `focus-visible`-gated, so mouse users (and visual baselines) see nothing.
93
- */
94
- const ROW_FOCUS_CLASS = 'focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring';
95
- function stopPropagation(event) {
96
- event.stopPropagation();
97
- }
98
- /**
99
- * ARIA sort state for one header cell. `undefined` (attribute omitted) on a
100
- * column that cannot sort, which covers both sorting-off tables and columns
101
- * that opted out, so the attribute never claims a control the user does not
102
- * have.
103
- */
104
- function ariaSortFor(column) {
105
- if (!column.getCanSort())
106
- return undefined;
107
- const sorted = column.getIsSorted();
108
- if (sorted === 'asc')
109
- return 'ascending';
110
- if (sorted === 'desc')
111
- return 'descending';
112
- return 'none';
113
- }
114
- function SelectAllCheckbox({ table }) {
115
- const allSelected = table.getIsAllPageRowsSelected();
116
- const someSelected = table.getIsSomePageRowsSelected();
117
- return ((0, jsx_runtime_1.jsx)("input", { type: "checkbox", className: CHECKBOX_CLASS, "aria-label": "Select all rows on this page", checked: allSelected, ref: (el) => {
118
- if (el)
119
- el.indeterminate = !allSelected && someSelected;
120
- }, onChange: table.getToggleAllPageRowsSelectedHandler() }));
121
- }
122
- function RowSelectionCheckbox({ row, getLabel }) {
123
- return ((0, jsx_runtime_1.jsx)("input", { type: "checkbox", className: CHECKBOX_CLASS, "aria-label": getLabel ? getLabel(row.original) : `Select row ${row.id}`, checked: row.getIsSelected(), disabled: !row.getCanSelect(), onChange: row.getToggleSelectedHandler() }));
124
- }
125
- function createSelectionColumn(getLabel) {
126
- return {
127
- id: SELECTION_COLUMN_ID,
128
- header: ({ table }) => (0, jsx_runtime_1.jsx)(SelectAllCheckbox, { table: table }),
129
- cell: ({ row }) => (0, jsx_runtime_1.jsx)(RowSelectionCheckbox, { row: row, getLabel: getLabel })
130
- };
131
- }
132
- function DataTable({ columns, data, loading = false, skeletonRows = 8, loadingLabel = 'Loading table rows', empty, getRowId, flush = false, density = 'comfortable', enableRowSelection = false, rowSelection, onRowSelectionChange, getRowSelectionLabel, enableSorting = false, sorting, onSortingChange, columnVisibility, onColumnVisibilityChange, onRowActivate, rowHref, className, headClassName, footer }) {
133
- const tableColumns = (0, react_1.useMemo)(() => enableRowSelection
134
- ? [createSelectionColumn(getRowSelectionLabel), ...columns]
135
- : columns, [columns, enableRowSelection, getRowSelectionLabel]);
136
- const table = (0, react_table_1.useReactTable)({
137
- data,
138
- columns: tableColumns,
139
- // Keeps `columnDef.size`/`minSize`/`maxSize` meaning "declared" — see
140
- // ./column-size. `getSize()` is unaffected; it falls back to the library
141
- // defaults itself.
142
- defaultColumn: column_size_1.UNSIZED_DEFAULT_COLUMN,
143
- getCoreRowModel: (0, react_table_1.getCoreRowModel)(),
144
- getRowId,
145
- enableRowSelection,
146
- // Controlled-only, exactly as sindarian-x shipped it: this component holds
147
- // no selection state. The `?? {}` is the JS-consumer safety net; the prop
148
- // types make the TS path require the controlled pair whenever selection is
149
- // enabled, so the dead-checkbox configuration is now unrepresentable.
150
- onRowSelectionChange: enableRowSelection ? onRowSelectionChange : undefined,
151
- // Controlled-only as well, and deliberately without `getSortedRowModel`:
152
- // `manualSorting` tells TanStack the rows arrive in the order the consumer
153
- // already chose, so enabling sorting changes what the header ANNOUNCES,
154
- // never what the body shows.
155
- manualSorting: true,
156
- enableSorting,
157
- onSortingChange: enableSorting ? onSortingChange : undefined,
158
- // ⛔ EACH VISIBILITY ENTRY IS GUARDED ON ITS OWN PROP, NEVER ON THE OTHER.
159
- //
160
- // TanStack merges options as `{...defaultOptions, ...options}` and state as
161
- // `{...internalState, ...options.state}`, both plain spreads — so a key
162
- // present and holding `undefined` OVERWRITES what it was meant to leave
163
- // alone. `onColumnVisibilityChange: undefined` replaces the feature's own
164
- // `makeStateUpdater`, and `setColumnVisibility` reads
165
- // `options.onColumnVisibilityChange == null ? void 0 : ...`, so it (and
166
- // every `column.toggleVisibility` behind it) becomes a silent no-op.
167
- // `columnVisibility: undefined` replaces the table's initial `{}`, so a
168
- // consumer reading the slice gets `undefined` instead of an empty object.
169
- //
170
- // Guarding the UPDATER on the STATE put that `undefined` back for the
171
- // union's first arm — state with no updater, which is the shipped console
172
- // usage, where a separate dropdown owns the state. A table that passes
173
- // neither prop is uncontrolled, exactly as before.
174
- ...(onColumnVisibilityChange !== undefined && { onColumnVisibilityChange }),
175
- state: {
176
- rowSelection: enableRowSelection ? (rowSelection ?? {}) : undefined,
177
- sorting: enableSorting ? (sorting ?? []) : undefined,
178
- ...(columnVisibility !== undefined && { columnVisibility })
179
- }
180
- });
181
- // Visible, not declared: the skeleton grid and the empty row's colSpan have
182
- // to match the header the table actually rendered, and a hidden column is in
183
- // `tableColumns` but in no `<th>`.
184
- const colCount = table.getVisibleLeafColumns().length;
185
- const dataRows = table.getRowModel().rows;
186
- const rowCount = dataRows.length;
187
- // Compact density overrides only THIS table's cell padding (tailwind-merge
188
- // lets the later utility win over TableHead/TableCell's defaults).
189
- // Comfortable passes nothing, so the default render is unchanged.
190
- const compact = density === 'compact';
191
- const headDensityClass = compact ? 'h-8 px-2' : undefined;
192
- const cellDensityClass = compact ? 'px-2 py-1.5' : undefined;
193
- // --- Roving row focus (active only when onRowActivate is provided) ---
194
- const keyboardNav = onRowActivate !== undefined;
195
- const [focusedIndex, setFocusedIndex] = (0, react_1.useState)(0);
196
- // ponytail: rowRefs is keyed by render index, while rows are id-keyed
197
- // (`key={row.id}`). This holds only because DataTable is server-driven with
198
- // no in-place client reorder, and React 19's per-render ref cleanup defuses
199
- // stale entries. If client-side reorder is ever added, re-key this Map by
200
- // row.id to keep focus targets aligned with their rows.
201
- const rowRefs = (0, react_1.useRef)(new Map());
202
- const focusWithinRef = (0, react_1.useRef)(false);
203
- const containerRef = (0, react_1.useRef)(null);
204
- // Render-time clamp: exactly one anchor row (tabIndex=0) even on the
205
- // frame where data shrank but state has not caught up yet.
206
- const anchorIndex = rowCount > 0 ? Math.min(focusedIndex, rowCount - 1) : 0;
207
- // Data changes clamp the anchor but never steal focus: DOM focus moves
208
- // only if focus was already inside the table and the focused row vanished
209
- // (e.g. page flip removed it). Never autofocus on mount.
210
- (0, react_1.useEffect)(() => {
211
- if (!keyboardNav)
212
- return;
213
- // Clamp the focus target ONCE and drive both the state setter and the
214
- // .focus() call from the same value — reading `focusedIndex` separately
215
- // after the functional update would use the stale pre-clamp closure value
216
- // and try to focus an unmounted row, dropping focus to <body>.
217
- const max = Math.max(rowCount - 1, 0);
218
- const target = Math.min(focusedIndex, max);
219
- setFocusedIndex(target);
220
- if (!focusWithinRef.current)
221
- return;
222
- const active = document.activeElement;
223
- if (active && containerRef.current?.contains(active))
224
- return;
225
- // The target row may have unmounted on a data-shrink frame; walk down to
226
- // the nearest existing lower index, falling back to the container, so
227
- // focus never escapes the table.
228
- for (let i = target; i >= 0; i--) {
229
- const rowEl = rowRefs.current.get(i);
230
- if (rowEl) {
231
- rowEl.focus();
232
- return;
233
- }
234
- }
235
- containerRef.current?.focus();
236
- }, [keyboardNav, rowCount, focusedIndex, data]);
237
- const focusRow = (index) => {
238
- rowRefs.current.get(index)?.focus();
239
- };
240
- const handleRowBlur = (event) => {
241
- const next = event.relatedTarget;
242
- if (!next || !containerRef.current?.contains(next)) {
243
- focusWithinRef.current = false;
244
- }
245
- };
246
- const handleRowKeyDown = (event, row, rowIndex) => {
247
- const target = event.target;
248
- if (target !== event.currentTarget &&
249
- target.closest(INTERACTIVE_CHILD_SELECTOR) !== null) {
250
- return;
251
- }
252
- switch (event.key) {
253
- case 'ArrowDown':
254
- event.preventDefault();
255
- focusRow(Math.min(rowIndex + 1, rowCount - 1));
256
- break;
257
- case 'ArrowUp':
258
- event.preventDefault();
259
- focusRow(Math.max(rowIndex - 1, 0));
260
- break;
261
- case 'Home':
262
- event.preventDefault();
263
- focusRow(0);
264
- break;
265
- case 'End':
266
- event.preventDefault();
267
- focusRow(rowCount - 1);
268
- break;
269
- case 'Enter':
270
- // Modified Enter (Cmd/Ctrl) means "open elsewhere" — a same-tab
271
- // activation would destroy the user's context. With rowHref it
272
- // opens the row's destination in a new tab; without it (sheet-based
273
- // tables), it stays a deliberate no-op.
274
- if (event.metaKey || event.ctrlKey) {
275
- if (rowHref) {
276
- window.open(rowHref(row.original), '_blank', 'noopener,noreferrer');
277
- }
278
- break;
279
- }
280
- onRowActivate?.(row.original);
281
- break;
282
- case ' ':
283
- if (enableRowSelection && row.getCanSelect()) {
284
- event.preventDefault();
285
- row.getToggleSelectedHandler()(event);
286
- }
287
- break;
288
- default:
289
- break;
290
- }
291
- };
292
- return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef,
293
- // tabIndex={-1} (keyboard-nav only) makes the container programmatically
294
- // focusable so the focus-restoration fallback can land here when every
295
- // row has unmounted, keeping focus inside the table rather than on <body>.
296
- tabIndex: keyboardNav ? -1 : undefined, className: (0, utils_1.cn)(!flush &&
297
- 'border-border bg-card text-card-foreground rounded-lg border', className), children: [(0, jsx_runtime_1.jsx)("span", { className: "sr-only", role: "status", children: loading
298
- ? loadingLabel
299
- : rowCount === 0
300
- ? 'No rows'
301
- : `${rowCount} rows` }), (0, jsx_runtime_1.jsxs)(table_1.Table, { "aria-busy": loading ? 'true' : undefined, children: [(0, jsx_runtime_1.jsx)(table_1.TableHeader, { children: table.getHeaderGroups().map((headerGroup) => ((0, jsx_runtime_1.jsx)(table_1.TableRow, { className: "hover:bg-transparent", children: headerGroup.headers.map((header) => {
302
- const meta = header.column.columnDef.meta;
303
- return ((0, jsx_runtime_1.jsx)(table_1.TableHead, { align: meta?.align ?? (meta?.numeric ? 'right' : undefined), "aria-sort": header.isPlaceholder
304
- ? undefined
305
- : ariaSortFor(header.column),
306
- // Only a column that DECLARED sizing gets an inline width;
307
- // everything else keeps the auto table layout it has today.
308
- style: (0, column_size_1.readPreferredColumnSize)(header.column), className: (0, utils_1.cn)(typography_1.LABEL_VOICE_CLASS, headDensityClass, header.column.id === SELECTION_COLUMN_ID && 'w-10', headClassName, meta?.headerClassName), children: header.isPlaceholder
309
- ? null
310
- : (0, react_table_1.flexRender)(header.column.columnDef.header, header.getContext()) }, header.id));
311
- }) }, headerGroup.id))) }), (0, jsx_runtime_1.jsx)(table_1.TableBody, { children: loading ? (Array.from({ length: skeletonRows }).map((_, rowIndex) => ((0, jsx_runtime_1.jsx)(table_1.TableRow, { className: "hover:bg-transparent", children: Array.from({ length: colCount }).map((__, cellIndex) => ((0, jsx_runtime_1.jsx)(table_1.TableCell, { className: cellDensityClass, children: (0, jsx_runtime_1.jsx)(skeleton_1.Skeleton, { className: "h-4 w-full max-w-[160px]" }) }, `skeleton-${rowIndex}-${cellIndex}`))) }, `skeleton-${rowIndex}`)))) : rowCount === 0 ? ((0, jsx_runtime_1.jsx)(table_1.TableRow, { className: "hover:bg-transparent", children: (0, jsx_runtime_1.jsx)(table_1.TableCell, { colSpan: colCount, className: "p-0", children: (0, jsx_runtime_1.jsx)(empty_state_1.EmptyState, { title: empty?.title ?? 'Nothing here yet', description: empty?.description, icon: empty?.icon, action: empty?.action,
312
- // The DataTable renders the ledger register grammar, so its
313
- // empty surface reads as a ruled page rather than a centered
314
- // void. Callers can still override via `empty.ruled = false`.
315
- ruled: empty?.ruled ?? true }) }) })) : (dataRows.map((row, rowIndex) => ((0, jsx_runtime_1.jsx)(table_1.TableRow, { ref: keyboardNav
316
- ? (el) => {
317
- if (el)
318
- rowRefs.current.set(rowIndex, el);
319
- else
320
- rowRefs.current.delete(rowIndex);
321
- }
322
- : undefined, tabIndex: keyboardNav ? (rowIndex === anchorIndex ? 0 : -1) : undefined, onFocus: keyboardNav
323
- ? () => {
324
- focusWithinRef.current = true;
325
- setFocusedIndex(rowIndex);
326
- }
327
- : undefined, onBlur: keyboardNav ? handleRowBlur : undefined, onKeyDown: keyboardNav
328
- ? (event) => handleRowKeyDown(event, row, rowIndex)
329
- : undefined, className: keyboardNav ? ROW_FOCUS_CLASS : undefined, "data-state": enableRowSelection && row.getIsSelected()
330
- ? 'selected'
331
- : undefined, children: row.getVisibleCells().map((cell) => {
332
- const meta = cell.column.columnDef.meta;
333
- const content = (0, react_table_1.flexRender)(cell.column.columnDef.cell, cell.getContext());
334
- // The column owns its `<td>`: render the consumer's cell bare.
335
- // The kit's selection column is built here and carries no
336
- // meta, so it can never take this path.
337
- if (meta?.renderOwnCell) {
338
- return (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: content }, cell.id);
339
- }
340
- const align = meta?.align ?? (meta?.numeric ? 'right' : undefined);
341
- return ((0, jsx_runtime_1.jsx)(table_1.TableCell, { style: (0, column_size_1.readPreferredColumnSize)(cell.column), className: (0, utils_1.cn)(meta?.numeric && NUMERIC_FIGURE_CLASS, align && ALIGN_CELL_CLASS[align], cellDensityClass, cell.column.id === SELECTION_COLUMN_ID && 'w-10', meta?.className), onClick: cell.column.id === SELECTION_COLUMN_ID
342
- ? stopPropagation
343
- : undefined, children: content }, cell.id));
344
- }) }, row.id)))) }), footer ? (0, jsx_runtime_1.jsx)(table_1.TableFooter, { children: footer }) : null] })] }));
345
- }
1
+ "use client";"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.DataTable=DataTable;const jsx_runtime_1=require("react/jsx-runtime");const react_1=require("react");const react_table_1=require("@tanstack/react-table");const table_1=require("../../components/ui/table");const skeleton_1=require("../../components/ui/skeleton");const typography_1=require("../../lib/typography");const utils_1=require("../../lib/utils");const empty_state_1=require("../empty-state");const column_size_1=require("./column-size");const SELECTION_COLUMN_ID="__select__";const CHECKBOX_CLASS="accent-primary block size-4";const NUMERIC_FIGURE_CLASS="font-mono tabular-nums";const ALIGN_CELL_CLASS={left:"text-left",center:"text-center",right:"text-right"};const INTERACTIVE_CHILD_SELECTOR='a, button, input, select, textarea, [role="checkbox"]';const ROW_FOCUS_CLASS="focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring";function stopPropagation(r){r.stopPropagation()}function ariaSortFor(r){if(!r.getCanSort())return void 0;const s=r.getIsSorted();if(s==="asc")return"ascending";if(s==="desc")return"descending";return"none"}function SelectAllCheckbox({table:r}){const s=r.getIsAllPageRowsSelected();const u=r.getIsSomePageRowsSelected();return(0,jsx_runtime_1.jsx)("input",{type:"checkbox",className:CHECKBOX_CLASS,"aria-label":"Select all rows on this page",checked:s,ref:f=>{if(f)f.indeterminate=!s&&u},onChange:r.getToggleAllPageRowsSelectedHandler()})}function RowSelectionCheckbox({row:r,getLabel:s}){return(0,jsx_runtime_1.jsx)("input",{type:"checkbox",className:CHECKBOX_CLASS,"aria-label":s?s(r.original):`Select row ${r.id}`,checked:r.getIsSelected(),disabled:!r.getCanSelect(),onChange:r.getToggleSelectedHandler()})}function createSelectionColumn(r){return{id:SELECTION_COLUMN_ID,header:({table:s})=>(0,jsx_runtime_1.jsx)(SelectAllCheckbox,{table:s}),cell:({row:s})=>(0,jsx_runtime_1.jsx)(RowSelectionCheckbox,{row:s,getLabel:r})}}function DataTable({columns:r,data:s,loading:u=false,skeletonRows:f=8,loadingLabel:w="Loading table rows",empty:i,getRowId:I,flush:M=false,density:O="comfortable",enableRowSelection:l=false,rowSelection:P,onRowSelectionChange:q,getRowSelectionLabel:_,enableSorting:h=false,sorting:F,onSortingChange:H,columnVisibility:S,onColumnVisibilityChange:k,onRowActivate:N,rowHref:T,className:U,headClassName:v,footer:j}){const z=(0,react_1.useMemo)(()=>l?[createSelectionColumn(_),...r]:r,[r,l,_]);const p=(0,react_table_1.useReactTable)({data:s,columns:z,defaultColumn:column_size_1.UNSIZED_DEFAULT_COLUMN,getCoreRowModel:(0,react_table_1.getCoreRowModel)(),getRowId:I,enableRowSelection:l,onRowSelectionChange:l?q:void 0,manualSorting:true,enableSorting:h,onSortingChange:h?H:void 0,...k!==void 0&&{onColumnVisibilityChange:k},state:{rowSelection:l?P??{}:void 0,sorting:h?F??[]:void 0,...S!==void 0&&{columnVisibility:S}}});const R=p.getVisibleLeafColumns().length;const y=p.getRowModel().rows;const c=y.length;const D=O==="compact";const B=D?"h-8 px-2":void 0;const E=D?"px-2 py-1.5":void 0;const o=N!==void 0;const[x,A]=(0,react_1.useState)(0);const m=(0,react_1.useRef)(new Map);const C=(0,react_1.useRef)(false);const g=(0,react_1.useRef)(null);const K=c>0?Math.min(x,c-1):0;(0,react_1.useEffect)(()=>{if(!o)return;const t=Math.max(c-1,0);const e=Math.min(x,t);A(e);if(!C.current)return;const n=document.activeElement;if(n&&g.current?.contains(n))return;for(let a=e;a>=0;a--){const d=m.current.get(a);if(d){d.focus();return}}g.current?.focus()},[o,c,x,s]);const b=t=>{m.current.get(t)?.focus()};const $=t=>{const e=t.relatedTarget;if(!e||!g.current?.contains(e)){C.current=false}};const G=(t,e,n)=>{const a=t.target;if(a!==t.currentTarget&&a.closest(INTERACTIVE_CHILD_SELECTOR)!==null){return}switch(t.key){case"ArrowDown":t.preventDefault();b(Math.min(n+1,c-1));break;case"ArrowUp":t.preventDefault();b(Math.max(n-1,0));break;case"Home":t.preventDefault();b(0);break;case"End":t.preventDefault();b(c-1);break;case"Enter":if(t.metaKey||t.ctrlKey){if(T){window.open(T(e.original),"_blank","noopener,noreferrer")}break}N?.(e.original);break;case" ":if(l&&e.getCanSelect()){t.preventDefault();e.getToggleSelectedHandler()(t)}break;default:break}};return(0,jsx_runtime_1.jsxs)("div",{ref:g,tabIndex:o?-1:void 0,className:(0,utils_1.cn)(!M&&"border-border bg-card text-card-foreground rounded-lg border",U),children:[(0,jsx_runtime_1.jsx)("span",{className:"sr-only",role:"status",children:u?w:c===0?"No rows":`${c} rows`}),(0,jsx_runtime_1.jsxs)(table_1.Table,{"aria-busy":u?"true":void 0,children:[(0,jsx_runtime_1.jsx)(table_1.TableHeader,{children:p.getHeaderGroups().map(t=>(0,jsx_runtime_1.jsx)(table_1.TableRow,{className:"hover:bg-transparent",children:t.headers.map(e=>{const n=e.column.columnDef.meta;return(0,jsx_runtime_1.jsx)(table_1.TableHead,{align:n?.align??(n?.numeric?"right":void 0),"aria-sort":e.isPlaceholder?void 0:ariaSortFor(e.column),style:(0,column_size_1.readPreferredColumnSize)(e.column),className:(0,utils_1.cn)(typography_1.LABEL_VOICE_CLASS,B,e.column.id===SELECTION_COLUMN_ID&&"w-10",v,n?.headerClassName),children:e.isPlaceholder?null:(0,react_table_1.flexRender)(e.column.columnDef.header,e.getContext())},e.id)})},t.id))}),(0,jsx_runtime_1.jsx)(table_1.TableBody,{children:u?Array.from({length:f}).map((t,e)=>(0,jsx_runtime_1.jsx)(table_1.TableRow,{className:"hover:bg-transparent",children:Array.from({length:R}).map((n,a)=>(0,jsx_runtime_1.jsx)(table_1.TableCell,{className:E,children:(0,jsx_runtime_1.jsx)(skeleton_1.Skeleton,{className:"h-4 w-full max-w-[160px]"})},`skeleton-${e}-${a}`))},`skeleton-${e}`)):c===0?(0,jsx_runtime_1.jsx)(table_1.TableRow,{className:"hover:bg-transparent",children:(0,jsx_runtime_1.jsx)(table_1.TableCell,{colSpan:R,className:"p-0",children:(0,jsx_runtime_1.jsx)(empty_state_1.EmptyState,{title:i?.title??"Nothing here yet",titleAs:i?.titleAs,description:i?.description,icon:i?.icon,action:i?.action,ruled:i?.ruled??true})})}):y.map((t,e)=>(0,jsx_runtime_1.jsx)(table_1.TableRow,{ref:o?n=>{if(n)m.current.set(e,n);else m.current.delete(e)}:void 0,tabIndex:o?e===K?0:-1:void 0,onFocus:o?()=>{C.current=true;A(e)}:void 0,onBlur:o?$:void 0,onKeyDown:o?n=>G(n,t,e):void 0,className:o?ROW_FOCUS_CLASS:void 0,"data-state":l&&t.getIsSelected()?"selected":void 0,children:t.getVisibleCells().map(n=>{const a=n.column.columnDef.meta;const d=(0,react_table_1.flexRender)(n.column.columnDef.cell,n.getContext());if(a?.renderOwnCell){return(0,jsx_runtime_1.jsx)(react_1.Fragment,{children:d},n.id)}const L=a?.align??(a?.numeric?"right":void 0);return(0,jsx_runtime_1.jsx)(table_1.TableCell,{style:(0,column_size_1.readPreferredColumnSize)(n.column),className:(0,utils_1.cn)(a?.numeric&&NUMERIC_FIGURE_CLASS,L&&ALIGN_CELL_CLASS[L],E,n.column.id===SELECTION_COLUMN_ID&&"w-10",a?.className),onClick:n.column.id===SELECTION_COLUMN_ID?stopPropagation:void 0,children:d},n.id)})},t.id))}),j?(0,jsx_runtime_1.jsx)(table_1.TableFooter,{children:j}):null]})]})}
@@ -1,115 +1 @@
1
- 'use client';
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.DateRangePicker = DateRangePicker;
5
- const jsx_runtime_1 = require("react/jsx-runtime");
6
- /**
7
- * DateRangePicker — a two-segment popover range control.
8
- *
9
- * Two labelled trigger segments (from / to) each open the SAME two-month
10
- * react-day-picker range calendar over the same range selection. The external
11
- * contract is plain YYYY-MM-DD strings (empty string = unset) so state shapes
12
- * that speak `date_from`/`date_to` stay untouched. The picker guarantees
13
- * from <= to (react-day-picker reorders inverted picks);
14
- * aria-invalid/aria-describedby pass-throughs keep external validation wiring
15
- * alive. i18n is via plain string/locale props.
16
- *
17
- * ONE POPOVER ROOT PER SEGMENT, deliberately. A single `Popover.Root` holds ONE
18
- * trigger ref and ONE open state, so wrapping the whole two-button row in a
19
- * single `PopoverTrigger asChild` put Radix's dialog attributes
20
- * (`aria-haspopup`, `aria-expanded`, `aria-controls`) on a plain, non-focusable
21
- * `div` — an aria-allowed-attr violation, two buttons advertising the same
22
- * expanded state, and focus that Radix could drop on `document.body` when the
23
- * popover closed. Each segment is now a real `PopoverTrigger` button: focusable,
24
- * correctly named, and the element Radix returns focus to on dismissal.
25
- */
26
- const react_1 = require("react");
27
- const lucide_react_1 = require("lucide-react");
28
- const locale_1 = require("react-day-picker/locale");
29
- const button_1 = require("../../components/ui/button");
30
- const calendar_1 = require("../../components/ui/calendar");
31
- const label_1 = require("../../components/ui/label");
32
- const popover_1 = require("../../components/ui/popover");
33
- const utils_1 = require("../../lib/utils");
34
- /** Leading YYYY-MM-DD of an ISO date (or date-time) string. */
35
- const ISO_DAY = /^(\d{4})-(\d{2})-(\d{2})/;
36
- /**
37
- * Parse a YYYY-MM-DD day into a LOCAL-midnight Date — the calendar works in
38
- * local time, so building from parts avoids the UTC shift `new Date(string)`
39
- * applies to date-only input (which can land the picker a day early).
40
- * Rejects impossible calendar days (e.g. 2024-02-31, which would roll over).
41
- */
42
- function parseDay(value) {
43
- const match = ISO_DAY.exec(value);
44
- if (!match)
45
- return undefined;
46
- const year = Number(match[1]);
47
- const month = Number(match[2]);
48
- const day = Number(match[3]);
49
- const parsed = new Date(year, month - 1, day);
50
- return parsed.getFullYear() === year &&
51
- parsed.getMonth() === month - 1 &&
52
- parsed.getDate() === day
53
- ? parsed
54
- : undefined;
55
- }
56
- /** Format a Date back to YYYY-MM-DD in LOCAL time (never via toISOString). */
57
- function toDayString(value) {
58
- if (!value)
59
- return '';
60
- const year = String(value.getFullYear()).padStart(4, '0');
61
- const month = String(value.getMonth() + 1).padStart(2, '0');
62
- const day = String(value.getDate()).padStart(2, '0');
63
- return `${year}-${month}-${day}`;
64
- }
65
- function DateRangePicker({ value, onValueChange, fromId, toId, fromLabel, toLabel, invalid = false, required = false, errorId, placeholder = 'Any date', ariaLabel = 'Select date range', clearLabel = 'Clear', locale = locale_1.enUS, disabled = false }) {
66
- // Which segment's popover is open, if any. One root per segment means one open
67
- // state per segment; holding the identity of the open one here keeps them
68
- // mutually exclusive, so clicking "to" while "from" is open swaps the anchor
69
- // instead of stacking two calendars.
70
- const [openSegment, setOpenSegment] = (0, react_1.useState)(null);
71
- // Suspending the control must FORGET which segment was open, not just hide
72
- // it. The `open` prop below already shuts the popover in the same frame
73
- // `disabled` flips, but a controlled Radix root never calls `onOpenChange`
74
- // for a prop-driven close, so the identity survived: lifting `disabled`
75
- // re-satisfied the same condition and the portaled calendar reopened with no
76
- // user gesture, pulling focus into it.
77
- (0, react_1.useEffect)(() => {
78
- if (disabled)
79
- setOpenSegment(null);
80
- }, [disabled]);
81
- const fromDate = parseDay(value.from);
82
- const toDate = parseDay(value.to);
83
- const selected = fromDate || toDate ? { from: fromDate, to: toDate } : undefined;
84
- // Derived from the RAW strings, not the parsed dates: a value the calendar
85
- // cannot parse still needs to be clearable, and gating Clear on `fromDate`
86
- // would strand the field holding text the user can no longer remove.
87
- const hasValue = value.from !== '' || value.to !== '';
88
- const onSelect = (range) => {
89
- onValueChange({
90
- from: toDayString(range?.from),
91
- to: toDayString(range?.to)
92
- });
93
- };
94
- const triggerClass = (0, utils_1.cn)(
95
- // border-input-border, not border-input: `--input` is a SURFACE token and
96
- // is white in the light theme, so the trigger had no visible edge next to
97
- // the Input and Select it sits with. font-sans, not font-mono: the dates are
98
- // figures in the body face with tabular figures, like every other figure in
99
- // the console.
100
- 'border-input-border bg-card hover:bg-secondary focus-visible:ring-ring flex h-9 items-center gap-2 rounded-md border px-3 text-left font-sans text-sm tabular-nums transition-colors duration-150 ease-out focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:outline-none sm:w-40', invalid && 'border-destructive',
101
- // Conditional rather than `disabled:` variants, matching how this file
102
- // already applies `border-destructive`: with the prop absent the class
103
- // string stays byte-identical to what consumers render today.
104
- disabled && 'cursor-not-allowed opacity-50');
105
- // The one calendar, rendered inside whichever segment's popover is open. Both
106
- // segments read and write the SAME range selection, so which one you opened
107
- // changes only the anchor, never the state.
108
- const calendar = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(calendar_1.Calendar, { mode: "range", numberOfMonths: 2, defaultMonth: fromDate ?? toDate ?? new Date(), selected: selected, onSelect: onSelect, locale: locale }), (0, jsx_runtime_1.jsx)("div", { className: "border-border flex items-center justify-end border-t px-3 py-2", children: (0, jsx_runtime_1.jsx)(button_1.Button, { type: "button", variant: "plain", size: "small", disabled: !hasValue, onClick: () => onValueChange({ from: '', to: '' }), children: clearLabel }) })] }));
109
- const renderSegment = (segment, id, label, dateValue) => ((0, jsx_runtime_1.jsxs)(popover_1.Popover, {
110
- // A disabled trigger cannot open a popover, but a surface that suspends
111
- // itself WHILE one is open (a filter bar flipping to "show all") would
112
- // otherwise leave the portaled calendar on screen with no way back to it.
113
- open: !disabled && openSegment === segment, onOpenChange: (next) => setOpenSegment(next ? segment : null), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-1.5", children: [(0, jsx_runtime_1.jsxs)(label_1.Label, { htmlFor: id, children: [label, required ? ' *' : ''] }), (0, jsx_runtime_1.jsxs)(popover_1.PopoverTrigger, { type: "button", id: id, className: triggerClass, disabled: disabled, "aria-invalid": invalid || undefined, "aria-describedby": invalid ? errorId : undefined, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.CalendarDays, { className: "text-muted-foreground size-4 shrink-0", "aria-hidden": true }), dateValue ? ((0, jsx_runtime_1.jsx)("span", { children: dateValue })) : ((0, jsx_runtime_1.jsx)("span", { className: "text-muted-foreground", children: placeholder }))] })] }), (0, jsx_runtime_1.jsx)(popover_1.PopoverContent, { align: "start", className: "w-auto p-0", "aria-label": ariaLabel, children: calendar })] }, segment));
114
- return ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-end", children: [renderSegment('from', fromId, fromLabel, value.from), renderSegment('to', toId, toLabel, value.to)] }));
115
- }
1
+ "use client";"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.DateRangePicker=DateRangePicker;const jsx_runtime_1=require("react/jsx-runtime");const react_1=require("react");const lucide_react_1=require("lucide-react");const locale_1=require("react-day-picker/locale");const button_1=require("../../components/ui/button");const calendar_1=require("../../components/ui/calendar");const label_1=require("../../components/ui/label");const popover_1=require("../../components/ui/popover");const utils_1=require("../../lib/utils");const ISO_DAY=/^(\d{4})-(\d{2})-(\d{2})/;function parseDay(e){const t=ISO_DAY.exec(e);if(!t)return void 0;const r=Number(t[1]);const n=Number(t[2]);const a=Number(t[3]);const o=new Date(r,n-1,a);return o.getFullYear()===r&&o.getMonth()===n-1&&o.getDate()===a?o:void 0}function toDayString(e){if(!e)return"";const t=String(e.getFullYear()).padStart(4,"0");const r=String(e.getMonth()+1).padStart(2,"0");const n=String(e.getDate()).padStart(2,"0");return`${t}-${r}-${n}`}function DateRangePicker({value:e,onValueChange:t,fromId:r,toId:n,fromLabel:a,toLabel:o,invalid:i=false,required:g=false,errorId:x,placeholder:b="Any date",ariaLabel:h="Select date range",clearLabel:j="Clear",locale:y=locale_1.enUS,disabled:c=false}){const[S,u]=(0,react_1.useState)(null);(0,react_1.useEffect)(()=>{if(c)u(null)},[c]);const l=parseDay(e.from);const d=parseDay(e.to);const _=l||d?{from:l,to:d}:void 0;const D=e.from!==""||e.to!=="";const N=s=>{t({from:toDayString(s?.from),to:toDayString(s?.to)})};const q=(0,utils_1.cn)("border-input-border bg-card hover:bg-secondary focus-visible:ring-ring flex h-9 items-center gap-2 rounded-md border px-3 text-left font-sans text-sm tabular-nums transition-colors duration-150 ease-out focus-visible:ring-2 focus-visible:ring-offset-1 focus-visible:outline-none sm:w-40",i&&"border-destructive",c&&"cursor-not-allowed opacity-50");const v=(0,jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment,{children:[(0,jsx_runtime_1.jsx)(calendar_1.Calendar,{mode:"range",numberOfMonths:2,defaultMonth:l??d??new Date,selected:_,onSelect:N,locale:y}),(0,jsx_runtime_1.jsx)("div",{className:"border-border flex items-center justify-end border-t px-3 py-2",children:(0,jsx_runtime_1.jsx)(button_1.Button,{type:"button",variant:"plain",size:"small",disabled:!D,onClick:()=>t({from:"",to:""}),children:j})})]});const f=(s,m,w,p)=>(0,jsx_runtime_1.jsxs)(popover_1.Popover,{open:!c&&S===s,onOpenChange:C=>u(C?s:null),children:[(0,jsx_runtime_1.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,jsx_runtime_1.jsxs)(label_1.Label,{htmlFor:m,children:[w,g?" *":""]}),(0,jsx_runtime_1.jsxs)(popover_1.PopoverTrigger,{type:"button",id:m,className:q,disabled:c,"aria-invalid":i||void 0,"aria-describedby":i?x:void 0,children:[(0,jsx_runtime_1.jsx)(lucide_react_1.CalendarDays,{className:"text-muted-foreground size-4 shrink-0","aria-hidden":true}),p?(0,jsx_runtime_1.jsx)("span",{children:p}):(0,jsx_runtime_1.jsx)("span",{className:"text-muted-foreground",children:b})]})]}),(0,jsx_runtime_1.jsx)(popover_1.PopoverContent,{align:"start",className:"w-auto p-0","aria-label":h,children:v})]},s);return(0,jsx_runtime_1.jsxs)("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-end",children:[f("from",r,a,e.from),f("to",n,o,e.to)]})}
@@ -1,20 +1 @@
1
- 'use client';
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.DetailPanel = DetailPanel;
5
- const jsx_runtime_1 = require("react/jsx-runtime");
6
- const lucide_react_1 = require("lucide-react");
7
- const sheet_1 = require("../../components/ui/sheet");
8
- const utils_1 = require("../../lib/utils");
9
- /**
10
- * The slide-over inspector. The header and footer stay pinned; only the body
11
- * scrolls. Sheet already renders an overlay, focus trap, and Esc/overlay
12
- * dismissal — we suppress its built-in corner close button (`[&>button.absolute]`)
13
- * and provide our own inside the header so the layout stays deliberate.
14
- */
15
- function DetailPanel({ open, onOpenChange, title, side = 'right', actions, footer, closeLabel = 'Close', children, className }) {
16
- return ((0, jsx_runtime_1.jsx)(sheet_1.Sheet, { open: open, onOpenChange: onOpenChange, children: (0, jsx_runtime_1.jsxs)(sheet_1.SheetContent, { side: side, className: (0, utils_1.cn)(
17
- // Reset Sheet's padding/gap and hide its built-in close button; we
18
- // own the three-slot layout and the header close affordance here.
19
- 'flex flex-col gap-0 overflow-hidden p-0', '[&>button.absolute]:hidden', className), children: [(0, jsx_runtime_1.jsxs)("header", { className: "border-border bg-card sticky top-0 z-10 flex shrink-0 items-start justify-between gap-3 border-b px-6 py-4", children: [(0, jsx_runtime_1.jsx)(sheet_1.SheetTitle, { className: "min-w-0 flex-1 truncate text-base font-semibold tracking-tight", children: title }), (0, jsx_runtime_1.jsxs)("div", { className: "flex shrink-0 items-center gap-1.5", children: [actions, (0, jsx_runtime_1.jsx)(sheet_1.SheetClose, { "data-slot": "detail-panel-close", className: "ring-offset-background focus:ring-ring rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:outline-none disabled:pointer-events-none", "aria-label": closeLabel, children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "size-4", "aria-hidden": true }) })] })] }), (0, jsx_runtime_1.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: (0, jsx_runtime_1.jsx)("div", { className: "px-6 py-5", children: children }) }), footer ? ((0, jsx_runtime_1.jsx)("footer", { className: "border-border bg-card sticky bottom-0 z-10 flex shrink-0 flex-col-reverse gap-2 border-t px-6 py-4 sm:flex-row sm:justify-end", children: footer })) : null] }) }));
20
- }
1
+ "use client";"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.DetailPanel=DetailPanel;const jsx_runtime_1=require("react/jsx-runtime");const lucide_react_1=require("lucide-react");const sheet_1=require("../../components/ui/sheet");const utils_1=require("../../lib/utils");function DetailPanel({open:s,onOpenChange:t,title:r,side:i="right",actions:n,footer:e,closeLabel:l="Close",children:a,className:o}){return(0,jsx_runtime_1.jsx)(sheet_1.Sheet,{open:s,onOpenChange:t,children:(0,jsx_runtime_1.jsxs)(sheet_1.SheetContent,{side:i,className:(0,utils_1.cn)("flex flex-col gap-0 overflow-hidden p-0","[&>button.absolute]:hidden",o),children:[(0,jsx_runtime_1.jsxs)("header",{className:"border-border bg-card sticky top-0 z-10 flex shrink-0 items-start justify-between gap-3 border-b px-6 py-4",children:[(0,jsx_runtime_1.jsx)(sheet_1.SheetTitle,{className:"min-w-0 flex-1 truncate text-base font-semibold tracking-tight",children:r}),(0,jsx_runtime_1.jsxs)("div",{className:"flex shrink-0 items-center gap-1.5",children:[n,(0,jsx_runtime_1.jsx)(sheet_1.SheetClose,{"data-slot":"detail-panel-close",className:"ring-offset-background focus:ring-ring rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:outline-none disabled:pointer-events-none","aria-label":l,children:(0,jsx_runtime_1.jsx)(lucide_react_1.X,{className:"size-4","aria-hidden":true})})]})]}),(0,jsx_runtime_1.jsx)("div",{className:"min-h-0 flex-1 overflow-y-auto",children:(0,jsx_runtime_1.jsx)("div",{className:"px-6 py-5",children:a})}),e?(0,jsx_runtime_1.jsx)("footer",{className:"border-border bg-card sticky bottom-0 z-10 flex shrink-0 flex-col-reverse gap-2 border-t px-6 py-4 sm:flex-row sm:justify-end",children:e}):null]})})}