import React, { useCallback, useEffect, useMemo, useRef } from 'react' import CloseButton from '@/components/atoms/CloseButton/CloseButton.component' import { IOffCanvas } from './OffCanvas.interface' import PortalComponent from '../../common/PortalComponent' import { StyledBackdrop, StyledOffCanvas2, StyledOffCanvasBody, StyledOffCanvasHeader } from './OffCanvas.theme' import { getId } from '@/helpers/uuid' const OffCanvas = ({ theme = 'dark', title = 'Offcanvas Title', position = 'top', backdrop = true, allowClickAway = true, allowEsc = true, allowScroll = true, children, isOpen = false, onClose, styles = {} }: IOffCanvas) => { const wrapperId = useMemo(() => getId(), []) const offCanvasRef = useRef(null) const onClickOutside = useCallback( (event: MouseEvent) => { if (!allowClickAway) return const offCanvasElement = offCanvasRef.current if ( offCanvasElement && !offCanvasElement.contains(event.target as Node) && isOpen ) { if (onClose) onClose() } }, [allowClickAway, isOpen, onClose] ) const onEscKey = useCallback( (event: KeyboardEvent) => { if (!allowEsc) return if (event.key === 'Escape' && isOpen) { if (onClose) onClose() } }, [allowEsc, isOpen, onClose] ) useEffect(() => { const handleMouseDown = (event: MouseEvent) => onClickOutside(event) const handleKeyDown = (event: KeyboardEvent) => onEscKey(event) // Attach the event listeners when the component mounts document.addEventListener('mousedown', handleMouseDown) document.addEventListener('keydown', handleKeyDown) // Detach the event listeners when the component unmounts return () => { document.removeEventListener('mousedown', handleMouseDown) document.removeEventListener('keydown', handleKeyDown) } }, [onClickOutside, onEscKey]) useEffect(() => { if (!allowScroll && isOpen) { document.body.style.overflow = 'hidden' } return () => { document.body.style.overflow = '' } }, [isOpen, allowScroll]) return ( {title} {children} {backdrop && } ) } export default OffCanvas