import React, { useEffect } from 'react' import * as DialogPrimitive from '@radix-ui/react-dialog' import classNames from 'classnames' import debounce from 'lodash.debounce' import Overlay from '~components/common/Overlay' import styles from './index.module.scss' interface Props extends React.DetailedHTMLProps< React.DialogHTMLAttributes, HTMLDivElement > { wrapperClassName?: string headerRef?: React.RefObject footerRef?: React.RefObject scrollable?: boolean onEscapeKeyDown: (event: KeyboardEvent) => void onOpenAutoFocus: (event: Event) => void } const DialogContent = React.forwardRef(function Dialog( { scrollable, wrapperClassName, headerRef, footerRef, children, ...props }, forwardedRef ) { // Classes const classes = classNames( { [styles.dialogContent]: true, }, props.className?.split(' ').map((className) => styles[className]) ) // Handlers function handleScroll(event: React.UIEvent) { const scrollTop = event.currentTarget.scrollTop const scrollHeight = event.currentTarget.scrollHeight const clientHeight = event.currentTarget.clientHeight if (headerRef && headerRef.current) manipulateHeaderShadow(headerRef.current, scrollTop) if (footerRef && footerRef.current) manipulateFooterShadow( footerRef.current, scrollTop, scrollHeight, clientHeight ) } function manipulateHeaderShadow(header: HTMLDivElement, scrollTop: number) { const boxShadowBase = '0 2px 8px' const maxValue = 50 if (scrollTop >= 0) { const input = scrollTop > maxValue ? maxValue : scrollTop const boxShadowOpacity = mapRange(input, 0, maxValue, 0.0, 0.16) const borderOpacity = mapRange(input, 0, maxValue, 0.0, 0.24) header.style.boxShadow = `${boxShadowBase} rgba(0, 0, 0, ${boxShadowOpacity})` header.style.borderBottomColor = `rgba(0, 0, 0, ${borderOpacity})` } } function manipulateFooterShadow( footer: HTMLDivElement, scrollTop: number, scrollHeight: number, clientHeight: number ) { const boxShadowBase = '0 -2px 8px' const minValue = scrollHeight - 200 const currentScroll = scrollTop + clientHeight if (currentScroll >= minValue) { const input = currentScroll < minValue ? minValue : currentScroll const boxShadowOpacity = mapRange( input, minValue, scrollHeight, 0.16, 0.0 ) const borderOpacity = mapRange(input, minValue, scrollHeight, 0.24, 0.0) footer.style.boxShadow = `${boxShadowBase} rgba(0, 0, 0, ${boxShadowOpacity})` footer.style.borderTopColor = `rgba(0, 0, 0, ${borderOpacity})` } } const calculateFooterShadow = debounce(() => { const boxShadowBase = '0 -2px 8px' const scrollable = document.querySelector(`.${styles.scrollable}`) const footer = footerRef if (footer && footer.current) { if (scrollable && scrollable.clientHeight >= scrollable.scrollHeight) { footer.current.style.boxShadow = `${boxShadowBase} rgba(0, 0, 0, 0)` footer.current.style.borderTopColor = `rgba(0, 0, 0, 0)` } else { footer.current.style.boxShadow = `${boxShadowBase} rgba(0, 0, 0, 0.16)` footer.current.style.borderTopColor = `rgba(0, 0, 0, 0.24)` } } }, 100) useEffect(() => { window.addEventListener('resize', calculateFooterShadow) calculateFooterShadow() return () => { window.removeEventListener('resize', calculateFooterShadow) } }, [calculateFooterShadow]) function mapRange( value: number, low1: number, high1: number, low2: number, high2: number ) { return low2 + ((high2 - low2) * (value - low1)) / (high1 - low1) } return ( styles[className]) )} >
{children}
) }) DialogContent.defaultProps = { scrollable: true, } export default DialogContent