@lumx/react 3.20.0 → 3.20.1-alpha.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/index.js +13 -20
- package/_internal/index.js.map +1 -1
- package/index.d.ts +6 -5
- package/index.js +2439 -2399
- package/index.js.map +1 -1
- package/package.json +13 -10
- package/src/components/alert-dialog/AlertDialog.test.tsx +2 -3
- package/src/components/autocomplete/Autocomplete.test.tsx +3 -3
- package/src/components/button/Button.test.tsx +9 -9
- package/src/components/button/ButtonRoot.tsx +36 -6
- package/src/components/checkbox/Checkbox.test.tsx +3 -3
- package/src/components/chip/Chip.test.tsx +17 -19
- package/src/components/date-picker/DatePicker.test.tsx +3 -3
- package/src/components/date-picker/DatePickerControlled.test.tsx +6 -6
- package/src/components/date-picker/DatePickerField.test.tsx +3 -3
- package/src/components/dialog/Dialog.test.tsx +4 -4
- package/src/components/dropdown/Dropdown.test.tsx +3 -3
- package/src/components/expansion-panel/ExpansionPanel.test.tsx +5 -6
- package/src/components/icon/Icon.stories.tsx +4 -30
- package/src/components/icon/Icon.test.tsx +2 -85
- package/src/components/icon/Icon.tsx +7 -118
- package/src/components/image-lightbox/ImageLightbox.test.tsx +7 -11
- package/src/components/link/Link.test.tsx +11 -13
- package/src/components/link/Link.tsx +20 -9
- package/src/components/list/ListItem.test.tsx +5 -5
- package/src/components/message/Message.test.tsx +1 -1
- package/src/components/mosaic/Mosaic.test.tsx +3 -3
- package/src/components/navigation/NavigationItem.tsx +10 -6
- package/src/components/navigation/NavigationSection.tsx +3 -4
- package/src/components/notification/Notification.test.tsx +3 -4
- package/src/components/popover-dialog/PopoverDialog.test.tsx +1 -1
- package/src/components/radio-button/RadioButton.test.tsx +3 -3
- package/src/components/select/Select.test.tsx +7 -8
- package/src/components/select/SelectMultiple.test.tsx +5 -5
- package/src/components/side-navigation/SideNavigationItem.test.tsx +2 -2
- package/src/components/side-navigation/SideNavigationItem.tsx +27 -22
- package/src/components/slider/Slider.test.tsx +1 -1
- package/src/components/switch/Switch.test.tsx +5 -5
- package/src/components/table/TableCell.test.tsx +1 -1
- package/src/components/text-field/TextField.test.tsx +8 -9
- package/src/components/thumbnail/Thumbnail.test.tsx +5 -29
- package/src/components/thumbnail/Thumbnail.tsx +11 -11
- package/src/components/tooltip/Tooltip.test.tsx +8 -14
- package/src/components/uploader/Uploader.test.tsx +2 -2
- package/src/components/user-block/UserBlock.test.tsx +1 -1
- package/src/untypped-modules.d.ts +0 -4
- package/src/utils/Portal/PortalProvider.test.tsx +1 -1
- package/src/utils/date/getYearDisplayName.test.ts +1 -1
- package/src/utils/disabled/useDisableStateProps.test.tsx +2 -2
- package/src/utils/react/renderButtonOrLink.tsx +16 -0
- package/src/utils/type/index.ts +0 -1
- package/utils/index.d.ts +1 -1
- package/utils/index.js +1 -1
- package/src/utils/react/RawClickable.test.tsx +0 -153
- package/src/utils/react/RawClickable.tsx +0 -65
- package/src/utils/type/HasRequiredLinkHref.ts +0 -1
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.20.
|
|
10
|
-
"@lumx/icons": "^3.20.
|
|
9
|
+
"@lumx/core": "^3.20.1-alpha.1",
|
|
10
|
+
"@lumx/icons": "^3.20.1-alpha.1",
|
|
11
11
|
"@popperjs/core": "^2.5.4",
|
|
12
12
|
"body-scroll-lock": "^3.1.5",
|
|
13
13
|
"classnames": "^2.3.2",
|
|
@@ -30,21 +30,24 @@
|
|
|
30
30
|
"@rollup/plugin-babel": "^6.0.4",
|
|
31
31
|
"@rollup/plugin-commonjs": "^19.0.2",
|
|
32
32
|
"@rollup/plugin-node-resolve": "16.0.0",
|
|
33
|
+
"@rollup/pluginutils": "5.2.0",
|
|
33
34
|
"@storybook/addon-a11y": "^9.1.4",
|
|
34
35
|
"@storybook/addon-docs": "^9.1.4",
|
|
35
36
|
"@storybook/react-vite": "^9.1.4",
|
|
36
|
-
"@testing-library/dom": "^
|
|
37
|
+
"@testing-library/dom": "^9.3.4",
|
|
38
|
+
"@testing-library/jest-dom": "^5.16.4",
|
|
37
39
|
"@testing-library/react": "^12.1.2",
|
|
38
40
|
"@testing-library/user-event": "^14.4.3",
|
|
39
41
|
"@types/body-scroll-lock": "^2.6.1",
|
|
40
42
|
"@types/classnames": "^2.2.9",
|
|
41
43
|
"@types/dom-view-transitions": "^1.0.5",
|
|
44
|
+
"@types/jest": "^29.2.1",
|
|
42
45
|
"@types/lodash": "^4.14.149",
|
|
43
46
|
"@types/react": "^17.0.2",
|
|
44
47
|
"@types/react-dom": "^17.0.2",
|
|
45
48
|
"@types/react-is": "^17.0.2",
|
|
46
|
-
"@vitest/ui": "^1.0.0",
|
|
47
49
|
"autoprefixer": "^9.7.4",
|
|
50
|
+
"babel-jest": "29.1.2",
|
|
48
51
|
"babel-loader": "^8.0.6",
|
|
49
52
|
"chromatic": "^13.1.4",
|
|
50
53
|
"core-js": "^3.6.4",
|
|
@@ -52,7 +55,8 @@
|
|
|
52
55
|
"glob": "^7.1.6",
|
|
53
56
|
"install-peers-cli": "^2.2.0",
|
|
54
57
|
"is-ci": "^2.0.0",
|
|
55
|
-
"
|
|
58
|
+
"jest": "29.1.2",
|
|
59
|
+
"jest-environment-jsdom": "29.1.2",
|
|
56
60
|
"node-notifier": "^10.0.1",
|
|
57
61
|
"react": "^17.0.2",
|
|
58
62
|
"react-dom": "^17.0.2",
|
|
@@ -67,13 +71,12 @@
|
|
|
67
71
|
"typescript": "^5.4.3",
|
|
68
72
|
"vite": "^6.3.5",
|
|
69
73
|
"vite-tsconfig-paths": "^5.1.4",
|
|
70
|
-
"vitest": "^1.0.0",
|
|
71
74
|
"yargs": "^15.4.1"
|
|
72
75
|
},
|
|
73
76
|
"peerDependencies": {
|
|
74
77
|
"lodash": "4.17.21",
|
|
75
|
-
"react": ">=
|
|
76
|
-
"react-dom": ">=
|
|
78
|
+
"react": ">= 17.0.0",
|
|
79
|
+
"react-dom": ">= 17.0.0"
|
|
77
80
|
},
|
|
78
81
|
"description": "The official LumApps Design System (LumX) for React applications",
|
|
79
82
|
"homepage": "https://github.com/lumapps/design-system",
|
|
@@ -98,10 +101,10 @@
|
|
|
98
101
|
"scripts": {
|
|
99
102
|
"build": "rollup -c",
|
|
100
103
|
"prepare": "install-peers || exit 0",
|
|
101
|
-
"test": "
|
|
104
|
+
"test": "jest --config jest/index.js --coverage --notify --passWithNoTests --detectOpenHandles --runInBand",
|
|
102
105
|
"start:storybook": "storybook dev -p 9000",
|
|
103
106
|
"build:storybook": "storybook build"
|
|
104
107
|
},
|
|
105
108
|
"sideEffects": false,
|
|
106
|
-
"version": "3.20.
|
|
109
|
+
"version": "3.20.1-alpha.1"
|
|
107
110
|
}
|
|
@@ -3,10 +3,9 @@ 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';
|
|
7
6
|
import { AlertDialog, AlertDialogProps } from './AlertDialog';
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
jest.mock('@lumx/react/hooks/useId', () => ({ useId: () => ':r1:' }));
|
|
10
9
|
|
|
11
10
|
const CLASSNAME = AlertDialog.className as string;
|
|
12
11
|
|
|
@@ -18,7 +17,7 @@ const setup = (propsOverride: Partial<AlertDialogProps> = {}) => {
|
|
|
18
17
|
title: 'Alert',
|
|
19
18
|
isOpen: true,
|
|
20
19
|
description: 'Deserunt et sunt qui consequat sint sit.',
|
|
21
|
-
confirmProps: { onClick:
|
|
20
|
+
confirmProps: { onClick: jest.fn(), label: 'OK' },
|
|
22
21
|
...propsOverride,
|
|
23
22
|
};
|
|
24
23
|
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 =
|
|
56
|
+
const onChange = jest.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 =
|
|
72
|
-
const onBlur =
|
|
71
|
+
const onFocus = jest.fn();
|
|
72
|
+
const onBlur = jest.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 =
|
|
71
|
+
const onClick = jest.fn();
|
|
72
72
|
const { button } = setup({ children: 'Label', disabled: true, onClick });
|
|
73
73
|
expect(button).toHaveAttribute('disabled');
|
|
74
74
|
await userEvent.click(button);
|
|
@@ -76,18 +76,17 @@ describe(`<${Button.displayName}>`, () => {
|
|
|
76
76
|
});
|
|
77
77
|
|
|
78
78
|
it('should render disabled link', async () => {
|
|
79
|
-
const onClick =
|
|
79
|
+
const onClick = jest.fn();
|
|
80
80
|
const { button } = setup({ children: 'Label', disabled: true, href: 'https://example.com', onClick });
|
|
81
|
-
|
|
82
|
-
expect(
|
|
83
|
-
|
|
84
|
-
expect(button).toHaveAttribute('tabindex', '-1');
|
|
81
|
+
// Disabled link do not exist so we fallback to a button
|
|
82
|
+
expect(screen.queryByRole('link')).not.toBeInTheDocument();
|
|
83
|
+
expect(button).toHaveAttribute('disabled');
|
|
85
84
|
await userEvent.click(button);
|
|
86
85
|
expect(onClick).not.toHaveBeenCalled();
|
|
87
86
|
});
|
|
88
87
|
|
|
89
88
|
it('should render aria-disabled button', async () => {
|
|
90
|
-
const onClick =
|
|
89
|
+
const onClick = jest.fn();
|
|
91
90
|
const { button } = setup({ children: 'Label', 'aria-disabled': true, onClick });
|
|
92
91
|
expect(button).toHaveAttribute('aria-disabled');
|
|
93
92
|
await userEvent.click(button);
|
|
@@ -95,7 +94,7 @@ describe(`<${Button.displayName}>`, () => {
|
|
|
95
94
|
});
|
|
96
95
|
|
|
97
96
|
it('should render aria-disabled link', async () => {
|
|
98
|
-
const onClick =
|
|
97
|
+
const onClick = jest.fn();
|
|
99
98
|
const { button } = setup({
|
|
100
99
|
children: 'Label',
|
|
101
100
|
'aria-disabled': true,
|
|
@@ -103,7 +102,8 @@ describe(`<${Button.displayName}>`, () => {
|
|
|
103
102
|
onClick,
|
|
104
103
|
});
|
|
105
104
|
expect(button).toHaveAccessibleName('Label');
|
|
106
|
-
|
|
105
|
+
// Disabled link do not exist so we fallback to a button
|
|
106
|
+
expect(screen.queryByRole('link')).not.toBeInTheDocument();
|
|
107
107
|
expect(button).toHaveAttribute('aria-disabled', 'true');
|
|
108
108
|
await userEvent.click(button);
|
|
109
109
|
expect(onClick).not.toHaveBeenCalled();
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import React, { AriaAttributes, ButtonHTMLAttributes, DetailedHTMLProps, RefObject } from 'react';
|
|
2
2
|
|
|
3
|
+
import isEmpty from 'lodash/isEmpty';
|
|
4
|
+
|
|
3
5
|
import classNames from 'classnames';
|
|
4
6
|
|
|
5
7
|
import { ColorPalette, Emphasis, Size, Theme } from '@lumx/react';
|
|
6
8
|
import { CSS_PREFIX } from '@lumx/react/constants';
|
|
7
9
|
import { GenericProps, HasTheme } from '@lumx/react/utils/type';
|
|
8
10
|
import { handleBasicClasses } from '@lumx/core/js/utils/className';
|
|
11
|
+
import { renderLink } from '@lumx/react/utils/react/renderLink';
|
|
9
12
|
import { forwardRef } from '@lumx/react/utils/react/forwardRef';
|
|
13
|
+
import { useDisableStateProps } from '@lumx/react/utils/disabled/useDisableStateProps';
|
|
10
14
|
import { HasAriaDisabled } from '@lumx/react/utils/type/HasAriaDisabled';
|
|
11
|
-
import { RawClickable } from '@lumx/react/utils/react/RawClickable';
|
|
12
|
-
import { useDisableStateProps } from '@lumx/react/utils/disabled';
|
|
13
15
|
|
|
14
16
|
type HTMLButtonProps = DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;
|
|
15
17
|
|
|
@@ -105,14 +107,18 @@ export const ButtonRoot = forwardRef<ButtonRootProps, HTMLButtonElement | HTMLAn
|
|
|
105
107
|
color,
|
|
106
108
|
emphasis,
|
|
107
109
|
hasBackground,
|
|
110
|
+
href,
|
|
108
111
|
isSelected,
|
|
109
112
|
isActive,
|
|
110
113
|
isFocused,
|
|
111
114
|
isHovered,
|
|
112
115
|
linkAs,
|
|
116
|
+
name,
|
|
113
117
|
size,
|
|
118
|
+
target,
|
|
114
119
|
theme,
|
|
115
120
|
variant,
|
|
121
|
+
type = 'button',
|
|
116
122
|
fullWidth,
|
|
117
123
|
...forwardedProps
|
|
118
124
|
} = otherProps;
|
|
@@ -133,7 +139,7 @@ export const ButtonRoot = forwardRef<ButtonRootProps, HTMLButtonElement | HTMLAn
|
|
|
133
139
|
color: adaptedColor,
|
|
134
140
|
emphasis,
|
|
135
141
|
isSelected,
|
|
136
|
-
isDisabled:
|
|
142
|
+
isDisabled: isAnyDisabled,
|
|
137
143
|
isActive,
|
|
138
144
|
isFocused,
|
|
139
145
|
isHovered,
|
|
@@ -145,18 +151,42 @@ export const ButtonRoot = forwardRef<ButtonRootProps, HTMLButtonElement | HTMLAn
|
|
|
145
151
|
}),
|
|
146
152
|
);
|
|
147
153
|
|
|
154
|
+
/**
|
|
155
|
+
* If the linkAs prop is used, we use the linkAs component instead of a <button>.
|
|
156
|
+
* If there is an href attribute, we display an <a> instead of a <button>.
|
|
157
|
+
*
|
|
158
|
+
* However, in any case, if the component is disabled, we returned a <button> since disabled is not compatible with <a>.
|
|
159
|
+
*/
|
|
160
|
+
if ((linkAs || !isEmpty(props.href)) && !isAnyDisabled) {
|
|
161
|
+
return renderLink(
|
|
162
|
+
{
|
|
163
|
+
linkAs,
|
|
164
|
+
...forwardedProps,
|
|
165
|
+
'aria-label': ariaLabel,
|
|
166
|
+
href,
|
|
167
|
+
target,
|
|
168
|
+
className: buttonClassName,
|
|
169
|
+
ref: ref as RefObject<HTMLAnchorElement>,
|
|
170
|
+
},
|
|
171
|
+
children,
|
|
172
|
+
);
|
|
173
|
+
}
|
|
148
174
|
return (
|
|
149
|
-
<
|
|
150
|
-
as={linkAs || (forwardedProps.href ? 'a' : 'button')}
|
|
175
|
+
<button
|
|
151
176
|
{...forwardedProps}
|
|
152
177
|
{...disabledStateProps}
|
|
153
178
|
aria-disabled={isAnyDisabled}
|
|
154
179
|
aria-label={ariaLabel}
|
|
155
180
|
ref={ref as RefObject<HTMLButtonElement>}
|
|
156
181
|
className={buttonClassName}
|
|
182
|
+
name={name}
|
|
183
|
+
type={
|
|
184
|
+
// eslint-disable-next-line react/button-has-type
|
|
185
|
+
type
|
|
186
|
+
}
|
|
157
187
|
>
|
|
158
188
|
{children}
|
|
159
|
-
</
|
|
189
|
+
</button>
|
|
160
190
|
);
|
|
161
191
|
});
|
|
162
192
|
ButtonRoot.displayName = COMPONENT_NAME;
|
|
@@ -98,7 +98,7 @@ describe(`<${Checkbox.displayName}>`, () => {
|
|
|
98
98
|
});
|
|
99
99
|
|
|
100
100
|
describe('Events', () => {
|
|
101
|
-
const onChange =
|
|
101
|
+
const onChange = jest.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 =
|
|
117
|
+
const onChange = jest.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 =
|
|
129
|
+
const onChange = jest.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 =
|
|
45
|
+
const onClick = jest.fn();
|
|
46
46
|
const { chip } = setup({ children: 'Chip text', onClick });
|
|
47
47
|
expect(chip).toHaveAttribute('role', 'button');
|
|
48
48
|
expect(chip.className).toMatchInlineSnapshot(
|
|
@@ -70,13 +70,11 @@ describe('<Chip />', () => {
|
|
|
70
70
|
});
|
|
71
71
|
|
|
72
72
|
describe('Events', () => {
|
|
73
|
-
const onClick =
|
|
74
|
-
const onAfterClick =
|
|
75
|
-
const onBeforeClick =
|
|
73
|
+
const onClick = jest.fn();
|
|
74
|
+
const onAfterClick = jest.fn();
|
|
75
|
+
const onBeforeClick = jest.fn();
|
|
76
76
|
|
|
77
|
-
beforeEach(
|
|
78
|
-
vi.clearAllMocks();
|
|
79
|
-
});
|
|
77
|
+
beforeEach(jest.clearAllMocks);
|
|
80
78
|
|
|
81
79
|
it('should trigger onBeforeClick only when clicking on the "before" element', async () => {
|
|
82
80
|
const { after, before, chip } = setup({
|
|
@@ -90,12 +88,12 @@ describe('<Chip />', () => {
|
|
|
90
88
|
await userEvent.click(chip);
|
|
91
89
|
expect(onBeforeClick).not.toHaveBeenCalled();
|
|
92
90
|
|
|
93
|
-
|
|
91
|
+
jest.clearAllMocks();
|
|
94
92
|
|
|
95
93
|
await userEvent.click(after as any);
|
|
96
94
|
expect(onBeforeClick).not.toHaveBeenCalled();
|
|
97
95
|
|
|
98
|
-
|
|
96
|
+
jest.clearAllMocks();
|
|
99
97
|
|
|
100
98
|
await userEvent.click(before as any);
|
|
101
99
|
expect(onBeforeClick).toHaveBeenCalled();
|
|
@@ -113,12 +111,12 @@ describe('<Chip />', () => {
|
|
|
113
111
|
await userEvent.click(chip);
|
|
114
112
|
expect(onClick).toHaveBeenCalled();
|
|
115
113
|
|
|
116
|
-
|
|
114
|
+
jest.clearAllMocks();
|
|
117
115
|
|
|
118
116
|
await userEvent.click(after as any);
|
|
119
117
|
expect(onClick).not.toHaveBeenCalled();
|
|
120
118
|
|
|
121
|
-
|
|
119
|
+
jest.clearAllMocks();
|
|
122
120
|
|
|
123
121
|
await userEvent.click(before as any);
|
|
124
122
|
expect(onClick).not.toHaveBeenCalled();
|
|
@@ -136,12 +134,12 @@ describe('<Chip />', () => {
|
|
|
136
134
|
await userEvent.click(chip);
|
|
137
135
|
expect(onAfterClick).not.toHaveBeenCalled();
|
|
138
136
|
|
|
139
|
-
|
|
137
|
+
jest.clearAllMocks();
|
|
140
138
|
|
|
141
139
|
await userEvent.click(after as any);
|
|
142
140
|
expect(onAfterClick).toHaveBeenCalled();
|
|
143
141
|
|
|
144
|
-
|
|
142
|
+
jest.clearAllMocks();
|
|
145
143
|
|
|
146
144
|
await userEvent.click(before as any);
|
|
147
145
|
expect(onAfterClick).not.toHaveBeenCalled();
|
|
@@ -164,7 +162,7 @@ describe('<Chip />', () => {
|
|
|
164
162
|
});
|
|
165
163
|
|
|
166
164
|
it('should forward key down event', async () => {
|
|
167
|
-
const onKeyDown =
|
|
165
|
+
const onKeyDown = jest.fn();
|
|
168
166
|
const { chip } = setup({ onClick, onKeyDown });
|
|
169
167
|
|
|
170
168
|
fireEvent.keyDown(chip, { key: 'A', code: 'KeyA' });
|
|
@@ -173,7 +171,7 @@ describe('<Chip />', () => {
|
|
|
173
171
|
|
|
174
172
|
it('should forward key down event and trigger `onClick` when pressing Enter', async () => {
|
|
175
173
|
const user = userEvent.setup();
|
|
176
|
-
const onKeyDown =
|
|
174
|
+
const onKeyDown = jest.fn();
|
|
177
175
|
const { chip } = setup({ onClick, onKeyDown });
|
|
178
176
|
|
|
179
177
|
await user.tab();
|
|
@@ -189,7 +187,7 @@ describe('<Chip />', () => {
|
|
|
189
187
|
|
|
190
188
|
describe('Disabled state', () => {
|
|
191
189
|
it('should render disabled chip button', async () => {
|
|
192
|
-
const onClick =
|
|
190
|
+
const onClick = jest.fn();
|
|
193
191
|
const { chip } = setup({ children: 'Label', isDisabled: true, onClick });
|
|
194
192
|
expect(chip).toHaveAttribute('aria-disabled', 'true');
|
|
195
193
|
await userEvent.click(chip);
|
|
@@ -197,7 +195,7 @@ describe('<Chip />', () => {
|
|
|
197
195
|
});
|
|
198
196
|
|
|
199
197
|
it('should render disabled chip link', async () => {
|
|
200
|
-
const onClick =
|
|
198
|
+
const onClick = jest.fn();
|
|
201
199
|
const { chip } = setup({ children: 'Label', isDisabled: true, href: 'https://example.com', onClick });
|
|
202
200
|
// Disabled link should not have an href.
|
|
203
201
|
expect(chip).not.toHaveAttribute('href');
|
|
@@ -207,7 +205,7 @@ describe('<Chip />', () => {
|
|
|
207
205
|
});
|
|
208
206
|
|
|
209
207
|
it('should render aria-disabled chip button', async () => {
|
|
210
|
-
const onClick =
|
|
208
|
+
const onClick = jest.fn();
|
|
211
209
|
const { chip } = setup({ children: 'Label', 'aria-disabled': true, onClick });
|
|
212
210
|
expect(chip).toHaveAttribute('aria-disabled', 'true');
|
|
213
211
|
await userEvent.click(chip);
|
|
@@ -216,7 +214,7 @@ describe('<Chip />', () => {
|
|
|
216
214
|
});
|
|
217
215
|
|
|
218
216
|
it('should render aria-disabled chip link', async () => {
|
|
219
|
-
const onClick =
|
|
217
|
+
const onClick = jest.fn();
|
|
220
218
|
const { chip } = setup({
|
|
221
219
|
children: 'Label',
|
|
222
220
|
'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 =
|
|
13
|
-
|
|
12
|
+
Date.now = jest.fn(() => mockedDate.valueOf());
|
|
13
|
+
jest.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:
|
|
20
|
+
onChange: jest.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 =
|
|
14
|
-
|
|
13
|
+
Date.now = jest.fn(() => mockedDate.valueOf());
|
|
14
|
+
jest.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:
|
|
24
|
-
onNextMonthChange:
|
|
25
|
-
onPrevMonthChange:
|
|
23
|
+
onChange: jest.fn(),
|
|
24
|
+
onNextMonthChange: jest.fn(),
|
|
25
|
+
onPrevMonthChange: jest.fn(),
|
|
26
26
|
selectedMonth: mockedDate,
|
|
27
27
|
value: mockedDate,
|
|
28
28
|
nextButtonProps: { label: 'Next month' },
|
|
29
29
|
previousButtonProps: { label: 'Previous month' },
|
|
30
|
-
onMonthChange:
|
|
30
|
+
onMonthChange: jest.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 =
|
|
14
|
-
|
|
13
|
+
Date.now = jest.fn(() => mockedDate.valueOf());
|
|
14
|
+
jest.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:
|
|
22
|
+
onChange: jest.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 =
|
|
54
|
+
const onClose = jest.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 =
|
|
62
|
+
const onClose = jest.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 =
|
|
70
|
+
const onClose = jest.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 =
|
|
78
|
+
const onClose = jest.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 =
|
|
31
|
+
const onClose = jest.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 =
|
|
43
|
+
const onClose = jest.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 =
|
|
51
|
+
const onClose = jest.fn();
|
|
52
52
|
setup({ isOpen: true, onClose, closeOnEscape: false });
|
|
53
53
|
|
|
54
54
|
await userEvent.keyboard('[Escape]');
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Mock } from 'vitest';
|
|
2
1
|
import React from 'react';
|
|
3
2
|
|
|
4
3
|
import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
|
|
@@ -12,7 +11,7 @@ import { ExpansionPanel, ExpansionPanelProps } from '.';
|
|
|
12
11
|
|
|
13
12
|
const CLASSNAME = ExpansionPanel.className as string;
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
jest.mock('@lumx/react/utils/browser/isFocusVisible');
|
|
16
15
|
|
|
17
16
|
const mockChildrenContent = 'children content';
|
|
18
17
|
|
|
@@ -56,7 +55,7 @@ const setup = (
|
|
|
56
55
|
};
|
|
57
56
|
|
|
58
57
|
describe(`<${ExpansionPanel.displayName}>`, () => {
|
|
59
|
-
(isFocusVisible as Mock).mockReturnValue(false);
|
|
58
|
+
(isFocusVisible as jest.Mock).mockReturnValue(false);
|
|
60
59
|
|
|
61
60
|
describe('Render', () => {
|
|
62
61
|
it('should render default', () => {
|
|
@@ -101,9 +100,9 @@ describe(`<${ExpansionPanel.displayName}>`, () => {
|
|
|
101
100
|
});
|
|
102
101
|
|
|
103
102
|
describe('Events', () => {
|
|
104
|
-
const onOpen =
|
|
105
|
-
const onClose =
|
|
106
|
-
const onToggleOpen =
|
|
103
|
+
const onOpen = jest.fn();
|
|
104
|
+
const onClose = jest.fn();
|
|
105
|
+
const onToggleOpen = jest.fn();
|
|
107
106
|
|
|
108
107
|
beforeEach(onOpen.mockClear);
|
|
109
108
|
beforeEach(onClose.mockClear);
|
|
@@ -1,47 +1,21 @@
|
|
|
1
|
+
import DefaultStory, { SizeAndShape as DefaultSizeAndShape } from '@lumx/core/js/components/Icon/Stories';
|
|
1
2
|
import { mdiEmail } from '@lumx/icons';
|
|
2
|
-
import { ColorPalette, ColorVariant, GridColumn, Icon,
|
|
3
|
+
import { ColorPalette, ColorVariant, GridColumn, Icon, Size } from '@lumx/react';
|
|
3
4
|
import { withCombinations } from '@lumx/react/stories/decorators/withCombinations';
|
|
4
5
|
import { withUndefined } from '@lumx/react/stories/controls/withUndefined';
|
|
5
|
-
import { iconArgType } from '@lumx/react/stories/controls/icons';
|
|
6
|
-
import { colorArgType, colorVariantArgType } from '@lumx/react/stories/controls/color';
|
|
7
6
|
import { withWrapper } from '@lumx/react/stories/decorators/withWrapper';
|
|
8
7
|
|
|
9
|
-
const iconSizes: Array<IconSizes> = [Size.xxs, Size.xs, Size.s, Size.m, Size.l, Size.xl, Size.xxl];
|
|
10
|
-
|
|
11
8
|
export default {
|
|
12
9
|
title: 'LumX components/icon/Icon',
|
|
13
10
|
component: Icon,
|
|
14
|
-
|
|
15
|
-
argTypes: {
|
|
16
|
-
icon: iconArgType,
|
|
17
|
-
hasShape: { control: 'boolean' },
|
|
18
|
-
color: colorArgType,
|
|
19
|
-
colorVariant: colorVariantArgType,
|
|
20
|
-
},
|
|
11
|
+
...DefaultStory,
|
|
21
12
|
};
|
|
22
13
|
|
|
23
14
|
/**
|
|
24
15
|
* All combinations of size and shape
|
|
25
16
|
*/
|
|
26
17
|
export const SizeAndShape = {
|
|
27
|
-
|
|
28
|
-
icon: mdiEmail,
|
|
29
|
-
},
|
|
30
|
-
argTypes: {
|
|
31
|
-
hasShape: { control: false },
|
|
32
|
-
size: { control: false },
|
|
33
|
-
},
|
|
34
|
-
decorators: [
|
|
35
|
-
withCombinations({
|
|
36
|
-
combinations: {
|
|
37
|
-
cols: { key: 'size', options: withUndefined(iconSizes) },
|
|
38
|
-
rows: {
|
|
39
|
-
Default: {},
|
|
40
|
-
'Has shape': { hasShape: true },
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
}),
|
|
44
|
-
],
|
|
18
|
+
...DefaultSizeAndShape,
|
|
45
19
|
};
|
|
46
20
|
|
|
47
21
|
/**
|