@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,188 +0,0 @@
1
- import { renderHook, act } from "@testing-library/react";
2
- import { useWindowEvent } from "./useWindowEvent";
3
-
4
- describe("useWindowEvent", () => {
5
- const addEventListenerSpy = jest.spyOn(window, "addEventListener");
6
- const removeEventListenerSpy = jest.spyOn(window, "removeEventListener");
7
-
8
- beforeEach(() => {
9
- addEventListenerSpy.mockClear();
10
- removeEventListenerSpy.mockClear();
11
- });
12
-
13
- afterAll(() => {
14
- addEventListenerSpy.mockRestore();
15
- removeEventListenerSpy.mockRestore();
16
- });
17
-
18
- it("adds event listener on mount", () => {
19
- const handler = jest.fn();
20
- renderHook(() => useWindowEvent("click", handler));
21
-
22
- expect(addEventListenerSpy).toHaveBeenCalledWith(
23
- "click",
24
- expect.any(Function),
25
- expect.objectContaining({ signal: expect.any(AbortSignal) }),
26
- );
27
- });
28
-
29
- it("removes event listener on unmount", () => {
30
- const handler = jest.fn();
31
- const { unmount } = renderHook(() => useWindowEvent("click", handler));
32
-
33
- removeEventListenerSpy.mockClear();
34
- unmount();
35
-
36
- expect(removeEventListenerSpy).toHaveBeenCalledWith(
37
- "click",
38
- expect.any(Function),
39
- expect.objectContaining({ signal: expect.any(AbortSignal) }),
40
- );
41
- });
42
-
43
- it("calls listener when event fires", () => {
44
- const handler = jest.fn();
45
- renderHook(() => useWindowEvent("click", handler));
46
-
47
- act(() => {
48
- window.dispatchEvent(new MouseEvent("click", { bubbles: true }));
49
- });
50
-
51
- expect(handler).toHaveBeenCalledTimes(1);
52
- });
53
-
54
- it("uses latest listener without re-subscribing (useEffectEvent behavior)", () => {
55
- const handler1 = jest.fn();
56
- const handler2 = jest.fn();
57
-
58
- const { rerender } = renderHook(
59
- ({ listener }) => useWindowEvent("click", listener),
60
- { initialProps: { listener: handler1 } },
61
- );
62
-
63
- // Clear the spy to only count new subscriptions
64
- addEventListenerSpy.mockClear();
65
-
66
- // Rerender with new handler
67
- rerender({ listener: handler2 });
68
-
69
- // Should not re-subscribe (useEffectEvent handles this)
70
- expect(addEventListenerSpy).not.toHaveBeenCalled();
71
-
72
- // Trigger event - should call the new handler
73
- act(() => {
74
- window.dispatchEvent(new MouseEvent("click", { bubbles: true }));
75
- });
76
-
77
- expect(handler1).not.toHaveBeenCalled();
78
- expect(handler2).toHaveBeenCalledTimes(1);
79
- });
80
-
81
- it("re-subscribes when type changes", () => {
82
- const handler = jest.fn();
83
-
84
- const { rerender } = renderHook<void, { type: "click" | "keydown" }>(
85
- ({ type }) => useWindowEvent(type, handler),
86
- {
87
- initialProps: { type: "click" },
88
- },
89
- );
90
-
91
- addEventListenerSpy.mockClear();
92
- removeEventListenerSpy.mockClear();
93
-
94
- // Change event type
95
- rerender({ type: "keydown" });
96
-
97
- // Should remove old listener and add new one
98
- expect(removeEventListenerSpy).toHaveBeenCalledWith(
99
- "click",
100
- expect.any(Function),
101
- expect.any(Object),
102
- );
103
- expect(addEventListenerSpy).toHaveBeenCalledWith(
104
- "keydown",
105
- expect.any(Function),
106
- expect.any(Object),
107
- );
108
- });
109
-
110
- it("re-subscribes when options change", () => {
111
- const handler = jest.fn();
112
-
113
- const { rerender } = renderHook(
114
- ({ options }) => useWindowEvent("click", handler, options),
115
- { initialProps: { options: { capture: false } } },
116
- );
117
-
118
- addEventListenerSpy.mockClear();
119
- removeEventListenerSpy.mockClear();
120
-
121
- // Change options
122
- rerender({ options: { capture: true } });
123
-
124
- // Should re-subscribe with new options
125
- expect(removeEventListenerSpy).toHaveBeenCalled();
126
- expect(addEventListenerSpy).toHaveBeenCalledWith(
127
- "click",
128
- expect.any(Function),
129
- expect.objectContaining({ capture: true }),
130
- );
131
- });
132
-
133
- it("handles boolean options (capture: true)", () => {
134
- const handler = jest.fn();
135
- renderHook(() => useWindowEvent("click", handler, { capture: true }));
136
-
137
- expect(addEventListenerSpy).toHaveBeenCalledWith(
138
- "click",
139
- expect.any(Function),
140
- expect.objectContaining({ capture: true }),
141
- );
142
- });
143
-
144
- it("handles undefined options", () => {
145
- const handler = jest.fn();
146
- renderHook(() => useWindowEvent("click", handler));
147
-
148
- expect(addEventListenerSpy).toHaveBeenCalledWith(
149
- "click",
150
- expect.any(Function),
151
- expect.objectContaining({ signal: expect.any(AbortSignal) }),
152
- );
153
- });
154
-
155
- it("AbortController cleanup works on unmount", () => {
156
- const handler = jest.fn();
157
- const { unmount } = renderHook(() => useWindowEvent("click", handler));
158
-
159
- // Get the signal that was passed to addEventListener
160
- const addCall = addEventListenerSpy.mock.calls[0];
161
- const options = addCall[2] as AddEventListenerOptions;
162
- const signal = options.signal as AbortSignal;
163
-
164
- expect(signal.aborted).toBe(false);
165
-
166
- unmount();
167
-
168
- expect(signal.aborted).toBe(true);
169
- });
170
-
171
- it("works with different window events", () => {
172
- const resizeHandler = jest.fn();
173
- const scrollHandler = jest.fn();
174
-
175
- renderHook(() => {
176
- useWindowEvent("resize", resizeHandler);
177
- useWindowEvent("scroll", scrollHandler);
178
- });
179
-
180
- act(() => {
181
- window.dispatchEvent(new Event("resize"));
182
- window.dispatchEvent(new Event("scroll"));
183
- });
184
-
185
- expect(resizeHandler).toHaveBeenCalledTimes(1);
186
- expect(scrollHandler).toHaveBeenCalledTimes(1);
187
- });
188
- });
@@ -1,41 +0,0 @@
1
- "use client";
2
-
3
- import { useEffect, useEffectEvent } from "react";
4
-
5
- function normaliseOptions(
6
- options?: boolean | AddEventListenerOptions,
7
- otherOptions: AddEventListenerOptions = {},
8
- ): AddEventListenerOptions {
9
- if (typeof options === "undefined") {
10
- return otherOptions;
11
- }
12
-
13
- if (typeof options === "boolean") {
14
- return { capture: options, ...otherOptions };
15
- }
16
-
17
- return { ...options, ...otherOptions };
18
- }
19
-
20
- export function useWindowEvent<EventType extends keyof WindowEventMap>(
21
- type: EventType,
22
- listener: (this: Window, ev: WindowEventMap[EventType]) => unknown,
23
- options?: AddEventListenerOptions,
24
- ): void {
25
- // useEffectEvent creates a stable reference to the callback
26
- // that always calls the latest version of the listener
27
- const stableListener = useEffectEvent(listener);
28
-
29
- useEffect(() => {
30
- // Create an abort controller to abort the event listener if the hook is re-rendered
31
- const controller = new AbortController();
32
- const { signal } = controller;
33
- const normalisedOptions = normaliseOptions(options, { signal });
34
-
35
- window.addEventListener(type, stableListener, normalisedOptions);
36
- return () => {
37
- controller.abort();
38
- window.removeEventListener(type, stableListener, normalisedOptions);
39
- };
40
- }, [type, options]);
41
- }
@@ -1,16 +0,0 @@
1
- export const jestMockMatchMedia = (matches: boolean) => {
2
- Object.defineProperty(window, "matchMedia", {
3
- writable: true,
4
- configurable: true,
5
- value: jest.fn().mockImplementation(query => ({
6
- matches,
7
- media: query,
8
- onchange: null,
9
- addListener: jest.fn(),
10
- removeListener: jest.fn(),
11
- addEventListener: jest.fn(),
12
- removeEventListener: jest.fn(),
13
- dispatchEvent: jest.fn(),
14
- })),
15
- });
16
- };