@vygruppen/spor-react 13.6.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @vygruppen/spor-react@13.6.0 build /home/runner/work/spor/spor/packages/spor-react
2
+ > @vygruppen/spor-react@13.7.0 build /home/runner/work/spor/spor/packages/spor-react
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: src/index.tsx, src/icons/index.tsx
@@ -11,18 +11,18 @@ CLI Cleaning output folder
11
11
  ESM Build start
12
12
  CJS Build start
13
13
  DTS Build start
14
- ESM dist/index.mjs 353.61 KB
14
+ ESM dist/index.mjs 356.08 KB
15
15
  ESM dist/icons/index.mjs 110.00 B
16
+ ESM dist/index.mjs.map 756.21 KB
16
17
  ESM dist/icons/index.mjs.map 157.00 B
17
- ESM dist/index.mjs.map 752.22 KB
18
- ESM ⚡️ Build success in 2851ms
19
- CJS dist/index.cjs 378.29 KB
18
+ ESM ⚡️ Build success in 2676ms
19
+ CJS dist/index.cjs 380.79 KB
20
20
  CJS dist/icons/index.cjs 381.00 B
21
+ CJS dist/index.cjs.map 756.21 KB
21
22
  CJS dist/icons/index.cjs.map 157.00 B
22
- CJS dist/index.cjs.map 752.22 KB
23
- CJS ⚡️ Build success in 2850ms
24
- DTS ⚡️ Build success in 21728ms
23
+ CJS ⚡️ Build success in 2678ms
24
+ DTS ⚡️ Build success in 21841ms
25
25
  DTS dist/icons/index.d.ts 44.00 B
26
- DTS dist/index.d.ts 155.16 KB
26
+ DTS dist/index.d.ts 156.17 KB
27
27
  DTS dist/icons/index.d.cts 44.00 B
28
- DTS dist/index.d.cts 155.16 KB
28
+ DTS dist/index.d.cts 156.17 KB
@@ -1,8 +1,8 @@
1
1
 
2
- > @vygruppen/spor-react@13.6.0 postinstall /home/runner/work/spor/spor/packages/spor-react
2
+ > @vygruppen/spor-react@13.7.0 postinstall /home/runner/work/spor/spor/packages/spor-react
3
3
  > chakra typegen src/theme/index.ts
4
4
 
5
- ◇ injected env (0) from .env // tip: secrets for agents [www.dotenvx.com]
5
+ ◇ injected env (0) from .env // tip: override existing { override: true }
6
6
  ┌ Chakra CLI ⚡️
7
7
  [?25l│
8
8
  ◒ Generating conditions types...
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @vygruppen/spor-react
2
2
 
3
+ ## 13.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b80fda2: Toast: Introduce "inverted" as a prop, that uses darkmode colors in lightmode, and lightmode colors in darkmode.
8
+ - a1d5a12: Autocomplete: add a size-prop that can be set to either 'md' or 'sm'.
9
+
10
+ ### Patch Changes
11
+
12
+ - e6bfa69: override safari autofill for input fields with spor colors
13
+ - 6d0bf57: TextLink: Add non-breaking space for external icon so that it never breaks over to a newline alone.
14
+ - 022e894: Separator: Change borderColor of the dashed separator to use the outline.default token
15
+ InputChip: Adjust the height of the different sizes to match with design.
16
+ TextLink: Change the ExternalLink-Icon to be of size 30x30 when TextLink is of size "lg"
17
+ - Updated dependencies [783c84f]
18
+ - @vygruppen/spor-design-tokens@5.1.1
19
+
3
20
  ## 13.6.0
4
21
 
5
22
  ### Minor Changes
@@ -0,0 +1,108 @@
1
+ import { render, screen, waitFor } from "@testing-library/react";
2
+ import userEvent from "@testing-library/user-event";
3
+ import { Button, createToast, SporProvider } from "@vygruppen/spor-react";
4
+ import { describe, expect, test, vi } from "vitest";
5
+
6
+ // SporProvider renders the Toaster internally, so toasts appear within it
7
+
8
+ describe("Toast", () => {
9
+ test("shows toast triggered by a button click", async () => {
10
+ const user = userEvent.setup();
11
+
12
+ render(
13
+ <SporProvider>
14
+ <Button
15
+ variant="secondary"
16
+ onClick={() =>
17
+ createToast({
18
+ variant: "success",
19
+ text: "Button triggered toast",
20
+ })
21
+ }
22
+ >
23
+ Show toast
24
+ </Button>
25
+ </SporProvider>,
26
+ );
27
+
28
+ expect(
29
+ screen.queryByText("Button triggered toast"),
30
+ ).not.toBeInTheDocument();
31
+
32
+ await user.click(screen.getByRole("button", { name: "Show toast" }));
33
+
34
+ await waitFor(() => {
35
+ expect(screen.getByText("Button triggered toast")).toBeInTheDocument();
36
+ });
37
+ });
38
+
39
+ test("close toast by a close trigger button click", async () => {
40
+ const user = userEvent.setup();
41
+
42
+ render(
43
+ <SporProvider>
44
+ <Button
45
+ variant="secondary"
46
+ onClick={() =>
47
+ createToast({
48
+ variant: "success",
49
+ text: "Button triggered toast 2",
50
+ duration: 10_000,
51
+ closable: true,
52
+ })
53
+ }
54
+ >
55
+ Show toast
56
+ </Button>
57
+ </SporProvider>,
58
+ );
59
+
60
+ expect(
61
+ screen.queryByText("Button triggered toast 2"),
62
+ ).not.toBeInTheDocument();
63
+
64
+ await user.click(screen.getByRole("button", { name: "Show toast" }));
65
+
66
+ await waitFor(() => {
67
+ expect(screen.getByText("Button triggered toast 2")).toBeInTheDocument();
68
+ });
69
+
70
+ await user.click(screen.getByRole("button", { name: "Lukk" }));
71
+ await new Promise((resolve) => setTimeout(resolve, 2000));
72
+ expect(
73
+ screen.queryByText("Button triggered toast 2"),
74
+ ).not.toBeInTheDocument();
75
+ });
76
+
77
+ test("click on custom action button in toast", async () => {
78
+ const user = userEvent.setup();
79
+ const onButtonClick = vi.fn();
80
+
81
+ render(
82
+ <SporProvider>
83
+ <Button
84
+ variant="secondary"
85
+ onClick={() =>
86
+ createToast({
87
+ variant: "success",
88
+ text: "Button triggered toast 3",
89
+ action: {
90
+ label: "Undo",
91
+ onClick: onButtonClick,
92
+ },
93
+ })
94
+ }
95
+ >
96
+ Show toast
97
+ </Button>
98
+ </SporProvider>,
99
+ );
100
+
101
+ await user.click(screen.getByRole("button", { name: "Show toast" }));
102
+ await waitFor(() => {
103
+ expect(screen.getByText("Button triggered toast 3")).toBeInTheDocument();
104
+ });
105
+ await user.click(screen.getByRole("button", { name: "Undo" }));
106
+ expect(onButtonClick).toHaveBeenCalled();
107
+ });
108
+ });
package/dist/index.cjs CHANGED
@@ -3304,10 +3304,29 @@ var texts14 = createTexts({
3304
3304
  var ExternalIcon = ({
3305
3305
  label,
3306
3306
  size
3307
- }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3308
- size === "lg" || size === "md" ? /* @__PURE__ */ jsxRuntime.jsx(spor_icon_react_star.LinkOutOutline24Icon, { "aria-hidden": true, display: "inline" }) : /* @__PURE__ */ jsxRuntime.jsx(spor_icon_react_star.LinkOutOutline18Icon, { "aria-hidden": true, display: "inline" }),
3309
- /* @__PURE__ */ jsxRuntime.jsx(react.VisuallyHidden, { children: label })
3310
- ] });
3307
+ }) => {
3308
+ const getIcon = () => {
3309
+ switch (size) {
3310
+ case "lg": {
3311
+ return /* @__PURE__ */ jsxRuntime.jsx(spor_icon_react_star.LinkOutOutline30Icon, { "aria-hidden": true, display: "inline" });
3312
+ }
3313
+ case "md": {
3314
+ return /* @__PURE__ */ jsxRuntime.jsx(spor_icon_react_star.LinkOutOutline24Icon, { "aria-hidden": true, display: "inline" });
3315
+ }
3316
+ case "sm": {
3317
+ return /* @__PURE__ */ jsxRuntime.jsx(spor_icon_react_star.LinkOutOutline18Icon, { "aria-hidden": true, display: "inline" });
3318
+ }
3319
+ default: {
3320
+ return /* @__PURE__ */ jsxRuntime.jsx(spor_icon_react_star.LinkOutOutline24Icon, { "aria-hidden": true, display: "inline" });
3321
+ }
3322
+ }
3323
+ };
3324
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { whiteSpace: "nowrap" }, children: [
3325
+ "\u2060",
3326
+ getIcon(),
3327
+ /* @__PURE__ */ jsxRuntime.jsx(react.VisuallyHidden, { children: label })
3328
+ ] });
3329
+ };
3311
3330
  var TextLink = ({
3312
3331
  ref,
3313
3332
  children,
@@ -3668,6 +3687,7 @@ function Autocomplete({
3668
3687
  openOnClick = true,
3669
3688
  openOnFocus = true,
3670
3689
  ref,
3690
+ size = "md",
3671
3691
  ...rest
3672
3692
  }) {
3673
3693
  const { contains } = react.useFilter({ sensitivity: "base" });
@@ -3726,7 +3746,8 @@ function Autocomplete({
3726
3746
  onFocus == null ? void 0 : onFocus(event);
3727
3747
  if (openOnFocus && filteredChildren.length > 0)
3728
3748
  combobox.setOpen(true);
3729
- }
3749
+ },
3750
+ size
3730
3751
  }
3731
3752
  ) }),
3732
3753
  /* @__PURE__ */ jsxRuntime.jsx(react.Combobox.IndicatorGroup, { children: /* @__PURE__ */ jsxRuntime.jsx(react.Combobox.ClearTrigger, { asChild: true, "aria-label": t(texts16.clearValue), children: /* @__PURE__ */ jsxRuntime.jsx(CloseButton, { size: "xs", tabIndex: 0 }) }) })
@@ -6699,31 +6720,38 @@ var createToast = ({
6699
6720
  duration = 6e3,
6700
6721
  width = "sm",
6701
6722
  action,
6702
- closable = false
6723
+ closable = false,
6724
+ inverted = false
6703
6725
  }) => toaster.create({
6704
6726
  description: text,
6705
6727
  type: variant,
6706
6728
  id: id ?? crypto.randomUUID(),
6707
6729
  duration,
6708
6730
  action,
6709
- meta: { width },
6731
+ meta: { width, inverted },
6710
6732
  closable
6711
6733
  });
6712
6734
  var Toaster = () => {
6713
6735
  return /* @__PURE__ */ jsxRuntime.jsx(react.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(react.Toaster, { toaster, insetInline: { mdDown: "4" }, children: (toast) => {
6714
- var _a6;
6736
+ var _a6, _b5;
6715
6737
  return /* @__PURE__ */ jsxRuntime.jsxs(
6716
6738
  react.Toast.Root,
6717
6739
  {
6718
6740
  width: { md: (_a6 = toast.meta) == null ? void 0 : _a6.width },
6719
- border: "sm",
6720
- borderColor: `outline.${toast.type}`,
6721
- boxShadow: "sm",
6741
+ "data-inverted": ((_b5 = toast.meta) == null ? void 0 : _b5.inverted) ? "" : void 0,
6722
6742
  role: "alert",
6723
6743
  children: [
6724
6744
  /* @__PURE__ */ jsxRuntime.jsx(AlertIcon, { variant: toast.type }),
6725
6745
  /* @__PURE__ */ jsxRuntime.jsx(react.Stack, { gap: "1", flex: "1", maxWidth: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(react.Toast.Description, { children: toast.description }) }),
6726
- toast.action && /* @__PURE__ */ jsxRuntime.jsx(react.Toast.ActionTrigger, { onClick: toast.action.onClick, children: /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "ghost", size: "xs", children: toast.action.label }) }),
6746
+ toast.action && /* @__PURE__ */ jsxRuntime.jsx(react.Toast.ActionTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
6747
+ Button,
6748
+ {
6749
+ variant: "ghost",
6750
+ size: "xs",
6751
+ onClick: toast.action.onClick,
6752
+ children: toast.action.label
6753
+ }
6754
+ ) }),
6727
6755
  toast.closable && /* @__PURE__ */ jsxRuntime.jsx(react.Toast.CloseTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(CloseButton, { size: "xs" }) })
6728
6756
  ]
6729
6757
  }
@@ -7395,6 +7423,10 @@ var inputRecipe = react.defineRecipe({
7395
7423
  _focus: {
7396
7424
  outline: "2px solid",
7397
7425
  outlineColor: "outline.focus"
7426
+ },
7427
+ "&:-webkit-autofill, &:-webkit-autofill:focus": {
7428
+ boxShadow: "0 0 0 1000px var(--spor-colors-surface-info-hover) inset",
7429
+ WebkitTextFillColor: "var(--spor-colors-text)"
7398
7430
  }
7399
7431
  },
7400
7432
  floating: {
@@ -7414,6 +7446,10 @@ var inputRecipe = react.defineRecipe({
7414
7446
  focus: {
7415
7447
  outline: "1px solid",
7416
7448
  outlineColor: "outline.focus"
7449
+ },
7450
+ "&:-webkit-autofill, &:-webkit-autofill:focus": {
7451
+ boxShadow: "0 0 0 1000px var(--spor-colors-surface-info-hover) inset",
7452
+ WebkitTextFillColor: "var(--spor-colors-text)"
7417
7453
  }
7418
7454
  }
7419
7455
  },
@@ -7587,13 +7623,14 @@ var separatorRecipe = react.defineRecipe({
7587
7623
  borderStyle: "solid"
7588
7624
  },
7589
7625
  dashed: {
7626
+ "--dash-color": "var(--spor-colors-outline)",
7590
7627
  borderImageSlice: 1,
7591
7628
  borderImageSource: `repeating-linear-gradient(
7592
7629
  var(--gradient-direction),
7593
- var(--spor-colors-outline-disabled) 0,
7594
- var(--spor-colors-outline-disabled) var(--dash-size),
7630
+ var(--dash-color) 0,
7631
+ var(--dash-color) var(--dash-size),
7595
7632
  transparent var(--dash-size),
7596
- transparent calc(var(--dash-size) + var(--dash-gap))
7633
+ transparent calc(var(--dash-size) + var(--dash-gap))
7597
7634
  )`
7598
7635
  }
7599
7636
  },
@@ -10367,7 +10404,7 @@ var inputChipSlotRecipe = react.defineSlotRecipe({
10367
10404
  root: {
10368
10405
  fontSize: "desktop.xs",
10369
10406
  paddingX: "1.5",
10370
- paddingY: "0",
10407
+ height: 5,
10371
10408
  fontWeight: "normal",
10372
10409
  borderRadius: "xs"
10373
10410
  }
@@ -10376,17 +10413,16 @@ var inputChipSlotRecipe = react.defineSlotRecipe({
10376
10413
  root: {
10377
10414
  fontSize: "desktop.sm",
10378
10415
  paddingX: "2",
10379
- paddingY: "0.5",
10416
+ height: 6,
10380
10417
  fontWeight: "bold",
10381
10418
  borderRadius: "9px"
10382
10419
  }
10383
10420
  },
10384
10421
  md: {
10385
10422
  root: {
10386
- padding: 5,
10387
10423
  fontSize: "desktop.md",
10388
10424
  paddingX: "2",
10389
- paddingY: "1",
10425
+ height: 7,
10390
10426
  fontWeight: "bold",
10391
10427
  borderRadius: "sm"
10392
10428
  }
@@ -10395,7 +10431,7 @@ var inputChipSlotRecipe = react.defineSlotRecipe({
10395
10431
  root: {
10396
10432
  fontSize: "desktop.md",
10397
10433
  paddingX: "2",
10398
- paddingY: "3",
10434
+ height: "8",
10399
10435
  fontWeight: "bold",
10400
10436
  borderRadius: "md"
10401
10437
  }
@@ -12292,6 +12328,7 @@ var toastSlotRecipe = react.defineSlotRecipe({
12292
12328
  translate: "var(--x) var(--y)",
12293
12329
  opacity: "var(--opacity)",
12294
12330
  willChange: "translate, opacity, scale",
12331
+ outline: "1px solid",
12295
12332
  borderRadius: "sm",
12296
12333
  transition: "translate 400ms, scale 400ms, opacity 400ms, height 400ms, box-shadow 200ms",
12297
12334
  transitionTimingFunction: "cubic-bezier(0.21, 1.02, 0.73, 1)",
@@ -12299,16 +12336,52 @@ var toastSlotRecipe = react.defineSlotRecipe({
12299
12336
  transition: "translate 400ms, scale 400ms, opacity 200ms",
12300
12337
  transitionTimingFunction: "cubic-bezier(0.06, 0.71, 0.55, 1)"
12301
12338
  },
12302
- boxShadow: "xl",
12339
+ boxShadow: "sm",
12303
12340
  color: "text",
12304
12341
  "&[data-type=success]": {
12305
- backgroundColor: "surface.success"
12342
+ backgroundColor: "surface.success",
12343
+ outlineColor: "outline.success"
12306
12344
  },
12307
12345
  "&[data-type=error]": {
12308
- backgroundColor: "surface.critical"
12346
+ backgroundColor: "surface.critical",
12347
+ outlineColor: "outline.critical"
12309
12348
  },
12310
12349
  "&[data-type=info]": {
12311
- backgroundColor: "surface.info"
12350
+ backgroundColor: "surface.info",
12351
+ outlineColor: "outline.info"
12352
+ },
12353
+ "&[data-inverted][data-type=success]": {
12354
+ backgroundColor: { _light: "darkTeal", _dark: "seaMist" },
12355
+ color: { _light: "mint", _dark: "jungle" },
12356
+ outlineColor: { _light: "greenHaze", _dark: "coralGreen" },
12357
+ "& path:first-of-type": {
12358
+ fill: { _light: "mint", _dark: "jungle" }
12359
+ },
12360
+ "& path:not(:first-of-type)": {
12361
+ fill: { _light: "darkTeal", _dark: "seaMist" }
12362
+ }
12363
+ },
12364
+ "&[data-inverted][data-type=error]": {
12365
+ backgroundColor: { _light: "burgundy", _dark: "lightRed" },
12366
+ color: { _light: "pink", _dark: "maroon" },
12367
+ outlineColor: { _light: "crimson", _dark: "salmon" },
12368
+ "& path:first-of-type": {
12369
+ fill: { _light: "pink", _dark: "maroon" }
12370
+ },
12371
+ "& path:not(:first-of-type)": {
12372
+ fill: { _light: "burgundy", _dark: "lightRed" }
12373
+ }
12374
+ },
12375
+ "&[data-inverted][data-type=info]": {
12376
+ backgroundColor: { _light: "darkBlue", _dark: "lightBlue" },
12377
+ color: { _light: "icyBlue", _dark: "royal" },
12378
+ outlineColor: { _light: "ocean", _dark: "cloudy" },
12379
+ "& path:first-of-type": {
12380
+ fill: { _light: "icyBlue", _dark: "navy" }
12381
+ },
12382
+ "& path:not(:first-of-type)": {
12383
+ fill: { _light: "darkBlue", _dark: "lightBlue" }
12384
+ }
12312
12385
  }
12313
12386
  },
12314
12387
  title: {