@patternfly/react-core 4.247.0 → 4.247.1
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 +8 -0
- package/dist/umd/react-core.min.css +2199 -2199
- package/package.json +2 -2
- package/src/demos/Page.md +47 -0
- package/src/demos/examples/DashboardWrapper.js +3 -1
- package/src/demos/examples/Page/PageStickySectionBreadcrumb.tsx +305 -0
- package/src/demos/examples/Page/PageStickySectionGroup.tsx +306 -0
- package/src/demos/examples/Page/PageStickySectionGroupAlternate.tsx +301 -0
- package/src/demos/examples/Page/PageStickySectionGroupUsingPageHeader.tsx +293 -0
- package/src/demos/Page/Page.md +0 -1184
- package/src/demos/Page/imgAvatar.svg +0 -33
- package/src/demos/Page/imgBrand.svg +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-core",
|
|
3
|
-
"version": "4.247.
|
|
3
|
+
"version": "4.247.1",
|
|
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",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"react": "^16.8 || ^17 || ^18",
|
|
71
71
|
"react-dom": "^16.8 || ^17 || ^18"
|
|
72
72
|
},
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "22fc7d8e8189ef2da0eb483a8c35c4c0e2be3807"
|
|
74
74
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: Page
|
|
3
|
+
section: components
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
|
|
7
|
+
import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
|
|
8
|
+
import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon';
|
|
9
|
+
import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon';
|
|
10
|
+
import imgBrand from '@patternfly/react-core/src/demos/examples/pfColorLogo.svg';
|
|
11
|
+
import imgAvatar from '@patternfly/react-core/src/components/Avatar/examples/avatarImg.svg';
|
|
12
|
+
import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';
|
|
13
|
+
import AttentionBellIcon from '@patternfly/react-icons/dist/esm/icons/attention-bell-icon';
|
|
14
|
+
import LightbulbIcon from '@patternfly/react-icons/dist/esm/icons/lightbulb-icon';
|
|
15
|
+
|
|
16
|
+
- All examples set the `isManagedSidebar` prop on the Page component to have the sidebar automatically close for smaller screen widths. You can also manually control this behavior by not adding the `isManagedSidebar` prop and instead:
|
|
17
|
+
|
|
18
|
+
1. Add an onNavToggle callback to PageHeader
|
|
19
|
+
2. Pass a boolean into the isNavOpen prop to PageSidebar
|
|
20
|
+
|
|
21
|
+
- To make the page take up the full height, it is recommended to set the height of all ancestor elements up to the page component to `100%`
|
|
22
|
+
|
|
23
|
+
## Layouts
|
|
24
|
+
|
|
25
|
+
This demonstrates a variety of navigation patterns in the context of a full page layout. These can be used as a basis for choosing the most appropriate page template for your application.
|
|
26
|
+
|
|
27
|
+
### Sticky section group
|
|
28
|
+
|
|
29
|
+
```ts file='./examples/Page/PageStickySectionGroup.tsx' isFullscreen
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Sticky section group (alternate syntax)
|
|
33
|
+
|
|
34
|
+
```ts file='./examples/Page/PageStickySectionGroupAlternate.tsx' isFullscreen
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Sticky section group (using PageHeader)
|
|
38
|
+
|
|
39
|
+
This demo is provided becuase PageHeader and PageHeaderTools are still in use; however, going forward Masthead and Toolbar should be used to make headers rather than PageHeader and PageHeaderTools.
|
|
40
|
+
|
|
41
|
+
```ts file='./examples/Page/PageStickySectionGroupUsingPageHeader.tsx' isFullscreen
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Sticky section breadcrumb (with breakpoints)
|
|
45
|
+
|
|
46
|
+
```ts file='./examples/Page/PageStickySectionBreadcrumb.tsx' isFullscreen
|
|
47
|
+
```
|
|
@@ -60,7 +60,8 @@ export default class DashboardWrapper extends React.Component {
|
|
|
60
60
|
hasNoBreadcrumb,
|
|
61
61
|
notificationDrawer,
|
|
62
62
|
isNotificationDrawerExpanded,
|
|
63
|
-
hasPageTemplateTitle
|
|
63
|
+
hasPageTemplateTitle,
|
|
64
|
+
...pageProps
|
|
64
65
|
} = this.props;
|
|
65
66
|
|
|
66
67
|
let renderedBreadcrumb;
|
|
@@ -108,6 +109,7 @@ export default class DashboardWrapper extends React.Component {
|
|
|
108
109
|
notificationDrawer={notificationDrawer}
|
|
109
110
|
isNotificationDrawerExpanded={isNotificationDrawerExpanded}
|
|
110
111
|
onPageResize={onPageResize}
|
|
112
|
+
{...pageProps}
|
|
111
113
|
>
|
|
112
114
|
{hasPageTemplateTitle && PageTemplateTitle}
|
|
113
115
|
{children}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
ApplicationLauncher,
|
|
4
|
+
ApplicationLauncherItem,
|
|
5
|
+
Avatar,
|
|
6
|
+
Brand,
|
|
7
|
+
Breadcrumb,
|
|
8
|
+
BreadcrumbItem,
|
|
9
|
+
Button,
|
|
10
|
+
ButtonVariant,
|
|
11
|
+
Card,
|
|
12
|
+
CardBody,
|
|
13
|
+
Divider,
|
|
14
|
+
Dropdown,
|
|
15
|
+
DropdownGroup,
|
|
16
|
+
DropdownItem,
|
|
17
|
+
DropdownToggle,
|
|
18
|
+
Gallery,
|
|
19
|
+
GalleryItem,
|
|
20
|
+
KebabToggle,
|
|
21
|
+
Masthead,
|
|
22
|
+
MastheadBrand,
|
|
23
|
+
MastheadContent,
|
|
24
|
+
MastheadMain,
|
|
25
|
+
MastheadToggle,
|
|
26
|
+
Nav,
|
|
27
|
+
NavItem,
|
|
28
|
+
NavList,
|
|
29
|
+
Page,
|
|
30
|
+
PageSection,
|
|
31
|
+
PageSectionVariants,
|
|
32
|
+
PageSidebar,
|
|
33
|
+
PageToggleButton,
|
|
34
|
+
SkipToContent,
|
|
35
|
+
Text,
|
|
36
|
+
TextContent,
|
|
37
|
+
Toolbar,
|
|
38
|
+
ToolbarContent,
|
|
39
|
+
ToolbarGroup,
|
|
40
|
+
ToolbarItem
|
|
41
|
+
} from '@patternfly/react-core';
|
|
42
|
+
import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';
|
|
43
|
+
import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
|
|
44
|
+
import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
|
|
45
|
+
import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon';
|
|
46
|
+
import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon';
|
|
47
|
+
import imgAvatar from '@patternfly/react-core/src/components/Avatar/examples/avatarImg.svg';
|
|
48
|
+
|
|
49
|
+
interface NavOnSelectProps {
|
|
50
|
+
groupId: number | string;
|
|
51
|
+
itemId: number | string;
|
|
52
|
+
to: string;
|
|
53
|
+
event: React.FormEvent<HTMLInputElement>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const PageStickySectionBreadcrumb: React.FunctionComponent = () => {
|
|
57
|
+
const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);
|
|
58
|
+
const [isKebabDropdownOpen, setIsKebabDropdownOpen] = React.useState(false);
|
|
59
|
+
const [isFullKebabDropdownOpen, setIsFullKebabDropdownOpen] = React.useState(false);
|
|
60
|
+
const [isAppLauncherOpen, setIsAppLauncherOpen] = React.useState(false);
|
|
61
|
+
const [activeItem, setActiveItem] = React.useState(1);
|
|
62
|
+
|
|
63
|
+
const onNavSelect = (selectedItem: NavOnSelectProps) => {
|
|
64
|
+
typeof selectedItem.itemId === 'number' && setActiveItem(selectedItem.itemId);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const onDropdownToggle = (isOpen: boolean) => {
|
|
68
|
+
setIsDropdownOpen(isOpen);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const onDropdownSelect = () => {
|
|
72
|
+
setIsDropdownOpen(!isDropdownOpen);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const onKebabDropdownToggle = (isOpen: boolean) => {
|
|
76
|
+
setIsKebabDropdownOpen(isOpen);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const onKebabDropdownSelect = () => {
|
|
80
|
+
setIsKebabDropdownOpen(!isKebabDropdownOpen);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const onFullKebabDropdownToggle = (isOpen: boolean) => {
|
|
84
|
+
setIsFullKebabDropdownOpen(isOpen);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const onFullKebabDropdownSelect = () => {
|
|
88
|
+
setIsFullKebabDropdownOpen(!isFullKebabDropdownOpen);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const onAppLauncherToggle = (isOpen: boolean) => {
|
|
92
|
+
setIsAppLauncherOpen(isOpen);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const onAppLauncherSelect = () => {
|
|
96
|
+
setIsAppLauncherOpen(!isAppLauncherOpen);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const dashboardBreadcrumb = (
|
|
100
|
+
<Breadcrumb>
|
|
101
|
+
<BreadcrumbItem>Section home</BreadcrumbItem>
|
|
102
|
+
<BreadcrumbItem to="#">Section title</BreadcrumbItem>
|
|
103
|
+
<BreadcrumbItem to="#">Section title</BreadcrumbItem>
|
|
104
|
+
<BreadcrumbItem to="#" isActive>
|
|
105
|
+
Section landing
|
|
106
|
+
</BreadcrumbItem>
|
|
107
|
+
</Breadcrumb>
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const kebabDropdownItems = [
|
|
111
|
+
<DropdownItem key="settings">
|
|
112
|
+
<CogIcon /> Settings
|
|
113
|
+
</DropdownItem>,
|
|
114
|
+
<DropdownItem key="help">
|
|
115
|
+
<HelpIcon /> Help
|
|
116
|
+
</DropdownItem>
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
const fullKebabDropdownItems = [
|
|
120
|
+
<DropdownGroup key="group 2">
|
|
121
|
+
<DropdownItem key="group 2 profile">My profile</DropdownItem>
|
|
122
|
+
<DropdownItem key="group 2 user" component="button">
|
|
123
|
+
User management
|
|
124
|
+
</DropdownItem>
|
|
125
|
+
<DropdownItem key="group 2 logout">Logout</DropdownItem>
|
|
126
|
+
</DropdownGroup>,
|
|
127
|
+
<Divider key="divider" />,
|
|
128
|
+
<DropdownItem key="settings">
|
|
129
|
+
<CogIcon /> Settings
|
|
130
|
+
</DropdownItem>,
|
|
131
|
+
<DropdownItem key="help">
|
|
132
|
+
<HelpIcon /> Help
|
|
133
|
+
</DropdownItem>
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
const userDropdownItems = [
|
|
137
|
+
<DropdownGroup key="group 2">
|
|
138
|
+
<DropdownItem key="group 2 profile">My profile</DropdownItem>
|
|
139
|
+
<DropdownItem key="group 2 user" component="button">
|
|
140
|
+
User management
|
|
141
|
+
</DropdownItem>
|
|
142
|
+
<DropdownItem key="group 2 logout">Logout</DropdownItem>
|
|
143
|
+
</DropdownGroup>
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
const appLauncherItems = [
|
|
147
|
+
<ApplicationLauncherItem key="application_1a" href="#">
|
|
148
|
+
Application 1 (anchor link)
|
|
149
|
+
</ApplicationLauncherItem>,
|
|
150
|
+
<ApplicationLauncherItem key="application_2a" component="button" onClick={() => alert('Clicked item 2')}>
|
|
151
|
+
Application 2 (button with onClick)
|
|
152
|
+
</ApplicationLauncherItem>
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
const headerToolbar = (
|
|
156
|
+
<Toolbar id="toolbar" isFullHeight isStatic>
|
|
157
|
+
<ToolbarContent>
|
|
158
|
+
<ToolbarGroup
|
|
159
|
+
variant="icon-button-group"
|
|
160
|
+
alignment={{ default: 'alignRight' }}
|
|
161
|
+
spacer={{ default: 'spacerNone', md: 'spacerMd' }}
|
|
162
|
+
>
|
|
163
|
+
<ToolbarItem>
|
|
164
|
+
<Button aria-label="Notifications" variant={ButtonVariant.plain} icon={<BellIcon />} />
|
|
165
|
+
</ToolbarItem>
|
|
166
|
+
<ToolbarGroup variant="icon-button-group" visibility={{ default: 'hidden', lg: 'visible' }}>
|
|
167
|
+
<ToolbarItem visibility={{ default: 'hidden', md: 'hidden', lg: 'visible' }}>
|
|
168
|
+
<ApplicationLauncher
|
|
169
|
+
onSelect={onAppLauncherSelect}
|
|
170
|
+
onToggle={onAppLauncherToggle}
|
|
171
|
+
isOpen={isAppLauncherOpen}
|
|
172
|
+
items={appLauncherItems}
|
|
173
|
+
/>
|
|
174
|
+
</ToolbarItem>
|
|
175
|
+
<ToolbarItem>
|
|
176
|
+
<Button aria-label="Settings" variant={ButtonVariant.plain} icon={<CogIcon />} />
|
|
177
|
+
</ToolbarItem>
|
|
178
|
+
<ToolbarItem>
|
|
179
|
+
<Button aria-label="Help" variant={ButtonVariant.plain} icon={<QuestionCircleIcon />} />
|
|
180
|
+
</ToolbarItem>
|
|
181
|
+
</ToolbarGroup>
|
|
182
|
+
<ToolbarItem visibility={{ default: 'hidden', md: 'visible', lg: 'hidden' }}>
|
|
183
|
+
<Dropdown
|
|
184
|
+
isPlain
|
|
185
|
+
position="right"
|
|
186
|
+
onSelect={onKebabDropdownSelect}
|
|
187
|
+
toggle={<KebabToggle onToggle={onKebabDropdownToggle} />}
|
|
188
|
+
isOpen={isKebabDropdownOpen}
|
|
189
|
+
dropdownItems={kebabDropdownItems}
|
|
190
|
+
/>
|
|
191
|
+
</ToolbarItem>
|
|
192
|
+
<ToolbarItem visibility={{ md: 'hidden' }}>
|
|
193
|
+
<Dropdown
|
|
194
|
+
isPlain
|
|
195
|
+
position="right"
|
|
196
|
+
onSelect={onFullKebabDropdownSelect}
|
|
197
|
+
toggle={<KebabToggle onToggle={onFullKebabDropdownToggle} />}
|
|
198
|
+
isOpen={isFullKebabDropdownOpen}
|
|
199
|
+
dropdownItems={fullKebabDropdownItems}
|
|
200
|
+
/>
|
|
201
|
+
</ToolbarItem>
|
|
202
|
+
</ToolbarGroup>
|
|
203
|
+
<ToolbarItem visibility={{ default: 'hidden', md: 'visible' }}>
|
|
204
|
+
<Dropdown
|
|
205
|
+
isFullHeight
|
|
206
|
+
onSelect={onDropdownSelect}
|
|
207
|
+
isOpen={isDropdownOpen}
|
|
208
|
+
toggle={
|
|
209
|
+
<DropdownToggle icon={<Avatar src={imgAvatar} alt="Avatar" />} onToggle={onDropdownToggle}>
|
|
210
|
+
Ned Username
|
|
211
|
+
</DropdownToggle>
|
|
212
|
+
}
|
|
213
|
+
dropdownItems={userDropdownItems}
|
|
214
|
+
/>
|
|
215
|
+
</ToolbarItem>
|
|
216
|
+
</ToolbarContent>
|
|
217
|
+
</Toolbar>
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
const masthead = (
|
|
221
|
+
<Masthead>
|
|
222
|
+
<MastheadToggle>
|
|
223
|
+
<PageToggleButton variant="plain" aria-label="Global navigation">
|
|
224
|
+
<BarsIcon />
|
|
225
|
+
</PageToggleButton>
|
|
226
|
+
</MastheadToggle>
|
|
227
|
+
<MastheadMain>
|
|
228
|
+
<MastheadBrand>
|
|
229
|
+
<Brand
|
|
230
|
+
widths={{ default: '180px', md: '180px', '2xl': '220px' }}
|
|
231
|
+
src="/assets/images/logo__pf--reverse--base.png"
|
|
232
|
+
alt="Fallback patternFly default logo"
|
|
233
|
+
>
|
|
234
|
+
<source media="(min-width: 768px)" srcSet="/assets/images/logo__pf--reverse-on-md.svg" />
|
|
235
|
+
<source srcSet="/assets/images/logo__pf--reverse--base.svg" />
|
|
236
|
+
</Brand>
|
|
237
|
+
</MastheadBrand>
|
|
238
|
+
</MastheadMain>
|
|
239
|
+
<MastheadContent>{headerToolbar}</MastheadContent>
|
|
240
|
+
</Masthead>
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
const pageNav = (
|
|
244
|
+
<Nav onSelect={onNavSelect}>
|
|
245
|
+
<NavList>
|
|
246
|
+
<NavItem itemId={0} isActive={activeItem === 0} to="#system-panel">
|
|
247
|
+
System panel
|
|
248
|
+
</NavItem>
|
|
249
|
+
<NavItem itemId={1} isActive={activeItem === 1} to="#policy">
|
|
250
|
+
Policy
|
|
251
|
+
</NavItem>
|
|
252
|
+
<NavItem itemId={2} isActive={activeItem === 2} to="#auth">
|
|
253
|
+
Authentication
|
|
254
|
+
</NavItem>
|
|
255
|
+
<NavItem itemId={3} isActive={activeItem === 3} to="#network">
|
|
256
|
+
Network services
|
|
257
|
+
</NavItem>
|
|
258
|
+
<NavItem itemId={4} isActive={activeItem === 4} to="#server">
|
|
259
|
+
Server
|
|
260
|
+
</NavItem>
|
|
261
|
+
</NavList>
|
|
262
|
+
</Nav>
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
const sidebar = <PageSidebar nav={pageNav} />;
|
|
266
|
+
|
|
267
|
+
const mainContainerId = 'main-content';
|
|
268
|
+
|
|
269
|
+
const pageSkipToContent = <SkipToContent href={`#${mainContainerId}`}>Skip to content</SkipToContent>;
|
|
270
|
+
|
|
271
|
+
return (
|
|
272
|
+
<Page
|
|
273
|
+
header={masthead}
|
|
274
|
+
sidebar={sidebar}
|
|
275
|
+
isManagedSidebar
|
|
276
|
+
skipToContent={pageSkipToContent}
|
|
277
|
+
breadcrumb={dashboardBreadcrumb}
|
|
278
|
+
mainContainerId={mainContainerId}
|
|
279
|
+
isBreadcrumbWidthLimited
|
|
280
|
+
breadcrumbProps={{
|
|
281
|
+
stickyOnBreakpoint: {
|
|
282
|
+
md: 'top'
|
|
283
|
+
}
|
|
284
|
+
}}
|
|
285
|
+
>
|
|
286
|
+
<PageSection variant={PageSectionVariants.light} isWidthLimited>
|
|
287
|
+
<TextContent>
|
|
288
|
+
<Text component="h1">Main title</Text>
|
|
289
|
+
<Text component="p">This is a full page demo.</Text>
|
|
290
|
+
</TextContent>
|
|
291
|
+
</PageSection>
|
|
292
|
+
<PageSection isWidthLimited>
|
|
293
|
+
<Gallery hasGutter>
|
|
294
|
+
{Array.apply(0, Array(50)).map((_x, i) => (
|
|
295
|
+
<GalleryItem key={i}>
|
|
296
|
+
<Card>
|
|
297
|
+
<CardBody>This is a card</CardBody>
|
|
298
|
+
</Card>
|
|
299
|
+
</GalleryItem>
|
|
300
|
+
))}
|
|
301
|
+
</Gallery>
|
|
302
|
+
</PageSection>
|
|
303
|
+
</Page>
|
|
304
|
+
);
|
|
305
|
+
};
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
ApplicationLauncher,
|
|
4
|
+
ApplicationLauncherItem,
|
|
5
|
+
Avatar,
|
|
6
|
+
Brand,
|
|
7
|
+
Breadcrumb,
|
|
8
|
+
BreadcrumbItem,
|
|
9
|
+
Button,
|
|
10
|
+
ButtonVariant,
|
|
11
|
+
Card,
|
|
12
|
+
CardBody,
|
|
13
|
+
Divider,
|
|
14
|
+
Dropdown,
|
|
15
|
+
DropdownGroup,
|
|
16
|
+
DropdownItem,
|
|
17
|
+
DropdownToggle,
|
|
18
|
+
Gallery,
|
|
19
|
+
GalleryItem,
|
|
20
|
+
KebabToggle,
|
|
21
|
+
Masthead,
|
|
22
|
+
MastheadBrand,
|
|
23
|
+
MastheadContent,
|
|
24
|
+
MastheadMain,
|
|
25
|
+
MastheadToggle,
|
|
26
|
+
Nav,
|
|
27
|
+
NavItem,
|
|
28
|
+
NavList,
|
|
29
|
+
Page,
|
|
30
|
+
PageSection,
|
|
31
|
+
PageSectionVariants,
|
|
32
|
+
PageSidebar,
|
|
33
|
+
PageToggleButton,
|
|
34
|
+
SkipToContent,
|
|
35
|
+
Text,
|
|
36
|
+
TextContent,
|
|
37
|
+
Toolbar,
|
|
38
|
+
ToolbarContent,
|
|
39
|
+
ToolbarGroup,
|
|
40
|
+
ToolbarItem
|
|
41
|
+
} from '@patternfly/react-core';
|
|
42
|
+
import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';
|
|
43
|
+
import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
|
|
44
|
+
import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
|
|
45
|
+
import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon';
|
|
46
|
+
import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon';
|
|
47
|
+
import imgAvatar from '@patternfly/react-core/src/components/Avatar/examples/avatarImg.svg';
|
|
48
|
+
|
|
49
|
+
interface NavOnSelectProps {
|
|
50
|
+
groupId: number | string;
|
|
51
|
+
itemId: number | string;
|
|
52
|
+
to: string;
|
|
53
|
+
event: React.FormEvent<HTMLInputElement>;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const PageStickySectionGroup: React.FunctionComponent = () => {
|
|
57
|
+
const [isDropdownOpen, setIsDropdownOpen] = React.useState(false);
|
|
58
|
+
const [isKebabDropdownOpen, setIsKebabDropdownOpen] = React.useState(false);
|
|
59
|
+
const [isFullKebabDropdownOpen, setIsFullKebabDropdownOpen] = React.useState(false);
|
|
60
|
+
const [isAppLauncherOpen, setIsAppLauncherOpen] = React.useState(false);
|
|
61
|
+
const [activeItem, setActiveItem] = React.useState(1);
|
|
62
|
+
|
|
63
|
+
const onNavSelect = (selectedItem: NavOnSelectProps) => {
|
|
64
|
+
typeof selectedItem.itemId === 'number' && setActiveItem(selectedItem.itemId);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const onDropdownToggle = (isOpen: boolean) => {
|
|
68
|
+
setIsDropdownOpen(isOpen);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const onDropdownSelect = () => {
|
|
72
|
+
setIsDropdownOpen(!isDropdownOpen);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const onKebabDropdownToggle = (isOpen: boolean) => {
|
|
76
|
+
setIsKebabDropdownOpen(isOpen);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const onKebabDropdownSelect = () => {
|
|
80
|
+
setIsKebabDropdownOpen(!isKebabDropdownOpen);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const onFullKebabDropdownToggle = (isOpen: boolean) => {
|
|
84
|
+
setIsFullKebabDropdownOpen(isOpen);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const onFullKebabDropdownSelect = () => {
|
|
88
|
+
setIsFullKebabDropdownOpen(!isFullKebabDropdownOpen);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const onAppLauncherToggle = (isOpen: boolean) => {
|
|
92
|
+
setIsAppLauncherOpen(isOpen);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const onAppLauncherSelect = () => {
|
|
96
|
+
setIsAppLauncherOpen(!isAppLauncherOpen);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const dashboardBreadcrumb = (
|
|
100
|
+
<Breadcrumb>
|
|
101
|
+
<BreadcrumbItem>Section home</BreadcrumbItem>
|
|
102
|
+
<BreadcrumbItem to="#">Section title</BreadcrumbItem>
|
|
103
|
+
<BreadcrumbItem to="#">Section title</BreadcrumbItem>
|
|
104
|
+
<BreadcrumbItem to="#" isActive>
|
|
105
|
+
Section landing
|
|
106
|
+
</BreadcrumbItem>
|
|
107
|
+
</Breadcrumb>
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
const kebabDropdownItems = [
|
|
111
|
+
<DropdownItem key="settings">
|
|
112
|
+
<CogIcon /> Settings
|
|
113
|
+
</DropdownItem>,
|
|
114
|
+
<DropdownItem key="help">
|
|
115
|
+
<HelpIcon /> Help
|
|
116
|
+
</DropdownItem>
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
const fullKebabDropdownItems = [
|
|
120
|
+
<DropdownGroup key="group 2">
|
|
121
|
+
<DropdownItem key="group 2 profile">My profile</DropdownItem>
|
|
122
|
+
<DropdownItem key="group 2 user" component="button">
|
|
123
|
+
User management
|
|
124
|
+
</DropdownItem>
|
|
125
|
+
<DropdownItem key="group 2 logout">Logout</DropdownItem>
|
|
126
|
+
</DropdownGroup>,
|
|
127
|
+
<Divider key="divider" />,
|
|
128
|
+
<DropdownItem key="settings">
|
|
129
|
+
<CogIcon /> Settings
|
|
130
|
+
</DropdownItem>,
|
|
131
|
+
<DropdownItem key="help">
|
|
132
|
+
<HelpIcon /> Help
|
|
133
|
+
</DropdownItem>
|
|
134
|
+
];
|
|
135
|
+
|
|
136
|
+
const userDropdownItems = [
|
|
137
|
+
<DropdownGroup key="group 2">
|
|
138
|
+
<DropdownItem key="group 2 profile">My profile</DropdownItem>
|
|
139
|
+
<DropdownItem key="group 2 user" component="button">
|
|
140
|
+
User management
|
|
141
|
+
</DropdownItem>
|
|
142
|
+
<DropdownItem key="group 2 logout">Logout</DropdownItem>
|
|
143
|
+
</DropdownGroup>
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
const appLauncherItems = [
|
|
147
|
+
<ApplicationLauncherItem key="application_1a" href="#">
|
|
148
|
+
Application 1 (anchor link)
|
|
149
|
+
</ApplicationLauncherItem>,
|
|
150
|
+
<ApplicationLauncherItem key="application_2a" component="button" onClick={() => alert('Clicked item 2')}>
|
|
151
|
+
Application 2 (button with onClick)
|
|
152
|
+
</ApplicationLauncherItem>
|
|
153
|
+
];
|
|
154
|
+
|
|
155
|
+
const headerToolbar = (
|
|
156
|
+
<Toolbar id="toolbar" isFullHeight isStatic>
|
|
157
|
+
<ToolbarContent>
|
|
158
|
+
<ToolbarGroup
|
|
159
|
+
variant="icon-button-group"
|
|
160
|
+
alignment={{ default: 'alignRight' }}
|
|
161
|
+
spacer={{ default: 'spacerNone', md: 'spacerMd' }}
|
|
162
|
+
>
|
|
163
|
+
<ToolbarItem>
|
|
164
|
+
<Button aria-label="Notifications" variant={ButtonVariant.plain} icon={<BellIcon />} />
|
|
165
|
+
</ToolbarItem>
|
|
166
|
+
<ToolbarGroup variant="icon-button-group" visibility={{ default: 'hidden', lg: 'visible' }}>
|
|
167
|
+
<ToolbarItem visibility={{ default: 'hidden', md: 'hidden', lg: 'visible' }}>
|
|
168
|
+
<ApplicationLauncher
|
|
169
|
+
onSelect={onAppLauncherSelect}
|
|
170
|
+
onToggle={onAppLauncherToggle}
|
|
171
|
+
isOpen={isAppLauncherOpen}
|
|
172
|
+
items={appLauncherItems}
|
|
173
|
+
/>
|
|
174
|
+
</ToolbarItem>
|
|
175
|
+
<ToolbarItem>
|
|
176
|
+
<Button aria-label="Settings" variant={ButtonVariant.plain} icon={<CogIcon />} />
|
|
177
|
+
</ToolbarItem>
|
|
178
|
+
<ToolbarItem>
|
|
179
|
+
<Button aria-label="Help" variant={ButtonVariant.plain} icon={<QuestionCircleIcon />} />
|
|
180
|
+
</ToolbarItem>
|
|
181
|
+
</ToolbarGroup>
|
|
182
|
+
<ToolbarItem visibility={{ default: 'hidden', md: 'visible', lg: 'hidden' }}>
|
|
183
|
+
<Dropdown
|
|
184
|
+
isPlain
|
|
185
|
+
position="right"
|
|
186
|
+
onSelect={onKebabDropdownSelect}
|
|
187
|
+
toggle={<KebabToggle onToggle={onKebabDropdownToggle} />}
|
|
188
|
+
isOpen={isKebabDropdownOpen}
|
|
189
|
+
dropdownItems={kebabDropdownItems}
|
|
190
|
+
/>
|
|
191
|
+
</ToolbarItem>
|
|
192
|
+
<ToolbarItem visibility={{ md: 'hidden' }}>
|
|
193
|
+
<Dropdown
|
|
194
|
+
isPlain
|
|
195
|
+
position="right"
|
|
196
|
+
onSelect={onFullKebabDropdownSelect}
|
|
197
|
+
toggle={<KebabToggle onToggle={onFullKebabDropdownToggle} />}
|
|
198
|
+
isOpen={isFullKebabDropdownOpen}
|
|
199
|
+
dropdownItems={fullKebabDropdownItems}
|
|
200
|
+
/>
|
|
201
|
+
</ToolbarItem>
|
|
202
|
+
</ToolbarGroup>
|
|
203
|
+
<ToolbarItem visibility={{ default: 'hidden', md: 'visible' }}>
|
|
204
|
+
<Dropdown
|
|
205
|
+
isFullHeight
|
|
206
|
+
onSelect={onDropdownSelect}
|
|
207
|
+
isOpen={isDropdownOpen}
|
|
208
|
+
toggle={
|
|
209
|
+
<DropdownToggle icon={<Avatar src={imgAvatar} alt="Avatar" />} onToggle={onDropdownToggle}>
|
|
210
|
+
Ned Username
|
|
211
|
+
</DropdownToggle>
|
|
212
|
+
}
|
|
213
|
+
dropdownItems={userDropdownItems}
|
|
214
|
+
/>
|
|
215
|
+
</ToolbarItem>
|
|
216
|
+
</ToolbarContent>
|
|
217
|
+
</Toolbar>
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
const masthead = (
|
|
221
|
+
<Masthead>
|
|
222
|
+
<MastheadToggle>
|
|
223
|
+
<PageToggleButton variant="plain" aria-label="Global navigation">
|
|
224
|
+
<BarsIcon />
|
|
225
|
+
</PageToggleButton>
|
|
226
|
+
</MastheadToggle>
|
|
227
|
+
<MastheadMain>
|
|
228
|
+
<MastheadBrand>
|
|
229
|
+
<Brand
|
|
230
|
+
widths={{ default: '180px', md: '180px', '2xl': '220px' }}
|
|
231
|
+
src="/assets/images/logo__pf--reverse--base.png"
|
|
232
|
+
alt="Fallback patternFly default logo"
|
|
233
|
+
>
|
|
234
|
+
<source media="(min-width: 768px)" srcSet="/assets/images/logo__pf--reverse-on-md.svg" />
|
|
235
|
+
<source srcSet="/assets/images/logo__pf--reverse--base.svg" />
|
|
236
|
+
</Brand>
|
|
237
|
+
</MastheadBrand>
|
|
238
|
+
</MastheadMain>
|
|
239
|
+
<MastheadContent>{headerToolbar}</MastheadContent>
|
|
240
|
+
</Masthead>
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
const pageNav = (
|
|
244
|
+
<Nav onSelect={onNavSelect}>
|
|
245
|
+
<NavList>
|
|
246
|
+
<NavItem itemId={0} isActive={activeItem === 0} to="#system-panel">
|
|
247
|
+
System panel
|
|
248
|
+
</NavItem>
|
|
249
|
+
<NavItem itemId={1} isActive={activeItem === 1} to="#policy">
|
|
250
|
+
Policy
|
|
251
|
+
</NavItem>
|
|
252
|
+
<NavItem itemId={2} isActive={activeItem === 2} to="#auth">
|
|
253
|
+
Authentication
|
|
254
|
+
</NavItem>
|
|
255
|
+
<NavItem itemId={3} isActive={activeItem === 3} to="#network">
|
|
256
|
+
Network services
|
|
257
|
+
</NavItem>
|
|
258
|
+
<NavItem itemId={4} isActive={activeItem === 4} to="#server">
|
|
259
|
+
Server
|
|
260
|
+
</NavItem>
|
|
261
|
+
</NavList>
|
|
262
|
+
</Nav>
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
const sidebar = <PageSidebar nav={pageNav} />;
|
|
266
|
+
|
|
267
|
+
const mainContainerId = 'main-content';
|
|
268
|
+
|
|
269
|
+
const pageSkipToContent = <SkipToContent href={`#${mainContainerId}`}>Skip to content</SkipToContent>;
|
|
270
|
+
|
|
271
|
+
return (
|
|
272
|
+
<Page
|
|
273
|
+
header={masthead}
|
|
274
|
+
sidebar={sidebar}
|
|
275
|
+
isManagedSidebar
|
|
276
|
+
skipToContent={pageSkipToContent}
|
|
277
|
+
breadcrumb={dashboardBreadcrumb}
|
|
278
|
+
mainContainerId={mainContainerId}
|
|
279
|
+
isBreadcrumbWidthLimited
|
|
280
|
+
isBreadcrumbGrouped
|
|
281
|
+
additionalGroupedContent={
|
|
282
|
+
<PageSection variant={PageSectionVariants.light} isWidthLimited>
|
|
283
|
+
<TextContent>
|
|
284
|
+
<Text component="h1">Main title</Text>
|
|
285
|
+
<Text component="p">This is a full page demo.</Text>
|
|
286
|
+
</TextContent>
|
|
287
|
+
</PageSection>
|
|
288
|
+
}
|
|
289
|
+
groupProps={{
|
|
290
|
+
stickyOnBreakpoint: { default: 'top' }
|
|
291
|
+
}}
|
|
292
|
+
>
|
|
293
|
+
<PageSection>
|
|
294
|
+
<Gallery hasGutter>
|
|
295
|
+
{Array.apply(0, Array(50)).map((x, i) => (
|
|
296
|
+
<GalleryItem key={i}>
|
|
297
|
+
<Card>
|
|
298
|
+
<CardBody>This is a card</CardBody>
|
|
299
|
+
</Card>
|
|
300
|
+
</GalleryItem>
|
|
301
|
+
))}
|
|
302
|
+
</Gallery>
|
|
303
|
+
</PageSection>
|
|
304
|
+
</Page>
|
|
305
|
+
);
|
|
306
|
+
};
|