Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[docs][base] Update useMenu and useMenuItem hooks demo #34166

104 changes: 98 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, ...other } = props;

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

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

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

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

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

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

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

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

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}
>
Commands
</button>
<PopperUnstyled open={open} anchorEl={anchorEl}>
<Menu onClose={handleOnClose}>
<MenuItem>Cut</MenuItem>
<MenuItem>Copy</MenuItem>
<MenuItem>Paste</MenuItem>
</Menu>
</PopperUnstyled>
</React.Fragment>
);
}
106 changes: 99 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,56 @@ 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 },
ref: React.Ref<HTMLUListElement>,
) {
const { children, ...other } = props;
const { children, onClose, ...other } = props;

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

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

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

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

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

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

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}
>
Commands
</button>
<PopperUnstyled open={open} anchorEl={anchorEl}>
<Menu onClose={handleOnClose}>
<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.