/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */ import * as React from 'react'; import { styled, alpha } from '@mui/material/styles'; import Box from '@mui/material/Box'; import ButtonBase from '@mui/material/ButtonBase'; import Popper from '@mui/material/Popper'; import Paper from '@mui/material/Paper'; import { unstable_debounce as debounce } from '@mui/utils'; import Fade from '@mui/material/Fade'; import Typography from '@mui/material/Typography'; import IconImage from 'docs/src/components/icon/IconImage'; import ROUTES from 'docs/src/route'; import { Link } from '@mui/docs/Link'; import MuiProductSelector from 'docs/src/modules/components/MuiProductSelector'; const Navigation = styled('nav')(({ theme }) => [ { '& > div': { cursor: 'default', }, '& ul': { padding: 0, margin: 0, listStyle: 'none', display: 'flex', }, '& li': { ...theme.typography.body2, color: (theme.vars || theme).palette.text.secondary, fontWeight: theme.typography.fontWeightSemiBold, '& > a, & > button': { display: 'inline-block', color: 'inherit', font: 'inherit', textDecoration: 'none', padding: theme.spacing('6px', '8px'), borderRadius: (theme.vars || theme).shape.borderRadius, border: '1px solid transparent', '&:hover': { color: (theme.vars || theme).palette.text.primary, backgroundColor: (theme.vars || theme).palette.grey[50], borderColor: (theme.vars || theme).palette.grey[100], '@media (hover: none)': { backgroundColor: 'initial', // Reset on touch devices, it doesn't add specificity }, }, '&:focus-visible': { outline: `3px solid ${alpha(theme.palette.primary[500], 0.5)}`, outlineOffset: '2px', }, }, }, }, theme.applyDarkStyles({ '& li': { '& > a, & > button': { '&:hover': { color: (theme.vars || theme).palette.primary[50], backgroundColor: alpha(theme.palette.primaryDark[700], 0.8), borderColor: (theme.vars || theme).palette.divider, }, }, }, }), ]); const PRODUCT_IDS = [ 'product-core', 'product-advanced', 'product-templates', 'product-design', ] as const; type ProductSubMenuProps = { icon: React.ReactElement; name: React.ReactNode; description: React.ReactNode; chip?: React.ReactNode; href: string; } & Omit; const ProductSubMenu = React.forwardRef( function ProductSubMenu({ icon, name, description, chip, href, ...props }, ref) { return ( ({ display: 'flex', alignItems: 'center', py: 2, pr: 3, '&:hover, &:focus': { backgroundColor: (theme.vars || theme).palette.grey[50], outline: 0, '@media (hover: none)': { backgroundColor: 'initial', outline: 'initial', }, }, ...theme.applyDarkStyles({ '&:hover, &:focus': { backgroundColor: alpha(theme.palette.primaryDark[700], 0.4), }, }), })} {...props} > {icon}
{name} {chip}
{description}
); }, ); export default function HeaderNavBar() { const [subMenuOpen, setSubMenuOpen] = React.useState(null); const [subMenuIndex, setSubMenuIndex] = React.useState(null); const navRef = React.useRef(null); const productSelectorRef = React.useRef(null); const productsMenuRef = React.useRef(null); const docsMenuRef = React.useRef(null); React.useEffect(() => { if (typeof subMenuIndex === 'number' && subMenuOpen === 'products') { document.getElementById(PRODUCT_IDS[subMenuIndex])!.focus(); } if (typeof subMenuIndex === 'number' && subMenuOpen === 'docs') { (productSelectorRef.current!.querySelector('[role="menuitem"]') as HTMLElement).focus(); } }, [subMenuIndex, subMenuOpen]); function handleKeyDown(event: React.KeyboardEvent) { let menuItem; if (subMenuOpen === 'products') { menuItem = productsMenuRef.current!; } else if (subMenuOpen === 'docs') { menuItem = docsMenuRef.current!; } else { return; } if (event.key === 'ArrowDown') { event.preventDefault(); if (subMenuOpen === 'products') { setSubMenuIndex((prevValue) => { if (prevValue === null) { return 0; } if (prevValue === PRODUCT_IDS.length - 1) { return 0; } return prevValue + 1; }); } else if (subMenuOpen === 'docs') { setSubMenuIndex(0); } } else if (event.key === 'ArrowUp') { event.preventDefault(); if (subMenuOpen === 'products') { setSubMenuIndex((prevValue) => { if (prevValue === null) { return 0; } if (prevValue === 0) { return PRODUCT_IDS.length - 1; } return prevValue - 1; }); } else if (subMenuOpen === 'docs') { setSubMenuIndex(0); } } else if (event.key === 'Escape' || event.key === 'Tab') { menuItem.focus(); setSubMenuOpen(null); setSubMenuIndex(null); } } const setSubMenuOpenDebounced = React.useMemo( () => debounce(setSubMenuOpen, 40), [setSubMenuOpen], ); const setSubMenuOpenUndebounce = (value: typeof subMenuOpen) => (event: React.MouseEvent | React.FocusEvent) => { setSubMenuOpenDebounced.clear(); setSubMenuOpen(value); if (event.type === 'mouseenter') { // Reset keyboard setSubMenuIndex(null); } }; const handleClickMenu = (value: typeof subMenuOpen) => () => { setSubMenuOpenDebounced.clear(); setSubMenuOpen(subMenuOpen ? null : value); }; React.useEffect(() => { return () => { setSubMenuOpenDebounced.clear(); }; }, [setSubMenuOpenDebounced]); return (
  • setSubMenuOpenDebounced(null)} onBlur={setSubMenuOpenUndebounce(null)} > Products {({ TransitionProps }) => ( ({ mt: 1, minWidth: 498, overflow: 'hidden', borderColor: 'grey.200', bgcolor: 'background.paper', boxShadow: `0px 4px 16px ${alpha(theme.palette.grey[200], 0.8)}`, '& ul': { margin: 0, padding: 0, listStyle: 'none', }, '& li:not(:last-of-type)': { borderBottom: '1px solid', borderColor: 'grey.100', }, '& a': { textDecoration: 'none' }, ...theme.applyDarkStyles({ borderColor: 'primaryDark.700', bgcolor: 'primaryDark.900', boxShadow: `0px 4px 16px ${alpha(theme.palette.common.black, 0.8)}`, '& li:not(:last-of-type)': { borderColor: 'primaryDark.700', }, }), })} >
    • } name="MUI Core" description="Ready-to-use foundational React components, free forever." />
    • } name="MUI X" description="Advanced and powerful components for complex use cases." />
    • } name="Templates" description="Fully built templates for your application." />
    • } name="Design Kits" description="Material UI components in your favorite design tool." />
    )}
  • setSubMenuOpenDebounced(null)} onBlur={setSubMenuOpenUndebounce(null)} > Docs {({ TransitionProps }) => ( ({ mt: 1, overflow: 'hidden', borderColor: 'grey.200', bgcolor: 'background.paper', boxShadow: `0px 4px 16px ${alpha(theme.palette.grey[200], 0.8)}`, ...theme.applyDarkStyles({ borderColor: 'primaryDark.700', bgcolor: 'primaryDark.900', boxShadow: `0px 4px 16px ${alpha(theme.palette.common.black, 0.8)}`, }), })} > )}
  • Pricing
  • About us
  • Blog
); }