@patternfly/react-core 5.1.1-prerelease.1 → 5.1.1-prerelease.11

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.
Files changed (245) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/components/package.json +1 -1
  3. package/deprecated/package.json +1 -1
  4. package/dist/dynamic/components/AboutModal/package.json +1 -1
  5. package/dist/dynamic/components/Accordion/package.json +1 -1
  6. package/dist/dynamic/components/ActionList/package.json +1 -1
  7. package/dist/dynamic/components/Alert/package.json +1 -1
  8. package/dist/dynamic/components/Avatar/package.json +1 -1
  9. package/dist/dynamic/components/BackToTop/package.json +1 -1
  10. package/dist/dynamic/components/Backdrop/package.json +1 -1
  11. package/dist/dynamic/components/BackgroundImage/package.json +1 -1
  12. package/dist/dynamic/components/Badge/package.json +1 -1
  13. package/dist/dynamic/components/Banner/package.json +1 -1
  14. package/dist/dynamic/components/Brand/package.json +1 -1
  15. package/dist/dynamic/components/Breadcrumb/package.json +1 -1
  16. package/dist/dynamic/components/Button/package.json +1 -1
  17. package/dist/dynamic/components/CalendarMonth/package.json +1 -1
  18. package/dist/dynamic/components/Card/package.json +1 -1
  19. package/dist/dynamic/components/Checkbox/package.json +1 -1
  20. package/dist/dynamic/components/Chip/package.json +1 -1
  21. package/dist/dynamic/components/ClipboardCopy/package.json +1 -1
  22. package/dist/dynamic/components/CodeBlock/package.json +1 -1
  23. package/dist/dynamic/components/DataList/package.json +1 -1
  24. package/dist/dynamic/components/DatePicker/package.json +1 -1
  25. package/dist/dynamic/components/DescriptionList/package.json +1 -1
  26. package/dist/dynamic/components/Divider/package.json +1 -1
  27. package/dist/dynamic/components/DragDrop/package.json +1 -1
  28. package/dist/dynamic/components/Drawer/package.json +1 -1
  29. package/dist/dynamic/components/Dropdown/package.json +1 -1
  30. package/dist/dynamic/components/DualListSelector/package.json +1 -1
  31. package/dist/dynamic/components/EmptyState/package.json +1 -1
  32. package/dist/dynamic/components/ExpandableSection/package.json +1 -1
  33. package/dist/dynamic/components/FileUpload/package.json +1 -1
  34. package/dist/dynamic/components/Form/package.json +1 -1
  35. package/dist/dynamic/components/FormSelect/package.json +1 -1
  36. package/dist/dynamic/components/HelperText/package.json +1 -1
  37. package/dist/dynamic/components/Hint/package.json +1 -1
  38. package/dist/dynamic/components/Icon/package.json +1 -1
  39. package/dist/dynamic/components/InputGroup/package.json +1 -1
  40. package/dist/dynamic/components/JumpLinks/package.json +1 -1
  41. package/dist/dynamic/components/Label/package.json +1 -1
  42. package/dist/dynamic/components/List/package.json +1 -1
  43. package/dist/dynamic/components/LoginPage/package.json +1 -1
  44. package/dist/dynamic/components/Masthead/package.json +1 -1
  45. package/dist/dynamic/components/Menu/package.json +1 -1
  46. package/dist/dynamic/components/MenuToggle/package.json +1 -1
  47. package/dist/dynamic/components/Modal/package.json +1 -1
  48. package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
  49. package/dist/dynamic/components/Nav/package.json +1 -1
  50. package/dist/dynamic/components/NotificationBadge/package.json +1 -1
  51. package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
  52. package/dist/dynamic/components/NumberInput/package.json +1 -1
  53. package/dist/dynamic/components/OverflowMenu/package.json +1 -1
  54. package/dist/dynamic/components/Page/package.json +1 -1
  55. package/dist/dynamic/components/Pagination/package.json +1 -1
  56. package/dist/dynamic/components/Panel/package.json +1 -1
  57. package/dist/dynamic/components/Popover/package.json +1 -1
  58. package/dist/dynamic/components/Progress/package.json +1 -1
  59. package/dist/dynamic/components/ProgressStepper/package.json +1 -1
  60. package/dist/dynamic/components/Radio/package.json +1 -1
  61. package/dist/dynamic/components/SearchInput/package.json +1 -1
  62. package/dist/dynamic/components/Select/package.json +1 -1
  63. package/dist/dynamic/components/Sidebar/package.json +1 -1
  64. package/dist/dynamic/components/SimpleList/package.json +1 -1
  65. package/dist/dynamic/components/Skeleton/package.json +1 -1
  66. package/dist/dynamic/components/SkipToContent/package.json +1 -1
  67. package/dist/dynamic/components/Slider/package.json +1 -1
  68. package/dist/dynamic/components/Spinner/package.json +1 -1
  69. package/dist/dynamic/components/Switch/package.json +1 -1
  70. package/dist/dynamic/components/Tabs/package.json +1 -1
  71. package/dist/dynamic/components/Text/package.json +1 -1
  72. package/dist/dynamic/components/TextArea/package.json +1 -1
  73. package/dist/dynamic/components/TextInput/package.json +1 -1
  74. package/dist/dynamic/components/TextInputGroup/package.json +1 -1
  75. package/dist/dynamic/components/Tile/package.json +1 -1
  76. package/dist/dynamic/components/TimePicker/package.json +1 -1
  77. package/dist/dynamic/components/Timestamp/package.json +1 -1
  78. package/dist/dynamic/components/Title/package.json +1 -1
  79. package/dist/dynamic/components/ToggleGroup/package.json +1 -1
  80. package/dist/dynamic/components/Toolbar/package.json +1 -1
  81. package/dist/dynamic/components/Tooltip/package.json +1 -1
  82. package/dist/dynamic/components/TreeView/package.json +1 -1
  83. package/dist/dynamic/components/Truncate/package.json +1 -1
  84. package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
  85. package/dist/dynamic/components/Wizard/package.json +1 -1
  86. package/dist/dynamic/deprecated/components/ApplicationLauncher/package.json +1 -1
  87. package/dist/dynamic/deprecated/components/ContextSelector/package.json +1 -1
  88. package/dist/dynamic/deprecated/components/Dropdown/package.json +1 -1
  89. package/dist/dynamic/deprecated/components/OptionsMenu/package.json +1 -1
  90. package/dist/dynamic/deprecated/components/PageHeader/package.json +1 -1
  91. package/dist/dynamic/deprecated/components/Select/package.json +1 -1
  92. package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
  93. package/dist/dynamic/deprecated/components/package.json +1 -1
  94. package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
  95. package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
  96. package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
  97. package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
  98. package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
  99. package/dist/dynamic/helpers/constants/package.json +1 -1
  100. package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
  101. package/dist/dynamic/helpers/favorites/package.json +1 -1
  102. package/dist/dynamic/helpers/fileUtils/package.json +1 -1
  103. package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
  104. package/dist/dynamic/helpers/package.json +1 -1
  105. package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
  106. package/dist/dynamic/helpers/typeUtils/package.json +1 -1
  107. package/dist/dynamic/helpers/useInterval/package.json +1 -1
  108. package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
  109. package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
  110. package/dist/dynamic/helpers/util/package.json +1 -1
  111. package/dist/dynamic/layouts/Bullseye/package.json +1 -1
  112. package/dist/dynamic/layouts/Flex/package.json +1 -1
  113. package/dist/dynamic/layouts/Gallery/package.json +1 -1
  114. package/dist/dynamic/layouts/Grid/package.json +1 -1
  115. package/dist/dynamic/layouts/Level/package.json +1 -1
  116. package/dist/dynamic/layouts/Split/package.json +1 -1
  117. package/dist/dynamic/layouts/Stack/package.json +1 -1
  118. package/dist/dynamic/next/components/package.json +1 -1
  119. package/dist/esm/components/BackToTop/BackToTop.js +1 -1
  120. package/dist/esm/components/BackToTop/BackToTop.js.map +1 -1
  121. package/dist/esm/components/Button/Button.d.ts +2 -2
  122. package/dist/esm/components/Button/Button.d.ts.map +1 -1
  123. package/dist/esm/components/Button/Button.js +3 -3
  124. package/dist/esm/components/Button/Button.js.map +1 -1
  125. package/dist/esm/components/Drawer/DrawerPanelContent.d.ts +16 -0
  126. package/dist/esm/components/Drawer/DrawerPanelContent.d.ts.map +1 -1
  127. package/dist/esm/components/Drawer/DrawerPanelContent.js +55 -15
  128. package/dist/esm/components/Drawer/DrawerPanelContent.js.map +1 -1
  129. package/dist/esm/components/Icon/Icon.d.ts +4 -0
  130. package/dist/esm/components/Icon/Icon.d.ts.map +1 -1
  131. package/dist/esm/components/Icon/Icon.js +2 -2
  132. package/dist/esm/components/Icon/Icon.js.map +1 -1
  133. package/dist/esm/components/Nav/NavItem.d.ts +1 -1
  134. package/dist/esm/components/Nav/NavItem.d.ts.map +1 -1
  135. package/dist/esm/components/Toolbar/ToolbarContent.d.ts.map +1 -1
  136. package/dist/esm/components/Toolbar/ToolbarContent.js +8 -6
  137. package/dist/esm/components/Toolbar/ToolbarContent.js.map +1 -1
  138. package/dist/esm/components/Toolbar/ToolbarExpandableContent.d.ts.map +1 -1
  139. package/dist/esm/components/Toolbar/ToolbarExpandableContent.js +3 -5
  140. package/dist/esm/components/Toolbar/ToolbarExpandableContent.js.map +1 -1
  141. package/dist/esm/components/Toolbar/ToolbarFilter.d.ts +4 -0
  142. package/dist/esm/components/Toolbar/ToolbarFilter.d.ts.map +1 -1
  143. package/dist/esm/components/Toolbar/ToolbarFilter.js +8 -4
  144. package/dist/esm/components/Toolbar/ToolbarFilter.js.map +1 -1
  145. package/dist/esm/components/Toolbar/ToolbarToggleGroup.d.ts +14 -0
  146. package/dist/esm/components/Toolbar/ToolbarToggleGroup.d.ts.map +1 -1
  147. package/dist/esm/components/Toolbar/ToolbarToggleGroup.js +21 -20
  148. package/dist/esm/components/Toolbar/ToolbarToggleGroup.js.map +1 -1
  149. package/dist/esm/components/Toolbar/ToolbarUtils.d.ts +4 -0
  150. package/dist/esm/components/Toolbar/ToolbarUtils.d.ts.map +1 -1
  151. package/dist/esm/components/Toolbar/ToolbarUtils.js +2 -1
  152. package/dist/esm/components/Toolbar/ToolbarUtils.js.map +1 -1
  153. package/dist/esm/components/Toolbar/index.d.ts +1 -0
  154. package/dist/esm/components/Toolbar/index.d.ts.map +1 -1
  155. package/dist/esm/components/Toolbar/index.js +1 -0
  156. package/dist/esm/components/Toolbar/index.js.map +1 -1
  157. package/dist/esm/deprecated/components/Select/Select.d.ts.map +1 -1
  158. package/dist/esm/deprecated/components/Select/Select.js +43 -42
  159. package/dist/esm/deprecated/components/Select/Select.js.map +1 -1
  160. package/dist/js/components/BackToTop/BackToTop.js +1 -1
  161. package/dist/js/components/BackToTop/BackToTop.js.map +1 -1
  162. package/dist/js/components/Button/Button.d.ts +2 -2
  163. package/dist/js/components/Button/Button.d.ts.map +1 -1
  164. package/dist/js/components/Button/Button.js +3 -3
  165. package/dist/js/components/Button/Button.js.map +1 -1
  166. package/dist/js/components/Drawer/DrawerPanelContent.d.ts +16 -0
  167. package/dist/js/components/Drawer/DrawerPanelContent.d.ts.map +1 -1
  168. package/dist/js/components/Drawer/DrawerPanelContent.js +55 -15
  169. package/dist/js/components/Drawer/DrawerPanelContent.js.map +1 -1
  170. package/dist/js/components/Icon/Icon.d.ts +4 -0
  171. package/dist/js/components/Icon/Icon.d.ts.map +1 -1
  172. package/dist/js/components/Icon/Icon.js +2 -2
  173. package/dist/js/components/Icon/Icon.js.map +1 -1
  174. package/dist/js/components/Nav/NavItem.d.ts +1 -1
  175. package/dist/js/components/Nav/NavItem.d.ts.map +1 -1
  176. package/dist/js/components/Toolbar/ToolbarContent.d.ts.map +1 -1
  177. package/dist/js/components/Toolbar/ToolbarContent.js +8 -6
  178. package/dist/js/components/Toolbar/ToolbarContent.js.map +1 -1
  179. package/dist/js/components/Toolbar/ToolbarExpandableContent.d.ts.map +1 -1
  180. package/dist/js/components/Toolbar/ToolbarExpandableContent.js +3 -5
  181. package/dist/js/components/Toolbar/ToolbarExpandableContent.js.map +1 -1
  182. package/dist/js/components/Toolbar/ToolbarFilter.d.ts +4 -0
  183. package/dist/js/components/Toolbar/ToolbarFilter.d.ts.map +1 -1
  184. package/dist/js/components/Toolbar/ToolbarFilter.js +8 -4
  185. package/dist/js/components/Toolbar/ToolbarFilter.js.map +1 -1
  186. package/dist/js/components/Toolbar/ToolbarToggleGroup.d.ts +14 -0
  187. package/dist/js/components/Toolbar/ToolbarToggleGroup.d.ts.map +1 -1
  188. package/dist/js/components/Toolbar/ToolbarToggleGroup.js +21 -20
  189. package/dist/js/components/Toolbar/ToolbarToggleGroup.js.map +1 -1
  190. package/dist/js/components/Toolbar/ToolbarUtils.d.ts +4 -0
  191. package/dist/js/components/Toolbar/ToolbarUtils.d.ts.map +1 -1
  192. package/dist/js/components/Toolbar/ToolbarUtils.js +2 -1
  193. package/dist/js/components/Toolbar/ToolbarUtils.js.map +1 -1
  194. package/dist/js/components/Toolbar/index.d.ts +1 -0
  195. package/dist/js/components/Toolbar/index.d.ts.map +1 -1
  196. package/dist/js/components/Toolbar/index.js +1 -0
  197. package/dist/js/components/Toolbar/index.js.map +1 -1
  198. package/dist/js/deprecated/components/Select/Select.d.ts.map +1 -1
  199. package/dist/js/deprecated/components/Select/Select.js +43 -42
  200. package/dist/js/deprecated/components/Select/Select.js.map +1 -1
  201. package/dist/styles/base-no-reset.css +19 -0
  202. package/dist/styles/base.css +19 -0
  203. package/dist/umd/react-core.min.js +3 -3
  204. package/helpers/package.json +1 -1
  205. package/layouts/package.json +1 -1
  206. package/next/package.json +1 -1
  207. package/package.json +6 -6
  208. package/src/components/Alert/__tests__/AlertGroup.test.tsx +77 -73
  209. package/src/components/BackToTop/BackToTop.tsx +1 -1
  210. package/src/components/BackToTop/__tests__/BackToTop.test.tsx +1 -1
  211. package/src/components/BackToTop/__tests__/__snapshots__/BackToTop.test.tsx.snap +1 -1
  212. package/src/components/Button/Button.tsx +5 -5
  213. package/src/components/Button/examples/ButtonVariations.tsx +1 -1
  214. package/src/components/Drawer/DrawerPanelContent.tsx +120 -55
  215. package/src/components/Drawer/__tests__/DrawerPanelContent.test.tsx +89 -0
  216. package/src/components/Drawer/examples/Drawer.md +31 -0
  217. package/src/components/Drawer/examples/DrawerFocusTrap.tsx +58 -0
  218. package/src/components/Icon/Icon.tsx +15 -1
  219. package/src/components/Icon/__tests__/Icon.test.tsx +16 -0
  220. package/src/components/Nav/NavItem.tsx +1 -1
  221. package/src/components/SearchInput/examples/SearchInputAdvanced.tsx +1 -1
  222. package/src/components/Tile/examples/Tile.md +14 -10
  223. package/src/components/Toolbar/ToolbarContent.tsx +7 -11
  224. package/src/components/Toolbar/ToolbarExpandableContent.tsx +7 -3
  225. package/src/components/Toolbar/ToolbarFilter.tsx +12 -2
  226. package/src/components/Toolbar/ToolbarToggleGroup.tsx +92 -47
  227. package/src/components/Toolbar/ToolbarUtils.tsx +6 -1
  228. package/src/components/Toolbar/__tests__/Generated/__snapshots__/ToolbarContent.test.tsx.snap +0 -8
  229. package/src/components/Toolbar/__tests__/Toolbar.test.tsx +3 -4
  230. package/src/components/Toolbar/__tests__/ToolbarToggleGroup.test.tsx +13 -10
  231. package/src/components/Toolbar/__tests__/__snapshots__/Toolbar.test.tsx.snap +0 -59
  232. package/src/components/Toolbar/examples/Test.tsx +258 -0
  233. package/src/components/Toolbar/examples/Toolbar.md +12 -6
  234. package/src/components/Toolbar/index.ts +1 -0
  235. package/src/demos/Card/Card.md +3 -664
  236. package/src/demos/Card/examples/CardView.tsx +575 -0
  237. package/src/demos/CardDemos.md +4 -4
  238. package/src/demos/NotificationDrawer/NotificationDrawer.md +2 -1435
  239. package/src/demos/NotificationDrawer/examples/NotificationDrawerBasic.tsx +557 -0
  240. package/src/demos/NotificationDrawer/examples/NotificationDrawerGrouped.tsx +796 -0
  241. package/src/demos/PrimaryDetail.md +2 -2
  242. package/src/deprecated/components/Select/Select.tsx +47 -45
  243. package/src/deprecated/components/Select/__tests__/__snapshots__/Select.test.tsx.snap +9 -5
  244. package/src/components/Alert/__tests__/__snapshots__/AlertGroup.test.tsx.snap +0 -10
  245. /package/src/demos/Card/{CardData.jsx → examples/CardData.jsx} +0 -0
@@ -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.0","private":true}
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.10","private":true}
@@ -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.0","private":true}
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.10","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.0","private":true}
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.10","private":true}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "5.1.1-prerelease.1",
3
+ "version": "5.1.1-prerelease.11",
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.1",
49
- "@patternfly/react-styles": "^5.1.1-prerelease.1",
50
- "@patternfly/react-tokens": "^5.1.1-prerelease.1",
48
+ "@patternfly/react-icons": "^5.1.1-prerelease.5",
49
+ "@patternfly/react-styles": "^5.1.1-prerelease.5",
50
+ "@patternfly/react-tokens": "^5.1.1-prerelease.5",
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.8",
56
+ "@patternfly/patternfly": "5.1.0-prerelease.24",
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": "1e1305e5f7450e087ff8d1690d2be28b00dac0a1"
73
+ "gitHead": "10e4992a19129f0123d894612b9160e498553d73"
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
- describe('AlertGroup', () => {
11
- test('Alert Group renders without children', () => {
12
- const { asFragment } = render(<AlertGroup />);
13
- expect(asFragment()).toMatchSnapshot();
14
- });
15
-
16
- test('Alert Group works with n children', () => {
17
- const { asFragment } = render(
18
- <AlertGroup>
19
- <Alert variant="success" title="alert title" />
20
- <Alert variant="warning" title="another alert title" />
21
- </AlertGroup>
22
- );
23
- expect(asFragment()).toBeTruthy();
24
- });
25
-
26
- test('Alert group overflow shows up', async () => {
27
- const overflowMessage = 'View 2 more alerts';
28
- const onOverflowClick = jest.fn();
29
- const user = userEvent.setup();
30
-
31
- render(
32
- <AlertGroup overflowMessage={overflowMessage} onOverflowClick={onOverflowClick}>
33
- <Alert variant="danger" title="alert title" />
34
- </AlertGroup>
35
- );
36
-
37
- expect(screen.getAllByRole('listitem')).toHaveLength(2);
38
-
39
- const overflowButton = screen.getByRole('button', { name: 'View 2 more alerts' });
40
- expect(overflowButton).toBeInTheDocument();
41
-
42
- await user.click(overflowButton);
43
- expect(onOverflowClick).toHaveBeenCalled();
44
- });
45
-
46
- test('Standard Alert Group is not a toast alert group', () => {
47
- render(
48
- <AlertGroup>
49
- <Alert variant="danger" title="alert title" />
50
- </AlertGroup>
51
- );
52
-
53
- expect(screen.getByText('alert title').parentElement).not.toHaveClass('pf-m-toast');
54
- });
55
-
56
- test('Toast Alert Group contains expected modifier class', () => {
57
- render(
58
- <AlertGroup isToast aria-label="group label">
59
- <Alert variant="warning" title="alert title" />
60
- </AlertGroup>
61
- );
62
-
63
- expect(screen.getByLabelText('group label')).toHaveClass('pf-m-toast');
64
- });
65
-
66
- test('alertgroup closes when alerts are closed', async () => {
67
- const onClose = jest.fn();
68
- const user = userEvent.setup();
69
-
70
- render(
71
- <AlertGroup isToast appendTo={document.body}>
72
- <Alert
73
- isLiveRegion
74
- title={'Test Alert'}
75
- actionClose={<AlertActionCloseButton aria-label="Close" onClose={onClose} />}
76
- />
77
- </AlertGroup>
78
- );
79
-
80
- await user.click(screen.getByLabelText('Close'));
81
- expect(onClose).toHaveBeenCalled();
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
  });
@@ -82,7 +82,7 @@ const BackToTopBase: React.FunctionComponent<BackToTopProps> = ({
82
82
  onClick={handleClick}
83
83
  {...props}
84
84
  >
85
- <Button variant="primary" icon={<AngleUpIcon aria-hidden="true" />} iconPosition="right">
85
+ <Button variant="primary" icon={<AngleUpIcon aria-hidden="true" />} iconPosition="end">
86
86
  {title}
87
87
  </Button>
88
88
  </div>
@@ -135,7 +135,7 @@ test('Passes correct variant to button child component', () => {
135
135
  test('Passes correct iconPosition to button child component', () => {
136
136
  render(<BackToTop />);
137
137
 
138
- expect(screen.getByText('iconPosition: right')).toBeVisible();
138
+ expect(screen.getByText('iconPosition: end')).toBeVisible();
139
139
  });
140
140
 
141
141
  test('Passes correct icon to button child component', () => {
@@ -20,7 +20,7 @@ exports[`Matches the snapshot 1`] = `
20
20
  isInline: undefined
21
21
  </p>
22
22
  <p>
23
- iconPosition: right
23
+ iconPosition: end
24
24
  </p>
25
25
  <div
26
26
  data-testid="icon"
@@ -70,8 +70,8 @@ export interface ButtonProps extends Omit<React.HTMLProps<HTMLButtonElement>, 'r
70
70
  type?: 'button' | 'submit' | 'reset';
71
71
  /** Adds button variant styles */
72
72
  variant?: 'primary' | 'secondary' | 'tertiary' | 'danger' | 'warning' | 'link' | 'plain' | 'control';
73
- /** Sets position of the link icon */
74
- iconPosition?: 'left' | 'right';
73
+ /** Sets position of the icon. Note: "left" and "right" are deprecated. Use "start" and "end" instead */
74
+ iconPosition?: 'start' | 'end' | 'left' | 'right';
75
75
  /** Adds accessible text to the button. */
76
76
  'aria-label'?: string;
77
77
  /** Icon for the button. Usable by all variants except for plain. */
@@ -108,7 +108,7 @@ const ButtonBase: React.FunctionComponent<ButtonProps> = ({
108
108
  isInline = false,
109
109
  type = ButtonType.button,
110
110
  variant = ButtonVariant.primary,
111
- iconPosition = 'left',
111
+ iconPosition = 'start',
112
112
  'aria-label': ariaLabel = null,
113
113
  icon = null,
114
114
  ouiaId,
@@ -183,11 +183,11 @@ const ButtonBase: React.FunctionComponent<ButtonProps> = ({
183
183
  </span>
184
184
  )}
185
185
  {variant === ButtonVariant.plain && children === null && icon ? icon : null}
186
- {variant !== ButtonVariant.plain && icon && iconPosition === 'left' && (
186
+ {variant !== ButtonVariant.plain && icon && (iconPosition === 'start' || iconPosition === 'left') && (
187
187
  <span className={css(styles.buttonIcon, styles.modifiers.start)}>{icon}</span>
188
188
  )}
189
189
  {children}
190
- {variant !== ButtonVariant.plain && icon && iconPosition === 'right' && (
190
+ {variant !== ButtonVariant.plain && icon && (iconPosition === 'end' || iconPosition === 'right') && (
191
191
  <span className={css(styles.buttonIcon, styles.modifiers.end)}>{icon}</span>
192
192
  )}
193
193
  {countOptions && (
@@ -30,7 +30,7 @@ export const ButtonVariations: React.FunctionComponent = () => (
30
30
  <Button variant="link" icon={<PlusCircleIcon />}>
31
31
  Link
32
32
  </Button>{' '}
33
- <Button variant="link" icon={<ExternalLinkSquareAltIcon />} iconPosition="right">
33
+ <Button variant="link" icon={<ExternalLinkSquareAltIcon />} iconPosition="end">
34
34
  Link
35
35
  </Button>{' '}
36
36
  <Button variant="link" isInline>
@@ -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
- <div
253
- id={id || panelId}
254
- className={css(
255
- styles.drawerPanel,
256
- isResizable && styles.modifiers.resizable,
257
- hasNoBorder && styles.modifiers.noBorder,
258
- formatBreakpointMods(widths, styles),
259
- colorVariant === DrawerColorVariant.light200 && styles.modifiers.light_200,
260
- colorVariant === DrawerColorVariant.noBackground && styles.modifiers.noBackground,
261
- className
262
- )}
263
- ref={panel}
264
- onTransitionEnd={(ev) => {
265
- if ((ev.target as HTMLElement) === panel.current) {
266
- if (!hidden && ev.nativeEvent.propertyName === 'transform') {
267
- onExpand(ev);
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
- setIsExpandedInternal(!hidden);
270
- }
271
- }}
272
- hidden={hidden}
273
- {...((defaultSize || minSize || maxSize) && {
274
- style: boundaryCssVars as React.CSSProperties
275
- })}
276
- {...props}
277
- >
278
- {isExpandedInternal && (
279
- <React.Fragment>
280
- {isResizable && (
281
- <React.Fragment>
282
- <div
283
- className={css(styles.drawerSplitter, position !== 'bottom' && styles.modifiers.vertical)}
284
- role="separator"
285
- tabIndex={0}
286
- aria-orientation={position === 'bottom' ? 'horizontal' : 'vertical'}
287
- aria-label={resizeAriaLabel}
288
- aria-valuenow={separatorValue}
289
- aria-valuemin={0}
290
- aria-valuemax={100}
291
- aria-controls={id || panelId}
292
- onMouseDown={handleMousedown}
293
- onKeyDown={handleKeys}
294
- onTouchStart={handleTouchStart}
295
- ref={splitterRef}
296
- >
297
- <div className={css(styles.drawerSplitterHandle)} aria-hidden></div>
298
- </div>
299
- <div className={css(styles.drawerPanelMain)}>{children}</div>
300
- </React.Fragment>
301
- )}
302
- {!isResizable && children}
303
- </React.Fragment>
304
- )}
305
- </div>
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
+ });