Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

index.tsx 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import { Fragment, useCallback } from 'react'
  2. import type { ElementType, ReactNode } from 'react'
  3. import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild } from '@headlessui/react'
  4. import classNames from '@/utils/classnames'
  5. // https://headlessui.com/react/dialog
  6. type DialogProps = {
  7. className?: string
  8. titleClassName?: string
  9. bodyClassName?: string
  10. footerClassName?: string
  11. titleAs?: ElementType
  12. title?: ReactNode
  13. children: ReactNode
  14. footer?: ReactNode
  15. show: boolean
  16. onClose?: () => void
  17. }
  18. const CustomDialog = ({
  19. className,
  20. titleClassName,
  21. bodyClassName,
  22. footerClassName,
  23. titleAs,
  24. title,
  25. children,
  26. footer,
  27. show,
  28. onClose,
  29. }: DialogProps) => {
  30. const close = useCallback(() => onClose?.(), [onClose])
  31. return (
  32. <Transition appear show={show} as={Fragment}>
  33. <Dialog as="div" className="relative z-40" onClose={close}>
  34. <TransitionChild>
  35. <div className={classNames(
  36. 'fixed inset-0 bg-background-overlay-backdrop backdrop-blur-[6px]',
  37. 'duration-300 ease-in data-[closed]:opacity-0',
  38. 'data-[enter]:opacity-100',
  39. 'data-[leave]:opacity-0',
  40. )} />
  41. </TransitionChild>
  42. <div className="fixed inset-0 overflow-y-auto">
  43. <div className="flex min-h-full items-center justify-center">
  44. <TransitionChild>
  45. <DialogPanel className={classNames(
  46. 'w-full max-w-[800px] overflow-hidden rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg p-6 shadow-xl transition-all',
  47. 'duration-100 ease-in data-[closed]:scale-95 data-[closed]:opacity-0',
  48. 'data-[enter]:scale-100 data-[enter]:opacity-100',
  49. 'data-[enter]:scale-95 data-[leave]:opacity-0',
  50. className,
  51. )}>
  52. {Boolean(title) && (
  53. <DialogTitle
  54. as={titleAs || 'h3'}
  55. className={classNames('title-2xl-semi-bold pb-3 pr-8 text-text-primary', titleClassName)}
  56. >
  57. {title}
  58. </DialogTitle>
  59. )}
  60. <div className={classNames(bodyClassName)}>
  61. {children}
  62. </div>
  63. {Boolean(footer) && (
  64. <div className={classNames('flex items-center justify-end gap-2 px-6 pb-6 pt-3', footerClassName)}>
  65. {footer}
  66. </div>
  67. )}
  68. </DialogPanel>
  69. </TransitionChild>
  70. </div>
  71. </div>
  72. </Dialog>
  73. </Transition >
  74. )
  75. }
  76. export default CustomDialog