@ahrowe/ui 0.35.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (727) hide show
  1. package/README.md +100 -71
  2. package/dist/cjs-types/common/accordion/accordion.d.ts +4 -0
  3. package/dist/cjs-types/common/accordion/accordion.types.d.ts +21 -0
  4. package/dist/cjs-types/common/accordion/index.d.ts +2 -0
  5. package/dist/cjs-types/common/actionButtons/actionButtons.d.ts +2 -0
  6. package/dist/cjs-types/common/actionButtons/actionButtons.types.d.ts +34 -0
  7. package/dist/cjs-types/common/actionButtons/index.d.ts +2 -0
  8. package/dist/cjs-types/common/actionIcon/actionIcon.d.ts +4 -0
  9. package/dist/cjs-types/common/actionIcon/actionIcon.types.d.ts +15 -0
  10. package/dist/cjs-types/common/actionIcon/index.d.ts +2 -0
  11. package/dist/cjs-types/common/alert/alert.d.ts +4 -0
  12. package/dist/cjs-types/common/alert/alert.types.d.ts +30 -0
  13. package/dist/cjs-types/common/alert/index.d.ts +2 -0
  14. package/dist/cjs-types/common/animatedIcon/animatedIcon.d.ts +3 -0
  15. package/dist/cjs-types/common/animatedIcon/animatedIcon.types.d.ts +25 -0
  16. package/dist/cjs-types/common/animatedIcon/index.d.ts +2 -0
  17. package/dist/cjs-types/common/animatedLogo/animatedLogo.d.ts +4 -0
  18. package/dist/cjs-types/common/animatedLogo/animatedLogo.types.d.ts +35 -0
  19. package/dist/cjs-types/common/animatedLogo/index.d.ts +2 -0
  20. package/dist/cjs-types/common/animatedText/animatedText.d.ts +4 -0
  21. package/dist/cjs-types/common/animatedText/animatedText.types.d.ts +65 -0
  22. package/dist/cjs-types/common/animatedText/index.d.ts +2 -0
  23. package/dist/cjs-types/common/avatar/avatar.d.ts +4 -0
  24. package/dist/cjs-types/common/avatar/avatar.types.d.ts +26 -0
  25. package/dist/cjs-types/common/avatar/avatarGroup.d.ts +4 -0
  26. package/dist/cjs-types/common/avatar/index.d.ts +3 -0
  27. package/dist/cjs-types/common/badge/badge.d.ts +4 -0
  28. package/dist/cjs-types/common/badge/badge.types.d.ts +31 -0
  29. package/dist/cjs-types/common/badge/index.d.ts +2 -0
  30. package/dist/cjs-types/common/bodyEnd/bodyEnd.d.ts +4 -0
  31. package/dist/cjs-types/common/bodyEnd/bodyEnd.types.d.ts +4 -0
  32. package/dist/cjs-types/common/bodyEnd/index.d.ts +2 -0
  33. package/dist/cjs-types/common/breadcrumb/breadcrumb.d.ts +4 -0
  34. package/dist/cjs-types/common/breadcrumb/breadcrumb.types.d.ts +33 -0
  35. package/dist/cjs-types/common/breadcrumb/index.d.ts +2 -0
  36. package/dist/cjs-types/common/button/button.d.ts +9 -0
  37. package/dist/cjs-types/common/button/button.types.d.ts +42 -0
  38. package/dist/cjs-types/common/button/index.d.ts +2 -0
  39. package/dist/cjs-types/common/buttonGroup/buttonGroup.d.ts +4 -0
  40. package/dist/cjs-types/common/buttonGroup/buttonGroup.types.d.ts +12 -0
  41. package/dist/cjs-types/common/buttonGroup/index.d.ts +2 -0
  42. package/dist/cjs-types/common/card/Card.d.ts +4 -0
  43. package/dist/cjs-types/common/card/CardActions.d.ts +4 -0
  44. package/dist/cjs-types/common/card/CardContent.d.ts +4 -0
  45. package/dist/cjs-types/common/card/CardHeader.d.ts +4 -0
  46. package/dist/cjs-types/common/card/CardMedia.d.ts +4 -0
  47. package/dist/cjs-types/common/card/card.types.d.ts +55 -0
  48. package/dist/cjs-types/common/card/index.d.ts +6 -0
  49. package/dist/cjs-types/common/carousel/carousel.d.ts +4 -0
  50. package/dist/cjs-types/common/carousel/carousel.types.d.ts +35 -0
  51. package/dist/cjs-types/common/carousel/index.d.ts +2 -0
  52. package/dist/cjs-types/common/checkbox/checkbox.d.ts +4 -0
  53. package/dist/cjs-types/common/checkbox/checkbox.types.d.ts +27 -0
  54. package/dist/cjs-types/common/checkbox/index.d.ts +2 -0
  55. package/dist/cjs-types/common/chip/chip.d.ts +4 -0
  56. package/dist/cjs-types/common/chip/chip.types.d.ts +35 -0
  57. package/dist/cjs-types/common/chip/chipContainer.d.ts +4 -0
  58. package/dist/cjs-types/common/chip/index.d.ts +3 -0
  59. package/dist/cjs-types/common/colorPicker/colorPicker.d.ts +4 -0
  60. package/dist/cjs-types/common/colorPicker/colorPicker.types.d.ts +25 -0
  61. package/dist/cjs-types/common/colorPicker/index.d.ts +2 -0
  62. package/dist/cjs-types/common/colorPicker/toHex.d.ts +11 -0
  63. package/dist/cjs-types/common/configProvider/configProvider.d.ts +13 -0
  64. package/dist/cjs-types/common/configProvider/configProvider.types.d.ts +133 -0
  65. package/dist/cjs-types/common/configProvider/index.d.ts +6 -0
  66. package/dist/cjs-types/common/configProvider/presentation.types.d.ts +14 -0
  67. package/dist/cjs-types/common/configProvider/useComponentDefaults.d.ts +17 -0
  68. package/dist/cjs-types/common/configProvider/useLabels.d.ts +22 -0
  69. package/dist/cjs-types/common/configProvider/usePresentationDefault.d.ts +8 -0
  70. package/dist/cjs-types/common/confirmModal/confirmModal.d.ts +4 -0
  71. package/dist/cjs-types/common/confirmModal/confirmModal.types.d.ts +24 -0
  72. package/dist/cjs-types/common/confirmModal/index.d.ts +2 -0
  73. package/dist/cjs-types/common/datePicker/components/datePickerMonth/datePickerMonth.d.ts +2 -0
  74. package/dist/cjs-types/common/datePicker/components/datePickerMonth/datePickerMonth.types.d.ts +23 -0
  75. package/dist/cjs-types/common/datePicker/components/datePickerMonth/index.d.ts +1 -0
  76. package/dist/cjs-types/common/datePicker/dateFunctions.d.ts +44 -0
  77. package/dist/cjs-types/common/datePicker/datePicker.d.ts +3 -0
  78. package/dist/cjs-types/common/datePicker/datePicker.types.d.ts +60 -0
  79. package/dist/cjs-types/common/datePicker/index.d.ts +2 -0
  80. package/dist/cjs-types/common/divider/divider.d.ts +4 -0
  81. package/dist/cjs-types/common/divider/divider.types.d.ts +21 -0
  82. package/dist/cjs-types/common/divider/index.d.ts +2 -0
  83. package/dist/cjs-types/common/drawer/drawer.d.ts +4 -0
  84. package/dist/cjs-types/common/drawer/drawer.types.d.ts +15 -0
  85. package/dist/cjs-types/common/drawer/index.d.ts +2 -0
  86. package/dist/cjs-types/common/dropZone/dropZone.d.ts +4 -0
  87. package/dist/cjs-types/common/dropZone/dropZone.types.d.ts +90 -0
  88. package/dist/cjs-types/common/dropZone/index.d.ts +2 -0
  89. package/dist/cjs-types/common/dropdown/dropdown.d.ts +4 -0
  90. package/dist/cjs-types/common/dropdown/dropdown.types.d.ts +47 -0
  91. package/dist/cjs-types/common/dropdown/index.d.ts +2 -0
  92. package/dist/cjs-types/common/emptyState/emptyState.d.ts +3 -0
  93. package/dist/cjs-types/common/emptyState/emptyState.types.d.ts +20 -0
  94. package/dist/cjs-types/common/emptyState/index.d.ts +2 -0
  95. package/dist/cjs-types/common/errorBoundary/errorBoundary.d.ts +14 -0
  96. package/dist/cjs-types/common/errorBoundary/errorBoundary.types.d.ts +57 -0
  97. package/dist/cjs-types/common/errorBoundary/index.d.ts +2 -0
  98. package/dist/cjs-types/common/fab/components/fabBase/fabBase.d.ts +3 -0
  99. package/dist/cjs-types/common/fab/components/fabBase/fabBase.types.d.ts +12 -0
  100. package/dist/cjs-types/common/fab/components/fabBase/index.d.ts +1 -0
  101. package/dist/cjs-types/common/fab/fab.d.ts +3 -0
  102. package/dist/cjs-types/common/fab/fab.types.d.ts +22 -0
  103. package/dist/cjs-types/common/fab/index.d.ts +2 -0
  104. package/dist/cjs-types/common/flip/flip.d.ts +3 -0
  105. package/dist/cjs-types/common/flip/flip.types.d.ts +44 -0
  106. package/dist/cjs-types/common/flip/index.d.ts +2 -0
  107. package/dist/cjs-types/common/floorPlan/floorPlan.faces.d.ts +33 -0
  108. package/dist/cjs-types/common/floorPlan/floorPlan.fixtures.d.ts +35 -0
  109. package/dist/cjs-types/common/floorPlan/floorPlan.geometry.d.ts +111 -0
  110. package/dist/cjs-types/common/floorPlan/floorPlan.graph.d.ts +184 -0
  111. package/dist/cjs-types/common/floorPlan/floorPlan.hit.d.ts +26 -0
  112. package/dist/cjs-types/common/floorPlan/floorPlan.json.d.ts +23 -0
  113. package/dist/cjs-types/common/floorPlan/floorPlan.mesh.d.ts +36 -0
  114. package/dist/cjs-types/common/floorPlan/floorPlan.path.d.ts +59 -0
  115. package/dist/cjs-types/common/floorPlan/floorPlan.plan.d.ts +98 -0
  116. package/dist/cjs-types/common/floorPlan/floorPlan.rooms.d.ts +47 -0
  117. package/dist/cjs-types/common/floorPlan/floorPlan.snap.d.ts +101 -0
  118. package/dist/cjs-types/common/floorPlan/floorPlan.triangulate.d.ts +11 -0
  119. package/dist/cjs-types/common/floorPlan/floorPlan.types.d.ts +276 -0
  120. package/dist/cjs-types/common/floorPlan/index.d.ts +30 -0
  121. package/dist/cjs-types/common/floorPlan/legacySvg.d.ts +27 -0
  122. package/dist/cjs-types/common/hooks/useAnchorTracking.d.ts +40 -0
  123. package/dist/cjs-types/common/hooks/useCoarsePointer.d.ts +3 -0
  124. package/dist/cjs-types/common/hooks/useFocusBoundary.d.ts +20 -0
  125. package/dist/cjs-types/common/hooks/useMediaQuery.d.ts +9 -0
  126. package/dist/cjs-types/common/hooks/useOverlay.d.ts +26 -0
  127. package/dist/cjs-types/common/hooks/useScrollEdges.d.ts +18 -0
  128. package/dist/cjs-types/common/hooks/useSheet.d.ts +19 -0
  129. package/dist/cjs-types/common/hooks/useSwipeDismiss.d.ts +33 -0
  130. package/dist/cjs-types/common/hooks/useVisualViewportSize.d.ts +13 -0
  131. package/dist/cjs-types/common/iconPicker/iconPicker.d.ts +3 -0
  132. package/dist/cjs-types/common/iconPicker/iconPicker.types.d.ts +23 -0
  133. package/dist/cjs-types/common/iconPicker/index.d.ts +2 -0
  134. package/dist/cjs-types/common/idleManager/idleManager.d.ts +3 -0
  135. package/dist/cjs-types/common/idleManager/idleManager.types.d.ts +8 -0
  136. package/dist/cjs-types/common/idleManager/index.d.ts +2 -0
  137. package/dist/cjs-types/common/infiniteBlock/useInfiniteScroll.d.ts +5 -0
  138. package/dist/cjs-types/common/input/index.d.ts +2 -0
  139. package/dist/cjs-types/common/input/input.d.ts +4 -0
  140. package/dist/cjs-types/common/input/input.types.d.ts +84 -0
  141. package/dist/cjs-types/common/inputDropdown/index.d.ts +2 -0
  142. package/dist/cjs-types/common/inputDropdown/inputDropdown.d.ts +3 -0
  143. package/dist/cjs-types/common/inputDropdown/inputDropdown.types.d.ts +36 -0
  144. package/dist/cjs-types/common/interactableDiv/index.d.ts +2 -0
  145. package/dist/cjs-types/common/interactableDiv/interactableDiv.d.ts +8 -0
  146. package/dist/cjs-types/common/kanbanBoard/KanbanBoard.d.ts +3 -0
  147. package/dist/cjs-types/common/kanbanBoard/KanbanColumn.d.ts +45 -0
  148. package/dist/cjs-types/common/kanbanBoard/KanbanItem.d.ts +3 -0
  149. package/dist/cjs-types/common/kanbanBoard/index.d.ts +3 -0
  150. package/dist/cjs-types/common/kanbanBoard/kanbanBoard.types.d.ts +129 -0
  151. package/dist/cjs-types/common/kanbanBoard/kanbanBoard.utils.d.ts +60 -0
  152. package/dist/cjs-types/common/klipyPicker/components/gifPreview/gifPreview.d.ts +3 -0
  153. package/dist/cjs-types/common/klipyPicker/components/gifPreview/gifPreview.types.d.ts +7 -0
  154. package/dist/cjs-types/common/klipyPicker/components/gifPreview/index.d.ts +1 -0
  155. package/dist/cjs-types/common/klipyPicker/components/gifView/gifView.d.ts +3 -0
  156. package/dist/cjs-types/common/klipyPicker/components/gifView/gifView.types.d.ts +4 -0
  157. package/dist/cjs-types/common/klipyPicker/components/gifView/index.d.ts +1 -0
  158. package/dist/cjs-types/common/klipyPicker/index.d.ts +2 -0
  159. package/dist/cjs-types/common/klipyPicker/klipyPicker.d.ts +3 -0
  160. package/dist/cjs-types/common/klipyPicker/klipyPicker.types.d.ts +15 -0
  161. package/dist/cjs-types/common/loading/iconLoading/iconLoading.d.ts +5 -0
  162. package/dist/cjs-types/common/loading/iconLoading/index.d.ts +2 -0
  163. package/dist/cjs-types/common/loading/index.d.ts +2 -0
  164. package/dist/cjs-types/common/loading/spinnerLoading/index.d.ts +2 -0
  165. package/dist/cjs-types/common/loading/spinnerLoading/spinnerLoading.d.ts +6 -0
  166. package/dist/cjs-types/common/maskedInput/index.d.ts +2 -0
  167. package/dist/cjs-types/common/maskedInput/mask.d.ts +48 -0
  168. package/dist/cjs-types/common/maskedInput/maskedInput.d.ts +13 -0
  169. package/dist/cjs-types/common/maskedInput/maskedInput.types.d.ts +38 -0
  170. package/dist/cjs-types/common/menu/index.d.ts +2 -0
  171. package/dist/cjs-types/common/menu/menu.d.ts +14 -0
  172. package/dist/cjs-types/common/menu/menu.types.d.ts +55 -0
  173. package/dist/cjs-types/common/modal/index.d.ts +2 -0
  174. package/dist/cjs-types/common/modal/modal.d.ts +3 -0
  175. package/dist/cjs-types/common/modal/modal.types.d.ts +31 -0
  176. package/dist/cjs-types/common/multiSelect/index.d.ts +2 -0
  177. package/dist/cjs-types/common/multiSelect/multiSelect.d.ts +4 -0
  178. package/dist/cjs-types/common/multiSelect/multiSelect.types.d.ts +69 -0
  179. package/dist/cjs-types/common/numberInput/index.d.ts +3 -0
  180. package/dist/cjs-types/common/numberInput/numberInput.d.ts +5 -0
  181. package/dist/cjs-types/common/numberInput/numberInput.types.d.ts +76 -0
  182. package/dist/cjs-types/common/numberInput/useStepRepeat.d.ts +17 -0
  183. package/dist/cjs-types/common/optionPicker/index.d.ts +2 -0
  184. package/dist/cjs-types/common/optionPicker/optionPicker.d.ts +4 -0
  185. package/dist/cjs-types/common/optionPicker/optionPicker.types.d.ts +16 -0
  186. package/dist/cjs-types/common/otpInput/index.d.ts +2 -0
  187. package/dist/cjs-types/common/otpInput/otpInput.d.ts +4 -0
  188. package/dist/cjs-types/common/otpInput/otpInput.types.d.ts +60 -0
  189. package/dist/cjs-types/common/overscroll/index.d.ts +2 -0
  190. package/dist/cjs-types/common/overscroll/overscroll.d.ts +2 -0
  191. package/dist/cjs-types/common/overscroll/overscroll.types.d.ts +14 -0
  192. package/dist/cjs-types/common/pagination/index.d.ts +2 -0
  193. package/dist/cjs-types/common/pagination/pagination.d.ts +4 -0
  194. package/dist/cjs-types/common/pagination/pagination.types.d.ts +45 -0
  195. package/dist/cjs-types/common/planCanvas/index.d.ts +2 -0
  196. package/dist/cjs-types/common/planCanvas/planCanvas.d.ts +7 -0
  197. package/dist/cjs-types/common/planCanvas/planCanvas.types.d.ts +64 -0
  198. package/dist/cjs-types/common/popover/index.d.ts +2 -0
  199. package/dist/cjs-types/common/popover/popover.d.ts +3 -0
  200. package/dist/cjs-types/common/popover/popover.types.d.ts +94 -0
  201. package/dist/cjs-types/common/popover/usePopoverPosition.d.ts +44 -0
  202. package/dist/cjs-types/common/progressBar/index.d.ts +2 -0
  203. package/dist/cjs-types/common/progressBar/progressBar.d.ts +5 -0
  204. package/dist/cjs-types/common/progressBar/progressBar.types.d.ts +18 -0
  205. package/dist/cjs-types/common/radioGroup/index.d.ts +2 -0
  206. package/dist/cjs-types/common/radioGroup/radioGroup.d.ts +4 -0
  207. package/dist/cjs-types/common/radioGroup/radioGroup.types.d.ts +45 -0
  208. package/dist/cjs-types/common/rating/index.d.ts +2 -0
  209. package/dist/cjs-types/common/rating/rating.d.ts +4 -0
  210. package/dist/cjs-types/common/rating/rating.types.d.ts +19 -0
  211. package/dist/cjs-types/common/revealLens/index.d.ts +2 -0
  212. package/dist/cjs-types/common/revealLens/revealLens.d.ts +4 -0
  213. package/dist/cjs-types/common/revealLens/revealLens.types.d.ts +24 -0
  214. package/dist/cjs-types/common/ripple/index.d.ts +2 -0
  215. package/dist/cjs-types/common/ripple/ripple.d.ts +5 -0
  216. package/dist/cjs-types/common/ripple/ripple.types.d.ts +16 -0
  217. package/dist/cjs-types/common/roomDrawer/index.d.ts +2 -0
  218. package/dist/cjs-types/common/roomDrawer/roomDrawer.d.ts +3 -0
  219. package/dist/cjs-types/common/roomDrawer/roomDrawer.types.d.ts +308 -0
  220. package/dist/cjs-types/common/roomDrawer/usePlanHistory.d.ts +24 -0
  221. package/dist/cjs-types/common/roomViewer/index.d.ts +2 -0
  222. package/dist/cjs-types/common/roomViewer/roomViewer.d.ts +10 -0
  223. package/dist/cjs-types/common/roomViewer/roomViewer.types.d.ts +91 -0
  224. package/dist/cjs-types/common/scrollFade/index.d.ts +2 -0
  225. package/dist/cjs-types/common/scrollFade/scrollFade.d.ts +4 -0
  226. package/dist/cjs-types/common/scrollFade/scrollFade.types.d.ts +20 -0
  227. package/dist/cjs-types/common/scrollbarProvider/index.d.ts +2 -0
  228. package/dist/cjs-types/common/scrollbarProvider/scrollbarProvider.d.ts +7 -0
  229. package/dist/cjs-types/common/searchInput/index.d.ts +2 -0
  230. package/dist/cjs-types/common/searchInput/searchInput.d.ts +3 -0
  231. package/dist/cjs-types/common/searchInput/searchInput.types.d.ts +28 -0
  232. package/dist/cjs-types/common/sectionHeader/index.d.ts +2 -0
  233. package/dist/cjs-types/common/sectionHeader/sectionHeader.d.ts +4 -0
  234. package/dist/cjs-types/common/sectionHeader/sectionHeader.types.d.ts +27 -0
  235. package/dist/cjs-types/common/sheetBackdrop/index.d.ts +2 -0
  236. package/dist/cjs-types/common/sheetBackdrop/sheetBackdrop.d.ts +16 -0
  237. package/dist/cjs-types/common/sheetBackdrop/sheetBackdrop.types.d.ts +7 -0
  238. package/dist/cjs-types/common/skeleton/index.d.ts +2 -0
  239. package/dist/cjs-types/common/skeleton/skeleton.d.ts +4 -0
  240. package/dist/cjs-types/common/skeleton/skeleton.types.d.ts +22 -0
  241. package/dist/cjs-types/common/slider/index.d.ts +2 -0
  242. package/dist/cjs-types/common/slider/slider.d.ts +3 -0
  243. package/dist/cjs-types/common/slider/slider.types.d.ts +68 -0
  244. package/dist/cjs-types/common/splitButton/index.d.ts +2 -0
  245. package/dist/cjs-types/common/splitButton/splitButton.d.ts +3 -0
  246. package/dist/cjs-types/common/splitButton/splitButton.types.d.ts +35 -0
  247. package/dist/cjs-types/common/stepper/index.d.ts +2 -0
  248. package/dist/cjs-types/common/stepper/stepper.d.ts +3 -0
  249. package/dist/cjs-types/common/stepper/stepper.types.d.ts +77 -0
  250. package/dist/cjs-types/common/sticky/index.d.ts +1 -0
  251. package/dist/cjs-types/common/sticky/sticky.d.ts +3 -0
  252. package/dist/cjs-types/common/sticky/sticky.types.d.ts +22 -0
  253. package/dist/cjs-types/common/sticky/stickyStack.d.ts +46 -0
  254. package/dist/cjs-types/common/switch/index.d.ts +2 -0
  255. package/dist/cjs-types/common/switch/switch.d.ts +4 -0
  256. package/dist/cjs-types/common/switch/switch.types.d.ts +21 -0
  257. package/dist/cjs-types/common/tabHeader/index.d.ts +2 -0
  258. package/dist/cjs-types/common/tabHeader/tabHeader.d.ts +4 -0
  259. package/dist/cjs-types/common/tabHeader/tabHeader.types.d.ts +20 -0
  260. package/dist/cjs-types/common/textarea/index.d.ts +2 -0
  261. package/dist/cjs-types/common/textarea/textarea.d.ts +3 -0
  262. package/dist/cjs-types/common/textarea/textarea.types.d.ts +2 -0
  263. package/dist/cjs-types/common/themeProvider/defaultTheme.d.ts +7 -0
  264. package/dist/cjs-types/common/themeProvider/index.d.ts +4 -0
  265. package/dist/cjs-types/common/themeProvider/lightTheme.d.ts +13 -0
  266. package/dist/cjs-types/common/themeProvider/theme.types.d.ts +272 -0
  267. package/dist/cjs-types/common/themeProvider/themeProvider.d.ts +38 -0
  268. package/dist/cjs-types/common/themeProvider/themeVariablesContext.d.ts +11 -0
  269. package/dist/cjs-types/common/themeProvider/useTheme.d.ts +4 -0
  270. package/dist/cjs-types/common/tilt/index.d.ts +4 -0
  271. package/dist/cjs-types/common/tilt/tilt.d.ts +3 -0
  272. package/dist/cjs-types/common/tilt/tilt.types.d.ts +40 -0
  273. package/dist/cjs-types/common/tilt/tiltMath.d.ts +24 -0
  274. package/dist/cjs-types/common/tiltGroup/index.d.ts +3 -0
  275. package/dist/cjs-types/common/tiltGroup/tiltGroup.d.ts +6 -0
  276. package/dist/cjs-types/common/tiltGroup/tiltGroup.types.d.ts +16 -0
  277. package/dist/cjs-types/common/timeInput/components/clockDial/clockDial.d.ts +3 -0
  278. package/dist/cjs-types/common/timeInput/components/clockDial/clockDial.types.d.ts +24 -0
  279. package/dist/cjs-types/common/timeInput/components/clockDial/index.d.ts +1 -0
  280. package/dist/cjs-types/common/timeInput/index.d.ts +1 -0
  281. package/dist/cjs-types/common/timeInput/timeFunctions.d.ts +36 -0
  282. package/dist/cjs-types/common/timeInput/timeInput.d.ts +3 -0
  283. package/dist/cjs-types/common/timeInput/timeInput.types.d.ts +44 -0
  284. package/dist/cjs-types/common/timeline/index.d.ts +2 -0
  285. package/dist/cjs-types/common/timeline/timeline.d.ts +3 -0
  286. package/dist/cjs-types/common/timeline/timeline.types.d.ts +51 -0
  287. package/dist/cjs-types/common/timer/index.d.ts +2 -0
  288. package/dist/cjs-types/common/timer/timer.chime.d.ts +1 -0
  289. package/dist/cjs-types/common/timer/timer.d.ts +3 -0
  290. package/dist/cjs-types/common/timer/timer.types.d.ts +110 -0
  291. package/dist/cjs-types/common/toast/index.d.ts +3 -0
  292. package/dist/cjs-types/common/toast/toast.d.ts +11 -0
  293. package/dist/cjs-types/common/toast/toast.types.d.ts +50 -0
  294. package/dist/cjs-types/common/toast/toastProvider.d.ts +8 -0
  295. package/dist/cjs-types/common/toast/toastService.d.ts +7 -0
  296. package/dist/cjs-types/common/tooltip/index.d.ts +2 -0
  297. package/dist/cjs-types/common/tooltip/tooltip.d.ts +3 -0
  298. package/dist/cjs-types/common/tooltip/tooltip.types.d.ts +17 -0
  299. package/dist/cjs-types/common/tree/flattenTree.d.ts +3 -0
  300. package/dist/cjs-types/common/tree/index.d.ts +3 -0
  301. package/dist/cjs-types/common/tree/tree.d.ts +4 -0
  302. package/dist/cjs-types/common/tree/tree.types.d.ts +67 -0
  303. package/dist/cjs-types/common/types/actions.types.d.ts +7 -0
  304. package/dist/cjs-types/common/types/baseProps.types.d.ts +29 -0
  305. package/dist/cjs-types/common/types/icon.types.d.ts +17 -0
  306. package/dist/cjs-types/common/types/slots.types.d.ts +4 -0
  307. package/dist/cjs-types/common/utils/activationKey.d.ts +9 -0
  308. package/dist/cjs-types/common/utils/interactiveTarget.d.ts +7 -0
  309. package/dist/cjs-types/common/utils/listNavigation.d.ts +49 -0
  310. package/dist/cjs-types/common/utils/mergeRefs.d.ts +12 -0
  311. package/dist/cjs-types/common/utils/renderIcon.d.ts +29 -0
  312. package/dist/cjs-types/common/utils/scrollAncestors.d.ts +2 -0
  313. package/dist/cjs-types/common/utils/visualViewport.d.ts +7 -0
  314. package/dist/cjs-types/common/virtualList/index.d.ts +2 -0
  315. package/dist/cjs-types/common/virtualList/useColumnResize.d.ts +59 -0
  316. package/dist/cjs-types/common/virtualList/useColumns.d.ts +52 -0
  317. package/dist/cjs-types/common/virtualList/useHeaderNavigation.d.ts +22 -0
  318. package/dist/cjs-types/common/virtualList/useRowDrag.d.ts +58 -0
  319. package/dist/cjs-types/common/virtualList/useRowNavigation.d.ts +50 -0
  320. package/dist/cjs-types/common/virtualList/useSelection.d.ts +24 -0
  321. package/dist/cjs-types/common/virtualList/useSorting.d.ts +26 -0
  322. package/dist/cjs-types/common/virtualList/useVirtualWindow.d.ts +36 -0
  323. package/dist/cjs-types/common/virtualList/virtualList.d.ts +5 -0
  324. package/dist/cjs-types/common/virtualList/virtualList.types.d.ts +317 -0
  325. package/dist/cjs-types/common/virtualList/virtualList.utils.d.ts +126 -0
  326. package/dist/cjs-types/common/virtualList/virtualListHeader.d.ts +35 -0
  327. package/dist/cjs-types/common/virtualList/virtualRow.d.ts +62 -0
  328. package/dist/cjs-types/common/wizard/index.d.ts +1 -0
  329. package/dist/cjs-types/common/wizard/wizard.d.ts +3 -0
  330. package/dist/cjs-types/common/wizard/wizard.types.d.ts +12 -0
  331. package/dist/cjs-types/hooks/useWindowSize.d.ts +6 -0
  332. package/dist/cjs-types/index.d.ts +154 -0
  333. package/dist/cjs-types/package.json +3 -0
  334. package/dist/cjs-types/services/formValidation/FormValidatorGroupWithForm.d.ts +18 -0
  335. package/dist/cjs-types/services/formValidation/index.d.ts +5 -0
  336. package/dist/cjs-types/services/formValidation/useFormValidatorGroup.d.ts +10 -0
  337. package/dist/cjs-types/services/formValidation/validatableComponent.d.ts +36 -0
  338. package/dist/cjs-types/services/klipy.d.ts +36 -0
  339. package/dist/cjs-types/services/localization.d.ts +3 -0
  340. package/dist/esm/common/carousel/carousel.mjs +1 -1
  341. package/dist/esm/common/carousel/carousel.mjs.map +1 -1
  342. package/dist/esm/common/carousel/carousel.module.mjs.map +1 -1
  343. package/dist/esm/common/confirmModal/confirmModal.mjs +1 -1
  344. package/dist/esm/common/confirmModal/confirmModal.mjs.map +1 -1
  345. package/dist/esm/common/datePicker/datePicker.mjs +1 -1
  346. package/dist/esm/common/datePicker/datePicker.mjs.map +1 -1
  347. package/dist/esm/common/drawer/drawer.module.mjs.map +1 -1
  348. package/dist/esm/common/dropdown/dropdown.mjs +1 -1
  349. package/dist/esm/common/dropdown/dropdown.mjs.map +1 -1
  350. package/dist/esm/common/dropdown/dropdown.module.mjs +1 -1
  351. package/dist/esm/common/dropdown/dropdown.module.mjs.map +1 -1
  352. package/dist/esm/common/hooks/useScrollEdges.mjs +2 -0
  353. package/dist/esm/common/hooks/useScrollEdges.mjs.map +1 -0
  354. package/dist/esm/common/infiniteBlock/useInfiniteScroll.mjs +2 -0
  355. package/dist/esm/common/infiniteBlock/useInfiniteScroll.mjs.map +1 -0
  356. package/dist/esm/common/inputDropdown/inputDropdown.mjs +1 -1
  357. package/dist/esm/common/inputDropdown/inputDropdown.mjs.map +1 -1
  358. package/dist/esm/common/interactableDiv/interactableDiv.mjs +1 -1
  359. package/dist/esm/common/interactableDiv/interactableDiv.mjs.map +1 -1
  360. package/dist/esm/common/klipyPicker/components/gifPreview/gifPreview.module.mjs.map +1 -1
  361. package/dist/esm/common/klipyPicker/components/gifView/gifView.module.mjs.map +1 -1
  362. package/dist/esm/common/maskedInput/mask.mjs +2 -0
  363. package/dist/esm/common/maskedInput/mask.mjs.map +1 -0
  364. package/dist/esm/common/maskedInput/maskedInput.mjs +2 -0
  365. package/dist/esm/common/maskedInput/maskedInput.mjs.map +1 -0
  366. package/dist/esm/common/modal/modal.mjs +1 -1
  367. package/dist/esm/common/modal/modal.mjs.map +1 -1
  368. package/dist/esm/common/modal/modal.module.mjs +1 -1
  369. package/dist/esm/common/modal/modal.module.mjs.map +1 -1
  370. package/dist/esm/common/multiSelect/multiSelect.mjs +1 -1
  371. package/dist/esm/common/multiSelect/multiSelect.mjs.map +1 -1
  372. package/dist/esm/common/radioGroup/radioGroup.types.mjs.map +1 -1
  373. package/dist/esm/common/rating/rating.module.mjs.map +1 -1
  374. package/dist/esm/common/ripple/ripple.mjs +1 -1
  375. package/dist/esm/common/ripple/ripple.mjs.map +1 -1
  376. package/dist/esm/common/scrollFade/scrollFade.mjs +2 -0
  377. package/dist/esm/common/scrollFade/scrollFade.mjs.map +1 -0
  378. package/dist/esm/common/scrollFade/scrollFade.module.mjs +2 -0
  379. package/dist/esm/common/scrollFade/scrollFade.module.mjs.map +1 -0
  380. package/dist/esm/common/scrollFade/scrollFade.types.mjs +2 -0
  381. package/dist/esm/common/scrollFade/scrollFade.types.mjs.map +1 -0
  382. package/dist/esm/common/styles/scrollFade.module.mjs +2 -0
  383. package/dist/esm/common/styles/scrollFade.module.mjs.map +1 -0
  384. package/dist/esm/common/styles/sheet.module.mjs.map +1 -1
  385. package/dist/esm/common/timeInput/timeInput.mjs +1 -1
  386. package/dist/esm/common/timeInput/timeInput.mjs.map +1 -1
  387. package/dist/esm/common/utils/interactiveTarget.mjs +2 -0
  388. package/dist/esm/common/utils/interactiveTarget.mjs.map +1 -0
  389. package/dist/esm/common/utils/listNavigation.mjs +2 -0
  390. package/dist/esm/common/utils/listNavigation.mjs.map +1 -0
  391. package/dist/esm/common/wizard/wizard.module.mjs.map +1 -1
  392. package/dist/esm/index.mjs +1 -1
  393. package/dist/esm/og.png +0 -0
  394. package/dist/index.cjs +3 -3
  395. package/dist/index.cjs.map +1 -1
  396. package/dist/mcp.js +341 -56
  397. package/dist/og.png +0 -0
  398. package/dist/style.css +1 -1
  399. package/dist/types/common/accordion/accordion.d.ts +1 -1
  400. package/dist/types/common/accordion/accordion.types.d.ts +1 -1
  401. package/dist/types/common/accordion/index.d.ts +2 -2
  402. package/dist/types/common/actionButtons/actionButtons.d.ts +1 -1
  403. package/dist/types/common/actionButtons/actionButtons.types.d.ts +3 -3
  404. package/dist/types/common/actionButtons/index.d.ts +2 -2
  405. package/dist/types/common/actionIcon/actionIcon.d.ts +1 -1
  406. package/dist/types/common/actionIcon/actionIcon.types.d.ts +2 -2
  407. package/dist/types/common/actionIcon/index.d.ts +2 -2
  408. package/dist/types/common/alert/alert.d.ts +1 -1
  409. package/dist/types/common/alert/alert.types.d.ts +2 -2
  410. package/dist/types/common/alert/index.d.ts +2 -2
  411. package/dist/types/common/animatedIcon/animatedIcon.d.ts +1 -1
  412. package/dist/types/common/animatedIcon/animatedIcon.types.d.ts +1 -1
  413. package/dist/types/common/animatedIcon/index.d.ts +2 -2
  414. package/dist/types/common/animatedLogo/animatedLogo.d.ts +1 -1
  415. package/dist/types/common/animatedLogo/animatedLogo.types.d.ts +1 -1
  416. package/dist/types/common/animatedLogo/index.d.ts +2 -2
  417. package/dist/types/common/animatedText/animatedText.d.ts +1 -1
  418. package/dist/types/common/animatedText/animatedText.types.d.ts +1 -1
  419. package/dist/types/common/animatedText/index.d.ts +2 -2
  420. package/dist/types/common/avatar/avatar.d.ts +1 -1
  421. package/dist/types/common/avatar/avatar.types.d.ts +2 -2
  422. package/dist/types/common/avatar/avatarGroup.d.ts +1 -1
  423. package/dist/types/common/avatar/index.d.ts +3 -3
  424. package/dist/types/common/badge/badge.d.ts +1 -1
  425. package/dist/types/common/badge/badge.types.d.ts +1 -1
  426. package/dist/types/common/badge/index.d.ts +2 -2
  427. package/dist/types/common/bodyEnd/bodyEnd.d.ts +1 -1
  428. package/dist/types/common/bodyEnd/index.d.ts +2 -2
  429. package/dist/types/common/breadcrumb/breadcrumb.d.ts +1 -1
  430. package/dist/types/common/breadcrumb/breadcrumb.types.d.ts +2 -2
  431. package/dist/types/common/breadcrumb/index.d.ts +2 -2
  432. package/dist/types/common/button/button.d.ts +1 -1
  433. package/dist/types/common/button/button.types.d.ts +2 -2
  434. package/dist/types/common/button/index.d.ts +2 -2
  435. package/dist/types/common/buttonGroup/buttonGroup.d.ts +1 -1
  436. package/dist/types/common/buttonGroup/buttonGroup.types.d.ts +1 -1
  437. package/dist/types/common/buttonGroup/index.d.ts +2 -2
  438. package/dist/types/common/card/Card.d.ts +1 -1
  439. package/dist/types/common/card/CardActions.d.ts +1 -1
  440. package/dist/types/common/card/CardContent.d.ts +1 -1
  441. package/dist/types/common/card/CardHeader.d.ts +1 -1
  442. package/dist/types/common/card/CardMedia.d.ts +1 -1
  443. package/dist/types/common/card/card.types.d.ts +3 -3
  444. package/dist/types/common/card/index.d.ts +6 -6
  445. package/dist/types/common/carousel/carousel.d.ts +1 -1
  446. package/dist/types/common/carousel/carousel.types.d.ts +1 -1
  447. package/dist/types/common/carousel/index.d.ts +2 -2
  448. package/dist/types/common/checkbox/checkbox.d.ts +1 -1
  449. package/dist/types/common/checkbox/checkbox.types.d.ts +2 -2
  450. package/dist/types/common/checkbox/index.d.ts +2 -2
  451. package/dist/types/common/chip/chip.d.ts +1 -1
  452. package/dist/types/common/chip/chip.types.d.ts +1 -1
  453. package/dist/types/common/chip/chipContainer.d.ts +1 -1
  454. package/dist/types/common/chip/index.d.ts +3 -3
  455. package/dist/types/common/colorPicker/colorPicker.d.ts +1 -1
  456. package/dist/types/common/colorPicker/colorPicker.types.d.ts +1 -1
  457. package/dist/types/common/colorPicker/index.d.ts +2 -2
  458. package/dist/types/common/configProvider/configProvider.d.ts +2 -2
  459. package/dist/types/common/configProvider/configProvider.types.d.ts +44 -44
  460. package/dist/types/common/configProvider/index.d.ts +6 -6
  461. package/dist/types/common/configProvider/useComponentDefaults.d.ts +1 -1
  462. package/dist/types/common/configProvider/useLabels.d.ts +1 -1
  463. package/dist/types/common/configProvider/usePresentationDefault.d.ts +1 -1
  464. package/dist/types/common/confirmModal/confirmModal.d.ts +1 -1
  465. package/dist/types/common/confirmModal/confirmModal.types.d.ts +2 -2
  466. package/dist/types/common/confirmModal/index.d.ts +2 -2
  467. package/dist/types/common/datePicker/components/datePickerMonth/datePickerMonth.d.ts +1 -1
  468. package/dist/types/common/datePicker/components/datePickerMonth/index.d.ts +1 -1
  469. package/dist/types/common/datePicker/datePicker.d.ts +1 -1
  470. package/dist/types/common/datePicker/datePicker.types.d.ts +2 -2
  471. package/dist/types/common/datePicker/index.d.ts +2 -2
  472. package/dist/types/common/divider/divider.d.ts +1 -1
  473. package/dist/types/common/divider/divider.types.d.ts +1 -1
  474. package/dist/types/common/divider/index.d.ts +2 -2
  475. package/dist/types/common/drawer/drawer.d.ts +1 -1
  476. package/dist/types/common/drawer/drawer.types.d.ts +1 -1
  477. package/dist/types/common/drawer/index.d.ts +2 -2
  478. package/dist/types/common/dropZone/dropZone.d.ts +1 -1
  479. package/dist/types/common/dropZone/dropZone.types.d.ts +1 -1
  480. package/dist/types/common/dropZone/index.d.ts +2 -2
  481. package/dist/types/common/dropdown/dropdown.d.ts +1 -1
  482. package/dist/types/common/dropdown/dropdown.types.d.ts +3 -3
  483. package/dist/types/common/dropdown/index.d.ts +2 -2
  484. package/dist/types/common/emptyState/emptyState.d.ts +1 -1
  485. package/dist/types/common/emptyState/emptyState.types.d.ts +2 -2
  486. package/dist/types/common/emptyState/index.d.ts +2 -2
  487. package/dist/types/common/errorBoundary/errorBoundary.d.ts +1 -1
  488. package/dist/types/common/errorBoundary/errorBoundary.types.d.ts +1 -1
  489. package/dist/types/common/errorBoundary/index.d.ts +2 -2
  490. package/dist/types/common/fab/components/fabBase/fabBase.d.ts +1 -1
  491. package/dist/types/common/fab/components/fabBase/fabBase.types.d.ts +1 -1
  492. package/dist/types/common/fab/components/fabBase/index.d.ts +1 -1
  493. package/dist/types/common/fab/fab.d.ts +1 -1
  494. package/dist/types/common/fab/fab.types.d.ts +2 -2
  495. package/dist/types/common/fab/index.d.ts +2 -2
  496. package/dist/types/common/flip/flip.d.ts +1 -1
  497. package/dist/types/common/flip/flip.types.d.ts +1 -1
  498. package/dist/types/common/flip/index.d.ts +2 -2
  499. package/dist/types/common/floorPlan/floorPlan.faces.d.ts +2 -2
  500. package/dist/types/common/floorPlan/floorPlan.fixtures.d.ts +1 -1
  501. package/dist/types/common/floorPlan/floorPlan.geometry.d.ts +1 -1
  502. package/dist/types/common/floorPlan/floorPlan.graph.d.ts +1 -1
  503. package/dist/types/common/floorPlan/floorPlan.hit.d.ts +1 -1
  504. package/dist/types/common/floorPlan/floorPlan.json.d.ts +1 -1
  505. package/dist/types/common/floorPlan/floorPlan.mesh.d.ts +1 -1
  506. package/dist/types/common/floorPlan/floorPlan.path.d.ts +1 -1
  507. package/dist/types/common/floorPlan/floorPlan.plan.d.ts +1 -1
  508. package/dist/types/common/floorPlan/floorPlan.rooms.d.ts +1 -1
  509. package/dist/types/common/floorPlan/floorPlan.snap.d.ts +1 -1
  510. package/dist/types/common/floorPlan/floorPlan.triangulate.d.ts +1 -1
  511. package/dist/types/common/floorPlan/index.d.ts +22 -22
  512. package/dist/types/common/floorPlan/legacySvg.d.ts +2 -2
  513. package/dist/types/common/hooks/useScrollEdges.d.ts +18 -0
  514. package/dist/types/common/hooks/useSheet.d.ts +1 -1
  515. package/dist/types/common/iconPicker/iconPicker.d.ts +1 -1
  516. package/dist/types/common/iconPicker/iconPicker.types.d.ts +2 -2
  517. package/dist/types/common/iconPicker/index.d.ts +2 -1
  518. package/dist/types/common/idleManager/idleManager.d.ts +1 -1
  519. package/dist/types/common/idleManager/index.d.ts +2 -1
  520. package/dist/types/common/infiniteBlock/useInfiniteScroll.d.ts +5 -0
  521. package/dist/types/common/input/index.d.ts +2 -2
  522. package/dist/types/common/input/input.d.ts +1 -1
  523. package/dist/types/common/input/input.types.d.ts +2 -2
  524. package/dist/types/common/inputDropdown/index.d.ts +2 -1
  525. package/dist/types/common/inputDropdown/inputDropdown.d.ts +1 -1
  526. package/dist/types/common/inputDropdown/inputDropdown.types.d.ts +2 -2
  527. package/dist/types/common/interactableDiv/index.d.ts +1 -1
  528. package/dist/types/common/interactableDiv/interactableDiv.d.ts +1 -1
  529. package/dist/types/common/kanbanBoard/KanbanBoard.d.ts +1 -1
  530. package/dist/types/common/kanbanBoard/KanbanColumn.d.ts +1 -1
  531. package/dist/types/common/kanbanBoard/KanbanItem.d.ts +1 -1
  532. package/dist/types/common/kanbanBoard/index.d.ts +3 -3
  533. package/dist/types/common/kanbanBoard/kanbanBoard.types.d.ts +1 -1
  534. package/dist/types/common/kanbanBoard/kanbanBoard.utils.d.ts +1 -1
  535. package/dist/types/common/klipyPicker/components/gifPreview/gifPreview.d.ts +1 -1
  536. package/dist/types/common/klipyPicker/components/gifPreview/gifPreview.types.d.ts +1 -1
  537. package/dist/types/common/klipyPicker/components/gifPreview/index.d.ts +1 -1
  538. package/dist/types/common/klipyPicker/components/gifView/gifView.d.ts +1 -1
  539. package/dist/types/common/klipyPicker/components/gifView/index.d.ts +1 -1
  540. package/dist/types/common/klipyPicker/index.d.ts +2 -2
  541. package/dist/types/common/klipyPicker/klipyPicker.d.ts +1 -1
  542. package/dist/types/common/klipyPicker/klipyPicker.types.d.ts +1 -1
  543. package/dist/types/common/loading/index.d.ts +2 -2
  544. package/dist/types/common/loading/spinnerLoading/index.d.ts +1 -1
  545. package/dist/types/common/maskedInput/index.d.ts +2 -0
  546. package/dist/types/common/maskedInput/mask.d.ts +48 -0
  547. package/dist/types/common/maskedInput/maskedInput.d.ts +13 -0
  548. package/dist/types/common/maskedInput/maskedInput.types.d.ts +38 -0
  549. package/dist/types/common/menu/index.d.ts +2 -2
  550. package/dist/types/common/menu/menu.d.ts +1 -1
  551. package/dist/types/common/menu/menu.types.d.ts +4 -4
  552. package/dist/types/common/modal/index.d.ts +2 -2
  553. package/dist/types/common/modal/modal.d.ts +1 -1
  554. package/dist/types/common/modal/modal.types.d.ts +6 -3
  555. package/dist/types/common/multiSelect/index.d.ts +2 -2
  556. package/dist/types/common/multiSelect/multiSelect.d.ts +1 -1
  557. package/dist/types/common/multiSelect/multiSelect.types.d.ts +3 -3
  558. package/dist/types/common/numberInput/index.d.ts +2 -2
  559. package/dist/types/common/numberInput/numberInput.d.ts +2 -2
  560. package/dist/types/common/numberInput/numberInput.types.d.ts +2 -2
  561. package/dist/types/common/optionPicker/index.d.ts +2 -2
  562. package/dist/types/common/optionPicker/optionPicker.d.ts +1 -1
  563. package/dist/types/common/optionPicker/optionPicker.types.d.ts +1 -1
  564. package/dist/types/common/otpInput/index.d.ts +2 -2
  565. package/dist/types/common/otpInput/otpInput.d.ts +1 -1
  566. package/dist/types/common/otpInput/otpInput.types.d.ts +2 -2
  567. package/dist/types/common/overscroll/index.d.ts +2 -2
  568. package/dist/types/common/overscroll/overscroll.d.ts +1 -1
  569. package/dist/types/common/pagination/index.d.ts +2 -2
  570. package/dist/types/common/pagination/pagination.d.ts +1 -1
  571. package/dist/types/common/pagination/pagination.types.d.ts +2 -2
  572. package/dist/types/common/planCanvas/index.d.ts +2 -2
  573. package/dist/types/common/planCanvas/planCanvas.d.ts +1 -1
  574. package/dist/types/common/planCanvas/planCanvas.types.d.ts +2 -2
  575. package/dist/types/common/popover/index.d.ts +2 -2
  576. package/dist/types/common/popover/popover.d.ts +1 -1
  577. package/dist/types/common/popover/popover.types.d.ts +2 -2
  578. package/dist/types/common/popover/usePopoverPosition.d.ts +1 -1
  579. package/dist/types/common/progressBar/index.d.ts +2 -2
  580. package/dist/types/common/progressBar/progressBar.d.ts +1 -1
  581. package/dist/types/common/progressBar/progressBar.types.d.ts +1 -1
  582. package/dist/types/common/radioGroup/index.d.ts +2 -2
  583. package/dist/types/common/radioGroup/radioGroup.d.ts +1 -1
  584. package/dist/types/common/radioGroup/radioGroup.types.d.ts +3 -3
  585. package/dist/types/common/rating/index.d.ts +2 -2
  586. package/dist/types/common/rating/rating.d.ts +1 -1
  587. package/dist/types/common/rating/rating.types.d.ts +2 -2
  588. package/dist/types/common/revealLens/index.d.ts +2 -2
  589. package/dist/types/common/revealLens/revealLens.d.ts +1 -1
  590. package/dist/types/common/revealLens/revealLens.types.d.ts +1 -1
  591. package/dist/types/common/ripple/index.d.ts +2 -2
  592. package/dist/types/common/ripple/ripple.d.ts +1 -1
  593. package/dist/types/common/ripple/ripple.types.d.ts +1 -1
  594. package/dist/types/common/roomDrawer/index.d.ts +2 -2
  595. package/dist/types/common/roomDrawer/roomDrawer.d.ts +1 -1
  596. package/dist/types/common/roomDrawer/roomDrawer.types.d.ts +3 -3
  597. package/dist/types/common/roomDrawer/usePlanHistory.d.ts +2 -2
  598. package/dist/types/common/roomViewer/index.d.ts +2 -2
  599. package/dist/types/common/roomViewer/roomViewer.d.ts +1 -1
  600. package/dist/types/common/roomViewer/roomViewer.types.d.ts +3 -3
  601. package/dist/types/common/scrollFade/index.d.ts +2 -0
  602. package/dist/types/common/scrollFade/scrollFade.d.ts +4 -0
  603. package/dist/types/common/scrollFade/scrollFade.types.d.ts +20 -0
  604. package/dist/types/common/scrollbarProvider/index.d.ts +1 -1
  605. package/dist/types/common/searchInput/index.d.ts +2 -2
  606. package/dist/types/common/searchInput/searchInput.d.ts +1 -1
  607. package/dist/types/common/searchInput/searchInput.types.d.ts +1 -1
  608. package/dist/types/common/sectionHeader/index.d.ts +2 -2
  609. package/dist/types/common/sectionHeader/sectionHeader.d.ts +1 -1
  610. package/dist/types/common/sectionHeader/sectionHeader.types.d.ts +3 -3
  611. package/dist/types/common/sheetBackdrop/index.d.ts +2 -2
  612. package/dist/types/common/sheetBackdrop/sheetBackdrop.d.ts +1 -1
  613. package/dist/types/common/skeleton/index.d.ts +2 -2
  614. package/dist/types/common/skeleton/skeleton.d.ts +1 -1
  615. package/dist/types/common/skeleton/skeleton.types.d.ts +1 -1
  616. package/dist/types/common/slider/index.d.ts +2 -2
  617. package/dist/types/common/slider/slider.d.ts +1 -1
  618. package/dist/types/common/slider/slider.types.d.ts +2 -2
  619. package/dist/types/common/splitButton/index.d.ts +2 -2
  620. package/dist/types/common/splitButton/splitButton.d.ts +1 -1
  621. package/dist/types/common/splitButton/splitButton.types.d.ts +4 -4
  622. package/dist/types/common/stepper/index.d.ts +2 -2
  623. package/dist/types/common/stepper/stepper.d.ts +1 -1
  624. package/dist/types/common/stepper/stepper.types.d.ts +2 -2
  625. package/dist/types/common/sticky/index.d.ts +1 -1
  626. package/dist/types/common/sticky/sticky.d.ts +1 -1
  627. package/dist/types/common/sticky/sticky.types.d.ts +1 -1
  628. package/dist/types/common/switch/index.d.ts +2 -2
  629. package/dist/types/common/switch/switch.d.ts +1 -1
  630. package/dist/types/common/switch/switch.types.d.ts +2 -2
  631. package/dist/types/common/tabHeader/index.d.ts +2 -2
  632. package/dist/types/common/tabHeader/tabHeader.d.ts +1 -1
  633. package/dist/types/common/tabHeader/tabHeader.types.d.ts +2 -2
  634. package/dist/types/common/textarea/index.d.ts +2 -2
  635. package/dist/types/common/textarea/textarea.d.ts +1 -1
  636. package/dist/types/common/textarea/textarea.types.d.ts +1 -1
  637. package/dist/types/common/themeProvider/defaultTheme.d.ts +1 -1
  638. package/dist/types/common/themeProvider/index.d.ts +4 -4
  639. package/dist/types/common/themeProvider/lightTheme.d.ts +1 -1
  640. package/dist/types/common/themeProvider/theme.types.d.ts +28 -0
  641. package/dist/types/common/themeProvider/themeProvider.d.ts +1 -1
  642. package/dist/types/common/tilt/index.d.ts +4 -4
  643. package/dist/types/common/tilt/tilt.d.ts +1 -1
  644. package/dist/types/common/tilt/tilt.types.d.ts +2 -2
  645. package/dist/types/common/tiltGroup/index.d.ts +3 -3
  646. package/dist/types/common/tiltGroup/tiltGroup.d.ts +1 -1
  647. package/dist/types/common/tiltGroup/tiltGroup.types.d.ts +1 -1
  648. package/dist/types/common/timeInput/components/clockDial/clockDial.d.ts +1 -1
  649. package/dist/types/common/timeInput/components/clockDial/clockDial.types.d.ts +3 -3
  650. package/dist/types/common/timeInput/components/clockDial/index.d.ts +1 -1
  651. package/dist/types/common/timeInput/index.d.ts +1 -1
  652. package/dist/types/common/timeInput/timeInput.d.ts +1 -1
  653. package/dist/types/common/timeInput/timeInput.types.d.ts +2 -2
  654. package/dist/types/common/timeline/index.d.ts +2 -2
  655. package/dist/types/common/timeline/timeline.d.ts +1 -1
  656. package/dist/types/common/timeline/timeline.types.d.ts +2 -2
  657. package/dist/types/common/timer/index.d.ts +2 -2
  658. package/dist/types/common/timer/timer.d.ts +1 -1
  659. package/dist/types/common/timer/timer.types.d.ts +2 -2
  660. package/dist/types/common/toast/index.d.ts +3 -3
  661. package/dist/types/common/toast/toast.d.ts +1 -1
  662. package/dist/types/common/toast/toast.types.d.ts +1 -1
  663. package/dist/types/common/toast/toastProvider.d.ts +1 -1
  664. package/dist/types/common/toast/toastService.d.ts +1 -1
  665. package/dist/types/common/tooltip/index.d.ts +2 -2
  666. package/dist/types/common/tooltip/tooltip.d.ts +1 -1
  667. package/dist/types/common/tree/flattenTree.d.ts +1 -1
  668. package/dist/types/common/tree/index.d.ts +3 -3
  669. package/dist/types/common/tree/tree.d.ts +1 -1
  670. package/dist/types/common/tree/tree.types.d.ts +2 -2
  671. package/dist/types/common/types/actions.types.d.ts +1 -1
  672. package/dist/types/common/types/slots.types.d.ts +1 -1
  673. package/dist/types/common/utils/interactiveTarget.d.ts +7 -0
  674. package/dist/types/common/utils/listNavigation.d.ts +49 -0
  675. package/dist/types/common/utils/renderIcon.d.ts +1 -1
  676. package/dist/types/common/virtualList/index.d.ts +2 -2
  677. package/dist/types/common/virtualList/useColumnResize.d.ts +1 -1
  678. package/dist/types/common/virtualList/useColumns.d.ts +1 -1
  679. package/dist/types/common/virtualList/useRowDrag.d.ts +1 -1
  680. package/dist/types/common/virtualList/useRowNavigation.d.ts +1 -1
  681. package/dist/types/common/virtualList/useSorting.d.ts +1 -1
  682. package/dist/types/common/virtualList/useVirtualWindow.d.ts +1 -1
  683. package/dist/types/common/virtualList/virtualList.d.ts +2 -2
  684. package/dist/types/common/virtualList/virtualList.types.d.ts +1 -1
  685. package/dist/types/common/virtualList/virtualList.utils.d.ts +1 -1
  686. package/dist/types/common/virtualList/virtualListHeader.d.ts +4 -4
  687. package/dist/types/common/virtualList/virtualRow.d.ts +1 -1
  688. package/dist/types/common/wizard/index.d.ts +1 -1
  689. package/dist/types/common/wizard/wizard.d.ts +1 -1
  690. package/dist/types/common/wizard/wizard.types.d.ts +1 -1
  691. package/dist/types/index.d.ts +153 -153
  692. package/dist/types/services/formValidation/index.d.ts +3 -3
  693. package/dist/types/services/formValidation/useFormValidatorGroup.d.ts +1 -1
  694. package/docs/ActionIcon.md +2 -0
  695. package/docs/CLAUDE.md +123 -230
  696. package/docs/Card.md +1 -1
  697. package/docs/Divider.md +2 -0
  698. package/docs/Dropdown.md +20 -0
  699. package/docs/IdleManager.md +38 -8
  700. package/docs/InputDropdown.md +11 -0
  701. package/docs/InteractableDiv.md +7 -1
  702. package/docs/KlipyPicker.md +1 -1
  703. package/docs/Loading.md +3 -1
  704. package/docs/Menu.md +2 -0
  705. package/docs/Modal.md +34 -10
  706. package/docs/MultiSelect.md +2 -2
  707. package/docs/Pagination.md +1 -1
  708. package/docs/Popover.md +2 -0
  709. package/docs/RadioGroup.md +1 -1
  710. package/docs/Rating.md +2 -0
  711. package/docs/Ripple.md +3 -0
  712. package/docs/RoomViewer.md +3 -5
  713. package/docs/ScrollFade.md +77 -0
  714. package/docs/ScrollbarProvider.md +2 -0
  715. package/docs/Slider.md +1 -1
  716. package/docs/Timer.md +1 -1
  717. package/docs/Wizard.md +1 -1
  718. package/package.json +33 -11
  719. package/dist/esm/common/infiniteBlock/infiniteBlock.mjs +0 -2
  720. package/dist/esm/common/infiniteBlock/infiniteBlock.mjs.map +0 -1
  721. package/dist/esm/common/infiniteBlock/infiniteBlock.module.mjs +0 -2
  722. package/dist/esm/common/infiniteBlock/infiniteBlock.module.mjs.map +0 -1
  723. package/dist/types/common/infiniteBlock/index.d.ts +0 -1
  724. package/dist/types/common/infiniteBlock/infiniteBlock.d.ts +0 -4
  725. package/dist/types/common/infiniteBlock/infiniteBlock.types.d.ts +0 -13
  726. package/docs/Icon.md +0 -27
  727. package/docs/InfiniteBlock.md +0 -23
@@ -1,2 +1,2 @@
1
- "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{PopoverAlign as t,PopoverPlacement as n}from"../popover/popover.types.mjs";import r from"../popover/popover.mjs";import i from"../input/input.mjs";import a from"./inputDropdown.module.mjs";import{useCallback as o,useEffect as s,useLayoutEffect as c,useMemo as l,useRef as u,useState as d}from"react";import f from"classnames";import{jsx as p}from"react/jsx-runtime";function m(e,t){return t?t.value??``:e??``}function h(e,t){let n=t.find(t=>t.value===e);return n?n.label??n.value:e}function g(g){let{label:_=``,value:v=``,formValidator:y=null,error:b,isRequired:x=!1,items:S=[],allowCustomValue:C=!1,maxItems:w=100,className:T,style:E,classNames:D,styles:O,onSelect:k=()=>null,onChange:A,placeholder:j=``,readOnly:M=!1,...N}=e(`InputDropdown`,g),P=m(v,y),[,F]=d(0),I=u(y);s(()=>{if(I.current=y,!y)return;let e=()=>F(e=>e+1);return y.registerOnUpdateListener(e),()=>{y.removeOnUpdateListener(e)}},[y]);let L=x||!!y?.validators.find(e=>e.validatorId===`required`),[R,z]=d(()=>h(P,S)),[B,V]=d(P),[H,U]=d(!1),[W,G]=d(null),K=u(null),q=u(null),J=u(null),Y=O?.dropdown?.fontSize;if(c(()=>{let e=q.current,t=J.current;H&&e&&t&&Y==null&&(t.style.fontSize=window.getComputedStyle(e).fontSize)},[H,Y]),P!==B){V(P);let e=S.find(e=>e.value===P);e?z(e.label??e.value):C&&z(P)}let X=l(()=>{let e=R.toLowerCase(),t=[];for(let n of S)if((n.label??n.value).toLowerCase().includes(e)&&(t.push(n),w>0&&t.length>=w))break;return t},[S,R,w]),Z=()=>{M||(K.current&&=(clearTimeout(K.current),null),U(!0))},Q=()=>{I.current&&(I.current.touched=!0),K.current=setTimeout(()=>{U(!1),K.current=null,C||z(h(P,S))},100)},$=o(e=>{z(e.label??e.value),U(!1),G(null),y&&y.set(e.value),A&&A(e.value),k(e.value)},[y,A,k]),ee=o(e=>{M||(e.key===`ArrowUp`?(e.preventDefault(),G(e=>e?e-1:null)):e.key===`ArrowDown`?(e.preventDefault(),G(e=>e===null?0:Math.min(e+1,X.length-1))):e.key===`Enter`&&(W!==null&&X[W]?$(X[W]):C&&(U(!1),G(null))))},[X,W,$,C,M]),te=p(`div`,{ref:J,className:f(a.dropdown,D?.dropdown),style:O?.dropdown,children:p(`div`,{className:a.dropdownScroll,children:X.map((e,t)=>p(`div`,{className:f(a.dropdownItem,W===t&&a.dropdownItemHighlighted,D?.item),style:O?.item,onMouseDown:e=>e.preventDefault(),onClick:()=>$(e),children:e.label??e.value},`${t}_${e.label}_${e.value}`))})});return p(`div`,{...N,ref:q,className:f(a.inputDropdown,D?.root,T),style:{...O?.root,...E},onFocus:Z,onBlur:Q,onKeyDown:ee,children:p(r,{isOpen:H&&!M,onOpenChange:e=>{e||U(!1)},placement:n.Bottom,align:t.Start,offset:0,withArrow:!1,constrainWidth:!1,closeOnTriggerClick:!1,focusOnOpen:!1,classNames:{panel:a.inputDropdownPanel},content:te,children:p(i,{autoComplete:`off`,label:_,value:R,readOnly:M,formValidator:null,isRequired:L,isValid:y?!y.touched||!y.hasError():!b,errorMessage:y?y.touched?y.getCurrentErrorMessage()??``:``:b??``,onChange:e=>{if(z(e),G(null),U(!0),C)y&&y.set(e),A&&A(e);else if(e===``)y&&y.set(``),A&&A(``),k(``);else{let t=S.find(t=>(t.label??t.value).toLowerCase()===e.toLowerCase());t&&(y&&y.set(t.value),A&&A(t.value),k(t.value))}},placeholder:j})})})}export{g as default};
1
+ "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{PopoverAlign as t,PopoverPlacement as n}from"../popover/popover.types.mjs";import ee from"../popover/popover.mjs";import r from"../input/input.mjs";import{nextIndex as i,scrollOptionIntoView as a}from"../utils/listNavigation.mjs";import o from"./inputDropdown.module.mjs";import{useCallback as s,useEffect as c,useLayoutEffect as l,useMemo as u,useRef as d,useState as f}from"react";import p from"classnames";import{jsx as m}from"react/jsx-runtime";function h(e,t){return t?t.value??``:e??``}function g(e,t){let n=t.find(t=>t.value===e);return n?n.label??n.value:e}var te={wrap:!1};function _(_){let{label:v=``,value:y=``,formValidator:b=null,error:x,isRequired:S=!1,items:C=[],allowCustomValue:w=!1,maxItems:T=100,className:E,style:D,classNames:O,styles:k,onSelect:A=()=>null,onChange:j,placeholder:M=``,readOnly:N=!1,...P}=e(`InputDropdown`,_),F=h(y,b),[,I]=f(0),L=d(b);c(()=>{if(L.current=b,!b)return;let e=()=>I(e=>e+1);return b.registerOnUpdateListener(e),()=>{b.removeOnUpdateListener(e)}},[b]);let R=S||!!b?.validators.find(e=>e.validatorId===`required`),[z,B]=f(()=>g(F,C)),[V,H]=f(F),[U,W]=f(!1),[G,K]=f(null),q=d(null),J=d(null),Y=d(null),X=d(null),Z=k?.dropdown?.fontSize;if(l(()=>{let e=J.current,t=Y.current;U&&e&&t&&Z==null&&(t.style.fontSize=window.getComputedStyle(e).fontSize)},[U,Z]),F!==V){H(F);let e=C.find(e=>e.value===F);e?B(e.label??e.value):w&&B(F)}let Q=u(()=>{let e=z.toLowerCase(),t=[];for(let n of C)if((n.label??n.value).toLowerCase().includes(e)&&(t.push(n),T>0&&t.length>=T))break;return t},[C,z,T]),ne=()=>{N||(q.current&&=(clearTimeout(q.current),null),W(!0))},re=()=>{L.current&&(L.current.touched=!0),q.current=setTimeout(()=>{W(!1),q.current=null,w||B(g(F,C))},100)};c(()=>{U&&G!==null&&a(X.current,X.current?.children[G])},[U,G]);let $=s(e=>{B(e.label??e.value),W(!1),K(null),b&&b.set(e.value),j&&j(e.value),A(e.value)},[b,j,A]),ie=s(e=>{if(!N){if(e.key===`ArrowUp`||e.key===`ArrowDown`){e.preventDefault();let t=e.key===`ArrowDown`?1:-1;K(e=>e!==null&&e===(t===1?Q.length-1:0)?null:i(e,t,Q.length,te))}else e.key===`Enter`&&(G!==null&&Q[G]?(e.preventDefault(),$(Q[G])):w&&(W(!1),K(null)))}},[Q,G,$,w,N]),ae=m(`div`,{ref:Y,className:p(o.dropdown,O?.dropdown),style:k?.dropdown,children:m(`div`,{ref:X,className:o.dropdownScroll,children:Q.map((e,t)=>m(`div`,{className:p(o.dropdownItem,G===t&&o.dropdownItemHighlighted,O?.item),style:k?.item,onMouseDown:e=>e.preventDefault(),onClick:()=>$(e),children:e.label??e.value},`${t}_${e.label}_${e.value}`))})});return m(`div`,{...P,ref:J,className:p(o.inputDropdown,O?.root,E),style:{...k?.root,...D},onFocus:ne,onBlur:re,onKeyDown:ie,children:m(ee,{isOpen:U&&!N,onOpenChange:e=>{e||W(!1)},placement:n.Bottom,align:t.Start,offset:0,withArrow:!1,constrainWidth:!1,closeOnTriggerClick:!1,focusOnOpen:!1,classNames:{panel:o.inputDropdownPanel},content:ae,children:m(r,{autoComplete:`off`,label:v,value:z,readOnly:N,formValidator:null,isRequired:R,isValid:b?!b.touched||!b.hasError():!x,errorMessage:b?b.touched?b.getCurrentErrorMessage()??``:``:x??``,onChange:e=>{if(B(e),K(null),W(!0),w)b&&b.set(e),j&&j(e);else if(e===``)b&&b.set(``),j&&j(``),A(``);else{let t=C.find(t=>(t.label??t.value).toLowerCase()===e.toLowerCase());t&&(b&&b.set(t.value),j&&j(t.value),A(t.value))}},placeholder:M})})})}export{_ as default};
2
2
  //# sourceMappingURL=inputDropdown.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"inputDropdown.mjs","names":[],"sources":["../../../../package/common/inputDropdown/inputDropdown.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport styles from './inputDropdown.module.pcss';\nimport Input from '../input';\nimport Popover from '../popover';\nimport { PopoverAlign, PopoverPlacement } from '../popover/popover.types';\nimport { useComponentDefaults } from '../configProvider';\nimport type { InputDropdownItem, InputDropdownProps } from './inputDropdown.types';\n\nfunction getKeyFromProps(value: string | undefined, formValidator: InputDropdownProps['formValidator']): string {\n return formValidator ? ((formValidator.value as string) ?? '') : (value ?? '');\n}\n\nfunction labelForKey(key: string, items: InputDropdownItem[]): string {\n const match = items.find((item) => item.value === key);\n return match ? (match.label ?? match.value) : key;\n}\n\nexport default function InputDropdown(props: InputDropdownProps) {\n const {\n label = '',\n value = '',\n formValidator = null,\n error,\n isRequired = false,\n items = [],\n allowCustomValue = false,\n maxItems = 100,\n className,\n style,\n classNames,\n styles: slotStyles,\n onSelect = () => null,\n onChange,\n placeholder = '',\n readOnly = false,\n ...rest\n } = useComponentDefaults('InputDropdown', props);\n const currentKey = getKeyFromProps(value, formValidator);\n const [, forceUpdate] = useState(0);\n const fvRef = useRef(formValidator);\n\n useEffect(() => {\n fvRef.current = formValidator;\n if (!formValidator) return;\n const listener = () => forceUpdate((n) => n + 1);\n formValidator.registerOnUpdateListener(listener);\n return () => {\n formValidator.removeOnUpdateListener(listener);\n };\n }, [formValidator]);\n\n const computedIsRequired =\n isRequired || !!formValidator?.validators.find((v) => (v as { validatorId?: string }).validatorId === 'required');\n\n const [inputText, setInputText] = useState(() => labelForKey(currentKey, items));\n const [prevKey, setPrevKey] = useState(currentKey);\n const [isMenuShown, setIsMenuShown] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState<number | null>(null);\n const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n const anchorRef = useRef<HTMLDivElement>(null);\n\n const menuFontSizeOverride = slotStyles?.dropdown?.fontSize;\n useLayoutEffect(() => {\n const trigger = triggerRef.current;\n const menu = anchorRef.current;\n if (!isMenuShown || !trigger || !menu || menuFontSizeOverride != null) return;\n menu.style.fontSize = window.getComputedStyle(trigger).fontSize;\n }, [isMenuShown, menuFontSizeOverride]);\n\n // Sync display text when the controlled key changes externally (e.g. parent reset).\n if (currentKey !== prevKey) {\n setPrevKey(currentKey);\n const match = items.find((item) => item.value === currentKey);\n if (match) setInputText(match.label ?? match.value);\n else if (allowCustomValue) setInputText(currentKey);\n }\n\n const currItems = useMemo(() => {\n const needle = inputText.toLowerCase();\n const matches: InputDropdownItem[] = [];\n for (const item of items) {\n if (!(item.label ?? item.value).toLowerCase().includes(needle)) continue;\n matches.push(item);\n if (maxItems > 0 && matches.length >= maxItems) break;\n }\n return matches;\n }, [items, inputText, maxItems]);\n\n const handleFocus = () => {\n if (readOnly) return;\n if (hideTimeoutRef.current) {\n clearTimeout(hideTimeoutRef.current);\n hideTimeoutRef.current = null;\n }\n setIsMenuShown(true);\n };\n\n const handleBlur = () => {\n if (fvRef.current) fvRef.current.touched = true;\n hideTimeoutRef.current = setTimeout(() => {\n setIsMenuShown(false);\n hideTimeoutRef.current = null;\n // Without custom values, uncommitted typed text is invalid — snap the\n // display back to the currently selected item's label.\n if (!allowCustomValue) setInputText(labelForKey(currentKey, items));\n }, 100);\n };\n\n const handleSelect = useCallback(\n (item: InputDropdownItem) => {\n setInputText(item.label ?? item.value);\n setIsMenuShown(false);\n setHighlightedIndex(null);\n if (formValidator) formValidator.set(item.value);\n if (onChange) onChange(item.value);\n onSelect(item.value);\n },\n [formValidator, onChange, onSelect],\n );\n\n const onKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (readOnly) return;\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n setHighlightedIndex((idx) => (!idx ? null : idx - 1));\n } else if (event.key === 'ArrowDown') {\n event.preventDefault();\n setHighlightedIndex((idx) => (idx === null ? 0 : Math.min(idx + 1, currItems.length - 1)));\n } else if (event.key === 'Enter') {\n if (highlightedIndex !== null && currItems[highlightedIndex]) {\n handleSelect(currItems[highlightedIndex]);\n } else if (allowCustomValue) {\n setIsMenuShown(false);\n setHighlightedIndex(null);\n }\n }\n },\n [currItems, highlightedIndex, handleSelect, allowCustomValue, readOnly],\n );\n\n const menu = (\n <div ref={anchorRef} className={cx(styles.dropdown, classNames?.dropdown)} style={slotStyles?.dropdown}>\n <div className={styles.dropdownScroll}>\n {currItems.map((item, key) => (\n <div\n key={`${key}_${item.label}_${item.value}`}\n className={cx(\n styles.dropdownItem,\n highlightedIndex === key && styles.dropdownItemHighlighted,\n classNames?.item,\n )}\n style={slotStyles?.item}\n // Prevent the input from blurring before the click resolves.\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => handleSelect(item)}\n >\n {item.label ?? item.value}\n </div>\n ))}\n </div>\n </div>\n );\n\n return (\n <div\n {...rest}\n ref={triggerRef}\n className={cx(styles.inputDropdown, classNames?.root, className)}\n style={{ ...slotStyles?.root, ...style }}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={onKeyDown}\n >\n <Popover\n // The field owns the open state: it opens on typing and closes on blur, on\n // a pick, or on Escape. Only a close is taken from Popover, which is the\n // outside click its portaled panel would otherwise not see.\n isOpen={isMenuShown && !readOnly}\n onOpenChange={(next) => {\n if (!next) setIsMenuShown(false);\n }}\n placement={PopoverPlacement.Bottom}\n align={PopoverAlign.Start}\n offset={0}\n withArrow={false}\n constrainWidth={false}\n closeOnTriggerClick={false}\n focusOnOpen={false}\n classNames={{ panel: styles.inputDropdownPanel }}\n content={menu}\n >\n <Input\n // A combobox renders its own suggestion list; the browser's autofill dropdown\n // opens on top of it, so two lists compete for the same space.\n autoComplete='off'\n label={label}\n value={inputText}\n readOnly={readOnly}\n formValidator={null}\n isRequired={computedIsRequired}\n isValid={formValidator ? (formValidator.touched ? !formValidator.hasError() : true) : !error}\n errorMessage={\n formValidator\n ? formValidator.touched\n ? (formValidator.getCurrentErrorMessage() ?? '')\n : ''\n : (error ?? '')\n }\n onChange={(text) => {\n setInputText(text);\n setHighlightedIndex(null);\n setIsMenuShown(true);\n if (allowCustomValue) {\n if (formValidator) formValidator.set(text);\n if (onChange) onChange(text);\n } else if (text === '') {\n if (formValidator) formValidator.set('');\n if (onChange) onChange('');\n onSelect('');\n } else {\n // Emit when the typed text exactly matches an item's label/value.\n const match = items.find((item) => (item.label ?? item.value).toLowerCase() === text.toLowerCase());\n if (match) {\n if (formValidator) formValidator.set(match.value);\n if (onChange) onChange(match.value);\n onSelect(match.value);\n }\n }\n }}\n placeholder={placeholder}\n />\n </Popover>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"inputDropdown.mjs","names":[],"sources":["../../../../package/common/inputDropdown/inputDropdown.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport cx from 'classnames';\nimport styles from './inputDropdown.module.pcss';\nimport Input from '../input';\nimport Popover from '../popover';\nimport { PopoverAlign, PopoverPlacement } from '../popover/popover.types';\nimport { useComponentDefaults } from '../configProvider';\nimport type { InputDropdownItem, InputDropdownProps } from './inputDropdown.types';\nimport { nextIndex, scrollOptionIntoView } from '../utils/listNavigation';\n\nfunction getKeyFromProps(value: string | undefined, formValidator: InputDropdownProps['formValidator']): string {\n return formValidator ? ((formValidator.value as string) ?? '') : (value ?? '');\n}\n\nfunction labelForKey(key: string, items: InputDropdownItem[]): string {\n const match = items.find((item) => item.value === key);\n return match ? (match.label ?? match.value) : key;\n}\n\n/**\n * The suggestions do not wrap: the list is filtered by what is being typed, so running off one\n * end and reappearing at the other reads as the list having changed under the caret.\n */\nconst NO_WRAP = { wrap: false };\n\nexport default function InputDropdown(props: InputDropdownProps) {\n const {\n label = '',\n value = '',\n formValidator = null,\n error,\n isRequired = false,\n items = [],\n allowCustomValue = false,\n maxItems = 100,\n className,\n style,\n classNames,\n styles: slotStyles,\n onSelect = () => null,\n onChange,\n placeholder = '',\n readOnly = false,\n ...rest\n } = useComponentDefaults('InputDropdown', props);\n const currentKey = getKeyFromProps(value, formValidator);\n const [, forceUpdate] = useState(0);\n const fvRef = useRef(formValidator);\n\n useEffect(() => {\n fvRef.current = formValidator;\n if (!formValidator) return;\n const listener = () => forceUpdate((n) => n + 1);\n formValidator.registerOnUpdateListener(listener);\n return () => {\n formValidator.removeOnUpdateListener(listener);\n };\n }, [formValidator]);\n\n const computedIsRequired =\n isRequired || !!formValidator?.validators.find((v) => (v as { validatorId?: string }).validatorId === 'required');\n\n const [inputText, setInputText] = useState(() => labelForKey(currentKey, items));\n const [prevKey, setPrevKey] = useState(currentKey);\n const [isMenuShown, setIsMenuShown] = useState(false);\n const [highlightedIndex, setHighlightedIndex] = useState<number | null>(null);\n const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n const anchorRef = useRef<HTMLDivElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n\n const menuFontSizeOverride = slotStyles?.dropdown?.fontSize;\n useLayoutEffect(() => {\n const trigger = triggerRef.current;\n const menu = anchorRef.current;\n if (!isMenuShown || !trigger || !menu || menuFontSizeOverride != null) return;\n menu.style.fontSize = window.getComputedStyle(trigger).fontSize;\n }, [isMenuShown, menuFontSizeOverride]);\n\n // Sync display text when the controlled key changes externally (e.g. parent reset).\n if (currentKey !== prevKey) {\n setPrevKey(currentKey);\n const match = items.find((item) => item.value === currentKey);\n if (match) setInputText(match.label ?? match.value);\n else if (allowCustomValue) setInputText(currentKey);\n }\n\n const currItems = useMemo(() => {\n const needle = inputText.toLowerCase();\n const matches: InputDropdownItem[] = [];\n for (const item of items) {\n if (!(item.label ?? item.value).toLowerCase().includes(needle)) continue;\n matches.push(item);\n if (maxItems > 0 && matches.length >= maxItems) break;\n }\n return matches;\n }, [items, inputText, maxItems]);\n\n const handleFocus = () => {\n if (readOnly) return;\n if (hideTimeoutRef.current) {\n clearTimeout(hideTimeoutRef.current);\n hideTimeoutRef.current = null;\n }\n setIsMenuShown(true);\n };\n\n const handleBlur = () => {\n if (fvRef.current) fvRef.current.touched = true;\n hideTimeoutRef.current = setTimeout(() => {\n setIsMenuShown(false);\n hideTimeoutRef.current = null;\n // Without custom values, uncommitted typed text is invalid — snap the\n // display back to the currently selected item's label.\n if (!allowCustomValue) setInputText(labelForKey(currentKey, items));\n }, 100);\n };\n\n useEffect(() => {\n if (!isMenuShown || highlightedIndex === null) return;\n scrollOptionIntoView(scrollRef.current, scrollRef.current?.children[highlightedIndex]);\n }, [isMenuShown, highlightedIndex]);\n\n const handleSelect = useCallback(\n (item: InputDropdownItem) => {\n setInputText(item.label ?? item.value);\n setIsMenuShown(false);\n setHighlightedIndex(null);\n if (formValidator) formValidator.set(item.value);\n if (onChange) onChange(item.value);\n onSelect(item.value);\n },\n [formValidator, onChange, onSelect],\n );\n\n const onKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (readOnly) return;\n if (event.key === 'ArrowUp' || event.key === 'ArrowDown') {\n event.preventDefault();\n const step = event.key === 'ArrowDown' ? 1 : -1;\n setHighlightedIndex((idx) => {\n // The text being typed is part of the cycle, so both ends lead back to it and on round\n // to the far end: last → text → first, first → text → last. That is how a browser's own\n // address bar behaves, and it is why this list does not wrap straight around the way\n // Dropdown and MultiSelect do — they have no typed text to pass through.\n const atFarEnd = idx !== null && idx === (step === 1 ? currItems.length - 1 : 0);\n return atFarEnd ? null : nextIndex(idx, step, currItems.length, NO_WRAP);\n });\n } else if (event.key === 'Enter') {\n if (highlightedIndex !== null && currItems[highlightedIndex]) {\n // This Enter picked a suggestion, so it must not also reach the form around the field.\n // Without this the browser's implicit submission runs as well, and choosing from the\n // list submitted the form underneath the user. The blank state deliberately does not\n // do this: Enter there means the text as typed, and submitting is a fair reading of it.\n event.preventDefault();\n handleSelect(currItems[highlightedIndex]);\n } else if (allowCustomValue) {\n setIsMenuShown(false);\n setHighlightedIndex(null);\n }\n }\n },\n [currItems, highlightedIndex, handleSelect, allowCustomValue, readOnly],\n );\n\n const menu = (\n <div ref={anchorRef} className={cx(styles.dropdown, classNames?.dropdown)} style={slotStyles?.dropdown}>\n <div ref={scrollRef} className={styles.dropdownScroll}>\n {currItems.map((item, key) => (\n <div\n key={`${key}_${item.label}_${item.value}`}\n className={cx(\n styles.dropdownItem,\n highlightedIndex === key && styles.dropdownItemHighlighted,\n classNames?.item,\n )}\n style={slotStyles?.item}\n // Prevent the input from blurring before the click resolves.\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => handleSelect(item)}\n >\n {item.label ?? item.value}\n </div>\n ))}\n </div>\n </div>\n );\n\n return (\n <div\n {...rest}\n ref={triggerRef}\n className={cx(styles.inputDropdown, classNames?.root, className)}\n style={{ ...slotStyles?.root, ...style }}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={onKeyDown}\n >\n <Popover\n // The field owns the open state: it opens on typing and closes on blur, on\n // a pick, or on Escape. Only a close is taken from Popover, which is the\n // outside click its portaled panel would otherwise not see.\n isOpen={isMenuShown && !readOnly}\n onOpenChange={(next) => {\n if (!next) setIsMenuShown(false);\n }}\n placement={PopoverPlacement.Bottom}\n align={PopoverAlign.Start}\n offset={0}\n withArrow={false}\n constrainWidth={false}\n closeOnTriggerClick={false}\n focusOnOpen={false}\n classNames={{ panel: styles.inputDropdownPanel }}\n content={menu}\n >\n <Input\n // A combobox renders its own suggestion list; the browser's autofill dropdown\n // opens on top of it, so two lists compete for the same space.\n autoComplete='off'\n label={label}\n value={inputText}\n readOnly={readOnly}\n formValidator={null}\n isRequired={computedIsRequired}\n isValid={formValidator ? (formValidator.touched ? !formValidator.hasError() : true) : !error}\n errorMessage={\n formValidator\n ? formValidator.touched\n ? (formValidator.getCurrentErrorMessage() ?? '')\n : ''\n : (error ?? '')\n }\n onChange={(text) => {\n setInputText(text);\n setHighlightedIndex(null);\n setIsMenuShown(true);\n if (allowCustomValue) {\n if (formValidator) formValidator.set(text);\n if (onChange) onChange(text);\n } else if (text === '') {\n if (formValidator) formValidator.set('');\n if (onChange) onChange('');\n onSelect('');\n } else {\n // Emit when the typed text exactly matches an item's label/value.\n const match = items.find((item) => (item.label ?? item.value).toLowerCase() === text.toLowerCase());\n if (match) {\n if (formValidator) formValidator.set(match.value);\n if (onChange) onChange(match.value);\n onSelect(match.value);\n }\n }\n }}\n placeholder={placeholder}\n />\n </Popover>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use client";import{isSelfActivation as e}from"../utils/activationKey.mjs";import t from"./interactableDiv.module.mjs";import{useCallback as n}from"react";import r from"classnames";import{jsx as i}from"react/jsx-runtime";function a({className:a,children:o,onClick:s,onKeyDown:c,tabIndex:l,ref:u,...d}){let f=n(t=>{e(t)&&(t.key===` `&&t.preventDefault(),t.currentTarget.click()),c?.(t)},[c]);return i(`div`,{className:r(t.interactableDiv,a),onClick:s,tabIndex:l===void 0?s?0:void 0:l??void 0,role:s?`button`:void 0,onKeyDown:f,ref:u,...d,children:o})}export{a as default};
1
+ "use client";import{isSelfActivation as e}from"../utils/activationKey.mjs";import{isInteractiveTarget as t}from"../utils/interactiveTarget.mjs";import n from"./interactableDiv.module.mjs";import{useCallback as r}from"react";import i from"classnames";import{jsx as a}from"react/jsx-runtime";function o({className:o,children:s,onClick:c,onKeyDown:l,tabIndex:u,ref:d,...f}){let p=r(e=>{t(e.target,e.currentTarget)||c?.(e)},[c]),m=r(t=>{e(t)&&(t.key===` `&&t.preventDefault(),t.currentTarget.click()),l?.(t)},[l]);return a(`div`,{className:i(n.interactableDiv,o),onClick:c?p:void 0,tabIndex:u===void 0?c?0:void 0:u??void 0,role:c?`button`:void 0,onKeyDown:m,ref:d,...f,children:s})}export{o as default};
2
2
  //# sourceMappingURL=interactableDiv.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"interactableDiv.mjs","names":[],"sources":["../../../../package/common/interactableDiv/interactableDiv.tsx"],"sourcesContent":["import cx from 'classnames';\nimport React, { useCallback, type KeyboardEvent, type ReactElement } from 'react';\n\nimport styles from './interactableDiv.module.pcss';\nimport type { DataProps } from '../types/baseProps.types';\nimport { isSelfActivation } from '../utils/activationKey';\n\ninterface Properties extends DataProps, Omit<React.HTMLAttributes<HTMLDivElement>, 'tabIndex'> {\n tabIndex?: number | null;\n ref?: React.Ref<HTMLDivElement>;\n}\n\nfunction InteractableDiv({\n className,\n children,\n onClick,\n onKeyDown,\n tabIndex,\n ref,\n ...props\n}: Properties): ReactElement {\n const onKeyDownHandler = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (isSelfActivation(e)) {\n if (e.key === ' ') e.preventDefault();\n // A real click, the way a native button answers Enter and Space, rather\n // than calling `onClick` directly: it arrives as a MouseEvent instead of\n // a keyboard event wearing one, and it bubbles, so a parent that owns the\n // click sees it too. That parent is how a `Popover` or `Menu` opens from\n // a trigger that is not a button.\n e.currentTarget.click();\n }\n onKeyDown?.(e);\n },\n [onKeyDown],\n );\n\n // Compared to undefined rather than using ??, so an explicit null still means \"no tabindex\"\n // instead of falling through to the default.\n return (\n <div\n className={cx(styles.interactableDiv, className)}\n onClick={onClick}\n tabIndex={tabIndex === undefined ? (onClick ? 0 : undefined) : (tabIndex ?? undefined)}\n role={onClick ? 'button' : undefined}\n onKeyDown={onKeyDownHandler}\n ref={ref}\n {...props}\n >\n {children}\n </div>\n );\n}\n\nexport default InteractableDiv;\n"],"mappings":"6NAYA,SAAS,EAAgB,CACvB,YACA,WACA,UACA,YACA,WACA,MACA,GAAG,GACwB,CAC3B,IAAM,EAAmB,EACtB,GAAqC,CAChC,EAAiB,CAAC,IAChB,EAAE,MAAQ,KAAK,EAAE,eAAe,EAMpC,EAAE,cAAc,MAAM,GAExB,IAAY,CAAC,CACf,EACA,CAAC,CAAS,CACZ,EAIA,OACE,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,gBAAiB,CAAS,EACtC,UACT,SAAU,IAAa,IAAA,GAAa,EAAU,EAAI,IAAA,GAAc,GAAY,IAAA,GAC5E,KAAM,EAAU,SAAW,IAAA,GAC3B,UAAW,EACN,MACL,GAAI,EAEH,UACE,CAAA,CAET"}
1
+ {"version":3,"file":"interactableDiv.mjs","names":[],"sources":["../../../../package/common/interactableDiv/interactableDiv.tsx"],"sourcesContent":["import cx from 'classnames';\nimport React, { useCallback, type KeyboardEvent, type MouseEvent, type ReactElement } from 'react';\n\nimport styles from './interactableDiv.module.pcss';\nimport type { DataProps } from '../types/baseProps.types';\nimport { isSelfActivation } from '../utils/activationKey';\nimport { isInteractiveTarget } from '../utils/interactiveTarget';\n\ninterface Properties extends DataProps, Omit<React.HTMLAttributes<HTMLDivElement>, 'tabIndex'> {\n tabIndex?: number | null;\n ref?: React.Ref<HTMLDivElement>;\n}\n\nfunction InteractableDiv({\n className,\n children,\n onClick,\n onKeyDown,\n tabIndex,\n ref,\n ...props\n}: Properties): ReactElement {\n const onClickHandler = useCallback(\n (e: MouseEvent<HTMLDivElement>) => {\n // The pointer half of `isSelfActivation`: while only keydown checked its target, a click\n // into a card's text field counted as pressing the card and a Space typed into it did not.\n if (isInteractiveTarget(e.target, e.currentTarget)) return;\n onClick?.(e);\n },\n [onClick],\n );\n\n const onKeyDownHandler = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (isSelfActivation(e)) {\n if (e.key === ' ') e.preventDefault();\n // A real click, the way a native button answers Enter and Space, rather\n // than calling `onClick` directly: it arrives as a MouseEvent instead of\n // a keyboard event wearing one, and it bubbles, so a parent that owns the\n // click sees it too. That parent is how a `Popover` or `Menu` opens from\n // a trigger that is not a button.\n e.currentTarget.click();\n }\n onKeyDown?.(e);\n },\n [onKeyDown],\n );\n\n // Compared to undefined rather than using ??, so an explicit null still means \"no tabindex\"\n // instead of falling through to the default.\n return (\n <div\n className={cx(styles.interactableDiv, className)}\n onClick={onClick ? onClickHandler : undefined}\n tabIndex={tabIndex === undefined ? (onClick ? 0 : undefined) : (tabIndex ?? undefined)}\n role={onClick ? 'button' : undefined}\n onKeyDown={onKeyDownHandler}\n ref={ref}\n {...props}\n >\n {children}\n </div>\n );\n}\n\nexport default InteractableDiv;\n"],"mappings":"kSAaA,SAAS,EAAgB,CACvB,YACA,WACA,UACA,YACA,WACA,MACA,GAAG,GACwB,CAC3B,IAAM,EAAiB,EACpB,GAAkC,CAG7B,EAAoB,EAAE,OAAQ,EAAE,aAAa,GACjD,IAAU,CAAC,CACb,EACA,CAAC,CAAO,CACV,EAEM,EAAmB,EACtB,GAAqC,CAChC,EAAiB,CAAC,IAChB,EAAE,MAAQ,KAAK,EAAE,eAAe,EAMpC,EAAE,cAAc,MAAM,GAExB,IAAY,CAAC,CACf,EACA,CAAC,CAAS,CACZ,EAIA,OACE,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,gBAAiB,CAAS,EAC/C,QAAS,EAAU,EAAiB,IAAA,GACpC,SAAU,IAAa,IAAA,GAAa,EAAU,EAAI,IAAA,GAAc,GAAY,IAAA,GAC5E,KAAM,EAAU,SAAW,IAAA,GAC3B,UAAW,EACN,MACL,GAAI,EAEH,UACE,CAAA,CAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"gifPreview.module.mjs","names":[],"sources":["../../../../../../package/common/klipyPicker/components/gifPreview/gifPreview.module.pcss"],"sourcesContent":[".gifPreview {\n width: min(420px, 90vw);\n aspect-ratio: 1;\n display: flex;\n flex-wrap: wrap;\n\n --gif-preview-gap-size: 5px;\n\n gap: var(--gif-preview-gap-size);\n position: relative;\n justify-content: center;\n overflow: auto;\n\n &-image {\n background-position: center;\n background-size: cover;\n width: 100%;\n height: 100%;\n\n &-container {\n aspect-ratio: 1;\n background: linear-gradient(\n 45deg,\n var(--primary-color) 10%,\n var(--primary-lighter),\n var(--primary-accent),\n var(--primary-color) 85%\n );\n background-size: 500% 500%;\n animation: gradientBottomLeftToTopRight 1s infinite linear;\n border-radius: var(--default-border-radius);\n overflow: hidden;\n width: min(calc(140px - var(--gif-preview-gap-size)), calc(33.3% - var(--gif-preview-gap-size)));\n }\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"gifPreview.module.mjs","names":[],"sources":["../../../../../../package/common/klipyPicker/components/gifPreview/gifPreview.module.pcss"],"sourcesContent":[".gifPreview {\n width: min(420px, 90vw);\n aspect-ratio: 1;\n display: flex;\n flex-wrap: wrap;\n\n --gif-preview-gap-size: 5px;\n\n gap: var(--gif-preview-gap-size);\n position: relative;\n justify-content: center;\n overflow: auto;\n\n &-image {\n background-position: center;\n background-size: cover;\n width: 100%;\n height: 100%;\n\n &-container {\n aspect-ratio: 1;\n background: linear-gradient(\n 45deg,\n var(--primary-color) 10%,\n var(--primary-lighter),\n var(--primary-accent),\n var(--primary-color) 85%\n );\n background-size: 500% 500%;\n animation: gradientBottomLeftToTopRight 1s infinite linear;\n border-radius: var(--default-border-radius);\n overflow: hidden;\n width: min(calc(140px - var(--gif-preview-gap-size)), calc(33.3% - var(--gif-preview-gap-size)));\n }\n }\n}\n\n/* The gradient stops sweeping and stays a plain block, which still reads as \"loading\". */\n@media (prefers-reduced-motion: reduce) {\n .gifPreview-image-container {\n animation: none;\n }\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"gifView.module.mjs","names":[],"sources":["../../../../../../package/common/klipyPicker/components/gifView/gifView.module.pcss"],"sourcesContent":[".gifView {\n display: flex;\n justify-content: center;\n align-items: center;\n position: relative;\n\n img {\n max-width: 100%;\n border-radius: var(--default-border-radius);\n overflow: hidden;\n }\n\n &-loading {\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background: linear-gradient(\n 45deg,\n var(--primary-color) 10%,\n var(--primary-lighter),\n var(--primary-accent),\n var(--primary-color) 85%\n );\n background-size: 500% 500%;\n animation: gradientBottomLeftToTopRight 1s infinite linear;\n border-radius: var(--default-border-radius);\n overflow: hidden;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"gifView.module.mjs","names":[],"sources":["../../../../../../package/common/klipyPicker/components/gifView/gifView.module.pcss"],"sourcesContent":[".gifView {\n display: flex;\n justify-content: center;\n align-items: center;\n position: relative;\n\n img {\n max-width: 100%;\n border-radius: var(--default-border-radius);\n overflow: hidden;\n }\n\n &-loading {\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n background: linear-gradient(\n 45deg,\n var(--primary-color) 10%,\n var(--primary-lighter),\n var(--primary-accent),\n var(--primary-color) 85%\n );\n background-size: 500% 500%;\n animation: gradientBottomLeftToTopRight 1s infinite linear;\n border-radius: var(--default-border-radius);\n overflow: hidden;\n }\n}\n\n/* The gradient stops sweeping and stays a plain block, which still reads as \"loading\". */\n@media (prefers-reduced-motion: reduce) {\n .gifView-loading {\n animation: none;\n }\n}\n"],"mappings":""}
@@ -0,0 +1,2 @@
1
+ "use client";var e=e=>e!==void 0&&e>=`0`&&e<=`9`;function t(e){let t=[];for(let n=0;n<e.length;n++)e[n]===`9`&&t.push(n);return t}function n(t,n,r){return[...n].map((n,i)=>n===`9`?e(t[i])?t[i]:r:n).join(``)}function r(e,t,n){return e>=t.length?n.length:t[e]}function i(e,t){let n=t.findIndex(t=>t>=e);return n===-1?t.length:n}function a(e,t){for(let n=t.length-1;n>=0;n--)if(t[n]<e)return n;return-1}function o(r,i,a){let o=t(i),s=n(r,i,a),c=o.findIndex(t=>!e(s[t]));return c===-1?i.length:o[c]}function s(e,t,n){let r=Math.max(0,Math.min(e.length,e.length-(t.length-n))),i=0;for(;i<r&&i<n&&e[i]===t[i];)i++;return{from:i,to:r,inserted:t.slice(i,n)}}function c(o,c,l,u,d){let f=t(u),p=[...n(o,u,d)],m=e=>r(e,f,u),h=(e,t)=>f.filter(n=>n>=e&&n<t),{from:g,to:_,inserted:v}=s(o,c,l),y=[...v].filter(e);if(v.length>0&&y.length===0){let e=i(g,f);return{value:p.join(``),selection:{start:m(e),end:m(e)}}}if(v.length===0){let e=h(g,_),t=a(g,f),n=e.length>0?e:t===-1?[]:[f[t]];for(let e of n)p[e]=d;let r=e.length>0?i(g,f):Math.max(t,0);return{value:p.join(``),selection:{start:m(r),end:m(r)}}}for(let e of h(g,_))p[e]=d;let b=i(g,f);if(b>=f.length){let t=f.findIndex(t=>!e(p[t]));t!==-1&&(b=t)}for(let e of y){if(b>=f.length)break;p[f[b]]=e,b++}return{value:p.join(``),selection:{start:m(b),end:m(b)}}}function l(n,r){return!t(r).some(t=>e(n[t]))}export{o as firstEmptyCaret,l as isBlank,c as maskChange,t as slotIndices,n as toMask};
2
+ //# sourceMappingURL=mask.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mask.mjs","names":[],"sources":["../../../../package/common/maskedInput/mask.ts"],"sourcesContent":["/**\n * A fixed-width digit mask: `99:99`, `99.99.9999`.\n *\n * Fixed means every character keeps its position. Clearing a digit in the middle leaves a hole\n * rather than pulling the rest left, which is what a date or a time wants: deleting the month\n * out of `11.11.2025` must not turn the year into the month.\n *\n * `9` marks a slot that takes a digit. Every other character is a literal the caret steps over\n * and the user cannot type into.\n */\n\nconst DIGIT_SLOT = '9';\n\nexport interface MaskSelection {\n start: number;\n end: number;\n}\n\nexport interface MaskState {\n value: string;\n selection: MaskSelection | null;\n}\n\nconst isDigit = (character: string | undefined): boolean =>\n character !== undefined && character >= '0' && character <= '9';\n\n/** The mask indices that take a digit, in order. */\nexport function slotIndices(mask: string): number[] {\n const slots: number[] = [];\n for (let index = 0; index < mask.length; index++) if (mask[index] === DIGIT_SLOT) slots.push(index);\n return slots;\n}\n\n/** The mask with every slot empty: `__.__.____`. */\nexport function emptyMask(mask: string, placeholder: string): string {\n return [...mask].map((character) => (character === DIGIT_SLOT ? placeholder : character)).join('');\n}\n\n/**\n * Any string as one character per mask index, so slots can be read and written by position.\n *\n * Every other function here assumes a value exactly as long as the mask, with literals where the\n * mask has them. Putting a value through this is what guarantees that, whether it came from a\n * keystroke, from a consumer's state, or from nothing at all.\n */\nexport function toMask(value: string, mask: string, placeholder: string): string {\n return [...mask]\n .map((maskCharacter, index) => {\n if (maskCharacter !== DIGIT_SLOT) return maskCharacter;\n return isDigit(value[index]) ? value[index] : placeholder;\n })\n .join('');\n}\n\n/** Where the caret belongs so the next digit typed lands in `slot`. */\nfunction caretForSlot(slot: number, slots: number[], mask: string): number {\n return slot >= slots.length ? mask.length : slots[slot];\n}\n\n/** The first slot at or after `index`, or the slot count when there is none. */\nfunction slotAtOrAfter(index: number, slots: number[]): number {\n const found = slots.findIndex((position) => position >= index);\n return found === -1 ? slots.length : found;\n}\n\n/** The last slot strictly before `index`, or -1. */\nfunction slotBefore(index: number, slots: number[]): number {\n for (let slot = slots.length - 1; slot >= 0; slot--) if (slots[slot] < index) return slot;\n return -1;\n}\n\n/**\n * Where the caret belongs when the field is entered: the first slot with no digit in it.\n *\n * A mask is as wide when empty as when full, so a click lands wherever it likes, and clicking at\n * the end of `__.__.____` would otherwise leave the caret past every slot with nowhere to put the\n * next digit.\n */\nexport function firstEmptyCaret(value: string, mask: string, placeholder: string): number {\n const slots = slotIndices(mask);\n const filled = toMask(value, mask, placeholder);\n const empty = slots.findIndex((index) => !isDigit(filled[index]));\n return empty === -1 ? mask.length : slots[empty];\n}\n\n/** One edit, as the region of the old value it replaced and the text it put there. */\nfunction editOf(previous: string, raw: string, caret: number) {\n // Everything after the caret is untouched, so the replaced region ends exactly as far from the\n // end of the old value as the caret is from the end of the new one. This is what the caret is\n // for: a prefix/suffix diff alone cannot tell a forward Delete from a Backspace one place along,\n // nor typing `1` over a `1` from typing nothing at all.\n const to = Math.max(0, Math.min(previous.length, previous.length - (raw.length - caret)));\n\n let from = 0;\n while (from < to && from < caret && previous[from] === raw[from]) from++;\n\n return { from, to, inserted: raw.slice(from, caret) };\n}\n\n/**\n * What the field should show after the browser has changed its raw text, and where the caret\n * belongs.\n *\n * Works from the edit rather than from key events, so a paste, a drag, a replaced selection, an\n * autofill and a keystroke all arrive the same way.\n */\nexport function maskChange(previous: string, raw: string, caret: number, mask: string, placeholder: string): MaskState {\n const slots = slotIndices(mask);\n const characters = [...toMask(previous, mask, placeholder)];\n const at = (slot: number) => caretForSlot(slot, slots, mask);\n const held = (from: number, to: number) => slots.filter((index) => index >= from && index < to);\n\n const { from, to, inserted } = editOf(previous, raw, caret);\n const digits = [...inserted].filter(isDigit);\n\n // Something was typed that the mask has no room for: a separator the mask already draws, a\n // letter, a symbol. The old library dropped these, and so does this — writing nothing would\n // still be wrong, because the browser has already put the character in the field.\n if (inserted.length > 0 && digits.length === 0) {\n const caretSlot = slotAtOrAfter(from, slots);\n return { value: characters.join(''), selection: { start: at(caretSlot), end: at(caretSlot) } };\n }\n\n if (inserted.length === 0) {\n const touched = held(from, to);\n\n // Backspace over a literal reads as deleting only that literal, which the user cannot have\n // meant: nothing they typed is there. Take the digit in front of it instead, the way the\n // caret would have if it had never been allowed to rest on a literal.\n const previousSlot = slotBefore(from, slots);\n const target = touched.length > 0 ? touched : previousSlot === -1 ? [] : [slots[previousSlot]];\n\n for (const index of target) characters[index] = placeholder;\n const caretSlot = touched.length > 0 ? slotAtOrAfter(from, slots) : Math.max(previousSlot, 0);\n return { value: characters.join(''), selection: { start: at(caretSlot), end: at(caretSlot) } };\n }\n\n // A replaced selection clears what it covered first, so typing over a highlighted month does\n // not leave its second digit behind.\n for (const index of held(from, to)) characters[index] = placeholder;\n\n let slot = slotAtOrAfter(from, slots);\n // Typed past the last slot: a mask is as wide empty as full, so a click can leave the caret\n // there with nothing after it. Fall back to the first slot still free, which is where the digit\n // was going to end up anyway. A value with no free slot is left alone, as it should be.\n if (slot >= slots.length) {\n const free = slots.findIndex((index) => !isDigit(characters[index]));\n if (free !== -1) slot = free;\n }\n\n for (const digit of digits) {\n if (slot >= slots.length) break;\n characters[slots[slot]] = digit;\n slot++;\n }\n\n return { value: characters.join(''), selection: { start: at(slot), end: at(slot) } };\n}\n\n/** Whether a masked value holds no digits at all, so the field reads as empty. */\nexport function isBlank(value: string, mask: string): boolean {\n return !slotIndices(mask).some((index) => isDigit(value[index]));\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use client";import{mergeRefs as e}from"../utils/mergeRefs.mjs";import{firstEmptyCaret as t,isBlank as n,maskChange as r,toMask as i}from"./mask.mjs";import{useLayoutEffect as a,useRef as o,useState as s}from"react";import{jsx as c}from"react/jsx-runtime";function l(l){let{mask:u,maskPlaceholder:d=`_`,value:f=``,onChange:p,beforeMaskedStateChange:m,onFocus:h,onBlur:g,onClick:_,ref:v,...y}=l,b=o(null),[x,S]=s(!1),C=o(null);a(()=>{C.current!==null&&(b.current?.setSelectionRange(C.current,C.current),C.current=null)});let w=n(f,u),T=w?x?i(``,u,d):``:i(f,u,d),E=e=>{C.current=e,b.current?.setSelectionRange(e,e)},D=e=>{let a=e.target,o=a.value,s=r(T,o,a.selectionStart??o.length,u,d),c=m?m({previousState:{value:T,selection:null},nextState:s}):s,l=i(c.value,u,d),f=c.selection?.start??t(l,u,d);if(l===T){a.value=T,E(f);return}C.current=f,p?.(n(l,u)?``:l)},O=e=>{S(!0),w&&(C.current=0),h?.(e)},k=e=>{let n=e.currentTarget,r=t(T,u,d);n.selectionStart===n.selectionEnd&&(n.selectionStart??0)>r&&n.setSelectionRange(r,r),_?.(e)},A=e=>{S(!1),g?.(e)};return c(`input`,{...y,ref:e(b,v),value:T,onChange:D,onFocus:O,onBlur:A,onClick:k,inputMode:`numeric`})}export{l as default};
2
+ //# sourceMappingURL=maskedInput.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maskedInput.mjs","names":[],"sources":["../../../../package/common/maskedInput/maskedInput.tsx"],"sourcesContent":["import { useLayoutEffect, useRef, useState } from 'react';\nimport type React from 'react';\n\nimport { mergeRefs } from '../utils/mergeRefs';\nimport { firstEmptyCaret, isBlank, maskChange, toMask } from './mask';\nimport type { MaskedInputProps } from './maskedInput.types';\n\n/**\n * A text input under a fixed digit mask, used by `DatePicker` and `TimeInput` through `Input`'s\n * `customInput`. Internal: consumers reach it through those two.\n *\n * Controlled, with one exception. An empty field shows nothing until it is focused, and then shows\n * the bare mask, so a form full of `__.__.____` does not greet someone who has typed nothing. That\n * mask is display only and is never reported through `onChange`, or every untouched date field\n * would submit a value made of underscores.\n */\nfunction MaskedInput(props: MaskedInputProps) {\n const {\n mask,\n maskPlaceholder = '_',\n value = '',\n onChange,\n beforeMaskedStateChange,\n onFocus,\n onBlur,\n onClick,\n ref,\n ...rest\n } = props;\n\n const inputRef = useRef<HTMLInputElement>(null);\n const [isFocused, setIsFocused] = useState(false);\n /**\n * Where the caret belongs after the value the parent holds comes back to us. Set during the\n * change and applied on the next paint, because the browser puts the caret at the end of any\n * value it did not compute itself.\n */\n const caretRef = useRef<number | null>(null);\n\n useLayoutEffect(() => {\n if (caretRef.current === null) return;\n inputRef.current?.setSelectionRange(caretRef.current, caretRef.current);\n caretRef.current = null;\n });\n\n const blank = isBlank(value, mask);\n // Everything below assumes a value exactly as long as the mask. The prop is whatever the parent\n // holds, which on a first render can be a date from somewhere else entirely, so it is put\n // through the mask rather than trusted.\n const display = blank ? (isFocused ? toMask('', mask, maskPlaceholder) : '') : toMask(value, mask, maskPlaceholder);\n\n const setCaret = (position: number) => {\n caretRef.current = position;\n inputRef.current?.setSelectionRange(position, position);\n };\n\n const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {\n const input = event.target;\n const raw = input.value;\n const nextState = maskChange(display, raw, input.selectionStart ?? raw.length, mask, maskPlaceholder);\n\n const state = beforeMaskedStateChange\n ? beforeMaskedStateChange({ previousState: { value: display, selection: null }, nextState })\n : nextState;\n\n const next = toMask(state.value, mask, maskPlaceholder);\n const caret = state.selection?.start ?? firstEmptyCaret(next, mask, maskPlaceholder);\n\n // Nothing came of it — a letter typed into an empty field, or a separator the mask already\n // draws. React re-renders nothing when the value it holds has not changed, so the caret has\n // to be put back here; the layout effect will not run.\n if (next === display) {\n input.value = display;\n setCaret(caret);\n return;\n }\n\n caretRef.current = caret;\n onChange?.(isBlank(next, mask) ? '' : next);\n };\n\n const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {\n setIsFocused(true);\n // Only when the mask is about to appear. The field showed nothing a moment ago, so whatever\n // caret the browser picked was measured against an empty string. A field with something in it\n // keeps the caret where the user put it, and `handleClick` pulls it back only if it landed\n // past the last free slot.\n if (blank) caretRef.current = 0;\n onFocus?.(event);\n };\n\n /**\n * A click can leave the caret past every slot, because a mask is as wide empty as full. Runs on\n * click rather than on focus: the browser sets the selection on mouse *up*, after focus, so at\n * focus time there is nothing reliable to read.\n */\n const handleClick = (event: React.MouseEvent<HTMLInputElement>) => {\n const input = event.currentTarget;\n const limit = firstEmptyCaret(display, mask, maskPlaceholder);\n // A drag that selected something is left alone; so is a caret already inside the filled part.\n if (input.selectionStart === input.selectionEnd && (input.selectionStart ?? 0) > limit) {\n input.setSelectionRange(limit, limit);\n }\n onClick?.(event);\n };\n\n const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {\n setIsFocused(false);\n onBlur?.(event);\n };\n\n return (\n <input\n {...rest}\n ref={mergeRefs(inputRef, ref)}\n value={display}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onClick={handleClick}\n inputMode='numeric'\n />\n );\n}\n\nexport default MaskedInput;\n"],"mappings":"gQAgBA,SAAS,EAAY,EAAyB,CAC5C,GAAM,CACJ,OACA,kBAAkB,IAClB,QAAQ,GACR,WACA,0BACA,UACA,SACA,UACA,MACA,GAAG,GACD,EAEE,EAAW,EAAyB,IAAI,EACxC,CAAC,EAAW,GAAgB,EAAS,EAAK,EAM1C,EAAW,EAAsB,IAAI,EAE3C,MAAsB,CAChB,EAAS,UAAY,OACzB,EAAS,SAAS,kBAAkB,EAAS,QAAS,EAAS,OAAO,EACtE,EAAS,QAAU,KACrB,CAAC,EAED,IAAM,EAAQ,EAAQ,EAAO,CAAI,EAI3B,EAAU,EAAS,EAAY,EAAO,GAAI,EAAM,CAAe,EAAI,GAAM,EAAO,EAAO,EAAM,CAAe,EAE5G,EAAY,GAAqB,CACrC,EAAS,QAAU,EACnB,EAAS,SAAS,kBAAkB,EAAU,CAAQ,CACxD,EAEM,EAAgB,GAA+C,CACnE,IAAM,EAAQ,EAAM,OACd,EAAM,EAAM,MACZ,EAAY,EAAW,EAAS,EAAK,EAAM,gBAAkB,EAAI,OAAQ,EAAM,CAAe,EAE9F,EAAQ,EACV,EAAwB,CAAE,cAAe,CAAE,MAAO,EAAS,UAAW,IAAK,EAAG,WAAU,CAAC,EACzF,EAEE,EAAO,EAAO,EAAM,MAAO,EAAM,CAAe,EAChD,EAAQ,EAAM,WAAW,OAAS,EAAgB,EAAM,EAAM,CAAe,EAKnF,GAAI,IAAS,EAAS,CACpB,EAAM,MAAQ,EACd,EAAS,CAAK,EACd,MACF,CAEA,EAAS,QAAU,EACnB,IAAW,EAAQ,EAAM,CAAI,EAAI,GAAK,CAAI,CAC5C,EAEM,EAAe,GAA8C,CACjE,EAAa,EAAI,EAKb,IAAO,EAAS,QAAU,GAC9B,IAAU,CAAK,CACjB,EAOM,EAAe,GAA8C,CACjE,IAAM,EAAQ,EAAM,cACd,EAAQ,EAAgB,EAAS,EAAM,CAAe,EAExD,EAAM,iBAAmB,EAAM,eAAiB,EAAM,gBAAkB,GAAK,GAC/E,EAAM,kBAAkB,EAAO,CAAK,EAEtC,IAAU,CAAK,CACjB,EAEM,EAAc,GAA8C,CAChE,EAAa,EAAK,EAClB,IAAS,CAAK,CAChB,EAEA,OACE,EAAC,QAAD,CACE,GAAI,EACJ,IAAK,EAAU,EAAU,CAAG,EAC5B,MAAO,EACP,SAAU,EACV,QAAS,EACT,OAAQ,EACR,QAAS,EACT,UAAU,SACX,CAAA,CAEL"}
@@ -1,2 +1,2 @@
1
- "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{usePresentationDefault as n}from"../configProvider/usePresentationDefault.mjs";import r from"../bodyEnd/bodyEnd.mjs";import i from"../styles/sheet.module.mjs";import{useVisualViewportSize as a}from"../hooks/useVisualViewportSize.mjs";import o from"../hooks/useSheet.mjs";import{useOverlay as s}from"../hooks/useOverlay.mjs";import c from"./modal.module.mjs";import{useEffect as l,useId as u,useRef as d,useState as f}from"react";import p from"classnames";import{FontAwesomeIcon as m}from"@fortawesome/react-fontawesome";import{faXmark as h}from"@fortawesome/free-solid-svg-icons";import{jsx as g,jsxs as _}from"react/jsx-runtime";var v={close:`Close`};function y(y){let{children:b=null,title:x=``,isOpen:S=!1,onClose:C=()=>null,className:w=``,style:T,hideHeader:E=!1,closeOnEscape:D=!0,presentation:O,classNames:k,styles:A,labels:j,...M}=e(`Modal`,y),N=t(`Modal`,j,v),[P,F]=f(S),[I,L]=f(S),R=d(null),z=u(),{height:B,offsetTop:V}=a(),H=n(),{isSheet:U,sheetStyle:W}=o(O??H);if(l(()=>{S?(F(S),setTimeout(()=>L(!0),1)):(L(!1),setTimeout(()=>F(S),300))},[S]),s({isActive:P&&I,containerRef:R,onEscape:D?C:void 0}),!P)return null;let G=!E&&!!x;return g(r,{children:_(`div`,{className:p(c.modalContainer,k?.container),style:{height:B,top:V,...A?.container},children:[g(`div`,{className:p(c.modalWrapper,I&&c.modalWrapperShown,k?.backdrop),style:A?.backdrop,onClick:C}),I&&_(`div`,{...M,ref:R,role:`dialog`,"aria-modal":`true`,"aria-labelledby":G?z:void 0,tabIndex:-1,className:p(c.modal,I&&c.modalShown,U&&[i.sheet,i.sheetSurface,c.modalSheet],w,k?.modal),style:{...U?W:void 0,...T,...A?.modal},onClick:e=>e.stopPropagation(),children:[!E&&_(`div`,{className:p(c.modalHeader,k?.header),style:A?.header,children:[g(`div`,{id:z,className:k?.title,style:A?.title,children:x}),g(`button`,{type:`button`,onClick:C,"aria-label":N.close,className:p(c.modalCloseButton,k?.closeButton),style:A?.closeButton,children:g(m,{icon:h})})]}),g(`div`,{className:p(c.modalBody,k?.body),style:A?.body,children:b})]})]})})}export{y as default};
1
+ "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{usePresentationDefault as n}from"../configProvider/usePresentationDefault.mjs";import r from"../bodyEnd/bodyEnd.mjs";import i from"../styles/sheet.module.mjs";import{useVisualViewportSize as a}from"../hooks/useVisualViewportSize.mjs";import o from"../hooks/useSheet.mjs";import{useOverlay as s}from"../hooks/useOverlay.mjs";import c from"../styles/scrollFade.module.mjs";import l from"./modal.module.mjs";import{useScrollEdges as u}from"../hooks/useScrollEdges.mjs";import{useEffect as d,useId as f,useRef as p,useState as m}from"react";import h from"classnames";import{FontAwesomeIcon as g}from"@fortawesome/react-fontawesome";import{faXmark as _}from"@fortawesome/free-solid-svg-icons";import{jsx as v,jsxs as y}from"react/jsx-runtime";var b={close:`Close`};function x(x){let{children:S=null,title:C=``,isOpen:w=!1,onClose:T=()=>null,footer:E=null,className:D=``,style:O,hideHeader:k=!1,closeOnEscape:A=!0,presentation:j,classNames:M,styles:N,labels:P,...F}=e(`Modal`,x),I=t(`Modal`,P,b),[L,R]=m(w),[z,B]=m(w),V=p(null),H=p(null),U=f(),{height:W,offsetTop:G}=a(),K=n(),{isSheet:q,sheetStyle:J}=o(j??K);d(()=>{w?(R(w),setTimeout(()=>B(!0),1)):(B(!1),setTimeout(()=>R(w),300))},[w]),s({isActive:L&&z,containerRef:V,onEscape:A?T:void 0});let{hasStart:Y,hasEnd:X}=u(H,{isEnabled:L&&z});if(!L)return null;let Z=!k&&!!C;return v(r,{children:y(`div`,{className:h(l.modalContainer,M?.container),style:{height:W,top:G,...N?.container},children:[v(`div`,{className:h(l.modalWrapper,z&&l.modalWrapperShown,M?.backdrop),style:N?.backdrop,onClick:T}),z&&y(`div`,{...F,ref:V,role:`dialog`,"aria-modal":`true`,"aria-labelledby":Z?U:void 0,tabIndex:-1,className:h(l.modal,z&&l.modalShown,q&&[i.sheet,i.sheetSurface,l.modalSheet],D,M?.modal),style:{...q?J:void 0,...O,...N?.modal},onClick:e=>e.stopPropagation(),children:[!k&&y(`div`,{className:h(l.modalHeader,M?.header),style:N?.header,children:[v(`div`,{id:U,className:M?.title,style:N?.title,children:C}),v(`button`,{type:`button`,onClick:T,"aria-label":I.close,className:h(l.modalCloseButton,M?.closeButton),style:N?.closeButton,children:v(g,{icon:_})})]}),v(`div`,{ref:H,className:h(l.modalBody,c.scrollFade,c.scrollFadeY,Y&&c.scrollFadeFadedStart,X&&c.scrollFadeFadedEnd,M?.body),style:N?.body,children:S}),E&&v(`div`,{className:h(l.modalFooter,M?.footer),style:N?.footer,children:E})]})]})})}export{x as default};
2
2
  //# sourceMappingURL=modal.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"modal.mjs","names":[],"sources":["../../../../package/common/modal/modal.tsx"],"sourcesContent":["import cx from 'classnames';\nimport BodyEnd from 'components/common/bodyEnd';\n\nimport styles from './modal.module.pcss';\nimport sheetStyles from 'components/common/styles/sheet.module.pcss';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faXmark as closeIcon } from '@fortawesome/free-solid-svg-icons';\nimport { ModalProps } from './modal.types';\nimport type { ModalLabels } from './modal.types';\nimport { useEffect, useId, useRef, useState } from 'react';\nimport { useVisualViewportSize } from 'components/common/hooks/useVisualViewportSize';\nimport { useOverlay } from 'components/common/hooks/useOverlay';\nimport { useSheet } from 'components/common/hooks/useSheet';\nimport { useComponentDefaults, useLabels, usePresentationDefault } from 'components/common/configProvider';\n\nconst DEFAULT_LABELS: Required<ModalLabels> = {\n close: 'Close',\n};\n\nfunction Modal(props: ModalProps) {\n const {\n children = null,\n title = '',\n isOpen = false,\n onClose = () => null,\n className = '',\n style,\n hideHeader = false,\n closeOnEscape = true,\n presentation: presentationProp,\n classNames,\n styles: slotStyles,\n labels,\n ...rest\n } = useComponentDefaults('Modal', props);\n const text = useLabels('Modal', labels, DEFAULT_LABELS);\n const [isRendered, setIsRendered] = useState(isOpen);\n const [animateIn, setAnimateIn] = useState(isOpen);\n const modalRef = useRef<HTMLDivElement>(null);\n const titleId = useId();\n // Centering/sizing against the actually-visible viewport (not the full layout viewport) keeps\n // the modal — and whatever's focused inside it — from ending up under a mobile keyboard.\n const { height: viewportHeight, offsetTop: viewportOffsetTop } = useVisualViewportSize();\n // Explicit prop → this component's global default → the app-wide one. There's no built-in\n // fallback to add: `Default` and no presentation at all both mean the ordinary centred dialog.\n const appPresentation = usePresentationDefault();\n const presentation = presentationProp ?? appPresentation;\n const { isSheet, sheetStyle } = useSheet(presentation);\n\n useEffect(() => {\n if (isOpen) {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setIsRendered(isOpen);\n setTimeout(() => setAnimateIn(true), 1);\n } else {\n setAnimateIn(false);\n setTimeout(() => setIsRendered(isOpen), 300);\n }\n }, [isOpen]);\n\n // Keyed on `animateIn` rather than `isOpen`, because the panel this needs to focus and trap\n // focus inside of only mounts once that flips.\n useOverlay({\n isActive: isRendered && animateIn,\n containerRef: modalRef,\n onEscape: closeOnEscape ? onClose : undefined,\n });\n\n if (!isRendered) return null;\n\n const hasHeaderTitle = !hideHeader && !!title;\n\n return (\n <BodyEnd>\n <div\n className={cx(styles.modalContainer, classNames?.container)}\n style={{ height: viewportHeight, top: viewportOffsetTop, ...slotStyles?.container }}\n >\n <div\n className={cx(styles.modalWrapper, animateIn && styles.modalWrapperShown, classNames?.backdrop)}\n style={slotStyles?.backdrop}\n onClick={onClose}\n />\n {animateIn && (\n <div\n {...rest}\n ref={modalRef}\n role='dialog'\n aria-modal='true'\n aria-labelledby={hasHeaderTitle ? titleId : undefined}\n // Focusable so the trap has somewhere to put focus when the content has no tabbables.\n tabIndex={-1}\n className={cx(\n styles.modal,\n animateIn && styles.modalShown,\n // The panel is its own sheet surface here: there's no inner panel to fill, since\n // Modal already splits itself into a fixed header and a scrolling body.\n isSheet && [sheetStyles.sheet, sheetStyles.sheetSurface, styles.modalSheet],\n className,\n classNames?.modal,\n )}\n style={{ ...(isSheet ? sheetStyle : undefined), ...style, ...slotStyles?.modal }}\n onClick={(e) => e.stopPropagation()}\n >\n {!hideHeader && (\n <div className={cx(styles.modalHeader, classNames?.header)} style={slotStyles?.header}>\n <div id={titleId} className={classNames?.title} style={slotStyles?.title}>\n {title}\n </div>\n <button\n type='button'\n onClick={onClose}\n aria-label={text.close}\n className={cx(styles.modalCloseButton, classNames?.closeButton)}\n style={slotStyles?.closeButton}\n >\n <FontAwesomeIcon icon={closeIcon} />\n </button>\n </div>\n )}\n <div className={cx(styles.modalBody, classNames?.body)} style={slotStyles?.body}>\n {children}\n </div>\n </div>\n )}\n </div>\n </BodyEnd>\n );\n}\n\nexport default Modal;\n"],"mappings":"wxBAeA,IAAM,EAAwC,CAC5C,MAAO,OACT,EAEA,SAAS,EAAM,EAAmB,CAChC,GAAM,CACJ,WAAW,KACX,QAAQ,GACR,SAAS,GACT,cAAgB,KAChB,YAAY,GACZ,QACA,aAAa,GACb,gBAAgB,GAChB,aAAc,EACd,aACA,OAAQ,EACR,SACA,GAAG,GACD,EAAqB,QAAS,CAAK,EACjC,EAAO,EAAU,QAAS,EAAQ,CAAc,EAChD,CAAC,EAAY,GAAiB,EAAS,CAAM,EAC7C,CAAC,EAAW,GAAgB,EAAS,CAAM,EAC3C,EAAW,EAAuB,IAAI,EACtC,EAAU,EAAM,EAGhB,CAAE,OAAQ,EAAgB,UAAW,GAAsB,EAAsB,EAGjF,EAAkB,EAAuB,EAEzC,CAAE,UAAS,cAAe,EADX,GAAoB,CACY,EAqBrD,GAnBA,MAAgB,CACV,GAEF,EAAc,CAAM,EACpB,eAAiB,EAAa,EAAI,EAAG,CAAC,IAEtC,EAAa,EAAK,EAClB,eAAiB,EAAc,CAAM,EAAG,GAAG,EAE/C,EAAG,CAAC,CAAM,CAAC,EAIX,EAAW,CACT,SAAU,GAAc,EACxB,aAAc,EACd,SAAU,EAAgB,EAAU,IAAA,EACtC,CAAC,EAEG,CAAC,EAAY,OAAO,KAExB,IAAM,EAAiB,CAAC,GAAc,CAAC,CAAC,EAExC,OACE,EAAC,EAAD,CAAA,SACE,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,eAAgB,GAAY,SAAS,EAC1D,MAAO,CAAE,OAAQ,EAAgB,IAAK,EAAmB,GAAG,GAAY,SAAU,EAFpF,SAAA,CAIE,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,aAAc,GAAa,EAAO,kBAAmB,GAAY,QAAQ,EAC9F,MAAO,GAAY,SACnB,QAAS,CACV,CAAA,EACA,GACC,EAAC,MAAD,CACE,GAAI,EACJ,IAAK,EACL,KAAK,SACL,aAAW,OACX,kBAAiB,EAAiB,EAAU,IAAA,GAE5C,SAAU,GACV,UAAW,EACT,EAAO,MACP,GAAa,EAAO,WAGpB,GAAW,CAAC,EAAY,MAAO,EAAY,aAAc,EAAO,UAAU,EAC1E,EACA,GAAY,KACd,EACA,MAAO,CAAE,GAAI,EAAU,EAAa,IAAA,GAAY,GAAG,EAAO,GAAG,GAAY,KAAM,EAC/E,QAAU,GAAM,EAAE,gBAAgB,EAlBpC,SAAA,CAoBG,CAAC,GACA,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,YAAa,GAAY,MAAM,EAAG,MAAO,GAAY,OAA/E,SAAA,CACE,EAAC,MAAD,CAAK,GAAI,EAAS,UAAW,GAAY,MAAO,MAAO,GAAY,MAChE,SAAA,CACE,CAAA,EACL,EAAC,SAAD,CACE,KAAK,SACL,QAAS,EACT,aAAY,EAAK,MACjB,UAAW,EAAG,EAAO,iBAAkB,GAAY,WAAW,EAC9D,MAAO,GAAY,YAEnB,SAAA,EAAC,EAAD,CAAiB,KAAM,CAAY,CAAA,CAC7B,CAAA,CACL,CAEP,CAAA,EAAA,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,UAAW,GAAY,IAAI,EAAG,MAAO,GAAY,KACxE,UACE,CAAA,CACF,CAEJ,CAAA,CAAA,CACE,CAAA,CAAA,CAAA,CAEb"}
1
+ {"version":3,"file":"modal.mjs","names":[],"sources":["../../../../package/common/modal/modal.tsx"],"sourcesContent":["import cx from 'classnames';\nimport BodyEnd from 'components/common/bodyEnd';\n\nimport styles from './modal.module.pcss';\nimport sheetStyles from 'components/common/styles/sheet.module.pcss';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport { faXmark as closeIcon } from '@fortawesome/free-solid-svg-icons';\nimport { ModalProps } from './modal.types';\nimport type { ModalLabels } from './modal.types';\nimport { useEffect, useId, useRef, useState } from 'react';\nimport { useVisualViewportSize } from 'components/common/hooks/useVisualViewportSize';\nimport { useOverlay } from 'components/common/hooks/useOverlay';\nimport { useSheet } from 'components/common/hooks/useSheet';\nimport { useScrollEdges } from 'components/common/hooks/useScrollEdges';\nimport fadeStyles from 'components/common/styles/scrollFade.module.pcss';\nimport { useComponentDefaults, useLabels, usePresentationDefault } from 'components/common/configProvider';\n\nconst DEFAULT_LABELS: Required<ModalLabels> = {\n close: 'Close',\n};\n\nfunction Modal(props: ModalProps) {\n const {\n children = null,\n title = '',\n isOpen = false,\n onClose = () => null,\n footer = null,\n className = '',\n style,\n hideHeader = false,\n closeOnEscape = true,\n presentation: presentationProp,\n classNames,\n styles: slotStyles,\n labels,\n ...rest\n } = useComponentDefaults('Modal', props);\n const text = useLabels('Modal', labels, DEFAULT_LABELS);\n const [isRendered, setIsRendered] = useState(isOpen);\n const [animateIn, setAnimateIn] = useState(isOpen);\n const modalRef = useRef<HTMLDivElement>(null);\n const bodyRef = useRef<HTMLDivElement>(null);\n const titleId = useId();\n // Centering/sizing against the actually-visible viewport (not the full layout viewport) keeps\n // the modal — and whatever's focused inside it — from ending up under a mobile keyboard.\n const { height: viewportHeight, offsetTop: viewportOffsetTop } = useVisualViewportSize();\n // Explicit prop → this component's global default → the app-wide one. There's no built-in\n // fallback to add: `Default` and no presentation at all both mean the ordinary centred dialog.\n const appPresentation = usePresentationDefault();\n const presentation = presentationProp ?? appPresentation;\n const { isSheet, sheetStyle } = useSheet(presentation);\n\n useEffect(() => {\n if (isOpen) {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setIsRendered(isOpen);\n setTimeout(() => setAnimateIn(true), 1);\n } else {\n setAnimateIn(false);\n setTimeout(() => setIsRendered(isOpen), 300);\n }\n }, [isOpen]);\n\n // Keyed on `animateIn` rather than `isOpen`, because the panel this needs to focus and trap\n // focus inside of only mounts once that flips.\n useOverlay({\n isActive: isRendered && animateIn,\n containerRef: modalRef,\n onEscape: closeOnEscape ? onClose : undefined,\n });\n\n const { hasStart, hasEnd } = useScrollEdges(bodyRef, { isEnabled: isRendered && animateIn });\n\n if (!isRendered) return null;\n\n const hasHeaderTitle = !hideHeader && !!title;\n\n return (\n <BodyEnd>\n <div\n className={cx(styles.modalContainer, classNames?.container)}\n style={{ height: viewportHeight, top: viewportOffsetTop, ...slotStyles?.container }}\n >\n <div\n className={cx(styles.modalWrapper, animateIn && styles.modalWrapperShown, classNames?.backdrop)}\n style={slotStyles?.backdrop}\n onClick={onClose}\n />\n {animateIn && (\n <div\n {...rest}\n ref={modalRef}\n role='dialog'\n aria-modal='true'\n aria-labelledby={hasHeaderTitle ? titleId : undefined}\n // Focusable so the trap has somewhere to put focus when the content has no tabbables.\n tabIndex={-1}\n className={cx(\n styles.modal,\n animateIn && styles.modalShown,\n // The panel is its own sheet surface here: there's no inner panel to fill, since\n // Modal already splits itself into a fixed header and a scrolling body.\n isSheet && [sheetStyles.sheet, sheetStyles.sheetSurface, styles.modalSheet],\n className,\n classNames?.modal,\n )}\n style={{ ...(isSheet ? sheetStyle : undefined), ...style, ...slotStyles?.modal }}\n onClick={(e) => e.stopPropagation()}\n >\n {!hideHeader && (\n <div className={cx(styles.modalHeader, classNames?.header)} style={slotStyles?.header}>\n <div id={titleId} className={classNames?.title} style={slotStyles?.title}>\n {title}\n </div>\n <button\n type='button'\n onClick={onClose}\n aria-label={text.close}\n className={cx(styles.modalCloseButton, classNames?.closeButton)}\n style={slotStyles?.closeButton}\n >\n <FontAwesomeIcon icon={closeIcon} />\n </button>\n </div>\n )}\n <div\n ref={bodyRef}\n className={cx(\n styles.modalBody,\n fadeStyles.scrollFade,\n fadeStyles.scrollFadeY,\n hasStart && fadeStyles.scrollFadeFadedStart,\n hasEnd && fadeStyles.scrollFadeFadedEnd,\n classNames?.body,\n )}\n style={slotStyles?.body}\n >\n {children}\n </div>\n {footer && (\n <div className={cx(styles.modalFooter, classNames?.footer)} style={slotStyles?.footer}>\n {footer}\n </div>\n )}\n </div>\n )}\n </div>\n </BodyEnd>\n );\n}\n\nexport default Modal;\n"],"mappings":"o4BAiBA,IAAM,EAAwC,CAC5C,MAAO,OACT,EAEA,SAAS,EAAM,EAAmB,CAChC,GAAM,CACJ,WAAW,KACX,QAAQ,GACR,SAAS,GACT,cAAgB,KAChB,SAAS,KACT,YAAY,GACZ,QACA,aAAa,GACb,gBAAgB,GAChB,aAAc,EACd,aACA,OAAQ,EACR,SACA,GAAG,GACD,EAAqB,QAAS,CAAK,EACjC,EAAO,EAAU,QAAS,EAAQ,CAAc,EAChD,CAAC,EAAY,GAAiB,EAAS,CAAM,EAC7C,CAAC,EAAW,GAAgB,EAAS,CAAM,EAC3C,EAAW,EAAuB,IAAI,EACtC,EAAU,EAAuB,IAAI,EACrC,EAAU,EAAM,EAGhB,CAAE,OAAQ,EAAgB,UAAW,GAAsB,EAAsB,EAGjF,EAAkB,EAAuB,EAEzC,CAAE,UAAS,cAAe,EADX,GAAoB,CACY,EAErD,MAAgB,CACV,GAEF,EAAc,CAAM,EACpB,eAAiB,EAAa,EAAI,EAAG,CAAC,IAEtC,EAAa,EAAK,EAClB,eAAiB,EAAc,CAAM,EAAG,GAAG,EAE/C,EAAG,CAAC,CAAM,CAAC,EAIX,EAAW,CACT,SAAU,GAAc,EACxB,aAAc,EACd,SAAU,EAAgB,EAAU,IAAA,EACtC,CAAC,EAED,GAAM,CAAE,WAAU,UAAW,EAAe,EAAS,CAAE,UAAW,GAAc,CAAU,CAAC,EAE3F,GAAI,CAAC,EAAY,OAAO,KAExB,IAAM,EAAiB,CAAC,GAAc,CAAC,CAAC,EAExC,OACE,EAAC,EAAD,CAAA,SACE,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,eAAgB,GAAY,SAAS,EAC1D,MAAO,CAAE,OAAQ,EAAgB,IAAK,EAAmB,GAAG,GAAY,SAAU,EAFpF,SAAA,CAIE,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,aAAc,GAAa,EAAO,kBAAmB,GAAY,QAAQ,EAC9F,MAAO,GAAY,SACnB,QAAS,CACV,CAAA,EACA,GACC,EAAC,MAAD,CACE,GAAI,EACJ,IAAK,EACL,KAAK,SACL,aAAW,OACX,kBAAiB,EAAiB,EAAU,IAAA,GAE5C,SAAU,GACV,UAAW,EACT,EAAO,MACP,GAAa,EAAO,WAGpB,GAAW,CAAC,EAAY,MAAO,EAAY,aAAc,EAAO,UAAU,EAC1E,EACA,GAAY,KACd,EACA,MAAO,CAAE,GAAI,EAAU,EAAa,IAAA,GAAY,GAAG,EAAO,GAAG,GAAY,KAAM,EAC/E,QAAU,GAAM,EAAE,gBAAgB,EAlBpC,SAAA,CAoBG,CAAC,GACA,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,YAAa,GAAY,MAAM,EAAG,MAAO,GAAY,OAA/E,SAAA,CACE,EAAC,MAAD,CAAK,GAAI,EAAS,UAAW,GAAY,MAAO,MAAO,GAAY,MAChE,SAAA,CACE,CAAA,EACL,EAAC,SAAD,CACE,KAAK,SACL,QAAS,EACT,aAAY,EAAK,MACjB,UAAW,EAAG,EAAO,iBAAkB,GAAY,WAAW,EAC9D,MAAO,GAAY,YAEnB,SAAA,EAAC,EAAD,CAAiB,KAAM,CAAY,CAAA,CAC7B,CAAA,CACL,IAEP,EAAC,MAAD,CACE,IAAK,EACL,UAAW,EACT,EAAO,UACP,EAAW,WACX,EAAW,YACX,GAAY,EAAW,qBACvB,GAAU,EAAW,mBACrB,GAAY,IACd,EACA,MAAO,GAAY,KAElB,UACE,CAAA,EACJ,GACC,EAAC,MAAD,CAAK,UAAW,EAAG,EAAO,YAAa,GAAY,MAAM,EAAG,MAAO,GAAY,OAC5E,SAAA,CACE,CAAA,CAEJ,CAEJ,CAAA,CAAA,CACE,CAAA,CAAA,CAAA,CAEb"}
@@ -1,2 +1,2 @@
1
- "use client";var e=`modal_L-Fkd`,t=`slideIn_RVIHR`,n=`fadeIn_XSuIE`,r=`modal-sheet_WkXR4`,i=`modal-container_qwKIm`,a=`modal-header_DhsRr`,o=`modal-body_Mmn0-`,s=`modal-close-button_UMZjq`,c=`modal-wrapper_r5wzq`,l=`modal-wrapper-shown_F0BgK`,u={modal:e,slideIn:t,fadeIn:n,"modal-sheet":`modal-sheet_WkXR4`,modalSheet:r,"modal-container":`modal-container_qwKIm`,modalContainer:i,"modal-header":`modal-header_DhsRr`,modalHeader:a,"modal-body":`modal-body_Mmn0-`,modalBody:o,"modal-close-button":`modal-close-button_UMZjq`,modalCloseButton:s,"modal-wrapper":`modal-wrapper_r5wzq`,modalWrapper:c,"modal-wrapper-shown":`modal-wrapper-shown_F0BgK`,modalWrapperShown:l};export{u as default,n as fadeIn,e as modal,o as modalBody,s as modalCloseButton,i as modalContainer,a as modalHeader,r as modalSheet,c as modalWrapper,l as modalWrapperShown,t as slideIn};
1
+ "use client";var e=`modal_L-Fkd`,t=`slideIn_RVIHR`,n=`fadeIn_XSuIE`,r=`modal-sheet_WkXR4`,i=`modal-container_qwKIm`,a=`modal-header_DhsRr`,o=`modal-body_Mmn0-`,s=`modal-footer_idArP`,c=`modal-close-button_UMZjq`,l=`modal-wrapper_r5wzq`,u=`modal-wrapper-shown_F0BgK`,d={modal:e,slideIn:t,fadeIn:n,"modal-sheet":`modal-sheet_WkXR4`,modalSheet:r,"modal-container":`modal-container_qwKIm`,modalContainer:i,"modal-header":`modal-header_DhsRr`,modalHeader:a,"modal-body":`modal-body_Mmn0-`,modalBody:o,"modal-footer":`modal-footer_idArP`,modalFooter:s,"modal-close-button":`modal-close-button_UMZjq`,modalCloseButton:c,"modal-wrapper":`modal-wrapper_r5wzq`,modalWrapper:l,"modal-wrapper-shown":`modal-wrapper-shown_F0BgK`,modalWrapperShown:u};export{d as default,n as fadeIn,e as modal,o as modalBody,c as modalCloseButton,i as modalContainer,s as modalFooter,a as modalHeader,r as modalSheet,l as modalWrapper,u as modalWrapperShown,t as slideIn};
2
2
  //# sourceMappingURL=modal.module.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"modal.module.mjs","names":[],"sources":["../../../../package/common/modal/modal.module.pcss"],"sourcesContent":[".modal {\n padding: 16px;\n border-radius: var(--default-border-radius);\n background: var(--background-modal);\n color: var(--text-color);\n font-family: var(--default-font);\n box-sizing: border-box;\n position: relative;\n display: flex;\n flex-direction: column;\n transform-origin: bottom center;\n animation:\n slideIn 0.2s,\n fadeIn 0.3s forwards;\n max-width: 95%;\n max-height: 95%;\n\n /* The panel itself never scrolls, so the header stays put; `&-body` is what scrolls. */\n overflow: hidden;\n\n @media (width <= 767px) {\n max-width: 100%;\n max-height: 100%;\n }\n\n /* A sheet-presented modal carries forms and detail views, not a short menu, so it takes more\n of the screen than the shared default — and keeps the panel's own 16px at the bottom edge. */\n &-sheet {\n --sheet-max-height: 90dvh;\n --sheet-safe-padding: 16px;\n }\n\n &-container {\n position: fixed;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n top: 0;\n left: 0;\n }\n\n &-header {\n display: flex;\n gap: 8px;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n flex: 0 0 auto;\n\n div {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n }\n\n &-body {\n /* `min-height: 0` lets this shrink below its content's height so it, not the panel, scrolls. */\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n margin: -0.6em;\n padding: 0.6em;\n }\n\n &-close-button {\n flex-shrink: 0;\n background: none;\n border: none;\n padding: 0;\n color: inherit;\n font-size: inherit;\n line-height: 1;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n\n &-wrapper {\n position: fixed;\n width: 100%;\n height: 100%;\n background: #00000052;\n top: 0;\n left: 0;\n transition: all 0.3s ease-in-out;\n opacity: 0;\n\n &-shown {\n opacity: 1;\n }\n }\n}\n\n@keyframes slideIn {\n from {\n transform: scale(0);\n }\n\n to {\n transform: scale(0.99);\n }\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n\n to {\n opacity: 1;\n }\n}\n\n/* Only the scale-in goes; the backdrop and the panel still fade, which is not motion.\n `slideIn` ends at scale(0.99) and the panel has no transform of its own, so dropping the\n animation lands it at scale(1) rather than leaving it collapsed. */\n@media (prefers-reduced-motion: reduce) {\n .modal {\n animation: fadeIn 0.3s forwards;\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"modal.module.mjs","names":[],"sources":["../../../../package/common/modal/modal.module.pcss"],"sourcesContent":[".modal {\n /* Theme tokens resolved once, each with a built-in fallback. Set any of the public\n `--modal-*` variables via ThemeProvider (theme-wide) or `style` (per instance) to\n override; unset ones fall back to the values below. */\n --custom-modal-padding: var(--modal-padding, var(--spacing-l));\n --custom-modal-gap: var(--modal-gap, var(--spacing-l));\n\n /* Half the gap, so the scroll port's clipping edge — where the divider sits — lands midway\n between the chrome and where the content rests, with the same room either side. Flush\n against the chrome (bleed = gap) reads as a sliced line of text colliding with the title;\n an unrelated value (this was `0.6em`) puts it at a distance that drifts with the font size. */\n --custom-modal-body-bleed: var(--modal-body-bleed, calc(var(--custom-modal-gap) / 2));\n\n /* The panel never comes closer to the screen edge than its own padding, at every size. A\n percentage instead reads as a different inset on every screen, and pairing one with a\n breakpoint made the two axes disagree: 5% of a 390px width is 19.5px but 5% of a 780px\n height is 39px, so the same rule came out narrower and taller than the default on one phone. */\n --custom-modal-max-width: var(--modal-max-width, calc(100% - 2 * var(--custom-modal-padding)));\n --custom-modal-max-height: var(--modal-max-height, calc(100% - 2 * var(--custom-modal-padding)));\n\n padding: var(--custom-modal-padding);\n border-radius: var(--default-border-radius);\n background: var(--background-modal);\n color: var(--text-color);\n font-family: var(--default-font);\n box-sizing: border-box;\n position: relative;\n display: flex;\n flex-direction: column;\n transform-origin: bottom center;\n animation:\n slideIn 0.2s,\n fadeIn 0.3s forwards;\n max-width: var(--custom-modal-max-width);\n max-height: var(--custom-modal-max-height);\n\n /* The panel itself never scrolls, so the header stays put; `&-body` is what scrolls. */\n overflow: hidden;\n\n /* A sheet-presented modal carries forms and detail views, not a short menu, so it takes more\n of the screen than the shared default — and keeps the panel's own padding at the bottom edge. */\n &-sheet {\n --sheet-max-height: 90dvh;\n --sheet-safe-padding: var(--custom-modal-padding);\n }\n\n &-container {\n position: fixed;\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n top: 0;\n left: 0;\n }\n\n &-header {\n display: flex;\n gap: var(--spacing-m);\n justify-content: space-between;\n align-items: center;\n margin-bottom: var(--custom-modal-gap);\n flex: 0 0 auto;\n\n div {\n overflow: hidden;\n text-overflow: ellipsis;\n }\n }\n\n &-body {\n /* `min-height: 0` lets this shrink below its content's height so it, not the panel, scrolls. */\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n\n /* A negative margin cancelled by an equal padding, so a focus ring or a floating label at\n the body's edge isn't clipped by the scroll container. Override the pair with\n `--modal-body-bleed`, never with a plain `padding`, which drops the negative half and\n brings the clipping back. See `docs/Modal.md` for what the two do together. */\n margin: calc(-1 * var(--custom-modal-body-bleed));\n padding: var(--custom-modal-body-bleed);\n\n /* The mask lives in `styles/scrollFade.module.pcss`; the component applies it along with the\n modifiers saying which end genuinely hides content. The run has to clear the port's own\n padding before any content fades at all, hence gap + bleed. Set here as the shared sheet's\n private length rather than as `--scroll-fade-length`, which would inherit down into a\n `ScrollFade` nested in the body. */\n --custom-scroll-fade-length: var(\n --modal-scroll-fade,\n calc(var(--custom-modal-gap) + var(--custom-modal-body-bleed))\n );\n }\n\n &-footer {\n margin-top: var(--custom-modal-gap);\n flex: 0 0 auto;\n }\n\n &-close-button {\n flex-shrink: 0;\n background: none;\n border: none;\n padding: 0;\n color: inherit;\n font-size: inherit;\n line-height: 1;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n\n &-wrapper {\n position: fixed;\n width: 100%;\n height: 100%;\n background: #00000052;\n top: 0;\n left: 0;\n transition: all 0.3s ease-in-out;\n opacity: 0;\n\n &-shown {\n opacity: 1;\n }\n }\n}\n\n@keyframes slideIn {\n from {\n transform: scale(0);\n }\n\n to {\n transform: scale(0.99);\n }\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n\n to {\n opacity: 1;\n }\n}\n\n/* Only the scale-in goes; the backdrop and the panel still fade, which is not motion.\n `slideIn` ends at scale(0.99) and the panel has no transform of its own, so dropping the\n animation lands it at scale(1) rather than leaving it collapsed. */\n@media (prefers-reduced-motion: reduce) {\n .modal {\n animation: fadeIn 0.3s forwards;\n }\n}\n"],"mappings":""}
@@ -1,2 +1,2 @@
1
- "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{PopoverAlign as n,PopoverPlacement as r,PopoverTrigger as ee}from"../popover/popover.types.mjs";import te from"../popover/popover.mjs";import ne from"../chip/chip.mjs";import re from"../tooltip/tooltip.mjs";import ie from"../searchInput/searchInput.mjs";import i from"./multiSelect.module.mjs";import{useEffect as a,useId as ae,useRef as o,useState as s}from"react";import c from"classnames";import{FontAwesomeIcon as l}from"@fortawesome/react-fontawesome";import{faCheck as oe,faChevronDown as se,faXmark as ce}from"@fortawesome/free-solid-svg-icons";import{jsx as u,jsxs as d}from"react/jsx-runtime";var le=[],ue={clearSelection:`Clear selection`,create:e=>`Add "${e}"`,searchPlaceholder:`Search…`,empty:`No matches`};function f(f){let{items:p,value:m,defaultValue:de=[],onChange:fe=()=>{},label:h=``,alwaysFloatLabel:pe=!1,placeholder:g=``,searchable:me=!1,allowCustomValues:_=!1,maxSelected:v,clearable:he=!0,disabled:y=!1,readOnly:b=!1,presentation:ge,formValidator:x=null,errorMessage:_e=``,isValid:ve=!0,className:ye,style:be,classNames:S,styles:C,onMouseEnter:xe,onMouseLeave:Se,onFocus:Ce,onBlur:we,labels:Te,...Ee}=e(`MultiSelect`,f),w=t(`MultiSelect`,Te,ue),T=o(null),E=o(null),D=o(null),O=ae(),[De,Oe]=s(de),[k,ke]=s(!1),[A,j]=s(``),[M,N]=s(0),[P,F]=s(!1),[Ae,I]=s(!1),[L,je]=s(),R=o(x),[,Me]=s(0);a(()=>{R.current=x;let e=R.current;if(!e)return;e.label=h,e.validate();let t=()=>Me(e=>e+1);return e.registerOnUpdateListener(t),()=>{e.removeOnUpdateListener(t)}},[x,h]);let z=m!==void 0&&!x,B=x?x.value:z?m:De,V=Array.isArray(B)?B:le,H=x?x.touched&&x.hasError():!ve||!!_e,Ne=x?x.getCurrentErrorMessage():_e||``,U=!y&&!b,W=v!==void 0&&V.length>=v,G=pe||k||P||V.length>0,K=me||_,q=A.trim(),J=K?q.toLowerCase():``,Pe=J?p.filter(e=>e.label.toLowerCase().includes(J)):p,Fe=_&&q.length>0&&!W&&!p.some(e=>e.label.toLowerCase()===J||String(e.key).toLowerCase()===J)&&!V.some(e=>String(e).toLowerCase()===J),Y=Fe?[...Pe,{key:q,label:w.create(q)}]:Pe,Ie=V.map(e=>p.find(t=>t.key===e)??(_?{key:e,label:String(e)}:void 0)).filter(e=>e!==void 0);function X(e){x?x.set(e):z||Oe(e),fe(e)}function Z(e){U&&!e.disabled&&(V.includes(e.key)?X(V.filter(t=>t!==e.key)):W||X([...V,e.key]),Fe&&e.key===q&&j(``))}function Le(){T.current?.contains(document.activeElement)&&E.current?.focus()}function Q(e){(!e||U)&&(ke(e),e?(je(E.current?.offsetWidth),N(0)):(j(``),R.current&&(R.current.touched=!0)))}a(()=>{k&&K&&D.current?.querySelector(`input`)?.focus()},[k,K]);function $(e){if(U){if(!k){e.key===`ArrowDown`||e.key===`Enter`||e.key===` `?(e.preventDefault(),Q(!0)):e.key===`Backspace`&&V.length>0&&X(V.slice(0,-1));return}if(e.key===`ArrowDown`||e.key===`ArrowUp`){if(e.preventDefault(),Y.length===0)return;let t=e.key===`ArrowDown`?1:-1;N(e=>(e+t+Y.length)%Y.length)}else if(e.key===`Home`||e.key===`End`)e.preventDefault(),N(e.key===`Home`?0:Y.length-1);else if(e.key===`Enter`){e.preventDefault();let t=Y[M];t&&Z(t)}else e.key===`Backspace`&&!A&&V.length>0&&X(V.slice(0,-1))}}let Re=d(`div`,{className:c(i.multiSelectPanel,S?.panel),style:C?.panel,children:[K&&u(`div`,{ref:D,className:c(i.multiSelectSearch,S?.search),style:C?.search,children:u(ie,{value:A,onChange:e=>{j(e),N(0)},placeholder:w.searchPlaceholder,onKeyDown:$})}),u(`div`,{id:O,role:`listbox`,"aria-multiselectable":`true`,"aria-label":h||void 0,className:c(i.multiSelectOptions,S?.options),style:C?.options,children:Y.length===0?u(`div`,{className:c(i.multiSelectEmpty,S?.empty),style:C?.empty,children:w.empty}):Y.map((e,t)=>{let n=V.includes(e.key),r=e.disabled||W&&!n;return d(`div`,{id:`${O}-${t}`,role:`option`,"aria-selected":n,"aria-disabled":r||void 0,className:c(i.multiSelectOption,t===M&&i.multiSelectOptionActive,n&&i.multiSelectOptionSelected,r&&i.multiSelectOptionDisabled,S?.option),style:C?.option,onMouseDown:e=>e.preventDefault(),onMouseEnter:()=>N(t),onClick:()=>Z(e),children:[u(`span`,{className:c(i.multiSelectOptionCheck,S?.optionCheck),style:C?.optionCheck,children:n&&u(l,{icon:oe})}),u(`span`,{className:c(i.multiSelectOptionLabel,S?.optionLabel),style:C?.optionLabel,children:e.label})]},e.key)})})]});return d(`div`,{...Ee,ref:T,className:c(i.multiSelect,y&&i.multiSelectDisabled,S?.root,ye),style:{...be,...C?.root},onMouseEnter:e=>{I(!0),xe?.(e)},onMouseLeave:e=>{I(!1),Se?.(e)},onFocus:e=>{F(!0),Ce?.(e)},onBlur:e=>{e.currentTarget.contains(e.relatedTarget)||(F(!1),we?.(e))},children:[u(te,{isOpen:k,onOpenChange:Q,trigger:ee.Click,placement:r.Bottom,align:n.Start,offset:4,withArrow:!1,focusOnOpen:K,constrainWidth:!1,width:`trigger`,disabled:!U,presentation:ge,content:Re,styles:{panel:L?{minWidth:L}:void 0},children:d(`div`,{ref:E,role:`combobox`,tabIndex:y?-1:0,"aria-expanded":k,"aria-haspopup":`listbox`,"aria-controls":O,"aria-activedescendant":k&&Y.length>0?`${O}-${M}`:void 0,"aria-disabled":y||void 0,"aria-readonly":b||void 0,className:c(i.multiSelectControl,S?.control),style:C?.control,onKeyDown:$,children:[g&&Ie.length===0&&u(`span`,{className:c(i.multiSelectPlaceholder,(!h||G)&&i.multiSelectPlaceholderShown,!h&&i.multiSelectPlaceholderInstant,S?.placeholder),style:C?.placeholder,children:g}),u(`div`,{className:c(i.multiSelectValues,S?.values),style:C?.values,children:Ie.map(e=>u(ne,{text:e.label,showRemoveIcon:U,labels:{remove:`Remove ${e.label}`},onMouseDown:e=>e.preventDefault(),onRemove:()=>{Z(e),Le()},className:c(i.multiSelectChip,S?.chip),style:C?.chip},e.key))}),he&&U&&V.length>0&&u(`button`,{type:`button`,tabIndex:-1,"aria-label":w.clearSelection,className:c(i.multiSelectClearButton,S?.clearButton),style:C?.clearButton,onMouseDown:e=>e.preventDefault(),onClick:e=>{e.stopPropagation(),X([]),Le()},children:u(l,{icon:ce})}),u(l,{icon:se,className:c(i.multiSelectIcon,k&&i.multiSelectIconOpen,S?.icon),style:C?.icon}),h&&u(`div`,{className:c(i.multiSelectLabel,G&&i.multiSelectLabelFloating,S?.label),style:C?.label,children:h}),u(`fieldset`,{className:c(i.multiSelectFieldset,!h&&i.multiSelectFieldsetNoNotch,(P||k)&&i.multiSelectFieldsetFocused,H&&i.multiSelectFieldsetError,S?.fieldset),style:C?.fieldset,children:u(`legend`,{className:c(i.multiSelectFieldsetLegend,G&&i.multiSelectFieldsetLegendActive),children:u(`span`,{children:h})})})]})}),u(re,{variant:`error`,message:Ne,isVisible:H&&(P||Ae)})]})}export{f as default};
1
+ "use client";import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{useLabels as t}from"../configProvider/useLabels.mjs";import{PopoverAlign as n,PopoverPlacement as r,PopoverTrigger as ee}from"../popover/popover.types.mjs";import te from"../popover/popover.mjs";import ne from"../chip/chip.mjs";import re from"../tooltip/tooltip.mjs";import{edgeIndex as ie,nextIndex as ae,scrollOptionIntoView as oe}from"../utils/listNavigation.mjs";import se from"../searchInput/searchInput.mjs";import i from"./multiSelect.module.mjs";import{useEffect as a,useId as ce,useRef as o,useState as s}from"react";import c from"classnames";import{FontAwesomeIcon as l}from"@fortawesome/react-fontawesome";import{faCheck as le,faChevronDown as ue,faXmark as de}from"@fortawesome/free-solid-svg-icons";import{jsx as u,jsxs as d}from"react/jsx-runtime";var fe=[],pe={clearSelection:`Clear selection`,create:e=>`Add "${e}"`,searchPlaceholder:`Search…`,empty:`No matches`};function f(f){let{items:p,value:m,defaultValue:me=[],onChange:he=()=>{},label:h=``,alwaysFloatLabel:ge=!1,placeholder:g=``,searchable:_e=!1,allowCustomValues:_=!1,maxSelected:v,clearable:ve=!0,disabled:y=!1,readOnly:b=!1,presentation:ye,formValidator:x=null,errorMessage:S=``,isValid:be=!0,className:xe,style:Se,classNames:C,styles:w,onMouseEnter:Ce,onMouseLeave:we,onFocus:Te,onBlur:Ee,labels:De,...Oe}=e(`MultiSelect`,f),T=t(`MultiSelect`,De,pe),E=o(null),D=o(null),O=o(null),k=o(null),A=ce(),[ke,Ae]=s(me),[j,je]=s(!1),[M,N]=s(``),[P,F]=s(0),[I,L]=s(!1),[Me,Ne]=s(!1),[Pe,Fe]=s(),R=o(x),[,Ie]=s(0);a(()=>{R.current=x;let e=R.current;if(!e)return;e.label=h,e.validate();let t=()=>Ie(e=>e+1);return e.registerOnUpdateListener(t),()=>{e.removeOnUpdateListener(t)}},[x,h]);let z=m!==void 0&&!x,B=x?x.value:z?m:ke,V=Array.isArray(B)?B:fe,H=x?x.touched&&x.hasError():!be||!!S,Le=x?x.getCurrentErrorMessage():S||``,U=!y&&!b,W=v!==void 0&&V.length>=v,G=ge||j||I||V.length>0,K=_e||_,q=M.trim(),J=K?q.toLowerCase():``,Y=J?p.filter(e=>e.label.toLowerCase().includes(J)):p,X=_&&q.length>0&&!W&&!p.some(e=>e.label.toLowerCase()===J||String(e.key).toLowerCase()===J)&&!V.some(e=>String(e).toLowerCase()===J),Z=X?[...Y,{key:q,label:T.create(q)}]:Y,Re=V.map(e=>p.find(t=>t.key===e)??(_?{key:e,label:String(e)}:void 0)).filter(e=>e!==void 0);function Q(e){x?x.set(e):z||Ae(e),he(e)}function $(e){U&&!e.disabled&&(V.includes(e.key)?Q(V.filter(t=>t!==e.key)):W||Q([...V,e.key]),X&&e.key===q&&N(``))}function ze(){E.current?.contains(document.activeElement)&&D.current?.focus()}function Be(e){(!e||U)&&(je(e),e?(Fe(D.current?.offsetWidth),F(0)):(N(``),R.current&&(R.current.touched=!0)))}a(()=>{j&&K&&O.current?.querySelector(`input`)?.focus()},[j,K]),a(()=>{j&&oe(k.current,document.getElementById(`${A}-${P}`))},[j,P,A]);let Ve={isDisabled:e=>{let t=Z[e];return!!t.disabled||W&&!V.includes(t.key)}};function He(e){if(U){if(!j){e.key===`ArrowDown`||e.key===`Enter`||e.key===` `?(e.preventDefault(),Be(!0)):e.key===`Backspace`&&V.length>0&&Q(V.slice(0,-1));return}if(e.key===`ArrowDown`||e.key===`ArrowUp`)e.preventDefault(),F(ae(P,e.key===`ArrowDown`?1:-1,Z.length,Ve)??0);else if(e.key===`Home`||e.key===`End`)e.preventDefault(),F(ie(e.key===`Home`?`first`:`last`,Z.length,Ve)??0);else if(e.key===`Enter`){e.preventDefault();let t=Z[P];t&&$(t)}else e.key===`Backspace`&&!M&&V.length>0&&Q(V.slice(0,-1))}}let Ue=d(`div`,{className:c(i.multiSelectPanel,C?.panel),style:w?.panel,children:[K&&u(`div`,{ref:O,className:c(i.multiSelectSearch,C?.search),style:w?.search,children:u(se,{value:M,onChange:e=>{N(e),F(0)},placeholder:T.searchPlaceholder,onKeyDown:He})}),u(`div`,{ref:k,id:A,role:`listbox`,"aria-multiselectable":`true`,"aria-label":h||void 0,className:c(i.multiSelectOptions,C?.options),style:w?.options,children:Z.length===0?u(`div`,{className:c(i.multiSelectEmpty,C?.empty),style:w?.empty,children:T.empty}):Z.map((e,t)=>{let n=V.includes(e.key),r=e.disabled||W&&!n;return d(`div`,{id:`${A}-${t}`,role:`option`,"aria-selected":n,"aria-disabled":r||void 0,className:c(i.multiSelectOption,t===P&&i.multiSelectOptionActive,n&&i.multiSelectOptionSelected,r&&i.multiSelectOptionDisabled,C?.option),style:w?.option,onMouseDown:e=>e.preventDefault(),onMouseEnter:()=>F(t),onClick:()=>$(e),children:[u(`span`,{className:c(i.multiSelectOptionCheck,C?.optionCheck),style:w?.optionCheck,children:n&&u(l,{icon:le})}),u(`span`,{className:c(i.multiSelectOptionLabel,C?.optionLabel),style:w?.optionLabel,children:e.label})]},e.key)})})]});return d(`div`,{...Oe,ref:E,className:c(i.multiSelect,y&&i.multiSelectDisabled,C?.root,xe),style:{...Se,...w?.root},onMouseEnter:e=>{Ne(!0),Ce?.(e)},onMouseLeave:e=>{Ne(!1),we?.(e)},onFocus:e=>{L(!0),Te?.(e)},onBlur:e=>{e.currentTarget.contains(e.relatedTarget)||(L(!1),Ee?.(e))},children:[u(te,{isOpen:j,onOpenChange:Be,trigger:ee.Click,placement:r.Bottom,align:n.Start,offset:4,withArrow:!1,focusOnOpen:K,constrainWidth:!1,width:`trigger`,disabled:!U,presentation:ye,content:Ue,styles:{panel:Pe?{minWidth:Pe}:void 0},children:d(`div`,{ref:D,role:`combobox`,tabIndex:y?-1:0,"aria-expanded":j,"aria-haspopup":`listbox`,"aria-controls":A,"aria-activedescendant":j&&Z.length>0?`${A}-${P}`:void 0,"aria-disabled":y||void 0,"aria-readonly":b||void 0,className:c(i.multiSelectControl,C?.control),style:w?.control,onKeyDown:He,children:[g&&Re.length===0&&u(`span`,{className:c(i.multiSelectPlaceholder,(!h||G)&&i.multiSelectPlaceholderShown,!h&&i.multiSelectPlaceholderInstant,C?.placeholder),style:w?.placeholder,children:g}),u(`div`,{className:c(i.multiSelectValues,C?.values),style:w?.values,children:Re.map(e=>u(ne,{text:e.label,showRemoveIcon:U,labels:{remove:`Remove ${e.label}`},onMouseDown:e=>e.preventDefault(),onRemove:()=>{$(e),ze()},className:c(i.multiSelectChip,C?.chip),style:w?.chip},e.key))}),ve&&U&&V.length>0&&u(`button`,{type:`button`,tabIndex:-1,"aria-label":T.clearSelection,className:c(i.multiSelectClearButton,C?.clearButton),style:w?.clearButton,onMouseDown:e=>e.preventDefault(),onClick:e=>{e.stopPropagation(),Q([]),ze()},children:u(l,{icon:de})}),u(l,{icon:ue,className:c(i.multiSelectIcon,j&&i.multiSelectIconOpen,C?.icon),style:w?.icon}),h&&u(`div`,{className:c(i.multiSelectLabel,G&&i.multiSelectLabelFloating,C?.label),style:w?.label,children:h}),u(`fieldset`,{className:c(i.multiSelectFieldset,!h&&i.multiSelectFieldsetNoNotch,(I||j)&&i.multiSelectFieldsetFocused,H&&i.multiSelectFieldsetError,C?.fieldset),style:w?.fieldset,children:u(`legend`,{className:c(i.multiSelectFieldsetLegend,G&&i.multiSelectFieldsetLegendActive),children:u(`span`,{children:h})})})]})}),u(re,{variant:`error`,message:Le,isVisible:H&&(I||Me)})]})}export{f as default};
2
2
  //# sourceMappingURL=multiSelect.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"multiSelect.mjs","names":[],"sources":["../../../../package/common/multiSelect/multiSelect.tsx"],"sourcesContent":["import { useEffect, useId, useRef, useState } from 'react';\nimport type { ReactElement } from 'react';\nimport cx from 'classnames';\nimport { faChevronDown, faCheck, faXmark } from '@fortawesome/free-solid-svg-icons';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\n\nimport Chip from 'components/common/chip';\nimport SearchInput from 'components/common/searchInput';\nimport Tooltip from 'components/common/tooltip';\nimport Popover from 'components/common/popover';\nimport { PopoverAlign, PopoverPlacement, PopoverTrigger } from '../popover/popover.types';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport type { MultiSelectItem, MultiSelectLabels, MultiSelectProps, MultiSelectValue } from './multiSelect.types';\n\nimport styles from './multiSelect.module.pcss';\n\nconst EMPTY: MultiSelectValue[] = [];\n\nconst DEFAULT_LABELS: Required<MultiSelectLabels> = {\n clearSelection: 'Clear selection',\n create: (value) => `Add \"${value}\"`,\n searchPlaceholder: 'Search…',\n empty: 'No matches',\n};\n\nfunction MultiSelect(props: MultiSelectProps): ReactElement {\n const {\n items,\n value,\n defaultValue = [],\n onChange = () => {},\n label = '',\n alwaysFloatLabel = false,\n placeholder = '',\n searchable = false,\n allowCustomValues = false,\n maxSelected,\n clearable = true,\n disabled = false,\n readOnly = false,\n presentation,\n formValidator = null,\n errorMessage = '',\n isValid = true,\n className,\n style,\n classNames,\n styles: slotStyles,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n labels,\n ...rest\n } = useComponentDefaults('MultiSelect', props);\n const text = useLabels('MultiSelect', labels, DEFAULT_LABELS);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const controlRef = useRef<HTMLDivElement>(null);\n const searchRef = useRef<HTMLDivElement>(null);\n const listboxId = useId();\n\n const [internalValue, setInternalValue] = useState<MultiSelectValue[]>(defaultValue);\n const [isOpen, setIsOpen] = useState(false);\n const [search, setSearch] = useState('');\n const [activeIndex, setActiveIndex] = useState(0);\n const [isFocused, setIsFocused] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [panelWidth, setPanelWidth] = useState<number>();\n\n // A ref as well as the prop: react-hooks/immutability refuses a mutation of the prop itself in\n // an event handler, and marking the validator touched happens in one.\n const fvRef = useRef(formValidator);\n const [, forceUpdate] = useState(0);\n useEffect(() => {\n fvRef.current = formValidator;\n const fv = fvRef.current;\n if (!fv) return;\n fv.label = label;\n fv.validate();\n const listener = () => forceUpdate((n) => n + 1);\n fv.registerOnUpdateListener(listener);\n return () => {\n fv.removeOnUpdateListener(listener);\n };\n }, [formValidator, label]);\n\n const isControlled = value !== undefined && !formValidator;\n const rawValue = formValidator ? formValidator.value : isControlled ? value : internalValue;\n const selected = Array.isArray(rawValue) ? (rawValue as MultiSelectValue[]) : EMPTY;\n\n const hasError = formValidator ? formValidator.touched && formValidator.hasError() : !isValid || !!errorMessage;\n const errorText = formValidator ? formValidator.getCurrentErrorMessage() : errorMessage || '';\n\n const isInteractive = !disabled && !readOnly;\n const atMax = maxSelected !== undefined && selected.length >= maxSelected;\n\n const shouldFloatLabel = alwaysFloatLabel || isOpen || isFocused || selected.length > 0;\n\n const isSearchable = searchable || allowCustomValues;\n const typed = search.trim();\n const needle = isSearchable ? typed.toLowerCase() : '';\n const matches = needle ? items.filter((item) => item.label.toLowerCase().includes(needle)) : items;\n\n const canCreate =\n allowCustomValues &&\n typed.length > 0 &&\n !atMax &&\n !items.some((item) => item.label.toLowerCase() === needle || String(item.key).toLowerCase() === needle) &&\n !selected.some((key) => String(key).toLowerCase() === needle);\n\n const visibleItems: MultiSelectItem[] = canCreate ? [...matches, { key: typed, label: text.create(typed) }] : matches;\n\n // Mapped from `selected`, not filtered from `items`, to keep the chips in pick order. A custom\n // value has no entry in `items`, so it stands in for itself.\n const selectedItems = selected\n .map<MultiSelectItem | undefined>(\n (key) => items.find((item) => item.key === key) ?? (allowCustomValues ? { key, label: String(key) } : undefined),\n )\n .filter((item): item is MultiSelectItem => item !== undefined);\n\n function commit(next: MultiSelectValue[]) {\n if (formValidator) formValidator.set(next);\n else if (!isControlled) setInternalValue(next);\n onChange(next);\n }\n\n function toggle(item: MultiSelectItem) {\n if (!isInteractive || item.disabled) return;\n if (selected.includes(item.key)) commit(selected.filter((key) => key !== item.key));\n else if (!atMax) commit([...selected, item.key]);\n // The typed text has become a chip, so leaving it in the box would offer to add it again.\n if (canCreate && item.key === typed) setSearch('');\n }\n\n /**\n * A focused element that unmounts fires no blur, so removing the chip or clear button that was\n * just clicked would leave `isFocused` stuck true. Hand focus back so there is still something\n * left to blur.\n */\n function keepFocusInControl() {\n if (rootRef.current?.contains(document.activeElement)) controlRef.current?.focus();\n }\n\n function handleOpenChange(next: boolean) {\n if (next && !isInteractive) return;\n setIsOpen(next);\n if (next) {\n setPanelWidth(controlRef.current?.offsetWidth);\n setActiveIndex(0);\n } else {\n setSearch('');\n if (fvRef.current) fvRef.current.touched = true;\n }\n }\n\n useEffect(() => {\n if (!isOpen || !isSearchable) return;\n searchRef.current?.querySelector('input')?.focus();\n }, [isOpen, isSearchable]);\n\n function handleKeyDown(event: React.KeyboardEvent) {\n if (!isInteractive) return;\n\n if (!isOpen) {\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n handleOpenChange(true);\n } else if (event.key === 'Backspace' && selected.length > 0) {\n commit(selected.slice(0, -1));\n }\n return;\n }\n\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n if (visibleItems.length === 0) return;\n const step = event.key === 'ArrowDown' ? 1 : -1;\n setActiveIndex((current) => (current + step + visibleItems.length) % visibleItems.length);\n } else if (event.key === 'Home' || event.key === 'End') {\n event.preventDefault();\n setActiveIndex(event.key === 'Home' ? 0 : visibleItems.length - 1);\n } else if (event.key === 'Enter') {\n event.preventDefault();\n const item = visibleItems[activeIndex];\n if (item) toggle(item);\n } else if (event.key === 'Backspace' && !search && selected.length > 0) {\n commit(selected.slice(0, -1));\n }\n }\n\n const panel = (\n <div className={cx(styles.multiSelectPanel, classNames?.panel)} style={slotStyles?.panel}>\n {isSearchable && (\n <div ref={searchRef} className={cx(styles.multiSelectSearch, classNames?.search)} style={slotStyles?.search}>\n <SearchInput\n value={search}\n onChange={(value) => {\n setSearch(value);\n setActiveIndex(0);\n }}\n placeholder={text.searchPlaceholder}\n onKeyDown={handleKeyDown}\n />\n </div>\n )}\n <div\n id={listboxId}\n role='listbox'\n aria-multiselectable='true'\n aria-label={label || undefined}\n className={cx(styles.multiSelectOptions, classNames?.options)}\n style={slotStyles?.options}\n >\n {visibleItems.length === 0 ? (\n <div className={cx(styles.multiSelectEmpty, classNames?.empty)} style={slotStyles?.empty}>\n {text.empty}\n </div>\n ) : (\n visibleItems.map((item, index) => {\n const isSelected = selected.includes(item.key);\n const isDisabled = item.disabled || (atMax && !isSelected);\n\n return (\n <div\n key={item.key}\n id={`${listboxId}-${index}`}\n role='option'\n aria-selected={isSelected}\n aria-disabled={isDisabled || undefined}\n className={cx(\n styles.multiSelectOption,\n index === activeIndex && styles.multiSelectOptionActive,\n isSelected && styles.multiSelectOptionSelected,\n isDisabled && styles.multiSelectOptionDisabled,\n classNames?.option,\n )}\n style={slotStyles?.option}\n onMouseDown={(event) => event.preventDefault()}\n onMouseEnter={() => setActiveIndex(index)}\n onClick={() => toggle(item)}\n >\n <span\n className={cx(styles.multiSelectOptionCheck, classNames?.optionCheck)}\n style={slotStyles?.optionCheck}\n >\n {isSelected && <FontAwesomeIcon icon={faCheck} />}\n </span>\n <span\n className={cx(styles.multiSelectOptionLabel, classNames?.optionLabel)}\n style={slotStyles?.optionLabel}\n >\n {item.label}\n </span>\n </div>\n );\n })\n )}\n </div>\n </div>\n );\n\n return (\n <div\n {...rest}\n ref={rootRef}\n className={cx(styles.multiSelect, disabled && styles.multiSelectDisabled, classNames?.root, className)}\n style={{ ...style, ...slotStyles?.root }}\n onMouseEnter={(event) => {\n setIsHovered(true);\n onMouseEnter?.(event);\n }}\n onMouseLeave={(event) => {\n setIsHovered(false);\n onMouseLeave?.(event);\n }}\n onFocus={(event) => {\n setIsFocused(true);\n onFocus?.(event);\n }}\n onBlur={(event) => {\n if (event.currentTarget.contains(event.relatedTarget as Node | null)) return;\n setIsFocused(false);\n onBlur?.(event);\n }}\n >\n <Popover\n isOpen={isOpen}\n onOpenChange={handleOpenChange}\n trigger={PopoverTrigger.Click}\n placement={PopoverPlacement.Bottom}\n align={PopoverAlign.Start}\n offset={4}\n withArrow={false}\n // Neither half of this is the keyboard-only default. A search field takes\n // the caret however the panel was opened, and without one the control\n // keeps the focus and points at the active option with\n // `aria-activedescendant`, so nothing may take it away.\n focusOnOpen={isSearchable}\n constrainWidth={false}\n width='trigger'\n disabled={!isInteractive}\n presentation={presentation}\n content={panel}\n styles={{ panel: panelWidth ? { minWidth: panelWidth } : undefined }}\n >\n <div\n ref={controlRef}\n role='combobox'\n tabIndex={disabled ? -1 : 0}\n aria-expanded={isOpen}\n aria-haspopup='listbox'\n aria-controls={listboxId}\n aria-activedescendant={isOpen && visibleItems.length > 0 ? `${listboxId}-${activeIndex}` : undefined}\n aria-disabled={disabled || undefined}\n aria-readonly={readOnly || undefined}\n className={cx(styles.multiSelectControl, classNames?.control)}\n style={slotStyles?.control}\n onKeyDown={handleKeyDown}\n >\n {placeholder && selectedItems.length === 0 && (\n <span\n className={cx(\n styles.multiSelectPlaceholder,\n (!label || shouldFloatLabel) && styles.multiSelectPlaceholderShown,\n !label && styles.multiSelectPlaceholderInstant,\n classNames?.placeholder,\n )}\n style={slotStyles?.placeholder}\n >\n {placeholder}\n </span>\n )}\n\n <div className={cx(styles.multiSelectValues, classNames?.values)} style={slotStyles?.values}>\n {selectedItems.map((item) => (\n <Chip\n key={item.key}\n text={item.label}\n showRemoveIcon={isInteractive}\n labels={{ remove: `Remove ${item.label}` }}\n onMouseDown={(event) => event.preventDefault()}\n onRemove={() => {\n toggle(item);\n keepFocusInControl();\n }}\n className={cx(styles.multiSelectChip, classNames?.chip)}\n style={slotStyles?.chip}\n />\n ))}\n </div>\n\n {clearable && isInteractive && selected.length > 0 && (\n <button\n type='button'\n tabIndex={-1}\n aria-label={text.clearSelection}\n className={cx(styles.multiSelectClearButton, classNames?.clearButton)}\n style={slotStyles?.clearButton}\n onMouseDown={(event) => event.preventDefault()}\n onClick={(event) => {\n event.stopPropagation();\n commit([]);\n keepFocusInControl();\n }}\n >\n <FontAwesomeIcon icon={faXmark} />\n </button>\n )}\n\n <FontAwesomeIcon\n icon={faChevronDown}\n className={cx(styles.multiSelectIcon, isOpen && styles.multiSelectIconOpen, classNames?.icon)}\n style={slotStyles?.icon as React.CSSProperties & Record<`--fa-font-${string}`, string>}\n />\n\n {label && (\n <div\n className={cx(\n styles.multiSelectLabel,\n shouldFloatLabel && styles.multiSelectLabelFloating,\n classNames?.label,\n )}\n style={slotStyles?.label}\n >\n {label}\n </div>\n )}\n\n {/* The visible border lives here rather than on the control, because the legend is what\n cuts the notch the floating label sits in. Same construction as Input. */}\n <fieldset\n className={cx(\n styles.multiSelectFieldset,\n !label && styles.multiSelectFieldsetNoNotch,\n (isFocused || isOpen) && styles.multiSelectFieldsetFocused,\n hasError && styles.multiSelectFieldsetError,\n classNames?.fieldset,\n )}\n style={slotStyles?.fieldset}\n >\n <legend\n className={cx(\n styles.multiSelectFieldsetLegend,\n shouldFloatLabel && styles.multiSelectFieldsetLegendActive,\n )}\n >\n <span>{label}</span>\n </legend>\n </fieldset>\n </div>\n </Popover>\n\n <Tooltip variant='error' message={errorText} isVisible={hasError && (isFocused || isHovered)} />\n </div>\n );\n}\n\nexport default MultiSelect;\n"],"mappings":"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"}
1
+ {"version":3,"file":"multiSelect.mjs","names":[],"sources":["../../../../package/common/multiSelect/multiSelect.tsx"],"sourcesContent":["import { useEffect, useId, useRef, useState } from 'react';\nimport type { ReactElement } from 'react';\nimport cx from 'classnames';\nimport { faChevronDown, faCheck, faXmark } from '@fortawesome/free-solid-svg-icons';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\n\nimport Chip from 'components/common/chip';\nimport SearchInput from 'components/common/searchInput';\nimport Tooltip from 'components/common/tooltip';\nimport Popover from 'components/common/popover';\nimport { PopoverAlign, PopoverPlacement, PopoverTrigger } from '../popover/popover.types';\nimport { useComponentDefaults, useLabels } from '../configProvider';\nimport { edgeIndex, nextIndex, scrollOptionIntoView } from '../utils/listNavigation';\nimport type { MultiSelectItem, MultiSelectLabels, MultiSelectProps, MultiSelectValue } from './multiSelect.types';\n\nimport styles from './multiSelect.module.pcss';\n\nconst EMPTY: MultiSelectValue[] = [];\n\nconst DEFAULT_LABELS: Required<MultiSelectLabels> = {\n clearSelection: 'Clear selection',\n create: (value) => `Add \"${value}\"`,\n searchPlaceholder: 'Search…',\n empty: 'No matches',\n};\n\nfunction MultiSelect(props: MultiSelectProps): ReactElement {\n const {\n items,\n value,\n defaultValue = [],\n onChange = () => {},\n label = '',\n alwaysFloatLabel = false,\n placeholder = '',\n searchable = false,\n allowCustomValues = false,\n maxSelected,\n clearable = true,\n disabled = false,\n readOnly = false,\n presentation,\n formValidator = null,\n errorMessage = '',\n isValid = true,\n className,\n style,\n classNames,\n styles: slotStyles,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n labels,\n ...rest\n } = useComponentDefaults('MultiSelect', props);\n const text = useLabels('MultiSelect', labels, DEFAULT_LABELS);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const controlRef = useRef<HTMLDivElement>(null);\n const searchRef = useRef<HTMLDivElement>(null);\n const optionsRef = useRef<HTMLDivElement>(null);\n const listboxId = useId();\n\n const [internalValue, setInternalValue] = useState<MultiSelectValue[]>(defaultValue);\n const [isOpen, setIsOpen] = useState(false);\n const [search, setSearch] = useState('');\n const [activeIndex, setActiveIndex] = useState(0);\n const [isFocused, setIsFocused] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [panelWidth, setPanelWidth] = useState<number>();\n\n // A ref as well as the prop: react-hooks/immutability refuses a mutation of the prop itself in\n // an event handler, and marking the validator touched happens in one.\n const fvRef = useRef(formValidator);\n const [, forceUpdate] = useState(0);\n useEffect(() => {\n fvRef.current = formValidator;\n const fv = fvRef.current;\n if (!fv) return;\n fv.label = label;\n fv.validate();\n const listener = () => forceUpdate((n) => n + 1);\n fv.registerOnUpdateListener(listener);\n return () => {\n fv.removeOnUpdateListener(listener);\n };\n }, [formValidator, label]);\n\n const isControlled = value !== undefined && !formValidator;\n const rawValue = formValidator ? formValidator.value : isControlled ? value : internalValue;\n const selected = Array.isArray(rawValue) ? (rawValue as MultiSelectValue[]) : EMPTY;\n\n const hasError = formValidator ? formValidator.touched && formValidator.hasError() : !isValid || !!errorMessage;\n const errorText = formValidator ? formValidator.getCurrentErrorMessage() : errorMessage || '';\n\n const isInteractive = !disabled && !readOnly;\n const atMax = maxSelected !== undefined && selected.length >= maxSelected;\n\n const shouldFloatLabel = alwaysFloatLabel || isOpen || isFocused || selected.length > 0;\n\n const isSearchable = searchable || allowCustomValues;\n const typed = search.trim();\n const needle = isSearchable ? typed.toLowerCase() : '';\n const matches = needle ? items.filter((item) => item.label.toLowerCase().includes(needle)) : items;\n\n const canCreate =\n allowCustomValues &&\n typed.length > 0 &&\n !atMax &&\n !items.some((item) => item.label.toLowerCase() === needle || String(item.key).toLowerCase() === needle) &&\n !selected.some((key) => String(key).toLowerCase() === needle);\n\n const visibleItems: MultiSelectItem[] = canCreate ? [...matches, { key: typed, label: text.create(typed) }] : matches;\n\n // Mapped from `selected`, not filtered from `items`, to keep the chips in pick order. A custom\n // value has no entry in `items`, so it stands in for itself.\n const selectedItems = selected\n .map<MultiSelectItem | undefined>(\n (key) => items.find((item) => item.key === key) ?? (allowCustomValues ? { key, label: String(key) } : undefined),\n )\n .filter((item): item is MultiSelectItem => item !== undefined);\n\n function commit(next: MultiSelectValue[]) {\n if (formValidator) formValidator.set(next);\n else if (!isControlled) setInternalValue(next);\n onChange(next);\n }\n\n function toggle(item: MultiSelectItem) {\n if (!isInteractive || item.disabled) return;\n if (selected.includes(item.key)) commit(selected.filter((key) => key !== item.key));\n else if (!atMax) commit([...selected, item.key]);\n // The typed text has become a chip, so leaving it in the box would offer to add it again.\n if (canCreate && item.key === typed) setSearch('');\n }\n\n /**\n * A focused element that unmounts fires no blur, so removing the chip or clear button that was\n * just clicked would leave `isFocused` stuck true. Hand focus back so there is still something\n * left to blur.\n */\n function keepFocusInControl() {\n if (rootRef.current?.contains(document.activeElement)) controlRef.current?.focus();\n }\n\n function handleOpenChange(next: boolean) {\n if (next && !isInteractive) return;\n setIsOpen(next);\n if (next) {\n setPanelWidth(controlRef.current?.offsetWidth);\n setActiveIndex(0);\n } else {\n setSearch('');\n if (fvRef.current) fvRef.current.touched = true;\n }\n }\n\n useEffect(() => {\n if (!isOpen || !isSearchable) return;\n searchRef.current?.querySelector('input')?.focus();\n }, [isOpen, isSearchable]);\n\n useEffect(() => {\n if (!isOpen) return;\n scrollOptionIntoView(optionsRef.current, document.getElementById(`${listboxId}-${activeIndex}`));\n }, [isOpen, activeIndex, listboxId]);\n\n // Matches what the options render as `aria-disabled`, so the arrows cannot land on one.\n const navigation = {\n isDisabled: (index: number) => {\n const item = visibleItems[index];\n return !!item.disabled || (atMax && !selected.includes(item.key));\n },\n };\n\n function handleKeyDown(event: React.KeyboardEvent) {\n if (!isInteractive) return;\n\n if (!isOpen) {\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n handleOpenChange(true);\n } else if (event.key === 'Backspace' && selected.length > 0) {\n commit(selected.slice(0, -1));\n }\n return;\n }\n\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n setActiveIndex(nextIndex(activeIndex, event.key === 'ArrowDown' ? 1 : -1, visibleItems.length, navigation) ?? 0);\n } else if (event.key === 'Home' || event.key === 'End') {\n event.preventDefault();\n setActiveIndex(edgeIndex(event.key === 'Home' ? 'first' : 'last', visibleItems.length, navigation) ?? 0);\n } else if (event.key === 'Enter') {\n event.preventDefault();\n const item = visibleItems[activeIndex];\n if (item) toggle(item);\n } else if (event.key === 'Backspace' && !search && selected.length > 0) {\n commit(selected.slice(0, -1));\n }\n }\n\n const panel = (\n <div className={cx(styles.multiSelectPanel, classNames?.panel)} style={slotStyles?.panel}>\n {isSearchable && (\n <div ref={searchRef} className={cx(styles.multiSelectSearch, classNames?.search)} style={slotStyles?.search}>\n <SearchInput\n value={search}\n onChange={(value) => {\n setSearch(value);\n setActiveIndex(0);\n }}\n placeholder={text.searchPlaceholder}\n onKeyDown={handleKeyDown}\n />\n </div>\n )}\n <div\n ref={optionsRef}\n id={listboxId}\n role='listbox'\n aria-multiselectable='true'\n aria-label={label || undefined}\n className={cx(styles.multiSelectOptions, classNames?.options)}\n style={slotStyles?.options}\n >\n {visibleItems.length === 0 ? (\n <div className={cx(styles.multiSelectEmpty, classNames?.empty)} style={slotStyles?.empty}>\n {text.empty}\n </div>\n ) : (\n visibleItems.map((item, index) => {\n const isSelected = selected.includes(item.key);\n const isDisabled = item.disabled || (atMax && !isSelected);\n\n return (\n <div\n key={item.key}\n id={`${listboxId}-${index}`}\n role='option'\n aria-selected={isSelected}\n aria-disabled={isDisabled || undefined}\n className={cx(\n styles.multiSelectOption,\n index === activeIndex && styles.multiSelectOptionActive,\n isSelected && styles.multiSelectOptionSelected,\n isDisabled && styles.multiSelectOptionDisabled,\n classNames?.option,\n )}\n style={slotStyles?.option}\n onMouseDown={(event) => event.preventDefault()}\n onMouseEnter={() => setActiveIndex(index)}\n onClick={() => toggle(item)}\n >\n <span\n className={cx(styles.multiSelectOptionCheck, classNames?.optionCheck)}\n style={slotStyles?.optionCheck}\n >\n {isSelected && <FontAwesomeIcon icon={faCheck} />}\n </span>\n <span\n className={cx(styles.multiSelectOptionLabel, classNames?.optionLabel)}\n style={slotStyles?.optionLabel}\n >\n {item.label}\n </span>\n </div>\n );\n })\n )}\n </div>\n </div>\n );\n\n return (\n <div\n {...rest}\n ref={rootRef}\n className={cx(styles.multiSelect, disabled && styles.multiSelectDisabled, classNames?.root, className)}\n style={{ ...style, ...slotStyles?.root }}\n onMouseEnter={(event) => {\n setIsHovered(true);\n onMouseEnter?.(event);\n }}\n onMouseLeave={(event) => {\n setIsHovered(false);\n onMouseLeave?.(event);\n }}\n onFocus={(event) => {\n setIsFocused(true);\n onFocus?.(event);\n }}\n onBlur={(event) => {\n if (event.currentTarget.contains(event.relatedTarget as Node | null)) return;\n setIsFocused(false);\n onBlur?.(event);\n }}\n >\n <Popover\n isOpen={isOpen}\n onOpenChange={handleOpenChange}\n trigger={PopoverTrigger.Click}\n placement={PopoverPlacement.Bottom}\n align={PopoverAlign.Start}\n offset={4}\n withArrow={false}\n // Neither half of this is the keyboard-only default. A search field takes\n // the caret however the panel was opened, and without one the control\n // keeps the focus and points at the active option with\n // `aria-activedescendant`, so nothing may take it away.\n focusOnOpen={isSearchable}\n constrainWidth={false}\n width='trigger'\n disabled={!isInteractive}\n presentation={presentation}\n content={panel}\n styles={{ panel: panelWidth ? { minWidth: panelWidth } : undefined }}\n >\n <div\n ref={controlRef}\n role='combobox'\n tabIndex={disabled ? -1 : 0}\n aria-expanded={isOpen}\n aria-haspopup='listbox'\n aria-controls={listboxId}\n aria-activedescendant={isOpen && visibleItems.length > 0 ? `${listboxId}-${activeIndex}` : undefined}\n aria-disabled={disabled || undefined}\n aria-readonly={readOnly || undefined}\n className={cx(styles.multiSelectControl, classNames?.control)}\n style={slotStyles?.control}\n onKeyDown={handleKeyDown}\n >\n {placeholder && selectedItems.length === 0 && (\n <span\n className={cx(\n styles.multiSelectPlaceholder,\n (!label || shouldFloatLabel) && styles.multiSelectPlaceholderShown,\n !label && styles.multiSelectPlaceholderInstant,\n classNames?.placeholder,\n )}\n style={slotStyles?.placeholder}\n >\n {placeholder}\n </span>\n )}\n\n <div className={cx(styles.multiSelectValues, classNames?.values)} style={slotStyles?.values}>\n {selectedItems.map((item) => (\n <Chip\n key={item.key}\n text={item.label}\n showRemoveIcon={isInteractive}\n labels={{ remove: `Remove ${item.label}` }}\n onMouseDown={(event) => event.preventDefault()}\n onRemove={() => {\n toggle(item);\n keepFocusInControl();\n }}\n className={cx(styles.multiSelectChip, classNames?.chip)}\n style={slotStyles?.chip}\n />\n ))}\n </div>\n\n {clearable && isInteractive && selected.length > 0 && (\n <button\n type='button'\n tabIndex={-1}\n aria-label={text.clearSelection}\n className={cx(styles.multiSelectClearButton, classNames?.clearButton)}\n style={slotStyles?.clearButton}\n onMouseDown={(event) => event.preventDefault()}\n onClick={(event) => {\n event.stopPropagation();\n commit([]);\n keepFocusInControl();\n }}\n >\n <FontAwesomeIcon icon={faXmark} />\n </button>\n )}\n\n <FontAwesomeIcon\n icon={faChevronDown}\n className={cx(styles.multiSelectIcon, isOpen && styles.multiSelectIconOpen, classNames?.icon)}\n style={slotStyles?.icon as React.CSSProperties & Record<`--fa-font-${string}`, string>}\n />\n\n {label && (\n <div\n className={cx(\n styles.multiSelectLabel,\n shouldFloatLabel && styles.multiSelectLabelFloating,\n classNames?.label,\n )}\n style={slotStyles?.label}\n >\n {label}\n </div>\n )}\n\n {/* The visible border lives here rather than on the control, because the legend is what\n cuts the notch the floating label sits in. Same construction as Input. */}\n <fieldset\n className={cx(\n styles.multiSelectFieldset,\n !label && styles.multiSelectFieldsetNoNotch,\n (isFocused || isOpen) && styles.multiSelectFieldsetFocused,\n hasError && styles.multiSelectFieldsetError,\n classNames?.fieldset,\n )}\n style={slotStyles?.fieldset}\n >\n <legend\n className={cx(\n styles.multiSelectFieldsetLegend,\n shouldFloatLabel && styles.multiSelectFieldsetLegendActive,\n )}\n >\n <span>{label}</span>\n </legend>\n </fieldset>\n </div>\n </Popover>\n\n <Tooltip variant='error' message={errorText} isVisible={hasError && (isFocused || isHovered)} />\n </div>\n );\n}\n\nexport default MultiSelect;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"radioGroup.types.mjs","names":[],"sources":["../../../../package/common/radioGroup/radioGroup.types.ts"],"sourcesContent":["import type { CSSProperties, ReactNode } from 'react';\nimport type { FormValidator } from 'services/formValidation';\nimport type { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types';\n\nexport type RadioValue = string | number;\n\nexport enum RadioGroupOrientation {\n Vertical = 'vertical',\n Horizontal = 'horizontal',\n}\n\nexport interface RadioOption {\n value: RadioValue;\n /** Visible label; falls back to `value` when omitted. */\n label?: ReactNode;\n /** Secondary description shown under the label. */\n description?: ReactNode;\n /** Disable just this option. */\n disabled?: boolean;\n}\n\nexport type RadioGroupSlots = 'root' | 'option' | 'radio' | 'dot' | 'label' | 'description';\n\nexport interface RadioGroupProps extends Omit<HtmlProps, 'onChange'> {\n /** The selectable options. */\n options: RadioOption[];\n /** Controlled selected value. Omit for uncontrolled. */\n value?: RadioValue;\n /** Initial value when uncontrolled. */\n defaultValue?: RadioValue;\n /** Fires with the newly selected value. */\n onChange?: (value: RadioValue, event?: React.MouseEvent | React.KeyboardEvent) => void;\n /** Layout direction (default `Vertical`). */\n orientation?: RadioGroupOrientation;\n /** Disable the whole group. */\n disabled?: boolean;\n /** Diameter of the radio circle (default `'18px'`). */\n size?: string;\n /** Tab index of the active (roving) option. */\n tabIndex?: number;\n formValidator?: FormValidator | null;\n /** Manual error message shown in a tooltip (used when there's no `formValidator`, or to force one). */\n errorMessage?: string;\n /** Manual valid state when not using a `formValidator` (default `true`). */\n isValid?: boolean;\n\n className?: string;\n style?: CSSProperties;\n classNames?: SlotClassNames<RadioGroupSlots>;\n styles?: SlotStyles<RadioGroupSlots>;\n}\n"],"mappings":"aAMA,IAAY,EAAL,SAAA,EAAA,OACL,GAAA,SAAA,WACA,EAAA,WAAA,cACF,EAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"radioGroup.types.mjs","names":[],"sources":["../../../../package/common/radioGroup/radioGroup.types.ts"],"sourcesContent":["import type { CSSProperties, ReactNode } from 'react';\nimport type { FormValidator } from 'services/formValidation';\nimport type { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types';\n\nexport type RadioValue = string | number;\n\nexport enum RadioGroupOrientation {\n Vertical = 'vertical',\n Horizontal = 'horizontal',\n}\n\nexport interface RadioOption {\n value: RadioValue;\n /** Visible label; falls back to `value` when omitted. */\n label?: ReactNode;\n /** Secondary description shown under the label. */\n description?: ReactNode;\n /** Disable just this option. */\n disabled?: boolean;\n}\n\nexport type RadioGroupSlots = 'root' | 'option' | 'radio' | 'dot' | 'label' | 'description';\n\nexport interface RadioGroupProps extends Omit<HtmlProps, 'onChange'> {\n /** The selectable options. */\n options: RadioOption[];\n /** Controlled selected value. Omit for uncontrolled. */\n value?: RadioValue;\n /** Initial value when uncontrolled. */\n defaultValue?: RadioValue;\n /** Fires with the newly selected value. */\n onChange?: (value: RadioValue, event?: React.MouseEvent | React.KeyboardEvent) => void;\n /** Layout direction (default `Vertical`). */\n orientation?: RadioGroupOrientation;\n /** Disable the whole group. */\n disabled?: boolean;\n /** Diameter of the radio circle. Defaults to `1.125em` of `--default-font-size`, 18px at a 16px base. */\n size?: string;\n /** Tab index of the active (roving) option. */\n tabIndex?: number;\n formValidator?: FormValidator | null;\n /** Manual error message shown in a tooltip (used when there's no `formValidator`, or to force one). */\n errorMessage?: string;\n /** Manual valid state when not using a `formValidator` (default `true`). */\n isValid?: boolean;\n\n className?: string;\n style?: CSSProperties;\n classNames?: SlotClassNames<RadioGroupSlots>;\n styles?: SlotStyles<RadioGroupSlots>;\n}\n"],"mappings":"aAMA,IAAY,EAAL,SAAA,EAAA,OACL,GAAA,SAAA,WACA,EAAA,WAAA,cACF,EAAA,CAAA,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"rating.module.mjs","names":[],"sources":["../../../../package/common/rating/rating.module.pcss"],"sourcesContent":[".rating {\n /* calc, not em: this is the element that sets the base, so an em here would measure\n whatever the rating happens to sit in instead of the theme's text size. */\n --custom-rating-size: var(--rating-size, calc(var(--default-font-size) * 1.25));\n\n display: inline-flex;\n align-items: center;\n align-self: flex-start;\n width: fit-content;\n gap: 0.15em;\n font-size: var(--custom-rating-size);\n outline: none;\n touch-action: pan-y;\n user-select: none;\n\n &:focus-visible {\n box-shadow: 0 0 0 2px var(--primary-lighter);\n border-radius: var(--default-border-radius);\n }\n\n &-disabled {\n opacity: 0.5;\n }\n\n &-disabled,\n &-readOnly {\n pointer-events: none;\n }\n\n &-item {\n position: relative;\n display: inline-flex;\n width: 1em;\n height: 1em;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n\n &-iconEmpty {\n width: 1em;\n height: 1em;\n color: var(--rating-empty-color, var(--background-accent-light));\n }\n\n &-iconFilledClip {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n overflow: hidden;\n pointer-events: none;\n }\n\n &-iconFilled {\n width: 1em;\n height: 1em;\n color: var(--rating-filled-color, var(--primary-color));\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"rating.module.mjs","names":[],"sources":["../../../../package/common/rating/rating.module.pcss"],"sourcesContent":[".rating {\n /* calc, not em: this is the element that sets the base, so an em here would measure\n whatever the rating happens to sit in instead of the theme's text size. */\n --custom-rating-size: var(--rating-size, calc(var(--default-font-size) * 1.25));\n\n display: inline-flex;\n align-items: center;\n align-self: flex-start;\n width: fit-content;\n gap: 0.15em;\n font-size: var(--custom-rating-size);\n outline: none;\n touch-action: pan-y;\n user-select: none;\n\n &:focus-visible {\n box-shadow: 0 0 0 2px var(--primary-lighter);\n border-radius: var(--default-border-radius);\n }\n\n &-disabled {\n opacity: 0.5;\n }\n\n &-disabled,\n &-readOnly {\n pointer-events: none;\n }\n\n &-item {\n position: relative;\n display: inline-flex;\n width: 1em;\n height: 1em;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n\n &-iconEmpty {\n width: 1em;\n height: 1em;\n color: var(--rating-empty-color, var(--background-accent-light));\n }\n\n &-iconFilledClip {\n position: absolute;\n top: 0;\n left: 0;\n\n /* flex, so the icon is not an inline box: on a baseline it sat a fraction of a pixel below\n the empty icon behind it, which the clip then cut off the bottom of. */\n display: flex;\n height: 100%;\n overflow: hidden;\n pointer-events: none;\n }\n\n &-iconFilled {\n width: 1em;\n height: 1em;\n\n /* The clip is narrower than a star at a partial fill. An `svg` refuses to shrink, but `icon`\n takes any element, and a wrapped one would be squeezed rather than clipped. */\n flex-shrink: 0;\n color: var(--rating-filled-color, var(--primary-color));\n }\n}\n"],"mappings":""}
@@ -1,2 +1,2 @@
1
- "use client";import e from"./ripple.module.mjs";import{useEffect as t,useImperativeHandle as n,useRef as r}from"react";import{jsx as i,jsxs as a}from"react/jsx-runtime";function o({disabled:o=!1,children:s,className:c,style:l,overflowHidden:u=!0,rippleAnimationLength:d=.6,rippleBackground:f=`rgba(255, 255, 255, 0.2)`,manualOnly:p=!1,ref:m,...h}){let g=r(null),_=r(null);function v(t,n){if(o)return;let r=document.createElement(`div`);r.style.left=`${t}px`,r.style.top=`${n}px`,r.style.background=f,r.classList.add(e.ripple),g.current?.appendChild(r),setTimeout(()=>{g.current?.removeChild(r)},d*1e3+50)}function y(e){if(!g.current)return;let t=g.current.getBoundingClientRect();v(e.clientX-t.x,e.clientY-t.y)}n(m,()=>({addRipple(){let e=g.current;e&&v(e.offsetWidth/2,e.offsetHeight/2)}})),t(()=>{_.current=y}),t(()=>{if(s!==void 0||p)return;let e=g.current?.parentElement;if(!e)return;let t=e=>_.current?.(e);return e.addEventListener(`click`,t),()=>e.removeEventListener(`click`,t)},[s,p]);let b={"--ripple-animation-length":`${d}s`};return s===void 0?i(`div`,{className:e.rippleContainer,ref:g,style:{overflow:u?`hidden`:`visible`,...b}}):a(`div`,{...h,className:c,onClick:p?void 0:e=>y(e),style:{position:`relative`,...l},children:[s,i(`div`,{className:e.rippleContainer,ref:g,style:{overflow:u?`hidden`:`visible`,...b}})]})}export{o as default};
1
+ "use client";import e from"./ripple.module.mjs";import{isInteractiveTarget as t}from"../utils/interactiveTarget.mjs";import{useEffect as n,useImperativeHandle as r,useRef as i}from"react";import{jsx as a,jsxs as o}from"react/jsx-runtime";function s({disabled:s=!1,children:c,className:l,style:u,overflowHidden:d=!0,rippleAnimationLength:f=.6,rippleBackground:p=`rgba(255, 255, 255, 0.2)`,manualOnly:m=!1,ref:h,...g}){let _=i(null),v=i(null);function y(t,n){if(s)return;let r=document.createElement(`div`);r.style.left=`${t}px`,r.style.top=`${n}px`,r.style.background=p,r.classList.add(e.ripple),_.current?.appendChild(r),setTimeout(()=>{_.current?.removeChild(r)},f*1e3+50)}function b(e){if(!_.current)return;let t=_.current.getBoundingClientRect();y(e.clientX-t.x,e.clientY-t.y)}r(h,()=>({addRipple(){let e=_.current;e&&y(e.offsetWidth/2,e.offsetHeight/2)}})),n(()=>{v.current=b}),n(()=>{if(c!==void 0||m)return;let e=_.current?.parentElement;if(!e)return;let n=n=>{t(n.target,e)||v.current?.(n)};return e.addEventListener(`click`,n),()=>e.removeEventListener(`click`,n)},[c,m]);let x={"--ripple-animation-length":`${f}s`};return c===void 0?a(`div`,{className:e.rippleContainer,ref:_,style:{overflow:d?`hidden`:`visible`,...x}}):o(`div`,{...g,className:l,onClick:m?void 0:e=>{t(e.target,e.currentTarget)||b(e)},style:{position:`relative`,...u},children:[c,a(`div`,{className:e.rippleContainer,ref:_,style:{overflow:d?`hidden`:`visible`,...x}})]})}export{s as default};
2
2
  //# sourceMappingURL=ripple.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ripple.mjs","names":[],"sources":["../../../../package/common/ripple/ripple.tsx"],"sourcesContent":["import React, { useRef, useEffect, useImperativeHandle } from 'react';\n\nimport styles from './ripple.module.pcss';\nimport type { RippleProps, RippleHandle } from './ripple.types';\n\nexport type { RippleProps, RippleHandle };\n\nfunction Ripple({\n disabled = false,\n children,\n className,\n style,\n overflowHidden = true,\n rippleAnimationLength = 0.6,\n rippleBackground = 'rgba(255, 255, 255, 0.2)',\n manualOnly = false,\n ref,\n ...rest\n}: RippleProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const addRippleRef = useRef<((event: MouseEvent) => void) | null>(null);\n\n function spawnRipple(x: number, y: number) {\n if (disabled) return;\n const ripple = document.createElement('div');\n ripple.style.left = `${x}px`;\n ripple.style.top = `${y}px`;\n ripple.style.background = rippleBackground;\n ripple.classList.add(styles.ripple);\n containerRef.current?.appendChild(ripple);\n setTimeout(\n () => {\n containerRef.current?.removeChild(ripple);\n },\n rippleAnimationLength * 1000 + 50,\n );\n }\n\n function addRipple(event: MouseEvent | React.MouseEvent) {\n if (!containerRef.current) return;\n const pos = containerRef.current.getBoundingClientRect();\n spawnRipple(event.clientX - pos.x, event.clientY - pos.y);\n }\n\n useImperativeHandle(ref, () => ({\n addRipple() {\n const el = containerRef.current;\n if (!el) return;\n spawnRipple(el.offsetWidth / 2, el.offsetHeight / 2);\n },\n }));\n\n useEffect(() => {\n addRippleRef.current = addRipple;\n });\n\n useEffect(() => {\n if (children !== undefined || manualOnly) return;\n const parent = containerRef.current?.parentElement;\n if (!parent) return;\n const handler = (e: MouseEvent) => addRippleRef.current?.(e);\n parent.addEventListener('click', handler);\n return () => parent.removeEventListener('click', handler);\n }, [children, manualOnly]);\n\n const containerStyle: React.CSSProperties & { '--ripple-animation-length'?: string } = {\n '--ripple-animation-length': `${rippleAnimationLength}s`,\n };\n\n if (children !== undefined) {\n return (\n <div\n {...rest}\n className={className}\n onClick={manualOnly ? undefined : (e) => addRipple(e)}\n style={{\n position: 'relative',\n ...style,\n }}\n >\n {children}\n <div\n className={styles.rippleContainer}\n ref={containerRef}\n style={{\n overflow: overflowHidden ? 'hidden' : 'visible',\n ...containerStyle,\n }}\n />\n </div>\n );\n }\n\n return (\n <div\n className={styles.rippleContainer}\n ref={containerRef}\n style={{\n overflow: overflowHidden ? 'hidden' : 'visible',\n ...containerStyle,\n }}\n />\n );\n}\n\nexport default Ripple;\n"],"mappings":"yKAOA,SAAS,EAAO,CACd,WAAW,GACX,WACA,YACA,QACA,iBAAiB,GACjB,wBAAwB,GACxB,mBAAmB,2BACnB,aAAa,GACb,MACA,GAAG,GACW,CACd,IAAM,EAAe,EAAuB,IAAI,EAC1C,EAAe,EAA6C,IAAI,EAEtE,SAAS,EAAY,EAAW,EAAW,CACzC,GAAI,EAAU,OACd,IAAM,EAAS,SAAS,cAAc,KAAK,EAC3C,EAAO,MAAM,KAAO,GAAG,EAAE,IACzB,EAAO,MAAM,IAAM,GAAG,EAAE,IACxB,EAAO,MAAM,WAAa,EAC1B,EAAO,UAAU,IAAI,EAAO,MAAM,EAClC,EAAa,SAAS,YAAY,CAAM,EACxC,eACQ,CACJ,EAAa,SAAS,YAAY,CAAM,CAC1C,EACA,EAAwB,IAAO,EACjC,CACF,CAEA,SAAS,EAAU,EAAsC,CACvD,GAAI,CAAC,EAAa,QAAS,OAC3B,IAAM,EAAM,EAAa,QAAQ,sBAAsB,EACvD,EAAY,EAAM,QAAU,EAAI,EAAG,EAAM,QAAU,EAAI,CAAC,CAC1D,CAEA,EAAoB,OAAY,CAC9B,WAAY,CACV,IAAM,EAAK,EAAa,QACnB,GACL,EAAY,EAAG,YAAc,EAAG,EAAG,aAAe,CAAC,CACrD,CACF,EAAE,EAEF,MAAgB,CACd,EAAa,QAAU,CACzB,CAAC,EAED,MAAgB,CACd,GAAI,IAAa,IAAA,IAAa,EAAY,OAC1C,IAAM,EAAS,EAAa,SAAS,cACrC,GAAI,CAAC,EAAQ,OACb,IAAM,EAAW,GAAkB,EAAa,UAAU,CAAC,EAE3D,OADA,EAAO,iBAAiB,QAAS,CAAO,MAC3B,EAAO,oBAAoB,QAAS,CAAO,CAC1D,EAAG,CAAC,EAAU,CAAU,CAAC,EAEzB,IAAM,EAAiF,CACrF,4BAA6B,GAAG,EAAsB,EACxD,EA0BA,OAxBI,IAAa,IAAA,GAyBf,EAAC,MAAD,CACE,UAAW,EAAO,gBAClB,IAAK,EACL,MAAO,CACL,SAAU,EAAiB,SAAW,UACtC,GAAG,CACL,CACD,CAAA,EA9BC,EAAC,MAAD,CACE,GAAI,EACO,YACX,QAAS,EAAa,IAAA,GAAa,GAAM,EAAU,CAAC,EACpD,MAAO,CACL,SAAU,WACV,GAAG,CACL,EAPF,SAAA,CASG,EACD,EAAC,MAAD,CACE,UAAW,EAAO,gBAClB,IAAK,EACL,MAAO,CACL,SAAU,EAAiB,SAAW,UACtC,GAAG,CACL,CACD,CAAA,CACE,GAcX"}
1
+ {"version":3,"file":"ripple.mjs","names":[],"sources":["../../../../package/common/ripple/ripple.tsx"],"sourcesContent":["import React, { useRef, useEffect, useImperativeHandle } from 'react';\n\nimport styles from './ripple.module.pcss';\nimport { isInteractiveTarget } from '../utils/interactiveTarget';\nimport type { RippleProps, RippleHandle } from './ripple.types';\n\nexport type { RippleProps, RippleHandle };\n\nfunction Ripple({\n disabled = false,\n children,\n className,\n style,\n overflowHidden = true,\n rippleAnimationLength = 0.6,\n rippleBackground = 'rgba(255, 255, 255, 0.2)',\n manualOnly = false,\n ref,\n ...rest\n}: RippleProps) {\n const containerRef = useRef<HTMLDivElement>(null);\n const addRippleRef = useRef<((event: MouseEvent) => void) | null>(null);\n\n function spawnRipple(x: number, y: number) {\n if (disabled) return;\n const ripple = document.createElement('div');\n ripple.style.left = `${x}px`;\n ripple.style.top = `${y}px`;\n ripple.style.background = rippleBackground;\n ripple.classList.add(styles.ripple);\n containerRef.current?.appendChild(ripple);\n setTimeout(\n () => {\n containerRef.current?.removeChild(ripple);\n },\n rippleAnimationLength * 1000 + 50,\n );\n }\n\n function addRipple(event: MouseEvent | React.MouseEvent) {\n if (!containerRef.current) return;\n const pos = containerRef.current.getBoundingClientRect();\n spawnRipple(event.clientX - pos.x, event.clientY - pos.y);\n }\n\n useImperativeHandle(ref, () => ({\n addRipple() {\n const el = containerRef.current;\n if (!el) return;\n spawnRipple(el.offsetWidth / 2, el.offsetHeight / 2);\n },\n }));\n\n useEffect(() => {\n addRippleRef.current = addRipple;\n });\n\n useEffect(() => {\n if (children !== undefined || manualOnly) return;\n const parent = containerRef.current?.parentElement;\n if (!parent) return;\n // A click on a control inside the rippling element belongs to that control: the ripple is\n // feedback for activating this element, and the element it landed on gives its own.\n const handler = (e: MouseEvent) => {\n if (isInteractiveTarget(e.target, parent)) return;\n addRippleRef.current?.(e);\n };\n parent.addEventListener('click', handler);\n return () => parent.removeEventListener('click', handler);\n }, [children, manualOnly]);\n\n const containerStyle: React.CSSProperties & { '--ripple-animation-length'?: string } = {\n '--ripple-animation-length': `${rippleAnimationLength}s`,\n };\n\n if (children !== undefined) {\n return (\n <div\n {...rest}\n className={className}\n onClick={\n manualOnly\n ? undefined\n : (e) => {\n if (isInteractiveTarget(e.target, e.currentTarget)) return;\n addRipple(e);\n }\n }\n style={{\n position: 'relative',\n ...style,\n }}\n >\n {children}\n <div\n className={styles.rippleContainer}\n ref={containerRef}\n style={{\n overflow: overflowHidden ? 'hidden' : 'visible',\n ...containerStyle,\n }}\n />\n </div>\n );\n }\n\n return (\n <div\n className={styles.rippleContainer}\n ref={containerRef}\n style={{\n overflow: overflowHidden ? 'hidden' : 'visible',\n ...containerStyle,\n }}\n />\n );\n}\n\nexport default Ripple;\n"],"mappings":"8OAQA,SAAS,EAAO,CACd,WAAW,GACX,WACA,YACA,QACA,iBAAiB,GACjB,wBAAwB,GACxB,mBAAmB,2BACnB,aAAa,GACb,MACA,GAAG,GACW,CACd,IAAM,EAAe,EAAuB,IAAI,EAC1C,EAAe,EAA6C,IAAI,EAEtE,SAAS,EAAY,EAAW,EAAW,CACzC,GAAI,EAAU,OACd,IAAM,EAAS,SAAS,cAAc,KAAK,EAC3C,EAAO,MAAM,KAAO,GAAG,EAAE,IACzB,EAAO,MAAM,IAAM,GAAG,EAAE,IACxB,EAAO,MAAM,WAAa,EAC1B,EAAO,UAAU,IAAI,EAAO,MAAM,EAClC,EAAa,SAAS,YAAY,CAAM,EACxC,eACQ,CACJ,EAAa,SAAS,YAAY,CAAM,CAC1C,EACA,EAAwB,IAAO,EACjC,CACF,CAEA,SAAS,EAAU,EAAsC,CACvD,GAAI,CAAC,EAAa,QAAS,OAC3B,IAAM,EAAM,EAAa,QAAQ,sBAAsB,EACvD,EAAY,EAAM,QAAU,EAAI,EAAG,EAAM,QAAU,EAAI,CAAC,CAC1D,CAEA,EAAoB,OAAY,CAC9B,WAAY,CACV,IAAM,EAAK,EAAa,QACnB,GACL,EAAY,EAAG,YAAc,EAAG,EAAG,aAAe,CAAC,CACrD,CACF,EAAE,EAEF,MAAgB,CACd,EAAa,QAAU,CACzB,CAAC,EAED,MAAgB,CACd,GAAI,IAAa,IAAA,IAAa,EAAY,OAC1C,IAAM,EAAS,EAAa,SAAS,cACrC,GAAI,CAAC,EAAQ,OAGb,IAAM,EAAW,GAAkB,CAC7B,EAAoB,EAAE,OAAQ,CAAM,GACxC,EAAa,UAAU,CAAC,CAC1B,EAEA,OADA,EAAO,iBAAiB,QAAS,CAAO,MAC3B,EAAO,oBAAoB,QAAS,CAAO,CAC1D,EAAG,CAAC,EAAU,CAAU,CAAC,EAEzB,IAAM,EAAiF,CACrF,4BAA6B,GAAG,EAAsB,EACxD,EAiCA,OA/BI,IAAa,IAAA,GAgCf,EAAC,MAAD,CACE,UAAW,EAAO,gBAClB,IAAK,EACL,MAAO,CACL,SAAU,EAAiB,SAAW,UACtC,GAAG,CACL,CACD,CAAA,EArCC,EAAC,MAAD,CACE,GAAI,EACO,YACX,QACE,EACI,IAAA,GACC,GAAM,CACD,EAAoB,EAAE,OAAQ,EAAE,aAAa,GACjD,EAAU,CAAC,CACb,EAEN,MAAO,CACL,SAAU,WACV,GAAG,CACL,EAdF,SAAA,CAgBG,EACD,EAAC,MAAD,CACE,UAAW,EAAO,gBAClB,IAAK,EACL,MAAO,CACL,SAAU,EAAiB,SAAW,UACtC,GAAG,CACL,CACD,CAAA,CACE,GAcX"}
@@ -0,0 +1,2 @@
1
+ "use client";import e from"../styles/scrollFade.module.mjs";import{mergeRefs as t}from"../utils/mergeRefs.mjs";import{useScrollEdges as n}from"../hooks/useScrollEdges.mjs";import{ScrollFadeAxis as r}from"./scrollFade.types.mjs";import i from"./scrollFade.module.mjs";import{useRef as a}from"react";import o from"classnames";import{jsx as s}from"react/jsx-runtime";function c({children:c=null,axis:l=r.Vertical,fadeLength:u,isAlwaysFaded:d=!1,className:f,style:p,ref:m,...h}){let g=a(null),_=l===r.Horizontal,{hasStart:v,hasEnd:y}=n(g,{axis:l,isEnabled:!d});return s(`div`,{...h,ref:t(g,m),className:o(_?i.scrollFadeHorizontal:i.scrollFadeVertical,e.scrollFade,_?e.scrollFadeX:e.scrollFadeY,(d||v)&&e.scrollFadeFadedStart,(d||y)&&e.scrollFadeFadedEnd,f),style:{...u?{"--custom-scroll-fade-length":u}:void 0,...p},children:c})}export{c as default};
2
+ //# sourceMappingURL=scrollFade.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrollFade.mjs","names":[],"sources":["../../../../package/common/scrollFade/scrollFade.tsx"],"sourcesContent":["import { useRef, type CSSProperties, type ReactElement } from 'react';\nimport cx from 'classnames';\nimport { useScrollEdges } from 'components/common/hooks/useScrollEdges';\nimport { mergeRefs } from 'components/common/utils/mergeRefs';\n\nimport { ScrollFadeAxis, type ScrollFadeProps } from './scrollFade.types';\nimport styles from './scrollFade.module.pcss';\nimport fadeStyles from 'components/common/styles/scrollFade.module.pcss';\n\nfunction ScrollFade({\n children = null,\n axis = ScrollFadeAxis.Vertical,\n fadeLength,\n isAlwaysFaded = false,\n className,\n style,\n ref,\n ...rest\n}: ScrollFadeProps): ReactElement {\n const scrollRef = useRef<HTMLDivElement>(null);\n const isHorizontal = axis === ScrollFadeAxis.Horizontal;\n const { hasStart, hasEnd } = useScrollEdges(scrollRef, {\n axis,\n isEnabled: !isAlwaysFaded,\n });\n\n return (\n <div\n {...rest}\n ref={mergeRefs(scrollRef, ref)}\n className={cx(\n isHorizontal ? styles.scrollFadeHorizontal : styles.scrollFadeVertical,\n fadeStyles.scrollFade,\n isHorizontal ? fadeStyles.scrollFadeX : fadeStyles.scrollFadeY,\n (isAlwaysFaded || hasStart) && fadeStyles.scrollFadeFadedStart,\n (isAlwaysFaded || hasEnd) && fadeStyles.scrollFadeFadedEnd,\n className,\n )}\n // The shared sheet's private length, not `--scroll-fade-length`: an inline custom property\n // would otherwise reach a `ScrollFade` nested in the content.\n style={{\n ...(fadeLength ? ({ '--custom-scroll-fade-length': fadeLength } as CSSProperties) : undefined),\n ...style,\n }}\n >\n {children}\n </div>\n );\n}\n\nexport default ScrollFade;\n"],"mappings":"4WASA,SAAS,EAAW,CAClB,WAAW,KACX,OAAO,EAAe,SACtB,aACA,gBAAgB,GAChB,YACA,QACA,MACA,GAAG,GAC6B,CAChC,IAAM,EAAY,EAAuB,IAAI,EACvC,EAAe,IAAS,EAAe,WACvC,CAAE,WAAU,UAAW,EAAe,EAAW,CACrD,OACA,UAAW,CAAC,CACd,CAAC,EAED,OACE,EAAC,MAAD,CACE,GAAI,EACJ,IAAK,EAAU,EAAW,CAAG,EAC7B,UAAW,EACT,EAAe,EAAO,qBAAuB,EAAO,mBACpD,EAAW,WACX,EAAe,EAAW,YAAc,EAAW,aAClD,GAAiB,IAAa,EAAW,sBACzC,GAAiB,IAAW,EAAW,mBACxC,CACF,EAGA,MAAO,CACL,GAAI,EAAc,CAAE,8BAA+B,CAAW,EAAsB,IAAA,GACpF,GAAG,CACL,EAEC,UACE,CAAA,CAET"}
@@ -0,0 +1,2 @@
1
+ "use client";var e=`scrollFade-vertical_48p38`,t=`scrollFade-horizontal_nX2dg`,n={"scrollFade-vertical":`scrollFade-vertical_48p38`,scrollFadeVertical:e,"scrollFade-horizontal":`scrollFade-horizontal_nX2dg`,scrollFadeHorizontal:t};export{n as default,t as scrollFadeHorizontal,e as scrollFadeVertical};
2
+ //# sourceMappingURL=scrollFade.module.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrollFade.module.mjs","names":[],"sources":["../../../../package/common/scrollFade/scrollFade.module.pcss"],"sourcesContent":["/* The mask itself lives in `styles/scrollFade.module.pcss`, shared with every component that has\n a scroll port of its own. All this adds is the scrolling — hence two classes and no shared base:\n an empty parent rule is dropped from the module, so `styles.scrollFade` would be undefined. */\n.scrollFade-vertical {\n overflow-y: auto;\n}\n\n.scrollFade-horizontal {\n overflow-x: auto;\n}\n"],"mappings":""}
@@ -0,0 +1,2 @@
1
+ "use client";var e=function(e){return e.Vertical=`vertical`,e.Horizontal=`horizontal`,e}({});export{e as ScrollFadeAxis};
2
+ //# sourceMappingURL=scrollFade.types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrollFade.types.mjs","names":[],"sources":["../../../../package/common/scrollFade/scrollFade.types.ts"],"sourcesContent":["import type { CSSProperties, ReactNode, Ref } from 'react';\nimport type { HtmlProps } from '../types/slots.types';\n\nexport enum ScrollFadeAxis {\n Vertical = 'vertical',\n Horizontal = 'horizontal',\n}\n\nexport interface ScrollFadeProps extends HtmlProps<HTMLDivElement> {\n /** The scrolling content. */\n children?: ReactNode;\n /** Which way it scrolls. Default `ScrollFadeAxis.Vertical`. */\n axis?: ScrollFadeAxis;\n /** How far the fade runs from each edge, any CSS length. Default `24px`. */\n fadeLength?: string;\n /** Fade both ends whether or not content is hidden there. Default `false`. */\n isAlwaysFaded?: boolean;\n className?: string;\n style?: CSSProperties;\n /** The scrolling element itself. */\n ref?: Ref<HTMLDivElement>;\n}\n"],"mappings":"aAGA,IAAY,EAAL,SAAA,EAAA,OACL,GAAA,SAAA,WACA,EAAA,WAAA,cACF,EAAA,CAAA,CAAA"}
@@ -0,0 +1,2 @@
1
+ "use client";var e=`scroll-fade_owdg4`,t=`scroll-fade-y_wJ1fr`,n=`scroll-fade-x_WoTqS`,r=`scroll-fade-faded-start_x28G6`,i=`scroll-fade-faded-end_buuWg`,a={"scroll-fade":`scroll-fade_owdg4`,scrollFade:e,"scroll-fade-y":`scroll-fade-y_wJ1fr`,scrollFadeY:t,"scroll-fade-x":`scroll-fade-x_WoTqS`,scrollFadeX:n,"scroll-fade-faded-start":`scroll-fade-faded-start_x28G6`,scrollFadeFadedStart:r,"scroll-fade-faded-end":`scroll-fade-faded-end_buuWg`,scrollFadeFadedEnd:i};export{a as default,e as scrollFade,i as scrollFadeFadedEnd,r as scrollFadeFadedStart,n as scrollFadeX,t as scrollFadeY};
2
+ //# sourceMappingURL=scrollFade.module.mjs.map