A flexible radio group component with labels, descriptions, validation, and Zod integration for single-choice selections.
Overview
The Radio Input component provides an accessible and flexible solution for single-choice selections, essential for forms requiring mutually exclusive options. It supports both vertical and horizontal layouts with rich option descriptions, individual option disabling, and comprehensive validation. Perfect for preference settings, plan selections, and any scenario requiring clear single-choice decisions with optimal user experience.
Installation
pnpm dlx shadcn@latest add https://deltacomponents.dev/r/radio-input.json
Usage
1"use client"23import { Building, Globe, Users } from "lucide-react"45import { RadioInput } from "@/registry/inputs/radio-input"67export function Component() {8 const options = [9 {10 value: "small",11 label: "Small",12 description: "Perfect for individuals",13 icon: <Users className="w-4 h-4" />,14 },15 {16 value: "medium",17 label: "Medium",18 description: "Great for small teams",19 icon: <Building className="w-4 h-4" />,20 },21 {22 value: "large",23 label: "Large",24 description: "Ideal for organizations",25 icon: <Globe className="w-4 h-4" />,26 },27 ]2829 return (30 <RadioInput31 label="Plan Size"32 name="planSize"33 options={options}34 required35 onValueChange={(value) => console.log("Selected:", value)}36 />37 )38}
API Reference
Props
Prop | Type | Default | Description |
---|---|---|---|
label | string | - | Label for the radio group (required) |
name | string | - | Name of the radio group for form submission (required) |
options | RadioOption[] | - | Array of radio options (required) |
description | string | undefined | Description text below the label |
error | string | undefined | Error message to display |
required | boolean | false | Whether the field is required |
pending | boolean | false | Whether the field is in a loading state |
defaultValue | string | undefined | Default selected value |
value | string | undefined | Controlled selected value |
disabled | boolean | false | Whether the radio group is disabled |
id | string | name | ID for the radio group |
orientation | "vertical" | "horizontal" | "vertical" | Layout orientation |
variant | "default" | "pill" | "default" | Radio input styling variant |
labelVariant | "default" | "muted" | "default" | Label text styling variant |
containerClassName | string | "" | CSS classes for the container |
radioGroupClassName | string | "" | CSS classes for the radio group |
radioItemClassName | string | "" | CSS classes for radio items |
labelClassName | string | "" | CSS classes for the label |
schema | ZodType<string> | undefined | Zod schema for validation |
onValidate | (isValid: boolean, value: string, error?: string) => void | undefined | Validation callback |
onValueChange | (value: string) => void | undefined | Callback when selection changes |
allowNoSelection | boolean | false | Whether to allow no selection (no default value) |
RadioOption Interface
1interface RadioOption {2 value: string3 label: string4 description?: string5 disabled?: boolean6 icon?: React.ReactNode7}
Examples
Pill Variant
Modern pill-style radio input with colored border and enhanced visual design for plan selection.
With Icons
Radio input options enhanced with SVG icons or images positioned on the right side, perfect for payment methods, features, or visual categorization.
No Default Selection
Radio input that allows no initial selection by setting allowNoSelection={true}
, useful for optional choices where users should actively make a decision rather than having a pre-selected option.