@lumx/react 3.11.3 → 3.11.4-alpha.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.
- package/index.js +11 -5
- package/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/dialog/Dialog.test.tsx +16 -0
- package/src/components/dialog/Dialog.tsx +66 -56
- package/src/components/lightbox/Lightbox.test.tsx +18 -0
- package/src/components/lightbox/Lightbox.tsx +10 -8
- package/src/components/popover-dialog/PopoverDialog.stories.tsx +2 -1
- package/src/components/popover-dialog/PopoverDialog.test.tsx +21 -1
- package/src/components/popover-dialog/PopoverDialog.tsx +2 -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.11.
|
|
10
|
-
"@lumx/icons": "^3.11.
|
|
9
|
+
"@lumx/core": "^3.11.4-alpha.0",
|
|
10
|
+
"@lumx/icons": "^3.11.4-alpha.0",
|
|
11
11
|
"@popperjs/core": "^2.5.4",
|
|
12
12
|
"body-scroll-lock": "^3.1.5",
|
|
13
13
|
"classnames": "^2.3.2",
|
|
@@ -110,5 +110,5 @@
|
|
|
110
110
|
"build:storybook": "storybook build"
|
|
111
111
|
},
|
|
112
112
|
"sideEffects": false,
|
|
113
|
-
"version": "3.11.
|
|
113
|
+
"version": "3.11.4-alpha.0"
|
|
114
114
|
}
|
|
@@ -6,6 +6,7 @@ import { render, screen } from '@testing-library/react';
|
|
|
6
6
|
import { commonTestsSuiteRTL, SetupRenderOptions } from '@lumx/react/testing/utils';
|
|
7
7
|
import userEvent from '@testing-library/user-event';
|
|
8
8
|
import { ThemeSentinel } from '@lumx/react/testing/utils/ThemeSentinel';
|
|
9
|
+
import { Heading, HeadingLevelProvider } from '@lumx/react';
|
|
9
10
|
|
|
10
11
|
const CLASSNAME = Dialog.className as string;
|
|
11
12
|
|
|
@@ -33,6 +34,21 @@ describe(`<${Dialog.displayName}>`, () => {
|
|
|
33
34
|
expect(container).toHaveAttribute('aria-modal', 'true');
|
|
34
35
|
});
|
|
35
36
|
|
|
37
|
+
it('should have reset the heading level context', () => {
|
|
38
|
+
setup(
|
|
39
|
+
// Heading inside the dialog
|
|
40
|
+
{ children: <Heading>Title</Heading> },
|
|
41
|
+
{
|
|
42
|
+
// This level context should not affect headings inside the dialog
|
|
43
|
+
wrapper({ children }) {
|
|
44
|
+
return <HeadingLevelProvider level={3}>{children}</HeadingLevelProvider>;
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
);
|
|
48
|
+
// Heading inside should use the dialog heading level 2
|
|
49
|
+
expect(screen.queryByRole('heading', { name: 'Title', level: 2 })).toBeInTheDocument();
|
|
50
|
+
});
|
|
51
|
+
|
|
36
52
|
describe('Events', () => {
|
|
37
53
|
it('should trigger `onClose` when pressing `escape` key', async () => {
|
|
38
54
|
const onClose = jest.fn();
|
|
@@ -3,7 +3,7 @@ import { createPortal } from 'react-dom';
|
|
|
3
3
|
|
|
4
4
|
import classNames from 'classnames';
|
|
5
5
|
|
|
6
|
-
import { Progress, ProgressVariant, Size } from '@lumx/react';
|
|
6
|
+
import { HeadingLevelProvider, Progress, ProgressVariant, Size } from '@lumx/react';
|
|
7
7
|
|
|
8
8
|
import { DIALOG_TRANSITION_DURATION, DOCUMENT } from '@lumx/react/constants';
|
|
9
9
|
import { useCallbackOnEscape } from '@lumx/react/hooks/useCallbackOnEscape';
|
|
@@ -212,67 +212,77 @@ export const Dialog = forwardRef<DialogProps, HTMLDivElement>((props, ref) => {
|
|
|
212
212
|
>
|
|
213
213
|
<div className={`${CLASSNAME}__overlay`} />
|
|
214
214
|
|
|
215
|
-
<
|
|
216
|
-
<
|
|
217
|
-
<
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
215
|
+
<HeadingLevelProvider level={2}>
|
|
216
|
+
<ThemeProvider value={undefined}>
|
|
217
|
+
<section
|
|
218
|
+
className={`${CLASSNAME}__container`}
|
|
219
|
+
role="dialog"
|
|
220
|
+
aria-modal="true"
|
|
221
|
+
{...dialogProps}
|
|
221
222
|
>
|
|
222
|
-
<
|
|
223
|
-
{
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
headerChildProps
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
223
|
+
<ClickAwayProvider
|
|
224
|
+
callback={!shouldPreventCloseOnClickAway && onClose}
|
|
225
|
+
childrenRefs={clickAwayRefs}
|
|
226
|
+
parentRef={rootRef}
|
|
227
|
+
>
|
|
228
|
+
<div className={`${CLASSNAME}__wrapper`} ref={wrapperRef}>
|
|
229
|
+
{(header || headerChildContent) && (
|
|
230
|
+
<header
|
|
231
|
+
{...headerChildProps}
|
|
232
|
+
className={classNames(
|
|
233
|
+
`${CLASSNAME}__header`,
|
|
234
|
+
(forceHeaderDivider || hasTopIntersection) &&
|
|
235
|
+
`${CLASSNAME}__header--has-divider`,
|
|
236
|
+
headerChildProps?.className,
|
|
237
|
+
)}
|
|
238
|
+
>
|
|
239
|
+
{header}
|
|
240
|
+
{headerChildContent}
|
|
241
|
+
</header>
|
|
242
|
+
)}
|
|
237
243
|
|
|
238
|
-
<div ref={mergeRefs(contentRef, localContentRef)} className={`${CLASSNAME}__content`}>
|
|
239
244
|
<div
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
+
ref={mergeRefs(contentRef, localContentRef)}
|
|
246
|
+
className={`${CLASSNAME}__content`}
|
|
247
|
+
>
|
|
248
|
+
<div
|
|
249
|
+
className={`${CLASSNAME}__sentinel ${CLASSNAME}__sentinel--top`}
|
|
250
|
+
ref={setSentinelTop}
|
|
251
|
+
/>
|
|
245
252
|
|
|
246
|
-
|
|
247
|
-
className={`${CLASSNAME}__sentinel ${CLASSNAME}__sentinel--bottom`}
|
|
248
|
-
ref={setSentinelBottom}
|
|
249
|
-
/>
|
|
250
|
-
</div>
|
|
253
|
+
{content}
|
|
251
254
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
`${CLASSNAME}__footer`,
|
|
257
|
-
(forceFooterDivider || hasBottomIntersection) &&
|
|
258
|
-
`${CLASSNAME}__footer--has-divider`,
|
|
259
|
-
footerChildProps?.className,
|
|
260
|
-
)}
|
|
261
|
-
>
|
|
262
|
-
{footer}
|
|
263
|
-
{footerChildContent}
|
|
264
|
-
</footer>
|
|
265
|
-
)}
|
|
266
|
-
|
|
267
|
-
{isLoading && (
|
|
268
|
-
<div className={`${CLASSNAME}__progress-overlay`}>
|
|
269
|
-
<Progress variant={ProgressVariant.circular} />
|
|
255
|
+
<div
|
|
256
|
+
className={`${CLASSNAME}__sentinel ${CLASSNAME}__sentinel--bottom`}
|
|
257
|
+
ref={setSentinelBottom}
|
|
258
|
+
/>
|
|
270
259
|
</div>
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
260
|
+
|
|
261
|
+
{(footer || footerChildContent) && (
|
|
262
|
+
<footer
|
|
263
|
+
{...footerChildProps}
|
|
264
|
+
className={classNames(
|
|
265
|
+
`${CLASSNAME}__footer`,
|
|
266
|
+
(forceFooterDivider || hasBottomIntersection) &&
|
|
267
|
+
`${CLASSNAME}__footer--has-divider`,
|
|
268
|
+
footerChildProps?.className,
|
|
269
|
+
)}
|
|
270
|
+
>
|
|
271
|
+
{footer}
|
|
272
|
+
{footerChildContent}
|
|
273
|
+
</footer>
|
|
274
|
+
)}
|
|
275
|
+
|
|
276
|
+
{isLoading && (
|
|
277
|
+
<div className={`${CLASSNAME}__progress-overlay`}>
|
|
278
|
+
<Progress variant={ProgressVariant.circular} />
|
|
279
|
+
</div>
|
|
280
|
+
)}
|
|
281
|
+
</div>
|
|
282
|
+
</ClickAwayProvider>
|
|
283
|
+
</section>
|
|
284
|
+
</ThemeProvider>
|
|
285
|
+
</HeadingLevelProvider>
|
|
276
286
|
</div>,
|
|
277
287
|
document.body,
|
|
278
288
|
)
|
|
@@ -5,6 +5,7 @@ import { queryByClassName } from '@lumx/react/testing/utils/queries';
|
|
|
5
5
|
import { render, screen } from '@testing-library/react';
|
|
6
6
|
import { ThemeSentinel } from '@lumx/react/testing/utils/ThemeSentinel';
|
|
7
7
|
|
|
8
|
+
import { Heading, HeadingLevelProvider } from '@lumx/react';
|
|
8
9
|
import { Lightbox, LightboxProps } from './Lightbox';
|
|
9
10
|
|
|
10
11
|
const CLASSNAME = Lightbox.className as string;
|
|
@@ -22,6 +23,23 @@ const setup = (props: Partial<LightboxProps> = {}, { wrapper }: SetupRenderOptio
|
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
describe(`<${Lightbox.displayName}>`, () => {
|
|
26
|
+
it('should have reset the heading level context', () => {
|
|
27
|
+
setup(
|
|
28
|
+
{
|
|
29
|
+
// Heading inside the lightbox
|
|
30
|
+
children: <Heading>Title</Heading>,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
// This level context should not affect headings inside the lightbox
|
|
34
|
+
wrapper({ children }) {
|
|
35
|
+
return <HeadingLevelProvider level={3}>{children}</HeadingLevelProvider>;
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
);
|
|
39
|
+
// Heading inside should use the lightbox heading level 2
|
|
40
|
+
expect(screen.queryByRole('heading', { name: 'Title', level: 2 })).toBeInTheDocument();
|
|
41
|
+
});
|
|
42
|
+
|
|
25
43
|
// Common tests suite.
|
|
26
44
|
commonTestsSuiteRTL(setup, {
|
|
27
45
|
baseClassName: CLASSNAME,
|
|
@@ -4,7 +4,7 @@ import classNames from 'classnames';
|
|
|
4
4
|
import { createPortal } from 'react-dom';
|
|
5
5
|
|
|
6
6
|
import { mdiClose } from '@lumx/icons';
|
|
7
|
-
import { IconButton, IconButtonProps } from '@lumx/react';
|
|
7
|
+
import { HeadingLevelProvider, IconButton, IconButtonProps } from '@lumx/react';
|
|
8
8
|
import { DIALOG_TRANSITION_DURATION, DOCUMENT } from '@lumx/react/constants';
|
|
9
9
|
import { GenericProps, HasTheme } from '@lumx/react/utils/type';
|
|
10
10
|
import { getRootClassName, handleBasicClasses } from '@lumx/react/utils/className';
|
|
@@ -162,13 +162,15 @@ export const Lightbox = forwardRef<LightboxProps, HTMLDivElement>((props, ref) =
|
|
|
162
162
|
/>
|
|
163
163
|
</div>
|
|
164
164
|
)}
|
|
165
|
-
<
|
|
166
|
-
<
|
|
167
|
-
<
|
|
168
|
-
{
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
165
|
+
<HeadingLevelProvider level={2}>
|
|
166
|
+
<ThemeProvider value={undefined}>
|
|
167
|
+
<ClickAwayProvider callback={!preventAutoClose && onClose} childrenRefs={clickAwayRefs}>
|
|
168
|
+
<div ref={childrenRef} className={`${CLASSNAME}__wrapper`} role="presentation">
|
|
169
|
+
{children}
|
|
170
|
+
</div>
|
|
171
|
+
</ClickAwayProvider>
|
|
172
|
+
</ThemeProvider>
|
|
173
|
+
</HeadingLevelProvider>
|
|
172
174
|
</div>,
|
|
173
175
|
document.body,
|
|
174
176
|
);
|
|
@@ -40,7 +40,7 @@ export const WithButtonTrigger = (props: any) => {
|
|
|
40
40
|
/**
|
|
41
41
|
* Example PopoverDialog using an icon button as a trigger
|
|
42
42
|
*/
|
|
43
|
-
export const WithIconButtonTrigger = (props: any) => {
|
|
43
|
+
export const WithIconButtonTrigger = ({ children, ...props }: any) => {
|
|
44
44
|
const anchorRef = React.useRef(null);
|
|
45
45
|
const [isOpen, close, open] = useBooleanState(false);
|
|
46
46
|
|
|
@@ -57,6 +57,7 @@ export const WithIconButtonTrigger = (props: any) => {
|
|
|
57
57
|
{...props}
|
|
58
58
|
>
|
|
59
59
|
<Button onClick={close}>Close</Button>
|
|
60
|
+
{children}
|
|
60
61
|
</PopoverDialog>
|
|
61
62
|
</>
|
|
62
63
|
);
|
|
@@ -2,8 +2,9 @@ import React from 'react';
|
|
|
2
2
|
import { render, screen, within } from '@testing-library/react';
|
|
3
3
|
import userEvent from '@testing-library/user-event';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Heading, HeadingLevelProvider } from '@lumx/react';
|
|
6
6
|
import { WithButtonTrigger, WithIconButtonTrigger } from './PopoverDialog.stories';
|
|
7
|
+
import { PopoverDialog } from './PopoverDialog';
|
|
7
8
|
|
|
8
9
|
jest.mock('@lumx/react/utils/browser/isFocusVisible');
|
|
9
10
|
|
|
@@ -117,4 +118,23 @@ describe(`<${PopoverDialog.displayName}>`, () => {
|
|
|
117
118
|
// Focus restored to the trigger element
|
|
118
119
|
expect(triggerElement).toHaveFocus();
|
|
119
120
|
});
|
|
121
|
+
|
|
122
|
+
it('should have reset the heading level context', async () => {
|
|
123
|
+
render(
|
|
124
|
+
// This level context should not affect headings inside the popover dialog
|
|
125
|
+
|
|
126
|
+
<HeadingLevelProvider level={3}>
|
|
127
|
+
<WithIconButtonTrigger>
|
|
128
|
+
{/* Heading inside the popover dialog */}
|
|
129
|
+
<Heading>Title</Heading>
|
|
130
|
+
</WithIconButtonTrigger>
|
|
131
|
+
</HeadingLevelProvider>,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// Open popover
|
|
135
|
+
await userEvent.click(screen.getByRole('button', { name: 'Open popover' }));
|
|
136
|
+
|
|
137
|
+
// Heading inside should use the popover dialog heading level 2
|
|
138
|
+
expect(screen.getByRole('heading', { name: 'Title', level: 2 })).toBeInTheDocument();
|
|
139
|
+
});
|
|
120
140
|
});
|
|
@@ -6,6 +6,7 @@ import { HasAriaLabelOrLabelledBy } from '@lumx/react/utils/type';
|
|
|
6
6
|
import { getRootClassName } from '@lumx/react/utils/className';
|
|
7
7
|
import { forwardRef } from '@lumx/react/utils/react/forwardRef';
|
|
8
8
|
|
|
9
|
+
import { HeadingLevelProvider } from '@lumx/react/components/heading';
|
|
9
10
|
import { Popover, PopoverProps } from '../popover/Popover';
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -65,7 +66,7 @@ export const PopoverDialog = forwardRef<PopoverDialogProps, HTMLDivElement>((pro
|
|
|
65
66
|
closeOnEscape
|
|
66
67
|
withFocusTrap
|
|
67
68
|
>
|
|
68
|
-
{children}
|
|
69
|
+
<HeadingLevelProvider level={2}>{children}</HeadingLevelProvider>
|
|
69
70
|
</Popover>
|
|
70
71
|
);
|
|
71
72
|
});
|