Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 6x 10x 10x 10x 6x 4x 4x 4x 4x 4x 6x 6x 6x 6x 6x 6x 6x 10x 10x 10x 1x 1x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 3x 10x 10x 10x 10x 10x 10x 10x 10x | import { useEffect, useState } from 'react';
import { debounce } from 'lodash';
import { c } from '../../helpers';
import { hasClosestElement } from '../../helpers/htmlSelectorsHelpers';
import { IconVerticalDots } from '../Icons';
import {
SETTINGS_MODAL_TIMEOUT_TO_CLOSE,
SettingsModalPosition,
} from './SettingsModalConstants';
import { SettingsModalProps } from './SettingsModalProps';
import styles from './SettingsModal.module.css';
export default function SettingsModal({
className,
items = [],
position = SettingsModalPosition.LEFT,
visible,
onClose,
}: SettingsModalProps): JSX.Element {
const [openerWrapperId] = useState(crypto.randomUUID());
const [innerVisible, setInnerVisible] = useState(visible);
useEffect(() => {
setInnerVisible(visible);
}, [visible]);
useEffect(() => {
const handleClick = debounce((event: MouseEvent): void => {
if (event.defaultPrevented) {
return;
}
if (hasClosestElement(event, openerWrapperId)) {
return;
}
setInnerVisible(false);
onClose?.();
}, SETTINGS_MODAL_TIMEOUT_TO_CLOSE);
window.document.body.addEventListener('click', handleClick, true);
return () => {
window.document.body.removeEventListener('click', handleClick);
};
}, [openerWrapperId, onClose]);
const handleOpenerClick = (): void => {
setInnerVisible(!innerVisible);
};
return (
<div
className={c(
className,
styles.settings_menu,
innerVisible ? styles.open : styles.close,
styles[position]
)}
id={openerWrapperId}
>
<ul className={c(styles.menu)}>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
<button onClick={handleOpenerClick} className={c(styles.opener)}>
<IconVerticalDots className={c(styles.opener_icon)} />
</button>
</div>
);
}
|