From c11cc534cb411afa562980f9bb7a4ed4c8fcc3d0 Mon Sep 17 00:00:00 2001 From: Ajay Pratap Date: Mon, 10 Jun 2024 20:02:16 +0530 Subject: [PATCH] Masthead: add demo that includes horizontal nav (#10241) * add masthead with horizontal nav * implement review comments * add toolbar * Update packages/react-core/src/demos/examples/Masthead/MastheadWithHorizontalNav.tsx Co-authored-by: Matt Nolting * Update packages/react-core/src/demos/examples/Masthead/MastheadWithHorizontalNav.tsx Co-authored-by: Matt Nolting * Update packages/react-core/src/demos/examples/Masthead/MastheadWithHorizontalNav.tsx Co-authored-by: Matt Nolting * fix layout issue --------- Co-authored-by: Titani Labaj <39532947+tlabaj@users.noreply.github.com> Co-authored-by: Matt Nolting --- packages/react-core/src/demos/Masthead.md | 10 +- .../Masthead/MastheadWithHorizontalNav.tsx | 322 ++++++++++++++++++ 2 files changed, 327 insertions(+), 5 deletions(-) create mode 100644 packages/react-core/src/demos/examples/Masthead/MastheadWithHorizontalNav.tsx diff --git a/packages/react-core/src/demos/Masthead.md b/packages/react-core/src/demos/Masthead.md index a11302319ad..85608100fcd 100644 --- a/packages/react-core/src/demos/Masthead.md +++ b/packages/react-core/src/demos/Masthead.md @@ -3,24 +3,24 @@ id: Masthead section: components --- -import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon'; import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-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 ThIcon from '@patternfly/react-icons/dist/esm/icons/th-icon'; import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon'; import imgAvatar from '@patternfly/react-core/src/components/assets/avatarImg.svg'; -import pfIcon from './assets/pf-logo-small.svg'; import pfLogo from './assets/pf-logo.svg'; -import { Link } from '@reach/router'; ## Demos -### Masthead with utilities and user dropdown menu +### Utilities and user dropdown menu Many mastheads contain utilities which collapse into a dropdown at smaller viewport widths. These utilities could include a notification badge to open and close a notification drawer, a link to app or user settings, a help icon which could launch quick starts or link to other resources, and many other utilities. In this demo, the notification badge does not collapse down into the mobile menu so that it is always visible even at narrower viewport widths. ```ts file='./examples/Masthead/MastheadWithUtilitiesAndUserDropdownMenu.tsx' isFullscreen ``` +### Horizontal nav +```ts file='./examples/Masthead/MastheadWithHorizontalNav.tsx' isFullscreen + +``` \ No newline at end of file diff --git a/packages/react-core/src/demos/examples/Masthead/MastheadWithHorizontalNav.tsx b/packages/react-core/src/demos/examples/Masthead/MastheadWithHorizontalNav.tsx new file mode 100644 index 00000000000..eac29a21e3b --- /dev/null +++ b/packages/react-core/src/demos/examples/Masthead/MastheadWithHorizontalNav.tsx @@ -0,0 +1,322 @@ +import React from 'react'; +import { + Avatar, + Brand, + Breadcrumb, + BreadcrumbItem, + Button, + ButtonVariant, + Card, + CardBody, + Divider, + Dropdown, + DropdownGroup, + DropdownItem, + DropdownList, + Gallery, + GalleryItem, + Masthead, + MastheadBrand, + MastheadContent, + MastheadMain, + MenuToggle, + MenuToggleElement, + Nav, + NavItem, + NavList, + Page, + PageSection, + PageSectionVariants, + SkipToContent, + Text, + TextContent, + Toolbar, + ToolbarContent, + ToolbarGroup, + ToolbarItem +} from '@patternfly/react-core'; +import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-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/assets/avatarImg.svg'; +import pfLogo from '@patternfly/react-core/src/demos/assets/pf-logo.svg'; + +interface NavOnSelectProps { + groupId: number | string; + itemId: number | string; + to: string; +} + +export const MastheadWithHorizontalNav: React.FunctionComponent = () => { + const [isDropdownOpen, setIsDropdownOpen] = React.useState(false); + const [isKebabDropdownOpen, setIsKebabDropdownOpen] = React.useState(false); + const [isFullKebabDropdownOpen, setIsFullKebabDropdownOpen] = React.useState(false); + const [activeItem, setActiveItem] = React.useState(0); + + const [isOpen, setIsOpen] = React.useState(false); + const menuRef = React.useRef(null); + const toggleRef = React.useRef(null); + + const onNavSelect = (_event: React.FormEvent, selectedItem: NavOnSelectProps) => { + typeof selectedItem.itemId === 'number' && setActiveItem(selectedItem.itemId); + }; + + const onDropdownToggle = () => { + setIsDropdownOpen(!isDropdownOpen); + }; + + const onDropdownSelect = () => { + setIsDropdownOpen(!isDropdownOpen); + }; + + const onKebabDropdownToggle = () => { + setIsKebabDropdownOpen(!isKebabDropdownOpen); + }; + + const onKebabDropdownSelect = () => { + setIsKebabDropdownOpen(!isKebabDropdownOpen); + }; + + const onFullKebabDropdownToggle = () => { + setIsFullKebabDropdownOpen(!isFullKebabDropdownOpen); + }; + + const onFullKebabDropdownSelect = () => { + setIsFullKebabDropdownOpen(!isFullKebabDropdownOpen); + }; + + const handleMenuKeys = (event: KeyboardEvent) => { + if (!isOpen) { + return; + } + if (menuRef.current?.contains(event.target as Node) || toggleRef.current?.contains(event.target as Node)) { + if (event.key === 'Escape') { + setIsOpen(!isOpen); + toggleRef.current?.focus(); + } + } + }; + + const handleClickOutside = (event: MouseEvent) => { + if (isOpen && !menuRef.current?.contains(event.target as Node)) { + setIsOpen(false); + } + }; + + React.useEffect(() => { + window.addEventListener('keydown', handleMenuKeys); + window.addEventListener('click', handleClickOutside); + + return () => { + window.removeEventListener('keydown', handleMenuKeys); + window.removeEventListener('click', handleClickOutside); + }; + }, [isOpen, menuRef]); + + const dashboardBreadcrumb = ( + + Section home + Section title + Section title + + Section landing + + + ); + + const kebabDropdownItems = ( + <> + + Settings + + + Help + + + ); + const userDropdownItems = [ + <> + My profile + User management + Logout + + ]; + + const PageHorizontalNav = () => ( + + + + ); + + const headerToolbar = ( + + + + + +