@helpwave/hightide 0.0.8 → 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.
- package/README.md +1 -1
- package/dist/coloring/shading.d.ts +2 -0
- package/dist/coloring/shading.js +40 -0
- package/dist/coloring/types.d.ts +11 -0
- package/dist/coloring/types.js +1 -0
- package/dist/components/Avatar.d.ts +14 -0
- package/dist/components/Avatar.js +35 -0
- package/dist/components/AvatarGroup.d.ts +10 -0
- package/dist/components/AvatarGroup.js +13 -0
- package/dist/components/BreadCrumb.d.ts +16 -0
- package/dist/components/BreadCrumb.js +12 -0
- package/dist/components/Button.d.ts +41 -0
- package/dist/components/Button.js +84 -0
- package/dist/components/ChipList.d.ts +21 -0
- package/dist/components/ChipList.js +38 -0
- package/dist/components/Circle.d.ts +6 -0
- package/dist/components/Circle.js +10 -0
- package/dist/components/ErrorComponent.d.ts +13 -0
- package/dist/components/ErrorComponent.js +19 -0
- package/dist/components/Expandable.d.ts +30 -0
- package/dist/components/Expandable.js +16 -0
- package/dist/components/HelpwaveBadge.d.ts +11 -0
- package/dist/components/HelpwaveBadge.js +14 -0
- package/dist/components/HideableContentSection.d.ts +10 -0
- package/dist/components/HideableContentSection.js +15 -0
- package/dist/components/InputGroup.d.ts +13 -0
- package/dist/components/InputGroup.js +33 -0
- package/dist/components/LoadingAndErrorComponent.d.ts +17 -0
- package/dist/components/LoadingAndErrorComponent.js +25 -0
- package/dist/components/LoadingAnimation.d.ts +13 -0
- package/dist/components/LoadingAnimation.js +19 -0
- package/dist/components/LoadingButton.d.ts +6 -0
- package/dist/components/LoadingButton.js +10 -0
- package/dist/components/MarkdownInterpreter.d.ts +25 -0
- package/dist/components/MarkdownInterpreter.js +190 -0
- package/dist/components/Pagination.d.ts +14 -0
- package/dist/components/Pagination.js +25 -0
- package/dist/components/Profile.d.ts +28 -0
- package/dist/components/Profile.js +45 -0
- package/dist/components/ProgressIndicator.d.ts +21 -0
- package/dist/components/ProgressIndicator.js +24 -0
- package/dist/components/Ring.d.ts +31 -0
- package/dist/components/Ring.js +113 -0
- package/dist/components/SearchableList.d.ts +18 -0
- package/dist/components/SearchableList.js +27 -0
- package/dist/components/SortButton.d.ts +10 -0
- package/dist/components/SortButton.js +9 -0
- package/dist/components/Span.js +1 -0
- package/dist/components/StepperBar.d.ts +23 -0
- package/dist/components/StepperBar.js +47 -0
- package/dist/components/Table.d.ts +87 -0
- package/dist/components/Table.js +187 -0
- package/dist/components/TechRadar.d.ts +36 -0
- package/dist/components/TechRadar.js +191 -0
- package/dist/components/TextImage.d.ts +20 -0
- package/dist/components/TextImage.js +31 -0
- package/dist/components/TimeDisplay.d.ts +30 -0
- package/dist/components/TimeDisplay.js +83 -0
- package/dist/components/Tooltip.d.ts +34 -0
- package/dist/components/Tooltip.js +38 -0
- package/dist/components/VerticalDivider.d.ts +11 -0
- package/dist/components/VerticalDivider.js +7 -0
- package/dist/components/date/DatePicker.d.ts +26 -0
- package/dist/components/date/DatePicker.js +58 -0
- package/dist/components/date/DayPicker.d.ts +16 -0
- package/dist/components/date/DayPicker.js +37 -0
- package/dist/components/date/TimePicker.d.ts +12 -0
- package/dist/components/date/TimePicker.js +79 -0
- package/dist/components/date/YearMonthPicker.d.ts +11 -0
- package/dist/components/date/YearMonthPicker.js +59 -0
- package/dist/components/examples/InputGroupExample.d.ts +6 -0
- package/dist/components/examples/InputGroupExample.js +21 -0
- package/dist/components/examples/MultiSelectExample.d.ts +7 -0
- package/dist/components/examples/MultiSelectExample.js +27 -0
- package/dist/components/examples/SearchableSelectExample.d.ts +6 -0
- package/dist/components/examples/SearchableSelectExample.js +17 -0
- package/dist/components/examples/SelectExample.d.ts +4 -0
- package/dist/components/examples/SelectExample.js +15 -0
- package/dist/components/examples/StackingModals.d.ts +4 -0
- package/dist/components/examples/StackingModals.js +15 -0
- package/dist/components/examples/TableExample.d.ts +9 -0
- package/dist/components/examples/TableExample.js +92 -0
- package/dist/components/examples/TextareaExample.d.ts +6 -0
- package/dist/components/examples/TextareaExample.js +10 -0
- package/dist/components/examples/TileExample.d.ts +9 -0
- package/dist/components/examples/TileExample.js +9 -0
- package/dist/components/examples/Title.js +1 -0
- package/dist/components/examples/date/DateTimePickerExample.d.ts +10 -0
- package/dist/components/examples/date/DateTimePickerExample.js +21 -0
- package/dist/components/examples/properties/CheckboxPropertyExample.d.ts +8 -0
- package/dist/components/examples/properties/CheckboxPropertyExample.js +13 -0
- package/dist/components/examples/properties/DatePropertyExample.d.ts +8 -0
- package/dist/components/examples/properties/DatePropertyExample.js +23 -0
- package/dist/components/examples/properties/MultiSelectPropertyExample.d.ts +8 -0
- package/dist/components/examples/properties/MultiSelectPropertyExample.js +16 -0
- package/dist/components/examples/properties/NumberPropertyExample.d.ts +6 -0
- package/dist/components/examples/properties/NumberPropertyExample.js +13 -0
- package/dist/components/examples/properties/SelectPropertyExample.d.ts +6 -0
- package/dist/components/examples/properties/SelectPropertyExample.js +18 -0
- package/dist/components/examples/properties/TextPropertyExample.d.ts +8 -0
- package/dist/components/examples/properties/TextPropertyExample.js +13 -0
- package/dist/components/icons/Helpwave.d.ts +10 -0
- package/dist/components/icons/Helpwave.js +20 -0
- package/dist/components/icons/Tag.d.ts +10 -0
- package/dist/components/icons/Tag.js +12 -0
- package/dist/components/layout/Carousel.d.ts +22 -0
- package/dist/components/layout/Carousel.js +233 -0
- package/dist/components/layout/DividerInserter.d.ts +11 -0
- package/dist/components/layout/DividerInserter.js +20 -0
- package/dist/components/layout/FAQSection.d.ts +23 -0
- package/dist/components/layout/FAQSection.js +14 -0
- package/dist/components/layout/Tile.d.ts +34 -0
- package/dist/components/layout/Tile.js +18 -0
- package/dist/components/modals/ConfirmDialog.d.ts +34 -0
- package/dist/components/modals/ConfirmDialog.js +31 -0
- package/dist/components/modals/DiscardChangesDialog.d.ts +19 -0
- package/dist/components/modals/DiscardChangesDialog.js +24 -0
- package/dist/components/modals/InputModal.d.ts +9 -0
- package/dist/components/modals/InputModal.js +9 -0
- package/dist/components/modals/LanguageModal.d.ts +17 -0
- package/dist/components/modals/LanguageModal.js +35 -0
- package/dist/components/modals/Modal.d.ts +38 -0
- package/dist/components/modals/Modal.js +57 -0
- package/dist/components/modals/ModalRegister.d.ts +11 -0
- package/dist/components/modals/ModalRegister.js +28 -0
- package/dist/components/properties/CheckboxProperty.d.ts +15 -0
- package/dist/components/properties/CheckboxProperty.js +27 -0
- package/dist/components/properties/DateProperty.d.ts +11 -0
- package/dist/components/properties/DateProperty.js +22 -0
- package/dist/components/properties/MultiSelectProperty.d.ts +12 -0
- package/dist/components/properties/MultiSelectProperty.js +33 -0
- package/dist/components/properties/NumberProperty.d.ts +16 -0
- package/dist/components/properties/NumberProperty.js +42 -0
- package/dist/components/properties/PropertyBase.d.ts +23 -0
- package/dist/components/properties/PropertyBase.js +27 -0
- package/dist/components/properties/SelectProperty.d.ts +12 -0
- package/dist/components/properties/SelectProperty.js +22 -0
- package/dist/components/properties/TextProperty.d.ts +15 -0
- package/dist/components/properties/TextProperty.js +37 -0
- package/dist/components/user-input/Checkbox.d.ts +37 -0
- package/dist/components/user-input/Checkbox.js +63 -0
- package/dist/components/user-input/DateAndTimePicker.d.ts +39 -0
- package/dist/components/user-input/DateAndTimePicker.js +65 -0
- package/dist/components/user-input/Input.d.ts +61 -0
- package/dist/components/user-input/Input.js +61 -0
- package/dist/components/user-input/Label.d.ts +12 -0
- package/dist/components/user-input/Label.js +12 -0
- package/dist/components/user-input/Menu.d.ts +21 -0
- package/dist/components/user-input/Menu.js +26 -0
- package/dist/components/user-input/MultiSelect.d.ts +39 -0
- package/dist/components/user-input/MultiSelect.js +57 -0
- package/dist/components/user-input/ScrollPicker.d.ts +11 -0
- package/dist/components/user-input/ScrollPicker.js +151 -0
- package/dist/components/user-input/SearchableSelect.d.ts +8 -0
- package/dist/components/user-input/SearchableSelect.js +14 -0
- package/dist/components/user-input/Select.d.ts +32 -0
- package/dist/components/user-input/Select.js +48 -0
- package/dist/components/user-input/Textarea.d.ts +20 -0
- package/dist/components/user-input/Textarea.js +33 -0
- package/dist/components/user-input/ToggleableInput.d.ts +32 -0
- package/dist/components/user-input/ToggleableInput.js +40 -0
- package/{globals.css → dist/css/globals.css} +1 -1
- package/dist/hooks/useHoverState.d.ts +40 -0
- package/dist/hooks/useHoverState.js +46 -0
- package/dist/hooks/useLanguage.d.ts +17 -0
- package/dist/hooks/useLanguage.js +51 -0
- package/dist/hooks/useLocalStorage.d.ts +4 -0
- package/dist/hooks/useLocalStorage.js +24 -0
- package/dist/hooks/useOutsideClick.d.ts +2 -0
- package/dist/hooks/useOutsideClick.js +22 -0
- package/dist/hooks/useSaveDelay.d.ts +5 -0
- package/dist/hooks/useSaveDelay.js +41 -0
- package/dist/hooks/useTheme.d.ts +16 -0
- package/dist/hooks/useTheme.js +32 -0
- package/dist/hooks/useTranslation.d.ts +24 -0
- package/dist/hooks/useTranslation.js +11 -0
- package/dist/util/array.d.ts +23 -0
- package/dist/util/array.js +103 -0
- package/{util/builder.ts → dist/util/builder.d.ts} +1 -4
- package/dist/util/builder.js +9 -0
- package/dist/util/date.d.ts +28 -0
- package/dist/util/date.js +133 -0
- package/dist/util/easeFunctions.d.ts +9 -0
- package/dist/util/easeFunctions.js +30 -0
- package/dist/util/emailValidation.d.ts +1 -0
- package/dist/util/emailValidation.js +3 -0
- package/dist/util/loopingArray.d.ts +23 -0
- package/dist/util/loopingArray.js +67 -0
- package/dist/util/math.d.ts +1 -0
- package/dist/util/math.js +3 -0
- package/dist/util/news.d.ts +98 -0
- package/dist/util/news.js +27 -0
- package/dist/util/noop.d.ts +1 -0
- package/dist/util/noop.js +1 -0
- package/{util/simpleSearch.ts → dist/util/simpleSearch.d.ts} +4 -21
- package/dist/util/simpleSearch.js +62 -0
- package/dist/util/storage.d.ts +15 -0
- package/dist/util/storage.js +32 -0
- package/dist/util/types.d.ts +1 -0
- package/dist/util/types.js +1 -0
- package/package.json +7 -8
- package/coloring/shading.ts +0 -46
- package/coloring/types.ts +0 -13
- package/components/Avatar.tsx +0 -58
- package/components/AvatarGroup.tsx +0 -48
- package/components/BreadCrumb.tsx +0 -35
- package/components/Button.tsx +0 -236
- package/components/ChipList.tsx +0 -89
- package/components/Circle.tsx +0 -27
- package/components/ErrorComponent.tsx +0 -40
- package/components/Expandable.tsx +0 -61
- package/components/HelpwaveBadge.tsx +0 -35
- package/components/HideableContentSection.tsx +0 -43
- package/components/InputGroup.tsx +0 -72
- package/components/LoadingAndErrorComponent.tsx +0 -47
- package/components/LoadingAnimation.tsx +0 -40
- package/components/LoadingButton.tsx +0 -27
- package/components/MarkdownInterpreter.tsx +0 -278
- package/components/Pagination.tsx +0 -65
- package/components/Profile.tsx +0 -124
- package/components/ProgressIndicator.tsx +0 -58
- package/components/Ring.tsx +0 -286
- package/components/SearchableList.tsx +0 -69
- package/components/SortButton.tsx +0 -33
- package/components/StepperBar.tsx +0 -124
- package/components/Table.tsx +0 -330
- package/components/TechRadar.tsx +0 -247
- package/components/TextImage.tsx +0 -86
- package/components/TimeDisplay.tsx +0 -121
- package/components/Tooltip.tsx +0 -92
- package/components/VerticalDivider.tsx +0 -51
- package/components/date/DatePicker.tsx +0 -164
- package/components/date/DayPicker.tsx +0 -95
- package/components/date/TimePicker.tsx +0 -167
- package/components/date/YearMonthPicker.tsx +0 -130
- package/components/examples/InputGroupExample.tsx +0 -58
- package/components/examples/MultiSelectExample.tsx +0 -57
- package/components/examples/SearchableSelectExample.tsx +0 -34
- package/components/examples/SelectExample.tsx +0 -28
- package/components/examples/StackingModals.tsx +0 -54
- package/components/examples/TableExample.tsx +0 -159
- package/components/examples/TextareaExample.tsx +0 -23
- package/components/examples/TileExample.tsx +0 -25
- package/components/examples/date/DateTimePickerExample.tsx +0 -53
- package/components/examples/properties/CheckboxPropertyExample.tsx +0 -29
- package/components/examples/properties/DatePropertyExample.tsx +0 -44
- package/components/examples/properties/MultiSelectPropertyExample.tsx +0 -39
- package/components/examples/properties/NumberPropertyExample.tsx +0 -28
- package/components/examples/properties/SelectPropertyExample.tsx +0 -39
- package/components/examples/properties/TextPropertyExample.tsx +0 -30
- package/components/icons/Helpwave.tsx +0 -51
- package/components/icons/Tag.tsx +0 -29
- package/components/layout/Carousel.tsx +0 -396
- package/components/layout/DividerInserter.tsx +0 -37
- package/components/layout/FAQSection.tsx +0 -57
- package/components/layout/Tile.tsx +0 -67
- package/components/modals/ConfirmDialog.tsx +0 -105
- package/components/modals/DiscardChangesDialog.tsx +0 -71
- package/components/modals/InputModal.tsx +0 -26
- package/components/modals/LanguageModal.tsx +0 -76
- package/components/modals/Modal.tsx +0 -149
- package/components/modals/ModalRegister.tsx +0 -45
- package/components/properties/CheckboxProperty.tsx +0 -62
- package/components/properties/DateProperty.tsx +0 -58
- package/components/properties/MultiSelectProperty.tsx +0 -82
- package/components/properties/NumberProperty.tsx +0 -86
- package/components/properties/PropertyBase.tsx +0 -84
- package/components/properties/SelectProperty.tsx +0 -67
- package/components/properties/TextProperty.tsx +0 -81
- package/components/user-input/Checkbox.tsx +0 -139
- package/components/user-input/DateAndTimePicker.tsx +0 -156
- package/components/user-input/Input.tsx +0 -192
- package/components/user-input/Label.tsx +0 -32
- package/components/user-input/Menu.tsx +0 -75
- package/components/user-input/MultiSelect.tsx +0 -158
- package/components/user-input/ScrollPicker.tsx +0 -240
- package/components/user-input/SearchableSelect.tsx +0 -36
- package/components/user-input/Select.tsx +0 -132
- package/components/user-input/Textarea.tsx +0 -86
- package/components/user-input/ToggleableInput.tsx +0 -115
- package/hooks/useHoverState.ts +0 -88
- package/hooks/useLanguage.tsx +0 -78
- package/hooks/useLocalStorage.tsx +0 -33
- package/hooks/useOutsideClick.ts +0 -25
- package/hooks/useSaveDelay.ts +0 -46
- package/hooks/useTheme.tsx +0 -57
- package/hooks/useTranslation.ts +0 -43
- package/index.ts +0 -0
- package/util/array.ts +0 -115
- package/util/date.ts +0 -180
- package/util/easeFunctions.ts +0 -37
- package/util/emailValidation.ts +0 -3
- package/util/loopingArray.ts +0 -94
- package/util/math.ts +0 -3
- package/util/news.ts +0 -43
- package/util/noop.ts +0 -1
- package/util/storage.ts +0 -37
- package/util/types.ts +0 -4
- /package/{components/Span.tsx → dist/components/Span.d.ts} +0 -0
- /package/{components/examples/Title.tsx → dist/components/examples/Title.d.ts} +0 -0
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import type { PropsWithChildren } from 'react'
|
|
2
|
-
import { useEffect, useState } from 'react'
|
|
3
|
-
import { ChevronDown, ChevronUp } from 'lucide-react'
|
|
4
|
-
import clsx from 'clsx'
|
|
5
|
-
import { noop } from '../util/noop'
|
|
6
|
-
|
|
7
|
-
export type InputGroupProps = PropsWithChildren<{
|
|
8
|
-
title: string,
|
|
9
|
-
expanded?: boolean,
|
|
10
|
-
isExpandable?: boolean,
|
|
11
|
-
disabled?: boolean,
|
|
12
|
-
onChange?: (value: boolean) => void,
|
|
13
|
-
className?: string,
|
|
14
|
-
}>
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* A Component for layouting inputs in an expandable group
|
|
18
|
-
*/
|
|
19
|
-
export const InputGroup = ({
|
|
20
|
-
children,
|
|
21
|
-
title,
|
|
22
|
-
expanded = true,
|
|
23
|
-
isExpandable = true,
|
|
24
|
-
disabled = false,
|
|
25
|
-
onChange = noop,
|
|
26
|
-
className = '',
|
|
27
|
-
}: InputGroupProps) => {
|
|
28
|
-
const [isExpanded, setIsExpanded] = useState<boolean>(expanded)
|
|
29
|
-
|
|
30
|
-
useEffect(() => {
|
|
31
|
-
setIsExpanded(expanded)
|
|
32
|
-
}, [expanded])
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<div className={clsx('col gap-y-4 p-4 bg-white rounded-xl', className)}>
|
|
36
|
-
<div
|
|
37
|
-
className={clsx('row justify-between items-center', {
|
|
38
|
-
'cursor-pointer': isExpandable && !disabled,
|
|
39
|
-
'cursor-not-allowed': disabled,
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
'text-primary': !disabled,
|
|
43
|
-
'text-primary/40': disabled
|
|
44
|
-
})}
|
|
45
|
-
onClick={() => {
|
|
46
|
-
if (!isExpandable) {
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
const updatedIsExpanded = !isExpanded
|
|
50
|
-
onChange(updatedIsExpanded)
|
|
51
|
-
setIsExpanded(updatedIsExpanded)
|
|
52
|
-
}}
|
|
53
|
-
>
|
|
54
|
-
<span className="textstyle-title-md">{title}</span>
|
|
55
|
-
<div className={clsx('rounded-full text-white w-6 h-6', {
|
|
56
|
-
'bg-primary': (isExpandable && !disabled) || expanded,
|
|
57
|
-
'bg-primary/40': disabled,
|
|
58
|
-
})}>
|
|
59
|
-
{isExpanded
|
|
60
|
-
? <ChevronUp className="-translate-y-[1px]" size={24}/>
|
|
61
|
-
: <ChevronDown className="translate-y-[1px]" size={24}/>
|
|
62
|
-
}
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
65
|
-
{isExpanded && (
|
|
66
|
-
<div className="col gap-y-2 h-full">
|
|
67
|
-
{children}
|
|
68
|
-
</div>
|
|
69
|
-
)}
|
|
70
|
-
</div>
|
|
71
|
-
)
|
|
72
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import type { PropsWithChildren } from 'react'
|
|
2
|
-
import { useState } from 'react'
|
|
3
|
-
import type { LoadingAnimationProps } from './LoadingAnimation'
|
|
4
|
-
import type { ErrorComponentProps } from './ErrorComponent'
|
|
5
|
-
import { LoadingAnimation } from './LoadingAnimation'
|
|
6
|
-
import { ErrorComponent } from './ErrorComponent'
|
|
7
|
-
|
|
8
|
-
export type LoadingAndErrorComponentProps = PropsWithChildren<{
|
|
9
|
-
isLoading?: boolean,
|
|
10
|
-
hasError?: boolean,
|
|
11
|
-
loadingProps?: LoadingAnimationProps,
|
|
12
|
-
errorProps?: ErrorComponentProps,
|
|
13
|
-
/**
|
|
14
|
-
* in milliseconds
|
|
15
|
-
*/
|
|
16
|
-
minimumLoadingDuration?: number,
|
|
17
|
-
}>
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* A Component that shows the Error and Loading animation, when appropriate and the children otherwise
|
|
21
|
-
*/
|
|
22
|
-
export const LoadingAndErrorComponent = ({
|
|
23
|
-
children,
|
|
24
|
-
isLoading = false,
|
|
25
|
-
hasError = false,
|
|
26
|
-
errorProps,
|
|
27
|
-
loadingProps,
|
|
28
|
-
minimumLoadingDuration
|
|
29
|
-
}: LoadingAndErrorComponentProps) => {
|
|
30
|
-
const [isInMinimumLoading, setIsInMinimumLoading] = useState(false)
|
|
31
|
-
const [hasUsedMinimumLoading, setHasUsedMinimumLoading] = useState(false)
|
|
32
|
-
if (minimumLoadingDuration && !isInMinimumLoading && !hasUsedMinimumLoading) {
|
|
33
|
-
setIsInMinimumLoading(true)
|
|
34
|
-
setTimeout(() => {
|
|
35
|
-
setIsInMinimumLoading(false)
|
|
36
|
-
setHasUsedMinimumLoading(true)
|
|
37
|
-
}, minimumLoadingDuration)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (isLoading || (minimumLoadingDuration && isInMinimumLoading)) {
|
|
41
|
-
return <LoadingAnimation {...loadingProps}/>
|
|
42
|
-
}
|
|
43
|
-
if (hasError) {
|
|
44
|
-
return <ErrorComponent {...errorProps}/>
|
|
45
|
-
}
|
|
46
|
-
return children
|
|
47
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { Languages } from '../hooks/useLanguage'
|
|
2
|
-
import type { PropsForTranslation } from '../hooks/useTranslation'
|
|
3
|
-
import { useTranslation } from '../hooks/useTranslation'
|
|
4
|
-
import { Helpwave } from './icons/Helpwave'
|
|
5
|
-
import clsx from 'clsx'
|
|
6
|
-
|
|
7
|
-
type LoadingAnimationTranslation = {
|
|
8
|
-
loading: string,
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const defaultLoadingAnimationTranslation: Record<Languages, LoadingAnimationTranslation> = {
|
|
12
|
-
en: {
|
|
13
|
-
loading: 'Loading data'
|
|
14
|
-
},
|
|
15
|
-
de: {
|
|
16
|
-
loading: 'Lade Daten'
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export type LoadingAnimationProps = {
|
|
21
|
-
loadingText?: string,
|
|
22
|
-
classname?: string,
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* A Component to show when loading data
|
|
27
|
-
*/
|
|
28
|
-
export const LoadingAnimation = ({
|
|
29
|
-
overwriteTranslation,
|
|
30
|
-
loadingText,
|
|
31
|
-
classname
|
|
32
|
-
}: PropsForTranslation<LoadingAnimationTranslation, LoadingAnimationProps>) => {
|
|
33
|
-
const translation = useTranslation(defaultLoadingAnimationTranslation, overwriteTranslation)
|
|
34
|
-
return (
|
|
35
|
-
<div className={clsx('col items-center justify-center w-full h-24', classname)}>
|
|
36
|
-
<Helpwave animate="loading" />
|
|
37
|
-
{loadingText ?? `${translation.loading}...`}
|
|
38
|
-
</div>
|
|
39
|
-
)
|
|
40
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import clsx from 'clsx'
|
|
2
|
-
import { Helpwave } from './icons/Helpwave'
|
|
3
|
-
import type { SolidButtonProps } from './Button'
|
|
4
|
-
import { ButtonSizePaddings } from './Button'
|
|
5
|
-
import { SolidButton } from './Button'
|
|
6
|
-
import { noop } from '../util/noop'
|
|
7
|
-
|
|
8
|
-
type LoadingButtonProps = {
|
|
9
|
-
isLoading?: boolean,
|
|
10
|
-
} & SolidButtonProps
|
|
11
|
-
|
|
12
|
-
export const LoadingButton = ({ isLoading = false, size = 'medium', onClick, ...rest }: LoadingButtonProps) => {
|
|
13
|
-
const paddingClass = ButtonSizePaddings[size]
|
|
14
|
-
|
|
15
|
-
return (
|
|
16
|
-
<div className="inline-block relative">
|
|
17
|
-
{
|
|
18
|
-
isLoading && (
|
|
19
|
-
<div className={clsx('absolute inset-0 row items-center justify-center bg-white/40', paddingClass)}>
|
|
20
|
-
<Helpwave animate="loading" className="text-white"/>
|
|
21
|
-
</div>
|
|
22
|
-
)
|
|
23
|
-
}
|
|
24
|
-
<SolidButton {...rest} disabled={rest.disabled} onClick={isLoading ? noop: onClick}/>
|
|
25
|
-
</div>
|
|
26
|
-
)
|
|
27
|
-
}
|
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
type ASTNodeModifierType =
|
|
2
|
-
'none'
|
|
3
|
-
| 'italic'
|
|
4
|
-
| 'bold'
|
|
5
|
-
| 'underline'
|
|
6
|
-
| 'font-space'
|
|
7
|
-
| 'primary'
|
|
8
|
-
| 'secondary'
|
|
9
|
-
| 'warn'
|
|
10
|
-
| 'positive'
|
|
11
|
-
| 'negative'
|
|
12
|
-
|
|
13
|
-
const astNodeInserterType = ['helpwave', 'newline'] as const
|
|
14
|
-
type ASTNodeInserterType = typeof astNodeInserterType[number]
|
|
15
|
-
type ASTNodeDefaultType = 'text'
|
|
16
|
-
|
|
17
|
-
type ASTNode = {
|
|
18
|
-
type: ASTNodeModifierType,
|
|
19
|
-
children: ASTNode[],
|
|
20
|
-
} | {
|
|
21
|
-
type: ASTNodeInserterType,
|
|
22
|
-
} | {
|
|
23
|
-
type: ASTNodeDefaultType,
|
|
24
|
-
text: string,
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export type ASTNodeInterpreterProps = {
|
|
28
|
-
node: ASTNode,
|
|
29
|
-
isRoot?: boolean,
|
|
30
|
-
className?: string,
|
|
31
|
-
}
|
|
32
|
-
export const ASTNodeInterpreter = ({
|
|
33
|
-
node,
|
|
34
|
-
isRoot = false,
|
|
35
|
-
className = '',
|
|
36
|
-
}: ASTNodeInterpreterProps) => {
|
|
37
|
-
switch (node.type) {
|
|
38
|
-
case 'newline':
|
|
39
|
-
return <br/>
|
|
40
|
-
case 'text':
|
|
41
|
-
return isRoot ? <span className={className}>{node.text}</span> : node.text
|
|
42
|
-
case 'helpwave':
|
|
43
|
-
return (<span className="font-bold font-space no-underline">helpwave</span>)
|
|
44
|
-
case 'none':
|
|
45
|
-
return isRoot ? (
|
|
46
|
-
<span className={className}>{node.children.map((value, index) => (
|
|
47
|
-
<ASTNodeInterpreter key={index}
|
|
48
|
-
node={value}/>
|
|
49
|
-
))}</span>
|
|
50
|
-
) :
|
|
51
|
-
<>{node.children.map((value, index) => <ASTNodeInterpreter key={index} node={value}/>)}</>
|
|
52
|
-
case 'bold':
|
|
53
|
-
return <b>{node.children.map((value, index) => <ASTNodeInterpreter key={index} node={value}/>)}</b>
|
|
54
|
-
case 'italic':
|
|
55
|
-
return <i>{node.children.map((value, index) => <ASTNodeInterpreter key={index} node={value}/>)}</i>
|
|
56
|
-
case 'underline':
|
|
57
|
-
return (<u>{node.children.map((value, index) => (<ASTNodeInterpreter key={index} node={value}/>))}</u>)
|
|
58
|
-
case 'font-space':
|
|
59
|
-
return (
|
|
60
|
-
<span className="font-space">{node.children.map((value, index) => (
|
|
61
|
-
<ASTNodeInterpreter key={index}
|
|
62
|
-
node={value}/>
|
|
63
|
-
))}</span>
|
|
64
|
-
)
|
|
65
|
-
case 'primary':
|
|
66
|
-
return (
|
|
67
|
-
<span className="text-primary">{node.children.map((value, index) => (
|
|
68
|
-
<ASTNodeInterpreter
|
|
69
|
-
key={index} node={value}/>
|
|
70
|
-
))}</span>
|
|
71
|
-
)
|
|
72
|
-
case 'secondary':
|
|
73
|
-
return (
|
|
74
|
-
<span className="text-secondary">{node.children.map((value, index) => (
|
|
75
|
-
<ASTNodeInterpreter
|
|
76
|
-
key={index} node={value}/>
|
|
77
|
-
))}</span>
|
|
78
|
-
)
|
|
79
|
-
case 'warn':
|
|
80
|
-
return (
|
|
81
|
-
<span className="text-warning">{node.children.map((value, index) => (
|
|
82
|
-
<ASTNodeInterpreter
|
|
83
|
-
key={index} node={value}/>
|
|
84
|
-
))}</span>
|
|
85
|
-
)
|
|
86
|
-
case 'positive':
|
|
87
|
-
return (
|
|
88
|
-
<span className="text-positive">{node.children.map((value, index) => (
|
|
89
|
-
<ASTNodeInterpreter
|
|
90
|
-
key={index} node={value}/>
|
|
91
|
-
))}</span>
|
|
92
|
-
)
|
|
93
|
-
case 'negative':
|
|
94
|
-
return (
|
|
95
|
-
<span className="text-negative">{node.children.map((value, index) => (
|
|
96
|
-
<ASTNodeInterpreter
|
|
97
|
-
key={index} node={value}/>
|
|
98
|
-
))}</span>
|
|
99
|
-
)
|
|
100
|
-
default:
|
|
101
|
-
return null
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const modifierIdentifierMapping = [
|
|
106
|
-
{ id: 'i', name: 'italic' },
|
|
107
|
-
{ id: 'b', name: 'bold' },
|
|
108
|
-
{ id: 'u', name: 'underline' },
|
|
109
|
-
{ id: 'space', name: 'font-space' },
|
|
110
|
-
{ id: 'primary', name: 'primary' },
|
|
111
|
-
{ id: 'secondary', name: 'secondary' },
|
|
112
|
-
{ id: 'warn', name: 'warn' },
|
|
113
|
-
{ id: 'positive', name: 'positive' },
|
|
114
|
-
{ id: 'negative', name: 'negative' },
|
|
115
|
-
] as const
|
|
116
|
-
|
|
117
|
-
const inserterIdentifierMapping = [
|
|
118
|
-
{ id: 'helpwave', name: 'helpwave' },
|
|
119
|
-
{ id: 'newline', name: 'newline' }
|
|
120
|
-
] as const
|
|
121
|
-
const parseMarkdown = (
|
|
122
|
-
text: string,
|
|
123
|
-
commandStart: string = '\\',
|
|
124
|
-
open: string = '{',
|
|
125
|
-
close: string = '}'
|
|
126
|
-
): ASTNode => {
|
|
127
|
-
let start = text.indexOf(commandStart)
|
|
128
|
-
const children: ASTNode[] = []
|
|
129
|
-
|
|
130
|
-
// parse the text step by step
|
|
131
|
-
while (text !== '') {
|
|
132
|
-
if (start === -1) {
|
|
133
|
-
children.push({
|
|
134
|
-
type: 'text',
|
|
135
|
-
text
|
|
136
|
-
})
|
|
137
|
-
break
|
|
138
|
-
}
|
|
139
|
-
children.push(parseMarkdown(text.substring(0, start)))
|
|
140
|
-
text = text.substring(start)
|
|
141
|
-
if (text.length <= 1) {
|
|
142
|
-
children.push({
|
|
143
|
-
type: 'text',
|
|
144
|
-
text
|
|
145
|
-
})
|
|
146
|
-
text = ''
|
|
147
|
-
continue
|
|
148
|
-
}
|
|
149
|
-
const simpleReplace = [commandStart, open, close]
|
|
150
|
-
if (simpleReplace.some(value => text[1] === value)) {
|
|
151
|
-
children.push({
|
|
152
|
-
type: 'text',
|
|
153
|
-
text: simpleReplace.find(value => text[1] === value)!
|
|
154
|
-
})
|
|
155
|
-
text = text.substring(2)
|
|
156
|
-
start = text.indexOf(commandStart)
|
|
157
|
-
continue
|
|
158
|
-
}
|
|
159
|
-
const inserter = inserterIdentifierMapping.find(value => text.substring(1).startsWith(value.id))
|
|
160
|
-
if (inserter) {
|
|
161
|
-
children.push({
|
|
162
|
-
type: inserter.name,
|
|
163
|
-
})
|
|
164
|
-
text = text.substring(inserter.id.length + 1)
|
|
165
|
-
start = text.indexOf(commandStart)
|
|
166
|
-
continue
|
|
167
|
-
}
|
|
168
|
-
const modifier = modifierIdentifierMapping.find(value => text.substring(1).startsWith(value.id))
|
|
169
|
-
if (modifier) {
|
|
170
|
-
// check brackets
|
|
171
|
-
if (text[modifier.id.length + 1] !== open) {
|
|
172
|
-
children.push({
|
|
173
|
-
type: 'text',
|
|
174
|
-
text: text.substring(0, modifier.id.length + 1)
|
|
175
|
-
})
|
|
176
|
-
text = text.substring(modifier.id.length + 2)
|
|
177
|
-
start = text.indexOf(commandStart)
|
|
178
|
-
continue
|
|
179
|
-
}
|
|
180
|
-
let closing = -1
|
|
181
|
-
let index = modifier.id.length + 2
|
|
182
|
-
let counter = 1
|
|
183
|
-
let escaping = false
|
|
184
|
-
while (index < text.length) {
|
|
185
|
-
if (text[index] === open && !escaping) {
|
|
186
|
-
counter++
|
|
187
|
-
}
|
|
188
|
-
if (text[index] === close && !escaping) {
|
|
189
|
-
counter--
|
|
190
|
-
if (counter === 0) {
|
|
191
|
-
closing = index
|
|
192
|
-
break
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
escaping = text[index] === commandStart
|
|
196
|
-
index++
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (closing !== -1) {
|
|
200
|
-
children.push({
|
|
201
|
-
type: modifier.name,
|
|
202
|
-
children: [parseMarkdown(text.substring(modifier.id.length + 2, closing))]
|
|
203
|
-
})
|
|
204
|
-
text = text.substring(closing + 1)
|
|
205
|
-
start = text.indexOf(commandStart)
|
|
206
|
-
continue
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
// nothing could be applied to command start
|
|
210
|
-
children.push({
|
|
211
|
-
type: 'text',
|
|
212
|
-
text: text[0]!
|
|
213
|
-
})
|
|
214
|
-
text = text.substring(1)
|
|
215
|
-
start = text.indexOf(commandStart)
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return {
|
|
219
|
-
type: 'none',
|
|
220
|
-
children
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const optimizeTree = (node: ASTNode) => {
|
|
225
|
-
if (node.type === 'text') {
|
|
226
|
-
return !node.text ? undefined : node
|
|
227
|
-
}
|
|
228
|
-
if (astNodeInserterType.some(value => value === node.type)) {
|
|
229
|
-
return node
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const currentNode = node as
|
|
233
|
-
{ type: ASTNodeModifierType, children: ASTNode[] }
|
|
234
|
-
|
|
235
|
-
if (currentNode.children.length === 0) {
|
|
236
|
-
return undefined
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
let children: ASTNode[] = []
|
|
240
|
-
for (let i = 0; i < currentNode.children.length; i++) {
|
|
241
|
-
const child = optimizeTree(currentNode.children[i]!)
|
|
242
|
-
if (!child) {
|
|
243
|
-
continue
|
|
244
|
-
}
|
|
245
|
-
if (child.type === 'none') {
|
|
246
|
-
children.push(...child.children)
|
|
247
|
-
} else {
|
|
248
|
-
children.push(child)
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
currentNode.children = children
|
|
253
|
-
children = []
|
|
254
|
-
|
|
255
|
-
for (let i = 0; i < currentNode.children.length; i++) {
|
|
256
|
-
const child = currentNode.children[i]!
|
|
257
|
-
if (child) {
|
|
258
|
-
if (child.type === 'text' && children[children.length - 1]?.type === 'text') {
|
|
259
|
-
(children[children.length - 1]! as { type: ASTNodeDefaultType, text: string }).text += child.text
|
|
260
|
-
} else {
|
|
261
|
-
children.push(child)
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
currentNode.children = children
|
|
266
|
-
return currentNode
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
export type MarkdownInterpreterProps = {
|
|
270
|
-
text: string,
|
|
271
|
-
className?: string,
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
export const MarkdownInterpreter = ({ text, className }: MarkdownInterpreterProps) => {
|
|
275
|
-
const tree = parseMarkdown(text)
|
|
276
|
-
const optimizedTree = optimizeTree(tree)!
|
|
277
|
-
return <ASTNodeInterpreter node={optimizedTree} isRoot={true} className={className}/>
|
|
278
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { ChevronLast, ChevronLeft, ChevronFirst, ChevronRight } from 'lucide-react'
|
|
2
|
-
import clsx from 'clsx'
|
|
3
|
-
import type { PropsForTranslation } from '../hooks/useTranslation'
|
|
4
|
-
import { useTranslation } from '../hooks/useTranslation'
|
|
5
|
-
import type { Languages } from '../hooks/useLanguage'
|
|
6
|
-
|
|
7
|
-
type PaginationTranslation = {
|
|
8
|
-
of: string,
|
|
9
|
-
}
|
|
10
|
-
const defaultPaginationTranslations: Record<Languages, PaginationTranslation> = {
|
|
11
|
-
en: {
|
|
12
|
-
of: 'of'
|
|
13
|
-
},
|
|
14
|
-
de: {
|
|
15
|
-
of: 'von'
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export type PaginationProps = {
|
|
20
|
-
page: number, // starts with 0
|
|
21
|
-
numberOfPages: number,
|
|
22
|
-
onPageChanged: (page: number) => void,
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* A Component showing the pagination allowing first, before, next and last page navigation
|
|
27
|
-
*/
|
|
28
|
-
export const Pagination = ({
|
|
29
|
-
overwriteTranslation,
|
|
30
|
-
page,
|
|
31
|
-
numberOfPages,
|
|
32
|
-
onPageChanged
|
|
33
|
-
}: PropsForTranslation<PaginationTranslation, PaginationProps>) => {
|
|
34
|
-
const translation = useTranslation(defaultPaginationTranslations, overwriteTranslation)
|
|
35
|
-
|
|
36
|
-
const changePage = (page:number) => {
|
|
37
|
-
onPageChanged(page)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const noPages = numberOfPages === 0
|
|
41
|
-
const onFirstPage = page === 0 && !noPages
|
|
42
|
-
const onLastPage = page === numberOfPages - 1
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<div className={clsx('row', { 'opacity-30': noPages })}>
|
|
46
|
-
<button onClick={() => changePage(0)} disabled={onFirstPage}>
|
|
47
|
-
<ChevronFirst className={clsx({ 'opacity-30': onFirstPage })}/>
|
|
48
|
-
</button>
|
|
49
|
-
<button onClick={() => changePage(page - 1)} disabled={onFirstPage}>
|
|
50
|
-
<ChevronLeft className={clsx({ 'opacity-30': onFirstPage })}/>
|
|
51
|
-
</button>
|
|
52
|
-
<div className="min-w-[80px] justify-center mx-2">
|
|
53
|
-
<span className="select-none text-right flex-1">{noPages ? 0 : page + 1}</span>
|
|
54
|
-
<span className="select-none mx-2">{translation.of}</span>
|
|
55
|
-
<span className="select-none text-left flex-1">{numberOfPages}</span>
|
|
56
|
-
</div>
|
|
57
|
-
<button onClick={() => changePage(page + 1)} disabled={onLastPage || noPages}>
|
|
58
|
-
<ChevronRight className={clsx({ 'opacity-30': onLastPage })}/>
|
|
59
|
-
</button>
|
|
60
|
-
<button onClick={() => changePage(numberOfPages - 1)} disabled={onLastPage || noPages}>
|
|
61
|
-
<ChevronLast className={clsx({ 'opacity-30': onLastPage })}/>
|
|
62
|
-
</button>
|
|
63
|
-
</div>
|
|
64
|
-
)
|
|
65
|
-
}
|
package/components/Profile.tsx
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import type { HTMLAttributes, ReactNode } from 'react'
|
|
2
|
-
import clsx from 'clsx'
|
|
3
|
-
import Image from 'next/image'
|
|
4
|
-
import Link from 'next/link'
|
|
5
|
-
import { Github, Globe, Linkedin, Mail } from 'lucide-react'
|
|
6
|
-
import { Helpwave } from './icons/Helpwave'
|
|
7
|
-
import { Chip } from './ChipList'
|
|
8
|
-
|
|
9
|
-
type SocialType = 'mail' | 'github' | 'linkedin' | 'website' | 'medium'
|
|
10
|
-
|
|
11
|
-
export type SocialIconProps = {
|
|
12
|
-
type: SocialType,
|
|
13
|
-
url: string,
|
|
14
|
-
size?: number,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* A Component for showing a lin
|
|
19
|
-
*/
|
|
20
|
-
const SocialIcon = ({ type, url, size = 24 }: SocialIconProps) => {
|
|
21
|
-
let icon: ReactNode
|
|
22
|
-
switch (type) {
|
|
23
|
-
case 'mail':
|
|
24
|
-
icon = <Mail size={size}/>
|
|
25
|
-
break
|
|
26
|
-
case 'linkedin':
|
|
27
|
-
// TODO find an alternative icon
|
|
28
|
-
icon = <Linkedin size={size}/>
|
|
29
|
-
break
|
|
30
|
-
case 'github':
|
|
31
|
-
// TODO find an alternative icon
|
|
32
|
-
icon = <Github size={size}/>
|
|
33
|
-
break
|
|
34
|
-
case 'website':
|
|
35
|
-
icon = <Globe size={size}/>
|
|
36
|
-
break
|
|
37
|
-
case 'medium':
|
|
38
|
-
icon = <Globe size={size}/> // TODO find an appropriate medium svg
|
|
39
|
-
break
|
|
40
|
-
default:
|
|
41
|
-
icon = <Helpwave size={24}/>
|
|
42
|
-
}
|
|
43
|
-
return (
|
|
44
|
-
<Link href={url} target="_blank">
|
|
45
|
-
<Chip color="dark" className="!p-2">
|
|
46
|
-
{icon}
|
|
47
|
-
</Chip>
|
|
48
|
-
</Link>
|
|
49
|
-
)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export type ProfileProps = HTMLAttributes<HTMLDivElement> & {
|
|
53
|
-
name: string,
|
|
54
|
-
imageUrl: string,
|
|
55
|
-
badge?: ReactNode,
|
|
56
|
-
prefix?: string,
|
|
57
|
-
suffix?: string,
|
|
58
|
-
roleBadge?: string,
|
|
59
|
-
role?: string,
|
|
60
|
-
/**
|
|
61
|
-
* The list of tags for the
|
|
62
|
-
*/
|
|
63
|
-
tags?: string[],
|
|
64
|
-
info?: string,
|
|
65
|
-
socials?: SocialIconProps[],
|
|
66
|
-
imageClassName?: string,
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// TODO add colors for dark-mode
|
|
71
|
-
/**
|
|
72
|
-
* A Component for showing a Profile
|
|
73
|
-
*/
|
|
74
|
-
export const Profile = ({
|
|
75
|
-
name,
|
|
76
|
-
imageUrl,
|
|
77
|
-
badge,
|
|
78
|
-
prefix,
|
|
79
|
-
suffix,
|
|
80
|
-
roleBadge,
|
|
81
|
-
role,
|
|
82
|
-
tags,
|
|
83
|
-
info,
|
|
84
|
-
socials,
|
|
85
|
-
className,
|
|
86
|
-
imageClassName,
|
|
87
|
-
...divProps
|
|
88
|
-
}: ProfileProps) => {
|
|
89
|
-
return (
|
|
90
|
-
<div
|
|
91
|
-
{...divProps}
|
|
92
|
-
className={clsx(`col items-center text-center rounded-3xl p-3 pb-4 bg-white text-gray-900 w-min shadow-around-lg`, className)}
|
|
93
|
-
>
|
|
94
|
-
<div className="relative mb-6">
|
|
95
|
-
<div className={clsx('relative rounded-xl row items-center justify-center overflow-hidden', imageClassName)}>
|
|
96
|
-
<Image src={imageUrl} alt="" className={clsx('z-[2] object-cover', imageClassName)} width={0} height={0} style={{ width: 'auto', height: 'auto' }}/>
|
|
97
|
-
</div>
|
|
98
|
-
<div className="absolute top-[6px] left-[6px] z-[3]">{badge}</div>
|
|
99
|
-
{roleBadge && (
|
|
100
|
-
<div className="absolute bottom-0 left-1/2 -translate-x-1/2 translate-y-2/3 z-[4] rounded-md">
|
|
101
|
-
<Chip color="dark" className="font-bold px-3">{roleBadge}</Chip>
|
|
102
|
-
</div>
|
|
103
|
-
)}
|
|
104
|
-
</div>
|
|
105
|
-
{prefix && <span className="font-semibold">{prefix}</span>}
|
|
106
|
-
<h2 id={name} className="textstyle-title-md">{name}</h2>
|
|
107
|
-
{suffix && <span className="text-sm mb-1">{suffix}</span>}
|
|
108
|
-
{role && <span className="font-space font-bold text-sm">{role}</span>}
|
|
109
|
-
{tags && (
|
|
110
|
-
<div className="flex flex-wrap mx-4 mt-2 gap-x-2 justify-center">
|
|
111
|
-
{tags.map((tag, index) => <span key={index} className="textstyle-description text-sm">{`#${tag}`}</span>)}
|
|
112
|
-
</div>
|
|
113
|
-
)}
|
|
114
|
-
{info && <span className="mt-2 text-sm">{info}</span>}
|
|
115
|
-
{socials && (
|
|
116
|
-
<div className="flex flex-wrap grow items-end justify-center gap-x-4 gap-y-2 mt-4">
|
|
117
|
-
{socials.map((socialIconProps, index) => (
|
|
118
|
-
<SocialIcon key={index} {...socialIconProps} size={socialIconProps.size ?? 20}/>
|
|
119
|
-
))}
|
|
120
|
-
</div>
|
|
121
|
-
)}
|
|
122
|
-
</div>
|
|
123
|
-
)
|
|
124
|
-
}
|