orchetera
Version:
Welcome to **Orchetera** — your orchestration tool to kickstart Firebase-ready projects with ease!
155 lines (145 loc) • 3.46 kB
JSX
import React, { useState, useRef } from "react";
import {
IconButton,
Dialog,
DialogTitle,
DialogContent,
DialogActions,
Popover,
Typography,
Stack,
useTheme,
} from "@mui/material";
const ActionableButton = ({
icon,
popupType = "dialog",
title,
label = "",
color = "inherit",
content,
actions,
onOpen,
onClose,
dialogProps = {},
popoverProps = {},
iconButtonProps = {},
labelProps = {},
direction = "row",
spacing = 1,
...props
}) => {
const theme = useTheme();
const [open, setOpen] = useState(false);
const anchorRef = useRef(null);
const actionableAction = React.Children.map(actions, (action) => {
if (!React.isValidElement(action)) return action;
if (action.props.closeTrigger) {
return React.cloneElement(action, {
onClick: (e) => {
action.props.onClick?.(e);
handleClose(e);
},
});
}
return action;
});
const handleOpen = (e) => {
setOpen(true);
if (onOpen) onOpen(e);
};
const handleClose = (e) => {
setOpen(false);
if (onClose) onClose(e);
};
return (
<>
<Stack
direction={direction}
spacing={spacing}
alignItems="center"
sx={{
"&.MuiBox-root": {
lineHeight: direction === "row" ? 0 : "normal",
display: "inline-flex",
},
"&:hover, &:active": {
backgroundColor: theme.palette.primary.alpha,
},
cursor: "pointer",
p: 1,
px: 2,
borderRadius: 2,
transition: "background-color .2s ease-out",
}}
onClick={handleOpen}
ref={anchorRef}
>
<IconButton
color={color}
ref={anchorRef}
onClick={handleOpen}
{...iconButtonProps}
sx={{
padding: label ? 0 : undefined,
color: `${color}`,
...iconButtonProps?.sx,
}}
{...props}
>
{icon}
</IconButton>
{label && (
<Typography
color={color}
variant="body1"
{...labelProps}
sx={{
userSelect: "none",
color: `${color}`,
...labelProps?.sx,
}}
>
{label}
</Typography>
)}
</Stack>
{popupType === "dialog" ? (
<Dialog open={open} onClose={handleClose} {...dialogProps}>
{title && <DialogTitle>{title}</DialogTitle>}
<DialogContent>{content}</DialogContent>
{actionableAction && (
<DialogActions>{actionableAction}</DialogActions>
)}
</Dialog>
) : (
<Popover
open={open}
anchorEl={anchorRef.current}
onClose={handleClose}
anchorOrigin={{
vertical: "bottom",
horizontal: "center",
}}
transformOrigin={{
vertical: "top",
horizontal: "center",
}}
{...popoverProps}
>
{title && <DialogTitle>{title}</DialogTitle>}
<DialogContent
sx={{
p: 0,
}}
>
{content}
</DialogContent>
{actionableAction && (
<DialogActions>{actionableAction}</DialogActions>
)}
</Popover>
)}
</>
);
};
export default ActionableButton;