All files / src/components/DialogBox DialogBox.tsx

0% Statements 0/10
0% Branches 0/29
0% Functions 0/4
0% Lines 0/10

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107                                                                                                                                                                                                                     
import React, { CSSProperties, ReactNode } from 'react';
import './styles.scss';
import Icon from '../Icon/Icon';
import { IconButton } from '@mui/material';
import { useDeviceInfo } from '../../utils';
 
export type DialogBoxSize = 'small' | 'medium' | 'large' | 'x-large';
 
export interface Props {
  title: string;
  size: DialogBoxSize;
  message?: string | string[];
  children?: ReactNode;
  leftButton?: ReactNode;
  rightButtons?: JSX.Element[];
  middleButtons?: JSX.Element[];
  onClose?: () => void;
  open: boolean;
  scrolled?: boolean;
  skrim?: boolean;
  style?: CSSProperties;
}
 
export default function DialogBox(props: Props): JSX.Element | null {
  const {
    title,
    size,
    message,
    children,
    leftButton,
    rightButtons,
    middleButtons,
    onClose,
    open,
    scrolled,
    skrim,
    style,
  } = props;
 
  const hasFooter = leftButton || rightButtons || middleButtons;
 
  const { isMobile } = useDeviceInfo();
 
  return open ? (
    <div
      className={`dialog-box-container${skrim ? '--skrim' : ''} ${open ? 'dialog-box--opened' : 'dialog-box--closed'} ${
        isMobile ? 'mobile' : ''
      }`}
      onClick={(event) => {
        if (event.target instanceof HTMLElement && event.target.classList.contains('dialog-box--opened')) {
          onClose?.();
        }
      }}
      style={style}
    >
      <div className={`dialog-box dialog-box--${size}`}>
        <div className='dialog-box--header'>
          <div className='close-icon-spacer' />
          <p className='title'>{title}</p>
          <IconButton onClick={onClose} size='small'>
            <Icon name='close' className='icon-close' />
          </IconButton>
        </div>
        <div
          className={(hasFooter ? 'dialog-box--body' : 'dialog-box--body-no-footer') + (scrolled ? ' scrolled' : '')}
        >
          <div className='dialog-box--message'>{message}</div>
          <div className='dialog-box--boundary'>{children}</div>
        </div>
        {hasFooter && (
          <div className='dialog-box--footer'>
            {leftButton && (
              <div className='dialog-box--footer-container'>
                <div className='left-button'>{leftButton}</div>
                <div className='right-buttons'>
                  {rightButtons?.map((rb, index) => {
                    const rbWithKey = {
                      ...rb,
                      key: `rb-${index}`,
                      props: { ...rb.props, size: rb.props.size || 'medium' },
                    };
 
                    return rbWithKey;
                  })}
                </div>
              </div>
            )}
            {middleButtons && (
              <div className='dialog-box--actions-container'>
                {middleButtons?.map((mb, index) => {
                  const mbWithKey = {
                    ...mb,
                    key: `mb-${index}`,
                    props: { ...mb.props, size: mb.props.size || 'medium' },
                  };
 
                  return mbWithKey;
                })}
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  ) : null;
}