diff --git a/packages/react-core/src/demos/Page.md b/packages/react-core/src/demos/Page.md new file mode 100644 index 00000000000..200d36df8bc --- /dev/null +++ b/packages/react-core/src/demos/Page.md @@ -0,0 +1,47 @@ +--- +id: Page +section: components +--- + +import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon'; +import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'; +import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; +import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon'; +import imgBrand from '@patternfly/react-core/src/demos/examples/pfColorLogo.svg'; +import imgAvatar from '@patternfly/react-core/src/components/Avatar/examples/avatarImg.svg'; +import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon'; +import AttentionBellIcon from '@patternfly/react-icons/dist/esm/icons/attention-bell-icon'; +import LightbulbIcon from '@patternfly/react-icons/dist/esm/icons/lightbulb-icon'; + +- 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: + + 1. Add an onNavToggle callback to PageHeader + 2. Pass a boolean into the isNavOpen prop to PageSidebar + +- 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%` + +## Layouts + +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. + +### Sticky section group + +```ts file='./examples/Page/PageStickySectionGroup.tsx' isFullscreen +``` + +### Sticky section group (alternate syntax) + +```ts file='./examples/Page/PageStickySectionGroupAlternate.tsx' isFullscreen +``` + +### Sticky section group (using PageHeader) + +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. + +```ts file='./examples/Page/PageStickySectionGroupUsingPageHeader.tsx' isFullscreen +``` + +### Sticky section breadcrumb (with breakpoints) + +```ts file='./examples/Page/PageStickySectionBreadcrumb.tsx' isFullscreen +``` diff --git a/packages/react-core/src/demos/Page/Page.md b/packages/react-core/src/demos/Page/Page.md deleted file mode 100644 index b80d24b2c33..00000000000 --- a/packages/react-core/src/demos/Page/Page.md +++ /dev/null @@ -1,1184 +0,0 @@ ---- -id: Page -section: components ---- - -import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'; -import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; -import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon'; -import imgBrand from '@patternfly/react-core/src/demos/examples/pfColorLogo.svg'; -import imgAvatar from '@patternfly/react-core/src/components/Avatar/examples/avatarImg.svg'; -import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon'; -import AttentionBellIcon from '@patternfly/react-icons/dist/esm/icons/attention-bell-icon'; -import LightbulbIcon from '@patternfly/react-icons/dist/esm/icons/lightbulb-icon'; - -- All but the last example 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: - - 1. Add an onNavToggle callback to PageHeader - 1. Pass a boolean into the isNavOpen prop to PageSidebar - - The last example demonstrates this. - -- 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%` - -## Layouts - -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. - -### Sticky section group - -```js isFullscreen -import React from 'react'; -import { - Avatar, - Brand, - Breadcrumb, - BreadcrumbItem, - Button, - ButtonVariant, - Card, - CardBody, - Divider, - Dropdown, - DropdownGroup, - DropdownToggle, - DropdownItem, - Gallery, - GalleryItem, - KebabToggle, - Masthead, - MastheadBrand, - MastheadContent, - MastheadMain, - MastheadToggle, - Nav, - NavItem, - NavList, - Page, - PageSection, - PageSectionVariants, - PageSidebar, - PageToggleButton, - SkipToContent, - TextContent, - Text, - Toolbar, - ToolbarContent, - ToolbarGroup, - ToolbarItem, - Drawer, - DrawerPanelContent, - DrawerContent, - DrawerContentBody, - DrawerHead, - DrawerActions, - DrawerCloseButton, -} from '@patternfly/react-core'; -import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'; -import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; -import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon'; -import AttentionBellIcon from '@patternfly/react-icons/dist/esm/icons/attention-bell-icon'; -import LightbulbIcon from '@patternfly/react-icons/dist/esm/icons/lightbulb-icon'; -import BarsIcon from '@patternfly/react-icons/dist/js/icons/bars-icon'; -import imgBrand from './imgBrand.svg'; -import imgAvatar from './imgAvatar.svg'; - -class PageLayoutGrouped extends React.Component { - constructor(props) { - super(props); - this.state = { - isDropdownOpen: false, - isKebabDropdownOpen: false, - isFullKebabDropdownOpen: false, - activeItem: 0, - isDrawerExpanded: false - }; - this.onDropdownToggle = isDropdownOpen => { - this.setState({ - isDropdownOpen - }); - }; - - this.onDropdownSelect = event => { - this.setState({ - isDropdownOpen: !this.state.isDropdownOpen - }); - }; - - this.onKebabDropdownToggle = isKebabDropdownOpen => { - this.setState({ - isKebabDropdownOpen - }); - }; - - this.onKebabDropdownSelect = event => { - this.setState({ - isKebabDropdownOpen: !this.state.isKebabDropdownOpen - }); - }; - - this.onNavSelect = result => { - this.setState({ - activeItem: result.itemId - }); - }; - - this.onFullKebabToggle = isFullKebabDropdownOpen => { - this.setState({ - isFullKebabDropdownOpen - }); - }; - - this.onFullKebabSelect = () => { - this.setState({ - isFullKebabDropdownOpen: !this.state.isFullKebabDropdownOpen - }); - }; - - this.onDrawerToggle = () => { - const isDrawerExpanded = !this.state.isDrawerExpanded; - this.setState({ - isDrawerExpanded - }); - }; - - this.onDrawerClose = () => { - this.setState({ - isDrawerExpanded: false - }); - }; - } - - render() { - const { isDropdownOpen, isKebabDropdownOpen, activeItem, isFullKebabDropdownOpen, isDrawerExpanded } = this.state; - - const PageNav = ( - - ); - - const kebabDropdownItems = [ - - Settings - , - - Help - - ]; - - const userDropdownItems = [ - - My profile - - User management - - Logout - - ]; - - const fullKebabItems = [ - - My profile - - User management - - Logout - , - , - - Settings - , - - Help - - ]; - - const headerToolbar = ( - - - - - - - - - - - - - - - - - - - } - isOpen={isKebabDropdownOpen} - dropdownItems={kebabDropdownItems} - /> - - - } - isOpen={isFullKebabDropdownOpen} - dropdownItems={fullKebabItems} - /> - - - - } onToggle={this.onDropdownToggle}> - John Smith - - } - dropdownItems={userDropdownItems} - /> - - - - ); - - const Header = ( - - - - - - - - - - - - {headerToolbar} - - ); - - const pageId = 'main-content-page-layout-tertiary-nav'; - const PageSkipToContent = Skip to content; - - const PageBreadcrumb = ( - - Section home - Section title - Section title - - Section landing - - - ); - - const panelContent = ( - - - - drawer-panel - - - - - - - ); - - const Sidebar = ; - - return ( - - - - - - Main title - - Body text should be Overpass Regular at 16px. It should have leading of 24px because
- of its relative line height of 1.5. -
-
- - } - groupProps={{ - stickyOnBreakpoint: { default: 'top' } - }} - > - - - {Array.apply(0, Array(20)).map((x, i) => ( - - - This is a card - - - ))} - - -
-
-
-
- ); - } -} -``` - -### Sticky section group (using PageHeader) - -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. - -```js isFullscreen -import React from 'react'; -import { - Avatar, - Brand, - Breadcrumb, - BreadcrumbItem, - Button, - ButtonVariant, - Card, - CardBody, - Dropdown, - DropdownGroup, - DropdownToggle, - DropdownItem, - Gallery, - GalleryItem, - KebabToggle, - Nav, - NavItem, - NavList, - Page, - PageHeader, - PageSection, - PageSectionVariants, - SkipToContent, - TextContent, - Text, - PageHeaderTools, - PageHeaderToolsGroup, - PageHeaderToolsItem -} from '@patternfly/react-core'; -import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'; -import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; -import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon'; -import imgBrand from './imgBrand.svg'; -import imgAvatar from './imgAvatar.svg'; - -class PageLayoutGrouped extends React.Component { - constructor(props) { - super(props); - this.state = { - isDropdownOpen: false, - isKebabDropdownOpen: false, - activeItem: 0 - }; - this.onDropdownToggle = isDropdownOpen => { - this.setState({ - isDropdownOpen - }); - }; - - this.onDropdownSelect = event => { - this.setState({ - isDropdownOpen: !this.state.isDropdownOpen - }); - }; - - this.onKebabDropdownToggle = isKebabDropdownOpen => { - this.setState({ - isKebabDropdownOpen - }); - }; - - this.onKebabDropdownSelect = event => { - this.setState({ - isKebabDropdownOpen: !this.state.isKebabDropdownOpen - }); - }; - - this.onNavSelect = result => { - this.setState({ - activeItem: result.itemId - }); - }; - } - - render() { - const { isDropdownOpen, isKebabDropdownOpen, activeItem } = this.state; - - const PageNav = ( - - ); - const kebabDropdownItems = [ - - Settings - , - - Help - - ]; - const userDropdownItems = [ - - My profile - - User management - - Logout - - ]; - const headerTools = ( - - - - - - - - - - - - - - - - ); - - const Header = ( - } headerTools={headerTools} showNavToggle /> - ); - const pageId = 'main-content-page-layout-tertiary-nav'; - const PageSkipToContent = Skip to content; - - const PageBreadcrumb = ( - - Section home - Section title - Section title - - Section landing - - - ); - - return ( - - - - Main title - - Body text should be Overpass Regular at 16px. It should have leading of 24px because
- of its relative line height of 1.5. -
-
- - } - groupProps={{ - stickyOnBreakpoint: { - default: 'top' - } - }} - > - - - {Array.apply(0, Array(20)).map((x, i) => ( - - - This is a card - - - ))} - - -
-
- ); - } -} -``` - -### Sticky section group (alternate syntax and using PageHeader) - -Please see this note regarding PageHeader. - -```js isFullscreen -import React from 'react'; -import { - Avatar, - Brand, - Breadcrumb, - BreadcrumbItem, - Button, - ButtonVariant, - Card, - CardBody, - Dropdown, - DropdownGroup, - DropdownToggle, - DropdownItem, - Gallery, - GalleryItem, - KebabToggle, - Nav, - NavItem, - NavList, - Page, - PageHeader, - PageSection, - PageSectionVariants, - PageGroup, - PageBreadcrumb, - PageNavigation, - SkipToContent, - TextContent, - Text, - PageHeaderTools, - PageHeaderToolsGroup, - PageHeaderToolsItem -} from '@patternfly/react-core'; -import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'; -import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; -import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon'; -import imgBrand from './imgBrand.svg'; -import imgAvatar from './imgAvatar.svg'; - -class PageLayoutGroupedAlt extends React.Component { - constructor(props) { - super(props); - this.state = { - isDropdownOpen: false, - isKebabDropdownOpen: false, - activeItem: 0 - }; - this.onDropdownToggle = isDropdownOpen => { - this.setState({ - isDropdownOpen - }); - }; - - this.onDropdownSelect = event => { - this.setState({ - isDropdownOpen: !this.state.isDropdownOpen - }); - }; - - this.onKebabDropdownToggle = isKebabDropdownOpen => { - this.setState({ - isKebabDropdownOpen - }); - }; - - this.onKebabDropdownSelect = event => { - this.setState({ - isKebabDropdownOpen: !this.state.isKebabDropdownOpen - }); - }; - - this.onNavSelect = result => { - this.setState({ - activeItem: result.itemId - }); - }; - } - - render() { - const { isDropdownOpen, isKebabDropdownOpen, activeItem } = this.state; - - const kebabDropdownItems = [ - - Settings - , - - Help - - ]; - const userDropdownItems = [ - - My profile - - User management - - Logout - - ]; - const headerTools = ( - - - - - - - - - - - - - - - - ); - - const Header = ( - } headerTools={headerTools} showNavToggle /> - ); - const pageId = 'main-content-page-layout-tertiary-nav'; - const PageSkipToContent = Skip to content; - - return ( - - - - - - - - - Section home - Section title - Section title - - Section landing - - - - - - Main title - - Body text should be Overpass Regular at 16px. It should have leading of 24px because
- of its relative line height of 1.5. -
-
-
{' '} -
- - - {Array.apply(0, Array(20)).map((x, i) => ( - - - This is a card - - - ))} - - -
-
- ); - } -} -``` - -### Sticky section breadcrumb (with breakpoints) - -```js isFullscreen -import React from 'react'; -import { - Avatar, - Brand, - Breadcrumb, - BreadcrumbItem, - Button, - ButtonVariant, - Card, - CardBody, - Divider, - Dropdown, - DropdownGroup, - DropdownToggle, - DropdownItem, - Gallery, - GalleryItem, - KebabToggle, - Masthead, - MastheadBrand, - MastheadContent, - MastheadMain, - MastheadToggle, - Nav, - NavItem, - NavList, - Page, - PageSection, - PageSectionVariants, - PageToggleButton, - PageSidebar, - SkipToContent, - TextContent, - Text, - Toolbar, - ToolbarContent, - ToolbarGroup, - ToolbarItem, - Drawer, - DrawerPanelContent, - DrawerContent, - DrawerContentBody, - DrawerHead, - DrawerActions, - DrawerCloseButton, -} from '@patternfly/react-core'; -import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'; -import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; -import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon'; -import AttentionBellIcon from '@patternfly/react-icons/dist/esm/icons/attention-bell-icon'; -import LightbulbIcon from '@patternfly/react-icons/dist/esm/icons/lightbulb-icon'; -import BarsIcon from '@patternfly/react-icons/dist/js/icons/bars-icon'; -import imgBrand from './imgBrand.svg'; -import imgAvatar from './imgAvatar.svg'; - -class PageLayoutGrouped extends React.Component { - constructor(props) { - super(props); - this.state = { - isDropdownOpen: false, - isKebabDropdownOpen: false, - isFullKebabDropdownOpen: false, - activeItem: 0, - isDrawerExpanded: false - }; - this.onDropdownToggle = isDropdownOpen => { - this.setState({ - isDropdownOpen - }); - }; - - this.onDropdownSelect = event => { - this.setState({ - isDropdownOpen: !this.state.isDropdownOpen - }); - }; - - this.onKebabDropdownToggle = isKebabDropdownOpen => { - this.setState({ - isKebabDropdownOpen - }); - }; - - this.onKebabDropdownSelect = event => { - this.setState({ - isKebabDropdownOpen: !this.state.isKebabDropdownOpen - }); - }; - - this.onNavSelect = result => { - this.setState({ - activeItem: result.itemId - }); - }; - - this.onFullKebabToggle = isFullKebabDropdownOpen => { - this.setState({ - isFullKebabDropdownOpen - }); - }; - - this.onFullKebabSelect = () => { - this.setState({ - isFullKebabDropdownOpen: !this.state.isFullKebabDropdownOpen - }); - }; - - this.onDrawerToggle = () => { - const isDrawerExpanded = !this.state.isDrawerExpanded; - this.setState({ - isDrawerExpanded - }); - }; - - this.onDrawerClose = () => { - this.setState({ - isDrawerExpanded: false - }); - }; - } - - render() { - const { isDropdownOpen, isKebabDropdownOpen, activeItem, isFullKebabDropdownOpen, isDrawerExpanded } = this.state; - - const PageNav = ( - - ); - - const kebabDropdownItems = [ - - Settings - , - - Help - - ]; - - const userDropdownItems = [ - - My profile - - User management - - Logout - - ]; - - const fullKebabItems = [ - - My profile - - User management - - Logout - , - , - - Settings - , - - Help - - ]; - - const headerToolbar = ( - - - - - - - - - - - - - - - - - - - } - isOpen={isKebabDropdownOpen} - dropdownItems={kebabDropdownItems} - /> - - - } - isOpen={isFullKebabDropdownOpen} - dropdownItems={fullKebabItems} - /> - - - - } onToggle={this.onDropdownToggle}> - John Smith - - } - dropdownItems={userDropdownItems} - /> - - - - ); - - const Header = ( - - - - - - - - - - - - {headerToolbar} - - ); - - const pageId = 'main-content-page-layout-tertiary-nav'; - const PageSkipToContent = Skip to content; - - const PageBreadcrumb = ( - - Section home - Section title - Section title - - Section landing - - - ); - - const panelContent = ( - - - - drawer-panel - - - - - - - ); - - const Sidebar = ; - - return ( - - - - - - - Main title - - Body text should be Overpass Regular at 16px. It should have leading of 24px because
- of its relative line height of 1.5. -
-
-
- - - {Array.apply(0, Array(50)).map((x, i) => ( - - - This is a card - - - ))} - - -
-
-
-
- ); - } -} -``` diff --git a/packages/react-core/src/demos/Page/imgAvatar.svg b/packages/react-core/src/demos/Page/imgAvatar.svg deleted file mode 100755 index 11c80b85ff6..00000000000 --- a/packages/react-core/src/demos/Page/imgAvatar.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/react-core/src/demos/Page/imgBrand.svg b/packages/react-core/src/demos/Page/imgBrand.svg deleted file mode 100644 index c29cc6c9a89..00000000000 --- a/packages/react-core/src/demos/Page/imgBrand.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/react-core/src/demos/examples/DashboardWrapper.js b/packages/react-core/src/demos/examples/DashboardWrapper.js index a7330240c5d..83efd392223 100644 --- a/packages/react-core/src/demos/examples/DashboardWrapper.js +++ b/packages/react-core/src/demos/examples/DashboardWrapper.js @@ -60,7 +60,8 @@ export default class DashboardWrapper extends React.Component { hasNoBreadcrumb, notificationDrawer, isNotificationDrawerExpanded, - hasPageTemplateTitle + hasPageTemplateTitle, + ...pageProps } = this.props; let renderedBreadcrumb; @@ -108,6 +109,7 @@ export default class DashboardWrapper extends React.Component { notificationDrawer={notificationDrawer} isNotificationDrawerExpanded={isNotificationDrawerExpanded} onPageResize={onPageResize} + {...pageProps} > {hasPageTemplateTitle && PageTemplateTitle} {children} diff --git a/packages/react-core/src/demos/examples/Page/PageStickySectionBreadcrumb.tsx b/packages/react-core/src/demos/examples/Page/PageStickySectionBreadcrumb.tsx new file mode 100644 index 00000000000..085dec5d174 --- /dev/null +++ b/packages/react-core/src/demos/examples/Page/PageStickySectionBreadcrumb.tsx @@ -0,0 +1,305 @@ +import React from 'react'; +import { + ApplicationLauncher, + ApplicationLauncherItem, + Avatar, + Brand, + Breadcrumb, + BreadcrumbItem, + Button, + ButtonVariant, + Card, + CardBody, + Divider, + Dropdown, + DropdownGroup, + DropdownItem, + DropdownToggle, + Gallery, + GalleryItem, + KebabToggle, + Masthead, + MastheadBrand, + MastheadContent, + MastheadMain, + MastheadToggle, + Nav, + NavItem, + NavList, + Page, + PageSection, + PageSectionVariants, + PageSidebar, + PageToggleButton, + SkipToContent, + Text, + TextContent, + Toolbar, + ToolbarContent, + ToolbarGroup, + ToolbarItem +} from '@patternfly/react-core'; +import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon'; +import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon'; +import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'; +import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; +import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon'; +import imgAvatar from '@patternfly/react-core/src/components/Avatar/examples/avatarImg.svg'; + +interface NavOnSelectProps { + groupId: number | string; + itemId: number | string; + to: string; + event: React.FormEvent; +} + +export const PageStickySectionBreadcrumb: React.FunctionComponent = () => { + const [isDropdownOpen, setIsDropdownOpen] = React.useState(false); + const [isKebabDropdownOpen, setIsKebabDropdownOpen] = React.useState(false); + const [isFullKebabDropdownOpen, setIsFullKebabDropdownOpen] = React.useState(false); + const [isAppLauncherOpen, setIsAppLauncherOpen] = React.useState(false); + const [activeItem, setActiveItem] = React.useState(1); + + const onNavSelect = (selectedItem: NavOnSelectProps) => { + typeof selectedItem.itemId === 'number' && setActiveItem(selectedItem.itemId); + }; + + const onDropdownToggle = (isOpen: boolean) => { + setIsDropdownOpen(isOpen); + }; + + const onDropdownSelect = () => { + setIsDropdownOpen(!isDropdownOpen); + }; + + const onKebabDropdownToggle = (isOpen: boolean) => { + setIsKebabDropdownOpen(isOpen); + }; + + const onKebabDropdownSelect = () => { + setIsKebabDropdownOpen(!isKebabDropdownOpen); + }; + + const onFullKebabDropdownToggle = (isOpen: boolean) => { + setIsFullKebabDropdownOpen(isOpen); + }; + + const onFullKebabDropdownSelect = () => { + setIsFullKebabDropdownOpen(!isFullKebabDropdownOpen); + }; + + const onAppLauncherToggle = (isOpen: boolean) => { + setIsAppLauncherOpen(isOpen); + }; + + const onAppLauncherSelect = () => { + setIsAppLauncherOpen(!isAppLauncherOpen); + }; + + const dashboardBreadcrumb = ( + + Section home + Section title + Section title + + Section landing + + + ); + + const kebabDropdownItems = [ + + Settings + , + + Help + + ]; + + const fullKebabDropdownItems = [ + + My profile + + User management + + Logout + , + , + + Settings + , + + Help + + ]; + + const userDropdownItems = [ + + My profile + + User management + + Logout + + ]; + + const appLauncherItems = [ + + Application 1 (anchor link) + , + alert('Clicked item 2')}> + Application 2 (button with onClick) + + ]; + + const headerToolbar = ( + + + + +