Published on

❤️ Styling Radix UI Radio Groups with Shadcn/UI in Next.js

Authors
  • Name
    Ripal & Zalak
    Twitter

Styling Radix UI Radio Groups with Shadcn/UI in Next.js

Radix UI is a powerful library for building accessible React components, and Shadcn/UI enhances it with TailwindCSS-based styling. If you want to style Radio Groups with modern designs and interactive features, this guide is for you.

What We’ll Cover

  1. Introduction to Radix UI Radio Groups
  2. Using Shadcn/UI for styling
  3. Step-by-step example
  4. Common issues and solutions
  5. FAQs

Why Radix UI for Radio Groups?

Radix UI provides:

  • Accessibility: Fully ARIA-compliant components.
  • Customizability: Flexible primitives for styling.
  • Performance: Lightweight and efficient.

With Shadcn/UI, you can style these components effortlessly using TailwindCSS.


Setting Up the Project

Prerequisites:

  • Next.js 13
  • TypeScript
  • TailwindCSS
  • Radix UI

Install the required packages:

npm install @radix-ui/react-radio-group tailwindcss

Set up TailwindCSS if not already done by following the official guide.


Implementing Radix UI Radio Groups

Below is a styled Radio Group implementation using Radix UI and Shadcn/UI.

Component Code:

import React from 'react'
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group'
import { cn } from '@/lib/utils' // Utility for conditional classNames
import { Icons } from '@/components/icons' // Replace with your icon setup

const RadioGroupItemModern = React.forwardRef<
  React.ElementRef<typeof RadioGroupPrimitive.Item>,
  React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>
>(({ className, children, ...props }, ref) => {
  return (
    <RadioGroupPrimitive.Item ref={ref} className={cn('peer hidden', className)} {...props}>
      <RadioGroupPrimitive.Indicator className="focus:ring-primary peer-checked:ring-primary block w-full cursor-pointer rounded-lg border border-gray-300 p-4 ring-2 ring-transparent ring-offset-2 hover:border-gray-400">
        <div>{children}</div>
        <Icons.checkCircle className="h-6 w-6 text-current" />
      </RadioGroupPrimitive.Indicator>
    </RadioGroupPrimitive.Item>
  )
})

RadioGroupItemModern.displayName = RadioGroupPrimitive.Item.displayName

export default function ExampleRadioGroup() {
  return (
    <RadioGroupPrimitive.Root className="grid gap-4">
      {[
        { value: 'option1', label: 'Option 1', description: 'Description 1' },
        { value: 'option2', label: 'Option 2', description: 'Description 2' },
      ].map((item) => (
        <RadioGroupItemModern key={item.value} value={item.value}>
          <div>
            <div className="font-bold">{item.label}</div>
            <div className="text-sm text-gray-500">{item.description}</div>
          </div>
        </RadioGroupItemModern>
      ))}
    </RadioGroupPrimitive.Root>
  )
}

Key Styling Concepts

  1. Peer Selector: TailwindCSS peer class lets you style sibling elements based on the state of an input. For example:
peer-aria-checked: border-primary;
  1. Data Attributes: Radix UI uses data-state attributes, which you can target:
[data-state="checked"]: border-primary;
  1. Utility Classes: Use Tailwind’s utility classes like ring, focus-visible, and hover for interactive styling.

Common Issues & Fixes

  1. Borders Not Activating:

    • Ensure you’re using peer and targeting the correct sibling elements.
  2. Label Text Alignment:

    • Wrap the label text and description inside a <div> for better structure.
  3. Missing Icons:

    • Use a proper icon library like Heroicons or Material Icons.

FAQs

Q: Can I use custom designs instead of TailwindCSS? A: Yes! Radix UI works with any CSS framework or custom styles.

Q: How do I add animations? A: Use libraries like Framer Motion or TailwindCSS animations.

Q: Can I nest Radio Groups? A: It’s possible but avoid nested Radio Groups to maintain accessibility.


Conclusion

Radix UI and Shadcn/UI make styling Radio Groups both accessible and visually appealing. By leveraging TailwindCSS and Radix’s primitives, you can create responsive, interactive, and accessible components in no time.

For more examples, check out the Radix UI Docs and Shadcn/UI.