@neynar/ui 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/context7.json +17 -0
- package/llm/components/accordion.llm.md +205 -0
- package/llm/components/alert-dialog.llm.md +289 -0
- package/llm/components/alert.llm.md +310 -0
- package/llm/components/aspect-ratio.llm.md +110 -0
- package/llm/components/avatar.llm.md +282 -0
- package/llm/components/badge.llm.md +185 -0
- package/llm/components/blockquote.llm.md +86 -0
- package/llm/components/breadcrumb.llm.md +245 -0
- package/llm/components/button-group.llm.md +248 -0
- package/llm/components/button.llm.md +247 -0
- package/llm/components/calendar.llm.md +252 -0
- package/llm/components/card.llm.md +356 -0
- package/llm/components/carousel.llm.md +281 -0
- package/llm/components/chart.llm.md +278 -0
- package/llm/components/checkbox.llm.md +234 -0
- package/llm/components/code.llm.md +75 -0
- package/llm/components/collapsible.llm.md +271 -0
- package/llm/components/color-mode.llm.md +196 -0
- package/llm/components/combobox.llm.md +346 -0
- package/llm/components/command.llm.md +353 -0
- package/llm/components/context-menu.llm.md +368 -0
- package/llm/components/dialog.llm.md +283 -0
- package/llm/components/drawer.llm.md +326 -0
- package/llm/components/dropdown-menu.llm.md +404 -0
- package/llm/components/empty.llm.md +282 -0
- package/llm/components/field.llm.md +303 -0
- package/llm/components/first-light.llm.md +129 -0
- package/llm/components/hover-card.llm.md +278 -0
- package/llm/components/input-group.llm.md +334 -0
- package/llm/components/input-otp.llm.md +270 -0
- package/llm/components/input.llm.md +197 -0
- package/llm/components/item.llm.md +347 -0
- package/llm/components/kbd.llm.md +221 -0
- package/llm/components/label.llm.md +219 -0
- package/llm/components/menubar.llm.md +378 -0
- package/llm/components/navigation-menu.llm.md +320 -0
- package/llm/components/pagination.llm.md +337 -0
- package/llm/components/popover.llm.md +278 -0
- package/llm/components/progress.llm.md +259 -0
- package/llm/components/radio-group.llm.md +269 -0
- package/llm/components/resizable.llm.md +222 -0
- package/llm/components/scroll-area.llm.md +290 -0
- package/llm/components/select.llm.md +338 -0
- package/llm/components/separator.llm.md +129 -0
- package/llm/components/sheet.llm.md +275 -0
- package/llm/components/sidebar.llm.md +528 -0
- package/llm/components/skeleton.llm.md +140 -0
- package/llm/components/slider.llm.md +213 -0
- package/llm/components/sonner.llm.md +299 -0
- package/llm/components/spinner.llm.md +187 -0
- package/llm/components/switch.llm.md +258 -0
- package/llm/components/table.llm.md +334 -0
- package/llm/components/tabs.llm.md +245 -0
- package/llm/components/text.llm.md +108 -0
- package/llm/components/textarea.llm.md +236 -0
- package/llm/components/title.llm.md +88 -0
- package/llm/components/toggle-group.llm.md +228 -0
- package/llm/components/toggle.llm.md +235 -0
- package/llm/components/tooltip.llm.md +191 -0
- package/llm/contributing.llm.md +273 -0
- package/llm/hooks.llm.md +91 -0
- package/llm/index.llm.md +178 -0
- package/llm/theming.llm.md +381 -0
- package/llm/utilities.llm.md +97 -0
- package/llms-full.txt +15995 -0
- package/llms.txt +182 -0
- package/package.json +5 -1
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# Progress
|
|
2
|
+
|
|
3
|
+
Progress bar for displaying task completion, loading states, and quota usage.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import {
|
|
9
|
+
Progress,
|
|
10
|
+
ProgressTrack,
|
|
11
|
+
ProgressIndicator,
|
|
12
|
+
ProgressLabel,
|
|
13
|
+
ProgressValue,
|
|
14
|
+
} from "@neynar/ui/progress"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Anatomy
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
<Progress value={65}>
|
|
21
|
+
<ProgressLabel>Loading</ProgressLabel>
|
|
22
|
+
<ProgressValue />
|
|
23
|
+
<ProgressTrack>
|
|
24
|
+
<ProgressIndicator />
|
|
25
|
+
</ProgressTrack>
|
|
26
|
+
</Progress>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Components
|
|
30
|
+
|
|
31
|
+
| Component | Description |
|
|
32
|
+
|-----------|-------------|
|
|
33
|
+
| Progress | Root container managing progress state and rendering |
|
|
34
|
+
| ProgressLabel | Text label describing the task |
|
|
35
|
+
| ProgressValue | Formatted percentage display (auto-positioned right) |
|
|
36
|
+
| ProgressTrack | Container for the progress bar track |
|
|
37
|
+
| ProgressIndicator | Visual bar showing completion (auto-width based on value) |
|
|
38
|
+
|
|
39
|
+
## Props
|
|
40
|
+
|
|
41
|
+
### Progress
|
|
42
|
+
|
|
43
|
+
Root component providing progress state context to all children.
|
|
44
|
+
|
|
45
|
+
| Prop | Type | Default | Description |
|
|
46
|
+
|------|------|---------|-------------|
|
|
47
|
+
| value | number \| null | - | Progress value 0-100, or null for indeterminate |
|
|
48
|
+
| min | number | 0 | Minimum value |
|
|
49
|
+
| max | number | 100 | Maximum value |
|
|
50
|
+
| aria-valuetext | string | - | Custom accessible label for current value |
|
|
51
|
+
| getAriaValueText | (formatted: string \| null, value: number \| null) => string | - | Function to generate accessible label |
|
|
52
|
+
| locale | Intl.LocalesArgument | - | Locale for number formatting |
|
|
53
|
+
| format | Intl.NumberFormatOptions | - | Options for value formatting |
|
|
54
|
+
| className | string | - | Additional CSS classes |
|
|
55
|
+
|
|
56
|
+
### ProgressTrack
|
|
57
|
+
|
|
58
|
+
Container for the progress indicator. Customize height via className.
|
|
59
|
+
|
|
60
|
+
| Prop | Type | Default | Description |
|
|
61
|
+
|------|------|---------|-------------|
|
|
62
|
+
| className | string | - | Override default styles (default: `h-1.5`) |
|
|
63
|
+
|
|
64
|
+
**Default styles**: `bg-muted h-1.5 rounded-full relative flex w-full items-center overflow-x-hidden`
|
|
65
|
+
|
|
66
|
+
### ProgressIndicator
|
|
67
|
+
|
|
68
|
+
Visual bar showing task completion. Width automatically adjusts based on parent Progress value.
|
|
69
|
+
|
|
70
|
+
| Prop | Type | Default | Description |
|
|
71
|
+
|------|------|---------|-------------|
|
|
72
|
+
| className | string | - | Override colors/animation (default: `bg-primary`) |
|
|
73
|
+
|
|
74
|
+
**Default styles**: `bg-primary h-full transition-all`
|
|
75
|
+
|
|
76
|
+
Color customization examples:
|
|
77
|
+
- Success: `bg-green-500 dark:bg-green-400`
|
|
78
|
+
- Warning: `bg-yellow-500 dark:bg-yellow-400`
|
|
79
|
+
- Danger: `bg-red-500 dark:bg-red-400`
|
|
80
|
+
|
|
81
|
+
### ProgressLabel
|
|
82
|
+
|
|
83
|
+
Text label for the progress task.
|
|
84
|
+
|
|
85
|
+
| Prop | Type | Default | Description |
|
|
86
|
+
|------|------|---------|-------------|
|
|
87
|
+
| className | string | - | Additional CSS classes |
|
|
88
|
+
| children | ReactNode | - | Label text |
|
|
89
|
+
|
|
90
|
+
**Default styles**: `text-sm font-medium`
|
|
91
|
+
|
|
92
|
+
### ProgressValue
|
|
93
|
+
|
|
94
|
+
Displays formatted progress value (e.g., "65%").
|
|
95
|
+
|
|
96
|
+
| Prop | Type | Default | Description |
|
|
97
|
+
|------|------|---------|-------------|
|
|
98
|
+
| className | string | - | Additional CSS classes |
|
|
99
|
+
| children | (formatted: string \| null, value: number \| null) => ReactNode | - | Custom formatter function |
|
|
100
|
+
|
|
101
|
+
**Default styles**: `text-muted-foreground ml-auto text-sm tabular-nums`
|
|
102
|
+
|
|
103
|
+
## Data Attributes
|
|
104
|
+
|
|
105
|
+
All components share these data attributes for styling:
|
|
106
|
+
|
|
107
|
+
| Attribute | When Present |
|
|
108
|
+
|-----------|--------------|
|
|
109
|
+
| data-progressing | Value is between min and max |
|
|
110
|
+
| data-complete | Value equals max (100 by default) |
|
|
111
|
+
| data-indeterminate | Value is null (unknown duration) |
|
|
112
|
+
|
|
113
|
+
## Examples
|
|
114
|
+
|
|
115
|
+
### Basic Progress
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
<Progress value={65}>
|
|
119
|
+
<ProgressLabel>Loading</ProgressLabel>
|
|
120
|
+
<ProgressValue />
|
|
121
|
+
<ProgressTrack>
|
|
122
|
+
<ProgressIndicator />
|
|
123
|
+
</ProgressTrack>
|
|
124
|
+
</Progress>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Minimal (No Label/Value)
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
<Progress value={45}>
|
|
131
|
+
<ProgressTrack>
|
|
132
|
+
<ProgressIndicator />
|
|
133
|
+
</ProgressTrack>
|
|
134
|
+
</Progress>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Semantic Colors for States
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
// Success state (healthy usage)
|
|
141
|
+
<Progress value={45}>
|
|
142
|
+
<ProgressLabel>API Usage</ProgressLabel>
|
|
143
|
+
<ProgressValue />
|
|
144
|
+
<ProgressTrack>
|
|
145
|
+
<ProgressIndicator className="bg-green-500 dark:bg-green-400" />
|
|
146
|
+
</ProgressTrack>
|
|
147
|
+
</Progress>
|
|
148
|
+
|
|
149
|
+
// Warning state (approaching limit)
|
|
150
|
+
<Progress value={78}>
|
|
151
|
+
<ProgressLabel>Rate Limit</ProgressLabel>
|
|
152
|
+
<ProgressValue />
|
|
153
|
+
<ProgressTrack>
|
|
154
|
+
<ProgressIndicator className="bg-yellow-500 dark:bg-yellow-400" />
|
|
155
|
+
</ProgressTrack>
|
|
156
|
+
</Progress>
|
|
157
|
+
|
|
158
|
+
// Critical state
|
|
159
|
+
<Progress value={94}>
|
|
160
|
+
<ProgressLabel>Storage</ProgressLabel>
|
|
161
|
+
<ProgressValue />
|
|
162
|
+
<ProgressTrack>
|
|
163
|
+
<ProgressIndicator className="bg-red-500 dark:bg-red-400" />
|
|
164
|
+
</ProgressTrack>
|
|
165
|
+
</Progress>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Size Variants
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
// Small
|
|
172
|
+
<Progress value={65}>
|
|
173
|
+
<ProgressLabel>Small</ProgressLabel>
|
|
174
|
+
<ProgressValue />
|
|
175
|
+
<ProgressTrack className="h-1">
|
|
176
|
+
<ProgressIndicator />
|
|
177
|
+
</ProgressTrack>
|
|
178
|
+
</Progress>
|
|
179
|
+
|
|
180
|
+
// Default
|
|
181
|
+
<Progress value={65}>
|
|
182
|
+
<ProgressLabel>Default</ProgressLabel>
|
|
183
|
+
<ProgressValue />
|
|
184
|
+
<ProgressTrack className="h-1.5">
|
|
185
|
+
<ProgressIndicator />
|
|
186
|
+
</ProgressTrack>
|
|
187
|
+
</Progress>
|
|
188
|
+
|
|
189
|
+
// Large
|
|
190
|
+
<Progress value={65}>
|
|
191
|
+
<ProgressLabel>Large</ProgressLabel>
|
|
192
|
+
<ProgressValue />
|
|
193
|
+
<ProgressTrack className="h-3">
|
|
194
|
+
<ProgressIndicator />
|
|
195
|
+
</ProgressTrack>
|
|
196
|
+
</Progress>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Indeterminate State
|
|
200
|
+
|
|
201
|
+
For tasks with unknown duration:
|
|
202
|
+
|
|
203
|
+
```tsx
|
|
204
|
+
<Progress value={null}>
|
|
205
|
+
<ProgressLabel>Processing...</ProgressLabel>
|
|
206
|
+
<ProgressTrack>
|
|
207
|
+
<ProgressIndicator className="w-1/3 animate-pulse" />
|
|
208
|
+
</ProgressTrack>
|
|
209
|
+
</Progress>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### API Usage Dashboard Context
|
|
213
|
+
|
|
214
|
+
```tsx
|
|
215
|
+
<div className="border-border bg-card rounded-lg border p-5">
|
|
216
|
+
<div className="mb-4 flex items-start justify-between">
|
|
217
|
+
<div className="flex items-center gap-3">
|
|
218
|
+
<div className="bg-primary/10 text-primary rounded-md p-2">
|
|
219
|
+
<ActivityIcon className="size-5" />
|
|
220
|
+
</div>
|
|
221
|
+
<div>
|
|
222
|
+
<p className="font-medium">Monthly API Calls</p>
|
|
223
|
+
<p className="text-muted-foreground text-sm">
|
|
224
|
+
Standard Plan: 1M requests/month
|
|
225
|
+
</p>
|
|
226
|
+
</div>
|
|
227
|
+
</div>
|
|
228
|
+
<span className="rounded-full bg-green-500/10 px-2.5 py-1 text-xs font-medium text-green-600">
|
|
229
|
+
Healthy
|
|
230
|
+
</span>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<Progress value={45}>
|
|
234
|
+
<ProgressLabel>API Requests</ProgressLabel>
|
|
235
|
+
<ProgressValue />
|
|
236
|
+
<ProgressTrack>
|
|
237
|
+
<ProgressIndicator className="bg-green-500 dark:bg-green-400" />
|
|
238
|
+
</ProgressTrack>
|
|
239
|
+
</Progress>
|
|
240
|
+
|
|
241
|
+
<p className="text-muted-foreground mt-2 text-sm">
|
|
242
|
+
450,000 of 1,000,000 requests used
|
|
243
|
+
</p>
|
|
244
|
+
</div>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Accessibility
|
|
248
|
+
|
|
249
|
+
- Uses `role="progressbar"` with proper ARIA attributes
|
|
250
|
+
- Announces progress value and label to screen readers
|
|
251
|
+
- Supports `aria-valuetext` for custom accessible labels
|
|
252
|
+
- `getAriaValueText` prop allows dynamic accessible descriptions
|
|
253
|
+
- Indeterminate state properly announced when `value={null}`
|
|
254
|
+
|
|
255
|
+
## Related
|
|
256
|
+
|
|
257
|
+
- **Skeleton** - Loading placeholders for content
|
|
258
|
+
- **Spinner** - Circular loading indicator
|
|
259
|
+
- **Badge** - Status indicators with semantic colors
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# RadioGroup
|
|
2
|
+
|
|
3
|
+
Mutually exclusive selection from a group of options.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { RadioGroup, RadioGroupItem } from "@neynar/ui/radio-group"
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<RadioGroup value={value} onValueChange={setValue}>
|
|
15
|
+
<RadioGroupItem value="option-1" id="option-1" />
|
|
16
|
+
<RadioGroupItem value="option-2" id="option-2" />
|
|
17
|
+
</RadioGroup>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Components
|
|
21
|
+
|
|
22
|
+
| Component | Description |
|
|
23
|
+
|-----------|-------------|
|
|
24
|
+
| RadioGroup | Container that manages state for radio items |
|
|
25
|
+
| RadioGroupItem | Individual radio button with automatic indicator |
|
|
26
|
+
|
|
27
|
+
## Props
|
|
28
|
+
|
|
29
|
+
### RadioGroup
|
|
30
|
+
|
|
31
|
+
| Prop | Type | Default | Description |
|
|
32
|
+
|------|------|---------|-------------|
|
|
33
|
+
| value | unknown | - | Controlled selected value |
|
|
34
|
+
| onValueChange | (value: unknown) => void | - | Called when selection changes |
|
|
35
|
+
| defaultValue | unknown | - | Uncontrolled initial value |
|
|
36
|
+
| name | string | - | Form field name for submission |
|
|
37
|
+
| disabled | boolean | false | Disable all radio items |
|
|
38
|
+
| readOnly | boolean | false | Prevent selection changes |
|
|
39
|
+
| required | boolean | false | Mark as required for forms |
|
|
40
|
+
| inputRef | Ref\<HTMLInputElement\> | - | Ref to hidden input element |
|
|
41
|
+
| className | string | - | Additional CSS classes |
|
|
42
|
+
|
|
43
|
+
### RadioGroupItem
|
|
44
|
+
|
|
45
|
+
| Prop | Type | Default | Description |
|
|
46
|
+
|------|------|---------|-------------|
|
|
47
|
+
| value | string | - | Value for this radio option |
|
|
48
|
+
| id | string | - | HTML id for label association |
|
|
49
|
+
| disabled | boolean | false | Disable this specific item |
|
|
50
|
+
| aria-invalid | boolean | - | Mark as invalid (error state) |
|
|
51
|
+
| className | string | - | Additional CSS classes |
|
|
52
|
+
|
|
53
|
+
The RadioGroupItem automatically renders a checked indicator (filled circle) when selected.
|
|
54
|
+
|
|
55
|
+
## Data Attributes
|
|
56
|
+
|
|
57
|
+
### RadioGroup
|
|
58
|
+
|
|
59
|
+
| Attribute | When Present |
|
|
60
|
+
|-----------|--------------|
|
|
61
|
+
| data-disabled | Group is disabled |
|
|
62
|
+
|
|
63
|
+
### RadioGroupItem
|
|
64
|
+
|
|
65
|
+
| Attribute | When Present |
|
|
66
|
+
|-----------|--------------|
|
|
67
|
+
| data-checked | Item is selected |
|
|
68
|
+
| data-unchecked | Item is not selected |
|
|
69
|
+
| data-disabled | Item is disabled |
|
|
70
|
+
|
|
71
|
+
## Examples
|
|
72
|
+
|
|
73
|
+
### Basic Usage
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
function NotificationPreferences() {
|
|
77
|
+
const [method, setMethod] = useState("email")
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<RadioGroup value={method} onValueChange={(v) => setMethod(v as string)}>
|
|
81
|
+
<div className="flex items-center space-x-2">
|
|
82
|
+
<RadioGroupItem value="email" id="email" />
|
|
83
|
+
<Label htmlFor="email">Email</Label>
|
|
84
|
+
</div>
|
|
85
|
+
<div className="flex items-center space-x-2">
|
|
86
|
+
<RadioGroupItem value="sms" id="sms" />
|
|
87
|
+
<Label htmlFor="sms">SMS</Label>
|
|
88
|
+
</div>
|
|
89
|
+
<div className="flex items-center space-x-2">
|
|
90
|
+
<RadioGroupItem value="push" id="push" />
|
|
91
|
+
<Label htmlFor="push">Push Notifications</Label>
|
|
92
|
+
</div>
|
|
93
|
+
</RadioGroup>
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Uncontrolled with Default Value
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
<RadioGroup defaultValue="standard" name="shipping">
|
|
102
|
+
<div className="flex items-center space-x-2">
|
|
103
|
+
<RadioGroupItem value="standard" id="standard" />
|
|
104
|
+
<Label htmlFor="standard">Standard Shipping</Label>
|
|
105
|
+
</div>
|
|
106
|
+
<div className="flex items-center space-x-2">
|
|
107
|
+
<RadioGroupItem value="express" id="express" />
|
|
108
|
+
<Label htmlFor="express">Express Shipping</Label>
|
|
109
|
+
</div>
|
|
110
|
+
</RadioGroup>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### With Descriptions
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
<RadioGroup defaultValue="mainnet">
|
|
117
|
+
<div className="flex items-start space-x-3">
|
|
118
|
+
<RadioGroupItem value="mainnet" id="mainnet" className="mt-0.5" />
|
|
119
|
+
<div className="flex-1">
|
|
120
|
+
<Label htmlFor="mainnet" className="font-medium">Mainnet</Label>
|
|
121
|
+
<p className="text-muted-foreground text-sm">
|
|
122
|
+
Production-ready network with real users and data.
|
|
123
|
+
</p>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
<div className="flex items-start space-x-3">
|
|
127
|
+
<RadioGroupItem value="testnet" id="testnet" className="mt-0.5" />
|
|
128
|
+
<div className="flex-1">
|
|
129
|
+
<Label htmlFor="testnet" className="font-medium">Testnet</Label>
|
|
130
|
+
<p className="text-muted-foreground text-sm">
|
|
131
|
+
Testing environment for development.
|
|
132
|
+
</p>
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</RadioGroup>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Error State
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
function FormField() {
|
|
142
|
+
const [value, setValue] = useState("")
|
|
143
|
+
const [showError, setShowError] = useState(false)
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<div className="space-y-2">
|
|
147
|
+
<RadioGroup
|
|
148
|
+
value={value}
|
|
149
|
+
onValueChange={(v) => {
|
|
150
|
+
setValue(v as string)
|
|
151
|
+
setShowError(false)
|
|
152
|
+
}}
|
|
153
|
+
aria-invalid={showError}
|
|
154
|
+
>
|
|
155
|
+
<div className="flex items-center space-x-2">
|
|
156
|
+
<RadioGroupItem value="yes" id="yes" aria-invalid={showError} />
|
|
157
|
+
<Label htmlFor="yes">Yes</Label>
|
|
158
|
+
</div>
|
|
159
|
+
<div className="flex items-center space-x-2">
|
|
160
|
+
<RadioGroupItem value="no" id="no" aria-invalid={showError} />
|
|
161
|
+
<Label htmlFor="no">No</Label>
|
|
162
|
+
</div>
|
|
163
|
+
</RadioGroup>
|
|
164
|
+
{showError && (
|
|
165
|
+
<p className="text-destructive text-sm">Please make a selection.</p>
|
|
166
|
+
)}
|
|
167
|
+
</div>
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Disabled Group
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
<RadioGroup disabled defaultValue="option-1">
|
|
176
|
+
<div className="flex items-center space-x-2">
|
|
177
|
+
<RadioGroupItem value="option-1" id="option-1" />
|
|
178
|
+
<Label htmlFor="option-1">Option 1</Label>
|
|
179
|
+
</div>
|
|
180
|
+
<div className="flex items-center space-x-2">
|
|
181
|
+
<RadioGroupItem value="option-2" id="option-2" />
|
|
182
|
+
<Label htmlFor="option-2">Option 2</Label>
|
|
183
|
+
</div>
|
|
184
|
+
</RadioGroup>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Individual Disabled Items
|
|
188
|
+
|
|
189
|
+
```tsx
|
|
190
|
+
<RadioGroup defaultValue="available-1">
|
|
191
|
+
<div className="flex items-center space-x-2">
|
|
192
|
+
<RadioGroupItem value="available-1" id="available-1" />
|
|
193
|
+
<Label htmlFor="available-1">Available Option</Label>
|
|
194
|
+
</div>
|
|
195
|
+
<div className="flex items-center space-x-2">
|
|
196
|
+
<RadioGroupItem value="sold-out" id="sold-out" disabled />
|
|
197
|
+
<Label htmlFor="sold-out">Sold Out</Label>
|
|
198
|
+
</div>
|
|
199
|
+
<div className="flex items-center space-x-2">
|
|
200
|
+
<RadioGroupItem value="available-2" id="available-2" />
|
|
201
|
+
<Label htmlFor="available-2">Another Available</Label>
|
|
202
|
+
</div>
|
|
203
|
+
</RadioGroup>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Card-Based Layout
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
<RadioGroup defaultValue="pro">
|
|
210
|
+
<div className="grid gap-4 sm:grid-cols-3">
|
|
211
|
+
<label
|
|
212
|
+
htmlFor="free"
|
|
213
|
+
className="hover:border-primary/50 border-border flex cursor-pointer flex-col gap-3 rounded-lg border p-4"
|
|
214
|
+
>
|
|
215
|
+
<RadioGroupItem value="free" id="free" />
|
|
216
|
+
<div>
|
|
217
|
+
<p className="font-semibold">Free Plan</p>
|
|
218
|
+
<p className="text-muted-foreground text-sm">Perfect for testing</p>
|
|
219
|
+
</div>
|
|
220
|
+
</label>
|
|
221
|
+
|
|
222
|
+
<label
|
|
223
|
+
htmlFor="pro"
|
|
224
|
+
className="hover:border-primary/50 border-primary border-2 flex cursor-pointer flex-col gap-3 rounded-lg p-4"
|
|
225
|
+
>
|
|
226
|
+
<RadioGroupItem value="pro" id="pro" />
|
|
227
|
+
<div>
|
|
228
|
+
<p className="font-semibold">Pro Plan</p>
|
|
229
|
+
<p className="text-muted-foreground text-sm">For production apps</p>
|
|
230
|
+
</div>
|
|
231
|
+
</label>
|
|
232
|
+
|
|
233
|
+
<label
|
|
234
|
+
htmlFor="enterprise"
|
|
235
|
+
className="hover:border-primary/50 border-border flex cursor-pointer flex-col gap-3 rounded-lg border p-4"
|
|
236
|
+
>
|
|
237
|
+
<RadioGroupItem value="enterprise" id="enterprise" />
|
|
238
|
+
<div>
|
|
239
|
+
<p className="font-semibold">Enterprise</p>
|
|
240
|
+
<p className="text-muted-foreground text-sm">Custom solutions</p>
|
|
241
|
+
</div>
|
|
242
|
+
</label>
|
|
243
|
+
</div>
|
|
244
|
+
</RadioGroup>
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Keyboard
|
|
248
|
+
|
|
249
|
+
| Key | Action |
|
|
250
|
+
|-----|--------|
|
|
251
|
+
| Tab | Focus next radio item |
|
|
252
|
+
| Shift+Tab | Focus previous radio item |
|
|
253
|
+
| Space | Select focused item |
|
|
254
|
+
| Arrow Down/Right | Select next item |
|
|
255
|
+
| Arrow Up/Left | Select previous item |
|
|
256
|
+
|
|
257
|
+
## Accessibility
|
|
258
|
+
|
|
259
|
+
- Each RadioGroupItem should have a unique `id` and paired `<Label htmlFor={id}>`
|
|
260
|
+
- Uses `role="radiogroup"` and `role="radio"` with proper ARIA attributes
|
|
261
|
+
- Manages focus with roving tabindex for keyboard navigation
|
|
262
|
+
- Error states use `aria-invalid` for screen reader announcements
|
|
263
|
+
- Disabled state prevents interaction and is announced to assistive technologies
|
|
264
|
+
|
|
265
|
+
## Related
|
|
266
|
+
|
|
267
|
+
- [Label](./label.llm.md) - For labeling radio items
|
|
268
|
+
- [Checkbox](./checkbox.llm.md) - For multi-select options
|
|
269
|
+
- [Select](./select.llm.md) - For dropdown selections
|