@vygruppen/spor-react 4.0.2 → 4.1.0
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 +10 -10
- package/CHANGELOG.md +27 -0
- package/dist/{CountryCodeSelect-WSPQNU6B.mjs → CountryCodeSelect-FBKDO5JS.mjs} +1 -1
- package/dist/{chunk-MGJQOEU2.mjs → chunk-FPWAXD72.mjs} +149 -220
- package/dist/index.d.mts +22 -96
- package/dist/index.d.ts +22 -96
- package/dist/index.js +148 -219
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/accordion/Accordion.test.tsx +1 -1
- package/src/accordion/Accordion.tsx +1 -1
- package/src/accordion/AccordionContext.tsx +1 -1
- package/src/accordion/Expandable.tsx +6 -6
- package/src/alert/BaseAlert.test.tsx +5 -5
- package/src/alert/BaseAlert.tsx +5 -1
- package/src/alert/ClosableAlert.test.tsx +3 -3
- package/src/alert/ExpandableAlert.test.tsx +5 -5
- package/src/button/Button.test.tsx +1 -1
- package/src/button/Button.tsx +1 -1
- package/src/button/CloseButton.tsx +1 -1
- package/src/button/FloatingActionButton.tsx +5 -5
- package/src/button/IconButton.tsx +1 -1
- package/src/card/Card.tsx +3 -2
- package/src/card/index.tsx +1 -1
- package/src/datepicker/Calendar.tsx +6 -6
- package/src/datepicker/CalendarCell.tsx +9 -8
- package/src/datepicker/CalendarGrid.tsx +9 -9
- package/src/datepicker/CalendarHeader.tsx +2 -2
- package/src/datepicker/CalendarTriggerButton.tsx +5 -10
- package/src/datepicker/DateField.tsx +2 -2
- package/src/datepicker/DatePicker.tsx +3 -3
- package/src/datepicker/DateTimeSegment.tsx +2 -2
- package/src/datepicker/RangeCalendar.tsx +5 -2
- package/src/datepicker/StyledField.tsx +2 -6
- package/src/datepicker/TimePicker.test.tsx +4 -4
- package/src/datepicker/TimePicker.tsx +9 -7
- package/src/index.tsx +0 -1
- package/src/input/CardSelect.tsx +3 -3
- package/src/input/Combobox.tsx +1 -1
- package/src/input/CountryCodeSelect.tsx +1 -1
- package/src/input/FormErrorMessage.tsx +1 -1
- package/src/input/InfoSelect.tsx +1 -1
- package/src/input/Input.tsx +1 -1
- package/src/input/InputElement.tsx +2 -2
- package/src/input/ListBox.tsx +3 -3
- package/src/input/NativeSelect.tsx +1 -1
- package/src/input/PasswordInput.tsx +1 -1
- package/src/input/PhoneNumberInput.tsx +13 -4
- package/src/input/Popover.tsx +4 -4
- package/src/input/RadioGroup.tsx +1 -1
- package/src/input/SearchInput.tsx +1 -1
- package/src/input/Switch.tsx +1 -1
- package/src/layout/Stack.tsx +1 -1
- package/src/linjetag/TravelTag.tsx +2 -2
- package/src/link/TextLink.tsx +1 -1
- package/src/list/index.tsx +0 -1
- package/src/loader/DarkSpinner.tsx +5 -5
- package/src/loader/SkeletonText.tsx +6 -3
- package/src/loader/useRotatingLabel.tsx +2 -2
- package/src/media-controller/index.test.tsx +6 -6
- package/src/modal/Drawer.tsx +2 -4
- package/src/modal/ModalHeader.tsx +1 -1
- package/src/provider/index.tsx +1 -1
- package/src/stepper/Stepper.tsx +10 -6
- package/src/stepper/StepperContext.tsx +7 -7
- package/src/stepper/StepperStep.tsx +56 -16
- package/src/theme/components/button.ts +25 -44
- package/src/theme/components/card.ts +7 -1
- package/src/theme/components/close-button.ts +3 -1
- package/src/theme/components/datepicker.ts +2 -2
- package/src/theme/components/divider.ts +17 -17
- package/src/theme/components/fab.ts +16 -13
- package/src/theme/components/info-tag.ts +7 -8
- package/src/theme/components/input.ts +4 -2
- package/src/theme/components/line-icon.ts +1 -2
- package/src/theme/components/media-controller-button.ts +1 -1
- package/src/theme/components/popover.ts +1 -2
- package/src/theme/components/select.ts +4 -4
- package/src/theme/components/stepper.ts +8 -155
- package/src/theme/components/switch.ts +9 -9
- package/src/theme/components/table.ts +3 -3
- package/src/theme/components/tabs.ts +24 -18
- package/src/theme/components/textarea.ts +1 -1
- package/src/theme/components/travel-tag.ts +2 -2
- package/src/theme/foundations/spacing.ts +1 -1
- package/src/theme/foundations/styles.ts +10 -10
- package/src/theme/utils/box-shadow-utils.ts +2 -2
- package/src/toast/ActionToast.test.tsx +1 -1
- package/src/toast/BaseToast.test.tsx +3 -3
- package/src/toast/ClosableToast.test.tsx +1 -1
- package/src/toast/index.tsx +1 -1
- package/src/toast/useToast.tsx +3 -3
- package/src/typography/Badge.tsx +1 -1
- package/src/typography/Text.tsx +1 -1
- package/tsconfig.json +1 -1
@@ -39,7 +39,7 @@ export const FormErrorMessage = ({
|
|
39
39
|
const formControlContext = useFormControlContext();
|
40
40
|
if (!formControlContext) {
|
41
41
|
throw new Error(
|
42
|
-
"FormErrorMessage must be used within a FormControl component"
|
42
|
+
"FormErrorMessage must be used within a FormControl component",
|
43
43
|
);
|
44
44
|
}
|
45
45
|
if (!formControlContext.isInvalid) {
|
package/src/input/InfoSelect.tsx
CHANGED
package/src/input/Input.tsx
CHANGED
@@ -23,7 +23,7 @@ export type InputElementProps = ChakraInputElementProps;
|
|
23
23
|
* ```
|
24
24
|
*/
|
25
25
|
export const InputLeftElement = forwardRef<InputElementProps, "div">(
|
26
|
-
(props, ref) => <ChakraInputLeftElement {...props} ref={ref}
|
26
|
+
(props, ref) => <ChakraInputLeftElement {...props} ref={ref} />,
|
27
27
|
);
|
28
28
|
|
29
29
|
/**
|
@@ -41,5 +41,5 @@ export const InputLeftElement = forwardRef<InputElementProps, "div">(
|
|
41
41
|
* ```
|
42
42
|
*/
|
43
43
|
export const InputRightElement = forwardRef<InputElementProps, "div">(
|
44
|
-
(props, ref) => <ChakraInputRightElement {...props} ref={ref}
|
44
|
+
(props, ref) => <ChakraInputRightElement {...props} ref={ref} />,
|
45
45
|
);
|
package/src/input/ListBox.tsx
CHANGED
@@ -89,7 +89,7 @@ export function ListBox<T extends object>({
|
|
89
89
|
<ListBoxSection key={item.key} section={item} state={state} />
|
90
90
|
) : (
|
91
91
|
<Option key={item.key} item={item} state={state} />
|
92
|
-
)
|
92
|
+
),
|
93
93
|
)}
|
94
94
|
</List>
|
95
95
|
);
|
@@ -163,7 +163,7 @@ function Option({ item, state }: OptionProps) {
|
|
163
163
|
(event: TouchEvent) => {
|
164
164
|
event.preventDefault();
|
165
165
|
},
|
166
|
-
{ passive: false, once: true }
|
166
|
+
{ passive: false, once: true },
|
167
167
|
);
|
168
168
|
}, []);
|
169
169
|
|
@@ -221,7 +221,7 @@ function ListBoxSection({ section, state }: ListBoxSectionProps) {
|
|
221
221
|
{Array.from(state.collection.getChildren(section.key)).map(
|
222
222
|
(item: any) => (
|
223
223
|
<Option key={item.key} item={item} state={state} />
|
224
|
-
)
|
224
|
+
),
|
225
225
|
)}
|
226
226
|
</List>
|
227
227
|
</ListItem>
|
@@ -13,6 +13,8 @@ type CountryCodeAndPhoneNumber = {
|
|
13
13
|
nationalNumber: string;
|
14
14
|
};
|
15
15
|
type PhoneNumberInputProps = Omit<BoxProps, "onChange"> & {
|
16
|
+
/** The label. Defaults to a localized version of "Phone number" */
|
17
|
+
label?: string;
|
16
18
|
/** The root name.
|
17
19
|
*
|
18
20
|
* Please note that when specifying the name, the rendered names will be `${name}-country-code` and `${name}-phone-number`, respectively
|
@@ -42,10 +44,17 @@ type PhoneNumberInputProps = Omit<BoxProps, "onChange"> & {
|
|
42
44
|
*/
|
43
45
|
export const PhoneNumberInput = forwardRef<PhoneNumberInputProps, As>(
|
44
46
|
(
|
45
|
-
{
|
46
|
-
|
47
|
+
{
|
48
|
+
label: externalLabel,
|
49
|
+
name,
|
50
|
+
value: externalValue,
|
51
|
+
onChange: externalOnChange,
|
52
|
+
...boxProps
|
53
|
+
},
|
54
|
+
ref,
|
47
55
|
) => {
|
48
56
|
const { t } = useTranslation();
|
57
|
+
const label = externalLabel ?? t(texts.phoneNumber);
|
49
58
|
const [value, onChange] = useControllableState({
|
50
59
|
value: externalValue,
|
51
60
|
onChange: externalOnChange,
|
@@ -85,7 +94,7 @@ export const PhoneNumberInput = forwardRef<PhoneNumberInputProps, As>(
|
|
85
94
|
<Input
|
86
95
|
ref={ref}
|
87
96
|
type="tel"
|
88
|
-
label={
|
97
|
+
label={label}
|
89
98
|
value={value.nationalNumber}
|
90
99
|
name={name ? `${name}-phone-number` : "phone-number"}
|
91
100
|
onChange={(e) => {
|
@@ -101,7 +110,7 @@ export const PhoneNumberInput = forwardRef<PhoneNumberInputProps, As>(
|
|
101
110
|
/>
|
102
111
|
</AttachedInputs>
|
103
112
|
);
|
104
|
-
}
|
113
|
+
},
|
105
114
|
);
|
106
115
|
|
107
116
|
const texts = createTexts({
|
package/src/input/Popover.tsx
CHANGED
@@ -45,7 +45,7 @@ type PopoverProps = {
|
|
45
45
|
*/
|
46
46
|
hasBackdrop?: boolean;
|
47
47
|
/** The minimum padding required between the popover and the surrounding container
|
48
|
-
*
|
48
|
+
*
|
49
49
|
* Defaults to 12 (the same as React Aria's default)
|
50
50
|
*/
|
51
51
|
containerPadding?: number;
|
@@ -69,7 +69,7 @@ export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
|
|
69
69
|
hasBackdrop = true,
|
70
70
|
containerPadding = 12,
|
71
71
|
},
|
72
|
-
ref
|
72
|
+
ref,
|
73
73
|
) => {
|
74
74
|
const internalRef = useRef<HTMLDivElement>(null);
|
75
75
|
const popoverRef = ref ?? (internalRef as any);
|
@@ -85,7 +85,7 @@ export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
|
|
85
85
|
isNonModal,
|
86
86
|
containerPadding,
|
87
87
|
},
|
88
|
-
state
|
88
|
+
state,
|
89
89
|
);
|
90
90
|
|
91
91
|
const popoverBox = (
|
@@ -109,5 +109,5 @@ export const Popover = forwardRef<HTMLDivElement, PopoverProps>(
|
|
109
109
|
{popoverBox}
|
110
110
|
</Overlay>
|
111
111
|
);
|
112
|
-
}
|
112
|
+
},
|
113
113
|
);
|
package/src/input/RadioGroup.tsx
CHANGED
package/src/input/Switch.tsx
CHANGED
package/src/layout/Stack.tsx
CHANGED
@@ -71,7 +71,7 @@ export const TravelTag = forwardRef<TravelTagProps, As>(
|
|
71
71
|
isDisabled,
|
72
72
|
...rest
|
73
73
|
},
|
74
|
-
ref
|
74
|
+
ref,
|
75
75
|
) => {
|
76
76
|
const styles = useMultiStyleConfig("TravelTag", {
|
77
77
|
variant,
|
@@ -100,7 +100,7 @@ export const TravelTag = forwardRef<TravelTagProps, As>(
|
|
100
100
|
{DeviationLevelIcon && <DeviationLevelIcon sx={styles.deviationIcon} />}
|
101
101
|
</Box>
|
102
102
|
);
|
103
|
-
}
|
103
|
+
},
|
104
104
|
);
|
105
105
|
|
106
106
|
const getDeviationLevelIcon = ({
|
package/src/link/TextLink.tsx
CHANGED
package/src/list/index.tsx
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import { spinnerDarkData } from "@vygruppen/spor-loader";
|
1
|
+
import { spinnerDarkData, spinnerLightData } from "@vygruppen/spor-loader";
|
2
2
|
import React from "react";
|
3
|
-
import { Box, BoxProps, Center } from "..";
|
3
|
+
import { Box, BoxProps, Center, useColorMode } from "..";
|
4
4
|
import { ClientOnly } from "./ClientOnly";
|
5
5
|
import Lottie from "./Lottie";
|
6
6
|
|
@@ -26,12 +26,12 @@ export const DarkSpinner = ({
|
|
26
26
|
maxWidth,
|
27
27
|
...props
|
28
28
|
}: DarkSpinnerProps) => {
|
29
|
+
const { colorMode } = useColorMode();
|
30
|
+
const spinnerData = colorMode === "dark" ? spinnerLightData : spinnerDarkData;
|
29
31
|
return (
|
30
32
|
<Center flexDirection="column" {...props}>
|
31
33
|
<Box width={width} maxWidth={maxWidth}>
|
32
|
-
<ClientOnly>
|
33
|
-
{() => <Lottie animationData={spinnerDarkData} />}
|
34
|
-
</ClientOnly>
|
34
|
+
<ClientOnly>{() => <Lottie animationData={spinnerData} />}</ClientOnly>
|
35
35
|
</Box>
|
36
36
|
{children && (
|
37
37
|
<Box marginTop={3} fontWeight="bold">
|
@@ -1,8 +1,11 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
SkeletonText as ChakraSkeletonText,
|
3
|
+
SkeletonTextProps as ChakraSkeletonTextProps,
|
4
|
+
} from "@chakra-ui/react";
|
2
5
|
import React from "react";
|
3
6
|
|
4
|
-
export type SkeletonTextProps = ChakraSkeletonTextProps
|
5
|
-
|
7
|
+
export type SkeletonTextProps = ChakraSkeletonTextProps;
|
8
|
+
|
6
9
|
/**
|
7
10
|
* SkeletonText renders a loading animation for a given text. It works great as a placeholder to avoid layout shifts.
|
8
11
|
*/
|
@@ -9,13 +9,13 @@ type UseRotatingLabelArgs = {
|
|
9
9
|
export const useRotatingLabel = ({ label, delay }: UseRotatingLabelArgs) => {
|
10
10
|
const loadingTextArray = useMemo(
|
11
11
|
() => (Array.isArray(label) ? label : [label]),
|
12
|
-
[label]
|
12
|
+
[label],
|
13
13
|
);
|
14
14
|
const [currentLoadingTextIndex, setCurrentLoadingTextIndex] = useState(0);
|
15
15
|
|
16
16
|
useInterval(() => {
|
17
17
|
setCurrentLoadingTextIndex(
|
18
|
-
(prevIndex) => (prevIndex + 1) % loadingTextArray.length
|
18
|
+
(prevIndex) => (prevIndex + 1) % loadingTextArray.length,
|
19
19
|
);
|
20
20
|
}, delay);
|
21
21
|
return loadingTextArray[currentLoadingTextIndex];
|
@@ -8,7 +8,7 @@ describe("<PlayPauseButton />", () => {
|
|
8
8
|
it("works like a button", async () => {
|
9
9
|
const handleClick = vi.fn();
|
10
10
|
const { getByRole } = render(
|
11
|
-
<PlayPauseButton size="sm" isPlaying={true} onClick={handleClick}
|
11
|
+
<PlayPauseButton size="sm" isPlaying={true} onClick={handleClick} />,
|
12
12
|
);
|
13
13
|
getByRole("button").click();
|
14
14
|
expect(handleClick).toHaveBeenCalled();
|
@@ -16,7 +16,7 @@ describe("<PlayPauseButton />", () => {
|
|
16
16
|
|
17
17
|
it("is accessible", async () => {
|
18
18
|
const { container } = render(
|
19
|
-
<PlayPauseButton size="sm" isPlaying={true} onClick={() => {}}
|
19
|
+
<PlayPauseButton size="sm" isPlaying={true} onClick={() => {}} />,
|
20
20
|
);
|
21
21
|
expect(await axe(container)).toHaveNoViolations();
|
22
22
|
});
|
@@ -26,7 +26,7 @@ describe("<SkipButtonButton />", () => {
|
|
26
26
|
it("works like a button", async () => {
|
27
27
|
const handleClick = vi.fn();
|
28
28
|
const { getByRole } = render(
|
29
|
-
<SkipButton size="sm" direction="forward" onClick={handleClick}
|
29
|
+
<SkipButton size="sm" direction="forward" onClick={handleClick} />,
|
30
30
|
);
|
31
31
|
getByRole("button").click();
|
32
32
|
expect(handleClick).toHaveBeenCalled();
|
@@ -34,7 +34,7 @@ describe("<SkipButtonButton />", () => {
|
|
34
34
|
|
35
35
|
it("is accessible", async () => {
|
36
36
|
const { container } = render(
|
37
|
-
<SkipButton size="sm" direction="forward" onClick={() => {}}
|
37
|
+
<SkipButton size="sm" direction="forward" onClick={() => {}} />,
|
38
38
|
);
|
39
39
|
expect(await axe(container)).toHaveNoViolations();
|
40
40
|
});
|
@@ -44,7 +44,7 @@ describe("<JumpButtonButton />", () => {
|
|
44
44
|
it("works like a button", async () => {
|
45
45
|
const handleClick = vi.fn();
|
46
46
|
const { getByRole } = render(
|
47
|
-
<JumpButton size="sm" direction="forward" onClick={handleClick}
|
47
|
+
<JumpButton size="sm" direction="forward" onClick={handleClick} />,
|
48
48
|
);
|
49
49
|
getByRole("button").click();
|
50
50
|
expect(handleClick).toHaveBeenCalled();
|
@@ -52,7 +52,7 @@ describe("<JumpButtonButton />", () => {
|
|
52
52
|
|
53
53
|
it("is accessible", async () => {
|
54
54
|
const { container } = render(
|
55
|
-
<JumpButton size="sm" direction="forward" onClick={() => {}}
|
55
|
+
<JumpButton size="sm" direction="forward" onClick={() => {}} />,
|
56
56
|
);
|
57
57
|
expect(await axe(container)).toHaveNoViolations();
|
58
58
|
});
|
package/src/modal/Drawer.tsx
CHANGED
@@ -73,7 +73,7 @@ export const DrawerContent = forwardRef<DrawerContentProps, any>(
|
|
73
73
|
</ChakraDrawerContent>
|
74
74
|
</Box>
|
75
75
|
);
|
76
|
-
}
|
76
|
+
},
|
77
77
|
);
|
78
78
|
|
79
79
|
const Notch = forwardRef<BoxProps, any>((props, ref) => {
|
@@ -90,9 +90,7 @@ const Notch = forwardRef<BoxProps, any>((props, ref) => {
|
|
90
90
|
ref={ref}
|
91
91
|
>
|
92
92
|
<Center
|
93
|
-
background={
|
94
|
-
placement === "bottom" ? "bottom" : "top"
|
95
|
-
}
|
93
|
+
background={placement === "bottom" ? "bottom" : "top"}
|
96
94
|
padding={2}
|
97
95
|
borderRadius="md"
|
98
96
|
>
|
package/src/provider/index.tsx
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export * from "./SporProvider";
|
1
|
+
export * from "./SporProvider";
|
package/src/stepper/Stepper.tsx
CHANGED
@@ -13,10 +13,10 @@ import { StepperProvider } from "./StepperContext";
|
|
13
13
|
|
14
14
|
type StepperProps = {
|
15
15
|
onClick: (clickedStep: number) => void;
|
16
|
-
colorScheme: "light" | "dark" | "green";
|
17
16
|
title?: string;
|
18
17
|
activeStep: number;
|
19
18
|
steps: string[];
|
19
|
+
variant: "base" | "accent";
|
20
20
|
};
|
21
21
|
/**
|
22
22
|
* A stepper is used to show which step of a process a user is currently in.
|
@@ -37,9 +37,9 @@ export const Stepper = ({
|
|
37
37
|
steps,
|
38
38
|
activeStep: activeStepAsStringOrNumber,
|
39
39
|
title,
|
40
|
-
|
40
|
+
variant,
|
41
41
|
}: StepperProps) => {
|
42
|
-
const style = useMultiStyleConfig("Stepper", {
|
42
|
+
const style = useMultiStyleConfig("Stepper", { variant });
|
43
43
|
const numberOfSteps = steps.length;
|
44
44
|
const activeStep = Number(activeStepAsStringOrNumber);
|
45
45
|
const { t } = useTranslation();
|
@@ -48,7 +48,7 @@ export const Stepper = ({
|
|
48
48
|
<StepperProvider
|
49
49
|
onClick={onClick}
|
50
50
|
activeStep={activeStep}
|
51
|
-
|
51
|
+
variant={variant}
|
52
52
|
numberOfSteps={numberOfSteps}
|
53
53
|
>
|
54
54
|
<Box __css={style.container}>
|
@@ -74,7 +74,11 @@ export const Stepper = ({
|
|
74
74
|
borderRadius="xs"
|
75
75
|
>
|
76
76
|
{steps.map((step, index) => (
|
77
|
-
<StepperStep
|
77
|
+
<StepperStep
|
78
|
+
key={step}
|
79
|
+
stepNumber={index + 1}
|
80
|
+
variant={variant}
|
81
|
+
>
|
78
82
|
{step}
|
79
83
|
</StepperStep>
|
80
84
|
))}
|
@@ -88,7 +92,7 @@ export const Stepper = ({
|
|
88
92
|
</Box>
|
89
93
|
<Flex justifyContent="center" display={["none", "flex"]}>
|
90
94
|
{steps.map((step, index) => (
|
91
|
-
<StepperStep key={index} stepNumber={index + 1}>
|
95
|
+
<StepperStep key={index} stepNumber={index + 1} variant={variant}>
|
92
96
|
{step}
|
93
97
|
</StepperStep>
|
94
98
|
))}
|
@@ -3,24 +3,24 @@ import React from "react";
|
|
3
3
|
type StepperContextType = {
|
4
4
|
activeStep: number;
|
5
5
|
numberOfSteps: number;
|
6
|
-
|
6
|
+
variant: Variant;
|
7
7
|
onClick: (clickedIndex: number) => void;
|
8
8
|
};
|
9
9
|
const StepperContext = React.createContext<StepperContextType | null>(null);
|
10
10
|
|
11
|
-
type
|
11
|
+
type Variant = "base" | "accent";
|
12
12
|
|
13
13
|
type StepperProviderProps = {
|
14
14
|
/** Stepper steps */
|
15
15
|
children: React.ReactNode;
|
16
16
|
/** Callback whenever a stepper step is clicked */
|
17
17
|
onClick: (clickedIndex: number) => void;
|
18
|
-
/** The current color scheme */
|
19
|
-
colorScheme: ColorScheme;
|
20
18
|
/** The currently active step */
|
21
19
|
activeStep: number;
|
22
20
|
/** The amount of steps */
|
23
21
|
numberOfSteps: number;
|
22
|
+
/** The current variant */
|
23
|
+
variant: Variant;
|
24
24
|
};
|
25
25
|
/**
|
26
26
|
* Internal provider for sharing logic between stepper and stepper steps.
|
@@ -29,12 +29,12 @@ export const StepperProvider = ({
|
|
29
29
|
activeStep,
|
30
30
|
children,
|
31
31
|
onClick,
|
32
|
-
colorScheme,
|
33
32
|
numberOfSteps,
|
33
|
+
variant,
|
34
34
|
}: StepperProviderProps) => {
|
35
35
|
return (
|
36
36
|
<StepperContext.Provider
|
37
|
-
value={{ activeStep, onClick,
|
37
|
+
value={{ activeStep, onClick, numberOfSteps, variant }}
|
38
38
|
>
|
39
39
|
{children}
|
40
40
|
</StepperContext.Provider>
|
@@ -48,7 +48,7 @@ export const useStepper = () => {
|
|
48
48
|
const context = React.useContext(StepperContext);
|
49
49
|
if (!context) {
|
50
50
|
throw new Error(
|
51
|
-
"useStepper must be used within a StepperProvider. Most likely, you forgot to wrap your StepperStep in a Stepper component"
|
51
|
+
"useStepper must be used within a StepperProvider. Most likely, you forgot to wrap your StepperStep in a Stepper component",
|
52
52
|
);
|
53
53
|
}
|
54
54
|
return context;
|
@@ -1,43 +1,83 @@
|
|
1
|
-
import {
|
1
|
+
import { useMultiStyleConfig } from "@chakra-ui/react";
|
2
2
|
import { DropdownRightFill18Icon } from "@vygruppen/spor-icon-react";
|
3
3
|
import React from "react";
|
4
|
-
import { Box } from "..";
|
4
|
+
import { Box, Button } from "..";
|
5
5
|
import { useStepper } from "./StepperContext";
|
6
6
|
|
7
7
|
type StepperStepProps = {
|
8
8
|
children: React.ReactNode;
|
9
9
|
stepNumber: number;
|
10
|
+
variant: "base" | "accent";
|
10
11
|
};
|
11
|
-
export const StepperStep = ({
|
12
|
-
|
13
|
-
|
12
|
+
export const StepperStep = ({
|
13
|
+
children,
|
14
|
+
stepNumber,
|
15
|
+
variant,
|
16
|
+
}: StepperStepProps) => {
|
17
|
+
const { activeStep, onClick } = useStepper();
|
18
|
+
const state = getState(stepNumber!, activeStep);
|
14
19
|
const style = useMultiStyleConfig("Stepper", {
|
20
|
+
state,
|
15
21
|
variant,
|
16
|
-
colorScheme,
|
17
22
|
});
|
18
23
|
|
24
|
+
const adjustedProps = getButtonStylesForState(state);
|
25
|
+
|
19
26
|
return (
|
20
27
|
<Box __css={style.stepContainer}>
|
21
28
|
{stepNumber > 1 && (
|
22
29
|
<DropdownRightFill18Icon marginX={5} display={["none", "block"]} />
|
23
30
|
)}
|
24
31
|
|
25
|
-
<
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
32
|
+
<Button
|
33
|
+
size={"xs"}
|
34
|
+
variant={
|
35
|
+
state === "active"
|
36
|
+
? "primary"
|
37
|
+
: state === "completed"
|
38
|
+
? "additional"
|
39
|
+
: "ghost"
|
40
|
+
}
|
41
|
+
{...adjustedProps}
|
31
42
|
onClick={() => onClick(stepNumber)}
|
32
43
|
>
|
33
|
-
|
34
|
-
|
35
|
-
</Flex>
|
44
|
+
{children}
|
45
|
+
</Button>
|
36
46
|
</Box>
|
37
47
|
);
|
38
48
|
};
|
39
49
|
|
40
|
-
const
|
50
|
+
const getButtonStylesForState = (
|
51
|
+
state: "completed" | "active" | "disabled",
|
52
|
+
): Record<string, any> => {
|
53
|
+
switch (state) {
|
54
|
+
case "active":
|
55
|
+
return {
|
56
|
+
_hover: {},
|
57
|
+
boxShadow: "none",
|
58
|
+
_focus: {},
|
59
|
+
_active: {},
|
60
|
+
cursor: "auto",
|
61
|
+
};
|
62
|
+
case "completed":
|
63
|
+
return {
|
64
|
+
boxShadow: "none",
|
65
|
+
};
|
66
|
+
case "disabled":
|
67
|
+
return {
|
68
|
+
_disabled: {},
|
69
|
+
_hover: {},
|
70
|
+
_focus: {},
|
71
|
+
_active: {},
|
72
|
+
color: "dimGrey",
|
73
|
+
cursor: "auto",
|
74
|
+
};
|
75
|
+
default:
|
76
|
+
return {};
|
77
|
+
}
|
78
|
+
};
|
79
|
+
|
80
|
+
const getState = (stepNumber: number, activeStep: number) => {
|
41
81
|
if (stepNumber < activeStep) {
|
42
82
|
return "completed";
|
43
83
|
}
|