@re-flex/ui
Version:
Re-Flex ui library
114 lines (113 loc) • 4.6 kB
JavaScript
import Box from "@re-flex/styled/Box";
import { useTheme, useThemingCss, } from "@re-flex/styles";
import clsx from "clsx";
import React, { useImperativeHandle, useMemo, useState } from "react";
import { Slide } from "..";
import useIsomorphicEffect from "../hooks/useIsomorphicEffect";
import Modal from "../Modal";
import { Fade } from "../Transitions/Fade";
import Text from "../Typography";
const getDrawerPosition = (placement) => {
return placement === "top"
? { top: "0", left: "0", right: "0" }
: placement === "bottom"
? { bottom: "0", left: "0", right: "0" }
: placement === "left"
? { top: "0", bottom: "0", left: "0" }
: { top: "0", bottom: "0", right: "0" };
};
const Dialog = React.forwardRef(({ role = "dialog", position = "absolute", placement = "top", radius = 1, duration = 300, children, header, content, fullScreen, footer, maxWidth, fullWidth, headerProps = {}, containerProps = {}, contentProps = {}, footerProps = {}, }, ref) => {
const theme = useTheme();
const sxss = useThemingCss();
const [visible, setVisible] = useState(null);
const Transition = role === "drawer" ? Slide : Fade;
const onOpen = () => {
setVisible(true);
};
const onClose = () => {
setVisible(false);
};
const onDestroy = () => {
setVisible(null);
};
useIsomorphicEffect(() => {
if (visible === false) {
let timeout = setTimeout(() => {
setVisible(null);
clearTimeout(timeout);
}, duration);
}
}, [visible]);
useImperativeHandle(ref, () => ({
onOpen,
onClose,
onDestroy,
}));
const renderStyles = useMemo(() => {
const style = [
{
bgColor: "background.paper",
borderRadius: role === "dialog" ? radius : "0",
transition: `all ${duration}ms ease-in-out`,
position: role === "drawer" ? "fixed" : position,
display: "flex",
flexDirection: "column",
zIndex: theme.zIndex.modal + 1,
},
(fullWidth ||
(role === "drawer" &&
(placement === "top" || placement === "bottom"))) && {
width: "100%",
},
maxWidth && {
maxWidth: Math.max(theme.breakpoints.values[maxWidth], 444),
margin: 32,
width: "calc(100% - 64px)",
},
{
height: role === "drawer" && (placement === "left" || placement === "right")
? "100%"
: "inherit",
},
role === "drawer" && getDrawerPosition(placement),
fullScreen && {
inset: "0",
height: "100%",
width: "100%",
},
];
return style.filter(Boolean).map(sxss);
}, [
theme,
fullScreen,
maxWidth,
fullWidth,
duration,
role,
position,
placement,
radius,
]);
console.log("renderStyles", clsx(renderStyles));
return (React.createElement(Modal, { open: visible, onClose: onClose, duration: duration, onClosed: onDestroy },
React.createElement(Transition, { duration: duration, in: visible, onExit: onClose, onExited: onDestroy, className: clsx(renderStyles), ...(role === "drawer"
? { direction: placement === "top" ? "up" : placement }
: {}) },
!!header && (React.createElement(Box, { p: 3, mb: 1, ...headerProps }, typeof header === "string" ? (React.createElement(Text, { variant: "h6", component: "h6" }, header)) : (React.isValidElement(header) &&
header({
onOpen,
onClose,
})))),
React.createElement(Box, { ...contentProps },
!!content && (React.createElement(Box, { p: 3, mb: !!children && 2 }, typeof content === "string" ? (React.createElement(Text, { variant: "body1", component: "p" }, content)) : (content({
onOpen,
onClose,
})))),
children),
React.createElement("div", { style: { flexGrow: 1 } }),
footer && (React.createElement(Box, { p: 3, display: "flex", justifyContent: "flex-end", columnGap: 1, ...footerProps }, footer({
onOpen,
onClose,
}))))));
});
export default Dialog;