Radio Group

A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.

Description

Description

Description

import RadioGroup from "@tailus-ui/RadioGroup";
import Label from "@tailus-ui/Label";
import Aligner from "@tailus-ui/Aligner";
import { Caption } from "@tailus-ui/typography";

export const MyComponent = () => (
    <RadioGroup.Root
        aria-label="User feedback"
        defaultValue="problem"
        className="space-y-4"
    >   
        <Aligner>
            <RadioGroup.Item value="problem" id="problem">
                <RadioGroup.Indicator />
            </RadioGroup.Item>
            <Label htmlFor="problem">Solved my problem</Label>
            <Caption className="col-start-2">Description</Caption>
        </Aligner>
        <Aligner>
            <RadioGroup.Item value="understanding" id="understanding">
                <RadioGroup.Indicator />
            </RadioGroup.Item>
            <Label htmlFor="understanding">Easy understanding</Label>
            <Caption className="col-start-2">Description</Caption>
        </Aligner>
        <Aligner>
            <RadioGroup.Item value="other" id="other">
                <RadioGroup.Indicator />
            </RadioGroup.Item>
            <Label htmlFor="other">Other</Label>
            <Caption className="col-start-2">Description</Caption>
        </Aligner>
    </RadioGroup.Root>
)

Installation

Install the primitive and Copy-Paste the component code in a .tsx file.

npm install @radix-ui/react-radio-group
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
import React from "react";
import { useContext } from "react";
import { radio, fancyRadio, type RadioProps } from "@tailus/themer";

export interface RadioRootProps extends RadioProps {
  className?: string;
}

const RadioGroupContext = React.createContext<RadioRootProps>({fancy: false, intent: "primary"});

const RadioGroupRoot = React.forwardRef<
  React.ElementRef<typeof RadioGroupPrimitive.Root>,
  React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> & RadioRootProps
  >(({ className, intent, fancy, ...props }, forwardedRef) => {
  
    return (
      <RadioGroupContext.Provider value={{fancy, intent}}>
        <RadioGroupPrimitive.Root
          {...props}
          ref={forwardedRef}
          className={className}
        />
      </RadioGroupContext.Provider>
    )
  });

export interface RadioItemProps {
  fancy?: boolean;
  intent?: RadioProps['intent'];
  className?: string;
}

const RadioGroupItem = React.forwardRef<
  React.ElementRef<typeof RadioGroupPrimitive.Item>,
  React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> & RadioItemProps
  >((props, forwardedRef) => {
    const {intent, fancy} = useContext(RadioGroupContext);
    const {item} = fancy ? fancyRadio({intent}) : radio({intent});
    return (
        <RadioGroupPrimitive.Item
          {...props}
          ref={forwardedRef}
          className={item({className: props.className})}
        />
    )
});

const RadioGroupIndicator = React.forwardRef<
  React.ElementRef<typeof RadioGroupPrimitive.Indicator>,
  React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Indicator> & RadioProps & {
    className?: string;
  }
  >((props, forwardedRef) => {
    const {intent} = useContext(RadioGroupContext);
  const {indicator} = radio({intent});
  return (
    <RadioGroupPrimitive.Indicator
      {...props}
      ref={forwardedRef}
      className={indicator({intent:props.intent, className: props.className})}
    />
  )
});

export default {
  Root: RadioGroupRoot,
  Item: RadioGroupItem,
  Indicator: RadioGroupIndicator,
}

export {
  RadioGroupRoot,
  RadioGroupItem,
  RadioGroupIndicator,
}

Add Aligner component

Useful for aligning Checkbox, RadioGroup, and Switch components with their associated Label and Caption

import React from "react"
import { aligner, type AlignerProps as AlignerVariants } from "@tailus/themer"

export interface AlignerProps extends React.HTMLAttributes<HTMLDivElement>, AlignerVariants {}

export const Aligner = React.forwardRef<HTMLDivElement, AlignerProps>(
    ({className, children, fromRight, ...props }, forwardedRef) => {
        return (
            <div
                className={aligner({ fromRight, className})}
                ref={forwardedRef}
                children={children}
                {...props}
            />
        )
    })

export default Aligner;

Usage

Import all the parts and build your Radio Group.

import RadioGroup from "@tailus-ui/RadioGroup";
import Label from "@tailus-ui/Label";
const MyComponent = () => (
    <div>
        <RadioGroup.Root defaultValue="problem" aria-label="User feedback">
            <RadioGroup.Item value="easy" id="easy">
                <RadioGroup.Indicator/>
            </RadioGroup.Item>
            <Label htmlFor="easy">
                Easy understanding
            </Label>
        </RadioGroup.Root>
    </div>
)

Reference

Root

The Radio Group <Root /> has the following additional props.

Prop
Type
Default
intent
enum
primary
fancy
boolean
false

Aligner

The Aligner component has the following props.

Prop
Type
Default
fromRight
boolean
false

Examples