File size: 3,033 Bytes
4304c6d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { Dialog, Transition } from '@headlessui/react'
import { Fragment } from 'react'
import { XMarkIcon } from '@heroicons/react/24/outline'
// https://headlessui.com/react/dialog

type IModal = {
  className?: string
  wrapperClassName?: string
  isShow: boolean
  onClose: () => void
  title?: React.ReactNode
  description?: React.ReactNode
  children: React.ReactNode
  closable?: boolean
  overflowVisible?: boolean
}

export default function Modal({

  className,

  wrapperClassName,

  isShow,

  onClose,

  title,

  description,

  children,

  closable = false,

  overflowVisible = false,

}: IModal) {
  return (
    <Transition appear show={isShow} as={Fragment}>

      <Dialog as="div" className={`relative z-10 ${wrapperClassName}`} onClose={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"

        >

          <div className="fixed inset-0 bg-black bg-opacity-25" />

        </Transition.Child>



        <div

          className="fixed inset-0 overflow-y-auto"

          onClick={(e) => {

            e.preventDefault()

            e.stopPropagation()

          }}

        >

          <div className="flex min-h-full items-center justify-center p-4 text-center">

            <Transition.Child

              as={Fragment}

              enter="ease-out duration-300"

              enterFrom="opacity-0 scale-95"

              enterTo="opacity-100 scale-100"

              leave="ease-in duration-200"

              leaveFrom="opacity-100 scale-100"

              leaveTo="opacity-0 scale-95"

            >

              <Dialog.Panel className={`w-full max-w-md transform ${overflowVisible ? 'overflow-visible' : 'overflow-hidden'} rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all ${className}`}>

                {title && <Dialog.Title

                  as="h3"

                  className="text-lg font-medium leading-6 text-gray-900"

                >

                  {title}

                </Dialog.Title>}

                {description && <Dialog.Description className='text-gray-500 text-xs font-normal mt-2'>

                  {description}

                </Dialog.Description>}

                {closable

                  && <div className='absolute z-10 top-6 right-6 w-5 h-5 rounded-2xl flex items-center justify-center hover:cursor-pointer hover:bg-gray-100'>

                    <XMarkIcon className='w-4 h-4 text-gray-500' onClick={

                      (e) => {

                        e.stopPropagation()

                        onClose()

                      }

                    } />

                  </div>}

                {children}

              </Dialog.Panel>

            </Transition.Child>

          </div>

        </div>

      </Dialog>

    </Transition>
  )
}