@vygruppen/spor-react 11.3.10 → 12.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/.turbo/turbo-build.log +33 -11
- package/.turbo/turbo-typegen.log +22 -0
- package/CHANGELOG.md +247 -0
- package/dist/index.d.mts +2589 -8303
- package/dist/index.d.ts +2589 -8303
- package/dist/index.js +9609 -8608
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +9487 -8455
- package/dist/index.mjs.map +1 -1
- package/package.json +23 -15
- package/src/accordion/Accordion.tsx +96 -45
- package/src/accordion/Expandable.tsx +54 -127
- package/src/accordion/helpers.ts +31 -0
- package/src/accordion/types.ts +60 -0
- package/src/alert/Alert.tsx +101 -0
- package/src/alert/AlertIcon.tsx +63 -45
- package/src/alert/ExpandableAlert.tsx +96 -64
- package/src/alert/ServiceAlert.tsx +127 -125
- package/src/alert/{index.tsx → index.ts} +1 -2
- package/src/breadcrumb/Breadcrumb.tsx +39 -24
- package/src/button/Button.tsx +86 -105
- package/src/button/ButtonGroup.tsx +45 -20
- package/src/button/Clipboard.tsx +82 -0
- package/src/button/CloseButton.tsx +4 -3
- package/src/button/FloatingActionButton.tsx +35 -41
- package/src/button/IconButton.tsx +34 -30
- package/src/button/index.tsx +1 -0
- package/src/color-mode/color-mode.tsx +75 -0
- package/src/color-mode/index.ts +1 -0
- package/src/datepicker/Calendar.tsx +17 -8
- package/src/datepicker/CalendarCell.tsx +20 -13
- package/src/datepicker/CalendarGrid.tsx +18 -10
- package/src/datepicker/CalendarHeader.tsx +2 -0
- package/src/datepicker/CalendarNavigationButton.tsx +1 -0
- package/src/datepicker/CalendarTriggerButton.tsx +43 -45
- package/src/datepicker/DateField.tsx +21 -12
- package/src/datepicker/DatePicker.tsx +61 -58
- package/src/datepicker/DateRangePicker.tsx +52 -58
- package/src/datepicker/DateTimeSegment.tsx +13 -5
- package/src/datepicker/RangeCalendar.tsx +13 -7
- package/src/datepicker/StyledField.tsx +25 -17
- package/src/datepicker/TimeField.tsx +10 -8
- package/src/datepicker/TimePicker.tsx +48 -45
- package/src/datepicker/types.ts +5 -0
- package/src/dialog/Dialog.tsx +56 -0
- package/src/dialog/Drawer.tsx +187 -0
- package/src/dialog/index.ts +2 -0
- package/src/dialog/types.ts +26 -0
- package/src/image/index.tsx +2 -2
- package/src/index.tsx +5 -3
- package/src/input/AttachedInputs.tsx +17 -42
- package/src/input/CardSelect.tsx +75 -162
- package/src/input/Checkbox.tsx +30 -6
- package/src/input/CheckboxGroup.tsx +25 -16
- package/src/input/ChoiceChip.tsx +58 -77
- package/src/input/Combobox.tsx +172 -172
- package/src/input/CountryCodeSelect.tsx +42 -28
- package/src/input/Dialog.tsx +1 -0
- package/src/input/Field.tsx +71 -0
- package/src/input/Fieldset.tsx +7 -0
- package/src/input/Input.tsx +68 -73
- package/src/input/InputGroup.tsx +66 -0
- package/src/input/ListBox.tsx +83 -70
- package/src/input/NativeSelect.tsx +70 -33
- package/src/input/NumericStepper.tsx +173 -171
- package/src/input/PasswordInput.tsx +99 -52
- package/src/input/PhoneNumberInput.tsx +69 -72
- package/src/input/Popover.tsx +1 -0
- package/src/input/Radio.tsx +37 -17
- package/src/input/SearchInput.tsx +24 -86
- package/src/input/Select.tsx +237 -0
- package/src/input/Switch.tsx +60 -18
- package/src/input/Textarea.tsx +53 -101
- package/src/input/{index.tsx → index.ts} +2 -8
- package/src/layout/PressableCard.tsx +12 -21
- package/src/layout/RadioCard.tsx +68 -101
- package/src/layout/Separator.tsx +32 -0
- package/src/layout/StaticCard.tsx +13 -33
- package/src/layout/index.tsx +3 -7
- package/src/linjetag/InfoTag.tsx +16 -9
- package/src/linjetag/LineIcon.tsx +74 -28
- package/src/linjetag/TravelTag.tsx +38 -27
- package/src/link/TextLink.tsx +25 -16
- package/src/list/index.tsx +24 -2
- package/src/loader/ClientOnly.tsx +8 -7
- package/src/loader/ColorInlineLoader.tsx +4 -3
- package/src/loader/ColorSpinner.tsx +5 -4
- package/src/loader/ContentLoader.tsx +6 -4
- package/src/loader/DarkFullScreenLoader.tsx +11 -3
- package/src/loader/DarkInlineLoader.tsx +5 -3
- package/src/loader/DarkSpinner.tsx +7 -3
- package/src/loader/LightFullScreenLoader.tsx +11 -3
- package/src/loader/LightInlineLoader.tsx +11 -3
- package/src/loader/LightSpinner.tsx +5 -3
- package/src/loader/Lottie.tsx +3 -3
- package/src/loader/ProgressBar.tsx +83 -84
- package/src/loader/ProgressLoader.tsx +120 -75
- package/src/loader/Skeleton.tsx +94 -19
- package/src/loader/index.tsx +0 -2
- package/src/loader/useHydrated.tsx +1 -0
- package/src/loader/useRotatingLabel.tsx +2 -1
- package/src/logo/CargonetLogo.tsx +89 -89
- package/src/logo/VyLogo.tsx +61 -42
- package/src/logo/VyLogoPride.tsx +137 -139
- package/src/media-controller/JumpButton.tsx +48 -38
- package/src/media-controller/PlayPauseButton.tsx +31 -29
- package/src/media-controller/SkipButton.tsx +38 -37
- package/src/nudge/Nudge.tsx +195 -123
- package/src/nudge/index.tsx +0 -1
- package/src/pagination/Pagination.tsx +221 -118
- package/src/pagination/types.ts +23 -0
- package/src/popover/index.tsx +67 -0
- package/src/progress-indicator/ProgressDot.tsx +11 -10
- package/src/progress-indicator/ProgressIndicator.tsx +28 -15
- package/src/provider/SporProvider.tsx +17 -14
- package/src/stepper/Stepper.tsx +88 -85
- package/src/stepper/StepperContext.tsx +2 -1
- package/src/stepper/StepperStep.tsx +28 -21
- package/src/tab/Tabs.tsx +62 -12
- package/src/tab/index.tsx +1 -9
- package/src/table/Table.tsx +35 -30
- package/src/table/index.tsx +11 -7
- package/src/theme/brand.ts +7 -0
- package/src/theme/index.ts +45 -37
- package/src/theme/recipes/attached-inputs.ts +43 -0
- package/src/theme/recipes/badge.ts +104 -0
- package/src/theme/recipes/button.ts +124 -0
- package/src/theme/recipes/choice-chip.ts +144 -0
- package/src/theme/recipes/close-button.ts +41 -0
- package/src/theme/recipes/code.ts +14 -0
- package/src/theme/recipes/group.ts +19 -0
- package/src/theme/recipes/index.ts +29 -0
- package/src/theme/recipes/input.ts +89 -0
- package/src/theme/recipes/link.ts +64 -0
- package/src/theme/recipes/nudge.ts +12 -0
- package/src/theme/recipes/pressable-card.ts +83 -0
- package/src/theme/recipes/progress-loader.ts +14 -0
- package/src/theme/recipes/separator.ts +85 -0
- package/src/theme/recipes/skeleton.ts +57 -0
- package/src/theme/recipes/static-card.ts +39 -0
- package/src/theme/recipes/textarea.ts +27 -0
- package/src/theme/semantic-tokens/colors.ts +22 -0
- package/src/theme/semantic-tokens/index.ts +24 -0
- package/src/theme/semantic-tokens/radii.ts +14 -0
- package/src/theme/semantic-tokens/shadows.ts +17 -0
- package/src/theme/slot-recipes/accordion.ts +131 -0
- package/src/theme/slot-recipes/alert-expandable.ts +133 -0
- package/src/theme/slot-recipes/alert-service.ts +66 -0
- package/src/theme/slot-recipes/alert.ts +72 -0
- package/src/theme/slot-recipes/anatomy.ts +269 -0
- package/src/theme/slot-recipes/breadcrumb.ts +61 -0
- package/src/theme/slot-recipes/checkbox.ts +89 -0
- package/src/theme/slot-recipes/datepicker.ts +214 -0
- package/src/theme/slot-recipes/dialog.ts +221 -0
- package/src/theme/slot-recipes/drawer.ts +205 -0
- package/src/theme/slot-recipes/field.ts +79 -0
- package/src/theme/slot-recipes/floating-action-button.ts +131 -0
- package/src/theme/slot-recipes/index.ts +65 -0
- package/src/theme/slot-recipes/info-tag.ts +62 -0
- package/src/theme/slot-recipes/line-icon.ts +140 -0
- package/src/theme/slot-recipes/list.ts +45 -0
- package/src/theme/slot-recipes/listbox.ts +72 -0
- package/src/theme/slot-recipes/media-controller-button.ts +131 -0
- package/src/theme/slot-recipes/native-select.ts +54 -0
- package/src/theme/slot-recipes/numeric-stepper.ts +65 -0
- package/src/theme/slot-recipes/pagination.ts +41 -0
- package/src/theme/slot-recipes/popover.ts +78 -0
- package/src/theme/slot-recipes/progress-bar.ts +39 -0
- package/src/theme/slot-recipes/progress-indicator.ts +22 -0
- package/src/theme/slot-recipes/radio-card.ts +112 -0
- package/src/theme/slot-recipes/radio.ts +80 -0
- package/src/theme/slot-recipes/select.ts +243 -0
- package/src/theme/slot-recipes/stepper.ts +92 -0
- package/src/theme/slot-recipes/switch.ts +147 -0
- package/src/theme/slot-recipes/table.ts +200 -0
- package/src/theme/slot-recipes/tabs.ts +169 -0
- package/src/theme/slot-recipes/toast.ts +56 -0
- package/src/theme/slot-recipes/travel-tag.ts +192 -0
- package/src/theme/tokens/animation-styles.ts +50 -0
- package/src/theme/tokens/animations.ts +22 -0
- package/src/theme/tokens/aspect-ratios.ts +22 -0
- package/src/theme/tokens/blurs.ts +28 -0
- package/src/theme/tokens/borders.ts +26 -0
- package/src/theme/{foundations → tokens}/breakpoints.ts +0 -1
- package/src/theme/tokens/colors.ts +10 -0
- package/src/theme/tokens/config.ts +10 -0
- package/src/theme/tokens/cursor.ts +28 -0
- package/src/theme/tokens/durations.ts +25 -0
- package/src/theme/tokens/easings.ts +16 -0
- package/src/theme/tokens/font-sizes.ts +30 -0
- package/src/theme/tokens/font-weights.ts +31 -0
- package/src/theme/tokens/fonts.ts +8 -0
- package/src/theme/tokens/global-css.ts +18 -0
- package/src/theme/tokens/index.ts +37 -0
- package/src/theme/tokens/keyframes.ts +255 -0
- package/src/theme/tokens/letter-spacings.ts +19 -0
- package/src/theme/tokens/line-heights.ts +19 -0
- package/src/theme/tokens/radii.ts +13 -0
- package/src/theme/tokens/sizes.ts +51 -0
- package/src/theme/tokens/spacing.ts +20 -0
- package/src/theme/tokens/text-styles.ts +89 -0
- package/src/theme/tokens/z-index.ts +17 -0
- package/src/theme/utils/accent-utils.ts +8 -21
- package/src/theme/utils/bg-utils.ts +4 -6
- package/src/theme/utils/brand-utils.ts +6 -19
- package/src/theme/utils/core-utils.ts +91 -0
- package/src/theme/utils/floating-utils.ts +20 -39
- package/src/theme/utils/ghost-utils.ts +7 -21
- package/src/theme/utils/input-utils.ts +32 -37
- package/src/theme/utils/outline-utils.ts +4 -11
- package/src/theme/utils/surface-utils.ts +5 -19
- package/src/theme/utils/types.ts +1 -0
- package/src/toast/index.tsx +1 -1
- package/src/toast/toast.tsx +105 -0
- package/src/transition/index.ts +2 -8
- package/src/typography/Badge.tsx +15 -61
- package/src/typography/Code.tsx +16 -28
- package/src/typography/Heading.tsx +36 -21
- package/src/typography/Text.tsx +9 -6
- package/src/typography/{index.tsx → index.ts} +1 -0
- package/src/util/externals.tsx +13 -27
- package/tsconfig.json +5 -1
- package/src/accordion/Accordion.test.tsx +0 -20
- package/src/alert/BaseAlert.test.tsx +0 -37
- package/src/alert/BaseAlert.tsx +0 -34
- package/src/alert/ClosableAlert.test.tsx +0 -37
- package/src/alert/ClosableAlert.tsx +0 -85
- package/src/alert/ExpandableAlert.test.tsx +0 -84
- package/src/alert/StaticAlert.tsx +0 -33
- package/src/button/Button.test.tsx +0 -23
- package/src/datepicker/TimePicker.test.tsx +0 -74
- package/src/input/FormControl.tsx +0 -2
- package/src/input/FormErrorMessage.tsx +0 -95
- package/src/input/FormLabel.tsx +0 -11
- package/src/input/InfoSelect.tsx +0 -274
- package/src/input/InputElement.tsx +0 -44
- package/src/input/RadioGroup.tsx +0 -47
- package/src/layout/Divider.tsx +0 -27
- package/src/layout/RadioCardGroup.tsx +0 -79
- package/src/layout/Stack.tsx +0 -42
- package/src/loader/SkeletonCircle.tsx +0 -13
- package/src/loader/SkeletonText.tsx +0 -14
- package/src/media-controller/index.test.tsx +0 -59
- package/src/modal/Drawer.tsx +0 -120
- package/src/modal/FullScreenDrawer.tsx +0 -239
- package/src/modal/Modal.tsx +0 -15
- package/src/modal/ModalHeader.tsx +0 -31
- package/src/modal/SimpleDrawer.tsx +0 -51
- package/src/modal/index.tsx +0 -5
- package/src/nudge/WizardNudge.tsx +0 -107
- package/src/theme/components/accordion.ts +0 -102
- package/src/theme/components/alert-expandable.ts +0 -125
- package/src/theme/components/alert-service.ts +0 -98
- package/src/theme/components/alert.ts +0 -71
- package/src/theme/components/badge.ts +0 -109
- package/src/theme/components/breadcrumb.ts +0 -60
- package/src/theme/components/button.ts +0 -125
- package/src/theme/components/card-select.ts +0 -117
- package/src/theme/components/checkbox.ts +0 -88
- package/src/theme/components/choice-chip.ts +0 -161
- package/src/theme/components/close-button.ts +0 -48
- package/src/theme/components/code.ts +0 -17
- package/src/theme/components/datepicker.ts +0 -198
- package/src/theme/components/divider.ts +0 -50
- package/src/theme/components/drawer.ts +0 -95
- package/src/theme/components/fab.ts +0 -109
- package/src/theme/components/form-label.ts +0 -17
- package/src/theme/components/form.ts +0 -27
- package/src/theme/components/index.ts +0 -45
- package/src/theme/components/info-select.ts +0 -85
- package/src/theme/components/info-tag.ts +0 -63
- package/src/theme/components/input.ts +0 -28
- package/src/theme/components/line-icon.ts +0 -129
- package/src/theme/components/link.ts +0 -78
- package/src/theme/components/list.ts +0 -23
- package/src/theme/components/listbox.ts +0 -77
- package/src/theme/components/media-controller-button.ts +0 -97
- package/src/theme/components/modal.ts +0 -96
- package/src/theme/components/numeric-stepper.ts +0 -65
- package/src/theme/components/pagination.ts +0 -74
- package/src/theme/components/popover.ts +0 -68
- package/src/theme/components/pressable-card.ts +0 -72
- package/src/theme/components/progress-bar.ts +0 -47
- package/src/theme/components/progress-indicator.ts +0 -44
- package/src/theme/components/radio-card.ts +0 -134
- package/src/theme/components/radio.ts +0 -68
- package/src/theme/components/select.ts +0 -74
- package/src/theme/components/skeleton.ts +0 -40
- package/src/theme/components/static-card.ts +0 -82
- package/src/theme/components/stepper.ts +0 -100
- package/src/theme/components/switch.ts +0 -112
- package/src/theme/components/table.ts +0 -161
- package/src/theme/components/tabs.ts +0 -135
- package/src/theme/components/textarea.ts +0 -33
- package/src/theme/components/toast.ts +0 -28
- package/src/theme/components/travel-tag.ts +0 -256
- package/src/theme/foundations/borders.ts +0 -11
- package/src/theme/foundations/colors.ts +0 -12
- package/src/theme/foundations/config.ts +0 -5
- package/src/theme/foundations/fontSizes.ts +0 -29
- package/src/theme/foundations/fontWeights.ts +0 -5
- package/src/theme/foundations/fonts.ts +0 -7
- package/src/theme/foundations/index.ts +0 -15
- package/src/theme/foundations/lineHeights.ts +0 -6
- package/src/theme/foundations/radii.ts +0 -12
- package/src/theme/foundations/shadows.ts +0 -8
- package/src/theme/foundations/sizes.ts +0 -36
- package/src/theme/foundations/spacing.ts +0 -31
- package/src/theme/foundations/styles.ts +0 -12
- package/src/theme/foundations/textStyles.ts +0 -74
- package/src/theme/foundations/zIndices.ts +0 -17
- package/src/theme/utils/base-utils.ts +0 -104
- package/src/theme/utils/focus-utils.ts +0 -10
- package/src/toast/ActionToast.test.tsx +0 -22
- package/src/toast/ActionToast.tsx +0 -28
- package/src/toast/BaseToast.test.tsx +0 -27
- package/src/toast/BaseToast.tsx +0 -75
- package/src/toast/ClosableToast.test.tsx +0 -17
- package/src/toast/ClosableToast.tsx +0 -40
- package/src/toast/useToast.tsx +0 -121
- package/src/tooltip/Tooltip.tsx +0 -70
- package/src/tooltip/index.tsx +0 -1
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vygruppen/spor-react",
|
3
|
-
"version": "
|
3
|
+
"version": "12.0.1",
|
4
4
|
"main": "./dist/index.js",
|
5
5
|
"module": "./dist/index.mjs",
|
6
6
|
"types": "./dist/index.d.ts",
|
@@ -13,29 +13,34 @@
|
|
13
13
|
"directory": "packages/spor-react"
|
14
14
|
},
|
15
15
|
"dependencies": {
|
16
|
+
"@chakra-ui/react": "^3.9.0",
|
17
|
+
"@ark-ui/react": "^4.9.2",
|
16
18
|
"@chakra-ui/anatomy": "^2.3.4",
|
17
|
-
"@chakra-ui/react": "^2.8.2",
|
18
19
|
"@chakra-ui/react-use-size": "^2.1.0",
|
19
20
|
"@chakra-ui/styled-system": "^2.12.0",
|
20
21
|
"@chakra-ui/system": "^2.6.2",
|
21
22
|
"@chakra-ui/theme": "^3.4.6",
|
22
23
|
"@chakra-ui/theme-tools": "^2.0.12",
|
23
24
|
"@chakra-ui/utils": "^2.2.2",
|
24
|
-
"@emotion/react": "^11.
|
25
|
+
"@emotion/react": "^11.14.0",
|
25
26
|
"@emotion/styled": "^11.11.5",
|
26
|
-
"@internationalized/date": "^3.
|
27
|
+
"@internationalized/date": "^3.6.0",
|
27
28
|
"awesome-phonenumber": "^5.11.0",
|
28
29
|
"deepmerge": "^4.3.1",
|
29
|
-
"framer-motion": "^
|
30
|
-
"lottie-react": "^2.4.
|
30
|
+
"framer-motion": "^11.11.17",
|
31
|
+
"lottie-react": "^2.4.1",
|
32
|
+
"next-themes": "^0.4.4",
|
31
33
|
"react-aria": "^3.33.1",
|
34
|
+
"react-icons": "^5.4.0",
|
32
35
|
"react-stately": "^3.31.1",
|
33
36
|
"react-swipeable": "^7.0.1",
|
34
|
-
"
|
35
|
-
"@vygruppen/spor-
|
36
|
-
"@vygruppen/spor-loader": "0.
|
37
|
+
"usehooks-ts": "^3.1.0",
|
38
|
+
"@vygruppen/spor-design-tokens": "4.0.0",
|
39
|
+
"@vygruppen/spor-loader": "0.6.0",
|
40
|
+
"@vygruppen/spor-icon-react": "4.0.1"
|
37
41
|
},
|
38
42
|
"devDependencies": {
|
43
|
+
"@chakra-ui/cli": "^3.8.0",
|
39
44
|
"@react-types/datepicker": "^3.10.0",
|
40
45
|
"@react-types/shared": "^3.27.0",
|
41
46
|
"@testing-library/jest-dom": "^6.4.5",
|
@@ -46,18 +51,21 @@
|
|
46
51
|
"react": "^18.3.1",
|
47
52
|
"react-dom": "^18.3.1",
|
48
53
|
"tsup": "^7.2.0",
|
54
|
+
"typescript": "^5.7.3",
|
49
55
|
"vitest": "^0.26.3",
|
50
56
|
"vitest-axe": "^0.1.0",
|
51
57
|
"vitest-canvas-mock": "^0.2.2",
|
52
|
-
"
|
53
|
-
"@vygruppen/tsconfig": "0.0.0"
|
58
|
+
"@vygruppen/tsconfig": "0.1.0"
|
54
59
|
},
|
55
60
|
"peerDependencies": {
|
56
|
-
"react": "
|
57
|
-
"react-dom": "
|
61
|
+
"react": ">=18.0.0 <19.0.0",
|
62
|
+
"react-dom": ">=18.0.0 <19.0.0"
|
58
63
|
},
|
59
64
|
"scripts": {
|
60
|
-
"build": "tsup",
|
61
|
-
"dev": "tsup --watch"
|
65
|
+
"build": "pnpm typegen && tsup",
|
66
|
+
"dev": "tsup --watch",
|
67
|
+
"typegen": "npx @chakra-ui/cli typegen src/theme/index.ts",
|
68
|
+
"typegen:watch": "npx @chakra-ui/cli typegen src/theme/index.ts --watch",
|
69
|
+
"typegen:strict": "npx @chakra-ui/cli typegen /src/theme/index.ts --strict"
|
62
70
|
}
|
63
71
|
}
|
@@ -1,64 +1,115 @@
|
|
1
|
+
"use client";
|
2
|
+
|
1
3
|
import {
|
4
|
+
Box,
|
2
5
|
Accordion as ChakraAccordion,
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
import React from "react";
|
7
|
-
import { Stack, StackProps } from "../layout";
|
8
|
-
export {
|
9
|
-
AccordionButton,
|
10
|
-
AccordionIcon,
|
11
|
-
AccordionItem,
|
12
|
-
AccordionPanel,
|
13
|
-
} from "@chakra-ui/react";
|
14
|
-
export type {
|
15
|
-
AccordionButtonProps,
|
16
|
-
AccordionItemProps,
|
17
|
-
AccordionPanelProps,
|
6
|
+
HStack,
|
7
|
+
Stack,
|
8
|
+
useSlotRecipe,
|
18
9
|
} from "@chakra-ui/react";
|
10
|
+
import { DropdownDownFill24Icon } from "@vygruppen/spor-icon-react";
|
11
|
+
import React, { forwardRef } from "react";
|
12
|
+
import {
|
13
|
+
AccordionProps,
|
14
|
+
AccordionItemTriggerProps,
|
15
|
+
AccordionItemContentProps,
|
16
|
+
} from "./types";
|
17
|
+
import { warnAboutMismatchingIcon } from "./helpers";
|
19
18
|
|
20
|
-
export type AccordionProps = Omit<ChakraAccordionProps, "variant" | "size"> & {
|
21
|
-
/**
|
22
|
-
* The display variant of the accordion items.
|
23
|
-
*
|
24
|
-
* - `ghost` renders a pretty unstyled expandable list without any borders
|
25
|
-
* - `base` renders an outlined version
|
26
|
-
* - `floating` renders a version with a drop shadow
|
27
|
-
*/
|
28
|
-
variant?: "ghost" | "base" | "floating";
|
29
|
-
/** The margin between accordion items */
|
30
|
-
spacing?: StackProps["spacing"];
|
31
|
-
};
|
32
19
|
/*
|
33
|
-
* Wraps a set of
|
20
|
+
* Wraps a set of AccordionItem or AccordionItem components.
|
34
21
|
*
|
35
22
|
* ```tsx
|
36
23
|
* <Accordion variant="ghost">
|
37
|
-
* <
|
38
|
-
*
|
39
|
-
*
|
40
|
-
*
|
41
|
-
*
|
42
|
-
*
|
24
|
+
* <AccordionItem>
|
25
|
+
* <AccordionItemTrigger>Is Spor easy?</AccordionItemTrigger>
|
26
|
+
* <AccordionItemContent>Yes</AccordionItemContent>
|
27
|
+
* </AccordionItem>
|
28
|
+
* <AccordionItem>
|
29
|
+
* <AccordionItemTrigger>Is Spor lovable?</AccordionItemTrigger>
|
30
|
+
* <AccordionItemContent>Yes</AccordionItemContent>
|
31
|
+
* </AccordionItem>
|
32
|
+
* </Accordion>
|
33
|
+
* ```
|
34
|
+
*
|
35
|
+
* If you need to have a default open item, you can use the `defaultValue` prop.
|
36
|
+
*
|
37
|
+
* ```tsx
|
38
|
+
* <Accordion defaultValue={["a"]}>
|
39
|
+
* <AccordionItem value="a">
|
40
|
+
* <AccordionItemTrigger>Is Spor easy?</AccordionItemTrigger>
|
41
|
+
* <AccordionItemContent>Yes</AccordionItemContent>
|
42
|
+
* </AccordionItem>
|
43
|
+
* <AccordionItem value="b">
|
44
|
+
* <AccordionItemTrigger>Is Spor lovable?</AccordionItemTrigger>
|
45
|
+
* <AccordionItemContent>Yes</AccordionItemContent>
|
46
|
+
* </AccordionItem>
|
43
47
|
* </Accordion>
|
44
48
|
* ```
|
45
49
|
*
|
46
50
|
* If you only have one expandable item, you can use the `<Expandable />` component instead.
|
51
|
+
*
|
52
|
+
* @see https://spor.vy.no/components/accordion
|
47
53
|
*/
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
+
|
55
|
+
export const Accordion = forwardRef<HTMLDivElement, AccordionProps>(
|
56
|
+
(props, ref) => {
|
57
|
+
const { variant = "core", children, gap = 2, ...rest } = props;
|
58
|
+
const recipe = useSlotRecipe({ key: "accordion" });
|
59
|
+
const styles = recipe({ variant });
|
54
60
|
return (
|
55
|
-
<ChakraAccordion
|
56
|
-
{...
|
61
|
+
<ChakraAccordion.Root
|
62
|
+
{...rest}
|
57
63
|
ref={ref}
|
58
|
-
|
64
|
+
css={styles.root}
|
65
|
+
variant={variant}
|
59
66
|
>
|
60
|
-
<Stack
|
61
|
-
</ChakraAccordion>
|
67
|
+
<Stack gap={gap}>{children}</Stack>
|
68
|
+
</ChakraAccordion.Root>
|
62
69
|
);
|
63
70
|
},
|
64
71
|
);
|
72
|
+
|
73
|
+
export const AccordionItemTrigger = forwardRef<
|
74
|
+
HTMLButtonElement,
|
75
|
+
AccordionItemTriggerProps
|
76
|
+
>(function AccordionItemTrigger(props, ref) {
|
77
|
+
const { startElement, children, headingLevel, ...rest } = props;
|
78
|
+
warnAboutMismatchingIcon({ icon: startElement });
|
79
|
+
const recipe = useSlotRecipe({ key: "accordion" });
|
80
|
+
const styles = recipe();
|
81
|
+
return (
|
82
|
+
<Box as={headingLevel}>
|
83
|
+
<ChakraAccordion.ItemTrigger {...rest} ref={ref} css={styles.itemTrigger}>
|
84
|
+
<HStack flex="1" gap={1} textAlign="start" width="full">
|
85
|
+
{startElement && startElement}
|
86
|
+
{children}
|
87
|
+
</HStack>
|
88
|
+
|
89
|
+
<ChakraAccordion.ItemIndicator>
|
90
|
+
<DropdownDownFill24Icon />
|
91
|
+
</ChakraAccordion.ItemIndicator>
|
92
|
+
</ChakraAccordion.ItemTrigger>
|
93
|
+
</Box>
|
94
|
+
);
|
95
|
+
});
|
96
|
+
|
97
|
+
export const AccordionItemContent = forwardRef<
|
98
|
+
HTMLDivElement,
|
99
|
+
AccordionItemContentProps
|
100
|
+
>(function AccordionItemContent(props, ref) {
|
101
|
+
const { children } = props;
|
102
|
+
|
103
|
+
const recipe = useSlotRecipe({ key: "accordion" });
|
104
|
+
const styles = recipe();
|
105
|
+
|
106
|
+
return (
|
107
|
+
<ChakraAccordion.ItemContent css={styles.itemContent}>
|
108
|
+
<ChakraAccordion.ItemBody {...props} ref={ref}>
|
109
|
+
{children}
|
110
|
+
</ChakraAccordion.ItemBody>
|
111
|
+
</ChakraAccordion.ItemContent>
|
112
|
+
);
|
113
|
+
});
|
114
|
+
|
115
|
+
export const AccordionItem = ChakraAccordion.Item;
|
@@ -1,40 +1,15 @@
|
|
1
|
+
"use client";
|
2
|
+
|
3
|
+
import React, { forwardRef } from "react";
|
1
4
|
import {
|
2
|
-
|
3
|
-
AccordionIcon,
|
5
|
+
Accordion,
|
4
6
|
AccordionItem,
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
} from "
|
10
|
-
import React from "react";
|
11
|
-
import { Accordion, AccordionProps } from "./Accordion";
|
12
|
-
|
13
|
-
type HeadingLevel = "h2" | "h3" | "h4" | "h5" | "h6";
|
14
|
-
type ExpandableProps = Omit<
|
15
|
-
AccordionProps,
|
16
|
-
"title" | "index" | "defaultIndex" | "onChange"
|
17
|
-
> & {
|
18
|
-
/** The hidden content */
|
19
|
-
children: React.ReactNode;
|
20
|
-
/** The title that's shown inside the toggle button */
|
21
|
-
title: React.ReactNode;
|
22
|
-
/** The semantic heading level of the toggle button */
|
23
|
-
headingLevel?: HeadingLevel;
|
24
|
-
/**
|
25
|
-
* Icon shown to the left of the title
|
26
|
-
*
|
27
|
-
* Make sure it's the 24px outlined version of the icon
|
28
|
-
*/
|
29
|
-
leftIcon?: React.ReactNode;
|
7
|
+
AccordionItemContent,
|
8
|
+
AccordionItemTrigger,
|
9
|
+
} from "./Accordion";
|
10
|
+
import { ExpandableItemProps, ExpandableProps } from "./types";
|
11
|
+
import { warnAboutMismatchingIcon } from "./helpers";
|
30
12
|
|
31
|
-
/** Controlled value of whether the accordion is open or not */
|
32
|
-
isOpen?: boolean;
|
33
|
-
/** Default value of when the accordion is open or not */
|
34
|
-
defaultOpen?: boolean;
|
35
|
-
/** Callback for when the expandable opens or closes */
|
36
|
-
onChange?: (isOpen: boolean) => void;
|
37
|
-
};
|
38
13
|
/**
|
39
14
|
* A standalone expandable component.
|
40
15
|
*
|
@@ -42,118 +17,70 @@ type ExpandableProps = Omit<
|
|
42
17
|
* If you want several expandables in a row, use the `Accordion` and `ExpandableItem` components instead.
|
43
18
|
*
|
44
19
|
* ```tsx
|
45
|
-
* <Expandable title="Click for more" variant="
|
20
|
+
* <Expandable title="Click for more" variant="core">
|
46
21
|
* <Text>MORE! 🎉</Text>
|
47
22
|
* </Expandable>
|
48
23
|
* ```
|
49
24
|
*/
|
50
|
-
export const Expandable = ({
|
51
|
-
children,
|
52
|
-
headingLevel,
|
53
|
-
title,
|
54
|
-
leftIcon,
|
55
|
-
defaultOpen,
|
56
|
-
isOpen,
|
57
|
-
onChange = () => {},
|
58
|
-
...rest
|
59
|
-
}: ExpandableProps) => {
|
60
|
-
return (
|
61
|
-
<Accordion
|
62
|
-
{...rest}
|
63
|
-
index={isOpen ? 0 : undefined}
|
64
|
-
defaultIndex={defaultOpen ? 0 : undefined}
|
65
|
-
onChange={(expandedIndex) => onChange(expandedIndex === 0)}
|
66
|
-
>
|
67
|
-
<ExpandableItem
|
68
|
-
headingLevel={headingLevel}
|
69
|
-
title={title}
|
70
|
-
leftIcon={leftIcon}
|
71
|
-
>
|
72
|
-
{children}
|
73
|
-
</ExpandableItem>
|
74
|
-
</Accordion>
|
75
|
-
);
|
76
|
-
};
|
77
25
|
|
78
|
-
export
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
26
|
+
export const Expandable = forwardRef<HTMLDivElement, ExpandableProps>(
|
27
|
+
(props, ref) => {
|
28
|
+
const { title, children, headingLevel, startElement, ...rest } = props;
|
29
|
+
return (
|
30
|
+
<Accordion {...props} ref={ref} {...rest}>
|
31
|
+
<ExpandableItem
|
32
|
+
title={title}
|
33
|
+
headingLevel={headingLevel}
|
34
|
+
startElement={startElement}
|
35
|
+
value="single-expandable"
|
36
|
+
>
|
37
|
+
{children}
|
38
|
+
</ExpandableItem>
|
39
|
+
</Accordion>
|
40
|
+
);
|
41
|
+
},
|
42
|
+
);
|
43
|
+
|
92
44
|
/**
|
93
45
|
* An item in a set of Expandables. Must be wrapped in an `<Accordion>` component.
|
94
46
|
*
|
95
47
|
* ```tsx
|
96
48
|
* <Accordion variant="ghost">
|
97
|
-
* <ExpandableItem title="Is Spor easy?" headingLevel="h3">
|
49
|
+
* <ExpandableItem value="a" title="Is Spor easy?" headingLevel="h3">
|
98
50
|
* Yes
|
99
51
|
* </ExpandableItem>
|
100
|
-
* <ExpandableItem title="Do you love it?" headingLevel="h3">
|
52
|
+
* <ExpandableItem value="b" title="Do you love it?" headingLevel="h3">
|
101
53
|
* 🥰
|
102
54
|
* </ExpandableItem>
|
103
55
|
* </Accordion>
|
104
56
|
* ```
|
105
57
|
*
|
106
|
-
*
|
58
|
+
*
|
59
|
+
* If you need even more control, you can put together your own expandable with the `Accordion`, `AccordionItem`, `AccordionItemTrigger`, and `AccordionItemContent` components.
|
60
|
+
*
|
61
|
+
* @see https://spor.vy.no/components/accordion
|
107
62
|
*/
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
63
|
+
|
64
|
+
export const ExpandableItem = (props: ExpandableItemProps) => {
|
65
|
+
const {
|
66
|
+
title,
|
67
|
+
children,
|
68
|
+
value,
|
69
|
+
headingLevel = "h3",
|
70
|
+
startElement,
|
71
|
+
...rest
|
72
|
+
} = props;
|
73
|
+
warnAboutMismatchingIcon({ icon: startElement });
|
116
74
|
return (
|
117
|
-
<AccordionItem {...rest}>
|
118
|
-
<
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
</Box>
|
127
|
-
<AccordionPanel>{children}</AccordionPanel>
|
75
|
+
<AccordionItem value={value} {...rest}>
|
76
|
+
<AccordionItemTrigger
|
77
|
+
startElement={startElement}
|
78
|
+
headingLevel={headingLevel}
|
79
|
+
>
|
80
|
+
{title}
|
81
|
+
</AccordionItemTrigger>
|
82
|
+
|
83
|
+
<AccordionItemContent>{children}</AccordionItemContent>
|
128
84
|
</AccordionItem>
|
129
85
|
);
|
130
86
|
};
|
131
|
-
|
132
|
-
type WarnAboutMismatchingIcon = {
|
133
|
-
icon: any;
|
134
|
-
};
|
135
|
-
const warnAboutMismatchingIcon = ({ icon }: WarnAboutMismatchingIcon) => {
|
136
|
-
if (process.env.NODE_ENV !== "production") {
|
137
|
-
const displayName = icon?.type?.render?.displayName;
|
138
|
-
if (!displayName) {
|
139
|
-
return;
|
140
|
-
}
|
141
|
-
if (displayName.includes("Fill")) {
|
142
|
-
console.warn(
|
143
|
-
`You passed a filled icon. This component requires outlined icons. You passed ${displayName}, replace it with ${displayName.replace(
|
144
|
-
"Fill",
|
145
|
-
"Outline",
|
146
|
-
)}.`,
|
147
|
-
);
|
148
|
-
return;
|
149
|
-
}
|
150
|
-
if (!displayName.includes("24Icon")) {
|
151
|
-
console.warn(
|
152
|
-
`The icon you passed was of the wrong size. You passed ${displayName}, replace it with ${displayName.replace(
|
153
|
-
/(\d{2})Icon/,
|
154
|
-
"24Icon",
|
155
|
-
)}.`,
|
156
|
-
);
|
157
|
-
}
|
158
|
-
}
|
159
|
-
};
|
@@ -0,0 +1,31 @@
|
|
1
|
+
type WarnAboutMismatchingIcon = {
|
2
|
+
icon: any;
|
3
|
+
};
|
4
|
+
|
5
|
+
export const warnAboutMismatchingIcon = ({
|
6
|
+
icon,
|
7
|
+
}: WarnAboutMismatchingIcon) => {
|
8
|
+
if (process.env.NODE_ENV !== "production") {
|
9
|
+
const displayName = icon?.type?.render?.displayName;
|
10
|
+
if (!displayName) {
|
11
|
+
return;
|
12
|
+
}
|
13
|
+
if (displayName.includes("Fill")) {
|
14
|
+
console.warn(
|
15
|
+
`You passed a filled icon. This component requires outlined icons. You passed ${displayName}, replace it with ${displayName.replace(
|
16
|
+
"Fill",
|
17
|
+
"Outline",
|
18
|
+
)}.`,
|
19
|
+
);
|
20
|
+
return;
|
21
|
+
}
|
22
|
+
if (!displayName.includes("24Icon")) {
|
23
|
+
console.warn(
|
24
|
+
`The icon you passed was of the wrong size. You passed ${displayName}, replace it with ${displayName.replace(
|
25
|
+
/(\d{2})Icon/,
|
26
|
+
"24Icon",
|
27
|
+
)}.`,
|
28
|
+
);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
};
|
@@ -0,0 +1,60 @@
|
|
1
|
+
import { accordionSlotRecipe } from "@/theme/slot-recipes/accordion";
|
2
|
+
import { RecipeVariantProps } from "@chakra-ui/react";
|
3
|
+
import {
|
4
|
+
AccordionRootProps as ChakraAccordionProps,
|
5
|
+
Accordion as ChakraAccordion,
|
6
|
+
} from "@chakra-ui/react";
|
7
|
+
import { PropsWithChildren } from "react";
|
8
|
+
|
9
|
+
export type AccordionVariantProps = RecipeVariantProps<
|
10
|
+
typeof accordionSlotRecipe
|
11
|
+
>;
|
12
|
+
|
13
|
+
export type AccordionProps = Exclude<
|
14
|
+
ChakraAccordionProps,
|
15
|
+
"variant" | "size" | "orientation"
|
16
|
+
> &
|
17
|
+
AccordionVariantProps &
|
18
|
+
PropsWithChildren & {
|
19
|
+
/**
|
20
|
+
* The display variant of the accordion items.
|
21
|
+
*
|
22
|
+
* - `core` renders a pretty unstyled expandable list without any borders
|
23
|
+
* - `base` renders an outlined version
|
24
|
+
* - `floating` renders a version with a drop shadow
|
25
|
+
*/
|
26
|
+
variant?: "ghost" | "core" | "floating";
|
27
|
+
/* Gap between accordions */
|
28
|
+
gap?: string | number;
|
29
|
+
};
|
30
|
+
|
31
|
+
export type HeadingLevel = {
|
32
|
+
/** Heading level of the trigger button */
|
33
|
+
headingLevel?: "h2" | "h3" | "h4" | "h5" | "h6";
|
34
|
+
};
|
35
|
+
|
36
|
+
export type AccordionItemTriggerProps = Omit<
|
37
|
+
ChakraAccordion.ItemTriggerProps,
|
38
|
+
"indicatorElement"
|
39
|
+
> &
|
40
|
+
HeadingLevel & {
|
41
|
+
/** Icon to be displayed on the left of the trigger button. Use 24px outline. */
|
42
|
+
startElement?: React.ReactNode;
|
43
|
+
};
|
44
|
+
|
45
|
+
export type AccordionItemContentProps = ChakraAccordion.ItemContentProps & {
|
46
|
+
children?: React.ReactNode;
|
47
|
+
};
|
48
|
+
|
49
|
+
export type ExpandableProps = AccordionProps &
|
50
|
+
AccordionItemTriggerProps &
|
51
|
+
HeadingLevel & {
|
52
|
+
title: string;
|
53
|
+
};
|
54
|
+
|
55
|
+
export type ExpandableItemProps = HeadingLevel & {
|
56
|
+
value: string;
|
57
|
+
title: string;
|
58
|
+
children?: React.ReactNode;
|
59
|
+
startElement?: React.ReactNode;
|
60
|
+
};
|
@@ -0,0 +1,101 @@
|
|
1
|
+
"use client";
|
2
|
+
|
3
|
+
import {
|
4
|
+
Alert as ChakraAlert,
|
5
|
+
useDisclosure,
|
6
|
+
HStack,
|
7
|
+
useSlotRecipe,
|
8
|
+
} from "@chakra-ui/react";
|
9
|
+
import React, { forwardRef } from "react";
|
10
|
+
import { AlertIcon } from "./AlertIcon";
|
11
|
+
import { CloseButton } from "@/button";
|
12
|
+
import { IconComponent } from "@vygruppen/spor-icon-react";
|
13
|
+
|
14
|
+
export type AlertProps = Omit<ChakraAlert.RootProps, "colorPalette"> & {
|
15
|
+
/** Whether or not to show the alert icon */
|
16
|
+
showIndicator?: boolean;
|
17
|
+
/** Whether or not the alert is closable */
|
18
|
+
icon?: IconComponent;
|
19
|
+
closable?: boolean;
|
20
|
+
/** Callback for when the alert is closed */
|
21
|
+
onAlertClose?: () => void;
|
22
|
+
};
|
23
|
+
|
24
|
+
/**
|
25
|
+
*
|
26
|
+
* Alerts are used to communicate important information to the user.
|
27
|
+
* They can be used to inform about success, errors, warnings, or other important information.
|
28
|
+
*
|
29
|
+
* ```tsx
|
30
|
+
* <Alert variant="info" title="Information">
|
31
|
+
* This is an information alert
|
32
|
+
* </Alert>
|
33
|
+
* ```
|
34
|
+
*
|
35
|
+
* You may also use the closable prop to allow the user to dismiss the alert.
|
36
|
+
*
|
37
|
+
* ```tsx
|
38
|
+
* <Alert variant="info" title="Information" closable>
|
39
|
+
* This is an closable alert
|
40
|
+
* </Alert>
|
41
|
+
*
|
42
|
+
* @see Docs https://spor.vy.no/alert
|
43
|
+
*/
|
44
|
+
|
45
|
+
export const Alert = forwardRef<HTMLDivElement, AlertProps>((props, ref) => {
|
46
|
+
const {
|
47
|
+
title,
|
48
|
+
showIndicator = true,
|
49
|
+
icon,
|
50
|
+
closable = false,
|
51
|
+
onAlertClose,
|
52
|
+
children,
|
53
|
+
} = props;
|
54
|
+
const { open, onClose } = useDisclosure({ defaultOpen: true });
|
55
|
+
|
56
|
+
const handleAlertClose = () => {
|
57
|
+
onClose();
|
58
|
+
onAlertClose?.();
|
59
|
+
};
|
60
|
+
|
61
|
+
const recipe = useSlotRecipe({ key: "alert" });
|
62
|
+
const styles = recipe({ variant: props.variant });
|
63
|
+
|
64
|
+
if (!open) return null;
|
65
|
+
return (
|
66
|
+
<ChakraAlert.Root ref={ref} {...props}>
|
67
|
+
<ChakraAlert.Content flexDirection={title ? "column" : "row"}>
|
68
|
+
<HStack gap="1" alignItems="flex-start">
|
69
|
+
{showIndicator && (
|
70
|
+
<ChakraAlert.Indicator asChild>
|
71
|
+
<AlertIcon variant={props.variant} customIcon={icon} />
|
72
|
+
</ChakraAlert.Indicator>
|
73
|
+
)}
|
74
|
+
{title && (
|
75
|
+
<ChakraAlert.Title paddingRight={closable ? 6 : 0}>
|
76
|
+
{title}
|
77
|
+
</ChakraAlert.Title>
|
78
|
+
)}
|
79
|
+
</HStack>
|
80
|
+
{children && (
|
81
|
+
<ChakraAlert.Description
|
82
|
+
paddingLeft={title ? 0.5 : 0}
|
83
|
+
paddingRight={closable ? 6 : 0}
|
84
|
+
>
|
85
|
+
{children}
|
86
|
+
</ChakraAlert.Description>
|
87
|
+
)}
|
88
|
+
</ChakraAlert.Content>
|
89
|
+
{closable && (
|
90
|
+
<CloseButton
|
91
|
+
size="xs"
|
92
|
+
position="absolute"
|
93
|
+
top="1.5"
|
94
|
+
right="1.5"
|
95
|
+
onClick={handleAlertClose}
|
96
|
+
css={styles.closeButton}
|
97
|
+
/>
|
98
|
+
)}
|
99
|
+
</ChakraAlert.Root>
|
100
|
+
);
|
101
|
+
});
|