Building accessible UIs with Radix primitives
Radix UI ships headless components: behavior and accessibility without opinionated styles. That matches design systems where tokens live in Tailwind or CSS variables but interaction patterns (dialogs, dropdowns, tabs) must still satisfy WCAG.
Dialogs and focus management
A modal is not “a div with position: fixed”. Keyboard users expect focus trapped inside, Escape to close, and restore focus to the trigger. @radix-ui/react-dialog wires aria-modal, role="dialog", and focus scope for you—style the overlay and panel with your stack.
Composition over configuration
Primitives split into Root, Trigger, Content, Close. You decide layout; Radix guarantees the state machine. This reduces one-off bugs when product asks for “nested drawer inside dialog” edge cases.
Styling with Tailwind
Use className on each part. For animations, pair with data-state attributes Radix exposes (open, closed) for enter/exit transitions without fighting display: none timing—@radix-ui/react-dialog supports forceMount + CSS when you need it.
Testing
Pair Radix with Testing Library queries (getByRole('dialog', { name: /…/ })) instead of brittle CSS selectors. Storybook + a11y addon catches missing labels early.
Summary
Reach for Radix (or similar primitives) when accessibility and keyboard behavior are non-negotiable. Your tokens handle look; Radix handles the interaction contract.