Radio
Radio lets users select one option from a group of choices.
Source
LLM docs
Package
Examples
5
Properties
58
Playground
Basics
Use standalone
Radio components for custom layouts or pass an options array to RadioGroup for quick single-selection forms.Loading demo…
import { useState } from 'react';
import { Block, Radio, RadioGroup, Text } from '@plocks/ui';
const TEAMS = ['Falcons', 'Tigers', 'Sharks'] as const;
export function Demo() {
const [favoriteTeam, setFavoriteTeam] = useState<string>('Tigers');
const [ticketType, setTicketType] = useState<string>('reserved');
return (
<Block>
<Block>
<Text variant="small" c="muted">
Standalone radios
</Text>
<Block>
{TEAMS.map((team) => (
<Radio
key={team}
value={team}
checked={favoriteTeam === team}
onChange={setFavoriteTeam}
label={team}
/>
))}
</Block>
</Block>
<Block>
<Text variant="small" c="muted">
Grouped selection
</Text>
<RadioGroup
value={ticketType}
onChange={setTicketType}
options={[
{ label: 'General admission', value: 'general' },
{ label: 'Reserved seating', value: 'reserved' },
{ label: 'VIP hospitality', value: 'vip' }
]}
/>
</Block>
</Block>
);
}Variants
The
variant prop on RadioGroup selects how the group is laid out and how the selected option is communicated. default keeps the classic dot indicators; card renders each option as a bordered surface (useful when options have descriptions); segmented joins the options into a single iOS-style control; chip lays them out as wrap-friendly pills (good for filter UIs).Loading demo…
import { useState } from 'react';
import { Block, RadioGroup, Text } from '@plocks/ui';
const PLAN_OPTIONS = [
{ label: 'Starter', value: 'starter', description: 'Up to 3 projects, community support' },
{ label: 'Growth', value: 'growth', description: 'Unlimited projects, priority email support' },
{ label: 'Scale', value: 'scale', description: 'Dedicated success manager + SSO' },
];
const FREQUENCY_OPTIONS = [
{ label: 'Daily', value: 'daily' },
{ label: 'Weekly', value: 'weekly' },
{ label: 'Monthly', value: 'monthly' },
];
const FILTER_OPTIONS = [
{ label: 'All', value: 'all' },
{ label: 'Active', value: 'active' },
{ label: 'Archived', value: 'archived' },
{ label: 'Trashed', value: 'trashed' },
];
export function Demo() {
const [defaultValue, setDefaultValue] = useState('weekly');
const [planValue, setPlanValue] = useState('growth');
const [frequencyValue, setFrequencyValue] = useState('weekly');
const [filterValue, setFilterValue] = useState('active');
return (
<Block>
<Block>
<Text variant="small" c="muted">default</Text>
<RadioGroup
variant="default"
value={defaultValue}
onChange={setDefaultValue}
options={FREQUENCY_OPTIONS}
/>
</Block>
<Block>
<Text variant="small" c="muted">card</Text>
<RadioGroup
variant="card"
value={planValue}
onChange={setPlanValue}
options={PLAN_OPTIONS}
/>
</Block>
<Block>
<Text variant="small" c="muted">segmented</Text>
<RadioGroup
variant="segmented"
value={frequencyValue}
onChange={setFrequencyValue}
options={FREQUENCY_OPTIONS}
/>
</Block>
<Block>
<Text variant="small" c="muted">chip</Text>
<RadioGroup
variant="chip"
value={filterValue}
onChange={setFilterValue}
options={FILTER_OPTIONS}
/>
</Block>
</Block>
);
}Theming
Combine the
size, color, and validation props to align radios with your UI tokens and state requirements.Loading demo…
import { useState } from 'react';
import { Block, Radio, RadioGroup, Text } from '@plocks/ui';
const COLOR_OPTIONS = ['primary', 'secondary', 'success', 'error'] as const;
export function Demo() {
const [sizeValue, setSizeValue] = useState<string>('club');
const [colorValue, setColorValue] = useState<typeof COLOR_OPTIONS[number]>('primary');
return (
<Block>
<Block>
<Text variant="small" c="muted">
Size tokens
</Text>
<RadioGroup
size="sm"
value={sizeValue}
onChange={setSizeValue}
options={[
{ label: 'Club', value: 'club' },
{ label: 'Suite', value: 'suite' },
{ label: 'Field level', value: 'field' }
]}
/>
</Block>
<Block>
<Text variant="small" c="muted">
Semantic colors
</Text>
<Block>
{COLOR_OPTIONS.map((tone) => (
<Radio
key={tone}
value={tone}
checked={colorValue === tone}
onChange={(value) => setColorValue(value as typeof COLOR_OPTIONS[number])}
label={`${tone.charAt(0).toUpperCase()}${tone.slice(1)} tickets`}
color={tone}
/>
))}
</Block>
</Block>
<Block>
<Text variant="small" c="muted">
Common states
</Text>
<Radio value="available" checked label="Available" />
<Radio value="disabled" disabled label="Disabled" />
<Radio value="error" error="Select a seat" label="Needs attention" />
</Block>
</Block>
);
}Orientations
Toggle
orientation between horizontal and vertical to adapt radio groups to the available space.Loading demo…
import { useState } from 'react';
import { Block, RadioGroup, Text } from '@plocks/ui';
export function Demo() {
const [favoriteSport, setFavoriteSport] = useState<string>('soccer');
const [skillLevel, setSkillLevel] = useState<string>('intermediate');
return (
<Block>
<Block>
<Text variant="small" c="muted">
Horizontal layout
</Text>
<RadioGroup
orientation="horizontal"
value={favoriteSport}
onChange={setFavoriteSport}
options={[
{ label: 'Soccer', value: 'soccer' },
{ label: 'Basketball', value: 'basketball' },
{ label: 'Tennis', value: 'tennis' },
{ label: 'Volleyball', value: 'volleyball' }
]}
/>
</Block>
<Block>
<Text variant="small" c="muted">
Vertical layout
</Text>
<RadioGroup
orientation="vertical"
value={skillLevel}
onChange={setSkillLevel}
options={[
{ label: 'Beginner', value: 'beginner' },
{ label: 'Intermediate', value: 'intermediate' },
{ label: 'Advanced', value: 'advanced' },
{ label: 'Expert', value: 'expert' }
]}
/>
</Block>
</Block>
);
}Forms
Pair
RadioGroup with required and error messaging to validate selections before submitting a form workflow.Loading demo…
import { useState } from 'react';
import { Block, Button, RadioGroup, Text } from '@plocks/ui';
const PLANS = [
{
label: 'Starter — $9/mo',
value: 'starter',
description: 'Streamline a single project'
},
{
label: 'Team — $19/mo',
value: 'team',
description: 'Collaborate with up to 10 teammates'
},
{
label: 'Club — $39/mo',
value: 'club',
description: 'Unlock advanced analytics'
}
];
const BILLING = [
{ label: 'Monthly', value: 'monthly' },
{ label: 'Annual (save 20%)', value: 'annual' }
];
export function Demo() {
const [plan, setPlan] = useState<string>('');
const [billingCycle, setBillingCycle] = useState<string>('monthly');
const [planError, setPlanError] = useState<string | undefined>();
const [confirmation, setConfirmation] = useState<string | null>(null);
const handleSubmit = () => {
if (!plan) {
setPlanError('Select a plan to continue');
setConfirmation(null);
return;
}
setPlanError(undefined);
setConfirmation(`Subscribed to the ${plan} plan with ${billingCycle} billing.`);
};
return (
<Block>
<RadioGroup
label="Select a membership"
options={PLANS}
value={plan}
onChange={(next) => {
setPlan(next);
setPlanError(undefined);
}}
error={planError}
required
/>
<RadioGroup
label="Billing cadence"
orientation="horizontal"
options={BILLING}
value={billingCycle}
onChange={setBillingCycle}
/>
<Button onPress={handleSubmit}>Confirm subscription</Button>
{confirmation && (
<Text variant="small" c="success">
{confirmation}
</Text>
)}
</Block>
);
}React Native design for iOS, Android, and Web.
Quick Links
Resources