@ahrowe/ui 0.28.0 → 0.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (656) hide show
  1. package/dist/esm/common/accordion/accordion.mjs.map +1 -1
  2. package/dist/esm/common/accordion/accordion.module.mjs +1 -1
  3. package/dist/esm/common/accordion/accordion.module.mjs.map +1 -1
  4. package/dist/esm/common/accordion/accordion.plain.module.mjs +1 -1
  5. package/dist/esm/common/accordion/accordion.plain.module.mjs.map +1 -1
  6. package/dist/esm/common/accordion/accordion.primary.module.mjs +1 -1
  7. package/dist/esm/common/accordion/accordion.primary.module.mjs.map +1 -1
  8. package/dist/esm/common/actionButtons/actionButtons.mjs.map +1 -1
  9. package/dist/esm/common/actionButtons/actionButtons.module.mjs +1 -1
  10. package/dist/esm/common/actionButtons/actionButtons.module.mjs.map +1 -1
  11. package/dist/esm/common/actionIcon/actionIcon.mjs.map +1 -1
  12. package/dist/esm/common/actionIcon/actionIcon.module.mjs +1 -1
  13. package/dist/esm/common/actionIcon/actionIcon.module.mjs.map +1 -1
  14. package/dist/esm/common/alert/alert.mjs.map +1 -1
  15. package/dist/esm/common/alert/alert.module.mjs +1 -1
  16. package/dist/esm/common/animatedIcon/animatedIcon.mjs.map +1 -1
  17. package/dist/esm/common/animatedIcon/animatedIcon.module.mjs +1 -1
  18. package/dist/esm/common/animatedIcon/animatedIcon.module.mjs.map +1 -1
  19. package/dist/esm/common/animatedLogo/animatedLogo.mjs.map +1 -1
  20. package/dist/esm/common/animatedLogo/animatedLogo.module.mjs +1 -1
  21. package/dist/esm/common/animatedText/animatedText.mjs +1 -1
  22. package/dist/esm/common/animatedText/animatedText.mjs.map +1 -1
  23. package/dist/esm/common/animatedText/animatedText.module.mjs +1 -1
  24. package/dist/esm/common/animatedText/animatedText.module.mjs.map +1 -1
  25. package/dist/esm/common/avatar/avatar.mjs.map +1 -1
  26. package/dist/esm/common/avatar/avatar.module.mjs +1 -1
  27. package/dist/esm/common/avatar/avatar.module.mjs.map +1 -1
  28. package/dist/esm/common/avatar/avatarGroup.mjs.map +1 -1
  29. package/dist/esm/common/badge/badge.mjs.map +1 -1
  30. package/dist/esm/common/badge/badge.module.mjs +1 -1
  31. package/dist/esm/common/badge/badge.module.mjs.map +1 -1
  32. package/dist/esm/common/breadcrumb/breadcrumb.mjs.map +1 -1
  33. package/dist/esm/common/breadcrumb/breadcrumb.module.mjs +1 -1
  34. package/dist/esm/common/button/button.mjs.map +1 -1
  35. package/dist/esm/common/button/button.module.mjs +1 -1
  36. package/dist/esm/common/button/button.module.mjs.map +1 -1
  37. package/dist/esm/common/buttonGroup/buttonGroup.mjs.map +1 -1
  38. package/dist/esm/common/buttonGroup/buttonGroup.module.mjs +1 -1
  39. package/dist/esm/common/buttonGroup/buttonGroup.module.mjs.map +1 -1
  40. package/dist/esm/common/card/Card.mjs +1 -1
  41. package/dist/esm/common/card/Card.mjs.map +1 -1
  42. package/dist/esm/common/card/CardActions.mjs.map +1 -1
  43. package/dist/esm/common/card/CardHeader.mjs.map +1 -1
  44. package/dist/esm/common/card/card.module.mjs +1 -1
  45. package/dist/esm/common/card/card.module.mjs.map +1 -1
  46. package/dist/esm/common/carousel/carousel.mjs +1 -1
  47. package/dist/esm/common/carousel/carousel.mjs.map +1 -1
  48. package/dist/esm/common/carousel/carousel.module.mjs +1 -1
  49. package/dist/esm/common/carousel/carousel.module.mjs.map +1 -1
  50. package/dist/esm/common/checkbox/checkbox.mjs.map +1 -1
  51. package/dist/esm/common/checkbox/checkbox.module.mjs +1 -1
  52. package/dist/esm/common/checkbox/checkbox.module.mjs.map +1 -1
  53. package/dist/esm/common/chip/chip.mjs +1 -1
  54. package/dist/esm/common/chip/chip.mjs.map +1 -1
  55. package/dist/esm/common/chip/chip.module.mjs +1 -1
  56. package/dist/esm/common/chip/chip.module.mjs.map +1 -1
  57. package/dist/esm/common/colorPicker/colorPicker.mjs.map +1 -1
  58. package/dist/esm/common/colorPicker/colorPicker.module.mjs +1 -1
  59. package/dist/esm/common/colorPicker/colorPicker.module.mjs.map +1 -1
  60. package/dist/esm/common/configProvider/configProvider.mjs.map +1 -1
  61. package/dist/esm/common/configProvider/useComponentDefaults.mjs.map +1 -1
  62. package/dist/esm/common/confirmModal/confirmModal.mjs.map +1 -1
  63. package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.mjs.map +1 -1
  64. package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.module.mjs +1 -1
  65. package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.module.mjs.map +1 -1
  66. package/dist/esm/common/datePicker/dateFunctions.mjs.map +1 -1
  67. package/dist/esm/common/datePicker/datePicker.mjs +1 -1
  68. package/dist/esm/common/datePicker/datePicker.mjs.map +1 -1
  69. package/dist/esm/common/datePicker/datePicker.module.mjs +1 -1
  70. package/dist/esm/common/divider/divider.mjs.map +1 -1
  71. package/dist/esm/common/divider/divider.module.mjs +1 -1
  72. package/dist/esm/common/drawer/drawer.mjs.map +1 -1
  73. package/dist/esm/common/drawer/drawer.module.mjs +1 -1
  74. package/dist/esm/common/drawer/drawer.module.mjs.map +1 -1
  75. package/dist/esm/common/dropZone/dropZone.mjs +1 -1
  76. package/dist/esm/common/dropZone/dropZone.mjs.map +1 -1
  77. package/dist/esm/common/dropZone/dropZone.module.mjs +1 -1
  78. package/dist/esm/common/dropZone/dropZone.module.mjs.map +1 -1
  79. package/dist/esm/common/dropdown/dropdown.mjs +1 -1
  80. package/dist/esm/common/dropdown/dropdown.mjs.map +1 -1
  81. package/dist/esm/common/dropdown/dropdown.module.mjs +1 -1
  82. package/dist/esm/common/dropdown/dropdown.module.mjs.map +1 -1
  83. package/dist/esm/common/emptyState/emptyState.mjs.map +1 -1
  84. package/dist/esm/common/emptyState/emptyState.module.mjs +1 -1
  85. package/dist/esm/common/errorBoundary/errorBoundary.mjs.map +1 -1
  86. package/dist/esm/common/errorBoundary/errorBoundary.module.mjs +1 -1
  87. package/dist/esm/common/errorBoundary/errorBoundary.module.mjs.map +1 -1
  88. package/dist/esm/common/fab/components/fabBase/fabBase.mjs.map +1 -1
  89. package/dist/esm/common/fab/components/fabBase/fabBase.module.mjs +1 -1
  90. package/dist/esm/common/fab/fab.mjs.map +1 -1
  91. package/dist/esm/common/fab/fab.module.mjs +1 -1
  92. package/dist/esm/common/fab/fab.module.mjs.map +1 -1
  93. package/dist/esm/common/flip/flip.mjs +1 -1
  94. package/dist/esm/common/flip/flip.mjs.map +1 -1
  95. package/dist/esm/common/flip/flip.module.mjs +1 -1
  96. package/dist/esm/common/floatingMenu/floatingMenu.mjs +1 -1
  97. package/dist/esm/common/floatingMenu/floatingMenu.mjs.map +1 -1
  98. package/dist/esm/common/floatingMenu/floatingMenu.module.mjs +1 -1
  99. package/dist/esm/common/floatingMenu/floatingMenu.module.mjs.map +1 -1
  100. package/dist/esm/common/floatingMenu/floatingMenu.types.mjs.map +1 -1
  101. package/dist/esm/common/floatingMenu/useFloatingPosition.mjs.map +1 -1
  102. package/dist/esm/common/floorPlan/floorPlan.faces.mjs.map +1 -1
  103. package/dist/esm/common/floorPlan/floorPlan.geometry.mjs.map +1 -1
  104. package/dist/esm/common/floorPlan/floorPlan.graph.mjs +1 -1
  105. package/dist/esm/common/floorPlan/floorPlan.graph.mjs.map +1 -1
  106. package/dist/esm/common/floorPlan/floorPlan.hit.mjs.map +1 -1
  107. package/dist/esm/common/floorPlan/floorPlan.json.mjs +1 -1
  108. package/dist/esm/common/floorPlan/floorPlan.json.mjs.map +1 -1
  109. package/dist/esm/common/floorPlan/floorPlan.mesh.mjs.map +1 -1
  110. package/dist/esm/common/floorPlan/floorPlan.path.mjs.map +1 -1
  111. package/dist/esm/common/floorPlan/floorPlan.plan.mjs +1 -1
  112. package/dist/esm/common/floorPlan/floorPlan.plan.mjs.map +1 -1
  113. package/dist/esm/common/floorPlan/floorPlan.rooms.mjs +1 -1
  114. package/dist/esm/common/floorPlan/floorPlan.rooms.mjs.map +1 -1
  115. package/dist/esm/common/floorPlan/floorPlan.snap.mjs.map +1 -1
  116. package/dist/esm/common/floorPlan/floorPlan.triangulate.mjs +1 -1
  117. package/dist/esm/common/floorPlan/floorPlan.triangulate.mjs.map +1 -1
  118. package/dist/esm/common/floorPlan/legacySvg.mjs.map +1 -1
  119. package/dist/esm/common/hooks/useAnchorTracking.mjs +1 -1
  120. package/dist/esm/common/hooks/useAnchorTracking.mjs.map +1 -1
  121. package/dist/esm/common/hooks/useCoarsePointer.mjs +1 -1
  122. package/dist/esm/common/hooks/useFocusBoundary.mjs.map +1 -1
  123. package/dist/esm/common/hooks/useMediaQuery.mjs +1 -1
  124. package/dist/esm/common/hooks/useMediaQuery.mjs.map +1 -1
  125. package/dist/esm/common/hooks/useOverlay.mjs.map +1 -1
  126. package/dist/esm/common/hooks/useSheet.mjs +1 -1
  127. package/dist/esm/common/hooks/useSheet.mjs.map +1 -1
  128. package/dist/esm/common/hooks/useSwipeDismiss.mjs +1 -1
  129. package/dist/esm/common/hooks/useSwipeDismiss.mjs.map +1 -1
  130. package/dist/esm/common/iconPicker/iconPicker.mjs +1 -1
  131. package/dist/esm/common/iconPicker/iconPicker.mjs.map +1 -1
  132. package/dist/esm/common/iconPicker/iconPicker.module.mjs +1 -1
  133. package/dist/esm/common/idleManager/idleManager.mjs.map +1 -1
  134. package/dist/esm/common/infiniteBlock/infiniteBlock.mjs.map +1 -1
  135. package/dist/esm/common/infiniteBlock/infiniteBlock.module.mjs +1 -1
  136. package/dist/esm/common/input/input.mjs +1 -1
  137. package/dist/esm/common/input/input.mjs.map +1 -1
  138. package/dist/esm/common/input/input.module.mjs +1 -1
  139. package/dist/esm/common/input/input.module.mjs.map +1 -1
  140. package/dist/esm/common/input/input.types.mjs.map +1 -1
  141. package/dist/esm/common/inputDropdown/inputDropdown.mjs +1 -1
  142. package/dist/esm/common/inputDropdown/inputDropdown.mjs.map +1 -1
  143. package/dist/esm/common/inputDropdown/inputDropdown.module.mjs +1 -1
  144. package/dist/esm/common/inputDropdown/inputDropdown.module.mjs.map +1 -1
  145. package/dist/esm/common/interactableDiv/interactableDiv.mjs +1 -1
  146. package/dist/esm/common/interactableDiv/interactableDiv.mjs.map +1 -1
  147. package/dist/esm/common/interactableDiv/interactableDiv.module.mjs +1 -1
  148. package/dist/esm/common/kanbanBoard/KanbanBoard.mjs +1 -1
  149. package/dist/esm/common/kanbanBoard/KanbanBoard.mjs.map +1 -1
  150. package/dist/esm/common/kanbanBoard/KanbanColumn.mjs +1 -1
  151. package/dist/esm/common/kanbanBoard/KanbanColumn.mjs.map +1 -1
  152. package/dist/esm/common/kanbanBoard/KanbanItem.mjs.map +1 -1
  153. package/dist/esm/common/kanbanBoard/kanbanBoard.module.mjs +1 -1
  154. package/dist/esm/common/kanbanBoard/kanbanBoard.module.mjs.map +1 -1
  155. package/dist/esm/common/kanbanBoard/kanbanBoard.utils.mjs +1 -1
  156. package/dist/esm/common/kanbanBoard/kanbanBoard.utils.mjs.map +1 -1
  157. package/dist/esm/common/klipyPicker/components/gifPreview/gifPreview.mjs.map +1 -1
  158. package/dist/esm/common/klipyPicker/components/gifPreview/gifPreview.module.mjs +1 -1
  159. package/dist/esm/common/klipyPicker/components/gifPreview/gifPreview.module.mjs.map +1 -1
  160. package/dist/esm/common/klipyPicker/components/gifView/gifView.mjs.map +1 -1
  161. package/dist/esm/common/klipyPicker/components/gifView/gifView.module.mjs +1 -1
  162. package/dist/esm/common/klipyPicker/components/gifView/gifView.module.mjs.map +1 -1
  163. package/dist/esm/common/klipyPicker/klipyPicker.mjs.map +1 -1
  164. package/dist/esm/common/klipyPicker/klipyPicker.module.mjs +1 -1
  165. package/dist/esm/common/loading/iconLoading/iconLoading.mjs.map +1 -1
  166. package/dist/esm/common/loading/iconLoading/iconLoading.module.mjs +1 -1
  167. package/dist/esm/common/loading/iconLoading/iconLoading.module.mjs.map +1 -1
  168. package/dist/esm/common/loading/spinnerLoading/spinnerLoading.mjs.map +1 -1
  169. package/dist/esm/common/loading/spinnerLoading/spinnerLoading.module.mjs +1 -1
  170. package/dist/esm/common/modal/modal.mjs.map +1 -1
  171. package/dist/esm/common/modal/modal.module.mjs +1 -1
  172. package/dist/esm/common/modal/modal.module.mjs.map +1 -1
  173. package/dist/esm/common/multiSelect/multiSelect.mjs +1 -1
  174. package/dist/esm/common/multiSelect/multiSelect.mjs.map +1 -1
  175. package/dist/esm/common/multiSelect/multiSelect.module.mjs +1 -1
  176. package/dist/esm/common/multiSelect/multiSelect.module.mjs.map +1 -1
  177. package/dist/esm/common/numberInput/numberInput.mjs +1 -1
  178. package/dist/esm/common/numberInput/numberInput.mjs.map +1 -1
  179. package/dist/esm/common/numberInput/numberInput.module.mjs +1 -1
  180. package/dist/esm/common/numberInput/numberInput.module.mjs.map +1 -1
  181. package/dist/esm/common/numberInput/useStepRepeat.mjs +1 -1
  182. package/dist/esm/common/numberInput/useStepRepeat.mjs.map +1 -1
  183. package/dist/esm/common/optionPicker/optionPicker.mjs +1 -1
  184. package/dist/esm/common/optionPicker/optionPicker.mjs.map +1 -1
  185. package/dist/esm/common/optionPicker/optionPicker.module.mjs +1 -1
  186. package/dist/esm/common/optionPicker/optionPicker.module.mjs.map +1 -1
  187. package/dist/esm/common/otpInput/otpInput.mjs.map +1 -1
  188. package/dist/esm/common/otpInput/otpInput.module.mjs +1 -1
  189. package/dist/esm/common/otpInput/otpInput.module.mjs.map +1 -1
  190. package/dist/esm/common/overscroll/overscroll.mjs.map +1 -1
  191. package/dist/esm/common/overscroll/overscroll.module.mjs +1 -1
  192. package/dist/esm/common/pagination/pagination.mjs.map +1 -1
  193. package/dist/esm/common/pagination/pagination.module.mjs +1 -1
  194. package/dist/esm/common/pagination/pagination.module.mjs.map +1 -1
  195. package/dist/esm/common/planCanvas/planCanvas.mjs +1 -1
  196. package/dist/esm/common/planCanvas/planCanvas.mjs.map +1 -1
  197. package/dist/esm/common/planCanvas/planCanvas.module.mjs +1 -1
  198. package/dist/esm/common/planCanvas/planCanvas.module.mjs.map +1 -1
  199. package/dist/esm/common/popover/popover.mjs +1 -1
  200. package/dist/esm/common/popover/popover.mjs.map +1 -1
  201. package/dist/esm/common/popover/popover.module.mjs +1 -1
  202. package/dist/esm/common/popover/popover.module.mjs.map +1 -1
  203. package/dist/esm/common/popover/usePopoverPosition.mjs.map +1 -1
  204. package/dist/esm/common/progressBar/progressBar.mjs +1 -1
  205. package/dist/esm/common/progressBar/progressBar.mjs.map +1 -1
  206. package/dist/esm/common/progressBar/progressBar.module.mjs +1 -1
  207. package/dist/esm/common/progressBar/progressBar.module.mjs.map +1 -1
  208. package/dist/esm/common/radioGroup/radioGroup.mjs +1 -1
  209. package/dist/esm/common/radioGroup/radioGroup.mjs.map +1 -1
  210. package/dist/esm/common/radioGroup/radioGroup.module.mjs +1 -1
  211. package/dist/esm/common/radioGroup/radioGroup.module.mjs.map +1 -1
  212. package/dist/esm/common/rating/rating.mjs +1 -1
  213. package/dist/esm/common/rating/rating.mjs.map +1 -1
  214. package/dist/esm/common/rating/rating.module.mjs +1 -1
  215. package/dist/esm/common/revealLens/revealLens.mjs.map +1 -1
  216. package/dist/esm/common/revealLens/revealLens.module.mjs +1 -1
  217. package/dist/esm/common/revealLens/revealLens.module.mjs.map +1 -1
  218. package/dist/esm/common/ripple/ripple.mjs.map +1 -1
  219. package/dist/esm/common/ripple/ripple.module.mjs +1 -1
  220. package/dist/esm/common/ripple/ripple.module.mjs.map +1 -1
  221. package/dist/esm/common/roomDrawer/roomDrawer.mjs +1 -1
  222. package/dist/esm/common/roomDrawer/roomDrawer.mjs.map +1 -1
  223. package/dist/esm/common/roomDrawer/roomDrawer.module.mjs +1 -1
  224. package/dist/esm/common/roomDrawer/roomDrawer.module.mjs.map +1 -1
  225. package/dist/esm/common/roomDrawer/usePlanHistory.mjs.map +1 -1
  226. package/dist/esm/common/roomViewer/roomViewer.mjs +1 -1
  227. package/dist/esm/common/roomViewer/roomViewer.mjs.map +1 -1
  228. package/dist/esm/common/roomViewer/roomViewer.module.mjs +1 -1
  229. package/dist/esm/common/scrollbarProvider/scrollbarProvider.mjs.map +1 -1
  230. package/dist/esm/common/scrollbarProvider/scrollbarProvider.module.mjs +1 -1
  231. package/dist/esm/common/scrollbarProvider/scrollbarProvider.module.mjs.map +1 -1
  232. package/dist/esm/common/searchInput/searchInput.mjs.map +1 -1
  233. package/dist/esm/common/searchInput/searchInput.module.mjs +1 -1
  234. package/dist/esm/common/sectionHeader/sectionHeader.mjs.map +1 -1
  235. package/dist/esm/common/sectionHeader/sectionHeader.module.mjs +1 -1
  236. package/dist/esm/common/sectionHeader/sectionHeader.module.mjs.map +1 -1
  237. package/dist/esm/common/skeleton/skeleton.mjs.map +1 -1
  238. package/dist/esm/common/skeleton/skeleton.module.mjs +1 -1
  239. package/dist/esm/common/slider/slider.mjs +1 -1
  240. package/dist/esm/common/slider/slider.mjs.map +1 -1
  241. package/dist/esm/common/slider/slider.module.mjs +1 -1
  242. package/dist/esm/common/slider/slider.module.mjs.map +1 -1
  243. package/dist/esm/common/splitButton/splitButton.mjs.map +1 -1
  244. package/dist/esm/common/splitButton/splitButton.module.mjs +1 -1
  245. package/dist/esm/common/stepper/stepper.mjs.map +1 -1
  246. package/dist/esm/common/stepper/stepper.module.mjs +1 -1
  247. package/dist/esm/common/stepper/stepper.module.mjs.map +1 -1
  248. package/dist/esm/common/sticky/sticky.mjs.map +1 -1
  249. package/dist/esm/common/sticky/sticky.module.mjs +1 -1
  250. package/dist/esm/common/sticky/stickyStack.mjs.map +1 -1
  251. package/dist/esm/common/styles/sheet.module.mjs +1 -1
  252. package/dist/esm/common/styles/sheet.module.mjs.map +1 -1
  253. package/dist/esm/common/switch/switch.mjs.map +1 -1
  254. package/dist/esm/common/switch/switch.module.mjs +1 -1
  255. package/dist/esm/common/tabHeader/tabHeader.mjs.map +1 -1
  256. package/dist/esm/common/tabHeader/tabHeader.module.mjs +1 -1
  257. package/dist/esm/common/tabHeader/tabHeader.module.mjs.map +1 -1
  258. package/dist/esm/common/themeProvider/defaultTheme.mjs.map +1 -1
  259. package/dist/esm/common/themeProvider/theme.module.mjs +1 -1
  260. package/dist/esm/common/themeProvider/themeProvider.mjs +1 -1
  261. package/dist/esm/common/themeProvider/themeProvider.mjs.map +1 -1
  262. package/dist/esm/common/themeProvider/useTheme.mjs.map +1 -1
  263. package/dist/esm/common/tilt/tilt.mjs.map +1 -1
  264. package/dist/esm/common/tilt/tilt.module.mjs +1 -1
  265. package/dist/esm/common/tiltGroup/tiltGroup.mjs.map +1 -1
  266. package/dist/esm/common/timeInput/components/clockDial/clockDial.mjs +1 -1
  267. package/dist/esm/common/timeInput/components/clockDial/clockDial.mjs.map +1 -1
  268. package/dist/esm/common/timeInput/components/clockDial/clockDial.module.mjs +1 -1
  269. package/dist/esm/common/timeInput/components/clockDial/clockDial.module.mjs.map +1 -1
  270. package/dist/esm/common/timeInput/timeFunctions.mjs +1 -1
  271. package/dist/esm/common/timeInput/timeFunctions.mjs.map +1 -1
  272. package/dist/esm/common/timeInput/timeInput.mjs +1 -1
  273. package/dist/esm/common/timeInput/timeInput.mjs.map +1 -1
  274. package/dist/esm/common/timeInput/timeInput.module.mjs +1 -1
  275. package/dist/esm/common/timeInput/timeInput.module.mjs.map +1 -1
  276. package/dist/esm/common/timeline/timeline.mjs.map +1 -1
  277. package/dist/esm/common/timeline/timeline.module.mjs +1 -1
  278. package/dist/esm/common/timeline/timeline.module.mjs.map +1 -1
  279. package/dist/esm/common/timer/timer.chime.mjs.map +1 -1
  280. package/dist/esm/common/timer/timer.mjs +1 -1
  281. package/dist/esm/common/timer/timer.mjs.map +1 -1
  282. package/dist/esm/common/timer/timer.module.mjs +1 -1
  283. package/dist/esm/common/timer/timer.module.mjs.map +1 -1
  284. package/dist/esm/common/toast/toast.mjs.map +1 -1
  285. package/dist/esm/common/toast/toast.module.mjs +1 -1
  286. package/dist/esm/common/toast/toast.module.mjs.map +1 -1
  287. package/dist/esm/common/toast/toastProvider.mjs.map +1 -1
  288. package/dist/esm/common/tooltip/tooltip.mjs.map +1 -1
  289. package/dist/esm/common/tooltip/tooltip.module.mjs +1 -1
  290. package/dist/esm/common/tooltip/tooltip.module.mjs.map +1 -1
  291. package/dist/esm/common/tree/flattenTree.mjs.map +1 -1
  292. package/dist/esm/common/tree/tree.mjs +1 -1
  293. package/dist/esm/common/tree/tree.mjs.map +1 -1
  294. package/dist/esm/common/tree/tree.module.mjs +1 -1
  295. package/dist/esm/common/utils/activationKey.mjs +2 -0
  296. package/dist/esm/common/utils/activationKey.mjs.map +1 -0
  297. package/dist/esm/common/utils/renderIcon.mjs +1 -1
  298. package/dist/esm/common/utils/renderIcon.mjs.map +1 -1
  299. package/dist/esm/common/virtualList/useColumns.mjs +1 -1
  300. package/dist/esm/common/virtualList/useColumns.mjs.map +1 -1
  301. package/dist/esm/common/virtualList/useRowDrag.mjs +1 -1
  302. package/dist/esm/common/virtualList/useRowDrag.mjs.map +1 -1
  303. package/dist/esm/common/virtualList/useSelection.mjs.map +1 -1
  304. package/dist/esm/common/virtualList/useVirtualWindow.mjs +1 -1
  305. package/dist/esm/common/virtualList/useVirtualWindow.mjs.map +1 -1
  306. package/dist/esm/common/virtualList/virtualList.mjs.map +1 -1
  307. package/dist/esm/common/virtualList/virtualList.module.mjs +1 -1
  308. package/dist/esm/common/virtualList/virtualList.module.mjs.map +1 -1
  309. package/dist/esm/common/virtualList/virtualList.utils.mjs.map +1 -1
  310. package/dist/esm/common/virtualList/virtualRow.mjs +1 -1
  311. package/dist/esm/common/virtualList/virtualRow.mjs.map +1 -1
  312. package/dist/esm/common/wizard/wizard.mjs +1 -1
  313. package/dist/esm/common/wizard/wizard.mjs.map +1 -1
  314. package/dist/esm/common/wizard/wizard.module.mjs +1 -1
  315. package/dist/esm/services/formValidation/FormValidatorGroupWithForm.mjs.map +1 -1
  316. package/dist/esm/services/formValidation/index.mjs +1 -1
  317. package/dist/esm/services/formValidation/useFormValidatorGroup.mjs.map +1 -1
  318. package/dist/esm/services/formValidation/validatableComponent.mjs.map +1 -1
  319. package/dist/esm/services/klipy.mjs.map +1 -1
  320. package/dist/esm/services/localization.mjs.map +1 -1
  321. package/dist/index.cjs +3 -3
  322. package/dist/index.cjs.map +1 -1
  323. package/dist/style.css +1 -1
  324. package/dist/types/{package/common → common}/actionButtons/actionButtons.d.ts +1 -1
  325. package/dist/types/{package/common → common}/animatedIcon/animatedIcon.d.ts +1 -1
  326. package/dist/types/common/card/Card.d.ts +4 -0
  327. package/dist/types/{package/common → common}/card/CardActions.d.ts +2 -1
  328. package/dist/types/common/card/CardContent.d.ts +4 -0
  329. package/dist/types/{package/common → common}/card/CardHeader.d.ts +2 -1
  330. package/dist/types/common/card/CardMedia.d.ts +4 -0
  331. package/dist/types/common/carousel/carousel.d.ts +4 -0
  332. package/dist/types/common/chip/chip.d.ts +4 -0
  333. package/dist/types/{package/common → common}/configProvider/configProvider.d.ts +1 -1
  334. package/dist/types/{package/common → common}/datePicker/components/datePickerMonth/datePickerMonth.d.ts +1 -1
  335. package/dist/types/{package/common → common}/datePicker/datePicker.d.ts +1 -1
  336. package/dist/types/{package/common → common}/drawer/drawer.d.ts +1 -1
  337. package/dist/types/{package/common → common}/dropZone/dropZone.d.ts +2 -1
  338. package/dist/types/common/dropdown/dropdown.d.ts +4 -0
  339. package/dist/types/{package/common → common}/fab/components/fabBase/fabBase.d.ts +1 -1
  340. package/dist/types/{package/common → common}/fab/fab.d.ts +1 -1
  341. package/dist/types/{package/common → common}/floatingMenu/floatingMenu.d.ts +1 -1
  342. package/dist/types/{package/common → common}/floatingMenu/useFloatingPosition.d.ts +1 -1
  343. package/dist/types/{package/common → common}/hooks/useOverlay.d.ts +1 -1
  344. package/dist/types/{package/common → common}/iconPicker/iconPicker.d.ts +2 -1
  345. package/dist/types/{package/common → common}/idleManager/idleManager.d.ts +1 -1
  346. package/dist/types/{package/common → common}/infiniteBlock/infiniteBlock.d.ts +2 -1
  347. package/dist/types/common/input/input.d.ts +4 -0
  348. package/dist/types/{package/common → common}/inputDropdown/inputDropdown.d.ts +2 -1
  349. package/dist/types/{package/common → common}/kanbanBoard/KanbanBoard.d.ts +1 -1
  350. package/dist/types/{package/common → common}/kanbanBoard/KanbanColumn.d.ts +1 -1
  351. package/dist/types/{package/common → common}/kanbanBoard/KanbanItem.d.ts +1 -1
  352. package/dist/types/{package/common → common}/loading/iconLoading/iconLoading.d.ts +2 -1
  353. package/dist/types/common/modal/modal.d.ts +3 -0
  354. package/dist/types/{package/common → common}/overscroll/overscroll.d.ts +1 -1
  355. package/dist/types/common/popover/popover.d.ts +3 -0
  356. package/dist/types/{package/common → common}/scrollbarProvider/scrollbarProvider.d.ts +1 -1
  357. package/dist/types/{package/common → common}/sheetBackdrop/sheetBackdrop.d.ts +1 -1
  358. package/dist/types/common/slider/slider.d.ts +3 -0
  359. package/dist/types/{package/common → common}/slider/slider.types.d.ts +35 -10
  360. package/dist/types/{package/common → common}/splitButton/splitButton.d.ts +1 -1
  361. package/dist/types/{package/common → common}/stepper/stepper.d.ts +2 -1
  362. package/dist/types/{package/common → common}/sticky/sticky.d.ts +2 -1
  363. package/dist/types/{package/common → common}/tabHeader/tabHeader.d.ts +2 -1
  364. package/dist/types/common/textarea/textarea.d.ts +3 -0
  365. package/dist/types/{package/common → common}/themeProvider/theme.types.d.ts +30 -0
  366. package/dist/types/{package/common → common}/themeProvider/themeProvider.d.ts +1 -1
  367. package/dist/types/{package/common → common}/timeInput/components/clockDial/clockDial.d.ts +2 -1
  368. package/dist/types/{package/common → common}/timeInput/timeInput.d.ts +2 -1
  369. package/dist/types/{package/common → common}/timeline/timeline.d.ts +2 -1
  370. package/dist/types/{package/common → common}/toast/index.d.ts +1 -1
  371. package/dist/types/{package/common → common}/toast/toast.d.ts +2 -1
  372. package/dist/types/{package/common → common}/toast/toastProvider.d.ts +2 -2
  373. package/dist/types/{package/common → common}/tooltip/tooltip.d.ts +2 -1
  374. package/dist/types/common/utils/activationKey.d.ts +9 -0
  375. package/dist/types/{package/common → common}/virtualList/virtualRow.d.ts +1 -1
  376. package/dist/types/{package/common → common}/wizard/wizard.d.ts +2 -1
  377. package/dist/types/{package/services → services}/formValidation/index.d.ts +1 -1
  378. package/docs/Flip.md +1 -1
  379. package/docs/RoomDrawer.md +13 -5
  380. package/docs/RoomViewer.md +4 -0
  381. package/docs/Slider.md +34 -4
  382. package/package.json +73 -69
  383. package/dist/types/package/common/card/Card.d.ts +0 -3
  384. package/dist/types/package/common/card/CardContent.d.ts +0 -3
  385. package/dist/types/package/common/card/CardMedia.d.ts +0 -3
  386. package/dist/types/package/common/carousel/carousel.d.ts +0 -3
  387. package/dist/types/package/common/chip/chip.d.ts +0 -3
  388. package/dist/types/package/common/dropdown/dropdown.d.ts +0 -3
  389. package/dist/types/package/common/input/input.d.ts +0 -3
  390. package/dist/types/package/common/modal/modal.d.ts +0 -3
  391. package/dist/types/package/common/popover/popover.d.ts +0 -3
  392. package/dist/types/package/common/slider/slider.d.ts +0 -3
  393. package/dist/types/package/common/textarea/textarea.d.ts +0 -2
  394. /package/dist/types/{package/common → common}/accordion/accordion.d.ts +0 -0
  395. /package/dist/types/{package/common → common}/accordion/accordion.types.d.ts +0 -0
  396. /package/dist/types/{package/common → common}/accordion/index.d.ts +0 -0
  397. /package/dist/types/{package/common → common}/actionButtons/actionButtons.types.d.ts +0 -0
  398. /package/dist/types/{package/common → common}/actionButtons/index.d.ts +0 -0
  399. /package/dist/types/{package/common → common}/actionIcon/actionIcon.d.ts +0 -0
  400. /package/dist/types/{package/common → common}/actionIcon/actionIcon.types.d.ts +0 -0
  401. /package/dist/types/{package/common → common}/actionIcon/index.d.ts +0 -0
  402. /package/dist/types/{package/common → common}/alert/alert.d.ts +0 -0
  403. /package/dist/types/{package/common → common}/alert/alert.types.d.ts +0 -0
  404. /package/dist/types/{package/common → common}/alert/index.d.ts +0 -0
  405. /package/dist/types/{package/common → common}/animatedIcon/animatedIcon.types.d.ts +0 -0
  406. /package/dist/types/{package/common → common}/animatedIcon/index.d.ts +0 -0
  407. /package/dist/types/{package/common → common}/animatedLogo/animatedLogo.d.ts +0 -0
  408. /package/dist/types/{package/common → common}/animatedLogo/animatedLogo.types.d.ts +0 -0
  409. /package/dist/types/{package/common → common}/animatedLogo/index.d.ts +0 -0
  410. /package/dist/types/{package/common → common}/animatedText/animatedText.d.ts +0 -0
  411. /package/dist/types/{package/common → common}/animatedText/animatedText.types.d.ts +0 -0
  412. /package/dist/types/{package/common → common}/animatedText/index.d.ts +0 -0
  413. /package/dist/types/{package/common → common}/avatar/avatar.d.ts +0 -0
  414. /package/dist/types/{package/common → common}/avatar/avatar.types.d.ts +0 -0
  415. /package/dist/types/{package/common → common}/avatar/avatarGroup.d.ts +0 -0
  416. /package/dist/types/{package/common → common}/avatar/index.d.ts +0 -0
  417. /package/dist/types/{package/common → common}/badge/badge.d.ts +0 -0
  418. /package/dist/types/{package/common → common}/badge/badge.types.d.ts +0 -0
  419. /package/dist/types/{package/common → common}/badge/index.d.ts +0 -0
  420. /package/dist/types/{package/common → common}/bodyEnd/bodyEnd.d.ts +0 -0
  421. /package/dist/types/{package/common → common}/bodyEnd/bodyEnd.types.d.ts +0 -0
  422. /package/dist/types/{package/common → common}/bodyEnd/index.d.ts +0 -0
  423. /package/dist/types/{package/common → common}/breadcrumb/breadcrumb.d.ts +0 -0
  424. /package/dist/types/{package/common → common}/breadcrumb/breadcrumb.types.d.ts +0 -0
  425. /package/dist/types/{package/common → common}/breadcrumb/index.d.ts +0 -0
  426. /package/dist/types/{package/common → common}/button/button.d.ts +0 -0
  427. /package/dist/types/{package/common → common}/button/button.types.d.ts +0 -0
  428. /package/dist/types/{package/common → common}/button/index.d.ts +0 -0
  429. /package/dist/types/{package/common → common}/buttonGroup/buttonGroup.d.ts +0 -0
  430. /package/dist/types/{package/common → common}/buttonGroup/buttonGroup.types.d.ts +0 -0
  431. /package/dist/types/{package/common → common}/buttonGroup/index.d.ts +0 -0
  432. /package/dist/types/{package/common → common}/card/card.types.d.ts +0 -0
  433. /package/dist/types/{package/common → common}/card/index.d.ts +0 -0
  434. /package/dist/types/{package/common → common}/carousel/carousel.types.d.ts +0 -0
  435. /package/dist/types/{package/common → common}/carousel/index.d.ts +0 -0
  436. /package/dist/types/{package/common → common}/checkbox/checkbox.d.ts +0 -0
  437. /package/dist/types/{package/common → common}/checkbox/checkbox.types.d.ts +0 -0
  438. /package/dist/types/{package/common → common}/checkbox/index.d.ts +0 -0
  439. /package/dist/types/{package/common → common}/chip/chip.types.d.ts +0 -0
  440. /package/dist/types/{package/common → common}/chip/chipContainer.d.ts +0 -0
  441. /package/dist/types/{package/common → common}/chip/index.d.ts +0 -0
  442. /package/dist/types/{package/common → common}/colorPicker/colorPicker.d.ts +0 -0
  443. /package/dist/types/{package/common → common}/colorPicker/colorPicker.types.d.ts +0 -0
  444. /package/dist/types/{package/common → common}/colorPicker/index.d.ts +0 -0
  445. /package/dist/types/{package/common → common}/configProvider/configProvider.types.d.ts +0 -0
  446. /package/dist/types/{package/common → common}/configProvider/index.d.ts +0 -0
  447. /package/dist/types/{package/common → common}/configProvider/useComponentDefaults.d.ts +0 -0
  448. /package/dist/types/{package/common → common}/configProvider/usePresentationDefault.d.ts +0 -0
  449. /package/dist/types/{package/common → common}/confirmModal/confirmModal.d.ts +0 -0
  450. /package/dist/types/{package/common → common}/confirmModal/confirmModal.types.d.ts +0 -0
  451. /package/dist/types/{package/common → common}/confirmModal/index.d.ts +0 -0
  452. /package/dist/types/{package/common → common}/datePicker/components/datePickerMonth/index.d.ts +0 -0
  453. /package/dist/types/{package/common → common}/datePicker/dateFunctions.d.ts +0 -0
  454. /package/dist/types/{package/common → common}/datePicker/index.d.ts +0 -0
  455. /package/dist/types/{package/common → common}/divider/divider.d.ts +0 -0
  456. /package/dist/types/{package/common → common}/divider/divider.types.d.ts +0 -0
  457. /package/dist/types/{package/common → common}/divider/index.d.ts +0 -0
  458. /package/dist/types/{package/common → common}/drawer/drawer.types.d.ts +0 -0
  459. /package/dist/types/{package/common → common}/drawer/index.d.ts +0 -0
  460. /package/dist/types/{package/common → common}/dropZone/dropZone.types.d.ts +0 -0
  461. /package/dist/types/{package/common → common}/dropZone/index.d.ts +0 -0
  462. /package/dist/types/{package/common → common}/dropdown/dropdown.types.d.ts +0 -0
  463. /package/dist/types/{package/common → common}/dropdown/index.d.ts +0 -0
  464. /package/dist/types/{package/common → common}/emptyState/emptyState.d.ts +0 -0
  465. /package/dist/types/{package/common → common}/emptyState/emptyState.types.d.ts +0 -0
  466. /package/dist/types/{package/common → common}/emptyState/index.d.ts +0 -0
  467. /package/dist/types/{package/common → common}/errorBoundary/errorBoundary.d.ts +0 -0
  468. /package/dist/types/{package/common → common}/errorBoundary/errorBoundary.types.d.ts +0 -0
  469. /package/dist/types/{package/common → common}/errorBoundary/index.d.ts +0 -0
  470. /package/dist/types/{package/common → common}/fab/components/fabBase/fabBase.types.d.ts +0 -0
  471. /package/dist/types/{package/common → common}/fab/components/fabBase/index.d.ts +0 -0
  472. /package/dist/types/{package/common → common}/fab/fab.types.d.ts +0 -0
  473. /package/dist/types/{package/common → common}/fab/index.d.ts +0 -0
  474. /package/dist/types/{package/common → common}/flip/flip.d.ts +0 -0
  475. /package/dist/types/{package/common → common}/flip/flip.types.d.ts +0 -0
  476. /package/dist/types/{package/common → common}/flip/index.d.ts +0 -0
  477. /package/dist/types/{package/common → common}/floatingMenu/floatingMenu.types.d.ts +0 -0
  478. /package/dist/types/{package/common → common}/floatingMenu/index.d.ts +0 -0
  479. /package/dist/types/{package/common → common}/floorPlan/floorPlan.faces.d.ts +0 -0
  480. /package/dist/types/{package/common → common}/floorPlan/floorPlan.fixtures.d.ts +0 -0
  481. /package/dist/types/{package/common → common}/floorPlan/floorPlan.geometry.d.ts +0 -0
  482. /package/dist/types/{package/common → common}/floorPlan/floorPlan.graph.d.ts +0 -0
  483. /package/dist/types/{package/common → common}/floorPlan/floorPlan.hit.d.ts +0 -0
  484. /package/dist/types/{package/common → common}/floorPlan/floorPlan.json.d.ts +0 -0
  485. /package/dist/types/{package/common → common}/floorPlan/floorPlan.mesh.d.ts +0 -0
  486. /package/dist/types/{package/common → common}/floorPlan/floorPlan.path.d.ts +0 -0
  487. /package/dist/types/{package/common → common}/floorPlan/floorPlan.plan.d.ts +0 -0
  488. /package/dist/types/{package/common → common}/floorPlan/floorPlan.rooms.d.ts +0 -0
  489. /package/dist/types/{package/common → common}/floorPlan/floorPlan.snap.d.ts +0 -0
  490. /package/dist/types/{package/common → common}/floorPlan/floorPlan.triangulate.d.ts +0 -0
  491. /package/dist/types/{package/common → common}/floorPlan/floorPlan.types.d.ts +0 -0
  492. /package/dist/types/{package/common → common}/floorPlan/index.d.ts +0 -0
  493. /package/dist/types/{package/common → common}/floorPlan/legacySvg.d.ts +0 -0
  494. /package/dist/types/{package/common → common}/hooks/useAnchorTracking.d.ts +0 -0
  495. /package/dist/types/{package/common → common}/hooks/useCoarsePointer.d.ts +0 -0
  496. /package/dist/types/{package/common → common}/hooks/useFocusBoundary.d.ts +0 -0
  497. /package/dist/types/{package/common → common}/hooks/useMediaQuery.d.ts +0 -0
  498. /package/dist/types/{package/common → common}/hooks/useSheet.d.ts +0 -0
  499. /package/dist/types/{package/common → common}/hooks/useSwipeDismiss.d.ts +0 -0
  500. /package/dist/types/{package/common → common}/hooks/useVisualViewportSize.d.ts +0 -0
  501. /package/dist/types/{package/common → common}/iconPicker/iconPicker.types.d.ts +0 -0
  502. /package/dist/types/{package/common → common}/iconPicker/index.d.ts +0 -0
  503. /package/dist/types/{package/common → common}/idleManager/idleManager.types.d.ts +0 -0
  504. /package/dist/types/{package/common → common}/idleManager/index.d.ts +0 -0
  505. /package/dist/types/{package/common → common}/infiniteBlock/index.d.ts +0 -0
  506. /package/dist/types/{package/common → common}/infiniteBlock/infiniteBlock.types.d.ts +0 -0
  507. /package/dist/types/{package/common → common}/input/index.d.ts +0 -0
  508. /package/dist/types/{package/common → common}/input/input.types.d.ts +0 -0
  509. /package/dist/types/{package/common → common}/inputDropdown/index.d.ts +0 -0
  510. /package/dist/types/{package/common → common}/inputDropdown/inputDropdown.types.d.ts +0 -0
  511. /package/dist/types/{package/common → common}/interactableDiv/index.d.ts +0 -0
  512. /package/dist/types/{package/common → common}/interactableDiv/interactableDiv.d.ts +0 -0
  513. /package/dist/types/{package/common → common}/kanbanBoard/index.d.ts +0 -0
  514. /package/dist/types/{package/common → common}/kanbanBoard/kanbanBoard.types.d.ts +0 -0
  515. /package/dist/types/{package/common → common}/kanbanBoard/kanbanBoard.utils.d.ts +0 -0
  516. /package/dist/types/{package/common → common}/klipyPicker/components/gifPreview/gifPreview.d.ts +0 -0
  517. /package/dist/types/{package/common → common}/klipyPicker/components/gifPreview/gifPreview.types.d.ts +0 -0
  518. /package/dist/types/{package/common → common}/klipyPicker/components/gifPreview/index.d.ts +0 -0
  519. /package/dist/types/{package/common → common}/klipyPicker/components/gifView/gifView.d.ts +0 -0
  520. /package/dist/types/{package/common → common}/klipyPicker/components/gifView/gifView.types.d.ts +0 -0
  521. /package/dist/types/{package/common → common}/klipyPicker/components/gifView/index.d.ts +0 -0
  522. /package/dist/types/{package/common → common}/klipyPicker/index.d.ts +0 -0
  523. /package/dist/types/{package/common → common}/klipyPicker/klipyPicker.d.ts +0 -0
  524. /package/dist/types/{package/common → common}/klipyPicker/klipyPicker.types.d.ts +0 -0
  525. /package/dist/types/{package/common → common}/loading/iconLoading/index.d.ts +0 -0
  526. /package/dist/types/{package/common → common}/loading/index.d.ts +0 -0
  527. /package/dist/types/{package/common → common}/loading/spinnerLoading/index.d.ts +0 -0
  528. /package/dist/types/{package/common → common}/loading/spinnerLoading/spinnerLoading.d.ts +0 -0
  529. /package/dist/types/{package/common → common}/modal/index.d.ts +0 -0
  530. /package/dist/types/{package/common → common}/modal/modal.types.d.ts +0 -0
  531. /package/dist/types/{package/common → common}/multiSelect/index.d.ts +0 -0
  532. /package/dist/types/{package/common → common}/multiSelect/multiSelect.d.ts +0 -0
  533. /package/dist/types/{package/common → common}/multiSelect/multiSelect.types.d.ts +0 -0
  534. /package/dist/types/{package/common → common}/numberInput/index.d.ts +0 -0
  535. /package/dist/types/{package/common → common}/numberInput/numberInput.d.ts +0 -0
  536. /package/dist/types/{package/common → common}/numberInput/numberInput.types.d.ts +0 -0
  537. /package/dist/types/{package/common → common}/numberInput/useStepRepeat.d.ts +0 -0
  538. /package/dist/types/{package/common → common}/optionPicker/index.d.ts +0 -0
  539. /package/dist/types/{package/common → common}/optionPicker/optionPicker.d.ts +0 -0
  540. /package/dist/types/{package/common → common}/optionPicker/optionPicker.types.d.ts +0 -0
  541. /package/dist/types/{package/common → common}/otpInput/index.d.ts +0 -0
  542. /package/dist/types/{package/common → common}/otpInput/otpInput.d.ts +0 -0
  543. /package/dist/types/{package/common → common}/otpInput/otpInput.types.d.ts +0 -0
  544. /package/dist/types/{package/common → common}/overscroll/index.d.ts +0 -0
  545. /package/dist/types/{package/common → common}/overscroll/overscroll.types.d.ts +0 -0
  546. /package/dist/types/{package/common → common}/pagination/index.d.ts +0 -0
  547. /package/dist/types/{package/common → common}/pagination/pagination.d.ts +0 -0
  548. /package/dist/types/{package/common → common}/pagination/pagination.types.d.ts +0 -0
  549. /package/dist/types/{package/common → common}/planCanvas/index.d.ts +0 -0
  550. /package/dist/types/{package/common → common}/planCanvas/planCanvas.d.ts +0 -0
  551. /package/dist/types/{package/common → common}/planCanvas/planCanvas.types.d.ts +0 -0
  552. /package/dist/types/{package/common → common}/popover/index.d.ts +0 -0
  553. /package/dist/types/{package/common → common}/popover/popover.types.d.ts +0 -0
  554. /package/dist/types/{package/common → common}/popover/usePopoverPosition.d.ts +0 -0
  555. /package/dist/types/{package/common → common}/progressBar/index.d.ts +0 -0
  556. /package/dist/types/{package/common → common}/progressBar/progressBar.d.ts +0 -0
  557. /package/dist/types/{package/common → common}/progressBar/progressBar.types.d.ts +0 -0
  558. /package/dist/types/{package/common → common}/radioGroup/index.d.ts +0 -0
  559. /package/dist/types/{package/common → common}/radioGroup/radioGroup.d.ts +0 -0
  560. /package/dist/types/{package/common → common}/radioGroup/radioGroup.types.d.ts +0 -0
  561. /package/dist/types/{package/common → common}/rating/index.d.ts +0 -0
  562. /package/dist/types/{package/common → common}/rating/rating.d.ts +0 -0
  563. /package/dist/types/{package/common → common}/rating/rating.types.d.ts +0 -0
  564. /package/dist/types/{package/common → common}/revealLens/index.d.ts +0 -0
  565. /package/dist/types/{package/common → common}/revealLens/revealLens.d.ts +0 -0
  566. /package/dist/types/{package/common → common}/revealLens/revealLens.types.d.ts +0 -0
  567. /package/dist/types/{package/common → common}/ripple/index.d.ts +0 -0
  568. /package/dist/types/{package/common → common}/ripple/ripple.d.ts +0 -0
  569. /package/dist/types/{package/common → common}/ripple/ripple.types.d.ts +0 -0
  570. /package/dist/types/{package/common → common}/roomDrawer/index.d.ts +0 -0
  571. /package/dist/types/{package/common → common}/roomDrawer/roomDrawer.d.ts +0 -0
  572. /package/dist/types/{package/common → common}/roomDrawer/roomDrawer.types.d.ts +0 -0
  573. /package/dist/types/{package/common → common}/roomDrawer/usePlanHistory.d.ts +0 -0
  574. /package/dist/types/{package/common → common}/roomViewer/index.d.ts +0 -0
  575. /package/dist/types/{package/common → common}/roomViewer/roomViewer.d.ts +0 -0
  576. /package/dist/types/{package/common → common}/roomViewer/roomViewer.types.d.ts +0 -0
  577. /package/dist/types/{package/common → common}/scrollbarProvider/index.d.ts +0 -0
  578. /package/dist/types/{package/common → common}/searchInput/index.d.ts +0 -0
  579. /package/dist/types/{package/common → common}/searchInput/searchInput.d.ts +0 -0
  580. /package/dist/types/{package/common → common}/searchInput/searchInput.types.d.ts +0 -0
  581. /package/dist/types/{package/common → common}/sectionHeader/index.d.ts +0 -0
  582. /package/dist/types/{package/common → common}/sectionHeader/sectionHeader.d.ts +0 -0
  583. /package/dist/types/{package/common → common}/sectionHeader/sectionHeader.types.d.ts +0 -0
  584. /package/dist/types/{package/common → common}/sheetBackdrop/index.d.ts +0 -0
  585. /package/dist/types/{package/common → common}/sheetBackdrop/sheetBackdrop.types.d.ts +0 -0
  586. /package/dist/types/{package/common → common}/skeleton/index.d.ts +0 -0
  587. /package/dist/types/{package/common → common}/skeleton/skeleton.d.ts +0 -0
  588. /package/dist/types/{package/common → common}/skeleton/skeleton.types.d.ts +0 -0
  589. /package/dist/types/{package/common → common}/slider/index.d.ts +0 -0
  590. /package/dist/types/{package/common → common}/splitButton/index.d.ts +0 -0
  591. /package/dist/types/{package/common → common}/splitButton/splitButton.types.d.ts +0 -0
  592. /package/dist/types/{package/common → common}/stepper/index.d.ts +0 -0
  593. /package/dist/types/{package/common → common}/stepper/stepper.types.d.ts +0 -0
  594. /package/dist/types/{package/common → common}/sticky/index.d.ts +0 -0
  595. /package/dist/types/{package/common → common}/sticky/sticky.types.d.ts +0 -0
  596. /package/dist/types/{package/common → common}/sticky/stickyStack.d.ts +0 -0
  597. /package/dist/types/{package/common → common}/switch/index.d.ts +0 -0
  598. /package/dist/types/{package/common → common}/switch/switch.d.ts +0 -0
  599. /package/dist/types/{package/common → common}/switch/switch.types.d.ts +0 -0
  600. /package/dist/types/{package/common → common}/tabHeader/index.d.ts +0 -0
  601. /package/dist/types/{package/common → common}/tabHeader/tabHeader.types.d.ts +0 -0
  602. /package/dist/types/{package/common → common}/textarea/index.d.ts +0 -0
  603. /package/dist/types/{package/common → common}/textarea/textarea.types.d.ts +0 -0
  604. /package/dist/types/{package/common → common}/themeProvider/defaultTheme.d.ts +0 -0
  605. /package/dist/types/{package/common → common}/themeProvider/index.d.ts +0 -0
  606. /package/dist/types/{package/common → common}/themeProvider/useTheme.d.ts +0 -0
  607. /package/dist/types/{package/common → common}/tilt/index.d.ts +0 -0
  608. /package/dist/types/{package/common → common}/tilt/tilt.d.ts +0 -0
  609. /package/dist/types/{package/common → common}/tilt/tilt.types.d.ts +0 -0
  610. /package/dist/types/{package/common → common}/tilt/tiltMath.d.ts +0 -0
  611. /package/dist/types/{package/common → common}/tiltGroup/index.d.ts +0 -0
  612. /package/dist/types/{package/common → common}/tiltGroup/tiltGroup.d.ts +0 -0
  613. /package/dist/types/{package/common → common}/tiltGroup/tiltGroup.types.d.ts +0 -0
  614. /package/dist/types/{package/common → common}/timeInput/components/clockDial/clockDial.types.d.ts +0 -0
  615. /package/dist/types/{package/common → common}/timeInput/components/clockDial/index.d.ts +0 -0
  616. /package/dist/types/{package/common → common}/timeInput/index.d.ts +0 -0
  617. /package/dist/types/{package/common → common}/timeInput/timeFunctions.d.ts +0 -0
  618. /package/dist/types/{package/common → common}/timeInput/timeInput.types.d.ts +0 -0
  619. /package/dist/types/{package/common → common}/timeline/index.d.ts +0 -0
  620. /package/dist/types/{package/common → common}/timeline/timeline.types.d.ts +0 -0
  621. /package/dist/types/{package/common → common}/timer/index.d.ts +0 -0
  622. /package/dist/types/{package/common → common}/timer/timer.chime.d.ts +0 -0
  623. /package/dist/types/{package/common → common}/timer/timer.d.ts +0 -0
  624. /package/dist/types/{package/common → common}/timer/timer.types.d.ts +0 -0
  625. /package/dist/types/{package/common → common}/toast/toast.types.d.ts +0 -0
  626. /package/dist/types/{package/common → common}/toast/toastService.d.ts +0 -0
  627. /package/dist/types/{package/common → common}/tooltip/index.d.ts +0 -0
  628. /package/dist/types/{package/common → common}/tooltip/tooltip.types.d.ts +0 -0
  629. /package/dist/types/{package/common → common}/tree/flattenTree.d.ts +0 -0
  630. /package/dist/types/{package/common → common}/tree/index.d.ts +0 -0
  631. /package/dist/types/{package/common → common}/tree/tree.d.ts +0 -0
  632. /package/dist/types/{package/common → common}/tree/tree.types.d.ts +0 -0
  633. /package/dist/types/{package/common → common}/types/actions.types.d.ts +0 -0
  634. /package/dist/types/{package/common → common}/types/baseProps.types.d.ts +0 -0
  635. /package/dist/types/{package/common → common}/types/icon.types.d.ts +0 -0
  636. /package/dist/types/{package/common → common}/types/slots.types.d.ts +0 -0
  637. /package/dist/types/{package/common → common}/utils/renderIcon.d.ts +0 -0
  638. /package/dist/types/{package/common → common}/utils/scrollAncestors.d.ts +0 -0
  639. /package/dist/types/{package/common → common}/utils/visualViewport.d.ts +0 -0
  640. /package/dist/types/{package/common → common}/virtualList/index.d.ts +0 -0
  641. /package/dist/types/{package/common → common}/virtualList/useColumns.d.ts +0 -0
  642. /package/dist/types/{package/common → common}/virtualList/useRowDrag.d.ts +0 -0
  643. /package/dist/types/{package/common → common}/virtualList/useSelection.d.ts +0 -0
  644. /package/dist/types/{package/common → common}/virtualList/useVirtualWindow.d.ts +0 -0
  645. /package/dist/types/{package/common → common}/virtualList/virtualList.d.ts +0 -0
  646. /package/dist/types/{package/common → common}/virtualList/virtualList.types.d.ts +0 -0
  647. /package/dist/types/{package/common → common}/virtualList/virtualList.utils.d.ts +0 -0
  648. /package/dist/types/{package/common → common}/wizard/index.d.ts +0 -0
  649. /package/dist/types/{package/common → common}/wizard/wizard.types.d.ts +0 -0
  650. /package/dist/types/{package/hooks → hooks}/useWindowSize.d.ts +0 -0
  651. /package/dist/types/{package/index.d.ts → index.d.ts} +0 -0
  652. /package/dist/types/{package/services → services}/formValidation/FormValidatorGroupWithForm.d.ts +0 -0
  653. /package/dist/types/{package/services → services}/formValidation/useFormValidatorGroup.d.ts +0 -0
  654. /package/dist/types/{package/services → services}/formValidation/validatableComponent.d.ts +0 -0
  655. /package/dist/types/{package/services → services}/klipy.d.ts +0 -0
  656. /package/dist/types/{package/services → services}/localization.d.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"useRowDrag.mjs","names":[],"sources":["../../../../package/common/virtualList/useRowDrag.ts"],"sourcesContent":["import React, { useState, useRef, useEffect, useLayoutEffect, useCallback } from 'react';\n\nimport styles from './virtualList.module.pcss';\nimport { resolveReorderTarget, resolveTreeDropTarget, lastDescendantIndex } from './virtualList.utils';\nimport type { TreeDropPosition, TreeDropTarget } from './virtualList.types';\n\ninterface UseRowDragArgs {\n reorderable: boolean;\n treeReorder: boolean;\n onReorder?: (fromIndex: number, toIndex: number) => void;\n onTreeDrop?: (dragKey: string | number, target: TreeDropTarget) => void;\n longPressDelay: number;\n dragHandle: boolean;\n treeIndentPx: number;\n /** Current flat ordering and depth tags (mouse handlers read these directly). */\n keys: (string | number)[];\n depths: number[];\n isGroupAt: (index: number) => boolean;\n rootRef: React.RefObject<HTMLDivElement | null>;\n /** Latest keys for async (touch / rAF) consumers — owned by useVirtualWindow. */\n keysRef: React.RefObject<(string | number)[]>;\n}\n\n/** The drag-related props the parent spreads onto a given row. */\nexport interface RowDragProps {\n reorderable: boolean;\n /** Native mouse DnD is active for the list (independent of which row is armed). */\n mouseDragEnabled: boolean;\n draggable: boolean | undefined;\n isDragging: boolean;\n onMouseDown: ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined;\n onMouseOver: ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined;\n onMouseLeave: ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined;\n onDragStart: ((e: React.DragEvent<HTMLDivElement>) => void) | undefined;\n onDragOver: ((e: React.DragEvent<HTMLDivElement>) => void) | undefined;\n onDragEnd: (() => void) | undefined;\n onDrop: ((e: React.DragEvent<HTMLDivElement>) => void) | undefined;\n onTouchStart: ((e: React.TouchEvent<HTMLDivElement>) => void) | undefined;\n dropPosition: TreeDropPosition | undefined;\n dropIndentPx: number | undefined;\n}\n\ninterface UseRowDragResult {\n /** True while a row is being dragged (for the root reordering style). */\n draggingKey: string | number | null;\n /** Whether either drag mode is active. */\n dragEnabled: boolean;\n /** Drag props for the row at `index` / `key`. */\n getRowDragProps: (index: number, key: string | number) => RowDragProps;\n /** Returns true (and resets) if the next click should be swallowed (post-drag). */\n consumeSuppressedClick: () => boolean;\n}\n\n/**\n * Row drag-and-drop for both modes:\n * - `reorderable` (flat): native HTML5 drag on desktop; rows move live via\n * `onReorder` with midpoint hysteresis.\n * - `treeReorder`: a drop indicator (before/after/inside) is shown during the\n * drag and `onTreeDrop` fires once on release; dropping onto the dragged\n * node's own subtree is forbidden.\n * Touch uses a long-press → lifted-clone → pointer-move path with edge\n * auto-scroll. `dragHandle` restricts initiation to `[data-drag-handle]`.\n */\nexport function useRowDrag({\n reorderable,\n treeReorder,\n onReorder,\n onTreeDrop,\n longPressDelay,\n dragHandle,\n treeIndentPx,\n keys,\n depths,\n isGroupAt,\n rootRef,\n keysRef,\n}: UseRowDragArgs): UseRowDragResult {\n // The dragged item is tracked by its stable key (indices shift after each\n // live reorder); the ref drives the logic, the state drives the row's style.\n const dragKeyRef = useRef<string | number | null>(null);\n const [draggingKey, setDraggingKey] = useState<string | number | null>(null);\n // Tree-reorder drop indicator. Unlike flat reorder (which moves rows live),\n // tree mode shows where the drop will land and commits once on release.\n const [dropTarget, setDropTarget] = useState<TreeDropTarget | null>(null);\n const dropTargetRef = useRef<TreeDropTarget | null>(null);\n const onReorderRef = useRef(onReorder);\n const onTreeDropRef = useRef(onTreeDrop);\n const treeModeRef = useRef(treeReorder);\n const depthsRef = useRef<number[]>(depths);\n const isGroupAtRef = useRef<(i: number) => boolean>(isGroupAt);\n // When `dragHandle` is on, a mousedown sets this to whether it landed on a\n // `[data-drag-handle]` element, gating whether the ensuing dragstart is honoured.\n const dragFromHandleRef = useRef(true);\n // In `dragHandle` mode the `draggable` attribute is only on the row whose\n // handle the pointer is currently over (\"armed\"). A permanently `draggable`\n // row breaks mouse text selection (caret placement, double-click word select,\n // drag select) inside any child input in Firefox — see Mozilla bugs 739071 /\n // 800050 / 1189486. Arming on hover rather than on mousedown means the\n // attribute is already in place before the press, so the browser never has to\n // notice it appearing mid-gesture, and any pointer move re-derives it.\n const armedKeyRef = useRef<string | number | null>(null);\n const [armedKey, setArmedKeyState] = useState<string | number | null>(null);\n const longPressRef = useRef<number | null>(null);\n const touchActiveRef = useRef(false);\n const touchStartYRef = useRef<number | null>(null);\n const pointerXRef = useRef(0);\n const pointerYRef = useRef(0);\n const autoScrollRef = useRef<number | null>(null);\n const suppressNextClickRef = useRef(false);\n // Floating clone that follows the finger during a touch drag.\n const dragCloneRef = useRef<HTMLElement | null>(null);\n const grabOffsetYRef = useRef(0);\n const cloneLeftRef = useRef(0);\n const dragHeightRef = useRef(0);\n // The native `draggable` attribute (mouse DnD) makes a long-press start the\n // browser's own drag on touch devices, which hijacks our touch handlers. So\n // expose it only where the primary pointer is fine (mouse/trackpad); touch\n // devices use the touch handlers below instead.\n const [isCoarsePointer] = useState(() =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia('(pointer: coarse)').matches\n : false,\n );\n\n useLayoutEffect(() => {\n onReorderRef.current = onReorder;\n onTreeDropRef.current = onTreeDrop;\n treeModeRef.current = treeReorder;\n depthsRef.current = depths;\n dropTargetRef.current = dropTarget;\n isGroupAtRef.current = isGroupAt;\n });\n\n // ── Mouse / shared start ──────────────────────────────────────────────────\n\n /** Move the `draggable` attribute to `next` (or off entirely for `null`). */\n function arm(next: string | number | null) {\n // Arming exists purely to place the native `draggable` attribute, which is\n // never set on a coarse pointer (touch uses the handlers below instead). A\n // tap still synthesises mouseover/mousedown, so without this a touch device\n // would re-render the list on every handle tap to no effect whatsoever.\n if (isCoarsePointer) return;\n if (armedKeyRef.current === next) return; // mouseover fires constantly — no-op\n armedKeyRef.current = next;\n setArmedKeyState(next);\n }\n\n // Arm while the pointer rests on this row's handle, disarm as it moves off.\n // `buttons !== 0` means a press is already in progress: the pointer can drift\n // off the handle before the browser reaches its drag threshold, so hover is\n // ignored until release rather than disarming a drag that is about to start.\n function handleRowMouseOver(key: string | number, e: React.MouseEvent<HTMLDivElement>) {\n if (e.buttons !== 0) return;\n arm((e.target as HTMLElement).closest('[data-drag-handle]') ? key : null);\n }\n\n function handleRowMouseLeave(e: React.MouseEvent<HTMLDivElement>) {\n if (e.buttons !== 0) return;\n arm(null);\n }\n\n // With `dragHandle`, remember on mousedown whether the press landed on a\n // handle, so the dragstart that follows can be ignored if it didn't. Arming\n // here too covers a handle that came to sit under an already-stationary cursor\n // (the list scrolled), which produces no mouseover.\n function handleRowMouseDown(key: string | number, e: React.MouseEvent<HTMLDivElement>) {\n if (e.button !== 0) return; // only a primary press can begin a drag\n const fromHandle = !!(e.target as HTMLElement).closest('[data-drag-handle]');\n dragFromHandleRef.current = fromHandle;\n if (fromHandle) arm(key);\n }\n\n function handleReorderStart(key: string | number, e: React.DragEvent<HTMLDivElement>) {\n if (dragHandle && !dragFromHandleRef.current) {\n e.preventDefault(); // not started from a handle — let the row stay put\n return;\n }\n dragKeyRef.current = key;\n setDraggingKey(key);\n if (treeReorder) setDropTarget(null);\n }\n\n // ── Tree mode ─────────────────────────────────────────────────────────────\n\n /** Resolve the tree drop target for the row at `overIndex` under pointer `y`. */\n function computeTreeDrop(overIndex: number, y: number, rect: DOMRect): TreeDropTarget | null {\n const dragKey = dragKeyRef.current;\n if (dragKey == null) return null;\n const fromIndex = keys.indexOf(dragKey);\n // Forbid dropping onto the dragged node or anything in its own subtree.\n if (fromIndex !== -1 && overIndex >= fromIndex && overIndex <= lastDescendantIndex(fromIndex, depths)) {\n return null;\n }\n const position = resolveTreeDropTarget(y, rect.top, rect.height, isGroupAt(overIndex));\n return { key: keys[overIndex], position };\n }\n\n function handleTreeDragOver(overIndex: number, e: React.DragEvent<HTMLDivElement>) {\n e.preventDefault(); // allow the drop\n const rect = e.currentTarget.getBoundingClientRect();\n const next = computeTreeDrop(overIndex, e.clientY, rect);\n setDropTarget((prev) =>\n prev?.key === next?.key && prev?.position === next?.position ? prev : next,\n );\n }\n\n function commitTreeDrop() {\n const dragKey = dragKeyRef.current;\n const target = dropTargetRef.current;\n if (dragKey != null && target && target.key !== dragKey) onTreeDrop?.(dragKey, target);\n }\n\n function handleTreeDrop(e: React.DragEvent<HTMLDivElement>) {\n e.preventDefault();\n commitTreeDrop();\n setDropTarget(null);\n dragKeyRef.current = null;\n setDraggingKey(null);\n arm(null);\n }\n\n function handleTreeDragEnd() {\n // Fires after `drop` (or on its own when released off a valid target).\n setDropTarget(null);\n dragKeyRef.current = null;\n setDraggingKey(null);\n arm(null);\n }\n\n // ── Flat mode ─────────────────────────────────────────────────────────────\n\n function handleReorderOver(overIndex: number, e: React.DragEvent<HTMLDivElement>) {\n e.preventDefault(); // allow the drop\n const dragKey = dragKeyRef.current;\n if (dragKey == null) return;\n const fromIndex = keys.indexOf(dragKey);\n // Midpoint hysteresis (see resolveReorderTarget): a move only happens once\n // the pointer crosses the centre of the row it's over. After a swap the\n // dragged row sits under the cursor, so moving again needs real pointer\n // travel — this stops the oscillation that made dragging feel jumpy.\n const rect = e.currentTarget.getBoundingClientRect();\n const target = resolveReorderTarget(fromIndex, overIndex, e.clientY, rect.top, rect.height);\n if (target != null) onReorder?.(fromIndex, target);\n }\n\n function handleReorderEnd() {\n dragKeyRef.current = null;\n setDraggingKey(null);\n arm(null);\n }\n\n // ── Touch reordering (long-press to arm, then drag) ──────────────────────────\n // These handlers run from window listeners during a touch drag, so they read\n // mutable state from refs and are stable across renders.\n\n const reorderAtPoint = useCallback((x: number) => {\n const dragKey = dragKeyRef.current;\n const root = rootRef.current;\n if (dragKey == null || !root) return;\n // Reorder against the centre of the lifted clone, not the raw finger — the\n // finger sits below the clone's top by the grab offset, so using it would\n // make the top (and bottom) rows unreachable. The clone is what the user\n // aims with, so match it.\n const y = dragCloneRef.current\n ? pointerYRef.current - grabOffsetYRef.current + dragHeightRef.current / 2\n : pointerYRef.current;\n const el = document.elementFromPoint(x, y) as HTMLElement | null;\n const rowEl = el && root.contains(el) ? el.closest<HTMLElement>('[data-index]') : null;\n if (!rowEl) return;\n const overIndex = Number(rowEl.dataset.index);\n if (Number.isNaN(overIndex)) return;\n const fromIndex = keysRef.current.indexOf(dragKey);\n const rect = rowEl.getBoundingClientRect();\n if (treeModeRef.current) {\n // Tree mode: don't move live — just track where the drop will land.\n const ks = keysRef.current;\n const ds = depthsRef.current;\n if (fromIndex !== -1 && overIndex >= fromIndex && overIndex <= lastDescendantIndex(fromIndex, ds)) {\n setDropTarget(null);\n return;\n }\n const position = resolveTreeDropTarget(y, rect.top, rect.height, isGroupAtRef.current(overIndex));\n const next: TreeDropTarget = { key: ks[overIndex], position };\n setDropTarget((prev) => (prev?.key === next.key && prev?.position === next.position ? prev : next));\n return;\n }\n const target = resolveReorderTarget(fromIndex, overIndex, y, rect.top, rect.height);\n if (target != null) onReorderRef.current?.(fromIndex, target);\n }, [rootRef, keysRef]);\n\n // Keep the floating clone glued under the finger (same grab point).\n const positionDragClone = useCallback(() => {\n const clone = dragCloneRef.current;\n if (!clone) return;\n clone.style.transform = `translate(${cloneLeftRef.current}px, ${pointerYRef.current - grabOffsetYRef.current}px)`;\n }, []);\n\n // While the finger sits near a top/bottom edge (and within the list's width),\n // scroll the list and keep reordering against the rows now passing under it.\n const autoScrollTick = useCallback(() => {\n const root = rootRef.current;\n if (!root || !touchActiveRef.current) { autoScrollRef.current = null; return; }\n const rect = root.getBoundingClientRect();\n const x = pointerXRef.current;\n const y = pointerYRef.current;\n const EDGE = 48;\n let dy = 0;\n // Only auto-scroll while the finger is actually over the list — moving it\n // outside (any direction) stops the scroll instead of running away; pinning\n // the dragged row keeps touch events alive so it resumes when you come back.\n const inside = x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;\n if (inside) {\n if (y < rect.top + EDGE) dy = -Math.min(18, Math.ceil((rect.top + EDGE - y) / 3));\n else if (y > rect.bottom - EDGE) dy = Math.min(18, Math.ceil((y - (rect.bottom - EDGE)) / 3));\n }\n if (dy !== 0) {\n root.scrollTop += dy;\n reorderAtPoint(x);\n }\n autoScrollRef.current = requestAnimationFrame(autoScrollTick);\n }, [reorderAtPoint, rootRef]);\n\n const endTouchDrag = useCallback(() => {\n if (longPressRef.current != null) { clearTimeout(longPressRef.current); longPressRef.current = null; }\n window.removeEventListener('touchmove', handleTouchMove);\n window.removeEventListener('touchend', endTouchDrag);\n window.removeEventListener('touchcancel', endTouchDrag);\n if (autoScrollRef.current != null) { cancelAnimationFrame(autoScrollRef.current); autoScrollRef.current = null; }\n if (dragCloneRef.current) { dragCloneRef.current.remove(); dragCloneRef.current = null; }\n // Restore native scrolling that was locked for the duration of the drag.\n document.body.style.touchAction = '';\n document.body.style.overscrollBehavior = '';\n if (touchActiveRef.current) {\n // A real drag happened — swallow the click the browser fires afterwards\n // so it doesn't, e.g., toggle row selection.\n suppressNextClickRef.current = true;\n setTimeout(() => { suppressNextClickRef.current = false; }, 350);\n // Tree mode commits the pending drop on release (flat mode already moved\n // rows live during the drag, so there's nothing to commit here).\n if (treeModeRef.current) {\n const dk = dragKeyRef.current;\n const target = dropTargetRef.current;\n if (dk != null && target && target.key !== dk) onTreeDropRef.current?.(dk, target);\n }\n }\n setDropTarget(null);\n touchActiveRef.current = false;\n touchStartYRef.current = null;\n dragKeyRef.current = null;\n setDraggingKey(null);\n }, []);\n\n const handleTouchMove = useCallback((e: TouchEvent) => {\n const t = e.touches[0];\n if (!t) return;\n pointerXRef.current = t.clientX;\n pointerYRef.current = t.clientY;\n if (!touchActiveRef.current) {\n // Before the long-press fires: if the finger travels, the user means to\n // scroll, so disarm and let the browser handle it (we don't preventDefault).\n const sy = touchStartYRef.current;\n if (sy != null && Math.abs(t.clientY - sy) > 10 && longPressRef.current != null) {\n clearTimeout(longPressRef.current);\n longPressRef.current = null;\n }\n return;\n }\n // Non-passive listener: preventDefault cancels the native scroll for this\n // gesture — the only reliable way once touch-action has been latched at\n // touchstart. This is what makes the drag actually move on touch devices.\n if (e.cancelable) e.preventDefault();\n positionDragClone();\n reorderAtPoint(t.clientX);\n }, [reorderAtPoint, positionDragClone]);\n\n function handleRowTouchStart(key: string | number, e: React.TouchEvent<HTMLDivElement>) {\n if (!reorderable && !treeReorder) return;\n // With a drag handle, only a press that starts on it arms the drag, so the\n // rest of the row stays free for tapping/typing into inputs.\n if (dragHandle && !(e.target as HTMLElement).closest('[data-drag-handle]')) return;\n if (longPressRef.current != null || touchActiveRef.current) return; // ignore extra fingers\n const t = e.touches[0];\n if (!t) return;\n touchStartYRef.current = t.clientY;\n pointerXRef.current = t.clientX;\n pointerYRef.current = t.clientY;\n window.addEventListener('touchmove', handleTouchMove, { passive: false });\n window.addEventListener('touchend', endTouchDrag);\n window.addEventListener('touchcancel', endTouchDrag);\n longPressRef.current = window.setTimeout(() => {\n longPressRef.current = null;\n touchActiveRef.current = true;\n dragKeyRef.current = key;\n setDraggingKey(key);\n navigator.vibrate?.(10);\n // Lock native scrolling for the whole gesture — relying on per-move\n // preventDefault isn't enough once the finger leaves and re-enters the\n // list (the browser commits to a scroll and ignores it). We do all the\n // scrolling ourselves via autoScrollTick.\n document.body.style.touchAction = 'none';\n document.body.style.overscrollBehavior = 'none';\n createDragClone(key);\n if (autoScrollRef.current == null) autoScrollRef.current = requestAnimationFrame(autoScrollTick);\n }, longPressDelay);\n }\n\n // Build a floating copy of the picked-up row that tracks the finger, so the\n // drag has a visible \"lifted\" element (the original row stays dimmed in place\n // as a drop placeholder).\n function createDragClone(key: string | number) {\n const root = rootRef.current;\n if (!root) return;\n const idx = keysRef.current.indexOf(key);\n const src = root.querySelector<HTMLElement>(`[data-index=\"${idx}\"]`);\n if (!src) return;\n const r = src.getBoundingClientRect();\n grabOffsetYRef.current = pointerYRef.current - r.top;\n cloneLeftRef.current = r.left;\n dragHeightRef.current = r.height;\n const clone = src.cloneNode(true) as HTMLElement;\n clone.removeAttribute('data-index');\n clone.setAttribute('data-drag-clone', 'true');\n clone.setAttribute('aria-hidden', 'true');\n clone.classList.add(styles.virtualListDragClone);\n Object.assign(clone.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n width: `${r.width}px`,\n height: `${r.height}px`,\n margin: '0',\n opacity: '1',\n pointerEvents: 'none',\n // Above the sticky header (z-index 2) and any focused row (z-index 1).\n zIndex: '3',\n background: 'var(--background)',\n boxShadow: 'var(--card-shadow)',\n borderRadius: 'var(--default-border-radius)',\n } as Partial<CSSStyleDeclaration>);\n // Appended inside the list so it inherits the active theme's CSS variables;\n // position:fixed keeps it in viewport coordinates regardless.\n root.appendChild(clone);\n dragCloneRef.current = clone;\n positionDragClone();\n }\n\n // Tear down any in-flight touch drag if the component unmounts mid-gesture.\n useEffect(() => endTouchDrag, [endTouchDrag]);\n\n // Either drag mode arms the same row gestures; the handlers above branch on\n // `treeReorder` for the differing target resolution / commit behaviour.\n const dragEnabled = reorderable || treeReorder;\n // Native mouse DnD is in play for this list. Row-level fallbacks that must\n // cover *every* row — swallowing the browser's own drop and context menu —\n // key off this, not off `draggable`, which in `dragHandle` mode is only ever\n // on the single armed row.\n const mouseDragEnabled = dragEnabled && !isCoarsePointer;\n\n function getRowDragProps(index: number, key: string | number): RowDragProps {\n // The drop indicator only renders on the row currently targeted. `before`/\n // `after` lines indent to the target's depth so they sit under where the\n // dropped content will start; `inside` highlights the whole row instead.\n const rowDrop = treeReorder && dropTarget?.key === key ? dropTarget.position : undefined;\n return {\n // Drives the row-wide grab cursor. With `dragHandle`, only the handle\n // initiates a drag, so the cursor belongs on the handle (styled by the\n // consumer), not across the whole row.\n reorderable: dragEnabled && !dragHandle,\n mouseDragEnabled,\n // In `dragHandle` mode the attribute only goes on the row the pointer has\n // armed, so rows stay text-selectable in Firefox the rest of the time.\n draggable: (mouseDragEnabled && (!dragHandle || key === armedKey)) || undefined,\n isDragging: dragEnabled && key === draggingKey,\n onMouseDown: dragEnabled && dragHandle ? (e) => handleRowMouseDown(key, e) : undefined,\n onMouseOver: dragEnabled && dragHandle ? (e) => handleRowMouseOver(key, e) : undefined,\n onMouseLeave: dragEnabled && dragHandle ? handleRowMouseLeave : undefined,\n onDragStart: dragEnabled ? (e) => handleReorderStart(key, e) : undefined,\n onDragOver:\n treeReorder ? (e) => handleTreeDragOver(index, e)\n : reorderable ? (e) => handleReorderOver(index, e)\n : undefined,\n onDragEnd: treeReorder ? handleTreeDragEnd : reorderable ? handleReorderEnd : undefined,\n onDrop: treeReorder ? handleTreeDrop : undefined,\n onTouchStart: dragEnabled ? (e) => handleRowTouchStart(key, e) : undefined,\n dropPosition: rowDrop,\n dropIndentPx: rowDrop ? (depths[index] ?? 0) * treeIndentPx : undefined,\n };\n }\n\n function consumeSuppressedClick(): boolean {\n if (suppressNextClickRef.current) { suppressNextClickRef.current = false; return true; }\n return false;\n }\n\n return { draggingKey, dragEnabled, getRowDragProps, consumeSuppressedClick };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useRowDrag.mjs","names":[],"sources":["../../../../package/common/virtualList/useRowDrag.ts"],"sourcesContent":["import React, { useState, useRef, useEffect, useLayoutEffect, useCallback } from 'react';\n\nimport styles from './virtualList.module.pcss';\nimport { resolveReorderTarget, resolveTreeDropTarget, lastDescendantIndex } from './virtualList.utils';\nimport type { TreeDropPosition, TreeDropTarget } from './virtualList.types';\n\ninterface UseRowDragArgs {\n reorderable: boolean;\n treeReorder: boolean;\n onReorder?: (fromIndex: number, toIndex: number) => void;\n onTreeDrop?: (dragKey: string | number, target: TreeDropTarget) => void;\n longPressDelay: number;\n dragHandle: boolean;\n treeIndentPx: number;\n /** Current flat ordering and depth tags (mouse handlers read these directly). */\n keys: (string | number)[];\n depths: number[];\n isGroupAt: (index: number) => boolean;\n rootRef: React.RefObject<HTMLDivElement | null>;\n /** Latest keys for async (touch / rAF) consumers — owned by useVirtualWindow. */\n keysRef: React.RefObject<(string | number)[]>;\n}\n\n/** The drag-related props the parent spreads onto a given row. */\nexport interface RowDragProps {\n reorderable: boolean;\n /** Native mouse DnD is active for the list (independent of which row is armed). */\n mouseDragEnabled: boolean;\n draggable: boolean | undefined;\n isDragging: boolean;\n onMouseDown: ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined;\n onMouseOver: ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined;\n onMouseLeave: ((e: React.MouseEvent<HTMLDivElement>) => void) | undefined;\n onDragStart: ((e: React.DragEvent<HTMLDivElement>) => void) | undefined;\n onDragOver: ((e: React.DragEvent<HTMLDivElement>) => void) | undefined;\n onDragEnd: (() => void) | undefined;\n onDrop: ((e: React.DragEvent<HTMLDivElement>) => void) | undefined;\n onTouchStart: ((e: React.TouchEvent<HTMLDivElement>) => void) | undefined;\n dropPosition: TreeDropPosition | undefined;\n dropIndentPx: number | undefined;\n}\n\ninterface UseRowDragResult {\n /** True while a row is being dragged (for the root reordering style). */\n draggingKey: string | number | null;\n /** Whether either drag mode is active. */\n dragEnabled: boolean;\n /** Drag props for the row at `index` / `key`. */\n getRowDragProps: (index: number, key: string | number) => RowDragProps;\n /** Returns true (and resets) if the next click should be swallowed (post-drag). */\n consumeSuppressedClick: () => boolean;\n}\n\n/**\n * Row drag-and-drop for both modes:\n * - `reorderable` (flat): native HTML5 drag on desktop; rows move live via\n * `onReorder` with midpoint hysteresis.\n * - `treeReorder`: a drop indicator (before/after/inside) is shown during the\n * drag and `onTreeDrop` fires once on release; dropping onto the dragged\n * node's own subtree is forbidden.\n * Touch uses a long-press → lifted-clone → pointer-move path with edge\n * auto-scroll. `dragHandle` restricts initiation to `[data-drag-handle]`.\n */\nexport function useRowDrag({\n reorderable,\n treeReorder,\n onReorder,\n onTreeDrop,\n longPressDelay,\n dragHandle,\n treeIndentPx,\n keys,\n depths,\n isGroupAt,\n rootRef,\n keysRef,\n}: UseRowDragArgs): UseRowDragResult {\n // The dragged item is tracked by its stable key (indices shift after each\n // live reorder); the ref drives the logic, the state drives the row's style.\n const dragKeyRef = useRef<string | number | null>(null);\n const [draggingKey, setDraggingKey] = useState<string | number | null>(null);\n // Tree-reorder drop indicator. Unlike flat reorder (which moves rows live),\n // tree mode shows where the drop will land and commits once on release.\n const [dropTarget, setDropTarget] = useState<TreeDropTarget | null>(null);\n const dropTargetRef = useRef<TreeDropTarget | null>(null);\n const onReorderRef = useRef(onReorder);\n const onTreeDropRef = useRef(onTreeDrop);\n const treeModeRef = useRef(treeReorder);\n const depthsRef = useRef<number[]>(depths);\n const isGroupAtRef = useRef<(i: number) => boolean>(isGroupAt);\n // When `dragHandle` is on, a mousedown sets this to whether it landed on a\n // `[data-drag-handle]` element, gating whether the ensuing dragstart is honoured.\n const dragFromHandleRef = useRef(true);\n // In `dragHandle` mode the `draggable` attribute is only on the row whose\n // handle the pointer is currently over (\"armed\"). A permanently `draggable`\n // row breaks mouse text selection (caret placement, double-click word select,\n // drag select) inside any child input in Firefox — see Mozilla bugs 739071 /\n // 800050 / 1189486. Arming on hover rather than on mousedown means the\n // attribute is already in place before the press, so the browser never has to\n // notice it appearing mid-gesture, and any pointer move re-derives it.\n const armedKeyRef = useRef<string | number | null>(null);\n const [armedKey, setArmedKeyState] = useState<string | number | null>(null);\n const longPressRef = useRef<number | null>(null);\n const touchActiveRef = useRef(false);\n const touchStartYRef = useRef<number | null>(null);\n const pointerXRef = useRef(0);\n const pointerYRef = useRef(0);\n const autoScrollRef = useRef<number | null>(null);\n const suppressNextClickRef = useRef(false);\n // Floating clone that follows the finger during a touch drag.\n const dragCloneRef = useRef<HTMLElement | null>(null);\n const grabOffsetYRef = useRef(0);\n const cloneLeftRef = useRef(0);\n const dragHeightRef = useRef(0);\n // The native `draggable` attribute (mouse DnD) makes a long-press start the\n // browser's own drag on touch devices, which hijacks our touch handlers. So\n // expose it only where the primary pointer is fine (mouse/trackpad); touch\n // devices use the touch handlers below instead.\n const [isCoarsePointer] = useState(() =>\n typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia('(pointer: coarse)').matches\n : false,\n );\n\n useLayoutEffect(() => {\n onReorderRef.current = onReorder;\n onTreeDropRef.current = onTreeDrop;\n treeModeRef.current = treeReorder;\n depthsRef.current = depths;\n dropTargetRef.current = dropTarget;\n isGroupAtRef.current = isGroupAt;\n });\n\n // ── Mouse / shared start ──────────────────────────────────────────────────\n\n /** Move the `draggable` attribute to `next` (or off entirely for `null`). */\n function arm(next: string | number | null) {\n // Arming exists purely to place the native `draggable` attribute, which is\n // never set on a coarse pointer (touch uses the handlers below instead). A\n // tap still synthesises mouseover/mousedown, so without this a touch device\n // would re-render the list on every handle tap to no effect whatsoever.\n if (isCoarsePointer) return;\n if (armedKeyRef.current === next) return; // mouseover fires constantly — no-op\n armedKeyRef.current = next;\n setArmedKeyState(next);\n }\n\n // Arm while the pointer rests on this row's handle, disarm as it moves off.\n // `buttons !== 0` means a press is already in progress: the pointer can drift\n // off the handle before the browser reaches its drag threshold, so hover is\n // ignored until release rather than disarming a drag that is about to start.\n function handleRowMouseOver(key: string | number, e: React.MouseEvent<HTMLDivElement>) {\n if (e.buttons !== 0) return;\n arm((e.target as HTMLElement).closest('[data-drag-handle]') ? key : null);\n }\n\n function handleRowMouseLeave(e: React.MouseEvent<HTMLDivElement>) {\n if (e.buttons !== 0) return;\n arm(null);\n }\n\n // With `dragHandle`, remember on mousedown whether the press landed on a\n // handle, so the dragstart that follows can be ignored if it didn't. Arming\n // here too covers a handle that came to sit under an already-stationary cursor\n // (the list scrolled), which produces no mouseover.\n function handleRowMouseDown(key: string | number, e: React.MouseEvent<HTMLDivElement>) {\n if (e.button !== 0) return; // only a primary press can begin a drag\n const fromHandle = !!(e.target as HTMLElement).closest('[data-drag-handle]');\n dragFromHandleRef.current = fromHandle;\n if (fromHandle) arm(key);\n }\n\n function handleReorderStart(key: string | number, e: React.DragEvent<HTMLDivElement>) {\n if (dragHandle && !dragFromHandleRef.current) {\n e.preventDefault(); // not started from a handle — let the row stay put\n return;\n }\n dragKeyRef.current = key;\n setDraggingKey(key);\n if (treeReorder) setDropTarget(null);\n }\n\n // ── Tree mode ─────────────────────────────────────────────────────────────\n\n /** Resolve the tree drop target for the row at `overIndex` under pointer `y`. */\n function computeTreeDrop(overIndex: number, y: number, rect: DOMRect): TreeDropTarget | null {\n const dragKey = dragKeyRef.current;\n if (dragKey == null) return null;\n const fromIndex = keys.indexOf(dragKey);\n // Forbid dropping onto the dragged node or anything in its own subtree.\n if (fromIndex !== -1 && overIndex >= fromIndex && overIndex <= lastDescendantIndex(fromIndex, depths)) {\n return null;\n }\n const position = resolveTreeDropTarget(y, rect.top, rect.height, isGroupAt(overIndex));\n return { key: keys[overIndex], position };\n }\n\n function handleTreeDragOver(overIndex: number, e: React.DragEvent<HTMLDivElement>) {\n e.preventDefault(); // allow the drop\n const rect = e.currentTarget.getBoundingClientRect();\n const next = computeTreeDrop(overIndex, e.clientY, rect);\n setDropTarget((prev) => (prev?.key === next?.key && prev?.position === next?.position ? prev : next));\n }\n\n function commitTreeDrop() {\n const dragKey = dragKeyRef.current;\n const target = dropTargetRef.current;\n if (dragKey != null && target && target.key !== dragKey) onTreeDrop?.(dragKey, target);\n }\n\n function handleTreeDrop(e: React.DragEvent<HTMLDivElement>) {\n e.preventDefault();\n commitTreeDrop();\n setDropTarget(null);\n dragKeyRef.current = null;\n setDraggingKey(null);\n arm(null);\n }\n\n function handleTreeDragEnd() {\n // Fires after `drop` (or on its own when released off a valid target).\n setDropTarget(null);\n dragKeyRef.current = null;\n setDraggingKey(null);\n arm(null);\n }\n\n // ── Flat mode ─────────────────────────────────────────────────────────────\n\n function handleReorderOver(overIndex: number, e: React.DragEvent<HTMLDivElement>) {\n e.preventDefault(); // allow the drop\n const dragKey = dragKeyRef.current;\n if (dragKey == null) return;\n const fromIndex = keys.indexOf(dragKey);\n // Midpoint hysteresis (see resolveReorderTarget): a move only happens once\n // the pointer crosses the centre of the row it's over. After a swap the\n // dragged row sits under the cursor, so moving again needs real pointer\n // travel — this stops the oscillation that made dragging feel jumpy.\n const rect = e.currentTarget.getBoundingClientRect();\n const target = resolveReorderTarget(fromIndex, overIndex, e.clientY, rect.top, rect.height);\n if (target != null) onReorder?.(fromIndex, target);\n }\n\n function handleReorderEnd() {\n dragKeyRef.current = null;\n setDraggingKey(null);\n arm(null);\n }\n\n // ── Touch reordering (long-press to arm, then drag) ──────────────────────────\n // These handlers run from window listeners during a touch drag, so they read\n // mutable state from refs and are stable across renders.\n\n const reorderAtPoint = useCallback(\n (x: number) => {\n const dragKey = dragKeyRef.current;\n const root = rootRef.current;\n if (dragKey == null || !root) return;\n // Reorder against the centre of the lifted clone, not the raw finger — the\n // finger sits below the clone's top by the grab offset, so using it would\n // make the top (and bottom) rows unreachable. The clone is what the user\n // aims with, so match it.\n const y = dragCloneRef.current\n ? pointerYRef.current - grabOffsetYRef.current + dragHeightRef.current / 2\n : pointerYRef.current;\n const el = document.elementFromPoint(x, y) as HTMLElement | null;\n const rowEl = el && root.contains(el) ? el.closest<HTMLElement>('[data-index]') : null;\n if (!rowEl) return;\n const overIndex = Number(rowEl.dataset.index);\n if (Number.isNaN(overIndex)) return;\n const fromIndex = keysRef.current.indexOf(dragKey);\n const rect = rowEl.getBoundingClientRect();\n if (treeModeRef.current) {\n // Tree mode: don't move live — just track where the drop will land.\n const ks = keysRef.current;\n const ds = depthsRef.current;\n if (fromIndex !== -1 && overIndex >= fromIndex && overIndex <= lastDescendantIndex(fromIndex, ds)) {\n setDropTarget(null);\n return;\n }\n const position = resolveTreeDropTarget(y, rect.top, rect.height, isGroupAtRef.current(overIndex));\n const next: TreeDropTarget = { key: ks[overIndex], position };\n setDropTarget((prev) => (prev?.key === next.key && prev?.position === next.position ? prev : next));\n return;\n }\n const target = resolveReorderTarget(fromIndex, overIndex, y, rect.top, rect.height);\n if (target != null) onReorderRef.current?.(fromIndex, target);\n },\n [rootRef, keysRef],\n );\n\n // Keep the floating clone glued under the finger (same grab point).\n const positionDragClone = useCallback(() => {\n const clone = dragCloneRef.current;\n if (!clone) return;\n clone.style.transform = `translate(${cloneLeftRef.current}px, ${pointerYRef.current - grabOffsetYRef.current}px)`;\n }, []);\n\n // While the finger sits near a top/bottom edge (and within the list's width),\n // scroll the list and keep reordering against the rows now passing under it.\n const autoScrollTick = useCallback(() => {\n const root = rootRef.current;\n if (!root || !touchActiveRef.current) {\n autoScrollRef.current = null;\n return;\n }\n const rect = root.getBoundingClientRect();\n const x = pointerXRef.current;\n const y = pointerYRef.current;\n const EDGE = 48;\n let dy = 0;\n // Only auto-scroll while the finger is actually over the list — moving it\n // outside (any direction) stops the scroll instead of running away; pinning\n // the dragged row keeps touch events alive so it resumes when you come back.\n const inside = x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;\n if (inside) {\n if (y < rect.top + EDGE) dy = -Math.min(18, Math.ceil((rect.top + EDGE - y) / 3));\n else if (y > rect.bottom - EDGE) dy = Math.min(18, Math.ceil((y - (rect.bottom - EDGE)) / 3));\n }\n if (dy !== 0) {\n root.scrollTop += dy;\n reorderAtPoint(x);\n }\n autoScrollRef.current = requestAnimationFrame(autoScrollTick);\n }, [reorderAtPoint, rootRef]);\n\n const endTouchDrag = useCallback(() => {\n if (longPressRef.current != null) {\n clearTimeout(longPressRef.current);\n longPressRef.current = null;\n }\n window.removeEventListener('touchmove', handleTouchMove);\n window.removeEventListener('touchend', endTouchDrag);\n window.removeEventListener('touchcancel', endTouchDrag);\n if (autoScrollRef.current != null) {\n cancelAnimationFrame(autoScrollRef.current);\n autoScrollRef.current = null;\n }\n if (dragCloneRef.current) {\n dragCloneRef.current.remove();\n dragCloneRef.current = null;\n }\n // Restore native scrolling that was locked for the duration of the drag.\n document.body.style.touchAction = '';\n document.body.style.overscrollBehavior = '';\n if (touchActiveRef.current) {\n // A real drag happened — swallow the click the browser fires afterwards\n // so it doesn't, e.g., toggle row selection.\n suppressNextClickRef.current = true;\n setTimeout(() => {\n suppressNextClickRef.current = false;\n }, 350);\n // Tree mode commits the pending drop on release (flat mode already moved\n // rows live during the drag, so there's nothing to commit here).\n if (treeModeRef.current) {\n const dk = dragKeyRef.current;\n const target = dropTargetRef.current;\n if (dk != null && target && target.key !== dk) onTreeDropRef.current?.(dk, target);\n }\n }\n setDropTarget(null);\n touchActiveRef.current = false;\n touchStartYRef.current = null;\n dragKeyRef.current = null;\n setDraggingKey(null);\n // handleTouchMove and endTouchDrag remove each other’s listeners, so neither can list\n // the other without a cycle.\n // oxlint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const handleTouchMove = useCallback(\n (e: TouchEvent) => {\n const t = e.touches[0];\n if (!t) return;\n pointerXRef.current = t.clientX;\n pointerYRef.current = t.clientY;\n if (!touchActiveRef.current) {\n // Before the long-press fires: if the finger travels, the user means to\n // scroll, so disarm and let the browser handle it (we don't preventDefault).\n const sy = touchStartYRef.current;\n if (sy != null && Math.abs(t.clientY - sy) > 10 && longPressRef.current != null) {\n clearTimeout(longPressRef.current);\n longPressRef.current = null;\n }\n return;\n }\n // Non-passive listener: preventDefault cancels the native scroll for this\n // gesture — the only reliable way once touch-action has been latched at\n // touchstart. This is what makes the drag actually move on touch devices.\n if (e.cancelable) e.preventDefault();\n positionDragClone();\n reorderAtPoint(t.clientX);\n },\n [reorderAtPoint, positionDragClone],\n );\n\n function handleRowTouchStart(key: string | number, e: React.TouchEvent<HTMLDivElement>) {\n if (!reorderable && !treeReorder) return;\n // With a drag handle, only a press that starts on it arms the drag, so the\n // rest of the row stays free for tapping/typing into inputs.\n if (dragHandle && !(e.target as HTMLElement).closest('[data-drag-handle]')) return;\n if (longPressRef.current != null || touchActiveRef.current) return; // ignore extra fingers\n const t = e.touches[0];\n if (!t) return;\n touchStartYRef.current = t.clientY;\n pointerXRef.current = t.clientX;\n pointerYRef.current = t.clientY;\n window.addEventListener('touchmove', handleTouchMove, { passive: false });\n window.addEventListener('touchend', endTouchDrag);\n window.addEventListener('touchcancel', endTouchDrag);\n longPressRef.current = window.setTimeout(() => {\n longPressRef.current = null;\n touchActiveRef.current = true;\n dragKeyRef.current = key;\n setDraggingKey(key);\n navigator.vibrate?.(10);\n // Lock native scrolling for the whole gesture — relying on per-move\n // preventDefault isn't enough once the finger leaves and re-enters the\n // list (the browser commits to a scroll and ignores it). We do all the\n // scrolling ourselves via autoScrollTick.\n document.body.style.touchAction = 'none';\n document.body.style.overscrollBehavior = 'none';\n createDragClone(key);\n if (autoScrollRef.current == null) autoScrollRef.current = requestAnimationFrame(autoScrollTick);\n }, longPressDelay);\n }\n\n // Build a floating copy of the picked-up row that tracks the finger, so the\n // drag has a visible \"lifted\" element (the original row stays dimmed in place\n // as a drop placeholder).\n function createDragClone(key: string | number) {\n const root = rootRef.current;\n if (!root) return;\n const idx = keysRef.current.indexOf(key);\n const src = root.querySelector<HTMLElement>(`[data-index=\"${idx}\"]`);\n if (!src) return;\n const r = src.getBoundingClientRect();\n grabOffsetYRef.current = pointerYRef.current - r.top;\n cloneLeftRef.current = r.left;\n dragHeightRef.current = r.height;\n const clone = src.cloneNode(true) as HTMLElement;\n clone.removeAttribute('data-index');\n clone.setAttribute('data-drag-clone', 'true');\n clone.setAttribute('aria-hidden', 'true');\n clone.classList.add(styles.virtualListDragClone);\n Object.assign(clone.style, {\n position: 'fixed',\n left: '0',\n top: '0',\n width: `${r.width}px`,\n height: `${r.height}px`,\n margin: '0',\n opacity: '1',\n pointerEvents: 'none',\n // Above the sticky header (z-index 2) and any focused row (z-index 1).\n zIndex: '3',\n background: 'var(--background)',\n boxShadow: 'var(--card-shadow)',\n borderRadius: 'var(--default-border-radius)',\n } as Partial<CSSStyleDeclaration>);\n // Appended inside the list so it inherits the active theme's CSS variables;\n // position:fixed keeps it in viewport coordinates regardless.\n root.appendChild(clone);\n dragCloneRef.current = clone;\n positionDragClone();\n }\n\n // Tear down any in-flight touch drag if the component unmounts mid-gesture.\n useEffect(() => endTouchDrag, [endTouchDrag]);\n\n // Either drag mode arms the same row gestures; the handlers above branch on\n // `treeReorder` for the differing target resolution / commit behaviour.\n const dragEnabled = reorderable || treeReorder;\n // Native mouse DnD is in play for this list. Row-level fallbacks that must\n // cover *every* row — swallowing the browser's own drop and context menu —\n // key off this, not off `draggable`, which in `dragHandle` mode is only ever\n // on the single armed row.\n const mouseDragEnabled = dragEnabled && !isCoarsePointer;\n\n function getRowDragProps(index: number, key: string | number): RowDragProps {\n // The drop indicator only renders on the row currently targeted. `before`/\n // `after` lines indent to the target's depth so they sit under where the\n // dropped content will start; `inside` highlights the whole row instead.\n const rowDrop = treeReorder && dropTarget?.key === key ? dropTarget.position : undefined;\n return {\n // Drives the row-wide grab cursor. With `dragHandle`, only the handle\n // initiates a drag, so the cursor belongs on the handle (styled by the\n // consumer), not across the whole row.\n reorderable: dragEnabled && !dragHandle,\n mouseDragEnabled,\n // In `dragHandle` mode the attribute only goes on the row the pointer has\n // armed, so rows stay text-selectable in Firefox the rest of the time.\n draggable: (mouseDragEnabled && (!dragHandle || key === armedKey)) || undefined,\n isDragging: dragEnabled && key === draggingKey,\n onMouseDown: dragEnabled && dragHandle ? (e) => handleRowMouseDown(key, e) : undefined,\n onMouseOver: dragEnabled && dragHandle ? (e) => handleRowMouseOver(key, e) : undefined,\n onMouseLeave: dragEnabled && dragHandle ? handleRowMouseLeave : undefined,\n onDragStart: dragEnabled ? (e) => handleReorderStart(key, e) : undefined,\n onDragOver: treeReorder\n ? (e) => handleTreeDragOver(index, e)\n : reorderable\n ? (e) => handleReorderOver(index, e)\n : undefined,\n onDragEnd: treeReorder ? handleTreeDragEnd : reorderable ? handleReorderEnd : undefined,\n onDrop: treeReorder ? handleTreeDrop : undefined,\n onTouchStart: dragEnabled ? (e) => handleRowTouchStart(key, e) : undefined,\n dropPosition: rowDrop,\n dropIndentPx: rowDrop ? (depths[index] ?? 0) * treeIndentPx : undefined,\n };\n }\n\n function consumeSuppressedClick(): boolean {\n if (suppressNextClickRef.current) {\n suppressNextClickRef.current = false;\n return true;\n }\n return false;\n }\n\n return { draggingKey, dragEnabled, getRowDragProps, consumeSuppressedClick };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSelection.mjs","names":[],"sources":["../../../../package/common/virtualList/useSelection.ts"],"sourcesContent":["import { useState, useMemo } from 'react';\n\ninterface UseSelectionArgs<T> {\n items: T[];\n getKey: (item: T, index: number) => string | number;\n multiSelect: boolean;\n /** Controlled selected keys. When provided, internal state is ignored. */\n selectedKeys?: Set<string | number>;\n onSelectionChange?: (keys: Set<string | number>) => void;\n}\n\ninterface UseSelectionResult {\n effectiveSelectedKeys: Set<string | number>;\n /** Toggle one row's membership in the selection. */\n handleRowSelect: (key: string | number) => void;\n /** Select all rows, or clear if all are already selected. */\n handleSelectAll: () => void;\n allSelected: boolean;\n someSelected: boolean;\n}\n\n/**\n * Multi-row selection, controlled or uncontrolled. `allSelected`/`someSelected`\n * (for the header checkbox) are O(n) scans, so they're only computed when\n * `multiSelect` is on.\n */\nexport function useSelection<T>({\n items,\n getKey,\n multiSelect,\n selectedKeys,\n onSelectionChange,\n}: UseSelectionArgs<T>): UseSelectionResult {\n const isControlled = selectedKeys !== undefined;\n const [internalSelectedKeys, setInternalSelectedKeys] = useState<Set<string | number>>(new Set());\n const effectiveSelectedKeys = isControlled ? selectedKeys! : internalSelectedKeys;\n\n function applySelection(next: Set<string | number>) {\n if (!isControlled) setInternalSelectedKeys(next);\n onSelectionChange?.(next);\n }\n\n function handleRowSelect(key: string | number) {\n const next = new Set(effectiveSelectedKeys);\n if (next.has(key)) next.delete(key); else next.add(key);\n applySelection(next);\n }\n\n function handleSelectAll() {\n const allKeys = items.map((item, i) => getKey(item, i));\n const allChosen = allKeys.every((k) => effectiveSelectedKeys.has(k));\n applySelection(allChosen ? new Set() : new Set(allKeys));\n }\n\n // O(n) header-checkbox state. The component re-renders every scroll frame\n // (scrollTop is state), but these depend only on the items and the selection —\n // so memoise to keep two full-list scans off the scroll path.\n const { allSelected, someSelected } = useMemo(() => {\n if (!multiSelect || items.length === 0) return { allSelected: false, someSelected: false };\n const all = items.every((item, i) => effectiveSelectedKeys.has(getKey(item, i)));\n const some = !all && items.some((item, i) => effectiveSelectedKeys.has(getKey(item, i)));\n return { allSelected: all, someSelected: some };\n }, [multiSelect, items, effectiveSelectedKeys, getKey]);\n\n return { effectiveSelectedKeys, handleRowSelect, handleSelectAll, allSelected, someSelected };\n}\n"],"mappings":"8CA0BA,SAAgB,EAAgB,CAC9B,QACA,SACA,cACA,eACA,qBAC0C,CAC1C,IAAM,EAAe,IAAiB,IAAA,GAChC,CAAC,EAAsB,GAA2B,EAA+B,IAAI,GAAK,EAC1F,EAAwB,EAAe,EAAgB,EAE7D,SAAS,EAAe,EAA4B,CAC7C,GAAc,EAAwB,CAAI,EAC/C,IAAoB,CAAI,CAC1B,CAEA,SAAS,EAAgB,EAAsB,CAC7C,IAAM,EAAO,IAAI,IAAI,CAAqB,EACtC,EAAK,IAAI,CAAG,EAAG,EAAK,OAAO,CAAG,EAAQ,EAAK,IAAI,CAAG,EACtD,EAAe,CAAI,CACrB,CAEA,SAAS,GAAkB,CACzB,IAAM,EAAU,EAAM,KAAK,EAAM,IAAM,EAAO,EAAM,CAAC,CAAC,EAEtD,EADkB,EAAQ,MAAO,GAAM,EAAsB,IAAI,CAAC,CACnD,EAAY,IAAI,IAAQ,IAAI,IAAI,CAAO,CAAC,CACzD,CAKA,GAAM,CAAE,cAAa,gBAAiB,MAAc,CAClD,GAAI,CAAC,GAAe,EAAM,SAAW,EAAG,MAAO,CAAE,YAAa,GAAO,aAAc,EAAM,EACzF,IAAM,EAAM,EAAM,OAAO,EAAM,IAAM,EAAsB,IAAI,EAAO,EAAM,CAAC,CAAC,CAAC,EAE/E,MAAO,CAAE,YAAa,EAAK,aADd,CAAC,GAAO,EAAM,MAAM,EAAM,IAAM,EAAsB,IAAI,EAAO,EAAM,CAAC,CAAC,CAAC,CACzC,CAChD,EAAG,CAAC,EAAa,EAAO,EAAuB,CAAM,CAAC,EAEtD,MAAO,CAAE,wBAAuB,kBAAiB,kBAAiB,cAAa,cAAa,CAC9F"}
1
+ {"version":3,"file":"useSelection.mjs","names":[],"sources":["../../../../package/common/virtualList/useSelection.ts"],"sourcesContent":["import { useState, useMemo } from 'react';\n\ninterface UseSelectionArgs<T> {\n items: T[];\n getKey: (item: T, index: number) => string | number;\n multiSelect: boolean;\n /** Controlled selected keys. When provided, internal state is ignored. */\n selectedKeys?: Set<string | number>;\n onSelectionChange?: (keys: Set<string | number>) => void;\n}\n\ninterface UseSelectionResult {\n effectiveSelectedKeys: Set<string | number>;\n /** Toggle one row's membership in the selection. */\n handleRowSelect: (key: string | number) => void;\n /** Select all rows, or clear if all are already selected. */\n handleSelectAll: () => void;\n allSelected: boolean;\n someSelected: boolean;\n}\n\n/**\n * Multi-row selection, controlled or uncontrolled. `allSelected`/`someSelected`\n * (for the header checkbox) are O(n) scans, so they're only computed when\n * `multiSelect` is on.\n */\nexport function useSelection<T>({\n items,\n getKey,\n multiSelect,\n selectedKeys,\n onSelectionChange,\n}: UseSelectionArgs<T>): UseSelectionResult {\n const isControlled = selectedKeys !== undefined;\n const [internalSelectedKeys, setInternalSelectedKeys] = useState<Set<string | number>>(new Set());\n const effectiveSelectedKeys = isControlled ? selectedKeys! : internalSelectedKeys;\n\n function applySelection(next: Set<string | number>) {\n if (!isControlled) setInternalSelectedKeys(next);\n onSelectionChange?.(next);\n }\n\n function handleRowSelect(key: string | number) {\n const next = new Set(effectiveSelectedKeys);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n applySelection(next);\n }\n\n function handleSelectAll() {\n const allKeys = items.map((item, i) => getKey(item, i));\n const allChosen = allKeys.every((k) => effectiveSelectedKeys.has(k));\n applySelection(allChosen ? new Set() : new Set(allKeys));\n }\n\n // O(n) header-checkbox state. The component re-renders every scroll frame\n // (scrollTop is state), but these depend only on the items and the selection —\n // so memoise to keep two full-list scans off the scroll path.\n const { allSelected, someSelected } = useMemo(() => {\n if (!multiSelect || items.length === 0) return { allSelected: false, someSelected: false };\n const all = items.every((item, i) => effectiveSelectedKeys.has(getKey(item, i)));\n const some = !all && items.some((item, i) => effectiveSelectedKeys.has(getKey(item, i)));\n return { allSelected: all, someSelected: some };\n }, [multiSelect, items, effectiveSelectedKeys, getKey]);\n\n return { effectiveSelectedKeys, handleRowSelect, handleSelectAll, allSelected, someSelected };\n}\n"],"mappings":"8CA0BA,SAAgB,EAAgB,CAC9B,QACA,SACA,cACA,eACA,qBAC0C,CAC1C,IAAM,EAAe,IAAiB,IAAA,GAChC,CAAC,EAAsB,GAA2B,EAA+B,IAAI,GAAK,EAC1F,EAAwB,EAAe,EAAgB,EAE7D,SAAS,EAAe,EAA4B,CAC7C,GAAc,EAAwB,CAAI,EAC/C,IAAoB,CAAI,CAC1B,CAEA,SAAS,EAAgB,EAAsB,CAC7C,IAAM,EAAO,IAAI,IAAI,CAAqB,EACtC,EAAK,IAAI,CAAG,EAAG,EAAK,OAAO,CAAG,EAC7B,EAAK,IAAI,CAAG,EACjB,EAAe,CAAI,CACrB,CAEA,SAAS,GAAkB,CACzB,IAAM,EAAU,EAAM,KAAK,EAAM,IAAM,EAAO,EAAM,CAAC,CAAC,EAEtD,EADkB,EAAQ,MAAO,GAAM,EAAsB,IAAI,CAAC,CACnD,EAAY,IAAI,IAAQ,IAAI,IAAI,CAAO,CAAC,CACzD,CAKA,GAAM,CAAE,cAAa,gBAAiB,MAAc,CAClD,GAAI,CAAC,GAAe,EAAM,SAAW,EAAG,MAAO,CAAE,YAAa,GAAO,aAAc,EAAM,EACzF,IAAM,EAAM,EAAM,OAAO,EAAM,IAAM,EAAsB,IAAI,EAAO,EAAM,CAAC,CAAC,CAAC,EAE/E,MAAO,CAAE,YAAa,EAAK,aADd,CAAC,GAAO,EAAM,MAAM,EAAM,IAAM,EAAsB,IAAI,EAAO,EAAM,CAAC,CAAC,CAAC,CACzC,CAChD,EAAG,CAAC,EAAa,EAAO,EAAuB,CAAM,CAAC,EAEtD,MAAO,CAAE,wBAAuB,kBAAiB,kBAAiB,cAAa,cAAa,CAC9F"}
@@ -1,2 +1,2 @@
1
- import{buildOffsets as e,findStartIndex as t,getVisibleRange as n}from"./virtualList.utils.mjs";import{useCallback as r,useEffect as i,useLayoutEffect as a,useMemo as o,useRef as s,useState as c}from"react";function l(e,t){if(typeof e==`number`)return e;let n=e.trim();if(n===``)return 0;let r=Number(n);if(!Number.isNaN(r))return r;let i=/^(-?\d*\.?\d+)px$/.exec(n);if(i)return parseFloat(i[1]);if(typeof document>`u`||!t)return 0;let a=document.createElement(`div`);a.style.cssText=`position:absolute;visibility:hidden;height:${n};`,t.appendChild(a);let o=a.getBoundingClientRect().height;return t.removeChild(a),Number.isFinite(o)?o:0}function u({items:u,keys:d,getItemKey:f,estimatedRowHeight:p,rowGap:m,overscan:h,onLoadMore:g,loadMoreThreshold:_,isLoading:v}){let[y,b]=c(0),[x,S]=c(0),[C,w]=c(0),[T,E]=c(()=>l(m,null)),[D,O]=c(new Map),[k,A]=c(!1),j=s(!1),M=s(null),N=s(null),P=s([]),F=s(null),I=s(0),L=s([]),[R]=c(()=>typeof ResizeObserver>`u`?null:new ResizeObserver(e=>{O(t=>{let n=null;for(let r of e){let e=r.target,i=Number(e.dataset.index);if(Number.isNaN(i))continue;let a=L.current[i];if(a===void 0)continue;let o=r.borderBoxSize?.[0],s=o?Math.round(o.blockSize):e.offsetHeight;t.get(a)!==s&&(n||=new Map(t),n.set(a,s))}return n??t})}));i(()=>()=>R?.disconnect(),[R]),a(()=>{let e=M.current;if(!e)return;S(e.clientHeight),w(e.clientWidth);let t=new ResizeObserver(()=>{S(e.clientHeight),w(e.clientWidth)});return t.observe(e),()=>t.disconnect()},[]);let z=s(g);a(()=>{z.current=g});let B=r(()=>{let e=z.current;!e||j.current||(j.current=!0,A(!0),e().finally(()=>{j.current=!1,A(!1)}))},[]),V=r(e=>{let t=e.currentTarget;I.current=t.scrollTop,F.current??=requestAnimationFrame(()=>{F.current=null,b(I.current)}),t.scrollTop+t.clientHeight>=t.scrollHeight-_&&B()},[_,B]);i(()=>()=>{F.current!=null&&cancelAnimationFrame(F.current)},[]),a(()=>{L.current=d}),a(()=>{let e=l(m,M.current);E(t=>t===e?t:e)},[m,C,x]);let{offsets:H,totalHeight:U}=o(()=>e(d,D,p,T),[d,D,p,T]),W=s(``);i(()=>{if(!g||v||k||x===0||U>=x-(N.current?.offsetHeight??0))return;let e=`${u.length}:${x}`;W.current!==e&&(W.current=e,B())},[g,v,k,u.length,U,x,B]),a(()=>{let e=M.current,n=P.current;if(P.current=H,!e||n.length===0)return;let r=e.scrollTop;if(r<=0)return;let i=t(n,r,n.length-1);if(i>=u.length)return;let a=r-n[i],o=H[i]+a;Math.abs(o-r)>.5&&(e.scrollTop=o,I.current=o,b(o))},[H,u.length]);let G=o(()=>{function e(e,t){let n=M.current;if(!n)return;let r=Math.max(0,e);typeof n.scrollTo==`function`?n.scrollTo({top:r,behavior:t??`auto`}):n.scrollTop=r}function t(t,n){let r=M.current;if(!r||u.length===0)return;let i=Math.max(0,Math.min(t,u.length-1)),a=H[i]??0,o=(H[i+1]??a)-a,s=N.current?.offsetHeight??0,c=Math.max(0,r.clientHeight-s),l=n?.align??`start`,d=a-s;l===`center`?d-=(c-o)/2:l===`end`&&(d-=c-o),e(d,n?.behavior)}return{scrollToIndex:t,scrollToKey(e,n){let r=u.findIndex((t,n)=>(f?f(t,n):n)===e);r>=0&&t(r,n)},scrollToTop(t){e(0,t?.behavior)},getScrollElement:()=>M.current}},[u,H,f]),{startIndex:K,endIndex:q}=o(()=>n(H,y,x,h,u.length),[H,y,x,h,u.length]);return{rootRef:M,headerRef:N,rowObserver:R,keysRef:L,offsets:H,totalHeight:U,containerHeight:x,containerWidth:C,startIndex:K,endIndex:q,handleScroll:V,showLoadMoreSpinner:k,scrollApi:G}}export{u as useVirtualWindow};
1
+ import{buildOffsets as e,findStartIndex as t,getVisibleRange as n}from"./virtualList.utils.mjs";import{useCallback as r,useEffect as i,useLayoutEffect as a,useMemo as o,useRef as s,useState as c}from"react";function l(e,t){if(typeof e==`number`)return e;let n=e.trim();if(n===``)return 0;let r=Number(n);if(!Number.isNaN(r))return r;let i=/^(-?\d*\.?\d+)px$/.exec(n);if(i)return parseFloat(i[1]);if(typeof document>`u`||!t)return 0;let a=document.createElement(`div`);a.style.cssText=`position:absolute;visibility:hidden;height:${n};`,t.appendChild(a);let o=a.getBoundingClientRect().height;return t.removeChild(a),Number.isFinite(o)?o:0}function u({items:u,keys:d,getItemKey:f,estimatedRowHeight:p,rowGap:m,overscan:h,onLoadMore:g,loadMoreThreshold:_,isLoading:v}){let[y,b]=c(0),[x,S]=c(0),[C,w]=c(0),[T,E]=c(()=>l(m,null)),[D,O]=c(new Map),[k,A]=c(!1),j=s(!1),M=s(null),N=s(null),P=s([]),F=s(null),I=s(0),L=s([]),[R]=c(()=>typeof ResizeObserver>`u`?null:new ResizeObserver(e=>{O(t=>{let n=null;for(let r of e){let e=r.target,i=Number(e.dataset.index);if(Number.isNaN(i))continue;let a=L.current[i];if(a===void 0)continue;let o=r.borderBoxSize?.[0],s=o?Math.round(o.blockSize):e.offsetHeight;t.get(a)!==s&&(n||=new Map(t),n.set(a,s))}return n??t})}));i(()=>()=>R?.disconnect(),[R]),a(()=>{let e=M.current;if(!e)return;S(e.clientHeight),w(e.clientWidth);let t=new ResizeObserver(()=>{S(e.clientHeight),w(e.clientWidth)});return t.observe(e),()=>t.disconnect()},[]);let z=s(g);a(()=>{z.current=g});let B=r(()=>{let e=z.current;e&&!j.current&&(j.current=!0,A(!0),e().finally(()=>{j.current=!1,A(!1)}))},[]),V=r(e=>{let t=e.currentTarget;I.current=t.scrollTop,F.current??=requestAnimationFrame(()=>{F.current=null,b(I.current)}),t.scrollTop+t.clientHeight>=t.scrollHeight-_&&B()},[_,B]);i(()=>()=>{F.current!=null&&cancelAnimationFrame(F.current)},[]),a(()=>{L.current=d}),a(()=>{let e=l(m,M.current);E(t=>t===e?t:e)},[m,C,x]);let{offsets:H,totalHeight:U}=o(()=>e(d,D,p,T),[d,D,p,T]),W=s(``);i(()=>{if(!g||v||k||x===0)return;let e=N.current?.offsetHeight??0;if(U>=x-e)return;let t=`${u.length}:${x}`;W.current!==t&&(W.current=t,B())},[g,v,k,u.length,U,x,B]),a(()=>{let e=M.current,n=P.current;if(P.current=H,!e||n.length===0)return;let r=e.scrollTop;if(r<=0)return;let i=n.length-1,a=t(n,r,i);if(a>=u.length)return;let o=r-n[a],s=H[a]+o;Math.abs(s-r)>.5&&(e.scrollTop=s,I.current=s,b(s))},[H,u.length]);let G=o(()=>{function e(e,t){let n=M.current;if(!n)return;let r=Math.max(0,e);typeof n.scrollTo==`function`?n.scrollTo({top:r,behavior:t??`auto`}):n.scrollTop=r}function t(t,n){let r=M.current;if(!r||u.length===0)return;let i=Math.max(0,Math.min(t,u.length-1)),a=H[i]??0,o=(H[i+1]??a)-a,s=N.current?.offsetHeight??0,c=Math.max(0,r.clientHeight-s),l=n?.align??`start`,d=a-s;l===`center`?d-=(c-o)/2:l===`end`&&(d-=c-o),e(d,n?.behavior)}return{scrollToIndex:t,scrollToKey(e,n){let r=u.findIndex((t,n)=>(f?f(t,n):n)===e);r>=0&&t(r,n)},scrollToTop(t){e(0,t?.behavior)},getScrollElement:()=>M.current}},[u,H,f]),{startIndex:K,endIndex:q}=o(()=>n(H,y,x,h,u.length),[H,y,x,h,u.length]);return{rootRef:M,headerRef:N,rowObserver:R,keysRef:L,offsets:H,totalHeight:U,containerHeight:x,containerWidth:C,startIndex:K,endIndex:q,handleScroll:V,showLoadMoreSpinner:k,scrollApi:G}}export{u as useVirtualWindow};
2
2
  //# sourceMappingURL=useVirtualWindow.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useVirtualWindow.mjs","names":[],"sources":["../../../../package/common/virtualList/useVirtualWindow.ts"],"sourcesContent":["import React, { useState, useRef, useEffect, useLayoutEffect, useMemo, useCallback } from 'react';\n\nimport { buildOffsets, findStartIndex, getVisibleRange } from './virtualList.utils';\nimport type { VirtualListHandle, VirtualListScrollOptions } from './virtualList.types';\n\n/**\n * Resolve a `rowGap` value to pixels for the offset math. Numbers and plain\n * `px`/numeric strings parse directly (no DOM, SSR/test-safe); any other CSS\n * length (`em`, `rem`, `%`, `var(...)`) is resolved via a hidden probe appended\n * to `contextEl` so it inherits the list's font-size and custom properties.\n */\nfunction resolveCssLength(value: number | string, contextEl: HTMLElement | null): number {\n if (typeof value === 'number') return value;\n const trimmed = value.trim();\n if (trimmed === '') return 0;\n const asNumber = Number(trimmed);\n if (!Number.isNaN(asNumber)) return asNumber; // \"8\" → 8\n const pxMatch = /^(-?\\d*\\.?\\d+)px$/.exec(trimmed);\n if (pxMatch) return parseFloat(pxMatch[1]); // \"8px\" → 8\n if (typeof document === 'undefined' || !contextEl) return 0;\n const probe = document.createElement('div');\n probe.style.cssText = `position:absolute;visibility:hidden;height:${trimmed};`;\n contextEl.appendChild(probe);\n const px = probe.getBoundingClientRect().height;\n contextEl.removeChild(probe);\n return Number.isFinite(px) ? px : 0;\n}\n\ninterface UseVirtualWindowArgs<T> {\n items: T[];\n /** Stable key per row (already derived by the caller). */\n keys: (string | number)[];\n getItemKey?: (item: T, index: number) => string | number;\n estimatedRowHeight: number;\n rowGap: number | string;\n overscan: number;\n onLoadMore?: () => Promise<void>;\n loadMoreThreshold: number;\n /** Initial/filter load in progress — the body is replaced by a spinner. */\n isLoading: boolean;\n}\n\ninterface UseVirtualWindowResult {\n rootRef: React.RefObject<HTMLDivElement | null>;\n headerRef: React.RefObject<HTMLDivElement | null>;\n /** Shared by every row to measure its height (read back via `data-index`). */\n rowObserver: ResizeObserver | null;\n /** Latest index → key mapping, for async consumers (e.g. the drag hook). */\n keysRef: React.RefObject<(string | number)[]>;\n offsets: number[];\n totalHeight: number;\n containerHeight: number;\n containerWidth: number;\n startIndex: number;\n endIndex: number;\n handleScroll: (e: React.UIEvent<HTMLDivElement>) => void;\n showLoadMoreSpinner: boolean;\n /** The scroll-related imperative methods, for the component to compose into\n * the forwarded handle alongside column controls. */\n scrollApi: Omit<VirtualListHandle, 'recalculateColumns'>;\n}\n\n/**\n * The generic virtualization engine: viewport measurement, per-row height\n * caching, offset/visible-range computation, scroll coalescing, scroll\n * anchoring on height changes, infinite-load triggering, and the imperative\n * scroll handle. Mode-agnostic — knows nothing about columns, selection or\n * dragging.\n */\nexport function useVirtualWindow<T>({\n items,\n keys,\n getItemKey,\n estimatedRowHeight,\n rowGap,\n overscan,\n onLoadMore,\n loadMoreThreshold,\n isLoading,\n}: UseVirtualWindowArgs<T>): UseVirtualWindowResult {\n const [scrollTop, setScrollTop] = useState(0);\n const [containerHeight, setContainerHeight] = useState(0);\n const [containerWidth, setContainerWidth] = useState(0);\n // rowGap may be any CSS length; resolve it to px for the offset math. Seed with\n // the synchronous fast path (number / px), then refine before paint for units\n // that need the DOM (em/rem/%/var).\n const [resolvedRowGap, setResolvedRowGap] = useState<number>(() => resolveCssLength(rowGap, null));\n const [heightsMap, setHeightsMap] = useState<Map<string | number, number>>(new Map());\n const [showLoadMoreSpinner, setShowLoadMoreSpinner] = useState(false);\n const isLoadingMoreRef = useRef(false);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const headerRef = useRef<HTMLDivElement>(null);\n const prevOffsetsRef = useRef<number[]>([]);\n const scrollRafRef = useRef<number | null>(null);\n const pendingScrollTopRef = useRef(0);\n const keysRef = useRef<(string | number)[]>([]);\n\n // One ResizeObserver shared by every row, created once via a lazy state\n // initializer so rows mounting in the same commit can register in their\n // layout effect. Batching all entries into a single setState avoids a\n // re-render per row when many rows enter the viewport at once (the main\n // source of scroll jank). The row index is read back from `data-index`.\n const [rowObserver] = useState<ResizeObserver | null>(() => {\n if (typeof ResizeObserver === 'undefined') return null;\n return new ResizeObserver((entries) => {\n setHeightsMap((prev) => {\n let next: Map<string | number, number> | null = null;\n for (const entry of entries) {\n const el = entry.target as HTMLElement;\n const idx = Number(el.dataset.index);\n if (Number.isNaN(idx)) continue;\n // Resolve the row's stable key so the cache survives reorders/filters.\n const key = keysRef.current[idx];\n if (key === undefined) continue;\n // Prefer the size the observer already computed — reading offsetHeight\n // here would force a synchronous reflow on every measurement batch.\n const box = entry.borderBoxSize?.[0];\n const h = box ? Math.round(box.blockSize) : el.offsetHeight;\n if (prev.get(key) === h) continue;\n if (!next) next = new Map(prev);\n next.set(key, h);\n }\n return next ?? prev;\n });\n });\n });\n useEffect(() => () => rowObserver?.disconnect(), [rowObserver]);\n\n useLayoutEffect(() => {\n const el = rootRef.current;\n if (!el) return;\n // Measure synchronously before the first paint so the initial render fills\n // the viewport, instead of painting a few overscan rows and re-rendering.\n setContainerHeight(el.clientHeight);\n setContainerWidth(el.clientWidth);\n // Track width too: `fit` columns are measured against this box and capped at\n // its width, so when the container settles to its real width after a route\n // transition / async layout, that change has to re-trigger the measure —\n // otherwise an early measure against a 0/tiny width gets pinned and sticks.\n const observer = new ResizeObserver(() => {\n setContainerHeight(el.clientHeight);\n setContainerWidth(el.clientWidth);\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n\n // Read through a ref so the trigger below stays stable even when the consumer\n // passes a fresh `onLoadMore` closure on every render.\n const onLoadMoreRef = useRef(onLoadMore);\n useLayoutEffect(() => {\n onLoadMoreRef.current = onLoadMore;\n });\n\n /** Start a load unless one is already in flight (and drive the bottom spinner). */\n const triggerLoadMore = useCallback(() => {\n const load = onLoadMoreRef.current;\n if (!load || isLoadingMoreRef.current) return;\n isLoadingMoreRef.current = true;\n setShowLoadMoreSpinner(true);\n load().finally(() => {\n isLoadingMoreRef.current = false;\n setShowLoadMoreSpinner(false);\n });\n }, []);\n\n const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {\n const el = e.currentTarget;\n // Coalesce scroll-driven re-renders to at most one per animation frame.\n // Scroll events can fire several times per frame (especially while dragging\n // the scrollbar thumb); rendering the visible window once per frame keeps\n // the content in step with the cursor instead of lagging behind.\n pendingScrollTopRef.current = el.scrollTop;\n if (scrollRafRef.current == null) {\n scrollRafRef.current = requestAnimationFrame(() => {\n scrollRafRef.current = null;\n setScrollTop(pendingScrollTopRef.current);\n });\n }\n\n if (el.scrollTop + el.clientHeight >= el.scrollHeight - loadMoreThreshold) triggerLoadMore();\n }, [loadMoreThreshold, triggerLoadMore]);\n\n useEffect(() => () => {\n if (scrollRafRef.current != null) cancelAnimationFrame(scrollRafRef.current);\n }, []);\n\n useLayoutEffect(() => {\n keysRef.current = keys;\n });\n\n // Resolve the gap to px before paint, re-running when the value or the\n // container's layout changes (a theme/font change that alters em/var is caught\n // by the container ResizeObserver feeding containerWidth/Height).\n useLayoutEffect(() => {\n const px = resolveCssLength(rowGap, rootRef.current);\n setResolvedRowGap((prev) => (prev === px ? prev : px));\n }, [rowGap, containerWidth, containerHeight]);\n\n const { offsets, totalHeight } = useMemo(\n () => buildOffsets(keys, heightsMap, estimatedRowHeight, resolvedRowGap),\n [keys, heightsMap, estimatedRowHeight, resolvedRowGap],\n );\n\n // The scroll trigger above can only fire on a list that actually scrolls. When\n // a batch is smaller than the viewport there is no overflow, so no scroll event\n // ever happens and lazy loading dead-ends after the first batch. Keep asking\n // for more until the content overflows; the consumer ends the loop by appending\n // nothing (or by dropping `onLoadMore` once its source is exhausted).\n //\n // Each (row count, viewport height) pair is probed at most once, so rows\n // settling to their measured heights can't re-ask a source that already ran\n // dry, and progress depends entirely on the consumer appending rows.\n const fillProbeRef = useRef('');\n useEffect(() => {\n if (!onLoadMore || isLoading || showLoadMoreSpinner) return;\n // 0 while the list is unmeasured or `display: none` — nothing to fill yet.\n if (containerHeight === 0) return;\n // The sticky header eats into the scroll area, so it isn't usable space.\n const headerH = headerRef.current?.offsetHeight ?? 0;\n if (totalHeight >= containerHeight - headerH) return; // already scrollable\n const probe = `${items.length}:${containerHeight}`;\n if (fillProbeRef.current === probe) return;\n fillProbeRef.current = probe;\n triggerLoadMore();\n }, [\n onLoadMore, isLoading, showLoadMoreSpinner,\n items.length, totalHeight, containerHeight, triggerLoadMore,\n ]);\n\n useLayoutEffect(() => {\n const el = rootRef.current;\n const prevOffsets = prevOffsetsRef.current;\n prevOffsetsRef.current = offsets;\n\n // Nothing to anchor against on the first pass or when pinned at the top.\n if (!el || prevOffsets.length === 0) return;\n const curScrollTop = el.scrollTop;\n if (curScrollTop <= 0) return;\n\n // Scroll anchoring: pin the row at the top of the viewport. Find it under\n // the *previous* offsets, then re-derive scrollTop from its *new* offset so\n // it stays visually fixed when rows above it are measured or resized. This\n // is more robust than summing per-row height deltas — it can't drift, and\n // one correction covers any number of simultaneous changes above the fold.\n const prevCount = prevOffsets.length - 1;\n const anchor = findStartIndex(prevOffsets, curScrollTop, prevCount);\n if (anchor >= items.length) return;\n const within = curScrollTop - prevOffsets[anchor];\n const target = offsets[anchor] + within;\n if (Math.abs(target - curScrollTop) > 0.5) {\n el.scrollTop = target;\n pendingScrollTopRef.current = target;\n setScrollTop(target);\n }\n }, [offsets, items.length]);\n\n const scrollApi = useMemo<Omit<VirtualListHandle, 'recalculateColumns'>>(() => {\n function scrollToOffset(top: number, behavior?: ScrollBehavior) {\n const el = rootRef.current;\n if (!el) return;\n const clamped = Math.max(0, top);\n if (typeof el.scrollTo === 'function') el.scrollTo({ top: clamped, behavior: behavior ?? 'auto' });\n else el.scrollTop = clamped;\n }\n function scrollToIndex(index: number, options?: VirtualListScrollOptions) {\n const el = rootRef.current;\n if (!el || items.length === 0) return;\n const i = Math.max(0, Math.min(index, items.length - 1));\n const rowTop = offsets[i] ?? 0;\n const rowHeight = (offsets[i + 1] ?? rowTop) - rowTop;\n // The sticky header overlaps the top of the scroll area, so the usable\n // viewport starts below it — account for that when aligning.\n const headerH = headerRef.current?.offsetHeight ?? 0;\n const usable = Math.max(0, el.clientHeight - headerH);\n const align = options?.align ?? 'start';\n let top = rowTop - headerH;\n if (align === 'center') top -= (usable - rowHeight) / 2;\n else if (align === 'end') top -= usable - rowHeight;\n scrollToOffset(top, options?.behavior);\n }\n return {\n scrollToIndex,\n scrollToKey(key, options) {\n const i = items.findIndex((item, idx) => (getItemKey ? getItemKey(item, idx) : idx) === key);\n if (i >= 0) scrollToIndex(i, options);\n },\n scrollToTop(options) {\n scrollToOffset(0, options?.behavior);\n },\n getScrollElement: () => rootRef.current,\n };\n }, [items, offsets, getItemKey]);\n\n const { startIndex, endIndex } = useMemo(\n () => getVisibleRange(offsets, scrollTop, containerHeight, overscan, items.length),\n [offsets, scrollTop, containerHeight, overscan, items.length],\n );\n\n return {\n rootRef,\n headerRef,\n rowObserver,\n keysRef,\n offsets,\n totalHeight,\n containerHeight,\n containerWidth,\n startIndex,\n endIndex,\n handleScroll,\n showLoadMoreSpinner,\n scrollApi,\n };\n}\n"],"mappings":"+MAWA,SAAS,EAAiB,EAAwB,EAAuC,CACvF,GAAI,OAAO,GAAU,SAAU,OAAO,EACtC,IAAM,EAAU,EAAM,KAAK,EAC3B,GAAI,IAAY,GAAI,MAAO,GAC3B,IAAM,EAAW,OAAO,CAAO,EAC/B,GAAI,CAAC,OAAO,MAAM,CAAQ,EAAG,OAAO,EACpC,IAAM,EAAU,oBAAoB,KAAK,CAAO,EAChD,GAAI,EAAS,OAAO,WAAW,EAAQ,EAAE,EACzC,GAAI,OAAO,SAAa,KAAe,CAAC,EAAW,MAAO,GAC1D,IAAM,EAAQ,SAAS,cAAc,KAAK,EAC1C,EAAM,MAAM,QAAU,8CAA8C,EAAQ,GAC5E,EAAU,YAAY,CAAK,EAC3B,IAAM,EAAK,EAAM,sBAAsB,EAAE,OAEzC,OADA,EAAU,YAAY,CAAK,EACpB,OAAO,SAAS,CAAE,EAAI,EAAK,CACpC,CA2CA,SAAgB,EAAoB,CAClC,QACA,OACA,aACA,qBACA,SACA,WACA,aACA,oBACA,aACkD,CAClD,GAAM,CAAC,EAAW,GAAgB,EAAS,CAAC,EACtC,CAAC,EAAiB,GAAsB,EAAS,CAAC,EAClD,CAAC,EAAgB,GAAqB,EAAS,CAAC,EAIhD,CAAC,EAAgB,GAAqB,MAAuB,EAAiB,EAAQ,IAAI,CAAC,EAC3F,CAAC,EAAY,GAAiB,EAAuC,IAAI,GAAK,EAC9E,CAAC,EAAqB,GAA0B,EAAS,EAAK,EAC9D,EAAmB,EAAO,EAAK,EAE/B,EAAU,EAAuB,IAAI,EACrC,EAAY,EAAuB,IAAI,EACvC,EAAiB,EAAiB,CAAC,CAAC,EACpC,EAAe,EAAsB,IAAI,EACzC,EAAsB,EAAO,CAAC,EAC9B,EAAU,EAA4B,CAAC,CAAC,EAOxC,CAAC,GAAe,MAChB,OAAO,eAAmB,IAAoB,KAC3C,IAAI,eAAgB,GAAY,CACrC,EAAe,GAAS,CACtB,IAAI,EAA4C,KAChD,IAAK,IAAM,KAAS,EAAS,CAC3B,IAAM,EAAK,EAAM,OACX,EAAM,OAAO,EAAG,QAAQ,KAAK,EACnC,GAAI,OAAO,MAAM,CAAG,EAAG,SAEvB,IAAM,EAAM,EAAQ,QAAQ,GAC5B,GAAI,IAAQ,IAAA,GAAW,SAGvB,IAAM,EAAM,EAAM,gBAAgB,GAC5B,EAAI,EAAM,KAAK,MAAM,EAAI,SAAS,EAAI,EAAG,aAC3C,EAAK,IAAI,CAAG,IAAM,IACtB,AAAW,IAAO,IAAI,IAAI,CAAI,EAC9B,EAAK,IAAI,EAAK,CAAC,EACjB,CACA,OAAO,GAAQ,CACjB,CAAC,CACH,CAAC,CACF,EACD,UAAsB,GAAa,WAAW,EAAG,CAAC,CAAW,CAAC,EAE9D,MAAsB,CACpB,IAAM,EAAK,EAAQ,QACnB,GAAI,CAAC,EAAI,OAGT,EAAmB,EAAG,YAAY,EAClC,EAAkB,EAAG,WAAW,EAKhC,IAAM,EAAW,IAAI,mBAAqB,CACxC,EAAmB,EAAG,YAAY,EAClC,EAAkB,EAAG,WAAW,CAClC,CAAC,EAED,OADA,EAAS,QAAQ,CAAE,MACN,EAAS,WAAW,CACnC,EAAG,CAAC,CAAC,EAIL,IAAM,EAAgB,EAAO,CAAU,EACvC,MAAsB,CACpB,EAAc,QAAU,CAC1B,CAAC,EAGD,IAAM,EAAkB,MAAkB,CACxC,IAAM,EAAO,EAAc,QACvB,CAAC,GAAQ,EAAiB,UAC9B,EAAiB,QAAU,GAC3B,EAAuB,EAAI,EAC3B,EAAK,EAAE,YAAc,CACnB,EAAiB,QAAU,GAC3B,EAAuB,EAAK,CAC9B,CAAC,EACH,EAAG,CAAC,CAAC,EAEC,EAAe,EAAa,GAAqC,CACrE,IAAM,EAAK,EAAE,cAKb,EAAoB,QAAU,EAAG,UACjC,AACE,EAAa,UAAU,0BAA4B,CACjD,EAAa,QAAU,KACvB,EAAa,EAAoB,OAAO,CAC1C,CAAC,EAGC,EAAG,UAAY,EAAG,cAAgB,EAAG,aAAe,GAAmB,EAAgB,CAC7F,EAAG,CAAC,EAAmB,CAAe,CAAC,EAEvC,UAAsB,CAChB,EAAa,SAAW,MAAM,qBAAqB,EAAa,OAAO,CAC7E,EAAG,CAAC,CAAC,EAEL,MAAsB,CACpB,EAAQ,QAAU,CACpB,CAAC,EAKD,MAAsB,CACpB,IAAM,EAAK,EAAiB,EAAQ,EAAQ,OAAO,EACnD,EAAmB,GAAU,IAAS,EAAK,EAAO,CAAG,CACvD,EAAG,CAAC,EAAQ,EAAgB,CAAe,CAAC,EAE5C,GAAM,CAAE,UAAS,eAAgB,MACzB,EAAa,EAAM,EAAY,EAAoB,CAAc,EACvE,CAAC,EAAM,EAAY,EAAoB,CAAc,CACvD,EAWM,EAAe,EAAO,EAAE,EAC9B,MAAgB,CAMd,GALI,CAAC,GAAc,GAAa,GAE5B,IAAoB,GAGpB,GAAe,GADH,EAAU,SAAS,cAAgB,GACL,OAC9C,IAAM,EAAQ,GAAG,EAAM,OAAO,GAAG,IAC7B,EAAa,UAAY,IAC7B,EAAa,QAAU,EACvB,EAAgB,EAClB,EAAG,CACD,EAAY,EAAW,EACvB,EAAM,OAAQ,EAAa,EAAiB,CAC9C,CAAC,EAED,MAAsB,CACpB,IAAM,EAAK,EAAQ,QACb,EAAc,EAAe,QAInC,GAHA,EAAe,QAAU,EAGrB,CAAC,GAAM,EAAY,SAAW,EAAG,OACrC,IAAM,EAAe,EAAG,UACxB,GAAI,GAAgB,EAAG,OAQvB,IAAM,EAAS,EAAe,EAAa,EADzB,EAAY,OAAS,CAC2B,EAClE,GAAI,GAAU,EAAM,OAAQ,OAC5B,IAAM,EAAS,EAAe,EAAY,GACpC,EAAS,EAAQ,GAAU,EAC7B,KAAK,IAAI,EAAS,CAAY,EAAI,KACpC,EAAG,UAAY,EACf,EAAoB,QAAU,EAC9B,EAAa,CAAM,EAEvB,EAAG,CAAC,EAAS,EAAM,MAAM,CAAC,EAE1B,IAAM,EAAY,MAA6D,CAC7E,SAAS,EAAe,EAAa,EAA2B,CAC9D,IAAM,EAAK,EAAQ,QACnB,GAAI,CAAC,EAAI,OACT,IAAM,EAAU,KAAK,IAAI,EAAG,CAAG,EAC3B,OAAO,EAAG,UAAa,WAAY,EAAG,SAAS,CAAE,IAAK,EAAS,SAAU,GAAY,MAAO,CAAC,EAC5F,EAAG,UAAY,CACtB,CACA,SAAS,EAAc,EAAe,EAAoC,CACxE,IAAM,EAAK,EAAQ,QACnB,GAAI,CAAC,GAAM,EAAM,SAAW,EAAG,OAC/B,IAAM,EAAI,KAAK,IAAI,EAAG,KAAK,IAAI,EAAO,EAAM,OAAS,CAAC,CAAC,EACjD,EAAS,EAAQ,IAAM,EACvB,GAAa,EAAQ,EAAI,IAAM,GAAU,EAGzC,EAAU,EAAU,SAAS,cAAgB,EAC7C,EAAS,KAAK,IAAI,EAAG,EAAG,aAAe,CAAO,EAC9C,EAAQ,GAAS,OAAS,QAC5B,EAAM,EAAS,EACf,IAAU,SAAU,IAAQ,EAAS,GAAa,EAC7C,IAAU,QAAO,GAAO,EAAS,GAC1C,EAAe,EAAK,GAAS,QAAQ,CACvC,CACA,MAAO,CACL,gBACA,YAAY,EAAK,EAAS,CACxB,IAAM,EAAI,EAAM,WAAW,EAAM,KAAS,EAAa,EAAW,EAAM,CAAG,EAAI,KAAS,CAAG,EACvF,GAAK,GAAG,EAAc,EAAG,CAAO,CACtC,EACA,YAAY,EAAS,CACnB,EAAe,EAAG,GAAS,QAAQ,CACrC,EACA,qBAAwB,EAAQ,OAClC,CACF,EAAG,CAAC,EAAO,EAAS,CAAU,CAAC,EAEzB,CAAE,aAAY,YAAa,MACzB,EAAgB,EAAS,EAAW,EAAiB,EAAU,EAAM,MAAM,EACjF,CAAC,EAAS,EAAW,EAAiB,EAAU,EAAM,MAAM,CAC9D,EAEA,MAAO,CACL,UACA,YACA,cACA,UACA,UACA,cACA,kBACA,iBACA,aACA,WACA,eACA,sBACA,WACF,CACF"}
1
+ {"version":3,"file":"useVirtualWindow.mjs","names":[],"sources":["../../../../package/common/virtualList/useVirtualWindow.ts"],"sourcesContent":["import React, { useState, useRef, useEffect, useLayoutEffect, useMemo, useCallback } from 'react';\n\nimport { buildOffsets, findStartIndex, getVisibleRange } from './virtualList.utils';\nimport type { VirtualListHandle, VirtualListScrollOptions } from './virtualList.types';\n\n/**\n * Resolve a `rowGap` value to pixels for the offset math. Numbers and plain\n * `px`/numeric strings parse directly (no DOM, SSR/test-safe); any other CSS\n * length (`em`, `rem`, `%`, `var(...)`) is resolved via a hidden probe appended\n * to `contextEl` so it inherits the list's font-size and custom properties.\n */\nfunction resolveCssLength(value: number | string, contextEl: HTMLElement | null): number {\n if (typeof value === 'number') return value;\n const trimmed = value.trim();\n if (trimmed === '') return 0;\n const asNumber = Number(trimmed);\n if (!Number.isNaN(asNumber)) return asNumber; // \"8\" → 8\n const pxMatch = /^(-?\\d*\\.?\\d+)px$/.exec(trimmed);\n if (pxMatch) return parseFloat(pxMatch[1]); // \"8px\" → 8\n if (typeof document === 'undefined' || !contextEl) return 0;\n const probe = document.createElement('div');\n probe.style.cssText = `position:absolute;visibility:hidden;height:${trimmed};`;\n contextEl.appendChild(probe);\n const px = probe.getBoundingClientRect().height;\n contextEl.removeChild(probe);\n return Number.isFinite(px) ? px : 0;\n}\n\ninterface UseVirtualWindowArgs<T> {\n items: T[];\n /** Stable key per row (already derived by the caller). */\n keys: (string | number)[];\n getItemKey?: (item: T, index: number) => string | number;\n estimatedRowHeight: number;\n rowGap: number | string;\n overscan: number;\n onLoadMore?: () => Promise<void>;\n loadMoreThreshold: number;\n /** Initial/filter load in progress — the body is replaced by a spinner. */\n isLoading: boolean;\n}\n\ninterface UseVirtualWindowResult {\n rootRef: React.RefObject<HTMLDivElement | null>;\n headerRef: React.RefObject<HTMLDivElement | null>;\n /** Shared by every row to measure its height (read back via `data-index`). */\n rowObserver: ResizeObserver | null;\n /** Latest index → key mapping, for async consumers (e.g. the drag hook). */\n keysRef: React.RefObject<(string | number)[]>;\n offsets: number[];\n totalHeight: number;\n containerHeight: number;\n containerWidth: number;\n startIndex: number;\n endIndex: number;\n handleScroll: (e: React.UIEvent<HTMLDivElement>) => void;\n showLoadMoreSpinner: boolean;\n /** The scroll-related imperative methods, for the component to compose into\n * the forwarded handle alongside column controls. */\n scrollApi: Omit<VirtualListHandle, 'recalculateColumns'>;\n}\n\n/**\n * The generic virtualization engine: viewport measurement, per-row height\n * caching, offset/visible-range computation, scroll coalescing, scroll\n * anchoring on height changes, infinite-load triggering, and the imperative\n * scroll handle. Mode-agnostic — knows nothing about columns, selection or\n * dragging.\n */\nexport function useVirtualWindow<T>({\n items,\n keys,\n getItemKey,\n estimatedRowHeight,\n rowGap,\n overscan,\n onLoadMore,\n loadMoreThreshold,\n isLoading,\n}: UseVirtualWindowArgs<T>): UseVirtualWindowResult {\n const [scrollTop, setScrollTop] = useState(0);\n const [containerHeight, setContainerHeight] = useState(0);\n const [containerWidth, setContainerWidth] = useState(0);\n // rowGap may be any CSS length; resolve it to px for the offset math. Seed with\n // the synchronous fast path (number / px), then refine before paint for units\n // that need the DOM (em/rem/%/var).\n const [resolvedRowGap, setResolvedRowGap] = useState<number>(() => resolveCssLength(rowGap, null));\n const [heightsMap, setHeightsMap] = useState<Map<string | number, number>>(new Map());\n const [showLoadMoreSpinner, setShowLoadMoreSpinner] = useState(false);\n const isLoadingMoreRef = useRef(false);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const headerRef = useRef<HTMLDivElement>(null);\n const prevOffsetsRef = useRef<number[]>([]);\n const scrollRafRef = useRef<number | null>(null);\n const pendingScrollTopRef = useRef(0);\n const keysRef = useRef<(string | number)[]>([]);\n\n // One ResizeObserver shared by every row, created once via a lazy state\n // initializer so rows mounting in the same commit can register in their\n // layout effect. Batching all entries into a single setState avoids a\n // re-render per row when many rows enter the viewport at once (the main\n // source of scroll jank). The row index is read back from `data-index`.\n const [rowObserver] = useState<ResizeObserver | null>(() => {\n if (typeof ResizeObserver === 'undefined') return null;\n return new ResizeObserver((entries) => {\n setHeightsMap((prev) => {\n let next: Map<string | number, number> | null = null;\n for (const entry of entries) {\n const el = entry.target as HTMLElement;\n const idx = Number(el.dataset.index);\n if (Number.isNaN(idx)) continue;\n // Resolve the row's stable key so the cache survives reorders/filters.\n const key = keysRef.current[idx];\n if (key === undefined) continue;\n // Prefer the size the observer already computed — reading offsetHeight\n // here would force a synchronous reflow on every measurement batch.\n const box = entry.borderBoxSize?.[0];\n const h = box ? Math.round(box.blockSize) : el.offsetHeight;\n if (prev.get(key) === h) continue;\n if (!next) next = new Map(prev);\n next.set(key, h);\n }\n return next ?? prev;\n });\n });\n });\n useEffect(() => () => rowObserver?.disconnect(), [rowObserver]);\n\n useLayoutEffect(() => {\n const el = rootRef.current;\n if (!el) return;\n // Measure synchronously before the first paint so the initial render fills\n // the viewport, instead of painting a few overscan rows and re-rendering.\n setContainerHeight(el.clientHeight);\n setContainerWidth(el.clientWidth);\n // Track width too: `fit` columns are measured against this box and capped at\n // its width, so when the container settles to its real width after a route\n // transition / async layout, that change has to re-trigger the measure —\n // otherwise an early measure against a 0/tiny width gets pinned and sticks.\n const observer = new ResizeObserver(() => {\n setContainerHeight(el.clientHeight);\n setContainerWidth(el.clientWidth);\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n\n // Read through a ref so the trigger below stays stable even when the consumer\n // passes a fresh `onLoadMore` closure on every render.\n const onLoadMoreRef = useRef(onLoadMore);\n useLayoutEffect(() => {\n onLoadMoreRef.current = onLoadMore;\n });\n\n /** Start a load unless one is already in flight (and drive the bottom spinner). */\n const triggerLoadMore = useCallback(() => {\n const load = onLoadMoreRef.current;\n if (!load || isLoadingMoreRef.current) return;\n isLoadingMoreRef.current = true;\n setShowLoadMoreSpinner(true);\n load().finally(() => {\n isLoadingMoreRef.current = false;\n setShowLoadMoreSpinner(false);\n });\n }, []);\n\n const handleScroll = useCallback(\n (e: React.UIEvent<HTMLDivElement>) => {\n const el = e.currentTarget;\n // Coalesce scroll-driven re-renders to at most one per animation frame.\n // Scroll events can fire several times per frame (especially while dragging\n // the scrollbar thumb); rendering the visible window once per frame keeps\n // the content in step with the cursor instead of lagging behind.\n pendingScrollTopRef.current = el.scrollTop;\n if (scrollRafRef.current == null) {\n scrollRafRef.current = requestAnimationFrame(() => {\n scrollRafRef.current = null;\n setScrollTop(pendingScrollTopRef.current);\n });\n }\n\n if (el.scrollTop + el.clientHeight >= el.scrollHeight - loadMoreThreshold) triggerLoadMore();\n },\n [loadMoreThreshold, triggerLoadMore],\n );\n\n useEffect(\n () => () => {\n if (scrollRafRef.current != null) cancelAnimationFrame(scrollRafRef.current);\n },\n [],\n );\n\n useLayoutEffect(() => {\n keysRef.current = keys;\n });\n\n // Resolve the gap to px before paint, re-running when the value or the\n // container's layout changes (a theme/font change that alters em/var is caught\n // by the container ResizeObserver feeding containerWidth/Height).\n useLayoutEffect(() => {\n const px = resolveCssLength(rowGap, rootRef.current);\n setResolvedRowGap((prev) => (prev === px ? prev : px));\n }, [rowGap, containerWidth, containerHeight]);\n\n const { offsets, totalHeight } = useMemo(\n () => buildOffsets(keys, heightsMap, estimatedRowHeight, resolvedRowGap),\n [keys, heightsMap, estimatedRowHeight, resolvedRowGap],\n );\n\n // The scroll trigger above can only fire on a list that actually scrolls. When\n // a batch is smaller than the viewport there is no overflow, so no scroll event\n // ever happens and lazy loading dead-ends after the first batch. Keep asking\n // for more until the content overflows; the consumer ends the loop by appending\n // nothing (or by dropping `onLoadMore` once its source is exhausted).\n //\n // Each (row count, viewport height) pair is probed at most once, so rows\n // settling to their measured heights can't re-ask a source that already ran\n // dry, and progress depends entirely on the consumer appending rows.\n const fillProbeRef = useRef('');\n useEffect(() => {\n if (!onLoadMore || isLoading || showLoadMoreSpinner) return;\n // 0 while the list is unmeasured or `display: none` — nothing to fill yet.\n if (containerHeight === 0) return;\n // The sticky header eats into the scroll area, so it isn't usable space.\n const headerH = headerRef.current?.offsetHeight ?? 0;\n if (totalHeight >= containerHeight - headerH) return; // already scrollable\n const probe = `${items.length}:${containerHeight}`;\n if (fillProbeRef.current === probe) return;\n fillProbeRef.current = probe;\n triggerLoadMore();\n }, [onLoadMore, isLoading, showLoadMoreSpinner, items.length, totalHeight, containerHeight, triggerLoadMore]);\n\n useLayoutEffect(() => {\n const el = rootRef.current;\n const prevOffsets = prevOffsetsRef.current;\n prevOffsetsRef.current = offsets;\n\n // Nothing to anchor against on the first pass or when pinned at the top.\n if (!el || prevOffsets.length === 0) return;\n const curScrollTop = el.scrollTop;\n if (curScrollTop <= 0) return;\n\n // Scroll anchoring: pin the row at the top of the viewport. Find it under\n // the *previous* offsets, then re-derive scrollTop from its *new* offset so\n // it stays visually fixed when rows above it are measured or resized. This\n // is more robust than summing per-row height deltas — it can't drift, and\n // one correction covers any number of simultaneous changes above the fold.\n const prevCount = prevOffsets.length - 1;\n const anchor = findStartIndex(prevOffsets, curScrollTop, prevCount);\n if (anchor >= items.length) return;\n const within = curScrollTop - prevOffsets[anchor];\n const target = offsets[anchor] + within;\n if (Math.abs(target - curScrollTop) > 0.5) {\n el.scrollTop = target;\n pendingScrollTopRef.current = target;\n setScrollTop(target);\n }\n }, [offsets, items.length]);\n\n const scrollApi = useMemo<Omit<VirtualListHandle, 'recalculateColumns'>>(() => {\n function scrollToOffset(top: number, behavior?: ScrollBehavior) {\n const el = rootRef.current;\n if (!el) return;\n const clamped = Math.max(0, top);\n if (typeof el.scrollTo === 'function') el.scrollTo({ top: clamped, behavior: behavior ?? 'auto' });\n else el.scrollTop = clamped;\n }\n function scrollToIndex(index: number, options?: VirtualListScrollOptions) {\n const el = rootRef.current;\n if (!el || items.length === 0) return;\n const i = Math.max(0, Math.min(index, items.length - 1));\n const rowTop = offsets[i] ?? 0;\n const rowHeight = (offsets[i + 1] ?? rowTop) - rowTop;\n // The sticky header overlaps the top of the scroll area, so the usable\n // viewport starts below it — account for that when aligning.\n const headerH = headerRef.current?.offsetHeight ?? 0;\n const usable = Math.max(0, el.clientHeight - headerH);\n const align = options?.align ?? 'start';\n let top = rowTop - headerH;\n if (align === 'center') top -= (usable - rowHeight) / 2;\n else if (align === 'end') top -= usable - rowHeight;\n scrollToOffset(top, options?.behavior);\n }\n return {\n scrollToIndex,\n scrollToKey(key, options) {\n const i = items.findIndex((item, idx) => (getItemKey ? getItemKey(item, idx) : idx) === key);\n if (i >= 0) scrollToIndex(i, options);\n },\n scrollToTop(options) {\n scrollToOffset(0, options?.behavior);\n },\n getScrollElement: () => rootRef.current,\n };\n }, [items, offsets, getItemKey]);\n\n const { startIndex, endIndex } = useMemo(\n () => getVisibleRange(offsets, scrollTop, containerHeight, overscan, items.length),\n [offsets, scrollTop, containerHeight, overscan, items.length],\n );\n\n return {\n rootRef,\n headerRef,\n rowObserver,\n keysRef,\n offsets,\n totalHeight,\n containerHeight,\n containerWidth,\n startIndex,\n endIndex,\n handleScroll,\n showLoadMoreSpinner,\n scrollApi,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"virtualList.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualList.tsx"],"sourcesContent":["import React, { useMemo, useCallback, useImperativeHandle } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faGear } from '@fortawesome/free-solid-svg-icons';\n\nimport styles from './virtualList.module.pcss';\nimport SpinnerLoading from '../loading/spinnerLoading';\nimport Checkbox from '../checkbox';\nimport FloatingMenu, { Align } from '../floatingMenu';\nimport VirtualRow from './virtualRow';\nimport { useVirtualWindow } from './useVirtualWindow';\nimport { useSelection } from './useSelection';\nimport { useColumns } from './useColumns';\nimport { useRowDrag } from './useRowDrag';\nimport type { VirtualListProps, VirtualListHandle } from './virtualList.types';\n\n// Pure helpers live in ./virtualList.utils; re-exported here so existing\n// imports (and unit tests) keep working against the component entry point.\nexport {\n buildOffsets,\n findStartIndex,\n getVisibleRange,\n resolveReorderTarget,\n resolveTreeDropTarget,\n lastDescendantIndex,\n buildColumnTemplate,\n} from './virtualList.utils';\n\n// ─── Orchestrator ─────────────────────────────────────────────────────────────\n// VirtualListInner wires four focused hooks together and renders. Each concern\n// lives in its own module:\n// useVirtualWindow — generic scroll / measurement / windowing (all modes)\n// useSelection — multi-row selection\n// useColumns — table mode: columns, visibility, persistence, fit widths\n// useRowDrag — reorder + tree drag-and-drop (mouse + touch)\n\nfunction VirtualListInner<T>({\n items,\n renderRow,\n ariaRoles,\n columns,\n height = '100%',\n estimatedRowHeight = 40,\n overscan = 3,\n rowGap = 0,\n rowPadding,\n selectedKey,\n getItemKey,\n onRowClick,\n visibleColumnKeys,\n onVisibleColumnsChange,\n persistColumnsKey,\n showColumnToggle,\n onLoadMore,\n loadMoreThreshold = 100,\n isLoading = false,\n multiSelect = false,\n selectedKeys,\n onSelectionChange,\n reorderable = false,\n onReorder,\n longPressDelay = 400,\n treeReorder = false,\n getItemDepth,\n isGroup,\n onTreeDrop,\n treeIndentPx = 24,\n dragHandle = false,\n showDivider = true,\n rowHover = true,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: VirtualListProps<T>, ref: React.ForwardedRef<VirtualListHandle>) {\n const getKey = useCallback(\n (item: T, index: number): string | number => (getItemKey ? getItemKey(item, index) : index),\n [getItemKey],\n );\n const keys = useMemo(() => items.map((item, i) => getKey(item, i)), [items, getKey]);\n const depths = useMemo(\n () => (getItemDepth ? items.map((item, i) => getItemDepth(item, i)) : []),\n [items, getItemDepth],\n );\n const isGroupAt = useCallback(\n (i: number) => (isGroup ? isGroup(items[i], i) : false),\n [isGroup, items],\n );\n\n const win = useVirtualWindow<T>({\n items, keys, getItemKey, estimatedRowHeight, rowGap, overscan,\n onLoadMore, loadMoreThreshold, isLoading,\n });\n const { rootRef, headerRef, rowObserver, keysRef, offsets, totalHeight, startIndex, endIndex } = win;\n\n const selection = useSelection<T>({ items, getKey, multiSelect, selectedKeys, onSelectionChange });\n const { effectiveSelectedKeys } = selection;\n\n const cols = useColumns<T>({\n columns, items, multiSelect, visibleColumnKeys, onVisibleColumnsChange, persistColumnsKey,\n showColumnToggle, rootRef, startIndex, endIndex,\n containerHeight: win.containerHeight, containerWidth: win.containerWidth,\n });\n const {\n hasColumns, visibleColumns, columnTemplate, shouldShowToggle, effectiveVisible, manuallyHiddenCount,\n toggleOpen, setToggleOpen, handleToggleColumn, recalculateColumns,\n } = cols;\n\n // Compose the forwarded handle from both hooks: scroll methods come from the\n // windowing engine, column controls from the column hook.\n useImperativeHandle(\n ref,\n () => ({ ...win.scrollApi, recalculateColumns }),\n [win.scrollApi, recalculateColumns],\n );\n\n const drag = useRowDrag({\n reorderable, treeReorder, onReorder, onTreeDrop, longPressDelay, dragHandle, treeIndentPx,\n keys, depths, isGroupAt, rootRef, keysRef,\n });\n\n const rowPaddingValue = typeof rowPadding === 'number' ? `${rowPadding}px` : rowPadding;\n\n const renderRowAt = (i: number) => {\n const item = items[i];\n const key = getKey(item, i);\n const isSelected = (selectedKey != null && key === selectedKey) || effectiveSelectedKeys.has(key);\n const dragProps = drag.getRowDragProps(i, key);\n\n return (\n <VirtualRow\n key={key}\n index={i}\n top={offsets[i]}\n padding={rowPaddingValue}\n columnTemplate={columnTemplate}\n isSelected={isSelected}\n showDivider={showDivider}\n hover={rowHover}\n onClick={() => {\n if (drag.consumeSuppressedClick()) return;\n onRowClick?.(item, i);\n }}\n observer={rowObserver}\n ariaRowIndex={hasColumns ? i + 2 : undefined}\n ariaPosInSet={hasColumns ? undefined : i + 1}\n ariaSetSize={hasColumns ? undefined : items.length}\n rowRole={ariaRoles?.row ?? (hasColumns ? 'row' : 'listitem')}\n reserveToggleGutter={shouldShowToggle}\n {...dragProps}\n dropIndicatorClassName={classNames?.dropIndicator}\n dropIndicatorStyle={slotStyles?.dropIndicator}\n rowClassName={classNames?.row}\n rowStyle={slotStyles?.row}\n >\n {hasColumns\n ? <>\n {multiSelect && (\n <div\n className={cx(styles.virtualListSelectCell, classNames?.selectCell)}\n style={slotStyles?.selectCell}\n role=\"gridcell\"\n onClick={(e) => e.stopPropagation()}\n >\n <Checkbox\n selected={effectiveSelectedKeys.has(key)}\n onToggle={() => selection.handleRowSelect(key)}\n aria-label=\"Select row\"\n />\n </div>\n )}\n {visibleColumns.map((col) => (\n <div\n key={col.key}\n className={cx(styles.virtualListCell, classNames?.cell)}\n style={slotStyles?.cell}\n role=\"gridcell\"\n data-fit-key={col.width.type === 'fit' ? col.key : undefined}\n >\n {col.renderCell(item, i)}\n </div>\n ))}\n </>\n : renderRow?.(item, i)}\n </VirtualRow>\n );\n };\n\n const visibleRows: React.ReactNode[] = [];\n for (let i = startIndex; i <= endIndex; i++) visibleRows.push(renderRowAt(i));\n\n // Keep the row being touch-dragged mounted even if it scrolls out of the\n // window. Touch events are dispatched to the element under the finger at\n // touchstart; if that row unmounts, the browser stops delivering touchmove\n // and the drag freezes. Pinning its DOM node keeps the gesture alive.\n const draggedIndex = drag.draggingKey != null ? keys.indexOf(drag.draggingKey) : -1;\n if (draggedIndex >= 0 && (draggedIndex < startIndex || draggedIndex > endIndex)) {\n visibleRows.push(renderRowAt(draggedIndex));\n }\n\n return (\n <div\n {...rest}\n ref={rootRef}\n className={cx(styles.virtualList, drag.draggingKey != null && styles.virtualListReordering, className, classNames?.root)}\n style={{ height, ...style, ...slotStyles?.root }}\n onScroll={win.handleScroll}\n role={ariaRoles?.container ?? (hasColumns ? 'grid' : 'list')}\n aria-rowcount={hasColumns ? items.length + 1 : undefined}\n >\n {hasColumns && (\n <div\n ref={headerRef}\n className={cx(styles.virtualListHeader, classNames?.header)}\n style={{ gridTemplateColumns: columnTemplate, ...(shouldShowToggle ? { paddingRight: 32 } : {}), ...slotStyles?.header }}\n role=\"row\"\n aria-rowindex={1}\n >\n {multiSelect && (\n <div\n className={cx(styles.virtualListSelectCell, classNames?.selectCell)}\n style={slotStyles?.selectCell}\n role=\"columnheader\"\n >\n <Checkbox\n selected={selection.allSelected || selection.someSelected}\n onToggle={selection.handleSelectAll}\n aria-label=\"Select all rows\"\n />\n </div>\n )}\n {visibleColumns.map((col) => (\n <div\n key={col.key}\n className={cx(styles.virtualListHeaderCell, classNames?.headerCell)}\n style={slotStyles?.headerCell}\n role=\"columnheader\"\n data-fit-key={col.width.type === 'fit' ? col.key : undefined}\n >\n {col.label}\n </div>\n ))}\n {shouldShowToggle && (\n <div className={styles.virtualListToggleWrapper}>\n <FloatingMenu\n isOpen={toggleOpen}\n onOpenChange={setToggleOpen}\n align={Align.Right}\n dontCloseOnChildClick\n content={\n <div\n className={cx(styles.virtualListTogglePopover, classNames?.togglePopover)}\n style={slotStyles?.togglePopover}\n >\n {columns!.filter((col) => !col.hideFromToggle).map((col) => (\n <Checkbox\n key={col.key}\n className={cx(styles.virtualListToggleItem, classNames?.toggleItem)}\n style={slotStyles?.toggleItem}\n selected={effectiveVisible.has(col.key)}\n onToggle={() => handleToggleColumn(col.key)}\n disabled={col.lockVisible}\n cursorDefault={false}\n >\n {col.toggleLabel ?? col.label}\n </Checkbox>\n ))}\n </div>\n }\n >\n <button\n type=\"button\"\n className={cx(styles.virtualListHeaderToggle, classNames?.headerToggle)}\n style={slotStyles?.headerToggle}\n aria-label=\"Toggle column visibility\"\n >\n <FontAwesomeIcon\n icon={faGear}\n style={slotStyles?.headerToggle as React.CSSProperties & Record<`--fa-font-${string}`, string>}\n />\n </button>\n </FloatingMenu>\n {manuallyHiddenCount > 0 && (\n <span\n className={cx(styles.virtualListColumnChip, classNames?.columnChip)}\n style={slotStyles?.columnChip}\n data-column-hidden-count={manuallyHiddenCount}\n aria-label={`${manuallyHiddenCount} columns hidden`}\n >\n {manuallyHiddenCount}\n </span>\n )}\n </div>\n )}\n </div>\n )}\n {isLoading ? (\n <div className={styles.virtualListLoadingFull}>\n <SpinnerLoading className={styles.virtualListSpinner} />\n </div>\n ) : (\n <div\n className={cx(styles.virtualListBody, classNames?.body)}\n style={{ height: totalHeight, ...slotStyles?.body }}\n >\n {visibleRows}\n </div>\n )}\n {win.showLoadMoreSpinner && (\n <div\n className={cx(styles.virtualListLoadingIndicator, classNames?.loadingIndicator)}\n style={slotStyles?.loadingIndicator}\n >\n <SpinnerLoading className={styles.virtualListSpinner} />\n </div>\n )}\n </div>\n );\n}\n\n// forwardRef erases the generic, so cast back to a generic-preserving signature.\nconst VirtualList = React.forwardRef(VirtualListInner) as <T>(\n props: VirtualListProps<T> & { ref?: React.Ref<VirtualListHandle> },\n) => React.ReactElement | null;\n\nexport default VirtualList;\n"],"mappings":"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"}
1
+ {"version":3,"file":"virtualList.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualList.tsx"],"sourcesContent":["import React, { useMemo, useCallback, useImperativeHandle } from 'react';\nimport cx from 'classnames';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faGear } from '@fortawesome/free-solid-svg-icons';\n\nimport styles from './virtualList.module.pcss';\nimport SpinnerLoading from '../loading/spinnerLoading';\nimport Checkbox from '../checkbox';\nimport FloatingMenu, { Align } from '../floatingMenu';\nimport VirtualRow from './virtualRow';\nimport { useVirtualWindow } from './useVirtualWindow';\nimport { useSelection } from './useSelection';\nimport { useColumns } from './useColumns';\nimport { useRowDrag } from './useRowDrag';\nimport type { VirtualListProps, VirtualListHandle } from './virtualList.types';\n\n// Pure helpers live in ./virtualList.utils; re-exported here so existing\n// imports (and unit tests) keep working against the component entry point.\nexport {\n buildOffsets,\n findStartIndex,\n getVisibleRange,\n resolveReorderTarget,\n resolveTreeDropTarget,\n lastDescendantIndex,\n buildColumnTemplate,\n} from './virtualList.utils';\n\n// ─── Orchestrator ─────────────────────────────────────────────────────────────\n// VirtualListInner wires four focused hooks together and renders. Each concern\n// lives in its own module:\n// useVirtualWindow — generic scroll / measurement / windowing (all modes)\n// useSelection — multi-row selection\n// useColumns — table mode: columns, visibility, persistence, fit widths\n// useRowDrag — reorder + tree drag-and-drop (mouse + touch)\n\nfunction VirtualListInner<T>(\n {\n items,\n renderRow,\n ariaRoles,\n columns,\n height = '100%',\n estimatedRowHeight = 40,\n overscan = 3,\n rowGap = 0,\n rowPadding,\n selectedKey,\n getItemKey,\n onRowClick,\n visibleColumnKeys,\n onVisibleColumnsChange,\n persistColumnsKey,\n showColumnToggle,\n onLoadMore,\n loadMoreThreshold = 100,\n isLoading = false,\n multiSelect = false,\n selectedKeys,\n onSelectionChange,\n reorderable = false,\n onReorder,\n longPressDelay = 400,\n treeReorder = false,\n getItemDepth,\n isGroup,\n onTreeDrop,\n treeIndentPx = 24,\n dragHandle = false,\n showDivider = true,\n rowHover = true,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n }: VirtualListProps<T>,\n ref: React.ForwardedRef<VirtualListHandle>,\n) {\n const getKey = useCallback(\n (item: T, index: number): string | number => (getItemKey ? getItemKey(item, index) : index),\n [getItemKey],\n );\n const keys = useMemo(() => items.map((item, i) => getKey(item, i)), [items, getKey]);\n const depths = useMemo(\n () => (getItemDepth ? items.map((item, i) => getItemDepth(item, i)) : []),\n [items, getItemDepth],\n );\n const isGroupAt = useCallback((i: number) => (isGroup ? isGroup(items[i], i) : false), [isGroup, items]);\n\n const win = useVirtualWindow<T>({\n items,\n keys,\n getItemKey,\n estimatedRowHeight,\n rowGap,\n overscan,\n onLoadMore,\n loadMoreThreshold,\n isLoading,\n });\n const { rootRef, headerRef, rowObserver, keysRef, offsets, totalHeight, startIndex, endIndex } = win;\n\n const selection = useSelection<T>({ items, getKey, multiSelect, selectedKeys, onSelectionChange });\n const { effectiveSelectedKeys } = selection;\n\n const cols = useColumns<T>({\n columns,\n items,\n multiSelect,\n visibleColumnKeys,\n onVisibleColumnsChange,\n persistColumnsKey,\n showColumnToggle,\n rootRef,\n startIndex,\n endIndex,\n containerHeight: win.containerHeight,\n containerWidth: win.containerWidth,\n });\n const {\n hasColumns,\n visibleColumns,\n columnTemplate,\n shouldShowToggle,\n effectiveVisible,\n manuallyHiddenCount,\n toggleOpen,\n setToggleOpen,\n handleToggleColumn,\n recalculateColumns,\n } = cols;\n\n // Compose the forwarded handle from both hooks: scroll methods come from the\n // windowing engine, column controls from the column hook.\n useImperativeHandle(ref, () => ({ ...win.scrollApi, recalculateColumns }), [win.scrollApi, recalculateColumns]);\n\n const drag = useRowDrag({\n reorderable,\n treeReorder,\n onReorder,\n onTreeDrop,\n longPressDelay,\n dragHandle,\n treeIndentPx,\n keys,\n depths,\n isGroupAt,\n rootRef,\n keysRef,\n });\n\n const rowPaddingValue = typeof rowPadding === 'number' ? `${rowPadding}px` : rowPadding;\n\n const renderRowAt = (i: number) => {\n const item = items[i];\n const key = getKey(item, i);\n const isSelected = (selectedKey != null && key === selectedKey) || effectiveSelectedKeys.has(key);\n const dragProps = drag.getRowDragProps(i, key);\n\n return (\n <VirtualRow\n key={key}\n index={i}\n top={offsets[i]}\n padding={rowPaddingValue}\n columnTemplate={columnTemplate}\n isSelected={isSelected}\n showDivider={showDivider}\n hover={rowHover}\n onClick={() => {\n if (drag.consumeSuppressedClick()) return;\n onRowClick?.(item, i);\n }}\n observer={rowObserver}\n ariaRowIndex={hasColumns ? i + 2 : undefined}\n ariaPosInSet={hasColumns ? undefined : i + 1}\n ariaSetSize={hasColumns ? undefined : items.length}\n rowRole={ariaRoles?.row ?? (hasColumns ? 'row' : 'listitem')}\n reserveToggleGutter={shouldShowToggle}\n {...dragProps}\n dropIndicatorClassName={classNames?.dropIndicator}\n dropIndicatorStyle={slotStyles?.dropIndicator}\n rowClassName={classNames?.row}\n rowStyle={slotStyles?.row}\n >\n {hasColumns ? (\n <>\n {multiSelect && (\n <div\n className={cx(styles.virtualListSelectCell, classNames?.selectCell)}\n style={slotStyles?.selectCell}\n role='gridcell'\n onClick={(e) => e.stopPropagation()}\n >\n <Checkbox\n selected={effectiveSelectedKeys.has(key)}\n onToggle={() => selection.handleRowSelect(key)}\n aria-label='Select row'\n />\n </div>\n )}\n {visibleColumns.map((col) => (\n <div\n key={col.key}\n className={cx(styles.virtualListCell, classNames?.cell)}\n style={slotStyles?.cell}\n role='gridcell'\n data-fit-key={col.width.type === 'fit' ? col.key : undefined}\n >\n {col.renderCell(item, i)}\n </div>\n ))}\n </>\n ) : (\n renderRow?.(item, i)\n )}\n </VirtualRow>\n );\n };\n\n const visibleRows: React.ReactNode[] = [];\n for (let i = startIndex; i <= endIndex; i++) visibleRows.push(renderRowAt(i));\n\n // Keep the row being touch-dragged mounted even if it scrolls out of the\n // window. Touch events are dispatched to the element under the finger at\n // touchstart; if that row unmounts, the browser stops delivering touchmove\n // and the drag freezes. Pinning its DOM node keeps the gesture alive.\n const draggedIndex = drag.draggingKey != null ? keys.indexOf(drag.draggingKey) : -1;\n if (draggedIndex >= 0 && (draggedIndex < startIndex || draggedIndex > endIndex)) {\n visibleRows.push(renderRowAt(draggedIndex));\n }\n\n return (\n <div\n {...rest}\n ref={rootRef}\n className={cx(\n styles.virtualList,\n drag.draggingKey != null && styles.virtualListReordering,\n className,\n classNames?.root,\n )}\n style={{ height, ...style, ...slotStyles?.root }}\n onScroll={win.handleScroll}\n role={ariaRoles?.container ?? (hasColumns ? 'grid' : 'list')}\n aria-rowcount={hasColumns ? items.length + 1 : undefined}\n >\n {hasColumns && (\n <div\n ref={headerRef}\n className={cx(styles.virtualListHeader, classNames?.header)}\n style={{\n gridTemplateColumns: columnTemplate,\n ...(shouldShowToggle ? { paddingRight: 32 } : {}),\n ...slotStyles?.header,\n }}\n role='row'\n aria-rowindex={1}\n >\n {multiSelect && (\n <div\n className={cx(styles.virtualListSelectCell, classNames?.selectCell)}\n style={slotStyles?.selectCell}\n role='columnheader'\n >\n <Checkbox\n selected={selection.allSelected || selection.someSelected}\n onToggle={selection.handleSelectAll}\n aria-label='Select all rows'\n />\n </div>\n )}\n {visibleColumns.map((col) => (\n <div\n key={col.key}\n className={cx(styles.virtualListHeaderCell, classNames?.headerCell)}\n style={slotStyles?.headerCell}\n role='columnheader'\n data-fit-key={col.width.type === 'fit' ? col.key : undefined}\n >\n {col.label}\n </div>\n ))}\n {shouldShowToggle && (\n <div className={styles.virtualListToggleWrapper}>\n <FloatingMenu\n isOpen={toggleOpen}\n onOpenChange={setToggleOpen}\n align={Align.Right}\n dontCloseOnChildClick\n content={\n <div\n className={cx(styles.virtualListTogglePopover, classNames?.togglePopover)}\n style={slotStyles?.togglePopover}\n >\n {columns!\n .filter((col) => !col.hideFromToggle)\n .map((col) => (\n <Checkbox\n key={col.key}\n className={cx(styles.virtualListToggleItem, classNames?.toggleItem)}\n style={slotStyles?.toggleItem}\n selected={effectiveVisible.has(col.key)}\n onToggle={() => handleToggleColumn(col.key)}\n disabled={col.lockVisible}\n cursorDefault={false}\n >\n {col.toggleLabel ?? col.label}\n </Checkbox>\n ))}\n </div>\n }\n >\n <button\n type='button'\n className={cx(styles.virtualListHeaderToggle, classNames?.headerToggle)}\n style={slotStyles?.headerToggle}\n aria-label='Toggle column visibility'\n >\n <FontAwesomeIcon\n icon={faGear}\n style={slotStyles?.headerToggle as React.CSSProperties & Record<`--fa-font-${string}`, string>}\n />\n </button>\n </FloatingMenu>\n {manuallyHiddenCount > 0 && (\n <span\n className={cx(styles.virtualListColumnChip, classNames?.columnChip)}\n style={slotStyles?.columnChip}\n data-column-hidden-count={manuallyHiddenCount}\n aria-label={`${manuallyHiddenCount} columns hidden`}\n >\n {manuallyHiddenCount}\n </span>\n )}\n </div>\n )}\n </div>\n )}\n {isLoading ? (\n <div className={styles.virtualListLoadingFull}>\n <SpinnerLoading className={styles.virtualListSpinner} />\n </div>\n ) : (\n <div\n className={cx(styles.virtualListBody, classNames?.body)}\n style={{ height: totalHeight, ...slotStyles?.body }}\n >\n {visibleRows}\n </div>\n )}\n {win.showLoadMoreSpinner && (\n <div\n className={cx(styles.virtualListLoadingIndicator, classNames?.loadingIndicator)}\n style={slotStyles?.loadingIndicator}\n >\n <SpinnerLoading className={styles.virtualListSpinner} />\n </div>\n )}\n </div>\n );\n}\n\n// forwardRef erases the generic, so cast back to a generic-preserving signature.\nconst VirtualList = React.forwardRef(VirtualListInner) as <T>(\n props: VirtualListProps<T> & { ref?: React.Ref<VirtualListHandle> },\n) => React.ReactElement | null;\n\nexport default VirtualList;\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- var e={virtualList:`virtualList_qBPNc`,"virtualList-drag-clone":`virtualList-drag-clone_artnC`,virtualListDragClone:`virtualList-drag-clone_artnC`,"virtualList-header":`virtualList-header_0Ellb`,virtualListHeader:`virtualList-header_0Ellb`,"virtualList-header-cell":`virtualList-header-cell_c8NGV`,virtualListHeaderCell:`virtualList-header-cell_c8NGV`,"virtualList-header-toggle":`virtualList-header-toggle_pYFxD`,virtualListHeaderToggle:`virtualList-header-toggle_pYFxD`,"virtualList-toggle-wrapper":`virtualList-toggle-wrapper_JP32M`,virtualListToggleWrapper:`virtualList-toggle-wrapper_JP32M`,"virtualList-toggle-popover":`virtualList-toggle-popover_gbpd7`,virtualListTogglePopover:`virtualList-toggle-popover_gbpd7`,"virtualList-toggle-item":`virtualList-toggle-item_5gu5d`,virtualListToggleItem:`virtualList-toggle-item_5gu5d`,"virtualList-column-chip":`virtualList-column-chip_nOqr6`,virtualListColumnChip:`virtualList-column-chip_nOqr6`,"virtualList-select-cell":`virtualList-select-cell_s9kAy`,virtualListSelectCell:`virtualList-select-cell_s9kAy`,"virtualList-body":`virtualList-body_k-fRr`,virtualListBody:`virtualList-body_k-fRr`,"virtualList-row":`virtualList-row_TTY50`,virtualListRow:`virtualList-row_TTY50`,"virtualList-row-no-divider":`virtualList-row-no-divider_Ct0gV`,virtualListRowNoDivider:`virtualList-row-no-divider_Ct0gV`,"virtualList-row-no-hover":`virtualList-row-no-hover_2d3mH`,virtualListRowNoHover:`virtualList-row-no-hover_2d3mH`,"virtualList-row-selected":`virtualList-row-selected_hwEN-`,virtualListRowSelected:`virtualList-row-selected_hwEN-`,"virtualList-row-draggable":`virtualList-row-draggable_I86ha`,virtualListRowDraggable:`virtualList-row-draggable_I86ha`,"virtualList-row-dragging":`virtualList-row-dragging_6T5tQ`,virtualListRowDragging:`virtualList-row-dragging_6T5tQ`,"virtualList-row-drop-inside":`virtualList-row-drop-inside_Uhi9n`,virtualListRowDropInside:`virtualList-row-drop-inside_Uhi9n`,"virtualList-drop-line":`virtualList-drop-line_EM-g4`,virtualListDropLine:`virtualList-drop-line_EM-g4`,"virtualList-drop-line-before":`virtualList-drop-line-before_n-0iZ`,virtualListDropLineBefore:`virtualList-drop-line-before_n-0iZ`,"virtualList-drop-line-after":`virtualList-drop-line-after_2dld-`,virtualListDropLineAfter:`virtualList-drop-line-after_2dld-`,"virtualList-reordering":`virtualList-reordering_Rt9E3`,virtualListReordering:`virtualList-reordering_Rt9E3`,"virtualList-cell":`virtualList-cell_H0zBv`,virtualListCell:`virtualList-cell_H0zBv`,"virtualList-loading-full":`virtualList-loading-full_wzZNM`,virtualListLoadingFull:`virtualList-loading-full_wzZNM`,"virtualList-loading-indicator":`virtualList-loading-indicator_EJced`,virtualListLoadingIndicator:`virtualList-loading-indicator_EJced`,"virtualList-spinner":`virtualList-spinner_apClW`,virtualListSpinner:`virtualList-spinner_apClW`};export{e as default};
1
+ var e=`virtualList_qBPNc`,t=`virtualList-drag-clone_artnC`,n=`virtualList-header_0Ellb`,r=`virtualList-header-cell_c8NGV`,i=`virtualList-header-toggle_pYFxD`,a=`virtualList-toggle-wrapper_JP32M`,o=`virtualList-toggle-popover_gbpd7`,s=`virtualList-toggle-item_5gu5d`,c=`virtualList-column-chip_nOqr6`,l=`virtualList-select-cell_s9kAy`,u=`virtualList-body_k-fRr`,d=`virtualList-row_TTY50`,f=`virtualList-row-no-divider_Ct0gV`,p=`virtualList-row-no-hover_2d3mH`,m=`virtualList-row-selected_hwEN-`,h=`virtualList-row-draggable_I86ha`,g=`virtualList-row-dragging_6T5tQ`,_=`virtualList-row-drop-inside_Uhi9n`,v=`virtualList-drop-line_EM-g4`,y=`virtualList-drop-line-before_n-0iZ`,b=`virtualList-drop-line-after_2dld-`,x=`virtualList-reordering_Rt9E3`,S=`virtualList-cell_H0zBv`,C=`virtualList-loading-full_wzZNM`,w=`virtualList-loading-indicator_EJced`,T=`virtualList-spinner_apClW`,E={virtualList:e,"virtualList-drag-clone":`virtualList-drag-clone_artnC`,virtualListDragClone:t,"virtualList-header":`virtualList-header_0Ellb`,virtualListHeader:n,"virtualList-header-cell":`virtualList-header-cell_c8NGV`,virtualListHeaderCell:r,"virtualList-header-toggle":`virtualList-header-toggle_pYFxD`,virtualListHeaderToggle:i,"virtualList-toggle-wrapper":`virtualList-toggle-wrapper_JP32M`,virtualListToggleWrapper:a,"virtualList-toggle-popover":`virtualList-toggle-popover_gbpd7`,virtualListTogglePopover:o,"virtualList-toggle-item":`virtualList-toggle-item_5gu5d`,virtualListToggleItem:s,"virtualList-column-chip":`virtualList-column-chip_nOqr6`,virtualListColumnChip:c,"virtualList-select-cell":`virtualList-select-cell_s9kAy`,virtualListSelectCell:l,"virtualList-body":`virtualList-body_k-fRr`,virtualListBody:u,"virtualList-row":`virtualList-row_TTY50`,virtualListRow:d,"virtualList-row-no-divider":`virtualList-row-no-divider_Ct0gV`,virtualListRowNoDivider:f,"virtualList-row-no-hover":`virtualList-row-no-hover_2d3mH`,virtualListRowNoHover:p,"virtualList-row-selected":`virtualList-row-selected_hwEN-`,virtualListRowSelected:m,"virtualList-row-draggable":`virtualList-row-draggable_I86ha`,virtualListRowDraggable:h,"virtualList-row-dragging":`virtualList-row-dragging_6T5tQ`,virtualListRowDragging:g,"virtualList-row-drop-inside":`virtualList-row-drop-inside_Uhi9n`,virtualListRowDropInside:_,"virtualList-drop-line":`virtualList-drop-line_EM-g4`,virtualListDropLine:v,"virtualList-drop-line-before":`virtualList-drop-line-before_n-0iZ`,virtualListDropLineBefore:y,"virtualList-drop-line-after":`virtualList-drop-line-after_2dld-`,virtualListDropLineAfter:b,"virtualList-reordering":`virtualList-reordering_Rt9E3`,virtualListReordering:x,"virtualList-cell":`virtualList-cell_H0zBv`,virtualListCell:S,"virtualList-loading-full":`virtualList-loading-full_wzZNM`,virtualListLoadingFull:C,"virtualList-loading-indicator":`virtualList-loading-indicator_EJced`,virtualListLoadingIndicator:w,"virtualList-spinner":`virtualList-spinner_apClW`,virtualListSpinner:T};export{E as default,e as virtualList,u as virtualListBody,S as virtualListCell,c as virtualListColumnChip,t as virtualListDragClone,v as virtualListDropLine,b as virtualListDropLineAfter,y as virtualListDropLineBefore,n as virtualListHeader,r as virtualListHeaderCell,i as virtualListHeaderToggle,C as virtualListLoadingFull,w as virtualListLoadingIndicator,x as virtualListReordering,d as virtualListRow,h as virtualListRowDraggable,g as virtualListRowDragging,_ as virtualListRowDropInside,f as virtualListRowNoDivider,p as virtualListRowNoHover,m as virtualListRowSelected,l as virtualListSelectCell,T as virtualListSpinner,s as virtualListToggleItem,o as virtualListTogglePopover,a as virtualListToggleWrapper};
2
2
  //# sourceMappingURL=virtualList.module.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"virtualList.module.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualList.module.pcss"],"sourcesContent":[".virtualList {\n overflow-y: auto;\n box-sizing: border-box;\n color: var(--text-color);\n font-family: var(--default-font);\n /* Disable the browser's own scroll anchoring — the component does its own\n scroll-position correction when row heights change, and the two fighting\n each other causes the thumb to desync while dragging. */\n overflow-anchor: none;\n /* Reserve the scrollbar gutter so rows don't re-wrap (and re-measure) when the\n vertical scrollbar appears/disappears as content grows. */\n scrollbar-gutter: stable;\n /* Establish a stacking context so every z-index inside the list (sticky\n header, toggle popover, drag clone) stays scoped to this component and\n can't paint over outside content like a modal. */\n isolation: isolate;\n\n &-drag-clone {\n box-sizing: border-box;\n contain: layout paint style;\n cursor: grabbing;\n /* It tracks the finger via transform — never animate that. */\n transition: none;\n }\n\n &-header {\n display: grid;\n position: sticky;\n top: 0;\n /* Above focused rows (z-index 1) so a focused row scrolled under the header\n never paints over it; the drag clone (z-index 3) still floats above both. */\n z-index: 2;\n background: var(--background-accent);\n border-bottom: 1px solid var(--border-color);\n box-sizing: border-box;\n\n &-cell {\n padding: 8px 12px;\n font-weight: 600;\n font-size: 13px;\n color: var(--text-dark);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n box-sizing: border-box;\n }\n\n &-toggle {\n background: none;\n border: none;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n padding: 4px 8px;\n color: var(--text-dark);\n display: flex;\n align-items: center;\n border-radius: var(--default-border-radius);\n transition: background 0.15s;\n\n &:hover {\n background: var(--background-accent-light);\n color: var(--text-color);\n }\n }\n }\n\n &-toggle {\n &-wrapper {\n position: absolute;\n right: 0;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n padding: 0 4px;\n }\n\n /* Chrome (background, shadow, radius, positioning) is provided by the\n FloatingMenu container this renders inside — keep only sizing here. */\n &-popover {\n display: flex;\n flex-direction: column;\n min-width: 160px;\n }\n\n &-item {\n padding: 4px 12px;\n white-space: nowrap;\n transition: background 0.1s;\n font-size: 14px;\n\n &:hover {\n background: var(--background-accent-light);\n }\n }\n }\n\n /* Count badge on the column-toggle cog: how many columns the user has hidden.\n Positioned at the cog's upper-right corner; non-interactive. */\n &-column-chip {\n position: absolute;\n top: 0;\n right: 0;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--primary-color);\n color: var(--text-on-primary);\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n border-radius: 8px;\n pointer-events: none;\n }\n\n &-select-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\n box-sizing: border-box;\n }\n\n &-body {\n position: relative;\n box-sizing: border-box;\n }\n\n &-row {\n border-bottom: 1px solid var(--border-color);\n box-sizing: border-box;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition: background 0.1s;\n /* Isolate each row's layout/style so measuring or restyling one row can't force\n the whole list to re-layout — keeps fast scrolling smooth. */\n contain: layout style;\n\n &-no-divider {\n border-bottom: none;\n }\n\n &:hover {\n background: var(--background-accent-light);\n }\n\n /* Opt out of the hover highlight (e.g. when each row is a Card that handles\n its own hover). Declared before the `-selected` rule below, so a selected\n row's highlight still wins on hover. */\n &-no-hover:hover {\n background: transparent;\n }\n\n &-selected {\n background: var(--primary-lighter);\n\n &:hover {\n background: var(--primary-lighter);\n }\n }\n\n &-draggable {\n cursor: grab;\n /* Stop the mobile long-press from selecting text or showing the callout. */\n user-select: none;\n -webkit-touch-callout: none;\n\n &:active {\n cursor: grabbing;\n }\n }\n\n &-dragging {\n opacity: 0.4;\n }\n\n /* Tree-reorder `inside` drop: the dragged node becomes a child of this row,\n so highlight the whole row instead of drawing a between-rows line. */\n &-drop-inside {\n background: var(--primary-lighter);\n box-shadow: inset 0 0 0 2px var(--primary-color);\n }\n }\n\n /* Tree-reorder `before`/`after` drop line. Positioned inside the (relatively\n positioned absolute) row; `left` is set inline to the target's indent so it\n starts where the dropped content will. */\n &-drop-line {\n position: absolute;\n right: 0;\n height: 2px;\n background: var(--primary-color);\n pointer-events: none;\n z-index: 1;\n\n /* A small knob at the line's start, the usual tree drop-indicator look. */\n &::before {\n content: '';\n position: absolute;\n left: 0;\n top: 50%;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--primary-color);\n transform: translate(-50%, -50%);\n }\n\n &-before { top: -1px; }\n &-after { bottom: -1px; }\n }\n\n /* While a row is being dragged, suppress hover backgrounds so the pointer\n moving across rows doesn't light up the wrong one, and stop text selection.\n `touch-action: none` stops the touch drag from also scrolling the list\n (only active once the long-press has armed the drag). */\n &-reordering {\n touch-action: none;\n\n .virtualList-row {\n user-select: none;\n\n &:hover {\n background: transparent;\n }\n\n &.virtualList-row-selected:hover {\n background: var(--primary-lighter);\n }\n\n &.virtualList-row-dragging {\n background: transparent;\n }\n }\n }\n\n &-cell {\n padding: 8px 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 14px;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n min-width: 0;\n\n /* `fit` columns are content-sized — keep their cells on a single line so the\n content can't wrap, and so the width measurement reads the true intrinsic\n width. (Other cells are free to wrap for variable-height rows.) */\n &[data-fit-key] {\n white-space: nowrap;\n }\n }\n\n &-loading {\n &-full {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n }\n\n &-indicator {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 8px 0;\n }\n }\n\n &-spinner {\n width: 32px;\n height: 32px;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"virtualList.module.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualList.module.pcss"],"sourcesContent":[".virtualList {\n overflow-y: auto;\n box-sizing: border-box;\n color: var(--text-color);\n font-family: var(--default-font);\n\n /* Disable the browser's own scroll anchoring — the component does its own\n scroll-position correction when row heights change, and the two fighting\n each other causes the thumb to desync while dragging. */\n overflow-anchor: none;\n\n /* Reserve the scrollbar gutter so rows don't re-wrap (and re-measure) when the\n vertical scrollbar appears/disappears as content grows. */\n scrollbar-gutter: stable;\n\n /* Establish a stacking context so every z-index inside the list (sticky\n header, toggle popover, drag clone) stays scoped to this component and\n can't paint over outside content like a modal. */\n isolation: isolate;\n\n &-drag-clone {\n box-sizing: border-box;\n contain: layout paint style;\n cursor: grabbing;\n\n /* It tracks the finger via transform — never animate that. */\n transition: none;\n }\n\n &-header {\n display: grid;\n position: sticky;\n top: 0;\n\n /* Above focused rows (z-index 1) so a focused row scrolled under the header\n never paints over it; the drag clone (z-index 3) still floats above both. */\n z-index: 2;\n background: var(--background-accent);\n border-bottom: 1px solid var(--border-color);\n box-sizing: border-box;\n\n &-cell {\n padding: 8px 12px;\n font-weight: 600;\n font-size: 13px;\n color: var(--text-dark);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n box-sizing: border-box;\n }\n\n &-toggle {\n background: none;\n border: none;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n padding: 4px 8px;\n color: var(--text-dark);\n display: flex;\n align-items: center;\n border-radius: var(--default-border-radius);\n transition: background 0.15s;\n\n &:hover {\n background: var(--background-accent-light);\n color: var(--text-color);\n }\n }\n }\n\n &-toggle {\n &-wrapper {\n position: absolute;\n right: 0;\n top: 0;\n bottom: 0;\n display: flex;\n align-items: center;\n padding: 0 4px;\n }\n\n /* Chrome (background, shadow, radius, positioning) is provided by the\n FloatingMenu container this renders inside — keep only sizing here. */\n &-popover {\n display: flex;\n flex-direction: column;\n min-width: 160px;\n }\n\n &-item {\n padding: 4px 12px;\n white-space: nowrap;\n transition: background 0.1s;\n font-size: 14px;\n\n &:hover {\n background: var(--background-accent-light);\n }\n }\n }\n\n /* Count badge on the column-toggle cog: how many columns the user has hidden.\n Positioned at the cog's upper-right corner; non-interactive. */\n &-column-chip {\n position: absolute;\n top: 0;\n right: 0;\n min-width: 16px;\n height: 16px;\n padding: 0 4px;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--primary-color);\n color: var(--text-on-primary);\n font-size: 10px;\n font-weight: 600;\n line-height: 1;\n border-radius: 8px;\n pointer-events: none;\n }\n\n &-select-cell {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0 4px;\n box-sizing: border-box;\n }\n\n &-body {\n position: relative;\n box-sizing: border-box;\n }\n\n &-row {\n border-bottom: 1px solid var(--border-color);\n box-sizing: border-box;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n transition: background 0.1s;\n\n /* Isolate each row's layout/style so measuring or restyling one row can't force\n the whole list to re-layout — keeps fast scrolling smooth. */\n contain: layout style;\n\n &-no-divider {\n border-bottom: none;\n }\n\n &:hover {\n background: var(--background-accent-light);\n }\n\n /* Opt out of the hover highlight (e.g. when each row is a Card that handles\n its own hover). Declared before the `-selected` rule below, so a selected\n row's highlight still wins on hover. */\n &-no-hover:hover {\n background: transparent;\n }\n\n &-selected {\n background: var(--primary-lighter);\n\n &:hover {\n background: var(--primary-lighter);\n }\n }\n\n &-draggable {\n cursor: grab;\n\n /* Stop the mobile long-press from selecting text or showing the callout. */\n user-select: none;\n -webkit-touch-callout: none;\n\n &:active {\n cursor: grabbing;\n }\n }\n\n &-dragging {\n opacity: 0.4;\n }\n\n /* Tree-reorder `inside` drop: the dragged node becomes a child of this row,\n so highlight the whole row instead of drawing a between-rows line. */\n &-drop-inside {\n background: var(--primary-lighter);\n box-shadow: inset 0 0 0 2px var(--primary-color);\n }\n }\n\n /* Tree-reorder `before`/`after` drop line. Positioned inside the (relatively\n positioned absolute) row; `left` is set inline to the target's indent so it\n starts where the dropped content will. */\n &-drop-line {\n position: absolute;\n right: 0;\n height: 2px;\n background: var(--primary-color);\n pointer-events: none;\n z-index: 1;\n\n /* A small knob at the line's start, the usual tree drop-indicator look. */\n &::before {\n content: '';\n position: absolute;\n left: 0;\n top: 50%;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--primary-color);\n transform: translate(-50%, -50%);\n }\n\n &-before {\n top: -1px;\n }\n\n &-after {\n bottom: -1px;\n }\n }\n\n /* While a row is being dragged, suppress hover backgrounds so the pointer\n moving across rows doesn't light up the wrong one, and stop text selection.\n `touch-action: none` stops the touch drag from also scrolling the list\n (only active once the long-press has armed the drag). */\n &-reordering {\n touch-action: none;\n\n .virtualList-row {\n user-select: none;\n\n &:hover {\n background: transparent;\n }\n\n &.virtualList-row-selected:hover {\n background: var(--primary-lighter);\n }\n\n &.virtualList-row-dragging {\n background: transparent;\n }\n }\n }\n\n &-cell {\n padding: 8px 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n font-size: 14px;\n box-sizing: border-box;\n display: flex;\n align-items: center;\n min-width: 0;\n\n /* `fit` columns are content-sized — keep their cells on a single line so the\n content can't wrap, and so the width measurement reads the true intrinsic\n width. (Other cells are free to wrap for variable-height rows.) */\n &[data-fit-key] {\n white-space: nowrap;\n }\n }\n\n &-loading {\n &-full {\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n }\n\n &-indicator {\n display: flex;\n justify-content: center;\n align-items: center;\n padding: 8px 0;\n }\n }\n\n &-spinner {\n width: 32px;\n height: 32px;\n }\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"virtualList.utils.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualList.utils.ts"],"sourcesContent":["import type { ColumnWidthSpec, VirtualListColumn } from './virtualList.types';\n\n// ─── Layout / windowing math ──────────────────────────────────────────────────\n\nexport function buildOffsets(\n keys: (string | number)[],\n heightsMap: Map<string | number, number>,\n estimatedRowHeight: number,\n rowGap = 0,\n): { offsets: number[]; totalHeight: number } {\n const itemCount = keys.length;\n const offsets = new Array<number>(itemCount + 1);\n offsets[0] = 0;\n for (let i = 0; i < itemCount; i++) {\n const gap = i < itemCount - 1 ? rowGap : 0;\n // Heights are cached by item key, not index, so a measured row keeps its\n // height across reorders/filters instead of inheriting its neighbour's.\n offsets[i + 1] = offsets[i] + (heightsMap.get(keys[i]) ?? estimatedRowHeight) + gap;\n }\n return { offsets, totalHeight: offsets[itemCount] };\n}\n\n/** Index of the row that sits at `scrollTop` — i.e. the first row whose bottom edge is below it. */\nexport function findStartIndex(offsets: number[], scrollTop: number, itemCount: number): number {\n if (itemCount <= 0) return 0;\n let lo = 0;\n let hi = itemCount - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (offsets[mid + 1] <= scrollTop) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nexport function getVisibleRange(\n offsets: number[],\n scrollTop: number,\n containerHeight: number,\n overscan: number,\n itemCount: number,\n): { startIndex: number; endIndex: number } {\n if (itemCount === 0) return { startIndex: 0, endIndex: -1 };\n\n const lo = findStartIndex(offsets, scrollTop, itemCount);\n\n let end = lo;\n while (end < itemCount && offsets[end] < scrollTop + containerHeight) end++;\n\n return {\n startIndex: Math.max(0, lo - overscan),\n endIndex: Math.min(itemCount - 1, end + overscan - 1),\n };\n}\n\n// ─── Reorder / tree-drop math ─────────────────────────────────────────────────\n\n/**\n * Decides where a dragged row should move to, applying midpoint hysteresis: a\n * move only happens once the pointer has crossed the centre of the row it is\n * over (downwards when moving down, upwards when moving up). Returns the target\n * index, or null if no move should occur. Pure for easy unit testing.\n */\nexport function resolveReorderTarget(\n fromIndex: number,\n overIndex: number,\n pointerY: number,\n rowTop: number,\n rowHeight: number,\n): number | null {\n if (fromIndex === -1 || fromIndex === overIndex) return null;\n const midpoint = rowTop + rowHeight / 2;\n const movingDown = overIndex > fromIndex;\n if (movingDown ? pointerY >= midpoint : pointerY <= midpoint) return overIndex;\n return null;\n}\n\n/**\n * Decides where a tree-reorder drop should land relative to the row under the\n * pointer. Group rows expose three zones (top third → `before`, middle →\n * `inside`, bottom third → `after`); leaf rows split in half (`before`/`after`)\n * since they can't receive children. Pure for easy unit testing.\n */\nexport function resolveTreeDropTarget(\n pointerY: number,\n rowTop: number,\n rowHeight: number,\n isGroup: boolean,\n): 'before' | 'inside' | 'after' {\n if (rowHeight <= 0) return 'before';\n const rel = (pointerY - rowTop) / rowHeight;\n if (isGroup) {\n if (rel < 1 / 3) return 'before';\n if (rel > 2 / 3) return 'after';\n return 'inside';\n }\n return rel < 0.5 ? 'before' : 'after';\n}\n\n/**\n * Index of the last descendant of the node at `index` in a depth-tagged flat\n * list (a contiguous run of following rows with a greater depth). Returns\n * `index` itself when the node has no children. A drop is forbidden anywhere in\n * `[index, lastDescendantIndex]` — that's the node and its own subtree.\n */\nexport function lastDescendantIndex(index: number, depths: number[]): number {\n const d = depths[index];\n let i = index + 1;\n while (i < depths.length && depths[i] > d) i++;\n return i - 1;\n}\n\n// ─── Column template ──────────────────────────────────────────────────────────\n\nexport function buildColumnTemplate(\n columns: { key: string; width: ColumnWidthSpec }[],\n fitWidths?: Record<string, number>,\n): string {\n if (columns.length === 0) return '1fr';\n return columns\n .map((col) => {\n switch (col.width.type) {\n case 'fixed': return `${col.width.px}px`;\n case 'flex': return `${col.width.weight ?? 1}fr`;\n // A `fit` track is content-sized, so it resolves independently in each\n // grid (the header and every row are separate grids) and would drift\n // out of alignment. Once we've measured the column's natural width\n // across all those grids, pin it to that exact px so every grid uses an\n // identical track. Until then, fall back to content-sizing.\n case 'fit': {\n const w = fitWidths?.[col.key];\n return w != null ? `${w}px` : 'fit-content(100%)';\n }\n }\n })\n .join(' ');\n}\n\n// ─── Column-visibility persistence ────────────────────────────────────────────\n\nexport const COLUMN_STORAGE_PREFIX = 'ahroweui:virtuallist:columns:';\n\n// We persist both the visible keys and the full set of columns that existed at\n// save time. That lets us tell \"the user hid this column\" from \"this column\n// didn't exist yet\" when columns are added later — the former stays hidden, the\n// latter falls back to its defaultHidden value.\nexport interface PersistedColumns {\n visible: string[];\n known: string[];\n}\n\nexport function loadPersistedColumns(persistKey: string | undefined): PersistedColumns | null {\n if (!persistKey || typeof window === 'undefined') return null;\n try {\n const raw = window.localStorage.getItem(COLUMN_STORAGE_PREFIX + persistKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (parsed && Array.isArray(parsed.visible) && Array.isArray(parsed.known)) {\n return {\n visible: parsed.visible.filter((k: unknown): k is string => typeof k === 'string'),\n known: parsed.known.filter((k: unknown): k is string => typeof k === 'string'),\n };\n }\n } catch {\n // Corrupt/unavailable storage — fall back to defaults.\n }\n return null;\n}\n\n/** Whether a column should start visible, honouring saved settings then `defaultHidden`. */\nexport function isColumnInitiallyVisible<T>(col: VirtualListColumn<T>, persisted: PersistedColumns | null): boolean {\n // A locked column is always visible and can't be hidden — ignore saved state.\n if (col.lockVisible) return true;\n if (persisted && persisted.known.includes(col.key)) return persisted.visible.includes(col.key);\n return !col.defaultHidden;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"virtualList.utils.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualList.utils.ts"],"sourcesContent":["import type { ColumnWidthSpec, VirtualListColumn } from './virtualList.types';\n\n// ─── Layout / windowing math ──────────────────────────────────────────────────\n\nexport function buildOffsets(\n keys: (string | number)[],\n heightsMap: Map<string | number, number>,\n estimatedRowHeight: number,\n rowGap = 0,\n): { offsets: number[]; totalHeight: number } {\n const itemCount = keys.length;\n const offsets = new Array<number>(itemCount + 1);\n offsets[0] = 0;\n for (let i = 0; i < itemCount; i++) {\n const gap = i < itemCount - 1 ? rowGap : 0;\n // Heights are cached by item key, not index, so a measured row keeps its\n // height across reorders/filters instead of inheriting its neighbour's.\n offsets[i + 1] = offsets[i] + (heightsMap.get(keys[i]) ?? estimatedRowHeight) + gap;\n }\n return { offsets, totalHeight: offsets[itemCount] };\n}\n\n/** Index of the row that sits at `scrollTop` — i.e. the first row whose bottom edge is below it. */\nexport function findStartIndex(offsets: number[], scrollTop: number, itemCount: number): number {\n if (itemCount <= 0) return 0;\n let lo = 0;\n let hi = itemCount - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (offsets[mid + 1] <= scrollTop) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nexport function getVisibleRange(\n offsets: number[],\n scrollTop: number,\n containerHeight: number,\n overscan: number,\n itemCount: number,\n): { startIndex: number; endIndex: number } {\n if (itemCount === 0) return { startIndex: 0, endIndex: -1 };\n\n const lo = findStartIndex(offsets, scrollTop, itemCount);\n\n let end = lo;\n while (end < itemCount && offsets[end] < scrollTop + containerHeight) end++;\n\n return {\n startIndex: Math.max(0, lo - overscan),\n endIndex: Math.min(itemCount - 1, end + overscan - 1),\n };\n}\n\n// ─── Reorder / tree-drop math ─────────────────────────────────────────────────\n\n/**\n * Decides where a dragged row should move to, applying midpoint hysteresis: a\n * move only happens once the pointer has crossed the centre of the row it is\n * over (downwards when moving down, upwards when moving up). Returns the target\n * index, or null if no move should occur. Pure for easy unit testing.\n */\nexport function resolveReorderTarget(\n fromIndex: number,\n overIndex: number,\n pointerY: number,\n rowTop: number,\n rowHeight: number,\n): number | null {\n if (fromIndex === -1 || fromIndex === overIndex) return null;\n const midpoint = rowTop + rowHeight / 2;\n const movingDown = overIndex > fromIndex;\n if (movingDown ? pointerY >= midpoint : pointerY <= midpoint) return overIndex;\n return null;\n}\n\n/**\n * Decides where a tree-reorder drop should land relative to the row under the\n * pointer. Group rows expose three zones (top third → `before`, middle →\n * `inside`, bottom third → `after`); leaf rows split in half (`before`/`after`)\n * since they can't receive children. Pure for easy unit testing.\n */\nexport function resolveTreeDropTarget(\n pointerY: number,\n rowTop: number,\n rowHeight: number,\n isGroup: boolean,\n): 'before' | 'inside' | 'after' {\n if (rowHeight <= 0) return 'before';\n const rel = (pointerY - rowTop) / rowHeight;\n if (isGroup) {\n if (rel < 1 / 3) return 'before';\n if (rel > 2 / 3) return 'after';\n return 'inside';\n }\n return rel < 0.5 ? 'before' : 'after';\n}\n\n/**\n * Index of the last descendant of the node at `index` in a depth-tagged flat\n * list (a contiguous run of following rows with a greater depth). Returns\n * `index` itself when the node has no children. A drop is forbidden anywhere in\n * `[index, lastDescendantIndex]` — that's the node and its own subtree.\n */\nexport function lastDescendantIndex(index: number, depths: number[]): number {\n const d = depths[index];\n let i = index + 1;\n while (i < depths.length && depths[i] > d) i++;\n return i - 1;\n}\n\n// ─── Column template ──────────────────────────────────────────────────────────\n\nexport function buildColumnTemplate(\n columns: { key: string; width: ColumnWidthSpec }[],\n fitWidths?: Record<string, number>,\n): string {\n if (columns.length === 0) return '1fr';\n return columns\n .map((col) => {\n switch (col.width.type) {\n case 'fixed':\n return `${col.width.px}px`;\n case 'flex':\n return `${col.width.weight ?? 1}fr`;\n // A `fit` track is content-sized, so it resolves independently in each\n // grid (the header and every row are separate grids) and would drift\n // out of alignment. Once we've measured the column's natural width\n // across all those grids, pin it to that exact px so every grid uses an\n // identical track. Until then, fall back to content-sizing.\n case 'fit': {\n const w = fitWidths?.[col.key];\n return w != null ? `${w}px` : 'fit-content(100%)';\n }\n }\n })\n .join(' ');\n}\n\n// ─── Column-visibility persistence ────────────────────────────────────────────\n\nexport const COLUMN_STORAGE_PREFIX = 'ahroweui:virtuallist:columns:';\n\n// We persist both the visible keys and the full set of columns that existed at\n// save time. That lets us tell \"the user hid this column\" from \"this column\n// didn't exist yet\" when columns are added later — the former stays hidden, the\n// latter falls back to its defaultHidden value.\nexport interface PersistedColumns {\n visible: string[];\n known: string[];\n}\n\nexport function loadPersistedColumns(persistKey: string | undefined): PersistedColumns | null {\n if (!persistKey || typeof window === 'undefined') return null;\n try {\n const raw = window.localStorage.getItem(COLUMN_STORAGE_PREFIX + persistKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw);\n if (parsed && Array.isArray(parsed.visible) && Array.isArray(parsed.known)) {\n return {\n visible: parsed.visible.filter((k: unknown): k is string => typeof k === 'string'),\n known: parsed.known.filter((k: unknown): k is string => typeof k === 'string'),\n };\n }\n } catch {\n // Corrupt/unavailable storage — fall back to defaults.\n }\n return null;\n}\n\n/** Whether a column should start visible, honouring saved settings then `defaultHidden`. */\nexport function isColumnInitiallyVisible<T>(col: VirtualListColumn<T>, persisted: PersistedColumns | null): boolean {\n // A locked column is always visible and can't be hidden — ignore saved state.\n if (col.lockVisible) return true;\n if (persisted && persisted.known.includes(col.key)) return persisted.visible.includes(col.key);\n return !col.defaultHidden;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import e from"./virtualList.module.mjs";import{useLayoutEffect as t,useRef as n}from"react";import r from"classnames";import{jsx as i,jsxs as a}from"react/jsx-runtime";function o({index:o,top:s,padding:c,columnTemplate:l,isSelected:u,showDivider:d,hover:f,onClick:p,observer:m,ariaRowIndex:h,ariaPosInSet:g,ariaSetSize:_,rowRole:v,reorderable:y,mouseDragEnabled:b,draggable:x,isDragging:S,reserveToggleGutter:C,onMouseDown:w,onMouseOver:T,onMouseLeave:E,onDragStart:D,onDragOver:O,onDragEnd:k,onDrop:A,onTouchStart:j,dropPosition:M,dropIndentPx:N,dropIndicatorClassName:P,dropIndicatorStyle:F,rowClassName:I,rowStyle:L,children:R}){let z=n(null);return t(()=>{let e=z.current;if(!(!e||!m))return m.observe(e),()=>m.unobserve(e)},[m]),a(`div`,{ref:z,"data-index":o,className:r(e.virtualListRow,u&&e.virtualListRowSelected,!d&&e.virtualListRowNoDivider,!f&&e.virtualListRowNoHover,y&&e.virtualListRowDraggable,S&&e.virtualListRowDragging,M===`inside`&&e.virtualListRowDropInside,I),style:{position:`absolute`,top:0,left:0,right:0,transform:`translateY(${s}px)`,...c==null?{}:{padding:c},...l?{display:`grid`,gridTemplateColumns:l}:{},...C?{paddingRight:32}:{},...L},onClick:p,draggable:x,onMouseDown:w,onMouseOver:T,onMouseLeave:E,onDragStart:D,onDragOver:O,onDragEnd:k,onDrop:A??(b?e=>e.preventDefault():void 0),onTouchStart:j,onContextMenu:b?e=>e.preventDefault():void 0,"aria-selected":u,"aria-rowindex":h,"aria-posinset":g,"aria-setsize":_,role:v,children:[(M===`before`||M===`after`)&&i(`div`,{"data-drop-line":M,"aria-hidden":!0,className:r(e.virtualListDropLine,M===`before`?e.virtualListDropLineBefore:e.virtualListDropLineAfter,P),style:{left:N??0,...F}}),R]})}export{o as default};
1
+ import e from"./virtualList.module.mjs";import{useLayoutEffect as t,useRef as n}from"react";import r from"classnames";import{jsx as i,jsxs as a}from"react/jsx-runtime";function o({index:o,top:s,padding:c,columnTemplate:l,isSelected:u,showDivider:d,hover:f,onClick:p,observer:m,ariaRowIndex:h,ariaPosInSet:g,ariaSetSize:_,rowRole:v,reorderable:y,mouseDragEnabled:b,draggable:x,isDragging:S,reserveToggleGutter:C,onMouseDown:w,onMouseOver:T,onMouseLeave:E,onDragStart:D,onDragOver:O,onDragEnd:k,onDrop:A,onTouchStart:j,dropPosition:M,dropIndentPx:N,dropIndicatorClassName:P,dropIndicatorStyle:F,rowClassName:I,rowStyle:L,children:R}){let z=n(null);return t(()=>{let e=z.current;if(e&&m)return m.observe(e),()=>m.unobserve(e)},[m]),a(`div`,{ref:z,"data-index":o,className:r(e.virtualListRow,u&&e.virtualListRowSelected,!d&&e.virtualListRowNoDivider,!f&&e.virtualListRowNoHover,y&&e.virtualListRowDraggable,S&&e.virtualListRowDragging,M===`inside`&&e.virtualListRowDropInside,I),style:{position:`absolute`,top:0,left:0,right:0,transform:`translateY(${s}px)`,...c==null?{}:{padding:c},...l?{display:`grid`,gridTemplateColumns:l}:{},...C?{paddingRight:32}:{},...L},onClick:p,draggable:x,onMouseDown:w,onMouseOver:T,onMouseLeave:E,onDragStart:D,onDragOver:O,onDragEnd:k,onDrop:A??(b?e=>e.preventDefault():void 0),onTouchStart:j,onContextMenu:b?e=>e.preventDefault():void 0,"aria-selected":u,"aria-rowindex":h,"aria-posinset":g,"aria-setsize":_,role:v,children:[(M===`before`||M===`after`)&&i(`div`,{"data-drop-line":M,"aria-hidden":!0,className:r(e.virtualListDropLine,M===`before`?e.virtualListDropLineBefore:e.virtualListDropLineAfter,P),style:{left:N??0,...F}}),R]})}export{o as default};
2
2
  //# sourceMappingURL=virtualRow.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"virtualRow.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualRow.tsx"],"sourcesContent":["import React, { useRef, useLayoutEffect } from 'react';\nimport cx from 'classnames';\n\nimport styles from './virtualList.module.pcss';\nimport type { TreeDropPosition } from './virtualList.types';\n\nexport interface VirtualRowProps {\n index: number;\n top: number;\n /** Padding applied to the row (already normalised to a CSS string). */\n padding?: string;\n columnTemplate: string | undefined;\n isSelected: boolean;\n showDivider: boolean;\n hover: boolean;\n onClick: () => void;\n observer: ResizeObserver | null;\n ariaRowIndex?: number;\n ariaPosInSet?: number;\n ariaSetSize?: number;\n rowRole: string;\n reorderable?: boolean;\n /**\n * Native mouse DnD is active for the list. Distinct from `draggable`, which in\n * `dragHandle` mode is only set on the row the pointer has armed.\n */\n mouseDragEnabled?: boolean;\n draggable?: boolean;\n isDragging?: boolean;\n reserveToggleGutter?: boolean;\n onMouseDown?: (e: React.MouseEvent<HTMLDivElement>) => void;\n onMouseOver?: (e: React.MouseEvent<HTMLDivElement>) => void;\n onMouseLeave?: (e: React.MouseEvent<HTMLDivElement>) => void;\n onDragStart?: (e: React.DragEvent<HTMLDivElement>) => void;\n onDragOver?: (e: React.DragEvent<HTMLDivElement>) => void;\n onDragEnd?: () => void;\n onDrop?: (e: React.DragEvent<HTMLDivElement>) => void;\n onTouchStart?: (e: React.TouchEvent<HTMLDivElement>) => void;\n dropPosition?: TreeDropPosition;\n dropIndentPx?: number;\n dropIndicatorClassName?: string;\n dropIndicatorStyle?: React.CSSProperties;\n rowClassName?: string;\n rowStyle?: React.CSSProperties;\n children: React.ReactNode;\n}\n\n/**\n * A single virtualized row: absolutely positioned at its `top`, optionally a\n * grid (table mode), registering itself with the shared ResizeObserver and\n * carrying all the drag / drop-indicator wiring the parent assigns it.\n */\nfunction VirtualRow({\n index,\n top,\n padding,\n columnTemplate,\n isSelected,\n showDivider,\n hover,\n onClick,\n observer,\n ariaRowIndex,\n ariaPosInSet,\n ariaSetSize,\n rowRole,\n reorderable,\n mouseDragEnabled,\n draggable,\n isDragging,\n reserveToggleGutter,\n onMouseDown,\n onMouseOver,\n onMouseLeave,\n onDragStart,\n onDragOver,\n onDragEnd,\n onDrop,\n onTouchStart,\n dropPosition,\n dropIndentPx,\n dropIndicatorClassName,\n dropIndicatorStyle,\n rowClassName,\n rowStyle,\n children,\n}: VirtualRowProps) {\n const ref = useRef<HTMLDivElement>(null);\n\n // A single observer is shared across all rows (created by the parent); each\n // row just registers/unregisters its element. The parent reads the row index\n // back from the `data-index` attribute when the observer fires.\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el || !observer) return;\n observer.observe(el);\n return () => observer.unobserve(el);\n }, [observer]);\n\n return (\n <div\n ref={ref}\n data-index={index}\n className={cx(\n styles.virtualListRow,\n isSelected && styles.virtualListRowSelected,\n !showDivider && styles.virtualListRowNoDivider,\n !hover && styles.virtualListRowNoHover,\n reorderable && styles.virtualListRowDraggable,\n isDragging && styles.virtualListRowDragging,\n dropPosition === 'inside' && styles.virtualListRowDropInside,\n rowClassName,\n )}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n transform: `translateY(${top}px)`,\n ...(padding != null ? { padding } : {}),\n ...(columnTemplate ? { display: 'grid', gridTemplateColumns: columnTemplate } : {}),\n // Match the header's reserved gutter for the column-toggle cog so row\n // cells line up with their header cells instead of drifting under it.\n // Applied after `padding` so the alignment gutter always wins on the right.\n ...(reserveToggleGutter ? { paddingRight: 32 } : {}),\n ...rowStyle,\n }}\n onClick={onClick}\n draggable={draggable}\n onMouseDown={onMouseDown}\n onMouseOver={onMouseOver}\n onMouseLeave={onMouseLeave}\n onDragStart={onDragStart}\n onDragOver={onDragOver}\n onDragEnd={onDragEnd}\n onDrop={onDrop ?? (mouseDragEnabled ? (e) => e.preventDefault() : undefined)}\n onTouchStart={onTouchStart}\n onContextMenu={mouseDragEnabled ? (e) => e.preventDefault() : undefined}\n aria-selected={isSelected}\n aria-rowindex={ariaRowIndex}\n aria-posinset={ariaPosInSet}\n aria-setsize={ariaSetSize}\n role={rowRole}\n >\n {(dropPosition === 'before' || dropPosition === 'after') && (\n <div\n data-drop-line={dropPosition}\n aria-hidden\n className={cx(\n styles.virtualListDropLine,\n dropPosition === 'before' ? styles.virtualListDropLineBefore : styles.virtualListDropLineAfter,\n dropIndicatorClassName,\n )}\n style={{ left: dropIndentPx ?? 0, ...dropIndicatorStyle }}\n />\n )}\n {children}\n </div>\n );\n}\n\nexport default VirtualRow;\n"],"mappings":"wKAoDA,SAAS,EAAW,CAClB,QACA,MACA,UACA,iBACA,aACA,cACA,QACA,UACA,WACA,eACA,eACA,cACA,UACA,cACA,mBACA,YACA,aACA,sBACA,cACA,cACA,eACA,cACA,aACA,YACA,SACA,eACA,eACA,eACA,yBACA,qBACA,eACA,WACA,YACkB,CAClB,IAAM,EAAM,EAAuB,IAAI,EAYvC,OAPA,MAAsB,CACpB,IAAM,EAAK,EAAI,QACX,MAAC,GAAM,CAAC,GAEZ,OADA,EAAS,QAAQ,CAAE,MACN,EAAS,UAAU,CAAE,CACpC,EAAG,CAAC,CAAQ,CAAC,EAGX,EAAC,MAAD,CACO,MACL,aAAY,EACZ,UAAW,EACT,EAAO,eACP,GAAc,EAAO,uBACrB,CAAC,GAAe,EAAO,wBACvB,CAAC,GAAS,EAAO,sBACjB,GAAe,EAAO,wBACtB,GAAc,EAAO,uBACrB,IAAiB,UAAY,EAAO,yBACpC,CACF,EACA,MAAO,CACL,SAAU,WACV,IAAK,EACL,KAAM,EACN,MAAO,EACP,UAAW,cAAc,EAAI,KAC7B,GAAI,GAAW,KAAqB,CAAC,EAAf,CAAE,SAAQ,EAChC,GAAI,EAAiB,CAAE,QAAS,OAAQ,oBAAqB,CAAe,EAAI,CAAC,EAIjF,GAAI,EAAsB,CAAE,aAAc,EAAG,EAAI,CAAC,EAClD,GAAG,CACL,EACS,UACE,YACE,cACA,cACC,eACD,cACD,aACD,YACX,OAAQ,IAAW,EAAoB,GAAM,EAAE,eAAe,EAAI,IAAA,IACpD,eACd,cAAe,EAAoB,GAAM,EAAE,eAAe,EAAI,IAAA,GAC9D,gBAAe,EACf,gBAAe,EACf,gBAAe,EACf,eAAc,EACd,KAAM,WA1CR,EA4CI,IAAiB,UAAY,IAAiB,UAC9C,EAAC,MAAD,CACE,iBAAgB,EAChB,cAAA,GACA,UAAW,EACT,EAAO,oBACP,IAAiB,SAAW,EAAO,0BAA4B,EAAO,yBACtE,CACF,EACA,MAAO,CAAE,KAAM,GAAgB,EAAG,GAAG,CAAmB,CACzD,CAAA,EAEF,CACE,GAET"}
1
+ {"version":3,"file":"virtualRow.mjs","names":[],"sources":["../../../../package/common/virtualList/virtualRow.tsx"],"sourcesContent":["import React, { useRef, useLayoutEffect } from 'react';\nimport cx from 'classnames';\n\nimport styles from './virtualList.module.pcss';\nimport type { TreeDropPosition } from './virtualList.types';\n\nexport interface VirtualRowProps {\n index: number;\n top: number;\n /** Padding applied to the row (already normalised to a CSS string). */\n padding?: string;\n columnTemplate: string | undefined;\n isSelected: boolean;\n showDivider: boolean;\n hover: boolean;\n onClick: () => void;\n observer: ResizeObserver | null;\n ariaRowIndex?: number;\n ariaPosInSet?: number;\n ariaSetSize?: number;\n rowRole: string;\n reorderable?: boolean;\n /**\n * Native mouse DnD is active for the list. Distinct from `draggable`, which in\n * `dragHandle` mode is only set on the row the pointer has armed.\n */\n mouseDragEnabled?: boolean;\n draggable?: boolean;\n isDragging?: boolean;\n reserveToggleGutter?: boolean;\n onMouseDown?: (e: React.MouseEvent<HTMLDivElement>) => void;\n onMouseOver?: (e: React.MouseEvent<HTMLDivElement>) => void;\n onMouseLeave?: (e: React.MouseEvent<HTMLDivElement>) => void;\n onDragStart?: (e: React.DragEvent<HTMLDivElement>) => void;\n onDragOver?: (e: React.DragEvent<HTMLDivElement>) => void;\n onDragEnd?: () => void;\n onDrop?: (e: React.DragEvent<HTMLDivElement>) => void;\n onTouchStart?: (e: React.TouchEvent<HTMLDivElement>) => void;\n dropPosition?: TreeDropPosition;\n dropIndentPx?: number;\n dropIndicatorClassName?: string;\n dropIndicatorStyle?: React.CSSProperties;\n rowClassName?: string;\n rowStyle?: React.CSSProperties;\n children: React.ReactNode;\n}\n\n/**\n * A single virtualized row: absolutely positioned at its `top`, optionally a\n * grid (table mode), registering itself with the shared ResizeObserver and\n * carrying all the drag / drop-indicator wiring the parent assigns it.\n */\nfunction VirtualRow({\n index,\n top,\n padding,\n columnTemplate,\n isSelected,\n showDivider,\n hover,\n onClick,\n observer,\n ariaRowIndex,\n ariaPosInSet,\n ariaSetSize,\n rowRole,\n reorderable,\n mouseDragEnabled,\n draggable,\n isDragging,\n reserveToggleGutter,\n onMouseDown,\n onMouseOver,\n onMouseLeave,\n onDragStart,\n onDragOver,\n onDragEnd,\n onDrop,\n onTouchStart,\n dropPosition,\n dropIndentPx,\n dropIndicatorClassName,\n dropIndicatorStyle,\n rowClassName,\n rowStyle,\n children,\n}: VirtualRowProps) {\n const ref = useRef<HTMLDivElement>(null);\n\n // A single observer is shared across all rows (created by the parent); each\n // row just registers/unregisters its element. The parent reads the row index\n // back from the `data-index` attribute when the observer fires.\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el || !observer) return;\n observer.observe(el);\n return () => observer.unobserve(el);\n }, [observer]);\n\n return (\n <div\n ref={ref}\n data-index={index}\n className={cx(\n styles.virtualListRow,\n isSelected && styles.virtualListRowSelected,\n !showDivider && styles.virtualListRowNoDivider,\n !hover && styles.virtualListRowNoHover,\n reorderable && styles.virtualListRowDraggable,\n isDragging && styles.virtualListRowDragging,\n dropPosition === 'inside' && styles.virtualListRowDropInside,\n rowClassName,\n )}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n transform: `translateY(${top}px)`,\n ...(padding != null ? { padding } : {}),\n ...(columnTemplate ? { display: 'grid', gridTemplateColumns: columnTemplate } : {}),\n // Match the header's reserved gutter for the column-toggle cog so row\n // cells line up with their header cells instead of drifting under it.\n // Applied after `padding` so the alignment gutter always wins on the right.\n ...(reserveToggleGutter ? { paddingRight: 32 } : {}),\n ...rowStyle,\n }}\n onClick={onClick}\n draggable={draggable}\n onMouseDown={onMouseDown}\n onMouseOver={onMouseOver}\n onMouseLeave={onMouseLeave}\n onDragStart={onDragStart}\n onDragOver={onDragOver}\n onDragEnd={onDragEnd}\n onDrop={onDrop ?? (mouseDragEnabled ? (e) => e.preventDefault() : undefined)}\n onTouchStart={onTouchStart}\n onContextMenu={mouseDragEnabled ? (e) => e.preventDefault() : undefined}\n aria-selected={isSelected}\n aria-rowindex={ariaRowIndex}\n aria-posinset={ariaPosInSet}\n aria-setsize={ariaSetSize}\n role={rowRole}\n >\n {(dropPosition === 'before' || dropPosition === 'after') && (\n <div\n data-drop-line={dropPosition}\n aria-hidden\n className={cx(\n styles.virtualListDropLine,\n dropPosition === 'before' ? styles.virtualListDropLineBefore : styles.virtualListDropLineAfter,\n dropIndicatorClassName,\n )}\n style={{ left: dropIndentPx ?? 0, ...dropIndicatorStyle }}\n />\n )}\n {children}\n </div>\n );\n}\n\nexport default VirtualRow;\n"],"mappings":"wKAoDA,SAAS,EAAW,CAClB,QACA,MACA,UACA,iBACA,aACA,cACA,QACA,UACA,WACA,eACA,eACA,cACA,UACA,cACA,mBACA,YACA,aACA,sBACA,cACA,cACA,eACA,cACA,aACA,YACA,SACA,eACA,eACA,eACA,yBACA,qBACA,eACA,WACA,YACkB,CAClB,IAAM,EAAM,EAAuB,IAAI,EAYvC,OAPA,MAAsB,CACpB,IAAM,EAAK,EAAI,QACX,GAAC,GAAO,EAEZ,OADA,EAAS,QAAQ,CAAE,MACN,EAAS,UAAU,CAAE,CACpC,EAAG,CAAC,CAAQ,CAAC,EAGX,EAAC,MAAD,CACO,MACL,aAAY,EACZ,UAAW,EACT,EAAO,eACP,GAAc,EAAO,uBACrB,CAAC,GAAe,EAAO,wBACvB,CAAC,GAAS,EAAO,sBACjB,GAAe,EAAO,wBACtB,GAAc,EAAO,uBACrB,IAAiB,UAAY,EAAO,yBACpC,CACF,EACA,MAAO,CACL,SAAU,WACV,IAAK,EACL,KAAM,EACN,MAAO,EACP,UAAW,cAAc,EAAI,KAC7B,GAAI,GAAW,KAAqB,CAAC,EAAf,CAAE,SAAQ,EAChC,GAAI,EAAiB,CAAE,QAAS,OAAQ,oBAAqB,CAAe,EAAI,CAAC,EAIjF,GAAI,EAAsB,CAAE,aAAc,EAAG,EAAI,CAAC,EAClD,GAAG,CACL,EACS,UACE,YACE,cACA,cACC,eACD,cACD,aACD,YACX,OAAQ,IAAW,EAAoB,GAAM,EAAE,eAAe,EAAI,IAAA,IACpD,eACd,cAAe,EAAoB,GAAM,EAAE,eAAe,EAAI,IAAA,GAC9D,gBAAe,EACf,gBAAe,EACf,gBAAe,EACf,eAAc,EACd,KAAM,EA1CR,SAAA,EA4CI,IAAiB,UAAY,IAAiB,UAC9C,EAAC,MAAD,CACE,iBAAgB,EAChB,cAAA,GACA,UAAW,EACT,EAAO,oBACP,IAAiB,SAAW,EAAO,0BAA4B,EAAO,yBACtE,CACF,EACA,MAAO,CAAE,KAAM,GAAgB,EAAG,GAAG,CAAmB,CACzD,CAAA,EAEF,CACE,GAET"}
@@ -1,2 +1,2 @@
1
- import e from"./wizard.module.mjs";import{useEffect as t,useRef as n,useState as r}from"react";import i from"classnames";import{jsx as a}from"react/jsx-runtime";function o({currentStep:o=0,stepCount:s=0,renderStep:c=()=>null,className:l,style:u,classNames:d,styles:f,...p}){let[m,h]=r(void 0),[g,_]=r(!1),[v,y]=r(o),b=n([]),x=n(null);o!==v&&(y(o),_(!0)),t(()=>{if(!g)return;let e=setTimeout(()=>_(!1),400);return()=>clearTimeout(e)},[g]),t(()=>{x.current?.disconnect();let e=b.current[o];if(e)return h(e.clientHeight),x.current=new ResizeObserver(()=>{h(e.clientHeight)}),x.current.observe(e),()=>x.current?.disconnect()},[o,s]);let S={...m===void 0?{}:{height:`${m}px`},...f?.root,...u};return a(`div`,{...p,className:i(e.wizard,d?.root,l),style:S,children:a(`div`,{className:i(e.wizardContentContainer,d?.container),style:{width:`${s*100}%`,marginLeft:`-${o*100}%`,...f?.container},children:Array.from({length:s},(t,n)=>a(`div`,{ref:e=>{b.current[n]=e},className:i(e.wizardContent,d?.step),style:{width:`${100/s}%`,marginLeft:`${100/s*n}%`,...f?.step},children:a(`div`,{className:i({[e.wizardContentOutOfFrame]:o!==n&&!g},d?.stepContent),style:f?.stepContent,inert:o===n?void 0:!0,children:c(n)})},`wizardStep${n}`))})})}export{o as default};
1
+ import e from"./wizard.module.mjs";import{useEffect as t,useRef as n,useState as r}from"react";import i from"classnames";import{jsx as a}from"react/jsx-runtime";function o({currentStep:o=0,stepCount:s=0,renderStep:c=()=>null,className:l,style:u,classNames:d,styles:f,...p}){let[m,h]=r(void 0),[g,_]=r(!1),[v,y]=r(o),b=n([]),x=n(null);o!==v&&(y(o),_(!0)),t(()=>{if(!g)return;let e=setTimeout(()=>_(!1),400);return()=>clearTimeout(e)},[g]),t(()=>{x.current?.disconnect();let e=b.current[o];if(e)return h(e.clientHeight),x.current=new ResizeObserver(()=>{h(e.clientHeight)}),x.current.observe(e),()=>x.current?.disconnect()},[o,s]);let S={...m===void 0?{}:{height:`${m}px`},...f?.root,...u};return a(`div`,{...p,className:i(e.wizard,d?.root,l),style:S,children:a(`div`,{className:i(e.wizardContentContainer,d?.container),style:{width:`${s*100}%`,marginLeft:`-${o*100}%`,...f?.container},children:Array.from({length:s},(t,n)=>a(`div`,{ref:e=>{b.current[n]=e},className:i(e.wizardContent,d?.step),style:{width:`${100/s}%`,marginLeft:`${100/s*n}%`,...f?.step},children:a(`div`,{className:i({[e.wizardContentOutOfFrame]:o!==n&&!g},d?.stepContent),style:f?.stepContent,inert:o!==n||void 0,children:c(n)})},`wizardStep${n}`))})})}export{o as default};
2
2
  //# sourceMappingURL=wizard.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"wizard.mjs","names":[],"sources":["../../../../package/common/wizard/wizard.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport styles from './wizard.module.pcss';\nimport type { WizardProps } from './wizard.types';\n\nexport default function Wizard({\n currentStep = 0,\n stepCount = 0,\n renderStep = () => null,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: WizardProps) {\n const [height, setHeight] = useState<number | undefined>(undefined);\n const [showOtherContent, setShowOtherContent] = useState(false);\n const [prevStep, setPrevStep] = useState(currentStep);\n const stepRefs = useRef<(HTMLDivElement | null)[]>([]);\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n\n // When currentStep changes, briefly show off-screen steps so they animate out.\n if (currentStep !== prevStep) {\n setPrevStep(currentStep);\n setShowOtherContent(true);\n }\n\n useEffect(() => {\n if (!showOtherContent) return;\n const id = setTimeout(() => setShowOtherContent(false), 400);\n return () => clearTimeout(id);\n }, [showOtherContent]);\n\n // Track the height of the active step via ResizeObserver.\n useEffect(() => {\n resizeObserverRef.current?.disconnect();\n const el = stepRefs.current[currentStep];\n if (!el) return;\n setHeight(el.clientHeight);\n resizeObserverRef.current = new ResizeObserver(() => {\n setHeight(el.clientHeight);\n });\n resizeObserverRef.current.observe(el);\n return () => resizeObserverRef.current?.disconnect();\n }, [currentStep, stepCount]);\n\n const rootStyle: React.CSSProperties = {\n ...(height !== undefined ? { height: `${height}px` } : {}),\n ...slotStyles?.root,\n ...style,\n };\n\n return (\n <div\n {...rest}\n className={cx(styles.wizard, classNames?.root, className)}\n style={rootStyle}\n >\n <div\n className={cx(styles.wizardContentContainer, classNames?.container)}\n style={{\n width: `${stepCount * 100}%`,\n marginLeft: `-${currentStep * 100}%`,\n ...slotStyles?.container,\n }}\n >\n {Array.from({ length: stepCount }, (_, index) => (\n <div\n key={`wizardStep${index}`}\n ref={(ref) => { stepRefs.current[index] = ref; }}\n className={cx(styles.wizardContent, classNames?.step)}\n style={{\n width: `${100 / stepCount}%`,\n marginLeft: `${(100 / stepCount) * index}%`,\n ...slotStyles?.step,\n }}\n >\n <div\n className={cx(\n { [styles.wizardContentOutOfFrame]: currentStep !== index && !showOtherContent },\n classNames?.stepContent\n )}\n style={slotStyles?.stepContent}\n inert={currentStep !== index ? true : undefined}\n >\n {renderStep(index)}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"iKAKA,SAAwB,EAAO,CAC7B,cAAc,EACd,YAAY,EACZ,iBAAmB,KACnB,YACA,QACA,aACA,OAAQ,EACR,GAAG,GACW,CACd,GAAM,CAAC,EAAQ,GAAa,EAA6B,IAAA,EAAS,EAC5D,CAAC,EAAkB,GAAuB,EAAS,EAAK,EACxD,CAAC,EAAU,GAAe,EAAS,CAAW,EAC9C,EAAW,EAAkC,CAAC,CAAC,EAC/C,EAAoB,EAA8B,IAAI,EAGxD,IAAgB,IAClB,EAAY,CAAW,EACvB,EAAoB,EAAI,GAG1B,MAAgB,CACd,GAAI,CAAC,EAAkB,OACvB,IAAM,EAAK,eAAiB,EAAoB,EAAK,EAAG,GAAG,EAC3D,UAAa,aAAa,CAAE,CAC9B,EAAG,CAAC,CAAgB,CAAC,EAGrB,MAAgB,CACd,EAAkB,SAAS,WAAW,EACtC,IAAM,EAAK,EAAS,QAAQ,GACvB,KAML,OALA,EAAU,EAAG,YAAY,EACzB,EAAkB,QAAU,IAAI,mBAAqB,CACnD,EAAU,EAAG,YAAY,CAC3B,CAAC,EACD,EAAkB,QAAQ,QAAQ,CAAE,MACvB,EAAkB,SAAS,WAAW,CACrD,EAAG,CAAC,EAAa,CAAS,CAAC,EAE3B,IAAM,EAAiC,CACrC,GAAI,IAAW,IAAA,GAAwC,CAAC,EAA7B,CAAE,OAAQ,GAAG,EAAO,GAAI,EACnD,GAAG,GAAY,KACf,GAAG,CACL,EAEA,OACE,EAAC,MAAD,CACE,GAAI,EACJ,UAAW,EAAG,EAAO,OAAQ,GAAY,KAAM,CAAS,EACxD,MAAO,WAEP,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,uBAAwB,GAAY,SAAS,EAClE,MAAO,CACL,MAAO,GAAG,EAAY,IAAI,GAC1B,WAAY,IAAI,EAAc,IAAI,GAClC,GAAG,GAAY,SACjB,WAEC,MAAM,KAAK,CAAE,OAAQ,CAAU,GAAI,EAAG,IACrC,EAAC,MAAD,CAEE,IAAM,GAAQ,CAAE,EAAS,QAAQ,GAAS,CAAK,EAC/C,UAAW,EAAG,EAAO,cAAe,GAAY,IAAI,EACpD,MAAO,CACL,MAAO,GAAG,IAAM,EAAU,GAC1B,WAAY,GAAI,IAAM,EAAa,EAAM,GACzC,GAAG,GAAY,IACjB,WAEA,EAAC,MAAD,CACE,UAAW,EACT,EAAG,EAAO,yBAA0B,IAAgB,GAAS,CAAC,CAAiB,EAC/E,GAAY,WACd,EACA,MAAO,GAAY,YACnB,MAAO,IAAgB,EAAe,IAAA,GAAP,YAE9B,EAAW,CAAK,CACd,CAAA,CACF,EAnBE,aAAa,GAmBf,CACN,CACE,CAAA,CACF,CAAA,CAET"}
1
+ {"version":3,"file":"wizard.mjs","names":[],"sources":["../../../../package/common/wizard/wizard.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport styles from './wizard.module.pcss';\nimport type { WizardProps } from './wizard.types';\n\nexport default function Wizard({\n currentStep = 0,\n stepCount = 0,\n renderStep = () => null,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n}: WizardProps) {\n const [height, setHeight] = useState<number | undefined>(undefined);\n const [showOtherContent, setShowOtherContent] = useState(false);\n const [prevStep, setPrevStep] = useState(currentStep);\n const stepRefs = useRef<(HTMLDivElement | null)[]>([]);\n const resizeObserverRef = useRef<ResizeObserver | null>(null);\n\n // When currentStep changes, briefly show off-screen steps so they animate out.\n if (currentStep !== prevStep) {\n setPrevStep(currentStep);\n setShowOtherContent(true);\n }\n\n useEffect(() => {\n if (!showOtherContent) return;\n const id = setTimeout(() => setShowOtherContent(false), 400);\n return () => clearTimeout(id);\n }, [showOtherContent]);\n\n // Track the height of the active step via ResizeObserver.\n useEffect(() => {\n resizeObserverRef.current?.disconnect();\n const el = stepRefs.current[currentStep];\n if (!el) return;\n setHeight(el.clientHeight);\n resizeObserverRef.current = new ResizeObserver(() => {\n setHeight(el.clientHeight);\n });\n resizeObserverRef.current.observe(el);\n return () => resizeObserverRef.current?.disconnect();\n }, [currentStep, stepCount]);\n\n const rootStyle: React.CSSProperties = {\n ...(height !== undefined ? { height: `${height}px` } : {}),\n ...slotStyles?.root,\n ...style,\n };\n\n return (\n <div {...rest} className={cx(styles.wizard, classNames?.root, className)} style={rootStyle}>\n <div\n className={cx(styles.wizardContentContainer, classNames?.container)}\n style={{\n width: `${stepCount * 100}%`,\n marginLeft: `-${currentStep * 100}%`,\n ...slotStyles?.container,\n }}\n >\n {Array.from({ length: stepCount }, (_, index) => (\n <div\n key={`wizardStep${index}`}\n ref={(ref) => {\n stepRefs.current[index] = ref;\n }}\n className={cx(styles.wizardContent, classNames?.step)}\n style={{\n width: `${100 / stepCount}%`,\n marginLeft: `${(100 / stepCount) * index}%`,\n ...slotStyles?.step,\n }}\n >\n <div\n className={cx(\n { [styles.wizardContentOutOfFrame]: currentStep !== index && !showOtherContent },\n classNames?.stepContent,\n )}\n style={slotStyles?.stepContent}\n inert={currentStep !== index ? true : undefined}\n >\n {renderStep(index)}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"iKAKA,SAAwB,EAAO,CAC7B,cAAc,EACd,YAAY,EACZ,iBAAmB,KACnB,YACA,QACA,aACA,OAAQ,EACR,GAAG,GACW,CACd,GAAM,CAAC,EAAQ,GAAa,EAA6B,IAAA,EAAS,EAC5D,CAAC,EAAkB,GAAuB,EAAS,EAAK,EACxD,CAAC,EAAU,GAAe,EAAS,CAAW,EAC9C,EAAW,EAAkC,CAAC,CAAC,EAC/C,EAAoB,EAA8B,IAAI,EAGxD,IAAgB,IAClB,EAAY,CAAW,EACvB,EAAoB,EAAI,GAG1B,MAAgB,CACd,GAAI,CAAC,EAAkB,OACvB,IAAM,EAAK,eAAiB,EAAoB,EAAK,EAAG,GAAG,EAC3D,UAAa,aAAa,CAAE,CAC9B,EAAG,CAAC,CAAgB,CAAC,EAGrB,MAAgB,CACd,EAAkB,SAAS,WAAW,EACtC,IAAM,EAAK,EAAS,QAAQ,GACvB,KAML,OALA,EAAU,EAAG,YAAY,EACzB,EAAkB,QAAU,IAAI,mBAAqB,CACnD,EAAU,EAAG,YAAY,CAC3B,CAAC,EACD,EAAkB,QAAQ,QAAQ,CAAE,MACvB,EAAkB,SAAS,WAAW,CACrD,EAAG,CAAC,EAAa,CAAS,CAAC,EAE3B,IAAM,EAAiC,CACrC,GAAI,IAAW,IAAA,GAAwC,CAAC,EAA7B,CAAE,OAAQ,GAAG,EAAO,GAAI,EACnD,GAAG,GAAY,KACf,GAAG,CACL,EAEA,OACE,EAAC,MAAD,CAAK,GAAI,EAAM,UAAW,EAAG,EAAO,OAAQ,GAAY,KAAM,CAAS,EAAG,MAAO,EAC/E,SAAA,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,uBAAwB,GAAY,SAAS,EAClE,MAAO,CACL,MAAO,GAAG,EAAY,IAAI,GAC1B,WAAY,IAAI,EAAc,IAAI,GAClC,GAAG,GAAY,SACjB,EAEC,SAAA,MAAM,KAAK,CAAE,OAAQ,CAAU,GAAI,EAAG,IACrC,EAAC,MAAD,CAEE,IAAM,GAAQ,CACZ,EAAS,QAAQ,GAAS,CAC5B,EACA,UAAW,EAAG,EAAO,cAAe,GAAY,IAAI,EACpD,MAAO,CACL,MAAO,GAAG,IAAM,EAAU,GAC1B,WAAY,GAAI,IAAM,EAAa,EAAM,GACzC,GAAG,GAAY,IACjB,EAEA,SAAA,EAAC,MAAD,CACE,UAAW,EACT,EAAG,EAAO,yBAA0B,IAAgB,GAAS,CAAC,CAAiB,EAC/E,GAAY,WACd,EACA,MAAO,GAAY,YACnB,MAAO,IAAgB,GAAe,IAAA,GAErC,SAAA,EAAW,CAAK,CACd,CAAA,CACF,EArBE,aAAa,GAqBf,CACN,CACE,CAAA,CACF,CAAA,CAET"}
@@ -1,2 +1,2 @@
1
- var e={wizard:`wizard_uRBAN`,"wizard-content":`wizard-content_lcl4C`,wizardContent:`wizard-content_lcl4C`,"wizard-content-outOfFrame":`wizard-content-outOfFrame_Eks4Y`,wizardContentOutOfFrame:`wizard-content-outOfFrame_Eks4Y`,"wizard-content-container":`wizard-content-container_yxbCJ`,wizardContentContainer:`wizard-content-container_yxbCJ`};export{e as default};
1
+ var e=`wizard_uRBAN`,t=`wizard-content_lcl4C`,n=`wizard-content-outOfFrame_Eks4Y`,r=`wizard-content-container_yxbCJ`,i={wizard:e,"wizard-content":`wizard-content_lcl4C`,wizardContent:t,"wizard-content-outOfFrame":`wizard-content-outOfFrame_Eks4Y`,wizardContentOutOfFrame:n,"wizard-content-container":`wizard-content-container_yxbCJ`,wizardContentContainer:r};export{i as default,e as wizard,t as wizardContent,r as wizardContentContainer,n as wizardContentOutOfFrame};
2
2
  //# sourceMappingURL=wizard.module.mjs.map