@patternfly/react-core 5.1.1-prerelease.3 → 5.1.1-prerelease.5
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/Chip/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/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/DragDrop/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/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/Text/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/Tile/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/ApplicationLauncher/package.json +1 -1
- package/dist/dynamic/deprecated/components/ContextSelector/package.json +1 -1
- package/dist/dynamic/deprecated/components/Dropdown/package.json +1 -1
- package/dist/dynamic/deprecated/components/OptionsMenu/package.json +1 -1
- package/dist/dynamic/deprecated/components/PageHeader/package.json +1 -1
- package/dist/dynamic/deprecated/components/Select/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/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/constants/package.json +1 -1
- package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
- package/dist/dynamic/helpers/favorites/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/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/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/next/components/package.json +1 -1
- package/dist/esm/components/Drawer/DrawerPanelContent.d.ts +16 -0
- package/dist/esm/components/Drawer/DrawerPanelContent.d.ts.map +1 -1
- package/dist/esm/components/Drawer/DrawerPanelContent.js +55 -15
- package/dist/esm/components/Drawer/DrawerPanelContent.js.map +1 -1
- package/dist/esm/components/Toolbar/ToolbarContent.d.ts.map +1 -1
- package/dist/esm/components/Toolbar/ToolbarContent.js +8 -6
- package/dist/esm/components/Toolbar/ToolbarContent.js.map +1 -1
- package/dist/esm/components/Toolbar/ToolbarExpandableContent.d.ts.map +1 -1
- package/dist/esm/components/Toolbar/ToolbarExpandableContent.js +3 -5
- package/dist/esm/components/Toolbar/ToolbarExpandableContent.js.map +1 -1
- package/dist/esm/components/Toolbar/ToolbarFilter.d.ts +4 -0
- package/dist/esm/components/Toolbar/ToolbarFilter.d.ts.map +1 -1
- package/dist/esm/components/Toolbar/ToolbarFilter.js +8 -4
- package/dist/esm/components/Toolbar/ToolbarFilter.js.map +1 -1
- package/dist/esm/components/Toolbar/ToolbarToggleGroup.d.ts +14 -0
- package/dist/esm/components/Toolbar/ToolbarToggleGroup.d.ts.map +1 -1
- package/dist/esm/components/Toolbar/ToolbarToggleGroup.js +21 -20
- package/dist/esm/components/Toolbar/ToolbarToggleGroup.js.map +1 -1
- package/dist/esm/components/Toolbar/ToolbarUtils.d.ts +4 -0
- package/dist/esm/components/Toolbar/ToolbarUtils.d.ts.map +1 -1
- package/dist/esm/components/Toolbar/ToolbarUtils.js +2 -1
- package/dist/esm/components/Toolbar/ToolbarUtils.js.map +1 -1
- package/dist/esm/components/Toolbar/index.d.ts +1 -0
- package/dist/esm/components/Toolbar/index.d.ts.map +1 -1
- package/dist/esm/components/Toolbar/index.js +1 -0
- package/dist/esm/components/Toolbar/index.js.map +1 -1
- package/dist/js/components/Drawer/DrawerPanelContent.d.ts +16 -0
- package/dist/js/components/Drawer/DrawerPanelContent.d.ts.map +1 -1
- package/dist/js/components/Drawer/DrawerPanelContent.js +55 -15
- package/dist/js/components/Drawer/DrawerPanelContent.js.map +1 -1
- package/dist/js/components/Toolbar/ToolbarContent.d.ts.map +1 -1
- package/dist/js/components/Toolbar/ToolbarContent.js +8 -6
- package/dist/js/components/Toolbar/ToolbarContent.js.map +1 -1
- package/dist/js/components/Toolbar/ToolbarExpandableContent.d.ts.map +1 -1
- package/dist/js/components/Toolbar/ToolbarExpandableContent.js +3 -5
- package/dist/js/components/Toolbar/ToolbarExpandableContent.js.map +1 -1
- package/dist/js/components/Toolbar/ToolbarFilter.d.ts +4 -0
- package/dist/js/components/Toolbar/ToolbarFilter.d.ts.map +1 -1
- package/dist/js/components/Toolbar/ToolbarFilter.js +8 -4
- package/dist/js/components/Toolbar/ToolbarFilter.js.map +1 -1
- package/dist/js/components/Toolbar/ToolbarToggleGroup.d.ts +14 -0
- package/dist/js/components/Toolbar/ToolbarToggleGroup.d.ts.map +1 -1
- package/dist/js/components/Toolbar/ToolbarToggleGroup.js +21 -20
- package/dist/js/components/Toolbar/ToolbarToggleGroup.js.map +1 -1
- package/dist/js/components/Toolbar/ToolbarUtils.d.ts +4 -0
- package/dist/js/components/Toolbar/ToolbarUtils.d.ts.map +1 -1
- package/dist/js/components/Toolbar/ToolbarUtils.js +2 -1
- package/dist/js/components/Toolbar/ToolbarUtils.js.map +1 -1
- package/dist/js/components/Toolbar/index.d.ts +1 -0
- package/dist/js/components/Toolbar/index.d.ts.map +1 -1
- package/dist/js/components/Toolbar/index.js +1 -0
- package/dist/js/components/Toolbar/index.js.map +1 -1
- 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/Alert/__tests__/AlertGroup.test.tsx +77 -73
- package/src/components/Drawer/DrawerPanelContent.tsx +120 -55
- package/src/components/Drawer/__tests__/DrawerPanelContent.test.tsx +89 -0
- package/src/components/Drawer/examples/Drawer.md +31 -0
- package/src/components/Drawer/examples/DrawerFocusTrap.tsx +58 -0
- package/src/components/Toolbar/ToolbarContent.tsx +7 -11
- package/src/components/Toolbar/ToolbarExpandableContent.tsx +7 -3
- package/src/components/Toolbar/ToolbarFilter.tsx +12 -2
- package/src/components/Toolbar/ToolbarToggleGroup.tsx +92 -47
- package/src/components/Toolbar/ToolbarUtils.tsx +6 -1
- package/src/components/Toolbar/__tests__/Generated/__snapshots__/ToolbarContent.test.tsx.snap +0 -8
- package/src/components/Toolbar/__tests__/Toolbar.test.tsx +3 -4
- package/src/components/Toolbar/__tests__/ToolbarToggleGroup.test.tsx +13 -10
- package/src/components/Toolbar/__tests__/__snapshots__/Toolbar.test.tsx.snap +0 -59
- package/src/components/Toolbar/examples/Test.tsx +258 -0
- package/src/components/Toolbar/examples/Toolbar.md +12 -6
- package/src/components/Toolbar/index.ts +1 -0
- package/src/components/Alert/__tests__/__snapshots__/AlertGroup.test.tsx.snap +0 -10
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":"5.1.1-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":"5.1.1-prerelease.4","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":"5.1.1-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":"5.1.1-prerelease.4","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":"5.1.1-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":"5.1.1-prerelease.4","private":true}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-core",
|
|
3
|
-
"version": "5.1.1-prerelease.
|
|
3
|
+
"version": "5.1.1-prerelease.5",
|
|
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",
|
|
@@ -45,15 +45,15 @@
|
|
|
45
45
|
"subpaths": "node ../../scripts/exportSubpaths.js --config subpaths.config.json"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@patternfly/react-icons": "^5.1.1-prerelease.
|
|
49
|
-
"@patternfly/react-styles": "^5.1.1-prerelease.
|
|
50
|
-
"@patternfly/react-tokens": "^5.1.1-prerelease.
|
|
48
|
+
"@patternfly/react-icons": "^5.1.1-prerelease.3",
|
|
49
|
+
"@patternfly/react-styles": "^5.1.1-prerelease.3",
|
|
50
|
+
"@patternfly/react-tokens": "^5.1.1-prerelease.3",
|
|
51
51
|
"focus-trap": "7.5.2",
|
|
52
52
|
"react-dropzone": "^14.2.3",
|
|
53
53
|
"tslib": "^2.5.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@patternfly/patternfly": "5.1.0-prerelease.
|
|
56
|
+
"@patternfly/patternfly": "5.1.0-prerelease.20",
|
|
57
57
|
"@rollup/plugin-commonjs": "^25.0.0",
|
|
58
58
|
"@rollup/plugin-node-resolve": "^15.0.2",
|
|
59
59
|
"@rollup/plugin-replace": "^5.0.2",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"react": "^17 || ^18",
|
|
71
71
|
"react-dom": "^17 || ^18"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "f3dbce4c4d20bf3a0f21b90244d146e316c4e837"
|
|
74
74
|
}
|
|
@@ -7,77 +7,81 @@ import { Alert } from '../../Alert';
|
|
|
7
7
|
import { AlertGroup } from '../../Alert';
|
|
8
8
|
import { AlertActionCloseButton } from '../../../components/Alert/AlertActionCloseButton';
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
10
|
+
test('Alert Group renders without children', () => {
|
|
11
|
+
render(
|
|
12
|
+
<div data-testid="container">
|
|
13
|
+
<AlertGroup data-testid="alertgroup" />
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
expect(screen.getByTestId('container').firstChild).toBeVisible();
|
|
18
|
+
expect(screen.getByTestId('alertgroup').children.length).toBe(0);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('Alert Group works with n children', () => {
|
|
22
|
+
const { asFragment } = render(
|
|
23
|
+
<AlertGroup data-testid="container">
|
|
24
|
+
<Alert variant="success" title="alert title" />
|
|
25
|
+
<Alert variant="warning" title="another alert title" />
|
|
26
|
+
</AlertGroup>
|
|
27
|
+
);
|
|
28
|
+
expect(screen.getByTestId('container').children.length).toBe(2);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('Alert group overflow shows up', async () => {
|
|
32
|
+
const overflowMessage = 'View 2 more alerts';
|
|
33
|
+
const onOverflowClick = jest.fn();
|
|
34
|
+
const user = userEvent.setup();
|
|
35
|
+
|
|
36
|
+
render(
|
|
37
|
+
<AlertGroup overflowMessage={overflowMessage} onOverflowClick={onOverflowClick}>
|
|
38
|
+
<Alert variant="danger" title="alert title" />
|
|
39
|
+
</AlertGroup>
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
expect(screen.getAllByRole('listitem')).toHaveLength(2);
|
|
43
|
+
|
|
44
|
+
const overflowButton = screen.getByRole('button', { name: 'View 2 more alerts' });
|
|
45
|
+
expect(overflowButton).toBeInTheDocument();
|
|
46
|
+
|
|
47
|
+
await user.click(overflowButton);
|
|
48
|
+
expect(onOverflowClick).toHaveBeenCalled();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('Standard Alert Group is not a toast alert group', () => {
|
|
52
|
+
render(
|
|
53
|
+
<AlertGroup>
|
|
54
|
+
<Alert variant="danger" title="alert title" />
|
|
55
|
+
</AlertGroup>
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
expect(screen.getByText('alert title').parentElement).not.toHaveClass('pf-m-toast');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('Toast Alert Group contains expected modifier class', () => {
|
|
62
|
+
render(
|
|
63
|
+
<AlertGroup isToast aria-label="group label">
|
|
64
|
+
<Alert variant="warning" title="alert title" />
|
|
65
|
+
</AlertGroup>
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
expect(screen.getByLabelText('group label')).toHaveClass('pf-m-toast');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('alertgroup closes when alerts are closed', async () => {
|
|
72
|
+
const onClose = jest.fn();
|
|
73
|
+
const user = userEvent.setup();
|
|
74
|
+
|
|
75
|
+
render(
|
|
76
|
+
<AlertGroup isToast appendTo={document.body}>
|
|
77
|
+
<Alert
|
|
78
|
+
isLiveRegion
|
|
79
|
+
title={'Test Alert'}
|
|
80
|
+
actionClose={<AlertActionCloseButton aria-label="Close" onClose={onClose} />}
|
|
81
|
+
/>
|
|
82
|
+
</AlertGroup>
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
await user.click(screen.getByLabelText('Close'));
|
|
86
|
+
expect(onClose).toHaveBeenCalled();
|
|
83
87
|
});
|
|
@@ -4,6 +4,22 @@ import { css } from '@patternfly/react-styles';
|
|
|
4
4
|
import { DrawerColorVariant, DrawerContext } from './Drawer';
|
|
5
5
|
import { formatBreakpointMods } from '../../helpers/util';
|
|
6
6
|
import { GenerateId } from '../../helpers/GenerateId/GenerateId';
|
|
7
|
+
import { FocusTrap } from '../../helpers/FocusTrap/FocusTrap';
|
|
8
|
+
|
|
9
|
+
export interface DrawerPanelFocusTrapObject {
|
|
10
|
+
/** Enables a focus trap on the drawer panel content. This will also automatically
|
|
11
|
+
* handle focus management when the panel expands and when it collapses. Do not pass
|
|
12
|
+
* this prop if the isStatic prop on the drawer component is true.
|
|
13
|
+
*/
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
/** The element to focus when the drawer panel content expands. By default the
|
|
16
|
+
* first focusable element will receive focus. If there are no focusable elements, the
|
|
17
|
+
* panel itself will receive focus.
|
|
18
|
+
*/
|
|
19
|
+
elementToFocusOnExpand?: HTMLElement | SVGElement | string;
|
|
20
|
+
/** One or more id's to use for the drawer panel content's accessible label. */
|
|
21
|
+
'aria-labelledby'?: string;
|
|
22
|
+
}
|
|
7
23
|
|
|
8
24
|
export interface DrawerPanelContentProps extends React.HTMLProps<HTMLDivElement> {
|
|
9
25
|
/** Additional classes added to the drawer. */
|
|
@@ -37,6 +53,8 @@ export interface DrawerPanelContentProps extends React.HTMLProps<HTMLDivElement>
|
|
|
37
53
|
};
|
|
38
54
|
/** Color variant of the background of the drawer panel */
|
|
39
55
|
colorVariant?: DrawerColorVariant | 'light-200' | 'no-background' | 'default';
|
|
56
|
+
/** Adds and customizes a focus trap on the drawer panel content. */
|
|
57
|
+
focusTrap?: DrawerPanelFocusTrapObject;
|
|
40
58
|
}
|
|
41
59
|
let isResizing: boolean = null;
|
|
42
60
|
let newSize: number = 0;
|
|
@@ -55,6 +73,7 @@ export const DrawerPanelContent: React.FunctionComponent<DrawerPanelContentProps
|
|
|
55
73
|
resizeAriaLabel = 'Resize',
|
|
56
74
|
widths,
|
|
57
75
|
colorVariant = DrawerColorVariant.default,
|
|
76
|
+
focusTrap,
|
|
58
77
|
...props
|
|
59
78
|
}: DrawerPanelContentProps) => {
|
|
60
79
|
const panel = React.useRef<HTMLDivElement>();
|
|
@@ -64,6 +83,8 @@ export const DrawerPanelContent: React.FunctionComponent<DrawerPanelContentProps
|
|
|
64
83
|
React.useContext(DrawerContext);
|
|
65
84
|
const hidden = isStatic ? false : !isExpanded;
|
|
66
85
|
const [isExpandedInternal, setIsExpandedInternal] = React.useState(!hidden);
|
|
86
|
+
const [isFocusTrapActive, setIsFocusTrapActive] = React.useState(false);
|
|
87
|
+
const previouslyFocusedElement = React.useRef(null);
|
|
67
88
|
let currWidth: number = 0;
|
|
68
89
|
let panelRect: DOMRect;
|
|
69
90
|
let right: number;
|
|
@@ -71,6 +92,13 @@ export const DrawerPanelContent: React.FunctionComponent<DrawerPanelContentProps
|
|
|
71
92
|
let bottom: number;
|
|
72
93
|
let setInitialVals: boolean = true;
|
|
73
94
|
|
|
95
|
+
if (isStatic && focusTrap?.enabled) {
|
|
96
|
+
// eslint-disable-next-line no-console
|
|
97
|
+
console.warn(
|
|
98
|
+
`DrawerPanelContent: The focusTrap.enabled prop cannot be true if the Drawer's isStatic prop is true. This will cause a permanent focus trap.`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
74
102
|
React.useEffect(() => {
|
|
75
103
|
if (!isStatic && isExpanded) {
|
|
76
104
|
setIsExpandedInternal(isExpanded);
|
|
@@ -246,64 +274,101 @@ export const DrawerPanelContent: React.FunctionComponent<DrawerPanelContentProps
|
|
|
246
274
|
if (maxSize) {
|
|
247
275
|
boundaryCssVars['--pf-v5-c-drawer__panel--md--FlexBasis--max'] = maxSize;
|
|
248
276
|
}
|
|
277
|
+
|
|
278
|
+
const isValidFocusTrap = focusTrap?.enabled && !isStatic;
|
|
279
|
+
const Component = isValidFocusTrap ? FocusTrap : 'div';
|
|
280
|
+
|
|
249
281
|
return (
|
|
250
282
|
<GenerateId prefix="pf-drawer-panel-">
|
|
251
|
-
{(panelId) =>
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
283
|
+
{(panelId) => {
|
|
284
|
+
const focusTrapProps = {
|
|
285
|
+
tabIndex: -1,
|
|
286
|
+
'aria-modal': true,
|
|
287
|
+
role: 'dialog',
|
|
288
|
+
active: isFocusTrapActive,
|
|
289
|
+
'aria-labelledby': focusTrap?.['aria-labelledby'] || id || panelId,
|
|
290
|
+
focusTrapOptions: {
|
|
291
|
+
fallbackFocus: () => panel.current,
|
|
292
|
+
onActivate: () => {
|
|
293
|
+
if (previouslyFocusedElement.current !== document.activeElement) {
|
|
294
|
+
previouslyFocusedElement.current = document.activeElement;
|
|
295
|
+
}
|
|
296
|
+
},
|
|
297
|
+
onDeactivate: () => {
|
|
298
|
+
previouslyFocusedElement.current &&
|
|
299
|
+
previouslyFocusedElement.current.focus &&
|
|
300
|
+
previouslyFocusedElement.current.focus();
|
|
301
|
+
},
|
|
302
|
+
clickOutsideDeactivates: true,
|
|
303
|
+
returnFocusOnDeactivate: false,
|
|
304
|
+
// FocusTrap's initialFocus can accept false as a value to prevent initial focus.
|
|
305
|
+
// We want to prevent this in case false is ever passed in.
|
|
306
|
+
initialFocus: focusTrap?.elementToFocusOnExpand || undefined,
|
|
307
|
+
escapeDeactivates: false
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
return (
|
|
312
|
+
<Component
|
|
313
|
+
{...(isValidFocusTrap && focusTrapProps)}
|
|
314
|
+
id={id || panelId}
|
|
315
|
+
className={css(
|
|
316
|
+
styles.drawerPanel,
|
|
317
|
+
isResizable && styles.modifiers.resizable,
|
|
318
|
+
hasNoBorder && styles.modifiers.noBorder,
|
|
319
|
+
formatBreakpointMods(widths, styles),
|
|
320
|
+
colorVariant === DrawerColorVariant.light200 && styles.modifiers.light_200,
|
|
321
|
+
colorVariant === DrawerColorVariant.noBackground && styles.modifiers.noBackground,
|
|
322
|
+
className
|
|
323
|
+
)}
|
|
324
|
+
onTransitionEnd={(ev) => {
|
|
325
|
+
if ((ev.target as HTMLElement) === panel.current) {
|
|
326
|
+
if (!hidden && ev.nativeEvent.propertyName === 'transform') {
|
|
327
|
+
onExpand(ev);
|
|
328
|
+
}
|
|
329
|
+
setIsExpandedInternal(!hidden);
|
|
330
|
+
if (isValidFocusTrap && ev.nativeEvent.propertyName === 'transform') {
|
|
331
|
+
setIsFocusTrapActive((prevIsFocusTrapActive) => !prevIsFocusTrapActive);
|
|
332
|
+
}
|
|
268
333
|
}
|
|
269
|
-
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
334
|
+
}}
|
|
335
|
+
hidden={hidden}
|
|
336
|
+
{...((defaultSize || minSize || maxSize) && {
|
|
337
|
+
style: boundaryCssVars as React.CSSProperties
|
|
338
|
+
})}
|
|
339
|
+
{...props}
|
|
340
|
+
ref={panel}
|
|
341
|
+
>
|
|
342
|
+
{isExpandedInternal && (
|
|
343
|
+
<React.Fragment>
|
|
344
|
+
{isResizable && (
|
|
345
|
+
<React.Fragment>
|
|
346
|
+
<div
|
|
347
|
+
className={css(styles.drawerSplitter, position !== 'bottom' && styles.modifiers.vertical)}
|
|
348
|
+
role="separator"
|
|
349
|
+
tabIndex={0}
|
|
350
|
+
aria-orientation={position === 'bottom' ? 'horizontal' : 'vertical'}
|
|
351
|
+
aria-label={resizeAriaLabel}
|
|
352
|
+
aria-valuenow={separatorValue}
|
|
353
|
+
aria-valuemin={0}
|
|
354
|
+
aria-valuemax={100}
|
|
355
|
+
aria-controls={id || panelId}
|
|
356
|
+
onMouseDown={handleMousedown}
|
|
357
|
+
onKeyDown={handleKeys}
|
|
358
|
+
onTouchStart={handleTouchStart}
|
|
359
|
+
ref={splitterRef}
|
|
360
|
+
>
|
|
361
|
+
<div className={css(styles.drawerSplitterHandle)} aria-hidden></div>
|
|
362
|
+
</div>
|
|
363
|
+
<div className={css(styles.drawerPanelMain)}>{children}</div>
|
|
364
|
+
</React.Fragment>
|
|
365
|
+
)}
|
|
366
|
+
{!isResizable && children}
|
|
367
|
+
</React.Fragment>
|
|
368
|
+
)}
|
|
369
|
+
</Component>
|
|
370
|
+
);
|
|
371
|
+
}}
|
|
307
372
|
</GenerateId>
|
|
308
373
|
);
|
|
309
374
|
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { DrawerPanelContent } from '../DrawerPanelContent';
|
|
4
|
+
import { Drawer } from '../Drawer';
|
|
5
|
+
|
|
6
|
+
test('Does not render with aria-labelledby by default', () => {
|
|
7
|
+
render(
|
|
8
|
+
<Drawer isExpanded>
|
|
9
|
+
<DrawerPanelContent>Drawer panel content</DrawerPanelContent>
|
|
10
|
+
</Drawer>
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
expect(screen.getByText('Drawer panel content')).not.toHaveAccessibleName();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('Renders with aria-labelledby when focusTrap.enabled is true', () => {
|
|
17
|
+
render(
|
|
18
|
+
<Drawer isExpanded>
|
|
19
|
+
<DrawerPanelContent focusTrap={{ enabled: true }}>Drawer panel content</DrawerPanelContent>
|
|
20
|
+
</Drawer>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
expect(screen.getByText('Drawer panel content')).toHaveAccessibleName('Drawer panel content');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('Renders with aria-labelledby when id is passed in', () => {
|
|
27
|
+
render(
|
|
28
|
+
<Drawer isExpanded>
|
|
29
|
+
<DrawerPanelContent id="drawer-panel-content" focusTrap={{ enabled: true }}>
|
|
30
|
+
Drawer panel content
|
|
31
|
+
</DrawerPanelContent>
|
|
32
|
+
</Drawer>
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
expect(screen.getByText('Drawer panel content')).toHaveAccessibleName('Drawer panel content');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('Renders with custom aria-labelledby', () => {
|
|
39
|
+
render(
|
|
40
|
+
<Drawer isExpanded>
|
|
41
|
+
<DrawerPanelContent focusTrap={{ enabled: true, 'aria-labelledby': 'drawer-panel-title' }}>
|
|
42
|
+
<span id="drawer-panel-title">Title</span>
|
|
43
|
+
<span>Drawer panel content</span>
|
|
44
|
+
</DrawerPanelContent>
|
|
45
|
+
</Drawer>
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
expect(screen.getByText('Drawer panel content').parentElement).toHaveAccessibleName('Title');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('Does not render with aria-modal="true" by default', () => {
|
|
52
|
+
render(
|
|
53
|
+
<Drawer isExpanded>
|
|
54
|
+
<DrawerPanelContent>Drawer panel content</DrawerPanelContent>
|
|
55
|
+
</Drawer>
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
expect(screen.getByText('Drawer panel content')).not.toHaveAttribute('aria-modal');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('Renders with aria-modal="true" when focusTrap.enabled is true', () => {
|
|
62
|
+
render(
|
|
63
|
+
<Drawer isExpanded>
|
|
64
|
+
<DrawerPanelContent focusTrap={{ enabled: true }}>Drawer panel content</DrawerPanelContent>
|
|
65
|
+
</Drawer>
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
expect(screen.getByText('Drawer panel content')).toHaveAttribute('aria-modal', 'true');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('Does not render with role="dialog" by default', () => {
|
|
72
|
+
render(
|
|
73
|
+
<Drawer isExpanded>
|
|
74
|
+
<DrawerPanelContent>Drawer panel content</DrawerPanelContent>
|
|
75
|
+
</Drawer>
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('Renders with role="dialog" when focusTrap.enabled is true', () => {
|
|
82
|
+
render(
|
|
83
|
+
<Drawer isExpanded>
|
|
84
|
+
<DrawerPanelContent focusTrap={{ enabled: true }}>Drawer panel content</DrawerPanelContent>
|
|
85
|
+
</Drawer>
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
|
89
|
+
});
|
|
@@ -13,6 +13,7 @@ propComponents:
|
|
|
13
13
|
DrawerActions,
|
|
14
14
|
DrawerCloseButton,
|
|
15
15
|
DrawerColorVariant,
|
|
16
|
+
DrawerPanelFocusTrapObject
|
|
16
17
|
]
|
|
17
18
|
section: components
|
|
18
19
|
---
|
|
@@ -22,56 +23,67 @@ section: components
|
|
|
22
23
|
### Basic
|
|
23
24
|
|
|
24
25
|
```ts file="./DrawerBasic.tsx"
|
|
26
|
+
|
|
25
27
|
```
|
|
26
28
|
|
|
27
29
|
### Panel on right
|
|
28
30
|
|
|
29
31
|
```ts file="./DrawerPanelRight.tsx"
|
|
32
|
+
|
|
30
33
|
```
|
|
31
34
|
|
|
32
35
|
### Panel on left
|
|
33
36
|
|
|
34
37
|
```ts file="./DrawerPanelLeft.tsx"
|
|
38
|
+
|
|
35
39
|
```
|
|
36
40
|
|
|
37
41
|
### Panel on bottom
|
|
38
42
|
|
|
39
43
|
```ts file="./DrawerPanelBottom.tsx"
|
|
44
|
+
|
|
40
45
|
```
|
|
41
46
|
|
|
42
47
|
### Basic inline
|
|
43
48
|
|
|
44
49
|
```ts file="./DrawerBasicInline.tsx"
|
|
50
|
+
|
|
45
51
|
```
|
|
46
52
|
|
|
47
53
|
### Inline panel on right
|
|
48
54
|
|
|
49
55
|
```ts file="./DrawerInlinePanelRight.tsx"
|
|
56
|
+
|
|
50
57
|
```
|
|
51
58
|
|
|
52
59
|
### Inline panel on left
|
|
53
60
|
|
|
54
61
|
```ts file="./DrawerInlinePanelLeft.tsx"
|
|
62
|
+
|
|
55
63
|
```
|
|
56
64
|
|
|
57
65
|
### Stacked content body elements
|
|
58
66
|
|
|
59
67
|
```ts file="./DrawerStackedContentBodyElements.tsx"
|
|
68
|
+
|
|
60
69
|
```
|
|
61
70
|
|
|
62
71
|
### Modified content padding
|
|
63
72
|
|
|
64
73
|
```ts file="DrawerModifiedContentPadding.tsx"
|
|
74
|
+
|
|
65
75
|
```
|
|
66
76
|
|
|
67
77
|
### Modified panel padding
|
|
68
78
|
|
|
69
79
|
```ts file="DrawerModifiedPanelPadding.tsx"
|
|
80
|
+
|
|
70
81
|
```
|
|
71
82
|
|
|
72
83
|
### Additional section above drawer content
|
|
73
84
|
|
|
74
85
|
```ts file="DrawerAdditionalSectionAboveContent.tsx"
|
|
86
|
+
|
|
75
87
|
```
|
|
76
88
|
|
|
77
89
|
### Static drawer
|
|
@@ -79,34 +91,53 @@ section: components
|
|
|
79
91
|
**Note:** For mobile viewports, all drawer variants behave the same way. At the `md` breakpoint, or where `.pf-m-static{-on-[lg, xl, 2xl]}` is applied, the `static drawer` variant’s `close button` is automatically hidden because the drawer panel doesn’t close by design.
|
|
80
92
|
|
|
81
93
|
```ts file="DrawerStatic.tsx"
|
|
94
|
+
|
|
82
95
|
```
|
|
83
96
|
|
|
84
97
|
### Breakpoint
|
|
85
98
|
|
|
86
99
|
```ts file="DrawerBreakpoint.tsx"
|
|
100
|
+
|
|
87
101
|
```
|
|
88
102
|
|
|
89
103
|
### Resizable on right
|
|
90
104
|
|
|
91
105
|
```ts file="DrawerResizableOnRight.tsx"
|
|
106
|
+
|
|
92
107
|
```
|
|
93
108
|
|
|
94
109
|
### Resizable on left
|
|
95
110
|
|
|
96
111
|
```ts file="DrawerResizableOnLeft.tsx"
|
|
112
|
+
|
|
97
113
|
```
|
|
98
114
|
|
|
99
115
|
### Resizable on bottom
|
|
100
116
|
|
|
101
117
|
```ts file="DrawerResizableOnBottom.tsx"
|
|
118
|
+
|
|
102
119
|
```
|
|
103
120
|
|
|
104
121
|
### Resizable on inline
|
|
105
122
|
|
|
106
123
|
```ts file="DrawerResizableOnInline.tsx"
|
|
124
|
+
|
|
107
125
|
```
|
|
108
126
|
|
|
109
127
|
### Panel with secondary background
|
|
110
128
|
|
|
111
129
|
```ts file="DrawerSecondaryBackground.tsx"
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### With focus trap
|
|
134
|
+
|
|
135
|
+
When a [focus trap](/accessibility/product-development-guide#trapping-focus) is enabled on an element, a user will only be able to interact with the contents of that element until the focus trap is closed or deactivated.
|
|
136
|
+
|
|
137
|
+
To enable and customize a focus trap on a drawer panel, apply the `focusTrap` property to the `<DrawerPanelContent>` component. Enabling a focus trap with `focusTrap.enabled` will also automatically place focus on the first focusable element when the drawer panel expands, and return focus to the previously focused element when it collapses.
|
|
138
|
+
|
|
139
|
+
To customize which element receives focus when the drawer panel expands, use the `focusTrap.elementToFocusOnExpand` property.
|
|
140
|
+
|
|
141
|
+
```ts file="./DrawerFocusTrap.tsx"
|
|
142
|
+
|
|
112
143
|
```
|