diff --git a/src/components/common/IconMenuButton/IconMenuButton.jsx b/src/components/common/IconMenuButton/IconMenuButton.tsx similarity index 50% rename from src/components/common/IconMenuButton/IconMenuButton.jsx rename to src/components/common/IconMenuButton/IconMenuButton.tsx index d5f18dc0ceceab5781eab699f5256025cbb852ce..eb8937785bccc76f39dfd6427e5ceac46ec652fd 100644 --- a/src/components/common/IconMenuButton/IconMenuButton.jsx +++ b/src/components/common/IconMenuButton/IconMenuButton.tsx @@ -1,5 +1,4 @@ -import { useState, isValidElement } from "react"; -import { string, shape, func, element, arrayOf, oneOfType } from "prop-types"; +import { useState, isValidElement, ReactNode, MouseEvent } from "react"; import { Button, Tooltip, @@ -12,26 +11,31 @@ import { import { AddBox, KeyboardArrowDown } from "@mui/icons-material"; import { useUniqueKeys } from "../../../hooks/useUniqueKeys"; -const propTypes = { - menuItems: arrayOf( - shape({ - text: oneOfType([string, element]), - action: func, - icon: element - }) - ), - icon: element, - id: string -}; +interface MenuItem { + text: string | ReactNode; + action?: ( + event: MouseEvent<HTMLLIElement | HTMLAnchorElement | HTMLButtonElement> + ) => void; + icon?: ReactNode; +} + +export interface IconMenuButtonProps { + menuItems?: MenuItem[]; + icon?: ReactNode; + id?: string; + className?: string; +} export const IconMenuButton = ({ menuItems, icon = <AddBox />, id, className -}) => { - const [anchorEl, setAnchorEl] = useState(null); - const menuItemsKeys = useUniqueKeys(menuItems); +}: IconMenuButtonProps) => { + const [anchorEl, setAnchorEl] = useState< + HTMLAnchorElement | HTMLLIElement | HTMLButtonElement | null + >(null); + const menuItemsKeys = useUniqueKeys(menuItems || []); /* Check if menuItems prop is an array of one @@ -39,7 +43,9 @@ export const IconMenuButton = ({ */ const singleItem = menuItems?.length === 1 && id !== "user-login-profile-"; - const handleClick = (event) => { + const handleClick = ( + event: MouseEvent<HTMLAnchorElement | HTMLLIElement | HTMLButtonElement> + ) => { setAnchorEl(event.currentTarget); }; @@ -56,10 +62,15 @@ export const IconMenuButton = ({ <Button className={className} id={`${id}icon-menu-button-button`} - color="primaryContrastText" - sx={icon?.props?.alt ? undefined : { mr: 1 }} onClick={singleItem ? menuItems[0]?.action : handleClick} - aria-label={singleItem ? menuItems[0]?.text : undefined} + aria-label={ + // eslint-disable-next-line no-nested-ternary + singleItem + ? typeof menuItems[0]?.text === "string" + ? menuItems[0]?.text + : "" + : undefined + } aria-controls={anchorEl ? `${id}icon-menu-button-menu` : undefined} aria-expanded={ // eslint-disable-next-line no-nested-ternary @@ -87,33 +98,32 @@ export const IconMenuButton = ({ onClose={handleClose} MenuListProps={{ "aria-labelledby": `${id}icon-menu-button-button` }} > - {menuItems?.map(({ text, action, icon }, i) => ( - <MenuItem - key={menuItemsKeys[i]} - disabled={!action} - onClick={(e) => { - if (action) { - handleClose(); - action(e); - } - }} - sx={action ? undefined : { opacity: "1.0!important" }} - > - {icon && <ListItemIcon>{icon}</ListItemIcon>} - {isValidElement(text) ? ( - text - ) : ( - <ListItemText - primary={text && text} - primaryTypographyProps={{ variant: "button" }} - /> - )} - </MenuItem> - ))} + {menuItemsKeys && + menuItems?.map(({ text, action, icon }, i) => ( + <MenuItem + key={menuItemsKeys[i]} + disabled={!action} + onClick={(e) => { + if (action) { + handleClose(); + action(e); + } + }} + sx={action ? undefined : { opacity: "1.0!important" }} + > + {icon && <ListItemIcon>{icon}</ListItemIcon>} + {isValidElement(text) ? ( + text + ) : ( + <ListItemText + primary={text && text} + primaryTypographyProps={{ variant: "button" }} + /> + )} + </MenuItem> + ))} </Menu> )} </> ); }; - -IconMenuButton.propTypes = propTypes; diff --git a/src/components/common/IconMenuButton/index.js b/src/components/common/IconMenuButton/index.ts similarity index 100% rename from src/components/common/IconMenuButton/index.js rename to src/components/common/IconMenuButton/index.ts