| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 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 | 
					
						
							| 
									
										
										
										
											2023-05-17 19:05:51 +08:00
										 |  |  |   wrapperClassName?: string | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |   isShow: boolean | 
					
						
							|  |  |  |   onClose: () => void | 
					
						
							|  |  |  |   title?: React.ReactNode | 
					
						
							|  |  |  |   description?: React.ReactNode | 
					
						
							|  |  |  |   children: React.ReactNode | 
					
						
							|  |  |  |   closable?: boolean | 
					
						
							| 
									
										
										
										
											2023-05-31 14:10:59 +08:00
										 |  |  |   overflowVisible?: boolean | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default function Modal({ | 
					
						
							|  |  |  |   className, | 
					
						
							| 
									
										
										
										
											2023-05-17 19:05:51 +08:00
										 |  |  |   wrapperClassName, | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |   isShow, | 
					
						
							|  |  |  |   onClose, | 
					
						
							|  |  |  |   title, | 
					
						
							|  |  |  |   description, | 
					
						
							|  |  |  |   children, | 
					
						
							|  |  |  |   closable = false, | 
					
						
							| 
									
										
										
										
											2023-05-31 14:10:59 +08:00
										 |  |  |   overflowVisible = false, | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | }: IModal) { | 
					
						
							|  |  |  |   return ( | 
					
						
							| 
									
										
										
										
											2023-05-19 17:36:44 +08:00
										 |  |  |     <Transition appear show={isShow} as={Fragment}> | 
					
						
							| 
									
										
										
										
											2023-05-21 17:21:01 +08:00
										 |  |  |       <Dialog as="div" className={`relative z-10 ${wrapperClassName}`} onClose={onClose}> | 
					
						
							| 
									
										
										
										
											2023-05-19 17:36:44 +08:00
										 |  |  |         <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> | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-19 17:36:44 +08:00
										 |  |  |         <div className="fixed inset-0 overflow-y-auto"> | 
					
						
							|  |  |  |           <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" | 
					
						
							|  |  |  |             > | 
					
						
							| 
									
										
										
										
											2023-05-31 14:10:59 +08:00
										 |  |  |               <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}`}> | 
					
						
							| 
									
										
										
										
											2023-05-19 17:36:44 +08:00
										 |  |  |                 {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 | 
					
						
							| 
									
										
										
										
											2023-12-18 15:41:24 +08:00
										 |  |  |                   && <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() | 
					
						
							|  |  |  |                       } | 
					
						
							|  |  |  |                     } /> | 
					
						
							| 
									
										
										
										
											2023-05-19 17:36:44 +08:00
										 |  |  |                   </div>} | 
					
						
							|  |  |  |                 {children} | 
					
						
							|  |  |  |               </Dialog.Panel> | 
					
						
							|  |  |  |             </Transition.Child> | 
					
						
							|  |  |  |           </div> | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       </Dialog> | 
					
						
							|  |  |  |     </Transition> | 
					
						
							| 
									
										
										
										
											2023-05-15 08:51:32 +08:00
										 |  |  |   ) | 
					
						
							|  |  |  | } |