Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions tailwind.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,36 @@ module.exports = {
},
},
},
keyframes: {
menuOpen: {
'0%': {
opacity: '0',
transform: 'scale(0.60)',
transformOrigin: 'top right',
},
'100%': {
opacity: '1',
transform: 'scale(1)',
transformOrigin: 'top right',
},
},
menuClose: {
'0%': {
opacity: '1',
transform: 'scale(1)',
transformOrigin: 'top right',
},
'100%': {
opacity: '0',
transform: 'scale(0.60)',
transformOrigin: 'top right',
},
},
},
animation: {
menuOpen: 'menuOpen 300ms ease-in-out',
menuClose: 'menuClose 225ms ease-in-out',
},
},
},
plugins: [],
Expand Down
8 changes: 0 additions & 8 deletions web-components/src/components/header/Header.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,6 @@ export const useHeaderStyles = makeStyles<StyleProps>()(
// BEGIN HACK setting jss styles (duplicated from mui components built-in emotion styles)
// so it's initially rendered on gatsby build
// Remove once migrations from mui jss to emotion and to latest gatsby done
desktop: {
[theme.breakpoints.down('md')]: {
display: 'none',
},
[theme.breakpoints.up('md')]: {
display: 'block',
},
},
mobile: {
[theme.breakpoints.down('md')]: {
display: 'block',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const HeaderDropdownItem: React.FC<
alignItems="center"
className={cn(styles.item, className)}
onMouseEnter={onHover}
component="li"
>
{SVG && (
<Box className="mr-[18px] flex items-center">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,32 @@ const HeaderDropdown: React.FC<
items: HeaderDropdownItemProps[];
linkComponent: React.FC<React.PropsWithChildren<NavLinkProps>>;
title?: string;
isUserMenu?: boolean;
}>
> = props => {
const { classes: styles } = useStyles();
return (
<Box display="flex" flexDirection="column">
<Box
display="flex"
flexDirection="column"
className={`${props.isUserMenu ? 'pt-10' : 'p-25'}`}
>
{props.title && (
<Box mb={2}>
<Title variant="h4" className={styles.label}>
{ReactHtmlParser(props.title)}
</Title>
</Box>
)}
{props.items.map((link, i) => (
<HeaderDropdownItem
key={i}
{...link}
linkComponent={props.linkComponent}
/>
))}
<Box component="ul" className="p-0">
{props.items.map((link, i) => (
<HeaderDropdownItem
key={i}
{...link}
linkComponent={props.linkComponent}
/>
))}
</Box>
</Box>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ type Props = {
classes?: {
paper?: string;
};
isUserMenu?: boolean;
};

export const HeaderMenuItemContent = ({
item,
linkComponent: LinkComponent,
pathname,
classes,
isUserMenu,
}: Props): JSX.Element => {
const theme = useTheme();
const { classes: styles } = useHeaderMenuHoverStyles();
Expand All @@ -41,12 +43,14 @@ export const HeaderMenuItemContent = ({
title={item.title}
renderTitle={item.renderTitle}
classes={{ title: styles.title, paper: classes?.paper }}
isUserMenu={isUserMenu}
>
{/* `render` overrides default dropdown */}
{item.dropdownItems && !item.renderDropdownItems && (
<HeaderDropdown
items={item.dropdownItems}
linkComponent={LinkComponent}
isUserMenu={isUserMenu}
/>
)}
{item.renderDropdownItems && item.renderDropdownItems()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,11 @@ import { Theme } from '@mui/material/styles';
import { makeStyles } from 'tss-react/mui';

export const useMenuHoverStyles = makeStyles()((theme: Theme) => ({
popover: {
pointerEvents: 'none',
},
popoverContent: {
pointerEvents: 'auto',
marginTop: theme.spacing(4),
},
text: {
'& li.MuiMenuItem-root:hover': {
backgroundColor: 'transparent',
},
'& li > a': {
'& ul > li > a': {
fontFamily: 'lato',
color: '#000',
textDecoration: 'none',
Expand All @@ -29,11 +22,6 @@ export const useMenuHoverStyles = makeStyles()((theme: Theme) => ({
outline: 'none',
},
},
paper: {
borderRadius: '2px',
border: `1px solid ${theme.palette.grey[400]}`,
padding: theme.spacing(6.25),
},
icon: {
marginLeft: theme.spacing(1),
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React, { useRef } from 'react';
import { MenuList, Paper, Popover } from '@mui/material';
import cx from 'clsx';
import { MenuList } from '@mui/material';

import DropdownIcon from '../../../icons/DropdownIcon';
import { useMenuHoverStyles } from './HeaderMenuItem.Hover.styles';
import { useMenuState } from './hooks/useMenuState';

export interface MenuTitle {
title?: string;
Expand All @@ -18,6 +17,7 @@ interface Props extends MenuTitle {
children: React.ReactNode;
textColor?: string;
dropdownColor?: string;
isUserMenu?: boolean;
}

/**
Expand All @@ -30,31 +30,30 @@ const HeaderMenuItemHover = ({
classes,
dropdownColor,
children,
isUserMenu,
}: Props): JSX.Element => {
const { classes: styles } = useMenuHoverStyles();

const popoverAnchor = useRef(null);
const [anchorEl, setAnchorEl] = React.useState<HTMLElement | null>(null);

const handlePopoverOpen = () => {
setAnchorEl(popoverAnchor.current);
};

const handlePopoverClose = () => {
setAnchorEl(null);
};

const open = Boolean(anchorEl);
const {
isMenuOpen,
hasInteracted,
isTouchScreen,
openMenu,
closeMenu,
toggleMenu,
} = useMenuState();

return (
<div>
<div
className="relative p-10"
onMouseEnter={isTouchScreen ? undefined : openMenu}
onMouseLeave={closeMenu}
>
<span
ref={popoverAnchor}
aria-owns={open ? 'mouse-over-popover' : undefined}
className="relative"
aria-owns={isMenuOpen ? 'mouse-over-menu' : undefined}
aria-haspopup="true"
onMouseEnter={handlePopoverOpen}
onMouseLeave={handlePopoverClose}
onClick={handlePopoverOpen}
onClick={isTouchScreen ? toggleMenu : undefined}
>
{title && (
<span className={classes?.title}>
Expand All @@ -64,40 +63,29 @@ const HeaderMenuItemHover = ({
)}
{renderTitle && renderTitle()}
</span>
<Popover
disableRestoreFocus
id="mouse-over-popover"
className={styles.popover}
classes={{
paper: styles.popoverContent,
}}
open={open}
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
PaperProps={{
onMouseEnter: handlePopoverOpen,
onMouseLeave: handlePopoverClose,
}}
onClose={handlePopoverClose}
disableScrollLock={true}
sx={{ position: 'absolute' }}
<nav
id="mouse-over-menu"
className={`absolute top-15 ${
isUserMenu ? 'pt-35' : 'top-full'
} right-0 z-50 ${
isMenuOpen
? 'block opacity-100' + (hasInteracted ? ' animate-menuOpen' : '')
: 'opacity-0' +
(hasInteracted
? ' animate-menuClose pointer-events-none'
: ' hidden')
}`}
onClick={isTouchScreen ? closeMenu : undefined}
>
<Paper className={cx(classes?.paper, styles.paper)} elevation={5}>
<MenuList
classes={{ root: styles.text, padding: styles.noOutline }}
disablePadding
>
{children}
</MenuList>
</Paper>
</Popover>
<MenuList
className="bg-grey-0 rounded-[4px] border border-solid border-grey-300 shadow-[0px_5px_5px_-3px_rgba(0,0,0,0.2),_0px_8px_10px_1px_rgba(0,0,0,0.14),_0px_3px_14px_2px_rgba(0,0,0,0.12)]"
classes={{ root: styles.text, padding: styles.noOutline }}
disablePadding
component="div"
>
{children}
</MenuList>
</nav>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ export const useHeaderMenuHoverStyles = makeStyles()(theme => ({
boxSizing: 'border-box',
height: '100%',
lineHeight: theme.spacing(6),
paddingRight: theme.spacing(7.375),
paddingLeft: theme.spacing(7.375),
backgroundColor: 'inherit',
'& > a': {
borderBottom: '2px solid transparent',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import React from 'react';
import { BoxProps, MenuItem, SxProps } from '@mui/material';
import {
BoxProps,
MenuItem,
SxProps,
useMediaQuery,
useTheme,
} from '@mui/material';
import cx from 'clsx';

import { Theme } from '../../../../theme/muiTheme';
Expand Down Expand Up @@ -30,6 +35,7 @@ export interface HeaderMenuItemBase {

export interface MenuItemProps extends HeaderMenuItemBase {
item: Item;
isUserMenu?: boolean;
}

const HeaderMenuItem: React.FC<MenuItemProps> = ({
Expand All @@ -39,15 +45,18 @@ const HeaderMenuItem: React.FC<MenuItemProps> = ({
classes,
sx,
component = 'li',
isUserMenu,
}) => {
const { classes: styles } = useHeaderMenuHoverStyles();

const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down('md'));
return (
<MenuItem
className={cx(
classes?.root,
styles.menuItem,
pathname === item.href && styles.currentMenuItem,
isTablet && !isUserMenu ? '!hidden' : '',
)}
sx={[...sxToArray(sx)]}
component={component}
Expand All @@ -57,6 +66,7 @@ const HeaderMenuItem: React.FC<MenuItemProps> = ({
linkComponent={linkComponent}
pathname={pathname}
classes={{ paper: classes?.paper }}
isUserMenu={isUserMenu}
/>
</MenuItem>
);
Expand Down
Loading