@patternfly/react-core 6.7.0-prerelease.1 → 6.7.0-prerelease.3
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/CHANGELOG.md +12 -0
- package/components/package.json +1 -1
- package/deprecated/package.json +1 -1
- package/dist/dynamic/components/AboutModal/package.json +1 -1
- package/dist/dynamic/components/Accordion/package.json +1 -1
- package/dist/dynamic/components/ActionList/package.json +1 -1
- package/dist/dynamic/components/Alert/package.json +1 -1
- package/dist/dynamic/components/Avatar/package.json +1 -1
- package/dist/dynamic/components/BackToTop/package.json +1 -1
- package/dist/dynamic/components/Backdrop/package.json +1 -1
- package/dist/dynamic/components/BackgroundImage/package.json +1 -1
- package/dist/dynamic/components/Badge/package.json +1 -1
- package/dist/dynamic/components/Banner/package.json +1 -1
- package/dist/dynamic/components/Brand/package.json +1 -1
- package/dist/dynamic/components/Breadcrumb/package.json +1 -1
- package/dist/dynamic/components/Button/package.json +1 -1
- package/dist/dynamic/components/CalendarMonth/package.json +1 -1
- package/dist/dynamic/components/Card/package.json +1 -1
- package/dist/dynamic/components/Checkbox/package.json +1 -1
- package/dist/dynamic/components/ClipboardCopy/package.json +1 -1
- package/dist/dynamic/components/CodeBlock/package.json +1 -1
- package/dist/dynamic/components/Compass/package.json +1 -1
- package/dist/dynamic/components/Content/package.json +1 -1
- package/dist/dynamic/components/DataList/package.json +1 -1
- package/dist/dynamic/components/DatePicker/package.json +1 -1
- package/dist/dynamic/components/DescriptionList/package.json +1 -1
- package/dist/dynamic/components/Divider/package.json +1 -1
- package/dist/dynamic/components/Drawer/package.json +1 -1
- package/dist/dynamic/components/Dropdown/package.json +1 -1
- package/dist/dynamic/components/DualListSelector/package.json +1 -1
- package/dist/dynamic/components/EmptyState/package.json +1 -1
- package/dist/dynamic/components/ExpandableSection/package.json +1 -1
- package/dist/dynamic/components/FileUpload/package.json +1 -1
- package/dist/dynamic/components/Form/package.json +1 -1
- package/dist/dynamic/components/FormSelect/package.json +1 -1
- package/dist/dynamic/components/HelperText/package.json +1 -1
- package/dist/dynamic/components/Hero/package.json +1 -1
- package/dist/dynamic/components/Hint/package.json +1 -1
- package/dist/dynamic/components/Icon/package.json +1 -1
- package/dist/dynamic/components/InputGroup/package.json +1 -1
- package/dist/dynamic/components/JumpLinks/package.json +1 -1
- package/dist/dynamic/components/Label/package.json +1 -1
- package/dist/dynamic/components/List/package.json +1 -1
- package/dist/dynamic/components/LoginPage/package.json +1 -1
- package/dist/dynamic/components/Masthead/package.json +1 -1
- package/dist/dynamic/components/Menu/package.json +1 -1
- package/dist/dynamic/components/MenuToggle/package.json +1 -1
- package/dist/dynamic/components/Modal/package.json +1 -1
- package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
- package/dist/dynamic/components/Nav/package.json +1 -1
- package/dist/dynamic/components/NotificationBadge/package.json +1 -1
- package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
- package/dist/dynamic/components/NumberInput/package.json +1 -1
- package/dist/dynamic/components/OverflowMenu/package.json +1 -1
- package/dist/dynamic/components/Page/package.json +1 -1
- package/dist/dynamic/components/Pagination/package.json +1 -1
- package/dist/dynamic/components/Panel/package.json +1 -1
- package/dist/dynamic/components/Popover/package.json +1 -1
- package/dist/dynamic/components/Progress/package.json +1 -1
- package/dist/dynamic/components/ProgressStepper/package.json +1 -1
- package/dist/dynamic/components/Radio/package.json +1 -1
- package/dist/dynamic/components/SearchInput/package.json +1 -1
- package/dist/dynamic/components/Select/package.json +1 -1
- package/dist/dynamic/components/Sidebar/package.json +1 -1
- package/dist/dynamic/components/SimpleList/package.json +1 -1
- package/dist/dynamic/components/Skeleton/package.json +1 -1
- package/dist/dynamic/components/SkipToContent/package.json +1 -1
- package/dist/dynamic/components/Slider/package.json +1 -1
- package/dist/dynamic/components/Spinner/package.json +1 -1
- package/dist/dynamic/components/Switch/package.json +1 -1
- package/dist/dynamic/components/Tabs/package.json +1 -1
- package/dist/dynamic/components/TextArea/package.json +1 -1
- package/dist/dynamic/components/TextInput/package.json +1 -1
- package/dist/dynamic/components/TextInputGroup/package.json +1 -1
- package/dist/dynamic/components/TimePicker/package.json +1 -1
- package/dist/dynamic/components/Timestamp/package.json +1 -1
- package/dist/dynamic/components/Title/package.json +1 -1
- package/dist/dynamic/components/ToggleGroup/package.json +1 -1
- package/dist/dynamic/components/Toolbar/package.json +1 -1
- package/dist/dynamic/components/Tooltip/package.json +1 -1
- package/dist/dynamic/components/TreeView/package.json +1 -1
- package/dist/dynamic/components/Truncate/package.json +1 -1
- package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
- package/dist/dynamic/components/Wizard/package.json +1 -1
- package/dist/dynamic/deprecated/components/Chip/package.json +1 -1
- package/dist/dynamic/deprecated/components/DragDrop/package.json +1 -1
- package/dist/dynamic/deprecated/components/DualListSelector/package.json +1 -1
- package/dist/dynamic/deprecated/components/Modal/package.json +1 -1
- package/dist/dynamic/deprecated/components/Tile/package.json +1 -1
- package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
- package/dist/dynamic/deprecated/components/package.json +1 -1
- package/dist/dynamic/helpers/AnimationsProvider/AnimationsProvider/package.json +1 -1
- package/dist/dynamic/helpers/AnimationsProvider/package.json +1 -1
- package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
- package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
- package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
- package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
- package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
- package/dist/dynamic/helpers/SSRSafeIds/SSRSafeIds/package.json +1 -1
- package/dist/dynamic/helpers/constants/package.json +1 -1
- package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
- package/dist/dynamic/helpers/fileUtils/package.json +1 -1
- package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
- package/dist/dynamic/helpers/inert/package.json +1 -1
- package/dist/dynamic/helpers/package.json +1 -1
- package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
- package/dist/dynamic/helpers/typeUtils/package.json +1 -1
- package/dist/dynamic/helpers/useInterval/package.json +1 -1
- package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
- package/dist/dynamic/helpers/useSSRSafeId/package.json +1 -1
- package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
- package/dist/dynamic/helpers/util/package.json +1 -1
- package/dist/dynamic/layouts/Bullseye/package.json +1 -1
- package/dist/dynamic/layouts/Flex/package.json +1 -1
- package/dist/dynamic/layouts/Gallery/package.json +1 -1
- package/dist/dynamic/layouts/Grid/package.json +1 -1
- package/dist/dynamic/layouts/Level/package.json +1 -1
- package/dist/dynamic/layouts/Split/package.json +1 -1
- package/dist/dynamic/layouts/Stack/package.json +1 -1
- package/dist/dynamic/styles/package.json +1 -1
- package/dist/esm/components/Backdrop/Backdrop.d.ts +4 -0
- package/dist/esm/components/Backdrop/Backdrop.d.ts.map +1 -1
- package/dist/esm/components/Backdrop/Backdrop.js +4 -2
- package/dist/esm/components/Backdrop/Backdrop.js.map +1 -1
- package/dist/esm/components/Button/Button.d.ts +1 -3
- package/dist/esm/components/Button/Button.d.ts.map +1 -1
- package/dist/esm/components/Button/Button.js +2 -2
- package/dist/esm/components/Button/Button.js.map +1 -1
- package/dist/esm/components/Compass/Compass.d.ts +3 -7
- package/dist/esm/components/Compass/Compass.d.ts.map +1 -1
- package/dist/esm/components/Compass/Compass.js +2 -2
- package/dist/esm/components/Compass/Compass.js.map +1 -1
- package/dist/esm/components/MenuToggle/MenuToggle.d.ts +0 -2
- package/dist/esm/components/MenuToggle/MenuToggle.d.ts.map +1 -1
- package/dist/esm/components/MenuToggle/MenuToggle.js +2 -3
- package/dist/esm/components/MenuToggle/MenuToggle.js.map +1 -1
- package/dist/esm/components/Modal/Modal.d.ts +2 -0
- package/dist/esm/components/Modal/Modal.d.ts.map +1 -1
- package/dist/esm/components/Modal/Modal.js +2 -1
- package/dist/esm/components/Modal/Modal.js.map +1 -1
- package/dist/esm/components/Modal/ModalBox.d.ts +4 -0
- package/dist/esm/components/Modal/ModalBox.d.ts.map +1 -1
- package/dist/esm/components/Modal/ModalBox.js +2 -2
- package/dist/esm/components/Modal/ModalBox.js.map +1 -1
- package/dist/esm/components/Modal/ModalContent.d.ts +2 -0
- package/dist/esm/components/Modal/ModalContent.d.ts.map +1 -1
- package/dist/esm/components/Modal/ModalContent.js +40 -5
- package/dist/esm/components/Modal/ModalContent.js.map +1 -1
- package/dist/esm/components/Nav/Nav.d.ts +1 -1
- package/dist/esm/components/Nav/Nav.d.ts.map +1 -1
- package/dist/esm/components/Nav/Nav.js +2 -2
- package/dist/esm/components/Nav/Nav.js.map +1 -1
- package/dist/esm/components/Page/Page.d.ts +3 -7
- package/dist/esm/components/Page/Page.d.ts.map +1 -1
- package/dist/esm/components/Page/Page.js +3 -4
- package/dist/esm/components/Page/Page.js.map +1 -1
- package/dist/js/components/Backdrop/Backdrop.d.ts +4 -0
- package/dist/js/components/Backdrop/Backdrop.d.ts.map +1 -1
- package/dist/js/components/Backdrop/Backdrop.js +4 -2
- package/dist/js/components/Backdrop/Backdrop.js.map +1 -1
- package/dist/js/components/Button/Button.d.ts +1 -3
- package/dist/js/components/Button/Button.d.ts.map +1 -1
- package/dist/js/components/Button/Button.js +2 -2
- package/dist/js/components/Button/Button.js.map +1 -1
- package/dist/js/components/Compass/Compass.d.ts +3 -7
- package/dist/js/components/Compass/Compass.d.ts.map +1 -1
- package/dist/js/components/Compass/Compass.js +2 -2
- package/dist/js/components/Compass/Compass.js.map +1 -1
- package/dist/js/components/MenuToggle/MenuToggle.d.ts +0 -2
- package/dist/js/components/MenuToggle/MenuToggle.d.ts.map +1 -1
- package/dist/js/components/MenuToggle/MenuToggle.js +2 -3
- package/dist/js/components/MenuToggle/MenuToggle.js.map +1 -1
- package/dist/js/components/Modal/Modal.d.ts +2 -0
- package/dist/js/components/Modal/Modal.d.ts.map +1 -1
- package/dist/js/components/Modal/Modal.js +2 -1
- package/dist/js/components/Modal/Modal.js.map +1 -1
- package/dist/js/components/Modal/ModalBox.d.ts +4 -0
- package/dist/js/components/Modal/ModalBox.d.ts.map +1 -1
- package/dist/js/components/Modal/ModalBox.js +2 -2
- package/dist/js/components/Modal/ModalBox.js.map +1 -1
- package/dist/js/components/Modal/ModalContent.d.ts +2 -0
- package/dist/js/components/Modal/ModalContent.d.ts.map +1 -1
- package/dist/js/components/Modal/ModalContent.js +39 -4
- package/dist/js/components/Modal/ModalContent.js.map +1 -1
- package/dist/js/components/Nav/Nav.d.ts +1 -1
- package/dist/js/components/Nav/Nav.d.ts.map +1 -1
- package/dist/js/components/Nav/Nav.js +2 -2
- package/dist/js/components/Nav/Nav.js.map +1 -1
- package/dist/js/components/Page/Page.d.ts +3 -7
- package/dist/js/components/Page/Page.d.ts.map +1 -1
- package/dist/js/components/Page/Page.js +3 -4
- package/dist/js/components/Page/Page.js.map +1 -1
- package/dist/umd/assets/{output-Doo5KfbL.css → output-DjqlL2o3.css} +17550 -17557
- package/dist/umd/react-core.min.js +3 -3
- package/helpers/package.json +1 -1
- package/layouts/package.json +1 -1
- package/next/package.json +1 -1
- package/package.json +6 -6
- package/src/components/Backdrop/Backdrop.tsx +24 -5
- package/src/components/Backdrop/__tests__/Backdrop.test.tsx +35 -1
- package/src/components/Backdrop/__tests__/__snapshots__/Backdrop.test.tsx.snap +1 -1
- package/src/components/Button/Button.tsx +2 -5
- package/src/components/Button/__tests__/Button.test.tsx +8 -19
- package/src/components/Button/__tests__/__snapshots__/Button.test.tsx.snap +1 -1
- package/src/components/Compass/Compass.tsx +5 -11
- package/src/components/Compass/__tests__/Compass.test.tsx +3 -23
- package/src/components/MenuToggle/MenuToggle.tsx +0 -5
- package/src/components/MenuToggle/__tests__/MenuToggle.test.tsx +8 -19
- package/src/components/Modal/Modal.tsx +4 -1
- package/src/components/Modal/ModalBox.tsx +8 -0
- package/src/components/Modal/ModalContent.tsx +54 -4
- package/src/components/Modal/__tests__/Modal.test.tsx +14 -0
- package/src/components/Modal/__tests__/ModalContent.test.tsx +75 -1
- package/src/components/Modal/examples/Modal.md +12 -0
- package/src/components/Modal/examples/ModalNotAnimated.tsx +44 -0
- package/src/components/Nav/Nav.tsx +3 -3
- package/src/components/Nav/__tests__/Nav.test.tsx +8 -8
- package/src/components/Nav/examples/Nav.md +1 -1
- package/src/components/Page/Page.tsx +5 -12
- package/src/components/Page/__tests__/Page.test.tsx +4 -30
- package/src/demos/Compass/examples/CompassDockDemo.tsx +25 -43
- package/src/demos/Nav.md +3 -3
- package/src/demos/examples/Nav/NavDockedNav.tsx +25 -43
- package/src/deprecated/components/Modal/__tests__/__snapshots__/ModalContent.test.tsx.snap +8 -8
package/helpers/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@patternfly/react-core-helpers","main":"../dist/js/helpers/index.js","module":"../dist/esm/helpers/index.js","typings":"../dist/esm/helpers/index.d.ts","version":"6.7.0-prerelease.
|
|
1
|
+
{"name":"@patternfly/react-core-helpers","main":"../dist/js/helpers/index.js","module":"../dist/esm/helpers/index.js","typings":"../dist/esm/helpers/index.d.ts","version":"6.7.0-prerelease.2","private":true}
|
package/layouts/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@patternfly/react-core-layouts","main":"../dist/js/layouts/index.js","module":"../dist/esm/layouts/index.js","typings":"../dist/esm/layouts/index.d.ts","version":"6.7.0-prerelease.
|
|
1
|
+
{"name":"@patternfly/react-core-layouts","main":"../dist/js/layouts/index.js","module":"../dist/esm/layouts/index.js","typings":"../dist/esm/layouts/index.d.ts","version":"6.7.0-prerelease.2","private":true}
|
package/next/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@patternfly/react-core-next","main":"../dist/js/next/index.js","module":"../dist/esm/next/index.js","typings":"../dist/esm/next/index.d.ts","version":"6.7.0-prerelease.
|
|
1
|
+
{"name":"@patternfly/react-core-next","main":"../dist/js/next/index.js","module":"../dist/esm/next/index.js","typings":"../dist/esm/next/index.d.ts","version":"6.7.0-prerelease.2","private":true}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-core",
|
|
3
|
-
"version": "6.7.0-prerelease.
|
|
3
|
+
"version": "6.7.0-prerelease.3",
|
|
4
4
|
"description": "This library provides a set of common React components for use with the PatternFly reference implementation.",
|
|
5
5
|
"main": "dist/js/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -46,15 +46,15 @@
|
|
|
46
46
|
"subpaths": "node ../../scripts/exportSubpaths.mjs --config subpaths.config.json"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@patternfly/react-icons": "^6.7.0-prerelease.
|
|
50
|
-
"@patternfly/react-styles": "^6.7.0-prerelease.
|
|
51
|
-
"@patternfly/react-tokens": "^6.7.0-prerelease.
|
|
49
|
+
"@patternfly/react-icons": "^6.7.0-prerelease.1",
|
|
50
|
+
"@patternfly/react-styles": "^6.7.0-prerelease.1",
|
|
51
|
+
"@patternfly/react-tokens": "^6.7.0-prerelease.2",
|
|
52
52
|
"focus-trap": "7.6.6",
|
|
53
53
|
"react-dropzone": "^14.3.5",
|
|
54
54
|
"tslib": "^2.8.1"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@patternfly/patternfly": "6.6.0-prerelease.
|
|
57
|
+
"@patternfly/patternfly": "6.6.0-prerelease.50",
|
|
58
58
|
"case-anything": "^3.1.2",
|
|
59
59
|
"css": "^3.0.0",
|
|
60
60
|
"fs-extra": "^11.3.3"
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"react": "^17 || ^18 || ^19",
|
|
64
64
|
"react-dom": "^17 || ^18 || ^19"
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "32056428bd221fb8009157d7f7d29bae84f7fe3f"
|
|
67
67
|
}
|
|
@@ -1,20 +1,39 @@
|
|
|
1
1
|
import { css } from '@patternfly/react-styles';
|
|
2
2
|
import styles from '@patternfly/react-styles/css/components/Backdrop/backdrop';
|
|
3
|
+
import { useHasAnimations } from '../../helpers';
|
|
3
4
|
|
|
4
5
|
export interface BackdropProps extends React.HTMLProps<HTMLDivElement> {
|
|
5
6
|
/** Content rendered inside the backdrop */
|
|
6
7
|
children?: React.ReactNode;
|
|
7
8
|
/** Additional classes added to the backdrop */
|
|
8
9
|
className?: string;
|
|
10
|
+
/** Flag indicating whether animations are enabled. Animations are enabled by default. */
|
|
11
|
+
hasAnimations?: boolean;
|
|
12
|
+
/** Flag to show the backdrop when animations are enabled. Set to false while the backdrop remains mounted to play its exit transition. */
|
|
13
|
+
isVisible?: boolean;
|
|
9
14
|
}
|
|
10
15
|
|
|
11
16
|
export const Backdrop: React.FunctionComponent<BackdropProps> = ({
|
|
12
17
|
children = null,
|
|
13
18
|
className = '',
|
|
19
|
+
hasAnimations: hasAnimationsProp = true,
|
|
20
|
+
isVisible = true,
|
|
14
21
|
...props
|
|
15
|
-
}: BackdropProps) =>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
}: BackdropProps) => {
|
|
23
|
+
const hasAnimations = useHasAnimations(hasAnimationsProp);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<div
|
|
27
|
+
{...props}
|
|
28
|
+
className={css(
|
|
29
|
+
styles.backdrop,
|
|
30
|
+
hasAnimations && styles.modifiers.animate,
|
|
31
|
+
hasAnimations && isVisible && styles.modifiers.show,
|
|
32
|
+
className
|
|
33
|
+
)}
|
|
34
|
+
>
|
|
35
|
+
{children}
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
20
39
|
Backdrop.displayName = 'Backdrop';
|
|
@@ -21,11 +21,45 @@ test(`Renders with the ${styles.backdrop}`, () => {
|
|
|
21
21
|
expect(screen.getByText('Test')).toHaveClass(styles.backdrop);
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
test(
|
|
24
|
+
test('Renders with animations enabled by default', () => {
|
|
25
25
|
render(<Backdrop>Test</Backdrop>);
|
|
26
|
+
expect(screen.getByText('Test')).toHaveClass(styles.backdrop, styles.modifiers.animate, styles.modifiers.show, {
|
|
27
|
+
exact: true
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('Renders without animation classes when animations are explicitly disabled', () => {
|
|
32
|
+
render(<Backdrop hasAnimations={false}>Test</Backdrop>);
|
|
26
33
|
expect(screen.getByText('Test')).toHaveClass(styles.backdrop, { exact: true });
|
|
27
34
|
});
|
|
28
35
|
|
|
36
|
+
test('Renders as visible by default when animations are enabled', () => {
|
|
37
|
+
render(<Backdrop hasAnimations>Test</Backdrop>);
|
|
38
|
+
expect(screen.getByText('Test')).toHaveClass(styles.backdrop, styles.modifiers.animate, styles.modifiers.show, {
|
|
39
|
+
exact: true
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('Renders as hidden when animations are enabled and isVisible is false', () => {
|
|
44
|
+
render(
|
|
45
|
+
<Backdrop hasAnimations isVisible={false}>
|
|
46
|
+
Test
|
|
47
|
+
</Backdrop>
|
|
48
|
+
);
|
|
49
|
+
expect(screen.getByText('Test')).toHaveClass(styles.backdrop, styles.modifiers.animate, { exact: true });
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('Renders as visible when animations are enabled and isVisible is true', () => {
|
|
53
|
+
render(
|
|
54
|
+
<Backdrop hasAnimations isVisible>
|
|
55
|
+
Test
|
|
56
|
+
</Backdrop>
|
|
57
|
+
);
|
|
58
|
+
expect(screen.getByText('Test')).toHaveClass(styles.backdrop, styles.modifiers.animate, styles.modifiers.show, {
|
|
59
|
+
exact: true
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
29
63
|
test('Renders with custom class name when className prop is passed', () => {
|
|
30
64
|
render(<Backdrop className="test-class">Test</Backdrop>);
|
|
31
65
|
expect(screen.getByText('Test')).toHaveClass('test-class');
|
|
@@ -99,7 +99,7 @@ export interface ButtonProps extends Omit<React.HTMLProps<HTMLButtonElement>, 'r
|
|
|
99
99
|
tabIndex?: number;
|
|
100
100
|
/** Adds danger styling to secondary or link button variants */
|
|
101
101
|
isDanger?: boolean;
|
|
102
|
-
/** Flag indicating whether content the button controls is expanded or not. Required when isHamburger is true. */
|
|
102
|
+
/** Flag indicating whether content the button controls is expanded or not. Required when isHamburger is true. Applies additional expanded styling when isDocked is true. */
|
|
103
103
|
isExpanded?: boolean;
|
|
104
104
|
/** Flag indicating the button is a settings button. This will override the icon property. */
|
|
105
105
|
isSettings?: boolean;
|
|
@@ -111,8 +111,6 @@ export interface ButtonProps extends Omit<React.HTMLProps<HTMLButtonElement>, 'r
|
|
|
111
111
|
isCircle?: boolean;
|
|
112
112
|
/** @beta Flag indicating the button is a docked variant button. For use in docked navigation. */
|
|
113
113
|
isDocked?: boolean;
|
|
114
|
-
/** @beta Flag indicating the docked button should display text. Only applies when isDocked is true. */
|
|
115
|
-
isTextExpanded?: boolean;
|
|
116
114
|
/** @hide Forwarded ref */
|
|
117
115
|
innerRef?: React.Ref<any>;
|
|
118
116
|
/** Adds count number to button */
|
|
@@ -139,7 +137,6 @@ const ButtonBase: React.FunctionComponent<ButtonProps> = ({
|
|
|
139
137
|
hamburgerVariant,
|
|
140
138
|
isCircle,
|
|
141
139
|
isDocked = false,
|
|
142
|
-
isTextExpanded = false,
|
|
143
140
|
spinnerAriaValueText,
|
|
144
141
|
spinnerAriaLabelledBy,
|
|
145
142
|
spinnerAriaLabel,
|
|
@@ -272,7 +269,7 @@ const ButtonBase: React.FunctionComponent<ButtonProps> = ({
|
|
|
272
269
|
size === ButtonSize.lg && styles.modifiers.displayLg,
|
|
273
270
|
isCircle && styles.modifiers.circle,
|
|
274
271
|
isDocked && styles.modifiers.docked,
|
|
275
|
-
isDocked &&
|
|
272
|
+
isDocked && isExpanded && styles.modifiers.expanded,
|
|
276
273
|
className
|
|
277
274
|
)}
|
|
278
275
|
disabled={isButtonElement ? isDisabled : null}
|
|
@@ -566,34 +566,23 @@ describe('Dock variant', () => {
|
|
|
566
566
|
expect(screen.getByRole('button')).not.toHaveClass(styles.modifiers.docked);
|
|
567
567
|
});
|
|
568
568
|
|
|
569
|
-
test(`Renders with class ${styles.modifiers.
|
|
569
|
+
test(`Renders with class ${styles.modifiers.expanded} when isExpanded = true and isDocked = true`, () => {
|
|
570
570
|
render(
|
|
571
|
-
<Button
|
|
571
|
+
<Button isExpanded isDocked>
|
|
572
572
|
Text Expanded Button
|
|
573
573
|
</Button>
|
|
574
574
|
);
|
|
575
|
-
expect(screen.getByRole('button')).toHaveClass(styles.modifiers.
|
|
575
|
+
expect(screen.getByRole('button')).toHaveClass(styles.modifiers.expanded);
|
|
576
576
|
});
|
|
577
577
|
|
|
578
|
-
test(`Does not render with class ${styles.modifiers.
|
|
578
|
+
test(`Does not render with class ${styles.modifiers.expanded} when isExpanded is not passed`, () => {
|
|
579
579
|
render(<Button>Button</Button>);
|
|
580
|
-
expect(screen.getByRole('button')).not.toHaveClass(styles.modifiers.
|
|
580
|
+
expect(screen.getByRole('button')).not.toHaveClass(styles.modifiers.expanded);
|
|
581
581
|
});
|
|
582
582
|
|
|
583
|
-
test(`Does not render with class ${styles.modifiers.
|
|
584
|
-
render(<Button
|
|
585
|
-
expect(screen.getByRole('button')).not.toHaveClass(styles.modifiers.
|
|
586
|
-
});
|
|
587
|
-
|
|
588
|
-
test(`Renders with both ${styles.modifiers.docked} and ${styles.modifiers.textExpanded} when both props are true`, () => {
|
|
589
|
-
render(
|
|
590
|
-
<Button isDocked isTextExpanded>
|
|
591
|
-
Dock Text Expanded Button
|
|
592
|
-
</Button>
|
|
593
|
-
);
|
|
594
|
-
const button = screen.getByRole('button');
|
|
595
|
-
expect(button).toHaveClass(styles.modifiers.docked);
|
|
596
|
-
expect(button).toHaveClass(styles.modifiers.textExpanded);
|
|
583
|
+
test(`Does not render with class ${styles.modifiers.expanded} when isExpanded = true but isDocked is not passed`, () => {
|
|
584
|
+
render(<Button isExpanded>Text Expanded Button</Button>);
|
|
585
|
+
expect(screen.getByRole('button')).not.toHaveClass(styles.modifiers.expanded);
|
|
597
586
|
});
|
|
598
587
|
});
|
|
599
588
|
|
|
@@ -5,7 +5,7 @@ exports[`Renders basic button 1`] = `
|
|
|
5
5
|
<button
|
|
6
6
|
aria-label="basic button"
|
|
7
7
|
class="pf-v6-c-button pf-m-primary"
|
|
8
|
-
data-ouia-component-id="OUIA-Generated-Button-primary-:
|
|
8
|
+
data-ouia-component-id="OUIA-Generated-Button-primary-:r35:"
|
|
9
9
|
data-ouia-component-type="PF6/Button"
|
|
10
10
|
data-ouia-safe="true"
|
|
11
11
|
type="button"
|
|
@@ -10,14 +10,10 @@ export interface CompassProps extends React.HTMLProps<HTMLDivElement> {
|
|
|
10
10
|
masthead?: React.ReactNode;
|
|
11
11
|
/** Content of the docked navigation area of the layout */
|
|
12
12
|
dock?: React.ReactNode;
|
|
13
|
-
/** @beta Flag indicating the docked nav is expanded
|
|
13
|
+
/** @beta Flag indicating the docked nav is expanded. Only applies when dock content is passed. */
|
|
14
14
|
isDockExpanded?: boolean;
|
|
15
|
-
/** @beta Flag indicating
|
|
16
|
-
|
|
17
|
-
/** @beta Flag indicating the docked nav should display text on desktop. Only applies when dock content is passed, and
|
|
18
|
-
* will handle toggling the visibility of the text in individual isDocked components.
|
|
19
|
-
*/
|
|
20
|
-
isDockTextExpanded?: boolean;
|
|
15
|
+
/** @beta Flag indicating the docked nav should expand as an overlay instead of the default inline. */
|
|
16
|
+
isDockOverlay?: boolean;
|
|
21
17
|
/** Content placed at the top of the compass layout */
|
|
22
18
|
header?: React.ReactNode;
|
|
23
19
|
/** Flag indicating if the header is expanded */
|
|
@@ -47,8 +43,7 @@ export const Compass: React.FunctionComponent<CompassProps> = ({
|
|
|
47
43
|
masthead,
|
|
48
44
|
dock,
|
|
49
45
|
isDockExpanded,
|
|
50
|
-
|
|
51
|
-
isDockTextExpanded,
|
|
46
|
+
isDockOverlay,
|
|
52
47
|
header,
|
|
53
48
|
isHeaderExpanded = true,
|
|
54
49
|
sidebarStart,
|
|
@@ -72,8 +67,7 @@ export const Compass: React.FunctionComponent<CompassProps> = ({
|
|
|
72
67
|
className={css(
|
|
73
68
|
`${styles.compass}__dock`,
|
|
74
69
|
isDockExpanded && styles.modifiers.expanded,
|
|
75
|
-
|
|
76
|
-
isDockTextExpanded && styles.modifiers.textExpanded
|
|
70
|
+
isDockOverlay && styles.modifiers.overlay
|
|
77
71
|
)}
|
|
78
72
|
>
|
|
79
73
|
{dock}
|
|
@@ -94,19 +94,9 @@ test('Renders footer without expanded class and with inert when isFooterExpanded
|
|
|
94
94
|
expect(footerElement).toHaveAttribute('inert');
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
-
test(`Renders with ${styles.modifiers.
|
|
98
|
-
render(<Compass dock={<div>Dock content</div>}
|
|
99
|
-
expect(screen.getByText('Dock content').parentElement).toHaveClass(styles.modifiers.
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
test(`Does not render with ${styles.modifiers.expandableExpanded} class when isDockExpandableExpanded is false`, () => {
|
|
103
|
-
render(<Compass dock={<div>Dock content</div>} isDockExpandableExpanded={false} />);
|
|
104
|
-
expect(screen.getByText('Dock content').parentElement).not.toHaveClass(styles.modifiers.expandableExpanded);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
test(`Does not render with ${styles.modifiers.expandableExpanded} class by default`, () => {
|
|
108
|
-
render(<Compass dock={<div>Dock content</div>} />);
|
|
109
|
-
expect(screen.getByText('Dock content').parentElement).not.toHaveClass(styles.modifiers.expandableExpanded);
|
|
97
|
+
test(`Renders with ${styles.modifiers.overlay} class when isDockOverlay is true`, () => {
|
|
98
|
+
render(<Compass dock={<div>Dock content</div>} isDockOverlay />);
|
|
99
|
+
expect(screen.getByText('Dock content').parentElement).toHaveClass(styles.modifiers.overlay);
|
|
110
100
|
});
|
|
111
101
|
|
|
112
102
|
test('Renders with drawer when drawerContent is provided', () => {
|
|
@@ -194,13 +184,3 @@ test(`Renders dock without ${styles.modifiers.expanded} class when isDockExpande
|
|
|
194
184
|
render(<Compass dock="Dock content" isDockExpanded={false} />);
|
|
195
185
|
expect(screen.getByText('Dock content')).not.toHaveClass(styles.modifiers.expanded);
|
|
196
186
|
});
|
|
197
|
-
|
|
198
|
-
test(`Renders dock with ${styles.modifiers.textExpanded} class when isDockTextExpanded is true`, () => {
|
|
199
|
-
render(<Compass dock="Dock content" isDockTextExpanded />);
|
|
200
|
-
expect(screen.getByText('Dock content')).toHaveClass(styles.modifiers.textExpanded);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
test(`Renders dock without ${styles.modifiers.textExpanded} class when isDockTextExpanded is false`, () => {
|
|
204
|
-
render(<Compass dock="Dock content" isDockTextExpanded={false} />);
|
|
205
|
-
expect(screen.getByText('Dock content')).not.toHaveClass(styles.modifiers.textExpanded);
|
|
206
|
-
});
|
|
@@ -55,8 +55,6 @@ export interface MenuToggleProps
|
|
|
55
55
|
isSettings?: boolean;
|
|
56
56
|
/** @beta Flag indicating the menu toggle is a docked variant. For use in docked navigation. */
|
|
57
57
|
isDocked?: boolean;
|
|
58
|
-
/** @beta Flag indicating the docked toggle should display text. Only applies when isDocked is true. */
|
|
59
|
-
isTextExpanded?: boolean;
|
|
60
58
|
/** Elements to display before the toggle button. When included, renders the menu toggle as a split button. */
|
|
61
59
|
splitButtonItems?: React.ReactNode[];
|
|
62
60
|
/** Variant styles of the menu toggle */
|
|
@@ -95,7 +93,6 @@ class MenuToggleBase extends Component<MenuToggleProps> {
|
|
|
95
93
|
isPlaceholder: false,
|
|
96
94
|
isCircle: false,
|
|
97
95
|
isDocked: false,
|
|
98
|
-
isTextExpanded: false,
|
|
99
96
|
size: 'default',
|
|
100
97
|
ouiaSafe: true,
|
|
101
98
|
'aria-haspopup': 'menu'
|
|
@@ -116,7 +113,6 @@ class MenuToggleBase extends Component<MenuToggleProps> {
|
|
|
116
113
|
isCircle,
|
|
117
114
|
isSettings,
|
|
118
115
|
isDocked,
|
|
119
|
-
isTextExpanded,
|
|
120
116
|
splitButtonItems,
|
|
121
117
|
variant,
|
|
122
118
|
status,
|
|
@@ -204,7 +200,6 @@ class MenuToggleBase extends Component<MenuToggleProps> {
|
|
|
204
200
|
isPlaceholder && styles.modifiers.placeholder,
|
|
205
201
|
isSettings && styles.modifiers.settings,
|
|
206
202
|
isDocked && styles.modifiers.docked,
|
|
207
|
-
isDocked && isTextExpanded && styles.modifiers.textExpanded,
|
|
208
203
|
size === MenuToggleSize.sm && styles.modifiers.small,
|
|
209
204
|
className
|
|
210
205
|
);
|
|
@@ -166,32 +166,21 @@ test(`Does not render with class ${styles.modifiers.docked} when isDocked is not
|
|
|
166
166
|
expect(screen.getByRole('button')).not.toHaveClass(styles.modifiers.docked);
|
|
167
167
|
});
|
|
168
168
|
|
|
169
|
-
test(`Renders with class ${styles.modifiers.
|
|
169
|
+
test(`Renders with class ${styles.modifiers.expanded} when isExpanded is passed and isDocked is passed`, () => {
|
|
170
170
|
render(
|
|
171
|
-
<MenuToggle
|
|
171
|
+
<MenuToggle isExpanded isDocked>
|
|
172
172
|
Text Expanded Toggle
|
|
173
173
|
</MenuToggle>
|
|
174
174
|
);
|
|
175
|
-
expect(screen.getByRole('button')).toHaveClass(styles.modifiers.
|
|
175
|
+
expect(screen.getByRole('button')).toHaveClass(styles.modifiers.expanded);
|
|
176
176
|
});
|
|
177
177
|
|
|
178
|
-
test(`Does not render with class ${styles.modifiers.
|
|
178
|
+
test(`Does not render with class ${styles.modifiers.expanded} when isExpanded is not passed`, () => {
|
|
179
179
|
render(<MenuToggle>Toggle</MenuToggle>);
|
|
180
|
-
expect(screen.getByRole('button')).not.toHaveClass(styles.modifiers.
|
|
180
|
+
expect(screen.getByRole('button')).not.toHaveClass(styles.modifiers.expanded);
|
|
181
181
|
});
|
|
182
182
|
|
|
183
|
-
test(`Does not render with class ${styles.modifiers.
|
|
184
|
-
render(<MenuToggle
|
|
185
|
-
expect(screen.getByRole('button')).
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
test(`Renders with both ${styles.modifiers.docked} and ${styles.modifiers.textExpanded} when both props are passed`, () => {
|
|
189
|
-
render(
|
|
190
|
-
<MenuToggle isDocked isTextExpanded>
|
|
191
|
-
Dock Text Expanded Toggle
|
|
192
|
-
</MenuToggle>
|
|
193
|
-
);
|
|
194
|
-
const button = screen.getByRole('button');
|
|
195
|
-
expect(button).toHaveClass(styles.modifiers.docked);
|
|
196
|
-
expect(button).toHaveClass(styles.modifiers.textExpanded);
|
|
183
|
+
test(`Does not render with class ${styles.modifiers.expanded} when isExpanded is passed but isDocked is not passed`, () => {
|
|
184
|
+
render(<MenuToggle isExpanded>Text Expanded Toggle</MenuToggle>);
|
|
185
|
+
expect(screen.getByRole('button')).toHaveClass(styles.modifiers.expanded);
|
|
197
186
|
});
|
|
@@ -53,6 +53,8 @@ export interface ModalProps extends React.HTMLProps<HTMLDivElement>, OUIAProps {
|
|
|
53
53
|
ouiaId?: number | string;
|
|
54
54
|
/** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */
|
|
55
55
|
ouiaSafe?: boolean;
|
|
56
|
+
/** Flag indicating whether animations are enabled. Animations are enabled by default. */
|
|
57
|
+
hasAnimations?: boolean;
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
export enum ModalVariant {
|
|
@@ -78,7 +80,8 @@ class Modal extends Component<ModalProps, ModalState> {
|
|
|
78
80
|
variant: 'default',
|
|
79
81
|
appendTo: () => document.body,
|
|
80
82
|
ouiaSafe: true,
|
|
81
|
-
position: 'default'
|
|
83
|
+
position: 'default',
|
|
84
|
+
hasAnimations: true
|
|
82
85
|
};
|
|
83
86
|
|
|
84
87
|
constructor(props: ModalProps) {
|
|
@@ -19,6 +19,10 @@ export interface ModalBoxProps extends React.HTMLProps<HTMLDivElement> {
|
|
|
19
19
|
positionOffset?: string;
|
|
20
20
|
/** Variant of the modal. */
|
|
21
21
|
variant?: 'small' | 'medium' | 'large' | 'default';
|
|
22
|
+
/** Flag indicating whether animations are enabled. */
|
|
23
|
+
hasAnimations?: boolean;
|
|
24
|
+
/** Flag to show the modal. */
|
|
25
|
+
isOpen?: boolean;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
export const ModalBox: React.FunctionComponent<ModalBoxProps> = ({
|
|
@@ -31,6 +35,8 @@ export const ModalBox: React.FunctionComponent<ModalBoxProps> = ({
|
|
|
31
35
|
'aria-label': ariaLabel,
|
|
32
36
|
'aria-describedby': ariaDescribedby,
|
|
33
37
|
style,
|
|
38
|
+
isOpen,
|
|
39
|
+
hasAnimations,
|
|
34
40
|
...props
|
|
35
41
|
}: ModalBoxProps) => {
|
|
36
42
|
if (positionOffset) {
|
|
@@ -46,6 +52,8 @@ export const ModalBox: React.FunctionComponent<ModalBoxProps> = ({
|
|
|
46
52
|
aria-modal="true"
|
|
47
53
|
className={css(
|
|
48
54
|
styles.modalBox,
|
|
55
|
+
hasAnimations && styles.modifiers.animate,
|
|
56
|
+
hasAnimations && isOpen === true && styles.modifiers.open,
|
|
49
57
|
className,
|
|
50
58
|
position === 'top' && styles.modifiers.alignTop,
|
|
51
59
|
variant === 'large' && styles.modifiers.lg,
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
1
2
|
import { FocusTrap } from '../../helpers';
|
|
2
3
|
import bullsEyeStyles from '@patternfly/react-styles/css/layouts/Bullseye/bullseye';
|
|
3
4
|
import { css } from '@patternfly/react-styles';
|
|
4
|
-
import { getOUIAProps, OUIAProps } from '../../helpers';
|
|
5
|
+
import { getOUIAProps, OUIAProps, useHasAnimations } from '../../helpers';
|
|
5
6
|
import { Backdrop } from '../Backdrop';
|
|
6
7
|
import { ModalBoxCloseButton } from './ModalBoxCloseButton';
|
|
7
8
|
import { ModalBox } from './ModalBox';
|
|
8
9
|
|
|
10
|
+
const transitionEndFallbackDelay = 300;
|
|
11
|
+
|
|
9
12
|
export interface ModalContentProps extends OUIAProps {
|
|
10
13
|
/** Id to use for the modal box description. This should match the ModalHeader labelId or descriptorId. */
|
|
11
14
|
'aria-describedby'?: string;
|
|
@@ -49,6 +52,8 @@ export interface ModalContentProps extends OUIAProps {
|
|
|
49
52
|
ouiaId?: number | string;
|
|
50
53
|
/** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */
|
|
51
54
|
ouiaSafe?: boolean;
|
|
55
|
+
/** Flag indicating whether animations are enabled. */
|
|
56
|
+
hasAnimations?: boolean;
|
|
52
57
|
}
|
|
53
58
|
|
|
54
59
|
export const ModalContent: React.FunctionComponent<ModalContentProps> = ({
|
|
@@ -72,9 +77,30 @@ export const ModalContent: React.FunctionComponent<ModalContentProps> = ({
|
|
|
72
77
|
ouiaSafe = true,
|
|
73
78
|
elementToFocus,
|
|
74
79
|
focusTrapId,
|
|
80
|
+
hasAnimations: hasAnimationsProp,
|
|
75
81
|
...props
|
|
76
82
|
}: ModalContentProps) => {
|
|
77
|
-
|
|
83
|
+
const hasAnimations = useHasAnimations(hasAnimationsProp);
|
|
84
|
+
// Keeps the modal in the DOM while the close animation runs. When animations are enabled we defer
|
|
85
|
+
// unmounting until the backdrop's transition ends (see onTransitionEnd below) instead of removing
|
|
86
|
+
// it immediately when isOpen becomes false.
|
|
87
|
+
const [isRendered, setIsRendered] = useState(isOpen);
|
|
88
|
+
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (isOpen) {
|
|
91
|
+
setIsRendered(true);
|
|
92
|
+
} else if (!isRendered) {
|
|
93
|
+
return;
|
|
94
|
+
} else if (!hasAnimations) {
|
|
95
|
+
setIsRendered(false);
|
|
96
|
+
} else {
|
|
97
|
+
// Ensure the modal is removed if CSS transitions are disabled or transitionend does not fire.
|
|
98
|
+
const transitionEndFallback = window.setTimeout(() => setIsRendered(false), transitionEndFallbackDelay);
|
|
99
|
+
return () => window.clearTimeout(transitionEndFallback);
|
|
100
|
+
}
|
|
101
|
+
}, [isOpen, hasAnimations, isRendered]);
|
|
102
|
+
|
|
103
|
+
if (!isRendered) {
|
|
78
104
|
return null;
|
|
79
105
|
}
|
|
80
106
|
|
|
@@ -91,6 +117,8 @@ export const ModalContent: React.FunctionComponent<ModalContentProps> = ({
|
|
|
91
117
|
const modalBox = (
|
|
92
118
|
<ModalBox
|
|
93
119
|
className={css(className)}
|
|
120
|
+
isOpen={isOpen}
|
|
121
|
+
hasAnimations={hasAnimations}
|
|
94
122
|
variant={variant}
|
|
95
123
|
position={position}
|
|
96
124
|
positionOffset={positionOffset}
|
|
@@ -113,10 +141,32 @@ export const ModalContent: React.FunctionComponent<ModalContentProps> = ({
|
|
|
113
141
|
{children}
|
|
114
142
|
</ModalBox>
|
|
115
143
|
);
|
|
144
|
+
let focusTrapActive = !disableFocusTrap;
|
|
145
|
+
if (hasAnimations) {
|
|
146
|
+
focusTrapActive = !disableFocusTrap && isOpen;
|
|
147
|
+
}
|
|
148
|
+
|
|
116
149
|
return (
|
|
117
|
-
<Backdrop
|
|
150
|
+
<Backdrop
|
|
151
|
+
className={css(backdropClassName)}
|
|
152
|
+
id={backdropId}
|
|
153
|
+
hasAnimations={hasAnimations}
|
|
154
|
+
isVisible={isOpen}
|
|
155
|
+
aria-hidden={hasAnimations && !isOpen ? true : undefined}
|
|
156
|
+
onTransitionEnd={
|
|
157
|
+
hasAnimations
|
|
158
|
+
? (event) => {
|
|
159
|
+
// Only unmount once the backdrop's own closing transition finishes. Guarding on the
|
|
160
|
+
// target prevents bubbled transitions from child elements from triggering this early.
|
|
161
|
+
if (!isOpen && event.target === event.currentTarget) {
|
|
162
|
+
setIsRendered(false);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
: undefined
|
|
166
|
+
}
|
|
167
|
+
>
|
|
118
168
|
<FocusTrap
|
|
119
|
-
active={
|
|
169
|
+
active={focusTrapActive}
|
|
120
170
|
focusTrapOptions={{
|
|
121
171
|
clickOutsideDeactivates: true,
|
|
122
172
|
tabbableOptions: { displayCheck: 'none' },
|
|
@@ -111,6 +111,20 @@ describe('Modal', () => {
|
|
|
111
111
|
expect(document.body).toHaveClass(css(styles.backdropOpen));
|
|
112
112
|
});
|
|
113
113
|
|
|
114
|
+
test('modal has animations enabled by default', () => {
|
|
115
|
+
render(<Modal {...props} isOpen />);
|
|
116
|
+
const backdrop = screen.getByText('modal content').closest(`.${styles.backdrop}`);
|
|
117
|
+
|
|
118
|
+
expect(backdrop).toHaveClass(styles.modifiers.animate, styles.modifiers.show);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test('modal animations can be explicitly disabled', () => {
|
|
122
|
+
render(<Modal {...props} isOpen hasAnimations={false} />);
|
|
123
|
+
const backdrop = screen.getByText('modal content').closest(`.${styles.backdrop}`);
|
|
124
|
+
|
|
125
|
+
expect(backdrop).not.toHaveClass(styles.modifiers.animate, styles.modifiers.show);
|
|
126
|
+
});
|
|
127
|
+
|
|
114
128
|
test('modal has no body backdropOpen class when not open', () => {
|
|
115
129
|
render(<Modal {...props} />);
|
|
116
130
|
expect(document.body).not.toHaveClass(css(styles.backdropOpen));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
1
|
+
import { act, render, screen } from '@testing-library/react';
|
|
2
2
|
|
|
3
3
|
import { ModalContent } from '../ModalContent';
|
|
4
4
|
|
|
@@ -59,3 +59,77 @@ test('Modal content can add id to focus trap correctly for use with dropdowns',
|
|
|
59
59
|
'pf-v6-l-bullseye'
|
|
60
60
|
);
|
|
61
61
|
});
|
|
62
|
+
|
|
63
|
+
test('Modal content is hidden from assistive technologies during its closing animation', () => {
|
|
64
|
+
const { rerender } = render(
|
|
65
|
+
<ModalContent isOpen hasAnimations backdropId="backdropId" {...modalContentProps}>
|
|
66
|
+
This is a ModalBox header
|
|
67
|
+
</ModalContent>
|
|
68
|
+
);
|
|
69
|
+
const backdrop = document.getElementById('backdropId');
|
|
70
|
+
|
|
71
|
+
expect(backdrop).not.toHaveAttribute('aria-hidden');
|
|
72
|
+
|
|
73
|
+
rerender(
|
|
74
|
+
<ModalContent isOpen={false} hasAnimations backdropId="backdropId" {...modalContentProps}>
|
|
75
|
+
This is a ModalBox header
|
|
76
|
+
</ModalContent>
|
|
77
|
+
);
|
|
78
|
+
expect(backdrop).toHaveAttribute('aria-hidden', 'true');
|
|
79
|
+
|
|
80
|
+
rerender(
|
|
81
|
+
<ModalContent isOpen hasAnimations backdropId="backdropId" {...modalContentProps}>
|
|
82
|
+
This is a ModalBox header
|
|
83
|
+
</ModalContent>
|
|
84
|
+
);
|
|
85
|
+
expect(backdrop).not.toHaveAttribute('aria-hidden');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('Modal content unmounts if its closing transition does not end', () => {
|
|
89
|
+
jest.useFakeTimers();
|
|
90
|
+
try {
|
|
91
|
+
const { rerender } = render(
|
|
92
|
+
<ModalContent isOpen hasAnimations backdropId="backdropId" {...modalContentProps}>
|
|
93
|
+
This is a ModalBox header
|
|
94
|
+
</ModalContent>
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
rerender(
|
|
98
|
+
<ModalContent isOpen={false} hasAnimations backdropId="backdropId" {...modalContentProps}>
|
|
99
|
+
This is a ModalBox header
|
|
100
|
+
</ModalContent>
|
|
101
|
+
);
|
|
102
|
+
expect(document.getElementById('backdropId')).toBeInTheDocument();
|
|
103
|
+
|
|
104
|
+
act(() => jest.runOnlyPendingTimers());
|
|
105
|
+
expect(document.getElementById('backdropId')).not.toBeInTheDocument();
|
|
106
|
+
} finally {
|
|
107
|
+
jest.useRealTimers();
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('Modal content remains mounted during close when reduced motion is preferred', () => {
|
|
112
|
+
const matchMedia = window.matchMedia;
|
|
113
|
+
window.matchMedia = jest.fn().mockReturnValue({ matches: true } as MediaQueryList);
|
|
114
|
+
jest.useFakeTimers();
|
|
115
|
+
try {
|
|
116
|
+
const { rerender } = render(
|
|
117
|
+
<ModalContent isOpen hasAnimations backdropId="backdropId" {...modalContentProps}>
|
|
118
|
+
This is a ModalBox header
|
|
119
|
+
</ModalContent>
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
rerender(
|
|
123
|
+
<ModalContent isOpen={false} hasAnimations backdropId="backdropId" {...modalContentProps}>
|
|
124
|
+
This is a ModalBox header
|
|
125
|
+
</ModalContent>
|
|
126
|
+
);
|
|
127
|
+
expect(document.getElementById('backdropId')).toBeInTheDocument();
|
|
128
|
+
|
|
129
|
+
act(() => jest.runOnlyPendingTimers());
|
|
130
|
+
expect(document.getElementById('backdropId')).not.toBeInTheDocument();
|
|
131
|
+
} finally {
|
|
132
|
+
jest.useRealTimers();
|
|
133
|
+
window.matchMedia = matchMedia;
|
|
134
|
+
}
|
|
135
|
+
});
|