export default class FocusManager { static trapFocus(element, logger = null) { const focusableSelectors = [ 'button', '[href]', 'input', 'select', 'textarea', '[tabindex]:not([tabindex="-1"])' ].join(', '); const focusableElements = element.querySelectorAll(focusableSelectors); if (focusableElements.length === 0) { logger?.warn('No focusable elements found for trap'); return; } const firstElement = focusableElements[0]; const lastElement = focusableElements[focusableElements.length - 1]; const handleKeydown = (e) => { if (e.key !== 'Tab') return; if (e.shiftKey) { if (document.activeElement === firstElement) { lastElement.focus(); e.preventDefault(); } } else { if (document.activeElement === lastElement) { firstElement.focus(); e.preventDefault(); } } }; element.addEventListener('keydown', handleKeydown); return () => element.removeEventListener('keydown', handleKeydown); } static moveFocusToElement(element, options = {}) { const { smooth = true, center = true } = options; element.focus({ preventScroll: !smooth }); if (smooth) { element.scrollIntoView({ behavior: 'smooth', block: center ? 'center' : 'nearest' }); } } static getFirstFocusableElement(container) { const focusableSelectors = [ 'button', '[href]', 'input', 'select', 'textarea', '[tabindex]:not([tabindex="-1"])' ].join(', '); return container.querySelector(focusableSelectors); } static restoreFocus(element) { const prevElement = element.dataset.previousFocus; if (prevElement) { const el = document.querySelector(prevElement); if (el) el.focus(); } } static saveFocus(element) { const current = document.activeElement; if (current) { element.dataset.previousFocus = current.getAttribute('data-focus-id') || current.id; } } }