Хук useFocus в библиотеке Floating UI предназначен для
управления фокусом в компонентах пользовательского интерфейса, особенно
когда речь идёт о всплывающих элементах, таких как тултипы, поповеры и
модальные окна. Он обеспечивает корректное поведение фокуса при открытии
и закрытии этих элементов, предотвращает потерю фокуса и управляет его
возвратом к исходному элементу.
useFocus возвращает объект с несколькими ключевыми
свойствами и методами, которые позволяют интегрировать фокус с логикой
отображения Floating UI:
const { isFocused, getReferenceProps, getFloatingProps } = useFocus({ ...options });
useFocus поддерживает несколько опций, которые позволяют
гибко настраивать поведение фокуса:
true) — включает
или отключает отслеживание фокуса.true) —
возвращает фокус к исходному элементу после закрытия всплывающего
окна.Пример использования:
const { isFocused, getReferenceProps, getFloatingProps } = useFocus({
initialFocus: () => firstInputRef.current,
returnFocus: true,
});
useFocus идеально комбинируется с другими хуками
Floating UI, такими как useFloating,
useInteractions и useDismiss. С помощью
useInteractions можно объединить обработку кликов, ховеров
и фокуса в одном объекте пропсов:
const floating = useFloating({
placement: 'bottom-start',
});
const focus = useFocus({ returnFocus: true });
const dismiss = useDismiss(floating.context);
const interactions = useInteractions([focus, dismiss]);
return (
<>
<button {...interactions.getReferenceProps({ ref: referenceRef })}>
Открыть меню
</button>
{isOpen && (
<div {...interactions.getFloatingProps({ ref: floatingRef })}>
<input ref={firstInputRef} placeholder="Введите текст" />
<button>Подтвердить</button>
</div>
)}
</>
);
В этом примере useFocus обеспечивает, что фокус
автоматически перейдет на первый элемент внутри поповера при его
открытии, и вернется к кнопке после закрытия.
useFocus позволяет решать следующие задачи:
Автоматическая установка фокуса Используя
initialFocus, можно указать элемент для фокуса сразу после
открытия Floating UI.
Сохранение фокуса внутри всплывающего окна При попытке переместить фокус вне компонента хук предотвращает его потерю, что важно для модальных окон и меню.
Возврат фокуса к исходному элементу Когда всплывающее окно закрывается, фокус возвращается на элемент, с которого оно было вызвано, что улучшает навигацию с клавиатуры и доступность.
Совместимость с клавиатурными событиями
useFocus корректно работает с Tab и
Shift+Tab, обеспечивая циклическое перемещение фокуса
внутри всплывающего компонента.
Фокус на динамически добавленные элементы
const [items, setItems] = useState([]);
const { getFloatingProps } = useFocus({
initialFocus: () => floatingRef.current?.querySelector('input'),
});
useEffect(() => {
if (items.length > 0) {
floatingRef.current.querySelector('input')?.focus();
}
}, [items]);
Комбинация с анимациями открытия/закрытия
const { isFocused, getFloatingProps } = useFocus({
returnFocus: true,
});
return (
<motion.div
{...getFloatingProps()}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
>
<input />
</motion.div>
);
В этом случае useFocus гарантирует, что фокус будет
установлен на input даже при анимации открытия всплывающего
компонента.
initialFocus для указания конкретного
элемента фокуса.getReferenceProps и
getFloatingProps для корректного отслеживания.returnFocus повышает доступность интерфейса и удобство
работы с клавиатурой.useFocus является базовым инструментом для организации
корректного фокусного поведения, что особенно важно для создания
доступных интерфейсов с модальными окнами, тултипами и динамическими
меню.