import { useState, useCallback, useEffect } from 'react'; /** * Хук для управления состоянием модального окна * Упрощает работу с открытием/закрытием модалок */ export function useModal(initialState = false) { const [isOpen, setIsOpen] = useState(initialState); const open = useCallback(() => { setIsOpen(true); }, []); const close = useCallback(() => { setIsOpen(false); }, []); const toggle = useCallback(() => { setIsOpen(prev => !prev); }, []); return { isOpen, open, close, toggle, setIsOpen }; } /** * Хук для управления ESC и клавиатурной навигацией в модалках */ export function useModalKeyboard(isOpen, onClose) { useEffect(() => { if (!isOpen) return; const handleEscape = (e) => { if (e.key === 'Escape') { onClose?.(); } }; document.addEventListener('keydown', handleEscape); return () => document.removeEventListener('keydown', handleEscape); }, [isOpen, onClose]); } /** * Хук для управления классом modal-open на body */ export function useModalBodyClass(isOpen) { useEffect(() => { if (isOpen) { document.body.classList.add('modal-open'); } else { document.body.classList.remove('modal-open'); } return () => { document.body.classList.remove('modal-open'); }; }, [isOpen]); } /** * Хук для управления focus trap внутри модалки */ export function useFocusTrap(isOpen, containerRef) { useEffect(() => { if (!isOpen || !containerRef.current) return; const container = containerRef.current; const focusableElements = container.querySelectorAll( 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' ); if (focusableElements.length === 0) return; const firstElement = focusableElements[0]; const lastElement = focusableElements[focusableElements.length - 1]; // Фокус на первый элемент при открытии firstElement?.focus(); const handleTabKey = (e) => { if (e.key !== 'Tab') return; if (e.shiftKey) { // Shift + Tab if (document.activeElement === firstElement) { e.preventDefault(); lastElement?.focus(); } } else { // Tab if (document.activeElement === lastElement) { e.preventDefault(); firstElement?.focus(); } } }; container.addEventListener('keydown', handleTabKey); return () => container.removeEventListener('keydown', handleTabKey); }, [isOpen, containerRef]); } /** * Комплексный хук, объединяющий все хуки для модалок */ export function useModalManager(initialState = false) { const modal = useModal(initialState); return { ...modal, // Дополнительные утилиты openWithData: (data) => { modal.setData?.(data); modal.open(); }, }; } export default useModal;