@simplybusiness/mobius 8.0.1 → 9.0.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.
Files changed (143) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/dist/cjs/index.js +4773 -0
  3. package/dist/cjs/index.js.map +7 -0
  4. package/dist/cjs/meta.json +4948 -0
  5. package/dist/esm/index.js +542 -694
  6. package/dist/esm/index.js.map +4 -4
  7. package/dist/esm/meta.json +300 -532
  8. package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
  9. package/dist/types/src/hooks/index.d.ts +0 -7
  10. package/dist/types/src/utils/htmlDialogPolyfill.d.ts +1 -0
  11. package/dist/types/src/utils/index.d.ts +0 -1
  12. package/dist/types/src/utils/mockMatchMedia.d.ts +1 -0
  13. package/dist/types/vitest.config.d.ts +2 -0
  14. package/package.json +14 -18
  15. package/src/components/Accordion/Accordion.stories.tsx +1 -1
  16. package/src/components/Accordion/Accordion.test.tsx +12 -12
  17. package/src/components/Accordion/Accordion.tsx +1 -1
  18. package/src/components/Accordion/AccordionList.stories.tsx +1 -1
  19. package/src/components/Accordion/AccordionList.test.tsx +6 -6
  20. package/src/components/AddressLookup/AddressLookup.stories.tsx +1 -1
  21. package/src/components/AddressLookup/AddressLookup.test.tsx +19 -20
  22. package/src/components/AddressLookup/LoqateAddressLookupService.test.tsx +7 -6
  23. package/src/components/Alert/Alert.stories.tsx +1 -1
  24. package/src/components/Box/Box.stories.tsx +1 -1
  25. package/src/components/Breadcrumbs/Breadcrumbs.stories.tsx +1 -1
  26. package/src/components/Button/Button.stories.tsx +3 -4
  27. package/src/components/Button/Button.test.tsx +4 -4
  28. package/src/components/Checkbox/Checkbox.stories.tsx +1 -1
  29. package/src/components/Checkbox/Checkbox.test.tsx +2 -2
  30. package/src/components/Checkbox/CheckboxGroup.stories.tsx +1 -1
  31. package/src/components/Checkbox/CheckboxGroup.test.tsx +5 -5
  32. package/src/components/Combobox/Combobox.stories.tsx +1 -1
  33. package/src/components/Combobox/Combobox.test.tsx +67 -78
  34. package/src/components/Combobox/Combobox.tsx +2 -1
  35. package/src/components/Combobox/useComboboxOptions.test.ts +30 -30
  36. package/src/components/Combobox/useComboboxOptions.ts +1 -1
  37. package/src/components/Container/Container.stories.tsx +1 -1
  38. package/src/components/DateField/DateField.stories.tsx +1 -1
  39. package/src/components/DateField/DateField.test.tsx +1 -1
  40. package/src/components/Divider/Divider.stories.tsx +1 -1
  41. package/src/components/Drawer/Drawer.stories.tsx +1 -1
  42. package/src/components/Drawer/Drawer.test.tsx +6 -6
  43. package/src/components/DropdownMenu/DropdownMenu.stories.tsx +8 -10
  44. package/src/components/DropdownMenu/DropdownMenu.test.tsx +1 -1
  45. package/src/components/ErrorMessage/ErrorMessage.stories.tsx +1 -1
  46. package/src/components/ExpandableText/ExpandableText.test.tsx +14 -14
  47. package/src/components/Fieldset/Fieldset.stories.tsx +1 -1
  48. package/src/components/Flex/Flex.stories.tsx +1 -1
  49. package/src/components/Grid/Grid.stories.tsx +4 -7
  50. package/src/components/Icon/Icon.stories.tsx +1 -1
  51. package/src/components/Image/Image.stories.tsx +1 -1
  52. package/src/components/Label/Label.stories.tsx +1 -1
  53. package/src/components/Link/Link.stories.tsx +1 -1
  54. package/src/components/Link/Link.test.tsx +1 -1
  55. package/src/components/LinkButton/LinkButton.stories.tsx +1 -1
  56. package/src/components/LinkButton/LinkButton.test.tsx +2 -2
  57. package/src/components/List/List.stories.tsx +1 -1
  58. package/src/components/LoadingIndicator/LoadingIndicator.stories.tsx +1 -1
  59. package/src/components/Logo/Logo.stories.tsx +1 -1
  60. package/src/components/Modal/Modal.stories.tsx +1 -1
  61. package/src/components/Modal/Modal.test.tsx +6 -6
  62. package/src/components/NumberField/NumberField.stories.tsx +1 -1
  63. package/src/components/NumberField/NumberField.test.tsx +5 -5
  64. package/src/components/PasswordField/PasswordField.stories.tsx +1 -1
  65. package/src/components/Popover/Popover.stories.tsx +4 -8
  66. package/src/components/Popover/Popover.test.tsx +4 -4
  67. package/src/components/Popover/Popover.tsx +1 -1
  68. package/src/components/Progress/Progress.stories.tsx +1 -1
  69. package/src/components/Radio/Radio.stories.tsx +1 -1
  70. package/src/components/Radio/Radio.test.tsx +9 -9
  71. package/src/components/SVG/SVG.stories.tsx +1 -1
  72. package/src/components/Segment/Segment.stories.tsx +1 -1
  73. package/src/components/Select/Select.stories.tsx +1 -1
  74. package/src/components/Select/Select.test.tsx +1 -1
  75. package/src/components/Slider/Slider.stories.tsx +1 -1
  76. package/src/components/Slider/Slider.test.tsx +6 -6
  77. package/src/components/Slider/helpers.test.ts +1 -1
  78. package/src/components/Stack/Stack.stories.tsx +1 -1
  79. package/src/components/Switch/Switch.stories.tsx +1 -1
  80. package/src/components/Switch/Switch.test.tsx +1 -1
  81. package/src/components/Table/Table.stories.tsx +1 -1
  82. package/src/components/Text/Text.stories.tsx +1 -1
  83. package/src/components/TextArea/TextArea.stories.tsx +1 -1
  84. package/src/components/TextArea/TextArea.test.tsx +3 -3
  85. package/src/components/TextField/TextField.stories.tsx +1 -1
  86. package/src/components/TextOrHTML/TextOrHTML.stories.tsx +1 -1
  87. package/src/components/Title/Title.stories.tsx +1 -1
  88. package/src/components/Toast/Toast.stories.tsx +1 -1
  89. package/src/components/Toast/Toast.test.tsx +6 -6
  90. package/src/components/Trust/Trust.stories.tsx +1 -1
  91. package/src/components/VisuallyHidden/VisuallyHidden.stories.tsx +1 -1
  92. package/src/hooks/index.tsx +0 -7
  93. package/src/hooks/useBreakpoint/useBreakpoint.ssr.test.tsx +18 -0
  94. package/src/hooks/useBreakpoint/useBreakpoint.stories.tsx +1 -1
  95. package/src/hooks/useBreakpoint/useBreakpoint.test.tsx +65 -5
  96. package/src/hooks/useBreakpoint/useBreakpoint.tsx +25 -39
  97. package/src/hooks/useButton/useButton.test.tsx +4 -4
  98. package/src/hooks/useDialog/useDialog.ts +1 -1
  99. package/src/hooks/useLabel/useLabel.test.tsx +1 -1
  100. package/src/hooks/useTextField/useTextField.test.tsx +4 -4
  101. package/src/public-whitelist.test.ts +1 -0
  102. package/src/utils/delay.test.ts +4 -4
  103. package/src/utils/{jestHTMLDialogPolyfill.ts → htmlDialogPolyfill.ts} +5 -5
  104. package/src/utils/index.ts +0 -1
  105. package/src/utils/mockMatchMedia.ts +16 -0
  106. package/dist/types/src/hooks/useBodyScrollLock/index.d.ts +0 -1
  107. package/dist/types/src/hooks/useBodyScrollLock/useBodyScrollLock.d.ts +0 -3
  108. package/dist/types/src/hooks/useDebouncedValue/index.d.ts +0 -1
  109. package/dist/types/src/hooks/useDebouncedValue/useDebouncedValue.d.ts +0 -1
  110. package/dist/types/src/hooks/useOnClickOutside/index.d.ts +0 -1
  111. package/dist/types/src/hooks/useOnClickOutside/useOnClickOutside.d.ts +0 -2
  112. package/dist/types/src/hooks/useOnUnmount/index.d.ts +0 -1
  113. package/dist/types/src/hooks/useOnUnmount/useOnUnmount.d.ts +0 -1
  114. package/dist/types/src/hooks/usePrefersReducedMotion/index.d.ts +0 -1
  115. package/dist/types/src/hooks/usePrefersReducedMotion/usePrefersReducedMotion.d.ts +0 -1
  116. package/dist/types/src/hooks/useRenderCount/index.d.ts +0 -1
  117. package/dist/types/src/hooks/useRenderCount/useRenderCount.d.ts +0 -1
  118. package/dist/types/src/hooks/useWindowEvent/index.d.ts +0 -1
  119. package/dist/types/src/hooks/useWindowEvent/useWindowEvent.d.ts +0 -1
  120. package/dist/types/src/utils/jestHTMLDialogPolyfill.d.ts +0 -1
  121. package/dist/types/src/utils/jestMockMatchMedia.d.ts +0 -1
  122. package/src/hooks/useBodyScrollLock/index.ts +0 -1
  123. package/src/hooks/useBodyScrollLock/useBodyScrollLock.test.ts +0 -34
  124. package/src/hooks/useBodyScrollLock/useBodyScrollLock.ts +0 -30
  125. package/src/hooks/useDebouncedValue/index.tsx +0 -1
  126. package/src/hooks/useDebouncedValue/useDebouncedValue.test.tsx +0 -62
  127. package/src/hooks/useDebouncedValue/useDebouncedValue.tsx +0 -25
  128. package/src/hooks/useOnClickOutside/index.tsx +0 -1
  129. package/src/hooks/useOnClickOutside/useOnClickOutside.test.tsx +0 -189
  130. package/src/hooks/useOnClickOutside/useOnClickOutside.tsx +0 -44
  131. package/src/hooks/useOnUnmount/index.tsx +0 -1
  132. package/src/hooks/useOnUnmount/useOnUnmount.test.tsx +0 -37
  133. package/src/hooks/useOnUnmount/useOnUnmount.tsx +0 -8
  134. package/src/hooks/usePrefersReducedMotion/index.tsx +0 -1
  135. package/src/hooks/usePrefersReducedMotion/usePrefersReducedMotion.test.tsx +0 -48
  136. package/src/hooks/usePrefersReducedMotion/usePrefersReducedMotion.tsx +0 -22
  137. package/src/hooks/useRenderCount/index.ts +0 -1
  138. package/src/hooks/useRenderCount/useRenderCount.test.ts +0 -26
  139. package/src/hooks/useRenderCount/useRenderCount.ts +0 -9
  140. package/src/hooks/useWindowEvent/index.tsx +0 -1
  141. package/src/hooks/useWindowEvent/useWindowEvent.test.tsx +0 -188
  142. package/src/hooks/useWindowEvent/useWindowEvent.tsx +0 -41
  143. package/src/utils/jestMockMatchMedia.ts +0 -16
@@ -1,14 +1,7 @@
1
- export * from "./useBodyScrollLock";
2
1
  export * from "./useBreakpoint";
3
2
  export * from "./useButton";
4
- export * from "./useDebouncedValue";
5
3
  export * from "./useDialog";
6
4
  export * from "./useDialogPolyfill";
7
5
  export * from "./useLabel";
8
- export * from "./useOnClickOutside";
9
- export * from "./useOnUnmount";
10
- export * from "./usePrefersReducedMotion";
11
- export * from "./useRenderCount";
12
6
  export * from "./useTextField";
13
7
  export * from "./useValidationClasses";
14
- export * from "./useWindowEvent";
@@ -0,0 +1 @@
1
+ export declare const htmlDialogPolyfill: () => void;
@@ -3,7 +3,6 @@ export * from "./delay";
3
3
  export * from "./excludeControls";
4
4
  export * from "./filterUndefinedProps";
5
5
  export * from "./getSpacingValue";
6
- export * from "./jestHTMLDialogPolyfill";
7
6
  export * from "./mergeRefs";
8
7
  export * from "./polyfill-tests";
9
8
  export * from "./sizeClasses";
@@ -0,0 +1 @@
1
+ export declare const mockMatchMedia: (matches: boolean) => void;
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vite").UserConfig;
2
+ export default _default;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@simplybusiness/mobius",
3
3
  "license": "UNLICENSED",
4
- "version": "8.0.1",
4
+ "version": "9.0.0",
5
5
  "description": "Core library of Mobius react components",
6
6
  "repository": {
7
7
  "type": "git",
@@ -10,8 +10,7 @@
10
10
  "simplyBusiness": {
11
11
  "publishToPublicNpm": true
12
12
  },
13
- "type": "module",
14
- "main": "dist/esm/index.js",
13
+ "main": "dist/cjs/index.js",
15
14
  "types": "./dist/types/index.d.ts",
16
15
  "files": [
17
16
  "src",
@@ -20,18 +19,20 @@
20
19
  "exports": {
21
20
  ".": {
22
21
  "types": "./dist/types/index.d.ts",
22
+ "require": "./dist/cjs/index.js",
23
23
  "import": "./dist/esm/index.js",
24
24
  "default": "./dist/esm/index.js"
25
25
  },
26
26
  "./src/*.css": "./src/*.css"
27
27
  },
28
28
  "publishConfig": {
29
- "main": "dist/esm/index.js",
29
+ "main": "dist/cjs/index.js",
30
30
  "module": "dist/esm/index.js",
31
31
  "types": "./dist/types/index.d.ts",
32
32
  "exports": {
33
33
  ".": {
34
34
  "types": "./dist/types/index.d.ts",
35
+ "require": "./dist/cjs/index.js",
35
36
  "import": "./dist/esm/index.js",
36
37
  "default": "./dist/esm/index.js"
37
38
  },
@@ -41,13 +42,14 @@
41
42
  "scripts": {
42
43
  "clean": "rm -rf dist",
43
44
  "build": "yarn run -T turbo run turbo:build",
44
- "turbo:build": "yarn build:esm && yarn build:types",
45
+ "turbo:build": "yarn build:esm && yarn build:cjs && yarn build:types",
45
46
  "build:esm": "build-package esm",
47
+ "build:cjs": "build-package cjs",
46
48
  "build:types": "tsc --emitDeclarationOnly --project tsconfig.build.json",
47
49
  "lint": "eslint . --cache",
48
50
  "lint:fix": "eslint . --fix",
49
- "test": "NODE_OPTIONS=--experimental-vm-modules jest",
50
- "test:coverage": "NODE_OPTIONS=--experimental-vm-modules jest --collect-coverage",
51
+ "test": "vitest run",
52
+ "test:coverage": "vitest run --coverage",
51
53
  "check-types": "tsc --noEmit --pretty",
52
54
  "size": "turbo run turbo:size --",
53
55
  "turbo:size": "yarn workspace @simplybusiness/bundle-checker start",
@@ -63,32 +65,26 @@
63
65
  "@simplybusiness/build-scripts": "^2.0.1",
64
66
  "@simplybusiness/eslint-config": "^2.0.1",
65
67
  "@simplybusiness/eslint-plugin": "^1.2.1",
66
- "@swc/core": "^1.12.5",
67
- "@swc/jest": "^0.2.39",
68
68
  "@testing-library/dom": "^10.4.1",
69
69
  "@testing-library/jest-dom": "6.9.1",
70
70
  "@testing-library/react": "^16.3.2",
71
71
  "@testing-library/user-event": "^14.6.1",
72
72
  "@total-typescript/shoehorn": "^0.1.2",
73
- "@types/jest": "^30.0.0",
74
- "@types/lodash.debounce": "^4.0.9",
75
73
  "@types/node": "^25.2.0",
76
74
  "@types/react": "^19.2.11",
77
75
  "@types/react-dom": "^19.2.3",
78
76
  "@typescript-eslint/eslint-plugin": "^8.54.0",
79
77
  "@typescript-eslint/parser": "^8.54.0",
78
+ "@vitest/coverage-v8": "^4.0.18",
80
79
  "csstype": "^3.2.3",
81
80
  "eslint": "^9.39.2",
82
81
  "eslint-plugin-ssr-friendly": "^1.3.0",
83
- "identity-obj-proxy": "^3.0.0",
84
- "jest": "^30.2.0",
85
- "jest-config": "^30.2.0",
86
- "jest-environment-jsdom": "^30.2.0",
87
82
  "prettier": "^3.8.1",
88
83
  "react": "^19.2.4",
89
84
  "react-dom": "^19.2.4",
90
85
  "tslib": "^2.8.1",
91
- "typescript": "^5.9.3"
86
+ "typescript": "^5.9.3",
87
+ "vitest": "^4.0.18"
92
88
  },
93
89
  "peerDependencies": {
94
90
  "react": "^19.2.0",
@@ -96,10 +92,10 @@
96
92
  },
97
93
  "dependencies": {
98
94
  "@floating-ui/react": "^0.27.17",
99
- "@simplybusiness/icons": "^5.0.1",
95
+ "@simplybusiness/icons": "^5.0.2",
96
+ "@simplybusiness/mobius-hooks": "^0.1.0",
100
97
  "classnames": "^2.5.1",
101
98
  "dialog-polyfill": "^0.5.6",
102
- "lodash.debounce": "^4.0.8",
103
99
  "react-accessible-dropdown-menu-hook": "^4.0.1",
104
100
  "react-imask": "^7.6.1",
105
101
  "sonner": "^2.0.7"
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from "@storybook/react-webpack5";
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
2
  import type { AccordionProps } from "..";
3
3
  import { Accordion, Button, Segment, SegmentGroup } from "..";
4
4
  import { excludeControls } from "../../utils";
@@ -2,7 +2,7 @@ import { fireEvent, render, screen } from "@testing-library/react";
2
2
  import userEvent from "@testing-library/user-event";
3
3
  import type { AccordionLinkElementType } from "./AccordionLink";
4
4
  import { Accordion } from ".";
5
- import { jestMockMatchMedia } from "../../utils/jestMockMatchMedia";
5
+ import { mockMatchMedia } from "../../utils/mockMatchMedia";
6
6
 
7
7
  const CONTAINER_CLASS_NAME = "mobius-accordion";
8
8
  const CONTENT_CONTAINER_CLASS_NAME = "mobius-accordion__content-container";
@@ -14,7 +14,7 @@ const CLOSE_TEXT = "See less";
14
14
 
15
15
  describe("Accordion", () => {
16
16
  beforeEach(() => {
17
- jestMockMatchMedia(true);
17
+ mockMatchMedia(true);
18
18
  });
19
19
 
20
20
  it("should render without errors", () => {
@@ -165,7 +165,7 @@ describe("Accordion", () => {
165
165
 
166
166
  describe("events", () => {
167
167
  it("calls onChange when accordion is toggled", () => {
168
- const onChange = jest.fn();
168
+ const onChange = vi.fn();
169
169
 
170
170
  render(<Accordion onChange={onChange}>Sample Text</Accordion>);
171
171
 
@@ -181,8 +181,8 @@ describe("Accordion", () => {
181
181
  });
182
182
 
183
183
  it("calls onOpen when accordion is opened", () => {
184
- const onOpen = jest.fn();
185
- const onClose = jest.fn();
184
+ const onOpen = vi.fn();
185
+ const onClose = vi.fn();
186
186
 
187
187
  render(
188
188
  <Accordion onOpen={onOpen} onClose={onClose}>
@@ -199,8 +199,8 @@ describe("Accordion", () => {
199
199
  });
200
200
 
201
201
  it("calls onClose when accordion is closed", () => {
202
- const onOpen = jest.fn();
203
- const onClose = jest.fn();
202
+ const onOpen = vi.fn();
203
+ const onClose = vi.fn();
204
204
 
205
205
  render(
206
206
  <Accordion startOpen onOpen={onOpen} onClose={onClose}>
@@ -227,7 +227,7 @@ describe("Accordion", () => {
227
227
 
228
228
  describe("keyboard navigation", () => {
229
229
  it("should open on Enter key", async () => {
230
- const toggle = jest.fn();
230
+ const toggle = vi.fn();
231
231
  render(<Accordion onChange={toggle}>Sample text</Accordion>);
232
232
 
233
233
  await userEvent.tab();
@@ -237,7 +237,7 @@ describe("Accordion", () => {
237
237
  });
238
238
 
239
239
  it("should open on Space key", async () => {
240
- const toggle = jest.fn();
240
+ const toggle = vi.fn();
241
241
  render(<Accordion onChange={toggle}>Sample text</Accordion>);
242
242
 
243
243
  await userEvent.tab();
@@ -247,7 +247,7 @@ describe("Accordion", () => {
247
247
  });
248
248
 
249
249
  it("should not open on Tab key", async () => {
250
- const toggle = jest.fn();
250
+ const toggle = vi.fn();
251
251
  render(<Accordion onChange={toggle}>Sample text</Accordion>);
252
252
 
253
253
  await userEvent.tab();
@@ -259,7 +259,7 @@ describe("Accordion", () => {
259
259
 
260
260
  describe("semantic heading", () => {
261
261
  it("uses span by default", () => {
262
- const toggle = jest.fn();
262
+ const toggle = vi.fn();
263
263
  const { container } = render(
264
264
  <Accordion onChange={toggle}>Sample text</Accordion>,
265
265
  );
@@ -273,7 +273,7 @@ describe("Accordion", () => {
273
273
  it.each(["h1", "h2", "h3", "h4", "h5", "h6"])(
274
274
  "uses heading type %s",
275
275
  headingType => {
276
- const toggle = jest.fn();
276
+ const toggle = vi.fn();
277
277
  const { container } = render(
278
278
  <Accordion
279
279
  onChange={toggle}
@@ -3,7 +3,7 @@
3
3
  import classNames from "classnames/dedupe";
4
4
  import type { ReactNode, RefAttributes } from "react";
5
5
  import { useEffect, useState, useId } from "react";
6
- import { usePrefersReducedMotion } from "../../hooks";
6
+ import { usePrefersReducedMotion } from "@simplybusiness/mobius-hooks";
7
7
  import type { DOMProps } from "../../types";
8
8
 
9
9
  import type {
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from "@storybook/react-webpack5";
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
2
  import type { AccordionListProps } from "./AccordionList";
3
3
  import { AccordionList } from "./AccordionList";
4
4
 
@@ -1,12 +1,12 @@
1
1
  import { fireEvent, render, screen } from "@testing-library/react";
2
2
  import { AccordionList } from "./AccordionList";
3
- import { jestMockMatchMedia } from "../../utils/jestMockMatchMedia";
3
+ import { mockMatchMedia } from "../../utils/mockMatchMedia";
4
4
 
5
5
  const ACCORDION_LIST_CLASS_NAME = "mobius-accordion-list";
6
6
 
7
7
  describe("AccordionList", () => {
8
8
  beforeEach(() => {
9
- jestMockMatchMedia(true);
9
+ mockMatchMedia(true);
10
10
  });
11
11
 
12
12
  const mockContent = [
@@ -73,7 +73,7 @@ describe("AccordionList", () => {
73
73
  });
74
74
 
75
75
  it("should call onOpen callback with correct id", () => {
76
- const onOpen = jest.fn();
76
+ const onOpen = vi.fn();
77
77
  render(<AccordionList content={mockContent} onOpen={onOpen} />);
78
78
 
79
79
  const section2Toggle = screen.getByText("Section 2");
@@ -83,7 +83,7 @@ describe("AccordionList", () => {
83
83
  });
84
84
 
85
85
  it("should call onClose callback with correct id", () => {
86
- const onClose = jest.fn();
86
+ const onClose = vi.fn();
87
87
  render(<AccordionList content={mockContent} onClose={onClose} />);
88
88
 
89
89
  const section1Toggle = screen.getByText("Section 1");
@@ -187,8 +187,8 @@ describe("AccordionList", () => {
187
187
  });
188
188
 
189
189
  it("should call onOpen and onClose callbacks correctly when allowMultiple is true", () => {
190
- const onOpen = jest.fn();
191
- const onClose = jest.fn();
190
+ const onOpen = vi.fn();
191
+ const onClose = vi.fn();
192
192
  render(
193
193
  <AccordionList
194
194
  content={mockContent}
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from "@storybook/react-webpack5";
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
2
  import { useState } from "react";
3
3
  import { AddressLookup, type AddressLookupProps } from ".";
4
4
  import { excludeControls } from "../../utils";
@@ -3,8 +3,8 @@ import userEvent from "@testing-library/user-event";
3
3
  import { AddressLookup } from "./AddressLookup";
4
4
  import { LoqateAddressLookupService } from "./LoqateAddressLookupService";
5
5
 
6
- // Ensure Jest uses the mock from the __mocks__ directory
7
- jest.mock("./__mocks__/LoqateAddressLookupService");
6
+ // Ensure Vitest uses the mock from the __mocks__ directory
7
+ vi.mock("./__mocks__/LoqateAddressLookupService");
8
8
 
9
9
  describe("AddressLookup", () => {
10
10
  let addressLookupService: LoqateAddressLookupService;
@@ -17,7 +17,7 @@ describe("AddressLookup", () => {
17
17
  });
18
18
 
19
19
  afterEach(() => {
20
- jest.clearAllMocks();
20
+ vi.clearAllMocks();
21
21
  });
22
22
 
23
23
  it("renders without errors", () => {
@@ -41,7 +41,7 @@ describe("AddressLookup", () => {
41
41
  });
42
42
 
43
43
  it("calls address lookup service after typing 3 or more characters", async () => {
44
- const findSpy = jest.spyOn(addressLookupService, "search");
44
+ const findSpy = vi.spyOn(addressLookupService, "search");
45
45
  render(
46
46
  <AddressLookup
47
47
  addressLookupService={addressLookupService}
@@ -61,9 +61,9 @@ describe("AddressLookup", () => {
61
61
  });
62
62
 
63
63
  it("should display an error message when the address lookup service fails", async () => {
64
- jest
65
- .spyOn(addressLookupService, "search")
66
- .mockRejectedValueOnce(new Error("Test error"));
64
+ vi.spyOn(addressLookupService, "search").mockRejectedValueOnce(
65
+ new Error("Test error"),
66
+ );
67
67
  render(
68
68
  <AddressLookup
69
69
  addressLookupService={addressLookupService}
@@ -79,7 +79,7 @@ describe("AddressLookup", () => {
79
79
  });
80
80
 
81
81
  it("should show an error message when the address retrieval fails", async () => {
82
- jest.spyOn(addressLookupService, "search").mockResolvedValueOnce({
82
+ vi.spyOn(addressLookupService, "search").mockResolvedValueOnce({
83
83
  Items: [
84
84
  {
85
85
  Id: "123",
@@ -90,9 +90,9 @@ describe("AddressLookup", () => {
90
90
  },
91
91
  ],
92
92
  });
93
- jest
94
- .spyOn(addressLookupService, "get")
95
- .mockRejectedValueOnce(new Error("Test error"));
93
+ vi.spyOn(addressLookupService, "get").mockRejectedValueOnce(
94
+ new Error("Test error"),
95
+ );
96
96
  render(
97
97
  <AddressLookup
98
98
  addressLookupService={addressLookupService}
@@ -111,8 +111,7 @@ describe("AddressLookup", () => {
111
111
  });
112
112
 
113
113
  it("should clear the error message when a valid address is selected", async () => {
114
- jest
115
- .spyOn(addressLookupService, "search")
114
+ vi.spyOn(addressLookupService, "search")
116
115
  .mockRejectedValueOnce(new Error("Test error"))
117
116
  .mockResolvedValueOnce({
118
117
  Items: [
@@ -155,9 +154,9 @@ describe("AddressLookup", () => {
155
154
  });
156
155
 
157
156
  it("should set an accessibile description when an error occurs", async () => {
158
- jest
159
- .spyOn(addressLookupService, "search")
160
- .mockRejectedValueOnce(new Error("Test error"));
157
+ vi.spyOn(addressLookupService, "search").mockRejectedValueOnce(
158
+ new Error("Test error"),
159
+ );
161
160
  render(
162
161
  <AddressLookup
163
162
  addressLookupService={addressLookupService}
@@ -176,8 +175,8 @@ describe("AddressLookup", () => {
176
175
 
177
176
  it("should call onError callback when an error occurs", async () => {
178
177
  const error = new Error("Test error");
179
- const onError = jest.fn();
180
- jest.spyOn(addressLookupService, "search").mockRejectedValueOnce(error);
178
+ const onError = vi.fn();
179
+ vi.spyOn(addressLookupService, "search").mockRejectedValueOnce(error);
181
180
 
182
181
  render(
183
182
  <AddressLookup
@@ -195,7 +194,7 @@ describe("AddressLookup", () => {
195
194
  });
196
195
 
197
196
  it("should call onOptionsDisplayed when valid results are displayed", async () => {
198
- jest.spyOn(addressLookupService, "search").mockResolvedValueOnce({
197
+ vi.spyOn(addressLookupService, "search").mockResolvedValueOnce({
199
198
  Items: [
200
199
  {
201
200
  Id: "123",
@@ -206,7 +205,7 @@ describe("AddressLookup", () => {
206
205
  },
207
206
  ],
208
207
  });
209
- const mockOnOptionsDisplayed = jest.fn();
208
+ const mockOnOptionsDisplayed = vi.fn();
210
209
  render(
211
210
  <AddressLookup
212
211
  addressLookupService={addressLookupService}
@@ -1,3 +1,4 @@
1
+ import type { Mock } from "vitest";
1
2
  import { LoqateAddressLookupService } from "./LoqateAddressLookupService";
2
3
 
3
4
  describe("LoqateAddressLookupService", () => {
@@ -48,13 +49,13 @@ describe("LoqateAddressLookupService", () => {
48
49
 
49
50
  // Helper function for mocking fetch responses
50
51
  const mockFetchResponse = (response: unknown) => {
51
- (global.fetch as jest.Mock).mockResolvedValueOnce({
52
+ (global.fetch as Mock).mockResolvedValueOnce({
52
53
  json: () => Promise.resolve(response),
53
54
  });
54
55
  };
55
56
 
56
57
  beforeEach(() => {
57
- global.fetch = jest.fn();
58
+ global.fetch = vi.fn();
58
59
  service = new LoqateAddressLookupService({
59
60
  baseUrl: mockBaseUrl,
60
61
  apiKey: mockApiKey,
@@ -63,7 +64,7 @@ describe("LoqateAddressLookupService", () => {
63
64
  });
64
65
 
65
66
  afterEach(() => {
66
- jest.resetAllMocks();
67
+ vi.resetAllMocks();
67
68
  });
68
69
 
69
70
  it("uses default base URL and countries when none is provided", async () => {
@@ -188,7 +189,7 @@ describe("LoqateAddressLookupService", () => {
188
189
 
189
190
  await serviceWithFilters.search("987 Park Avenue");
190
191
 
191
- const calledUrl = (global.fetch as jest.Mock).mock.calls[0][0];
192
+ const calledUrl = (global.fetch as Mock).mock.calls[0][0];
192
193
  expect(calledUrl).toContain("AdministrativeArea:NY");
193
194
  expect(calledUrl).not.toContain("AdministrativeArea%3ANY");
194
195
  });
@@ -235,7 +236,7 @@ describe("LoqateAddressLookupService", () => {
235
236
  `${mockBaseUrl}/Retrieve/v1.2/json3.ws?Key=${mockApiKey}&Id=address123`,
236
237
  );
237
238
 
238
- const calledUrl = (global.fetch as jest.Mock).mock.calls[0][0];
239
+ const calledUrl = (global.fetch as Mock).mock.calls[0][0];
239
240
  expect(calledUrl).not.toContain("Filters");
240
241
  });
241
242
  });
@@ -250,7 +251,7 @@ describe("LoqateAddressLookupService", () => {
250
251
 
251
252
  it("propagates rejected promises", async () => {
252
253
  const networkError = new Error("Network error");
253
- (global.fetch as jest.Mock).mockRejectedValueOnce(networkError);
254
+ (global.fetch as Mock).mockRejectedValueOnce(networkError);
254
255
 
255
256
  await expect(service.search("test")).rejects.toThrow(networkError);
256
257
  });
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from "@storybook/react-webpack5";
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
2
  import type { AlertProps } from "./Alert";
3
3
  import { Alert } from "./Alert";
4
4
 
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from "@storybook/react-webpack5";
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
2
  import { Box } from "./Box";
3
3
  import { excludeControls, sizeOptions } from "../../utils";
4
4
  import type { BoxProps } from "./types";
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from "@storybook/react-webpack5";
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
2
  import type { BreadcrumbsProps } from "./Breadcrumbs";
3
3
  import { Breadcrumbs } from "./Breadcrumbs";
4
4
  import { BreadcrumbItem } from "./BreadcrumbItem";
@@ -1,10 +1,12 @@
1
1
  import { useState } from "react";
2
- import type { Meta, StoryObj } from "@storybook/react-webpack5";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
3
  import { leftArrow, menu } from "@simplybusiness/icons";
4
4
  import type { ButtonProps } from "./Button";
5
5
  import { Button } from "./Button";
6
6
  import { Icon } from "../Icon";
7
7
  import { excludeControls } from "../../utils";
8
+ // eslint-disable-next-line no-restricted-imports -- story-only styles
9
+ import "./Button.story.styles.css";
8
10
 
9
11
  type StoryType = StoryObj<typeof Button>;
10
12
 
@@ -188,7 +190,6 @@ export const Disabled: StoryType = {
188
190
 
189
191
  export const WithIconOnTheLeft: StoryType = {
190
192
  render: (args: ButtonProps) => {
191
- require("./Button.story.styles.css");
192
193
  return <Button {...args} />;
193
194
  },
194
195
  args: {
@@ -210,7 +211,6 @@ export const WithIconOnTheLeft: StoryType = {
210
211
 
211
212
  export const WithIconOnTheRight: StoryType = {
212
213
  render: (args: ButtonProps) => {
213
- require("./Button.story.styles.css");
214
214
  return <Button {...args} />;
215
215
  },
216
216
  args: {
@@ -231,7 +231,6 @@ export const WithIconOnTheRight: StoryType = {
231
231
 
232
232
  export const Themed: StoryType = {
233
233
  render: (args: ButtonProps) => {
234
- require("./Button.story.styles.css");
235
234
  return <Button {...args} />;
236
235
  },
237
236
  args: {
@@ -8,21 +8,21 @@ const CLASS_NAME = "mobius-button";
8
8
 
9
9
  describe("Button", () => {
10
10
  it("should render without errors", () => {
11
- const error = jest.spyOn(global.console, "error");
12
- const onPress = jest.fn();
11
+ const error = vi.spyOn(global.console, "error");
12
+ const onPress = vi.fn();
13
13
  render(<Button onPress={onPress}>Sample text</Button>);
14
14
  expect(error).not.toHaveBeenCalled();
15
15
  });
16
16
 
17
17
  it("should call the onPress", async () => {
18
- const onPress = jest.fn();
18
+ const onPress = vi.fn();
19
19
  const { getByText } = render(<Button onPress={onPress}>Press</Button>);
20
20
  await userEvent.click(getByText("Press"));
21
21
  expect(onPress).toHaveBeenCalled();
22
22
  });
23
23
 
24
24
  it("should call the onClick", async () => {
25
- const onClick = jest.fn();
25
+ const onClick = vi.fn();
26
26
  const { getByText } = render(<Button onClick={onClick}>Click</Button>);
27
27
  await userEvent.click(getByText("Click"));
28
28
  expect(onClick).toHaveBeenCalled();
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from "@storybook/react-webpack5";
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
2
  import type { CheckboxProps } from ".";
3
3
  import { Checkbox } from ".";
4
4
  import { excludeControls } from "../../utils";
@@ -27,7 +27,7 @@ describe("Checkbox", () => {
27
27
  });
28
28
 
29
29
  it("should call onChange when clicked", async () => {
30
- const callback = jest.fn();
30
+ const callback = vi.fn();
31
31
  const optionText = "Agree";
32
32
 
33
33
  const { getByLabelText } = render(
@@ -43,7 +43,7 @@ describe("Checkbox", () => {
43
43
  });
44
44
 
45
45
  it("should be selectable via keyboard", async () => {
46
- const callback = jest.fn();
46
+ const callback = vi.fn();
47
47
  const optionText = "Agree";
48
48
 
49
49
  const { getByLabelText } = render(
@@ -1,4 +1,4 @@
1
- import type { Meta, StoryObj } from "@storybook/react-webpack5";
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
2
  import type { CheckboxGroupProps } from ".";
3
3
  import { Checkbox, CheckboxGroup } from ".";
4
4
  import { excludeControls } from "../../utils";
@@ -50,7 +50,7 @@ describe("CheckboxGroup", () => {
50
50
  });
51
51
 
52
52
  it("does not call onChange on initial render", () => {
53
- const callback = jest.fn();
53
+ const callback = vi.fn();
54
54
 
55
55
  render(
56
56
  <CheckboxGroup onChange={callback}>
@@ -82,7 +82,7 @@ describe("CheckboxGroup", () => {
82
82
  describe("onChange", () => {
83
83
  describe("given an item is toggled", () => {
84
84
  it("should call onChange with a list of toggled items", async () => {
85
- const callback = jest.fn();
85
+ const callback = vi.fn();
86
86
  const option1Text = "Checkbox 1";
87
87
  const option2Text = "Checkbox 2";
88
88
  const option3Text = "Checkbox 3";
@@ -119,7 +119,7 @@ describe("CheckboxGroup", () => {
119
119
 
120
120
  describe("given an item is untoggled", () => {
121
121
  it("should call onChange with a list of toggled items", async () => {
122
- const callback = jest.fn();
122
+ const callback = vi.fn();
123
123
  const option1Text = "Checkbox 1";
124
124
  const option2Text = "Checkbox 2";
125
125
  const option3Text = "Checkbox 3";
@@ -163,7 +163,7 @@ describe("CheckboxGroup", () => {
163
163
  });
164
164
 
165
165
  it("should be selectable via keyboard", async () => {
166
- const callback = jest.fn();
166
+ const callback = vi.fn();
167
167
  const optionText = "Agree";
168
168
 
169
169
  const { getByLabelText } = render(
@@ -572,7 +572,7 @@ describe("CheckboxGroup", () => {
572
572
  });
573
573
 
574
574
  it("should overwrite group value when last item is selected", async () => {
575
- const callback = jest.fn();
575
+ const callback = vi.fn();
576
576
 
577
577
  const option1Text = "Checkbox 1";
578
578
  const option2Text = "Checkbox 2";
@@ -1,5 +1,5 @@
1
1
  import { search } from "@simplybusiness/icons";
2
- import type { Meta } from "@storybook/react-webpack5";
2
+ import type { Meta } from "@storybook/react";
3
3
  import type { ComboboxRef } from ".";
4
4
  import { Combobox, type ComboboxProps } from ".";
5
5
  import { delay, excludeControls } from "../../utils";