@lumx/react 3.19.1-alpha.1 → 3.19.1-alpha.11

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 (42) hide show
  1. package/index.js +99 -56
  2. package/index.js.map +1 -1
  3. package/package.json +8 -10
  4. package/src/components/alert-dialog/AlertDialog.test.tsx +3 -2
  5. package/src/components/autocomplete/Autocomplete.test.tsx +3 -3
  6. package/src/components/button/Button.test.tsx +4 -4
  7. package/src/components/checkbox/Checkbox.test.tsx +3 -3
  8. package/src/components/chip/Chip.test.tsx +19 -17
  9. package/src/components/date-picker/DatePicker.test.tsx +3 -3
  10. package/src/components/date-picker/DatePickerControlled.test.tsx +6 -6
  11. package/src/components/date-picker/DatePickerField.test.tsx +3 -3
  12. package/src/components/dialog/Dialog.test.tsx +4 -4
  13. package/src/components/dropdown/Dropdown.test.tsx +3 -3
  14. package/src/components/expansion-panel/ExpansionPanel.test.tsx +6 -5
  15. package/src/components/image-lightbox/ImageLightbox.test.tsx +11 -7
  16. package/src/components/link/Link.test.tsx +5 -5
  17. package/src/components/list/ListItem.test.tsx +8 -6
  18. package/src/components/list/ListItem.tsx +32 -19
  19. package/src/components/message/Message.test.tsx +1 -1
  20. package/src/components/mosaic/Mosaic.test.tsx +3 -3
  21. package/src/components/notification/Notification.test.tsx +4 -3
  22. package/src/components/popover-dialog/PopoverDialog.test.tsx +1 -1
  23. package/src/components/radio-button/RadioButton.test.tsx +3 -3
  24. package/src/components/select/Select.test.tsx +8 -7
  25. package/src/components/select/SelectMultiple.test.tsx +5 -5
  26. package/src/components/side-navigation/SideNavigationItem.test.tsx +2 -2
  27. package/src/components/slider/Slider.test.tsx +1 -1
  28. package/src/components/switch/Switch.test.tsx +5 -5
  29. package/src/components/table/TableCell.test.tsx +1 -1
  30. package/src/components/text-field/TextField.test.tsx +9 -8
  31. package/src/components/thumbnail/Thumbnail.test.tsx +4 -4
  32. package/src/components/thumbnail/Thumbnail.tsx +4 -3
  33. package/src/components/tooltip/Tooltip.test.tsx +14 -8
  34. package/src/components/uploader/Uploader.test.tsx +2 -2
  35. package/src/components/user-block/UserBlock.test.tsx +1 -1
  36. package/src/untypped-modules.d.ts +4 -0
  37. package/src/utils/Portal/PortalProvider.test.tsx +1 -1
  38. package/src/utils/date/getYearDisplayName.test.ts +1 -1
  39. package/src/utils/disabled/useDisableStateProps.test.tsx +2 -2
  40. package/src/utils/react/RawClickable.test.tsx +11 -11
  41. package/src/utils/react/RawClickable.tsx +1 -1
  42. package/src/utils/react/renderLink.tsx +17 -0
package/package.json CHANGED
@@ -6,8 +6,8 @@
6
6
  "url": "https://github.com/lumapps/design-system/issues"
7
7
  },
8
8
  "dependencies": {
9
- "@lumx/core": "^3.19.1-alpha.1",
10
- "@lumx/icons": "^3.19.1-alpha.1",
9
+ "@lumx/core": "^3.19.1-alpha.11",
10
+ "@lumx/icons": "^3.19.1-alpha.11",
11
11
  "@popperjs/core": "^2.5.4",
12
12
  "body-scroll-lock": "^3.1.5",
13
13
  "classnames": "^2.3.2",
@@ -33,20 +33,18 @@
33
33
  "@storybook/addon-a11y": "^9.1.4",
34
34
  "@storybook/addon-docs": "^9.1.4",
35
35
  "@storybook/react-vite": "^9.1.4",
36
- "@testing-library/dom": "^9.3.4",
37
- "@testing-library/jest-dom": "^5.16.4",
36
+ "@testing-library/dom": "^10.4.1",
38
37
  "@testing-library/react": "^12.1.2",
39
38
  "@testing-library/user-event": "^14.4.3",
40
39
  "@types/body-scroll-lock": "^2.6.1",
41
40
  "@types/classnames": "^2.2.9",
42
41
  "@types/dom-view-transitions": "^1.0.5",
43
- "@types/jest": "^29.2.1",
44
42
  "@types/lodash": "^4.14.149",
45
43
  "@types/react": "^17.0.2",
46
44
  "@types/react-dom": "^17.0.2",
47
45
  "@types/react-is": "^17.0.2",
46
+ "@vitest/ui": "^1.0.0",
48
47
  "autoprefixer": "^9.7.4",
49
- "babel-jest": "29.1.2",
50
48
  "babel-loader": "^8.0.6",
51
49
  "chromatic": "^13.1.4",
52
50
  "core-js": "^3.6.4",
@@ -54,8 +52,7 @@
54
52
  "glob": "^7.1.6",
55
53
  "install-peers-cli": "^2.2.0",
56
54
  "is-ci": "^2.0.0",
57
- "jest": "29.1.2",
58
- "jest-environment-jsdom": "29.1.2",
55
+ "jsdom": "^27.2.0",
59
56
  "node-notifier": "^10.0.1",
60
57
  "react": "^17.0.2",
61
58
  "react-dom": "^17.0.2",
@@ -70,6 +67,7 @@
70
67
  "typescript": "^5.4.3",
71
68
  "vite": "^6.3.5",
72
69
  "vite-tsconfig-paths": "^5.1.4",
70
+ "vitest": "^1.0.0",
73
71
  "yargs": "^15.4.1"
74
72
  },
75
73
  "peerDependencies": {
@@ -100,10 +98,10 @@
100
98
  "scripts": {
101
99
  "build": "rollup -c",
102
100
  "prepare": "install-peers || exit 0",
103
- "test": "jest --config jest/index.js --coverage --notify --passWithNoTests --detectOpenHandles --runInBand",
101
+ "test": "vitest run",
104
102
  "start:storybook": "storybook dev -p 9000",
105
103
  "build:storybook": "storybook build"
106
104
  },
107
105
  "sideEffects": false,
108
- "version": "3.19.1-alpha.1"
106
+ "version": "3.19.1-alpha.11"
109
107
  }
@@ -3,9 +3,10 @@ import React from 'react';
3
3
  import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
4
4
  import { queryByClassName } from '@lumx/react/testing/utils/queries';
5
5
  import { render } from '@testing-library/react';
6
+ import { vi } from 'vitest';
6
7
  import { AlertDialog, AlertDialogProps } from './AlertDialog';
7
8
 
8
- jest.mock('@lumx/react/hooks/useId', () => ({ useId: () => ':r1:' }));
9
+ vi.mock('@lumx/react/hooks/useId', () => ({ useId: () => ':r1:' }));
9
10
 
10
11
  const CLASSNAME = AlertDialog.className as string;
11
12
 
@@ -17,7 +18,7 @@ const setup = (propsOverride: Partial<AlertDialogProps> = {}) => {
17
18
  title: 'Alert',
18
19
  isOpen: true,
19
20
  description: 'Deserunt et sunt qui consequat sint sit.',
20
- confirmProps: { onClick: jest.fn(), label: 'OK' },
21
+ confirmProps: { onClick: vi.fn(), label: 'OK' },
21
22
  ...propsOverride,
22
23
  };
23
24
  render(<AlertDialog {...props} />);
@@ -53,7 +53,7 @@ describe(`<${Autocomplete.displayName}>`, () => {
53
53
  describe('Events', () => {
54
54
  it('should trigger the onChange callback when there is a change on the Text Field', async () => {
55
55
  const name = 'autocomplete-name';
56
- const onChange = jest.fn();
56
+ const onChange = vi.fn();
57
57
  const { inputNative } = setup({
58
58
  name,
59
59
  onChange,
@@ -68,8 +68,8 @@ describe(`<${Autocomplete.displayName}>`, () => {
68
68
  });
69
69
 
70
70
  it('should trigger the onFocus/onBlur callback when the text field is focused and blurred', async () => {
71
- const onFocus = jest.fn();
72
- const onBlur = jest.fn();
71
+ const onFocus = vi.fn();
72
+ const onBlur = vi.fn();
73
73
  const { inputNative } = setup({
74
74
  onFocus,
75
75
  onBlur,
@@ -68,7 +68,7 @@ describe(`<${Button.displayName}>`, () => {
68
68
 
69
69
  describe('Disabled state', () => {
70
70
  it('should render disabled button', async () => {
71
- const onClick = jest.fn();
71
+ const onClick = vi.fn();
72
72
  const { button } = setup({ children: 'Label', disabled: true, onClick });
73
73
  expect(button).toHaveAttribute('disabled');
74
74
  await userEvent.click(button);
@@ -76,7 +76,7 @@ describe(`<${Button.displayName}>`, () => {
76
76
  });
77
77
 
78
78
  it('should render disabled link', async () => {
79
- const onClick = jest.fn();
79
+ const onClick = vi.fn();
80
80
  const { button } = setup({ children: 'Label', disabled: true, href: 'https://example.com', onClick });
81
81
  expect(screen.queryByRole('link')).toBeInTheDocument();
82
82
  expect(button).toHaveAttribute('aria-disabled', 'true');
@@ -87,7 +87,7 @@ describe(`<${Button.displayName}>`, () => {
87
87
  });
88
88
 
89
89
  it('should render aria-disabled button', async () => {
90
- const onClick = jest.fn();
90
+ const onClick = vi.fn();
91
91
  const { button } = setup({ children: 'Label', 'aria-disabled': true, onClick });
92
92
  expect(button).toHaveAttribute('aria-disabled');
93
93
  await userEvent.click(button);
@@ -95,7 +95,7 @@ describe(`<${Button.displayName}>`, () => {
95
95
  });
96
96
 
97
97
  it('should render aria-disabled link', async () => {
98
- const onClick = jest.fn();
98
+ const onClick = vi.fn();
99
99
  const { button } = setup({
100
100
  children: 'Label',
101
101
  'aria-disabled': true,
@@ -98,7 +98,7 @@ describe(`<${Checkbox.displayName}>`, () => {
98
98
  });
99
99
 
100
100
  describe('Events', () => {
101
- const onChange = jest.fn();
101
+ const onChange = vi.fn();
102
102
 
103
103
  it('should trigger `onChange` when checkbox is clicked', async () => {
104
104
  const value = 'value';
@@ -114,7 +114,7 @@ describe(`<${Checkbox.displayName}>`, () => {
114
114
 
115
115
  describe('Disabled state', () => {
116
116
  it('should be disabled with isDisabled', async () => {
117
- const onChange = jest.fn();
117
+ const onChange = vi.fn();
118
118
  const { checkbox, input } = setup({ isDisabled: true, onChange });
119
119
 
120
120
  expect(checkbox).toHaveClass('lumx-checkbox--is-disabled');
@@ -126,7 +126,7 @@ describe(`<${Checkbox.displayName}>`, () => {
126
126
  });
127
127
 
128
128
  it('should be disabled with aria-disabled', async () => {
129
- const onChange = jest.fn();
129
+ const onChange = vi.fn();
130
130
  const { checkbox, input } = setup({ 'aria-disabled': true, onChange });
131
131
 
132
132
  expect(checkbox).toHaveClass('lumx-checkbox--is-disabled');
@@ -42,7 +42,7 @@ describe('<Chip />', () => {
42
42
  });
43
43
 
44
44
  it('should render clickable', () => {
45
- const onClick = jest.fn();
45
+ const onClick = vi.fn();
46
46
  const { chip } = setup({ children: 'Chip text', onClick });
47
47
  expect(chip).toHaveAttribute('role', 'button');
48
48
  expect(chip.className).toMatchInlineSnapshot(
@@ -70,11 +70,13 @@ describe('<Chip />', () => {
70
70
  });
71
71
 
72
72
  describe('Events', () => {
73
- const onClick = jest.fn();
74
- const onAfterClick = jest.fn();
75
- const onBeforeClick = jest.fn();
73
+ const onClick = vi.fn();
74
+ const onAfterClick = vi.fn();
75
+ const onBeforeClick = vi.fn();
76
76
 
77
- beforeEach(jest.clearAllMocks);
77
+ beforeEach(() => {
78
+ vi.clearAllMocks();
79
+ });
78
80
 
79
81
  it('should trigger onBeforeClick only when clicking on the "before" element', async () => {
80
82
  const { after, before, chip } = setup({
@@ -88,12 +90,12 @@ describe('<Chip />', () => {
88
90
  await userEvent.click(chip);
89
91
  expect(onBeforeClick).not.toHaveBeenCalled();
90
92
 
91
- jest.clearAllMocks();
93
+ vi.clearAllMocks();
92
94
 
93
95
  await userEvent.click(after as any);
94
96
  expect(onBeforeClick).not.toHaveBeenCalled();
95
97
 
96
- jest.clearAllMocks();
98
+ vi.clearAllMocks();
97
99
 
98
100
  await userEvent.click(before as any);
99
101
  expect(onBeforeClick).toHaveBeenCalled();
@@ -111,12 +113,12 @@ describe('<Chip />', () => {
111
113
  await userEvent.click(chip);
112
114
  expect(onClick).toHaveBeenCalled();
113
115
 
114
- jest.clearAllMocks();
116
+ vi.clearAllMocks();
115
117
 
116
118
  await userEvent.click(after as any);
117
119
  expect(onClick).not.toHaveBeenCalled();
118
120
 
119
- jest.clearAllMocks();
121
+ vi.clearAllMocks();
120
122
 
121
123
  await userEvent.click(before as any);
122
124
  expect(onClick).not.toHaveBeenCalled();
@@ -134,12 +136,12 @@ describe('<Chip />', () => {
134
136
  await userEvent.click(chip);
135
137
  expect(onAfterClick).not.toHaveBeenCalled();
136
138
 
137
- jest.clearAllMocks();
139
+ vi.clearAllMocks();
138
140
 
139
141
  await userEvent.click(after as any);
140
142
  expect(onAfterClick).toHaveBeenCalled();
141
143
 
142
- jest.clearAllMocks();
144
+ vi.clearAllMocks();
143
145
 
144
146
  await userEvent.click(before as any);
145
147
  expect(onAfterClick).not.toHaveBeenCalled();
@@ -162,7 +164,7 @@ describe('<Chip />', () => {
162
164
  });
163
165
 
164
166
  it('should forward key down event', async () => {
165
- const onKeyDown = jest.fn();
167
+ const onKeyDown = vi.fn();
166
168
  const { chip } = setup({ onClick, onKeyDown });
167
169
 
168
170
  fireEvent.keyDown(chip, { key: 'A', code: 'KeyA' });
@@ -171,7 +173,7 @@ describe('<Chip />', () => {
171
173
 
172
174
  it('should forward key down event and trigger `onClick` when pressing Enter', async () => {
173
175
  const user = userEvent.setup();
174
- const onKeyDown = jest.fn();
176
+ const onKeyDown = vi.fn();
175
177
  const { chip } = setup({ onClick, onKeyDown });
176
178
 
177
179
  await user.tab();
@@ -187,7 +189,7 @@ describe('<Chip />', () => {
187
189
 
188
190
  describe('Disabled state', () => {
189
191
  it('should render disabled chip button', async () => {
190
- const onClick = jest.fn();
192
+ const onClick = vi.fn();
191
193
  const { chip } = setup({ children: 'Label', isDisabled: true, onClick });
192
194
  expect(chip).toHaveAttribute('aria-disabled', 'true');
193
195
  await userEvent.click(chip);
@@ -195,7 +197,7 @@ describe('<Chip />', () => {
195
197
  });
196
198
 
197
199
  it('should render disabled chip link', async () => {
198
- const onClick = jest.fn();
200
+ const onClick = vi.fn();
199
201
  const { chip } = setup({ children: 'Label', isDisabled: true, href: 'https://example.com', onClick });
200
202
  // Disabled link should not have an href.
201
203
  expect(chip).not.toHaveAttribute('href');
@@ -205,7 +207,7 @@ describe('<Chip />', () => {
205
207
  });
206
208
 
207
209
  it('should render aria-disabled chip button', async () => {
208
- const onClick = jest.fn();
210
+ const onClick = vi.fn();
209
211
  const { chip } = setup({ children: 'Label', 'aria-disabled': true, onClick });
210
212
  expect(chip).toHaveAttribute('aria-disabled', 'true');
211
213
  await userEvent.click(chip);
@@ -214,7 +216,7 @@ describe('<Chip />', () => {
214
216
  });
215
217
 
216
218
  it('should render aria-disabled chip link', async () => {
217
- const onClick = jest.fn();
219
+ const onClick = vi.fn();
218
220
  const { chip } = setup({
219
221
  children: 'Label',
220
222
  'aria-disabled': true,
@@ -9,15 +9,15 @@ import { DatePicker } from '.';
9
9
  import { CLASSNAME } from './constants';
10
10
 
11
11
  const mockedDate = new Date(1487721600000);
12
- Date.now = jest.fn(() => mockedDate.valueOf());
13
- jest.mock('@lumx/react/utils/date/getYearDisplayName', () => ({
12
+ Date.now = vi.fn(() => mockedDate.valueOf());
13
+ vi.mock('@lumx/react/utils/date/getYearDisplayName', () => ({
14
14
  getYearDisplayName: () => 'année',
15
15
  }));
16
16
 
17
17
  const setup = (propsOverride: Partial<DatePickerProps> = {}) => {
18
18
  const props: DatePickerProps = {
19
19
  locale: 'fr',
20
- onChange: jest.fn(),
20
+ onChange: vi.fn(),
21
21
  value: mockedDate,
22
22
  nextButtonProps: { label: 'Next month' },
23
23
  previousButtonProps: { label: 'Previous month' },
@@ -10,8 +10,8 @@ import { DatePickerControlled, DatePickerControlledProps } from './DatePickerCon
10
10
  import { CLASSNAME } from './constants';
11
11
 
12
12
  const mockedDate = new Date(1487721600000);
13
- Date.now = jest.fn(() => mockedDate.valueOf());
14
- jest.mock('@lumx/react/utils/date/getYearDisplayName', () => ({
13
+ Date.now = vi.fn(() => mockedDate.valueOf());
14
+ vi.mock('@lumx/react/utils/date/getYearDisplayName', () => ({
15
15
  getYearDisplayName: () => 'année',
16
16
  }));
17
17
 
@@ -20,14 +20,14 @@ type SetupProps = Partial<DatePickerControlledProps>;
20
20
  const setup = (propsOverride: SetupProps = {}) => {
21
21
  const props: DatePickerControlledProps = {
22
22
  locale: 'fr',
23
- onChange: jest.fn(),
24
- onNextMonthChange: jest.fn(),
25
- onPrevMonthChange: jest.fn(),
23
+ onChange: vi.fn(),
24
+ onNextMonthChange: vi.fn(),
25
+ onPrevMonthChange: vi.fn(),
26
26
  selectedMonth: mockedDate,
27
27
  value: mockedDate,
28
28
  nextButtonProps: { label: 'Next month' },
29
29
  previousButtonProps: { label: 'Previous month' },
30
- onMonthChange: jest.fn(),
30
+ onMonthChange: vi.fn(),
31
31
  ...propsOverride,
32
32
  };
33
33
  render(<DatePickerControlled {...props} />);
@@ -10,8 +10,8 @@ import { DatePickerField, DatePickerFieldProps } from './DatePickerField';
10
10
  import { CLASSNAME } from './constants';
11
11
 
12
12
  const mockedDate = new Date(1487721600000);
13
- Date.now = jest.fn(() => mockedDate.valueOf());
14
- jest.mock('@lumx/react/utils/date/getYearDisplayName', () => ({
13
+ Date.now = vi.fn(() => mockedDate.valueOf());
14
+ vi.mock('@lumx/react/utils/date/getYearDisplayName', () => ({
15
15
  getYearDisplayName: () => 'année',
16
16
  }));
17
17
 
@@ -19,7 +19,7 @@ const setup = (propsOverride: Partial<DatePickerFieldProps> = {}, { wrapper }: S
19
19
  const props: DatePickerFieldProps = {
20
20
  label: 'DatePickerField',
21
21
  locale: 'fr',
22
- onChange: jest.fn(),
22
+ onChange: vi.fn(),
23
23
  value: mockedDate,
24
24
  nextButtonProps: { label: 'Next month' },
25
25
  previousButtonProps: { label: 'Previous month' },
@@ -51,7 +51,7 @@ describe(`<${Dialog.displayName}>`, () => {
51
51
 
52
52
  describe('Events', () => {
53
53
  it('should trigger `onClose` when pressing `escape` key', async () => {
54
- const onClose = jest.fn();
54
+ const onClose = vi.fn();
55
55
  setup({ isOpen: true, onClose });
56
56
 
57
57
  await userEvent.keyboard('[Escape]');
@@ -59,7 +59,7 @@ describe(`<${Dialog.displayName}>`, () => {
59
59
  });
60
60
 
61
61
  it('should not trigger `onClose` when pressing any other key', async () => {
62
- const onClose = jest.fn();
62
+ const onClose = vi.fn();
63
63
  setup({ isOpen: true, onClose });
64
64
 
65
65
  await userEvent.keyboard('a');
@@ -67,7 +67,7 @@ describe(`<${Dialog.displayName}>`, () => {
67
67
  });
68
68
 
69
69
  it('should not trigger `onClose` when pressing `escape` key with `preventAutoClose` set to `true`', async () => {
70
- const onClose = jest.fn();
70
+ const onClose = vi.fn();
71
71
  setup({ isOpen: true, onClose, preventAutoClose: true });
72
72
 
73
73
  await userEvent.keyboard('[Escape]');
@@ -75,7 +75,7 @@ describe(`<${Dialog.displayName}>`, () => {
75
75
  });
76
76
 
77
77
  it('should not trigger `onClose` when pressing `escape` key with `preventCloseOnEscape` set to `true`', async () => {
78
- const onClose = jest.fn();
78
+ const onClose = vi.fn();
79
79
  setup({ isOpen: true, onClose, preventCloseOnEscape: true });
80
80
 
81
81
  await userEvent.keyboard('[Escape]');
@@ -28,7 +28,7 @@ const setup = (propsOverride: Partial<DropdownProps> = {}) => {
28
28
  describe(`<${Dropdown.displayName}>`, () => {
29
29
  describe('Events', () => {
30
30
  it('should trigger `onClose` when pressing `escape` key', async () => {
31
- const onClose = jest.fn();
31
+ const onClose = vi.fn();
32
32
  setup({
33
33
  closeOnEscape: true,
34
34
  onClose,
@@ -40,7 +40,7 @@ describe(`<${Dropdown.displayName}>`, () => {
40
40
  });
41
41
 
42
42
  it('should not trigger `onClose` when pressing any other key', async () => {
43
- const onClose = jest.fn();
43
+ const onClose = vi.fn();
44
44
  setup({ isOpen: true, onClose, closeOnEscape: true });
45
45
 
46
46
  await userEvent.keyboard('a');
@@ -48,7 +48,7 @@ describe(`<${Dropdown.displayName}>`, () => {
48
48
  });
49
49
 
50
50
  it('should not trigger `onClose` when pressing `escape` key with `closeOnEscape` set to `false`', async () => {
51
- const onClose = jest.fn();
51
+ const onClose = vi.fn();
52
52
  setup({ isOpen: true, onClose, closeOnEscape: false });
53
53
 
54
54
  await userEvent.keyboard('[Escape]');
@@ -1,3 +1,4 @@
1
+ import { Mock } from 'vitest';
1
2
  import React from 'react';
2
3
 
3
4
  import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
@@ -11,7 +12,7 @@ import { ExpansionPanel, ExpansionPanelProps } from '.';
11
12
 
12
13
  const CLASSNAME = ExpansionPanel.className as string;
13
14
 
14
- jest.mock('@lumx/react/utils/browser/isFocusVisible');
15
+ vi.mock('@lumx/react/utils/browser/isFocusVisible');
15
16
 
16
17
  const mockChildrenContent = 'children content';
17
18
 
@@ -55,7 +56,7 @@ const setup = (
55
56
  };
56
57
 
57
58
  describe(`<${ExpansionPanel.displayName}>`, () => {
58
- (isFocusVisible as jest.Mock).mockReturnValue(false);
59
+ (isFocusVisible as Mock).mockReturnValue(false);
59
60
 
60
61
  describe('Render', () => {
61
62
  it('should render default', () => {
@@ -100,9 +101,9 @@ describe(`<${ExpansionPanel.displayName}>`, () => {
100
101
  });
101
102
 
102
103
  describe('Events', () => {
103
- const onOpen = jest.fn();
104
- const onClose = jest.fn();
105
- const onToggleOpen = jest.fn();
104
+ const onOpen = vi.fn();
105
+ const onClose = vi.fn();
106
+ const onToggleOpen = vi.fn();
106
107
 
107
108
  beforeEach(onOpen.mockClear);
108
109
  beforeEach(onClose.mockClear);
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
 
3
3
  import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
4
- import { render, within, screen } from '@testing-library/react';
4
+ import { render, within, screen, waitFor } from '@testing-library/react';
5
5
  import { getByClassName, queryByClassName } from '@lumx/react/testing/utils/queries';
6
6
  import userEvent from '@testing-library/user-event';
7
7
  import { useImageSize } from '@lumx/react/hooks/useImageSize';
@@ -18,8 +18,8 @@ import Meta, {
18
18
  WithMosaicTrigger,
19
19
  } from './ImageLightbox.stories';
20
20
 
21
- jest.mock('@lumx/react/hooks/useImageSize');
22
- jest.mock('@lumx/react/hooks/useSizeOnWindowResize');
21
+ vi.mock('@lumx/react/hooks/useImageSize');
22
+ vi.mock('@lumx/react/hooks/useSizeOnWindowResize');
23
23
 
24
24
  const CLASSNAME = ImageLightbox.className as string;
25
25
  const baseProps = Meta.args;
@@ -56,7 +56,7 @@ const queries = {
56
56
  describe(`<${ImageLightbox.displayName}>`, () => {
57
57
  beforeEach(() => {
58
58
  (useImageSize as any).mockReturnValue(null);
59
- (useSizeOnWindowResize as any).mockReturnValue([null, jest.fn()]);
59
+ (useSizeOnWindowResize as any).mockReturnValue([null, vi.fn()]);
60
60
  });
61
61
 
62
62
  describe('render', () => {
@@ -159,7 +159,9 @@ describe(`<${ImageLightbox.displayName}>`, () => {
159
159
 
160
160
  // Close on escape
161
161
  await userEvent.keyboard('{escape}');
162
- expect(imageLightbox).not.toBeInTheDocument();
162
+ await waitFor(() => {
163
+ expect(imageLightbox).not.toBeInTheDocument();
164
+ });
163
165
 
164
166
  // Focus moved back to the trigger button
165
167
  expect(buttonTrigger).toHaveFocus();
@@ -185,7 +187,9 @@ describe(`<${ImageLightbox.displayName}>`, () => {
185
187
 
186
188
  // Close on escape
187
189
  await userEvent.keyboard('{escape}');
188
- expect(imageLightbox).not.toBeInTheDocument();
190
+ await waitFor(() => {
191
+ expect(imageLightbox).not.toBeInTheDocument();
192
+ });
189
193
 
190
194
  // Focus moved back to the trigger button
191
195
  expect(buttonTrigger).toHaveFocus();
@@ -196,7 +200,7 @@ describe(`<${ImageLightbox.displayName}>`, () => {
196
200
  const scrollAreaSize = { width: 600, height: 600 };
197
201
  beforeEach(() => {
198
202
  (useImageSize as any).mockImplementation((_: any, getInitialSize: any) => getInitialSize?.() || null);
199
- (useSizeOnWindowResize as any).mockReturnValue([scrollAreaSize, jest.fn()]);
203
+ (useSizeOnWindowResize as any).mockReturnValue([scrollAreaSize, vi.fn()]);
200
204
  });
201
205
 
202
206
  it('should use the image initial size', () => {
@@ -51,7 +51,7 @@ describe(`<${Link.displayName}>`, () => {
51
51
 
52
52
  it('should render a button', () => {
53
53
  const name = 'Link';
54
- const onClick = jest.fn();
54
+ const onClick = vi.fn();
55
55
  const { link } = setup({ onClick, children: name });
56
56
  expect(link).toBe(screen.queryByRole('button', { name }));
57
57
  });
@@ -75,7 +75,7 @@ describe(`<${Link.displayName}>`, () => {
75
75
 
76
76
  describe('Disabled state', () => {
77
77
  it('should render disabled button', async () => {
78
- const onClick = jest.fn();
78
+ const onClick = vi.fn();
79
79
  const { link } = setup({ children: 'Label', isDisabled: true, onClick });
80
80
  expect(link).toHaveAttribute('disabled');
81
81
  await userEvent.click(link);
@@ -83,7 +83,7 @@ describe(`<${Link.displayName}>`, () => {
83
83
  });
84
84
 
85
85
  it('should render disabled link', async () => {
86
- const onClick = jest.fn();
86
+ const onClick = vi.fn();
87
87
  const { link } = setup({ children: 'Label', isDisabled: true, href: 'https://example.com', onClick });
88
88
  expect(screen.queryByRole('link')).toBeInTheDocument();
89
89
  expect(link).toHaveAttribute('aria-disabled');
@@ -94,7 +94,7 @@ describe(`<${Link.displayName}>`, () => {
94
94
  });
95
95
 
96
96
  it('should render aria-disabled button', async () => {
97
- const onClick = jest.fn();
97
+ const onClick = vi.fn();
98
98
  const { link } = setup({ children: 'Label', 'aria-disabled': true, onClick });
99
99
  expect(screen.queryByRole('button')).toBeInTheDocument();
100
100
  expect(link).toHaveAttribute('aria-disabled', 'true');
@@ -104,7 +104,7 @@ describe(`<${Link.displayName}>`, () => {
104
104
  });
105
105
 
106
106
  it('should render aria-disabled link', async () => {
107
- const onClick = jest.fn();
107
+ const onClick = vi.fn();
108
108
  const { link } = setup({
109
109
  children: 'Label',
110
110
  'aria-disabled': true,
@@ -29,7 +29,7 @@ describe(`<${ListItem.displayName}>`, () => {
29
29
  });
30
30
 
31
31
  it('should render as a button', () => {
32
- setup({ children: 'Label', onItemSelected: jest.fn() });
32
+ setup({ children: 'Label', onItemSelected: vi.fn() });
33
33
  expect(screen.getByRole('button', { name: 'Label' })).toBeInTheDocument();
34
34
  });
35
35
 
@@ -41,29 +41,30 @@ describe(`<${ListItem.displayName}>`, () => {
41
41
 
42
42
  describe('Disabled state', () => {
43
43
  it('should render disabled list item button', async () => {
44
- const onItemSelected = jest.fn();
44
+ const onItemSelected = vi.fn();
45
45
  const { link } = setup({ children: 'Label', isDisabled: true, onItemSelected });
46
- expect(link).toBeDisabled();
46
+ expect(link).toHaveAttribute('aria-disabled', 'true');
47
47
  // The `renderLink` util removes the onClick handler but `user-event` will also not fire events on disabled elements.
48
48
  if (link) await userEvent.click(link);
49
49
  expect(onItemSelected).not.toHaveBeenCalled();
50
50
  });
51
51
 
52
52
  it('should render disabled list item link', async () => {
53
- const onItemSelected = jest.fn();
53
+ const onItemSelected = vi.fn();
54
54
  const { link } = setup({
55
55
  children: 'Label',
56
56
  isDisabled: true,
57
57
  linkProps: { href: 'https://example.com' },
58
58
  onItemSelected,
59
59
  });
60
+ expect(link).not.toHaveAttribute('href');
60
61
  expect(link).toHaveAttribute('aria-disabled', 'true');
61
62
  if (link) await userEvent.click(link);
62
63
  expect(onItemSelected).not.toHaveBeenCalled();
63
64
  });
64
65
 
65
66
  it('should render aria-disabled list item button', async () => {
66
- const onItemSelected = jest.fn();
67
+ const onItemSelected = vi.fn();
67
68
  const { link } = setup({ children: 'Label', 'aria-disabled': true, onItemSelected });
68
69
  expect(link).toHaveAttribute('aria-disabled', 'true');
69
70
  if (link) await userEvent.click(link);
@@ -71,13 +72,14 @@ describe(`<${ListItem.displayName}>`, () => {
71
72
  });
72
73
 
73
74
  it('should render aria-disabled list item link', async () => {
74
- const onItemSelected = jest.fn();
75
+ const onItemSelected = vi.fn();
75
76
  const { link } = setup({
76
77
  children: 'Label',
77
78
  'aria-disabled': true,
78
79
  linkProps: { href: 'https://example.com' },
79
80
  onItemSelected,
80
81
  });
82
+ expect(link).not.toHaveAttribute('href');
81
83
  expect(link).toHaveAttribute('aria-disabled', 'true');
82
84
  if (link) await userEvent.click(link);
83
85
  expect(onItemSelected).not.toHaveBeenCalled();