Интерактивные тултипы

В библиотеке MUI (Material-UI) компонент Tooltip предоставляет возможность отображать всплывающие подсказки при наведении, фокусе или клике на элемент. Интерактивные тултипы отличаются тем, что пользователь может взаимодействовать с содержимым подсказки, не закрывая её сразу при попытке переместить курсор внутрь тултипа.

import React from 'react';
import Tooltip from '@mui/material/Tooltip';
import Button from '@mui/material/Button';

export default function InteractiveTooltip() {
  return (
    <Tooltip
      title="Это интерактивный тултип с кнопкой"
      interactive
    >
      <Button>Наведи на меня</Button>
    </Tooltip>
  );
}

Ключевой момент: для включения интерактивного поведения необходимо добавить проп interactive={true}. Без него тултип закрывается сразу при уходе курсора с элемента-мишени.


Настройка содержимого тултипа

Tooltip в MUI поддерживает любое JSX-содержимое, что позволяет добавлять кнопки, ссылки, списки и даже формы. Для этого используется проп title, который принимает JSX:

<Tooltip
  title={
    <div>
      <p>Подсказка с интерактивными элементами</p>
      <Button size="small">Действие</Button>
    </div>
  }
  interactive
>
  <Button>Наведи на меня</Button>
</Tooltip>

Важно: интерактивный тултип не требует дополнительных обработчиков для внутренних элементов — они автоматически доступны для клика.


Контроль задержки появления и исчезновения

MUI позволяет управлять временем появления (enterDelay) и исчезновения (leaveDelay) тултипа:

<Tooltip
  title="Тултип с задержкой"
  interactive
  enterDelay={500}   // 0.5 секунды до появления
  leaveDelay={200}   // 0.2 секунды до исчезновения
>
  <Button>Наведи на меня</Button>
</Tooltip>

Совет: для интерактивных тултипов лучше увеличить leaveDelay, чтобы пользователь успел переместить курсор внутрь подсказки и взаимодействовать с элементами.


Управление открытием тултипа через состояние

Для сложных случаев полезно полностью контролировать состояние тултипа с помощью пропов open, onOpen и onClose:

import React, { useState } from 'react';
import Tooltip from '@mui/material/Tooltip';
import Button from '@mui/material/Button';

export default function ControlledTooltip() {
  const [open, setOpen] = useState(false);

  return (
    <Tooltip
      title="Контролируемый интерактивный тултип"
      interactive
      open={open}
      onO pen={() => setOpen(true)}
      onCl ose={() => setOpen(false)}
    >
      <Button
        onMouseEn ter={() => setOpen(true)}
        onMouseLe ave={() => setOpen(false)}
      >
        Наведи на меня
      </Button>
    </Tooltip>
  );
}

Преимущество: такое управление позволяет интегрировать тултипы с внешней логикой и динамически менять содержимое подсказки.


Позиционирование тултипов

Tooltip поддерживает несколько вариантов позиционирования через проп placement. Основные значения: top, bottom, left, right, а также комбинации с start, end:

<Tooltip
  title="Тултип справа"
  interactive
  placement="right"
>
  <Button>Наведи на меня</Button>
</Tooltip>

Для интерактивных тултипов важно проверять, чтобы подсказка не перекрывала элементы, с которыми пользователь должен взаимодействовать.


Кастомизация внешнего вида

Стили тултипа можно менять через sx или styled. Пример изменения фона и тени:

import { styled } from '@mui/material/styles';
import Tooltip, { tooltipClasses } from '@mui/material/Tooltip';

const CustomTooltip = styled(({ className, ...props }) => (
  <Tooltip {...props} classes={{ popper: className }} />
))({
  [`& .${tooltipClasses.tooltip}`]: {
    backgroundColor: '#333',
    color: '#fff',
    fontSize: 14,
    boxShadow: '0 4px 20px rgba(0,0,0,0.3)',
  },
});

<CustomTooltip title="Стилизация тултипа" interactive>
  <Button>Наведи на меня</Button>
</CustomTooltip>

Особенность: использование styled позволяет детально контролировать как сам тултип, так и его содержимое.


Интерактивные тултипы с задержкой закрытия по клику

Чтобы тултип оставался открытым при клике на внутренние элементы, необходимо использовать комбинацию interactive и кастомного управления состоянием через onClose с проверкой события:

<Tooltip
  title={<Button onCl ick={() => alert('Клик внутри тултипа')}>Кликни меня</Button>}
  interactive
  open={open}
  onCl ose={(event) => {
    if (event && event.currentTarget.contains(event.relatedTarget)) return;
    setOpen(false);
  }}
>
  <Button onCl ick={() => setOpen(true)}>Открыть тултип</Button>
</Tooltip>

Пояснение: этот приём предотвращает мгновенное закрытие тултипа при попытке взаимодействия с его содержимым.


Интеграция с другими компонентами MUI

Интерактивные тултипы идеально подходят для меню, форм и списков, которые используют другие компоненты MUI, такие как Menu, List, TextField и Checkbox. Пример тултипа с формой:

<Tooltip
  title={
    <form>
      <input type="text" placeholder="Введите текст" />
      <Button type="submit">Отправить</Button>
    </form>
  }
  interactive
>
  <Button>Форма в тултипе</Button>
</Tooltip>

Рекомендация: для форм внутри тултипов стоит использовать onSubmit с предотвращением стандартного поведения, чтобы тултип не закрывался преждевременно.


Итоги использования интерактивных тултипов

  • Проп interactive — ключ к взаимодействию с содержимым.
  • JSX внутри title — позволяет создавать сложные интерфейсы.
  • Контроль состояния через open/onOpen/onClose — для сложной логики.
  • Настройка задержки с enterDelay и leaveDelay повышает удобство.
  • Стилизация через sx или styled — полный контроль внешнего вида.
  • Интеграция с формами и кнопками расширяет возможности тултипов до полноценного UI-компонента.