All files / src/Modal Modal.tsx

100% Statements 10/10
100% Branches 2/2
100% Functions 2/2
100% Lines 10/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 108 109 110 111 112 113 114 115 116 117 118 119                                    8x                                               422x 422x 422x                                                   422x         422x               422x                                             8x   200x 200x                  
import * as React from 'react';
import { Box as ReakitBox, DialogProps as ReakitDialogProps, useDialog as useReakitDialog } from 'reakit';
import _merge from 'lodash/merge';
 
import { AnimateProps, Placement } from '../types';
import { useClassName, createComponent, createElement, createHook, omitCSSProps } from '../utils';
import { Box, BoxProps } from '../Box';
 
import { ModalBackdrop } from './ModalBackdrop';
import { ModalContext } from './ModalState';
import * as styles from './styles';
 
export type LocalModalProps = {
  hideBackdrop?: boolean;
  placement?: Placement;
} & AnimateProps;
export type ModalProps = BoxProps & ReakitDialogProps & LocalModalProps;
 
const useProps = createHook<ModalProps>(
  (props, { themeKey, themeKeyOverride }) => {
    let {
      children,
      hideBackdrop,
      hide,
      hideOnEsc,
      hideOnClickOutside,
      modal,
      preventBodyScroll,
      setModal,
      visible,
      unstable_animating,
      unstable_animated,
      baseId,
      unstable_initialFocusRef,
      unstable_finalFocusRef,
      unstable_modal,
      unstable_orphan,
      unstable_autoFocusOnHide,
      unstable_autoFocusOnShow,
      unstable_stopAnimation,
      unstable_setIsMounted,
      ...htmlProps
    } = props;
    const modalContext = React.useContext(ModalContext);
    const modalProps = useReakitDialog(
      _merge(
        {
          hide,
          hideOnEsc,
          hideOnClickOutside,
          modal,
          preventBodyScroll,
          setModal,
          visible,
          unstable_animating,
          unstable_animated,
          baseId,
          unstable_initialFocusRef,
          unstable_finalFocusRef,
          unstable_modal,
          unstable_orphan,
          unstable_autoFocusOnHide,
          unstable_autoFocusOnShow,
          unstable_stopAnimation,
          unstable_setIsMounted
        },
        modalContext.modal
      ),
      htmlProps
    );
    htmlProps = Box.useProps({
      ...props,
      ...modalProps
    });
 
    const className = useClassName({
      style: styles.Modal,
      styleProps: props,
      themeKey,
      themeKeyOverride,
      prevClassName: htmlProps.className
    });
 
    return {
      ...htmlProps,
      className,
      children: (
        <React.Fragment>
          {!hideBackdrop && (
            <ModalBackdrop {...omitCSSProps(props)}>
              <div />
            </ModalBackdrop>
          )}
          {children}
        </React.Fragment>
      )
    };
  },
  {
    defaultProps: {
      placement: 'center'
    },
    themeKey: 'Modal'
  }
);
 
export const Modal = createComponent<ModalProps>(
  props => {
    const modalProps = useProps(props);
    return createElement({ children: props.children, component: ReakitBox, use: props.use, htmlProps: modalProps });
  },
  {
    attach: {
      useProps
    },
    themeKey: 'Modal'
  }
);