Библиотека Radix UI предоставляет низкоуровневые, полностью доступные компоненты пользовательского интерфейса. Для их стилизации часто используется подход с Styled Components, который позволяет писать CSS в JavaScript и создавать компоненты с собственным стилем без глобального загрязнения пространства имён.
Для начала необходимо подключить styled-components:
import styled from 'styled-components';
import * as Dialog from '@radix-ui/react-dialog';
Radix UI экспортирует компоненты как React-компоненты, что позволяет
их напрямую оборачивать в styled() для создания кастомных
версий. Например:
const StyledDialog = styled(Dialog.Root)`
position: relative;
z-index: 10;
`;
Важно понимать, что некоторые внутренние элементы Radix требуют
обертки отдельно, например, Dialog.Overlay и
Dialog.Content.
const Overlay = styled(Dialog.Overlay)`
background: rgba(0, 0, 0, 0.5);
position: fixed;
inset: 0;
`;
const Content = styled(Dialog.Content)`
background: white;
border-radius: 8px;
padding: 20px;
width: 400px;
max-width: 90%;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
`;
Styled Components позволяют использовать динамические пропсы для изменения стилей в зависимости от состояния компонента:
const Button = styled.button`
background-color: ${props => (props.primary ? '#4f46e5' : '#e5e7eb')};
color: ${props => (props.primary ? 'white' : 'black')};
padding: 10px 20px;
border-radius: 6px;
border: none;
cursor: pointer;
&:hover {
background-color: ${props => (props.primary ? '#4338ca' : '#d1d5db')};
}
`;
Пример использования с Radix:
import * as Toggle from '@radix-ui/react-toggle';
const StyledToggle = styled(Toggle.Root)`
background-color: ${props => (props.on ? '#4f46e5' : '#f3f4f6')};
color: ${props => (props.on ? 'white' : 'black')};
border-radius: 6px;
padding: 8px 16px;
cursor: pointer;
`;
Radix UI часто использует data-* атрибуты для управления
состояниями компонента. Эти атрибуты можно применять в CSS через
styled-components:
const StyledAccordionItem = styled.div`
border-bottom: 1px solid #e5e7eb;
&[data-state='open'] {
background-color: #f9fafb;
}
`;
Пример для анимации открытия/закрытия:
const StyledAccordionContent = styled.div`
overflow: hidden;
transition: max-height 0.3s ease;
&[data-state='open'] {
max-height: 500px; /* Достаточно для содержимого */
}
&[data-state='closed'] {
max-height: 0;
}
`;
Radix UI позволяет создавать сложные UI, комбинируя несколько компонентов. Styled Components дают возможность создавать связанные стили для вложенных элементов:
const StyledTabsList = styled(Tabs.List)`
display: flex;
border-bottom: 2px solid #e5e7eb;
`;
const StyledTabsTrigger = styled(Tabs.Trigger)`
padding: 10px 20px;
cursor: pointer;
border: none;
background: none;
&[data-state='active'] {
border-bottom: 2px solid #4f46e5;
color: #4f46e5;
}
`;
Styled Components поддерживает проп as, что позволяет
рендерить компонент как другой элемент или Radix-компонент, сохраняя
стили:
const BaseButton = styled.button`
padding: 12px 24px;
border-radius: 6px;
background-color: #4f46e5;
color: white;
`;
<BaseButton as={Dialog.Trigger}>Open Dialog</BaseButton>
Это особенно полезно для Radix-компонентов, где нужно сохранить семантику, но использовать собственные стили.
data-state, data-disabled), это
упрощает поддержку и предотвращает конфликт с внутренними стилями
Radix.<Dialog.Root> через CSS
напрямую.styled.keyframes вместе с
data-атрибутами состояний.<StyledDialog>
<Overlay />
<Content>
<h2>Заголовок модального окна</h2>
<p>Содержимое модального окна с красивой стилизацией.</p>
<Dialog.Close asChild>
<Button>Закрыть</Button>
</Dialog.Close>
</Content>
</StyledDialog>
Эта структура демонстрирует сочетание Radix UI и Styled Components для создания модальных окон, сохраняя доступность и полный контроль над стилями.
Radix UI в сочетании с Styled Components позволяет строить полностью
кастомные интерфейсы, управлять состояниями через data-*
атрибуты и динамически изменять стили с минимальной нагрузкой на кодовую
базу. Этот подход упрощает масштабирование и поддержку сложных
компонентов.