@vygruppen/spor-react 13.5.0 → 13.7.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 +12 -12
- package/.turbo/turbo-postinstall.log +2 -2
- package/CHANGELOG.md +33 -0
- package/__tests__/toast.test.tsx +108 -0
- package/dist/index.cjs +109 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -2
- package/dist/index.d.ts +25 -2
- package/dist/index.mjs +110 -25
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/input/Autocomplete.tsx +2 -0
- package/src/link/TextLink.tsx +27 -11
- package/src/theme/brand.ts +5 -0
- package/src/theme/index.ts +4 -0
- package/src/theme/recipes/input.ts +8 -1
- package/src/theme/recipes/separator.ts +4 -3
- package/src/theme/semantic-tokens/colors.ts +13 -0
- package/src/theme/semantic-tokens/index.ts +10 -1
- package/src/theme/slot-recipes/input-chip.ts +4 -5
- package/src/theme/slot-recipes/toast.ts +38 -1
- package/src/toast/toast.tsx +10 -6
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vygruppen/spor-react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "13.
|
|
4
|
+
"version": "13.7.0",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
"react-stately": "^3.31.1",
|
|
47
47
|
"react-swipeable": "^7.0.1",
|
|
48
48
|
"usehooks-ts": "^3.1.0",
|
|
49
|
-
"@vygruppen/spor-design-tokens": "5.
|
|
50
|
-
"@vygruppen/spor-
|
|
51
|
-
"@vygruppen/spor-
|
|
49
|
+
"@vygruppen/spor-design-tokens": "5.1.1",
|
|
50
|
+
"@vygruppen/spor-loader": "0.7.0",
|
|
51
|
+
"@vygruppen/spor-icon-react": "5.0.2"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@react-types/datepicker": "^3.10.0",
|
|
@@ -50,6 +50,7 @@ export function Autocomplete({
|
|
|
50
50
|
openOnClick = true,
|
|
51
51
|
openOnFocus = true,
|
|
52
52
|
ref,
|
|
53
|
+
size = "md",
|
|
53
54
|
...rest
|
|
54
55
|
}: Props) {
|
|
55
56
|
const { contains } = useFilter({ sensitivity: "base" });
|
|
@@ -114,6 +115,7 @@ export function Autocomplete({
|
|
|
114
115
|
if (openOnFocus && filteredChildren.length > 0)
|
|
115
116
|
combobox.setOpen(true);
|
|
116
117
|
}}
|
|
118
|
+
size={size}
|
|
117
119
|
/>
|
|
118
120
|
</Combobox.Input>
|
|
119
121
|
<Combobox.IndicatorGroup>
|
package/src/link/TextLink.tsx
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
LinkOutOutline18Icon,
|
|
9
9
|
LinkOutOutline24Icon,
|
|
10
|
+
LinkOutOutline30Icon,
|
|
10
11
|
} from "@vygruppen/spor-icon-react";
|
|
11
12
|
import React, {
|
|
12
13
|
cloneElement,
|
|
@@ -39,17 +40,32 @@ const ExternalIcon = ({
|
|
|
39
40
|
}: {
|
|
40
41
|
label: string;
|
|
41
42
|
size: LinkProps["size"];
|
|
42
|
-
}) =>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
}) => {
|
|
44
|
+
const getIcon = () => {
|
|
45
|
+
switch (size) {
|
|
46
|
+
case "lg": {
|
|
47
|
+
return <LinkOutOutline30Icon aria-hidden display="inline" />;
|
|
48
|
+
}
|
|
49
|
+
case "md": {
|
|
50
|
+
return <LinkOutOutline24Icon aria-hidden display="inline" />;
|
|
51
|
+
}
|
|
52
|
+
case "sm": {
|
|
53
|
+
return <LinkOutOutline18Icon aria-hidden display="inline" />;
|
|
54
|
+
}
|
|
55
|
+
default: {
|
|
56
|
+
return <LinkOutOutline24Icon aria-hidden display="inline" />;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return (
|
|
61
|
+
<span style={{ whiteSpace: "nowrap" }}>
|
|
62
|
+
{"\u2060"}
|
|
63
|
+
{getIcon()}
|
|
64
|
+
{/* Visually hidden text for screen readers */}
|
|
65
|
+
<VisuallyHidden>{label}</VisuallyHidden>
|
|
66
|
+
</span>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
53
69
|
|
|
54
70
|
export const TextLink = ({
|
|
55
71
|
ref,
|
package/src/theme/brand.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
export enum Brand {
|
|
2
2
|
VyDigital = "VyDigital",
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated The VyUtvikling theme is deprecated and will be removed in a
|
|
5
|
+
* future major version. Use {@link Brand.VyTeknologi} instead.
|
|
6
|
+
*/
|
|
3
7
|
VyUtvikling = "VyUtvikling",
|
|
8
|
+
VyTeknologi = "VyTeknologi",
|
|
4
9
|
CargoNet = "CargoNet",
|
|
5
10
|
}
|
|
6
11
|
|
package/src/theme/index.ts
CHANGED
|
@@ -56,6 +56,10 @@ export const inputRecipe = defineRecipe({
|
|
|
56
56
|
outline: "2px solid",
|
|
57
57
|
outlineColor: "outline.focus",
|
|
58
58
|
},
|
|
59
|
+
"&:-webkit-autofill, &:-webkit-autofill:focus": {
|
|
60
|
+
boxShadow: "0 0 0 1000px var(--spor-colors-surface-info-hover) inset",
|
|
61
|
+
WebkitTextFillColor: "var(--spor-colors-text)",
|
|
62
|
+
},
|
|
59
63
|
},
|
|
60
64
|
floating: {
|
|
61
65
|
boxShadow: "sm",
|
|
@@ -72,11 +76,14 @@ export const inputRecipe = defineRecipe({
|
|
|
72
76
|
outlineColor: "outline.neutral",
|
|
73
77
|
backgroundColor: "surface.floating.active",
|
|
74
78
|
},
|
|
75
|
-
|
|
76
79
|
focus: {
|
|
77
80
|
outline: "1px solid",
|
|
78
81
|
outlineColor: "outline.focus",
|
|
79
82
|
},
|
|
83
|
+
"&:-webkit-autofill, &:-webkit-autofill:focus": {
|
|
84
|
+
boxShadow: "0 0 0 1000px var(--spor-colors-surface-info-hover) inset",
|
|
85
|
+
WebkitTextFillColor: "var(--spor-colors-text)",
|
|
86
|
+
},
|
|
80
87
|
},
|
|
81
88
|
},
|
|
82
89
|
size: {
|
|
@@ -12,13 +12,14 @@ export const separatorRecipe = defineRecipe({
|
|
|
12
12
|
borderStyle: "solid",
|
|
13
13
|
},
|
|
14
14
|
dashed: {
|
|
15
|
+
"--dash-color": "var(--spor-colors-outline)",
|
|
15
16
|
borderImageSlice: 1,
|
|
16
17
|
borderImageSource: `repeating-linear-gradient(
|
|
17
18
|
var(--gradient-direction),
|
|
18
|
-
var(--
|
|
19
|
-
var(--
|
|
19
|
+
var(--dash-color) 0,
|
|
20
|
+
var(--dash-color) var(--dash-size),
|
|
20
21
|
transparent var(--dash-size),
|
|
21
|
-
transparent calc(var(--dash-size) + var(--dash-gap))
|
|
22
|
+
transparent calc(var(--dash-size) + var(--dash-gap))
|
|
22
23
|
)`,
|
|
23
24
|
},
|
|
24
25
|
},
|
|
@@ -3,7 +3,12 @@ import tokens from "@vygruppen/spor-design-tokens/raw-tokens";
|
|
|
3
3
|
|
|
4
4
|
export enum Brand {
|
|
5
5
|
VyDigital = "VyDigital",
|
|
6
|
+
/**
|
|
7
|
+
* @deprecated The VyUtvikling theme is deprecated and will be removed in a
|
|
8
|
+
* future major version. Use {@link Brand.VyTeknologi} instead.
|
|
9
|
+
*/
|
|
6
10
|
VyUtvikling = "VyUtvikling",
|
|
11
|
+
VyTeknologi = "VyTeknologi",
|
|
7
12
|
CargoNet = "CargoNet",
|
|
8
13
|
}
|
|
9
14
|
|
|
@@ -11,10 +16,18 @@ export const vyDigitalColors = defineSemanticTokens.colors({
|
|
|
11
16
|
...tokens.color["vy-digital"].color.vyDigital,
|
|
12
17
|
});
|
|
13
18
|
|
|
19
|
+
/**
|
|
20
|
+
* @deprecated The VyUtvikling theme is deprecated and will be removed in a
|
|
21
|
+
* future major version. Use {@link vyTeknologiColors} instead.
|
|
22
|
+
*/
|
|
14
23
|
export const vyUtviklingColors = defineSemanticTokens.colors({
|
|
15
24
|
...tokens.color["vy-utvikling"].color.vyUtvikling,
|
|
16
25
|
});
|
|
17
26
|
|
|
27
|
+
export const vyTeknologiColors = defineSemanticTokens.colors({
|
|
28
|
+
...tokens.color["vy-teknologi"].color.vyTeknologi,
|
|
29
|
+
});
|
|
30
|
+
|
|
18
31
|
export const cargonetColors = defineSemanticTokens.colors({
|
|
19
32
|
...tokens.color["cargonet"].color.cargonet,
|
|
20
33
|
});
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { Brand } from "../brand";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
cargonetColors,
|
|
4
|
+
vyDigitalColors,
|
|
5
|
+
vyTeknologiColors,
|
|
6
|
+
vyUtviklingColors,
|
|
7
|
+
} from "./colors";
|
|
3
8
|
import { radii } from "./radii";
|
|
4
9
|
import { shadows } from "./shadows";
|
|
5
10
|
|
|
@@ -13,6 +18,10 @@ export const semanticTokens = {
|
|
|
13
18
|
...baseSemanticTokens,
|
|
14
19
|
colors: vyUtviklingColors,
|
|
15
20
|
},
|
|
21
|
+
[Brand.VyTeknologi]: {
|
|
22
|
+
...baseSemanticTokens,
|
|
23
|
+
colors: vyTeknologiColors,
|
|
24
|
+
},
|
|
16
25
|
[Brand.CargoNet]: {
|
|
17
26
|
...baseSemanticTokens,
|
|
18
27
|
colors: cargonetColors,
|
|
@@ -76,7 +76,7 @@ export const inputChipSlotRecipe = defineSlotRecipe({
|
|
|
76
76
|
root: {
|
|
77
77
|
fontSize: "desktop.xs",
|
|
78
78
|
paddingX: "1.5",
|
|
79
|
-
|
|
79
|
+
height: 5,
|
|
80
80
|
fontWeight: "normal",
|
|
81
81
|
borderRadius: "xs",
|
|
82
82
|
},
|
|
@@ -85,17 +85,16 @@ export const inputChipSlotRecipe = defineSlotRecipe({
|
|
|
85
85
|
root: {
|
|
86
86
|
fontSize: "desktop.sm",
|
|
87
87
|
paddingX: "2",
|
|
88
|
-
|
|
88
|
+
height: 6,
|
|
89
89
|
fontWeight: "bold",
|
|
90
90
|
borderRadius: "9px",
|
|
91
91
|
},
|
|
92
92
|
},
|
|
93
93
|
md: {
|
|
94
94
|
root: {
|
|
95
|
-
padding: 5,
|
|
96
95
|
fontSize: "desktop.md",
|
|
97
96
|
paddingX: "2",
|
|
98
|
-
|
|
97
|
+
height: 7,
|
|
99
98
|
fontWeight: "bold",
|
|
100
99
|
borderRadius: "sm",
|
|
101
100
|
},
|
|
@@ -104,7 +103,7 @@ export const inputChipSlotRecipe = defineSlotRecipe({
|
|
|
104
103
|
root: {
|
|
105
104
|
fontSize: "desktop.md",
|
|
106
105
|
paddingX: "2",
|
|
107
|
-
|
|
106
|
+
height: "8",
|
|
108
107
|
fontWeight: "bold",
|
|
109
108
|
borderRadius: "md",
|
|
110
109
|
},
|
|
@@ -16,6 +16,7 @@ export const toastSlotRecipe = defineSlotRecipe({
|
|
|
16
16
|
translate: "var(--x) var(--y)",
|
|
17
17
|
opacity: "var(--opacity)",
|
|
18
18
|
willChange: "translate, opacity, scale",
|
|
19
|
+
outline: "1px solid",
|
|
19
20
|
|
|
20
21
|
borderRadius: "sm",
|
|
21
22
|
transition:
|
|
@@ -25,18 +26,54 @@ export const toastSlotRecipe = defineSlotRecipe({
|
|
|
25
26
|
transition: "translate 400ms, scale 400ms, opacity 200ms",
|
|
26
27
|
transitionTimingFunction: "cubic-bezier(0.06, 0.71, 0.55, 1)",
|
|
27
28
|
},
|
|
28
|
-
boxShadow: "
|
|
29
|
+
boxShadow: "sm",
|
|
29
30
|
|
|
30
31
|
color: "text",
|
|
31
32
|
"&[data-type=success]": {
|
|
32
33
|
backgroundColor: "surface.success",
|
|
34
|
+
outlineColor: "outline.success",
|
|
33
35
|
},
|
|
34
36
|
"&[data-type=error]": {
|
|
35
37
|
backgroundColor: "surface.critical",
|
|
38
|
+
outlineColor: "outline.critical",
|
|
36
39
|
},
|
|
37
40
|
|
|
38
41
|
"&[data-type=info]": {
|
|
39
42
|
backgroundColor: "surface.info",
|
|
43
|
+
outlineColor: "outline.info",
|
|
44
|
+
},
|
|
45
|
+
"&[data-inverted][data-type=success]": {
|
|
46
|
+
backgroundColor: { _light: "darkTeal", _dark: "seaMist" },
|
|
47
|
+
color: { _light: "mint", _dark: "jungle" },
|
|
48
|
+
outlineColor: { _light: "greenHaze", _dark: "coralGreen" },
|
|
49
|
+
"& path:first-of-type": {
|
|
50
|
+
fill: { _light: "mint", _dark: "jungle" },
|
|
51
|
+
},
|
|
52
|
+
"& path:not(:first-of-type)": {
|
|
53
|
+
fill: { _light: "darkTeal", _dark: "seaMist" },
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
"&[data-inverted][data-type=error]": {
|
|
57
|
+
backgroundColor: { _light: "burgundy", _dark: "lightRed" },
|
|
58
|
+
color: { _light: "pink", _dark: "maroon" },
|
|
59
|
+
outlineColor: { _light: "crimson", _dark: "salmon" },
|
|
60
|
+
"& path:first-of-type": {
|
|
61
|
+
fill: { _light: "pink", _dark: "maroon" },
|
|
62
|
+
},
|
|
63
|
+
"& path:not(:first-of-type)": {
|
|
64
|
+
fill: { _light: "burgundy", _dark: "lightRed" },
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
"&[data-inverted][data-type=info]": {
|
|
68
|
+
backgroundColor: { _light: "darkBlue", _dark: "lightBlue" },
|
|
69
|
+
color: { _light: "icyBlue", _dark: "royal" },
|
|
70
|
+
outlineColor: { _light: "ocean", _dark: "cloudy" },
|
|
71
|
+
"& path:first-of-type": {
|
|
72
|
+
fill: { _light: "icyBlue", _dark: "navy" },
|
|
73
|
+
},
|
|
74
|
+
"& path:not(:first-of-type)": {
|
|
75
|
+
fill: { _light: "darkBlue", _dark: "lightBlue" },
|
|
76
|
+
},
|
|
40
77
|
},
|
|
41
78
|
},
|
|
42
79
|
|
package/src/toast/toast.tsx
CHANGED
|
@@ -31,6 +31,7 @@ type ToastProps = {
|
|
|
31
31
|
id?: string;
|
|
32
32
|
action?: ToastAction;
|
|
33
33
|
closable?: boolean;
|
|
34
|
+
inverted?: boolean;
|
|
34
35
|
} & Pick<BoxProps, "width">;
|
|
35
36
|
|
|
36
37
|
export const createToast = ({
|
|
@@ -41,6 +42,7 @@ export const createToast = ({
|
|
|
41
42
|
width = "sm",
|
|
42
43
|
action,
|
|
43
44
|
closable = false,
|
|
45
|
+
inverted = false,
|
|
44
46
|
}: ToastProps) =>
|
|
45
47
|
toaster.create({
|
|
46
48
|
description: text,
|
|
@@ -48,7 +50,7 @@ export const createToast = ({
|
|
|
48
50
|
id: id ?? crypto.randomUUID(),
|
|
49
51
|
duration,
|
|
50
52
|
action,
|
|
51
|
-
meta: { width },
|
|
53
|
+
meta: { width, inverted },
|
|
52
54
|
closable: closable,
|
|
53
55
|
});
|
|
54
56
|
|
|
@@ -59,9 +61,7 @@ export const Toaster = () => {
|
|
|
59
61
|
{(toast) => (
|
|
60
62
|
<Toast.Root
|
|
61
63
|
width={{ md: toast.meta?.width }}
|
|
62
|
-
|
|
63
|
-
borderColor={`outline.${toast.type}`}
|
|
64
|
-
boxShadow="sm"
|
|
64
|
+
data-inverted={toast.meta?.inverted ? "" : undefined}
|
|
65
65
|
role="alert"
|
|
66
66
|
>
|
|
67
67
|
<AlertIcon variant={toast.type as Variant} />
|
|
@@ -69,8 +69,12 @@ export const Toaster = () => {
|
|
|
69
69
|
<Toast.Description>{toast.description}</Toast.Description>
|
|
70
70
|
</Stack>
|
|
71
71
|
{toast.action && (
|
|
72
|
-
<Toast.ActionTrigger
|
|
73
|
-
<Button
|
|
72
|
+
<Toast.ActionTrigger asChild>
|
|
73
|
+
<Button
|
|
74
|
+
variant="ghost"
|
|
75
|
+
size="xs"
|
|
76
|
+
onClick={toast.action.onClick}
|
|
77
|
+
>
|
|
74
78
|
{toast.action.label}
|
|
75
79
|
</Button>
|
|
76
80
|
</Toast.ActionTrigger>
|