fix(striker-ui): add button with menu

main
Tsu-ba-me 1 year ago
parent 5b231fdb7e
commit 753358a13b
  1. 83
      striker-ui/components/ButtonWithMenu.tsx
  2. 6
      striker-ui/types/ButtonWithMenu.d.ts

@ -0,0 +1,83 @@
import { MoreVert as MoreVertIcon } from '@mui/icons-material';
import { Box } from '@mui/material';
import { FC, MouseEventHandler, useCallback, useMemo, useState } from 'react';
import ContainedButton from './ContainedButton';
import IconButton from './IconButton/IconButton';
import Menu from './Menu';
const ButtonWithMenu: FC<ButtonWithMenuProps> = (props) => {
const {
children,
muiMenuProps,
onButtonClick,
onItemClick,
variant = 'icon',
...menuProps
} = props;
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
const open = useMemo(() => Boolean(anchorEl), [anchorEl]);
const buttonContent = useMemo(() => children ?? <MoreVertIcon />, [children]);
const buttonClickHandler = useCallback<MouseEventHandler<HTMLButtonElement>>(
(...args) => {
const {
0: { currentTarget },
} = args;
setAnchorEl(currentTarget);
return onButtonClick?.call(null, ...args);
},
[onButtonClick],
);
const buttonElement = useMemo(() => {
if (variant === 'contained') {
return (
<ContainedButton onClick={buttonClickHandler}>
{buttonContent}
</ContainedButton>
);
}
return (
<IconButton onClick={buttonClickHandler}>{buttonContent}</IconButton>
);
}, [buttonClickHandler, buttonContent, variant]);
const itemClickHandler = useCallback<
Exclude<MenuProps['onItemClick'], undefined>
>(
(key, value, ...rest) => {
setAnchorEl(null);
return onItemClick?.call(null, key, value, ...rest);
},
[onItemClick],
);
return (
<Box>
{buttonElement}
<Menu
muiMenuProps={{
anchorEl,
keepMounted: true,
onClose: () => setAnchorEl(null),
...muiMenuProps,
}}
onItemClick={itemClickHandler}
open={open}
{...menuProps}
/>
</Box>
);
};
export default ButtonWithMenu as <T>(
props: ButtonWithMenuProps<T>,
) => ReturnType<FC<ButtonWithMenuProps<T>>>;

@ -0,0 +1,6 @@
type ButtonWithMenuOptionalProps<T = unknown> = Omit<MenuProps<T>, 'open'> & {
onButtonClick?: import('react').MouseEventHandler<HTMLButtonElement>;
variant?: 'contained' | 'icon';
};
type ButtonWithMenuProps<T = unknown> = ButtonWithMenuOptionalProps<T>;
Loading…
Cancel
Save