Radix UI предоставляет набор высоко настраиваемых компонентов для React, при этом основной подход к темизации строится на CSS-переменных и системах стилей, совместимых с CSS-in-JS и Tailwind. Каждый компонент Radix UI использует структуру слотов и классов, что позволяет внедрять кастомные темы без изменения исходного кода библиотеки.
Главная идея — разделение логики компонента и внешнего вида, что обеспечивает гибкость и масштабируемость. Темизация может осуществляться на нескольких уровнях:
Radix UI активно использует подход с CSS-переменными. В качестве примера, для кнопки можно определить базовые переменные:
:root {
--button-bg: #1f2937;
--button-text: #f9fafb;
--button-hover-bg: #374151;
}
В компоненте эти переменные применяются через стили:
import { Button } from '@radix-ui/react-button';
import './button.css';
<Button style={{
backgroundColor: 'var(--button-bg)',
color: 'var(--button-text)'
}}>
Кнопка
</Button>
Преимущество: при смене темы достаточно изменить значения переменных, а компоненты автоматически адаптируются.
Для более динамичных решений часто используется Stitches — CSS-in-JS библиотека, рекомендуемая Radix. Она позволяет создавать варианты и темы, управлять состояниями компонента напрямую.
import { styled } from '@stitches/react';
import { Button as RadixButton } from '@radix-ui/react-button';
const Button = styled(RadixButton, {
variants: {
variant: {
primary: { backgroundColor: '$primary', color: '$onPrimary' },
secondary: { backgroundColor: '$secondary', color: '$onSecondary' }
},
size: {
small: { padding: '4px 8px', fontSize: '12px' },
large: { padding: '12px 24px', fontSize: '16px' }
}
}
});
// Применение темы
<Button variant="primary" size="large">Пример</Button>
Здесь $primary и $secondary — ключи темы,
которые можно менять через createTheme для динамических
светлых и темных режимов.
import { createTheme } from '@stitches/react';
const darkTheme = createTheme({
colors: {
primary: '#1f2937',
onPrimary: '#f9fafb',
secondary: '#374151',
onSecondary: '#e5e7eb'
}
});
Radix UI использует концепцию slots, что позволяет передавать пользовательские элементы в компоненты с сохранением логики. Это особенно важно для темизации, так как можно менять только визуальную часть, не затрагивая поведение.
import * as Tooltip from '@radix-ui/react-tooltip';
<Tooltip.Root>
<Tooltip.Trigger>Наведи меня</Tooltip.Trigger>
<Tooltip.Content className="tooltip-content">
Текст подсказки
</Tooltip.Content>
</Tooltip.Root>
С помощью CSS можно управлять стилями .tooltip-content
для разных тем:
[data-theme='dark'] .tooltip-content {
background: #1f2937;
color: #f9fafb;
}
[data-theme='light'] .tooltip-content {
background: #f3f4f6;
color: #111827;
}
Ключевой момент: использование
data-theme позволяет переключать тему глобально без
переписывания компонентов.
Для динамической темы часто используют контекст или React state. Например:
import { useState } from 'react';
function App() {
const [theme, setTheme] = useState('light');
return (
<div data-theme={theme}>
<Button variant="primary">Кнопка</Button>
<button onCl ick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Сменить тему
</button>
</div>
);
}
Компоненты Radix UI автоматически адаптируются к изменениям CSS-переменных или классов, что делает подход полностью реактивным.
Radix UI легко интегрируется с Tailwind CSS, где классы заменяют
CSS-переменные, а состояния компонентов управляются через
data- атрибуты:
<Button className="bg-gray-800 text-white hover:bg-gray-700">
Кнопка
</Button>
Для темного режима Tailwind предоставляет директиву
dark::
<Button className="bg-white text-black dark:bg-gray-800 dark:text-white">
Кнопка
</Button>
Radix UI автоматически добавляет необходимые атрибуты для состояний,
таких как data-state="open" или data-disabled,
что позволяет Tailwind управлять стилями с помощью этих селекторов.
Все компоненты Radix UI имеют структурированные состояния:
data-state — открыто/закрыто (open,
closed)data-disabled — отключеноdata-highlighted — подсвеченоЭто позволяет задавать уникальные стили для каждого состояния в рамках темы:
[data-theme='dark'] [data-state='open'] {
background-color: #374151;
}
[data-theme='light'] [data-disabled] {
opacity: 0.5;
}
Этот подход обеспечивает масштабируемую и гибкую систему темизации, полностью совместимую с реактивным обновлением состояния и современными CSS-инструментами.