Radio
Radio
An accessible radio button component with custom styling and label support.
import { Radio, Box } from '@beauginbey/vanilla-components'; export default function App() { return ( <Box display="flex" gap={3} flexDirection="column"> <Radio name="example1" label="Option 1" defaultChecked /> <Radio name="example1" label="Option 2" /> <Radio name="example1" label="Option 3" /> </Box> ); }
Props
label
- Text label for the radio buttonerror
- Show error statedisabled
- Disable the radio button- All standard HTML input attributes (except
type
)
Basic Usage
import { Radio, Box, Text } from '@beauginbey/vanilla-components'; export default function App() { return ( <Box display="flex" flexDirection="column" gap={4}> <Box> <Text size="sm" weight="semibold" mb={2}>Without Label</Text> <Box display="flex" gap={2}> <Radio name="basic1" defaultChecked /> <Radio name="basic1" /> <Radio name="basic1" /> </Box> </Box> <Box> <Text size="sm" weight="semibold" mb={2}>With Label</Text> <Box display="flex" flexDirection="column" gap={2}> <Radio name="basic2" label="First option" defaultChecked /> <Radio name="basic2" label="Second option" /> <Radio name="basic2" label="Third option" /> </Box> </Box> </Box> ); }
Radio Groups
import { Radio, Box, Text } from '@beauginbey/vanilla-components'; import { useState } from 'react'; export default function App() { const [selectedSize, setSelectedSize] = useState('medium'); const [selectedPlan, setSelectedPlan] = useState('pro'); return ( <Box display="flex" flexDirection="column" gap={4}> <Box> <Text size="sm" weight="semibold" mb={2}>Size Selection</Text> <Box display="flex" gap={3}> <Radio name="size" label="Small" value="small" checked={selectedSize === 'small'} onChange={(e) => setSelectedSize(e.target.value)} /> <Radio name="size" label="Medium" value="medium" checked={selectedSize === 'medium'} onChange={(e) => setSelectedSize(e.target.value)} /> <Radio name="size" label="Large" value="large" checked={selectedSize === 'large'} onChange={(e) => setSelectedSize(e.target.value)} /> </Box> <Text size="sm" mt={2} color="secondary"> Selected: {selectedSize} </Text> </Box> <Box> <Text size="sm" weight="semibold" mb={2}>Plan Selection</Text> <Box display="flex" flexDirection="column" gap={2}> <Radio name="plan" label="Basic - $9/month" value="basic" checked={selectedPlan === 'basic'} onChange={(e) => setSelectedPlan(e.target.value)} /> <Radio name="plan" label="Pro - $19/month" value="pro" checked={selectedPlan === 'pro'} onChange={(e) => setSelectedPlan(e.target.value)} /> <Radio name="plan" label="Enterprise - $49/month" value="enterprise" checked={selectedPlan === 'enterprise'} onChange={(e) => setSelectedPlan(e.target.value)} /> </Box> <Text size="sm" mt={2} color="secondary"> Selected: {selectedPlan} </Text> </Box> </Box> ); }
States
import { Radio, Box, Text } from '@beauginbey/vanilla-components'; export default function App() { return ( <Box display="flex" flexDirection="column" gap={4}> <Box> <Text size="sm" weight="semibold" mb={2}>Normal State</Text> <Box display="flex" gap={3}> <Radio name="normal" label="Unchecked" /> <Radio name="normal" label="Checked" defaultChecked /> </Box> </Box> <Box> <Text size="sm" weight="semibold" mb={2}>Error State</Text> <Box display="flex" gap={3}> <Radio name="error" label="Error unchecked" error /> <Radio name="error" label="Error checked" error defaultChecked /> </Box> </Box> <Box> <Text size="sm" weight="semibold" mb={2}>Disabled State</Text> <Box display="flex" gap={3}> <Radio name="disabled" label="Disabled unchecked" disabled /> <Radio name="disabled" label="Disabled checked" disabled defaultChecked /> </Box> </Box> </Box> ); }
Form Integration
import { Radio, Button, Box, Text } from '@beauginbey/vanilla-components'; import { useState } from 'react'; export default function App() { const [formData, setFormData] = useState({ delivery: 'standard', payment: 'card' }); const handleSubmit = (e) => { e.preventDefault(); alert(JSON.stringify(formData, null, 2)); }; const handleChange = (field) => (e) => { setFormData({ ...formData, [field]: e.target.value }); }; return ( <Box as="form" onSubmit={handleSubmit} display="flex" flexDirection="column" gap={4}> <Box> <Text size="md" weight="semibold" mb={2}>Delivery Method</Text> <Box display="flex" flexDirection="column" gap={2}> <Radio name="delivery" label="Standard (5-7 days) - Free" value="standard" checked={formData.delivery === 'standard'} onChange={handleChange('delivery')} /> <Radio name="delivery" label="Express (2-3 days) - $10" value="express" checked={formData.delivery === 'express'} onChange={handleChange('delivery')} /> <Radio name="delivery" label="Overnight - $25" value="overnight" checked={formData.delivery === 'overnight'} onChange={handleChange('delivery')} /> </Box> </Box> <Box> <Text size="md" weight="semibold" mb={2}>Payment Method</Text> <Box display="flex" flexDirection="column" gap={2}> <Radio name="payment" label="Credit/Debit Card" value="card" checked={formData.payment === 'card'} onChange={handleChange('payment')} /> <Radio name="payment" label="PayPal" value="paypal" checked={formData.payment === 'paypal'} onChange={handleChange('payment')} /> <Radio name="payment" label="Bank Transfer" value="bank" checked={formData.payment === 'bank'} onChange={handleChange('payment')} /> </Box> </Box> <Button type="submit" fullWidth> Continue to Checkout </Button> </Box> ); }
Accessibility Features
The Radio component includes built-in accessibility features:
import { Radio, Box, Text } from '@beauginbey/vanilla-components'; export default function App() { return ( <Box display="flex" flexDirection="column" gap={4}> <Box> <Text size="sm" weight="semibold" mb={2}>With aria-describedby</Text> <Radio name="a11y1" label="Subscribe to newsletter" aria-describedby="newsletter-help" /> <Text id="newsletter-help" size="sm" color="secondary" mt={1}> We'll send you weekly updates about new features </Text> </Box> <Box> <Text size="sm" weight="semibold" mb={2}>Required Field</Text> <Radio name="a11y2" label="I agree to the terms and conditions" aria-required="true" required /> </Box> <Box> <Text size="sm" weight="semibold" mb={2}>With Error</Text> <Radio name="a11y3" label="Option with error" error aria-invalid="true" aria-describedby="error-message" /> <Text id="error-message" size="sm" style={{ color: 'var(--color-feedback-error)' }} mt={1}> Please select a valid option </Text> </Box> </Box> ); }
TypeScript
Radio is fully typed with TypeScript:
import { Radio, RadioProps } from '@beauginbey/vanilla-components';
// Type-safe props
const MyRadio = (props: RadioProps) => {
return <Radio {...props} />;
};
// Controlled radio group
const RadioGroup = () => {
const [value, setValue] = useState<string>('option1');
return (
<>
<Radio
name="group"
value="option1"
label="Option 1"
checked={value === 'option1'}
onChange={(e) => setValue(e.target.value)}
/>
<Radio
name="group"
value="option2"
label="Option 2"
checked={value === 'option2'}
onChange={(e) => setValue(e.target.value)}
/>
</>
);
};