@patternfly/react-core 5.1.1-prerelease.1 → 5.1.1-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.
Files changed (136) hide show
  1. package/CHANGELOG.md +10 -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/deprecated/components/Select/Select.d.ts.map +1 -1
  120. package/dist/esm/deprecated/components/Select/Select.js +43 -42
  121. package/dist/esm/deprecated/components/Select/Select.js.map +1 -1
  122. package/dist/js/deprecated/components/Select/Select.d.ts.map +1 -1
  123. package/dist/js/deprecated/components/Select/Select.js +43 -42
  124. package/dist/js/deprecated/components/Select/Select.js.map +1 -1
  125. package/dist/styles/base-no-reset.css +20 -0
  126. package/dist/styles/base.css +20 -0
  127. package/dist/umd/react-core.min.js +1 -1
  128. package/helpers/package.json +1 -1
  129. package/layouts/package.json +1 -1
  130. package/next/package.json +1 -1
  131. package/package.json +6 -6
  132. package/src/demos/NotificationDrawer/NotificationDrawer.md +2 -1435
  133. package/src/demos/NotificationDrawer/examples/NotificationDrawerBasic.tsx +557 -0
  134. package/src/demos/NotificationDrawer/examples/NotificationDrawerGrouped.tsx +796 -0
  135. package/src/deprecated/components/Select/Select.tsx +47 -45
  136. package/src/deprecated/components/Select/__tests__/__snapshots__/Select.test.tsx.snap +9 -5
@@ -0,0 +1,796 @@
1
+ import React from 'react';
2
+ import {
3
+ Avatar,
4
+ Brand,
5
+ Breadcrumb,
6
+ BreadcrumbItem,
7
+ Button,
8
+ ButtonVariant,
9
+ Divider,
10
+ Dropdown,
11
+ DropdownItem,
12
+ DropdownList,
13
+ EmptyState,
14
+ EmptyStateActions,
15
+ EmptyStateBody,
16
+ EmptyStateIcon,
17
+ EmptyStateHeader,
18
+ EmptyStateFooter,
19
+ EmptyStateVariant,
20
+ MenuToggle,
21
+ Nav,
22
+ NavItem,
23
+ NavList,
24
+ NotificationBadge,
25
+ NotificationDrawer,
26
+ NotificationDrawerBody,
27
+ NotificationDrawerGroup,
28
+ NotificationDrawerGroupList,
29
+ NotificationDrawerHeader,
30
+ NotificationDrawerList,
31
+ NotificationDrawerListItem,
32
+ NotificationDrawerListItemBody,
33
+ NotificationDrawerListItemHeader,
34
+ Page,
35
+ PageSection,
36
+ PageSectionVariants,
37
+ PageSidebar,
38
+ PageSidebarBody,
39
+ SkipToContent,
40
+ TextContent,
41
+ Text,
42
+ PageToggleButton,
43
+ Masthead,
44
+ MastheadMain,
45
+ MastheadToggle,
46
+ MastheadContent,
47
+ MastheadBrand,
48
+ Toolbar,
49
+ ToolbarItem,
50
+ ToolbarGroup,
51
+ ToolbarContent
52
+ } from '@patternfly/react-core';
53
+ import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
54
+ import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
55
+ import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';
56
+ import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon';
57
+ import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
58
+ import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon';
59
+ import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
60
+ import imgAvatar from '@patternfly/react-core/src/components/assets/avatarImg.svg';
61
+ import pfLogo from '@patternfly/react-core/src/demos/assets/pf-logo.svg';
62
+
63
+ export const NotificationDrawerGrouped: React.FunctionComponent = () => {
64
+ const drawerRef = React.useRef<HTMLElement | null>(null);
65
+
66
+ const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);
67
+ const [isKebabDropdownOpen, setIsKebabDropdownOpen] = React.useState(false);
68
+ const [isDrawerExpanded, setIsDrawerExpanded] = React.useState(false);
69
+ const [firstDrawerGroupExpanded, setFirstDrawerGroupExpanded] = React.useState(false);
70
+ const [secondDrawerGroupExpanded, setSecondDrawerGroupExpanded] = React.useState(true);
71
+ const [thirdDrawerGroupExpanded, setThirdDrawerGroupExpanded] = React.useState(false);
72
+
73
+ interface UnreadMap {
74
+ [groupName: string]: {
75
+ [notificationId: string]: boolean;
76
+ } | null;
77
+ }
78
+
79
+ const [activeItem, setActiveItem] = React.useState<number | string>(0);
80
+ const [isUnreadMap, setIsUnreadMap] = React.useState<UnreadMap | null>({
81
+ 'group-1': {
82
+ 'notification-5': true,
83
+ 'notification-6': true
84
+ },
85
+ 'group-2': {
86
+ 'notification-9': true,
87
+ 'notification-10': true
88
+ },
89
+ 'group-3': null
90
+ });
91
+
92
+ const [shouldShowNotifications, setShouldShowNotifications] = React.useState(true);
93
+
94
+ interface ActionsMenu {
95
+ [toggleId: string]: boolean;
96
+ }
97
+
98
+ const [isActionsMenuOpen, setIsActionsMenuOpen] = React.useState<ActionsMenu | {}>({});
99
+
100
+ const onNavSelect = (
101
+ _event: React.FormEvent<HTMLInputElement>,
102
+ selectedItem: {
103
+ groupId: number | string;
104
+ itemId: number | string;
105
+ to: string;
106
+ }
107
+ ) => setActiveItem(selectedItem.itemId);
108
+
109
+ const onDropdownToggle = () => setIsDropdownOpen((prevState) => !prevState);
110
+ const onDropdownSelect = () => setIsDropdownOpen(false);
111
+ const onKebabDropdownToggle = () => setIsKebabDropdownOpen((prevState) => !prevState);
112
+ const onKebabDropdownSelect = () => setIsKebabDropdownOpen(false);
113
+ const onCloseNotificationDrawer = (_event: any) => setIsDrawerExpanded((prevState) => !prevState);
114
+
115
+ const onToggle = (id: string) => {
116
+ setIsActionsMenuOpen({ [id]: !isActionsMenuOpen[id] });
117
+ };
118
+
119
+ const closeActionsMenu = () => setIsActionsMenuOpen({});
120
+
121
+ const onListItemClick = (groupId: string, id: string) => {
122
+ if (isUnreadMap === null) {
123
+ return;
124
+ }
125
+ if (!isUnreadMap[groupId]) {
126
+ setIsUnreadMap({ ...isUnreadMap, [groupId]: { [id]: false } });
127
+ } else {
128
+ setIsUnreadMap({ ...isUnreadMap, [groupId]: { ...isUnreadMap[groupId], [id]: false } });
129
+ }
130
+ };
131
+
132
+ const isUnread = (groupId: string, id: string) =>
133
+ isUnreadMap && isUnreadMap[groupId] !== null && isUnreadMap[groupId][id];
134
+
135
+ const getNumberUnread = (groupId: string | null) => {
136
+ if (!isUnreadMap) {
137
+ return 0;
138
+ }
139
+
140
+ if (groupId) {
141
+ const group = isUnreadMap[groupId];
142
+ if (!group) {
143
+ return 0;
144
+ }
145
+ return Object.values(group).reduce((count, value) => (value ? count + 1 : count), 0);
146
+ }
147
+
148
+ return Object.keys(isUnreadMap).reduce((count, groupId) => {
149
+ const group = isUnreadMap[groupId];
150
+ if (!group) {
151
+ return count;
152
+ }
153
+
154
+ return Object.values(group).reduce((groupCount, value) => (value ? groupCount + 1 : groupCount), count);
155
+ }, 0);
156
+ };
157
+
158
+ const markAllRead = () => setIsUnreadMap(null);
159
+
160
+ const showNotifications = (showNotifications: boolean) => {
161
+ setIsUnreadMap(null);
162
+ setShouldShowNotifications(showNotifications);
163
+ };
164
+
165
+ const toggleFirstDrawer = (_event: any, value: boolean | ((prevState: boolean) => boolean)) => {
166
+ setFirstDrawerGroupExpanded(value);
167
+ };
168
+
169
+ const toggleSecondDrawer = (_event: any, value: boolean | ((prevState: boolean) => boolean)) => {
170
+ setSecondDrawerGroupExpanded(value);
171
+ };
172
+
173
+ const toggleThirdDrawer = (_event: any, value: boolean | ((prevState: boolean) => boolean)) => {
174
+ setThirdDrawerGroupExpanded(value);
175
+ };
176
+
177
+ const focusDrawer = (_event: any) => {
178
+ if (drawerRef.current === null) {
179
+ return;
180
+ }
181
+ // Prevent the NotificationDrawer from receiving focus if a drawer group item is opened
182
+ if (!document.activeElement?.closest(`.${drawerRef.current.className}`)) {
183
+ const firstTabbableItem = drawerRef.current.querySelector('a, button') as
184
+ | HTMLAnchorElement
185
+ | HTMLButtonElement
186
+ | null;
187
+ firstTabbableItem?.focus();
188
+ }
189
+ };
190
+
191
+ const PageNav = (
192
+ <Nav onSelect={onNavSelect} aria-label="Nav">
193
+ <NavList>
194
+ <NavItem itemId={0} isActive={activeItem === 0}>
195
+ System Panel
196
+ </NavItem>
197
+ <NavItem itemId={1} isActive={activeItem === 1}>
198
+ Policy
199
+ </NavItem>
200
+ <NavItem itemId={2} isActive={activeItem === 2}>
201
+ Authentication
202
+ </NavItem>
203
+ <NavItem itemId={3} isActive={activeItem === 3}>
204
+ Network Services
205
+ </NavItem>
206
+ <NavItem itemId={4} isActive={activeItem === 4}>
207
+ Server
208
+ </NavItem>
209
+ </NavList>
210
+ </Nav>
211
+ );
212
+ const kebabDropdownItems = (
213
+ <>
214
+ <DropdownItem>
215
+ <CogIcon /> Settings
216
+ </DropdownItem>
217
+ <DropdownItem>
218
+ <HelpIcon /> Help
219
+ </DropdownItem>
220
+ </>
221
+ );
222
+ const userDropdownItems = (
223
+ <>
224
+ <DropdownItem key="group 2 profile">My profile</DropdownItem>
225
+ <DropdownItem key="group 2 user">User management</DropdownItem>
226
+ <DropdownItem key="group 2 logout">Logout</DropdownItem>
227
+ </>
228
+ );
229
+ const headerToolbar = (
230
+ <Toolbar isFullHeight>
231
+ <ToolbarContent>
232
+ <ToolbarGroup spaceItems={{ default: 'spaceItemsNone' }} align={{ default: 'alignRight' }}>
233
+ <ToolbarGroup variant="icon-button-group">
234
+ <ToolbarItem visibility={{ default: 'visible' }} selected={isDrawerExpanded}>
235
+ <NotificationBadge
236
+ variant={getNumberUnread(null) === 0 ? 'read' : 'unread'}
237
+ onClick={(event: any) => onCloseNotificationDrawer(event)}
238
+ aria-label="Notifications"
239
+ isExpanded={isDrawerExpanded}
240
+ >
241
+ <BellIcon />
242
+ </NotificationBadge>
243
+ </ToolbarItem>
244
+ <ToolbarGroup
245
+ variant="icon-button-group"
246
+ visibility={{
247
+ default: 'hidden',
248
+ lg: 'visible'
249
+ }} /** the settings and help icon buttons are only visible on desktop sizes and replaced by a kebab dropdown for other sizes */
250
+ >
251
+ <ToolbarItem>
252
+ <Button aria-label="Settings actions" variant={ButtonVariant.plain}>
253
+ <CogIcon />
254
+ </Button>
255
+ </ToolbarItem>
256
+ <ToolbarItem>
257
+ <Button aria-label="Help actions" variant={ButtonVariant.plain}>
258
+ <QuestionCircleIcon />
259
+ </Button>
260
+ </ToolbarItem>
261
+ </ToolbarGroup>
262
+ </ToolbarGroup>
263
+ <ToolbarGroup>
264
+ <ToolbarItem
265
+ visibility={{
266
+ lg: 'hidden'
267
+ }} /** this kebab dropdown replaces the icon buttons and is hidden for desktop sizes */
268
+ >
269
+ <Dropdown
270
+ isOpen={isKebabDropdownOpen}
271
+ onSelect={onKebabDropdownSelect}
272
+ onOpenChange={setIsKebabDropdownOpen}
273
+ popperProps={{ position: 'right' }}
274
+ toggle={(toggleRef: React.RefObject<any>) => (
275
+ <MenuToggle
276
+ ref={toggleRef}
277
+ isExpanded={isKebabDropdownOpen}
278
+ onClick={onKebabDropdownToggle}
279
+ variant="plain"
280
+ aria-label="Settings and help"
281
+ >
282
+ <EllipsisVIcon aria-hidden="true" />
283
+ </MenuToggle>
284
+ )}
285
+ >
286
+ <DropdownList>{kebabDropdownItems}</DropdownList>
287
+ </Dropdown>
288
+ </ToolbarItem>
289
+ <ToolbarItem
290
+ visibility={{ default: 'hidden', md: 'visible' }} /** this user dropdown is hidden on mobile sizes */
291
+ >
292
+ <Dropdown
293
+ isOpen={isDropdownOpen}
294
+ onSelect={onDropdownSelect}
295
+ onOpenChange={setIsDropdownOpen}
296
+ popperProps={{ position: 'right' }}
297
+ toggle={(toggleRef: React.RefObject<any>) => (
298
+ <MenuToggle
299
+ ref={toggleRef}
300
+ isExpanded={isDropdownOpen}
301
+ onClick={onDropdownToggle}
302
+ icon={<Avatar src={imgAvatar} alt="" />}
303
+ isFullHeight
304
+ >
305
+ John Smith
306
+ </MenuToggle>
307
+ )}
308
+ >
309
+ <DropdownList>{userDropdownItems}</DropdownList>
310
+ </Dropdown>
311
+ </ToolbarItem>
312
+ </ToolbarGroup>
313
+ </ToolbarGroup>
314
+ </ToolbarContent>
315
+ </Toolbar>
316
+ );
317
+
318
+ const Header = (
319
+ <Masthead>
320
+ <MastheadToggle>
321
+ <PageToggleButton variant="plain" aria-label="Global navigation">
322
+ <BarsIcon />
323
+ </PageToggleButton>
324
+ </MastheadToggle>
325
+ <MastheadMain>
326
+ <MastheadBrand>
327
+ <Brand src={pfLogo} alt="PatternFly" heights={{ default: '36px' }} />
328
+ </MastheadBrand>
329
+ </MastheadMain>
330
+ <MastheadContent>{headerToolbar}</MastheadContent>
331
+ </Masthead>
332
+ );
333
+ const Sidebar = (
334
+ <PageSidebar>
335
+ <PageSidebarBody>{PageNav}</PageSidebarBody>
336
+ </PageSidebar>
337
+ );
338
+ const pageId = 'main-content-page-layout-default-nav';
339
+ const PageSkipToContent = <SkipToContent href={`#${pageId}`}>Skip to content</SkipToContent>;
340
+
341
+ const PageBreadcrumb = (
342
+ <Breadcrumb>
343
+ <BreadcrumbItem>Section home</BreadcrumbItem>
344
+ <BreadcrumbItem to="#">Section title</BreadcrumbItem>
345
+ <BreadcrumbItem to="#">Section title</BreadcrumbItem>
346
+ <BreadcrumbItem to="#" isActive>
347
+ Section landing
348
+ </BreadcrumbItem>
349
+ </Breadcrumb>
350
+ );
351
+
352
+ const notificationDrawerActions = (
353
+ <>
354
+ <DropdownItem key="markAllRead" onClick={markAllRead}>
355
+ Mark all read
356
+ </DropdownItem>
357
+ <DropdownItem key="clearAll" onClick={() => showNotifications(false)}>
358
+ Clear all
359
+ </DropdownItem>
360
+ <DropdownItem key="unclearLast" onClick={() => showNotifications(true)}>
361
+ Unclear last
362
+ </DropdownItem>
363
+ <DropdownItem key="settings">Settings</DropdownItem>
364
+ </>
365
+ );
366
+ const notificationDrawerDropdownItems = (
367
+ <>
368
+ <DropdownItem
369
+ key="link"
370
+ to="#"
371
+ // Prevent default onClick behavior for demo purposes
372
+ onClick={(ev: any) => ev.preventDefault()}
373
+ >
374
+ Link
375
+ </DropdownItem>
376
+ <DropdownItem key="action">Action</DropdownItem>
377
+ <Divider component="li" key="separator" />
378
+ <DropdownItem key="disabled link" isDisabled>
379
+ Disabled Link
380
+ </DropdownItem>
381
+ </>
382
+ );
383
+
384
+ const notificationDrawer = (
385
+ <NotificationDrawer ref={drawerRef}>
386
+ <NotificationDrawerHeader count={getNumberUnread(null)} onClose={onCloseNotificationDrawer}>
387
+ <Dropdown
388
+ onSelect={closeActionsMenu}
389
+ isOpen={isActionsMenuOpen['toggle-id-0'] || false}
390
+ id="notification-0"
391
+ onOpenChange={(isOpen: boolean) => !isOpen && closeActionsMenu()}
392
+ popperProps={{ position: 'right' }}
393
+ toggle={(toggleRef: React.RefObject<any>) => (
394
+ <MenuToggle
395
+ ref={toggleRef}
396
+ id="toggle-id-0"
397
+ aria-label="Notification drawer actions"
398
+ variant="plain"
399
+ onClick={() => onToggle('toggle-id-0')}
400
+ isExpanded={isActionsMenuOpen['toggle-id-0'] || false}
401
+ >
402
+ <EllipsisVIcon aria-hidden="true" />
403
+ </MenuToggle>
404
+ )}
405
+ >
406
+ <DropdownList>{notificationDrawerActions}</DropdownList>
407
+ </Dropdown>
408
+ </NotificationDrawerHeader>
409
+ <NotificationDrawerBody>
410
+ {shouldShowNotifications && (
411
+ <NotificationDrawerGroupList>
412
+ <NotificationDrawerGroup
413
+ title="First notification group"
414
+ isExpanded={firstDrawerGroupExpanded}
415
+ count={getNumberUnread('group-1')}
416
+ onExpand={toggleFirstDrawer}
417
+ >
418
+ <NotificationDrawerList isHidden={!firstDrawerGroupExpanded}>
419
+ <NotificationDrawerListItem
420
+ variant="info"
421
+ onClick={() => onListItemClick('group-1', 'notification-5')}
422
+ isRead={!isUnread('group-1', 'notification-5')}
423
+ >
424
+ <NotificationDrawerListItemHeader
425
+ variant="info"
426
+ title="Unread info notification title"
427
+ srTitle="Info notification:"
428
+ >
429
+ <Dropdown
430
+ onSelect={closeActionsMenu}
431
+ isOpen={isActionsMenuOpen['toggle-id-5'] || false}
432
+ id="notification-5"
433
+ onOpenChange={(isOpen: boolean) => !isOpen && closeActionsMenu()}
434
+ popperProps={{ position: 'right' }}
435
+ toggle={(toggleRef: React.RefObject<any>) => (
436
+ <MenuToggle
437
+ ref={toggleRef}
438
+ id="toggle-id-5"
439
+ aria-label="Notification drawer actions"
440
+ variant="plain"
441
+ onClick={() => onToggle('toggle-id-5')}
442
+ isExpanded={isActionsMenuOpen['toggle-id-5'] || false}
443
+ >
444
+ <EllipsisVIcon aria-hidden="true" />
445
+ </MenuToggle>
446
+ )}
447
+ >
448
+ <DropdownList>{notificationDrawerDropdownItems}</DropdownList>
449
+ </Dropdown>
450
+ </NotificationDrawerListItemHeader>
451
+ <NotificationDrawerListItemBody timestamp="5 minutes ago">
452
+ This is an info notification description.
453
+ </NotificationDrawerListItemBody>
454
+ </NotificationDrawerListItem>
455
+ <NotificationDrawerListItem
456
+ variant="danger"
457
+ onClick={() => onListItemClick('group-1', 'notification-6')}
458
+ isRead={!isUnread('group-1', 'notification-6')}
459
+ >
460
+ <NotificationDrawerListItemHeader
461
+ variant="danger"
462
+ title="Unread danger notification title. This is a long title to show how the title will wrap if it is long and wraps to multiple lines."
463
+ srTitle="Danger notification:"
464
+ >
465
+ <Dropdown
466
+ onSelect={closeActionsMenu}
467
+ isOpen={isActionsMenuOpen['toggle-id-6'] || false}
468
+ id="notification-6"
469
+ onOpenChange={(isOpen: boolean) => !isOpen && closeActionsMenu()}
470
+ popperProps={{ position: 'right' }}
471
+ toggle={(toggleRef: React.RefObject<any>) => (
472
+ <MenuToggle
473
+ ref={toggleRef}
474
+ id="toggle-id-6"
475
+ aria-label="Notification drawer actions"
476
+ variant="plain"
477
+ onClick={() => onToggle('toggle-id-6')}
478
+ isExpanded={isActionsMenuOpen['toggle-id-6'] || false}
479
+ >
480
+ <EllipsisVIcon aria-hidden="true" />
481
+ </MenuToggle>
482
+ )}
483
+ >
484
+ <DropdownList>{notificationDrawerDropdownItems}</DropdownList>
485
+ </Dropdown>
486
+ </NotificationDrawerListItemHeader>
487
+ <NotificationDrawerListItemBody timestamp="10 minutes ago">
488
+ This is a danger notification description. This is a long description to show how the title will
489
+ wrap if it is long and wraps to multiple lines.
490
+ </NotificationDrawerListItemBody>
491
+ </NotificationDrawerListItem>
492
+ <NotificationDrawerListItem
493
+ variant="warning"
494
+ onClick={() => onListItemClick('group-1', 'notification-7')}
495
+ isRead={!isUnread('group-1', 'notification-7')}
496
+ >
497
+ <NotificationDrawerListItemHeader
498
+ variant="warning"
499
+ title="Read warning notification title"
500
+ srTitle="Warning notification:"
501
+ >
502
+ <Dropdown
503
+ onSelect={closeActionsMenu}
504
+ isOpen={isActionsMenuOpen['toggle-id-7'] || false}
505
+ id="notification-7"
506
+ onOpenChange={(isOpen: boolean) => !isOpen && closeActionsMenu()}
507
+ popperProps={{ position: 'right' }}
508
+ toggle={(toggleRef: React.RefObject<any>) => (
509
+ <MenuToggle
510
+ ref={toggleRef}
511
+ id="toggle-id-7"
512
+ aria-label="Notification drawer actions"
513
+ variant="plain"
514
+ onClick={() => onToggle('toggle-id-7')}
515
+ isExpanded={isActionsMenuOpen['toggle-id-7'] || false}
516
+ >
517
+ <EllipsisVIcon aria-hidden="true" />
518
+ </MenuToggle>
519
+ )}
520
+ >
521
+ <DropdownList>{notificationDrawerDropdownItems}</DropdownList>
522
+ </Dropdown>
523
+ </NotificationDrawerListItemHeader>
524
+ <NotificationDrawerListItemBody timestamp="20 minutes ago">
525
+ This is a warning notification description.
526
+ </NotificationDrawerListItemBody>
527
+ </NotificationDrawerListItem>
528
+ <NotificationDrawerListItem
529
+ variant="success"
530
+ onClick={() => onListItemClick('group-1', 'notification-8')}
531
+ isRead={!isUnread('group-1', 'notification-8')}
532
+ >
533
+ <NotificationDrawerListItemHeader
534
+ variant="success"
535
+ title="Read success notification title"
536
+ srTitle="Success notification:"
537
+ >
538
+ <Dropdown
539
+ onSelect={closeActionsMenu}
540
+ isOpen={isActionsMenuOpen['toggle-id-8'] || false}
541
+ id="notification-8"
542
+ onOpenChange={(isOpen: boolean) => !isOpen && closeActionsMenu()}
543
+ popperProps={{ position: 'right' }}
544
+ toggle={(toggleRef: React.RefObject<any>) => (
545
+ <MenuToggle
546
+ ref={toggleRef}
547
+ id="toggle-id-8"
548
+ aria-label="Notification drawer actions"
549
+ variant="plain"
550
+ onClick={() => onToggle('toggle-id-8')}
551
+ isExpanded={isActionsMenuOpen['toggle-id-8'] || false}
552
+ >
553
+ <EllipsisVIcon aria-hidden="true" />
554
+ </MenuToggle>
555
+ )}
556
+ >
557
+ <DropdownList>{notificationDrawerDropdownItems}</DropdownList>
558
+ </Dropdown>
559
+ </NotificationDrawerListItemHeader>
560
+ <NotificationDrawerListItemBody timestamp="30 minutes ago">
561
+ This is a success notification description.
562
+ </NotificationDrawerListItemBody>
563
+ </NotificationDrawerListItem>
564
+ </NotificationDrawerList>
565
+ </NotificationDrawerGroup>
566
+ <NotificationDrawerGroup
567
+ title="Second notification group"
568
+ isExpanded={secondDrawerGroupExpanded}
569
+ count={getNumberUnread('group-2')}
570
+ onExpand={toggleSecondDrawer}
571
+ >
572
+ <NotificationDrawerList isHidden={!secondDrawerGroupExpanded}>
573
+ <NotificationDrawerListItem
574
+ variant="info"
575
+ onClick={() => onListItemClick('group-2', 'notification-9')}
576
+ isRead={!isUnread('group-2', 'notification-9')}
577
+ >
578
+ <NotificationDrawerListItemHeader
579
+ variant="info"
580
+ title="Unread info notification title"
581
+ srTitle="Info notification:"
582
+ >
583
+ <Dropdown
584
+ onSelect={closeActionsMenu}
585
+ isOpen={isActionsMenuOpen['toggle-id-9'] || false}
586
+ id="notification-9"
587
+ onOpenChange={(isOpen: boolean) => !isOpen && closeActionsMenu()}
588
+ popperProps={{ position: 'right' }}
589
+ toggle={(toggleRef: React.RefObject<any>) => (
590
+ <MenuToggle
591
+ ref={toggleRef}
592
+ id="toggle-id-9"
593
+ aria-label="Notification drawer actions"
594
+ variant="plain"
595
+ onClick={() => onToggle('toggle-id-9')}
596
+ isExpanded={isActionsMenuOpen['toggle-id-9'] || false}
597
+ >
598
+ <EllipsisVIcon aria-hidden="true" />
599
+ </MenuToggle>
600
+ )}
601
+ >
602
+ <DropdownList>{notificationDrawerDropdownItems}</DropdownList>
603
+ </Dropdown>
604
+ </NotificationDrawerListItemHeader>
605
+ <NotificationDrawerListItemBody timestamp="5 minutes ago">
606
+ This is an info notification description.
607
+ </NotificationDrawerListItemBody>
608
+ </NotificationDrawerListItem>
609
+ <NotificationDrawerListItem
610
+ variant="danger"
611
+ onClick={() => onListItemClick('group-2', 'notification-10')}
612
+ isRead={!isUnread('group-2', 'notification-10')}
613
+ >
614
+ <NotificationDrawerListItemHeader
615
+ variant="danger"
616
+ title="Unread danger notification title. This is a long title to show how the title will wrap if it is long and wraps to multiple lines."
617
+ srTitle="Danger notification:"
618
+ >
619
+ <Dropdown
620
+ onSelect={closeActionsMenu}
621
+ isOpen={isActionsMenuOpen['toggle-id-10'] || false}
622
+ id="notification-10"
623
+ onOpenChange={(isOpen: boolean) => !isOpen && closeActionsMenu()}
624
+ popperProps={{ position: 'right' }}
625
+ toggle={(toggleRef: React.RefObject<any>) => (
626
+ <MenuToggle
627
+ ref={toggleRef}
628
+ id="toggle-id-10"
629
+ aria-label="Notification drawer actions"
630
+ variant="plain"
631
+ onClick={() => onToggle('toggle-id-10')}
632
+ isExpanded={isActionsMenuOpen['toggle-id-10'] || false}
633
+ >
634
+ <EllipsisVIcon aria-hidden="true" />
635
+ </MenuToggle>
636
+ )}
637
+ >
638
+ <DropdownList>{notificationDrawerDropdownItems}</DropdownList>
639
+ </Dropdown>
640
+ </NotificationDrawerListItemHeader>
641
+ <NotificationDrawerListItemBody timestamp="10 minutes ago">
642
+ This is a danger notification description. This is a long description to show how the title will
643
+ wrap if it is long and wraps to multiple lines.
644
+ </NotificationDrawerListItemBody>
645
+ </NotificationDrawerListItem>
646
+ <NotificationDrawerListItem
647
+ variant="warning"
648
+ onClick={() => onListItemClick('group-2', 'notification-11')}
649
+ isRead={!isUnread('group-2', 'notification-11')}
650
+ >
651
+ <NotificationDrawerListItemHeader
652
+ variant="warning"
653
+ title="Read warning notification title"
654
+ srTitle="Warning notification:"
655
+ >
656
+ <Dropdown
657
+ onSelect={closeActionsMenu}
658
+ isOpen={isActionsMenuOpen['toggle-id-11'] || false}
659
+ id="notification-11"
660
+ onOpenChange={(isOpen: boolean) => !isOpen && closeActionsMenu()}
661
+ popperProps={{ position: 'right' }}
662
+ toggle={(toggleRef: React.RefObject<any>) => (
663
+ <MenuToggle
664
+ ref={toggleRef}
665
+ id="toggle-id-11"
666
+ aria-label="Notification drawer actions"
667
+ variant="plain"
668
+ onClick={() => onToggle('toggle-id-11')}
669
+ isExpanded={isActionsMenuOpen['toggle-id-11'] || false}
670
+ >
671
+ <EllipsisVIcon aria-hidden="true" />
672
+ </MenuToggle>
673
+ )}
674
+ >
675
+ <DropdownList>{notificationDrawerDropdownItems}</DropdownList>
676
+ </Dropdown>
677
+ </NotificationDrawerListItemHeader>
678
+ <NotificationDrawerListItemBody timestamp="20 minutes ago">
679
+ This is a warning notification description.
680
+ </NotificationDrawerListItemBody>
681
+ </NotificationDrawerListItem>
682
+ <NotificationDrawerListItem
683
+ variant="success"
684
+ onClick={() => onListItemClick('group-2', 'notification-12')}
685
+ isRead={!isUnread('group-2', 'notification-12')}
686
+ >
687
+ <NotificationDrawerListItemHeader
688
+ variant="success"
689
+ title="Read success notification title"
690
+ srTitle="Success notification:"
691
+ >
692
+ <Dropdown
693
+ onSelect={closeActionsMenu}
694
+ isOpen={isActionsMenuOpen['toggle-id-12'] || false}
695
+ id="notification-12"
696
+ onOpenChange={(isOpen: boolean) => !isOpen && closeActionsMenu()}
697
+ popperProps={{ position: 'right' }}
698
+ toggle={(toggleRef: React.RefObject<any>) => (
699
+ <MenuToggle
700
+ ref={toggleRef}
701
+ id="toggle-id-12"
702
+ aria-label="Notification drawer actions"
703
+ variant="plain"
704
+ onClick={() => onToggle('toggle-id-12')}
705
+ isExpanded={isActionsMenuOpen['toggle-id-12'] || false}
706
+ >
707
+ <EllipsisVIcon aria-hidden="true" />
708
+ </MenuToggle>
709
+ )}
710
+ >
711
+ <DropdownList>{notificationDrawerDropdownItems}</DropdownList>
712
+ </Dropdown>
713
+ </NotificationDrawerListItemHeader>
714
+ <NotificationDrawerListItemBody timestamp="30 minutes ago">
715
+ This is a success notification description.
716
+ </NotificationDrawerListItemBody>
717
+ </NotificationDrawerListItem>
718
+ </NotificationDrawerList>
719
+ </NotificationDrawerGroup>
720
+ <NotificationDrawerGroup
721
+ title="Third notification group"
722
+ isExpanded={thirdDrawerGroupExpanded}
723
+ count={getNumberUnread('group-3')}
724
+ onExpand={toggleThirdDrawer}
725
+ >
726
+ <NotificationDrawerList isHidden={!thirdDrawerGroupExpanded}>
727
+ <EmptyState variant={EmptyStateVariant.full}>
728
+ <EmptyStateHeader
729
+ headingLevel="h2"
730
+ titleText="No alerts found"
731
+ icon={<EmptyStateIcon icon={SearchIcon} />}
732
+ />
733
+ <EmptyStateBody>
734
+ There are currently no critical alerts firing. There may be firing alerts of other severities or
735
+ silenced critical alerts however.
736
+ </EmptyStateBody>
737
+ <EmptyStateFooter>
738
+ <EmptyStateActions>
739
+ <Button variant="link">Action</Button>
740
+ </EmptyStateActions>
741
+ </EmptyStateFooter>
742
+ </EmptyState>
743
+ </NotificationDrawerList>
744
+ </NotificationDrawerGroup>
745
+ </NotificationDrawerGroupList>
746
+ )}
747
+ {!shouldShowNotifications && (
748
+ <EmptyState variant={EmptyStateVariant.full}>
749
+ <EmptyStateHeader
750
+ headingLevel="h2"
751
+ titleText="No alerts found"
752
+ icon={<EmptyStateIcon icon={SearchIcon} />}
753
+ />
754
+ <EmptyStateBody>
755
+ There are currently no alerts. There may be silenced critical alerts however.
756
+ </EmptyStateBody>
757
+ <EmptyStateFooter>
758
+ <EmptyStateActions>
759
+ <Button variant="link">Action</Button>
760
+ </EmptyStateActions>
761
+ </EmptyStateFooter>
762
+ </EmptyState>
763
+ )}
764
+ </NotificationDrawerBody>
765
+ </NotificationDrawer>
766
+ );
767
+
768
+ return (
769
+ <React.Fragment>
770
+ <Page
771
+ header={Header}
772
+ sidebar={Sidebar}
773
+ isManagedSidebar
774
+ notificationDrawer={notificationDrawer}
775
+ isNotificationDrawerExpanded={isDrawerExpanded}
776
+ onNotificationDrawerExpand={(
777
+ event: React.MouseEvent<Element, MouseEvent> | KeyboardEvent | React.TransitionEvent<Element>
778
+ ) => focusDrawer(event)}
779
+ skipToContent={PageSkipToContent}
780
+ breadcrumb={PageBreadcrumb}
781
+ mainContainerId={pageId}
782
+ >
783
+ <PageSection variant={PageSectionVariants.light}>
784
+ <TextContent>
785
+ <Text component="h1">Main title</Text>
786
+ <Text component="p">
787
+ Body text should be Overpass Regular at 16px. It should have leading of 24px because <br />
788
+ of its relative line height of 1.5.
789
+ </Text>
790
+ </TextContent>
791
+ </PageSection>
792
+ <PageSection variant={PageSectionVariants.light}>Panel section content</PageSection>
793
+ </Page>
794
+ </React.Fragment>
795
+ );
796
+ };