Search

Jump to any page.

Forms

Radio Group

Single choice from a list; the dot springs in on selection.

Deployment
pnpm dlx shadcn@latest add @paragon/radio-group
Brings in@base-ui/reactcn

List

Compact radios for short options.

Reply language

States

The dot springs in from nothing when selected.

RestHoverFocusPressedInvalidDisabled
unselected
selected
registry/paragon/ui/radio-group.tsx
"use client"

import { Radio as RadioPrimitive } from "@base-ui/react/radio"
import { RadioGroup as RadioGroupPrimitive } from "@base-ui/react/radio-group"
import { cn } from "cn"

function RadioGroup({ className, ...props }: RadioGroupPrimitive.Props) {
  return <RadioGroupPrimitive data-slot="radio-group" className={cn("grid w-full gap-3", className)} {...props} />
}

/** The dot springs in from nothing when selected. */
function RadioGroupItem({ className, ...props }: RadioPrimitive.Root.Props) {
  return (
    <RadioPrimitive.Root
      data-slot="radio-group-item"
      className={cn(
        "peer relative flex aspect-square size-[1.125rem] shrink-0 items-center justify-center rounded-full border border-input bg-card outline-none",
        "[transition:background-color_var(--duration-base)_var(--ease-paragon),border-color_var(--duration-base)_var(--ease-paragon),scale_var(--duration-slow)_var(--ease-spring)]",
        "after:absolute after:-inset-2.5",
        "hover:border-foreground/45",
        "active:scale-90 active:[transition-duration:var(--duration-fast)] motion-reduce:active:scale-100",
        "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:outline-solid",
        "data-checked:border-primary data-checked:bg-primary",
        "aria-invalid:border-destructive aria-invalid:focus-visible:outline-destructive aria-invalid:data-checked:border-primary",
        "data-disabled:pointer-events-none data-disabled:opacity-50",
        "dark:bg-input/15",
        "group-has-[:focus-visible]/field-label:outline-none",
        className
      )}
      {...props}
    >
      <RadioPrimitive.Indicator
        data-slot="radio-group-indicator"
        className="size-[0.4375rem] rounded-full bg-primary-foreground [transition:scale_var(--duration-slow)_var(--ease-spring)] data-ending-style:scale-0 data-ending-style:duration-(--duration-fast) data-ending-style:ease-paragon data-starting-style:scale-0 motion-reduce:transition-none"
      />
    </RadioPrimitive.Root>
  )
}

export { RadioGroup, RadioGroupItem }