Skip to content

Commit

Permalink
[docs][base] Update useMenu and useMenuItem hooks demo (mui#34166)
Browse files Browse the repository at this point in the history
  • Loading branch information
ZeeshanTamboli authored and Daniel Rabe committed Nov 29, 2022
1 parent 12d533b commit 6cd7f08
Show file tree
Hide file tree
Showing 3 changed files with 209 additions and 21 deletions.
109 changes: 103 additions & 6 deletions docs/data/base/components/menu/UseMenu.js
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react';
import PropTypes from 'prop-types';
import { useMenu, MenuUnstyledContext } from '@mui/base/MenuUnstyled';
import { useMenuItem } from '@mui/base/MenuItemUnstyled';
import PopperUnstyled from '@mui/base/PopperUnstyled';
import { GlobalStyles } from '@mui/system';
import clsx from 'clsx';

Expand All @@ -18,6 +19,15 @@ const grey = {
900: '#24292f',
};

const blue = {
100: '#DAECFF',
200: '#99CCF3',
400: '#3399FF',
500: '#007FFF',
600: '#0072E5',
900: '#003A75',
};

const styles = `
.menu-root {
font-family: IBM Plex Sans, sans-serif;
Expand Down Expand Up @@ -80,10 +90,53 @@ const styles = `
background-color: ${grey[800]};
color: ${grey[300]};
}
.button {
font-family: IBM Plex Sans, sans-serif;
font-size: 0.875rem;
box-sizing: border-box;
min-height: calc(1.5em + 22px);
border-radius: 12px;
padding: 12px 16px;
line-height: 1.5;
background: #fff;
border: 1px solid ${grey[200]};
color: ${grey[900]};
cursor: pointer;
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 120ms;
&:hover {
background: ${grey[50]};
border-color: ${grey[300]};
}
&:focus {
border-color: ${blue[400]};
outline: 3px solid ${blue[200]};
}
}
.mode-dark .button {
background: ${grey[900]};
border: 1px solid ${grey[700]};
color: ${grey[300]};
&:hover {
background: ${grey[800]};
border-color: ${grey[600]};
}
&:focus {
outline: 3px solid ${blue[500]}
}
}
`;

const Menu = React.forwardRef(function Menu(props, ref) {
const { children, ...other } = props;
const { children, onClose, open, ...other } = props;

const {
registerItem,
Expand All @@ -93,6 +146,8 @@ const Menu = React.forwardRef(function Menu(props, ref) {
getItemState,
} = useMenu({
listboxRef: ref,
onClose,
open,
});

const contextValue = {
Expand All @@ -114,6 +169,8 @@ const Menu = React.forwardRef(function Menu(props, ref) {

Menu.propTypes = {
children: PropTypes.node,
onClose: PropTypes.func.isRequired,
open: PropTypes.bool.isRequired,
};

const MenuItem = React.forwardRef(function MenuItem(props, ref) {
Expand All @@ -139,14 +196,54 @@ MenuItem.propTypes = {
};

export default function UseMenu() {
const [anchorEl, setAnchorEl] = React.useState(null);
const preventReopen = React.useRef(false);
const buttonRef = React.useRef(null);

const handleOnClick = (event) => {
if (preventReopen.current) {
event.preventDefault();
preventReopen.current = false;
return;
}

setAnchorEl(anchorEl ? null : event.currentTarget);
};

const handleOnClose = () => {
setAnchorEl(null);
buttonRef.current.focus();
};

const open = Boolean(anchorEl);

const handleButtonMouseDown = () => {
if (open) {
// Prevents the menu from reopening right after closing
// when clicking the button.
preventReopen.current = true;
}
};

return (
<React.Fragment>
<GlobalStyles styles={styles} />
<Menu>
<MenuItem>Cut</MenuItem>
<MenuItem>Copy</MenuItem>
<MenuItem>Paste</MenuItem>
</Menu>
<button
type="button"
className="button"
onClick={handleOnClick}
onMouseDown={handleButtonMouseDown}
ref={buttonRef}
>
Commands
</button>
<PopperUnstyled open={open} anchorEl={anchorEl}>
<Menu onClose={handleOnClose} open={open}>
<MenuItem>Cut</MenuItem>
<MenuItem>Copy</MenuItem>
<MenuItem>Paste</MenuItem>
</Menu>
</PopperUnstyled>
</React.Fragment>
);
}
113 changes: 106 additions & 7 deletions docs/data/base/components/menu/UseMenu.tsx
Expand Up @@ -5,6 +5,7 @@ import {
MenuUnstyledContextType,
} from '@mui/base/MenuUnstyled';
import { useMenuItem } from '@mui/base/MenuItemUnstyled';
import PopperUnstyled from '@mui/base/PopperUnstyled';
import { GlobalStyles } from '@mui/system';
import clsx from 'clsx';

Expand All @@ -20,6 +21,16 @@ const grey = {
800: '#32383f',
900: '#24292f',
};

const blue = {
100: '#DAECFF',
200: '#99CCF3',
400: '#3399FF',
500: '#007FFF',
600: '#0072E5',
900: '#003A75',
};

const styles = `
.menu-root {
font-family: IBM Plex Sans, sans-serif;
Expand Down Expand Up @@ -82,13 +93,59 @@ const styles = `
background-color: ${grey[800]};
color: ${grey[300]};
}
.button {
font-family: IBM Plex Sans, sans-serif;
font-size: 0.875rem;
box-sizing: border-box;
min-height: calc(1.5em + 22px);
border-radius: 12px;
padding: 12px 16px;
line-height: 1.5;
background: #fff;
border: 1px solid ${grey[200]};
color: ${grey[900]};
cursor: pointer;
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 120ms;
&:hover {
background: ${grey[50]};
border-color: ${grey[300]};
}
&:focus {
border-color: ${blue[400]};
outline: 3px solid ${blue[200]};
}
}
.mode-dark .button {
background: ${grey[900]};
border: 1px solid ${grey[700]};
color: ${grey[300]};
&:hover {
background: ${grey[800]};
border-color: ${grey[600]};
}
&:focus {
outline: 3px solid ${blue[500]}
}
}
`;

const Menu = React.forwardRef(function Menu(
props: React.ComponentPropsWithoutRef<'ul'>,
props: React.ComponentPropsWithoutRef<'ul'> & {
onClose: () => void;
open: boolean;
},
ref: React.Ref<HTMLUListElement>,
) {
const { children, ...other } = props;
const { children, onClose, open, ...other } = props;

const {
registerItem,
Expand All @@ -98,6 +155,8 @@ const Menu = React.forwardRef(function Menu(
getItemState,
} = useMenu({
listboxRef: ref,
onClose,
open,
});

const contextValue: MenuUnstyledContextType = {
Expand Down Expand Up @@ -139,14 +198,54 @@ const MenuItem = React.forwardRef(function MenuItem(
});

export default function UseMenu() {
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const preventReopen = React.useRef(false);
const buttonRef = React.useRef<HTMLButtonElement>(null);

const handleOnClick = (event: React.MouseEvent<HTMLElement>) => {
if (preventReopen.current) {
event.preventDefault();
preventReopen.current = false;
return;
}

setAnchorEl(anchorEl ? null : event.currentTarget);
};

const handleOnClose = () => {
setAnchorEl(null);
buttonRef.current!.focus();
};

const open = Boolean(anchorEl);

const handleButtonMouseDown = () => {
if (open) {
// Prevents the menu from reopening right after closing
// when clicking the button.
preventReopen.current = true;
}
};

return (
<React.Fragment>
<GlobalStyles styles={styles} />
<Menu>
<MenuItem>Cut</MenuItem>
<MenuItem>Copy</MenuItem>
<MenuItem>Paste</MenuItem>
</Menu>
<button
type="button"
className="button"
onClick={handleOnClick}
onMouseDown={handleButtonMouseDown}
ref={buttonRef}
>
Commands
</button>
<PopperUnstyled open={open} anchorEl={anchorEl}>
<Menu onClose={handleOnClose} open={open}>
<MenuItem>Cut</MenuItem>
<MenuItem>Copy</MenuItem>
<MenuItem>Paste</MenuItem>
</Menu>
</PopperUnstyled>
</React.Fragment>
);
}
8 changes: 0 additions & 8 deletions docs/data/base/components/menu/UseMenu.tsx.preview

This file was deleted.

0 comments on commit 6cd7f08

Please sign in to comment.