@vygruppen/spor-react 12.10.1 → 12.10.3
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/.turbo/turbo-postinstall.log +1 -1
- package/CHANGELOG.md +21 -29
- package/dist/index.cjs +157 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +157 -132
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/alert/ServiceAlert.tsx +2 -2
- package/src/datepicker/DateField.tsx +6 -2
- package/src/datepicker/TimeField.tsx +9 -6
- package/src/datepicker/TimePicker.tsx +3 -0
- package/src/dialog/Drawer.tsx +6 -4
- package/src/dialog/types.ts +1 -0
- package/src/input/ListBox.tsx +16 -3
- package/src/input/PhoneNumberInput.tsx +31 -40
- package/src/input/Switch.tsx +1 -1
- package/src/layout/RadioCard.tsx +2 -6
- package/src/link/TextLink.tsx +18 -2
- package/src/theme/slot-recipes/alert-service.ts +2 -2
- package/src/theme/slot-recipes/drawer.ts +6 -6
- package/src/theme/slot-recipes/select.ts +8 -17
- package/src/theme/slot-recipes/switch.ts +1 -1
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vygruppen/spor-react",
|
3
3
|
"type": "module",
|
4
|
-
"version": "12.10.
|
4
|
+
"version": "12.10.3",
|
5
5
|
"exports": {
|
6
6
|
".": {
|
7
7
|
"types": "./dist/index.d.ts",
|
@@ -68,8 +68,8 @@
|
|
68
68
|
"vitest": "^0.26.3",
|
69
69
|
"vitest-axe": "^0.1.0",
|
70
70
|
"vitest-canvas-mock": "^0.2.2",
|
71
|
-
"@vygruppen/
|
72
|
-
"@vygruppen/
|
71
|
+
"@vygruppen/tsconfig": "0.1.1",
|
72
|
+
"@vygruppen/eslint-config": "1.2.3"
|
73
73
|
},
|
74
74
|
"peerDependencies": {
|
75
75
|
"react": ">=18.0.0 <19.0.0",
|
@@ -128,10 +128,10 @@ export const ServiceAlert = forwardRef<HTMLDivElement, ServiceAlertProps>(
|
|
128
128
|
</Accordion.ItemTrigger>
|
129
129
|
|
130
130
|
<Accordion.ItemContent asChild>
|
131
|
-
<Stack flexDirection="row"
|
131
|
+
<Stack flexDirection="row" width="100%">
|
132
132
|
<Accordion.ItemBody
|
133
133
|
as={Stack}
|
134
|
-
|
134
|
+
width={contentWidth}
|
135
135
|
css={styles.itemBody}
|
136
136
|
>
|
137
137
|
{children}
|
@@ -1,11 +1,13 @@
|
|
1
1
|
"use client";
|
2
|
-
import { Box, Flex, useSlotRecipe } from "@chakra-ui/react";
|
2
|
+
import { Box, Field, Flex, useSlotRecipe } from "@chakra-ui/react";
|
3
3
|
import { DateValue, GregorianCalendar } from "@internationalized/date";
|
4
4
|
import { DOMAttributes, FocusableElement } from "@react-types/shared";
|
5
5
|
import React, { forwardRef, PropsWithChildren, RefObject, useRef } from "react";
|
6
6
|
import { AriaDateFieldProps, useDateField } from "react-aria";
|
7
7
|
import { DateSegment, useDateFieldState } from "react-stately";
|
8
8
|
|
9
|
+
import { Label } from "@/input/Label";
|
10
|
+
|
9
11
|
import { createTexts, useTranslation } from "../i18n";
|
10
12
|
import { DatePickerVariantProps } from "./DatePicker";
|
11
13
|
import { DateTimeSegment } from "./DateTimeSegment";
|
@@ -61,7 +63,9 @@ export const DateField = forwardRef<HTMLDivElement, DateFieldProps>(
|
|
61
63
|
position="absolute"
|
62
64
|
paddingTop="2px"
|
63
65
|
>
|
64
|
-
<
|
66
|
+
<Label padding="0" fontSize="2xs" {...props.labelProps}>
|
67
|
+
{props.label} <Field.RequiredIndicator />
|
68
|
+
</Label>
|
65
69
|
</Box>
|
66
70
|
)}
|
67
71
|
<Flex {...fieldProps} ref={ref} paddingTop="3" paddingBottom="0.5">
|
@@ -30,20 +30,23 @@ export const TimeField = ({ state, ...props }: TimeFieldProps) => {
|
|
30
30
|
style={{
|
31
31
|
marginBottom: 0,
|
32
32
|
fontSize: "mobile.xs",
|
33
|
+
top: 0,
|
33
34
|
cursor: "text",
|
35
|
+
left: "50%",
|
36
|
+
transform: "translateX(-50%)",
|
34
37
|
position: "absolute",
|
35
38
|
paddingTop: "2px",
|
39
|
+
whiteSpace: "nowrap",
|
40
|
+
overflow: "hidden",
|
41
|
+
textOverflow: "ellipsis",
|
42
|
+
maxWidth: "80%",
|
36
43
|
}}
|
37
44
|
>
|
38
45
|
{props.label}
|
39
46
|
</label>
|
40
47
|
<Flex {...fieldProps} ref={ref} paddingTop="3" paddingBottom="0.5">
|
41
|
-
{state.segments.map((segment: DateSegment) => (
|
42
|
-
<DateTimeSegment
|
43
|
-
key={JSON.stringify(segment)}
|
44
|
-
segment={segment}
|
45
|
-
state={state}
|
46
|
-
/>
|
48
|
+
{state.segments.map((segment: DateSegment, index) => (
|
49
|
+
<DateTimeSegment key={index} segment={segment} state={state} />
|
47
50
|
))}
|
48
51
|
</Flex>
|
49
52
|
<input
|
@@ -146,6 +146,7 @@ export const TimePicker = ({
|
|
146
146
|
aria-disabled={isDisabled}
|
147
147
|
aria-live="assertive"
|
148
148
|
aria-label={ariaLabel}
|
149
|
+
position="relative"
|
149
150
|
{...boxProps}
|
150
151
|
>
|
151
152
|
<IconButton
|
@@ -158,6 +159,7 @@ export const TimePicker = ({
|
|
158
159
|
onClick={handleBackwardsClick}
|
159
160
|
disabled={isDisabled}
|
160
161
|
style={isDisabled ? { backgroundColor: "transparent" } : {}}
|
162
|
+
zIndex={1}
|
161
163
|
/>
|
162
164
|
<TimeField label={label} state={state} name={name} />
|
163
165
|
<IconButton
|
@@ -170,6 +172,7 @@ export const TimePicker = ({
|
|
170
172
|
onClick={handleForwardClick}
|
171
173
|
disabled={isDisabled}
|
172
174
|
style={isDisabled ? { backgroundColor: "transparent" } : {}}
|
175
|
+
zIndex={1}
|
173
176
|
/>
|
174
177
|
</StyledField>
|
175
178
|
</Field>
|
package/src/dialog/Drawer.tsx
CHANGED
@@ -145,7 +145,7 @@ export const DrawerFullScreenHeader = forwardRef<
|
|
145
145
|
HTMLDivElement,
|
146
146
|
DrawerFullScreenHeaderProps
|
147
147
|
>((props, ref) => {
|
148
|
-
const { backTrigger = true, title } = props;
|
148
|
+
const { backTrigger = true, closeTrigger = true, title } = props;
|
149
149
|
return (
|
150
150
|
<ChakraDrawer.Header {...props} ref={ref} asChild>
|
151
151
|
<Grid templateColumns="1fr auto 1fr" height="auto" paddingX="8">
|
@@ -155,9 +155,11 @@ export const DrawerFullScreenHeader = forwardRef<
|
|
155
155
|
<GridItem width="full" alignSelf="end" asChild>
|
156
156
|
{title && <DrawerTitle>{title}</DrawerTitle>}
|
157
157
|
</GridItem>
|
158
|
-
|
159
|
-
<
|
160
|
-
|
158
|
+
{closeTrigger && (
|
159
|
+
<GridItem width="full" alignSelf="end">
|
160
|
+
<DrawerCloseTrigger justifySelf="end" top="0" />
|
161
|
+
</GridItem>
|
162
|
+
)}
|
161
163
|
</Grid>
|
162
164
|
</ChakraDrawer.Header>
|
163
165
|
);
|
package/src/dialog/types.ts
CHANGED
package/src/input/ListBox.tsx
CHANGED
@@ -90,6 +90,7 @@ export const ListBox = (props: ListBoxProps<object>) => {
|
|
90
90
|
css={styles.root}
|
91
91
|
aria-busy={loading}
|
92
92
|
maxWidth={maxWidth}
|
93
|
+
padding="1"
|
93
94
|
>
|
94
95
|
{state.collection.size === 0 && props.emptyContent}
|
95
96
|
{[...state.collection].map((item) =>
|
@@ -181,7 +182,14 @@ function Option({ item, state }: OptionProps) {
|
|
181
182
|
}, []);
|
182
183
|
return (
|
183
184
|
<OptionContext.Provider value={{ labelProps, descriptionProps }}>
|
184
|
-
<ListItem
|
185
|
+
<ListItem
|
186
|
+
{...optionProps}
|
187
|
+
{...dataFields}
|
188
|
+
ref={ref}
|
189
|
+
css={styles.item}
|
190
|
+
padding="1"
|
191
|
+
marginX="0"
|
192
|
+
>
|
185
193
|
{item.rendered}
|
186
194
|
</ListItem>
|
187
195
|
</OptionContext.Provider>
|
@@ -217,14 +225,19 @@ function ListBoxSection({ section, state }: ListBoxSectionProps) {
|
|
217
225
|
|
218
226
|
return (
|
219
227
|
<List>
|
220
|
-
<ListItem
|
228
|
+
<ListItem
|
229
|
+
{...itemProps}
|
230
|
+
listStyleType={"none"}
|
231
|
+
marginLeft="0"
|
232
|
+
paddingX="1"
|
233
|
+
>
|
221
234
|
{section.rendered && (
|
222
235
|
<Box
|
223
236
|
fontSize="mobile.xs"
|
224
237
|
color={titleColor}
|
225
|
-
paddingX={3}
|
226
238
|
paddingTop={1}
|
227
239
|
marginTop={isFirstSection ? 0 : 2}
|
240
|
+
marginLeft="1"
|
228
241
|
textTransform="uppercase"
|
229
242
|
fontWeight="bold"
|
230
243
|
{...headingProps}
|
@@ -80,46 +80,37 @@ export const PhoneNumberInput = forwardRef<
|
|
80
80
|
};
|
81
81
|
|
82
82
|
return (
|
83
|
-
<AttachedInputs
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
{
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
countryCode: value.countryCode,
|
115
|
-
nationalNumber: strippedValue,
|
116
|
-
});
|
117
|
-
}}
|
118
|
-
variant={variant}
|
119
|
-
data-state="on"
|
120
|
-
label={label}
|
121
|
-
/>
|
122
|
-
</>
|
83
|
+
<AttachedInputs display="grid" gridTemplateColumns="1fr 10fr">
|
84
|
+
<CountryCodeSelect
|
85
|
+
value={[value.countryCode]}
|
86
|
+
onValueChange={handleCountryCodeChange}
|
87
|
+
height="100%"
|
88
|
+
width="6.25rem"
|
89
|
+
variant={variant}
|
90
|
+
allowedCountryCodes={allowedCountryCodes}
|
91
|
+
data-state="on"
|
92
|
+
invalid={invalid}
|
93
|
+
/>
|
94
|
+
<Input
|
95
|
+
ref={ref}
|
96
|
+
type="tel"
|
97
|
+
{...props}
|
98
|
+
value={value.nationalNumber}
|
99
|
+
invalid={invalid}
|
100
|
+
errorText={errorText}
|
101
|
+
onChange={(e) => {
|
102
|
+
const target = e.target as HTMLInputElement;
|
103
|
+
// Removes everything but numbers, spaces and dashes
|
104
|
+
const strippedValue = target.value.replaceAll(/[^\d\s-]/g, "");
|
105
|
+
onChange({
|
106
|
+
countryCode: value.countryCode,
|
107
|
+
nationalNumber: strippedValue,
|
108
|
+
});
|
109
|
+
}}
|
110
|
+
variant={variant}
|
111
|
+
data-state="on"
|
112
|
+
label={label}
|
113
|
+
/>
|
123
114
|
</AttachedInputs>
|
124
115
|
);
|
125
116
|
});
|
package/src/input/Switch.tsx
CHANGED
@@ -74,11 +74,11 @@ export const Switch = forwardRef<HTMLInputElement, SwitchProps>(
|
|
74
74
|
checked={props.checked}
|
75
75
|
css={styles.root}
|
76
76
|
>
|
77
|
-
<ChakraSwitch.Label>{label}</ChakraSwitch.Label>
|
78
77
|
<ChakraSwitch.HiddenInput ref={ref} />
|
79
78
|
<ChakraSwitch.Control css={styles.control}>
|
80
79
|
<ChakraSwitch.Thumb />
|
81
80
|
</ChakraSwitch.Control>
|
81
|
+
<ChakraSwitch.Label>{label}</ChakraSwitch.Label>
|
82
82
|
</ChakraSwitch.Root>
|
83
83
|
</Field>
|
84
84
|
);
|
package/src/layout/RadioCard.tsx
CHANGED
@@ -40,15 +40,11 @@ type RadioCardItemProps = Exclude<
|
|
40
40
|
|
41
41
|
export const RadioCard = forwardRef<HTMLInputElement, RadioCardItemProps>(
|
42
42
|
(props, ref) => {
|
43
|
-
const { inputProps, children
|
43
|
+
const { inputProps, children } = props;
|
44
44
|
|
45
45
|
return (
|
46
46
|
<ChakraRadioCard.Item {...props}>
|
47
|
-
<ChakraRadioCard.ItemHiddenInput
|
48
|
-
aria-label={ariaLabel ?? value}
|
49
|
-
ref={ref}
|
50
|
-
{...inputProps}
|
51
|
-
/>
|
47
|
+
<ChakraRadioCard.ItemHiddenInput ref={ref} {...inputProps} />
|
52
48
|
|
53
49
|
<ChakraRadioCard.ItemControl>{children}</ChakraRadioCard.ItemControl>
|
54
50
|
</ChakraRadioCard.Item>
|
package/src/link/TextLink.tsx
CHANGED
@@ -59,7 +59,15 @@ export const TextLink = forwardRef<HTMLAnchorElement, LinkProps>(
|
|
59
59
|
// If asChild is true, we need to clone the children and add the external icon
|
60
60
|
if (props.asChild && isValidElement(children)) {
|
61
61
|
return (
|
62
|
-
<ChakraLink
|
62
|
+
<ChakraLink
|
63
|
+
href={href}
|
64
|
+
{...props}
|
65
|
+
ref={ref}
|
66
|
+
{...(isExternal && {
|
67
|
+
target: "_blank",
|
68
|
+
rel: "noopener noreferrer",
|
69
|
+
})}
|
70
|
+
>
|
63
71
|
{cloneElement(children as React.ReactElement, {
|
64
72
|
...children.props,
|
65
73
|
children: (
|
@@ -76,7 +84,15 @@ export const TextLink = forwardRef<HTMLAnchorElement, LinkProps>(
|
|
76
84
|
}
|
77
85
|
|
78
86
|
return (
|
79
|
-
<ChakraLink
|
87
|
+
<ChakraLink
|
88
|
+
href={href}
|
89
|
+
{...props}
|
90
|
+
ref={ref}
|
91
|
+
{...(isExternal && {
|
92
|
+
target: "_blank",
|
93
|
+
rel: "noopener noreferrer",
|
94
|
+
})}
|
95
|
+
>
|
80
96
|
{children}
|
81
97
|
{isExternal && <ExternalIcon label={externalLabel} size={props.size} />}
|
82
98
|
</ChakraLink>
|
@@ -47,13 +47,13 @@ export const alertServiceSlotRecipe = defineSlotRecipe({
|
|
47
47
|
textWrap: "nowrap",
|
48
48
|
},
|
49
49
|
itemBody: {
|
50
|
-
|
50
|
+
marginX: "auto",
|
51
|
+
padding: "0 !important",
|
51
52
|
paddingBottom: ["0.5", null, null, "1"],
|
52
53
|
color: "text.inverted",
|
53
54
|
"& > p": {
|
54
55
|
gap: 2,
|
55
56
|
width: "full",
|
56
|
-
justifyContent: "center",
|
57
57
|
borderBottom: "1px dashed",
|
58
58
|
borderColor: "outline.inverted",
|
59
59
|
paddingBottom: "3",
|
@@ -45,7 +45,7 @@ export const drawerSlotRecipe = defineSlotRecipe({
|
|
45
45
|
maxHeight: "100dvh",
|
46
46
|
color: "inherit",
|
47
47
|
boxShadow: "lg",
|
48
|
-
minHeight: ["
|
48
|
+
minHeight: ["10rem", null, null, "auto"],
|
49
49
|
_open: {
|
50
50
|
animationDuration: "slowest",
|
51
51
|
animationTimingFunction: "ease-in-smooth",
|
@@ -59,16 +59,16 @@ export const drawerSlotRecipe = defineSlotRecipe({
|
|
59
59
|
display: "flex",
|
60
60
|
alignItems: "center",
|
61
61
|
justifyContent: "space-between",
|
62
|
-
paddingX: "5",
|
62
|
+
paddingX: ["3", null, null, "5"],
|
63
63
|
paddingBottom: "1",
|
64
64
|
},
|
65
65
|
body: {
|
66
|
-
paddingX: "5",
|
66
|
+
paddingX: ["3", null, null, "5"],
|
67
67
|
paddingY: ["1", null, null, "2"],
|
68
68
|
flex: "1",
|
69
69
|
overflow: "auto",
|
70
70
|
fontSize: ["xs", null, null, "sm"],
|
71
|
-
minHeight: ["
|
71
|
+
minHeight: ["2", null, null, "auto"],
|
72
72
|
},
|
73
73
|
footer: {
|
74
74
|
display: "flex",
|
@@ -85,8 +85,8 @@ export const drawerSlotRecipe = defineSlotRecipe({
|
|
85
85
|
},
|
86
86
|
closeTrigger: {
|
87
87
|
position: "absolute",
|
88
|
-
top: "
|
89
|
-
|
88
|
+
top: "0",
|
89
|
+
right: "0",
|
90
90
|
},
|
91
91
|
},
|
92
92
|
variants: {
|
@@ -201,29 +201,20 @@ export const selectSlotRecipe = defineSlotRecipe({
|
|
201
201
|
},
|
202
202
|
floating: {
|
203
203
|
control: {
|
204
|
-
backgroundColor: {
|
205
|
-
_light: "bg",
|
206
|
-
_dark: `color-mix(in srgb, white 10%, var(--spor-colors-bg))`,
|
207
|
-
},
|
208
204
|
outline: "1px solid",
|
209
205
|
outlineColor: "floating.outline",
|
210
206
|
_hover: {
|
211
|
-
outline: "
|
212
|
-
outlineColor: "floating.outline
|
213
|
-
backgroundColor: {
|
214
|
-
_light: "floating.surface.hover",
|
215
|
-
_dark: `color-mix(in srgb, white 10%, var(--spor-colors-bg))`,
|
216
|
-
},
|
207
|
+
outline: "2px solid",
|
208
|
+
outlineColor: "floating.outline",
|
217
209
|
},
|
218
210
|
_active: {
|
219
|
-
|
220
|
-
|
221
|
-
|
211
|
+
backgroundColor: "brand.surface.active",
|
212
|
+
},
|
213
|
+
_disabled: {
|
214
|
+
pointerEvents: "none",
|
215
|
+
color: "text.disabled",
|
216
|
+
backgroundColor: "surface.disabled",
|
222
217
|
},
|
223
|
-
},
|
224
|
-
selectContent: {
|
225
|
-
outline: "1px solid",
|
226
|
-
outlineColor: "floating.outline",
|
227
218
|
},
|
228
219
|
},
|
229
220
|
},
|