CSS-in-JS интеграция

Tippy.js — это мощная библиотека для создания тултипов и всплывающих подсказок в браузере, которая легко интегрируется с современными подходами CSS-in-JS. При использовании CSS-in-JS стили определяются внутри компонентов на JavaScript, что позволяет управлять внешним видом тултипов динамически и локально.

В Tippy.js есть два основных способа стилизации при работе с CSS-in-JS: через кастомные темы и через функцию render для создания кастомного DOM-элемента.


Использование кастомных тем

Tippy.js поддерживает систему тем, что позволяет привязывать стили к тултипу через класс. С CSS-in-JS можно создавать динамические темы с уникальными названиями и применять их через свойство theme.

import tippy from 'tippy.js';
import 'tippy.js/dist/tippy.css';
import { css } from '@emotion/css';

const customTheme = css`
  background-color: #1e1e2f;
  color: #ffffff;
  border-radius: 8px;
  padding: 10px 15px;
  font-size: 14px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
`;

tippy('#button', {
  content: 'Подсказка с CSS-in-JS',
  theme: customTheme,
});

Особенности подхода:

  • theme принимает строку, соответствующую классу, созданному с помощью CSS-in-JS (emotion, styled-components и т.д.).
  • Любые изменения темы можно динамически обновлять, создавая новые классы и переназначая их тултипам.
  • Поддерживается наследование стандартных стилей Tippy.js, например анимации fade, scale.

Кастомный рендеринг тултипа через render

Функция render позволяет создавать полностью кастомный тултип с собственной разметкой и стилями. Это полезно, когда нужно использовать динамические стили, зависящие от состояния компонента.

import tippy from 'tippy.js';
import { css } from '@emotion/css';

const tooltipStyle = css`
  background-color: #ff6f61;
  color: white;
  border-radius: 5px;
  padding: 8px 12px;
  font-weight: bold;
  max-width: 200px;
  text-align: center;
`;

tippy('#custom-button', {
  render(instance) {
    const tooltip = document.createElement('div');
    tooltip.className = tooltipStyle;
    tooltip.textContent = 'Динамический тултип';
    return {
      popper: tooltip,
      onUpdate: () => {},
      destroy: () => tooltip.remove(),
    };
  },
});

Преимущества такого подхода:

  • Полный контроль над DOM тултипа и стилями.
  • Возможность внедрять сложные компоненты React или Vue внутрь тултипа.
  • Динамическое обновление содержимого и стилей без перезапуска Tippy.

Интеграция с React и Styled Components

При использовании React и styled-components можно создавать стилизованные тултипы, которые полностью используют преимущества CSS-in-JS.

import React from 'react';
import tippy from 'tippy.js';
import styled from 'styled-components';

const TooltipContent = styled.div`
  background: #333;
  color: #fff;
  border-radius: 6px;
  padding: 10px;
  font-size: 13px;
  box-shadow: 0 3px 6px rgba(0,0,0,0.25);
`;

export default function App() {
  React.useEffect(() => {
    tippy('#react-button', {
      content: <TooltipContent>Стилизованный React тултип</TooltipContent>,
      allowHTML: true,
      animation: 'shift-away',
    });
  }, []);

  return <button id="react-button">Hover me</button>;
}

Особенности интеграции:

  • Используется allowHTML: true для рендеринга React-компонента в тултип.
  • Стили полностью управляются через styled-components.
  • Можно легко менять тему или стили в зависимости от состояния приложения.

Динамическое изменение стилей

Tippy.js позволяет динамически обновлять классы или содержимое тултипа через методы setProps и setContent.

const instance = tippy('#dynamic-button', {
  content: 'Первоначальный текст',
  theme: 'initial',
});

document.querySelector('#dynamic-button').addEventListener('click', () => {
  const newTheme = css`
    background-color: #0077ff;
    color: white;
    padding: 12px;
  `;
  instance.setProps({ theme: newTheme, content: 'Обновлённый текст' });
});

Такой подход полезен для:

  • Адаптации стилей под состояние интерфейса.
  • Создания интерактивных тултипов с изменяемым контентом и внешним видом.
  • Реализации мульти-тематических интерфейсов с минимальным дублированием CSS.

Анимации и CSS-in-JS

Tippy.js поддерживает несколько встроенных анимаций: fade, scale, shift-away, shift-toward. С CSS-in-JS можно комбинировать эти анимации с кастомными стилями.

const animatedTooltip = css`
  transition: all 0.25s ease;
  &[data-state='visible'] {
    transform: translateY(-5px);
    opacity: 1;
  }
  &[data-state='hidden'] {
    transform: translateY(0);
    opacity: 0;
  }
`;

tippy('#animated-button', {
  content: 'Анимированный тултип',
  theme: animatedTooltip,
});

Такой подход обеспечивает плавную кастомную анимацию, полностью контролируемую через JS.


Важные рекомендации

  1. Использовать уникальные классы CSS-in-JS для каждой темы, чтобы избежать конфликтов.
  2. Динамические темы создаются через функции, возвращающие строки классов.
  3. Комбинировать render и CSS-in-JS, если требуется сложный контент или интеграция с компонентами React/Vue.
  4. Проверять поддержку HTML-контента, устанавливая allowHTML: true, при использовании React-компонентов.
  5. Использовать setProps и setContent для динамических обновлений тултипов без полного пересоздания.

Интеграция Tippy.js с CSS-in-JS позволяет полностью контролировать внешний вид и поведение тултипов, делая их максимально гибкими и адаптивными под любые требования интерфейса.