Radix UI представляет собой набор низкоуровневых, доступных компонентов для React, которые предоставляют полностью контролируемые UI-элементы без собственного визуального стиля. Это делает их идеальными для интеграции с Tailwind CSS, так как стилизация полностью ложится на разработчика.
Tailwind CSS предоставляет утилитарный подход к стилизации, позволяя задавать классы напрямую в JSX. Основная задача при работе с Radix UI — обеспечить корректное отображение и взаимодействие компонентов при помощи классов Tailwind.
className с Radix компонентамиПрактически каждый компонент Radix поддерживает стандартный проп
className. Для адаптации под Tailwind CSS необходимо:
import * as Dialog from '@radix-ui/react-dialog';
function Example() {
return (
<Dialog.Root>
<Dialog.Trigger className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">
Открыть
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Overlay className="fixed inset-0 bg-black bg-opacity-50" />
<Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white p-6 rounded-lg shadow-lg">
<Dialog.Title className="text-lg font-semibold">Заголовок модального окна</Dialog.Title>
<Dialog.Description className="text-sm text-gray-500">
Подробное описание содержимого модального окна.
</Dialog.Description>
<Dialog.Close className="mt-4 px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700">
Закрыть
</Dialog.Close>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);
}
Ключевые моменты:
Dialog.Trigger — кнопка открытия, стилизуется как
обычная кнопка Tailwind.Dialog.Overlay — полупрозрачный фон, покрывающий весь
экран.Dialog.Content — основной контейнер модального окна с
позиционированием и тенью.Dialog.Title и Dialog.Description —
семантические элементы с возможностью кастомной типографики.Radix предоставляет различные состояния компонентов: открыто/закрыто, фокус, активное состояние, выбор элемента. Tailwind CSS поддерживает псевдоклассы, что позволяет связать эти состояния с динамическими классами.
Пример с Tabs:
import * as Tabs from '@radix-ui/react-tabs';
function TabsExample() {
return (
<Tabs.Root defaultValue="tab1" className="w-full">
<Tabs.List className="flex border-b border-gray-300">
<Tabs.Trigger
value="tab1"
className="px-4 py-2 text-gray-700 data-[state=active]:border-b-2 data-[state=active]:border-blue-600 data-[state=active]:text-blue-600"
>
Вкладка 1
</Tabs.Trigger>
<Tabs.Trigger
value="tab2"
className="px-4 py-2 text-gray-700 data-[state=active]:border-b-2 data-[state=active]:border-blue-600 data-[state=active]:text-blue-600"
>
Вкладка 2
</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="tab1" className="p-4">
Содержимое первой вкладки
</Tabs.Content>
<Tabs.Content value="tab2" className="p-4">
Содержимое второй вкладки
</Tabs.Content>
</Tabs.Root>
);
}
Особенности:
data-[state=active] позволяют Tailwind
применять стили для активного состояния.open,
checked, disabled) можно использовать через
селекторы [data-state=...] и
[data-disabled].Radix UI не навязывает анимации, что полностью соответствует
утилитарному подходу Tailwind. Для анимации открывающихся компонентов
используют классы Tailwind с поддержкой transition и
duration.
Пример анимации модального окна:
<Dialog.Content className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white p-6 rounded-lg shadow-lg
data-[state=open]:animate-fadeIn data-[state=closed]:animate-fadeOut"
>
...
</Dialog.Content>
Tailwind CSS конфиг может быть расширен, чтобы добавить кастомные анимации:
// tailwind.config.js
module.exports = {
theme: {
extend: {
keyframes: {
fadeIn: { '0%': { opacity: 0 }, '100%': { opacity: 1 } },
fadeOut: { '0%': { opacity: 1 }, '100%': { opacity: 0 } },
},
animation: {
fadeIn: 'fadeIn 0.2s ease-out',
fadeOut: 'fadeOut 0.2s ease-out',
},
},
},
};
Radix UI отлично комбинируется с Tailwind для создания собственных систем компонентов. Обычно создают обертки, где применяются стандартные классы Tailwind и поддерживаются состояния Radix.
Пример обертки для кнопки с состояниями Radix:
import * as Toggle from '@radix-ui/react-toggle';
const ButtonToggle = ({ children, className, ...props }) => (
<Toggle.Root
className={`px-4 py-2 rounded-md border border-gray-300
data-[state=on]:bg-blue-600 data-[state=on]:text-white
hover:bg-gray-100 transition-colors ${className}`}
{...props}
>
{children}
</Toggle.Root>
);
Преимущества:
Tailwind CSS с Radix позволяет использовать переменные CSS для цветов
и тем. Radix предоставляет возможность передавать style или
использовать CSS-переменные для динамической темы.
<Dialog.Content
style={{ '--dialog-bg': 'theme(colors.white)' }}
className="bg-[var(--dialog-bg)] p-6 rounded-lg shadow-lg"
>
...
</Dialog.Content>
Такой подход упрощает интеграцию с Dark Mode Tailwind:
className="bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"
[data-state], [data-disabled] позволяют писать
чистые условные стили.Dialog.Portal и Popover.Portal для корректного
позиционирования и z-index.sm:,
md:, lg: полностью применимы к Radix
компонентам.Radix UI в сочетании с Tailwind CSS создаёт гибкую, доступную и визуально управляемую систему компонентов, где логика поведения полностью отделена от визуального оформления, что облегчает поддержку и масштабирование интерфейсов.