Темизация

Floating UI предоставляет гибкие механизмы для управления позиционированием всплывающих элементов, таких как тултипы, модальные окна, меню и поповеры. Темизация в контексте Floating UI заключается в способности адаптировать внешний вид и поведение этих элементов под различные визуальные стили и темы приложения, обеспечивая согласованность интерфейса.

Работа с контекстом темы

Floating UI не ограничивается визуальной стороной компонентов, но интегрируется с системой темы через стили CSS или CSS-in-JS. Основной подход заключается в создании контекста темы, который передается компонентам через провайдер или через глобальные CSS-переменные.

Пример использования CSS-переменных для динамической смены темы:

:root {
  --floating-bg: #ffffff;
  --floating-color: #000000;
  --floating-shadow: 0 4px 8px rgba(0,0,0,0.1);
}

[data-theme="dark"] {
  --floating-bg: #1e1e1e;
  --floating-color: #f0f0f0;
  --floating-shadow: 0 4px 12px rgba(0,0,0,0.5);
}

В компоненте Floating UI можно применить эти переменные:

import { useFloating } from '@floating-ui/react';

function Tooltip({ reference, children }) {
  const { x, y, strategy } = useFloating({
    placement: 'top'
  });

  return (
    <div
      style={{
        position: strategy,
        top: y ?? 0,
        left: x ?? 0,
        backgroundColor: 'var(--floating-bg)',
        color: 'var(--floating-color)',
        boxShadow: 'var(--floating-shadow)',
        padding: '0.5rem 1rem',
        borderRadius: '4px'
      }}
    >
      {children}
    </div>
  );
}

Динамическая смена темы

Для динамического переключения темы Floating UI рекомендуется использовать состояние или контекст. Это позволяет мгновенно обновлять стили всплывающих элементов при изменении темы приложения.

import { useState } from 'react';

function App() {
  const [theme, setTheme] = useState('light');

  return (
    <div data-theme={theme}>
      <button onCl ick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        Переключить тему
      </button>
      <Tooltip reference={document.querySelector('#button')}>Пример тултипа</Tooltip>
    </div>
  );
}

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

Использование CSS-in-JS (например, styled-components или @emotion/styled) позволяет создавать тематические Floating UI элементы без прямой зависимости от глобальных переменных.

import styled from '@emotion/styled';

const FloatingContainer = styled.div`
  position: absolute;
  top: ${({ top }) => top}px;
  left: ${({ left }) => left}px;
  background-color: ${({ theme }) => theme.floatingBg};
  color: ${({ theme }) => theme.floatingColor};
  box-shadow: ${({ theme }) => theme.floatingShadow};
  border-radius: 4px;
  padding: 0.5rem 1rem;
`;

Тема передается через ThemeProvider:

import { ThemeProvider } from '@emotion/react';

const lightTheme = {
  floatingBg: '#fff',
  floatingColor: '#000',
  floatingShadow: '0 4px 8px rgba(0,0,0,0.1)',
};

const darkTheme = {
  floatingBg: '#1e1e1e',
  floatingColor: '#f0f0f0',
  floatingShadow: '0 4px 12px rgba(0,0,0,0.5)',
};

Темизация анимаций

Floating UI поддерживает анимации через библиотеку @floating-ui/react и CSS-переходы. Для согласованной темы анимации можно менять длительность и easing в зависимости от светлой или темной темы:

:root {
  --floating-animation-duration: 200ms;
  --floating-animation-easing: ease-out;
}

[data-theme="dark"] {
  --floating-animation-duration: 300ms;
  --floating-animation-easing: cubic-bezier(0.4, 0, 0.2, 1);
}

.floating-enter {
  opacity: 0;
  transform: translateY(-5px);
  transition: opacity var(--floating-animation-duration) var(--floating-animation-easing),
              transform var(--floating-animation-duration) var(--floating-animation-easing);
}

.floating-enter-active {
  opacity: 1;
  transform: translateY(0);
}

Поддержка контрастных режимов и accessibility

При создании тем Floating UI важно учитывать контрастность и доступность:

  • Для темного режима использовать светлые цвета текста и яркий акцент на фоне.
  • Для светлого режима избегать слишком светлых фоновых оттенков.
  • Использовать aria-* атрибуты для всех всплывающих элементов, чтобы они оставались доступными для screen reader.
<div
  role="tooltip"
  id="tooltip-1"
  aria-hidden={isVisible ? 'false' : 'true'}
>
  {children}
</div>

Комбинирование с Tailwind CSS

Tailwind CSS и Floating UI прекрасно сочетаются для быстрого создания тематических всплывающих элементов. Динамическая тема может быть реализована через условные классы:

<div
  className={`absolute top-0 left-0 rounded p-2 shadow-md ${
    theme === 'dark' ? 'bg-gray-800 text-white' : 'bg-white text-black'
  }`}
>
  Tooltip content
</div>

Вывод

Темизация в Floating UI строится на сочетании CSS-переменных, контекста темы и возможностей CSS-in-JS. Правильное управление темами позволяет создавать гибкие, согласованные и доступные интерфейсы, где всплывающие элементы автоматически подстраиваются под визуальный стиль приложения и пользовательские настройки.