useTooltipTrigger для триггеров

Хук useTooltipTrigger предназначен для создания интерактивных триггеров, которые управляют отображением подсказок (tooltip) в приложениях на React с использованием библиотеки React Aria. Он обеспечивает корректное управление состоянием подсказок, доступностью для экранных читалок и взаимодействием с клавиатурой и мышью, соблюдая рекомендации ARIA.


Импорт и базовое использование

Для работы с useTooltipTrigger необходимо импортировать хук из пакета @react-aria/tooltip:

import { useTooltipTrigger } from '@react-aria/tooltip';

Хук принимает объект параметров и возвращает свойства (props) для триггера и подсказки, а также объект состояния:

const { triggerProps, tooltipProps } = useTooltipTrigger({ 
    delay: 500, 
    placement: 'top' 
});
  • delay — задержка в миллисекундах перед отображением подсказки после наведения или фокуса.
  • placement — положение подсказки относительно триггера (top, bottom, left, right).

Свойства триггера

Хук возвращает объект triggerProps, который следует передавать элементу, выступающему триггером подсказки (например, кнопке или ссылке):

<button {...triggerProps}>Наведи на меня</button>

Основные моменты:

  1. События мыши: onMouseEnter и onMouseLeave автоматически управляют показом и скрытием подсказки с учётом задержки.
  2. Фокусировка клавиатурой: onFocus и onBlur обеспечивают открытие подсказки при фокусе и её скрытие при потере фокуса.
  3. ARIA-атрибуты: aria-describedby автоматически связывает триггер с подсказкой для поддержки экранных читалок.

Свойства подсказки

tooltipProps нужно применять к компоненту подсказки:

<div {...tooltipProps}>Это подсказка</div>

Особенности:

  • role="tooltip" устанавливается автоматически, что обеспечивает корректное поведение для пользователей с особыми потребностями.
  • Подсказка может быть позиционирована относительно триггера с помощью свойства placement.
  • Хук заботится о скрытии подсказки при кликах вне компонента и при навигации с клавиатуры.

Интеграция со useOverlayPosition

Для точного позиционирования часто используют useOverlayPosition:

import { useOverlayPosition } from '@react-aria/overlays';

const { overlayProps, placement } = useOverlayPosition({
  targetRef: triggerRef,
  overlayRef: tooltipRef,
  placement: 'top',
  offset: 8
});

В этом случае tooltipProps объединяется с overlayProps:

<div {...tooltipProps} {...overlayProps}>Подсказка с точным позиционированием</div>
  • targetRef — ссылка на элемент триггера.
  • overlayRef — ссылка на элемент подсказки.
  • offset — смещение подсказки относительно триггера.
  • placement — позиция подсказки.

Состояние подсказки

useTooltipTrigger можно комбинировать с useTooltipTriggerState из @react-stately/tooltip для управления состоянием:

import { useTooltipTriggerState } from '@react-stately/tooltip';

const state = useTooltipTriggerState({ delay: 500 });
const { triggerProps, tooltipProps } = useTooltipTrigger({ 
    delay: 500, 
    placement: 'top' 
}, state);
  • state.isOpen — проверка, открыта ли подсказка.
  • state.open() — открывает подсказку.
  • state.close() — закрывает подсказку.

Использование состояния позволяет программно управлять подсказками, а также синхронизировать их с другими компонентами интерфейса.


Обработка событий и кастомизация

useTooltipTrigger поддерживает передачу дополнительных обработчиков:

const { triggerProps } = useTooltipTrigger({
  onOpenChange: (isOpen) => console.log('Подсказка:', isOpen)
});
  • onOpenChange вызывается при каждом открытии или закрытии подсказки.
  • Можно комбинировать с пользовательскими событиями мыши и клавиатуры, сохраняя корректную работу ARIA.

Советы по использованию

  1. Минимизировать визуальные конфликты — избегать перекрытия подсказок другими интерактивными элементами.
  2. Учитывать задержку — слишком короткая задержка может создавать раздражение, слишком длинная — снижать удобство.
  3. Обеспечивать доступность — всегда использовать triggerProps и tooltipProps без изменения ключевых ARIA-атрибутов.
  4. Комбинировать с порталами — для сложных интерфейсов с модальными окнами и всплывающими элементами удобно использовать ReactDOM.createPortal.

Пример комплексного компонента

import { useTooltipTrigger } from '@react-aria/tooltip';
import { useTooltipTriggerState } from '@react-stately/tooltip';
import { useRef } from 'react';

function TooltipButton() {
  const triggerRef = useRef();
  const tooltipRef = useRef();
  const state = useTooltipTriggerState({ delay: 400 });
  const { triggerProps, tooltipProps } = useTooltipTrigger(
    { placement: 'bottom' }, 
    state
  );

  return (
    <>
      <button {...triggerProps} ref={triggerRef}>
        Нажми или наведи
      </button>
      {state.isOpen && (
        <div {...tooltipProps} ref={tooltipRef} style={{ background: '#333', color: '#fff', padding: '4px 8px', borderRadius: '4px', position: 'absolute' }}>
          Это подсказка
        </div>
      )}
    </>
  );
}
  • Используется ref для корректного позиционирования и передачи в useOverlayPosition, если требуется точная позиция.
  • Состояние подсказки управляется через useTooltipTriggerState.
  • Подсказка отображается условно через проверку state.isOpen.

Важные моменты

  • useTooltipTrigger автоматически заботится о доступности, связывая триггер с подсказкой через aria-describedby.
  • Совместим с клавиатурной навигацией и экранными читалками.
  • Легко комбинируется с оверлеями и другими компонентами React Aria.
  • Позволяет гибко управлять поведением подсказок через delay, placement и события.

useTooltipTrigger обеспечивает создание интерактивных, доступных и управляемых подсказок без необходимости вручную прописывать ARIA-атрибуты и обработчики событий, что делает его ключевым инструментом для интерфейсов с подсказками.