@lumx/react 3.3.1-alpha.0 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_internal/ClickAwayProvider.js.map +1 -1
- package/_internal/types.d.ts +0 -2
- package/index.d.ts +2 -0
- package/index.js +347 -75
- package/index.js.map +1 -1
- package/package.json +23 -19
- package/src/components/autocomplete/Autocomplete.test.tsx +55 -142
- package/src/components/autocomplete/AutocompleteMultiple.test.tsx +37 -75
- package/src/components/autocomplete/__mockData__/index.ts +6 -1
- package/src/components/badge/Badge.test.tsx +20 -64
- package/src/components/button/Button.test.tsx +44 -121
- package/src/components/button/ButtonGroup.test.tsx +16 -39
- package/src/components/button/IconButton.stories.tsx +7 -0
- package/src/components/button/IconButton.test.tsx +37 -78
- package/src/components/button/IconButton.tsx +8 -1
- package/src/components/checkbox/Checkbox.test.tsx +62 -67
- package/src/components/chip/Chip.test.tsx +89 -139
- package/src/components/chip/ChipGroup.test.tsx +27 -10
- package/src/components/date-picker/DatePicker.test.tsx +15 -23
- package/src/components/date-picker/DatePickerControlled.test.tsx +24 -20
- package/src/components/date-picker/DatePickerField.test.tsx +43 -27
- package/src/components/dialog/Dialog.test.tsx +36 -35
- package/src/components/divider/Divider.test.tsx +23 -69
- package/src/components/dropdown/Dropdown.test.tsx +30 -61
- package/src/components/expansion-panel/ExpansionPanel.test.tsx +12 -8
- package/src/components/flag/Flag.test.tsx +28 -53
- package/src/components/generic-block/GenericBlock.test.tsx +93 -89
- package/src/components/grid-column/GridColumn.stories.tsx +3 -3
- package/src/components/icon/Icon.test.tsx +80 -64
- package/src/components/index.ts +0 -2
- package/src/components/inline-list/InlineList.test.tsx +30 -17
- package/src/components/input-helper/InputHelper.test.tsx +21 -81
- package/src/components/input-label/InputLabel.test.tsx +19 -61
- package/src/components/lightbox/Lightbox.test.tsx +3 -2
- package/src/components/link/Link.test.tsx +47 -31
- package/src/components/link-preview/LinkPreview.test.tsx +51 -51
- package/src/components/message/Message.test.tsx +31 -52
- package/src/components/mosaic/Mosaic.test.tsx +56 -72
- package/src/components/notification/Notification.test.tsx +51 -82
- package/src/components/popover/Popover.tsx +7 -9
- package/src/components/progress-tracker/ProgressTracker.test.tsx +20 -33
- package/src/components/progress-tracker/ProgressTrackerProvider.test.tsx +61 -36
- package/src/components/progress-tracker/ProgressTrackerStep.test.tsx +19 -109
- package/src/components/progress-tracker/ProgressTrackerStepPanel.test.tsx +21 -58
- package/src/components/progress-tracker/ProgressTrackerStepPanel.tsx +1 -1
- package/src/components/radio-button/RadioButton.test.tsx +78 -92
- package/src/components/radio-button/RadioGroup.test.tsx +13 -59
- package/src/components/select/Select.test.tsx +115 -284
- package/src/components/select/SelectMultiple.stories.tsx +105 -2
- package/src/components/select/SelectMultiple.test.tsx +126 -322
- package/src/components/select/WithSelectContext.tsx +10 -4
- package/src/components/side-navigation/SideNavigation.test.tsx +22 -35
- package/src/components/side-navigation/SideNavigationItem.test.tsx +72 -139
- package/src/components/switch/Switch.test.tsx +70 -149
- package/src/components/table/Table.test.tsx +2 -0
- package/src/components/table/TableBody.test.tsx +18 -8
- package/src/components/table/TableCell.test.tsx +34 -9
- package/src/components/table/TableHeader.test.tsx +18 -8
- package/src/components/table/TableRow.test.tsx +28 -8
- package/src/components/tabs/Tab.test.tsx +27 -96
- package/src/components/tabs/TabList.test.tsx +21 -56
- package/src/components/tabs/TabPanel.test.tsx +20 -55
- package/src/components/tabs/TabPanel.tsx +1 -1
- package/src/components/tabs/TabProvider.test.tsx +158 -37
- package/src/components/tabs/test-utils.ts +39 -0
- package/src/components/text-field/TextField.stories.tsx +14 -5
- package/src/components/text-field/TextField.test.tsx +54 -8
- package/src/components/text-field/TextField.tsx +49 -5
- package/src/components/tooltip/Tooltip.test.tsx +134 -75
- package/src/components/tooltip/useInjectTooltipRef.tsx +9 -2
- package/src/components/uploader/Uploader.test.tsx +60 -48
- package/src/components/user-block/UserBlock.test.tsx +69 -13
- package/src/hooks/useFocusTrap.ts +2 -2
- package/src/testing/utils/commonTestsSuiteRTL.ts +18 -8
- package/src/testing/utils/index.ts +0 -1
- package/src/utils/flattenChildren.ts +5 -0
- package/src/components/autocomplete/__snapshots__/Autocomplete.test.tsx.snap +0 -213
- package/src/components/autocomplete/__snapshots__/AutocompleteMultiple.test.tsx.snap +0 -88
- package/src/components/badge/__snapshots__/Badge.test.tsx.snap +0 -11
- package/src/components/button/ButtonRoot.test.tsx +0 -203
- package/src/components/button/__snapshots__/Button.test.tsx.snap +0 -96
- package/src/components/button/__snapshots__/ButtonGroup.test.tsx.snap +0 -22
- package/src/components/button/__snapshots__/ButtonRoot.test.tsx.snap +0 -160
- package/src/components/button/__snapshots__/IconButton.test.tsx.snap +0 -83
- package/src/components/checkbox/__snapshots__/Checkbox.test.tsx.snap +0 -141
- package/src/components/chip/__snapshots__/Chip.test.tsx.snap +0 -12
- package/src/components/chip/__snapshots__/ChipGroup.test.tsx.snap +0 -29
- package/src/components/date-picker/__snapshots__/DatePicker.test.tsx.snap +0 -22
- package/src/components/date-picker/__snapshots__/DatePickerControlled.test.tsx.snap +0 -597
- package/src/components/date-picker/__snapshots__/DatePickerField.test.tsx.snap +0 -43
- package/src/components/divider/__snapshots__/Divider.test.tsx.snap +0 -9
- package/src/components/dropdown/__snapshots__/Dropdown.test.tsx.snap +0 -35
- package/src/components/icon/__snapshots__/Icon.test.tsx.snap +0 -49
- package/src/components/input-helper/__snapshots__/InputHelper.test.tsx.snap +0 -9
- package/src/components/input-label/__snapshots__/InputLabel.test.tsx.snap +0 -10
- package/src/components/link/__snapshots__/Link.test.tsx.snap +0 -29
- package/src/components/message/__snapshots__/Message.test.tsx.snap +0 -15
- package/src/components/notification/__snapshots__/Notification.test.tsx.snap +0 -34
- package/src/components/progress-tracker/__snapshots__/ProgressTracker.test.tsx.snap +0 -41
- package/src/components/progress-tracker/__snapshots__/ProgressTrackerStep.test.tsx.snap +0 -141
- package/src/components/progress-tracker/__snapshots__/ProgressTrackerStepPanel.test.tsx.snap +0 -25
- package/src/components/radio-button/__snapshots__/RadioButton.test.tsx.snap +0 -113
- package/src/components/radio-button/__snapshots__/RadioGroup.test.tsx.snap +0 -26
- package/src/components/select/__snapshots__/Select.test.tsx.snap +0 -43
- package/src/components/select/__snapshots__/SelectMultiple.test.tsx.snap +0 -87
- package/src/components/side-navigation/__snapshots__/SideNavigation.test.tsx.snap +0 -7
- package/src/components/side-navigation/__snapshots__/SideNavigationItem.test.tsx.snap +0 -30
- package/src/components/switch/__snapshots__/Switch.test.tsx.snap +0 -179
- package/src/components/tabs/__snapshots__/Tab.test.tsx.snap +0 -62
- package/src/components/tabs/__snapshots__/TabList.test.tsx.snap +0 -22
- package/src/components/tabs/__snapshots__/TabPanel.test.tsx.snap +0 -25
- package/src/components/tabs/test.mocks.ts +0 -33
- package/src/components/text-field/__snapshots__/TextField.test.tsx.snap +0 -42
- package/src/components/tooltip/__snapshots__/Tooltip.test.tsx.snap +0 -233
- package/src/components/uploader/__snapshots__/Uploader.test.tsx.snap +0 -14
- package/src/testing/utils/commonTestsSuite.ts +0 -71
- package/src/utils/flattenChildren.test.tsx +0 -58
|
@@ -1,89 +1,73 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { commonTestsSuite, Wrapper } from '@lumx/react/testing/utils';
|
|
3
|
-
|
|
4
|
-
import { mount, shallow } from 'enzyme';
|
|
5
|
-
import 'jest-enzyme';
|
|
1
|
+
import React from 'react';
|
|
6
2
|
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
3
|
+
import { Mosaic, MosaicProps } from '@lumx/react/components/mosaic/Mosaic';
|
|
4
|
+
import { render, screen, within } from '@testing-library/react';
|
|
5
|
+
import { getByClassName, queryAllByClassName, queryByClassName } from '@lumx/react/testing/utils/queries';
|
|
6
|
+
import { Thumbnail } from '@lumx/react';
|
|
7
|
+
import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
|
|
8
|
+
import range from 'lodash/range';
|
|
9
|
+
import userEvent from '@testing-library/user-event';
|
|
9
10
|
|
|
10
11
|
const CLASSNAME = Mosaic.className as string;
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const setup = (propsOverride: SetupProps = {}, shallowRendering = true) => {
|
|
20
|
-
const props: any = { ...propsOverride };
|
|
21
|
-
const renderer: (el: ReactElement) => Wrapper = shallowRendering ? shallow : mount;
|
|
22
|
-
const wrapper = renderer(<Mosaic {...props} />);
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
thumbnails: wrapper.find('Thumbnail'),
|
|
26
|
-
props,
|
|
27
|
-
wrapper,
|
|
28
|
-
};
|
|
13
|
+
const setup = (props: Partial<MosaicProps> = {}) => {
|
|
14
|
+
render(<Mosaic thumbnails={[]} {...props} />);
|
|
15
|
+
const mosaic = getByClassName(document.body, CLASSNAME);
|
|
16
|
+
const thumbnails = queryAllByClassName(mosaic, Thumbnail.className as string);
|
|
17
|
+
const overlay = queryByClassName(mosaic, `${CLASSNAME}__overlay`);
|
|
18
|
+
return { props, mosaic, thumbnails, overlay };
|
|
29
19
|
};
|
|
30
20
|
|
|
21
|
+
const generateThumbnails = (count: number) =>
|
|
22
|
+
range(1, count + 1).map((i) => ({
|
|
23
|
+
image: `https://example.com/image${i}.png`,
|
|
24
|
+
alt: '',
|
|
25
|
+
}));
|
|
26
|
+
|
|
31
27
|
describe(`<${Mosaic.displayName}>`, () => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const { thumbnails } = setup({
|
|
36
|
-
theme: expectedTheme,
|
|
37
|
-
thumbnails: [
|
|
38
|
-
{ alt: 'image0', image: 'image/file/path/0' },
|
|
39
|
-
{ alt: 'image1', image: 'image/file/path/1' },
|
|
40
|
-
{ alt: 'image2', image: 'image/file/path/2' },
|
|
41
|
-
{ alt: 'image3', image: 'image/file/path/3' },
|
|
42
|
-
],
|
|
43
|
-
});
|
|
44
|
-
thumbnails.forEach((thumbnail: Wrapper) => {
|
|
45
|
-
expect(thumbnail.prop('theme')).toBe(expectedTheme);
|
|
46
|
-
});
|
|
28
|
+
it.each([1, 2, 3, 4])('should render %s thumbnail', async (count) => {
|
|
29
|
+
const { mosaic, thumbnails } = setup({
|
|
30
|
+
thumbnails: generateThumbnails(count),
|
|
47
31
|
});
|
|
32
|
+
expect(mosaic).toHaveClass(`${CLASSNAME}--has-${count}-thumbnail${count > 1 ? 's' : ''}`);
|
|
33
|
+
expect(thumbnails.length).toBe(count);
|
|
34
|
+
for (const thumbnail of thumbnails) {
|
|
35
|
+
expect(within(thumbnail).queryByRole('img')).toBeInTheDocument();
|
|
36
|
+
}
|
|
48
37
|
});
|
|
49
38
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const { thumbnails } = setup({
|
|
54
|
-
thumbnails: [
|
|
55
|
-
{ alt: 'image0', image: 'image/file/path/0', onClick },
|
|
56
|
-
{ alt: 'image1', image: 'image/file/path/1' },
|
|
57
|
-
{ alt: 'image2', image: 'image/file/path/2' },
|
|
58
|
-
{ alt: 'image3', image: 'image/file/path/3' },
|
|
59
|
-
],
|
|
60
|
-
});
|
|
61
|
-
thumbnails.forEach((thumbnail: Wrapper) => {
|
|
62
|
-
thumbnail.simulate('click');
|
|
63
|
-
});
|
|
64
|
-
expect(onClick).toHaveBeenCalledTimes(1);
|
|
39
|
+
it('should render more than 4 thumbnails', () => {
|
|
40
|
+
const { mosaic, thumbnails, overlay } = setup({
|
|
41
|
+
thumbnails: generateThumbnails(6),
|
|
65
42
|
});
|
|
43
|
+
expect(mosaic).toHaveClass(`${CLASSNAME}--has-4-thumbnails`);
|
|
44
|
+
expect(thumbnails.length).toBe(4);
|
|
45
|
+
expect(overlay).toBeInTheDocument();
|
|
46
|
+
expect(overlay).toHaveTextContent('+2');
|
|
47
|
+
});
|
|
66
48
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
{ alt: 'image1', image: 'image/file/path/1' },
|
|
75
|
-
{ alt: 'image2', image: 'image/file/path/2' },
|
|
76
|
-
{ alt: 'image3', image: 'image/file/path/3' },
|
|
77
|
-
],
|
|
78
|
-
});
|
|
79
|
-
thumbnails.forEach((thumbnail: Wrapper) => {
|
|
80
|
-
thumbnail.simulate('click');
|
|
81
|
-
});
|
|
82
|
-
expect(onClick).toHaveBeenCalledTimes(1);
|
|
83
|
-
expect(onImageClick).toHaveBeenCalledTimes(4);
|
|
49
|
+
it('should render clickable', async () => {
|
|
50
|
+
const onClick = jest.fn();
|
|
51
|
+
const onImageClick = jest.fn();
|
|
52
|
+
const { thumbnails } = setup({
|
|
53
|
+
thumbnails: generateThumbnails(6),
|
|
54
|
+
onImageClick,
|
|
55
|
+
onClick,
|
|
84
56
|
});
|
|
57
|
+
|
|
58
|
+
expect(screen.queryAllByRole('button').length).toBe(thumbnails.length);
|
|
59
|
+
|
|
60
|
+
// Click the third image
|
|
61
|
+
await userEvent.click(thumbnails[2]);
|
|
62
|
+
expect(onImageClick).toHaveBeenCalledWith(2);
|
|
63
|
+
expect(onClick).toHaveBeenCalled();
|
|
85
64
|
});
|
|
86
65
|
|
|
87
66
|
// Common tests suite.
|
|
88
|
-
|
|
67
|
+
commonTestsSuiteRTL(setup, {
|
|
68
|
+
baseClassName: CLASSNAME,
|
|
69
|
+
forwardClassName: 'mosaic',
|
|
70
|
+
forwardAttributes: 'mosaic',
|
|
71
|
+
forwardRef: 'mosaic',
|
|
72
|
+
});
|
|
89
73
|
});
|
|
@@ -1,108 +1,77 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
|
|
3
|
-
import { mount, shallow } from 'enzyme';
|
|
4
|
-
import 'jest-enzyme';
|
|
5
|
-
|
|
6
|
-
import noop from 'lodash/noop';
|
|
7
3
|
import { Kind } from '@lumx/react';
|
|
8
|
-
import {
|
|
4
|
+
import { render, within } from '@testing-library/react';
|
|
5
|
+
import { queryByClassName } from '@lumx/react/testing/utils/queries';
|
|
6
|
+
import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
|
|
7
|
+
import userEvent from '@testing-library/user-event';
|
|
9
8
|
|
|
10
9
|
import { Notification, NotificationProps } from './Notification';
|
|
11
10
|
|
|
12
11
|
const CLASSNAME = Notification.className as string;
|
|
13
12
|
|
|
14
|
-
type SetupProps = Partial<NotificationProps>;
|
|
15
|
-
|
|
16
13
|
/**
|
|
17
14
|
* Mounts the component and returns common DOM elements / data needed in multiple tests further down.
|
|
18
15
|
*/
|
|
19
|
-
const setup = (
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
const wrapper: Wrapper = renderer(<Notification {...props} />);
|
|
23
|
-
|
|
24
|
-
const notification: Wrapper = wrapper.find('.lumx-notification');
|
|
25
|
-
const icon: Wrapper = wrapper.find('.lumx-notification__icon');
|
|
26
|
-
const content: Wrapper = wrapper.find('.lumx-notification__content');
|
|
27
|
-
const action: Wrapper = wrapper.find('.lumx-notification__action');
|
|
16
|
+
const setup = (props: Partial<NotificationProps> = {}) => {
|
|
17
|
+
render(<Notification isOpen type={Kind.info} {...props} />);
|
|
18
|
+
const notification = queryByClassName(document.body, CLASSNAME);
|
|
28
19
|
|
|
29
|
-
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const properties = {
|
|
33
|
-
error: {
|
|
34
|
-
content: 'Error',
|
|
35
|
-
onClick: noop,
|
|
36
|
-
isOpen: true,
|
|
37
|
-
type: Kind.error,
|
|
38
|
-
},
|
|
39
|
-
info: {
|
|
40
|
-
content: 'Info',
|
|
41
|
-
onClick: noop,
|
|
42
|
-
isOpen: true,
|
|
43
|
-
type: Kind.info,
|
|
44
|
-
},
|
|
45
|
-
infoWithCallback: {
|
|
46
|
-
onActionClick: noop,
|
|
47
|
-
actionLabel: 'Undo',
|
|
48
|
-
content: 'Info with callback',
|
|
49
|
-
onClick: noop,
|
|
50
|
-
isOpen: true,
|
|
51
|
-
type: Kind.info,
|
|
52
|
-
},
|
|
53
|
-
success: {
|
|
54
|
-
content: 'Success',
|
|
55
|
-
onClick: noop,
|
|
56
|
-
isOpen: true,
|
|
57
|
-
type: Kind.success,
|
|
58
|
-
},
|
|
20
|
+
const icon = notification && queryByClassName(notification, `${CLASSNAME}__icon`);
|
|
21
|
+
const action = notification && queryByClassName(notification, `${CLASSNAME}__action`);
|
|
22
|
+
const actionButton = action && within(action).queryByRole('button');
|
|
59
23
|
|
|
60
|
-
|
|
61
|
-
content: 'Warning',
|
|
62
|
-
onClick: noop,
|
|
63
|
-
isOpen: true,
|
|
64
|
-
type: Kind.warning,
|
|
65
|
-
},
|
|
24
|
+
return { action, actionButton, icon, notification, props };
|
|
66
25
|
};
|
|
67
26
|
|
|
68
27
|
describe(`<${Notification.displayName}>`, () => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
expect(wrapper).toMatchSnapshot();
|
|
28
|
+
it('should not render without type', () => {
|
|
29
|
+
const { notification } = setup({ type: undefined });
|
|
30
|
+
expect(notification).not.toBeInTheDocument();
|
|
31
|
+
});
|
|
74
32
|
|
|
75
|
-
|
|
33
|
+
it('should not render when closed', () => {
|
|
34
|
+
const { notification } = setup({ isOpen: false });
|
|
35
|
+
expect(notification).not.toBeInTheDocument();
|
|
36
|
+
});
|
|
76
37
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
});
|
|
38
|
+
it('should render content', () => {
|
|
39
|
+
const content = 'Content';
|
|
40
|
+
const { notification, icon } = setup({ content });
|
|
41
|
+
expect(notification).toBeInTheDocument();
|
|
42
|
+
expect(notification).toHaveTextContent(content);
|
|
43
|
+
expect(icon).toBeInTheDocument();
|
|
44
|
+
});
|
|
80
45
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
46
|
+
it('should render content & action', async () => {
|
|
47
|
+
const onClick = jest.fn();
|
|
48
|
+
const onActionClick = jest.fn();
|
|
49
|
+
const content = 'Content';
|
|
50
|
+
const actionLabel = 'actionLabel';
|
|
51
|
+
const { notification, action, actionButton } = setup({ content, actionLabel, onClick, onActionClick });
|
|
84
52
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
});
|
|
53
|
+
expect(notification).toBeInTheDocument();
|
|
54
|
+
expect(notification).toHaveTextContent(content);
|
|
88
55
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
});
|
|
56
|
+
expect(action).toBeInTheDocument();
|
|
57
|
+
expect(actionButton).toBeInTheDocument();
|
|
58
|
+
expect(actionButton).toHaveTextContent(actionLabel);
|
|
93
59
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
60
|
+
// Click action button
|
|
61
|
+
await userEvent.click(actionButton as any);
|
|
62
|
+
expect(onActionClick).toHaveBeenCalled();
|
|
63
|
+
expect(onClick).not.toHaveBeenCalled();
|
|
98
64
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
65
|
+
// Click notification
|
|
66
|
+
await userEvent.click(notification as any);
|
|
67
|
+
expect(onClick).toHaveBeenCalled();
|
|
102
68
|
});
|
|
103
69
|
|
|
104
|
-
//
|
|
105
|
-
|
|
106
|
-
|
|
70
|
+
// Common tests suite.
|
|
71
|
+
commonTestsSuiteRTL(setup, {
|
|
72
|
+
baseClassName: CLASSNAME,
|
|
73
|
+
forwardClassName: 'notification',
|
|
74
|
+
forwardAttributes: 'notification',
|
|
75
|
+
forwardRef: 'notification',
|
|
107
76
|
});
|
|
108
77
|
});
|
|
@@ -173,18 +173,16 @@ const _InnerPopover: Comp<PopoverProps, HTMLDivElement> = forwardRef((props, ref
|
|
|
173
173
|
* unless specifically requested not to.
|
|
174
174
|
*/
|
|
175
175
|
if (isFocusedWithin.current && focusAnchorOnClose) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const firstFocusable = anchorRef?.current && getFirstAndLastFocusable(anchorRef?.current).first;
|
|
181
|
-
if (firstFocusable) {
|
|
176
|
+
let elementToFocus = parentElement?.current;
|
|
177
|
+
if (!elementToFocus && anchorRef?.current) {
|
|
182
178
|
// Focus the first focusable element in anchor.
|
|
183
|
-
|
|
184
|
-
}
|
|
179
|
+
elementToFocus = getFirstAndLastFocusable(anchorRef.current).first;
|
|
180
|
+
}
|
|
181
|
+
if (!elementToFocus) {
|
|
185
182
|
// Fallback on the anchor element.
|
|
186
|
-
anchorRef?.current
|
|
183
|
+
elementToFocus = anchorRef?.current;
|
|
187
184
|
}
|
|
185
|
+
elementToFocus?.focus({ preventScroll: true });
|
|
188
186
|
}
|
|
189
187
|
|
|
190
188
|
onClose();
|
|
@@ -1,57 +1,44 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
1
3
|
import { ProgressTrackerStep } from '@lumx/react';
|
|
2
|
-
import {
|
|
4
|
+
import { render, within } from '@testing-library/react';
|
|
5
|
+
import { getByClassName } from '@lumx/react/testing/utils/queries';
|
|
6
|
+
import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
|
|
3
7
|
|
|
4
|
-
import { mount, shallow } from 'enzyme';
|
|
5
|
-
import 'jest-enzyme';
|
|
6
|
-
import React, { ReactElement } from 'react';
|
|
7
|
-
import { setupTabProviderMocks } from '../tabs/test.mocks';
|
|
8
8
|
import { ProgressTracker, ProgressTrackerProps } from './ProgressTracker';
|
|
9
9
|
|
|
10
10
|
const CLASSNAME = ProgressTracker.className as string;
|
|
11
11
|
|
|
12
|
-
// Mock useTabProviderContext.
|
|
13
|
-
jest.mock('../tabs/state', () => {
|
|
14
|
-
const state = jest.requireActual('../tabs/state');
|
|
15
|
-
return { ...state, useTabProviderContext: jest.fn(), useTabProviderContextState: jest.fn() };
|
|
16
|
-
});
|
|
17
|
-
|
|
18
12
|
type SetupProps = Partial<ProgressTrackerProps>;
|
|
19
13
|
|
|
20
14
|
/**
|
|
21
15
|
* Mounts the component and returns common DOM elements / data needed in multiple tests further down.
|
|
22
16
|
*/
|
|
23
|
-
const setup = (
|
|
17
|
+
const setup = (propsOverride: SetupProps = {}) => {
|
|
24
18
|
const steps = [<ProgressTrackerStep key={0} label="Step 0" />, <ProgressTrackerStep key={1} label="Step 1" />];
|
|
25
|
-
const props
|
|
19
|
+
const props = {
|
|
26
20
|
children: steps,
|
|
27
21
|
'aria-label': 'Steps',
|
|
28
22
|
...propsOverride,
|
|
29
23
|
};
|
|
30
|
-
|
|
31
|
-
const
|
|
24
|
+
render(<ProgressTracker {...props} />);
|
|
25
|
+
const progressTracker = getByClassName(document.body, CLASSNAME);
|
|
32
26
|
|
|
33
|
-
return { props,
|
|
27
|
+
return { props, progressTracker };
|
|
34
28
|
};
|
|
35
29
|
|
|
36
30
|
describe(`<${ProgressTracker.displayName}>`, () => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// 1. Test render via snapshot (default states of component).
|
|
42
|
-
describe('Snapshots and structure', () => {
|
|
43
|
-
it('should render correctly', () => {
|
|
44
|
-
const { wrapper } = setup();
|
|
45
|
-
expect(wrapper).toMatchSnapshot();
|
|
46
|
-
|
|
47
|
-
expect(wrapper).toExist();
|
|
48
|
-
expect(wrapper).toHaveClassName(CLASSNAME);
|
|
49
|
-
|
|
50
|
-
expect(wrapper.childAt(0)).toExist();
|
|
51
|
-
expect(wrapper.childAt(0)).toHaveClassName('lumx-progress-tracker__steps');
|
|
52
|
-
});
|
|
31
|
+
it('should render default', () => {
|
|
32
|
+
const label = 'Steps';
|
|
33
|
+
const { progressTracker } = setup({ 'aria-label': label });
|
|
34
|
+
expect(within(progressTracker).queryByRole('tablist', { name: label })).toBeInTheDocument();
|
|
53
35
|
});
|
|
54
36
|
|
|
55
37
|
// Common tests suite.
|
|
56
|
-
|
|
38
|
+
commonTestsSuiteRTL(setup, {
|
|
39
|
+
baseClassName: CLASSNAME,
|
|
40
|
+
forwardClassName: 'progressTracker',
|
|
41
|
+
forwardAttributes: 'progressTracker',
|
|
42
|
+
forwardRef: 'progressTracker',
|
|
43
|
+
});
|
|
57
44
|
});
|
|
@@ -1,42 +1,67 @@
|
|
|
1
|
-
import { ProgressTracker, ProgressTrackerProvider, ProgressTrackerStep, ProgressTrackerStepPanel } from '@lumx/react';
|
|
2
|
-
import { mount } from 'enzyme';
|
|
3
|
-
import 'jest-enzyme';
|
|
4
1
|
import React from 'react';
|
|
5
2
|
|
|
3
|
+
import {
|
|
4
|
+
ProgressTracker,
|
|
5
|
+
ProgressTrackerProvider,
|
|
6
|
+
ProgressTrackerProviderProps,
|
|
7
|
+
ProgressTrackerStep,
|
|
8
|
+
ProgressTrackerStepPanel,
|
|
9
|
+
} from '@lumx/react';
|
|
10
|
+
|
|
11
|
+
import { render } from '@testing-library/react';
|
|
12
|
+
import { checkTabActive, query } from '../tabs/test-utils';
|
|
13
|
+
|
|
14
|
+
const setup = (props: Partial<ProgressTrackerProviderProps> = {}) =>
|
|
15
|
+
render(
|
|
16
|
+
<ProgressTrackerProvider {...props}>
|
|
17
|
+
<ProgressTracker aria-label="Progress tracker steps">
|
|
18
|
+
<ProgressTrackerStep label="Step 1" />
|
|
19
|
+
<ProgressTrackerStep label="Step 2" />
|
|
20
|
+
</ProgressTracker>
|
|
21
|
+
|
|
22
|
+
<ProgressTrackerStepPanel>Progress tracker step 1 content</ProgressTrackerStepPanel>
|
|
23
|
+
<ProgressTrackerStepPanel>Progress tracker step 2 content</ProgressTrackerStepPanel>
|
|
24
|
+
</ProgressTrackerProvider>,
|
|
25
|
+
);
|
|
26
|
+
|
|
6
27
|
describe(`<${ProgressTrackerProvider.displayName}>`, () => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
expect(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
describe('default config', () => {
|
|
29
|
+
it('should render aria tab pattern', () => {
|
|
30
|
+
setup();
|
|
31
|
+
|
|
32
|
+
// Step list
|
|
33
|
+
const tabList = query.tabList('Progress tracker steps');
|
|
34
|
+
expect(tabList).toBeInTheDocument();
|
|
35
|
+
expect(query.tabs(tabList).length).toBe(2);
|
|
36
|
+
|
|
37
|
+
// Step 1
|
|
38
|
+
const tab1 = query.tab('Step 1', tabList);
|
|
39
|
+
expect(tab1).toBeInTheDocument();
|
|
40
|
+
|
|
41
|
+
// Step 2
|
|
42
|
+
const tab2 = query.tab('Step 2', tabList);
|
|
43
|
+
expect(tab2).toBeInTheDocument();
|
|
44
|
+
|
|
45
|
+
// Step panel 1
|
|
46
|
+
const tabPanel1 = query.tabPanel('Step 1');
|
|
47
|
+
expect(tabPanel1).toBeInTheDocument();
|
|
48
|
+
expect(tab1).toHaveAttribute('aria-controls', tabPanel1?.id);
|
|
49
|
+
|
|
50
|
+
// Step panel 2
|
|
51
|
+
const tabPanel2 = query.tabPanel('Step 2');
|
|
52
|
+
expect(tabPanel2).toBeInTheDocument();
|
|
53
|
+
expect(tab2).toHaveAttribute('aria-controls', tabPanel2?.id);
|
|
54
|
+
|
|
55
|
+
// First step is active
|
|
56
|
+
checkTabActive('Step 1');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe('not lazy', () => {
|
|
61
|
+
it('should render panel content', () => {
|
|
62
|
+
setup({ isLazy: false });
|
|
63
|
+
|
|
64
|
+
checkTabActive('Step 1', { isLazy: false });
|
|
40
65
|
});
|
|
41
66
|
});
|
|
42
67
|
});
|