123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- import { Dialog, Transition } from '@headlessui/react'
- import { Fragment } from 'react'
- import { XMarkIcon } from '@heroicons/react/24/outline'
- import classNames from '@/utils/classnames'
- // 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={classNames('modal-dialog', 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={classNames(
- 'modal-panel',
- overflowVisible ? 'overflow-visible' : 'overflow-hidden',
- 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>
- )
- }
|