@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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vygruppen/spor-react",
3
3
  "type": "module",
4
- "version": "13.5.0",
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.0.6",
50
- "@vygruppen/spor-icon-react": "5.0.2",
51
- "@vygruppen/spor-loader": "0.7.0"
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>
@@ -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
- {size === "lg" || size === "md" ? (
45
- <LinkOutOutline24Icon aria-hidden display="inline" />
46
- ) : (
47
- <LinkOutOutline18Icon aria-hidden display="inline" />
48
- )}
49
- {/* Visually hidden text for screen readers */}
50
- <VisuallyHidden>{label}</VisuallyHidden>
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,
@@ -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
 
@@ -48,6 +48,10 @@ export const themes = {
48
48
  defaultBaseConfig,
49
49
  generateTheme(Brand.VyUtvikling),
50
50
  ),
51
+ [Brand.VyTeknologi]: createSystem(
52
+ defaultBaseConfig,
53
+ generateTheme(Brand.VyTeknologi),
54
+ ),
51
55
  };
52
56
 
53
57
  export const system = themes[Brand.VyDigital];
@@ -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(--spor-colors-outline-disabled) 0,
19
- var(--spor-colors-outline-disabled) var(--dash-size),
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 { cargonetColors, vyDigitalColors, vyUtviklingColors } from "./colors";
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
- paddingY: "0",
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
- paddingY: "0.5",
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
- paddingY: "1",
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
- paddingY: "3",
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: "xl",
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
 
@@ -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
- border="sm"
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 onClick={toast.action.onClick}>
73
- <Button variant="ghost" size="xs">
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>