@patternfly/react-docs 5.22.3 → 5.22.7
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 +32 -0
- package/package.json +11 -11
- package/src/generated/components/back-to-top/react-demos/using-name-selector.png +0 -0
- package/src/generated/components/backdrop/react/basic.png +0 -0
- package/src/generated/components/backdrop/react/with-spinner.png +0 -0
- package/src/generated/components/background-image/react/basic.png +0 -0
- package/src/generated/components/banner/react-demos/basic-sticky-banner.png +0 -0
- package/src/generated/components/banner/react-demos/top-and-bottom-banner.png +0 -0
- package/src/generated/components/card/react-demos.js +46 -1
- package/src/generated/components/drawer/react.js +0 -2
- package/src/generated/components/jump-links/react-demos/scrollspy-with-subsections.png +0 -0
- package/src/generated/components/login-page/react/basic.png +0 -0
- package/src/generated/components/login-page/react/showhide-password.png +0 -0
- package/src/generated/components/navigation/react-demos/default-nav.png +0 -0
- package/src/generated/components/navigation/react-demos/expandable-nav.png +0 -0
- package/src/generated/components/navigation/react-demos/grouped-nav.png +0 -0
- package/src/generated/components/navigation/react-demos/horizontal-nav-with-horizontal-subnav.png +0 -0
- package/src/generated/components/navigation/react-demos/horizontal-nav.png +0 -0
- package/src/generated/components/navigation/react-demos/horizontal-subnav.png +0 -0
- package/src/generated/components/navigation/react-demos/legacy-tertiary-nav.png +0 -0
- package/src/generated/components/navigation/react-demos/legacylight-nav.png +0 -0
- package/src/generated/components/navigation/react-demos/manual-nav.png +0 -0
- package/src/generated/components/notification-drawer/react-demos/basic.png +0 -0
- package/src/generated/components/notification-drawer/react-demos/grouped.png +0 -0
- package/src/generated/components/page/react-demos/sticky-section-group-alternate-syntax-and-using-pageheader.png +0 -0
- package/src/generated/components/page/react-demos/sticky-section-group-using-pageheader.png +0 -0
- package/src/generated/components/page/react-demos/sticky-section-group.png +0 -0
- package/src/generated/components/page/react-demos.js +27 -7
- package/src/generated/components/page/react.js +21 -9
- package/src/generated/components/pagination/react/sticky.png +0 -0
- package/src/generated/components/select/react.js +6 -0
- package/src/generated/components/skip-to-content/react/basic.png +0 -0
- package/src/generated/components/table/react-demos/sticky-header.png +0 -0
- package/src/generated/components/tabs/react.js +43 -0
- package/src/generated/components/toolbar/react-demos/console-log-viewer-toolbar-demo.png +0 -0
- package/src/generated/components/wizard/react-demos/in-modal.png +0 -0
- package/src/generated/components/wizard/react-demos/in-page.png +0 -0
- package/src/generated/demos/card-view/react-demos/card-view.png +0 -0
- package/src/generated/demos/composable-menu/react-demos.js +15 -9
- package/src/generated/demos/primary-detail/react-demos/primary-detail-card-view.png +0 -0
- package/src/generated/demos/primary-detail/react-demos/primary-detail-content-padding.png +0 -0
- package/src/generated/demos/primary-detail/react-demos/primary-detail-data-list-in-card.png +0 -0
- package/src/generated/demos/primary-detail/react-demos/primary-detail-full-page.png +0 -0
- package/src/generated/demos/primary-detail/react-demos/primary-detail-inline-modifier.png +0 -0
- package/src/generated/demos/primary-detail/react-demos/primary-detail-simple-list-in-card.png +0 -0
- package/src/generated/index.js +12 -12
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { AutoLinkHeader, Example, Link as PatternflyThemeLink } from 'theme-patternfly-org/components';
|
|
3
|
-
|
|
3
|
+
import BarsIcon from '@patternfly/react-icons/dist/js/icons/bars-icon';
|
|
4
4
|
const pageData = {
|
|
5
5
|
"id": "Page",
|
|
6
6
|
"section": "components",
|
|
@@ -556,37 +556,48 @@ const pageData = {
|
|
|
556
556
|
"Main Section Padding",
|
|
557
557
|
"With or without fill",
|
|
558
558
|
"Uncontrolled nav",
|
|
559
|
-
"Group section"
|
|
559
|
+
"Group section",
|
|
560
|
+
"Vertical nav using PageHeader component"
|
|
560
561
|
]
|
|
561
562
|
};
|
|
563
|
+
pageData.liveContext = {
|
|
564
|
+
BarsIcon
|
|
565
|
+
};
|
|
562
566
|
pageData.examples = {
|
|
563
567
|
'Vertical nav': props =>
|
|
564
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n
|
|
568
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n Masthead,\n MastheadToggle,\n MastheadMain,\n MastheadBrand,\n MastheadContent,\n PageSidebar,\n PageSection,\n PageSectionVariants,\n PageToggleButton,\n Toolbar,\n ToolbarContent,\n ToolbarItem\n} from '@patternfly/react-core';\nimport BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';\n\nclass VerticalPage extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n isNavOpen: true\n };\n this.onNavToggle = () => {\n this.setState({\n isNavOpen: !this.state.isNavOpen\n });\n };\n }\n\n render() {\n const { isNavOpen } = this.state;\n\n const headerToolbar = (\n <Toolbar id=\"toolbar\">\n <ToolbarContent>\n <ToolbarItem>header-tools</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n );\n\n const Header = (\n <Masthead>\n <MastheadToggle>\n <PageToggleButton\n variant=\"plain\"\n aria-label=\"Global navigation\"\n isNavOpen={isNavOpen}\n onNavToggle={this.onNavToggle}\n >\n <BarsIcon />\n </PageToggleButton>\n </MastheadToggle>\n <MastheadMain>\n <MastheadBrand href=\"https://patternfly.org\" onClick={() => console.log('clicked logo')} target=\"_blank\">\n Logo\n </MastheadBrand>\n </MastheadMain>\n <MastheadContent>{headerToolbar}</MastheadContent>\n </Masthead>\n );\n const Sidebar = <PageSidebar nav=\"Navigation\" isNavOpen={isNavOpen} />;\n\n return (\n <Page header={Header} sidebar={Sidebar}>\n <PageSection variant={PageSectionVariants.darker}>Section with darker background</PageSection>\n <PageSection variant={PageSectionVariants.dark}>Section with dark background</PageSection>\n <PageSection variant={PageSectionVariants.light}>Section with light background</PageSection>\n </Page>\n );\n }\n}","title":"Vertical nav","lang":"js"}}>
|
|
565
569
|
|
|
566
570
|
</Example>,
|
|
567
571
|
'Horizontal nav': props =>
|
|
568
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n
|
|
572
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n Masthead,\n MastheadMain,\n MastheadBrand,\n MastheadContent,\n PageSection,\n PageSectionVariants,\n Toolbar,\n ToolbarContent,\n ToolbarItem\n} from '@patternfly/react-core';\n\nHorizontalPage = () => {\n const headerToolbar = (\n <Toolbar id=\"toolbar\">\n <ToolbarContent>\n <ToolbarItem>Navigation</ToolbarItem>\n <ToolbarItem>header-tools</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n );\n\n const Header = (\n <Masthead display={{ default: 'stack' }} inset={{ default: 'insetXs' }}>\n <MastheadMain>\n <MastheadBrand href=\"https://patternfly.org\" onClick={() => console.log('clicked logo')} target=\"_blank\">\n Logo\n </MastheadBrand>\n </MastheadMain>\n <MastheadContent>{headerToolbar}</MastheadContent>\n </Masthead>\n );\n\n return (\n <Page header={Header}>\n <PageSection variant={PageSectionVariants.darker}>Section with darker background</PageSection>\n <PageSection variant={PageSectionVariants.dark}>Section with dark background</PageSection>\n <PageSection variant={PageSectionVariants.light}>Section with light background</PageSection>\n </Page>\n );\n};","title":"Horizontal nav","lang":"js"}}>
|
|
569
573
|
|
|
570
574
|
</Example>,
|
|
571
575
|
'Tertiary nav': props =>
|
|
572
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n
|
|
576
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n Masthead,\n MastheadMain,\n MastheadBrand,\n MastheadContent,\n PageSection,\n PageSectionVariants,\n Toolbar,\n ToolbarContent,\n ToolbarItem\n} from '@patternfly/react-core';\n\nTertiaryPage = () => {\n const headerToolbar = (\n <Toolbar id=\"toolbar\">\n <ToolbarContent>\n <ToolbarItem>header-tools</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n );\n\n const Header = (\n <Masthead display={{ default: 'stack' }} inset={{ default: 'insetXs' }}>\n <MastheadMain>\n <MastheadBrand href=\"https://patternfly.org\" onClick={() => console.log('clicked logo')} target=\"_blank\">\n Logo\n </MastheadBrand>\n </MastheadMain>\n <MastheadContent>{headerToolbar}</MastheadContent>\n </Masthead>\n );\n\n return (\n <Page header={Header} tertiaryNav=\"Navigation\">\n <PageSection variant={PageSectionVariants.darker}>Section with darker background</PageSection>\n <PageSection variant={PageSectionVariants.dark}>Section with dark background</PageSection>\n <PageSection variant={PageSectionVariants.light}>Section with light background</PageSection>\n </Page>\n );\n};","title":"Tertiary nav","lang":"js"}}>
|
|
573
577
|
|
|
574
578
|
</Example>,
|
|
575
579
|
'Main Section Padding': props =>
|
|
576
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n
|
|
580
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n Masthead,\n MastheadToggle,\n MastheadMain,\n MastheadBrand,\n MastheadContent,\n PageSidebar,\n PageSection,\n PageSectionVariants,\n PageToggleButton,\n Toolbar,\n ToolbarContent,\n ToolbarItem\n} from '@patternfly/react-core';\nimport BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';\n\nclass VerticalPage extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n isNavOpen: true\n };\n this.onNavToggle = () => {\n this.setState({\n isNavOpen: !this.state.isNavOpen\n });\n };\n }\n\n render() {\n const { isNavOpen } = this.state;\n\n const headerToolbar = (\n <Toolbar id=\"toolbar\">\n <ToolbarContent>\n <ToolbarItem>header-tools</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n );\n\n const Header = (\n <Masthead>\n <MastheadToggle>\n <PageToggleButton\n variant=\"plain\"\n aria-label=\"Global navigation\"\n isNavOpen={isNavOpen}\n onNavToggle={this.onNavToggle}\n >\n <BarsIcon />\n </PageToggleButton>\n </MastheadToggle>\n <MastheadMain>\n <MastheadBrand href=\"https://patternfly.org\" onClick={() => console.log('clicked logo')} target=\"_blank\">\n Logo\n </MastheadBrand>\n </MastheadMain>\n <MastheadContent>{headerToolbar}</MastheadContent>\n </Masthead>\n );\n const Sidebar = <PageSidebar nav=\"Navigation\" isNavOpen={isNavOpen} />;\n\n return (\n <Page header={Header} sidebar={Sidebar}>\n <PageSection>Section with default padding</PageSection>\n <PageSection variant={PageSectionVariants.light} padding={{ default: 'noPadding' }}>\n Section with no padding\n </PageSection>\n <PageSection padding={{ default: 'noPadding', md: 'padding', lg: 'padding' }}>\n Section with padding only on medium/large\n </PageSection>\n <PageSection variant={PageSectionVariants.light} padding={{ md: 'noPadding' }}>\n Section with no padding on medium\n </PageSection>\n </Page>\n );\n }\n}","title":"Main Section Padding","lang":"js"}}>
|
|
577
581
|
|
|
578
582
|
</Example>,
|
|
579
583
|
'With or without fill': props =>
|
|
580
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n
|
|
584
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n Masthead,\n MastheadToggle,\n MastheadMain,\n MastheadBrand,\n MastheadContent,\n PageSidebar,\n PageSection,\n PageToggleButton,\n Toolbar,\n ToolbarContent,\n ToolbarItem\n} from '@patternfly/react-core';\nimport BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';\n\nclass FillPage extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n isNavOpen: true\n };\n this.onNavToggle = () => {\n this.setState({\n isNavOpen: !this.state.isNavOpen\n });\n };\n }\n\n render() {\n const { isNavOpen } = this.state;\n\n const headerToolbar = (\n <Toolbar id=\"toolbar\">\n <ToolbarContent>\n <ToolbarItem>header-tools</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n );\n\n const Header = (\n <Masthead>\n <MastheadToggle>\n <PageToggleButton\n variant=\"plain\"\n aria-label=\"Global navigation\"\n isNavOpen={isNavOpen}\n onNavToggle={this.onNavToggle}\n >\n <BarsIcon />\n </PageToggleButton>\n </MastheadToggle>\n <MastheadMain>\n <MastheadBrand href=\"https://patternfly.org\" onClick={() => console.log('clicked logo')} target=\"_blank\">\n Logo\n </MastheadBrand>\n </MastheadMain>\n <MastheadContent>{headerToolbar}</MastheadContent>\n </Masthead>\n );\n const Sidebar = <PageSidebar nav=\"Navigation\" isNavOpen={isNavOpen} />;\n\n return (\n <Page header={Header} sidebar={Sidebar}>\n <PageSection style={{ height: '10em' }}>This section is set to the default fill variant</PageSection>\n <PageSection style={{ height: '10em' }} isFilled={true}>\n This section fills the available space.\n </PageSection>\n <PageSection style={{ height: '10em' }} isFilled={false}>\n {' '}\n This section does not fill the available space.\n </PageSection>\n </Page>\n );\n }\n}","title":"With or without fill","lang":"js"}}>
|
|
581
585
|
|
|
582
586
|
</Example>,
|
|
583
587
|
'Uncontrolled nav': props =>
|
|
584
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n
|
|
588
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n Masthead,\n MastheadToggle,\n MastheadMain,\n MastheadBrand,\n MastheadContent,\n PageSidebar,\n PageSection,\n PageSectionVariants,\n PageToggleButton,\n Toolbar,\n ToolbarContent,\n ToolbarItem\n} from '@patternfly/react-core';\nimport BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';\n\nclass UncontrolledNavPage extends React.Component {\n render() {\n const headerToolbar = (\n <Toolbar id=\"toolbar\">\n <ToolbarContent>\n <ToolbarItem>header-tools</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n );\n\n const Header = (\n <Masthead>\n <MastheadToggle>\n <PageToggleButton variant=\"plain\" aria-label=\"Global navigation\">\n <BarsIcon />\n </PageToggleButton>\n </MastheadToggle>\n <MastheadMain>\n <MastheadBrand href=\"https://patternfly.org\" onClick={() => console.log('clicked logo')} target=\"_blank\">\n Logo\n </MastheadBrand>\n </MastheadMain>\n <MastheadContent>{headerToolbar}</MastheadContent>\n </Masthead>\n );\n const Sidebar = <PageSidebar nav=\"Navigation\" />;\n\n return (\n <Page isManagedSidebar header={Header} sidebar={Sidebar}>\n <PageSection variant={PageSectionVariants.darker}>Section with darker background</PageSection>\n <PageSection variant={PageSectionVariants.dark}>Section with dark background</PageSection>\n <PageSection variant={PageSectionVariants.light}>Section with light background</PageSection>\n </Page>\n );\n }\n}","title":"Uncontrolled nav","lang":"js"}}>
|
|
585
589
|
|
|
586
590
|
</Example>,
|
|
587
591
|
'Group section': props =>
|
|
588
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n
|
|
592
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n Masthead,\n MastheadToggle,\n MastheadMain,\n MastheadBrand,\n MastheadContent,\n PageSidebar,\n PageSection,\n PageGroup,\n PageBreadcrumb,\n PageNavigation,\n PageSectionVariants,\n PageToggleButton,\n Breadcrumb,\n BreadcrumbItem,\n Nav,\n NavList,\n NavItem,\n Toolbar,\n ToolbarContent,\n ToolbarItem\n} from '@patternfly/react-core';\nimport BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';\n\nclass GroupPage extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n isNavOpen: true\n };\n this.onNavToggle = () => {\n this.setState({\n isNavOpen: !this.state.isNavOpen\n });\n };\n }\n\n render() {\n const { isNavOpen } = this.state;\n\n const headerToolbar = (\n <Toolbar id=\"toolbar\">\n <ToolbarContent>\n <ToolbarItem>header-tools</ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n );\n\n const Header = (\n <Masthead>\n <MastheadToggle>\n <PageToggleButton\n variant=\"plain\"\n aria-label=\"Global navigation\"\n isNavOpen={isNavOpen}\n onNavToggle={this.onNavToggle}\n >\n <BarsIcon />\n </PageToggleButton>\n </MastheadToggle>\n <MastheadMain>\n <MastheadBrand href=\"https://patternfly.org\" onClick={() => console.log('clicked logo')} target=\"_blank\">\n Logo\n </MastheadBrand>\n </MastheadMain>\n <MastheadContent>{headerToolbar}</MastheadContent>\n </Masthead>\n );\n const Sidebar = <PageSidebar nav=\"Navigation\" isNavOpen={isNavOpen} />;\n\n return (\n <Page header={Header} sidebar={Sidebar}>\n <PageGroup>\n <PageNavigation>\n <Nav aria-label=\"Nav\" variant=\"tertiary\">\n <NavList>\n <NavItem itemId={0} isActive>\n System panel\n </NavItem>\n <NavItem itemId={1}>Policy</NavItem>\n <NavItem itemId={2}>Authentication</NavItem>\n <NavItem itemId={3}>Network services</NavItem>\n <NavItem itemId={4}>Server</NavItem>\n </NavList>\n </Nav>\n </PageNavigation>\n <PageBreadcrumb>\n <Breadcrumb>\n <BreadcrumbItem>Section home</BreadcrumbItem>\n <BreadcrumbItem to=\"#\">Section title</BreadcrumbItem>\n <BreadcrumbItem to=\"#\">Section title</BreadcrumbItem>\n <BreadcrumbItem to=\"#\" isActive>\n Section landing\n </BreadcrumbItem>\n </Breadcrumb>\n </PageBreadcrumb>\n <PageSection variant={PageSectionVariants.light}>Grouped section</PageSection>\n </PageGroup>\n <PageSection variant={PageSectionVariants.dark}>Section 1</PageSection>\n <PageSection variant={PageSectionVariants.dark}>Section 2</PageSection>\n </Page>\n );\n }\n}","title":"Group section","lang":"js"}}>
|
|
593
|
+
|
|
594
|
+
</Example>,
|
|
595
|
+
'Vertical nav using PageHeader component': props =>
|
|
596
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n Page,\n PageHeader,\n PageHeaderTools,\n PageSidebar,\n PageSection,\n PageSectionVariants\n} from '@patternfly/react-core';\n\nclass VerticalPage extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n isNavOpen: true\n };\n this.onNavToggle = () => {\n this.setState({\n isNavOpen: !this.state.isNavOpen\n });\n };\n }\n\n render() {\n const { isNavOpen } = this.state;\n\n const logoProps = {\n href: 'https://patternfly.org',\n onClick: () => console.log('clicked logo'),\n target: '_blank'\n };\n const Header = (\n <PageHeader\n logo=\"Logo\"\n logoProps={logoProps}\n headerTools={<PageHeaderTools>header-tools</PageHeaderTools>}\n showNavToggle\n isNavOpen={isNavOpen}\n onNavToggle={this.onNavToggle}\n />\n );\n const Sidebar = <PageSidebar nav=\"Navigation\" isNavOpen={isNavOpen} />;\n\n return (\n <Page header={Header} sidebar={Sidebar}>\n <PageSection variant={PageSectionVariants.darker}>Section with darker background</PageSection>\n <PageSection variant={PageSectionVariants.dark}>Section with dark background</PageSection>\n <PageSection variant={PageSectionVariants.light}>Section with light background</PageSection>\n </Page>\n );\n }\n}","title":"Vertical nav using PageHeader component","lang":"js"}}>
|
|
589
597
|
|
|
598
|
+
<p {...{"className":"ws-p"}}>
|
|
599
|
+
{`This example 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.`}
|
|
600
|
+
</p>
|
|
590
601
|
</Example>
|
|
591
602
|
};
|
|
592
603
|
|
|
@@ -602,6 +613,7 @@ const Component = () => (
|
|
|
602
613
|
{React.createElement(pageData.examples["With or without fill"])}
|
|
603
614
|
{React.createElement(pageData.examples["Uncontrolled nav"])}
|
|
604
615
|
{React.createElement(pageData.examples["Group section"])}
|
|
616
|
+
{React.createElement(pageData.examples["Vertical nav using PageHeader component"])}
|
|
605
617
|
</React.Fragment>
|
|
606
618
|
);
|
|
607
619
|
Component.displayName = 'ComponentsPageReactDocs';
|
|
Binary file
|
|
@@ -239,6 +239,12 @@ const pageData = {
|
|
|
239
239
|
"description": "Title text of Select",
|
|
240
240
|
"defaultValue": "''"
|
|
241
241
|
},
|
|
242
|
+
{
|
|
243
|
+
"name": "position",
|
|
244
|
+
"type": "SelectPosition | 'right' | 'left'",
|
|
245
|
+
"description": "Indicates where menu will be aligned horizontally",
|
|
246
|
+
"defaultValue": "SelectPosition.left"
|
|
247
|
+
},
|
|
242
248
|
{
|
|
243
249
|
"name": "removeSelectionAriaLabel",
|
|
244
250
|
"type": "string",
|
|
Binary file
|
|
Binary file
|
|
@@ -50,6 +50,16 @@ const pageData = {
|
|
|
50
50
|
"type": "number | string",
|
|
51
51
|
"description": "The index of the default active tab. Set this for uncontrolled Tabs"
|
|
52
52
|
},
|
|
53
|
+
{
|
|
54
|
+
"name": "defaultIsExpanded",
|
|
55
|
+
"type": "boolean",
|
|
56
|
+
"description": "Flag indicating the default expanded state for uncontrolled expand/collapse of"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"name": "expandable",
|
|
60
|
+
"type": "{\n default?: 'expandable' | 'nonExpandable';\n sm?: 'expandable' | 'nonExpandable';\n md?: 'expandable' | 'nonExpandable';\n lg?: 'expandable' | 'nonExpandable';\n xl?: 'expandable' | 'nonExpandable';\n '2xl'?: 'expandable' | 'nonExpandable';\n}",
|
|
61
|
+
"description": "Enable expandable vertical tabs at various breakpoints. (isVertical should be set to true for this to work)"
|
|
62
|
+
},
|
|
53
63
|
{
|
|
54
64
|
"name": "id",
|
|
55
65
|
"type": "string",
|
|
@@ -66,6 +76,11 @@ const pageData = {
|
|
|
66
76
|
"description": "Enables box styling to the tab component",
|
|
67
77
|
"defaultValue": "false"
|
|
68
78
|
},
|
|
79
|
+
{
|
|
80
|
+
"name": "isExpanded",
|
|
81
|
+
"type": "boolean",
|
|
82
|
+
"description": "Flag to indicate if the vertical tabs are expanded"
|
|
83
|
+
},
|
|
69
84
|
{
|
|
70
85
|
"name": "isFilled",
|
|
71
86
|
"type": "boolean",
|
|
@@ -102,6 +117,12 @@ const pageData = {
|
|
|
102
117
|
"description": "Callback to handle tab selection",
|
|
103
118
|
"defaultValue": "() => undefined as any"
|
|
104
119
|
},
|
|
120
|
+
{
|
|
121
|
+
"name": "onToggle",
|
|
122
|
+
"type": "(isExpanded: boolean) => void",
|
|
123
|
+
"description": "Callback function to toggle the expandable tabs.",
|
|
124
|
+
"defaultValue": "(isExpanded): void => undefined"
|
|
125
|
+
},
|
|
105
126
|
{
|
|
106
127
|
"name": "ouiaSafe",
|
|
107
128
|
"type": "No type info",
|
|
@@ -113,6 +134,16 @@ const pageData = {
|
|
|
113
134
|
"description": "Aria-label for the right scroll button",
|
|
114
135
|
"defaultValue": "'Scroll right'"
|
|
115
136
|
},
|
|
137
|
+
{
|
|
138
|
+
"name": "toggleAriaLabel",
|
|
139
|
+
"type": "string",
|
|
140
|
+
"description": "Aria-label for the left expandable toggle"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"name": "toggleText",
|
|
144
|
+
"type": "string",
|
|
145
|
+
"description": "Text that appears in the expandable toggle"
|
|
146
|
+
},
|
|
116
147
|
{
|
|
117
148
|
"name": "unmountOnExit",
|
|
118
149
|
"type": "boolean",
|
|
@@ -293,6 +324,8 @@ const pageData = {
|
|
|
293
324
|
"Box light variation",
|
|
294
325
|
"Default overflow",
|
|
295
326
|
"Vertical",
|
|
327
|
+
"Vertical expandable",
|
|
328
|
+
"Vertical expandable uncontrolled",
|
|
296
329
|
"Inset",
|
|
297
330
|
"Page Insets",
|
|
298
331
|
"Icons and text",
|
|
@@ -335,6 +368,14 @@ pageData.examples = {
|
|
|
335
368
|
'Vertical': props =>
|
|
336
369
|
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport { Tabs, Tab, TabTitleText, Checkbox, Tooltip } from '@patternfly/react-core';\n\nclass VerticalTabs extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n activeTabKey: 0,\n isBox: false\n };\n // Toggle currently active tab\n this.handleTabClick = (event, tabIndex) => {\n this.setState({\n activeTabKey: tabIndex\n });\n };\n\n this.toggleBox = checked => {\n this.setState({\n isBox: checked\n });\n };\n }\n\n render() {\n const {activeTabKey, isBox} = this.state;\n const tooltipRef = React.createRef();\n return (\n <div>\n <Tabs activeKey={activeTabKey} onSelect={this.handleTabClick} isVertical isBox={isBox}>\n <Tab eventKey={0} title={<TabTitleText>Users</TabTitleText>}>\n Users\n </Tab>\n <Tab eventKey={1} title={<TabTitleText>Containers</TabTitleText>}>\n Containers\n </Tab>\n <Tab eventKey={2} title={<TabTitleText>Database</TabTitleText>}>\n Database\n </Tab>\n <Tab eventKey={3} title={<TabTitleText>Disabled</TabTitleText>} isDisabled>\n Disabled\n </Tab>\n <Tab eventKey={4} title={<TabTitleText>ARIA Disabled</TabTitleText>} isAriaDisabled>\n ARIA Disabled\n </Tab>\n <Tab eventKey={5} title={<TabTitleText>ARIA Disabled (Tooltip)</TabTitleText>} isAriaDisabled ref={tooltipRef}>\n ARIA Disabled (Tooltip)\n </Tab>\n </Tabs>\n <Tooltip content=\"Aria-disabled tabs are like disabled tabs, but focusable. Allows for tooltip support.\" reference={tooltipRef} position=\"right\" />\n <div style={{marginTop: \"20px\"}}>\n <Checkbox\n label=\"isBox\"\n isChecked={isBox}\n onChange={this.toggleBox}\n aria-label=\"show box variation checkbox with vertical\"\n id=\"toggle-box-vertical\"\n name=\"toggle-box-vertical\"\n />\n </div>\n </div>\n );\n }\n}","title":"Vertical","lang":"js"}}>
|
|
337
370
|
|
|
371
|
+
</Example>,
|
|
372
|
+
'Vertical expandable': props =>
|
|
373
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core';\nclass VerticalExpandableTabs extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n activeTabKey: 0,\n isExpanded: false\n };\n // Toggle currently active tab\n this.handleTabClick = (event, tabIndex) => {\n this.setState({\n activeTabKey: tabIndex\n });\n };\n this.onToggle = isExpanded => {\n this.setState({\n isExpanded\n });\n };\n }\n render() {\n const {activeTabKey, isExpanded} = this.state;\n return (\n <Tabs activeKey={activeTabKey} onSelect={this.handleTabClick} isVertical expandable={{default: 'expandable', md: 'nonExpandable', lg: 'expandable'}} isExpanded={isExpanded} onToggle={this.onToggle} toggleText=\"Containers\">\n <Tab eventKey={0} title={<TabTitleText>Users</TabTitleText>}>\n Users\n </Tab>\n <Tab eventKey={1} title={<TabTitleText>Containers</TabTitleText>}>\n Containers\n </Tab>\n <Tab eventKey={2} title={<TabTitleText>Database</TabTitleText>}>\n Database\n </Tab>\n <Tab eventKey={3} title={<TabTitleText>Server</TabTitleText>}>\n Server\n </Tab>\n <Tab eventKey={4} title={<TabTitleText>System</TabTitleText>}>\n System\n </Tab>\n <Tab eventKey={6} title={<TabTitleText>Network</TabTitleText>}>\n Network\n </Tab>\n </Tabs>\n );\n }\n}","title":"Vertical expandable","lang":"js"}}>
|
|
374
|
+
|
|
375
|
+
</Example>,
|
|
376
|
+
'Vertical expandable uncontrolled': props =>
|
|
377
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core';\nclass VerticalExpandableUncontrolledTabs extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n activeTabKey: 0\n };\n // Toggle currently active tab\n this.handleTabClick = (event, tabIndex) => {\n this.setState({\n activeTabKey: tabIndex\n });\n };\n }\n render() {\n const {activeTabKey} = this.state;\n return (\n <Tabs activeKey={activeTabKey} onSelect={this.handleTabClick} isVertical expandable={{default: 'expandable', md: 'nonExpandable', lg: 'expandable'}} defaultIsExpanded={false} toggleText=\"Containers\">\n <Tab eventKey={0} title={<TabTitleText>Users</TabTitleText>}>\n Users\n </Tab>\n <Tab eventKey={1} title={<TabTitleText>Containers</TabTitleText>}>\n Containers\n </Tab>\n <Tab eventKey={2} title={<TabTitleText>Database</TabTitleText>}>\n Database\n </Tab>\n <Tab eventKey={3} title={<TabTitleText>Server</TabTitleText>}>\n Server\n </Tab>\n <Tab eventKey={4} title={<TabTitleText>System</TabTitleText>}>\n System\n </Tab>\n <Tab eventKey={6} title={<TabTitleText>Network</TabTitleText>}>\n Network\n </Tab>\n </Tabs>\n );\n }\n}","title":"Vertical expandable uncontrolled","lang":"js"}}>
|
|
378
|
+
|
|
338
379
|
</Example>,
|
|
339
380
|
'Inset': props =>
|
|
340
381
|
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core';\n\nclass InsetTabs extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n activeTabKey: 0,\n isBox: false\n };\n // Toggle currently active tab\n this.handleTabClick = (event, tabIndex) => {\n this.setState({\n activeTabKey: tabIndex\n });\n };\n\n this.toggleBox = checked => {\n this.setState({\n isBox: checked\n });\n };\n }\n\n render() {\n const {activeTabKey, isBox} = this.state;\n return (\n <div>\n <Tabs activeKey={activeTabKey} onSelect={this.handleTabClick} inset={{\n default: 'insetNone',\n md: 'insetSm',\n xl: 'inset2xl',\n '2xl': 'insetLg'\n }}\n isBox={isBox}>\n <Tab eventKey={0} title={<TabTitleText>Users</TabTitleText>}>\n Users\n </Tab>\n <Tab eventKey={1} title={<TabTitleText>Containers</TabTitleText>}>\n Containers\n </Tab>\n <Tab eventKey={2} title={<TabTitleText>Database</TabTitleText>}>\n Database\n </Tab>\n <Tab eventKey={3} title={<TabTitleText>Server</TabTitleText>}>\n Server\n </Tab>\n <Tab eventKey={4} title={<TabTitleText>System</TabTitleText>}>\n System\n </Tab>\n <Tab eventKey={6} title={<TabTitleText>Network</TabTitleText>}>\n Network\n </Tab>\n </Tabs>\n <div style={{marginTop: \"20px\"}}>\n <Checkbox\n label=\"isBox\"\n isChecked={isBox}\n onChange={this.toggleBox}\n aria-label=\"show box variation checkbox with inset\"\n id=\"toggle-box-inset\"\n name=\"toggle-box-inset\"\n />\n </div>\n </div>\n );\n }\n}","title":"Inset","lang":"js"}}>
|
|
@@ -401,6 +442,8 @@ Similarly the 'Tab content light variation' checkbox affects the TabContent back
|
|
|
401
442
|
{React.createElement(pageData.examples["Box light variation"])}
|
|
402
443
|
{React.createElement(pageData.examples["Default overflow"])}
|
|
403
444
|
{React.createElement(pageData.examples["Vertical"])}
|
|
445
|
+
{React.createElement(pageData.examples["Vertical expandable"])}
|
|
446
|
+
{React.createElement(pageData.examples["Vertical expandable uncontrolled"])}
|
|
404
447
|
{React.createElement(pageData.examples["Inset"])}
|
|
405
448
|
{React.createElement(pageData.examples["Page Insets"])}
|
|
406
449
|
{React.createElement(pageData.examples["Icons and text"])}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -30,7 +30,8 @@ const pageData = {
|
|
|
30
30
|
"Filter tree menu",
|
|
31
31
|
"Flyout",
|
|
32
32
|
"Application launcher using menu components",
|
|
33
|
-
"Context selector using menu components"
|
|
33
|
+
"Context selector using menu components",
|
|
34
|
+
"Options menu using menu components"
|
|
34
35
|
]
|
|
35
36
|
};
|
|
36
37
|
pageData.liveContext = {
|
|
@@ -51,27 +52,27 @@ pageData.liveContext = {
|
|
|
51
52
|
};
|
|
52
53
|
pageData.examples = {
|
|
53
54
|
'Basic menu with toggle': props =>
|
|
54
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport { MenuToggle, Menu, MenuContent, MenuList, MenuItem, Popper } from '@patternfly/react-core';\n\nBasicComposableMenu = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (!isOpen) {\n return;\n }\n if (menuRef.current.contains(event.target) || toggleRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n const firstElement = menuRef.current.querySelector('li > button:not(:disabled)');\n
|
|
55
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport { MenuToggle, Menu, MenuContent, MenuList, MenuItem, Popper } from '@patternfly/react-core';\n\nBasicComposableMenu = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (!isOpen) {\n return;\n }\n if (menuRef.current.contains(event.target) || toggleRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n if (menuRef.current) {\n const firstElement = menuRef.current.querySelector('li > button:not(:disabled)');\n firstElement && firstElement.focus();\n }\n }, 0);\n setIsOpen(!isOpen);\n };\n\n const toggle = (\n <MenuToggle ref={toggleRef} onClick={onToggleClick} isExpanded={isOpen}>\n {isOpen ? 'Expanded' : 'Collapsed'}\n </MenuToggle>\n );\n const menu = (\n <Menu ref={menuRef} onSelect={(_ev, itemId) => console.log('selected', itemId)}>\n <MenuContent>\n <MenuList>\n <MenuItem itemId={0}>Action</MenuItem>\n <MenuItem itemId={1} to=\"#default-link2\" onClick={ev => ev.preventDefault()}>\n Link\n </MenuItem>\n <MenuItem isDisabled>Disabled Action</MenuItem>\n <MenuItem isDisabled to=\"#default-link4\">\n Disabled Link\n </MenuItem>\n </MenuList>\n </MenuContent>\n </Menu>\n );\n return <Popper trigger={toggle} popper={menu} isVisible={isOpen} />;\n};","title":"Basic menu with toggle","lang":"js"}}>
|
|
55
56
|
|
|
56
57
|
</Example>,
|
|
57
58
|
'Menu with actions': props =>
|
|
58
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n MenuToggle,\n Menu,\n MenuContent,\n MenuList,\n MenuItem,\n MenuGroup,\n MenuItemAction,\n Popper\n} from '@patternfly/react-core';\nimport BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';\nimport ClipboardIcon from '@patternfly/react-icons/dist/esm/icons/clipboard-icon';\nimport CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon';\nimport LayerGroupIcon from '@patternfly/react-icons/dist/esm/icons/layer-group-icon';\nimport CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';\nimport TableIcon from '@patternfly/react-icons/dist/esm/icons/table-icon';\nimport BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';\n\nActionComposableMenu = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [selectedItems, setSelectedItems] = React.useState([]);\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (isOpen && menuRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onSelect = (event, itemId) => {\n if (selectedItems.includes(itemId)) {\n setSelectedItems(selectedItems.filter(id => id !== itemId));\n } else {\n setSelectedItems([...selectedItems, itemId]);\n }\n };\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n const firstElement = menuRef.current.querySelector('li > button:not(:disabled)');\n
|
|
59
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n MenuToggle,\n Menu,\n MenuContent,\n MenuList,\n MenuItem,\n MenuGroup,\n MenuItemAction,\n Popper\n} from '@patternfly/react-core';\nimport BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';\nimport ClipboardIcon from '@patternfly/react-icons/dist/esm/icons/clipboard-icon';\nimport CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon';\nimport LayerGroupIcon from '@patternfly/react-icons/dist/esm/icons/layer-group-icon';\nimport CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';\nimport TableIcon from '@patternfly/react-icons/dist/esm/icons/table-icon';\nimport BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';\n\nActionComposableMenu = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [selectedItems, setSelectedItems] = React.useState([]);\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (isOpen && menuRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onSelect = (event, itemId) => {\n if (selectedItems.includes(itemId)) {\n setSelectedItems(selectedItems.filter(id => id !== itemId));\n } else {\n setSelectedItems([...selectedItems, itemId]);\n }\n };\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n if (menuRef.current) {\n const firstElement = menuRef.current.querySelector('li > button:not(:disabled)');\n firstElement && firstElement.focus();\n }\n }, 0);\n setIsOpen(!isOpen);\n };\n\n const toggle = (\n <MenuToggle ref={toggleRef} onClick={onToggleClick} isExpanded={isOpen}>\n {isOpen ? 'Expanded' : 'Collapsed'}\n </MenuToggle>\n );\n const menu = (\n <Menu\n ref={menuRef}\n onActionClick={(event, itemId, actionId) => console.log(`clicked on ${itemId} - ${actionId}`)}\n onSelect={onSelect}\n >\n <MenuGroup label=\"Actions\">\n <MenuList>\n <MenuItem\n isSelected={selectedItems.includes(0)}\n actions={\n <MenuItemAction\n icon={<CodeBranchIcon aria-hidden />}\n actionId=\"code\"\n onClick={() => console.log('clicked on code icon')}\n aria-label=\"Code\"\n />\n }\n description=\"This is a description\"\n itemId={0}\n >\n Item 1\n </MenuItem>\n <MenuItem\n isDisabled\n isSelected={selectedItems.includes(1)}\n actions={<MenuItemAction icon={<BellIcon aria-hidden />} actionId=\"alert\" aria-label=\"Alert\" />}\n description=\"This is a description\"\n itemId={1}\n >\n Item 2\n </MenuItem>\n <MenuItem\n isSelected={selectedItems.includes(2)}\n actions={<MenuItemAction icon={<ClipboardIcon aria-hidden />} actionId=\"copy\" aria-label=\"Copy\" />}\n itemId={2}\n >\n Item 3\n </MenuItem>\n <MenuItem\n isSelected={selectedItems.includes(3)}\n actions={<MenuItemAction icon={<BarsIcon aria-hidden />} actionId=\"expand\" aria-label=\"Expand\" />}\n description=\"This is a description\"\n itemId={3}\n >\n Item 4\n </MenuItem>\n </MenuList>\n </MenuGroup>\n </Menu>\n );\n\n return <Popper trigger={toggle} popper={menu} isVisible={isOpen} />;\n};","title":"Menu with actions","lang":"js"}}>
|
|
59
60
|
|
|
60
61
|
</Example>,
|
|
61
62
|
'Select menu': props =>
|
|
62
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport { MenuToggle, Menu, MenuContent, MenuList, MenuItem, Popper } from '@patternfly/react-core';\nimport TableIcon from '@patternfly/react-icons/dist/esm/icons/table-icon';\n\nSelectComposableMenu = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [selected, setSelected] = React.useState('Select a value');\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (isOpen && menuRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n const firstElement = menuRef.current.querySelector('li > button:not(:disabled)');\n
|
|
63
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport { MenuToggle, Menu, MenuContent, MenuList, MenuItem, Popper } from '@patternfly/react-core';\nimport TableIcon from '@patternfly/react-icons/dist/esm/icons/table-icon';\n\nSelectComposableMenu = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [selected, setSelected] = React.useState('Select a value');\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (isOpen && menuRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n if (menuRef.current) {\n const firstElement = menuRef.current.querySelector('li > button:not(:disabled)');\n firstElement && firstElement.focus();\n }\n }, 0);\n setIsOpen(!isOpen);\n };\n\n const toggle = (\n <MenuToggle ref={toggleRef} onClick={onToggleClick} isExpanded={isOpen}>\n {selected}\n </MenuToggle>\n );\n const menu = (\n <Menu ref={menuRef} id=\"select-menu\" onSelect={(_ev, itemId) => setSelected(itemId)} selected={selected}>\n <MenuContent>\n <MenuList>\n <MenuItem itemId=\"Option 1\">Option 1</MenuItem>\n <MenuItem itemId=\"Option 2\">Option 2</MenuItem>\n <MenuItem itemId=\"Option 3\" icon={<TableIcon aria-hidden />}>\n Option 3\n </MenuItem>\n </MenuList>\n </MenuContent>\n </Menu>\n );\n return <Popper trigger={toggle} popper={menu} isVisible={isOpen} />;\n};","title":"Select menu","lang":"js"}}>
|
|
63
64
|
|
|
64
65
|
</Example>,
|
|
65
66
|
'Drilldown menu with toggle': props =>
|
|
66
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n MenuToggle,\n Menu,\n MenuContent,\n MenuList,\n MenuItem,\n DrilldownMenu,\n Divider,\n Popper\n} from '@patternfly/react-core';\nimport StorageDomainIcon from '@patternfly/react-icons/dist/esm/icons/storage-domain-icon';\nimport CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon';\nimport LayerGroupIcon from '@patternfly/react-icons/dist/esm/icons/layer-group-icon';\nimport CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';\n\nDrilldownComposableMenu = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [activeMenu, setActiveMenu] = React.useState('rootMenu');\n const [menuDrilledIn, setMenuDrilledIn] = React.useState([]);\n const [drilldownPath, setDrilldownPath] = React.useState([]);\n const [menuHeights, setMenuHeights] = React.useState({});\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (isOpen && menuRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n const firstElement = menuRef.current.querySelector('li > button:not(:disabled)');\n
|
|
67
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n MenuToggle,\n Menu,\n MenuContent,\n MenuList,\n MenuItem,\n DrilldownMenu,\n Divider,\n Popper\n} from '@patternfly/react-core';\nimport StorageDomainIcon from '@patternfly/react-icons/dist/esm/icons/storage-domain-icon';\nimport CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon';\nimport LayerGroupIcon from '@patternfly/react-icons/dist/esm/icons/layer-group-icon';\nimport CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';\n\nDrilldownComposableMenu = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [activeMenu, setActiveMenu] = React.useState('rootMenu');\n const [menuDrilledIn, setMenuDrilledIn] = React.useState([]);\n const [drilldownPath, setDrilldownPath] = React.useState([]);\n const [menuHeights, setMenuHeights] = React.useState({});\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (isOpen && menuRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n if (menuRef.current) {\n const firstElement = menuRef.current.querySelector('li > button:not(:disabled)');\n firstElement && firstElement.focus();\n }\n }, 0);\n setIsOpen(!isOpen);\n setMenuDrilledIn([]);\n setDrilldownPath([]);\n setActiveMenu('rootMenu');\n };\n\n const drillIn = (fromMenuId, toMenuId, pathId) => {\n setMenuDrilledIn([...menuDrilledIn, fromMenuId]);\n setDrilldownPath([...drilldownPath, pathId]);\n setActiveMenu(toMenuId);\n };\n\n const drillOut = toMenuId => {\n setMenuDrilledIn(menuDrilledIn.slice(0, menuDrilledIn.length - 1));\n setDrilldownPath(drilldownPath.slice(0, drilldownPath.length - 1));\n setActiveMenu(toMenuId);\n };\n\n const setHeight = (menuId, height) => {\n if (!menuHeights[menuId]) {\n setMenuHeights({\n ...menuHeights,\n [menuId]: height\n });\n }\n };\n\n const toggle = (\n <MenuToggle ref={toggleRef} onClick={onToggleClick} isExpanded={isOpen}>\n {isOpen ? 'Expanded' : 'Collapsed'}\n </MenuToggle>\n );\n const menu = (\n <Menu\n id=\"rootMenu\"\n containsDrilldown\n drilldownItemPath={drilldownPath}\n drilledInMenus={menuDrilledIn}\n activeMenu={activeMenu}\n onDrillIn={drillIn}\n onDrillOut={drillOut}\n onGetMenuHeight={setHeight}\n ref={menuRef}\n >\n <MenuContent menuHeight={`${menuHeights[activeMenu]}px`}>\n <MenuList>\n <MenuItem\n itemId=\"group:start_rollout\"\n direction=\"down\"\n drilldownMenu={\n <DrilldownMenu id=\"drilldownMenuStart\">\n <MenuItem itemId=\"group:start_rollout\" direction=\"up\">\n Start rollout\n </MenuItem>\n <Divider component=\"li\" />\n <MenuItem\n itemId=\"group:app_grouping\"\n description=\"Groups A-C\"\n direction=\"down\"\n drilldownMenu={\n <DrilldownMenu id=\"drilldownMenuStartGrouping\">\n <MenuItem itemId=\"group:app_grouping\" direction=\"up\">\n Application Grouping\n </MenuItem>\n <Divider component=\"li\" />\n <MenuItem itemId=\"group_a\">Group A</MenuItem>\n <MenuItem itemId=\"group_b\">Group B</MenuItem>\n <MenuItem itemId=\"group_c\">Group C</MenuItem>\n </DrilldownMenu>\n }\n >\n Application Grouping\n </MenuItem>\n <MenuItem itemId=\"count\">Count</MenuItem>\n <MenuItem\n itemId=\"group:labels\"\n direction=\"down\"\n drilldownMenu={\n <DrilldownMenu id=\"drilldownMenuStartLabels\">\n <MenuItem itemId=\"group:labels\" direction=\"up\">\n Labels\n </MenuItem>\n <Divider component=\"li\" />\n <MenuItem itemId=\"label_1\">Label 1</MenuItem>\n <MenuItem itemId=\"label_2\">Label 2</MenuItem>\n <MenuItem itemId=\"label_3\">Label 3</MenuItem>\n </DrilldownMenu>\n }\n >\n Labels\n </MenuItem>\n <MenuItem itemId=\"annotations\">Annotations</MenuItem>\n </DrilldownMenu>\n }\n >\n Start rollout\n </MenuItem>\n <MenuItem\n itemId=\"group:pause_rollout\"\n direction=\"down\"\n drilldownMenu={\n <DrilldownMenu id=\"drilldownMenuPause\">\n <MenuItem itemId=\"group:pause_rollout\" direction=\"up\">\n Pause rollouts\n </MenuItem>\n <Divider component=\"li\" />\n <MenuItem\n itemId=\"group:app_grouping\"\n description=\"Groups A-C\"\n direction=\"down\"\n drilldownMenu={\n <DrilldownMenu id=\"drilldownMenuGrouping\">\n <MenuItem itemId=\"group:app_grouping\" direction=\"up\">\n Application Grouping\n </MenuItem>\n <Divider component=\"li\" />\n <MenuItem itemId=\"group_a\">Group A</MenuItem>\n <MenuItem itemId=\"group_b\">Group B</MenuItem>\n <MenuItem itemId=\"group_c\">Group C</MenuItem>\n </DrilldownMenu>\n }\n >\n Application Grouping\n </MenuItem>\n <MenuItem itemId=\"count\">Count</MenuItem>\n <MenuItem\n itemId=\"group:labels\"\n direction=\"down\"\n drilldownMenu={\n <DrilldownMenu id=\"drilldownMenuLabels\">\n <MenuItem itemId=\"group:labels\" direction=\"up\">\n Labels\n </MenuItem>\n <Divider component=\"li\" />\n <MenuItem itemId=\"label_1\">Label 1</MenuItem>\n <MenuItem itemId=\"label_2\">Label 2</MenuItem>\n <MenuItem itemId=\"label_3\">Label 3</MenuItem>\n </DrilldownMenu>\n }\n >\n Labels\n </MenuItem>\n <MenuItem itemId=\"annotations\">Annotations</MenuItem>\n </DrilldownMenu>\n }\n >\n Pause rollouts\n </MenuItem>\n <MenuItem\n itemId=\"group:storage\"\n icon={<StorageDomainIcon aria-hidden />}\n direction=\"down\"\n drilldownMenu={\n <DrilldownMenu id=\"drilldownMenuStorage\">\n <MenuItem itemId=\"group:storage\" icon={<StorageDomainIcon aria-hidden />} direction=\"up\">\n Add storage\n </MenuItem>\n <Divider component=\"li\" />\n <MenuItem icon={<CodeBranchIcon aria-hidden />} itemId=\"git\">\n From Git\n </MenuItem>\n <MenuItem icon={<LayerGroupIcon aria-hidden />} itemId=\"container\">\n Container Image\n </MenuItem>\n <MenuItem icon={<CubeIcon aria-hidden />} itemId=\"docker\">\n Docker File\n </MenuItem>\n </DrilldownMenu>\n }\n >\n Add storage\n </MenuItem>\n <MenuItem itemId=\"edit\">Edit</MenuItem>\n <MenuItem itemId=\"delete_deployment\">Delete deployment config</MenuItem>\n </MenuList>\n </MenuContent>\n </Menu>\n );\n return <Popper trigger={toggle} popper={menu} isVisible={isOpen} />;\n};","title":"Drilldown menu with toggle","lang":"js"}}>
|
|
67
68
|
|
|
68
69
|
</Example>,
|
|
69
70
|
'Filter tree menu': props =>
|
|
70
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport { MenuToggle, Menu, MenuContent, MenuGroup, MenuList, MenuItem, Popper, TreeView } from '@patternfly/react-core';\n\nFilterTreeComposableMenu = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [checkedItems, setCheckedItems] = React.useState([]);\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n\n const statusOptions = [\n {\n name: 'Ready',\n id: 'ready',\n checkProps: { checked: false },\n customBadgeContent: 1,\n children: [\n {\n name: 'Updated',\n id: 'updated',\n checkProps: { checked: false },\n customBadgeContent: 0\n },\n {\n name: 'Waiting to update',\n id: 'waiting',\n checkProps: { checked: false },\n customBadgeContent: 0\n },\n {\n name: 'Conditions degraded',\n id: 'degraded',\n checkProps: { checked: false },\n customBadgeContent: 1\n },\n {\n name: 'Approval required',\n id: 'approval',\n checkProps: { checked: false },\n customBadgeContent: 0\n }\n ]\n },\n {\n name: 'Not ready',\n id: 'nr',\n checkProps: { checked: false },\n customBadgeContent: 1,\n children: [\n {\n name: 'Conditions degraded',\n id: 'nr-degraded',\n checkProps: { checked: false },\n customBadgeContent: 1\n }\n ]\n },\n {\n name: 'Updating',\n id: 'updating',\n checkProps: { checked: false },\n customBadgeContent: 0\n }\n ];\n\n const roleOptions = [\n {\n name: 'Server',\n id: 'server',\n checkProps: { checked: false },\n customBadgeContent: 2\n },\n {\n name: 'Worker',\n id: 'worker',\n checkProps: { checked: false },\n customBadgeContent: 0\n }\n ];\n // Helper functions\n const isChecked = dataItem => checkedItems.some(item => item.id === dataItem.id);\n const areAllDescendantsChecked = dataItem =>\n dataItem.children ? dataItem.children.every(child => areAllDescendantsChecked(child)) : isChecked(dataItem);\n const areSomeDescendantsChecked = dataItem =>\n dataItem.children ? dataItem.children.some(child => areSomeDescendantsChecked(child)) : isChecked(dataItem);\n const flattenTree = tree => {\n var result = [];\n tree.forEach(item => {\n result.push(item);\n if (item.children) {\n result = result.concat(flattenTree(item.children));\n }\n });\n return result;\n };\n\n mapTree = item => {\n const hasCheck = areAllDescendantsChecked(item);\n // Reset checked properties to be updated\n item.checkProps.checked = false;\n\n if (hasCheck) {\n item.checkProps.checked = true;\n } else {\n const hasPartialCheck = areSomeDescendantsChecked(item);\n if (hasPartialCheck) {\n item.checkProps.checked = null;\n }\n }\n\n if (item.children) {\n return {\n ...item,\n children: item.children.map(mapTree)\n };\n }\n return item;\n };\n\n filterItems = (item, checkedItem) => {\n if (item.id === checkedItem.id) {\n return true;\n }\n\n if (item.children) {\n return (\n (item.children = item.children\n .map(opt => Object.assign({}, opt))\n .filter(child => filterItems(child, checkedItem))).length > 0\n );\n }\n };\n\n const onCheck = (evt, treeViewItem, tree) => {\n const checked = evt.target.checked;\n\n let options = [];\n switch (tree) {\n case 'status':\n options = statusOptions;\n break;\n case 'role':\n options = roleOptions;\n break;\n default:\n break;\n }\n\n const checkedItemTree = options.map(opt => Object.assign({}, opt)).filter(item => filterItems(item, treeViewItem));\n const flatCheckedItems = flattenTree(checkedItemTree);\n\n setCheckedItems(\n prevState =>\n checked\n ? prevState.checkedItems.concat(\n flatCheckedItems.filter(item => !prevState.checkedItems.some(i => i.id === item.id))\n )\n : prevState.checkedItems.filter(item => !flatCheckedItems.some(i => i.id === item.id)),\n () => {\n console.log('Checked items: ', checkedItems);\n }\n );\n };\n\n const handleMenuKeys = event => {\n if (!isOpen) {\n return;\n }\n if (menuRef.current.contains(event.target) || toggleRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n
|
|
71
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport { MenuToggle, Menu, MenuContent, MenuGroup, MenuList, MenuItem, Popper, TreeView } from '@patternfly/react-core';\n\nFilterTreeComposableMenu = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [checkedItems, setCheckedItems] = React.useState([]);\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n\n const statusOptions = [\n {\n name: 'Ready',\n id: 'ready',\n checkProps: { checked: false },\n customBadgeContent: 1,\n children: [\n {\n name: 'Updated',\n id: 'updated',\n checkProps: { checked: false },\n customBadgeContent: 0\n },\n {\n name: 'Waiting to update',\n id: 'waiting',\n checkProps: { checked: false },\n customBadgeContent: 0\n },\n {\n name: 'Conditions degraded',\n id: 'degraded',\n checkProps: { checked: false },\n customBadgeContent: 1\n },\n {\n name: 'Approval required',\n id: 'approval',\n checkProps: { checked: false },\n customBadgeContent: 0\n }\n ]\n },\n {\n name: 'Not ready',\n id: 'nr',\n checkProps: { checked: false },\n customBadgeContent: 1,\n children: [\n {\n name: 'Conditions degraded',\n id: 'nr-degraded',\n checkProps: { checked: false },\n customBadgeContent: 1\n }\n ]\n },\n {\n name: 'Updating',\n id: 'updating',\n checkProps: { checked: false },\n customBadgeContent: 0\n }\n ];\n\n const roleOptions = [\n {\n name: 'Server',\n id: 'server',\n checkProps: { checked: false },\n customBadgeContent: 2\n },\n {\n name: 'Worker',\n id: 'worker',\n checkProps: { checked: false },\n customBadgeContent: 0\n }\n ];\n // Helper functions\n const isChecked = dataItem => checkedItems.some(item => item.id === dataItem.id);\n const areAllDescendantsChecked = dataItem =>\n dataItem.children ? dataItem.children.every(child => areAllDescendantsChecked(child)) : isChecked(dataItem);\n const areSomeDescendantsChecked = dataItem =>\n dataItem.children ? dataItem.children.some(child => areSomeDescendantsChecked(child)) : isChecked(dataItem);\n const flattenTree = tree => {\n var result = [];\n tree.forEach(item => {\n result.push(item);\n if (item.children) {\n result = result.concat(flattenTree(item.children));\n }\n });\n return result;\n };\n\n mapTree = item => {\n const hasCheck = areAllDescendantsChecked(item);\n // Reset checked properties to be updated\n item.checkProps.checked = false;\n\n if (hasCheck) {\n item.checkProps.checked = true;\n } else {\n const hasPartialCheck = areSomeDescendantsChecked(item);\n if (hasPartialCheck) {\n item.checkProps.checked = null;\n }\n }\n\n if (item.children) {\n return {\n ...item,\n children: item.children.map(mapTree)\n };\n }\n return item;\n };\n\n filterItems = (item, checkedItem) => {\n if (item.id === checkedItem.id) {\n return true;\n }\n\n if (item.children) {\n return (\n (item.children = item.children\n .map(opt => Object.assign({}, opt))\n .filter(child => filterItems(child, checkedItem))).length > 0\n );\n }\n };\n\n const onCheck = (evt, treeViewItem, tree) => {\n const checked = evt.target.checked;\n\n let options = [];\n switch (tree) {\n case 'status':\n options = statusOptions;\n break;\n case 'role':\n options = roleOptions;\n break;\n default:\n break;\n }\n\n const checkedItemTree = options.map(opt => Object.assign({}, opt)).filter(item => filterItems(item, treeViewItem));\n const flatCheckedItems = flattenTree(checkedItemTree);\n\n setCheckedItems(\n prevState =>\n checked\n ? prevState.checkedItems.concat(\n flatCheckedItems.filter(item => !prevState.checkedItems.some(i => i.id === item.id))\n )\n : prevState.checkedItems.filter(item => !flatCheckedItems.some(i => i.id === item.id)),\n () => {\n console.log('Checked items: ', checkedItems);\n }\n );\n };\n\n const handleMenuKeys = event => {\n if (!isOpen) {\n return;\n }\n if (menuRef.current.contains(event.target) || toggleRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n if (menuRef.current) {\n const firstElement = menuRef.current.querySelector('li > button:not(:disabled)');\n firstElement && firstElement.focus();\n }\n }, 0);\n setIsOpen(!isOpen);\n };\n\n const toggle = (\n <MenuToggle ref={toggleRef} onClick={onToggleClick} isExpanded={isOpen}>\n {isOpen ? 'Expanded' : 'Collapsed'}\n </MenuToggle>\n );\n const statusMapped = statusOptions.map(mapTree);\n const roleMapped = roleOptions.map(mapTree);\n const menu = (\n <Menu ref={menuRef} onSelect={(_ev, itemId) => console.log('selected', itemId)}>\n <MenuContent>\n <MenuList>\n <MenuGroup label=\"Status\">\n <TreeView\n data={statusMapped}\n hasBadges\n hasChecks\n onCheck={(event, item, parentItem) => onCheck(event, item, 'status')}\n />\n </MenuGroup>\n <MenuGroup label=\"Role\">\n <TreeView\n data={roleMapped}\n hasBadges\n hasChecks\n onCheck={(event, item, parentItem) => onCheck(event, item, 'role')}\n />\n </MenuGroup>\n </MenuList>\n </MenuContent>\n </Menu>\n );\n return <Popper trigger={toggle} popper={menu} isVisible={isOpen} />;\n};","title":"Filter tree menu","lang":"js"}}>
|
|
71
72
|
|
|
72
73
|
</Example>,
|
|
73
74
|
'Flyout': props =>
|
|
74
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport { MenuToggle, Menu, MenuContent, MenuGroup, MenuList, MenuItem, Popper } from '@patternfly/react-core';\n\nMenuWithFlyout = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const menuRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (!isOpen) {\n return;\n }\n if (menuRef.current.contains(event.target) || toggleRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onSelect = itemId => console.log('selected', itemId);\n\n const numFlyouts = 15;\n const FlyoutMenu = ({ depth, children }) => (\n <Menu key={depth} containsFlyout id={`menu-${depth}`} onSelect={onSelect}>\n <MenuContent>\n <MenuList>\n <MenuItem flyoutMenu={children} itemId={`next-menu-${depth}`}>\n Next menu\n </MenuItem>\n {[...Array(numFlyouts - depth).keys()].map(j => (\n <MenuItem key={`${depth}-${j}`} itemId={`${depth}-${j}`}>\n Menu {depth} item {j}\n </MenuItem>\n ))}\n <MenuItem flyoutMenu={children} itemId={`next-menu-2-${depth}`}>\n Next menu\n </MenuItem>\n </MenuList>\n </MenuContent>\n </Menu>\n );\n let curFlyout = <FlyoutMenu depth={1} />;\n for (let i = 2; i < numFlyouts - 1; i++) {\n curFlyout = <FlyoutMenu depth={i}>{curFlyout}</FlyoutMenu>;\n }\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n const firstElement = menuRef.current.querySelector('li > button:not(:disabled)');\n
|
|
75
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport { MenuToggle, Menu, MenuContent, MenuGroup, MenuList, MenuItem, Popper } from '@patternfly/react-core';\n\nMenuWithFlyout = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const menuRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (!isOpen) {\n return;\n }\n if (menuRef.current.contains(event.target) || toggleRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onSelect = itemId => console.log('selected', itemId);\n\n const numFlyouts = 15;\n const FlyoutMenu = ({ depth, children }) => (\n <Menu key={depth} containsFlyout id={`menu-${depth}`} onSelect={onSelect}>\n <MenuContent>\n <MenuList>\n <MenuItem flyoutMenu={children} itemId={`next-menu-${depth}`}>\n Next menu\n </MenuItem>\n {[...Array(numFlyouts - depth).keys()].map(j => (\n <MenuItem key={`${depth}-${j}`} itemId={`${depth}-${j}`}>\n Menu {depth} item {j}\n </MenuItem>\n ))}\n <MenuItem flyoutMenu={children} itemId={`next-menu-2-${depth}`}>\n Next menu\n </MenuItem>\n </MenuList>\n </MenuContent>\n </Menu>\n );\n let curFlyout = <FlyoutMenu depth={1} />;\n for (let i = 2; i < numFlyouts - 1; i++) {\n curFlyout = <FlyoutMenu depth={i}>{curFlyout}</FlyoutMenu>;\n }\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n if (menuRef.current) {\n const firstElement = menuRef.current.querySelector('li > button:not(:disabled)');\n firstElement && firstElement.focus();\n }\n }, 0);\n setIsOpen(!isOpen);\n };\n\n const toggle = (\n <MenuToggle onClick={onToggleClick} isExpanded={isOpen}>\n {isOpen ? 'Expanded' : 'Collapsed'}\n </MenuToggle>\n );\n\n const menu = (\n <Menu ref={menuRef} containsFlyout onSelect={onSelect}>\n <MenuContent>\n <MenuList>\n <MenuItem itemId=\"start\">Start rollout</MenuItem>\n <MenuItem itemId=\"pause\">Pause rollouts</MenuItem>\n <MenuItem itemId=\"storage\">Add storage</MenuItem>\n <MenuItem description=\"Description\" flyoutMenu={curFlyout} itemId=\"next-menu-root\">\n Edit\n </MenuItem>\n <MenuItem itemId=\"delete\">Delete deployment config</MenuItem>\n </MenuList>\n </MenuContent>\n </Menu>\n );\n\n return <Popper trigger={toggle} popper={menu} isVisible={isOpen} popperMatchesTriggerWidth={false} />;\n};","title":"Flyout","lang":"js"}}>
|
|
75
76
|
|
|
76
77
|
<p {...{"className":"ws-p"}}>
|
|
77
78
|
{`The flyout will automatically position to the left or top if it would otherwise go outside the window. The menu must be placed in a container outside the main content like Popper, `}
|
|
@@ -88,11 +89,15 @@ pageData.examples = {
|
|
|
88
89
|
</p>
|
|
89
90
|
</Example>,
|
|
90
91
|
'Application launcher using menu components': props =>
|
|
91
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n MenuToggle,\n Menu,\n MenuContent,\n MenuList,\n MenuItem,\n MenuGroup,\n MenuInput,\n Popper,\n Tooltip,\n Divider,\n TextInput\n} from '@patternfly/react-core';\nimport { Link } from '@reach/router';\nimport ThIcon from '@patternfly/react-icons/dist/js/icons/th-icon';\nimport pfIcon from './examples/pf-logo-small.svg';\n\nMenuAppLauncher = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [refFullOptions, setRefFullOptions] = React.useState();\n const [favorites, setFavorites] = React.useState([]);\n const [filteredIds, setFilteredIds] = React.useState(['*']);\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n const containerRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (!isOpen) {\n return;\n }\n if (menuRef.current.contains(event.target) || toggleRef.current.contains(event.target)) {\n if (event.key === 'Escape') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n
|
|
92
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n MenuToggle,\n Menu,\n MenuContent,\n MenuList,\n MenuItem,\n MenuGroup,\n MenuInput,\n Popper,\n Tooltip,\n Divider,\n TextInput\n} from '@patternfly/react-core';\nimport { Link } from '@reach/router';\nimport ThIcon from '@patternfly/react-icons/dist/js/icons/th-icon';\nimport pfIcon from './examples/pf-logo-small.svg';\n\nMenuAppLauncher = () => {\n const [isOpen, setIsOpen] = React.useState(false);\n const [refFullOptions, setRefFullOptions] = React.useState();\n const [favorites, setFavorites] = React.useState([]);\n const [filteredIds, setFilteredIds] = React.useState(['*']);\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n const containerRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (!isOpen) {\n return;\n }\n if (menuRef.current.contains(event.target) || toggleRef.current.contains(event.target)) {\n if (event.key === 'Escape') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n if (menuRef.current) {\n const firstElement = menuRef.current.querySelector('li > button,input:not(:disabled)');\n firstElement && firstElement.focus();\n setRefFullOptions(Array.from(menuRef.current.querySelectorAll('li:not(li[role=separator])')));\n }\n }, 0);\n setIsOpen(!isOpen);\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const toggle = (\n <MenuToggle\n aria-label=\"Toggle\"\n ref={toggleRef}\n variant=\"plain\"\n onClick={onToggleClick}\n isExpanded={isOpen}\n style={{ width: 'auto' }}\n >\n <ThIcon />\n </MenuToggle>\n );\n\n const menuItems = [\n <MenuGroup key=\"group1\" label=\"Group 1\">\n <MenuList>\n <MenuItem itemId=\"0\" id=\"0\" isFavorited={favorites.includes('0')}>\n Application 1\n </MenuItem>\n <MenuItem\n itemId=\"1\"\n id=\"1\"\n isFavorited={favorites.includes('1')}\n to=\"#default-link2\"\n onClick={ev => ev.preventDefault()}\n >\n Application 2\n </MenuItem>\n </MenuList>\n </MenuGroup>,\n <Divider key=\"group1-divider\" />,\n <MenuGroup key=\"group2\" label=\"Group 2\">\n <MenuList>\n <MenuItem\n itemId=\"2\"\n id=\"2\"\n isFavorited={favorites.includes('2')}\n component={props => <Link {...props} to=\"#router-link\" />}\n >\n @reach/router Link\n </MenuItem>\n <MenuItem\n itemId=\"3\"\n id=\"3\"\n isFavorited={favorites.includes('3')}\n isExternalLink\n icon={<img src={pfIcon} />}\n component={props => <Link {...props} to=\"#router-link2\" />}\n >\n @reach/router Link with icon\n </MenuItem>\n </MenuList>\n </MenuGroup>,\n <Divider key=\"group2-divider\" />,\n <MenuList key=\"other-items\">\n <MenuItem key=\"tooltip-app\" isFavorited={favorites.includes('4')} itemId=\"4\" id=\"4\">\n <Tooltip content={<div>Launch Application 3</div>} position=\"right\">\n <span>Application 3 with tooltip</span>\n </Tooltip>\n </MenuItem>\n <MenuItem key=\"disabled-app\" itemId=\"5\" id=\"5\" isDisabled>\n Unavailable Application\n </MenuItem>\n </MenuList>\n ];\n\n const createFavorites = favIds => {\n let favorites = [];\n\n menuItems.forEach(item => {\n if (item.type === MenuList) {\n item.props.children.filter(child => {\n if (favIds.includes(child.props.itemId)) {\n favorites.push(child);\n }\n });\n } else if (item.type === MenuGroup) {\n item.props.children.props.children.filter(child => {\n if (favIds.includes(child.props.itemId)) {\n favorites.push(child);\n }\n });\n } else {\n if (favIds.includes(item.props.itemId)) {\n favorites.push(item);\n }\n }\n });\n\n return favorites;\n };\n\n const filterItems = (items, filteredIds) => {\n if (filteredIds.length === 1 && filteredIds[0] === '*') {\n return items;\n }\n let keepDivider = false;\n let filteredCopy = items\n .map(group => {\n if (group.type === MenuGroup) {\n let filteredGroup = React.cloneElement(group, {\n children: React.cloneElement(group.props.children, {\n children: group.props.children.props.children.filter(child => {\n if (filteredIds.includes(child.props.itemId)) {\n return child;\n }\n })\n })\n });\n const filteredList = filteredGroup.props.children;\n if (filteredList.props.children.length > 0) {\n keepDivider = true;\n return filteredGroup;\n } else {\n keepDivider = false;\n }\n } else if (group.type === MenuList) {\n let filteredGroup = React.cloneElement(group, {\n children: group.props.children.filter(child => {\n if (filteredIds.includes(child.props.itemId)) {\n return child;\n }\n })\n });\n if (filteredGroup.props.children.length > 0) {\n keepDivider = true;\n return filteredGroup;\n } else {\n keepDivider = false;\n }\n } else {\n if ((keepDivider && group.type === Divider) || filteredIds.includes(group.props.itemId)) {\n return group;\n }\n }\n })\n .filter(newGroup => newGroup);\n\n if (filteredCopy.length > 0) {\n let lastGroup = filteredCopy.pop();\n if (lastGroup.type !== Divider) {\n filteredCopy.push(lastGroup);\n }\n }\n\n return filteredCopy;\n };\n\n const onTextChange = textValue => {\n if (textValue === '') {\n setFilteredIds(['*']);\n return;\n }\n\n const filteredIds = refFullOptions\n .filter(item => item.innerText.toLowerCase().includes(textValue.toString().toLowerCase()))\n .map(item => item.id);\n setFilteredIds(filteredIds);\n };\n\n const onFavorite = (event, itemId, actionId) => {\n event.stopPropagation();\n if (actionId === 'fav') {\n const isFavorite = favorites.includes(itemId);\n if (isFavorite) {\n setFavorites(favorites.filter(fav => fav !== itemId));\n } else {\n setFavorites([...favorites, itemId]);\n }\n }\n };\n\n const filteredFavorites = filterItems(createFavorites(favorites), filteredIds);\n const filteredItems = filterItems(menuItems, filteredIds);\n if (filteredItems.length === 0) {\n filteredItems.push(<MenuItem key=\"no-items\">No results found</MenuItem>);\n }\n\n const menu = (\n <Menu ref={menuRef} onActionClick={onFavorite} onSelect={(_ev, itemId) => console.log('selected', itemId)}>\n <MenuInput>\n <TextInput\n aria-label=\"Filter menu items\"\n iconVariant=\"search\"\n type=\"search\"\n onChange={value => onTextChange(value)}\n />\n </MenuInput>\n <Divider />\n <MenuContent>\n {filteredFavorites.length > 0 && (\n <React.Fragment>\n <MenuGroup key=\"favorites-group\" label=\"Favorites\">\n <MenuList>{filteredFavorites}</MenuList>\n </MenuGroup>\n <Divider key=\"favorites-divider\" />\n </React.Fragment>\n )}\n {filteredItems}\n </MenuContent>\n </Menu>\n );\n return (\n <div ref={containerRef}>\n <Popper\n trigger={toggle}\n popper={menu}\n isVisible={isOpen}\n popperMatchesTriggerWidth={false}\n appendTo={containerRef.current}\n />\n </div>\n );\n};","title":"Application launcher using menu components","lang":"js"}}>
|
|
92
93
|
|
|
93
94
|
</Example>,
|
|
94
95
|
'Context selector using menu components': props =>
|
|
95
|
-
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n MenuToggle,\n Menu,\n MenuContent,\n MenuFooter,\n MenuList,\n MenuItem,\n MenuGroup,\n MenuInput,\n Popper,\n Tooltip,\n Divider,\n TextInput,\n InputGroup,\n Button\n} from '@patternfly/react-core';\nimport { Link } from '@reach/router';\nimport SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';\nimport pfIcon from './examples/pf-logo-small.svg';\n\nMenuContextSelector = () => {\n const items = [\n 'My project',\n 'OpenShift cluster',\n 'Production Ansible',\n 'AWS',\n 'Azure',\n 'My project 2',\n 'OpenShift cluster ',\n 'Production Ansible 2 ',\n 'AWS 2',\n 'Azure 2'\n ];\n const [isOpen, setIsOpen] = React.useState(false);\n const [selected, setSelected] = React.useState(items[0]);\n const [filteredItems, setFilteredItems] = React.useState(items);\n const [searchInputValue, setSearchInputValue] = React.useState('');\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n const menuFooterBtnRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (!isOpen) {\n return;\n }\n if (menuFooterBtnRef.current.contains(event.target)) {\n if (event.key === 'Tab') {\n if (event.shiftKey) {\n return;\n }\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n if (menuRef.current.contains(event.target)) {\n if (event.key === 'Escape') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n const firstElement = menuRef.current.querySelector('li > button,input:not(:disabled)');\n
|
|
96
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n MenuToggle,\n Menu,\n MenuContent,\n MenuFooter,\n MenuList,\n MenuItem,\n MenuGroup,\n MenuInput,\n Popper,\n Tooltip,\n Divider,\n TextInput,\n InputGroup,\n Button\n} from '@patternfly/react-core';\nimport { Link } from '@reach/router';\nimport SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';\nimport pfIcon from './examples/pf-logo-small.svg';\n\nMenuContextSelector = () => {\n const items = [\n 'My project',\n 'OpenShift cluster',\n 'Production Ansible',\n 'AWS',\n 'Azure',\n 'My project 2',\n 'OpenShift cluster ',\n 'Production Ansible 2 ',\n 'AWS 2',\n 'Azure 2'\n ];\n const [isOpen, setIsOpen] = React.useState(false);\n const [selected, setSelected] = React.useState(items[0]);\n const [filteredItems, setFilteredItems] = React.useState(items);\n const [searchInputValue, setSearchInputValue] = React.useState('');\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n const menuFooterBtnRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (!isOpen) {\n return;\n }\n if (menuFooterBtnRef.current.contains(event.target)) {\n if (event.key === 'Tab') {\n if (event.shiftKey) {\n return;\n }\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n if (menuRef.current.contains(event.target)) {\n if (event.key === 'Escape') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n if (menuRef.current) {\n const firstElement = menuRef.current.querySelector('li > button,input:not(:disabled)');\n firstElement && firstElement.focus();\n }\n }, 0);\n setIsOpen(!isOpen);\n };\n\n const toggle = (\n <MenuToggle ref={toggleRef} onClick={onToggleClick} isExpanded={isOpen}>\n {selected}\n </MenuToggle>\n );\n\n const onSelect = (event, itemId) => {\n setSelected(itemId);\n setIsOpen(!isOpen);\n };\n\n const onSearchInputChange = value => {\n setSearchInputValue(value);\n };\n\n const onSearchButtonClick = event => {\n const filtered =\n searchInputValue === ''\n ? items\n : items.filter(str => str.toLowerCase().indexOf(searchInputValue.toLowerCase()) !== -1);\n\n setFilteredItems(filtered || []);\n setIsOpen(true); // Keep menu open after search executed\n };\n\n const onEnterPressed = event => {\n if (event.key === 'Enter') {\n onSearchButtonClick(event);\n }\n };\n\n const menu = (\n <Menu ref={menuRef} id=\"context-selector\" onSelect={onSelect}>\n <MenuInput>\n <InputGroup>\n <TextInput\n value={searchInputValue}\n type=\"search\"\n placeholder=\"Search\"\n onChange={onSearchInputChange}\n onKeyPress={onEnterPressed}\n aria-labelledby=\"pf-context-selector-search-button-id-1\"\n />\n <Button\n variant={ButtonVariant.control}\n aria-label=\"Search menu items\"\n id=\"pf-context-selector-search-button-id-1\"\n onClick={onSearchButtonClick}\n >\n <SearchIcon aria-hidden=\"true\" />\n </Button>\n </InputGroup>\n </MenuInput>\n <Divider />\n <MenuContent maxMenuHeight=\"200px\">\n <MenuList>\n {filteredItems.map((item, index) => (\n <MenuItem itemId={item} key={index}>\n {item}\n </MenuItem>\n ))}\n </MenuList>\n </MenuContent>\n <MenuFooter>\n <Button ref={menuFooterBtnRef} variant=\"link\" isInline>\n Action\n </Button>\n </MenuFooter>\n </Menu>\n );\n return <Popper trigger={toggle} popper={menu} isVisible={isOpen} />;\n};","title":"Context selector using menu components","lang":"js"}}>
|
|
97
|
+
|
|
98
|
+
</Example>,
|
|
99
|
+
'Options menu using menu components': props =>
|
|
100
|
+
<Example {...pageData} {...props} {...{"code":"import React from 'react';\nimport {\n MenuToggle,\n Menu,\n MenuContent,\n MenuList,\n MenuItem,\n MenuGroup,\n Popper,\n Divider\n} from '@patternfly/react-core';\n\nMenuOptionsMenu = () => {\n\n const [isOpen, setIsOpen] = React.useState(false);\n const [selected, setSelected] = React.useState(undefined);\n const toggleRef = React.useRef();\n const menuRef = React.useRef();\n\n const handleMenuKeys = event => {\n if (isOpen && menuRef.current.contains(event.target)) {\n if (event.key === 'Escape' || event.key === 'Tab') {\n setIsOpen(!isOpen);\n toggleRef.current.focus();\n }\n }\n };\n\n const handleClickOutside = event => {\n if (isOpen && !menuRef.current.contains(event.target)) {\n setIsOpen(false);\n }\n };\n\n React.useEffect(() => {\n window.addEventListener('keydown', handleMenuKeys);\n window.addEventListener('click', handleClickOutside);\n\n return () => {\n window.removeEventListener('keydown', handleMenuKeys);\n window.removeEventListener('click', handleClickOutside);\n };\n }, [isOpen, menuRef]);\n\n const onToggleClick = ev => {\n ev.stopPropagation(); // Stop handleClickOutside from handling\n setTimeout(() => {\n if (menuRef.current) {\n const firstElement = menuRef.current.querySelector('li > button,input:not(:disabled)');\n firstElement && firstElement.focus();\n }\n }, 0);\n setIsOpen(!isOpen);\n };\n\n const toggle = (\n <MenuToggle ref={toggleRef} onClick={onToggleClick} isExpanded={isOpen}>\n Options menu\n </MenuToggle>\n );\n\n const menu = (\n <Menu ref={menuRef} id=\"options-menu\" selected={selected} onSelect={(_ev, itemId) => setSelected(itemId)}>\n <MenuContent>\n <MenuList>\n <MenuItem itemId={0}>Option 1</MenuItem>\n <MenuItem itemId={1} isDisabled>Disabled Option</MenuItem>\n <Divider key=\"group1-divider\" />\n <MenuGroup label=\"Group 1\">\n <MenuList>\n <MenuItem itemId={2}>Option 1</MenuItem>\n <MenuItem itemId={3}>Option 2</MenuItem>\n </MenuList>\n </MenuGroup>\n <Divider key=\"group2-divider\" />\n <MenuGroup label=\"Group 2\">\n <MenuList>\n <MenuItem itemId={4}>Option 1</MenuItem>\n <MenuItem itemId={5}>Option 2</MenuItem>\n </MenuList>\n </MenuGroup>\n </MenuList>\n </MenuContent>\n </Menu>\n );\n return <Popper trigger={toggle} popper={menu} isVisible={isOpen} />;\n};","title":"Options menu using menu components","lang":"js"}}>
|
|
96
101
|
|
|
97
102
|
</Example>
|
|
98
103
|
};
|
|
@@ -121,6 +126,7 @@ const Component = () => (
|
|
|
121
126
|
{React.createElement(pageData.examples["Flyout"])}
|
|
122
127
|
{React.createElement(pageData.examples["Application launcher using menu components"])}
|
|
123
128
|
{React.createElement(pageData.examples["Context selector using menu components"])}
|
|
129
|
+
{React.createElement(pageData.examples["Options menu using menu components"])}
|
|
124
130
|
</React.Fragment>
|
|
125
131
|
);
|
|
126
132
|
Component.displayName = 'DemosComposableMenuReactDemosDocs';
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|