Getting Started
Components
- Advanced Toast
- ArrowButton
- Arrows
- Avatar
- Backdrop
- Basic Toast
- Breadcrumb
- Button
- CardBackground
- Card
- ChatButton
- Checkbox
- Checkboxes
- Chip
- ChoiceExpander
- Clickable
- Date Field
- Dropdown
- ElasticHeight
- ExpandableCard
- Filter
- FormCheckbox
- Form Control
- Form Label
- HamburgerIcon
- Heading
- Image
- Link
- Loader
- Number Field
- Pagination
- Password
- Phone Field
- Popin
- Portal
- Prose
- Radio Group
- Radio
- Range
- Select
- SidebarLayout
- Spinner
- Switch
- Tabs
- Tag
- TextField
- ValidationMessage
'use client';
import { FormControl } from '@/ui/forms/FormControl';
import { RadioGroup } from '@/ui/forms/radios/RadioGroup';
import { Radio } from '@/ui/forms/radios/Radio';
import { useState } from 'react';
export function RadioGroupDemo() {
const [value, setValue] = useState('option1');
return (
<FormControl label="Choose an option" id="demo-radio-group">
<RadioGroup
value={value}
onChange={(_, newValue) => setValue(newValue)}
name="demo-radio-group"
aria-labelledby="demo-radio-group"
>
<Radio value="option1">Option 1</Radio>
<Radio value="option2">Option 2</Radio>
<Radio value="option3">Option 3</Radio>
</RadioGroup>
</FormControl>
);
}
Installation
npx shadcn@latest add https://develop.trident-ui.pro.clubmed/r/radio-group.json
Usage
'use client';
import { FormControl } from '@/docs/lib/ui/forms/form-control';
import { RadioGroup } from '@/docs/lib/ui/forms/radios/radio-group';
import { Radio } from '@/docs/lib/ui/forms/radios/radio';
import { useState } from 'react';
export function Component() {
const [value, setValue] = useState('option1');
return (
<FormControl label="Choose an option" id="radio-example">
<RadioGroup
value={value}
onChange={(name, newValue) => {
console.log(`${name} changed to:`, newValue);
setValue(newValue);
}}
name="radio-group"
aria-labelledby="radio-example"
>
<Radio value="option1">Option 1</Radio>
<Radio value="option2">Option 2</Radio>
<Radio value="option3">Option 3</Radio>
</RadioGroup>
</FormControl>
);
}API Reference
RadioGroup
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | undefined | Radio or Button components to be grouped together |
id | string | auto | Unique identifier for the radio group. Auto-generated if not provided |
name | string | id | Name attribute for the radio group, used in form submissions. Defaults to the id value |
value | Value | undefined | Currently selected value. Can be any type (string, number, etc.) |
defaultValue | Value | undefined | Default selected value for uncontrolled component usage |
onChange | (name: string, value: Value) => void | undefined | Callback function called when the selected value changes. Receives the name and new value |
disabled | boolean | false | If true, disables all radio buttons in the group |
readOnly | boolean | false | If true, makes the radio group read-only (no changes allowed) |
tabIndex | number | 0 | Tab index for keyboard navigation. First or selected radio gets this value, others get -1 |
className | string | undefined | Additional CSS classes to apply to the radio group container |
| ...rest | Omit<HTMLAttributes<HTMLDivElement>, "onChange"> | - | All standard HTML div attributes except onChange |
Notes
- FormControl Integration: RadioGroup should typically be wrapped in a
FormControlcomponent for labels, descriptions, validation status, and error messages. Passlabel,description,validationStatus, anderrorMessageprops to FormControl, not RadioGroup - Keyboard Navigation: Use Arrow keys (Up/Down/Left/Right) to navigate between radio options. Press Space or Enter to select the focused option
- Accessibility: Implements proper ARIA attributes including
role="radiogroup",role="radio",aria-checked, and roving tabindex for keyboard navigation. Usearia-labelledbyto connect RadioGroup to FormControl's label - Generic Value Type: Supports any value type (string, number, object, etc.) through TypeScript generics
- Automatic State Management: Uses the
useValuehook internally to manage state, supporting both controlled and uncontrolled usage - Button Support: Can accept Button components as children for a button-style radio group with automatic styling (selected buttons get black color, unselected get white)
- Radio Support: Can accept Radio components as children for traditional radio button appearance
- Mixed Children: Supports non-Radio/Button children (like text or spans) which are rendered as-is without modification
- Roving Tabindex: Implements the roving tabindex pattern - only one radio button is tabbable at a time, improving keyboard navigation
- Client Component: This component uses hooks and event handlers, so it must be used in a client component (use "use client" directive)
- Gap Spacing: Radio options are spaced with a 12px gap by default (can be overridden with className)
- Data Attributes: Uses
data-valueattribute on Button children for keyboard navigation and selection logic