@helpwave/hightide 0.1.25 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (602) hide show
  1. package/README.md +1 -1
  2. package/dist/components/branding/HelpwaveBadge.d.mts +4 -5
  3. package/dist/components/branding/HelpwaveBadge.d.ts +4 -5
  4. package/dist/components/branding/HelpwaveBadge.js +46 -87
  5. package/dist/components/branding/HelpwaveBadge.js.map +1 -1
  6. package/dist/components/branding/HelpwaveBadge.mjs +46 -89
  7. package/dist/components/branding/HelpwaveBadge.mjs.map +1 -1
  8. package/dist/components/date/DatePicker.d.mts +1 -1
  9. package/dist/components/date/DatePicker.d.ts +1 -1
  10. package/dist/components/date/DatePicker.js +64 -13
  11. package/dist/components/date/DatePicker.js.map +1 -1
  12. package/dist/components/date/DatePicker.mjs +65 -14
  13. package/dist/components/date/DatePicker.mjs.map +1 -1
  14. package/dist/components/date/DayPicker.d.mts +1 -1
  15. package/dist/components/date/DayPicker.d.ts +1 -1
  16. package/dist/components/date/DayPicker.js +3 -3
  17. package/dist/components/date/DayPicker.js.map +1 -1
  18. package/dist/components/date/DayPicker.mjs +3 -3
  19. package/dist/components/date/DayPicker.mjs.map +1 -1
  20. package/dist/components/date/TimeDisplay.js.map +1 -1
  21. package/dist/components/date/TimeDisplay.mjs.map +1 -1
  22. package/dist/components/date/TimePicker.js +2 -2
  23. package/dist/components/date/TimePicker.js.map +1 -1
  24. package/dist/components/date/TimePicker.mjs +2 -2
  25. package/dist/components/date/TimePicker.mjs.map +1 -1
  26. package/dist/components/date/YearMonthPicker.js +58 -7
  27. package/dist/components/date/YearMonthPicker.js.map +1 -1
  28. package/dist/components/date/YearMonthPicker.mjs +59 -8
  29. package/dist/components/date/YearMonthPicker.mjs.map +1 -1
  30. package/dist/components/{dialogs → dialog}/ConfirmDialog.d.mts +9 -8
  31. package/dist/components/{dialogs → dialog}/ConfirmDialog.d.ts +9 -8
  32. package/dist/components/dialog/ConfirmDialog.js +938 -0
  33. package/dist/components/dialog/ConfirmDialog.js.map +1 -0
  34. package/dist/components/dialog/ConfirmDialog.mjs +902 -0
  35. package/dist/components/dialog/ConfirmDialog.mjs.map +1 -0
  36. package/dist/components/dialog/Dialog.d.mts +27 -0
  37. package/dist/components/dialog/Dialog.d.ts +27 -0
  38. package/dist/components/dialog/Dialog.js +879 -0
  39. package/dist/components/dialog/Dialog.js.map +1 -0
  40. package/dist/components/dialog/Dialog.mjs +845 -0
  41. package/dist/components/dialog/Dialog.mjs.map +1 -0
  42. package/dist/components/dialog/DiscardChangesDialog.d.mts +24 -0
  43. package/dist/components/dialog/DiscardChangesDialog.d.ts +24 -0
  44. package/dist/components/dialog/DiscardChangesDialog.js +966 -0
  45. package/dist/components/dialog/DiscardChangesDialog.js.map +1 -0
  46. package/dist/components/dialog/DiscardChangesDialog.mjs +930 -0
  47. package/dist/components/dialog/DiscardChangesDialog.mjs.map +1 -0
  48. package/dist/components/dialog/InputDialog.d.mts +22 -0
  49. package/dist/components/dialog/InputDialog.d.ts +22 -0
  50. package/dist/components/dialog/InputDialog.js +1139 -0
  51. package/dist/components/dialog/InputDialog.js.map +1 -0
  52. package/dist/components/dialog/InputDialog.mjs +1103 -0
  53. package/dist/components/dialog/InputDialog.mjs.map +1 -0
  54. package/dist/components/dialog/LanguageDialog.d.mts +25 -0
  55. package/dist/components/dialog/LanguageDialog.d.ts +25 -0
  56. package/dist/components/dialog/LanguageDialog.js +1684 -0
  57. package/dist/components/dialog/LanguageDialog.js.map +1 -0
  58. package/dist/components/dialog/LanguageDialog.mjs +1658 -0
  59. package/dist/components/dialog/LanguageDialog.mjs.map +1 -0
  60. package/dist/components/dialog/ThemeDialog.d.mts +26 -0
  61. package/dist/components/dialog/ThemeDialog.d.ts +26 -0
  62. package/dist/components/dialog/ThemeDialog.js +1715 -0
  63. package/dist/components/dialog/ThemeDialog.js.map +1 -0
  64. package/dist/components/dialog/ThemeDialog.mjs +1689 -0
  65. package/dist/components/dialog/ThemeDialog.mjs.map +1 -0
  66. package/dist/components/dialog/index.d.mts +17 -0
  67. package/dist/components/dialog/index.d.ts +17 -0
  68. package/dist/components/dialog/index.js +2062 -0
  69. package/dist/components/dialog/index.js.map +1 -0
  70. package/dist/components/dialog/index.mjs +2031 -0
  71. package/dist/components/dialog/index.mjs.map +1 -0
  72. package/dist/components/form/FormElementWrapper.d.mts +29 -0
  73. package/dist/components/form/FormElementWrapper.d.ts +29 -0
  74. package/dist/components/form/FormElementWrapper.js +98 -0
  75. package/dist/components/form/FormElementWrapper.js.map +1 -0
  76. package/dist/components/form/FormElementWrapper.mjs +64 -0
  77. package/dist/components/form/FormElementWrapper.mjs.map +1 -0
  78. package/dist/components/icons-and-geometry/Avatar.js +498 -2886
  79. package/dist/components/icons-and-geometry/Avatar.js.map +1 -1
  80. package/dist/components/icons-and-geometry/Avatar.mjs +490 -2878
  81. package/dist/components/icons-and-geometry/Avatar.mjs.map +1 -1
  82. package/dist/components/icons-and-geometry/{Helpwave.d.mts → HelpwaveLogo.d.mts} +3 -3
  83. package/dist/components/icons-and-geometry/{Helpwave.d.ts → HelpwaveLogo.d.ts} +3 -3
  84. package/dist/components/icons-and-geometry/{Helpwave.js → HelpwaveLogo.js} +21 -22
  85. package/dist/components/icons-and-geometry/HelpwaveLogo.js.map +1 -0
  86. package/dist/components/icons-and-geometry/{Helpwave.mjs → HelpwaveLogo.mjs} +17 -18
  87. package/dist/components/icons-and-geometry/HelpwaveLogo.mjs.map +1 -0
  88. package/dist/components/icons-and-geometry/Ring.js +1 -1
  89. package/dist/components/icons-and-geometry/Ring.js.map +1 -1
  90. package/dist/components/icons-and-geometry/Ring.mjs +1 -1
  91. package/dist/components/icons-and-geometry/Ring.mjs.map +1 -1
  92. package/dist/components/icons-and-geometry/Tag.js +8 -20
  93. package/dist/components/icons-and-geometry/Tag.js.map +1 -1
  94. package/dist/components/icons-and-geometry/Tag.mjs +8 -20
  95. package/dist/components/icons-and-geometry/Tag.mjs.map +1 -1
  96. package/dist/components/layout-and-navigation/BreadCrumb.js +667 -22
  97. package/dist/components/layout-and-navigation/BreadCrumb.js.map +1 -1
  98. package/dist/components/layout-and-navigation/BreadCrumb.mjs +667 -22
  99. package/dist/components/layout-and-navigation/BreadCrumb.mjs.map +1 -1
  100. package/dist/components/layout-and-navigation/Carousel.js +12 -10
  101. package/dist/components/layout-and-navigation/Carousel.js.map +1 -1
  102. package/dist/components/layout-and-navigation/Carousel.mjs +12 -10
  103. package/dist/components/layout-and-navigation/Carousel.mjs.map +1 -1
  104. package/dist/components/layout-and-navigation/Chip.d.mts +8 -5
  105. package/dist/components/layout-and-navigation/Chip.d.ts +8 -5
  106. package/dist/components/layout-and-navigation/Chip.js +17 -4
  107. package/dist/components/layout-and-navigation/Chip.js.map +1 -1
  108. package/dist/components/layout-and-navigation/Chip.mjs +17 -4
  109. package/dist/components/layout-and-navigation/Chip.mjs.map +1 -1
  110. package/dist/components/layout-and-navigation/Expandable.d.mts +13 -10
  111. package/dist/components/layout-and-navigation/Expandable.d.ts +13 -10
  112. package/dist/components/layout-and-navigation/Expandable.js +18 -5
  113. package/dist/components/layout-and-navigation/Expandable.js.map +1 -1
  114. package/dist/components/layout-and-navigation/Expandable.mjs +19 -6
  115. package/dist/components/layout-and-navigation/Expandable.mjs.map +1 -1
  116. package/dist/components/layout-and-navigation/FAQSection.js +21 -8
  117. package/dist/components/layout-and-navigation/FAQSection.js.map +1 -1
  118. package/dist/components/layout-and-navigation/FAQSection.mjs +22 -9
  119. package/dist/components/layout-and-navigation/FAQSection.mjs.map +1 -1
  120. package/dist/components/layout-and-navigation/FloatingContainer.d.mts +38 -0
  121. package/dist/components/layout-and-navigation/FloatingContainer.d.ts +38 -0
  122. package/dist/components/layout-and-navigation/FloatingContainer.js +219 -0
  123. package/dist/components/layout-and-navigation/FloatingContainer.js.map +1 -0
  124. package/dist/components/layout-and-navigation/FloatingContainer.mjs +195 -0
  125. package/dist/components/layout-and-navigation/FloatingContainer.mjs.map +1 -0
  126. package/dist/components/layout-and-navigation/ListBox.d.mts +44 -0
  127. package/dist/components/layout-and-navigation/ListBox.d.ts +44 -0
  128. package/dist/components/layout-and-navigation/ListBox.js +329 -0
  129. package/dist/components/layout-and-navigation/ListBox.js.map +1 -0
  130. package/dist/components/layout-and-navigation/ListBox.mjs +290 -0
  131. package/dist/components/layout-and-navigation/ListBox.mjs.map +1 -0
  132. package/dist/components/layout-and-navigation/Pagination.js +104 -189
  133. package/dist/components/layout-and-navigation/Pagination.js.map +1 -1
  134. package/dist/components/layout-and-navigation/Pagination.mjs +99 -184
  135. package/dist/components/layout-and-navigation/Pagination.mjs.map +1 -1
  136. package/dist/components/layout-and-navigation/ScrollArea.d.mts +15 -0
  137. package/dist/components/layout-and-navigation/ScrollArea.d.ts +15 -0
  138. package/dist/components/layout-and-navigation/ScrollArea.js +1252 -0
  139. package/dist/components/layout-and-navigation/ScrollArea.js.map +1 -0
  140. package/dist/components/layout-and-navigation/ScrollArea.mjs +1216 -0
  141. package/dist/components/layout-and-navigation/ScrollArea.mjs.map +1 -0
  142. package/dist/components/layout-and-navigation/StepperBar.js +41 -1
  143. package/dist/components/layout-and-navigation/StepperBar.js.map +1 -1
  144. package/dist/components/layout-and-navigation/StepperBar.mjs +41 -1
  145. package/dist/components/layout-and-navigation/StepperBar.mjs.map +1 -1
  146. package/dist/components/layout-and-navigation/TextImage.js +3 -1
  147. package/dist/components/layout-and-navigation/TextImage.js.map +1 -1
  148. package/dist/components/layout-and-navigation/TextImage.mjs +3 -1
  149. package/dist/components/layout-and-navigation/TextImage.mjs.map +1 -1
  150. package/dist/components/loading-states/ErrorComponent.js.map +1 -1
  151. package/dist/components/loading-states/ErrorComponent.mjs.map +1 -1
  152. package/dist/components/loading-states/LoadingAndErrorComponent.d.mts +1 -1
  153. package/dist/components/loading-states/LoadingAndErrorComponent.d.ts +1 -1
  154. package/dist/components/loading-states/LoadingAnimation.js +18 -17
  155. package/dist/components/loading-states/LoadingAnimation.js.map +1 -1
  156. package/dist/components/loading-states/LoadingAnimation.mjs +18 -17
  157. package/dist/components/loading-states/LoadingAnimation.mjs.map +1 -1
  158. package/dist/components/loading-states/LoadingButton.js +55 -18
  159. package/dist/components/loading-states/LoadingButton.js.map +1 -1
  160. package/dist/components/loading-states/LoadingButton.mjs +55 -18
  161. package/dist/components/loading-states/LoadingButton.mjs.map +1 -1
  162. package/dist/components/properties/CheckboxProperty.js +890 -135
  163. package/dist/components/properties/CheckboxProperty.js.map +1 -1
  164. package/dist/components/properties/CheckboxProperty.mjs +897 -142
  165. package/dist/components/properties/CheckboxProperty.mjs.map +1 -1
  166. package/dist/components/properties/DateProperty.js +153 -198
  167. package/dist/components/properties/DateProperty.js.map +1 -1
  168. package/dist/components/properties/DateProperty.mjs +146 -191
  169. package/dist/components/properties/DateProperty.mjs.map +1 -1
  170. package/dist/components/properties/MultiSelectProperty.d.mts +5 -10
  171. package/dist/components/properties/MultiSelectProperty.d.ts +5 -10
  172. package/dist/components/properties/MultiSelectProperty.js +1143 -1160
  173. package/dist/components/properties/MultiSelectProperty.js.map +1 -1
  174. package/dist/components/properties/MultiSelectProperty.mjs +1156 -1163
  175. package/dist/components/properties/MultiSelectProperty.mjs.map +1 -1
  176. package/dist/components/properties/NumberProperty.js +155 -201
  177. package/dist/components/properties/NumberProperty.js.map +1 -1
  178. package/dist/components/properties/NumberProperty.mjs +148 -194
  179. package/dist/components/properties/NumberProperty.mjs.map +1 -1
  180. package/dist/components/properties/PropertyBase.js +49 -9
  181. package/dist/components/properties/PropertyBase.js.map +1 -1
  182. package/dist/components/properties/PropertyBase.mjs +49 -9
  183. package/dist/components/properties/PropertyBase.mjs.map +1 -1
  184. package/dist/components/properties/SelectProperty.d.mts +5 -8
  185. package/dist/components/properties/SelectProperty.d.ts +5 -8
  186. package/dist/components/properties/SelectProperty.js +1047 -834
  187. package/dist/components/properties/SelectProperty.js.map +1 -1
  188. package/dist/components/properties/SelectProperty.mjs +1063 -840
  189. package/dist/components/properties/SelectProperty.mjs.map +1 -1
  190. package/dist/components/properties/TextProperty.js +97 -100
  191. package/dist/components/properties/TextProperty.js.map +1 -1
  192. package/dist/components/properties/TextProperty.mjs +100 -103
  193. package/dist/components/properties/TextProperty.mjs.map +1 -1
  194. package/dist/components/table/Table.js +1618 -993
  195. package/dist/components/table/Table.js.map +1 -1
  196. package/dist/components/table/Table.mjs +1625 -1000
  197. package/dist/components/table/Table.mjs.map +1 -1
  198. package/dist/components/table/TableFilterButton.js +116 -201
  199. package/dist/components/table/TableFilterButton.js.map +1 -1
  200. package/dist/components/table/TableFilterButton.mjs +105 -190
  201. package/dist/components/table/TableFilterButton.mjs.map +1 -1
  202. package/dist/components/table/TableSortButton.js +4 -3
  203. package/dist/components/table/TableSortButton.js.map +1 -1
  204. package/dist/components/table/TableSortButton.mjs +4 -3
  205. package/dist/components/table/TableSortButton.mjs.map +1 -1
  206. package/dist/components/user-action/Button.d.mts +15 -11
  207. package/dist/components/user-action/Button.d.ts +15 -11
  208. package/dist/components/user-action/Button.js +10 -9
  209. package/dist/components/user-action/Button.js.map +1 -1
  210. package/dist/components/user-action/Button.mjs +10 -9
  211. package/dist/components/user-action/Button.mjs.map +1 -1
  212. package/dist/components/user-action/Checkbox.d.mts +9 -25
  213. package/dist/components/user-action/Checkbox.d.ts +9 -25
  214. package/dist/components/user-action/Checkbox.js +793 -103
  215. package/dist/components/user-action/Checkbox.js.map +1 -1
  216. package/dist/components/user-action/Checkbox.mjs +794 -104
  217. package/dist/components/user-action/Checkbox.mjs.map +1 -1
  218. package/dist/components/user-action/CopyToClipboardWrapper.js +3 -1
  219. package/dist/components/user-action/CopyToClipboardWrapper.js.map +1 -1
  220. package/dist/components/user-action/CopyToClipboardWrapper.mjs +3 -1
  221. package/dist/components/user-action/CopyToClipboardWrapper.mjs.map +1 -1
  222. package/dist/components/user-action/DateAndTimePicker.d.mts +1 -1
  223. package/dist/components/user-action/DateAndTimePicker.d.ts +1 -1
  224. package/dist/components/user-action/DateAndTimePicker.js +66 -13
  225. package/dist/components/user-action/DateAndTimePicker.js.map +1 -1
  226. package/dist/components/user-action/DateAndTimePicker.mjs +67 -14
  227. package/dist/components/user-action/DateAndTimePicker.mjs.map +1 -1
  228. package/dist/components/user-action/Label.d.mts +6 -8
  229. package/dist/components/user-action/Label.d.ts +6 -8
  230. package/dist/components/user-action/Label.js +4 -6
  231. package/dist/components/user-action/Label.js.map +1 -1
  232. package/dist/components/user-action/Label.mjs +4 -6
  233. package/dist/components/user-action/Label.mjs.map +1 -1
  234. package/dist/components/user-action/Menu.d.mts +2 -2
  235. package/dist/components/user-action/Menu.d.ts +2 -2
  236. package/dist/components/user-action/Menu.js +1 -1
  237. package/dist/components/user-action/Menu.js.map +1 -1
  238. package/dist/components/user-action/Menu.mjs +1 -1
  239. package/dist/components/user-action/Menu.mjs.map +1 -1
  240. package/dist/components/user-action/ScrollPicker.js +8 -6
  241. package/dist/components/user-action/ScrollPicker.js.map +1 -1
  242. package/dist/components/user-action/ScrollPicker.mjs +8 -6
  243. package/dist/components/user-action/ScrollPicker.mjs.map +1 -1
  244. package/dist/components/user-action/SearchBar.d.mts +1 -2
  245. package/dist/components/user-action/SearchBar.d.ts +1 -2
  246. package/dist/components/user-action/SearchBar.js +93 -178
  247. package/dist/components/user-action/SearchBar.js.map +1 -1
  248. package/dist/components/user-action/SearchBar.mjs +86 -171
  249. package/dist/components/user-action/SearchBar.mjs.map +1 -1
  250. package/dist/components/user-action/Textarea.d.mts +22 -11
  251. package/dist/components/user-action/Textarea.d.ts +22 -11
  252. package/dist/components/user-action/Textarea.js +101 -92
  253. package/dist/components/user-action/Textarea.js.map +1 -1
  254. package/dist/components/user-action/Textarea.mjs +100 -92
  255. package/dist/components/user-action/Textarea.mjs.map +1 -1
  256. package/dist/components/user-action/input/Input.d.mts +37 -0
  257. package/dist/components/user-action/input/Input.d.ts +37 -0
  258. package/dist/components/user-action/input/Input.js +244 -0
  259. package/dist/components/user-action/input/Input.js.map +1 -0
  260. package/dist/components/user-action/input/Input.mjs +209 -0
  261. package/dist/components/user-action/input/Input.mjs.map +1 -0
  262. package/dist/components/user-action/input/InsideLabelInput.d.mts +20 -0
  263. package/dist/components/user-action/input/InsideLabelInput.d.ts +20 -0
  264. package/dist/components/user-action/input/InsideLabelInput.js +295 -0
  265. package/dist/components/user-action/input/InsideLabelInput.js.map +1 -0
  266. package/dist/components/user-action/input/InsideLabelInput.mjs +260 -0
  267. package/dist/components/user-action/input/InsideLabelInput.mjs.map +1 -0
  268. package/dist/components/user-action/input/ToggleableInput.d.mts +22 -0
  269. package/dist/components/user-action/input/ToggleableInput.d.ts +22 -0
  270. package/dist/components/user-action/{Input.js → input/ToggleableInput.js} +136 -171
  271. package/dist/components/user-action/input/ToggleableInput.js.map +1 -0
  272. package/dist/components/user-action/input/ToggleableInput.mjs +264 -0
  273. package/dist/components/user-action/input/ToggleableInput.mjs.map +1 -0
  274. package/dist/components/user-action/select/Select.d.mts +98 -0
  275. package/dist/components/user-action/select/Select.d.ts +98 -0
  276. package/dist/components/user-action/select/Select.js +1354 -0
  277. package/dist/components/user-action/select/Select.js.map +1 -0
  278. package/dist/components/user-action/select/Select.mjs +1320 -0
  279. package/dist/components/user-action/select/Select.mjs.map +1 -0
  280. package/dist/components/utils/FocusTrap.d.mts +28 -0
  281. package/dist/components/utils/FocusTrap.d.ts +28 -0
  282. package/dist/components/utils/FocusTrap.js +252 -0
  283. package/dist/components/utils/FocusTrap.js.map +1 -0
  284. package/dist/components/utils/FocusTrap.mjs +229 -0
  285. package/dist/components/utils/FocusTrap.mjs.map +1 -0
  286. package/dist/components/utils/Transition.d.mts +26 -0
  287. package/dist/components/utils/Transition.d.ts +26 -0
  288. package/dist/components/utils/Transition.js +74 -0
  289. package/dist/components/utils/Transition.js.map +1 -0
  290. package/dist/components/utils/Transition.mjs +50 -0
  291. package/dist/components/utils/Transition.mjs.map +1 -0
  292. package/dist/hooks/focus/useFocusGuards.d.mts +3 -0
  293. package/dist/hooks/focus/useFocusGuards.d.ts +3 -0
  294. package/dist/hooks/focus/useFocusGuards.js +74 -0
  295. package/dist/hooks/focus/useFocusGuards.js.map +1 -0
  296. package/dist/hooks/focus/useFocusGuards.mjs +50 -0
  297. package/dist/hooks/focus/useFocusGuards.mjs.map +1 -0
  298. package/dist/hooks/{useFocusManagement.js → focus/useFocusManagement.js} +1 -1
  299. package/dist/hooks/focus/useFocusManagement.js.map +1 -0
  300. package/dist/hooks/{useFocusManagement.mjs → focus/useFocusManagement.mjs} +1 -1
  301. package/dist/hooks/focus/useFocusManagement.mjs.map +1 -0
  302. package/dist/hooks/{useFocusOnceVisible.js → focus/useFocusOnceVisible.js} +1 -1
  303. package/dist/hooks/focus/useFocusOnceVisible.js.map +1 -0
  304. package/dist/hooks/{useFocusOnceVisible.mjs → focus/useFocusOnceVisible.mjs} +1 -1
  305. package/dist/hooks/focus/useFocusOnceVisible.mjs.map +1 -0
  306. package/dist/hooks/focus/useFocusTrap.d.mts +16 -0
  307. package/dist/hooks/focus/useFocusTrap.d.ts +16 -0
  308. package/dist/hooks/focus/useFocusTrap.js +233 -0
  309. package/dist/hooks/focus/useFocusTrap.js.map +1 -0
  310. package/dist/hooks/focus/useFocusTrap.mjs +210 -0
  311. package/dist/hooks/focus/useFocusTrap.mjs.map +1 -0
  312. package/dist/hooks/focus/useIsMounted.d.mts +3 -0
  313. package/dist/hooks/focus/useIsMounted.d.ts +3 -0
  314. package/dist/hooks/focus/useIsMounted.js +43 -0
  315. package/dist/hooks/focus/useIsMounted.js.map +1 -0
  316. package/dist/hooks/focus/useIsMounted.mjs +20 -0
  317. package/dist/hooks/focus/useIsMounted.mjs.map +1 -0
  318. package/dist/hooks/useFloatingElement.d.mts +22 -0
  319. package/dist/hooks/useFloatingElement.d.ts +22 -0
  320. package/dist/hooks/useFloatingElement.js +162 -0
  321. package/dist/hooks/useFloatingElement.js.map +1 -0
  322. package/dist/hooks/useFloatingElement.mjs +139 -0
  323. package/dist/hooks/useFloatingElement.mjs.map +1 -0
  324. package/dist/hooks/useLocalStorage.js +2 -2
  325. package/dist/hooks/useLocalStorage.js.map +1 -1
  326. package/dist/hooks/useLocalStorage.mjs +2 -2
  327. package/dist/hooks/useLocalStorage.mjs.map +1 -1
  328. package/dist/hooks/useLogOnce.d.mts +3 -4
  329. package/dist/hooks/useLogOnce.d.ts +3 -4
  330. package/dist/hooks/useLogOnce.js +5 -5
  331. package/dist/hooks/useLogOnce.js.map +1 -1
  332. package/dist/hooks/useLogOnce.mjs +5 -5
  333. package/dist/hooks/useLogOnce.mjs.map +1 -1
  334. package/dist/hooks/useRerender.d.mts +2 -2
  335. package/dist/hooks/useRerender.d.ts +2 -2
  336. package/dist/hooks/useSearch.d.mts +2 -2
  337. package/dist/hooks/useSearch.d.ts +2 -2
  338. package/dist/hooks/useSearch.js +1 -1
  339. package/dist/hooks/useSearch.js.map +1 -1
  340. package/dist/hooks/useSearch.mjs +1 -1
  341. package/dist/hooks/useSearch.mjs.map +1 -1
  342. package/dist/localization/LanguageProvider.d.mts +2 -2
  343. package/dist/localization/LanguageProvider.d.ts +2 -2
  344. package/dist/localization/LanguageProvider.js +2 -2
  345. package/dist/localization/LanguageProvider.js.map +1 -1
  346. package/dist/localization/LanguageProvider.mjs +2 -2
  347. package/dist/localization/LanguageProvider.mjs.map +1 -1
  348. package/dist/localization/defaults/form.d.mts +1 -0
  349. package/dist/localization/defaults/form.d.ts +1 -0
  350. package/dist/localization/defaults/form.js +2 -0
  351. package/dist/localization/defaults/form.js.map +1 -1
  352. package/dist/localization/defaults/form.mjs +2 -0
  353. package/dist/localization/defaults/form.mjs.map +1 -1
  354. package/dist/localization/useTranslation.js.map +1 -1
  355. package/dist/localization/useTranslation.mjs.map +1 -1
  356. package/dist/storybook/helper.d.mts +17 -0
  357. package/dist/storybook/helper.d.ts +17 -0
  358. package/dist/storybook/helper.js +61 -0
  359. package/dist/storybook/helper.js.map +1 -0
  360. package/dist/storybook/helper.mjs +37 -0
  361. package/dist/storybook/helper.mjs.map +1 -0
  362. package/dist/{css → style}/globals.css +779 -374
  363. package/dist/{css → style}/uncompiled/globals.css +75 -13
  364. package/dist/{css → style}/uncompiled/theme/colors-component.css +18 -4
  365. package/dist/{css → style}/uncompiled/theme/colors-semantic.css +2 -9
  366. package/dist/style/uncompiled/typography.css +171 -0
  367. package/dist/{css → style}/uncompiled/utitlity/animation.css +54 -42
  368. package/dist/{css → style}/uncompiled/utitlity/index.css +2 -1
  369. package/dist/{css → style}/uncompiled/utitlity/shadow.css +5 -1
  370. package/dist/style/uncompiled/utitlity/sizing.css +29 -0
  371. package/dist/theming/useTheme.d.mts +2 -2
  372. package/dist/theming/useTheme.d.ts +2 -2
  373. package/dist/theming/useTheme.js +3 -3
  374. package/dist/theming/useTheme.js.map +1 -1
  375. package/dist/theming/useTheme.mjs +3 -3
  376. package/dist/theming/useTheme.mjs.map +1 -1
  377. package/dist/{util → utils}/array.d.mts +1 -0
  378. package/dist/{util → utils}/array.d.ts +1 -0
  379. package/dist/{util → utils}/array.js +15 -2
  380. package/dist/utils/array.js.map +1 -0
  381. package/dist/{util → utils}/array.mjs +15 -2
  382. package/dist/utils/array.mjs.map +1 -0
  383. package/dist/utils/bagFunctions.d.mts +15 -0
  384. package/dist/utils/bagFunctions.d.ts +15 -0
  385. package/dist/{util/PropsWithFunctionChildren.js → utils/bagFunctions.js} +5 -5
  386. package/dist/utils/bagFunctions.js.map +1 -0
  387. package/dist/{util/PropsWithFunctionChildren.mjs → utils/bagFunctions.mjs} +2 -2
  388. package/dist/utils/bagFunctions.mjs.map +1 -0
  389. package/dist/{util → utils}/builder.js +1 -1
  390. package/dist/utils/builder.js.map +1 -0
  391. package/dist/{util → utils}/builder.mjs +1 -1
  392. package/dist/utils/builder.mjs.map +1 -0
  393. package/dist/{util → utils}/date.js +3 -3
  394. package/dist/utils/date.js.map +1 -0
  395. package/dist/{util → utils}/date.mjs +2 -2
  396. package/dist/utils/date.mjs.map +1 -0
  397. package/dist/{util → utils}/easeFunctions.js +5 -4
  398. package/dist/utils/easeFunctions.js.map +1 -0
  399. package/dist/{util → utils}/easeFunctions.mjs +4 -3
  400. package/dist/utils/easeFunctions.mjs.map +1 -0
  401. package/dist/{util → utils}/emailValidation.js +1 -1
  402. package/dist/utils/emailValidation.js.map +1 -0
  403. package/dist/{util → utils}/emailValidation.mjs +1 -1
  404. package/dist/utils/emailValidation.mjs.map +1 -0
  405. package/dist/{util → utils}/loopingArray.js +1 -1
  406. package/dist/utils/loopingArray.js.map +1 -0
  407. package/dist/{util → utils}/loopingArray.mjs +1 -1
  408. package/dist/utils/loopingArray.mjs.map +1 -0
  409. package/dist/utils/match.d.mts +3 -0
  410. package/dist/utils/match.d.ts +3 -0
  411. package/dist/utils/match.js +32 -0
  412. package/dist/utils/match.js.map +1 -0
  413. package/dist/utils/match.mjs +8 -0
  414. package/dist/utils/match.mjs.map +1 -0
  415. package/dist/utils/math.d.mts +3 -0
  416. package/dist/utils/math.d.ts +3 -0
  417. package/dist/{util → utils}/math.js +3 -2
  418. package/dist/utils/math.js.map +1 -0
  419. package/dist/utils/math.mjs +9 -0
  420. package/dist/utils/math.mjs.map +1 -0
  421. package/dist/{util → utils}/noop.js +1 -1
  422. package/dist/utils/noop.js.map +1 -0
  423. package/dist/utils/noop.mjs +6 -0
  424. package/dist/utils/noop.mjs.map +1 -0
  425. package/dist/{util → utils}/resolveSetState.js +1 -1
  426. package/dist/utils/resolveSetState.js.map +1 -0
  427. package/dist/{util → utils}/resolveSetState.mjs +1 -1
  428. package/dist/utils/resolveSetState.mjs.map +1 -0
  429. package/dist/{util → utils}/simpleSearch.js +1 -1
  430. package/dist/utils/simpleSearch.js.map +1 -0
  431. package/dist/{util → utils}/simpleSearch.mjs +1 -1
  432. package/dist/utils/simpleSearch.mjs.map +1 -0
  433. package/dist/{util → utils}/storage.js +1 -1
  434. package/dist/utils/storage.js.map +1 -0
  435. package/dist/{util → utils}/storage.mjs +1 -1
  436. package/dist/utils/storage.mjs.map +1 -0
  437. package/dist/{util → utils}/writeToClipboard.js +2 -1
  438. package/dist/utils/writeToClipboard.js.map +1 -0
  439. package/dist/{util → utils}/writeToClipboard.mjs +3 -1
  440. package/dist/utils/writeToClipboard.mjs.map +1 -0
  441. package/package.json +8 -8
  442. package/dist/components/dialogs/ConfirmDialog.js +0 -674
  443. package/dist/components/dialogs/ConfirmDialog.js.map +0 -1
  444. package/dist/components/dialogs/ConfirmDialog.mjs +0 -638
  445. package/dist/components/dialogs/ConfirmDialog.mjs.map +0 -1
  446. package/dist/components/icons-and-geometry/Helpwave.js.map +0 -1
  447. package/dist/components/icons-and-geometry/Helpwave.mjs.map +0 -1
  448. package/dist/components/layout-and-navigation/Overlay.d.mts +0 -67
  449. package/dist/components/layout-and-navigation/Overlay.d.ts +0 -67
  450. package/dist/components/layout-and-navigation/Overlay.js +0 -702
  451. package/dist/components/layout-and-navigation/Overlay.js.map +0 -1
  452. package/dist/components/layout-and-navigation/Overlay.mjs +0 -665
  453. package/dist/components/layout-and-navigation/Overlay.mjs.map +0 -1
  454. package/dist/components/layout-and-navigation/SearchableList.d.mts +0 -24
  455. package/dist/components/layout-and-navigation/SearchableList.d.ts +0 -24
  456. package/dist/components/layout-and-navigation/SearchableList.js +0 -758
  457. package/dist/components/layout-and-navigation/SearchableList.js.map +0 -1
  458. package/dist/components/layout-and-navigation/SearchableList.mjs +0 -724
  459. package/dist/components/layout-and-navigation/SearchableList.mjs.map +0 -1
  460. package/dist/components/layout-and-navigation/Tile.d.mts +0 -27
  461. package/dist/components/layout-and-navigation/Tile.d.ts +0 -27
  462. package/dist/components/layout-and-navigation/Tile.js +0 -96
  463. package/dist/components/layout-and-navigation/Tile.js.map +0 -1
  464. package/dist/components/layout-and-navigation/Tile.mjs +0 -61
  465. package/dist/components/layout-and-navigation/Tile.mjs.map +0 -1
  466. package/dist/components/modals/ConfirmModal.d.mts +0 -33
  467. package/dist/components/modals/ConfirmModal.d.ts +0 -33
  468. package/dist/components/modals/ConfirmModal.js +0 -687
  469. package/dist/components/modals/ConfirmModal.js.map +0 -1
  470. package/dist/components/modals/ConfirmModal.mjs +0 -651
  471. package/dist/components/modals/ConfirmModal.mjs.map +0 -1
  472. package/dist/components/modals/DiscardChangesModal.d.mts +0 -20
  473. package/dist/components/modals/DiscardChangesModal.d.ts +0 -20
  474. package/dist/components/modals/DiscardChangesModal.js +0 -717
  475. package/dist/components/modals/DiscardChangesModal.js.map +0 -1
  476. package/dist/components/modals/DiscardChangesModal.mjs +0 -681
  477. package/dist/components/modals/DiscardChangesModal.mjs.map +0 -1
  478. package/dist/components/modals/InputModal.d.mts +0 -21
  479. package/dist/components/modals/InputModal.d.ts +0 -21
  480. package/dist/components/modals/InputModal.js +0 -976
  481. package/dist/components/modals/InputModal.js.map +0 -1
  482. package/dist/components/modals/InputModal.mjs +0 -940
  483. package/dist/components/modals/InputModal.mjs.map +0 -1
  484. package/dist/components/modals/LanguageModal.d.mts +0 -21
  485. package/dist/components/modals/LanguageModal.d.ts +0 -21
  486. package/dist/components/modals/LanguageModal.js +0 -1468
  487. package/dist/components/modals/LanguageModal.js.map +0 -1
  488. package/dist/components/modals/LanguageModal.mjs +0 -1432
  489. package/dist/components/modals/LanguageModal.mjs.map +0 -1
  490. package/dist/components/modals/ThemeModal.d.mts +0 -21
  491. package/dist/components/modals/ThemeModal.d.ts +0 -21
  492. package/dist/components/modals/ThemeModal.js +0 -1497
  493. package/dist/components/modals/ThemeModal.js.map +0 -1
  494. package/dist/components/modals/ThemeModal.mjs +0 -1461
  495. package/dist/components/modals/ThemeModal.mjs.map +0 -1
  496. package/dist/components/user-action/Input.d.mts +0 -77
  497. package/dist/components/user-action/Input.d.ts +0 -77
  498. package/dist/components/user-action/Input.js.map +0 -1
  499. package/dist/components/user-action/Input.mjs +0 -298
  500. package/dist/components/user-action/Input.mjs.map +0 -1
  501. package/dist/components/user-action/MultiSelect.d.mts +0 -42
  502. package/dist/components/user-action/MultiSelect.d.ts +0 -42
  503. package/dist/components/user-action/MultiSelect.js +0 -1468
  504. package/dist/components/user-action/MultiSelect.js.map +0 -1
  505. package/dist/components/user-action/MultiSelect.mjs +0 -1433
  506. package/dist/components/user-action/MultiSelect.mjs.map +0 -1
  507. package/dist/components/user-action/Select.d.mts +0 -41
  508. package/dist/components/user-action/Select.d.ts +0 -41
  509. package/dist/components/user-action/Select.js +0 -1236
  510. package/dist/components/user-action/Select.js.map +0 -1
  511. package/dist/components/user-action/Select.mjs +0 -1201
  512. package/dist/components/user-action/Select.mjs.map +0 -1
  513. package/dist/components/user-action/ToggleableInput.d.mts +0 -37
  514. package/dist/components/user-action/ToggleableInput.d.ts +0 -37
  515. package/dist/components/user-action/ToggleableInput.js +0 -192
  516. package/dist/components/user-action/ToggleableInput.js.map +0 -1
  517. package/dist/components/user-action/ToggleableInput.mjs +0 -157
  518. package/dist/components/user-action/ToggleableInput.mjs.map +0 -1
  519. package/dist/css/uncompiled/textstyles.css +0 -69
  520. package/dist/hooks/useFocusManagement.js.map +0 -1
  521. package/dist/hooks/useFocusManagement.mjs.map +0 -1
  522. package/dist/hooks/useFocusOnceVisible.js.map +0 -1
  523. package/dist/hooks/useFocusOnceVisible.mjs.map +0 -1
  524. package/dist/index.d.mts +0 -103
  525. package/dist/index.d.ts +0 -103
  526. package/dist/index.js +0 -12610
  527. package/dist/index.js.map +0 -1
  528. package/dist/index.mjs +0 -12447
  529. package/dist/index.mjs.map +0 -1
  530. package/dist/util/PropsWithFunctionChildren.d.mts +0 -14
  531. package/dist/util/PropsWithFunctionChildren.d.ts +0 -14
  532. package/dist/util/PropsWithFunctionChildren.js.map +0 -1
  533. package/dist/util/PropsWithFunctionChildren.mjs.map +0 -1
  534. package/dist/util/array.js.map +0 -1
  535. package/dist/util/array.mjs.map +0 -1
  536. package/dist/util/builder.js.map +0 -1
  537. package/dist/util/builder.mjs.map +0 -1
  538. package/dist/util/date.js.map +0 -1
  539. package/dist/util/date.mjs.map +0 -1
  540. package/dist/util/easeFunctions.js.map +0 -1
  541. package/dist/util/easeFunctions.mjs.map +0 -1
  542. package/dist/util/emailValidation.js.map +0 -1
  543. package/dist/util/emailValidation.mjs.map +0 -1
  544. package/dist/util/loopingArray.js.map +0 -1
  545. package/dist/util/loopingArray.mjs.map +0 -1
  546. package/dist/util/math.d.mts +0 -3
  547. package/dist/util/math.d.ts +0 -3
  548. package/dist/util/math.js.map +0 -1
  549. package/dist/util/math.mjs +0 -8
  550. package/dist/util/math.mjs.map +0 -1
  551. package/dist/util/news.d.mts +0 -101
  552. package/dist/util/news.d.ts +0 -101
  553. package/dist/util/news.js +0 -76
  554. package/dist/util/news.js.map +0 -1
  555. package/dist/util/news.mjs +0 -49
  556. package/dist/util/news.mjs.map +0 -1
  557. package/dist/util/noop.js.map +0 -1
  558. package/dist/util/noop.mjs +0 -6
  559. package/dist/util/noop.mjs.map +0 -1
  560. package/dist/util/resolveSetState.js.map +0 -1
  561. package/dist/util/resolveSetState.mjs.map +0 -1
  562. package/dist/util/simpleSearch.js.map +0 -1
  563. package/dist/util/simpleSearch.mjs.map +0 -1
  564. package/dist/util/storage.js.map +0 -1
  565. package/dist/util/storage.mjs.map +0 -1
  566. package/dist/util/types.d.mts +0 -3
  567. package/dist/util/types.d.ts +0 -3
  568. package/dist/util/types.js +0 -18
  569. package/dist/util/types.js.map +0 -1
  570. package/dist/util/types.mjs +0 -1
  571. package/dist/util/types.mjs.map +0 -1
  572. package/dist/util/writeToClipboard.js.map +0 -1
  573. package/dist/util/writeToClipboard.mjs.map +0 -1
  574. /package/dist/hooks/{useFocusManagement.d.mts → focus/useFocusManagement.d.mts} +0 -0
  575. /package/dist/hooks/{useFocusManagement.d.ts → focus/useFocusManagement.d.ts} +0 -0
  576. /package/dist/hooks/{useFocusOnceVisible.d.mts → focus/useFocusOnceVisible.d.mts} +0 -0
  577. /package/dist/hooks/{useFocusOnceVisible.d.ts → focus/useFocusOnceVisible.d.ts} +0 -0
  578. /package/dist/{css → style}/uncompiled/theme/colors-basic.css +0 -0
  579. /package/dist/{css → style}/uncompiled/theme/index.css +0 -0
  580. /package/dist/{css → style}/uncompiled/theme/variants.css +0 -0
  581. /package/dist/{css → style}/uncompiled/utitlity/borderradius.css +0 -0
  582. /package/dist/{css → style}/uncompiled/utitlity/general.css +0 -0
  583. /package/dist/{util → utils}/builder.d.mts +0 -0
  584. /package/dist/{util → utils}/builder.d.ts +0 -0
  585. /package/dist/{util → utils}/date.d.mts +0 -0
  586. /package/dist/{util → utils}/date.d.ts +0 -0
  587. /package/dist/{util → utils}/easeFunctions.d.mts +0 -0
  588. /package/dist/{util → utils}/easeFunctions.d.ts +0 -0
  589. /package/dist/{util → utils}/emailValidation.d.mts +0 -0
  590. /package/dist/{util → utils}/emailValidation.d.ts +0 -0
  591. /package/dist/{util → utils}/loopingArray.d.mts +0 -0
  592. /package/dist/{util → utils}/loopingArray.d.ts +0 -0
  593. /package/dist/{util → utils}/noop.d.mts +0 -0
  594. /package/dist/{util → utils}/noop.d.ts +0 -0
  595. /package/dist/{util → utils}/resolveSetState.d.mts +0 -0
  596. /package/dist/{util → utils}/resolveSetState.d.ts +0 -0
  597. /package/dist/{util → utils}/simpleSearch.d.mts +0 -0
  598. /package/dist/{util → utils}/simpleSearch.d.ts +0 -0
  599. /package/dist/{util → utils}/storage.d.mts +0 -0
  600. /package/dist/{util → utils}/storage.d.ts +0 -0
  601. /package/dist/{util → utils}/writeToClipboard.d.mts +0 -0
  602. /package/dist/{util → utils}/writeToClipboard.d.ts +0 -0
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { RefObject, ReactNode, PropsWithChildren } from 'react';
3
- import { PropsWithBagFunctionOrChildren } from '../../util/PropsWithFunctionChildren.js';
2
+ import { PropsWithChildren, RefObject, ReactNode } from 'react';
3
+ import { PropsWithBagFunctionOrChildren } from '../../utils/bagFunctions.js';
4
4
  import { PopoverHorizontalAlignment, PopoverVerticalAlignment } from '../../hooks/usePopoverPosition.js';
5
5
 
6
6
  type MenuItemProps = {
@@ -100,7 +100,7 @@ var useHoverState = (props = void 0) => {
100
100
  };
101
101
  };
102
102
 
103
- // src/util/PropsWithFunctionChildren.ts
103
+ // src/utils/bagFunctions.ts
104
104
  var resolve = (children, bag) => {
105
105
  if (typeof children === "function") {
106
106
  return children(bag);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/user-action/Menu.tsx","../../../src/hooks/useOutsideClick.ts","../../../src/hooks/useHoverState.ts","../../../src/util/PropsWithFunctionChildren.ts","../../../src/hooks/usePopoverPosition.ts"],"sourcesContent":["import { type PropsWithChildren, type ReactNode, type RefObject, useEffect, useRef, useState } from 'react'\nimport clsx from 'clsx'\nimport { useOutsideClick } from '../../hooks/useOutsideClick'\nimport { useHoverState } from '../../hooks/useHoverState'\nimport type { PropsWithBagFunctionOrChildren } from '../../util/PropsWithFunctionChildren'\nimport { BagFunctionUtil } from '../../util/PropsWithFunctionChildren'\nimport type { PopoverHorizontalAlignment, PopoverVerticalAlignment } from '../../hooks/usePopoverPosition'\nimport { usePopoverPosition } from '../../hooks/usePopoverPosition'\nimport { createPortal } from 'react-dom'\n\nexport type MenuItemProps = {\n onClick?: () => void,\n alignment?: 'left' | 'right',\n isDisabled?: boolean,\n className?: string,\n}\nexport const MenuItem = ({\n children,\n onClick,\n alignment = 'left',\n isDisabled = false,\n className\n }: PropsWithChildren<MenuItemProps>) => (\n <div\n className={clsx('block px-3 py-1.5 first:rounded-t-md last:rounded-b-md text-sm font-semibold text-nowrap', {\n 'text-right': alignment === 'right',\n 'text-left': alignment === 'left',\n 'text-disabled-text cursor-not-allowed': isDisabled,\n 'text-menu-text hover:bg-primary/20': !isDisabled,\n 'cursor-pointer': !!onClick,\n }, className)}\n onClick={onClick}\n >\n {children}\n </div>\n)\n\nfunction getScrollableParents(element) {\n const scrollables = []\n let parent = element.parentElement\n while (parent) {\n scrollables.push(parent)\n parent = parent.parentElement\n }\n return scrollables\n}\n\nexport type MenuBag = {\n isOpen: boolean,\n disabled: boolean,\n toggleOpen: () => void,\n close: () => void,\n}\n\nexport type MenuProps<T> = PropsWithBagFunctionOrChildren<MenuBag> & {\n trigger: (bag: MenuBag, ref: RefObject<T>) => ReactNode,\n /**\n * @default 'l'\n */\n alignmentHorizontal?: PopoverHorizontalAlignment,\n alignmentVertical?: PopoverVerticalAlignment,\n showOnHover?: boolean,\n menuClassName?: string,\n disabled?: boolean,\n}\n\n/**\n * A Menu Component to allow the user to see different functions\n */\nexport const Menu = <T extends HTMLElement>({\n trigger,\n children,\n alignmentHorizontal = 'leftInside',\n alignmentVertical = 'bottomOutside',\n showOnHover = false,\n disabled = false,\n menuClassName = '',\n }: MenuProps<T>) => {\n const { isHovered: isOpen, setIsHovered: setIsOpen } = useHoverState({ isDisabled: !showOnHover || disabled })\n const triggerRef = useRef<T>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n useOutsideClick([triggerRef, menuRef], () => setIsOpen(false))\n\n const [isHidden, setIsHidden] = useState<boolean>(true)\n const bag: MenuBag = {\n isOpen,\n close: () => setIsOpen(false),\n toggleOpen: () => setIsOpen(prevState => !prevState),\n disabled,\n }\n\n const menuPosition = usePopoverPosition(\n triggerRef.current?.getBoundingClientRect(),\n { verticalAlignment: alignmentVertical, horizontalAlignment: alignmentHorizontal, disabled }\n )\n\n useEffect(() => {\n if (!isOpen) return\n\n const triggerEl = triggerRef.current\n if (!triggerEl) return\n\n const scrollableParents = getScrollableParents(triggerEl)\n\n const close = () => setIsOpen(false)\n scrollableParents.forEach((parent) => {\n parent.addEventListener('scroll', close)\n })\n window.addEventListener('resize', close)\n\n return () => {\n scrollableParents.forEach((parent) => {\n parent.removeEventListener('scroll', close)\n })\n window.removeEventListener('resize', close)\n }\n }, [isOpen, setIsOpen])\n\n useEffect(() => {\n if (isOpen) {\n setIsHidden(false)\n }\n }, [isOpen])\n\n return (\n <>\n {trigger(bag, triggerRef)}\n {createPortal((\n <div\n ref={menuRef}\n onClick={e => e.stopPropagation()}\n className={clsx(\n 'absolute rounded-md bg-menu-background text-menu-text shadow-around-lg shadow-strong z-[300]',\n {\n 'animate-pop-in': isOpen,\n 'animate-pop-out': !isOpen,\n 'hidden': isHidden,\n },\n menuClassName\n )}\n onAnimationEnd={() => {\n if (!isOpen) {\n setIsHidden(true)\n }\n }}\n style={{\n ...menuPosition\n }}\n >\n {BagFunctionUtil.resolve<MenuBag>(children, bag)}\n </div>\n ), document.body)}\n </>\n )\n}\n\n","import type { RefObject } from 'react'\nimport { useEffect } from 'react'\n\nexport const useOutsideClick = <Ts extends RefObject<HTMLElement>[]>(refs: Ts, handler: () => void) => {\n useEffect(() => {\n const listener = (event: MouseEvent | TouchEvent) => {\n // returning means not \"not clicking outside\"\n\n // if no target exists, return\n if (event.target === null) return\n // if the target is a ref's element or descendent thereof, return\n if (refs.some((ref) => !ref.current || ref.current.contains(event.target as Node))) {\n return\n }\n\n handler()\n }\n document.addEventListener('mousedown', listener)\n document.addEventListener('touchstart', listener)\n return () => {\n document.removeEventListener('mousedown', listener)\n document.removeEventListener('touchstart', listener)\n }\n }, [refs, handler])\n}\n","import type { Dispatch, SetStateAction } from 'react'\nimport { useEffect, useState } from 'react'\n\ntype UseHoverStateProps = {\n /**\n * The delay after which the menu is closed in milliseconds\n *\n * default: 200ms\n */\n closingDelay: number,\n /**\n * Whether the hover state management should be disabled\n *\n * default: false\n */\n isDisabled: boolean,\n}\n\ntype UseHoverStateReturnType = {\n /**\n * Whether the element is hovered\n */\n isHovered: boolean,\n /**\n * Function to change the current hover status\n */\n setIsHovered: Dispatch<SetStateAction<boolean>>,\n /**\n * Handlers to pass on to the component that should be hovered\n */\n handlers: {\n onMouseEnter: () => void,\n onMouseLeave: () => void,\n },\n}\n\nconst defaultUseHoverStateProps: UseHoverStateProps = {\n closingDelay: 200,\n isDisabled: false,\n}\n\n/**\n * @param props See UseHoverStateProps\n *\n * A react hook for managing the hover state of a component. The handlers provided should be\n * forwarded to the component which should be hovered over\n */\nexport const useHoverState = (props: Partial<UseHoverStateProps> | undefined = undefined): UseHoverStateReturnType => {\n const { closingDelay, isDisabled } = { ...defaultUseHoverStateProps, ...props }\n\n const [isHovered, setIsHovered] = useState(false)\n const [timer, setTimer] = useState<NodeJS.Timeout>()\n\n const onMouseEnter = () => {\n if (isDisabled) {\n return\n }\n clearTimeout(timer)\n setIsHovered(true)\n }\n\n const onMouseLeave = () => {\n if (isDisabled) {\n return\n }\n setTimer(setTimeout(() => {\n setIsHovered(false)\n }, closingDelay))\n }\n\n useEffect(() => {\n if (timer) {\n return () => {\n clearTimeout(timer)\n }\n }\n })\n\n useEffect(() => {\n if (timer) {\n clearTimeout(timer)\n }\n }, [isDisabled]) // eslint-disable-line react-hooks/exhaustive-deps\n\n return {\n isHovered, setIsHovered, handlers: { onMouseEnter, onMouseLeave }\n }\n}\n","import type { ReactNode } from 'react'\n\nexport type BagFunction<T> = (bag: T) => ReactNode\n\nexport type PropsWithBagFunction<T, P = unknown> = P & { children?: BagFunction<T> }\n\nexport type PropsWithBagFunctionOrChildren<T, P = unknown> = P & { children?: BagFunction<T> | ReactNode }\n\nconst resolve = <T>(children: BagFunction<T> | ReactNode, bag: T): ReactNode => {\n if (typeof children === 'function') {\n return (children as BagFunction<T>)(bag)\n }\n\n return children ?? undefined\n}\n\nexport const BagFunctionUtil = {\n resolve\n}","import type { CSSProperties } from 'react'\n\nexport type PopoverHorizontalAlignment = 'leftOutside' | 'leftInside' | 'rightOutside' | 'rightInside' | 'center'\nexport type PopoverVerticalAlignment = 'topOutside' | 'topInside' | 'bottomOutside' | 'bottomInside' | 'center'\n\ntype PopoverPositionOptionsResolved = {\n edgePadding: number,\n outerGap: number,\n verticalAlignment: PopoverVerticalAlignment,\n horizontalAlignment: PopoverHorizontalAlignment,\n disabled: boolean,\n}\n\ntype PopoverPositionOptions = Partial<PopoverPositionOptionsResolved>\n\nconst defaultPopoverPositionOptions: PopoverPositionOptionsResolved = {\n edgePadding: 16,\n outerGap: 4,\n horizontalAlignment: 'leftInside',\n verticalAlignment: 'bottomOutside',\n disabled: false,\n}\n\nexport const usePopoverPosition = (trigger?: DOMRect, options?: PopoverPositionOptions): CSSProperties => {\n const {\n edgePadding,\n outerGap,\n verticalAlignment,\n horizontalAlignment,\n disabled\n }: PopoverPositionOptionsResolved = { ...defaultPopoverPositionOptions, ...options }\n\n if (disabled || !trigger) {\n return {}\n }\n\n const left: number = {\n leftOutside: trigger.left - outerGap,\n leftInside: trigger.left,\n rightOutside: trigger.right + outerGap,\n rightInside: trigger.right,\n center: trigger.left + trigger.width / 2,\n }[horizontalAlignment]\n\n const top: number = {\n topOutside: trigger.top - outerGap,\n topInside: trigger.top,\n bottomOutside: trigger.bottom + outerGap,\n bottomInside: trigger.bottom,\n center: trigger.top + trigger.height / 2,\n }[verticalAlignment]\n\n const translateX: string | undefined = {\n leftOutside: '-100%',\n leftInside: undefined,\n rightOutside: undefined,\n rightInside: '-100%',\n center: '-50%',\n }[horizontalAlignment]\n\n const translateY: string | undefined = {\n topOutside: '-100%',\n topInside: undefined,\n bottomOutside: undefined,\n bottomInside: '-100%',\n center: '-50%',\n }[verticalAlignment]\n\n return {\n left: Math.max(left, edgePadding),\n top: Math.max(top, edgePadding),\n translate: [translateX ?? '0', translateY ?? '0'].join(' ')\n }\n}"],"mappings":"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","names":["import_react","import_react","clsx"]}
1
+ {"version":3,"sources":["../../../src/components/user-action/Menu.tsx","../../../src/hooks/useOutsideClick.ts","../../../src/hooks/useHoverState.ts","../../../src/utils/bagFunctions.ts","../../../src/hooks/usePopoverPosition.ts"],"sourcesContent":["import { type PropsWithChildren, type ReactNode, type RefObject, useEffect, useRef, useState } from 'react'\nimport clsx from 'clsx'\nimport { useOutsideClick } from '../../hooks/useOutsideClick'\nimport { useHoverState } from '../../hooks/useHoverState'\nimport type { PropsWithBagFunctionOrChildren } from '@/src/utils/bagFunctions'\nimport { BagFunctionUtil } from '@/src/utils/bagFunctions'\nimport type { PopoverHorizontalAlignment, PopoverVerticalAlignment } from '../../hooks/usePopoverPosition'\nimport { usePopoverPosition } from '../../hooks/usePopoverPosition'\nimport { createPortal } from 'react-dom'\n\nexport type MenuItemProps = {\n onClick?: () => void,\n alignment?: 'left' | 'right',\n isDisabled?: boolean,\n className?: string,\n}\nexport const MenuItem = ({\n children,\n onClick,\n alignment = 'left',\n isDisabled = false,\n className\n }: PropsWithChildren<MenuItemProps>) => (\n <div\n className={clsx('block px-3 py-1.5 first:rounded-t-md last:rounded-b-md text-sm font-semibold text-nowrap', {\n 'text-right': alignment === 'right',\n 'text-left': alignment === 'left',\n 'text-disabled-text cursor-not-allowed': isDisabled,\n 'text-menu-text hover:bg-primary/20': !isDisabled,\n 'cursor-pointer': !!onClick,\n }, className)}\n onClick={onClick}\n >\n {children}\n </div>\n)\n\nfunction getScrollableParents(element) {\n const scrollables = []\n let parent = element.parentElement\n while (parent) {\n scrollables.push(parent)\n parent = parent.parentElement\n }\n return scrollables\n}\n\nexport type MenuBag = {\n isOpen: boolean,\n disabled: boolean,\n toggleOpen: () => void,\n close: () => void,\n}\n\nexport type MenuProps<T> = PropsWithBagFunctionOrChildren<MenuBag> & {\n trigger: (bag: MenuBag, ref: RefObject<T>) => ReactNode,\n /**\n * @default 'l'\n */\n alignmentHorizontal?: PopoverHorizontalAlignment,\n alignmentVertical?: PopoverVerticalAlignment,\n showOnHover?: boolean,\n menuClassName?: string,\n disabled?: boolean,\n}\n\n/**\n * A Menu Component to allow the user to see different functions\n */\nexport const Menu = <T extends HTMLElement>({\n trigger,\n children,\n alignmentHorizontal = 'leftInside',\n alignmentVertical = 'bottomOutside',\n showOnHover = false,\n disabled = false,\n menuClassName = '',\n }: MenuProps<T>) => {\n const { isHovered: isOpen, setIsHovered: setIsOpen } = useHoverState({ isDisabled: !showOnHover || disabled })\n const triggerRef = useRef<T>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n useOutsideClick([triggerRef, menuRef], () => setIsOpen(false))\n\n const [isHidden, setIsHidden] = useState<boolean>(true)\n const bag: MenuBag = {\n isOpen,\n close: () => setIsOpen(false),\n toggleOpen: () => setIsOpen(prevState => !prevState),\n disabled,\n }\n\n const menuPosition = usePopoverPosition(\n triggerRef.current?.getBoundingClientRect(),\n { verticalAlignment: alignmentVertical, horizontalAlignment: alignmentHorizontal, disabled }\n )\n\n useEffect(() => {\n if (!isOpen) return\n\n const triggerEl = triggerRef.current\n if (!triggerEl) return\n\n const scrollableParents = getScrollableParents(triggerEl)\n\n const close = () => setIsOpen(false)\n scrollableParents.forEach((parent) => {\n parent.addEventListener('scroll', close)\n })\n window.addEventListener('resize', close)\n\n return () => {\n scrollableParents.forEach((parent) => {\n parent.removeEventListener('scroll', close)\n })\n window.removeEventListener('resize', close)\n }\n }, [isOpen, setIsOpen])\n\n useEffect(() => {\n if (isOpen) {\n setIsHidden(false)\n }\n }, [isOpen])\n\n return (\n <>\n {trigger(bag, triggerRef)}\n {createPortal((\n <div\n ref={menuRef}\n onClick={e => e.stopPropagation()}\n className={clsx(\n 'absolute rounded-md bg-menu-background text-menu-text shadow-around-lg shadow-strong z-[300]',\n {\n 'animate-pop-in': isOpen,\n 'animate-pop-out': !isOpen,\n 'hidden': isHidden,\n },\n menuClassName\n )}\n onAnimationEnd={() => {\n if (!isOpen) {\n setIsHidden(true)\n }\n }}\n style={{\n ...menuPosition\n }}\n >\n {BagFunctionUtil.resolve<MenuBag>(children, bag)}\n </div>\n ), document.body)}\n </>\n )\n}\n\n","import type { RefObject } from 'react'\nimport { useEffect } from 'react'\n\nexport const useOutsideClick = <Ts extends RefObject<HTMLElement>[]>(refs: Ts, handler: () => void) => {\n useEffect(() => {\n const listener = (event: MouseEvent | TouchEvent) => {\n // returning means not \"not clicking outside\"\n\n // if no target exists, return\n if (event.target === null) return\n // if the target is a ref's element or descendent thereof, return\n if (refs.some((ref) => !ref.current || ref.current.contains(event.target as Node))) {\n return\n }\n\n handler()\n }\n document.addEventListener('mousedown', listener)\n document.addEventListener('touchstart', listener)\n return () => {\n document.removeEventListener('mousedown', listener)\n document.removeEventListener('touchstart', listener)\n }\n }, [refs, handler])\n}\n","import type { Dispatch, SetStateAction } from 'react'\nimport { useEffect, useState } from 'react'\n\ntype UseHoverStateProps = {\n /**\n * The delay after which the menu is closed in milliseconds\n *\n * default: 200ms\n */\n closingDelay: number,\n /**\n * Whether the hover state management should be disabled\n *\n * default: false\n */\n isDisabled: boolean,\n}\n\ntype UseHoverStateReturnType = {\n /**\n * Whether the element is hovered\n */\n isHovered: boolean,\n /**\n * Function to change the current hover status\n */\n setIsHovered: Dispatch<SetStateAction<boolean>>,\n /**\n * Handlers to pass on to the component that should be hovered\n */\n handlers: {\n onMouseEnter: () => void,\n onMouseLeave: () => void,\n },\n}\n\nconst defaultUseHoverStateProps: UseHoverStateProps = {\n closingDelay: 200,\n isDisabled: false,\n}\n\n/**\n * @param props See UseHoverStateProps\n *\n * A react hook for managing the hover state of a component. The handlers provided should be\n * forwarded to the component which should be hovered over\n */\nexport const useHoverState = (props: Partial<UseHoverStateProps> | undefined = undefined): UseHoverStateReturnType => {\n const { closingDelay, isDisabled } = { ...defaultUseHoverStateProps, ...props }\n\n const [isHovered, setIsHovered] = useState(false)\n const [timer, setTimer] = useState<NodeJS.Timeout>()\n\n const onMouseEnter = () => {\n if (isDisabled) {\n return\n }\n clearTimeout(timer)\n setIsHovered(true)\n }\n\n const onMouseLeave = () => {\n if (isDisabled) {\n return\n }\n setTimer(setTimeout(() => {\n setIsHovered(false)\n }, closingDelay))\n }\n\n useEffect(() => {\n if (timer) {\n return () => {\n clearTimeout(timer)\n }\n }\n })\n\n useEffect(() => {\n if (timer) {\n clearTimeout(timer)\n }\n }, [isDisabled]) // eslint-disable-line react-hooks/exhaustive-deps\n\n return {\n isHovered, setIsHovered, handlers: { onMouseEnter, onMouseLeave }\n }\n}\n","import type { ReactNode } from 'react'\n\nexport type BagFunction<T> = (bag: T) => ReactNode\n\nexport type BagFunctionOrNode<T> = BagFunction<T> | ReactNode\n\nexport type PropsWithBagFunction<T, P = unknown> = P & { children?: BagFunction<T> }\n\nexport type PropsWithBagFunctionOrChildren<T, P = unknown> = P & { children?: BagFunctionOrNode<T> }\n\nconst resolve = <T>(children: BagFunctionOrNode<T>, bag: T): ReactNode => {\n if (typeof children === 'function') {\n return (children as BagFunction<T>)(bag)\n }\n\n return children ?? undefined\n}\n\nexport const BagFunctionUtil = {\n resolve\n}","import type { CSSProperties } from 'react'\n\nexport type PopoverHorizontalAlignment = 'leftOutside' | 'leftInside' | 'rightOutside' | 'rightInside' | 'center'\nexport type PopoverVerticalAlignment = 'topOutside' | 'topInside' | 'bottomOutside' | 'bottomInside' | 'center'\n\ntype PopoverPositionOptionsResolved = {\n edgePadding: number,\n outerGap: number,\n verticalAlignment: PopoverVerticalAlignment,\n horizontalAlignment: PopoverHorizontalAlignment,\n disabled: boolean,\n}\n\ntype PopoverPositionOptions = Partial<PopoverPositionOptionsResolved>\n\nconst defaultPopoverPositionOptions: PopoverPositionOptionsResolved = {\n edgePadding: 16,\n outerGap: 4,\n horizontalAlignment: 'leftInside',\n verticalAlignment: 'bottomOutside',\n disabled: false,\n}\n\nexport const usePopoverPosition = (trigger?: DOMRect, options?: PopoverPositionOptions): CSSProperties => {\n const {\n edgePadding,\n outerGap,\n verticalAlignment,\n horizontalAlignment,\n disabled\n }: PopoverPositionOptionsResolved = { ...defaultPopoverPositionOptions, ...options }\n\n if (disabled || !trigger) {\n return {}\n }\n\n const left: number = {\n leftOutside: trigger.left - outerGap,\n leftInside: trigger.left,\n rightOutside: trigger.right + outerGap,\n rightInside: trigger.right,\n center: trigger.left + trigger.width / 2,\n }[horizontalAlignment]\n\n const top: number = {\n topOutside: trigger.top - outerGap,\n topInside: trigger.top,\n bottomOutside: trigger.bottom + outerGap,\n bottomInside: trigger.bottom,\n center: trigger.top + trigger.height / 2,\n }[verticalAlignment]\n\n const translateX: string | undefined = {\n leftOutside: '-100%',\n leftInside: undefined,\n rightOutside: undefined,\n rightInside: '-100%',\n center: '-50%',\n }[horizontalAlignment]\n\n const translateY: string | undefined = {\n topOutside: '-100%',\n topInside: undefined,\n bottomOutside: undefined,\n bottomInside: '-100%',\n center: '-50%',\n }[verticalAlignment]\n\n return {\n left: Math.max(left, edgePadding),\n top: Math.max(top, edgePadding),\n translate: [translateX ?? '0', translateY ?? '0'].join(' ')\n }\n}"],"mappings":"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","names":["import_react","import_react","clsx"]}
@@ -66,7 +66,7 @@ var useHoverState = (props = void 0) => {
66
66
  };
67
67
  };
68
68
 
69
- // src/util/PropsWithFunctionChildren.ts
69
+ // src/utils/bagFunctions.ts
70
70
  var resolve = (children, bag) => {
71
71
  if (typeof children === "function") {
72
72
  return children(bag);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/user-action/Menu.tsx","../../../src/hooks/useOutsideClick.ts","../../../src/hooks/useHoverState.ts","../../../src/util/PropsWithFunctionChildren.ts","../../../src/hooks/usePopoverPosition.ts"],"sourcesContent":["import { type PropsWithChildren, type ReactNode, type RefObject, useEffect, useRef, useState } from 'react'\nimport clsx from 'clsx'\nimport { useOutsideClick } from '../../hooks/useOutsideClick'\nimport { useHoverState } from '../../hooks/useHoverState'\nimport type { PropsWithBagFunctionOrChildren } from '../../util/PropsWithFunctionChildren'\nimport { BagFunctionUtil } from '../../util/PropsWithFunctionChildren'\nimport type { PopoverHorizontalAlignment, PopoverVerticalAlignment } from '../../hooks/usePopoverPosition'\nimport { usePopoverPosition } from '../../hooks/usePopoverPosition'\nimport { createPortal } from 'react-dom'\n\nexport type MenuItemProps = {\n onClick?: () => void,\n alignment?: 'left' | 'right',\n isDisabled?: boolean,\n className?: string,\n}\nexport const MenuItem = ({\n children,\n onClick,\n alignment = 'left',\n isDisabled = false,\n className\n }: PropsWithChildren<MenuItemProps>) => (\n <div\n className={clsx('block px-3 py-1.5 first:rounded-t-md last:rounded-b-md text-sm font-semibold text-nowrap', {\n 'text-right': alignment === 'right',\n 'text-left': alignment === 'left',\n 'text-disabled-text cursor-not-allowed': isDisabled,\n 'text-menu-text hover:bg-primary/20': !isDisabled,\n 'cursor-pointer': !!onClick,\n }, className)}\n onClick={onClick}\n >\n {children}\n </div>\n)\n\nfunction getScrollableParents(element) {\n const scrollables = []\n let parent = element.parentElement\n while (parent) {\n scrollables.push(parent)\n parent = parent.parentElement\n }\n return scrollables\n}\n\nexport type MenuBag = {\n isOpen: boolean,\n disabled: boolean,\n toggleOpen: () => void,\n close: () => void,\n}\n\nexport type MenuProps<T> = PropsWithBagFunctionOrChildren<MenuBag> & {\n trigger: (bag: MenuBag, ref: RefObject<T>) => ReactNode,\n /**\n * @default 'l'\n */\n alignmentHorizontal?: PopoverHorizontalAlignment,\n alignmentVertical?: PopoverVerticalAlignment,\n showOnHover?: boolean,\n menuClassName?: string,\n disabled?: boolean,\n}\n\n/**\n * A Menu Component to allow the user to see different functions\n */\nexport const Menu = <T extends HTMLElement>({\n trigger,\n children,\n alignmentHorizontal = 'leftInside',\n alignmentVertical = 'bottomOutside',\n showOnHover = false,\n disabled = false,\n menuClassName = '',\n }: MenuProps<T>) => {\n const { isHovered: isOpen, setIsHovered: setIsOpen } = useHoverState({ isDisabled: !showOnHover || disabled })\n const triggerRef = useRef<T>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n useOutsideClick([triggerRef, menuRef], () => setIsOpen(false))\n\n const [isHidden, setIsHidden] = useState<boolean>(true)\n const bag: MenuBag = {\n isOpen,\n close: () => setIsOpen(false),\n toggleOpen: () => setIsOpen(prevState => !prevState),\n disabled,\n }\n\n const menuPosition = usePopoverPosition(\n triggerRef.current?.getBoundingClientRect(),\n { verticalAlignment: alignmentVertical, horizontalAlignment: alignmentHorizontal, disabled }\n )\n\n useEffect(() => {\n if (!isOpen) return\n\n const triggerEl = triggerRef.current\n if (!triggerEl) return\n\n const scrollableParents = getScrollableParents(triggerEl)\n\n const close = () => setIsOpen(false)\n scrollableParents.forEach((parent) => {\n parent.addEventListener('scroll', close)\n })\n window.addEventListener('resize', close)\n\n return () => {\n scrollableParents.forEach((parent) => {\n parent.removeEventListener('scroll', close)\n })\n window.removeEventListener('resize', close)\n }\n }, [isOpen, setIsOpen])\n\n useEffect(() => {\n if (isOpen) {\n setIsHidden(false)\n }\n }, [isOpen])\n\n return (\n <>\n {trigger(bag, triggerRef)}\n {createPortal((\n <div\n ref={menuRef}\n onClick={e => e.stopPropagation()}\n className={clsx(\n 'absolute rounded-md bg-menu-background text-menu-text shadow-around-lg shadow-strong z-[300]',\n {\n 'animate-pop-in': isOpen,\n 'animate-pop-out': !isOpen,\n 'hidden': isHidden,\n },\n menuClassName\n )}\n onAnimationEnd={() => {\n if (!isOpen) {\n setIsHidden(true)\n }\n }}\n style={{\n ...menuPosition\n }}\n >\n {BagFunctionUtil.resolve<MenuBag>(children, bag)}\n </div>\n ), document.body)}\n </>\n )\n}\n\n","import type { RefObject } from 'react'\nimport { useEffect } from 'react'\n\nexport const useOutsideClick = <Ts extends RefObject<HTMLElement>[]>(refs: Ts, handler: () => void) => {\n useEffect(() => {\n const listener = (event: MouseEvent | TouchEvent) => {\n // returning means not \"not clicking outside\"\n\n // if no target exists, return\n if (event.target === null) return\n // if the target is a ref's element or descendent thereof, return\n if (refs.some((ref) => !ref.current || ref.current.contains(event.target as Node))) {\n return\n }\n\n handler()\n }\n document.addEventListener('mousedown', listener)\n document.addEventListener('touchstart', listener)\n return () => {\n document.removeEventListener('mousedown', listener)\n document.removeEventListener('touchstart', listener)\n }\n }, [refs, handler])\n}\n","import type { Dispatch, SetStateAction } from 'react'\nimport { useEffect, useState } from 'react'\n\ntype UseHoverStateProps = {\n /**\n * The delay after which the menu is closed in milliseconds\n *\n * default: 200ms\n */\n closingDelay: number,\n /**\n * Whether the hover state management should be disabled\n *\n * default: false\n */\n isDisabled: boolean,\n}\n\ntype UseHoverStateReturnType = {\n /**\n * Whether the element is hovered\n */\n isHovered: boolean,\n /**\n * Function to change the current hover status\n */\n setIsHovered: Dispatch<SetStateAction<boolean>>,\n /**\n * Handlers to pass on to the component that should be hovered\n */\n handlers: {\n onMouseEnter: () => void,\n onMouseLeave: () => void,\n },\n}\n\nconst defaultUseHoverStateProps: UseHoverStateProps = {\n closingDelay: 200,\n isDisabled: false,\n}\n\n/**\n * @param props See UseHoverStateProps\n *\n * A react hook for managing the hover state of a component. The handlers provided should be\n * forwarded to the component which should be hovered over\n */\nexport const useHoverState = (props: Partial<UseHoverStateProps> | undefined = undefined): UseHoverStateReturnType => {\n const { closingDelay, isDisabled } = { ...defaultUseHoverStateProps, ...props }\n\n const [isHovered, setIsHovered] = useState(false)\n const [timer, setTimer] = useState<NodeJS.Timeout>()\n\n const onMouseEnter = () => {\n if (isDisabled) {\n return\n }\n clearTimeout(timer)\n setIsHovered(true)\n }\n\n const onMouseLeave = () => {\n if (isDisabled) {\n return\n }\n setTimer(setTimeout(() => {\n setIsHovered(false)\n }, closingDelay))\n }\n\n useEffect(() => {\n if (timer) {\n return () => {\n clearTimeout(timer)\n }\n }\n })\n\n useEffect(() => {\n if (timer) {\n clearTimeout(timer)\n }\n }, [isDisabled]) // eslint-disable-line react-hooks/exhaustive-deps\n\n return {\n isHovered, setIsHovered, handlers: { onMouseEnter, onMouseLeave }\n }\n}\n","import type { ReactNode } from 'react'\n\nexport type BagFunction<T> = (bag: T) => ReactNode\n\nexport type PropsWithBagFunction<T, P = unknown> = P & { children?: BagFunction<T> }\n\nexport type PropsWithBagFunctionOrChildren<T, P = unknown> = P & { children?: BagFunction<T> | ReactNode }\n\nconst resolve = <T>(children: BagFunction<T> | ReactNode, bag: T): ReactNode => {\n if (typeof children === 'function') {\n return (children as BagFunction<T>)(bag)\n }\n\n return children ?? undefined\n}\n\nexport const BagFunctionUtil = {\n resolve\n}","import type { CSSProperties } from 'react'\n\nexport type PopoverHorizontalAlignment = 'leftOutside' | 'leftInside' | 'rightOutside' | 'rightInside' | 'center'\nexport type PopoverVerticalAlignment = 'topOutside' | 'topInside' | 'bottomOutside' | 'bottomInside' | 'center'\n\ntype PopoverPositionOptionsResolved = {\n edgePadding: number,\n outerGap: number,\n verticalAlignment: PopoverVerticalAlignment,\n horizontalAlignment: PopoverHorizontalAlignment,\n disabled: boolean,\n}\n\ntype PopoverPositionOptions = Partial<PopoverPositionOptionsResolved>\n\nconst defaultPopoverPositionOptions: PopoverPositionOptionsResolved = {\n edgePadding: 16,\n outerGap: 4,\n horizontalAlignment: 'leftInside',\n verticalAlignment: 'bottomOutside',\n disabled: false,\n}\n\nexport const usePopoverPosition = (trigger?: DOMRect, options?: PopoverPositionOptions): CSSProperties => {\n const {\n edgePadding,\n outerGap,\n verticalAlignment,\n horizontalAlignment,\n disabled\n }: PopoverPositionOptionsResolved = { ...defaultPopoverPositionOptions, ...options }\n\n if (disabled || !trigger) {\n return {}\n }\n\n const left: number = {\n leftOutside: trigger.left - outerGap,\n leftInside: trigger.left,\n rightOutside: trigger.right + outerGap,\n rightInside: trigger.right,\n center: trigger.left + trigger.width / 2,\n }[horizontalAlignment]\n\n const top: number = {\n topOutside: trigger.top - outerGap,\n topInside: trigger.top,\n bottomOutside: trigger.bottom + outerGap,\n bottomInside: trigger.bottom,\n center: trigger.top + trigger.height / 2,\n }[verticalAlignment]\n\n const translateX: string | undefined = {\n leftOutside: '-100%',\n leftInside: undefined,\n rightOutside: undefined,\n rightInside: '-100%',\n center: '-50%',\n }[horizontalAlignment]\n\n const translateY: string | undefined = {\n topOutside: '-100%',\n topInside: undefined,\n bottomOutside: undefined,\n bottomInside: '-100%',\n center: '-50%',\n }[verticalAlignment]\n\n return {\n left: Math.max(left, edgePadding),\n top: Math.max(top, edgePadding),\n translate: [translateX ?? '0', translateY ?? '0'].join(' ')\n }\n}"],"mappings":"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","names":["useEffect","useState","useEffect","useState","useEffect"]}
1
+ {"version":3,"sources":["../../../src/components/user-action/Menu.tsx","../../../src/hooks/useOutsideClick.ts","../../../src/hooks/useHoverState.ts","../../../src/utils/bagFunctions.ts","../../../src/hooks/usePopoverPosition.ts"],"sourcesContent":["import { type PropsWithChildren, type ReactNode, type RefObject, useEffect, useRef, useState } from 'react'\nimport clsx from 'clsx'\nimport { useOutsideClick } from '../../hooks/useOutsideClick'\nimport { useHoverState } from '../../hooks/useHoverState'\nimport type { PropsWithBagFunctionOrChildren } from '@/src/utils/bagFunctions'\nimport { BagFunctionUtil } from '@/src/utils/bagFunctions'\nimport type { PopoverHorizontalAlignment, PopoverVerticalAlignment } from '../../hooks/usePopoverPosition'\nimport { usePopoverPosition } from '../../hooks/usePopoverPosition'\nimport { createPortal } from 'react-dom'\n\nexport type MenuItemProps = {\n onClick?: () => void,\n alignment?: 'left' | 'right',\n isDisabled?: boolean,\n className?: string,\n}\nexport const MenuItem = ({\n children,\n onClick,\n alignment = 'left',\n isDisabled = false,\n className\n }: PropsWithChildren<MenuItemProps>) => (\n <div\n className={clsx('block px-3 py-1.5 first:rounded-t-md last:rounded-b-md text-sm font-semibold text-nowrap', {\n 'text-right': alignment === 'right',\n 'text-left': alignment === 'left',\n 'text-disabled-text cursor-not-allowed': isDisabled,\n 'text-menu-text hover:bg-primary/20': !isDisabled,\n 'cursor-pointer': !!onClick,\n }, className)}\n onClick={onClick}\n >\n {children}\n </div>\n)\n\nfunction getScrollableParents(element) {\n const scrollables = []\n let parent = element.parentElement\n while (parent) {\n scrollables.push(parent)\n parent = parent.parentElement\n }\n return scrollables\n}\n\nexport type MenuBag = {\n isOpen: boolean,\n disabled: boolean,\n toggleOpen: () => void,\n close: () => void,\n}\n\nexport type MenuProps<T> = PropsWithBagFunctionOrChildren<MenuBag> & {\n trigger: (bag: MenuBag, ref: RefObject<T>) => ReactNode,\n /**\n * @default 'l'\n */\n alignmentHorizontal?: PopoverHorizontalAlignment,\n alignmentVertical?: PopoverVerticalAlignment,\n showOnHover?: boolean,\n menuClassName?: string,\n disabled?: boolean,\n}\n\n/**\n * A Menu Component to allow the user to see different functions\n */\nexport const Menu = <T extends HTMLElement>({\n trigger,\n children,\n alignmentHorizontal = 'leftInside',\n alignmentVertical = 'bottomOutside',\n showOnHover = false,\n disabled = false,\n menuClassName = '',\n }: MenuProps<T>) => {\n const { isHovered: isOpen, setIsHovered: setIsOpen } = useHoverState({ isDisabled: !showOnHover || disabled })\n const triggerRef = useRef<T>(null)\n const menuRef = useRef<HTMLDivElement>(null)\n useOutsideClick([triggerRef, menuRef], () => setIsOpen(false))\n\n const [isHidden, setIsHidden] = useState<boolean>(true)\n const bag: MenuBag = {\n isOpen,\n close: () => setIsOpen(false),\n toggleOpen: () => setIsOpen(prevState => !prevState),\n disabled,\n }\n\n const menuPosition = usePopoverPosition(\n triggerRef.current?.getBoundingClientRect(),\n { verticalAlignment: alignmentVertical, horizontalAlignment: alignmentHorizontal, disabled }\n )\n\n useEffect(() => {\n if (!isOpen) return\n\n const triggerEl = triggerRef.current\n if (!triggerEl) return\n\n const scrollableParents = getScrollableParents(triggerEl)\n\n const close = () => setIsOpen(false)\n scrollableParents.forEach((parent) => {\n parent.addEventListener('scroll', close)\n })\n window.addEventListener('resize', close)\n\n return () => {\n scrollableParents.forEach((parent) => {\n parent.removeEventListener('scroll', close)\n })\n window.removeEventListener('resize', close)\n }\n }, [isOpen, setIsOpen])\n\n useEffect(() => {\n if (isOpen) {\n setIsHidden(false)\n }\n }, [isOpen])\n\n return (\n <>\n {trigger(bag, triggerRef)}\n {createPortal((\n <div\n ref={menuRef}\n onClick={e => e.stopPropagation()}\n className={clsx(\n 'absolute rounded-md bg-menu-background text-menu-text shadow-around-lg shadow-strong z-[300]',\n {\n 'animate-pop-in': isOpen,\n 'animate-pop-out': !isOpen,\n 'hidden': isHidden,\n },\n menuClassName\n )}\n onAnimationEnd={() => {\n if (!isOpen) {\n setIsHidden(true)\n }\n }}\n style={{\n ...menuPosition\n }}\n >\n {BagFunctionUtil.resolve<MenuBag>(children, bag)}\n </div>\n ), document.body)}\n </>\n )\n}\n\n","import type { RefObject } from 'react'\nimport { useEffect } from 'react'\n\nexport const useOutsideClick = <Ts extends RefObject<HTMLElement>[]>(refs: Ts, handler: () => void) => {\n useEffect(() => {\n const listener = (event: MouseEvent | TouchEvent) => {\n // returning means not \"not clicking outside\"\n\n // if no target exists, return\n if (event.target === null) return\n // if the target is a ref's element or descendent thereof, return\n if (refs.some((ref) => !ref.current || ref.current.contains(event.target as Node))) {\n return\n }\n\n handler()\n }\n document.addEventListener('mousedown', listener)\n document.addEventListener('touchstart', listener)\n return () => {\n document.removeEventListener('mousedown', listener)\n document.removeEventListener('touchstart', listener)\n }\n }, [refs, handler])\n}\n","import type { Dispatch, SetStateAction } from 'react'\nimport { useEffect, useState } from 'react'\n\ntype UseHoverStateProps = {\n /**\n * The delay after which the menu is closed in milliseconds\n *\n * default: 200ms\n */\n closingDelay: number,\n /**\n * Whether the hover state management should be disabled\n *\n * default: false\n */\n isDisabled: boolean,\n}\n\ntype UseHoverStateReturnType = {\n /**\n * Whether the element is hovered\n */\n isHovered: boolean,\n /**\n * Function to change the current hover status\n */\n setIsHovered: Dispatch<SetStateAction<boolean>>,\n /**\n * Handlers to pass on to the component that should be hovered\n */\n handlers: {\n onMouseEnter: () => void,\n onMouseLeave: () => void,\n },\n}\n\nconst defaultUseHoverStateProps: UseHoverStateProps = {\n closingDelay: 200,\n isDisabled: false,\n}\n\n/**\n * @param props See UseHoverStateProps\n *\n * A react hook for managing the hover state of a component. The handlers provided should be\n * forwarded to the component which should be hovered over\n */\nexport const useHoverState = (props: Partial<UseHoverStateProps> | undefined = undefined): UseHoverStateReturnType => {\n const { closingDelay, isDisabled } = { ...defaultUseHoverStateProps, ...props }\n\n const [isHovered, setIsHovered] = useState(false)\n const [timer, setTimer] = useState<NodeJS.Timeout>()\n\n const onMouseEnter = () => {\n if (isDisabled) {\n return\n }\n clearTimeout(timer)\n setIsHovered(true)\n }\n\n const onMouseLeave = () => {\n if (isDisabled) {\n return\n }\n setTimer(setTimeout(() => {\n setIsHovered(false)\n }, closingDelay))\n }\n\n useEffect(() => {\n if (timer) {\n return () => {\n clearTimeout(timer)\n }\n }\n })\n\n useEffect(() => {\n if (timer) {\n clearTimeout(timer)\n }\n }, [isDisabled]) // eslint-disable-line react-hooks/exhaustive-deps\n\n return {\n isHovered, setIsHovered, handlers: { onMouseEnter, onMouseLeave }\n }\n}\n","import type { ReactNode } from 'react'\n\nexport type BagFunction<T> = (bag: T) => ReactNode\n\nexport type BagFunctionOrNode<T> = BagFunction<T> | ReactNode\n\nexport type PropsWithBagFunction<T, P = unknown> = P & { children?: BagFunction<T> }\n\nexport type PropsWithBagFunctionOrChildren<T, P = unknown> = P & { children?: BagFunctionOrNode<T> }\n\nconst resolve = <T>(children: BagFunctionOrNode<T>, bag: T): ReactNode => {\n if (typeof children === 'function') {\n return (children as BagFunction<T>)(bag)\n }\n\n return children ?? undefined\n}\n\nexport const BagFunctionUtil = {\n resolve\n}","import type { CSSProperties } from 'react'\n\nexport type PopoverHorizontalAlignment = 'leftOutside' | 'leftInside' | 'rightOutside' | 'rightInside' | 'center'\nexport type PopoverVerticalAlignment = 'topOutside' | 'topInside' | 'bottomOutside' | 'bottomInside' | 'center'\n\ntype PopoverPositionOptionsResolved = {\n edgePadding: number,\n outerGap: number,\n verticalAlignment: PopoverVerticalAlignment,\n horizontalAlignment: PopoverHorizontalAlignment,\n disabled: boolean,\n}\n\ntype PopoverPositionOptions = Partial<PopoverPositionOptionsResolved>\n\nconst defaultPopoverPositionOptions: PopoverPositionOptionsResolved = {\n edgePadding: 16,\n outerGap: 4,\n horizontalAlignment: 'leftInside',\n verticalAlignment: 'bottomOutside',\n disabled: false,\n}\n\nexport const usePopoverPosition = (trigger?: DOMRect, options?: PopoverPositionOptions): CSSProperties => {\n const {\n edgePadding,\n outerGap,\n verticalAlignment,\n horizontalAlignment,\n disabled\n }: PopoverPositionOptionsResolved = { ...defaultPopoverPositionOptions, ...options }\n\n if (disabled || !trigger) {\n return {}\n }\n\n const left: number = {\n leftOutside: trigger.left - outerGap,\n leftInside: trigger.left,\n rightOutside: trigger.right + outerGap,\n rightInside: trigger.right,\n center: trigger.left + trigger.width / 2,\n }[horizontalAlignment]\n\n const top: number = {\n topOutside: trigger.top - outerGap,\n topInside: trigger.top,\n bottomOutside: trigger.bottom + outerGap,\n bottomInside: trigger.bottom,\n center: trigger.top + trigger.height / 2,\n }[verticalAlignment]\n\n const translateX: string | undefined = {\n leftOutside: '-100%',\n leftInside: undefined,\n rightOutside: undefined,\n rightInside: '-100%',\n center: '-50%',\n }[horizontalAlignment]\n\n const translateY: string | undefined = {\n topOutside: '-100%',\n topInside: undefined,\n bottomOutside: undefined,\n bottomInside: '-100%',\n center: '-50%',\n }[verticalAlignment]\n\n return {\n left: Math.max(left, edgePadding),\n top: Math.max(top, edgePadding),\n translate: [translateX ?? '0', translateY ?? '0'].join(' ')\n }\n}"],"mappings":"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","names":["useEffect","useState","useEffect","useState","useEffect"]}
@@ -35,10 +35,10 @@ module.exports = __toCommonJS(ScrollPicker_exports);
35
35
  var import_react = require("react");
36
36
  var import_clsx = __toESM(require("clsx"));
37
37
 
38
- // src/util/noop.ts
38
+ // src/utils/noop.ts
39
39
  var noop = () => void 0;
40
40
 
41
- // src/util/array.ts
41
+ // src/utils/array.ts
42
42
  var defaultRangeOptions = {
43
43
  allowEmptyRange: false,
44
44
  stepSize: 1,
@@ -96,8 +96,9 @@ var getNeighbours = (list, item, neighbourDistance = 2) => {
96
96
  return result;
97
97
  };
98
98
 
99
- // src/util/math.ts
100
- var clamp = (value, min = 0, max = 1) => {
99
+ // src/utils/math.ts
100
+ var clamp = (value, range2 = [0, 1]) => {
101
+ const [min, max] = range2;
101
102
  return Math.min(Math.max(value, min), max);
102
103
  };
103
104
 
@@ -169,7 +170,7 @@ var ScrollPicker = ({
169
170
  let newVelocity = velocity;
170
171
  let usedVelocity;
171
172
  let newCurrentIndex = currentIndex2;
172
- const isAutoScrolling = velocity === 0 && (!lastScrollTimeStamp || timestamp - lastScrollTimeStamp > 300);
173
+ const isAutoScrolling = velocity <= 10 && (!lastScrollTimeStamp || timestamp - lastScrollTimeStamp > 50);
173
174
  const newLastScrollTimeStamp = velocity !== 0 ? timestamp : lastScrollTimeStamp;
174
175
  if (isAutoScrolling) {
175
176
  usedVelocity = direction * animationVelocity;
@@ -248,7 +249,8 @@ var ScrollPicker = ({
248
249
  style: { height: containerHeight },
249
250
  onWheel: (event) => {
250
251
  if (event.deltaY !== 0) {
251
- setAnimation(({ velocity, ...animationData }) => ({ ...animationData, velocity: velocity + event.deltaY }));
252
+ const deltaY = clamp(event.deltaY, [-itemHeight * 2 / 3, itemHeight * 2 / 3]);
253
+ setAnimation(({ velocity, ...animationData }) => ({ ...animationData, velocity: velocity + deltaY }));
252
254
  }
253
255
  },
254
256
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute top-1/2 -translate-y-1/2 -translate-x-1/2 left-1/2", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/user-action/ScrollPicker.tsx","../../../src/util/noop.ts","../../../src/util/array.ts","../../../src/util/math.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\nimport clsx from 'clsx'\nimport { noop } from '../../util/noop'\nimport { getNeighbours, range } from '../../util/array'\nimport { clamp } from '../../util/math'\n\nexport type ScrollPickerProps<T> = {\n options: T[],\n mapping: (value: T) => string,\n selected?: T,\n onChange?: (value: T) => void,\n disabled?: boolean,\n}\n\ntype AnimationData<T> = {\n /** The index we scroll to */\n targetIndex: number,\n /** The index we are currently showing centered */\n currentIndex: number,\n items: T[],\n /** From -0.5 to 0.5 */\n transition: number,\n velocity: number,\n animationVelocity: number,\n lastTimeStamp?: number,\n lastScrollTimeStamp?: number,\n}\n\nconst up = 1\nconst down = -1\ntype Direction = 1 | -1\n\n/**\n * A component for picking an option by scrolling\n */\nexport const ScrollPicker = <T, >({\n options,\n mapping,\n selected,\n onChange = noop,\n disabled = false,\n }: ScrollPickerProps<T>) => {\n let selectedIndex = 0\n if (selected && options.indexOf(selected) !== -1) {\n selectedIndex = options.indexOf(selected)\n }\n const [{\n currentIndex,\n transition,\n items,\n lastTimeStamp\n }, setAnimation] = useState<AnimationData<T>>({\n targetIndex: selectedIndex,\n currentIndex: disabled ? selectedIndex : 0,\n velocity: 0,\n animationVelocity: Math.floor(options.length / 2),\n transition: 0,\n items: options,\n })\n\n const itemsShownCount = 5\n const shownItems = getNeighbours(range(items.length), currentIndex).map(index => ({\n name: mapping(items[index]!), index\n }))\n\n const itemHeight = 40\n const distance = 8\n\n const containerHeight = itemHeight * (itemsShownCount - 2) + distance * (itemsShownCount - 2 + 1)\n\n const getDirection = useCallback((targetIndex: number, currentIndex: number, transition: number, length: number): Direction => {\n if (targetIndex === currentIndex) {\n return transition > 0 ? up : down\n }\n let distanceForward = targetIndex - currentIndex\n if (distanceForward < 0) {\n distanceForward += length\n }\n return distanceForward >= length / 2 ? down : up\n }, [])\n\n const animate = useCallback((timestamp: number, startTime: number | undefined) => {\n setAnimation((prevState) => {\n const {\n targetIndex,\n currentIndex,\n transition,\n animationVelocity,\n velocity,\n items,\n lastScrollTimeStamp\n } = prevState\n if (disabled) {\n return { ...prevState, currentIndex: targetIndex, velocity: 0, lastTimeStamp: timestamp }\n }\n if ((targetIndex === currentIndex && velocity === 0 && transition === 0) || !startTime) {\n return { ...prevState, lastTimeStamp: timestamp }\n }\n const progress = (timestamp - startTime) / 1000 // to seconds\n const direction = getDirection(targetIndex, currentIndex, transition, items.length)\n\n let newVelocity = velocity\n let usedVelocity\n let newCurrentIndex = currentIndex\n const isAutoScrolling = velocity === 0 && (!lastScrollTimeStamp || timestamp - lastScrollTimeStamp > 300)\n\n const newLastScrollTimeStamp = velocity !== 0 ? timestamp : lastScrollTimeStamp\n\n // manual scrolling\n if (isAutoScrolling) {\n usedVelocity = direction * animationVelocity\n } else {\n usedVelocity = velocity\n newVelocity = velocity * 0.5 // drag loss\n if (Math.abs(newVelocity) <= 0.05) {\n newVelocity = 0\n }\n }\n\n let newTransition = transition + usedVelocity * progress\n const changeThreshold = 0.5\n\n while (newTransition >= changeThreshold) {\n if (newCurrentIndex === targetIndex && newTransition >= changeThreshold && isAutoScrolling) {\n newTransition = 0\n break\n }\n newCurrentIndex = (currentIndex + 1) % items.length\n newTransition -= 1\n }\n if (newTransition >= changeThreshold) {\n newTransition = 0\n }\n while (newTransition <= -changeThreshold) {\n if (newCurrentIndex === targetIndex && newTransition <= -changeThreshold && isAutoScrolling) {\n newTransition = 0\n break\n }\n newCurrentIndex = currentIndex === 0 ? items.length - 1 : currentIndex - 1\n newTransition += 1\n }\n let newTargetIndex = targetIndex\n if (!isAutoScrolling) {\n newTargetIndex = newCurrentIndex\n }\n\n if ((currentIndex !== newTargetIndex || newTargetIndex !== targetIndex) && newTargetIndex === newCurrentIndex) {\n onChange(items[newCurrentIndex]!)\n }\n return {\n targetIndex: newTargetIndex,\n currentIndex: newCurrentIndex,\n animationVelocity,\n transition: newTransition,\n velocity: newVelocity,\n items,\n lastTimeStamp: timestamp,\n lastScrollTimeStamp: newLastScrollTimeStamp\n }\n })\n }, [disabled, getDirection, onChange])\n\n useEffect(() => {\n // constant update\n requestAnimationFrame((timestamp) => animate(timestamp, lastTimeStamp))\n })\n\n const opacity = (transition: number, index: number, itemsCount: number) => {\n const max = 100\n const min = 0\n const distance = max - min\n\n let opacityValue = min\n const unitTransition = clamp((transition) / 0.5)\n if (index === 1 || index === itemsCount - 2) {\n if (index === 1 && transition > 0) {\n opacityValue += Math.floor(unitTransition * distance)\n }\n if (index === itemsCount - 2 && transition < 0) {\n opacityValue += Math.floor(unitTransition * distance)\n }\n } else {\n opacityValue = max\n }\n\n // TODO this is not the right value for the bottom entry\n return clamp(1 - (opacityValue / max))\n }\n\n return (\n <div\n className=\"relative overflow-hidden\"\n style={{ height: containerHeight }}\n onWheel={event => {\n if (event.deltaY !== 0) {\n // TODO slower increase\n setAnimation(({ velocity, ...animationData }) =>\n ({ ...animationData, velocity: velocity + event.deltaY }))\n }\n }}\n >\n <div className=\"absolute top-1/2 -translate-y-1/2 -translate-x-1/2 left-1/2\">\n <div\n className=\"absolute z-[1] top-1/2 -translate-y-1/2 -translate-x-1/2 left-1/2 w-full min-w-[40px] border border-divider/50 border-y-2 border-x-0 \"\n style={{ height: `${itemHeight}px` }}\n />\n <div\n className=\"flex-col-2 select-none\"\n style={{\n transform: `translateY(${-transition * (distance + itemHeight)}px)`,\n columnGap: `${distance}px`,\n }}\n >\n {shownItems.map(({ name, index }, arrayIndex) => (\n <div\n key={index}\n className={clsx(\n `flex-col-2 items-center justify-center rounded-md`,\n {\n 'text-primary font-bold': currentIndex === index,\n 'text-on-background': currentIndex === index,\n 'cursor-pointer': !disabled,\n 'cursor-not-allowed': disabled,\n }\n )}\n style={{\n opacity: currentIndex !== index ? opacity(transition, arrayIndex, shownItems.length) : undefined,\n height: `${itemHeight}px`,\n maxHeight: `${itemHeight}px`,\n }}\n onClick={() => !disabled && setAnimation(prevState => ({ ...prevState, targetIndex: index }))}\n >\n {name}\n </div>\n ))}\n </div>\n </div>\n </div>\n )\n}\n","export const noop = () => undefined\n","export const equalSizeGroups = <T>(array: T[], groupSize: number): T[][] => {\n if (groupSize <= 0) {\n console.warn(`group size should be greater than 0: groupSize = ${groupSize}`)\n return [[...array]]\n }\n\n const groups = []\n for (let i = 0; i < array.length; i += groupSize) {\n groups.push(array.slice(i, Math.min(i + groupSize, array.length)))\n }\n return groups\n}\n\nexport type RangeOptions = {\n /** Whether the range can be defined empty via end < start without a warning */\n allowEmptyRange: boolean,\n stepSize: number,\n exclusiveStart: boolean,\n exclusiveEnd: boolean,\n}\n\nconst defaultRangeOptions: RangeOptions = {\n allowEmptyRange: false,\n stepSize: 1,\n exclusiveStart: false,\n exclusiveEnd: true,\n}\n\n/**\n * @param endOrRange The end value or a range [start, end], end is exclusive\n * @param options the options for defining the range\n */\nexport const range = (endOrRange: number | [number, number], options?: Partial<RangeOptions>): number[] => {\n const { allowEmptyRange, stepSize, exclusiveStart, exclusiveEnd } = { ...defaultRangeOptions, ...options }\n let start = 0\n let end: number\n if (typeof endOrRange === 'number') {\n end = endOrRange\n } else {\n start = endOrRange[0]\n end = endOrRange[1]\n }\n if (!exclusiveEnd) {\n end -= 1\n }\n if (exclusiveStart) {\n start += 1\n }\n\n if (end - 1 < start) {\n if (!allowEmptyRange) {\n console.warn(`range: end (${end}) < start (${start}) should be allowed explicitly, set options.allowEmptyRange to true`)\n }\n return []\n }\n return Array.from({ length: end - start }, (_, index) => index * stepSize + start)\n}\n\n/** Finds the closest match\n * @param list The list of all possible matches\n * @param firstCloser Return whether item1 is closer than item2\n */\nexport const closestMatch = <T>(list: T[], firstCloser: (item1: T, item2: T) => boolean) => {\n return list.reduce((item1, item2) => {\n return firstCloser(item1, item2) ? item1 : item2\n })\n}\n\n/**\n * returns the item in middle of a list and its neighbours before and after\n * e.g. [1,2,3,4,5,6] for item = 1 would return [5,6,1,2,3]\n */\nexport const getNeighbours = <T>(list: T[], item: T, neighbourDistance: number = 2) => {\n const index = list.indexOf(item)\n const totalItems = neighbourDistance * 2 + 1\n if (list.length < totalItems) {\n console.warn('List is to short')\n return list\n }\n\n if (index === -1) {\n console.error('item not found in list')\n return list.splice(0, totalItems)\n }\n\n let start = index - neighbourDistance\n if (start < 0) {\n start += list.length\n }\n const end = (index + neighbourDistance + 1) % list.length\n\n const result: T[] = []\n let ignoreOnce = list.length === totalItems\n for (let i = start; i !== end || ignoreOnce; i = (i + 1) % list.length) {\n result.push(list[i]!)\n if (end === i && ignoreOnce) {\n ignoreOnce = false\n }\n }\n return result\n}\n\nexport const createLoopingListWithIndex = <T>(list: T[], startIndex: number = 0, length: number = 0, forwards: boolean = true) => {\n if (length < 0) {\n console.warn(`createLoopingList: length must be >= 0, given ${length}`)\n } else if (length === 0) {\n length = list.length\n }\n\n const returnList: [number, T][] = []\n\n if (forwards) {\n for (let i = startIndex; returnList.length < length; i = (i + 1) % list.length) {\n returnList.push([i, list[i]!])\n }\n } else {\n for (let i = startIndex; returnList.length < length; i = i === 0 ? i = list.length - 1 : i - 1) {\n returnList.push([i, list[i]!])\n }\n }\n\n return returnList\n}\n\nexport const createLoopingList = <T>(list: T[], startIndex: number = 0, length: number = 0, forwards: boolean = true) => {\n return createLoopingListWithIndex(list, startIndex, length, forwards).map(([_, item]) => item)\n}\n\nexport const ArrayUtil = {\n unique: <T>(list: T[]): T[] => {\n const seen = new Set<T>()\n return list.filter((item) => {\n if (seen.has(item)) {\n return false\n }\n seen.add(item)\n return true\n })\n },\n\n difference: <T>(list: T[], removeList: T[]): T[] => {\n const remove = new Set<T>(removeList)\n return list.filter((item) => !remove.has(item))\n }\n}\n","export const clamp = (value: number, min: number = 0, max: number = 1): number => {\n return Math.min(Math.max(value, min), max)\n}\n"],"mappings":"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","names":["currentIndex","transition","items","distance","clsx"]}
1
+ {"version":3,"sources":["../../../src/components/user-action/ScrollPicker.tsx","../../../src/utils/noop.ts","../../../src/utils/array.ts","../../../src/utils/math.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\nimport clsx from 'clsx'\nimport { noop } from '@/src/utils/noop'\nimport { getNeighbours, range } from '@/src/utils/array'\nimport { clamp } from '@/src/utils/math'\n\nexport type ScrollPickerProps<T> = {\n options: T[],\n mapping: (value: T) => string,\n selected?: T,\n onChange?: (value: T) => void,\n disabled?: boolean,\n}\n\ntype AnimationData<T> = {\n /** The index we scroll to */\n targetIndex: number,\n /** The index we are currently showing centered */\n currentIndex: number,\n items: T[],\n /** From -0.5 to 0.5 */\n transition: number,\n velocity: number,\n animationVelocity: number,\n lastTimeStamp?: number,\n lastScrollTimeStamp?: number,\n}\n\nconst up = 1\nconst down = -1\ntype Direction = 1 | -1\n\n/**\n * A component for picking an option by scrolling\n */\nexport const ScrollPicker = <T, >({\n options,\n mapping,\n selected,\n onChange = noop,\n disabled = false,\n }: ScrollPickerProps<T>) => {\n let selectedIndex = 0\n if (selected && options.indexOf(selected) !== -1) {\n selectedIndex = options.indexOf(selected)\n }\n const [{\n currentIndex,\n transition,\n items,\n lastTimeStamp\n }, setAnimation] = useState<AnimationData<T>>({\n targetIndex: selectedIndex,\n currentIndex: disabled ? selectedIndex : 0,\n velocity: 0,\n animationVelocity: Math.floor(options.length / 2),\n transition: 0,\n items: options,\n })\n\n const itemsShownCount = 5\n const shownItems = getNeighbours(range(items.length), currentIndex).map(index => ({\n name: mapping(items[index]!), index\n }))\n\n const itemHeight = 40\n const distance = 8\n\n const containerHeight = itemHeight * (itemsShownCount - 2) + distance * (itemsShownCount - 2 + 1)\n\n const getDirection = useCallback((targetIndex: number, currentIndex: number, transition: number, length: number): Direction => {\n if (targetIndex === currentIndex) {\n return transition > 0 ? up : down\n }\n let distanceForward = targetIndex - currentIndex\n if (distanceForward < 0) {\n distanceForward += length\n }\n return distanceForward >= length / 2 ? down : up\n }, [])\n\n const animate = useCallback((timestamp: number, startTime: number | undefined) => {\n setAnimation((prevState) => {\n const {\n targetIndex,\n currentIndex,\n transition,\n animationVelocity,\n velocity,\n items,\n lastScrollTimeStamp\n } = prevState\n if (disabled) {\n return { ...prevState, currentIndex: targetIndex, velocity: 0, lastTimeStamp: timestamp }\n }\n if ((targetIndex === currentIndex && velocity === 0 && transition === 0) || !startTime) {\n return { ...prevState, lastTimeStamp: timestamp }\n }\n const progress = (timestamp - startTime) / 1000 // to seconds\n const direction = getDirection(targetIndex, currentIndex, transition, items.length)\n\n let newVelocity = velocity\n let usedVelocity\n let newCurrentIndex = currentIndex\n const isAutoScrolling = velocity <= 10 && (!lastScrollTimeStamp || timestamp - lastScrollTimeStamp > 50)\n\n const newLastScrollTimeStamp = velocity !== 0 ? timestamp : lastScrollTimeStamp\n\n // manual scrolling\n if (isAutoScrolling) {\n usedVelocity = direction * animationVelocity\n } else {\n usedVelocity = velocity\n newVelocity = velocity * 0.5 // drag loss\n if (Math.abs(newVelocity) <= 0.05) {\n newVelocity = 0\n }\n }\n\n let newTransition = transition + usedVelocity * progress\n const changeThreshold = 0.5\n\n while (newTransition >= changeThreshold) {\n if (newCurrentIndex === targetIndex && newTransition >= changeThreshold && isAutoScrolling) {\n newTransition = 0\n break\n }\n newCurrentIndex = (currentIndex + 1) % items.length\n newTransition -= 1\n }\n if (newTransition >= changeThreshold) {\n newTransition = 0\n }\n while (newTransition <= -changeThreshold) {\n if (newCurrentIndex === targetIndex && newTransition <= -changeThreshold && isAutoScrolling) {\n newTransition = 0\n break\n }\n newCurrentIndex = currentIndex === 0 ? items.length - 1 : currentIndex - 1\n newTransition += 1\n }\n let newTargetIndex = targetIndex\n if (!isAutoScrolling) {\n newTargetIndex = newCurrentIndex\n }\n\n if ((currentIndex !== newTargetIndex || newTargetIndex !== targetIndex) && newTargetIndex === newCurrentIndex) {\n onChange(items[newCurrentIndex]!)\n }\n return {\n targetIndex: newTargetIndex,\n currentIndex: newCurrentIndex,\n animationVelocity,\n transition: newTransition,\n velocity: newVelocity,\n items,\n lastTimeStamp: timestamp,\n lastScrollTimeStamp: newLastScrollTimeStamp\n }\n })\n }, [disabled, getDirection, onChange])\n\n useEffect(() => {\n // constant update\n requestAnimationFrame((timestamp) => animate(timestamp, lastTimeStamp))\n })\n\n const opacity = (transition: number, index: number, itemsCount: number) => {\n const max = 100\n const min = 0\n const distance = max - min\n\n let opacityValue = min\n const unitTransition = clamp((transition) / 0.5)\n if (index === 1 || index === itemsCount - 2) {\n if (index === 1 && transition > 0) {\n opacityValue += Math.floor(unitTransition * distance)\n }\n if (index === itemsCount - 2 && transition < 0) {\n opacityValue += Math.floor(unitTransition * distance)\n }\n } else {\n opacityValue = max\n }\n\n // TODO this is not the right value for the bottom entry\n return clamp(1 - (opacityValue / max))\n }\n\n return (\n <div\n className=\"relative overflow-hidden\"\n style={{ height: containerHeight }}\n onWheel={event => {\n if (event.deltaY !== 0) {\n const deltaY = clamp(event.deltaY,[-itemHeight*2/3, itemHeight*2/3])\n // TODO slower increase\n setAnimation(({ velocity, ...animationData }) =>\n ({ ...animationData, velocity: velocity + deltaY }))\n }\n }}\n >\n <div className=\"absolute top-1/2 -translate-y-1/2 -translate-x-1/2 left-1/2\">\n <div\n className=\"absolute z-[1] top-1/2 -translate-y-1/2 -translate-x-1/2 left-1/2 w-full min-w-[40px] border border-divider/50 border-y-2 border-x-0 \"\n style={{ height: `${itemHeight}px` }}\n />\n <div\n className=\"flex-col-2 select-none\"\n style={{\n transform: `translateY(${-transition * (distance + itemHeight)}px)`,\n columnGap: `${distance}px`,\n }}\n >\n {shownItems.map(({ name, index }, arrayIndex) => (\n <div\n key={index}\n className={clsx(\n `flex-col-2 items-center justify-center rounded-md`,\n {\n 'text-primary font-bold': currentIndex === index,\n 'text-on-background': currentIndex === index,\n 'cursor-pointer': !disabled,\n 'cursor-not-allowed': disabled,\n }\n )}\n style={{\n opacity: currentIndex !== index ? opacity(transition, arrayIndex, shownItems.length) : undefined,\n height: `${itemHeight}px`,\n maxHeight: `${itemHeight}px`,\n }}\n onClick={() => !disabled && setAnimation(prevState => ({ ...prevState, targetIndex: index }))}\n >\n {name}\n </div>\n ))}\n </div>\n </div>\n </div>\n )\n}\n","export const noop = () => undefined\n","export const equalSizeGroups = <T>(array: T[], groupSize: number): T[][] => {\n if (groupSize <= 0) {\n console.warn(`group size should be greater than 0: groupSize = ${groupSize}`)\n return [[...array]]\n }\n\n const groups = []\n for (let i = 0; i < array.length; i += groupSize) {\n groups.push(array.slice(i, Math.min(i + groupSize, array.length)))\n }\n return groups\n}\n\nexport type RangeOptions = {\n /** Whether the range can be defined empty via end < start without a warning */\n allowEmptyRange: boolean,\n stepSize: number,\n exclusiveStart: boolean,\n exclusiveEnd: boolean,\n}\n\nconst defaultRangeOptions: RangeOptions = {\n allowEmptyRange: false,\n stepSize: 1,\n exclusiveStart: false,\n exclusiveEnd: true,\n}\n\n/**\n * @param endOrRange The end value or a range [start, end], end is exclusive\n * @param options the options for defining the range\n */\nexport const range = (endOrRange: number | [number, number], options?: Partial<RangeOptions>): number[] => {\n const { allowEmptyRange, stepSize, exclusiveStart, exclusiveEnd } = { ...defaultRangeOptions, ...options }\n let start = 0\n let end: number\n if (typeof endOrRange === 'number') {\n end = endOrRange\n } else {\n start = endOrRange[0]\n end = endOrRange[1]\n }\n if (!exclusiveEnd) {\n end -= 1\n }\n if (exclusiveStart) {\n start += 1\n }\n\n if (end - 1 < start) {\n if (!allowEmptyRange) {\n console.warn(`range: end (${end}) < start (${start}) should be allowed explicitly, set options.allowEmptyRange to true`)\n }\n return []\n }\n return Array.from({ length: end - start }, (_, index) => index * stepSize + start)\n}\n\n/** Finds the closest match\n * @param list The list of all possible matches\n * @param firstCloser Return whether item1 is closer than item2\n */\nexport const closestMatch = <T>(list: T[], firstCloser: (item1: T, item2: T) => boolean) => {\n return list.reduce((item1, item2) => {\n return firstCloser(item1, item2) ? item1 : item2\n })\n}\n\n/**\n * returns the item in middle of a list and its neighbours before and after\n * e.g. [1,2,3,4,5,6] for item = 1 would return [5,6,1,2,3]\n */\nexport const getNeighbours = <T>(list: T[], item: T, neighbourDistance: number = 2) => {\n const index = list.indexOf(item)\n const totalItems = neighbourDistance * 2 + 1\n if (list.length < totalItems) {\n console.warn('List is to short')\n return list\n }\n\n if (index === -1) {\n console.error('item not found in list')\n return list.splice(0, totalItems)\n }\n\n let start = index - neighbourDistance\n if (start < 0) {\n start += list.length\n }\n const end = (index + neighbourDistance + 1) % list.length\n\n const result: T[] = []\n let ignoreOnce = list.length === totalItems\n for (let i = start; i !== end || ignoreOnce; i = (i + 1) % list.length) {\n result.push(list[i]!)\n if (end === i && ignoreOnce) {\n ignoreOnce = false\n }\n }\n return result\n}\n\nexport const createLoopingListWithIndex = <T>(list: T[], startIndex: number = 0, length: number = 0, forwards: boolean = true) => {\n if (length < 0) {\n console.warn(`createLoopingList: length must be >= 0, given ${length}`)\n } else if (length === 0) {\n length = list.length\n }\n\n const returnList: [number, T][] = []\n\n if (forwards) {\n for (let i = startIndex; returnList.length < length; i = (i + 1) % list.length) {\n returnList.push([i, list[i]!])\n }\n } else {\n for (let i = startIndex; returnList.length < length; i = i === 0 ? i = list.length - 1 : i - 1) {\n returnList.push([i, list[i]!])\n }\n }\n\n return returnList\n}\n\nexport const createLoopingList = <T>(list: T[], startIndex: number = 0, length: number = 0, forwards: boolean = true) => {\n return createLoopingListWithIndex(list, startIndex, length, forwards).map(([_, item]) => item)\n}\n\n/**\n * @param list The list to be changed\n * @param move The shifting applied to the array (can be negative)\n */\nconst moveItems = <T>(list: T[], move: number = 0) => {\n const result = []\n let start = move\n if (start < 0) {\n start = list.length - move\n }\n start = start % list.length\n for (let i = 0; i < list.length; i++) {\n result[i] = list[(i + start) % list.length]\n }\n return result\n}\n\nexport const ArrayUtil = {\n unique: <T>(list: T[]): T[] => {\n const seen = new Set<T>()\n return list.filter((item) => {\n if (seen.has(item)) {\n return false\n }\n seen.add(item)\n return true\n })\n },\n difference: <T>(list: T[], removeList: T[]): T[] => {\n const remove = new Set<T>(removeList)\n return list.filter((item) => !remove.has(item))\n },\n moveItems,\n}\n","export const clamp = (value: number, range: [number, number] = [0, 1]): number => {\n const [min, max] = range\n return Math.min(Math.max(value, min), max)\n}\n"],"mappings":"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","names":["range","currentIndex","transition","items","distance","clsx"]}
@@ -2,10 +2,10 @@
2
2
  import { useCallback, useEffect, useState } from "react";
3
3
  import clsx from "clsx";
4
4
 
5
- // src/util/noop.ts
5
+ // src/utils/noop.ts
6
6
  var noop = () => void 0;
7
7
 
8
- // src/util/array.ts
8
+ // src/utils/array.ts
9
9
  var defaultRangeOptions = {
10
10
  allowEmptyRange: false,
11
11
  stepSize: 1,
@@ -63,8 +63,9 @@ var getNeighbours = (list, item, neighbourDistance = 2) => {
63
63
  return result;
64
64
  };
65
65
 
66
- // src/util/math.ts
67
- var clamp = (value, min = 0, max = 1) => {
66
+ // src/utils/math.ts
67
+ var clamp = (value, range2 = [0, 1]) => {
68
+ const [min, max] = range2;
68
69
  return Math.min(Math.max(value, min), max);
69
70
  };
70
71
 
@@ -136,7 +137,7 @@ var ScrollPicker = ({
136
137
  let newVelocity = velocity;
137
138
  let usedVelocity;
138
139
  let newCurrentIndex = currentIndex2;
139
- const isAutoScrolling = velocity === 0 && (!lastScrollTimeStamp || timestamp - lastScrollTimeStamp > 300);
140
+ const isAutoScrolling = velocity <= 10 && (!lastScrollTimeStamp || timestamp - lastScrollTimeStamp > 50);
140
141
  const newLastScrollTimeStamp = velocity !== 0 ? timestamp : lastScrollTimeStamp;
141
142
  if (isAutoScrolling) {
142
143
  usedVelocity = direction * animationVelocity;
@@ -215,7 +216,8 @@ var ScrollPicker = ({
215
216
  style: { height: containerHeight },
216
217
  onWheel: (event) => {
217
218
  if (event.deltaY !== 0) {
218
- setAnimation(({ velocity, ...animationData }) => ({ ...animationData, velocity: velocity + event.deltaY }));
219
+ const deltaY = clamp(event.deltaY, [-itemHeight * 2 / 3, itemHeight * 2 / 3]);
220
+ setAnimation(({ velocity, ...animationData }) => ({ ...animationData, velocity: velocity + deltaY }));
219
221
  }
220
222
  },
221
223
  children: /* @__PURE__ */ jsxs("div", { className: "absolute top-1/2 -translate-y-1/2 -translate-x-1/2 left-1/2", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/user-action/ScrollPicker.tsx","../../../src/util/noop.ts","../../../src/util/array.ts","../../../src/util/math.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\nimport clsx from 'clsx'\nimport { noop } from '../../util/noop'\nimport { getNeighbours, range } from '../../util/array'\nimport { clamp } from '../../util/math'\n\nexport type ScrollPickerProps<T> = {\n options: T[],\n mapping: (value: T) => string,\n selected?: T,\n onChange?: (value: T) => void,\n disabled?: boolean,\n}\n\ntype AnimationData<T> = {\n /** The index we scroll to */\n targetIndex: number,\n /** The index we are currently showing centered */\n currentIndex: number,\n items: T[],\n /** From -0.5 to 0.5 */\n transition: number,\n velocity: number,\n animationVelocity: number,\n lastTimeStamp?: number,\n lastScrollTimeStamp?: number,\n}\n\nconst up = 1\nconst down = -1\ntype Direction = 1 | -1\n\n/**\n * A component for picking an option by scrolling\n */\nexport const ScrollPicker = <T, >({\n options,\n mapping,\n selected,\n onChange = noop,\n disabled = false,\n }: ScrollPickerProps<T>) => {\n let selectedIndex = 0\n if (selected && options.indexOf(selected) !== -1) {\n selectedIndex = options.indexOf(selected)\n }\n const [{\n currentIndex,\n transition,\n items,\n lastTimeStamp\n }, setAnimation] = useState<AnimationData<T>>({\n targetIndex: selectedIndex,\n currentIndex: disabled ? selectedIndex : 0,\n velocity: 0,\n animationVelocity: Math.floor(options.length / 2),\n transition: 0,\n items: options,\n })\n\n const itemsShownCount = 5\n const shownItems = getNeighbours(range(items.length), currentIndex).map(index => ({\n name: mapping(items[index]!), index\n }))\n\n const itemHeight = 40\n const distance = 8\n\n const containerHeight = itemHeight * (itemsShownCount - 2) + distance * (itemsShownCount - 2 + 1)\n\n const getDirection = useCallback((targetIndex: number, currentIndex: number, transition: number, length: number): Direction => {\n if (targetIndex === currentIndex) {\n return transition > 0 ? up : down\n }\n let distanceForward = targetIndex - currentIndex\n if (distanceForward < 0) {\n distanceForward += length\n }\n return distanceForward >= length / 2 ? down : up\n }, [])\n\n const animate = useCallback((timestamp: number, startTime: number | undefined) => {\n setAnimation((prevState) => {\n const {\n targetIndex,\n currentIndex,\n transition,\n animationVelocity,\n velocity,\n items,\n lastScrollTimeStamp\n } = prevState\n if (disabled) {\n return { ...prevState, currentIndex: targetIndex, velocity: 0, lastTimeStamp: timestamp }\n }\n if ((targetIndex === currentIndex && velocity === 0 && transition === 0) || !startTime) {\n return { ...prevState, lastTimeStamp: timestamp }\n }\n const progress = (timestamp - startTime) / 1000 // to seconds\n const direction = getDirection(targetIndex, currentIndex, transition, items.length)\n\n let newVelocity = velocity\n let usedVelocity\n let newCurrentIndex = currentIndex\n const isAutoScrolling = velocity === 0 && (!lastScrollTimeStamp || timestamp - lastScrollTimeStamp > 300)\n\n const newLastScrollTimeStamp = velocity !== 0 ? timestamp : lastScrollTimeStamp\n\n // manual scrolling\n if (isAutoScrolling) {\n usedVelocity = direction * animationVelocity\n } else {\n usedVelocity = velocity\n newVelocity = velocity * 0.5 // drag loss\n if (Math.abs(newVelocity) <= 0.05) {\n newVelocity = 0\n }\n }\n\n let newTransition = transition + usedVelocity * progress\n const changeThreshold = 0.5\n\n while (newTransition >= changeThreshold) {\n if (newCurrentIndex === targetIndex && newTransition >= changeThreshold && isAutoScrolling) {\n newTransition = 0\n break\n }\n newCurrentIndex = (currentIndex + 1) % items.length\n newTransition -= 1\n }\n if (newTransition >= changeThreshold) {\n newTransition = 0\n }\n while (newTransition <= -changeThreshold) {\n if (newCurrentIndex === targetIndex && newTransition <= -changeThreshold && isAutoScrolling) {\n newTransition = 0\n break\n }\n newCurrentIndex = currentIndex === 0 ? items.length - 1 : currentIndex - 1\n newTransition += 1\n }\n let newTargetIndex = targetIndex\n if (!isAutoScrolling) {\n newTargetIndex = newCurrentIndex\n }\n\n if ((currentIndex !== newTargetIndex || newTargetIndex !== targetIndex) && newTargetIndex === newCurrentIndex) {\n onChange(items[newCurrentIndex]!)\n }\n return {\n targetIndex: newTargetIndex,\n currentIndex: newCurrentIndex,\n animationVelocity,\n transition: newTransition,\n velocity: newVelocity,\n items,\n lastTimeStamp: timestamp,\n lastScrollTimeStamp: newLastScrollTimeStamp\n }\n })\n }, [disabled, getDirection, onChange])\n\n useEffect(() => {\n // constant update\n requestAnimationFrame((timestamp) => animate(timestamp, lastTimeStamp))\n })\n\n const opacity = (transition: number, index: number, itemsCount: number) => {\n const max = 100\n const min = 0\n const distance = max - min\n\n let opacityValue = min\n const unitTransition = clamp((transition) / 0.5)\n if (index === 1 || index === itemsCount - 2) {\n if (index === 1 && transition > 0) {\n opacityValue += Math.floor(unitTransition * distance)\n }\n if (index === itemsCount - 2 && transition < 0) {\n opacityValue += Math.floor(unitTransition * distance)\n }\n } else {\n opacityValue = max\n }\n\n // TODO this is not the right value for the bottom entry\n return clamp(1 - (opacityValue / max))\n }\n\n return (\n <div\n className=\"relative overflow-hidden\"\n style={{ height: containerHeight }}\n onWheel={event => {\n if (event.deltaY !== 0) {\n // TODO slower increase\n setAnimation(({ velocity, ...animationData }) =>\n ({ ...animationData, velocity: velocity + event.deltaY }))\n }\n }}\n >\n <div className=\"absolute top-1/2 -translate-y-1/2 -translate-x-1/2 left-1/2\">\n <div\n className=\"absolute z-[1] top-1/2 -translate-y-1/2 -translate-x-1/2 left-1/2 w-full min-w-[40px] border border-divider/50 border-y-2 border-x-0 \"\n style={{ height: `${itemHeight}px` }}\n />\n <div\n className=\"flex-col-2 select-none\"\n style={{\n transform: `translateY(${-transition * (distance + itemHeight)}px)`,\n columnGap: `${distance}px`,\n }}\n >\n {shownItems.map(({ name, index }, arrayIndex) => (\n <div\n key={index}\n className={clsx(\n `flex-col-2 items-center justify-center rounded-md`,\n {\n 'text-primary font-bold': currentIndex === index,\n 'text-on-background': currentIndex === index,\n 'cursor-pointer': !disabled,\n 'cursor-not-allowed': disabled,\n }\n )}\n style={{\n opacity: currentIndex !== index ? opacity(transition, arrayIndex, shownItems.length) : undefined,\n height: `${itemHeight}px`,\n maxHeight: `${itemHeight}px`,\n }}\n onClick={() => !disabled && setAnimation(prevState => ({ ...prevState, targetIndex: index }))}\n >\n {name}\n </div>\n ))}\n </div>\n </div>\n </div>\n )\n}\n","export const noop = () => undefined\n","export const equalSizeGroups = <T>(array: T[], groupSize: number): T[][] => {\n if (groupSize <= 0) {\n console.warn(`group size should be greater than 0: groupSize = ${groupSize}`)\n return [[...array]]\n }\n\n const groups = []\n for (let i = 0; i < array.length; i += groupSize) {\n groups.push(array.slice(i, Math.min(i + groupSize, array.length)))\n }\n return groups\n}\n\nexport type RangeOptions = {\n /** Whether the range can be defined empty via end < start without a warning */\n allowEmptyRange: boolean,\n stepSize: number,\n exclusiveStart: boolean,\n exclusiveEnd: boolean,\n}\n\nconst defaultRangeOptions: RangeOptions = {\n allowEmptyRange: false,\n stepSize: 1,\n exclusiveStart: false,\n exclusiveEnd: true,\n}\n\n/**\n * @param endOrRange The end value or a range [start, end], end is exclusive\n * @param options the options for defining the range\n */\nexport const range = (endOrRange: number | [number, number], options?: Partial<RangeOptions>): number[] => {\n const { allowEmptyRange, stepSize, exclusiveStart, exclusiveEnd } = { ...defaultRangeOptions, ...options }\n let start = 0\n let end: number\n if (typeof endOrRange === 'number') {\n end = endOrRange\n } else {\n start = endOrRange[0]\n end = endOrRange[1]\n }\n if (!exclusiveEnd) {\n end -= 1\n }\n if (exclusiveStart) {\n start += 1\n }\n\n if (end - 1 < start) {\n if (!allowEmptyRange) {\n console.warn(`range: end (${end}) < start (${start}) should be allowed explicitly, set options.allowEmptyRange to true`)\n }\n return []\n }\n return Array.from({ length: end - start }, (_, index) => index * stepSize + start)\n}\n\n/** Finds the closest match\n * @param list The list of all possible matches\n * @param firstCloser Return whether item1 is closer than item2\n */\nexport const closestMatch = <T>(list: T[], firstCloser: (item1: T, item2: T) => boolean) => {\n return list.reduce((item1, item2) => {\n return firstCloser(item1, item2) ? item1 : item2\n })\n}\n\n/**\n * returns the item in middle of a list and its neighbours before and after\n * e.g. [1,2,3,4,5,6] for item = 1 would return [5,6,1,2,3]\n */\nexport const getNeighbours = <T>(list: T[], item: T, neighbourDistance: number = 2) => {\n const index = list.indexOf(item)\n const totalItems = neighbourDistance * 2 + 1\n if (list.length < totalItems) {\n console.warn('List is to short')\n return list\n }\n\n if (index === -1) {\n console.error('item not found in list')\n return list.splice(0, totalItems)\n }\n\n let start = index - neighbourDistance\n if (start < 0) {\n start += list.length\n }\n const end = (index + neighbourDistance + 1) % list.length\n\n const result: T[] = []\n let ignoreOnce = list.length === totalItems\n for (let i = start; i !== end || ignoreOnce; i = (i + 1) % list.length) {\n result.push(list[i]!)\n if (end === i && ignoreOnce) {\n ignoreOnce = false\n }\n }\n return result\n}\n\nexport const createLoopingListWithIndex = <T>(list: T[], startIndex: number = 0, length: number = 0, forwards: boolean = true) => {\n if (length < 0) {\n console.warn(`createLoopingList: length must be >= 0, given ${length}`)\n } else if (length === 0) {\n length = list.length\n }\n\n const returnList: [number, T][] = []\n\n if (forwards) {\n for (let i = startIndex; returnList.length < length; i = (i + 1) % list.length) {\n returnList.push([i, list[i]!])\n }\n } else {\n for (let i = startIndex; returnList.length < length; i = i === 0 ? i = list.length - 1 : i - 1) {\n returnList.push([i, list[i]!])\n }\n }\n\n return returnList\n}\n\nexport const createLoopingList = <T>(list: T[], startIndex: number = 0, length: number = 0, forwards: boolean = true) => {\n return createLoopingListWithIndex(list, startIndex, length, forwards).map(([_, item]) => item)\n}\n\nexport const ArrayUtil = {\n unique: <T>(list: T[]): T[] => {\n const seen = new Set<T>()\n return list.filter((item) => {\n if (seen.has(item)) {\n return false\n }\n seen.add(item)\n return true\n })\n },\n\n difference: <T>(list: T[], removeList: T[]): T[] => {\n const remove = new Set<T>(removeList)\n return list.filter((item) => !remove.has(item))\n }\n}\n","export const clamp = (value: number, min: number = 0, max: number = 1): number => {\n return Math.min(Math.max(value, min), max)\n}\n"],"mappings":"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","names":["currentIndex","transition","items","distance"]}
1
+ {"version":3,"sources":["../../../src/components/user-action/ScrollPicker.tsx","../../../src/utils/noop.ts","../../../src/utils/array.ts","../../../src/utils/math.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\nimport clsx from 'clsx'\nimport { noop } from '@/src/utils/noop'\nimport { getNeighbours, range } from '@/src/utils/array'\nimport { clamp } from '@/src/utils/math'\n\nexport type ScrollPickerProps<T> = {\n options: T[],\n mapping: (value: T) => string,\n selected?: T,\n onChange?: (value: T) => void,\n disabled?: boolean,\n}\n\ntype AnimationData<T> = {\n /** The index we scroll to */\n targetIndex: number,\n /** The index we are currently showing centered */\n currentIndex: number,\n items: T[],\n /** From -0.5 to 0.5 */\n transition: number,\n velocity: number,\n animationVelocity: number,\n lastTimeStamp?: number,\n lastScrollTimeStamp?: number,\n}\n\nconst up = 1\nconst down = -1\ntype Direction = 1 | -1\n\n/**\n * A component for picking an option by scrolling\n */\nexport const ScrollPicker = <T, >({\n options,\n mapping,\n selected,\n onChange = noop,\n disabled = false,\n }: ScrollPickerProps<T>) => {\n let selectedIndex = 0\n if (selected && options.indexOf(selected) !== -1) {\n selectedIndex = options.indexOf(selected)\n }\n const [{\n currentIndex,\n transition,\n items,\n lastTimeStamp\n }, setAnimation] = useState<AnimationData<T>>({\n targetIndex: selectedIndex,\n currentIndex: disabled ? selectedIndex : 0,\n velocity: 0,\n animationVelocity: Math.floor(options.length / 2),\n transition: 0,\n items: options,\n })\n\n const itemsShownCount = 5\n const shownItems = getNeighbours(range(items.length), currentIndex).map(index => ({\n name: mapping(items[index]!), index\n }))\n\n const itemHeight = 40\n const distance = 8\n\n const containerHeight = itemHeight * (itemsShownCount - 2) + distance * (itemsShownCount - 2 + 1)\n\n const getDirection = useCallback((targetIndex: number, currentIndex: number, transition: number, length: number): Direction => {\n if (targetIndex === currentIndex) {\n return transition > 0 ? up : down\n }\n let distanceForward = targetIndex - currentIndex\n if (distanceForward < 0) {\n distanceForward += length\n }\n return distanceForward >= length / 2 ? down : up\n }, [])\n\n const animate = useCallback((timestamp: number, startTime: number | undefined) => {\n setAnimation((prevState) => {\n const {\n targetIndex,\n currentIndex,\n transition,\n animationVelocity,\n velocity,\n items,\n lastScrollTimeStamp\n } = prevState\n if (disabled) {\n return { ...prevState, currentIndex: targetIndex, velocity: 0, lastTimeStamp: timestamp }\n }\n if ((targetIndex === currentIndex && velocity === 0 && transition === 0) || !startTime) {\n return { ...prevState, lastTimeStamp: timestamp }\n }\n const progress = (timestamp - startTime) / 1000 // to seconds\n const direction = getDirection(targetIndex, currentIndex, transition, items.length)\n\n let newVelocity = velocity\n let usedVelocity\n let newCurrentIndex = currentIndex\n const isAutoScrolling = velocity <= 10 && (!lastScrollTimeStamp || timestamp - lastScrollTimeStamp > 50)\n\n const newLastScrollTimeStamp = velocity !== 0 ? timestamp : lastScrollTimeStamp\n\n // manual scrolling\n if (isAutoScrolling) {\n usedVelocity = direction * animationVelocity\n } else {\n usedVelocity = velocity\n newVelocity = velocity * 0.5 // drag loss\n if (Math.abs(newVelocity) <= 0.05) {\n newVelocity = 0\n }\n }\n\n let newTransition = transition + usedVelocity * progress\n const changeThreshold = 0.5\n\n while (newTransition >= changeThreshold) {\n if (newCurrentIndex === targetIndex && newTransition >= changeThreshold && isAutoScrolling) {\n newTransition = 0\n break\n }\n newCurrentIndex = (currentIndex + 1) % items.length\n newTransition -= 1\n }\n if (newTransition >= changeThreshold) {\n newTransition = 0\n }\n while (newTransition <= -changeThreshold) {\n if (newCurrentIndex === targetIndex && newTransition <= -changeThreshold && isAutoScrolling) {\n newTransition = 0\n break\n }\n newCurrentIndex = currentIndex === 0 ? items.length - 1 : currentIndex - 1\n newTransition += 1\n }\n let newTargetIndex = targetIndex\n if (!isAutoScrolling) {\n newTargetIndex = newCurrentIndex\n }\n\n if ((currentIndex !== newTargetIndex || newTargetIndex !== targetIndex) && newTargetIndex === newCurrentIndex) {\n onChange(items[newCurrentIndex]!)\n }\n return {\n targetIndex: newTargetIndex,\n currentIndex: newCurrentIndex,\n animationVelocity,\n transition: newTransition,\n velocity: newVelocity,\n items,\n lastTimeStamp: timestamp,\n lastScrollTimeStamp: newLastScrollTimeStamp\n }\n })\n }, [disabled, getDirection, onChange])\n\n useEffect(() => {\n // constant update\n requestAnimationFrame((timestamp) => animate(timestamp, lastTimeStamp))\n })\n\n const opacity = (transition: number, index: number, itemsCount: number) => {\n const max = 100\n const min = 0\n const distance = max - min\n\n let opacityValue = min\n const unitTransition = clamp((transition) / 0.5)\n if (index === 1 || index === itemsCount - 2) {\n if (index === 1 && transition > 0) {\n opacityValue += Math.floor(unitTransition * distance)\n }\n if (index === itemsCount - 2 && transition < 0) {\n opacityValue += Math.floor(unitTransition * distance)\n }\n } else {\n opacityValue = max\n }\n\n // TODO this is not the right value for the bottom entry\n return clamp(1 - (opacityValue / max))\n }\n\n return (\n <div\n className=\"relative overflow-hidden\"\n style={{ height: containerHeight }}\n onWheel={event => {\n if (event.deltaY !== 0) {\n const deltaY = clamp(event.deltaY,[-itemHeight*2/3, itemHeight*2/3])\n // TODO slower increase\n setAnimation(({ velocity, ...animationData }) =>\n ({ ...animationData, velocity: velocity + deltaY }))\n }\n }}\n >\n <div className=\"absolute top-1/2 -translate-y-1/2 -translate-x-1/2 left-1/2\">\n <div\n className=\"absolute z-[1] top-1/2 -translate-y-1/2 -translate-x-1/2 left-1/2 w-full min-w-[40px] border border-divider/50 border-y-2 border-x-0 \"\n style={{ height: `${itemHeight}px` }}\n />\n <div\n className=\"flex-col-2 select-none\"\n style={{\n transform: `translateY(${-transition * (distance + itemHeight)}px)`,\n columnGap: `${distance}px`,\n }}\n >\n {shownItems.map(({ name, index }, arrayIndex) => (\n <div\n key={index}\n className={clsx(\n `flex-col-2 items-center justify-center rounded-md`,\n {\n 'text-primary font-bold': currentIndex === index,\n 'text-on-background': currentIndex === index,\n 'cursor-pointer': !disabled,\n 'cursor-not-allowed': disabled,\n }\n )}\n style={{\n opacity: currentIndex !== index ? opacity(transition, arrayIndex, shownItems.length) : undefined,\n height: `${itemHeight}px`,\n maxHeight: `${itemHeight}px`,\n }}\n onClick={() => !disabled && setAnimation(prevState => ({ ...prevState, targetIndex: index }))}\n >\n {name}\n </div>\n ))}\n </div>\n </div>\n </div>\n )\n}\n","export const noop = () => undefined\n","export const equalSizeGroups = <T>(array: T[], groupSize: number): T[][] => {\n if (groupSize <= 0) {\n console.warn(`group size should be greater than 0: groupSize = ${groupSize}`)\n return [[...array]]\n }\n\n const groups = []\n for (let i = 0; i < array.length; i += groupSize) {\n groups.push(array.slice(i, Math.min(i + groupSize, array.length)))\n }\n return groups\n}\n\nexport type RangeOptions = {\n /** Whether the range can be defined empty via end < start without a warning */\n allowEmptyRange: boolean,\n stepSize: number,\n exclusiveStart: boolean,\n exclusiveEnd: boolean,\n}\n\nconst defaultRangeOptions: RangeOptions = {\n allowEmptyRange: false,\n stepSize: 1,\n exclusiveStart: false,\n exclusiveEnd: true,\n}\n\n/**\n * @param endOrRange The end value or a range [start, end], end is exclusive\n * @param options the options for defining the range\n */\nexport const range = (endOrRange: number | [number, number], options?: Partial<RangeOptions>): number[] => {\n const { allowEmptyRange, stepSize, exclusiveStart, exclusiveEnd } = { ...defaultRangeOptions, ...options }\n let start = 0\n let end: number\n if (typeof endOrRange === 'number') {\n end = endOrRange\n } else {\n start = endOrRange[0]\n end = endOrRange[1]\n }\n if (!exclusiveEnd) {\n end -= 1\n }\n if (exclusiveStart) {\n start += 1\n }\n\n if (end - 1 < start) {\n if (!allowEmptyRange) {\n console.warn(`range: end (${end}) < start (${start}) should be allowed explicitly, set options.allowEmptyRange to true`)\n }\n return []\n }\n return Array.from({ length: end - start }, (_, index) => index * stepSize + start)\n}\n\n/** Finds the closest match\n * @param list The list of all possible matches\n * @param firstCloser Return whether item1 is closer than item2\n */\nexport const closestMatch = <T>(list: T[], firstCloser: (item1: T, item2: T) => boolean) => {\n return list.reduce((item1, item2) => {\n return firstCloser(item1, item2) ? item1 : item2\n })\n}\n\n/**\n * returns the item in middle of a list and its neighbours before and after\n * e.g. [1,2,3,4,5,6] for item = 1 would return [5,6,1,2,3]\n */\nexport const getNeighbours = <T>(list: T[], item: T, neighbourDistance: number = 2) => {\n const index = list.indexOf(item)\n const totalItems = neighbourDistance * 2 + 1\n if (list.length < totalItems) {\n console.warn('List is to short')\n return list\n }\n\n if (index === -1) {\n console.error('item not found in list')\n return list.splice(0, totalItems)\n }\n\n let start = index - neighbourDistance\n if (start < 0) {\n start += list.length\n }\n const end = (index + neighbourDistance + 1) % list.length\n\n const result: T[] = []\n let ignoreOnce = list.length === totalItems\n for (let i = start; i !== end || ignoreOnce; i = (i + 1) % list.length) {\n result.push(list[i]!)\n if (end === i && ignoreOnce) {\n ignoreOnce = false\n }\n }\n return result\n}\n\nexport const createLoopingListWithIndex = <T>(list: T[], startIndex: number = 0, length: number = 0, forwards: boolean = true) => {\n if (length < 0) {\n console.warn(`createLoopingList: length must be >= 0, given ${length}`)\n } else if (length === 0) {\n length = list.length\n }\n\n const returnList: [number, T][] = []\n\n if (forwards) {\n for (let i = startIndex; returnList.length < length; i = (i + 1) % list.length) {\n returnList.push([i, list[i]!])\n }\n } else {\n for (let i = startIndex; returnList.length < length; i = i === 0 ? i = list.length - 1 : i - 1) {\n returnList.push([i, list[i]!])\n }\n }\n\n return returnList\n}\n\nexport const createLoopingList = <T>(list: T[], startIndex: number = 0, length: number = 0, forwards: boolean = true) => {\n return createLoopingListWithIndex(list, startIndex, length, forwards).map(([_, item]) => item)\n}\n\n/**\n * @param list The list to be changed\n * @param move The shifting applied to the array (can be negative)\n */\nconst moveItems = <T>(list: T[], move: number = 0) => {\n const result = []\n let start = move\n if (start < 0) {\n start = list.length - move\n }\n start = start % list.length\n for (let i = 0; i < list.length; i++) {\n result[i] = list[(i + start) % list.length]\n }\n return result\n}\n\nexport const ArrayUtil = {\n unique: <T>(list: T[]): T[] => {\n const seen = new Set<T>()\n return list.filter((item) => {\n if (seen.has(item)) {\n return false\n }\n seen.add(item)\n return true\n })\n },\n difference: <T>(list: T[], removeList: T[]): T[] => {\n const remove = new Set<T>(removeList)\n return list.filter((item) => !remove.has(item))\n },\n moveItems,\n}\n","export const clamp = (value: number, range: [number, number] = [0, 1]): number => {\n const [min, max] = range\n return Math.min(Math.max(value, min), max)\n}\n"],"mappings":"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","names":["range","currentIndex","transition","items","distance"]}
@@ -1,8 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { InputProps } from './Input.mjs';
2
+ import { InputProps } from './input/Input.mjs';
3
3
  import 'react';
4
4
  import '../../hooks/useDelay.mjs';
5
- import './Label.mjs';
6
5
 
7
6
  type SearchBarProps = InputProps & {
8
7
  onSearch?: () => void;
@@ -1,8 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { InputProps } from './Input.js';
2
+ import { InputProps } from './input/Input.js';
3
3
  import 'react';
4
4
  import '../../hooks/useDelay.js';
5
- import './Label.js';
6
5
 
7
6
  type SearchBarProps = InputProps & {
8
7
  onSearch?: () => void;