Radix Primitives are unstyled—and compatible with any styling solution—giving you complete control over styling.
You are in control of all aspects of styling, including functional styles. For example—by default—a Dialog Overlay won't cover the entire viewport. You're responsible for adding those styles, plus any presentation styles.
All components and their parts accept a className
prop. This class will be passed through to the DOM element. You can use it in CSS as expected.
When components are stateful, their state will be exposed in a data-state
attribute. For example, when an Accordion Item is opened, it includes a data-state="open"
attribute.
You can style a component part by targeting the className
that you provide.
import * as React from 'react';
import * as Accordion from '@radix-ui/react-accordion';
import './styles.css';
const AccordionDemo = () => (
<Accordion.Root>
<Accordion.Item className="AccordionItem" value="item-1" />
{/* … */}
</Accordion.Root>
);
export default AccordionDemo;
You can style a component state by targeting its data-state
attribute.
.AccordionItem {
border-bottom: 1px solid gainsboro;
}
.AccordionItem[data-state='open'] {
border-bottom-width: 2px;
}
The examples below are using Stitches, but you can use any CSS-in-JS library of your choice.
You can style a component part by wrapping it in a styled
function (or equivalent).
import * as React from 'react';
import * as Accordion from '@radix-ui/react-accordion';
import { styled } from '@stitches/react';
const StyledItem = styled(Accordion.Item, {
borderBottom: '1px solid gainsboro',
});
const AccordionDemo = () => (
<Accordion.Root>
<StyledItem value="item-1" />
{/* … */}
</Accordion.Root>
);
export default AccordionDemo;
You can style a component state by targeting its data-state
attribute.
import { styled } from '@stitches/react';
import * as Accordion from '@radix-ui/react-accordion';
const StyledItem = styled(Accordion.Item, {
borderBottom: '1px solid gainsboro',
'&[data-state=open]': {
borderBottomWidth: '2px',
},
});
Extending a primitive is done the same way you extend any React component.
import * as React from 'react';
import * as AccordionPrimitive from '@radix-ui/react-accordion';
const AccordionItem = React.forwardRef<
React.ElementRef<typeof AccordionPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof AccordionPrimitive.Item>
>((props, forwardedRef) => (
<AccordionPrimitive.Item {...props} ref={forwardedRef} />
));
AccordionItem.displayName = 'AccordionItem';
Radix Primitives were designed to encapsulate accessibility concerns and other complex functionalities, while ensuring you retain complete control over styling.
For convenience, stateful components include a data-state
attribute.