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.

index.tsx 3.0KB

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