@helpwave/hightide 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/.storybook/main.ts +24 -0
  2. package/.storybook/preview.tsx +67 -0
  3. package/LICENSE +373 -0
  4. package/README.md +8 -0
  5. package/coloring/shading.ts +46 -0
  6. package/coloring/types.ts +13 -0
  7. package/components/Avatar.tsx +58 -0
  8. package/components/AvatarGroup.tsx +48 -0
  9. package/components/BreadCrumb.tsx +35 -0
  10. package/components/Button.tsx +236 -0
  11. package/components/ChipList.tsx +89 -0
  12. package/components/Circle.tsx +27 -0
  13. package/components/ErrorComponent.tsx +40 -0
  14. package/components/Expandable.tsx +61 -0
  15. package/components/HelpwaveBadge.tsx +35 -0
  16. package/components/HideableContentSection.tsx +43 -0
  17. package/components/InputGroup.tsx +72 -0
  18. package/components/LoadingAndErrorComponent.tsx +47 -0
  19. package/components/LoadingAnimation.tsx +40 -0
  20. package/components/LoadingButton.tsx +27 -0
  21. package/components/MarkdownInterpreter.tsx +278 -0
  22. package/components/Pagination.tsx +65 -0
  23. package/components/Profile.tsx +124 -0
  24. package/components/ProgressIndicator.tsx +58 -0
  25. package/components/Ring.tsx +286 -0
  26. package/components/SearchableList.tsx +69 -0
  27. package/components/SortButton.tsx +33 -0
  28. package/components/Span.tsx +0 -0
  29. package/components/StepperBar.tsx +124 -0
  30. package/components/Table.tsx +330 -0
  31. package/components/TechRadar.tsx +247 -0
  32. package/components/TextImage.tsx +86 -0
  33. package/components/TimeDisplay.tsx +121 -0
  34. package/components/Tooltip.tsx +92 -0
  35. package/components/VerticalDivider.tsx +51 -0
  36. package/components/date/DatePicker.tsx +164 -0
  37. package/components/date/DayPicker.tsx +95 -0
  38. package/components/date/TimePicker.tsx +167 -0
  39. package/components/date/YearMonthPicker.tsx +130 -0
  40. package/components/examples/InputGroupExample.tsx +58 -0
  41. package/components/examples/MultiSelectExample.tsx +57 -0
  42. package/components/examples/SearchableSelectExample.tsx +34 -0
  43. package/components/examples/SelectExample.tsx +28 -0
  44. package/components/examples/StackingModals.tsx +54 -0
  45. package/components/examples/TableExample.tsx +159 -0
  46. package/components/examples/TextareaExample.tsx +23 -0
  47. package/components/examples/TileExample.tsx +25 -0
  48. package/components/examples/Title.tsx +0 -0
  49. package/components/examples/date/DateTimePickerExample.tsx +53 -0
  50. package/components/examples/properties/CheckboxPropertyExample.tsx +29 -0
  51. package/components/examples/properties/DatePropertyExample.tsx +44 -0
  52. package/components/examples/properties/MultiSelectPropertyExample.tsx +39 -0
  53. package/components/examples/properties/NumberPropertyExample.tsx +28 -0
  54. package/components/examples/properties/SelectPropertyExample.tsx +39 -0
  55. package/components/examples/properties/TextPropertyExample.tsx +30 -0
  56. package/components/icons/Helpwave.tsx +51 -0
  57. package/components/icons/Tag.tsx +29 -0
  58. package/components/layout/Carousel.tsx +396 -0
  59. package/components/layout/DividerInserter.tsx +37 -0
  60. package/components/layout/FAQSection.tsx +57 -0
  61. package/components/layout/Tile.tsx +67 -0
  62. package/components/modals/ConfirmDialog.tsx +105 -0
  63. package/components/modals/DiscardChangesDialog.tsx +71 -0
  64. package/components/modals/InputModal.tsx +26 -0
  65. package/components/modals/LanguageModal.tsx +76 -0
  66. package/components/modals/Modal.tsx +149 -0
  67. package/components/modals/ModalRegister.tsx +45 -0
  68. package/components/properties/CheckboxProperty.tsx +62 -0
  69. package/components/properties/DateProperty.tsx +58 -0
  70. package/components/properties/MultiSelectProperty.tsx +82 -0
  71. package/components/properties/NumberProperty.tsx +86 -0
  72. package/components/properties/PropertyBase.tsx +84 -0
  73. package/components/properties/SelectProperty.tsx +67 -0
  74. package/components/properties/TextProperty.tsx +81 -0
  75. package/components/user-input/Checkbox.tsx +139 -0
  76. package/components/user-input/DateAndTimePicker.tsx +156 -0
  77. package/components/user-input/Input.tsx +192 -0
  78. package/components/user-input/Label.tsx +32 -0
  79. package/components/user-input/Menu.tsx +75 -0
  80. package/components/user-input/MultiSelect.tsx +158 -0
  81. package/components/user-input/ScrollPicker.tsx +240 -0
  82. package/components/user-input/SearchableSelect.tsx +36 -0
  83. package/components/user-input/Select.tsx +132 -0
  84. package/components/user-input/Textarea.tsx +86 -0
  85. package/components/user-input/ToggleableInput.tsx +115 -0
  86. package/eslint.config.js +3 -0
  87. package/globals.css +488 -0
  88. package/hooks/useHoverState.ts +88 -0
  89. package/hooks/useLanguage.tsx +78 -0
  90. package/hooks/useLocalStorage.tsx +33 -0
  91. package/hooks/useOutsideClick.ts +25 -0
  92. package/hooks/useSaveDelay.ts +46 -0
  93. package/hooks/useTheme.tsx +57 -0
  94. package/hooks/useTranslation.ts +43 -0
  95. package/index.ts +0 -0
  96. package/package.json +71 -0
  97. package/postcss.config.mjs +7 -0
  98. package/stories/README.md +23 -0
  99. package/stories/coloring/shading.stories.tsx +54 -0
  100. package/stories/geometry/Circle.stories.tsx +16 -0
  101. package/stories/geometry/rings/AnimatedRing.stories.tsx +18 -0
  102. package/stories/geometry/rings/RadialRings.stories.tsx +19 -0
  103. package/stories/geometry/rings/Ring.stories.tsx +17 -0
  104. package/stories/geometry/rings/RingWave.stories.tsx +20 -0
  105. package/stories/layout/FAQSection.stories.tsx +49 -0
  106. package/stories/layout/InputGroup.stories.tsx +19 -0
  107. package/stories/layout/Table.stories.tsx +19 -0
  108. package/stories/layout/TextImage.stories.tsx +24 -0
  109. package/stories/layout/chip/Chip.stories.tsx +19 -0
  110. package/stories/layout/chip/ChipList.stories.tsx +27 -0
  111. package/stories/layout/tile/Tile.stories.ts +20 -0
  112. package/stories/layout/tile/TileWithImage.stories.tsx +27 -0
  113. package/stories/other/BreadCrumbs.stories.tsx +21 -0
  114. package/stories/other/HelpwaveBadge.stories.tsx +18 -0
  115. package/stories/other/HelpwaveSpinner.stories.tsx +19 -0
  116. package/stories/other/MarkdownInterpreter.stories.tsx +18 -0
  117. package/stories/other/Profile.stories.tsx +52 -0
  118. package/stories/other/SearchableList.stories.tsx +21 -0
  119. package/stories/other/StackingModals.stories.tsx +16 -0
  120. package/stories/other/TechRadar.stories.tsx +14 -0
  121. package/stories/other/Translation.stories.tsx +56 -0
  122. package/stories/other/VerticalDivider.stories.tsx +20 -0
  123. package/stories/other/avatar/Avatar.stories.tsx +19 -0
  124. package/stories/other/avatar/AvatarGroup.stories.tsx +26 -0
  125. package/stories/other/tooltip/Tooltip.stories.tsx +30 -0
  126. package/stories/other/tooltip/TooltipStack.stories.tsx +39 -0
  127. package/stories/user-action/button/LoadingButton.stories.tsx +21 -0
  128. package/stories/user-action/button/OutlineButton.stories.tsx +22 -0
  129. package/stories/user-action/button/SolidButton.stories.tsx +22 -0
  130. package/stories/user-action/button/TextButton.stories.tsx +22 -0
  131. package/stories/user-action/input/Checkbox.stories.tsx +20 -0
  132. package/stories/user-action/input/Label.stories.tsx +18 -0
  133. package/stories/user-action/input/ScrollPicker.stories.tsx +20 -0
  134. package/stories/user-action/input/Textarea.stories.tsx +22 -0
  135. package/stories/user-action/input/date/DatePicker.stories.tsx +23 -0
  136. package/stories/user-action/input/date/DateTimePicker.stories.tsx +26 -0
  137. package/stories/user-action/input/date/DayPicker.stories.tsx +20 -0
  138. package/stories/user-action/input/date/TimePicker.stories.tsx +20 -0
  139. package/stories/user-action/input/date/YearMonthPicker.stories.tsx +21 -0
  140. package/stories/user-action/input/select/MultiSelect.stories.tsx +39 -0
  141. package/stories/user-action/input/select/SearchableSelect.stories.tsx +32 -0
  142. package/stories/user-action/input/select/Select.stories.tsx +30 -0
  143. package/stories/user-action/properties/CheckboxProperty.stories.tsx +20 -0
  144. package/stories/user-action/properties/DateProperty.stories.tsx +21 -0
  145. package/stories/user-action/properties/MultiSelectProperty.stories.tsx +33 -0
  146. package/stories/user-action/properties/NumberProperty.stories.tsx +21 -0
  147. package/stories/user-action/properties/PropertyBase.stories.tsx +28 -0
  148. package/stories/user-action/properties/SingleSelectProperty.stories.tsx +35 -0
  149. package/stories/user-action/properties/TextProperty.stories.tsx +20 -0
  150. package/tsconfig.json +20 -0
  151. package/util/array.ts +115 -0
  152. package/util/builder.ts +9 -0
  153. package/util/date.ts +180 -0
  154. package/util/easeFunctions.ts +37 -0
  155. package/util/emailValidation.ts +3 -0
  156. package/util/loopingArray.ts +94 -0
  157. package/util/math.ts +3 -0
  158. package/util/news.ts +43 -0
  159. package/util/noop.ts +1 -0
  160. package/util/simpleSearch.ts +65 -0
  161. package/util/storage.ts +37 -0
  162. package/util/types.ts +4 -0
@@ -0,0 +1,94 @@
1
+ /**
2
+ * 1 is forwards
3
+ *
4
+ * -1 is backwards
5
+ */
6
+ export type Direction = 1 | -1
7
+
8
+ export class LoopingArrayCalculator {
9
+ length: number
10
+ isLooping: boolean
11
+ allowedOverScroll: number
12
+
13
+ constructor(length: number, isLooping: boolean = true, allowedOverScroll: number = 0.1) {
14
+ if (allowedOverScroll < 0 || length < 1) {
15
+ throw new Error('Invalid parameters: allowedOverScroll >= 0 and length >= 1 must be true')
16
+ }
17
+
18
+ this.length = length
19
+ this.isLooping = isLooping
20
+ this.allowedOverScroll = allowedOverScroll
21
+ }
22
+
23
+ getCorrectedPosition(position: number): number {
24
+ if (!this.isLooping) {
25
+ return Math.max(-this.allowedOverScroll, Math.min(this.allowedOverScroll + this.length - 1, position))
26
+ }
27
+ if (position >= this.length) {
28
+ return position % this.length
29
+ }
30
+ if (position < 0) {
31
+ return this.length - (Math.abs(position) % this.length)
32
+ }
33
+ return position
34
+ }
35
+
36
+ static withoutOffset(position: number): number {
37
+ return position + LoopingArrayCalculator.getOffset(position)
38
+ }
39
+
40
+ static getOffset(position: number): number {
41
+ return Math.round(position) - position // For example: 45.5 => 46 - 45.5 = 0.5
42
+ }
43
+
44
+ /**
45
+ * @return absolute distance forwards or Infinity when the target cannot be reached (only possible when not isLooping)
46
+ */
47
+ getDistanceDirectional(position: number, target: number, direction: Direction): number {
48
+ if (!this.isLooping && (position < -this.allowedOverScroll || position > this.allowedOverScroll + this.length - 1)) {
49
+ throw new Error('Invalid parameters: position is out of bounds.')
50
+ }
51
+
52
+ const isForwardInvalid = (direction === 1 && position > target)
53
+ const isBackwardInvalid = (direction === -1 && target < position)
54
+
55
+ if (!this.isLooping && (isForwardInvalid || isBackwardInvalid)) {
56
+ return Infinity
57
+ }
58
+
59
+ if (direction === -1) {
60
+ return this.getDistanceDirectional(target, position, 1)
61
+ }
62
+
63
+ position = this.getCorrectedPosition(position)
64
+ target = this.getCorrectedPosition(target)
65
+
66
+ let distance = (target - position) * direction
67
+ if (distance < 0) {
68
+ distance = this.length - (Math.abs(position) % this.length) + target
69
+ }
70
+
71
+ return distance
72
+ }
73
+
74
+ getDistanceForward(position: number, target: number): number {
75
+ return this.getDistanceDirectional(position, target, 1)
76
+ }
77
+
78
+ getDistanceBackward(position: number, target: number): number {
79
+ return this.getDistanceDirectional(position, target, -1)
80
+ }
81
+
82
+ getDistance(position: number, target: number): number {
83
+ const forwardDistance = this.getDistanceForward(position, target)
84
+ const backwardDistance = this.getDistanceBackward(position, target)
85
+
86
+ return Math.min(forwardDistance, backwardDistance)
87
+ }
88
+
89
+ getBestDirection(position: number, target: number): Direction {
90
+ const forwardDistance = this.getDistanceForward(position, target)
91
+ const backwardDistance = this.getDistanceBackward(position, target)
92
+ return forwardDistance < backwardDistance ? 1 : -1
93
+ }
94
+ }
package/util/math.ts ADDED
@@ -0,0 +1,3 @@
1
+ export const clamp = (value: number, min: number = 0, max: number = 1): number => {
2
+ return Math.min(Math.max(value, min), max)
3
+ }
package/util/news.ts ADDED
@@ -0,0 +1,43 @@
1
+ import { z } from 'zod'
2
+ import type { Languages } from '../hooks/useLanguage'
3
+ import { languages } from '../hooks/useLanguage'
4
+
5
+ export type News = {
6
+ title: string,
7
+ date: Date,
8
+ description: (string | URL)[],
9
+ externalResource?: URL,
10
+ keys: string[],
11
+ }
12
+
13
+ export type LocalizedNews = Record<Languages, News[]>
14
+
15
+ export const newsSchema = z.object({
16
+ title: z.string(),
17
+ description: z.string(),
18
+ date: z.string(),
19
+ image: z.string().url().optional(),
20
+ externalResource: z.string().url().optional(),
21
+ keys: z.array(z.string())
22
+ }).transform<News>((obj) => {
23
+ let description: (string | URL)[] = [obj.description]
24
+ if (obj.image) {
25
+ description = [new URL(obj.image), ...description]
26
+ }
27
+
28
+ return {
29
+ title: obj.title,
30
+ date: new Date(obj.date),
31
+ description,
32
+ externalResource: obj.externalResource ? new URL(obj.externalResource) : undefined,
33
+ keys: obj.keys
34
+ }
35
+ })
36
+
37
+ export const newsListSchema = z.array(newsSchema)
38
+
39
+ export const localizedNewsSchema = z.record(z.enum(languages), newsListSchema)
40
+
41
+ export const filterNews = (localizedNews: News[], requiredKeys: string[]) => {
42
+ return localizedNews.filter(news => requiredKeys.every(value => news.keys.includes(value)))
43
+ }
package/util/noop.ts ADDED
@@ -0,0 +1 @@
1
+ export const noop = () => undefined
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Finds all values matching the search values by first mapping the values to a string array and then checking each entry for matches.
3
+ * Returns the list of all matches.
4
+ *
5
+ * @param search The list of search strings e.g. `[name, type]`
6
+ *
7
+ * @param objects The list of objects to be searched in
8
+ *
9
+ * @param mapping The mapping of objects to the string properties they fulfil
10
+ *
11
+ * @return The list of objects that match all search strings
12
+ */
13
+ export const MultiSubjectSearchWithMapping = <T>(search: string[], objects: T[], mapping: (value:T) => (string| undefined)[]) => {
14
+ return objects.filter(object => {
15
+ const mappedSearchKeywords = mapping(object).map(value => value ? value.toLowerCase().trim() : undefined)
16
+ return search.every(searchValue => !!mappedSearchKeywords.find(value => !!value && value.includes(searchValue.toLowerCase().trim())))
17
+ })
18
+ }
19
+
20
+ /**
21
+ * Finds all values matching the search value by first mapping the values to a string array and then checking each entry for matches.
22
+ * Returns the list of all matches.
23
+ *
24
+ * @param search The search string e.g `name`
25
+ *
26
+ * @param objects The list of objects to be searched in
27
+ *
28
+ * @param mapping The mapping of objects to the string properties they fulfil
29
+ *
30
+ * @return The list of objects that match the search string
31
+ */
32
+ export const MultiSearchWithMapping = <T>(search: string, objects: T[], mapping: (value:T) => string[]) => {
33
+ return objects.filter(object => {
34
+ const mappedSearchKeywords = mapping(object).map(value => value.toLowerCase().trim())
35
+ return !!mappedSearchKeywords.find(value => value.includes(search.toLowerCase().trim()))
36
+ })
37
+ }
38
+
39
+ /**
40
+ * Finds all values matching the search value by first mapping the values to a string and returns the list of all matches.
41
+ *
42
+ * @param search The search string e.g `name`
43
+ *
44
+ * @param objects The list of objects to be searched in
45
+ *
46
+ * @param mapping The mapping of objects to a string that is compared to the search
47
+ *
48
+ * @return The list of objects that match the search string
49
+ */
50
+ export const SimpleSearchWithMapping = <T>(search: string, objects: T[], mapping: (value:T) => string) => {
51
+ return MultiSearchWithMapping(search, objects, value => [mapping(value)])
52
+ }
53
+
54
+ /**
55
+ * Finds all values matching the search value and returns the list of all matches.
56
+ *
57
+ * @param search The search string e.g `name`
58
+ *
59
+ * @param objects The list of objects to be searched in
60
+ *
61
+ * @return The list of objects that match the search string
62
+ */
63
+ export const SimpleSearch = (search: string, objects: string[]) => {
64
+ return SimpleSearchWithMapping(search, objects, value => value)
65
+ }
@@ -0,0 +1,37 @@
1
+ class StorageService {
2
+ // this seems to be a bug in eslint as 'paramter-properties' is a special syntax of typescript
3
+
4
+ constructor(private storage: Storage) {}
5
+
6
+ public get<T>(key: string): T | null {
7
+ const value = this.storage.getItem(key)
8
+ if (value === null) {
9
+ return null
10
+ }
11
+ return JSON.parse(value)
12
+ }
13
+
14
+ public set<T>(key: string, value: T) {
15
+ this.storage.setItem(key, JSON.stringify(value))
16
+ }
17
+
18
+ public delete(key: string) {
19
+ this.storage.removeItem(key)
20
+ }
21
+
22
+ public deleteAll() {
23
+ this.storage.clear()
24
+ }
25
+ }
26
+
27
+ export class LocalStorageService extends StorageService {
28
+ constructor() {
29
+ super(window.localStorage)
30
+ }
31
+ }
32
+
33
+ export class SessionStorageService extends StorageService {
34
+ constructor() {
35
+ super(window.sessionStorage)
36
+ }
37
+ }
package/util/types.ts ADDED
@@ -0,0 +1,4 @@
1
+ export type NativeProps<
2
+ NativeElement extends keyof React.ReactHTML,
3
+ OmittedKeys extends string | number | symbol | undefined = undefined
4
+ > = Omit<React.JSX.IntrinsicElements[NativeElement], OmittedKeys extends undefined ? 'ref' : 'ref' | OmittedKeys>