@findify/react-components
Version:
Findify react UI components
47 lines (46 loc) • 1.93 kB
JSX
import { useState, useEffect, useCallback } from 'react';
import { useSpring, config, animated } from 'react-spring';
import cx from 'classnames';
import styles from 'components/common/Drawer/style.css';
const defaultOptions = {
from: { transform: `translate3d(-100%, 0, 0)` },
to: { transform: `translate3d(0%, 0, 0)` },
};
let _scrollTop = 0;
export default ({ hideModal, name, theme = styles, options = defaultOptions, children, ...rest }) => {
const [open, setOpen] = useState(false);
const { opacity, ...style } = useSpring({
from: { opacity: 0 },
to: { ...(open ? options.to : options.from), opacity: open ? 1 : 0 },
config: config[options.easing || 'default'],
});
const close = useCallback(() => {
setOpen(false);
setTimeout(() => hideModal(name), 400);
}, []);
useEffect(() => {
const handleEscape = (e) => {
if (e.key !== 'Escape')
return;
close();
};
_scrollTop = window.scrollY;
document.querySelector('body')?.classList.add(theme.bodyNoScroll);
document.addEventListener('keydown', handleEscape);
requestAnimationFrame(() => setOpen(true));
return () => {
document.querySelector('body')?.classList.remove(theme.bodyNoScroll);
document.removeEventListener('keydown', handleEscape);
window.scrollTo(0, _scrollTop);
_scrollTop = 0;
};
}, []);
return (<>
<animated.div className={cx('findify-container', theme.backdrop)} onClick={close} style={{ opacity }}/>
<animated.div className={cx('findify-container', theme.content, options.className)} style={style} role="region" aria-live="polite" aria-modal="true" ref={(r) => r && r.focus()}>
{children instanceof Function
? children({ ...rest, hideModal: close })
: children}
</animated.div>
</>);
};