{"version":3,"file":"IconButtonMenu.mjs","sources":["../../../../../../../../web/src/adminPortal/components/IconButtonMenu.tsx"],"sourcesContent":["import { IconButton, Menu, MenuItem, MenuItemProps, PopoverOrigin, styled } from '@mui/material';\nimport React, { useCallback, useMemo, useState } from 'react';\n\nimport { useUniqueId } from '../../utils/uniqueId';\nimport { FlexBox } from './FlexBox';\nimport { Typography, TypographyProps } from './Typography';\n\nconst StyledMenuItem = styled(MenuItem)(({ theme }) => ({\n  padding: theme.spacing(1),\n  '& svg': {\n    height: 16,\n    width: 16,\n  },\n}));\n\nconst StyledIconButton = styled(IconButton)({\n  padding: '3px',\n});\n\nconst anchorOrigin = { horizontal: 'center', vertical: 'bottom' } as const;\nconst transformOrigin = { horizontal: 'right', vertical: 'top' } as const;\n\nexport interface Action<T> {\n  key: string;\n  label: string;\n  icon?: React.ReactNode;\n  onClick: (item: T) => void;\n  isDangerous?: boolean;\n  isVisible?: boolean | ((item: T) => boolean);\n}\n\ninterface ActionMenuItemProps<T> extends Omit<MenuItemProps, 'button' | 'onClick'> {\n  children: React.ReactNode;\n  onClick: (item: T) => void;\n  onClose: (() => void) | undefined;\n  icon?: React.ReactNode;\n  color?: TypographyProps['color'];\n  item: T;\n}\n\nconst ActionMenuItem = <T,>({ children, onClick, onClose, color, icon, item, ...rest }: ActionMenuItemProps<T>) => {\n  const handleClick = useCallback(() => {\n    onClick(item);\n    onClose?.();\n  }, [item, onClick, onClose]);\n\n  return (\n    <StyledMenuItem {...rest} disableRipple onClick={handleClick}>\n      <Typography variant=\"body2\" color={color}>\n        <FlexBox alignItems=\"center\">\n          {icon}\n          {children}\n        </FlexBox>\n      </Typography>\n    </StyledMenuItem>\n  );\n};\n\ninterface IconButtonMenuProps<T> {\n  actions: readonly Readonly<Action<T>>[];\n  anchorEl?: HTMLElement;\n  closeOnClick?: boolean;\n  item: T;\n  idPrefix: string;\n  icon: React.ReactNode;\n  menuAnchorOrigin?: PopoverOrigin;\n  menuTransformOrigin?: PopoverOrigin;\n  onOpen?: () => void;\n  onClose?: () => void;\n}\n\nexport const IconButtonMenu = <T,>({\n  actions,\n  anchorEl: anchorElProp,\n  closeOnClick = true,\n  icon,\n  item,\n  idPrefix,\n  menuAnchorOrigin = anchorOrigin,\n  menuTransformOrigin = transformOrigin,\n  onClose,\n  onOpen,\n}: IconButtonMenuProps<T>) => {\n  const [anchorEl, setAnchorEl] = useState<HTMLElement>();\n\n  const handleClose = useCallback(() => {\n    setAnchorEl(undefined);\n    onClose?.();\n  }, [onClose]);\n\n  const handleOpen = useCallback(\n    (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n      onOpen?.();\n      setAnchorEl(anchorElProp ?? e.currentTarget);\n    },\n    [anchorElProp, onOpen],\n  );\n\n  const id = useUniqueId(idPrefix);\n\n  const children = useMemo(() => {\n    return actions.map(({ key, label, onClick, icon, isDangerous, isVisible = true }) => {\n      if (!isVisible || (typeof isVisible === 'function' && !isVisible(item))) {\n        return null;\n      }\n\n      return (\n        <ActionMenuItem\n          key={key}\n          item={item}\n          onClick={onClick}\n          onClose={closeOnClick ? handleClose : undefined}\n          color={isDangerous ? 'error' : undefined}\n          icon={icon}\n        >\n          {label}\n        </ActionMenuItem>\n      );\n    });\n  }, [actions, closeOnClick, handleClose, item]);\n\n  const isOpen = !!anchorEl;\n\n  return (\n    <>\n      <StyledIconButton\n        disableTouchRipple\n        aria-label=\"actions\"\n        color=\"inherit\"\n        onClick={handleOpen}\n        aria-controls={id}\n        aria-haspopup\n        size=\"small\"\n      >\n        {icon}\n      </StyledIconButton>\n      <Menu\n        id={id}\n        open={isOpen}\n        anchorEl={anchorEl}\n        variant=\"menu\"\n        anchorOrigin={menuAnchorOrigin}\n        transformOrigin={menuTransformOrigin}\n        onClose={handleClose}\n      >\n        {children}\n      </Menu>\n    </>\n  );\n};\n"],"names":["StyledMenuItem","styled","MenuItem","theme","padding","spacing","height","width","StyledIconButton","IconButton","anchorOrigin","horizontal","vertical","transformOrigin","ActionMenuItem","children","onClick","onClose","color","icon","item","rest","handleClick","useCallback","React","disableRipple","Typography","variant","FlexBox","alignItems","IconButtonMenu","actions","anchorEl","anchorElProp","closeOnClick","idPrefix","menuAnchorOrigin","menuTransformOrigin","onOpen","setAnchorEl","useState","handleClose","undefined","handleOpen","e","currentTarget","id","useUniqueId","useMemo","map","key","label","isDangerous","isVisible","isOpen","disableTouchRipple","aria-label","aria-controls","aria-haspopup","size","Menu","open"],"mappings":"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"}