You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
2.3 KiB

  1. import { Fragment, PropsWithChildren } from 'react';
  2. import { Dialog, Transition } from '@headlessui/react';
  3. export default function Modal({
  4. children,
  5. show = false,
  6. maxWidth = '2xl',
  7. closeable = true,
  8. onClose = () => {},
  9. }: PropsWithChildren<{
  10. show: boolean;
  11. maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | '2xl';
  12. closeable?: boolean;
  13. onClose: CallableFunction;
  14. }>) {
  15. const close = () => {
  16. if (closeable) {
  17. onClose();
  18. }
  19. };
  20. const maxWidthClass = {
  21. sm: 'sm:max-w-sm',
  22. md: 'sm:max-w-md',
  23. lg: 'sm:max-w-lg',
  24. xl: 'sm:max-w-xl',
  25. '2xl': 'sm:max-w-2xl',
  26. }[maxWidth];
  27. return (
  28. <Transition show={show} as={Fragment} leave="duration-200">
  29. <Dialog
  30. as="div"
  31. id="modal"
  32. className="fixed inset-0 flex overflow-y-auto px-4 py-6 sm:px-0 items-center z-50 transform transition-all"
  33. onClose={close}
  34. >
  35. <Transition.Child
  36. as={Fragment}
  37. enter="ease-out duration-300"
  38. enterFrom="opacity-0"
  39. enterTo="opacity-100"
  40. leave="ease-in duration-200"
  41. leaveFrom="opacity-100"
  42. leaveTo="opacity-0"
  43. >
  44. <div className="absolute inset-0 bg-gray-500/75" />
  45. </Transition.Child>
  46. <Transition.Child
  47. as={Fragment}
  48. enter="ease-out duration-300"
  49. enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
  50. enterTo="opacity-100 translate-y-0 sm:scale-100"
  51. leave="ease-in duration-200"
  52. leaveFrom="opacity-100 translate-y-0 sm:scale-100"
  53. leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
  54. >
  55. <Dialog.Panel
  56. className={`mb-6 bg-white rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full sm:mx-auto ${maxWidthClass}`}
  57. >
  58. {children}
  59. </Dialog.Panel>
  60. </Transition.Child>
  61. </Dialog>
  62. </Transition>
  63. );
  64. }