@vygruppen/spor-react 7.0.0 → 7.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 +16 -0
- package/dist/{CountryCodeSelect-OK6RZ6AY.mjs → CountryCodeSelect-NMBC7YLP.mjs} +1 -1
- package/dist/{chunk-CYU6YFQK.mjs → chunk-UQDHT6S5.mjs} +114 -89
- package/dist/index.d.mts +73 -19
- package/dist/index.d.ts +73 -19
- package/dist/index.js +112 -87
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/stepper/Stepper.tsx +78 -54
- package/src/stepper/StepperStep.tsx +42 -51
- package/src/theme/components/button.ts +3 -3
- package/src/theme/components/fab.ts +6 -2
- package/src/theme/components/progress-indicator.ts +1 -1
- package/src/theme/components/stepper.ts +29 -15
package/src/stepper/Stepper.tsx
CHANGED
@@ -1,22 +1,42 @@
|
|
1
|
-
import { Flex,
|
2
|
-
import {
|
1
|
+
import { Flex, useMultiStyleConfig } from "@chakra-ui/react";
|
2
|
+
import { ArrowLeftFill24Icon } from "@vygruppen/spor-icon-react";
|
3
3
|
import React from "react";
|
4
4
|
import { StepperStep } from ".";
|
5
|
-
import {
|
6
|
-
Box,
|
7
|
-
IconButton,
|
8
|
-
SimplePopover,
|
9
|
-
createTexts,
|
10
|
-
useTranslation,
|
11
|
-
} from "..";
|
5
|
+
import { Box, IconButton, Text, createTexts, useTranslation } from "..";
|
12
6
|
import { StepperProvider } from "./StepperContext";
|
13
7
|
|
14
8
|
type StepperProps = {
|
9
|
+
/** Callback for when a step is clicked */
|
15
10
|
onClick: (clickedStep: number) => void;
|
11
|
+
/** Callback for when the back button is clicked (on smaller screens).
|
12
|
+
* A boolean indicating whether or not the user is on the first step is passed as an argument.
|
13
|
+
*
|
14
|
+
* If this is not provided, the back button will not be shown on smaller screens on the first step.
|
15
|
+
*/
|
16
|
+
onBackButtonClick?: (isFirstStep: boolean) => void;
|
17
|
+
/**
|
18
|
+
* Heading shown on smaller devices
|
19
|
+
* @deprecated Use `heading` instead
|
20
|
+
*/
|
16
21
|
title?: string;
|
22
|
+
/** Heading shown on smaller devices */
|
23
|
+
heading?: string;
|
24
|
+
/**
|
25
|
+
* The heading level rendered for the heading shown on smaller devices.
|
26
|
+
*
|
27
|
+
* Defaults to h2
|
28
|
+
* */
|
29
|
+
headingLevel?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p";
|
30
|
+
/** The currently active step */
|
17
31
|
activeStep: number;
|
32
|
+
/** The labels of each step */
|
18
33
|
steps: string[];
|
34
|
+
/** The variant.
|
35
|
+
* "base" has a transparent background,
|
36
|
+
* while "accent" has a slight accent color */
|
19
37
|
variant: "base" | "accent";
|
38
|
+
/** Disables all clicks */
|
39
|
+
isDisabled?: boolean;
|
20
40
|
};
|
21
41
|
/**
|
22
42
|
* A stepper is used to show which step of a process a user is currently in.
|
@@ -25,74 +45,78 @@ type StepperProps = {
|
|
25
45
|
*
|
26
46
|
* ```tsx
|
27
47
|
* <Stepper
|
28
|
-
* title="
|
48
|
+
* title="Example"
|
29
49
|
* onClick={handleStepClick}
|
30
50
|
* activeStep={2}
|
31
|
-
* steps={['
|
51
|
+
* steps={['Where', 'When', 'How']}
|
32
52
|
* />
|
33
53
|
* ```
|
34
54
|
**/
|
35
55
|
export const Stepper = ({
|
36
56
|
onClick = () => {},
|
57
|
+
onBackButtonClick,
|
37
58
|
steps,
|
38
59
|
activeStep: activeStepAsStringOrNumber,
|
39
60
|
title,
|
61
|
+
heading,
|
62
|
+
headingLevel,
|
40
63
|
variant,
|
64
|
+
isDisabled,
|
41
65
|
}: StepperProps) => {
|
42
66
|
const style = useMultiStyleConfig("Stepper", { variant });
|
43
67
|
const numberOfSteps = steps.length;
|
44
68
|
const activeStep = Number(activeStepAsStringOrNumber);
|
45
69
|
const { t } = useTranslation();
|
70
|
+
const hideBackButtonOnFirstStep = activeStep === 1 && !onBackButtonClick;
|
71
|
+
const shownHeading = heading || title;
|
46
72
|
return (
|
47
|
-
<Box
|
73
|
+
<Box sx={style.root}>
|
48
74
|
<StepperProvider
|
49
75
|
onClick={onClick}
|
50
76
|
activeStep={activeStep}
|
51
77
|
variant={variant}
|
52
78
|
numberOfSteps={numberOfSteps}
|
53
79
|
>
|
54
|
-
<Box
|
55
|
-
<Box
|
56
|
-
<
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
80
|
+
<Box sx={style.container}>
|
81
|
+
<Box sx={style.innerContainer}>
|
82
|
+
<Flex
|
83
|
+
justifyContent="space-between"
|
84
|
+
alignItems="center"
|
85
|
+
gap={2}
|
86
|
+
flex={1}
|
87
|
+
>
|
88
|
+
<IconButton
|
89
|
+
aria-label={t(texts.back)}
|
90
|
+
icon={<ArrowLeftFill24Icon />}
|
91
|
+
variant="ghost"
|
92
|
+
size="sm"
|
93
|
+
visibility={hideBackButtonOnFirstStep ? "hidden" : "visible"}
|
94
|
+
onClick={() => {
|
95
|
+
if (onBackButtonClick) {
|
96
|
+
onBackButtonClick(activeStep === 1);
|
97
|
+
}
|
98
|
+
onClick(activeStep - 1);
|
99
|
+
}}
|
100
|
+
/>
|
101
|
+
{shownHeading && (
|
102
|
+
<Text flex={1} variant="sm" as={headingLevel} sx={style.title}>
|
103
|
+
{shownHeading}
|
104
|
+
</Text>
|
66
105
|
)}
|
67
|
-
|
68
|
-
|
69
|
-
triggerElement={
|
70
|
-
<Box as="button" __css={style.stepCounter}>
|
71
|
-
{t(texts.stepsOf(activeStep, numberOfSteps))}
|
72
|
-
</Box>
|
73
|
-
}
|
74
|
-
borderRadius="xs"
|
75
|
-
>
|
76
|
-
{steps.map((step, index) => (
|
77
|
-
<StepperStep
|
78
|
-
key={step}
|
79
|
-
stepNumber={index + 1}
|
80
|
-
variant={variant}
|
81
|
-
>
|
82
|
-
{step}
|
83
|
-
</StepperStep>
|
84
|
-
))}
|
85
|
-
</SimplePopover>
|
86
|
-
</HStack>
|
87
|
-
{title && (
|
88
|
-
<Box as="h3" __css={style.title}>
|
89
|
-
{title}
|
106
|
+
<Box sx={style.stepCounter}>
|
107
|
+
{t(texts.stepsOf(activeStep, numberOfSteps))}
|
90
108
|
</Box>
|
91
|
-
|
109
|
+
</Flex>
|
92
110
|
</Box>
|
93
|
-
<Flex justifyContent="center" display={["none", "flex"]}>
|
111
|
+
<Flex justifyContent="center" display={["none", null, "flex"]}>
|
94
112
|
{steps.map((step, index) => (
|
95
|
-
<StepperStep
|
113
|
+
<StepperStep
|
114
|
+
key={index}
|
115
|
+
stepNumber={index + 1}
|
116
|
+
variant={variant}
|
117
|
+
aria-current={index + 1 === activeStep ? "step" : undefined}
|
118
|
+
isDisabled={isDisabled}
|
119
|
+
>
|
96
120
|
{step}
|
97
121
|
</StepperStep>
|
98
122
|
))}
|
@@ -105,10 +129,10 @@ export const Stepper = ({
|
|
105
129
|
|
106
130
|
const texts = createTexts({
|
107
131
|
stepsOf: (activeStep, numberOfSteps) => ({
|
108
|
-
nb: `Steg ${activeStep}
|
109
|
-
nn: `Steg ${activeStep}
|
110
|
-
sv: `Steg ${activeStep}
|
111
|
-
en: `Step ${activeStep}
|
132
|
+
nb: `Steg ${activeStep}/${numberOfSteps}`,
|
133
|
+
nn: `Steg ${activeStep}/${numberOfSteps}`,
|
134
|
+
sv: `Steg ${activeStep}/${numberOfSteps}`,
|
135
|
+
en: `Step ${activeStep}/${numberOfSteps}`,
|
112
136
|
}),
|
113
137
|
back: {
|
114
138
|
nb: "Tilbake",
|
@@ -1,82 +1,73 @@
|
|
1
|
-
import { useMultiStyleConfig } from "@chakra-ui/react";
|
1
|
+
import { useColorModeValue, useMultiStyleConfig } from "@chakra-ui/react";
|
2
2
|
import { DropdownRightFill18Icon } from "@vygruppen/spor-icon-react";
|
3
3
|
import React from "react";
|
4
|
-
import { Box, Button } from "..";
|
4
|
+
import { Box, Button, Text } from "..";
|
5
5
|
import { useStepper } from "./StepperContext";
|
6
6
|
|
7
7
|
type StepperStepProps = {
|
8
8
|
children: React.ReactNode;
|
9
9
|
stepNumber: number;
|
10
10
|
variant: "base" | "accent";
|
11
|
+
isDisabled?: boolean;
|
11
12
|
};
|
12
13
|
export const StepperStep = ({
|
13
14
|
children,
|
14
15
|
stepNumber,
|
15
16
|
variant,
|
17
|
+
isDisabled: isDisabledOverride,
|
16
18
|
}: StepperStepProps) => {
|
17
19
|
const { activeStep, onClick } = useStepper();
|
18
|
-
const state = getState(stepNumber
|
20
|
+
const state = getState(stepNumber, activeStep);
|
19
21
|
const style = useMultiStyleConfig("Stepper", {
|
20
22
|
state,
|
21
23
|
variant,
|
22
24
|
});
|
25
|
+
const disabledTextColor = useColorModeValue(
|
26
|
+
"blackAlpha.400",
|
27
|
+
"whiteAlpha.400",
|
28
|
+
);
|
29
|
+
const iconColor = useColorModeValue("blackAlpha.200", "whiteAlpha.200");
|
23
30
|
|
24
|
-
const
|
31
|
+
const isDisabled =
|
32
|
+
(state !== "active" && isDisabledOverride) || state === "disabled";
|
25
33
|
|
26
34
|
return (
|
27
|
-
<Box
|
35
|
+
<Box sx={style.stepContainer}>
|
28
36
|
{stepNumber > 1 && (
|
29
|
-
<DropdownRightFill18Icon
|
37
|
+
<DropdownRightFill18Icon
|
38
|
+
marginX={5}
|
39
|
+
display={["none", null, "block"]}
|
40
|
+
color={iconColor}
|
41
|
+
/>
|
42
|
+
)}
|
43
|
+
{isDisabled ? (
|
44
|
+
<Text
|
45
|
+
variant="xs"
|
46
|
+
fontSize="16px"
|
47
|
+
color={disabledTextColor}
|
48
|
+
cursor="default"
|
49
|
+
paddingX={2}
|
50
|
+
>
|
51
|
+
{children}
|
52
|
+
</Text>
|
53
|
+
) : (
|
54
|
+
<Button
|
55
|
+
size="xs"
|
56
|
+
variant={state === "active" ? "primary" : "ghost"}
|
57
|
+
onClick={
|
58
|
+
state === "completed" ? () => onClick(stepNumber) : undefined
|
59
|
+
}
|
60
|
+
pointerEvents={state === "active" ? "none" : "auto"}
|
61
|
+
tabIndex={state === "active" ? -1 : undefined}
|
62
|
+
sx={style.stepButton}
|
63
|
+
>
|
64
|
+
{children}
|
65
|
+
</Button>
|
30
66
|
)}
|
31
|
-
|
32
|
-
<Button
|
33
|
-
size={"xs"}
|
34
|
-
variant={
|
35
|
-
state === "active"
|
36
|
-
? "primary"
|
37
|
-
: state === "completed"
|
38
|
-
? "tertiary"
|
39
|
-
: "ghost"
|
40
|
-
}
|
41
|
-
{...adjustedProps}
|
42
|
-
onClick={() => onClick(stepNumber)}
|
43
|
-
>
|
44
|
-
{children}
|
45
|
-
</Button>
|
46
67
|
</Box>
|
47
68
|
);
|
48
69
|
};
|
49
70
|
|
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
71
|
const getState = (stepNumber: number, activeStep: number) => {
|
81
72
|
if (stepNumber < activeStep) {
|
82
73
|
return "completed";
|
@@ -24,12 +24,12 @@ const config = defineStyleConfig({
|
|
24
24
|
_disabled: {
|
25
25
|
cursor: "not-allowed",
|
26
26
|
boxShadow: "none",
|
27
|
-
backgroundColor: "
|
28
|
-
color: "
|
27
|
+
backgroundColor: mode("blackAlpha.100", "whiteAlpha.100")(props),
|
28
|
+
color: mode("blackAlpha.400", "whiteAlpha.400")(props),
|
29
29
|
},
|
30
30
|
_hover: {
|
31
31
|
_disabled: {
|
32
|
-
background: "
|
32
|
+
background: mode("blackAlpha.100", "whiteAlpha.100")(props),
|
33
33
|
},
|
34
34
|
},
|
35
35
|
}),
|
@@ -23,12 +23,16 @@ const config = helpers.defineMultiStyleConfig({
|
|
23
23
|
position: "fixed",
|
24
24
|
...getPositionProps(props),
|
25
25
|
_disabled: {
|
26
|
-
backgroundColor: "whiteAlpha.
|
27
|
-
color: "
|
26
|
+
backgroundColor: mode("blackAlpha.100", "whiteAlpha.100")(props),
|
27
|
+
color: mode("blackAlpha.400", "whiteAlpha.400")(props),
|
28
28
|
},
|
29
29
|
...focusVisibleStyles(props),
|
30
30
|
_hover: {
|
31
31
|
backgroundColor: "seaMist",
|
32
|
+
_disabled: {
|
33
|
+
backgroundColor: mode("blackAlpha.100", "whiteAlpha.100")(props),
|
34
|
+
color: mode("blackAlpha.400", "whiteAlpha.400")(props),
|
35
|
+
},
|
32
36
|
},
|
33
37
|
zIndex: "sticky",
|
34
38
|
},
|
@@ -5,7 +5,6 @@ const parts = anatomy("stepper").parts(
|
|
5
5
|
"root",
|
6
6
|
"container",
|
7
7
|
"innerContainer",
|
8
|
-
"backButton",
|
9
8
|
"title",
|
10
9
|
"stepCounter",
|
11
10
|
"stepContainer",
|
@@ -18,32 +17,27 @@ const parts = anatomy("stepper").parts(
|
|
18
17
|
const helpers = createMultiStyleConfigHelpers(parts.keys);
|
19
18
|
|
20
19
|
const config = helpers.defineMultiStyleConfig({
|
21
|
-
baseStyle:
|
20
|
+
baseStyle: {
|
22
21
|
root: {
|
23
22
|
display: "flex",
|
24
23
|
alignItems: "center",
|
25
|
-
justifyContent: ["space-between", "center"],
|
26
|
-
minHeight: ["48px", "60px"],
|
24
|
+
justifyContent: ["space-between", null, "center"],
|
25
|
+
minHeight: ["48px", null, "60px"],
|
27
26
|
overflowX: "auto",
|
28
27
|
width: "100%",
|
29
28
|
},
|
30
29
|
container: {
|
31
|
-
paddingX: [2,
|
30
|
+
paddingX: [2, null, null, 0],
|
32
31
|
maxWidth: "container.lg",
|
33
32
|
marginX: "auto",
|
34
33
|
width: "100%",
|
35
34
|
},
|
36
35
|
innerContainer: {
|
37
36
|
overflow: "hidden",
|
38
|
-
display: ["flex", "none"],
|
37
|
+
display: ["flex", null, "none"],
|
39
38
|
alignItems: "center",
|
40
39
|
justifyContent: "space-between",
|
41
|
-
|
42
|
-
backButton: {
|
43
|
-
borderRadius: "xs",
|
44
|
-
paddingX: 0,
|
45
|
-
width: "auto",
|
46
|
-
minWidth: "auto",
|
40
|
+
gap: 3,
|
47
41
|
},
|
48
42
|
title: {
|
49
43
|
overflow: "hidden",
|
@@ -51,8 +45,8 @@ const config = helpers.defineMultiStyleConfig({
|
|
51
45
|
WebkitLineClamp: 2,
|
52
46
|
display: "-webkit-box",
|
53
47
|
WebkitBoxOrient: "vertical",
|
54
|
-
|
55
|
-
|
48
|
+
textAlign: "center",
|
49
|
+
maxWidth: "80%",
|
56
50
|
},
|
57
51
|
stepContainer: {
|
58
52
|
display: "flex",
|
@@ -62,7 +56,7 @@ const config = helpers.defineMultiStyleConfig({
|
|
62
56
|
textStyle: "sm",
|
63
57
|
whiteSpace: "nowrap",
|
64
58
|
},
|
65
|
-
}
|
59
|
+
},
|
66
60
|
variants: {
|
67
61
|
base: () => ({
|
68
62
|
root: {
|
@@ -72,6 +66,26 @@ const config = helpers.defineMultiStyleConfig({
|
|
72
66
|
accent: (props) => ({
|
73
67
|
root: {
|
74
68
|
backgroundColor: mode("seaMist", "pine")(props),
|
69
|
+
color: mode("darkTeal", "seaMist")(props),
|
70
|
+
},
|
71
|
+
stepButton: {
|
72
|
+
color:
|
73
|
+
props.state === "disabled"
|
74
|
+
? mode("blackAlpha.400", "whiteAlpha.400")(props)
|
75
|
+
: props.state === "completed"
|
76
|
+
? mode("darkTeal", "white")(props)
|
77
|
+
: mode("white", "darkTeal")(props),
|
78
|
+
_hover: {
|
79
|
+
backgroundColor:
|
80
|
+
props.state === "disabled"
|
81
|
+
? "transparent"
|
82
|
+
: mode("coralGreen", "greenHaze")(props),
|
83
|
+
},
|
84
|
+
},
|
85
|
+
backButton: {
|
86
|
+
_hover: {
|
87
|
+
backgroundColor: mode("coralGreen", "greenHaze")(props),
|
88
|
+
},
|
75
89
|
},
|
76
90
|
}),
|
77
91
|
},
|