All files / app/src/shared/ui/modal modal.tsx

100% Statements 52/52
100% Branches 6/6
100% Functions 2/2
100% Lines 52/52

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 721x                       1x 36x   36x 33x 9x 9x 9x 33x 33x 33x 33x 36x   36x 36x 36x 36x 36x 36x   36x 36x 36x 36x 36x 36x 36x 36x     36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x 36x   36x 36x 36x 36x 36x 36x   36x 36x 36x 36x 36x   36x  
import { Fragment, useEffect } from 'react'
import { Dialog, Transition } from '@headlessui/react'
import { useRouter } from 'next/router'
import { FCWithChildren } from '@/shared/@types'
import cn from 'classnames'
 
export interface ModalProps {
  isOpen: boolean
  maskClosable?: boolean
  onClose: () => void
}
 
export const Modal: FCWithChildren<ModalProps> = ({ children, isOpen, maskClosable, className, onClose }) => {
  const router = useRouter()
 
  useEffect(() => {
    if (isOpen) {
      router.events.on('routeChangeComplete', onClose)
      router.events.on('routeChangeError', onClose)
    }
    return () => {
      router.events.off('routeChangeComplete', onClose)
      router.events.off('routeChangeError', onClose)
    }
  }, [isOpen])
 
  return (
    <Transition show={isOpen} as={Fragment}>
      <Dialog
        as='div'
        className='fixed inset-0 z-50 flex items-center justify-center overflow-y-auto'
        onClose={() => maskClosable && onClose()}
      >
        <Transition.Child
          as={Fragment}
          enter='ease-out duration-300'
          enterFrom='opacity-0'
          enterTo='opacity-100'
          leave='ease-in duration-200'
          leaveFrom='opacity-100'
          leaveTo='opacity-0'
        >
          {/* Цвет сделал статичным, т.к. скорее всего он дожен быть одинаковым не зависимо от темы */}
          <Dialog.Overlay
            data-testid='dialog-overlay'
            className='fixed bg-[#000] bg-opacity-50 inset-0 will-change-auto'
          />
        </Transition.Child>
        <Transition.Child
          as={Fragment}
          enter='ease-out duration-200'
          enterFrom='opacity-0 scale-95'
          enterTo='opacity-100 scale-100'
          leave='ease-in duration-150'
          leaveFrom='opacity-100 scale-100'
          leaveTo='opacity-0 scale-95'
        >
          <div
            data-testid='modal-body'
            className={cn(
              'bg-white p-[50px] rounded-base max-h-[calc(100vh-100px)] overflow-auto scrollbar will-change-transform',
              className
            )}
          >
            {children}
          </div>
        </Transition.Child>
      </Dialog>
    </Transition>
  )
}