@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.
- package/.storybook/main.ts +24 -0
- package/.storybook/preview.tsx +67 -0
- package/LICENSE +373 -0
- package/README.md +8 -0
- package/coloring/shading.ts +46 -0
- package/coloring/types.ts +13 -0
- package/components/Avatar.tsx +58 -0
- package/components/AvatarGroup.tsx +48 -0
- package/components/BreadCrumb.tsx +35 -0
- package/components/Button.tsx +236 -0
- package/components/ChipList.tsx +89 -0
- package/components/Circle.tsx +27 -0
- package/components/ErrorComponent.tsx +40 -0
- package/components/Expandable.tsx +61 -0
- package/components/HelpwaveBadge.tsx +35 -0
- package/components/HideableContentSection.tsx +43 -0
- package/components/InputGroup.tsx +72 -0
- package/components/LoadingAndErrorComponent.tsx +47 -0
- package/components/LoadingAnimation.tsx +40 -0
- package/components/LoadingButton.tsx +27 -0
- package/components/MarkdownInterpreter.tsx +278 -0
- package/components/Pagination.tsx +65 -0
- package/components/Profile.tsx +124 -0
- package/components/ProgressIndicator.tsx +58 -0
- package/components/Ring.tsx +286 -0
- package/components/SearchableList.tsx +69 -0
- package/components/SortButton.tsx +33 -0
- package/components/Span.tsx +0 -0
- package/components/StepperBar.tsx +124 -0
- package/components/Table.tsx +330 -0
- package/components/TechRadar.tsx +247 -0
- package/components/TextImage.tsx +86 -0
- package/components/TimeDisplay.tsx +121 -0
- package/components/Tooltip.tsx +92 -0
- package/components/VerticalDivider.tsx +51 -0
- package/components/date/DatePicker.tsx +164 -0
- package/components/date/DayPicker.tsx +95 -0
- package/components/date/TimePicker.tsx +167 -0
- package/components/date/YearMonthPicker.tsx +130 -0
- package/components/examples/InputGroupExample.tsx +58 -0
- package/components/examples/MultiSelectExample.tsx +57 -0
- package/components/examples/SearchableSelectExample.tsx +34 -0
- package/components/examples/SelectExample.tsx +28 -0
- package/components/examples/StackingModals.tsx +54 -0
- package/components/examples/TableExample.tsx +159 -0
- package/components/examples/TextareaExample.tsx +23 -0
- package/components/examples/TileExample.tsx +25 -0
- package/components/examples/Title.tsx +0 -0
- package/components/examples/date/DateTimePickerExample.tsx +53 -0
- package/components/examples/properties/CheckboxPropertyExample.tsx +29 -0
- package/components/examples/properties/DatePropertyExample.tsx +44 -0
- package/components/examples/properties/MultiSelectPropertyExample.tsx +39 -0
- package/components/examples/properties/NumberPropertyExample.tsx +28 -0
- package/components/examples/properties/SelectPropertyExample.tsx +39 -0
- package/components/examples/properties/TextPropertyExample.tsx +30 -0
- package/components/icons/Helpwave.tsx +51 -0
- package/components/icons/Tag.tsx +29 -0
- package/components/layout/Carousel.tsx +396 -0
- package/components/layout/DividerInserter.tsx +37 -0
- package/components/layout/FAQSection.tsx +57 -0
- package/components/layout/Tile.tsx +67 -0
- package/components/modals/ConfirmDialog.tsx +105 -0
- package/components/modals/DiscardChangesDialog.tsx +71 -0
- package/components/modals/InputModal.tsx +26 -0
- package/components/modals/LanguageModal.tsx +76 -0
- package/components/modals/Modal.tsx +149 -0
- package/components/modals/ModalRegister.tsx +45 -0
- package/components/properties/CheckboxProperty.tsx +62 -0
- package/components/properties/DateProperty.tsx +58 -0
- package/components/properties/MultiSelectProperty.tsx +82 -0
- package/components/properties/NumberProperty.tsx +86 -0
- package/components/properties/PropertyBase.tsx +84 -0
- package/components/properties/SelectProperty.tsx +67 -0
- package/components/properties/TextProperty.tsx +81 -0
- package/components/user-input/Checkbox.tsx +139 -0
- package/components/user-input/DateAndTimePicker.tsx +156 -0
- package/components/user-input/Input.tsx +192 -0
- package/components/user-input/Label.tsx +32 -0
- package/components/user-input/Menu.tsx +75 -0
- package/components/user-input/MultiSelect.tsx +158 -0
- package/components/user-input/ScrollPicker.tsx +240 -0
- package/components/user-input/SearchableSelect.tsx +36 -0
- package/components/user-input/Select.tsx +132 -0
- package/components/user-input/Textarea.tsx +86 -0
- package/components/user-input/ToggleableInput.tsx +115 -0
- package/eslint.config.js +3 -0
- package/globals.css +488 -0
- package/hooks/useHoverState.ts +88 -0
- package/hooks/useLanguage.tsx +78 -0
- package/hooks/useLocalStorage.tsx +33 -0
- package/hooks/useOutsideClick.ts +25 -0
- package/hooks/useSaveDelay.ts +46 -0
- package/hooks/useTheme.tsx +57 -0
- package/hooks/useTranslation.ts +43 -0
- package/index.ts +0 -0
- package/package.json +71 -0
- package/postcss.config.mjs +7 -0
- package/stories/README.md +23 -0
- package/stories/coloring/shading.stories.tsx +54 -0
- package/stories/geometry/Circle.stories.tsx +16 -0
- package/stories/geometry/rings/AnimatedRing.stories.tsx +18 -0
- package/stories/geometry/rings/RadialRings.stories.tsx +19 -0
- package/stories/geometry/rings/Ring.stories.tsx +17 -0
- package/stories/geometry/rings/RingWave.stories.tsx +20 -0
- package/stories/layout/FAQSection.stories.tsx +49 -0
- package/stories/layout/InputGroup.stories.tsx +19 -0
- package/stories/layout/Table.stories.tsx +19 -0
- package/stories/layout/TextImage.stories.tsx +24 -0
- package/stories/layout/chip/Chip.stories.tsx +19 -0
- package/stories/layout/chip/ChipList.stories.tsx +27 -0
- package/stories/layout/tile/Tile.stories.ts +20 -0
- package/stories/layout/tile/TileWithImage.stories.tsx +27 -0
- package/stories/other/BreadCrumbs.stories.tsx +21 -0
- package/stories/other/HelpwaveBadge.stories.tsx +18 -0
- package/stories/other/HelpwaveSpinner.stories.tsx +19 -0
- package/stories/other/MarkdownInterpreter.stories.tsx +18 -0
- package/stories/other/Profile.stories.tsx +52 -0
- package/stories/other/SearchableList.stories.tsx +21 -0
- package/stories/other/StackingModals.stories.tsx +16 -0
- package/stories/other/TechRadar.stories.tsx +14 -0
- package/stories/other/Translation.stories.tsx +56 -0
- package/stories/other/VerticalDivider.stories.tsx +20 -0
- package/stories/other/avatar/Avatar.stories.tsx +19 -0
- package/stories/other/avatar/AvatarGroup.stories.tsx +26 -0
- package/stories/other/tooltip/Tooltip.stories.tsx +30 -0
- package/stories/other/tooltip/TooltipStack.stories.tsx +39 -0
- package/stories/user-action/button/LoadingButton.stories.tsx +21 -0
- package/stories/user-action/button/OutlineButton.stories.tsx +22 -0
- package/stories/user-action/button/SolidButton.stories.tsx +22 -0
- package/stories/user-action/button/TextButton.stories.tsx +22 -0
- package/stories/user-action/input/Checkbox.stories.tsx +20 -0
- package/stories/user-action/input/Label.stories.tsx +18 -0
- package/stories/user-action/input/ScrollPicker.stories.tsx +20 -0
- package/stories/user-action/input/Textarea.stories.tsx +22 -0
- package/stories/user-action/input/date/DatePicker.stories.tsx +23 -0
- package/stories/user-action/input/date/DateTimePicker.stories.tsx +26 -0
- package/stories/user-action/input/date/DayPicker.stories.tsx +20 -0
- package/stories/user-action/input/date/TimePicker.stories.tsx +20 -0
- package/stories/user-action/input/date/YearMonthPicker.stories.tsx +21 -0
- package/stories/user-action/input/select/MultiSelect.stories.tsx +39 -0
- package/stories/user-action/input/select/SearchableSelect.stories.tsx +32 -0
- package/stories/user-action/input/select/Select.stories.tsx +30 -0
- package/stories/user-action/properties/CheckboxProperty.stories.tsx +20 -0
- package/stories/user-action/properties/DateProperty.stories.tsx +21 -0
- package/stories/user-action/properties/MultiSelectProperty.stories.tsx +33 -0
- package/stories/user-action/properties/NumberProperty.stories.tsx +21 -0
- package/stories/user-action/properties/PropertyBase.stories.tsx +28 -0
- package/stories/user-action/properties/SingleSelectProperty.stories.tsx +35 -0
- package/stories/user-action/properties/TextProperty.stories.tsx +20 -0
- package/tsconfig.json +20 -0
- package/util/array.ts +115 -0
- package/util/builder.ts +9 -0
- package/util/date.ts +180 -0
- package/util/easeFunctions.ts +37 -0
- package/util/emailValidation.ts +3 -0
- package/util/loopingArray.ts +94 -0
- package/util/math.ts +3 -0
- package/util/news.ts +43 -0
- package/util/noop.ts +1 -0
- package/util/simpleSearch.ts +65 -0
- package/util/storage.ts +37 -0
- 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
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
|
+
}
|
package/util/storage.ts
ADDED
|
@@ -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