@helpwave/hightide 0.0.9 → 0.0.12

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 (301) 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/dist/css/globals.css +2450 -0
  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/globals.css +0 -488
  282. package/hooks/useHoverState.ts +0 -88
  283. package/hooks/useLanguage.tsx +0 -78
  284. package/hooks/useLocalStorage.tsx +0 -33
  285. package/hooks/useOutsideClick.ts +0 -25
  286. package/hooks/useSaveDelay.ts +0 -46
  287. package/hooks/useTheme.tsx +0 -57
  288. package/hooks/useTranslation.ts +0 -43
  289. package/index.ts +0 -0
  290. package/util/array.ts +0 -115
  291. package/util/date.ts +0 -180
  292. package/util/easeFunctions.ts +0 -37
  293. package/util/emailValidation.ts +0 -3
  294. package/util/loopingArray.ts +0 -94
  295. package/util/math.ts +0 -3
  296. package/util/news.ts +0 -43
  297. package/util/noop.ts +0 -1
  298. package/util/storage.ts +0 -37
  299. package/util/types.ts +0 -4
  300. /package/{components/Span.tsx → dist/components/Span.d.ts} +0 -0
  301. /package/{components/examples/Title.tsx → dist/components/examples/Title.d.ts} +0 -0
@@ -1,240 +0,0 @@
1
- import { useCallback, useEffect, useState } from 'react'
2
- import clsx from 'clsx'
3
- import { noop } from '../../util/noop'
4
- import { getNeighbours, range } from '../../util/array'
5
- import { clamp } from '../../util/math'
6
-
7
- export type ScrollPickerProps<T> = {
8
- options: T[],
9
- mapping: (value: T) => string,
10
- selected?: T,
11
- onChange?: (value: T) => void,
12
- disabled?: boolean,
13
- }
14
-
15
- type AnimationData<T> = {
16
- /** The index we scroll to */
17
- targetIndex: number,
18
- /** The index we are currently showing centered */
19
- currentIndex: number,
20
- items: T[],
21
- /** From -0.5 to 0.5 */
22
- transition: number,
23
- velocity: number,
24
- animationVelocity: number,
25
- lastTimeStamp?: number,
26
- lastScrollTimeStamp?: number,
27
- }
28
-
29
- const up = 1
30
- const down = -1
31
- type Direction = 1 | -1
32
-
33
- /**
34
- * A component for picking an option by scrolling
35
- */
36
- export const ScrollPicker = <T, >({
37
- options,
38
- mapping,
39
- selected,
40
- onChange = noop,
41
- disabled = false,
42
- }: ScrollPickerProps<T>) => {
43
- let selectedIndex = 0
44
- if (selected && options.indexOf(selected) !== -1) {
45
- selectedIndex = options.indexOf(selected)
46
- }
47
- const [{
48
- currentIndex,
49
- transition,
50
- items,
51
- lastTimeStamp
52
- }, setAnimation] = useState<AnimationData<T>>({
53
- targetIndex: selectedIndex,
54
- currentIndex: disabled ? selectedIndex : 0,
55
- velocity: 0,
56
- animationVelocity: Math.floor(options.length / 2),
57
- transition: 0,
58
- items: options,
59
- })
60
-
61
- const itemsShownCount = 5
62
- const shownItems = getNeighbours(range(0, items.length - 1), currentIndex).map(index => ({
63
- name: mapping(items[index]!), index
64
- }))
65
-
66
- const itemHeight = 40
67
- const distance = 8
68
-
69
- const containerHeight = itemHeight * (itemsShownCount - 2) + distance * (itemsShownCount - 2 + 1)
70
-
71
- const getDirection = useCallback((targetIndex: number, currentIndex: number, transition: number, length: number): Direction => {
72
- if (targetIndex === currentIndex) {
73
- return transition > 0 ? up : down
74
- }
75
- let distanceForward = targetIndex - currentIndex
76
- if (distanceForward < 0) {
77
- distanceForward += length
78
- }
79
- return distanceForward >= length / 2 ? down : up
80
- }, [])
81
-
82
- const animate = useCallback((timestamp: number, startTime: number | undefined) => {
83
- setAnimation((prevState) => {
84
- const {
85
- targetIndex,
86
- currentIndex,
87
- transition,
88
- animationVelocity,
89
- velocity,
90
- items,
91
- lastScrollTimeStamp
92
- } = prevState
93
- if (disabled) {
94
- return { ...prevState, currentIndex: targetIndex, velocity: 0, lastTimeStamp: timestamp }
95
- }
96
- if ((targetIndex === currentIndex && velocity === 0 && transition === 0) || !startTime) {
97
- return { ...prevState, lastTimeStamp: timestamp }
98
- }
99
- const progress = (timestamp - startTime) / 1000 // to seconds
100
- const direction = getDirection(targetIndex, currentIndex, transition, items.length)
101
-
102
- let newVelocity = velocity
103
- let usedVelocity
104
- let newCurrentIndex = currentIndex
105
- const isAutoScrolling = velocity === 0 && (!lastScrollTimeStamp || timestamp - lastScrollTimeStamp > 300)
106
-
107
- const newLastScrollTimeStamp = velocity !== 0 ? timestamp : lastScrollTimeStamp
108
-
109
- // manual scrolling
110
- if (isAutoScrolling) {
111
- usedVelocity = direction * animationVelocity
112
- } else {
113
- usedVelocity = velocity
114
- newVelocity = velocity * 0.5 // drag loss
115
- if (Math.abs(newVelocity) <= 0.05) {
116
- newVelocity = 0
117
- }
118
- }
119
-
120
- let newTransition = transition + usedVelocity * progress
121
- const changeThreshold = 0.5
122
-
123
- while (newTransition >= changeThreshold) {
124
- if (newCurrentIndex === targetIndex && newTransition >= changeThreshold && isAutoScrolling) {
125
- newTransition = 0
126
- break
127
- }
128
- newCurrentIndex = (currentIndex + 1) % items.length
129
- newTransition -= 1
130
- }
131
- if (newTransition >= changeThreshold) {
132
- newTransition = 0
133
- }
134
- while (newTransition <= -changeThreshold) {
135
- if (newCurrentIndex === targetIndex && newTransition <= -changeThreshold && isAutoScrolling) {
136
- newTransition = 0
137
- break
138
- }
139
- newCurrentIndex = currentIndex === 0 ? items.length - 1 : currentIndex - 1
140
- newTransition += 1
141
- }
142
- let newTargetIndex = targetIndex
143
- if (!isAutoScrolling) {
144
- newTargetIndex = newCurrentIndex
145
- }
146
-
147
- if ((currentIndex !== newTargetIndex || newTargetIndex !== targetIndex) && newTargetIndex === newCurrentIndex) {
148
- onChange(items[newCurrentIndex]!)
149
- }
150
- return {
151
- targetIndex: newTargetIndex,
152
- currentIndex: newCurrentIndex,
153
- animationVelocity,
154
- transition: newTransition,
155
- velocity: newVelocity,
156
- items,
157
- lastTimeStamp: timestamp,
158
- lastScrollTimeStamp: newLastScrollTimeStamp
159
- }
160
- })
161
- }, [disabled, getDirection, onChange])
162
-
163
- useEffect(() => {
164
- // constant update
165
- requestAnimationFrame((timestamp) => animate(timestamp, lastTimeStamp))
166
- })
167
-
168
- const opacity = (transition: number, index: number, itemsCount: number) => {
169
- const max = 100
170
- const min = 0
171
- const distance = max - min
172
-
173
- let opacityValue = min
174
- const unitTransition = clamp((transition) / 0.5)
175
- if (index === 1 || index === itemsCount - 2) {
176
- if (index === 1 && transition > 0) {
177
- opacityValue += Math.floor(unitTransition * distance)
178
- }
179
- if (index === itemsCount - 2 && transition < 0) {
180
- opacityValue += Math.floor(unitTransition * distance)
181
- }
182
- } else {
183
- opacityValue = max
184
- }
185
-
186
- // TODO this is not the right value for the bottom entry
187
- return clamp(1- (opacityValue / max))
188
- }
189
-
190
- return (
191
- <div
192
- className="relative overflow-hidden"
193
- style={{ height: containerHeight }}
194
- onWheel={event => {
195
- if (event.deltaY !== 0) {
196
- // TODO slower increase
197
- setAnimation(({ velocity, ...animationData }) =>
198
- ({ ...animationData, velocity: velocity + event.deltaY }))
199
- }
200
- }}
201
- >
202
- <div className="absolute top-1/2 -translate-y-1/2 -translate-x-1/2 left-1/2">
203
- <div
204
- 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-y-2 border-x-0 border-[#00000033]"
205
- style={{ height: `${itemHeight}px` }}
206
- />
207
- <div
208
- className="col select-none"
209
- style={{
210
- transform: `translateY(${-transition * (distance + itemHeight)}px)`,
211
- columnGap: `${distance}px`,
212
- }}
213
- >
214
- {shownItems.map(({ name, index }, arrayIndex) => (
215
- <div
216
- key={index}
217
- className={clsx(
218
- `col items-center justify-center rounded-md`,
219
- {
220
- 'text-primary font-bold': currentIndex === index,
221
- 'text-on-background': currentIndex === index,
222
- 'cursor-pointer': !disabled,
223
- 'cursor-not-allowed': disabled,
224
- }
225
- )}
226
- style={{
227
- opacity: currentIndex !== index ? opacity(transition, arrayIndex, shownItems.length) : undefined,
228
- height: `${itemHeight}px`,
229
- maxHeight: `${itemHeight}px`,
230
- }}
231
- onClick={() => !disabled && setAnimation(prevState => ({ ...prevState, targetIndex: index }))}
232
- >
233
- {name}
234
- </div>
235
- ))}
236
- </div>
237
- </div>
238
- </div>
239
- )
240
- }
@@ -1,36 +0,0 @@
1
- import { useState } from 'react'
2
- import { Search } from 'lucide-react'
3
- import { MultiSearchWithMapping } from '../../util/simpleSearch'
4
- import type { SelectOption, SelectProps } from './Select'
5
- import { Select } from './Select'
6
- import { Input } from './Input'
7
-
8
- export type SearchableSelectProps<T> = SelectProps<T> & {
9
- searchMapping: (value: SelectOption<T>) => string[],
10
- }
11
-
12
- /**
13
- * A Select where items can be searched
14
- */
15
- export const SearchableSelect = <T, >({
16
- value,
17
- options,
18
- searchMapping,
19
- ...selectProps
20
- }: SearchableSelectProps<T>) => {
21
- const [search, setSearch] = useState<string>('')
22
- const filteredOptions = MultiSearchWithMapping(search, options, searchMapping)
23
- return (
24
- <Select
25
- value={value}
26
- options={filteredOptions}
27
- additionalItems={[(
28
- <div key="selectSearch" className="row gap-x-2 items-center">
29
- <Input autoFocus={true} value={search} onChange={setSearch} />
30
- <Search/>
31
- </div>
32
- )]}
33
- {...selectProps}
34
- />
35
- )
36
- }
@@ -1,132 +0,0 @@
1
- import { Menu } from '@headlessui/react'
2
- import { ChevronDown, ChevronUp } from 'lucide-react'
3
- import type { ReactNode } from 'react'
4
- import clsx from 'clsx'
5
- import type { LabelProps } from './Label'
6
- import { Label } from './Label'
7
-
8
- export type SelectOption<T> = {
9
- label: ReactNode,
10
- value: T,
11
- disabled?: boolean,
12
- className?: string,
13
- }
14
-
15
- export type SelectProps<T> = {
16
- value?: T,
17
- label?: LabelProps,
18
- options: SelectOption<T>[],
19
- onChange: (value: T) => void,
20
- isHidingCurrentValue?: boolean,
21
- hintText?: string,
22
- showDisabledOptions?: boolean,
23
- className?: string,
24
- isDisabled?: boolean,
25
- textColor?: string,
26
- hoverColor?: string,
27
- /**
28
- * The items will be at the start of the select and aren't selectable
29
- */
30
- additionalItems?: ReactNode[],
31
- selectedDisplayOverwrite?: ReactNode,
32
- };
33
-
34
- /**
35
- * A Select Component for selecting form a list of options
36
- *
37
- * The State is managed by the parent
38
- */
39
- export const Select = <T, >({
40
- value,
41
- label,
42
- options,
43
- onChange,
44
- isHidingCurrentValue = true,
45
- hintText = '',
46
- showDisabledOptions = true,
47
- isDisabled,
48
- className,
49
- textColor = 'text-menu-text',
50
- hoverColor = 'hover:brightness-90',
51
- additionalItems,
52
- selectedDisplayOverwrite,
53
- }: SelectProps<T>) => {
54
- // Notice: for more complex types this check here might need an additional compare method
55
- let filteredOptions = isHidingCurrentValue ? options.filter(option => option.value !== value) : options
56
- if (!showDisabledOptions) {
57
- filteredOptions = filteredOptions.filter(value => !value.disabled)
58
- }
59
- const selectedOption = options.find(option => option.value === value)
60
- if (value !== undefined && selectedOption === undefined && selectedDisplayOverwrite === undefined) {
61
- console.warn('The selected value is not found in the options list. This might be an error on your part or' +
62
- ' default behavior if it is complex data type on which === does not work. In case of the latter' +
63
- ' use selectedDisplayOverwrite to set your selected text or component')
64
- }
65
-
66
- const borderColor = 'border-menu-border'
67
-
68
- return (
69
- <div className={clsx(className)}>
70
- {label && (
71
- <Label {...label} labelType={label.labelType ?? 'labelBig'} className={clsx('mb-1', label.className)}/>
72
- )}
73
- <Menu as="div" className="relative text-menu-text">
74
- {({ open }) => (
75
- <>
76
- <Menu.Button
77
- className={clsx(
78
- 'inline-flex w-full justify-between items-center rounded-t-lg border-2 px-4 py-2 font-medium bg-menu-background text-menu-text',
79
- textColor, borderColor,
80
- {
81
- 'rounded-b-lg': !open,
82
- [hoverColor]: !isDisabled,
83
- 'bg-disabled-background cursor-not-allowed text-disabled': isDisabled
84
- }
85
- )}
86
- disabled={isDisabled}
87
- >
88
- <span>{selectedDisplayOverwrite ?? selectedOption?.label ?? hintText}</span>
89
- {open ? <ChevronUp/> : <ChevronDown/>}
90
- </Menu.Button>
91
- <Menu.Items
92
- className="absolute w-full z-10 rounded-b-lg bg-menu-background text-menu-text shadow-lg max-h-[500px] overflow-y-auto"
93
- >
94
- {(additionalItems ?? []).map((item, index) => (
95
- <div key={`additionalItems${index}`}
96
- className={clsx(borderColor, 'px-4 py-2 overflow-hidden whitespace-nowrap text-ellipsis border-2 border-t-0', {
97
- 'border-b-0 rounded-b-lg': filteredOptions.length === 0 && index === (additionalItems?.length ?? 1) - 1,
98
- })}
99
- >
100
- {item}
101
- </div>
102
- ))}
103
- {filteredOptions.map((option, index) => (
104
- <Menu.Item key={`item${index}`}>
105
- {
106
- <div
107
- className={clsx('px-4 py-2 overflow-hidden whitespace-nowrap text-ellipsis border-2 border-t-0 cursor-pointer',
108
- option.className, borderColor, {
109
- 'brightness-90': option.value === value,
110
- 'brightness-95': index % 2 === 1,
111
- 'text-disabled bg-disabled-background cursor-not-allowed': !!option.disabled,
112
- 'bg-menu-background text-menu-text hover:brightness-90 cursor-pointer': !option.disabled,
113
- 'rounded-b-lg': index === filteredOptions.length - 1,
114
- })}
115
- onClick={() => {
116
- if (!option.disabled) {
117
- onChange(option.value)
118
- }
119
- }}
120
- >
121
- {option.label}
122
- </div>
123
- }
124
- </Menu.Item>
125
- ))}
126
- </Menu.Items>
127
- </>
128
- )}
129
- </Menu>
130
- </div>
131
- )
132
- }
@@ -1,86 +0,0 @@
1
- import type { TextareaHTMLAttributes } from 'react'
2
- import { useState } from 'react'
3
- import clsx from 'clsx'
4
- import useSaveDelay from '../../hooks/useSaveDelay'
5
- import { noop } from '../../util/noop'
6
- import type { LabelProps } from './Label'
7
- import { Label } from './Label'
8
-
9
- export type TextareaProps = {
10
- /** Outside the area */
11
- label?: Omit<LabelProps, 'id'>,
12
- /** Inside the area */
13
- headline?: string,
14
- id?: string,
15
- resizable?: boolean,
16
- onChange?: (text: string) => void,
17
- disclaimer?: string,
18
- onEditCompleted?: (text: string) => void,
19
- defaultStyle?: boolean,
20
- } & Omit<TextareaHTMLAttributes<Element>, 'id' | 'onChange'>
21
-
22
- /**
23
- * A Textarea component for inputting longer texts
24
- *
25
- * The State is managed by the parent
26
- */
27
- export const Textarea = ({
28
- label,
29
- headline,
30
- id,
31
- resizable = false,
32
- onChange = noop,
33
- disclaimer,
34
- onBlur = noop,
35
- onEditCompleted = noop,
36
- defaultStyle = true,
37
- className,
38
- ...props
39
- }: TextareaProps) => {
40
- const [hasFocus, setHasFocus] = useState(false)
41
- const { restartTimer, clearUpdateTimer } = useSaveDelay(() => undefined, 3000)
42
-
43
- const onEditCompletedWrapper = (text: string) => {
44
- onEditCompleted(text)
45
- clearUpdateTimer()
46
- }
47
-
48
- return (
49
- <div className="w-full">
50
- {label && (<Label {...label} htmlFor={id} className={clsx('mb-1', label.className)} labelType={label.labelType ?? 'labelSmall'}/>)}
51
- <div className={`${clsx(' bg-surface text-on-surface focus-within:border-primary relative', { 'shadow border-2 border-gray-300 hover:border-primary rounded-lg': defaultStyle })}`}>
52
- {headline && (
53
- <span className="mx-3 mt-3 block text-gray-700 font-bold">
54
- {headline}
55
- </span>
56
- )}
57
- <textarea
58
- id={id}
59
- className={clsx('pt-0 px-3 border-transparent focus:border-transparent focus:ring-0 appearance-none border w-full leading-tight focus:outline-none', { 'resize-none': !resizable, 'h-32': defaultStyle, 'mt-3': !headline }, className)}
60
- onChange={(event) => {
61
- const value = event.target.value
62
- restartTimer(() => {
63
- onEditCompletedWrapper(value)
64
- })
65
- onChange(value)
66
- }}
67
- onFocus={() => {
68
- setHasFocus(true)
69
- }}
70
- onBlur={(event) => {
71
- onBlur(event)
72
- onEditCompletedWrapper(event.target.value)
73
- setHasFocus(false)
74
- }}
75
- {...props}
76
- >
77
- </textarea>
78
- </div>
79
- {(hasFocus && disclaimer) && (
80
- <label className="text-negative">
81
- {disclaimer}
82
- </label>
83
- )}
84
- </div>
85
- )
86
- }
@@ -1,115 +0,0 @@
1
- import { useState } from 'react'
2
- import type { HTMLInputTypeAttribute, InputHTMLAttributes } from 'react'
3
- import { Pencil } from 'lucide-react'
4
- import clsx from 'clsx'
5
- import useSaveDelay from '../../hooks/useSaveDelay'
6
- import { noop } from '../../util/noop'
7
-
8
- type InputProps = {
9
- /**
10
- * used for the label's `for` attribute
11
- */
12
- id: string,
13
- value: string,
14
- /**
15
- * @default 'text'
16
- */
17
- type?: HTMLInputTypeAttribute,
18
- /**
19
- * Callback for when the input's value changes
20
- * This is pretty much required but made optional for the rare cases where it actually isn't need such as when used with disabled
21
- * That could be enforced through a union type but that seems a bit overkill
22
- * @default noop
23
- */
24
- onChange?: (text: string) => void,
25
- labelClassName?: string,
26
- initialState?: 'editing' | 'display',
27
- size?: number,
28
- disclaimer?: string,
29
- onEditCompleted?: (text: string) => void,
30
- } & Omit<InputHTMLAttributes<HTMLInputElement>, 'id' | 'value' | 'label' | 'type' | 'onChange' | 'crossOrigin'>
31
-
32
- /**
33
- * A Text input component for inputting text. It changes appearance upon entering the edit mode and switches
34
- * back to display mode on loss of focus or on enter
35
- *
36
- * The State is managed by the parent
37
- */
38
- export const ToggleableInput = ({
39
- id,
40
- type = 'text',
41
- value,
42
- onChange = noop,
43
- labelClassName = '',
44
- initialState = 'display',
45
- size = 20,
46
- disclaimer,
47
- onBlur,
48
- onEditCompleted = noop,
49
- ...restProps
50
- }: InputProps) => {
51
- const [isEditing, setIsEditing] = useState(initialState !== 'display')
52
- const { restartTimer, clearUpdateTimer } = useSaveDelay(() => undefined, 3000)
53
-
54
- const onEditCompletedWrapper = (text: string) => {
55
- onEditCompleted(text)
56
- clearUpdateTimer()
57
- }
58
-
59
- return (
60
- <div>
61
- <div
62
- className="row items-center w-full gap-x-2 overflow-hidden"
63
- onClick={() => !isEditing ? setIsEditing(!isEditing) : undefined}
64
- >
65
- <div className={clsx('row overflow-hidden', { 'flex-1': isEditing })}>
66
- {isEditing ? (
67
- <input
68
- autoFocus
69
- {...restProps}
70
- value={value}
71
- type={type}
72
- id={id}
73
- onChange={event => {
74
- const value = event.target.value
75
- restartTimer(() => {
76
- onEditCompletedWrapper(value)
77
- })
78
- onChange(value)
79
- }}
80
- onBlur={(event) => {
81
- if (onBlur) {
82
- onBlur(event)
83
- }
84
- onEditCompletedWrapper(value)
85
- setIsEditing(false)
86
- }}
87
- onKeyDown={event => {
88
- if (event.key === 'Enter') {
89
- setIsEditing(false)
90
- onEditCompletedWrapper(value)
91
- }
92
- }}
93
- className={clsx(labelClassName, `w-full border-none rounded-none focus:ring-0 shadow-transparent decoration-primary p-0 underline-offset-4`, {
94
- underline: isEditing
95
- })}
96
- onFocus={event => event.target.select()}
97
- />
98
- ) : (
99
- <span
100
- className={clsx(labelClassName, 'max-w-xs break-words overflow-hidden')}
101
- >
102
- {value}
103
- </span>
104
- )}
105
- </div>
106
- <Pencil className={clsx(`min-w-[${size}px] cursor-pointer`, { 'text-transparent': isEditing })} size={size} />
107
- </div>
108
- {(isEditing && disclaimer) && (
109
- <label className="text-negative">
110
- {disclaimer}
111
- </label>
112
- )}
113
- </div>
114
- )
115
- }