adding-modals
Index

Adding Modal

Whenever a modal is added, if it has any input/form values, it should never close when clicked outside. This causes user to accidentally lose added information. Modals should always be center aligned.

Short code

sq-ui-new-modal

Example usage

<Modal
wrapClassName="app-modal-flat"
closable={false}
centered
title={null}
destroyOnClose
footer={null}
visible={showTemplateDeleteConfirmationPopup}
maskClosable={false}
 
> {children}
> </Modal>
 
import React, { FC } from "react";
import {
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  IconButton,
  Typography,
  Divider,
  useMediaQuery,
  useTheme,
  Box,
} from "@mui/material";
import { Close } from "@mui/icons-material";
 
interface ModalProps {
  children?: React.ReactNode;
  open: boolean;
  onClose?: () => void;
  headerButton?: React.ReactNode;
  className?: string;
  title: string | React.ReactNode;
  subtitle?: string | React.ReactNode;
  search?: React.ReactNode;
  content?: React.ReactNode;
  flushContent?: boolean; // Remove padding from content, useful for forms with padding
  maxWidth?: "xs" | "sm" | "md" | "lg" | "xl";
  actionsContent?: React.ReactNode;
  disableRestoreFocus?: boolean;
  zIndex?: string | number;
  height?: number | string;
  showBottomBar?: boolean;
}
 
const CustomModal: FC<ModalProps> = ({
  open,
  onClose,
  title,
  subtitle,
  content,
  flushContent,
  className,
  search,
  headerButton,
  maxWidth,
  actionsContent,
  disableRestoreFocus = false,
  children,
  zIndex,
  height,
  showBottomBar = true,
}) => {
  const theme = useTheme();
  const fullScreen = useMediaQuery(theme.breakpoints.down("md"));
 
  return (
    <Dialog
      open={open}
      disableRestoreFocus={disableRestoreFocus}
      maxWidth={maxWidth}
      sx={{ zIndex }}
      fullWidth={fullScreen}
      PaperProps={{
        style: {
          width: "100%",
          overflow: "visible",
          position: fullScreen ? "fixed" : "relative",
          minHeight: fullScreen ? "100%" : "auto",
          borderRadius: fullScreen ? 0 : 12,
        },
      }}
    >
      <DialogTitle className="p-0">
        <Box className="flex justify-between items-center flex-wrap-reverse px-4 py-3">
          <Box>
            <Typography variant="h6">{title}</Typography>
            {subtitle && (
              <Typography variant="subtitle2">{subtitle}</Typography>
            )}
          </Box>
 
          <Box className="flex gap-2 items-center">
            {headerButton}
            {onClose && (
              <Box>
                <IconButton onClick={onClose}>
                  <Close />
                </IconButton>
              </Box>
            )}
          </Box>
        </Box>
        {title && <Divider />}
        <Box className="px-4 py-2 w-full">{search}</Box>
        {search && <Divider />}
      </DialogTitle>
      {children ? (
        flushContent ? (
          <Box className={`${className}`}>{children}</Box>
        ) : (
          <>
            <DialogContent
              className={`${className}`}
              sx={{ overflowY: "auto", flexGrow: 1, height }}
            >
              {children}
            </DialogContent>
            {showBottomBar && <DialogActions />}
          </>
        )
      ) : (
        <>
          <DialogContent
            className={`${className}`}
            sx={{ overflowY: "auto", flexGrow: 1, height }}
          >
            {content}
          </DialogContent>
 
          {actionsContent && <Divider />}
 
          {actionsContent && (
            <DialogActions sx={{ position: "sticky", bottom: 0, zIndex: 1 }}>
              {actionsContent}
            </DialogActions>
          )}
        </>
      )}
    </Dialog>
  );
};
 
export default CustomModal;