@comitor/ui 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/LICENSE +35 -0
  2. package/README.md +67 -24
  3. package/dist/chart/chart.d.ts +6 -1
  4. package/dist/chart/chart.js +3 -1
  5. package/dist/chart/chart.js.map +1 -1
  6. package/dist/chart/comitor-chart.d.ts +4 -1
  7. package/dist/chart/comitor-chart.js +3 -1
  8. package/dist/chart/comitor-chart.js.map +1 -1
  9. package/dist/components/composite/avatar-group.d.ts +9 -6
  10. package/dist/components/composite/avatar-group.js +6 -2
  11. package/dist/components/composite/avatar-group.js.map +1 -1
  12. package/dist/components/composite/combobox.d.ts +11 -11
  13. package/dist/components/composite/combobox.js +25 -11
  14. package/dist/components/composite/combobox.js.map +1 -1
  15. package/dist/components/composite/command-palette-constants.d.ts +15 -5
  16. package/dist/components/composite/command-palette-constants.js +3 -2
  17. package/dist/components/composite/command-palette-constants.js.map +1 -1
  18. package/dist/components/composite/command-palette.d.ts +2 -2
  19. package/dist/components/composite/command-palette.js +8 -5
  20. package/dist/components/composite/command-palette.js.map +1 -1
  21. package/dist/components/composite/confirm-dialog.d.ts +8 -8
  22. package/dist/components/composite/confirm-dialog.js +8 -3
  23. package/dist/components/composite/confirm-dialog.js.map +1 -1
  24. package/dist/components/composite/copy-button.d.ts +7 -3
  25. package/dist/components/composite/copy-button.js +7 -3
  26. package/dist/components/composite/copy-button.js.map +1 -1
  27. package/dist/components/composite/data-table-constants.d.ts +7 -3
  28. package/dist/components/composite/data-table-constants.js +2 -9
  29. package/dist/components/composite/data-table-constants.js.map +1 -1
  30. package/dist/components/composite/data-table.js +3 -3
  31. package/dist/components/composite/data-table.js.map +1 -1
  32. package/dist/components/composite/date-picker-constants.d.ts +32 -9
  33. package/dist/components/composite/date-picker-constants.js +16 -11
  34. package/dist/components/composite/date-picker-constants.js.map +1 -1
  35. package/dist/components/composite/date-picker.d.ts +19 -10
  36. package/dist/components/composite/date-picker.js +33 -9
  37. package/dist/components/composite/date-picker.js.map +1 -1
  38. package/dist/components/composite/filter-chips.d.ts +4 -3
  39. package/dist/components/composite/filter-chips.js +6 -2
  40. package/dist/components/composite/filter-chips.js.map +1 -1
  41. package/dist/components/composite/inline-edit.d.ts +14 -3
  42. package/dist/components/composite/inline-edit.js +8 -4
  43. package/dist/components/composite/inline-edit.js.map +1 -1
  44. package/dist/components/composite/relative-time.d.ts +4 -4
  45. package/dist/components/composite/relative-time.js +4 -2
  46. package/dist/components/composite/relative-time.js.map +1 -1
  47. package/dist/components/composite/route-tabs-nav.d.ts +9 -0
  48. package/dist/components/composite/route-tabs-nav.js +11 -0
  49. package/dist/components/composite/route-tabs-nav.js.map +1 -0
  50. package/dist/components/composite/route-tabs.d.ts +4 -1
  51. package/dist/components/composite/route-tabs.js +3 -2
  52. package/dist/components/composite/route-tabs.js.map +1 -1
  53. package/dist/components/composite/search-filter-bar-constants.d.ts +18 -8
  54. package/dist/components/composite/search-filter-bar-constants.js +2 -14
  55. package/dist/components/composite/search-filter-bar-constants.js.map +1 -1
  56. package/dist/components/composite/search-filter-bar.d.ts +5 -2
  57. package/dist/components/composite/search-filter-bar.js +2 -2
  58. package/dist/components/composite/search-filter-bar.js.map +1 -1
  59. package/dist/components/composite/stat-card.d.ts +1 -1
  60. package/dist/components/composite/table-pagination-constants.d.ts +16 -11
  61. package/dist/components/composite/table-pagination-constants.js +2 -12
  62. package/dist/components/composite/table-pagination-constants.js.map +1 -1
  63. package/dist/components/composite/table-pagination.d.ts +6 -3
  64. package/dist/components/composite/table-pagination.js +3 -5
  65. package/dist/components/composite/table-pagination.js.map +1 -1
  66. package/dist/components/composite/toast.d.ts +4 -2
  67. package/dist/components/composite/toast.js +9 -1
  68. package/dist/components/composite/toast.js.map +1 -1
  69. package/dist/components/ui/action-bar-constants.d.ts +35 -0
  70. package/dist/components/ui/action-bar-constants.js +6 -0
  71. package/dist/components/ui/action-bar-constants.js.map +1 -0
  72. package/dist/components/ui/action-bar.d.ts +68 -0
  73. package/dist/components/ui/action-bar.js +522 -0
  74. package/dist/components/ui/action-bar.js.map +1 -0
  75. package/dist/components/ui/alert.d.ts +1 -1
  76. package/dist/components/ui/badge-overflow.d.ts +30 -0
  77. package/dist/components/ui/badge-overflow.js +181 -0
  78. package/dist/components/ui/badge-overflow.js.map +1 -0
  79. package/dist/components/ui/badge.d.ts +1 -1
  80. package/dist/components/ui/banner.d.ts +80 -0
  81. package/dist/components/ui/banner.js +520 -0
  82. package/dist/components/ui/banner.js.map +1 -0
  83. package/dist/components/ui/breadcrumb.d.ts +11 -4
  84. package/dist/components/ui/breadcrumb.js +7 -2
  85. package/dist/components/ui/breadcrumb.js.map +1 -1
  86. package/dist/components/ui/button.d.ts +2 -2
  87. package/dist/components/ui/calendar.d.ts +12 -5
  88. package/dist/components/ui/calendar.js +38 -3
  89. package/dist/components/ui/calendar.js.map +1 -1
  90. package/dist/components/ui/carousel.d.ts +4 -3
  91. package/dist/components/ui/carousel.js +11 -4
  92. package/dist/components/ui/carousel.js.map +1 -1
  93. package/dist/components/ui/circular-progress.d.ts +50 -0
  94. package/dist/components/ui/circular-progress.js +266 -0
  95. package/dist/components/ui/circular-progress.js.map +1 -0
  96. package/dist/components/ui/command.d.ts +5 -4
  97. package/dist/components/ui/command.js +6 -2
  98. package/dist/components/ui/command.js.map +1 -1
  99. package/dist/components/ui/cropper-constants.d.ts +39 -0
  100. package/dist/components/ui/cropper-constants.js +6 -0
  101. package/dist/components/ui/cropper-constants.js.map +1 -0
  102. package/dist/components/ui/cropper.d.ts +107 -0
  103. package/dist/components/ui/cropper.js +1269 -0
  104. package/dist/components/ui/cropper.js.map +1 -0
  105. package/dist/components/ui/dialog.d.ts +2 -2
  106. package/dist/components/ui/dialog.js +4 -1
  107. package/dist/components/ui/dialog.js.map +1 -1
  108. package/dist/components/ui/drawer.d.ts +1 -1
  109. package/dist/components/ui/drawer.js +2 -2
  110. package/dist/components/ui/drawer.js.map +1 -1
  111. package/dist/components/ui/item.d.ts +2 -2
  112. package/dist/components/ui/kanban-constants.d.ts +67 -0
  113. package/dist/components/ui/kanban-constants.js +6 -0
  114. package/dist/components/ui/kanban-constants.js.map +1 -0
  115. package/dist/components/ui/kanban.d.ts +72 -0
  116. package/dist/components/ui/kanban.js +787 -0
  117. package/dist/components/ui/kanban.js.map +1 -0
  118. package/dist/components/ui/key-value-constants.d.ts +37 -0
  119. package/dist/components/ui/key-value-constants.js +6 -0
  120. package/dist/components/ui/key-value-constants.js.map +1 -0
  121. package/dist/components/ui/key-value.d.ts +96 -0
  122. package/dist/components/ui/key-value.js +641 -0
  123. package/dist/components/ui/key-value.js.map +1 -0
  124. package/dist/components/ui/mask-input-constants.d.ts +98 -0
  125. package/dist/components/ui/mask-input-constants.js +600 -0
  126. package/dist/components/ui/mask-input-constants.js.map +1 -0
  127. package/dist/components/ui/mask-input.d.ts +39 -0
  128. package/dist/components/ui/mask-input.js +560 -0
  129. package/dist/components/ui/mask-input.js.map +1 -0
  130. package/dist/components/ui/mention.d.ts +32 -0
  131. package/dist/components/ui/mention.js +126 -0
  132. package/dist/components/ui/mention.js.map +1 -0
  133. package/dist/components/ui/pagination.d.ts +13 -9
  134. package/dist/components/ui/pagination.js +15 -6
  135. package/dist/components/ui/pagination.js.map +1 -1
  136. package/dist/components/ui/phone-input-constants.d.ts +65 -0
  137. package/dist/components/ui/phone-input-constants.js +6 -0
  138. package/dist/components/ui/phone-input-constants.js.map +1 -0
  139. package/dist/components/ui/phone-input.d.ts +92 -0
  140. package/dist/components/ui/phone-input.js +742 -0
  141. package/dist/components/ui/phone-input.js.map +1 -0
  142. package/dist/components/ui/progress.d.ts +2 -2
  143. package/dist/components/ui/rating.d.ts +57 -0
  144. package/dist/components/ui/rating.js +648 -0
  145. package/dist/components/ui/rating.js.map +1 -0
  146. package/dist/components/ui/responsive-dialog.d.ts +35 -0
  147. package/dist/components/ui/responsive-dialog.js +193 -0
  148. package/dist/components/ui/responsive-dialog.js.map +1 -0
  149. package/dist/components/ui/scroll-spy.d.ts +42 -0
  150. package/dist/components/ui/scroll-spy.js +336 -0
  151. package/dist/components/ui/scroll-spy.js.map +1 -0
  152. package/dist/components/ui/sheet.d.ts +2 -2
  153. package/dist/components/ui/sheet.js +10 -1
  154. package/dist/components/ui/sheet.js.map +1 -1
  155. package/dist/components/ui/spinner.js +4 -1
  156. package/dist/components/ui/spinner.js.map +1 -1
  157. package/dist/components/ui/stepper-constants.d.ts +34 -0
  158. package/dist/components/ui/stepper-constants.js +6 -0
  159. package/dist/components/ui/stepper-constants.js.map +1 -0
  160. package/dist/components/ui/stepper.d.ts +81 -0
  161. package/dist/components/ui/stepper.js +902 -0
  162. package/dist/components/ui/stepper.js.map +1 -0
  163. package/dist/components/ui/tags-input.d.ts +42 -0
  164. package/dist/components/ui/tags-input.js +129 -0
  165. package/dist/components/ui/tags-input.js.map +1 -0
  166. package/dist/components/ui/time-picker-constants.d.ts +51 -0
  167. package/dist/components/ui/time-picker-constants.js +6 -0
  168. package/dist/components/ui/time-picker-constants.js.map +1 -0
  169. package/dist/components/ui/time-picker.d.ts +120 -0
  170. package/dist/components/ui/time-picker.js +1618 -0
  171. package/dist/components/ui/time-picker.js.map +1 -0
  172. package/dist/components/ui/timeline.d.ts +32 -0
  173. package/dist/components/ui/timeline.js +559 -0
  174. package/dist/components/ui/timeline.js.map +1 -0
  175. package/dist/components/ui/toggle.d.ts +1 -1
  176. package/dist/components/ui/tour-constants.d.ts +44 -0
  177. package/dist/components/ui/tour-constants.js +6 -0
  178. package/dist/components/ui/tour-constants.js.map +1 -0
  179. package/dist/components/ui/tour.d.ts +125 -0
  180. package/dist/components/ui/tour.js +1207 -0
  181. package/dist/components/ui/tour.js.map +1 -0
  182. package/dist/data-grid/data-grid-cell-variants.js +4 -4
  183. package/dist/data-grid/data-grid-cell-variants.js.map +1 -1
  184. package/dist/data-grid/data-grid-cell-wrapper.js +1 -1
  185. package/dist/data-grid/data-grid-cell-wrapper.js.map +1 -1
  186. package/dist/data-grid/data-grid-column-header.js +1 -1
  187. package/dist/data-grid/data-grid-column-header.js.map +1 -1
  188. package/dist/data-grid/data-grid-context-menu.js +1 -1
  189. package/dist/data-grid/data-grid-context-menu.js.map +1 -1
  190. package/dist/data-grid/data-grid-filter-menu.d.ts +5 -4
  191. package/dist/data-grid/data-grid-filter-menu.js +13 -8
  192. package/dist/data-grid/data-grid-filter-menu.js.map +1 -1
  193. package/dist/data-grid/data-grid-keyboard-shortcuts.d.ts +4 -4
  194. package/dist/data-grid/data-grid-keyboard-shortcuts.js.map +1 -1
  195. package/dist/data-grid/data-grid-locale.d.ts +58 -6
  196. package/dist/data-grid/data-grid-locale.js +41 -9
  197. package/dist/data-grid/data-grid-locale.js.map +1 -1
  198. package/dist/data-grid/data-grid-paste-dialog.js +1 -1
  199. package/dist/data-grid/data-grid-paste-dialog.js.map +1 -1
  200. package/dist/data-grid/data-grid-row-height-menu.d.ts +4 -3
  201. package/dist/data-grid/data-grid-row-height-menu.js.map +1 -1
  202. package/dist/data-grid/data-grid-row.js +1 -1
  203. package/dist/data-grid/data-grid-row.js.map +1 -1
  204. package/dist/data-grid/data-grid-search.js +1 -1
  205. package/dist/data-grid/data-grid-search.js.map +1 -1
  206. package/dist/data-grid/data-grid-sort-menu.d.ts +4 -4
  207. package/dist/data-grid/data-grid-sort-menu.js +1 -1
  208. package/dist/data-grid/data-grid-sort-menu.js.map +1 -1
  209. package/dist/data-grid/data-grid-view-menu.d.ts +4 -4
  210. package/dist/data-grid/data-grid-view-menu.js.map +1 -1
  211. package/dist/data-grid/data-grid.d.ts +4 -3
  212. package/dist/data-grid/data-grid.js +3 -4
  213. package/dist/data-grid/data-grid.js.map +1 -1
  214. package/dist/data-grid/index.d.ts +1 -0
  215. package/dist/data-grid/index.js.map +1 -1
  216. package/dist/data-grid/messages-en.d.ts +23 -4
  217. package/dist/data-grid/messages-en.js +20 -0
  218. package/dist/data-grid/messages-en.js.map +1 -1
  219. package/dist/data-grid/messages-vi.d.ts +3 -1
  220. package/dist/data-grid/messages-vi.js +14 -0
  221. package/dist/data-grid/messages-vi.js.map +1 -1
  222. package/dist/data-grid/messages.d.ts +29 -3
  223. package/dist/data-grid/messages.js.map +1 -1
  224. package/dist/data-grid/sortable.js +17 -20
  225. package/dist/data-grid/sortable.js.map +1 -1
  226. package/dist/data-grid/types.d.ts +1 -1
  227. package/dist/data-grid/use-data-grid-undo-redo.d.ts +5 -4
  228. package/dist/data-grid/use-data-grid-undo-redo.js +4 -4
  229. package/dist/data-grid/use-data-grid-undo-redo.js.map +1 -1
  230. package/dist/data-grid/use-data-grid.d.ts +21 -6
  231. package/dist/data-grid/use-data-grid.js +11 -9
  232. package/dist/data-grid/use-data-grid.js.map +1 -1
  233. package/dist/data-grid/utils.d.ts +24 -4
  234. package/dist/data-grid/utils.js +15 -5
  235. package/dist/data-grid/utils.js.map +1 -1
  236. package/dist/i18n/locale-provider.d.ts +109 -0
  237. package/dist/i18n/locale-provider.js +47 -0
  238. package/dist/i18n/locale-provider.js.map +1 -0
  239. package/dist/i18n/locale.d.ts +27 -0
  240. package/dist/i18n/locale.js +10 -0
  241. package/dist/i18n/locale.js.map +1 -0
  242. package/dist/i18n/messages.d.ts +116 -0
  243. package/dist/i18n/messages.js +149 -0
  244. package/dist/i18n/messages.js.map +1 -0
  245. package/dist/i18n/namespaces/action-bar.d.ts +7 -0
  246. package/dist/i18n/namespaces/action-bar.js +15 -0
  247. package/dist/i18n/namespaces/action-bar.js.map +1 -0
  248. package/dist/i18n/namespaces/avatar-group.d.ts +14 -0
  249. package/dist/i18n/namespaces/avatar-group.js +13 -0
  250. package/dist/i18n/namespaces/avatar-group.js.map +1 -0
  251. package/dist/i18n/namespaces/badge-overflow.d.ts +12 -0
  252. package/dist/i18n/namespaces/badge-overflow.js +11 -0
  253. package/dist/i18n/namespaces/badge-overflow.js.map +1 -0
  254. package/dist/i18n/namespaces/banner.d.ts +9 -0
  255. package/dist/i18n/namespaces/banner.js +7 -0
  256. package/dist/i18n/namespaces/banner.js.map +1 -0
  257. package/dist/i18n/namespaces/breadcrumb.d.ts +11 -0
  258. package/dist/i18n/namespaces/breadcrumb.js +13 -0
  259. package/dist/i18n/namespaces/breadcrumb.js.map +1 -0
  260. package/dist/i18n/namespaces/calendar.d.ts +40 -0
  261. package/dist/i18n/namespaces/calendar.js +25 -0
  262. package/dist/i18n/namespaces/calendar.js.map +1 -0
  263. package/dist/i18n/namespaces/carousel.d.ts +15 -0
  264. package/dist/i18n/namespaces/carousel.js +17 -0
  265. package/dist/i18n/namespaces/carousel.js.map +1 -0
  266. package/dist/i18n/namespaces/combobox.d.ts +21 -0
  267. package/dist/i18n/namespaces/combobox.js +23 -0
  268. package/dist/i18n/namespaces/combobox.js.map +1 -0
  269. package/dist/i18n/namespaces/command-palette.d.ts +20 -0
  270. package/dist/i18n/namespaces/command-palette.js +19 -0
  271. package/dist/i18n/namespaces/command-palette.js.map +1 -0
  272. package/dist/i18n/namespaces/command.d.ts +11 -0
  273. package/dist/i18n/namespaces/command.js +13 -0
  274. package/dist/i18n/namespaces/command.js.map +1 -0
  275. package/dist/i18n/namespaces/confirm-dialog.d.ts +13 -0
  276. package/dist/i18n/namespaces/confirm-dialog.js +15 -0
  277. package/dist/i18n/namespaces/confirm-dialog.js.map +1 -0
  278. package/dist/i18n/namespaces/contrast.d.ts +7 -0
  279. package/dist/i18n/namespaces/contrast.js +13 -0
  280. package/dist/i18n/namespaces/contrast.js.map +1 -0
  281. package/dist/i18n/namespaces/copy-button.d.ts +11 -0
  282. package/dist/i18n/namespaces/copy-button.js +13 -0
  283. package/dist/i18n/namespaces/copy-button.js.map +1 -0
  284. package/dist/i18n/namespaces/cropper.d.ts +7 -0
  285. package/dist/i18n/namespaces/cropper.js +17 -0
  286. package/dist/i18n/namespaces/cropper.js.map +1 -0
  287. package/dist/i18n/namespaces/data-table.d.ts +7 -0
  288. package/dist/i18n/namespaces/data-table.js +23 -0
  289. package/dist/i18n/namespaces/data-table.js.map +1 -0
  290. package/dist/i18n/namespaces/date-picker.d.ts +42 -0
  291. package/dist/i18n/namespaces/date-picker.js +35 -0
  292. package/dist/i18n/namespaces/date-picker.js.map +1 -0
  293. package/dist/i18n/namespaces/dialog.d.ts +9 -0
  294. package/dist/i18n/namespaces/dialog.js +7 -0
  295. package/dist/i18n/namespaces/dialog.js.map +1 -0
  296. package/dist/i18n/namespaces/display-axis.d.ts +25 -0
  297. package/dist/i18n/namespaces/display-axis.js +21 -0
  298. package/dist/i18n/namespaces/display-axis.js.map +1 -0
  299. package/dist/i18n/namespaces/file-upload.d.ts +11 -0
  300. package/dist/i18n/namespaces/file-upload.js +19 -0
  301. package/dist/i18n/namespaces/file-upload.js.map +1 -0
  302. package/dist/i18n/namespaces/filter-chips.d.ts +11 -0
  303. package/dist/i18n/namespaces/filter-chips.js +13 -0
  304. package/dist/i18n/namespaces/filter-chips.js.map +1 -0
  305. package/dist/i18n/namespaces/image-upload-field.d.ts +12 -0
  306. package/dist/i18n/namespaces/image-upload-field.js +23 -0
  307. package/dist/i18n/namespaces/image-upload-field.js.map +1 -0
  308. package/dist/i18n/namespaces/inline-edit.d.ts +15 -0
  309. package/dist/i18n/namespaces/inline-edit.js +17 -0
  310. package/dist/i18n/namespaces/inline-edit.js.map +1 -0
  311. package/dist/i18n/namespaces/kanban.d.ts +11 -0
  312. package/dist/i18n/namespaces/kanban.js +39 -0
  313. package/dist/i18n/namespaces/kanban.js.map +1 -0
  314. package/dist/i18n/namespaces/key-value.d.ts +10 -0
  315. package/dist/i18n/namespaces/key-value.js +19 -0
  316. package/dist/i18n/namespaces/key-value.js.map +1 -0
  317. package/dist/i18n/namespaces/mention.d.ts +9 -0
  318. package/dist/i18n/namespaces/mention.js +7 -0
  319. package/dist/i18n/namespaces/mention.js.map +1 -0
  320. package/dist/i18n/namespaces/pagination.d.ts +19 -0
  321. package/dist/i18n/namespaces/pagination.js +21 -0
  322. package/dist/i18n/namespaces/pagination.js.map +1 -0
  323. package/dist/i18n/namespaces/phone-input.d.ts +10 -0
  324. package/dist/i18n/namespaces/phone-input.js +17 -0
  325. package/dist/i18n/namespaces/phone-input.js.map +1 -0
  326. package/dist/i18n/namespaces/rating.d.ts +12 -0
  327. package/dist/i18n/namespaces/rating.js +11 -0
  328. package/dist/i18n/namespaces/rating.js.map +1 -0
  329. package/dist/i18n/namespaces/route-tabs.d.ts +9 -0
  330. package/dist/i18n/namespaces/route-tabs.js +7 -0
  331. package/dist/i18n/namespaces/route-tabs.js.map +1 -0
  332. package/dist/i18n/namespaces/scroll-spy.d.ts +9 -0
  333. package/dist/i18n/namespaces/scroll-spy.js +7 -0
  334. package/dist/i18n/namespaces/scroll-spy.js.map +1 -0
  335. package/dist/i18n/namespaces/search-filter-bar.d.ts +15 -0
  336. package/dist/i18n/namespaces/search-filter-bar.js +32 -0
  337. package/dist/i18n/namespaces/search-filter-bar.js.map +1 -0
  338. package/dist/i18n/namespaces/sheet.d.ts +9 -0
  339. package/dist/i18n/namespaces/sheet.js +7 -0
  340. package/dist/i18n/namespaces/sheet.js.map +1 -0
  341. package/dist/i18n/namespaces/shell.d.ts +17 -0
  342. package/dist/i18n/namespaces/shell.js +75 -0
  343. package/dist/i18n/namespaces/shell.js.map +1 -0
  344. package/dist/i18n/namespaces/spinner.d.ts +9 -0
  345. package/dist/i18n/namespaces/spinner.js +7 -0
  346. package/dist/i18n/namespaces/spinner.js.map +1 -0
  347. package/dist/i18n/namespaces/stepper.d.ts +7 -0
  348. package/dist/i18n/namespaces/stepper.js +15 -0
  349. package/dist/i18n/namespaces/stepper.js.map +1 -0
  350. package/dist/i18n/namespaces/table-pagination.d.ts +7 -0
  351. package/dist/i18n/namespaces/table-pagination.js +29 -0
  352. package/dist/i18n/namespaces/table-pagination.js.map +1 -0
  353. package/dist/i18n/namespaces/tags-input.d.ts +12 -0
  354. package/dist/i18n/namespaces/tags-input.js +11 -0
  355. package/dist/i18n/namespaces/tags-input.js.map +1 -0
  356. package/dist/i18n/namespaces/time-picker.d.ts +15 -0
  357. package/dist/i18n/namespaces/time-picker.js +25 -0
  358. package/dist/i18n/namespaces/time-picker.js.map +1 -0
  359. package/dist/i18n/namespaces/toast.d.ts +15 -0
  360. package/dist/i18n/namespaces/toast.js +7 -0
  361. package/dist/i18n/namespaces/toast.js.map +1 -0
  362. package/dist/i18n/namespaces/tour.d.ts +7 -0
  363. package/dist/i18n/namespaces/tour.js +21 -0
  364. package/dist/i18n/namespaces/tour.js.map +1 -0
  365. package/dist/index.d.ts +63 -0
  366. package/dist/index.js +66 -1
  367. package/dist/index.js.map +1 -1
  368. package/dist/lib/compose-refs.js.map +1 -0
  369. package/dist/lib/use-as-ref.js.map +1 -0
  370. package/dist/lib/use-is-mobile.d.ts +10 -0
  371. package/dist/lib/use-is-mobile.js +21 -0
  372. package/dist/lib/use-is-mobile.js.map +1 -0
  373. package/dist/lib/use-isomorphic-layout-effect.js.map +1 -0
  374. package/dist/lib/use-lazy-ref.js.map +1 -0
  375. package/dist/lib/visually-hidden-input.d.ts +12 -0
  376. package/dist/lib/visually-hidden-input.js +105 -0
  377. package/dist/lib/visually-hidden-input.js.map +1 -0
  378. package/dist/shell/app-header.js.map +1 -1
  379. package/dist/shell/app-shell.d.ts +20 -2
  380. package/dist/shell/app-shell.js +4 -1
  381. package/dist/shell/app-shell.js.map +1 -1
  382. package/dist/shell/contrast-constants.d.ts +9 -1
  383. package/dist/shell/contrast-constants.js +2 -4
  384. package/dist/shell/contrast-constants.js.map +1 -1
  385. package/dist/shell/contrast-toggle.d.ts +4 -1
  386. package/dist/shell/contrast-toggle.js +2 -2
  387. package/dist/shell/contrast-toggle.js.map +1 -1
  388. package/dist/shell/display-axis-constants.d.ts +2 -1
  389. package/dist/shell/display-axis-constants.js.map +1 -1
  390. package/dist/shell/display-axis-controls.d.ts +15 -6
  391. package/dist/shell/display-axis-controls.js +11 -9
  392. package/dist/shell/display-axis-controls.js.map +1 -1
  393. package/dist/shell/mobile-menu.js.map +1 -1
  394. package/dist/shell/notifications-button.d.ts +1 -1
  395. package/dist/shell/notifications-button.js +3 -2
  396. package/dist/shell/notifications-button.js.map +1 -1
  397. package/dist/shell/shell-context.d.ts +4 -1
  398. package/dist/shell/shell-context.js +2 -4
  399. package/dist/shell/shell-context.js.map +1 -1
  400. package/dist/shell/sidebar.d.ts +1 -1
  401. package/dist/shell/sidebar.js.map +1 -1
  402. package/dist/shell/theme-toggle.d.ts +6 -3
  403. package/dist/shell/theme-toggle.js +2 -2
  404. package/dist/shell/theme-toggle.js.map +1 -1
  405. package/dist/shell/types.d.ts +14 -8
  406. package/dist/shell/types.js +2 -35
  407. package/dist/shell/types.js.map +1 -1
  408. package/dist/shell/user-menu.d.ts +6 -6
  409. package/dist/shell/user-menu.js.map +1 -1
  410. package/dist/shell/utils.d.ts +1 -1
  411. package/dist/shell/utils.js.map +1 -1
  412. package/dist/shell/workspace-switcher.js +1 -1
  413. package/dist/shell/workspace-switcher.js.map +1 -1
  414. package/dist/uploader/file-upload-constants.d.ts +13 -0
  415. package/dist/uploader/file-upload-constants.js +4 -16
  416. package/dist/uploader/file-upload-constants.js.map +1 -1
  417. package/dist/uploader/file-upload.d.ts +4 -1
  418. package/dist/uploader/file-upload.js +2 -2
  419. package/dist/uploader/file-upload.js.map +1 -1
  420. package/dist/uploader/image-upload-field.d.ts +5 -1
  421. package/dist/uploader/image-upload-field.js +2 -2
  422. package/dist/uploader/image-upload-field.js.map +1 -1
  423. package/dist/uploader/use-file-upload.d.ts +4 -0
  424. package/dist/uploader/use-file-upload.js +6 -2
  425. package/dist/uploader/use-file-upload.js.map +1 -1
  426. package/package.json +8 -3
  427. package/styles.css +19 -0
  428. package/dist/data-grid/compose-refs.js.map +0 -1
  429. package/dist/data-grid/use-as-ref.js.map +0 -1
  430. package/dist/data-grid/use-isomorphic-layout-effect.js.map +0 -1
  431. package/dist/data-grid/use-lazy-ref.js.map +0 -1
  432. /package/dist/{data-grid → lib}/compose-refs.d.ts +0 -0
  433. /package/dist/{data-grid → lib}/compose-refs.js +0 -0
  434. /package/dist/{data-grid → lib}/use-as-ref.d.ts +0 -0
  435. /package/dist/{data-grid → lib}/use-as-ref.js +0 -0
  436. /package/dist/{data-grid → lib}/use-isomorphic-layout-effect.d.ts +0 -0
  437. /package/dist/{data-grid → lib}/use-isomorphic-layout-effect.js +0 -0
  438. /package/dist/{data-grid → lib}/use-lazy-ref.d.ts +0 -0
  439. /package/dist/{data-grid → lib}/use-lazy-ref.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data-grid/messages-vi.ts"],"sourcesContent":["import type { DataGridMessages } from \"./messages-en.js\";\n\n/**\n * Bảng tiếng VIỆT của DataGrid. Hình dạng do `messages-en.ts` quy định — chú thích `: DataGridMessages`\n * ở đây là thứ bắt lỗi: thêm khoá mới ở bản tiếng Anh mà quên dịch thì typecheck đỏ ngay, thay vì\n * một chuỗi `undefined` lọt ra giao diện lúc chạy.\n *\n * ⚠ Bản này KHÔNG còn là mặc định từ `2.0.0`. Muốn nó thì truyền `locale=\"vi\"` (xem README §5).\n */\nexport const messagesVi: DataGridMessages = {\n grid: {\n /** Nhãn mặc định của vùng `role=\"grid\"` (ghi đè bằng prop `aria-label`) */\n label: \"Bảng dữ liệu\",\n addRow: \"Thêm dòng\"\n },\n\n search: {\n placeholder: \"Tìm trong bảng...\",\n label: \"Tìm trong bảng\",\n prevMatch: \"Kết quả trước\",\n nextMatch: \"Kết quả sau\",\n close: \"Đóng tìm kiếm\",\n matchPosition: (index: number, total: number) => `${index} / ${total}`,\n noResults: \"Không có kết quả\",\n typeToSearch: \"Gõ để tìm\"\n },\n\n column: {\n sortAsc: \"Sắp xếp tăng dần\",\n sortDesc: \"Sắp xếp giảm dần\",\n removeSort: \"Bỏ sắp xếp\",\n pinLeft: \"Ghim sang trái\",\n unpinLeft: \"Bỏ ghim trái\",\n pinRight: \"Ghim sang phải\",\n unpinRight: \"Bỏ ghim phải\",\n hide: \"Ẩn cột\",\n resize: (label: string) => `Đổi độ rộng cột ${label}`,\n /** Tên kiểu dữ liệu của cột, hiện trong tooltip ở tiêu đề cột */\n variant: {\n shortText: \"Văn bản ngắn\",\n longText: \"Văn bản dài\",\n number: \"Số\",\n url: \"Liên kết\",\n checkbox: \"Ô đánh dấu\",\n select: \"Chọn một\",\n multiSelect: \"Chọn nhiều\",\n date: \"Ngày\",\n file: \"Tệp\"\n }\n },\n\n select: {\n all: \"Chọn tất cả\",\n row: \"Chọn dòng\",\n rowNumber: (rowNumber: number) => `Chọn dòng ${rowNumber}`\n },\n\n contextMenu: {\n copy: \"Sao chép\",\n cut: \"Cắt\",\n clear: \"Xoá nội dung\",\n deleteRows: \"Xoá dòng\"\n },\n\n pasteDialog: {\n title: \"Thêm dòng để dán hết dữ liệu?\",\n description: (rowsNeeded: number) => `Cần thêm ${rowsNeeded} dòng nữa để dán hết nội dung đang có trong clipboard.`,\n expandTitle: \"Tạo dòng mới\",\n expandDescription: (rowsNeeded: number) => `Thêm ${rowsNeeded} dòng vào bảng rồi dán toàn bộ dữ liệu`,\n keepTitle: \"Giữ nguyên số dòng\",\n keepDescription: \"Chỉ dán phần vừa với các dòng hiện có\",\n cancel: \"Huỷ\",\n confirm: \"Tiếp tục\"\n },\n\n rowHeight: {\n label: \"Chiều cao dòng\",\n short: \"Thấp\",\n medium: \"Vừa\",\n tall: \"Cao\",\n extraTall: \"Rất cao\"\n },\n\n view: {\n trigger: \"Hiển thị\",\n toggleColumns: \"Ẩn/hiện cột\",\n searchPlaceholder: \"Tìm cột...\",\n empty: \"Không có cột phù hợp.\"\n },\n\n sort: {\n trigger: \"Sắp xếp\",\n title: \"Sắp xếp theo\",\n emptyTitle: \"Chưa sắp xếp\",\n description: \"Đổi tiêu chí sắp xếp cho danh sách.\",\n emptyDescription: \"Thêm tiêu chí để sắp xếp danh sách.\",\n add: \"Thêm sắp xếp\",\n reset: \"Bỏ sắp xếp\",\n remove: \"Xoá tiêu chí\",\n drag: \"Kéo để đổi thứ tự\",\n fieldPlaceholder: \"Tìm trường...\",\n fieldEmpty: \"Không có trường phù hợp.\",\n asc: \"Tăng dần\",\n desc: \"Giảm dần\"\n },\n\n filter: {\n trigger: \"Lọc\",\n title: \"Lọc theo\",\n emptyTitle: \"Chưa có bộ lọc\",\n description: \"Đổi điều kiện lọc để thu hẹp dữ liệu.\",\n emptyDescription: \"Thêm điều kiện lọc để thu hẹp dữ liệu.\",\n add: \"Thêm bộ lọc\",\n reset: \"Xoá bộ lọc\",\n remove: \"Xoá điều kiện\",\n drag: \"Kéo để đổi thứ tự\",\n where: \"Khi\",\n and: \"Và\",\n fieldPlaceholder: \"Tìm trường...\",\n fieldEmpty: \"Không có trường phù hợp.\",\n valuePlaceholder: \"Giá trị\",\n rangeStart: \"Từ\",\n rangeEnd: \"Đến\",\n pickDate: \"Chọn ngày\",\n pickRange: \"Chọn khoảng ngày\",\n optionPlaceholder: \"Tìm lựa chọn...\",\n optionEmpty: \"Không có lựa chọn phù hợp.\",\n selectedCount: (count: number) => `Đã chọn ${count}`,\n emptyValue: (label: string) => `Bộ lọc ${label} chưa cần giá trị`,\n /** Nhãn toán tử lọc — xem `filters.ts` để biết toán tử nào dùng cho kiểu ô nào */\n operators: {\n contains: \"Chứa\",\n notContains: \"Không chứa\",\n equals: \"Bằng\",\n notEquals: \"Khác\",\n startsWith: \"Bắt đầu bằng\",\n endsWith: \"Kết thúc bằng\",\n isEmpty: \"Đang trống\",\n isNotEmpty: \"Không trống\",\n lessThan: \"Nhỏ hơn\",\n lessThanOrEqual: \"Nhỏ hơn hoặc bằng\",\n greaterThan: \"Lớn hơn\",\n greaterThanOrEqual: \"Lớn hơn hoặc bằng\",\n isBetween: \"Trong khoảng\",\n dateEquals: \"Đúng ngày\",\n dateNotEquals: \"Khác ngày\",\n before: \"Trước ngày\",\n after: \"Sau ngày\",\n onOrBefore: \"Vào hoặc trước ngày\",\n onOrAfter: \"Vào hoặc sau ngày\",\n is: \"Là\",\n isNot: \"Không là\",\n isAnyOf: \"Là một trong\",\n isNoneOf: \"Không là bất kỳ\",\n isTrue: \"Có đánh dấu\",\n isFalse: \"Không đánh dấu\"\n }\n },\n\n cell: {\n longTextPlaceholder: \"Nhập nội dung...\",\n optionSearchPlaceholder: \"Tìm...\",\n optionEmpty: \"Không có lựa chọn phù hợp.\",\n clearAll: \"Bỏ chọn hết\",\n invalidUrlTitle: \"Liên kết không hợp lệ\",\n invalidUrlDescription: \"Liên kết chứa giao thức nguy hiểm (javascript:, data:, vbscript: hoặc file:)\"\n },\n\n file: {\n uploadLabel: \"Tải tệp lên\",\n dropHere: \"Thả tệp vào đây\",\n dragHere: \"Kéo tệp vào đây\",\n browse: \"hoặc bấm để chọn tệp\",\n limits: (maxSize?: string, maxFiles?: number) => {\n if (maxSize && maxFiles) return `Tối đa ${maxSize} • Tối đa ${maxFiles} tệp`;\n if (maxSize) return `Tối đa ${maxSize}`;\n if (maxFiles) return `Tối đa ${maxFiles} tệp`;\n return \"Chọn tệp để tải lên\";\n },\n count: (count: number) => `${count} tệp`,\n clearAll: \"Xoá hết\",\n remove: \"Xoá tệp\",\n uploading: \"Đang tải lên...\",\n deleting: \"Đang xoá...\",\n tooMany: (maxFiles: number) => `Chỉ cho phép tối đa ${maxFiles} tệp`,\n tooLarge: (maxSize: string) => `Tệp vượt quá ${maxSize}`,\n wrongType: \"Không chấp nhận định dạng tệp này\",\n rejectedOne: (name: string) => `Đã bỏ qua \"${name}\"`,\n rejectedMany: (name: string, others: number) => `Đã bỏ qua \"${name}\" và ${others} tệp khác`,\n uploadFailed: (count: number) => `Không tải lên được ${count} tệp`,\n deleteFailed: (name: string) => `Không xoá được ${name}`,\n deleteFailedMany: \"Không xoá được tệp\"\n },\n\n toast: {\n cellsCopied: (count: number) => `Đã sao chép ${count} ô`,\n copyFailed: \"Không sao chép được vào clipboard\",\n cellsCut: (count: number) => `Đã cắt ${count} ô`,\n cutFailed: \"Không cắt được vào clipboard\",\n cellsPasted: (count: number) => `Đã dán ${count} ô`,\n cellsPastedWithSkipped: (count: number, skipped: number) => `Đã dán ${count} ô, bỏ qua ${skipped} ô`,\n pasteSkipped: (skipped: number) => `Bỏ qua ${skipped} ô do dữ liệu không hợp lệ`,\n pasteFailed: \"Không dán được. Vui lòng thử lại.\",\n cellsCleared: (count: number) => `Đã xoá nội dung ${count} ô`,\n rowsDeleted: (count: number) => `Đã xoá ${count} dòng`,\n nothingToUndo: \"Không còn thao tác để hoàn tác\",\n nothingToRedo: \"Không còn thao tác để làm lại\",\n undone: (count: number) => `Đã hoàn tác ${count} thao tác`,\n redone: (count: number) => `Đã làm lại ${count} thao tác`\n },\n\n /** Giá trị văn bản khi dán boolean vào ô văn bản */\n booleanText: {\n checked: \"Có\",\n unchecked: \"Không\"\n },\n\n shortcuts: {\n trigger: \"Phím tắt\",\n title: \"Phím tắt\",\n description: \"Danh sách phím tắt để thao tác nhanh với bảng dữ liệu.\",\n searchPlaceholder: \"Tìm phím tắt...\",\n emptyTitle: \"Không tìm thấy phím tắt\",\n emptyDescription: \"Thử tìm với từ khoá khác.\",\n close: \"Đóng\",\n groups: {\n navigation: \"Di chuyển\",\n selection: \"Chọn ô\",\n editing: \"Sửa dữ liệu\",\n search: \"Tìm kiếm\",\n filtering: \"Lọc\",\n sorting: \"Sắp xếp\",\n general: \"Chung\"\n },\n keys: {\n click: \"Nhấp chuột\",\n doubleClick: \"Nhấp đúp\"\n },\n navigation: {\n move: \"Di chuyển giữa các ô\",\n nextCell: \"Sang ô kế tiếp\",\n prevCell: \"Về ô trước đó\",\n firstColumn: \"Về cột đầu\",\n lastColumn: \"Tới cột cuối\",\n firstRowSameColumn: \"Về dòng đầu (cùng cột)\",\n lastRowSameColumn: \"Tới dòng cuối (cùng cột)\",\n firstColumnSameRow: \"Về cột đầu (cùng dòng)\",\n lastColumnSameRow: \"Tới cột cuối (cùng dòng)\",\n firstCell: \"Về ô đầu bảng\",\n lastCell: \"Tới ô cuối bảng\",\n pageUp: \"Lên một trang\",\n pageDown: \"Xuống một trang\",\n scrollUp: \"Cuộn lên một trang\",\n scrollDown: \"Cuộn xuống một trang\",\n scrollLeft: \"Cuộn sang trái một trang cột\",\n scrollRight: \"Cuộn sang phải một trang cột\"\n },\n selection: {\n extend: \"Mở rộng vùng chọn\",\n toTop: \"Chọn tới đầu bảng\",\n toBottom: \"Chọn tới cuối bảng\",\n toFirstColumn: \"Chọn tới cột đầu\",\n toLastColumn: \"Chọn tới cột cuối\",\n all: \"Chọn toàn bộ ô\",\n toggle: \"Thêm/bớt một ô khỏi vùng chọn\",\n range: \"Chọn cả vùng\",\n clear: \"Bỏ chọn\"\n },\n editing: {\n start: \"Bắt đầu sửa ô\",\n insertRow: \"Chèn dòng bên dưới\",\n copy: \"Sao chép ô đang chọn\",\n cut: \"Cắt ô đang chọn\",\n paste: \"Dán vào ô\",\n clear: \"Xoá nội dung ô đang chọn\",\n deleteRows: \"Xoá dòng đang chọn\",\n undo: \"Hoàn tác\",\n redo: \"Làm lại\"\n },\n search: {\n open: \"Mở ô tìm kiếm\",\n next: \"Kết quả kế tiếp\",\n prev: \"Kết quả trước đó\",\n close: \"Đóng tìm kiếm\"\n },\n filtering: {\n toggle: \"Mở/đóng menu lọc\",\n remove: \"Xoá điều kiện lọc (khi đang chọn)\"\n },\n sorting: {\n toggle: \"Mở/đóng menu sắp xếp\",\n remove: \"Xoá tiêu chí sắp xếp (khi đang chọn)\"\n },\n general: {\n shortcuts: \"Xem danh sách phím tắt\"\n }\n }\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/data-grid/messages-vi.ts"],"sourcesContent":["import type { DataGridMessages } from \"./messages-en.js\";\n\n/**\n * Bảng tiếng VIỆT của DataGrid. Hình dạng do `messages-en.ts` quy định — chú thích `: DataGridMessages`\n * ở đây là thứ bắt lỗi: thêm khoá mới ở bản tiếng Anh mà quên dịch thì typecheck đỏ ngay, thay vì\n * một chuỗi `undefined` lọt ra giao diện lúc chạy.\n *\n * ⚠ Bản này KHÔNG còn là mặc định từ `2.0.0`. Từ `3.0.0` lưới tự chọn nó khi app đặt\n * `<ComitorLocaleProvider locale=\"vi\">` ở root; muốn riêng lưới tiếng Việt thì truyền `locale=\"vi\"`\n * (hoặc bọc `DataGridLocaleProvider locale=\"vi\"`).\n */\nexport const messagesVi: DataGridMessages = {\n grid: {\n /** Nhãn mặc định của vùng `role=\"grid\"` (ghi đè bằng prop `aria-label`) */\n label: \"Bảng dữ liệu\",\n addRow: \"Thêm dòng\"\n },\n\n search: {\n placeholder: \"Tìm trong bảng...\",\n label: \"Tìm trong bảng\",\n prevMatch: \"Kết quả trước\",\n nextMatch: \"Kết quả sau\",\n close: \"Đóng tìm kiếm\",\n matchPosition: (index: number, total: number) => `${index} / ${total}`,\n noResults: \"Không có kết quả\",\n typeToSearch: \"Gõ để tìm\"\n },\n\n column: {\n sortAsc: \"Sắp xếp tăng dần\",\n sortDesc: \"Sắp xếp giảm dần\",\n removeSort: \"Bỏ sắp xếp\",\n pinLeft: \"Ghim sang trái\",\n unpinLeft: \"Bỏ ghim trái\",\n pinRight: \"Ghim sang phải\",\n unpinRight: \"Bỏ ghim phải\",\n hide: \"Ẩn cột\",\n resize: (label: string) => `Đổi độ rộng cột ${label}`,\n /** Tên kiểu dữ liệu của cột, hiện trong tooltip ở tiêu đề cột */\n variant: {\n shortText: \"Văn bản ngắn\",\n longText: \"Văn bản dài\",\n number: \"Số\",\n url: \"Liên kết\",\n checkbox: \"Ô đánh dấu\",\n select: \"Chọn một\",\n multiSelect: \"Chọn nhiều\",\n date: \"Ngày\",\n file: \"Tệp\"\n }\n },\n\n select: {\n all: \"Chọn tất cả\",\n row: \"Chọn dòng\",\n rowNumber: (rowNumber: number) => `Chọn dòng ${rowNumber}`\n },\n\n contextMenu: {\n copy: \"Sao chép\",\n cut: \"Cắt\",\n clear: \"Xoá nội dung\",\n deleteRows: \"Xoá dòng\"\n },\n\n pasteDialog: {\n title: \"Thêm dòng để dán hết dữ liệu?\",\n description: (rowsNeeded: number) => `Cần thêm ${rowsNeeded} dòng nữa để dán hết nội dung đang có trong clipboard.`,\n expandTitle: \"Tạo dòng mới\",\n expandDescription: (rowsNeeded: number) => `Thêm ${rowsNeeded} dòng vào bảng rồi dán toàn bộ dữ liệu`,\n keepTitle: \"Giữ nguyên số dòng\",\n keepDescription: \"Chỉ dán phần vừa với các dòng hiện có\",\n cancel: \"Huỷ\",\n confirm: \"Tiếp tục\"\n },\n\n rowHeight: {\n label: \"Chiều cao dòng\",\n short: \"Thấp\",\n medium: \"Vừa\",\n tall: \"Cao\",\n extraTall: \"Rất cao\"\n },\n\n view: {\n trigger: \"Hiển thị\",\n toggleColumns: \"Ẩn/hiện cột\",\n searchPlaceholder: \"Tìm cột...\",\n empty: \"Không có cột phù hợp.\"\n },\n\n sort: {\n trigger: \"Sắp xếp\",\n title: \"Sắp xếp theo\",\n emptyTitle: \"Chưa sắp xếp\",\n description: \"Đổi tiêu chí sắp xếp cho danh sách.\",\n emptyDescription: \"Thêm tiêu chí để sắp xếp danh sách.\",\n add: \"Thêm sắp xếp\",\n reset: \"Bỏ sắp xếp\",\n remove: \"Xoá tiêu chí\",\n drag: \"Kéo để đổi thứ tự\",\n fieldPlaceholder: \"Tìm trường...\",\n fieldEmpty: \"Không có trường phù hợp.\",\n asc: \"Tăng dần\",\n desc: \"Giảm dần\"\n },\n\n filter: {\n trigger: \"Lọc\",\n title: \"Lọc theo\",\n emptyTitle: \"Chưa có bộ lọc\",\n description: \"Đổi điều kiện lọc để thu hẹp dữ liệu.\",\n emptyDescription: \"Thêm điều kiện lọc để thu hẹp dữ liệu.\",\n add: \"Thêm bộ lọc\",\n reset: \"Xoá bộ lọc\",\n remove: \"Xoá điều kiện\",\n drag: \"Kéo để đổi thứ tự\",\n where: \"Khi\",\n and: \"Và\",\n fieldPlaceholder: \"Tìm trường...\",\n fieldEmpty: \"Không có trường phù hợp.\",\n valuePlaceholder: \"Giá trị\",\n rangeStart: \"Từ\",\n rangeEnd: \"Đến\",\n pickDate: \"Chọn ngày\",\n pickRange: \"Chọn khoảng ngày\",\n optionPlaceholder: \"Tìm lựa chọn...\",\n optionEmpty: \"Không có lựa chọn phù hợp.\",\n selectedCount: (count: number) => `Đã chọn ${count}`,\n emptyValue: (label: string) => `Bộ lọc ${label} chưa cần giá trị`,\n /** Nhãn toán tử lọc — xem `filters.ts` để biết toán tử nào dùng cho kiểu ô nào */\n operators: {\n contains: \"Chứa\",\n notContains: \"Không chứa\",\n equals: \"Bằng\",\n notEquals: \"Khác\",\n startsWith: \"Bắt đầu bằng\",\n endsWith: \"Kết thúc bằng\",\n isEmpty: \"Đang trống\",\n isNotEmpty: \"Không trống\",\n lessThan: \"Nhỏ hơn\",\n lessThanOrEqual: \"Nhỏ hơn hoặc bằng\",\n greaterThan: \"Lớn hơn\",\n greaterThanOrEqual: \"Lớn hơn hoặc bằng\",\n isBetween: \"Trong khoảng\",\n dateEquals: \"Đúng ngày\",\n dateNotEquals: \"Khác ngày\",\n before: \"Trước ngày\",\n after: \"Sau ngày\",\n onOrBefore: \"Vào hoặc trước ngày\",\n onOrAfter: \"Vào hoặc sau ngày\",\n is: \"Là\",\n isNot: \"Không là\",\n isAnyOf: \"Là một trong\",\n isNoneOf: \"Không là bất kỳ\",\n isTrue: \"Có đánh dấu\",\n isFalse: \"Không đánh dấu\"\n }\n },\n\n cell: {\n longTextPlaceholder: \"Nhập nội dung...\",\n optionSearchPlaceholder: \"Tìm...\",\n optionEmpty: \"Không có lựa chọn phù hợp.\",\n clearAll: \"Bỏ chọn hết\",\n invalidUrlTitle: \"Liên kết không hợp lệ\",\n invalidUrlDescription: \"Liên kết chứa giao thức nguy hiểm (javascript:, data:, vbscript: hoặc file:)\"\n },\n\n file: {\n uploadLabel: \"Tải tệp lên\",\n dropHere: \"Thả tệp vào đây\",\n dragHere: \"Kéo tệp vào đây\",\n browse: \"hoặc bấm để chọn tệp\",\n limits: (maxSize?: string, maxFiles?: number) => {\n if (maxSize && maxFiles) return `Tối đa ${maxSize} • Tối đa ${maxFiles} tệp`;\n if (maxSize) return `Tối đa ${maxSize}`;\n if (maxFiles) return `Tối đa ${maxFiles} tệp`;\n return \"Chọn tệp để tải lên\";\n },\n count: (count: number) => `${count} tệp`,\n clearAll: \"Xoá hết\",\n remove: \"Xoá tệp\",\n uploading: \"Đang tải lên...\",\n deleting: \"Đang xoá...\",\n tooMany: (maxFiles: number) => `Chỉ cho phép tối đa ${maxFiles} tệp`,\n tooLarge: (maxSize: string) => `Tệp vượt quá ${maxSize}`,\n wrongType: \"Không chấp nhận định dạng tệp này\",\n rejectedOne: (name: string) => `Đã bỏ qua \"${name}\"`,\n rejectedMany: (name: string, others: number) => `Đã bỏ qua \"${name}\" và ${others} tệp khác`,\n uploadFailed: (count: number) => `Không tải lên được ${count} tệp`,\n deleteFailed: (name: string) => `Không xoá được ${name}`,\n deleteFailedMany: \"Không xoá được tệp\"\n },\n\n toast: {\n cellsCopied: (count: number) => `Đã sao chép ${count} ô`,\n copyFailed: \"Không sao chép được vào clipboard\",\n cellsCut: (count: number) => `Đã cắt ${count} ô`,\n cutFailed: \"Không cắt được vào clipboard\",\n cellsPasted: (count: number) => `Đã dán ${count} ô`,\n cellsPastedWithSkipped: (count: number, skipped: number) => `Đã dán ${count} ô, bỏ qua ${skipped} ô`,\n pasteSkipped: (skipped: number) => `Bỏ qua ${skipped} ô do dữ liệu không hợp lệ`,\n pasteFailed: \"Không dán được. Vui lòng thử lại.\",\n cellsCleared: (count: number) => `Đã xoá nội dung ${count} ô`,\n rowsDeleted: (count: number) => `Đã xoá ${count} dòng`,\n nothingToUndo: \"Không còn thao tác để hoàn tác\",\n nothingToRedo: \"Không còn thao tác để làm lại\",\n undone: (count: number) => `Đã hoàn tác ${count} thao tác`,\n redone: (count: number) => `Đã làm lại ${count} thao tác`\n },\n\n /** Giá trị văn bản khi dán boolean vào ô văn bản */\n booleanText: {\n checked: \"Có\",\n unchecked: \"Không\"\n },\n\n /** Lời đọc cho trình đọc màn hình khi kéo-thả đổi thứ tự trong menu Lọc / Sắp xếp */\n sortable: {\n instructions: (orientation: \"vertical\" | \"horizontal\" | \"mixed\") => {\n const keys = orientation === \"vertical\" ? \"lên/xuống\" : orientation === \"horizontal\" ? \"trái/phải\" : \"\";\n return `Nhấn phím cách hoặc Enter để nhấc mục lên. Khi đang giữ, dùng phím mũi tên${keys ? ` ${keys}` : \"\"} để di chuyển. Nhấn phím cách hoặc Enter lần nữa để thả vào vị trí mới, hoặc Esc để huỷ.`;\n },\n dragStart: (item: string, position: number, total: number) =>\n `Đã nhấc mục \"${item}\". Vị trí hiện tại ${position} / ${total}. Dùng phím mũi tên để di chuyển, phím cách để thả.`,\n dragOver: (item: string, direction: \"up\" | \"down\", position: number, total: number) =>\n `Mục \"${item}\" đã chuyển ${direction === \"down\" ? \"xuống\" : \"lên\"} vị trí ${position} / ${total}.`,\n dragMove: (item: string, direction: \"up\" | \"down\", position: number, total: number) =>\n `Mục \"${item}\" đang di chuyển ${direction === \"down\" ? \"xuống\" : \"lên\"} vị trí ${position} / ${total}.`,\n outside: \"Mục đang ở ngoài vùng thả. Nhấn Esc để huỷ.\",\n dragEnd: (item: string, position: number, total: number) => `Đã thả mục \"${item}\" ở vị trí ${position} / ${total}.`,\n dragEndNoChange: (item: string) => `Đã thả mục \"${item}\". Không có thay đổi nào.`,\n dragCancel: (item: string, position: number, total: number) =>\n `Đã huỷ sắp xếp. Mục \"${item}\" trở về vị trí ${position} / ${total}.`\n },\n\n shortcuts: {\n trigger: \"Phím tắt\",\n title: \"Phím tắt\",\n description: \"Danh sách phím tắt để thao tác nhanh với bảng dữ liệu.\",\n searchPlaceholder: \"Tìm phím tắt...\",\n emptyTitle: \"Không tìm thấy phím tắt\",\n emptyDescription: \"Thử tìm với từ khoá khác.\",\n close: \"Đóng\",\n groups: {\n navigation: \"Di chuyển\",\n selection: \"Chọn ô\",\n editing: \"Sửa dữ liệu\",\n search: \"Tìm kiếm\",\n filtering: \"Lọc\",\n sorting: \"Sắp xếp\",\n general: \"Chung\"\n },\n keys: {\n click: \"Nhấp chuột\",\n doubleClick: \"Nhấp đúp\"\n },\n navigation: {\n move: \"Di chuyển giữa các ô\",\n nextCell: \"Sang ô kế tiếp\",\n prevCell: \"Về ô trước đó\",\n firstColumn: \"Về cột đầu\",\n lastColumn: \"Tới cột cuối\",\n firstRowSameColumn: \"Về dòng đầu (cùng cột)\",\n lastRowSameColumn: \"Tới dòng cuối (cùng cột)\",\n firstColumnSameRow: \"Về cột đầu (cùng dòng)\",\n lastColumnSameRow: \"Tới cột cuối (cùng dòng)\",\n firstCell: \"Về ô đầu bảng\",\n lastCell: \"Tới ô cuối bảng\",\n pageUp: \"Lên một trang\",\n pageDown: \"Xuống một trang\",\n scrollUp: \"Cuộn lên một trang\",\n scrollDown: \"Cuộn xuống một trang\",\n scrollLeft: \"Cuộn sang trái một trang cột\",\n scrollRight: \"Cuộn sang phải một trang cột\"\n },\n selection: {\n extend: \"Mở rộng vùng chọn\",\n toTop: \"Chọn tới đầu bảng\",\n toBottom: \"Chọn tới cuối bảng\",\n toFirstColumn: \"Chọn tới cột đầu\",\n toLastColumn: \"Chọn tới cột cuối\",\n all: \"Chọn toàn bộ ô\",\n toggle: \"Thêm/bớt một ô khỏi vùng chọn\",\n range: \"Chọn cả vùng\",\n clear: \"Bỏ chọn\"\n },\n editing: {\n start: \"Bắt đầu sửa ô\",\n insertRow: \"Chèn dòng bên dưới\",\n copy: \"Sao chép ô đang chọn\",\n cut: \"Cắt ô đang chọn\",\n paste: \"Dán vào ô\",\n clear: \"Xoá nội dung ô đang chọn\",\n deleteRows: \"Xoá dòng đang chọn\",\n undo: \"Hoàn tác\",\n redo: \"Làm lại\"\n },\n search: {\n open: \"Mở ô tìm kiếm\",\n next: \"Kết quả kế tiếp\",\n prev: \"Kết quả trước đó\",\n close: \"Đóng tìm kiếm\"\n },\n filtering: {\n toggle: \"Mở/đóng menu lọc\",\n remove: \"Xoá điều kiện lọc (khi đang chọn)\"\n },\n sorting: {\n toggle: \"Mở/đóng menu sắp xếp\",\n remove: \"Xoá tiêu chí sắp xếp (khi đang chọn)\"\n },\n general: {\n shortcuts: \"Xem danh sách phím tắt\"\n }\n }\n};\n"],"mappings":"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","names":[]}
@@ -11,8 +11,11 @@ export { messagesVi } from './messages-vi.js';
11
11
  * `messages-<mã>.ts` chú thích `: DataGridMessages`, ghi vào `DATA_GRID_MESSAGES` bên dưới, và
12
12
  * `DataGridLocale` tự rộng ra theo — không có danh sách thứ hai nào phải nhớ cập nhật.
13
13
  *
14
- * ⚠ Mặc định là **tiếng Anh**, ngược với phần còn lại của gói (README §5). Đây là ngoại lệ có chủ
15
- * ý của riêng `DataGrid`, chốt ở `2.0.0` — lý do đầy đủ ở đầu `messages-en.ts`.
14
+ * Mặc định là **tiếng Anh** (từ `2.0.0`; cả gói theo từ `3.0.0`) — lý do tiếng Anh là bản gốc ở
15
+ * đầu `messages-en.ts`. Lưới giữ bảng RIÊNG chứ không nằm trong `src/i18n/`, nhưng khi không ai
16
+ * truyền `locale` nó chọn bảng theo ngôn ngữ của `ComitorLocaleProvider` — luật ưu tiên đầy đủ ở
17
+ * `data-grid-locale.tsx`. `DEFAULT_DATA_GRID_LOCALE` dưới đây là tầng CUỐI của luật ấy, và là thứ
18
+ * `getDataGridMessages()` (hàm thuần, không đọc context) trả về.
16
19
  */
17
20
 
18
21
  /** Mọi bảng ngôn ngữ dựng sẵn, tra theo mã. */
@@ -202,6 +205,16 @@ declare const DATA_GRID_MESSAGES: {
202
205
  checked: string;
203
206
  unchecked: string;
204
207
  };
208
+ sortable: {
209
+ instructions: (orientation: "vertical" | "horizontal" | "mixed") => string;
210
+ dragStart: (item: string, position: number, total: number) => string;
211
+ dragOver: (item: string, direction: "up" | "down", position: number, total: number) => string;
212
+ dragMove: (item: string, direction: "up" | "down", position: number, total: number) => string;
213
+ outside: string;
214
+ dragEnd: (item: string, position: number, total: number) => string;
215
+ dragEndNoChange: (item: string) => string;
216
+ dragCancel: (item: string, position: number, total: number) => string;
217
+ };
205
218
  shortcuts: {
206
219
  trigger: string;
207
220
  title: string;
@@ -468,6 +481,16 @@ declare const DATA_GRID_MESSAGES: {
468
481
  checked: string;
469
482
  unchecked: string;
470
483
  };
484
+ sortable: {
485
+ instructions: (orientation: "vertical" | "horizontal" | "mixed") => string;
486
+ dragStart: (item: string, position: number, total: number) => string;
487
+ dragOver: (item: string, direction: "up" | "down", position: number, total: number) => string;
488
+ dragMove: (item: string, direction: "up" | "down", position: number, total: number) => string;
489
+ outside: string;
490
+ dragEnd: (item: string, position: number, total: number) => string;
491
+ dragEndNoChange: (item: string) => string;
492
+ dragCancel: (item: string, position: number, total: number) => string;
493
+ };
471
494
  shortcuts: {
472
495
  trigger: string;
473
496
  title: string;
@@ -552,7 +575,10 @@ declare const DATA_GRID_MESSAGES: {
552
575
  };
553
576
  /** Mã ngôn ngữ mà `DataGrid` nhận. Suy từ `DATA_GRID_MESSAGES`, không viết tay lần hai. */
554
577
  type DataGridLocale = keyof typeof DATA_GRID_MESSAGES;
555
- /** Mặc định khi không ai truyền gì — xem ghi chú đầu file về vì sao là `"en"`. */
578
+ /**
579
+ * Mặc định khi không ai truyền gì VÀ không có `ComitorLocaleProvider` — xem ghi chú đầu file về
580
+ * vì sao là `"en"`.
581
+ */
556
582
  declare const DEFAULT_DATA_GRID_LOCALE: DataGridLocale;
557
583
  /**
558
584
  * Bảng chuỗi cho một ngôn ngữ, hoặc bảng do app tự truyền vào.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data-grid/messages.ts"],"sourcesContent":["/**\n * Sổ đăng ký ngôn ngữ của DataGrid. Module THUẦN — không directive, không hook — nên Server\n * Component đọc thẳng được (xem `verify:directives`, phép kiểm 2 và 3).\n *\n * Hai ngôn ngữ, và cố ý dừng ở hai: tiếng Anh là bản gốc định nghĩa hình dạng\n * ({@link DataGridMessages}), tiếng Việt là bản dịch đủ. Thêm ngôn ngữ thứ ba thì thêm một file\n * `messages-<mã>.ts` chú thích `: DataGridMessages`, ghi vào `DATA_GRID_MESSAGES` bên dưới, và\n * `DataGridLocale` tự rộng ra theo — không có danh sách thứ hai nào phải nhớ cập nhật.\n *\n * ⚠ Mặc định là **tiếng Anh**, ngược với phần còn lại của gói (README §5). Đây là ngoại lệ có chủ\n * ý của riêng `DataGrid`, chốt ở `2.0.0` — lý do đầy đủ ở đầu `messages-en.ts`.\n */\nimport { type DataGridMessages, messagesEn } from \"./messages-en.js\";\nimport { messagesVi } from \"./messages-vi.js\";\n\nexport type { DataGridMessages };\nexport { messagesEn, messagesVi };\n\n/** Mọi bảng ngôn ngữ dựng sẵn, tra theo mã. */\nexport const DATA_GRID_MESSAGES = {\n en: messagesEn,\n vi: messagesVi\n};\n\n/** Mã ngôn ngữ mà `DataGrid` nhận. Suy từ `DATA_GRID_MESSAGES`, không viết tay lần hai. */\nexport type DataGridLocale = keyof typeof DATA_GRID_MESSAGES;\n\n/** Mặc định khi không ai truyền gì — xem ghi chú đầu file về vì sao là `\"en\"`. */\nexport const DEFAULT_DATA_GRID_LOCALE: DataGridLocale = \"en\";\n\n/**\n * Bảng chuỗi cho một ngôn ngữ, hoặc bảng do app tự truyền vào.\n *\n * Nhận cả mã lẫn cả object để app không phải chọn giữa \"dùng bản dựng sẵn\" và \"sửa vài chữ\":\n * truyền `\"vi\"` là xong, còn muốn đổi từ ngữ theo nghiệp vụ thì trải bảng ra rồi ghi đè khoá cần\n * đổi. Mã lạ rơi về mặc định thay vì ném lỗi — một chữ sai chính tả trong prop không đáng làm\n * trắng cả màn hình.\n */\nexport function getDataGridMessages(locale?: DataGridLocale | DataGridMessages): DataGridMessages {\n if (!locale) return DATA_GRID_MESSAGES[DEFAULT_DATA_GRID_LOCALE];\n if (typeof locale === \"string\") return DATA_GRID_MESSAGES[locale] ?? DATA_GRID_MESSAGES[DEFAULT_DATA_GRID_LOCALE];\n return locale;\n}\n"],"mappings":"AAYA,SAAgC,kBAAkB;AAClD,SAAS,kBAAkB;AAMpB,MAAM,qBAAqB;AAAA,EAChC,IAAI;AAAA,EACJ,IAAI;AACN;AAMO,MAAM,2BAA2C;AAUjD,SAAS,oBAAoB,QAA8D;AAChG,MAAI,CAAC,OAAQ,QAAO,mBAAmB,wBAAwB;AAC/D,MAAI,OAAO,WAAW,SAAU,QAAO,mBAAmB,MAAM,KAAK,mBAAmB,wBAAwB;AAChH,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/data-grid/messages.ts"],"sourcesContent":["/**\n * Sổ đăng ký ngôn ngữ của DataGrid. Module THUẦN — không directive, không hook — nên Server\n * Component đọc thẳng được (xem `verify:directives`, phép kiểm 2 và 3).\n *\n * Hai ngôn ngữ, và cố ý dừng ở hai: tiếng Anh là bản gốc định nghĩa hình dạng\n * ({@link DataGridMessages}), tiếng Việt là bản dịch đủ. Thêm ngôn ngữ thứ ba thì thêm một file\n * `messages-<mã>.ts` chú thích `: DataGridMessages`, ghi vào `DATA_GRID_MESSAGES` bên dưới, và\n * `DataGridLocale` tự rộng ra theo — không có danh sách thứ hai nào phải nhớ cập nhật.\n *\n * Mặc định là **tiếng Anh** (từ `2.0.0`; cả gói theo từ `3.0.0`) — lý do tiếng Anh là bản gốc ở\n * đầu `messages-en.ts`. Lưới giữ bảng RIÊNG chứ không nằm trong `src/i18n/`, nhưng khi không ai\n * truyền `locale` nó chọn bảng theo ngôn ngữ của `ComitorLocaleProvider` — luật ưu tiên đầy đủ ở\n * `data-grid-locale.tsx`. `DEFAULT_DATA_GRID_LOCALE` dưới đây là tầng CUỐI của luật ấy, và là thứ\n * `getDataGridMessages()` (hàm thuần, không đọc context) trả về.\n */\nimport { type DataGridMessages, messagesEn } from \"./messages-en.js\";\nimport { messagesVi } from \"./messages-vi.js\";\n\nexport type { DataGridMessages };\nexport { messagesEn, messagesVi };\n\n/** Mọi bảng ngôn ngữ dựng sẵn, tra theo mã. */\nexport const DATA_GRID_MESSAGES = {\n en: messagesEn,\n vi: messagesVi\n};\n\n/** Mã ngôn ngữ mà `DataGrid` nhận. Suy từ `DATA_GRID_MESSAGES`, không viết tay lần hai. */\nexport type DataGridLocale = keyof typeof DATA_GRID_MESSAGES;\n\n/**\n * Mặc định khi không ai truyền gì VÀ không có `ComitorLocaleProvider` — xem ghi chú đầu file về\n * vì sao là `\"en\"`.\n */\nexport const DEFAULT_DATA_GRID_LOCALE: DataGridLocale = \"en\";\n\n/**\n * Bảng chuỗi cho một ngôn ngữ, hoặc bảng do app tự truyền vào.\n *\n * Nhận cả mã lẫn cả object để app không phải chọn giữa \"dùng bản dựng sẵn\" và \"sửa vài chữ\":\n * truyền `\"vi\"` là xong, còn muốn đổi từ ngữ theo nghiệp vụ thì trải bảng ra rồi ghi đè khoá cần\n * đổi. Mã lạ rơi về mặc định thay vì ném lỗi — một chữ sai chính tả trong prop không đáng làm\n * trắng cả màn hình.\n */\nexport function getDataGridMessages(locale?: DataGridLocale | DataGridMessages): DataGridMessages {\n if (!locale) return DATA_GRID_MESSAGES[DEFAULT_DATA_GRID_LOCALE];\n if (typeof locale === \"string\") return DATA_GRID_MESSAGES[locale] ?? DATA_GRID_MESSAGES[DEFAULT_DATA_GRID_LOCALE];\n return locale;\n}\n"],"mappings":"AAeA,SAAgC,kBAAkB;AAClD,SAAS,kBAAkB;AAMpB,MAAM,qBAAqB;AAAA,EAChC,IAAI;AAAA,EACJ,IAAI;AACN;AASO,MAAM,2BAA2C;AAUjD,SAAS,oBAAoB,QAA8D;AAChG,MAAI,CAAC,OAAQ,QAAO,mBAAmB,wBAAwB;AAC/D,MAAI,OAAO,WAAW,SAAU,QAAO,mBAAmB,MAAM,KAAK,mBAAmB,wBAAwB;AAChH,SAAO;AACT;","names":[]}
@@ -26,7 +26,8 @@ import { Slot } from "@radix-ui/react-slot";
26
26
  import * as React from "react";
27
27
  import * as ReactDOM from "react-dom";
28
28
  import { cn } from "../lib/cn.js";
29
- import { useComposedRefs } from "./compose-refs.js";
29
+ import { useComposedRefs } from "../lib/compose-refs.js";
30
+ import { useDataGridMessages } from "./data-grid-locale.js";
30
31
  const orientationConfig = {
31
32
  vertical: {
32
33
  modifiers: [restrictToVerticalAxis, restrictToParentElement],
@@ -127,53 +128,49 @@ function Sortable(props) {
127
128
  },
128
129
  [sortableProps.onDragCancel]
129
130
  );
131
+ const msg = useDataGridMessages().sortable;
130
132
  const announcements = React.useMemo(
131
133
  () => ({
132
134
  onDragStart({ active }) {
133
- return `\u0110\xE3 nh\u1EA5c m\u1EE5c "${active.id.toString()}". V\u1ECB tr\xED hi\u1EC7n t\u1EA1i ${active.data.current?.sortable.index + 1} / ${value.length}. D\xF9ng ph\xEDm m\u0169i t\xEAn \u0111\u1EC3 di chuy\u1EC3n, ph\xEDm c\xE1ch \u0111\u1EC3 th\u1EA3.`;
135
+ const activeIndex = active.data.current?.sortable.index ?? 0;
136
+ return msg.dragStart(active.id.toString(), activeIndex + 1, value.length);
134
137
  },
135
138
  onDragOver({ active, over }) {
136
139
  if (over) {
137
140
  const overIndex = over.data.current?.sortable.index ?? 0;
138
141
  const activeIndex = active.data.current?.sortable.index ?? 0;
139
- const moveDirection = overIndex > activeIndex ? "xu\u1ED1ng" : "l\xEAn";
140
- return `M\u1EE5c "${active.id.toString()}" \u0111\xE3 chuy\u1EC3n ${moveDirection} v\u1ECB tr\xED ${overIndex + 1} / ${value.length}.`;
142
+ const moveDirection = overIndex > activeIndex ? "down" : "up";
143
+ return msg.dragOver(active.id.toString(), moveDirection, overIndex + 1, value.length);
141
144
  }
142
- return "M\u1EE5c \u0111ang \u1EDF ngo\xE0i v\xF9ng th\u1EA3. Nh\u1EA5n Esc \u0111\u1EC3 hu\u1EF7.";
145
+ return msg.outside;
143
146
  },
144
147
  onDragEnd({ active, over }) {
145
148
  const activeValue = active.id.toString();
146
149
  if (over) {
147
150
  const overIndex = over.data.current?.sortable.index ?? 0;
148
- return `\u0110\xE3 th\u1EA3 m\u1EE5c "${activeValue}" \u1EDF v\u1ECB tr\xED ${overIndex + 1} / ${value.length}.`;
151
+ return msg.dragEnd(activeValue, overIndex + 1, value.length);
149
152
  }
150
- return `\u0110\xE3 th\u1EA3 m\u1EE5c "${activeValue}". Kh\xF4ng c\xF3 thay \u0111\u1ED5i n\xE0o.`;
153
+ return msg.dragEndNoChange(activeValue);
151
154
  },
152
155
  onDragCancel({ active }) {
153
156
  const activeIndex = active.data.current?.sortable.index ?? 0;
154
- return `\u0110\xE3 hu\u1EF7 s\u1EAFp x\u1EBFp. M\u1EE5c "${active.id.toString()}" tr\u1EDF v\u1EC1 v\u1ECB tr\xED ${activeIndex + 1} / ${value.length}.`;
157
+ return msg.dragCancel(active.id.toString(), activeIndex + 1, value.length);
155
158
  },
156
159
  onDragMove({ active, over }) {
157
160
  if (over) {
158
161
  const overIndex = over.data.current?.sortable.index ?? 0;
159
162
  const activeIndex = active.data.current?.sortable.index ?? 0;
160
- const moveDirection = overIndex > activeIndex ? "xu\u1ED1ng" : "l\xEAn";
161
- return `M\u1EE5c "${active.id.toString()}" \u0111ang di chuy\u1EC3n ${moveDirection} v\u1ECB tr\xED ${overIndex + 1} / ${value.length}.`;
163
+ const moveDirection = overIndex > activeIndex ? "down" : "up";
164
+ return msg.dragMove(active.id.toString(), moveDirection, overIndex + 1, value.length);
162
165
  }
163
- return "M\u1EE5c \u0111ang \u1EDF ngo\xE0i v\xF9ng th\u1EA3. Nh\u1EA5n Esc \u0111\u1EC3 hu\u1EF7.";
166
+ return msg.outside;
164
167
  }
165
168
  }),
166
- [value]
169
+ [value, msg]
167
170
  );
168
171
  const screenReaderInstructions = React.useMemo(
169
- () => ({
170
- draggable: `
171
- Nh\u1EA5n ph\xEDm c\xE1ch ho\u1EB7c Enter \u0111\u1EC3 nh\u1EA5c m\u1EE5c l\xEAn.
172
- Khi \u0111ang gi\u1EEF, d\xF9ng ph\xEDm m\u0169i t\xEAn ${orientation === "vertical" ? "l\xEAn/xu\u1ED1ng" : orientation === "horizontal" ? "tr\xE1i/ph\u1EA3i" : ""} \u0111\u1EC3 di chuy\u1EC3n.
173
- Nh\u1EA5n ph\xEDm c\xE1ch ho\u1EB7c Enter l\u1EA7n n\u1EEFa \u0111\u1EC3 th\u1EA3 v\xE0o v\u1ECB tr\xED m\u1EDBi, ho\u1EB7c Esc \u0111\u1EC3 hu\u1EF7.
174
- `
175
- }),
176
- [orientation]
172
+ () => ({ draggable: msg.instructions(orientation) }),
173
+ [orientation, msg]
177
174
  );
178
175
  const contextValue = React.useMemo(
179
176
  () => ({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data-grid/sortable.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type Announcements,\n closestCenter,\n closestCorners,\n DndContext,\n type DndContextProps,\n type DragEndEvent,\n type DraggableAttributes,\n type DraggableSyntheticListeners,\n DragOverlay,\n type DragStartEvent,\n type DropAnimation,\n defaultDropAnimationSideEffects,\n KeyboardSensor,\n MouseSensor,\n type ScreenReaderInstructions,\n TouchSensor,\n type UniqueIdentifier,\n useSensor,\n useSensors\n} from \"@dnd-kit/core\";\nimport { restrictToHorizontalAxis, restrictToParentElement, restrictToVerticalAxis } from \"@dnd-kit/modifiers\";\nimport {\n arrayMove,\n horizontalListSortingStrategy,\n SortableContext,\n type SortableContextProps,\n sortableKeyboardCoordinates,\n useSortable,\n verticalListSortingStrategy\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { cn } from \"../lib/cn.js\";\nimport { useComposedRefs } from \"./compose-refs.js\";\n\nconst orientationConfig = {\n vertical: {\n modifiers: [restrictToVerticalAxis, restrictToParentElement],\n strategy: verticalListSortingStrategy,\n collisionDetection: closestCenter\n },\n horizontal: {\n modifiers: [restrictToHorizontalAxis, restrictToParentElement],\n strategy: horizontalListSortingStrategy,\n collisionDetection: closestCenter\n },\n mixed: {\n modifiers: [restrictToParentElement],\n strategy: undefined,\n collisionDetection: closestCorners\n }\n};\n\nconst ROOT_NAME = \"Sortable\";\nconst CONTENT_NAME = \"SortableContent\";\nconst ITEM_NAME = \"SortableItem\";\nconst ITEM_HANDLE_NAME = \"SortableItemHandle\";\nconst OVERLAY_NAME = \"SortableOverlay\";\n\ninterface SortableRootContextValue<T> {\n id: string;\n items: UniqueIdentifier[];\n modifiers: DndContextProps[\"modifiers\"];\n strategy: SortableContextProps[\"strategy\"];\n activeId: UniqueIdentifier | null;\n setActiveId: (id: UniqueIdentifier | null) => void;\n getItemValue: (item: T) => UniqueIdentifier;\n flatCursor: boolean;\n}\n\nconst SortableRootContext = React.createContext<SortableRootContextValue<unknown> | null>(null);\n\nfunction useSortableContext(consumerName: string) {\n const context = React.useContext(SortableRootContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${ROOT_NAME}\\``);\n }\n return context;\n}\n\ninterface GetItemValue<T> {\n /**\n * Callback that returns a unique identifier for each sortable item. Required for array of objects.\n * @example getItemValue={(item) => item.id}\n */\n getItemValue: (item: T) => UniqueIdentifier;\n}\n\ntype SortableProps<T> = DndContextProps &\n (T extends object ? GetItemValue<T> : Partial<GetItemValue<T>>) & {\n value: T[];\n onValueChange?: (items: T[]) => void;\n onMove?: (event: DragEndEvent & { activeIndex: number; overIndex: number }) => void;\n strategy?: SortableContextProps[\"strategy\"];\n orientation?: \"vertical\" | \"horizontal\" | \"mixed\";\n flatCursor?: boolean;\n };\n\nfunction Sortable<T>(props: SortableProps<T>) {\n const {\n value,\n onValueChange,\n collisionDetection,\n modifiers,\n strategy,\n onMove,\n orientation = \"vertical\",\n flatCursor = false,\n getItemValue: getItemValueProp,\n accessibility,\n ...sortableProps\n } = props;\n\n const id = React.useId();\n const [activeId, setActiveId] = React.useState<UniqueIdentifier | null>(null);\n\n const sensors = useSensors(\n useSensor(MouseSensor),\n useSensor(TouchSensor),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates\n })\n );\n const config = React.useMemo(() => orientationConfig[orientation], [orientation]);\n\n const getItemValue = React.useCallback(\n (item: T): UniqueIdentifier => {\n if (typeof item === \"object\" && !getItemValueProp) {\n throw new Error(\"`getItemValue` is required when using array of objects\");\n }\n return getItemValueProp ? getItemValueProp(item) : (item as UniqueIdentifier);\n },\n [getItemValueProp]\n );\n\n const items = React.useMemo(() => {\n return value.map((item) => getItemValue(item));\n }, [value, getItemValue]);\n\n const onDragStart = React.useCallback(\n (event: DragStartEvent) => {\n sortableProps.onDragStart?.(event);\n\n if (event.activatorEvent.defaultPrevented) return;\n\n setActiveId(event.active.id);\n },\n [sortableProps.onDragStart]\n );\n\n const onDragEnd = React.useCallback(\n (event: DragEndEvent) => {\n sortableProps.onDragEnd?.(event);\n\n if (event.activatorEvent.defaultPrevented) return;\n\n const { active, over } = event;\n if (over && active.id !== over?.id) {\n const activeIndex = value.findIndex((item) => getItemValue(item) === active.id);\n const overIndex = value.findIndex((item) => getItemValue(item) === over.id);\n\n if (onMove) {\n onMove({ ...event, activeIndex, overIndex });\n } else {\n onValueChange?.(arrayMove(value, activeIndex, overIndex));\n }\n }\n setActiveId(null);\n },\n [value, onValueChange, onMove, getItemValue, sortableProps.onDragEnd]\n );\n\n const onDragCancel = React.useCallback(\n (event: DragEndEvent) => {\n sortableProps.onDragCancel?.(event);\n\n if (event.activatorEvent.defaultPrevented) return;\n\n setActiveId(null);\n },\n [sortableProps.onDragCancel]\n );\n\n const announcements: Announcements = React.useMemo(\n () => ({\n onDragStart({ active }) {\n return `Đã nhấc mục \"${active.id.toString()}\". Vị trí hiện tại ${active.data.current?.sortable.index + 1} / ${value.length}. Dùng phím mũi tên để di chuyển, phím cách để thả.`;\n },\n onDragOver({ active, over }) {\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const moveDirection = overIndex > activeIndex ? \"xuống\" : \"lên\";\n return `Mục \"${active.id.toString()}\" đã chuyển ${moveDirection} vị trí ${overIndex + 1} / ${value.length}.`;\n }\n return \"Mục đang ở ngoài vùng thả. Nhấn Esc để huỷ.\";\n },\n onDragEnd({ active, over }) {\n const activeValue = active.id.toString();\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n return `Đã thả mục \"${activeValue}\" ở vị trí ${overIndex + 1} / ${value.length}.`;\n }\n return `Đã thả mục \"${activeValue}\". Không có thay đổi nào.`;\n },\n onDragCancel({ active }) {\n const activeIndex = active.data.current?.sortable.index ?? 0;\n return `Đã huỷ sắp xếp. Mục \"${active.id.toString()}\" trở về vị trí ${activeIndex + 1} / ${value.length}.`;\n },\n onDragMove({ active, over }) {\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const moveDirection = overIndex > activeIndex ? \"xuống\" : \"lên\";\n return `Mục \"${active.id.toString()}\" đang di chuyển ${moveDirection} vị trí ${overIndex + 1} / ${value.length}.`;\n }\n return \"Mục đang ở ngoài vùng thả. Nhấn Esc để huỷ.\";\n }\n }),\n [value]\n );\n\n const screenReaderInstructions: ScreenReaderInstructions = React.useMemo(\n () => ({\n draggable: `\n Nhấn phím cách hoặc Enter để nhấc mục lên.\n Khi đang giữ, dùng phím mũi tên ${orientation === \"vertical\" ? \"lên/xuống\" : orientation === \"horizontal\" ? \"trái/phải\" : \"\"} để di chuyển.\n Nhấn phím cách hoặc Enter lần nữa để thả vào vị trí mới, hoặc Esc để huỷ.\n `\n }),\n [orientation]\n );\n\n const contextValue = React.useMemo(\n () => ({\n id,\n items,\n modifiers: modifiers ?? config.modifiers,\n strategy: strategy ?? config.strategy,\n activeId,\n setActiveId,\n getItemValue,\n flatCursor\n }),\n [id, items, modifiers, strategy, config.modifiers, config.strategy, activeId, getItemValue, flatCursor]\n );\n\n return (\n <SortableRootContext.Provider value={contextValue as SortableRootContextValue<unknown>}>\n <DndContext\n collisionDetection={collisionDetection ?? config.collisionDetection}\n modifiers={modifiers ?? config.modifiers}\n sensors={sensors}\n {...sortableProps}\n id={id}\n onDragStart={onDragStart}\n onDragEnd={onDragEnd}\n onDragCancel={onDragCancel}\n accessibility={{\n announcements,\n screenReaderInstructions,\n ...accessibility\n }}\n />\n </SortableRootContext.Provider>\n );\n}\n\nconst SortableContentContext = React.createContext<boolean>(false);\n\ninterface SortableContentProps extends React.ComponentProps<\"div\"> {\n strategy?: SortableContextProps[\"strategy\"];\n children: React.ReactNode;\n asChild?: boolean;\n withoutSlot?: boolean;\n}\n\nfunction SortableContent(props: SortableContentProps) {\n const { strategy: strategyProp, asChild, withoutSlot, children, ref, ...contentProps } = props;\n\n const context = useSortableContext(CONTENT_NAME);\n\n const ContentPrimitive = asChild ? Slot : \"div\";\n\n return (\n <SortableContentContext.Provider value={true}>\n <SortableContext items={context.items} strategy={strategyProp ?? context.strategy}>\n {withoutSlot ? (\n children\n ) : (\n <ContentPrimitive data-slot=\"sortable-content\" {...contentProps} ref={ref}>\n {children}\n </ContentPrimitive>\n )}\n </SortableContext>\n </SortableContentContext.Provider>\n );\n}\n\ninterface SortableItemContextValue {\n id: string;\n attributes: DraggableAttributes;\n listeners: DraggableSyntheticListeners | undefined;\n setActivatorNodeRef: (node: HTMLElement | null) => void;\n isDragging?: boolean;\n disabled?: boolean;\n}\n\nconst SortableItemContext = React.createContext<SortableItemContextValue | null>(null);\n\nfunction useSortableItemContext(consumerName: string) {\n const context = React.useContext(SortableItemContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${ITEM_NAME}\\``);\n }\n return context;\n}\n\ninterface SortableItemProps extends React.ComponentProps<\"div\"> {\n value: UniqueIdentifier;\n asHandle?: boolean;\n asChild?: boolean;\n disabled?: boolean;\n}\n\nfunction SortableItem(props: SortableItemProps) {\n const { value, style, asHandle, asChild, disabled, className, ref, ...itemProps } = props;\n\n const inSortableContent = React.useContext(SortableContentContext);\n const inSortableOverlay = React.useContext(SortableOverlayContext);\n\n if (!inSortableContent && !inSortableOverlay) {\n throw new Error(`\\`${ITEM_NAME}\\` must be used within \\`${CONTENT_NAME}\\` or \\`${OVERLAY_NAME}\\``);\n }\n\n if (value === \"\") {\n throw new Error(`\\`${ITEM_NAME}\\` value cannot be an empty string`);\n }\n\n const context = useSortableContext(ITEM_NAME);\n const id = React.useId();\n const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({\n id: value,\n disabled\n });\n\n const composedRef = useComposedRefs(ref, (node) => {\n if (disabled) return;\n setNodeRef(node);\n if (asHandle) setActivatorNodeRef(node);\n });\n\n const composedStyle = React.useMemo<React.CSSProperties>(() => {\n return {\n transform: CSS.Translate.toString(transform),\n transition,\n ...style\n };\n }, [transform, transition, style]);\n\n const itemContext = React.useMemo<SortableItemContextValue>(\n () => ({\n id,\n attributes,\n listeners,\n setActivatorNodeRef,\n isDragging,\n disabled\n }),\n [id, attributes, listeners, setActivatorNodeRef, isDragging, disabled]\n );\n\n const ItemPrimitive = asChild ? Slot : \"div\";\n\n return (\n <SortableItemContext.Provider value={itemContext}>\n <ItemPrimitive\n id={id}\n data-disabled={disabled}\n data-dragging={isDragging ? \"\" : undefined}\n data-slot=\"sortable-item\"\n {...itemProps}\n {...(asHandle && !disabled ? attributes : {})}\n {...(asHandle && !disabled ? listeners : {})}\n ref={composedRef}\n style={composedStyle}\n className={cn(\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1\",\n {\n \"touch-none select-none\": asHandle,\n \"cursor-default\": context.flatCursor,\n \"data-[dragging]:cursor-grabbing\": !context.flatCursor,\n \"cursor-grab\": !isDragging && asHandle && !context.flatCursor,\n \"opacity-50\": isDragging,\n \"pointer-events-none opacity-50\": disabled\n },\n className\n )}\n />\n </SortableItemContext.Provider>\n );\n}\n\ninterface SortableItemHandleProps extends React.ComponentProps<\"button\"> {\n asChild?: boolean;\n}\n\nfunction SortableItemHandle(props: SortableItemHandleProps) {\n const { asChild, disabled, className, ref, ...itemHandleProps } = props;\n\n const context = useSortableContext(ITEM_HANDLE_NAME);\n const itemContext = useSortableItemContext(ITEM_HANDLE_NAME);\n\n const isDisabled = disabled ?? itemContext.disabled;\n\n const composedRef = useComposedRefs(ref, (node) => {\n if (!isDisabled) return;\n itemContext.setActivatorNodeRef(node);\n });\n\n const HandlePrimitive = asChild ? Slot : \"button\";\n\n return (\n <HandlePrimitive\n type=\"button\"\n aria-controls={itemContext.id}\n data-disabled={isDisabled}\n data-dragging={itemContext.isDragging ? \"\" : undefined}\n data-slot=\"sortable-item-handle\"\n {...itemHandleProps}\n {...(isDisabled ? {} : itemContext.attributes)}\n {...(isDisabled ? {} : itemContext.listeners)}\n ref={composedRef}\n className={cn(\n \"select-none disabled:pointer-events-none disabled:opacity-50\",\n context.flatCursor ? \"cursor-default\" : \"cursor-grab data-[dragging]:cursor-grabbing\",\n className\n )}\n disabled={isDisabled}\n />\n );\n}\n\nconst SortableOverlayContext = React.createContext(false);\n\nconst dropAnimation: DropAnimation = {\n sideEffects: defaultDropAnimationSideEffects({\n styles: {\n active: {\n opacity: \"0.4\"\n }\n }\n })\n};\n\ninterface SortableOverlayProps extends Omit<React.ComponentProps<typeof DragOverlay>, \"children\"> {\n container?: Element | DocumentFragment | null;\n children?: ((params: { value: UniqueIdentifier }) => React.ReactNode) | React.ReactNode;\n}\n\nfunction SortableOverlay(props: SortableOverlayProps) {\n const { container: containerProp, children, ...overlayProps } = props;\n\n const context = useSortableContext(OVERLAY_NAME);\n\n const [mounted, setMounted] = React.useState(false);\n\n React.useLayoutEffect(() => setMounted(true), []);\n\n const container = containerProp ?? (mounted ? globalThis.document?.body : null);\n\n if (!container) return null;\n\n return ReactDOM.createPortal(\n <DragOverlay\n dropAnimation={dropAnimation}\n modifiers={context.modifiers}\n className={cn(!context.flatCursor && \"cursor-grabbing\")}\n {...overlayProps}\n >\n <SortableOverlayContext.Provider value={true}>\n {context.activeId ? (typeof children === \"function\" ? children({ value: context.activeId }) : children) : null}\n </SortableOverlayContext.Provider>\n </DragOverlay>,\n container\n );\n}\n\nexport { Sortable, SortableContent, SortableItem, SortableItemHandle, SortableOverlay, type SortableProps };\n"],"mappings":";AA8PM;AA5PN;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EAKA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EAEA;AAAA,EACA;AAAA,OACK;AACP,SAAS,0BAA0B,yBAAyB,8BAA8B;AAC1F;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,WAAW;AACpB,SAAS,YAAY;AACrB,YAAY,WAAW;AACvB,YAAY,cAAc;AAC1B,SAAS,UAAU;AACnB,SAAS,uBAAuB;AAEhC,MAAM,oBAAoB;AAAA,EACxB,UAAU;AAAA,IACR,WAAW,CAAC,wBAAwB,uBAAuB;AAAA,IAC3D,UAAU;AAAA,IACV,oBAAoB;AAAA,EACtB;AAAA,EACA,YAAY;AAAA,IACV,WAAW,CAAC,0BAA0B,uBAAuB;AAAA,IAC7D,UAAU;AAAA,IACV,oBAAoB;AAAA,EACtB;AAAA,EACA,OAAO;AAAA,IACL,WAAW,CAAC,uBAAuB;AAAA,IACnC,UAAU;AAAA,IACV,oBAAoB;AAAA,EACtB;AACF;AAEA,MAAM,YAAY;AAClB,MAAM,eAAe;AACrB,MAAM,YAAY;AAClB,MAAM,mBAAmB;AACzB,MAAM,eAAe;AAarB,MAAM,sBAAsB,MAAM,cAAwD,IAAI;AAE9F,SAAS,mBAAmB,cAAsB;AAChD,QAAM,UAAU,MAAM,WAAW,mBAAmB;AACpD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,KAAK,YAAY,4BAA4B,SAAS,IAAI;AAAA,EAC5E;AACA,SAAO;AACT;AAoBA,SAAS,SAAY,OAAyB;AAC5C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,aAAa;AAAA,IACb,cAAc;AAAA,IACd;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,KAAK,MAAM,MAAM;AACvB,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM,SAAkC,IAAI;AAE5E,QAAM,UAAU;AAAA,IACd,UAAU,WAAW;AAAA,IACrB,UAAU,WAAW;AAAA,IACrB,UAAU,gBAAgB;AAAA,MACxB,kBAAkB;AAAA,IACpB,CAAC;AAAA,EACH;AACA,QAAM,SAAS,MAAM,QAAQ,MAAM,kBAAkB,WAAW,GAAG,CAAC,WAAW,CAAC;AAEhF,QAAM,eAAe,MAAM;AAAA,IACzB,CAAC,SAA8B;AAC7B,UAAI,OAAO,SAAS,YAAY,CAAC,kBAAkB;AACjD,cAAM,IAAI,MAAM,wDAAwD;AAAA,MAC1E;AACA,aAAO,mBAAmB,iBAAiB,IAAI,IAAK;AAAA,IACtD;AAAA,IACA,CAAC,gBAAgB;AAAA,EACnB;AAEA,QAAM,QAAQ,MAAM,QAAQ,MAAM;AAChC,WAAO,MAAM,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC;AAAA,EAC/C,GAAG,CAAC,OAAO,YAAY,CAAC;AAExB,QAAM,cAAc,MAAM;AAAA,IACxB,CAAC,UAA0B;AACzB,oBAAc,cAAc,KAAK;AAEjC,UAAI,MAAM,eAAe,iBAAkB;AAE3C,kBAAY,MAAM,OAAO,EAAE;AAAA,IAC7B;AAAA,IACA,CAAC,cAAc,WAAW;AAAA,EAC5B;AAEA,QAAM,YAAY,MAAM;AAAA,IACtB,CAAC,UAAwB;AACvB,oBAAc,YAAY,KAAK;AAE/B,UAAI,MAAM,eAAe,iBAAkB;AAE3C,YAAM,EAAE,QAAQ,KAAK,IAAI;AACzB,UAAI,QAAQ,OAAO,OAAO,MAAM,IAAI;AAClC,cAAM,cAAc,MAAM,UAAU,CAAC,SAAS,aAAa,IAAI,MAAM,OAAO,EAAE;AAC9E,cAAM,YAAY,MAAM,UAAU,CAAC,SAAS,aAAa,IAAI,MAAM,KAAK,EAAE;AAE1E,YAAI,QAAQ;AACV,iBAAO,EAAE,GAAG,OAAO,aAAa,UAAU,CAAC;AAAA,QAC7C,OAAO;AACL,0BAAgB,UAAU,OAAO,aAAa,SAAS,CAAC;AAAA,QAC1D;AAAA,MACF;AACA,kBAAY,IAAI;AAAA,IAClB;AAAA,IACA,CAAC,OAAO,eAAe,QAAQ,cAAc,cAAc,SAAS;AAAA,EACtE;AAEA,QAAM,eAAe,MAAM;AAAA,IACzB,CAAC,UAAwB;AACvB,oBAAc,eAAe,KAAK;AAElC,UAAI,MAAM,eAAe,iBAAkB;AAE3C,kBAAY,IAAI;AAAA,IAClB;AAAA,IACA,CAAC,cAAc,YAAY;AAAA,EAC7B;AAEA,QAAM,gBAA+B,MAAM;AAAA,IACzC,OAAO;AAAA,MACL,YAAY,EAAE,OAAO,GAAG;AACtB,eAAO,kCAAgB,OAAO,GAAG,SAAS,CAAC,wCAAsB,OAAO,KAAK,SAAS,SAAS,QAAQ,CAAC,MAAM,MAAM,MAAM;AAAA,MAC5H;AAAA,MACA,WAAW,EAAE,QAAQ,KAAK,GAAG;AAC3B,YAAI,MAAM;AACR,gBAAM,YAAY,KAAK,KAAK,SAAS,SAAS,SAAS;AACvD,gBAAM,cAAc,OAAO,KAAK,SAAS,SAAS,SAAS;AAC3D,gBAAM,gBAAgB,YAAY,cAAc,eAAU;AAC1D,iBAAO,aAAQ,OAAO,GAAG,SAAS,CAAC,4BAAe,aAAa,mBAAW,YAAY,CAAC,MAAM,MAAM,MAAM;AAAA,QAC3G;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,EAAE,QAAQ,KAAK,GAAG;AAC1B,cAAM,cAAc,OAAO,GAAG,SAAS;AACvC,YAAI,MAAM;AACR,gBAAM,YAAY,KAAK,KAAK,SAAS,SAAS,SAAS;AACvD,iBAAO,iCAAe,WAAW,2BAAc,YAAY,CAAC,MAAM,MAAM,MAAM;AAAA,QAChF;AACA,eAAO,iCAAe,WAAW;AAAA,MACnC;AAAA,MACA,aAAa,EAAE,OAAO,GAAG;AACvB,cAAM,cAAc,OAAO,KAAK,SAAS,SAAS,SAAS;AAC3D,eAAO,oDAAwB,OAAO,GAAG,SAAS,CAAC,qCAAmB,cAAc,CAAC,MAAM,MAAM,MAAM;AAAA,MACzG;AAAA,MACA,WAAW,EAAE,QAAQ,KAAK,GAAG;AAC3B,YAAI,MAAM;AACR,gBAAM,YAAY,KAAK,KAAK,SAAS,SAAS,SAAS;AACvD,gBAAM,cAAc,OAAO,KAAK,SAAS,SAAS,SAAS;AAC3D,gBAAM,gBAAgB,YAAY,cAAc,eAAU;AAC1D,iBAAO,aAAQ,OAAO,GAAG,SAAS,CAAC,8BAAoB,aAAa,mBAAW,YAAY,CAAC,MAAM,MAAM,MAAM;AAAA,QAChH;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,CAAC,KAAK;AAAA,EACR;AAEA,QAAM,2BAAqD,MAAM;AAAA,IAC/D,OAAO;AAAA,MACL,WAAW;AAAA;AAAA,kEAEyB,gBAAgB,aAAa,sBAAc,gBAAgB,eAAe,sBAAc,EAAE;AAAA;AAAA;AAAA,IAGhI;AAAA,IACA,CAAC,WAAW;AAAA,EACd;AAEA,QAAM,eAAe,MAAM;AAAA,IACzB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,WAAW,aAAa,OAAO;AAAA,MAC/B,UAAU,YAAY,OAAO;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,IAAI,OAAO,WAAW,UAAU,OAAO,WAAW,OAAO,UAAU,UAAU,cAAc,UAAU;AAAA,EACxG;AAEA,SACE,oBAAC,oBAAoB,UAApB,EAA6B,OAAO,cACnC;AAAA,IAAC;AAAA;AAAA,MACC,oBAAoB,sBAAsB,OAAO;AAAA,MACjD,WAAW,aAAa,OAAO;AAAA,MAC/B;AAAA,MACC,GAAG;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe;AAAA,QACb;AAAA,QACA;AAAA,QACA,GAAG;AAAA,MACL;AAAA;AAAA,EACF,GACF;AAEJ;AAEA,MAAM,yBAAyB,MAAM,cAAuB,KAAK;AASjE,SAAS,gBAAgB,OAA6B;AACpD,QAAM,EAAE,UAAU,cAAc,SAAS,aAAa,UAAU,KAAK,GAAG,aAAa,IAAI;AAEzF,QAAM,UAAU,mBAAmB,YAAY;AAE/C,QAAM,mBAAmB,UAAU,OAAO;AAE1C,SACE,oBAAC,uBAAuB,UAAvB,EAAgC,OAAO,MACtC,8BAAC,mBAAgB,OAAO,QAAQ,OAAO,UAAU,gBAAgB,QAAQ,UACtE,wBACC,WAEA,oBAAC,oBAAiB,aAAU,oBAAoB,GAAG,cAAc,KAC9D,UACH,GAEJ,GACF;AAEJ;AAWA,MAAM,sBAAsB,MAAM,cAA+C,IAAI;AAErF,SAAS,uBAAuB,cAAsB;AACpD,QAAM,UAAU,MAAM,WAAW,mBAAmB;AACpD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,KAAK,YAAY,4BAA4B,SAAS,IAAI;AAAA,EAC5E;AACA,SAAO;AACT;AASA,SAAS,aAAa,OAA0B;AAC9C,QAAM,EAAE,OAAO,OAAO,UAAU,SAAS,UAAU,WAAW,KAAK,GAAG,UAAU,IAAI;AAEpF,QAAM,oBAAoB,MAAM,WAAW,sBAAsB;AACjE,QAAM,oBAAoB,MAAM,WAAW,sBAAsB;AAEjE,MAAI,CAAC,qBAAqB,CAAC,mBAAmB;AAC5C,UAAM,IAAI,MAAM,KAAK,SAAS,4BAA4B,YAAY,WAAW,YAAY,IAAI;AAAA,EACnG;AAEA,MAAI,UAAU,IAAI;AAChB,UAAM,IAAI,MAAM,KAAK,SAAS,oCAAoC;AAAA,EACpE;AAEA,QAAM,UAAU,mBAAmB,SAAS;AAC5C,QAAM,KAAK,MAAM,MAAM;AACvB,QAAM,EAAE,YAAY,WAAW,YAAY,qBAAqB,WAAW,YAAY,WAAW,IAAI,YAAY;AAAA,IAChH,IAAI;AAAA,IACJ;AAAA,EACF,CAAC;AAED,QAAM,cAAc,gBAAgB,KAAK,CAAC,SAAS;AACjD,QAAI,SAAU;AACd,eAAW,IAAI;AACf,QAAI,SAAU,qBAAoB,IAAI;AAAA,EACxC,CAAC;AAED,QAAM,gBAAgB,MAAM,QAA6B,MAAM;AAC7D,WAAO;AAAA,MACL,WAAW,IAAI,UAAU,SAAS,SAAS;AAAA,MAC3C;AAAA,MACA,GAAG;AAAA,IACL;AAAA,EACF,GAAG,CAAC,WAAW,YAAY,KAAK,CAAC;AAEjC,QAAM,cAAc,MAAM;AAAA,IACxB,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,IAAI,YAAY,WAAW,qBAAqB,YAAY,QAAQ;AAAA,EACvE;AAEA,QAAM,gBAAgB,UAAU,OAAO;AAEvC,SACE,oBAAC,oBAAoB,UAApB,EAA6B,OAAO,aACnC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,iBAAe;AAAA,MACf,iBAAe,aAAa,KAAK;AAAA,MACjC,aAAU;AAAA,MACT,GAAG;AAAA,MACH,GAAI,YAAY,CAAC,WAAW,aAAa,CAAC;AAAA,MAC1C,GAAI,YAAY,CAAC,WAAW,YAAY,CAAC;AAAA,MAC1C,KAAK;AAAA,MACL,OAAO;AAAA,MACP,WAAW;AAAA,QACT;AAAA,QACA;AAAA,UACE,0BAA0B;AAAA,UAC1B,kBAAkB,QAAQ;AAAA,UAC1B,mCAAmC,CAAC,QAAQ;AAAA,UAC5C,eAAe,CAAC,cAAc,YAAY,CAAC,QAAQ;AAAA,UACnD,cAAc;AAAA,UACd,kCAAkC;AAAA,QACpC;AAAA,QACA;AAAA,MACF;AAAA;AAAA,EACF,GACF;AAEJ;AAMA,SAAS,mBAAmB,OAAgC;AAC1D,QAAM,EAAE,SAAS,UAAU,WAAW,KAAK,GAAG,gBAAgB,IAAI;AAElE,QAAM,UAAU,mBAAmB,gBAAgB;AACnD,QAAM,cAAc,uBAAuB,gBAAgB;AAE3D,QAAM,aAAa,YAAY,YAAY;AAE3C,QAAM,cAAc,gBAAgB,KAAK,CAAC,SAAS;AACjD,QAAI,CAAC,WAAY;AACjB,gBAAY,oBAAoB,IAAI;AAAA,EACtC,CAAC;AAED,QAAM,kBAAkB,UAAU,OAAO;AAEzC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,iBAAe,YAAY;AAAA,MAC3B,iBAAe;AAAA,MACf,iBAAe,YAAY,aAAa,KAAK;AAAA,MAC7C,aAAU;AAAA,MACT,GAAG;AAAA,MACH,GAAI,aAAa,CAAC,IAAI,YAAY;AAAA,MAClC,GAAI,aAAa,CAAC,IAAI,YAAY;AAAA,MACnC,KAAK;AAAA,MACL,WAAW;AAAA,QACT;AAAA,QACA,QAAQ,aAAa,mBAAmB;AAAA,QACxC;AAAA,MACF;AAAA,MACA,UAAU;AAAA;AAAA,EACZ;AAEJ;AAEA,MAAM,yBAAyB,MAAM,cAAc,KAAK;AAExD,MAAM,gBAA+B;AAAA,EACnC,aAAa,gCAAgC;AAAA,IAC3C,QAAQ;AAAA,MACN,QAAQ;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAOA,SAAS,gBAAgB,OAA6B;AACpD,QAAM,EAAE,WAAW,eAAe,UAAU,GAAG,aAAa,IAAI;AAEhE,QAAM,UAAU,mBAAmB,YAAY;AAE/C,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAS,KAAK;AAElD,QAAM,gBAAgB,MAAM,WAAW,IAAI,GAAG,CAAC,CAAC;AAEhD,QAAM,YAAY,kBAAkB,UAAU,WAAW,UAAU,OAAO;AAE1E,MAAI,CAAC,UAAW,QAAO;AAEvB,SAAO,SAAS;AAAA,IACd;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,QAAQ;AAAA,QACnB,WAAW,GAAG,CAAC,QAAQ,cAAc,iBAAiB;AAAA,QACrD,GAAG;AAAA,QAEJ,8BAAC,uBAAuB,UAAvB,EAAgC,OAAO,MACrC,kBAAQ,WAAY,OAAO,aAAa,aAAa,SAAS,EAAE,OAAO,QAAQ,SAAS,CAAC,IAAI,WAAY,MAC5G;AAAA;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/data-grid/sortable.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type Announcements,\n closestCenter,\n closestCorners,\n DndContext,\n type DndContextProps,\n type DragEndEvent,\n type DraggableAttributes,\n type DraggableSyntheticListeners,\n DragOverlay,\n type DragStartEvent,\n type DropAnimation,\n defaultDropAnimationSideEffects,\n KeyboardSensor,\n MouseSensor,\n type ScreenReaderInstructions,\n TouchSensor,\n type UniqueIdentifier,\n useSensor,\n useSensors\n} from \"@dnd-kit/core\";\nimport { restrictToHorizontalAxis, restrictToParentElement, restrictToVerticalAxis } from \"@dnd-kit/modifiers\";\nimport {\n arrayMove,\n horizontalListSortingStrategy,\n SortableContext,\n type SortableContextProps,\n sortableKeyboardCoordinates,\n useSortable,\n verticalListSortingStrategy\n} from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport { cn } from \"../lib/cn.js\";\nimport { useComposedRefs } from \"../lib/compose-refs.js\";\nimport { useDataGridMessages } from \"./data-grid-locale.js\";\n\nconst orientationConfig = {\n vertical: {\n modifiers: [restrictToVerticalAxis, restrictToParentElement],\n strategy: verticalListSortingStrategy,\n collisionDetection: closestCenter\n },\n horizontal: {\n modifiers: [restrictToHorizontalAxis, restrictToParentElement],\n strategy: horizontalListSortingStrategy,\n collisionDetection: closestCenter\n },\n mixed: {\n modifiers: [restrictToParentElement],\n strategy: undefined,\n collisionDetection: closestCorners\n }\n};\n\nconst ROOT_NAME = \"Sortable\";\nconst CONTENT_NAME = \"SortableContent\";\nconst ITEM_NAME = \"SortableItem\";\nconst ITEM_HANDLE_NAME = \"SortableItemHandle\";\nconst OVERLAY_NAME = \"SortableOverlay\";\n\ninterface SortableRootContextValue<T> {\n id: string;\n items: UniqueIdentifier[];\n modifiers: DndContextProps[\"modifiers\"];\n strategy: SortableContextProps[\"strategy\"];\n activeId: UniqueIdentifier | null;\n setActiveId: (id: UniqueIdentifier | null) => void;\n getItemValue: (item: T) => UniqueIdentifier;\n flatCursor: boolean;\n}\n\nconst SortableRootContext = React.createContext<SortableRootContextValue<unknown> | null>(null);\n\nfunction useSortableContext(consumerName: string) {\n const context = React.useContext(SortableRootContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${ROOT_NAME}\\``);\n }\n return context;\n}\n\ninterface GetItemValue<T> {\n /**\n * Callback that returns a unique identifier for each sortable item. Required for array of objects.\n * @example getItemValue={(item) => item.id}\n */\n getItemValue: (item: T) => UniqueIdentifier;\n}\n\ntype SortableProps<T> = DndContextProps &\n (T extends object ? GetItemValue<T> : Partial<GetItemValue<T>>) & {\n value: T[];\n onValueChange?: (items: T[]) => void;\n onMove?: (event: DragEndEvent & { activeIndex: number; overIndex: number }) => void;\n strategy?: SortableContextProps[\"strategy\"];\n orientation?: \"vertical\" | \"horizontal\" | \"mixed\";\n flatCursor?: boolean;\n };\n\nfunction Sortable<T>(props: SortableProps<T>) {\n const {\n value,\n onValueChange,\n collisionDetection,\n modifiers,\n strategy,\n onMove,\n orientation = \"vertical\",\n flatCursor = false,\n getItemValue: getItemValueProp,\n accessibility,\n ...sortableProps\n } = props;\n\n const id = React.useId();\n const [activeId, setActiveId] = React.useState<UniqueIdentifier | null>(null);\n\n const sensors = useSensors(\n useSensor(MouseSensor),\n useSensor(TouchSensor),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates\n })\n );\n const config = React.useMemo(() => orientationConfig[orientation], [orientation]);\n\n const getItemValue = React.useCallback(\n (item: T): UniqueIdentifier => {\n if (typeof item === \"object\" && !getItemValueProp) {\n throw new Error(\"`getItemValue` is required when using array of objects\");\n }\n return getItemValueProp ? getItemValueProp(item) : (item as UniqueIdentifier);\n },\n [getItemValueProp]\n );\n\n const items = React.useMemo(() => {\n return value.map((item) => getItemValue(item));\n }, [value, getItemValue]);\n\n const onDragStart = React.useCallback(\n (event: DragStartEvent) => {\n sortableProps.onDragStart?.(event);\n\n if (event.activatorEvent.defaultPrevented) return;\n\n setActiveId(event.active.id);\n },\n [sortableProps.onDragStart]\n );\n\n const onDragEnd = React.useCallback(\n (event: DragEndEvent) => {\n sortableProps.onDragEnd?.(event);\n\n if (event.activatorEvent.defaultPrevented) return;\n\n const { active, over } = event;\n if (over && active.id !== over?.id) {\n const activeIndex = value.findIndex((item) => getItemValue(item) === active.id);\n const overIndex = value.findIndex((item) => getItemValue(item) === over.id);\n\n if (onMove) {\n onMove({ ...event, activeIndex, overIndex });\n } else {\n onValueChange?.(arrayMove(value, activeIndex, overIndex));\n }\n }\n setActiveId(null);\n },\n [value, onValueChange, onMove, getItemValue, sortableProps.onDragEnd]\n );\n\n const onDragCancel = React.useCallback(\n (event: DragEndEvent) => {\n sortableProps.onDragCancel?.(event);\n\n if (event.activatorEvent.defaultPrevented) return;\n\n setActiveId(null);\n },\n [sortableProps.onDragCancel]\n );\n\n // Lời đọc cho trình đọc màn hình lấy từ bảng chuỗi của lưới: `Sortable` chỉ được dùng bên\n // trong `DataGridFilterMenu` / `DataGridSortMenu`, cả hai đều bọc `DataGridLocaleProvider`.\n const msg = useDataGridMessages().sortable;\n\n const announcements: Announcements = React.useMemo(\n () => ({\n onDragStart({ active }) {\n const activeIndex = active.data.current?.sortable.index ?? 0;\n return msg.dragStart(active.id.toString(), activeIndex + 1, value.length);\n },\n onDragOver({ active, over }) {\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const moveDirection = overIndex > activeIndex ? \"down\" : \"up\";\n return msg.dragOver(active.id.toString(), moveDirection, overIndex + 1, value.length);\n }\n return msg.outside;\n },\n onDragEnd({ active, over }) {\n const activeValue = active.id.toString();\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n return msg.dragEnd(activeValue, overIndex + 1, value.length);\n }\n return msg.dragEndNoChange(activeValue);\n },\n onDragCancel({ active }) {\n const activeIndex = active.data.current?.sortable.index ?? 0;\n return msg.dragCancel(active.id.toString(), activeIndex + 1, value.length);\n },\n onDragMove({ active, over }) {\n if (over) {\n const overIndex = over.data.current?.sortable.index ?? 0;\n const activeIndex = active.data.current?.sortable.index ?? 0;\n const moveDirection = overIndex > activeIndex ? \"down\" : \"up\";\n return msg.dragMove(active.id.toString(), moveDirection, overIndex + 1, value.length);\n }\n return msg.outside;\n }\n }),\n [value, msg]\n );\n\n const screenReaderInstructions: ScreenReaderInstructions = React.useMemo(\n () => ({ draggable: msg.instructions(orientation) }),\n [orientation, msg]\n );\n\n const contextValue = React.useMemo(\n () => ({\n id,\n items,\n modifiers: modifiers ?? config.modifiers,\n strategy: strategy ?? config.strategy,\n activeId,\n setActiveId,\n getItemValue,\n flatCursor\n }),\n [id, items, modifiers, strategy, config.modifiers, config.strategy, activeId, getItemValue, flatCursor]\n );\n\n return (\n <SortableRootContext.Provider value={contextValue as SortableRootContextValue<unknown>}>\n <DndContext\n collisionDetection={collisionDetection ?? config.collisionDetection}\n modifiers={modifiers ?? config.modifiers}\n sensors={sensors}\n {...sortableProps}\n id={id}\n onDragStart={onDragStart}\n onDragEnd={onDragEnd}\n onDragCancel={onDragCancel}\n accessibility={{\n announcements,\n screenReaderInstructions,\n ...accessibility\n }}\n />\n </SortableRootContext.Provider>\n );\n}\n\nconst SortableContentContext = React.createContext<boolean>(false);\n\ninterface SortableContentProps extends React.ComponentProps<\"div\"> {\n strategy?: SortableContextProps[\"strategy\"];\n children: React.ReactNode;\n asChild?: boolean;\n withoutSlot?: boolean;\n}\n\nfunction SortableContent(props: SortableContentProps) {\n const { strategy: strategyProp, asChild, withoutSlot, children, ref, ...contentProps } = props;\n\n const context = useSortableContext(CONTENT_NAME);\n\n const ContentPrimitive = asChild ? Slot : \"div\";\n\n return (\n <SortableContentContext.Provider value={true}>\n <SortableContext items={context.items} strategy={strategyProp ?? context.strategy}>\n {withoutSlot ? (\n children\n ) : (\n <ContentPrimitive data-slot=\"sortable-content\" {...contentProps} ref={ref}>\n {children}\n </ContentPrimitive>\n )}\n </SortableContext>\n </SortableContentContext.Provider>\n );\n}\n\ninterface SortableItemContextValue {\n id: string;\n attributes: DraggableAttributes;\n listeners: DraggableSyntheticListeners | undefined;\n setActivatorNodeRef: (node: HTMLElement | null) => void;\n isDragging?: boolean;\n disabled?: boolean;\n}\n\nconst SortableItemContext = React.createContext<SortableItemContextValue | null>(null);\n\nfunction useSortableItemContext(consumerName: string) {\n const context = React.useContext(SortableItemContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${ITEM_NAME}\\``);\n }\n return context;\n}\n\ninterface SortableItemProps extends React.ComponentProps<\"div\"> {\n value: UniqueIdentifier;\n asHandle?: boolean;\n asChild?: boolean;\n disabled?: boolean;\n}\n\nfunction SortableItem(props: SortableItemProps) {\n const { value, style, asHandle, asChild, disabled, className, ref, ...itemProps } = props;\n\n const inSortableContent = React.useContext(SortableContentContext);\n const inSortableOverlay = React.useContext(SortableOverlayContext);\n\n if (!inSortableContent && !inSortableOverlay) {\n throw new Error(`\\`${ITEM_NAME}\\` must be used within \\`${CONTENT_NAME}\\` or \\`${OVERLAY_NAME}\\``);\n }\n\n if (value === \"\") {\n throw new Error(`\\`${ITEM_NAME}\\` value cannot be an empty string`);\n }\n\n const context = useSortableContext(ITEM_NAME);\n const id = React.useId();\n const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({\n id: value,\n disabled\n });\n\n const composedRef = useComposedRefs(ref, (node) => {\n if (disabled) return;\n setNodeRef(node);\n if (asHandle) setActivatorNodeRef(node);\n });\n\n const composedStyle = React.useMemo<React.CSSProperties>(() => {\n return {\n transform: CSS.Translate.toString(transform),\n transition,\n ...style\n };\n }, [transform, transition, style]);\n\n const itemContext = React.useMemo<SortableItemContextValue>(\n () => ({\n id,\n attributes,\n listeners,\n setActivatorNodeRef,\n isDragging,\n disabled\n }),\n [id, attributes, listeners, setActivatorNodeRef, isDragging, disabled]\n );\n\n const ItemPrimitive = asChild ? Slot : \"div\";\n\n return (\n <SortableItemContext.Provider value={itemContext}>\n <ItemPrimitive\n id={id}\n data-disabled={disabled}\n data-dragging={isDragging ? \"\" : undefined}\n data-slot=\"sortable-item\"\n {...itemProps}\n {...(asHandle && !disabled ? attributes : {})}\n {...(asHandle && !disabled ? listeners : {})}\n ref={composedRef}\n style={composedStyle}\n className={cn(\n \"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1\",\n {\n \"touch-none select-none\": asHandle,\n \"cursor-default\": context.flatCursor,\n \"data-[dragging]:cursor-grabbing\": !context.flatCursor,\n \"cursor-grab\": !isDragging && asHandle && !context.flatCursor,\n \"opacity-50\": isDragging,\n \"pointer-events-none opacity-50\": disabled\n },\n className\n )}\n />\n </SortableItemContext.Provider>\n );\n}\n\ninterface SortableItemHandleProps extends React.ComponentProps<\"button\"> {\n asChild?: boolean;\n}\n\nfunction SortableItemHandle(props: SortableItemHandleProps) {\n const { asChild, disabled, className, ref, ...itemHandleProps } = props;\n\n const context = useSortableContext(ITEM_HANDLE_NAME);\n const itemContext = useSortableItemContext(ITEM_HANDLE_NAME);\n\n const isDisabled = disabled ?? itemContext.disabled;\n\n const composedRef = useComposedRefs(ref, (node) => {\n if (!isDisabled) return;\n itemContext.setActivatorNodeRef(node);\n });\n\n const HandlePrimitive = asChild ? Slot : \"button\";\n\n return (\n <HandlePrimitive\n type=\"button\"\n aria-controls={itemContext.id}\n data-disabled={isDisabled}\n data-dragging={itemContext.isDragging ? \"\" : undefined}\n data-slot=\"sortable-item-handle\"\n {...itemHandleProps}\n {...(isDisabled ? {} : itemContext.attributes)}\n {...(isDisabled ? {} : itemContext.listeners)}\n ref={composedRef}\n className={cn(\n \"select-none disabled:pointer-events-none disabled:opacity-50\",\n context.flatCursor ? \"cursor-default\" : \"cursor-grab data-[dragging]:cursor-grabbing\",\n className\n )}\n disabled={isDisabled}\n />\n );\n}\n\nconst SortableOverlayContext = React.createContext(false);\n\nconst dropAnimation: DropAnimation = {\n sideEffects: defaultDropAnimationSideEffects({\n styles: {\n active: {\n opacity: \"0.4\"\n }\n }\n })\n};\n\ninterface SortableOverlayProps extends Omit<React.ComponentProps<typeof DragOverlay>, \"children\"> {\n container?: Element | DocumentFragment | null;\n children?: ((params: { value: UniqueIdentifier }) => React.ReactNode) | React.ReactNode;\n}\n\nfunction SortableOverlay(props: SortableOverlayProps) {\n const { container: containerProp, children, ...overlayProps } = props;\n\n const context = useSortableContext(OVERLAY_NAME);\n\n const [mounted, setMounted] = React.useState(false);\n\n React.useLayoutEffect(() => setMounted(true), []);\n\n const container = containerProp ?? (mounted ? globalThis.document?.body : null);\n\n if (!container) return null;\n\n return ReactDOM.createPortal(\n <DragOverlay\n dropAnimation={dropAnimation}\n modifiers={context.modifiers}\n className={cn(!context.flatCursor && \"cursor-grabbing\")}\n {...overlayProps}\n >\n <SortableOverlayContext.Provider value={true}>\n {context.activeId ? (typeof children === \"function\" ? children({ value: context.activeId }) : children) : null}\n </SortableOverlayContext.Provider>\n </DragOverlay>,\n container\n );\n}\n\nexport { Sortable, SortableContent, SortableItem, SortableItemHandle, SortableOverlay, type SortableProps };\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import { RowData, Cell, TableMeta } from '@tanstack/react-table';
2
2
 
3
- /** Hướng đọc của lưới (mặc định "ltr" — tiếng Việt) */
3
+ /** Hướng đọc của lưới (mặc định "ltr") */
4
4
  type Direction = "ltr" | "rtl";
5
5
  /** Chiều cao dòng: short 36px, medium 56px, tall 76px, extra-tall 96px */
6
6
  type RowHeightValue = "short" | "medium" | "tall" | "extra-tall";
@@ -22,11 +22,12 @@ interface UseDataGridUndoRedoProps<TData> {
22
22
  maxHistory?: number;
23
23
  enabled?: boolean;
24
24
  /**
25
- * Ngôn ngữ của toast mà hook bắn ra (`"en"` mặc định · `"vi"`, hoặc cả bảng chuỗi tự soạn).
25
+ * Ngôn ngữ của toast mà hook bắn ra (`"en"` · `"vi"`, hoặc cả bảng chuỗi tự soạn).
26
26
  *
27
- * Hook giữ bảng chuỗi của RIÊNG nó chứ không đọc `DataGridLocaleProvider`: toast render ở gốc
28
- * app qua `<Toaster />`, ngoài hẳn cây DOM của lưới, nên không có context nào để đọc. Truyền
29
- * cùng giá trị đã truyền cho `useDataGrid`.
27
+ * Toast render ở gốc app qua `<Toaster />`, ngoài hẳn cây của lưới, nên hook giải ngôn ngữ LÚC
28
+ * ĐƯỢC GỌI, từ context của component đang gọi: `locale` → `DataGridLocaleProvider` bọc NGOÀI
29
+ * component đó → `ComitorLocaleProvider` → `"en"`. ⚠ Provider đặt trong chính component gọi
30
+ * hook (hoặc sâu hơn) không với tới đây — khi ấy truyền cùng giá trị đã truyền cho `useDataGrid`.
30
31
  */
31
32
  locale?: DataGridLocale | DataGridMessages;
32
33
  }
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  import * as React from "react";
3
- import { getDataGridMessages } from "./messages.js";
3
+ import { useAsRef } from "../lib/use-as-ref.js";
4
+ import { useLazyRef } from "../lib/use-lazy-ref.js";
5
+ import { useResolvedDataGridMessages } from "./data-grid-locale.js";
4
6
  import { toastInfo, toastSuccess } from "./toast.js";
5
- import { useAsRef } from "./use-as-ref.js";
6
- import { useLazyRef } from "./use-lazy-ref.js";
7
7
  import { getIsInPopover } from "./utils.js";
8
8
  const DEFAULT_MAX_HISTORY = 100;
9
9
  const BATCH_TIMEOUT = 300;
@@ -32,7 +32,7 @@ function useDataGridUndoRedo({
32
32
  enabled = true,
33
33
  locale
34
34
  }) {
35
- const msg = React.useMemo(() => getDataGridMessages(locale), [locale]);
35
+ const msg = useResolvedDataGridMessages(locale);
36
36
  const msgRef = useAsRef(msg);
37
37
  const propsRef = useAsRef({
38
38
  data,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data-grid/use-data-grid-undo-redo.ts"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nimport { type DataGridLocale, type DataGridMessages, getDataGridMessages } from \"./messages.js\";\nimport { toastInfo, toastSuccess } from \"./toast.js\";\nimport { useAsRef } from \"./use-as-ref.js\";\nimport { useLazyRef } from \"./use-lazy-ref.js\";\nimport { getIsInPopover } from \"./utils.js\";\n\nconst DEFAULT_MAX_HISTORY = 100;\nconst BATCH_TIMEOUT = 300;\n\ninterface HistoryEntry<TData> {\n variant: \"cells_update\" | \"rows_add\" | \"rows_delete\";\n count: number;\n timestamp: number;\n undo: (currentData: TData[]) => TData[];\n redo: (currentData: TData[]) => TData[];\n}\n\ninterface UndoRedoCellUpdate {\n rowId: string;\n columnId: string;\n previousValue: unknown;\n newValue: unknown;\n}\n\ninterface StoreState<TData> {\n undoStack: HistoryEntry<TData>[];\n redoStack: HistoryEntry<TData>[];\n hasPendingChanges: boolean;\n}\n\ninterface Store<TData> {\n subscribe: (callback: () => void) => () => void;\n getState: () => StoreState<TData>;\n push: (entry: HistoryEntry<TData>) => void;\n undo: () => HistoryEntry<TData> | null;\n redo: () => HistoryEntry<TData> | null;\n clear: () => void;\n setPendingChanges: (value: boolean) => void;\n notify: () => void;\n}\n\nfunction useStore<T>(store: Store<T>, selector: (state: StoreState<T>) => boolean): boolean {\n const getSnapshot = React.useCallback(() => selector(store.getState()), [store, selector]);\n\n return React.useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);\n}\n\nfunction buildIndexById<TData>(data: TData[], getRowId: (row: TData) => string): Map<string, number> {\n const map = new Map<string, number>();\n for (let i = 0; i < data.length; i++) {\n const row = data[i];\n if (row) {\n map.set(getRowId(row), i);\n }\n }\n return map;\n}\n\nfunction getPendingKey(rowId: string, columnId: string): string {\n return `${rowId}\\0${columnId}`;\n}\n\n/**\n * Tuỳ chọn của {@link useDataGridUndoRedo}. Lịch sử nằm hoàn toàn ở phía trình duyệt:\n * hook tính ra mảng dữ liệu trước/sau rồi trả về qua `onDataChange` — ứng dụng tự\n * đồng bộ lên máy chủ (hoặc bỏ qua nếu chỉ làm việc với state cục bộ).\n */\ninterface UseDataGridUndoRedoProps<TData> {\n data: TData[];\n onDataChange: (data: TData[]) => void;\n /** Khoá định danh bản ghi — phải khớp với `getRowId` của lưới */\n getRowId: (row: TData) => string;\n /** Số thao tác giữ trong lịch sử (mặc định 100) */\n maxHistory?: number;\n enabled?: boolean;\n /**\n * Ngôn ngữ của toast mà hook bắn ra (`\"en\"` mặc định · `\"vi\"`, hoặc cả bảng chuỗi tự soạn).\n *\n * Hook giữ bảng chuỗi của RIÊNG nó chứ không đọc `DataGridLocaleProvider`: toast render ở gốc\n * app qua `<Toaster />`, ngoài hẳn cây DOM của lưới, nên không có context nào để đọc. Truyền\n * cùng giá trị đã truyền cho `useDataGrid`.\n */\n locale?: DataGridLocale | DataGridMessages;\n}\n\ninterface UseDataGridUndoRedoReturn<TData> {\n canUndo: boolean;\n canRedo: boolean;\n onUndo: () => void;\n onRedo: () => void;\n onClear: () => void;\n trackCellsUpdate: (updates: UndoRedoCellUpdate[]) => void;\n trackRowsAdd: (rows: TData[]) => void;\n trackRowsDelete: (rows: TData[]) => void;\n}\n\nfunction useDataGridUndoRedo<TData>({\n data,\n onDataChange,\n getRowId,\n maxHistory = DEFAULT_MAX_HISTORY,\n enabled = true,\n locale\n}: UseDataGridUndoRedoProps<TData>): UseDataGridUndoRedoReturn<TData> {\n const msg = React.useMemo(() => getDataGridMessages(locale), [locale]);\n const msgRef = useAsRef(msg);\n const propsRef = useAsRef({\n data,\n onDataChange,\n getRowId,\n maxHistory,\n enabled\n });\n\n const listenersRef = useLazyRef(() => new Set<() => void>());\n\n const stateRef = useLazyRef<StoreState<TData>>(() => ({\n undoStack: [],\n redoStack: [],\n hasPendingChanges: false\n }));\n\n const pendingBatchRef = React.useRef<{\n byKey: Map<string, UndoRedoCellUpdate>;\n timeoutId: ReturnType<typeof setTimeout> | null;\n }>({\n byKey: new Map(),\n timeoutId: null\n });\n\n const pendingNotifyRef = React.useRef(false);\n\n const store = React.useMemo<Store<TData>>(() => {\n return {\n subscribe: (callback) => {\n listenersRef.current.add(callback);\n return () => listenersRef.current.delete(callback);\n },\n getState: () => stateRef.current,\n push: (entry) => {\n const state = stateRef.current;\n const newUndoStack = [...state.undoStack, entry];\n\n if (newUndoStack.length > propsRef.current.maxHistory) {\n newUndoStack.shift();\n }\n\n stateRef.current = {\n undoStack: newUndoStack,\n redoStack: [],\n hasPendingChanges: false\n };\n store.notify();\n },\n undo: () => {\n const state = stateRef.current;\n if (state.undoStack.length === 0) return null;\n\n const entry = state.undoStack[state.undoStack.length - 1];\n if (!entry) return null;\n\n stateRef.current = {\n undoStack: state.undoStack.slice(0, -1),\n redoStack: [...state.redoStack, entry],\n hasPendingChanges: false\n };\n store.notify();\n return entry;\n },\n redo: () => {\n const state = stateRef.current;\n if (state.redoStack.length === 0) return null;\n\n const entry = state.redoStack[state.redoStack.length - 1];\n if (!entry) return null;\n\n stateRef.current = {\n undoStack: [...state.undoStack, entry],\n redoStack: state.redoStack.slice(0, -1),\n hasPendingChanges: false\n };\n store.notify();\n return entry;\n },\n clear: () => {\n stateRef.current = {\n undoStack: [],\n redoStack: [],\n hasPendingChanges: false\n };\n store.notify();\n },\n setPendingChanges: (value) => {\n if (stateRef.current.hasPendingChanges === value) return;\n stateRef.current = {\n ...stateRef.current,\n hasPendingChanges: value\n };\n\n if (!pendingNotifyRef.current) {\n pendingNotifyRef.current = true;\n queueMicrotask(() => {\n pendingNotifyRef.current = false;\n store.notify();\n });\n }\n },\n notify: () => {\n for (const listener of listenersRef.current) {\n listener();\n }\n }\n };\n }, [listenersRef, stateRef, propsRef]);\n\n const canUndo = useStore(store, (state) => state.undoStack.length > 0 || state.hasPendingChanges);\n const canRedo = useStore(store, (state) => state.redoStack.length > 0);\n\n const onCommit = React.useCallback(() => {\n const pending = pendingBatchRef.current;\n if (pending.byKey.size === 0) return;\n\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n pending.timeoutId = null;\n }\n\n const updates = Array.from(pending.byKey.values());\n pending.byKey.clear();\n\n const { getRowId } = propsRef.current;\n\n const entry: HistoryEntry<TData> = {\n variant: \"cells_update\",\n count: updates.length,\n timestamp: Date.now(),\n undo: (currentData) => {\n const newData = [...currentData];\n const indexById = buildIndexById(newData, getRowId);\n\n for (const update of updates) {\n const index = indexById.get(update.rowId);\n if (index !== undefined) {\n const row = newData[index];\n if (row) {\n newData[index] = {\n ...row,\n [update.columnId]: update.previousValue\n };\n }\n }\n }\n return newData;\n },\n redo: (currentData) => {\n const newData = [...currentData];\n const indexById = buildIndexById(newData, getRowId);\n\n for (const update of updates) {\n const index = indexById.get(update.rowId);\n if (index !== undefined) {\n const row = newData[index];\n if (row) {\n newData[index] = { ...row, [update.columnId]: update.newValue };\n }\n }\n }\n return newData;\n }\n };\n\n store.push(entry);\n }, [store, propsRef]);\n\n const onUndo = React.useCallback(() => {\n if (!propsRef.current.enabled) return;\n\n onCommit();\n\n const entry = store.undo();\n if (!entry) {\n toastInfo(msgRef.current.toast.nothingToUndo);\n return;\n }\n\n const newData = entry.undo(propsRef.current.data);\n propsRef.current.onDataChange(newData);\n\n toastSuccess(msgRef.current.toast.undone(entry.count));\n }, [store, propsRef, onCommit, msgRef]);\n\n const onRedo = React.useCallback(() => {\n if (!propsRef.current.enabled) return;\n\n onCommit();\n\n const entry = store.redo();\n if (!entry) {\n toastInfo(msgRef.current.toast.nothingToRedo);\n return;\n }\n\n const newData = entry.redo(propsRef.current.data);\n propsRef.current.onDataChange(newData);\n\n toastSuccess(msgRef.current.toast.redone(entry.count));\n }, [store, propsRef, onCommit, msgRef]);\n\n const onClear = React.useCallback(() => {\n const pending = pendingBatchRef.current;\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n pending.timeoutId = null;\n }\n pending.byKey.clear();\n\n store.clear();\n }, [store]);\n\n const trackCellsUpdate = React.useCallback(\n (updates: UndoRedoCellUpdate[]) => {\n if (!propsRef.current.enabled || updates.length === 0) return;\n\n const filteredUpdates = updates.filter((u) => !Object.is(u.previousValue, u.newValue));\n if (filteredUpdates.length === 0) return;\n\n const pending = pendingBatchRef.current;\n\n for (const update of filteredUpdates) {\n const key = getPendingKey(update.rowId, update.columnId);\n const existing = pending.byKey.get(key);\n\n if (existing) {\n pending.byKey.set(key, { ...existing, newValue: update.newValue });\n } else {\n pending.byKey.set(key, update);\n }\n }\n\n store.setPendingChanges(true);\n\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n pending.timeoutId = setTimeout(onCommit, BATCH_TIMEOUT);\n },\n [store, propsRef, onCommit]\n );\n\n const trackRowsAdd = React.useCallback(\n (rows: TData[]) => {\n if (!propsRef.current.enabled || rows.length === 0) return;\n\n onCommit();\n\n const { getRowId } = propsRef.current;\n\n const rowIds = new Set(rows.map((row) => getRowId(row)));\n const rowsCopy = rows.map((row) => ({ ...row }));\n\n const entry: HistoryEntry<TData> = {\n variant: \"rows_add\",\n count: rows.length,\n timestamp: Date.now(),\n undo: (currentData) => {\n return currentData.filter((row) => !rowIds.has(getRowId(row)));\n },\n redo: (currentData) => {\n return [...currentData, ...rowsCopy.map((row) => ({ ...row }))];\n }\n };\n\n store.push(entry);\n },\n [store, propsRef, onCommit]\n );\n\n const trackRowsDelete = React.useCallback(\n (rows: TData[]) => {\n if (!propsRef.current.enabled || rows.length === 0) return;\n\n onCommit();\n\n const { getRowId, data: currentData } = propsRef.current;\n\n const indexById = buildIndexById(currentData, getRowId);\n\n const rowsWithPositions: Array<{ index: number; row: TData }> = [];\n for (const row of rows) {\n const rowId = getRowId(row);\n const currentIndex = indexById.get(rowId);\n if (currentIndex !== undefined) {\n rowsWithPositions.push({\n index: currentIndex,\n row: { ...row }\n });\n }\n }\n\n rowsWithPositions.sort((a, b) => a.index - b.index);\n\n const rowIds = new Set(rows.map((row) => getRowId(row)));\n\n const entry: HistoryEntry<TData> = {\n variant: \"rows_delete\",\n count: rows.length,\n timestamp: Date.now(),\n undo: (currentData) => {\n const newData = [...currentData];\n for (const { index, row } of rowsWithPositions) {\n const insertIndex = Math.min(index, newData.length);\n newData.splice(insertIndex, 0, { ...row });\n }\n return newData;\n },\n redo: (currentData) => {\n return currentData.filter((row) => !rowIds.has(getRowId(row)));\n }\n };\n\n store.push(entry);\n },\n [store, propsRef, onCommit]\n );\n\n React.useEffect(() => {\n const pending = pendingBatchRef.current;\n return () => {\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n };\n }, []);\n\n React.useEffect(() => {\n if (!enabled) return;\n\n function onKeyDown(event: KeyboardEvent) {\n const isCtrlOrCmd = event.ctrlKey || event.metaKey;\n const key = event.key.toLowerCase();\n\n if (!isCtrlOrCmd || (key !== \"z\" && key !== \"y\")) return;\n\n const activeElement = document.activeElement;\n if (activeElement) {\n const isInput = activeElement.tagName === \"INPUT\" || activeElement.tagName === \"TEXTAREA\";\n const isContentEditable = activeElement.getAttribute(\"contenteditable\") === \"true\";\n const isInPopover = getIsInPopover(activeElement);\n\n if (isInput || isContentEditable || isInPopover) return;\n }\n\n if (key === \"z\" && !event.shiftKey) {\n event.preventDefault();\n onUndo();\n return;\n }\n\n if ((key === \"z\" && event.shiftKey) || key === \"y\") {\n event.preventDefault();\n onRedo();\n }\n }\n\n document.addEventListener(\"keydown\", onKeyDown);\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [enabled, onUndo, onRedo]);\n\n return React.useMemo(\n () => ({\n canUndo,\n canRedo,\n onUndo,\n onRedo,\n onClear,\n trackCellsUpdate,\n trackRowsAdd,\n trackRowsDelete\n }),\n [canUndo, canRedo, onUndo, onRedo, onClear, trackCellsUpdate, trackRowsAdd, trackRowsDelete]\n );\n}\n\nexport {\n //\n type UndoRedoCellUpdate,\n useDataGridUndoRedo\n};\n"],"mappings":"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","names":["getRowId","currentData"]}
1
+ {"version":3,"sources":["../../src/data-grid/use-data-grid-undo-redo.ts"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { useAsRef } from \"../lib/use-as-ref.js\";\nimport { useLazyRef } from \"../lib/use-lazy-ref.js\";\nimport { useResolvedDataGridMessages } from \"./data-grid-locale.js\";\nimport type { DataGridLocale, DataGridMessages } from \"./messages.js\";\nimport { toastInfo, toastSuccess } from \"./toast.js\";\nimport { getIsInPopover } from \"./utils.js\";\n\nconst DEFAULT_MAX_HISTORY = 100;\nconst BATCH_TIMEOUT = 300;\n\ninterface HistoryEntry<TData> {\n variant: \"cells_update\" | \"rows_add\" | \"rows_delete\";\n count: number;\n timestamp: number;\n undo: (currentData: TData[]) => TData[];\n redo: (currentData: TData[]) => TData[];\n}\n\ninterface UndoRedoCellUpdate {\n rowId: string;\n columnId: string;\n previousValue: unknown;\n newValue: unknown;\n}\n\ninterface StoreState<TData> {\n undoStack: HistoryEntry<TData>[];\n redoStack: HistoryEntry<TData>[];\n hasPendingChanges: boolean;\n}\n\ninterface Store<TData> {\n subscribe: (callback: () => void) => () => void;\n getState: () => StoreState<TData>;\n push: (entry: HistoryEntry<TData>) => void;\n undo: () => HistoryEntry<TData> | null;\n redo: () => HistoryEntry<TData> | null;\n clear: () => void;\n setPendingChanges: (value: boolean) => void;\n notify: () => void;\n}\n\nfunction useStore<T>(store: Store<T>, selector: (state: StoreState<T>) => boolean): boolean {\n const getSnapshot = React.useCallback(() => selector(store.getState()), [store, selector]);\n\n return React.useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);\n}\n\nfunction buildIndexById<TData>(data: TData[], getRowId: (row: TData) => string): Map<string, number> {\n const map = new Map<string, number>();\n for (let i = 0; i < data.length; i++) {\n const row = data[i];\n if (row) {\n map.set(getRowId(row), i);\n }\n }\n return map;\n}\n\nfunction getPendingKey(rowId: string, columnId: string): string {\n return `${rowId}\\0${columnId}`;\n}\n\n/**\n * Tuỳ chọn của {@link useDataGridUndoRedo}. Lịch sử nằm hoàn toàn ở phía trình duyệt:\n * hook tính ra mảng dữ liệu trước/sau rồi trả về qua `onDataChange` — ứng dụng tự\n * đồng bộ lên máy chủ (hoặc bỏ qua nếu chỉ làm việc với state cục bộ).\n */\ninterface UseDataGridUndoRedoProps<TData> {\n data: TData[];\n onDataChange: (data: TData[]) => void;\n /** Khoá định danh bản ghi — phải khớp với `getRowId` của lưới */\n getRowId: (row: TData) => string;\n /** Số thao tác giữ trong lịch sử (mặc định 100) */\n maxHistory?: number;\n enabled?: boolean;\n /**\n * Ngôn ngữ của toast mà hook bắn ra (`\"en\"` · `\"vi\"`, hoặc cả bảng chuỗi tự soạn).\n *\n * Toast render ở gốc app qua `<Toaster />`, ngoài hẳn cây của lưới, nên hook giải ngôn ngữ LÚC\n * ĐƯỢC GỌI, từ context của component đang gọi: `locale` → `DataGridLocaleProvider` bọc NGOÀI\n * component đó → `ComitorLocaleProvider` → `\"en\"`. ⚠ Provider đặt trong chính component gọi\n * hook (hoặc sâu hơn) không với tới đây — khi ấy truyền cùng giá trị đã truyền cho `useDataGrid`.\n */\n locale?: DataGridLocale | DataGridMessages;\n}\n\ninterface UseDataGridUndoRedoReturn<TData> {\n canUndo: boolean;\n canRedo: boolean;\n onUndo: () => void;\n onRedo: () => void;\n onClear: () => void;\n trackCellsUpdate: (updates: UndoRedoCellUpdate[]) => void;\n trackRowsAdd: (rows: TData[]) => void;\n trackRowsDelete: (rows: TData[]) => void;\n}\n\nfunction useDataGridUndoRedo<TData>({\n data,\n onDataChange,\n getRowId,\n maxHistory = DEFAULT_MAX_HISTORY,\n enabled = true,\n locale\n}: UseDataGridUndoRedoProps<TData>): UseDataGridUndoRedoReturn<TData> {\n const msg = useResolvedDataGridMessages(locale);\n const msgRef = useAsRef(msg);\n const propsRef = useAsRef({\n data,\n onDataChange,\n getRowId,\n maxHistory,\n enabled\n });\n\n const listenersRef = useLazyRef(() => new Set<() => void>());\n\n const stateRef = useLazyRef<StoreState<TData>>(() => ({\n undoStack: [],\n redoStack: [],\n hasPendingChanges: false\n }));\n\n const pendingBatchRef = React.useRef<{\n byKey: Map<string, UndoRedoCellUpdate>;\n timeoutId: ReturnType<typeof setTimeout> | null;\n }>({\n byKey: new Map(),\n timeoutId: null\n });\n\n const pendingNotifyRef = React.useRef(false);\n\n const store = React.useMemo<Store<TData>>(() => {\n return {\n subscribe: (callback) => {\n listenersRef.current.add(callback);\n return () => listenersRef.current.delete(callback);\n },\n getState: () => stateRef.current,\n push: (entry) => {\n const state = stateRef.current;\n const newUndoStack = [...state.undoStack, entry];\n\n if (newUndoStack.length > propsRef.current.maxHistory) {\n newUndoStack.shift();\n }\n\n stateRef.current = {\n undoStack: newUndoStack,\n redoStack: [],\n hasPendingChanges: false\n };\n store.notify();\n },\n undo: () => {\n const state = stateRef.current;\n if (state.undoStack.length === 0) return null;\n\n const entry = state.undoStack[state.undoStack.length - 1];\n if (!entry) return null;\n\n stateRef.current = {\n undoStack: state.undoStack.slice(0, -1),\n redoStack: [...state.redoStack, entry],\n hasPendingChanges: false\n };\n store.notify();\n return entry;\n },\n redo: () => {\n const state = stateRef.current;\n if (state.redoStack.length === 0) return null;\n\n const entry = state.redoStack[state.redoStack.length - 1];\n if (!entry) return null;\n\n stateRef.current = {\n undoStack: [...state.undoStack, entry],\n redoStack: state.redoStack.slice(0, -1),\n hasPendingChanges: false\n };\n store.notify();\n return entry;\n },\n clear: () => {\n stateRef.current = {\n undoStack: [],\n redoStack: [],\n hasPendingChanges: false\n };\n store.notify();\n },\n setPendingChanges: (value) => {\n if (stateRef.current.hasPendingChanges === value) return;\n stateRef.current = {\n ...stateRef.current,\n hasPendingChanges: value\n };\n\n if (!pendingNotifyRef.current) {\n pendingNotifyRef.current = true;\n queueMicrotask(() => {\n pendingNotifyRef.current = false;\n store.notify();\n });\n }\n },\n notify: () => {\n for (const listener of listenersRef.current) {\n listener();\n }\n }\n };\n }, [listenersRef, stateRef, propsRef]);\n\n const canUndo = useStore(store, (state) => state.undoStack.length > 0 || state.hasPendingChanges);\n const canRedo = useStore(store, (state) => state.redoStack.length > 0);\n\n const onCommit = React.useCallback(() => {\n const pending = pendingBatchRef.current;\n if (pending.byKey.size === 0) return;\n\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n pending.timeoutId = null;\n }\n\n const updates = Array.from(pending.byKey.values());\n pending.byKey.clear();\n\n const { getRowId } = propsRef.current;\n\n const entry: HistoryEntry<TData> = {\n variant: \"cells_update\",\n count: updates.length,\n timestamp: Date.now(),\n undo: (currentData) => {\n const newData = [...currentData];\n const indexById = buildIndexById(newData, getRowId);\n\n for (const update of updates) {\n const index = indexById.get(update.rowId);\n if (index !== undefined) {\n const row = newData[index];\n if (row) {\n newData[index] = {\n ...row,\n [update.columnId]: update.previousValue\n };\n }\n }\n }\n return newData;\n },\n redo: (currentData) => {\n const newData = [...currentData];\n const indexById = buildIndexById(newData, getRowId);\n\n for (const update of updates) {\n const index = indexById.get(update.rowId);\n if (index !== undefined) {\n const row = newData[index];\n if (row) {\n newData[index] = { ...row, [update.columnId]: update.newValue };\n }\n }\n }\n return newData;\n }\n };\n\n store.push(entry);\n }, [store, propsRef]);\n\n const onUndo = React.useCallback(() => {\n if (!propsRef.current.enabled) return;\n\n onCommit();\n\n const entry = store.undo();\n if (!entry) {\n toastInfo(msgRef.current.toast.nothingToUndo);\n return;\n }\n\n const newData = entry.undo(propsRef.current.data);\n propsRef.current.onDataChange(newData);\n\n toastSuccess(msgRef.current.toast.undone(entry.count));\n }, [store, propsRef, onCommit, msgRef]);\n\n const onRedo = React.useCallback(() => {\n if (!propsRef.current.enabled) return;\n\n onCommit();\n\n const entry = store.redo();\n if (!entry) {\n toastInfo(msgRef.current.toast.nothingToRedo);\n return;\n }\n\n const newData = entry.redo(propsRef.current.data);\n propsRef.current.onDataChange(newData);\n\n toastSuccess(msgRef.current.toast.redone(entry.count));\n }, [store, propsRef, onCommit, msgRef]);\n\n const onClear = React.useCallback(() => {\n const pending = pendingBatchRef.current;\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n pending.timeoutId = null;\n }\n pending.byKey.clear();\n\n store.clear();\n }, [store]);\n\n const trackCellsUpdate = React.useCallback(\n (updates: UndoRedoCellUpdate[]) => {\n if (!propsRef.current.enabled || updates.length === 0) return;\n\n const filteredUpdates = updates.filter((u) => !Object.is(u.previousValue, u.newValue));\n if (filteredUpdates.length === 0) return;\n\n const pending = pendingBatchRef.current;\n\n for (const update of filteredUpdates) {\n const key = getPendingKey(update.rowId, update.columnId);\n const existing = pending.byKey.get(key);\n\n if (existing) {\n pending.byKey.set(key, { ...existing, newValue: update.newValue });\n } else {\n pending.byKey.set(key, update);\n }\n }\n\n store.setPendingChanges(true);\n\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n pending.timeoutId = setTimeout(onCommit, BATCH_TIMEOUT);\n },\n [store, propsRef, onCommit]\n );\n\n const trackRowsAdd = React.useCallback(\n (rows: TData[]) => {\n if (!propsRef.current.enabled || rows.length === 0) return;\n\n onCommit();\n\n const { getRowId } = propsRef.current;\n\n const rowIds = new Set(rows.map((row) => getRowId(row)));\n const rowsCopy = rows.map((row) => ({ ...row }));\n\n const entry: HistoryEntry<TData> = {\n variant: \"rows_add\",\n count: rows.length,\n timestamp: Date.now(),\n undo: (currentData) => {\n return currentData.filter((row) => !rowIds.has(getRowId(row)));\n },\n redo: (currentData) => {\n return [...currentData, ...rowsCopy.map((row) => ({ ...row }))];\n }\n };\n\n store.push(entry);\n },\n [store, propsRef, onCommit]\n );\n\n const trackRowsDelete = React.useCallback(\n (rows: TData[]) => {\n if (!propsRef.current.enabled || rows.length === 0) return;\n\n onCommit();\n\n const { getRowId, data: currentData } = propsRef.current;\n\n const indexById = buildIndexById(currentData, getRowId);\n\n const rowsWithPositions: Array<{ index: number; row: TData }> = [];\n for (const row of rows) {\n const rowId = getRowId(row);\n const currentIndex = indexById.get(rowId);\n if (currentIndex !== undefined) {\n rowsWithPositions.push({\n index: currentIndex,\n row: { ...row }\n });\n }\n }\n\n rowsWithPositions.sort((a, b) => a.index - b.index);\n\n const rowIds = new Set(rows.map((row) => getRowId(row)));\n\n const entry: HistoryEntry<TData> = {\n variant: \"rows_delete\",\n count: rows.length,\n timestamp: Date.now(),\n undo: (currentData) => {\n const newData = [...currentData];\n for (const { index, row } of rowsWithPositions) {\n const insertIndex = Math.min(index, newData.length);\n newData.splice(insertIndex, 0, { ...row });\n }\n return newData;\n },\n redo: (currentData) => {\n return currentData.filter((row) => !rowIds.has(getRowId(row)));\n }\n };\n\n store.push(entry);\n },\n [store, propsRef, onCommit]\n );\n\n React.useEffect(() => {\n const pending = pendingBatchRef.current;\n return () => {\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n };\n }, []);\n\n React.useEffect(() => {\n if (!enabled) return;\n\n function onKeyDown(event: KeyboardEvent) {\n const isCtrlOrCmd = event.ctrlKey || event.metaKey;\n const key = event.key.toLowerCase();\n\n if (!isCtrlOrCmd || (key !== \"z\" && key !== \"y\")) return;\n\n const activeElement = document.activeElement;\n if (activeElement) {\n const isInput = activeElement.tagName === \"INPUT\" || activeElement.tagName === \"TEXTAREA\";\n const isContentEditable = activeElement.getAttribute(\"contenteditable\") === \"true\";\n const isInPopover = getIsInPopover(activeElement);\n\n if (isInput || isContentEditable || isInPopover) return;\n }\n\n if (key === \"z\" && !event.shiftKey) {\n event.preventDefault();\n onUndo();\n return;\n }\n\n if ((key === \"z\" && event.shiftKey) || key === \"y\") {\n event.preventDefault();\n onRedo();\n }\n }\n\n document.addEventListener(\"keydown\", onKeyDown);\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [enabled, onUndo, onRedo]);\n\n return React.useMemo(\n () => ({\n canUndo,\n canRedo,\n onUndo,\n onRedo,\n onClear,\n trackCellsUpdate,\n trackRowsAdd,\n trackRowsDelete\n }),\n [canUndo, canRedo, onUndo, onRedo, onClear, trackCellsUpdate, trackRowsAdd, trackRowsDelete]\n );\n}\n\nexport {\n //\n type UndoRedoCellUpdate,\n useDataGridUndoRedo\n};\n"],"mappings":"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","names":["getRowId","currentData"]}
@@ -64,14 +64,19 @@ interface UseDataGridProps<TData> extends Omit<TableOptions<TData>, "pageCount"
64
64
  /** Chỉ xem: khoá mọi thao tác sửa/xoá/dán */
65
65
  readOnly?: boolean;
66
66
  /**
67
- * Ngôn ngữ của lưới: `"en"` (mặc định) · `"vi"`, hoặc cả một bảng chuỗi tự soạn.
67
+ * Ngôn ngữ của lưới: `"en"` · `"vi"`, hoặc cả một bảng chuỗi tự soạn. Bỏ trống thì theo
68
+ * `DataGridLocaleProvider`, rồi ngôn ngữ của `ComitorLocaleProvider`, rồi `"en"` — app đã đặt
69
+ * `ComitorLocaleProvider` ở root thì không cần truyền.
68
70
  *
69
- * Giá trị này đi ra theo kết quả của hook, nên `<DataGrid {...gridProps}>` tự nhận được và tự
70
- * phát xuống cây con. Hook cũng giữ một bản cho RIÊNG nó, vì toast render ở gốc app
71
- * (`<Toaster />`) chứ không nằm trong cây của lưới — không có context nào ở đó để đọc.
71
+ * Giá trị này đi ra NGUYÊN VẸN theo kết quả của hook (kể cả khi bỏ trống), nên
72
+ * `<DataGrid {...gridProps}>` tự nhận được và tự giải lại trong cây của nó. Hook cũng giải một
73
+ * bản cho RIÊNG nó — cho toast (render ở `<Toaster />`, ngoài cây của lưới) và cho phép đọc ngày
74
+ * khi dán — từ context của component ĐANG GỌI hook. ⚠ Vì vậy một `DataGridLocaleProvider` đặt
75
+ * trong chính component đó (hoặc sâu hơn) không với tới toast: truyền `locale` ở đây, hoặc đưa
76
+ * provider lên component cha. `ComitorLocaleProvider` ở root thì luôn với tới.
72
77
  *
73
- * ⚠ Thanh công cụ nằm ngoài `<DataGrid>` nên KHÔNG nhận được giá trị này: bọc cả màn bằng
74
- * `DataGridLocaleProvider`, hoặc truyền `locale` cho từng menu.
78
+ * ⚠ Thanh công cụ nằm ngoài `<DataGrid>` nên KHÔNG nhận được giá trị này: chúng theo provider
79
+ * (`DataGridLocaleProvider` / `ComitorLocaleProvider`), hoặc nhận `locale` riêng từng menu.
75
80
  */
76
81
  locale?: DataGridLocale | DataGridMessages;
77
82
  }
@@ -286,6 +291,16 @@ declare function useDataGrid<TData>({ data, columns, rowHeight: rowHeightProp, o
286
291
  checked: string;
287
292
  unchecked: string;
288
293
  };
294
+ sortable: {
295
+ instructions: (orientation: "vertical" | "horizontal" | "mixed") => string;
296
+ dragStart: (item: string, position: number, total: number) => string;
297
+ dragOver: (item: string, direction: "up" | "down", position: number, total: number) => string;
298
+ dragMove: (item: string, direction: "up" | "down", position: number, total: number) => string;
299
+ outside: string;
300
+ dragEnd: (item: string, position: number, total: number) => string;
301
+ dragEndNoChange: (item: string) => string;
302
+ dragCancel: (item: string, position: number, total: number) => string;
303
+ };
289
304
  shortcuts: {
290
305
  trigger: string;
291
306
  title: string;