index.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useRef } from 'react'
  4. import { RiCloseLine } from '@remixicon/react'
  5. import cn from '@/utils/classnames'
  6. import Drawer from '@/app/components/base/drawer'
  7. import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
  8. type Props = {
  9. isShow: boolean
  10. onHide: () => void
  11. panelClassName?: string
  12. maxWidthClassName?: string
  13. contentClassName?: string
  14. headerClassName?: string
  15. height?: number | string
  16. title: string | JSX.Element
  17. titleDescription?: string | JSX.Element
  18. body: JSX.Element
  19. foot?: JSX.Element
  20. isShowMask?: boolean
  21. clickOutsideNotOpen?: boolean
  22. positionCenter?: boolean
  23. }
  24. const DrawerPlus: FC<Props> = ({
  25. isShow,
  26. onHide,
  27. panelClassName = '',
  28. maxWidthClassName = '!max-w-[640px]',
  29. height = 'calc(100vh - 72px)',
  30. contentClassName,
  31. headerClassName,
  32. title,
  33. titleDescription,
  34. body,
  35. foot,
  36. isShowMask,
  37. clickOutsideNotOpen = true,
  38. positionCenter,
  39. }) => {
  40. const ref = useRef(null)
  41. const media = useBreakpoints()
  42. const isMobile = media === MediaType.mobile
  43. if (!isShow)
  44. return null
  45. return (
  46. // clickOutsideNotOpen to fix confirm modal click cause drawer close
  47. <Drawer
  48. isOpen={isShow}
  49. clickOutsideNotOpen={clickOutsideNotOpen}
  50. onClose={onHide}
  51. footer={null}
  52. mask={isMobile || isShowMask}
  53. positionCenter={positionCenter}
  54. panelClassname={cn('mt-16 mx-2 sm:mr-2 mb-3 !p-0 rounded-xl', panelClassName, maxWidthClassName)}
  55. >
  56. <div
  57. className={cn(contentClassName, 'w-full flex flex-col bg-white border-[0.5px] border-gray-200 rounded-xl shadow-xl')}
  58. style={{
  59. height,
  60. }}
  61. ref={ref}
  62. >
  63. <div className={cn(headerClassName, 'shrink-0 border-b border-b-gray-100 py-4')}>
  64. <div className='flex justify-between items-center pl-6 pr-5 h-6'>
  65. <div className='text-base font-semibold text-gray-900'>
  66. {title}
  67. </div>
  68. <div className='flex items-center'>
  69. <div
  70. onClick={onHide}
  71. className='flex justify-center items-center w-6 h-6 cursor-pointer'
  72. >
  73. <RiCloseLine className='w-4 h-4 text-gray-500' />
  74. </div>
  75. </div>
  76. </div>
  77. {titleDescription && (
  78. <div className='pl-6 pr-10 leading-[18px] text-xs font-normal text-gray-500'>
  79. {titleDescription}
  80. </div>
  81. )}
  82. </div>
  83. <div className='grow overflow-y-auto'>
  84. {body}
  85. </div>
  86. {foot && (
  87. <div className='shrink-0'>
  88. {foot}
  89. </div>
  90. )}
  91. </div>
  92. </Drawer>
  93. )
  94. }
  95. export default React.memo(DrawerPlus)