@vygruppen/spor-react 10.1.0 → 10.3.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 +9 -9
- package/CHANGELOG.md +16 -0
- package/dist/{CountryCodeSelect-FKWNR6SG.mjs → CountryCodeSelect-KCPHU7A7.mjs} +1 -1
- package/dist/{chunk-MLRF67YM.mjs → chunk-5HRYDWQ5.mjs} +94 -23
- package/dist/index.d.mts +50 -319
- package/dist/index.d.ts +50 -319
- package/dist/index.js +94 -22
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/input/Input.tsx +7 -1
- package/src/input/NumericStepper.tsx +72 -19
- package/src/modal/ModalHeader.tsx +1 -1
- package/src/theme/components/input.ts +32 -3
package/package.json
CHANGED
package/src/input/Input.tsx
CHANGED
@@ -10,7 +10,7 @@ import {
|
|
10
10
|
} from "@chakra-ui/react";
|
11
11
|
import React, { useId } from "react";
|
12
12
|
|
13
|
-
export type InputProps = Omit<ChakraInputProps, "
|
13
|
+
export type InputProps = Omit<ChakraInputProps, "size"> & {
|
14
14
|
/** The input's label */
|
15
15
|
label: string;
|
16
16
|
/** Icon that shows up to the left */
|
@@ -32,6 +32,12 @@ export type InputProps = Omit<ChakraInputProps, "variant" | "size"> & {
|
|
32
32
|
* ```tsx
|
33
33
|
* <Input label="E-mail" leftIcon={<EmailOutline24Icon />} />
|
34
34
|
* ```
|
35
|
+
*
|
36
|
+
* Input has two variants base, and floating.
|
37
|
+
*
|
38
|
+
* ```tsx
|
39
|
+
* <Input label="E-mail" leftIcon={<EmailOutline24Icon />} variant="floating" />
|
40
|
+
* ```
|
35
41
|
*/
|
36
42
|
export const Input = forwardRef<InputProps, "input">(
|
37
43
|
({ label, leftIcon, rightIcon, id, size, ...props }, ref) => {
|
@@ -4,7 +4,7 @@ import {
|
|
4
4
|
useFormControl,
|
5
5
|
useMultiStyleConfig,
|
6
6
|
} from "@chakra-ui/react";
|
7
|
-
import React from "react";
|
7
|
+
import React, { useRef } from "react";
|
8
8
|
import {
|
9
9
|
Box,
|
10
10
|
BoxProps,
|
@@ -35,6 +35,8 @@ type NumericStepperProps = {
|
|
35
35
|
stepSize?: number;
|
36
36
|
/** Whether to show the number input when value is zero */
|
37
37
|
showZero?: boolean;
|
38
|
+
/** Name added to the aria-label of subtract and add buttons. */
|
39
|
+
ariaLabelContext?: { singular: string; plural: string };
|
38
40
|
} & Omit<BoxProps, "onChange">;
|
39
41
|
/** A simple stepper component for integer values
|
40
42
|
*
|
@@ -72,8 +74,10 @@ export function NumericStepper({
|
|
72
74
|
withInput = true,
|
73
75
|
stepSize = 1,
|
74
76
|
showZero = false,
|
77
|
+
ariaLabelContext = { singular: "", plural: "" },
|
75
78
|
...boxProps
|
76
79
|
}: NumericStepperProps) {
|
80
|
+
const addButtonRef = useRef<HTMLButtonElement>(null);
|
77
81
|
const { t } = useTranslation();
|
78
82
|
const styles = useMultiStyleConfig("NumericStepper", {});
|
79
83
|
const [value, onChange] = useControllableState<number>({
|
@@ -84,12 +88,26 @@ export function NumericStepper({
|
|
84
88
|
const formControlProps = useFormControl({ id: idProp, isDisabled });
|
85
89
|
const clampedStepSize = Math.max(Math.min(stepSize, 10), 1);
|
86
90
|
|
91
|
+
const focusOnAddButton = () => {
|
92
|
+
addButtonRef.current?.focus();
|
93
|
+
};
|
94
|
+
|
87
95
|
return (
|
88
96
|
<Flex __css={styles.container} {...boxProps}>
|
89
97
|
<VerySmallButton
|
90
98
|
icon={<SubtractIcon stepLabel={clampedStepSize} />}
|
91
|
-
aria-label={t(
|
92
|
-
|
99
|
+
aria-label={t(
|
100
|
+
texts.decrementButtonAriaLabel(
|
101
|
+
clampedStepSize,
|
102
|
+
stepSize == 1 ? ariaLabelContext.singular : ariaLabelContext.plural,
|
103
|
+
),
|
104
|
+
)}
|
105
|
+
onClick={() => {
|
106
|
+
onChange(Math.max(value - clampedStepSize, minValue));
|
107
|
+
if (Math.max(value - clampedStepSize, minValue) <= minValue) {
|
108
|
+
focusOnAddButton();
|
109
|
+
}
|
110
|
+
}}
|
93
111
|
visibility={value <= minValue ? "hidden" : "visible"}
|
94
112
|
isDisabled={formControlProps.disabled}
|
95
113
|
id={value <= minValue ? undefined : formControlProps.id}
|
@@ -107,27 +125,48 @@ export function NumericStepper({
|
|
107
125
|
width={`${Math.max(value.toString().length + 1, 3)}ch`}
|
108
126
|
visibility={!showZero && value === 0 ? "hidden" : "visible"}
|
109
127
|
aria-live="assertive"
|
110
|
-
aria-label={
|
128
|
+
aria-label={
|
129
|
+
ariaLabelContext.plural !== ""
|
130
|
+
? t(texts.currentNumberAriaLabel(ariaLabelContext.plural))
|
131
|
+
: ""
|
132
|
+
}
|
111
133
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
112
134
|
const numericInput = Number(e.target.value);
|
113
135
|
if (Number.isNaN(numericInput)) {
|
114
136
|
return;
|
115
137
|
}
|
116
138
|
onChange(Math.max(Math.min(numericInput, maxValue), minValue));
|
139
|
+
if (
|
140
|
+
!showZero &&
|
141
|
+
Math.max(Math.min(numericInput, maxValue), minValue) === 0
|
142
|
+
) {
|
143
|
+
focusOnAddButton();
|
144
|
+
}
|
117
145
|
}}
|
118
146
|
/>
|
119
147
|
) : (
|
120
148
|
<chakra.text
|
121
149
|
sx={styles.text}
|
122
150
|
visibility={!showZero && value === 0 ? "hidden" : "visible"}
|
123
|
-
aria-
|
151
|
+
aria-live="assertive"
|
152
|
+
aria-label={
|
153
|
+
ariaLabelContext.plural !== ""
|
154
|
+
? t(texts.currentNumberAriaLabel(ariaLabelContext.plural))
|
155
|
+
: ""
|
156
|
+
}
|
124
157
|
>
|
125
158
|
{value}
|
126
159
|
</chakra.text>
|
127
160
|
)}
|
128
161
|
<VerySmallButton
|
162
|
+
ref={addButtonRef}
|
129
163
|
icon={<AddIcon stepLabel={clampedStepSize} />}
|
130
|
-
aria-label={t(
|
164
|
+
aria-label={t(
|
165
|
+
texts.incrementButtonAriaLabel(
|
166
|
+
clampedStepSize,
|
167
|
+
stepSize == 1 ? ariaLabelContext.singular : ariaLabelContext.plural,
|
168
|
+
),
|
169
|
+
)}
|
131
170
|
onClick={() => onChange(Math.min(value + clampedStepSize, maxValue))}
|
132
171
|
visibility={value >= maxValue ? "hidden" : "visible"}
|
133
172
|
isDisabled={formControlProps.disabled}
|
@@ -152,12 +191,18 @@ type VerySmallButtonProps = {
|
|
152
191
|
id?: string;
|
153
192
|
};
|
154
193
|
/** Internal override for extra small icon buttons */
|
155
|
-
const VerySmallButton = (props: VerySmallButtonProps) => {
|
194
|
+
const VerySmallButton = React.forwardRef((props: VerySmallButtonProps, ref) => {
|
156
195
|
const styles = useMultiStyleConfig("NumericStepper", {});
|
157
196
|
return (
|
158
|
-
<IconButton
|
197
|
+
<IconButton
|
198
|
+
variant="primary"
|
199
|
+
size="xs"
|
200
|
+
sx={styles.button}
|
201
|
+
ref={ref}
|
202
|
+
{...props}
|
203
|
+
/>
|
159
204
|
);
|
160
|
-
};
|
205
|
+
});
|
161
206
|
|
162
207
|
type IconPropTypes = BoxProps & { stepLabel: number };
|
163
208
|
|
@@ -221,20 +266,28 @@ const AddIcon = ({ stepLabel, ...props }: IconPropTypes) => (
|
|
221
266
|
);
|
222
267
|
|
223
268
|
const texts = createTexts({
|
224
|
-
|
269
|
+
currentNumberAriaLabel(ariaContext) {
|
270
|
+
return {
|
271
|
+
nb: `Valgt antall ${ariaContext}`,
|
272
|
+
en: `Chosen number of ${ariaContext}`,
|
273
|
+
nn: `Valgt antall ${ariaContext}`,
|
274
|
+
sv: `Valgt antall ${ariaContext}`,
|
275
|
+
};
|
276
|
+
},
|
277
|
+
decrementButtonAriaLabel(stepSize, ariaContext) {
|
225
278
|
return {
|
226
|
-
nb: `Trekk fra ${stepSize}`,
|
227
|
-
en: `Subtract ${stepSize}`,
|
228
|
-
nn: `Trekk frå ${stepSize}`,
|
229
|
-
sv: `Subtrahera ${stepSize}`,
|
279
|
+
nb: `Trekk fra ${stepSize} ${ariaContext}`,
|
280
|
+
en: `Subtract ${stepSize} ${ariaContext}`,
|
281
|
+
nn: `Trekk frå ${stepSize} ${ariaContext}`,
|
282
|
+
sv: `Subtrahera ${stepSize} ${ariaContext}`,
|
230
283
|
};
|
231
284
|
},
|
232
|
-
incrementButtonAriaLabel(stepSize) {
|
285
|
+
incrementButtonAriaLabel(stepSize, ariaContext) {
|
233
286
|
return {
|
234
|
-
nb: `Legg til ${stepSize}`,
|
235
|
-
en: `Add ${stepSize}`,
|
236
|
-
nn: `Legg til ${stepSize}`,
|
237
|
-
sv: `Lägg till ${stepSize}`,
|
287
|
+
nb: `Legg til ${stepSize} ${ariaContext}`,
|
288
|
+
en: `Add ${stepSize} ${ariaContext}`,
|
289
|
+
nn: `Legg til ${stepSize} ${ariaContext}`,
|
290
|
+
sv: `Lägg till ${stepSize} ${ariaContext}`,
|
238
291
|
};
|
239
292
|
},
|
240
293
|
});
|
@@ -26,6 +26,6 @@ export const ModalHeader = forwardRef<ModalHeaderProps, "header">(
|
|
26
26
|
? "center"
|
27
27
|
: ("left" as ChakraModalHeaderProps["textAlign"]),
|
28
28
|
};
|
29
|
-
return <ChakraModalHeader {...props} ref={ref} {...styles} />;
|
29
|
+
return <ChakraModalHeader as={"h1"} {...props} ref={ref} {...styles} />;
|
30
30
|
},
|
31
31
|
);
|
@@ -3,6 +3,7 @@ import { createMultiStyleConfigHelpers } from "@chakra-ui/react";
|
|
3
3
|
import { baseBackground, baseBorder, baseText } from "../utils/base-utils";
|
4
4
|
import { focusVisibleStyles } from "../utils/focus-utils";
|
5
5
|
import { surface } from "../utils/surface-utils";
|
6
|
+
import { floatingBackground, floatingBorder } from "../utils/floating-utils";
|
6
7
|
|
7
8
|
const helpers = createMultiStyleConfigHelpers(parts.keys);
|
8
9
|
|
@@ -20,9 +21,6 @@ const config = helpers.defineMultiStyleConfig({
|
|
20
21
|
paddingX: 3,
|
21
22
|
height: 8,
|
22
23
|
fontSize: "mobile.md",
|
23
|
-
...baseBackground("default", props),
|
24
|
-
|
25
|
-
...baseBorder("default", props),
|
26
24
|
_hover: {
|
27
25
|
...baseBorder("hover", props),
|
28
26
|
},
|
@@ -73,6 +71,37 @@ const config = helpers.defineMultiStyleConfig({
|
|
73
71
|
},
|
74
72
|
},
|
75
73
|
}),
|
74
|
+
variants: {
|
75
|
+
base: (props) => ({
|
76
|
+
field: {
|
77
|
+
...baseBackground("default", props),
|
78
|
+
...baseBorder("default", props),
|
79
|
+
},
|
80
|
+
}),
|
81
|
+
floating: (props) => ({
|
82
|
+
field: {
|
83
|
+
boxShadow: "sm",
|
84
|
+
...floatingBackground("default", props),
|
85
|
+
...floatingBorder("default", props),
|
86
|
+
|
87
|
+
_hover: {
|
88
|
+
...floatingBorder("hover", props),
|
89
|
+
...floatingBackground("hover", props),
|
90
|
+
},
|
91
|
+
_active: {
|
92
|
+
...floatingBorder("active", props),
|
93
|
+
...floatingBackground("active", props),
|
94
|
+
},
|
95
|
+
_selected: {
|
96
|
+
...floatingBorder("selected", props),
|
97
|
+
...floatingBackground("selected", props),
|
98
|
+
},
|
99
|
+
},
|
100
|
+
}),
|
101
|
+
},
|
102
|
+
defaultProps: {
|
103
|
+
variant: "base",
|
104
|
+
},
|
76
105
|
});
|
77
106
|
|
78
107
|
export default config;
|