@helpwave/hightide 0.0.9 → 0.0.11

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 (300) hide show
  1. package/README.md +1 -1
  2. package/dist/coloring/shading.d.ts +2 -0
  3. package/dist/coloring/shading.js +40 -0
  4. package/dist/coloring/types.d.ts +11 -0
  5. package/dist/coloring/types.js +1 -0
  6. package/dist/components/Avatar.d.ts +14 -0
  7. package/dist/components/Avatar.js +35 -0
  8. package/dist/components/AvatarGroup.d.ts +10 -0
  9. package/dist/components/AvatarGroup.js +13 -0
  10. package/dist/components/BreadCrumb.d.ts +16 -0
  11. package/dist/components/BreadCrumb.js +12 -0
  12. package/dist/components/Button.d.ts +41 -0
  13. package/dist/components/Button.js +84 -0
  14. package/dist/components/ChipList.d.ts +21 -0
  15. package/dist/components/ChipList.js +38 -0
  16. package/dist/components/Circle.d.ts +6 -0
  17. package/dist/components/Circle.js +10 -0
  18. package/dist/components/ErrorComponent.d.ts +13 -0
  19. package/dist/components/ErrorComponent.js +19 -0
  20. package/dist/components/Expandable.d.ts +30 -0
  21. package/dist/components/Expandable.js +16 -0
  22. package/dist/components/HelpwaveBadge.d.ts +11 -0
  23. package/dist/components/HelpwaveBadge.js +14 -0
  24. package/dist/components/HideableContentSection.d.ts +10 -0
  25. package/dist/components/HideableContentSection.js +15 -0
  26. package/dist/components/InputGroup.d.ts +13 -0
  27. package/dist/components/InputGroup.js +33 -0
  28. package/dist/components/LoadingAndErrorComponent.d.ts +17 -0
  29. package/dist/components/LoadingAndErrorComponent.js +25 -0
  30. package/dist/components/LoadingAnimation.d.ts +13 -0
  31. package/dist/components/LoadingAnimation.js +19 -0
  32. package/dist/components/LoadingButton.d.ts +6 -0
  33. package/dist/components/LoadingButton.js +10 -0
  34. package/dist/components/MarkdownInterpreter.d.ts +25 -0
  35. package/dist/components/MarkdownInterpreter.js +190 -0
  36. package/dist/components/Pagination.d.ts +14 -0
  37. package/dist/components/Pagination.js +25 -0
  38. package/dist/components/Profile.d.ts +28 -0
  39. package/dist/components/Profile.js +45 -0
  40. package/dist/components/ProgressIndicator.d.ts +21 -0
  41. package/dist/components/ProgressIndicator.js +24 -0
  42. package/dist/components/Ring.d.ts +31 -0
  43. package/dist/components/Ring.js +113 -0
  44. package/dist/components/SearchableList.d.ts +18 -0
  45. package/dist/components/SearchableList.js +27 -0
  46. package/dist/components/SortButton.d.ts +10 -0
  47. package/dist/components/SortButton.js +9 -0
  48. package/dist/components/Span.js +1 -0
  49. package/dist/components/StepperBar.d.ts +23 -0
  50. package/dist/components/StepperBar.js +47 -0
  51. package/dist/components/Table.d.ts +87 -0
  52. package/dist/components/Table.js +187 -0
  53. package/dist/components/TechRadar.d.ts +36 -0
  54. package/dist/components/TechRadar.js +191 -0
  55. package/dist/components/TextImage.d.ts +20 -0
  56. package/dist/components/TextImage.js +31 -0
  57. package/dist/components/TimeDisplay.d.ts +30 -0
  58. package/dist/components/TimeDisplay.js +83 -0
  59. package/dist/components/Tooltip.d.ts +34 -0
  60. package/dist/components/Tooltip.js +38 -0
  61. package/dist/components/VerticalDivider.d.ts +11 -0
  62. package/dist/components/VerticalDivider.js +7 -0
  63. package/dist/components/date/DatePicker.d.ts +26 -0
  64. package/dist/components/date/DatePicker.js +58 -0
  65. package/dist/components/date/DayPicker.d.ts +16 -0
  66. package/dist/components/date/DayPicker.js +37 -0
  67. package/dist/components/date/TimePicker.d.ts +12 -0
  68. package/dist/components/date/TimePicker.js +79 -0
  69. package/dist/components/date/YearMonthPicker.d.ts +11 -0
  70. package/dist/components/date/YearMonthPicker.js +59 -0
  71. package/dist/components/examples/InputGroupExample.d.ts +6 -0
  72. package/dist/components/examples/InputGroupExample.js +21 -0
  73. package/dist/components/examples/MultiSelectExample.d.ts +7 -0
  74. package/dist/components/examples/MultiSelectExample.js +27 -0
  75. package/dist/components/examples/SearchableSelectExample.d.ts +6 -0
  76. package/dist/components/examples/SearchableSelectExample.js +17 -0
  77. package/dist/components/examples/SelectExample.d.ts +4 -0
  78. package/dist/components/examples/SelectExample.js +15 -0
  79. package/dist/components/examples/StackingModals.d.ts +4 -0
  80. package/dist/components/examples/StackingModals.js +15 -0
  81. package/dist/components/examples/TableExample.d.ts +9 -0
  82. package/dist/components/examples/TableExample.js +92 -0
  83. package/dist/components/examples/TextareaExample.d.ts +6 -0
  84. package/dist/components/examples/TextareaExample.js +10 -0
  85. package/dist/components/examples/TileExample.d.ts +9 -0
  86. package/dist/components/examples/TileExample.js +9 -0
  87. package/dist/components/examples/Title.js +1 -0
  88. package/dist/components/examples/date/DateTimePickerExample.d.ts +10 -0
  89. package/dist/components/examples/date/DateTimePickerExample.js +21 -0
  90. package/dist/components/examples/properties/CheckboxPropertyExample.d.ts +8 -0
  91. package/dist/components/examples/properties/CheckboxPropertyExample.js +13 -0
  92. package/dist/components/examples/properties/DatePropertyExample.d.ts +8 -0
  93. package/dist/components/examples/properties/DatePropertyExample.js +23 -0
  94. package/dist/components/examples/properties/MultiSelectPropertyExample.d.ts +8 -0
  95. package/dist/components/examples/properties/MultiSelectPropertyExample.js +16 -0
  96. package/dist/components/examples/properties/NumberPropertyExample.d.ts +6 -0
  97. package/dist/components/examples/properties/NumberPropertyExample.js +13 -0
  98. package/dist/components/examples/properties/SelectPropertyExample.d.ts +6 -0
  99. package/dist/components/examples/properties/SelectPropertyExample.js +18 -0
  100. package/dist/components/examples/properties/TextPropertyExample.d.ts +8 -0
  101. package/dist/components/examples/properties/TextPropertyExample.js +13 -0
  102. package/dist/components/icons/Helpwave.d.ts +10 -0
  103. package/dist/components/icons/Helpwave.js +20 -0
  104. package/dist/components/icons/Tag.d.ts +10 -0
  105. package/dist/components/icons/Tag.js +12 -0
  106. package/dist/components/layout/Carousel.d.ts +22 -0
  107. package/dist/components/layout/Carousel.js +233 -0
  108. package/dist/components/layout/DividerInserter.d.ts +11 -0
  109. package/dist/components/layout/DividerInserter.js +20 -0
  110. package/dist/components/layout/FAQSection.d.ts +23 -0
  111. package/dist/components/layout/FAQSection.js +14 -0
  112. package/dist/components/layout/Tile.d.ts +34 -0
  113. package/dist/components/layout/Tile.js +18 -0
  114. package/dist/components/modals/ConfirmDialog.d.ts +34 -0
  115. package/dist/components/modals/ConfirmDialog.js +31 -0
  116. package/dist/components/modals/DiscardChangesDialog.d.ts +19 -0
  117. package/dist/components/modals/DiscardChangesDialog.js +24 -0
  118. package/dist/components/modals/InputModal.d.ts +9 -0
  119. package/dist/components/modals/InputModal.js +9 -0
  120. package/dist/components/modals/LanguageModal.d.ts +17 -0
  121. package/dist/components/modals/LanguageModal.js +35 -0
  122. package/dist/components/modals/Modal.d.ts +38 -0
  123. package/dist/components/modals/Modal.js +57 -0
  124. package/dist/components/modals/ModalRegister.d.ts +11 -0
  125. package/dist/components/modals/ModalRegister.js +28 -0
  126. package/dist/components/properties/CheckboxProperty.d.ts +15 -0
  127. package/dist/components/properties/CheckboxProperty.js +27 -0
  128. package/dist/components/properties/DateProperty.d.ts +11 -0
  129. package/dist/components/properties/DateProperty.js +22 -0
  130. package/dist/components/properties/MultiSelectProperty.d.ts +12 -0
  131. package/dist/components/properties/MultiSelectProperty.js +33 -0
  132. package/dist/components/properties/NumberProperty.d.ts +16 -0
  133. package/dist/components/properties/NumberProperty.js +42 -0
  134. package/dist/components/properties/PropertyBase.d.ts +23 -0
  135. package/dist/components/properties/PropertyBase.js +27 -0
  136. package/dist/components/properties/SelectProperty.d.ts +12 -0
  137. package/dist/components/properties/SelectProperty.js +22 -0
  138. package/dist/components/properties/TextProperty.d.ts +15 -0
  139. package/dist/components/properties/TextProperty.js +37 -0
  140. package/dist/components/user-input/Checkbox.d.ts +37 -0
  141. package/dist/components/user-input/Checkbox.js +63 -0
  142. package/dist/components/user-input/DateAndTimePicker.d.ts +39 -0
  143. package/dist/components/user-input/DateAndTimePicker.js +65 -0
  144. package/dist/components/user-input/Input.d.ts +61 -0
  145. package/dist/components/user-input/Input.js +61 -0
  146. package/dist/components/user-input/Label.d.ts +12 -0
  147. package/dist/components/user-input/Label.js +12 -0
  148. package/dist/components/user-input/Menu.d.ts +21 -0
  149. package/dist/components/user-input/Menu.js +26 -0
  150. package/dist/components/user-input/MultiSelect.d.ts +39 -0
  151. package/dist/components/user-input/MultiSelect.js +57 -0
  152. package/dist/components/user-input/ScrollPicker.d.ts +11 -0
  153. package/dist/components/user-input/ScrollPicker.js +151 -0
  154. package/dist/components/user-input/SearchableSelect.d.ts +8 -0
  155. package/dist/components/user-input/SearchableSelect.js +14 -0
  156. package/dist/components/user-input/Select.d.ts +32 -0
  157. package/dist/components/user-input/Select.js +48 -0
  158. package/dist/components/user-input/Textarea.d.ts +20 -0
  159. package/dist/components/user-input/Textarea.js +33 -0
  160. package/dist/components/user-input/ToggleableInput.d.ts +32 -0
  161. package/dist/components/user-input/ToggleableInput.js +40 -0
  162. package/{globals.css → dist/css/globals.css} +1 -1
  163. package/dist/hooks/useHoverState.d.ts +40 -0
  164. package/dist/hooks/useHoverState.js +46 -0
  165. package/dist/hooks/useLanguage.d.ts +17 -0
  166. package/dist/hooks/useLanguage.js +51 -0
  167. package/dist/hooks/useLocalStorage.d.ts +4 -0
  168. package/dist/hooks/useLocalStorage.js +24 -0
  169. package/dist/hooks/useOutsideClick.d.ts +2 -0
  170. package/dist/hooks/useOutsideClick.js +22 -0
  171. package/dist/hooks/useSaveDelay.d.ts +5 -0
  172. package/dist/hooks/useSaveDelay.js +41 -0
  173. package/dist/hooks/useTheme.d.ts +16 -0
  174. package/dist/hooks/useTheme.js +32 -0
  175. package/dist/hooks/useTranslation.d.ts +24 -0
  176. package/dist/hooks/useTranslation.js +11 -0
  177. package/dist/util/array.d.ts +23 -0
  178. package/dist/util/array.js +103 -0
  179. package/{util/builder.ts → dist/util/builder.d.ts} +1 -4
  180. package/dist/util/builder.js +9 -0
  181. package/dist/util/date.d.ts +28 -0
  182. package/dist/util/date.js +133 -0
  183. package/dist/util/easeFunctions.d.ts +9 -0
  184. package/dist/util/easeFunctions.js +30 -0
  185. package/dist/util/emailValidation.d.ts +1 -0
  186. package/dist/util/emailValidation.js +3 -0
  187. package/dist/util/loopingArray.d.ts +23 -0
  188. package/dist/util/loopingArray.js +67 -0
  189. package/dist/util/math.d.ts +1 -0
  190. package/dist/util/math.js +3 -0
  191. package/dist/util/news.d.ts +98 -0
  192. package/dist/util/news.js +27 -0
  193. package/dist/util/noop.d.ts +1 -0
  194. package/dist/util/noop.js +1 -0
  195. package/{util/simpleSearch.ts → dist/util/simpleSearch.d.ts} +4 -21
  196. package/dist/util/simpleSearch.js +62 -0
  197. package/dist/util/storage.d.ts +15 -0
  198. package/dist/util/storage.js +32 -0
  199. package/dist/util/types.d.ts +1 -0
  200. package/dist/util/types.js +1 -0
  201. package/package.json +7 -8
  202. package/coloring/shading.ts +0 -46
  203. package/coloring/types.ts +0 -13
  204. package/components/Avatar.tsx +0 -58
  205. package/components/AvatarGroup.tsx +0 -48
  206. package/components/BreadCrumb.tsx +0 -35
  207. package/components/Button.tsx +0 -236
  208. package/components/ChipList.tsx +0 -89
  209. package/components/Circle.tsx +0 -27
  210. package/components/ErrorComponent.tsx +0 -40
  211. package/components/Expandable.tsx +0 -61
  212. package/components/HelpwaveBadge.tsx +0 -35
  213. package/components/HideableContentSection.tsx +0 -43
  214. package/components/InputGroup.tsx +0 -72
  215. package/components/LoadingAndErrorComponent.tsx +0 -47
  216. package/components/LoadingAnimation.tsx +0 -40
  217. package/components/LoadingButton.tsx +0 -27
  218. package/components/MarkdownInterpreter.tsx +0 -278
  219. package/components/Pagination.tsx +0 -65
  220. package/components/Profile.tsx +0 -124
  221. package/components/ProgressIndicator.tsx +0 -58
  222. package/components/Ring.tsx +0 -286
  223. package/components/SearchableList.tsx +0 -69
  224. package/components/SortButton.tsx +0 -33
  225. package/components/StepperBar.tsx +0 -124
  226. package/components/Table.tsx +0 -330
  227. package/components/TechRadar.tsx +0 -247
  228. package/components/TextImage.tsx +0 -86
  229. package/components/TimeDisplay.tsx +0 -121
  230. package/components/Tooltip.tsx +0 -92
  231. package/components/VerticalDivider.tsx +0 -51
  232. package/components/date/DatePicker.tsx +0 -164
  233. package/components/date/DayPicker.tsx +0 -95
  234. package/components/date/TimePicker.tsx +0 -167
  235. package/components/date/YearMonthPicker.tsx +0 -130
  236. package/components/examples/InputGroupExample.tsx +0 -58
  237. package/components/examples/MultiSelectExample.tsx +0 -57
  238. package/components/examples/SearchableSelectExample.tsx +0 -34
  239. package/components/examples/SelectExample.tsx +0 -28
  240. package/components/examples/StackingModals.tsx +0 -54
  241. package/components/examples/TableExample.tsx +0 -159
  242. package/components/examples/TextareaExample.tsx +0 -23
  243. package/components/examples/TileExample.tsx +0 -25
  244. package/components/examples/date/DateTimePickerExample.tsx +0 -53
  245. package/components/examples/properties/CheckboxPropertyExample.tsx +0 -29
  246. package/components/examples/properties/DatePropertyExample.tsx +0 -44
  247. package/components/examples/properties/MultiSelectPropertyExample.tsx +0 -39
  248. package/components/examples/properties/NumberPropertyExample.tsx +0 -28
  249. package/components/examples/properties/SelectPropertyExample.tsx +0 -39
  250. package/components/examples/properties/TextPropertyExample.tsx +0 -30
  251. package/components/icons/Helpwave.tsx +0 -51
  252. package/components/icons/Tag.tsx +0 -29
  253. package/components/layout/Carousel.tsx +0 -396
  254. package/components/layout/DividerInserter.tsx +0 -37
  255. package/components/layout/FAQSection.tsx +0 -57
  256. package/components/layout/Tile.tsx +0 -67
  257. package/components/modals/ConfirmDialog.tsx +0 -105
  258. package/components/modals/DiscardChangesDialog.tsx +0 -71
  259. package/components/modals/InputModal.tsx +0 -26
  260. package/components/modals/LanguageModal.tsx +0 -76
  261. package/components/modals/Modal.tsx +0 -149
  262. package/components/modals/ModalRegister.tsx +0 -45
  263. package/components/properties/CheckboxProperty.tsx +0 -62
  264. package/components/properties/DateProperty.tsx +0 -58
  265. package/components/properties/MultiSelectProperty.tsx +0 -82
  266. package/components/properties/NumberProperty.tsx +0 -86
  267. package/components/properties/PropertyBase.tsx +0 -84
  268. package/components/properties/SelectProperty.tsx +0 -67
  269. package/components/properties/TextProperty.tsx +0 -81
  270. package/components/user-input/Checkbox.tsx +0 -139
  271. package/components/user-input/DateAndTimePicker.tsx +0 -156
  272. package/components/user-input/Input.tsx +0 -192
  273. package/components/user-input/Label.tsx +0 -32
  274. package/components/user-input/Menu.tsx +0 -75
  275. package/components/user-input/MultiSelect.tsx +0 -158
  276. package/components/user-input/ScrollPicker.tsx +0 -240
  277. package/components/user-input/SearchableSelect.tsx +0 -36
  278. package/components/user-input/Select.tsx +0 -132
  279. package/components/user-input/Textarea.tsx +0 -86
  280. package/components/user-input/ToggleableInput.tsx +0 -115
  281. package/hooks/useHoverState.ts +0 -88
  282. package/hooks/useLanguage.tsx +0 -78
  283. package/hooks/useLocalStorage.tsx +0 -33
  284. package/hooks/useOutsideClick.ts +0 -25
  285. package/hooks/useSaveDelay.ts +0 -46
  286. package/hooks/useTheme.tsx +0 -57
  287. package/hooks/useTranslation.ts +0 -43
  288. package/index.ts +0 -0
  289. package/util/array.ts +0 -115
  290. package/util/date.ts +0 -180
  291. package/util/easeFunctions.ts +0 -37
  292. package/util/emailValidation.ts +0 -3
  293. package/util/loopingArray.ts +0 -94
  294. package/util/math.ts +0 -3
  295. package/util/news.ts +0 -43
  296. package/util/noop.ts +0 -1
  297. package/util/storage.ts +0 -37
  298. package/util/types.ts +0 -4
  299. /package/{components/Span.tsx → dist/components/Span.d.ts} +0 -0
  300. /package/{components/examples/Title.tsx → dist/components/examples/Title.d.ts} +0 -0
@@ -0,0 +1,233 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import clsx from 'clsx';
3
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
+ import { ChevronLeft, ChevronRight } from 'lucide-react';
5
+ import { createLoopingListWithIndex, range } from '../../util/array';
6
+ import { clamp } from '../../util/math';
7
+ import { EaseFunctions } from '../../util/easeFunctions';
8
+ import { LoopingArrayCalculator } from '../../util/loopingArray';
9
+ export const Carousel = ({ children, animationTime = 200, isLooping = false, isAutoLooping = false, autoLoopingTimeOut = 5000, autoLoopAnimationTime = 500, hintNext = false, arrows = false, dots = true, overScrollThreshold = 0.1, blurColor = 'from-white', className = '', heightClassName = 'h-[24rem]', widthClassName = 'w-[70%] desktop:w-1/2', }) => {
10
+ if (isAutoLooping && !isLooping) {
11
+ console.error('When isAutoLooping is true, isLooping should also be true');
12
+ isLooping = true;
13
+ }
14
+ const [{ currentPosition, dragState, animationState, }, setCarouselInformation] = useState({
15
+ currentPosition: 0,
16
+ });
17
+ const animationId = useRef(undefined);
18
+ const timeOut = useRef(undefined);
19
+ autoLoopingTimeOut = Math.max(0, autoLoopingTimeOut);
20
+ const length = children.length;
21
+ const paddingItemCount = 3; // The number of items to append left and right of the list to allow for clean transition when looping
22
+ const util = useMemo(() => new LoopingArrayCalculator(length, isLooping, overScrollThreshold), [length, isLooping, overScrollThreshold]);
23
+ const currentIndex = util.getCorrectedPosition(LoopingArrayCalculator.withoutOffset(currentPosition));
24
+ animationTime = Math.max(200, animationTime); // in ms, must be > 0
25
+ autoLoopAnimationTime = Math.max(200, autoLoopAnimationTime);
26
+ const getStyleOffset = (index) => {
27
+ const baseOffset = -50 + (index - currentPosition) * 100;
28
+ return `${baseOffset}%`;
29
+ };
30
+ const animation = useCallback((time) => {
31
+ let keepAnimating = true;
32
+ // Other calculation in the setState call to avoid updating the useCallback to often
33
+ setCarouselInformation((state) => {
34
+ const { animationState, dragState } = state;
35
+ if (animationState === undefined || dragState !== undefined) {
36
+ keepAnimating = false;
37
+ return state;
38
+ }
39
+ if (!animationState.startTime || !animationState.lastUpdateTime) {
40
+ return {
41
+ ...state,
42
+ animationState: {
43
+ ...animationState,
44
+ startTime: time,
45
+ lastUpdateTime: time
46
+ }
47
+ };
48
+ }
49
+ const useAnimationTime = animationState.isAutoLooping ? autoLoopAnimationTime : animationTime;
50
+ const progress = clamp((time - animationState.startTime) / useAnimationTime); // progress
51
+ const easedProgress = EaseFunctions.easeInEaseOut(progress);
52
+ const distance = util.getDistanceDirectional(animationState.startPosition, animationState.targetPosition, animationState.direction);
53
+ const newPosition = util.getCorrectedPosition(easedProgress * distance * animationState.direction + animationState.startPosition);
54
+ if (animationState.targetPosition === newPosition || progress === 1) {
55
+ keepAnimating = false;
56
+ return ({
57
+ currentPosition: LoopingArrayCalculator.withoutOffset(newPosition),
58
+ animationState: undefined
59
+ });
60
+ }
61
+ return ({
62
+ currentPosition: newPosition,
63
+ animationState: {
64
+ ...animationState,
65
+ lastUpdateTime: time
66
+ }
67
+ });
68
+ });
69
+ if (keepAnimating) {
70
+ animationId.current = requestAnimationFrame(time1 => animation(time1));
71
+ }
72
+ }, [animationTime, autoLoopAnimationTime, util]);
73
+ useEffect(() => {
74
+ if (animationState) {
75
+ animationId.current = requestAnimationFrame(animation);
76
+ }
77
+ return () => {
78
+ if (animationId.current) {
79
+ cancelAnimationFrame(animationId.current);
80
+ animationId.current = 0;
81
+ }
82
+ };
83
+ }, [animationState]); // eslint-disable-line react-hooks/exhaustive-deps
84
+ const startAutoLoop = () => setCarouselInformation(prevState => ({
85
+ ...prevState,
86
+ dragState: prevState.dragState,
87
+ animationState: prevState.animationState || prevState.dragState ? prevState.animationState : {
88
+ startPosition: currentPosition,
89
+ targetPosition: (currentPosition + 1) % length,
90
+ direction: 1, // always move forward
91
+ isAutoLooping: true
92
+ }
93
+ }));
94
+ useEffect(() => {
95
+ if (!animationId.current && !animationState && !dragState && !timeOut.current) {
96
+ if (autoLoopingTimeOut > 0) {
97
+ timeOut.current = setTimeout(() => {
98
+ startAutoLoop();
99
+ timeOut.current = undefined;
100
+ }, autoLoopingTimeOut);
101
+ }
102
+ else {
103
+ startAutoLoop();
104
+ }
105
+ }
106
+ }, [animationState, dragState, animationId.current, timeOut.current]); // eslint-disable-line react-hooks/exhaustive-deps
107
+ const startAnimation = (targetPosition) => {
108
+ if (targetPosition === undefined) {
109
+ targetPosition = LoopingArrayCalculator.withoutOffset(currentPosition);
110
+ }
111
+ if (targetPosition === currentPosition) {
112
+ return; // we are exactly where we want to be
113
+ }
114
+ // find target index and fastest path to it
115
+ const direction = util.getBestDirection(currentPosition, targetPosition);
116
+ clearTimeout(timeOut.current);
117
+ timeOut.current = undefined;
118
+ if (animationId.current) {
119
+ cancelAnimationFrame(animationId.current);
120
+ animationId.current = undefined;
121
+ }
122
+ setCarouselInformation(prevState => ({
123
+ ...prevState,
124
+ dragState: undefined,
125
+ animationState: {
126
+ targetPosition: targetPosition,
127
+ direction,
128
+ startPosition: currentPosition,
129
+ isAutoLooping: false
130
+ },
131
+ timeOut: undefined
132
+ }));
133
+ };
134
+ const canGoLeft = () => {
135
+ return isLooping || currentPosition !== 0;
136
+ };
137
+ const canGoRight = () => {
138
+ return isLooping || currentPosition !== length - 1;
139
+ };
140
+ const left = () => {
141
+ if (canGoLeft()) {
142
+ startAnimation(currentPosition === 0 ? length - 1 : LoopingArrayCalculator.withoutOffset(currentPosition - 1));
143
+ }
144
+ };
145
+ const right = () => {
146
+ if (canGoRight()) {
147
+ startAnimation(LoopingArrayCalculator.withoutOffset((currentPosition + 1) % length));
148
+ }
149
+ };
150
+ let items = children.map((item, index) => ({
151
+ index,
152
+ item
153
+ }));
154
+ if (isLooping) {
155
+ const before = createLoopingListWithIndex(children, length - 1, paddingItemCount, false).reverse().map(([index, item]) => ({
156
+ index,
157
+ item
158
+ }));
159
+ const after = createLoopingListWithIndex(children, 0, paddingItemCount).map(([index, item]) => ({
160
+ index,
161
+ item
162
+ }));
163
+ items = [
164
+ ...before,
165
+ ...items,
166
+ ...after
167
+ ];
168
+ }
169
+ const onDragStart = (x) => setCarouselInformation(prevState => ({
170
+ ...prevState,
171
+ dragState: {
172
+ lastX: x,
173
+ startX: x,
174
+ startTime: Date.now(),
175
+ startIndex: currentPosition,
176
+ },
177
+ animationState: undefined // cancel animation
178
+ }));
179
+ const onDrag = (x, width) => {
180
+ // For some weird reason the clientX is 0 on the last dragUpdate before drag end causing issues
181
+ if (!dragState || x === 0) {
182
+ return;
183
+ }
184
+ const offsetUpdate = (dragState.lastX - x) / width;
185
+ const newPosition = util.getCorrectedPosition(currentPosition + offsetUpdate);
186
+ setCarouselInformation(prevState => ({
187
+ ...prevState,
188
+ currentPosition: newPosition,
189
+ dragState: {
190
+ ...dragState,
191
+ lastX: x
192
+ },
193
+ }));
194
+ };
195
+ const onDragEnd = (x, width) => {
196
+ if (!dragState) {
197
+ return;
198
+ }
199
+ const distance = dragState.startX - x;
200
+ const relativeDistance = distance / width;
201
+ const duration = (Date.now() - dragState.startTime); // in milliseconds
202
+ const velocity = distance / (Date.now() - dragState.startTime);
203
+ const isSlide = Math.abs(velocity) > 2 || (duration < 200 && (Math.abs(relativeDistance) > 0.2 || Math.abs(distance) > 50));
204
+ if (isSlide) {
205
+ if (distance > 0 && canGoRight()) {
206
+ right();
207
+ return;
208
+ }
209
+ else if (distance < 0 && canGoLeft()) {
210
+ left();
211
+ return;
212
+ }
213
+ }
214
+ startAnimation();
215
+ };
216
+ const dragHandlers = {
217
+ draggable: true,
218
+ onDragStart: (event) => {
219
+ onDragStart(event.clientX);
220
+ event.dataTransfer.setDragImage(document.createElement('div'), 0, 0);
221
+ },
222
+ onDrag: (event) => onDrag(event.clientX, event.target.getBoundingClientRect().width),
223
+ onDragEnd: (event) => onDragEnd(event.clientX, event.target.getBoundingClientRect().width),
224
+ onTouchStart: (event) => onDragStart(event.touches[0].clientX),
225
+ onTouchMove: (event) => onDrag(event.touches[0].clientX, event.target.getBoundingClientRect().width),
226
+ onTouchEnd: (event) => onDragEnd(event.changedTouches[0].clientX, event.target.getBoundingClientRect().width),
227
+ onTouchCancel: (event) => onDragEnd(event.changedTouches[0].clientX, event.target.getBoundingClientRect().width),
228
+ };
229
+ return (_jsxs("div", { className: "col items-center w-full gap-y-2", children: [_jsxs("div", { className: clsx(`relative w-full overflow-hidden`, heightClassName, className), children: [arrows && (_jsxs(_Fragment, { children: [_jsx("div", { className: clsx('absolute z-10 left-0 top-1/2 -translate-y-1/2 bg-gray-200 hover:bg-gray-300 rounded-lg cursor-pointer border-black border-2', { hidden: !canGoLeft() }), onClick: () => left(), children: _jsx(ChevronLeft, { size: 32 }) }), _jsx("div", { className: clsx('absolute z-10 right-0 top-1/2 -translate-y-1/2 bg-gray-200 hover:bg-gray-300 rounded-lg cursor-pointer border-black border-2', { hidden: !canGoRight() }), onClick: () => right(), children: _jsx(ChevronRight, { size: 32 }) })] })), hintNext ? (_jsxs("div", { className: clsx(`relative row h-full`, heightClassName), children: [_jsx("div", { className: "relative row h-full w-full px-2 overflow-hidden", children: items.map(({ item, index }, listIndex) => (_jsx("div", { className: clsx(`absolute left-[50%] h-full overflow-hidden`, widthClassName, { '!cursor-grabbing': !!dragState }), style: { translate: getStyleOffset(listIndex - (isLooping ? paddingItemCount : 0)) }, ...dragHandlers, onClick: () => startAnimation(index), children: item }, listIndex))) }), _jsx("div", { className: clsx(`hidden pointer-events-none desktop:block absolute left-0 h-full w-[20%] bg-gradient-to-r to-transparent`, blurColor) }), _jsx("div", { className: clsx(`hidden pointer-events-none desktop:block absolute right-0 h-full w-[20%] bg-gradient-to-l to-transparent`, blurColor) })] })) : (_jsx("div", { className: clsx('px-16 h-full', { '!cursor-grabbing': !!dragState }), ...dragHandlers, children: children[currentIndex] }))] }), dots && (_jsx("div", { className: "row items-center justify-center w-full my-2", children: range(0, length - 1).map(index => (_jsx("button", { className: clsx('w-[2rem] min-w-[2rem] h-[0.75rem] min-h-[0.75rem] hover:bg-primary hover:brightness-90 first:rounded-l-md last:rounded-r-md', {
230
+ 'bg-gray-200': currentIndex !== index,
231
+ 'bg-primary': currentIndex === index
232
+ }), onClick: () => startAnimation(index) }, index))) }))] }));
233
+ };
@@ -0,0 +1,11 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ export type DividerInserterProps = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
3
+ children: ReactNode[];
4
+ divider: (index: number) => ReactNode;
5
+ };
6
+ /**
7
+ * A Component for inserting a divider in the middle of each child element
8
+ *
9
+ * undefined elements are removed
10
+ */
11
+ export declare const DividerInserter: ({ children, divider, className, ...restProps }: DividerInserterProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import clsx from 'clsx';
3
+ /**
4
+ * A Component for inserting a divider in the middle of each child element
5
+ *
6
+ * undefined elements are removed
7
+ */
8
+ export const DividerInserter = ({ children, divider, className, ...restProps }) => {
9
+ const nodes = [];
10
+ for (let index = 0; index < children.length; index++) {
11
+ const element = children[index];
12
+ if (element !== undefined) {
13
+ nodes.push(element);
14
+ if (index < children.length - 1) {
15
+ nodes.push(divider(index));
16
+ }
17
+ }
18
+ }
19
+ return (_jsx("div", { className: clsx(className), ...restProps, children: nodes }));
20
+ };
@@ -0,0 +1,23 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { ExpandableProps } from '../Expandable';
3
+ type ContentType = {
4
+ type: 'markdown';
5
+ value: string;
6
+ } | {
7
+ type: 'custom';
8
+ value: ReactNode;
9
+ };
10
+ export type FAQItem = Pick<ExpandableProps, 'initialExpansion' | 'className'> & {
11
+ id: string;
12
+ title: string;
13
+ content: ContentType;
14
+ };
15
+ export type FAQSectionProps = {
16
+ entries: FAQItem[];
17
+ expandableClassName?: string;
18
+ };
19
+ /**
20
+ * Description
21
+ */
22
+ export declare const FAQSection: ({ entries, expandableClassName }: FAQSectionProps) => import("react/jsx-runtime").JSX.Element;
23
+ export {};
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import clsx from 'clsx';
3
+ import { ChevronDown, ChevronUp } from 'lucide-react';
4
+ import { Expandable } from '../Expandable';
5
+ import { MarkdownInterpreter } from '../MarkdownInterpreter';
6
+ /**
7
+ * Description
8
+ */
9
+ export const FAQSection = ({ entries, expandableClassName }) => {
10
+ const chevronSize = 28;
11
+ return (_jsx("div", { className: "col gap-y-4", children: entries.map(({ id, title, content, ...restProps }) => (_jsx(Expandable, { ...restProps, label: (_jsx("h3", { id: id, className: "textstyle-title-md", children: title })), clickOnlyOnHeader: false, icon: (expanded) => expanded ?
12
+ (_jsx(ChevronUp, { size: chevronSize, className: "text-primary", style: { minWidth: `${chevronSize}px` } })) :
13
+ (_jsx(ChevronDown, { size: chevronSize, className: "text-primary" })), className: clsx('rounded-xl', expandableClassName), headerClassName: "px-6 py-4", children: _jsx("div", { className: "mt-2 px-6 pb-4", children: content.type === 'markdown' ? (_jsx(MarkdownInterpreter, { text: content.value })) : content.value }) }, id))) }));
14
+ };
@@ -0,0 +1,34 @@
1
+ import type { ReactNode } from 'react';
2
+ export type TileProps = {
3
+ title: {
4
+ value: string;
5
+ className?: string;
6
+ };
7
+ description?: {
8
+ value: string;
9
+ className?: string;
10
+ };
11
+ prefix?: ReactNode;
12
+ suffix?: ReactNode;
13
+ className?: string;
14
+ };
15
+ /**
16
+ * A component for creating a tile similar to the flutter ListTile
17
+ */
18
+ export declare const Tile: ({ title, description, prefix, suffix, className }: TileProps) => import("react/jsx-runtime").JSX.Element;
19
+ type ImageLocation = 'prefix' | 'suffix';
20
+ type ImageSize = {
21
+ width: number;
22
+ height: number;
23
+ };
24
+ export type TileWithImageProps = Omit<TileProps, 'suffix' | 'prefix'> & {
25
+ url: string;
26
+ imageLocation?: ImageLocation;
27
+ imageSize?: ImageSize;
28
+ imageClassName?: string;
29
+ };
30
+ /**
31
+ * A Tile with an image as prefix or suffix
32
+ */
33
+ export declare const TileWithImage: ({ url, imageLocation, imageSize, imageClassName, ...tileProps }: TileWithImageProps) => import("react/jsx-runtime").JSX.Element;
34
+ export {};
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Image from 'next/image';
3
+ import clsx from 'clsx';
4
+ /**
5
+ * A component for creating a tile similar to the flutter ListTile
6
+ */
7
+ export const Tile = ({ title, description, prefix, suffix, className }) => {
8
+ var _a;
9
+ return (_jsxs("div", { className: clsx('row gap-x-4 w-full items-center', className), children: [prefix, _jsxs("div", { className: "col w-full", children: [_jsx("span", { className: clsx(title.className), children: title.value }), !!description &&
10
+ _jsx("span", { className: clsx((_a = description.className) !== null && _a !== void 0 ? _a : 'textstyle-description'), children: description.value })] }), suffix] }));
11
+ };
12
+ /**
13
+ * A Tile with an image as prefix or suffix
14
+ */
15
+ export const TileWithImage = ({ url, imageLocation = 'prefix', imageSize = { width: 24, height: 24 }, imageClassName = '', ...tileProps }) => {
16
+ const image = _jsx(Image, { src: url, alt: "", ...imageSize, className: clsx(imageClassName) });
17
+ return (_jsx(Tile, { ...tileProps, prefix: imageLocation === 'prefix' ? image : undefined, suffix: imageLocation === 'suffix' ? image : undefined }));
18
+ };
@@ -0,0 +1,34 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ import type { SolidButtonColor } from '../Button';
3
+ import type { PropsForTranslation } from '../../hooks/useTranslation';
4
+ import { type ModalProps } from './Modal';
5
+ type ConfirmDialogTranslation = {
6
+ confirm: string;
7
+ cancel: string;
8
+ decline: string;
9
+ };
10
+ export type ConfirmDialogType = 'positive' | 'negative' | 'neutral';
11
+ export type ButtonOverwriteType = {
12
+ text?: string;
13
+ color?: SolidButtonColor;
14
+ disabled?: boolean;
15
+ };
16
+ export type ConfirmDialogProps = ModalProps & {
17
+ isShowingDecline?: boolean;
18
+ requireAnswer?: boolean;
19
+ onCancel?: () => void;
20
+ onConfirm: () => void;
21
+ onDecline?: () => void;
22
+ confirmType?: ConfirmDialogType;
23
+ /**
24
+ * Order: Cancel, Decline, Confirm
25
+ */
26
+ buttonOverwrites?: [ButtonOverwriteType, ButtonOverwriteType, ButtonOverwriteType];
27
+ };
28
+ /**
29
+ * A Dialog for asking the user for Confirmation
30
+ *
31
+ * To require an answer omit the onBackgroundClick
32
+ */
33
+ export declare const ConfirmDialog: ({ overwriteTranslation, children, onCancel, onConfirm, onDecline, confirmType, buttonOverwrites, ...restProps }: PropsForTranslation<ConfirmDialogTranslation, PropsWithChildren<ConfirmDialogProps>>) => import("react/jsx-runtime").JSX.Element;
34
+ export {};
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { SolidButton } from '../Button';
3
+ import { useTranslation } from '../../hooks/useTranslation';
4
+ import { Modal } from './Modal';
5
+ const defaultConfirmDialogTranslation = {
6
+ en: {
7
+ confirm: 'Confirm',
8
+ cancel: 'Cancel',
9
+ decline: 'Decline'
10
+ },
11
+ de: {
12
+ confirm: 'Bestätigen',
13
+ cancel: 'Abbrechen',
14
+ decline: 'Ablehnen'
15
+ }
16
+ };
17
+ /**
18
+ * A Dialog for asking the user for Confirmation
19
+ *
20
+ * To require an answer omit the onBackgroundClick
21
+ */
22
+ export const ConfirmDialog = ({ overwriteTranslation, children, onCancel, onConfirm, onDecline, confirmType = 'positive', buttonOverwrites, ...restProps }) => {
23
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
24
+ const translation = useTranslation(defaultConfirmDialogTranslation, overwriteTranslation);
25
+ const mapping = {
26
+ neutral: 'primary',
27
+ negative: 'negative',
28
+ positive: 'positive'
29
+ };
30
+ return (_jsxs(Modal, { ...restProps, children: [children, _jsxs("div", { className: "row mt-3 gap-x-4 justify-end", children: [onCancel && (_jsx(SolidButton, { color: (_a = buttonOverwrites === null || buttonOverwrites === void 0 ? void 0 : buttonOverwrites[0].color) !== null && _a !== void 0 ? _a : 'primary', onClick: onCancel, disabled: (_b = buttonOverwrites === null || buttonOverwrites === void 0 ? void 0 : buttonOverwrites[0].disabled) !== null && _b !== void 0 ? _b : false, children: (_c = buttonOverwrites === null || buttonOverwrites === void 0 ? void 0 : buttonOverwrites[0].text) !== null && _c !== void 0 ? _c : translation.cancel })), onDecline && (_jsx(SolidButton, { color: (_d = buttonOverwrites === null || buttonOverwrites === void 0 ? void 0 : buttonOverwrites[1].color) !== null && _d !== void 0 ? _d : 'negative', onClick: onDecline, disabled: (_e = buttonOverwrites === null || buttonOverwrites === void 0 ? void 0 : buttonOverwrites[1].disabled) !== null && _e !== void 0 ? _e : false, children: (_f = buttonOverwrites === null || buttonOverwrites === void 0 ? void 0 : buttonOverwrites[1].text) !== null && _f !== void 0 ? _f : translation.decline })), _jsx(SolidButton, { autoFocus: true, color: (_g = buttonOverwrites === null || buttonOverwrites === void 0 ? void 0 : buttonOverwrites[2].color) !== null && _g !== void 0 ? _g : mapping[confirmType], onClick: onConfirm, disabled: (_h = buttonOverwrites === null || buttonOverwrites === void 0 ? void 0 : buttonOverwrites[2].disabled) !== null && _h !== void 0 ? _h : false, children: (_j = buttonOverwrites === null || buttonOverwrites === void 0 ? void 0 : buttonOverwrites[2].text) !== null && _j !== void 0 ? _j : translation.confirm })] })] }));
31
+ };
@@ -0,0 +1,19 @@
1
+ import type { PropsWithChildren } from 'react';
2
+ import type { PropsForTranslation } from '../../hooks/useTranslation';
3
+ import { type ModalProps } from './Modal';
4
+ type DiscardChangesDialogTranslation = {
5
+ save: string;
6
+ cancel: string;
7
+ dontSave: string;
8
+ title: string;
9
+ description: string;
10
+ };
11
+ type DiscardChangesDialogProps = ModalProps & {
12
+ isShowingDecline?: boolean;
13
+ requireAnswer?: boolean;
14
+ onCancel: () => void;
15
+ onSave: () => void;
16
+ onDontSave: () => void;
17
+ };
18
+ export declare const DiscardChangesDialog: ({ overwriteTranslation, children, title, description, onCancel, onSave, onDontSave, ...modalProps }: PropsForTranslation<DiscardChangesDialogTranslation, PropsWithChildren<DiscardChangesDialogProps>>) => import("react/jsx-runtime").JSX.Element;
19
+ export {};
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { SolidButton } from '../Button';
3
+ import { useTranslation } from '../../hooks/useTranslation';
4
+ import { Modal } from './Modal';
5
+ const defaultDiscardChangesDialogTranslation = {
6
+ en: {
7
+ save: 'Save',
8
+ cancel: 'Cancel',
9
+ dontSave: 'Don\'t save',
10
+ title: 'Unsaved Changes',
11
+ description: 'Do you want to save your changes?'
12
+ },
13
+ de: {
14
+ save: 'Speichern',
15
+ cancel: 'Abbrechen',
16
+ dontSave: 'Nicht Speichern',
17
+ title: 'Ungespeicherte Änderungen',
18
+ description: 'Möchtest du die Änderungen speichern?'
19
+ }
20
+ };
21
+ export const DiscardChangesDialog = ({ overwriteTranslation, children, title, description, onCancel, onSave, onDontSave, ...modalProps }) => {
22
+ const translation = useTranslation(defaultDiscardChangesDialogTranslation, overwriteTranslation);
23
+ return (_jsxs(Modal, { title: title !== null && title !== void 0 ? title : translation.title, description: description !== null && description !== void 0 ? description : translation.description, ...modalProps, children: [children, _jsxs("div", { className: "row mt-3 gap-x-4 justify-end", children: [_jsx(SolidButton, { color: "positive", onClick: onSave, children: translation.save }), _jsx(SolidButton, { color: "negative", onClick: onDontSave, children: translation.dontSave }), _jsx(SolidButton, { autoFocus: true, color: "primary", onClick: onCancel, children: translation.cancel })] })] }));
24
+ };
@@ -0,0 +1,9 @@
1
+ import type { InputProps } from '../user-input/Input';
2
+ import type { ConfirmDialogProps } from './ConfirmDialog';
3
+ export type InputModalProps = ConfirmDialogProps & {
4
+ inputs: InputProps[];
5
+ };
6
+ /**
7
+ * A modal for receiving multiple inputs
8
+ */
9
+ export declare const InputModal: ({ inputs, buttonOverwrites, ...restProps }: InputModalProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Input } from '../user-input/Input';
3
+ import { ConfirmDialog } from './ConfirmDialog';
4
+ /**
5
+ * A modal for receiving multiple inputs
6
+ */
7
+ export const InputModal = ({ inputs, buttonOverwrites, ...restProps }) => {
8
+ return (_jsx(ConfirmDialog, { buttonOverwrites: buttonOverwrites, ...restProps, children: inputs.map((inputProps, index) => _jsx(Input, { ...inputProps }, `input ${index}`)) }));
9
+ };
@@ -0,0 +1,17 @@
1
+ import { type PropsWithChildren } from 'react';
2
+ import type { PropsForTranslation } from '../../hooks/useTranslation';
3
+ import { type ModalProps } from './Modal';
4
+ type LanguageModalTranslation = {
5
+ message: string;
6
+ done: string;
7
+ };
8
+ type LanguageModalProps = ModalProps & {
9
+ onDone: () => void;
10
+ };
11
+ /**
12
+ * A Modal for selecting the Language
13
+ *
14
+ * The State of open needs to be managed by the parent
15
+ */
16
+ export declare const LanguageModal: ({ overwriteTranslation, onDone, onBackgroundClick, ...modalProps }: PropsForTranslation<LanguageModalTranslation, PropsWithChildren<LanguageModalProps>>) => import("react/jsx-runtime").JSX.Element;
17
+ export {};
@@ -0,0 +1,35 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useTranslation } from '../../hooks/useTranslation';
3
+ import { Select } from '../user-input/Select';
4
+ import { useLanguage } from '../../hooks/useLanguage';
5
+ import { SolidButton } from '../Button';
6
+ import { Modal } from './Modal';
7
+ const languageDetails = {
8
+ en: 'English',
9
+ de: 'Deutsch'
10
+ };
11
+ const defaultConfirmDialogTranslation = {
12
+ en: {
13
+ message: 'Choose your language',
14
+ done: 'Done',
15
+ },
16
+ de: {
17
+ message: 'Wählen Sie Ihre Sprache',
18
+ done: 'Fertig',
19
+ }
20
+ };
21
+ /**
22
+ * A Modal for selecting the Language
23
+ *
24
+ * The State of open needs to be managed by the parent
25
+ */
26
+ export const LanguageModal = ({ overwriteTranslation, onDone, onBackgroundClick, ...modalProps }) => {
27
+ const { language, setLanguage } = useLanguage();
28
+ const translation = useTranslation(defaultConfirmDialogTranslation, overwriteTranslation);
29
+ return (_jsx(Modal, { titleText: translation.message, onBackgroundClick: (eventData) => {
30
+ onDone();
31
+ if (onBackgroundClick) {
32
+ onBackgroundClick(eventData);
33
+ }
34
+ }, ...modalProps, children: _jsxs("div", { className: "w-[320px]", children: [_jsx(Select, { className: "mt-2", value: language, options: Object.entries(languageDetails).map(([tag, name]) => ({ label: name, value: tag })), onChange: (language) => setLanguage(language) }), _jsx("div", { className: "row mt-3 gap-x-4 justify-end", children: _jsx(SolidButton, { autoFocus: true, color: "positive", onClick: onDone, children: translation.done }) })] }) }));
35
+ };
@@ -0,0 +1,38 @@
1
+ import { type MouseEventHandler, type PropsWithChildren, type ReactNode } from 'react';
2
+ import type { PropsForTranslation } from '../../hooks/useTranslation';
3
+ type ModalHeaderTranslation = {
4
+ close: string;
5
+ };
6
+ export type ModalHeaderProps = {
7
+ onCloseClick?: () => void;
8
+ /** The title of the Modal. If you want to only set the text use `titleText` instead */
9
+ title?: ReactNode;
10
+ /** The title text of the Modal. If you want to set a custom title use `title` instead */
11
+ titleText?: string;
12
+ /** The description of the Modal. If you want to only set the text use `descriptionText` instead */
13
+ description?: ReactNode;
14
+ /** The description text of the Modal. If you want to set a custom description use `description` instead */
15
+ descriptionText?: string;
16
+ };
17
+ /**
18
+ * A default Header to be used by modals to have a uniform design
19
+ */
20
+ export declare const ModalHeader: ({ overwriteTranslation, onCloseClick, title, titleText, description, descriptionText }: PropsForTranslation<ModalHeaderTranslation, ModalHeaderProps>) => import("react/jsx-runtime").JSX.Element;
21
+ export declare const modalRootName = "modal-root";
22
+ export type ModalProps = {
23
+ id: string;
24
+ isOpen: boolean;
25
+ onBackgroundClick?: MouseEventHandler<HTMLDivElement>;
26
+ backgroundClassName?: string;
27
+ modalClassName?: string;
28
+ containerClassName?: string;
29
+ } & ModalHeaderProps;
30
+ /**
31
+ * A Generic Modal Window
32
+ *
33
+ * The state needs to be managed by the parent of this component
34
+ *
35
+ * DO NOT Conditionally render this always use the isOpen to ensure that the ModalRegister is working properly
36
+ */
37
+ export declare const Modal: ({ children, id, isOpen, onBackgroundClick, backgroundClassName, modalClassName, containerClassName, ...modalHeaderProps }: PropsWithChildren<ModalProps>) => import("react").ReactPortal | null;
38
+ export {};
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useContext, useEffect } from 'react';
3
+ import ReactDOM from 'react-dom';
4
+ import { X } from 'lucide-react';
5
+ import clsx from 'clsx';
6
+ import { useTranslation } from '../../hooks/useTranslation';
7
+ import { Tooltip } from '../Tooltip';
8
+ import { ModalContext } from './ModalRegister';
9
+ const defaultModalHeaderTranslation = {
10
+ en: {
11
+ close: 'Close'
12
+ },
13
+ de: {
14
+ close: 'Schließen'
15
+ }
16
+ };
17
+ /**
18
+ * A default Header to be used by modals to have a uniform design
19
+ */
20
+ export const ModalHeader = ({ overwriteTranslation, onCloseClick, title, titleText = '', description, descriptionText = '' }) => {
21
+ const translation = useTranslation(defaultModalHeaderTranslation, overwriteTranslation);
22
+ return (_jsxs("div", { className: "col", children: [_jsxs("div", { className: "row justify-between items-start gap-x-8", children: [title !== null && title !== void 0 ? title : (_jsx("span", { className: clsx('textstyle-title-lg', {
23
+ 'mb-1': description || descriptionText,
24
+ }), children: titleText })), !!onCloseClick && (_jsx(Tooltip, { tooltip: translation.close, children: _jsx("button", { className: "row bg-gray-200 hover:bg-gray-300 rounded-md p-1", onClick: onCloseClick, children: _jsx(X, {}) }) }))] }), description !== null && description !== void 0 ? description : (_jsx("span", { className: "textstyle-description", children: descriptionText }))] }));
25
+ };
26
+ export const modalRootName = 'modal-root';
27
+ /**
28
+ * A Generic Modal Window
29
+ *
30
+ * The state needs to be managed by the parent of this component
31
+ *
32
+ * DO NOT Conditionally render this always use the isOpen to ensure that the ModalRegister is working properly
33
+ */
34
+ export const Modal = ({ children, id, isOpen, onBackgroundClick, backgroundClassName = '', modalClassName = '', containerClassName = '', ...modalHeaderProps }) => {
35
+ const modalRoot = typeof window !== 'undefined' ? document.getElementById(modalRootName) : null;
36
+ const { register, addToRegister, removeFromRegister } = useContext(ModalContext);
37
+ if (!id) {
38
+ console.error('the id cannot be empty');
39
+ }
40
+ useEffect(() => {
41
+ if (isOpen) {
42
+ addToRegister(id);
43
+ }
44
+ else {
45
+ removeFromRegister(id);
46
+ }
47
+ }, [addToRegister, id, removeFromRegister, isOpen]);
48
+ if (modalRoot === null || !isOpen)
49
+ return null;
50
+ const isLast = register.length < 1 || register[register.length - 1] === id;
51
+ const isSecondLast = register.length < 2 || register[register.length - 2] === id;
52
+ return ReactDOM.createPortal(_jsxs("div", { className: clsx('fixed inset-0 overflow-y-auto z-[99]', containerClassName), id: id, children: [isLast && (_jsx("div", { className: clsx('fixed inset-0 h-screen w-screen', backgroundClassName, {
53
+ 'bg-black/70': isLast && register.length === 1,
54
+ }), onClick: onBackgroundClick })), _jsxs("div", { className: clsx('fixed left-1/2 top-1/2 -translate-y-1/2 -translate-x-1/2 col p-4 bg-white text-black rounded-xl shadow-xl', modalClassName), children: [_jsx(ModalHeader, { ...modalHeaderProps }), children] }), !isLast && (_jsx("div", { className: clsx('fixed inset-0 h-screen w-screen', backgroundClassName, {
55
+ 'bg-black/70': isSecondLast && register.length > 1,
56
+ }) }))] }), modalRoot, id);
57
+ };