UNPKG

@re-flex/ui

Version:
114 lines (113 loc) 4.6 kB
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;