torch-glare 2.5.6 → 2.6.0
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/README.md +4 -3
- package/dist/bin/index.js +9 -24
- package/dist/bin/index.js.map +1 -1
- package/dist/src/commands/add.d.ts +2 -2
- package/dist/src/commands/add.d.ts.map +1 -1
- package/dist/src/commands/add.js +4 -70
- package/dist/src/commands/add.js.map +1 -1
- package/dist/src/commands/hook.d.ts +5 -4
- package/dist/src/commands/hook.d.ts.map +1 -1
- package/dist/src/commands/hook.js +7 -75
- package/dist/src/commands/hook.js.map +1 -1
- package/dist/src/commands/init.js +1 -1
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/layout.d.ts +5 -4
- package/dist/src/commands/layout.d.ts.map +1 -1
- package/dist/src/commands/layout.js +7 -75
- package/dist/src/commands/layout.js.map +1 -1
- package/dist/src/commands/provider.d.ts +5 -4
- package/dist/src/commands/provider.d.ts.map +1 -1
- package/dist/src/commands/provider.js +7 -75
- package/dist/src/commands/provider.js.map +1 -1
- package/dist/src/commands/update.d.ts.map +1 -1
- package/dist/src/commands/update.js +78 -43
- package/dist/src/commands/update.js.map +1 -1
- package/dist/src/commands/utils.d.ts +5 -4
- package/dist/src/commands/utils.d.ts.map +1 -1
- package/dist/src/commands/utils.js +7 -80
- package/dist/src/commands/utils.js.map +1 -1
- package/dist/src/shared/addFromRegistry.d.ts +16 -0
- package/dist/src/shared/addFromRegistry.d.ts.map +1 -0
- package/dist/src/shared/addFromRegistry.js +88 -0
- package/dist/src/shared/addFromRegistry.js.map +1 -0
- package/dist/src/shared/getInstallCommand.d.ts.map +1 -1
- package/dist/src/shared/getInstallCommand.js +5 -0
- package/dist/src/shared/getInstallCommand.js.map +1 -1
- package/dist/src/shared/installDependencies.d.ts +0 -10
- package/dist/src/shared/installDependencies.d.ts.map +1 -1
- package/dist/src/shared/installDependencies.js +0 -17
- package/dist/src/shared/installDependencies.js.map +1 -1
- package/dist/src/shared/installFromPlan.d.ts +7 -5
- package/dist/src/shared/installFromPlan.d.ts.map +1 -1
- package/dist/src/shared/installFromPlan.js +103 -36
- package/dist/src/shared/installFromPlan.js.map +1 -1
- package/dist/src/shared/loadRegistry.d.ts +12 -3
- package/dist/src/shared/loadRegistry.d.ts.map +1 -1
- package/dist/src/shared/loadRegistry.js +19 -20
- package/dist/src/shared/loadRegistry.js.map +1 -1
- package/dist/src/shared/registryClient.d.ts +19 -0
- package/dist/src/shared/registryClient.d.ts.map +1 -0
- package/dist/src/shared/registryClient.js +128 -0
- package/dist/src/shared/registryClient.js.map +1 -0
- package/dist/src/shared/resolveEntry.d.ts +10 -7
- package/dist/src/shared/resolveEntry.d.ts.map +1 -1
- package/dist/src/shared/resolveEntry.js +18 -13
- package/dist/src/shared/resolveEntry.js.map +1 -1
- package/dist/src/shared/suggestOtherCommand.d.ts +7 -1
- package/dist/src/shared/suggestOtherCommand.d.ts.map +1 -1
- package/dist/src/shared/suggestOtherCommand.js +29 -23
- package/dist/src/shared/suggestOtherCommand.js.map +1 -1
- package/dist/src/types/main.d.ts +31 -2
- package/dist/src/types/main.d.ts.map +1 -1
- package/package.json +6 -11
- package/apps/lib/components/ActionButton.tsx +0 -93
- package/apps/lib/components/ActionsGroup.tsx +0 -27
- package/apps/lib/components/AlertDialog.tsx +0 -204
- package/apps/lib/components/Avatar.tsx +0 -46
- package/apps/lib/components/Badge.tsx +0 -250
- package/apps/lib/components/BadgeField.tsx +0 -403
- package/apps/lib/components/Breadcrumb.tsx +0 -280
- package/apps/lib/components/Button.tsx +0 -325
- package/apps/lib/components/ButtonGroup.tsx +0 -190
- package/apps/lib/components/Calendar.tsx +0 -115
- package/apps/lib/components/Card.tsx +0 -95
- package/apps/lib/components/Checkbox.tsx +0 -42
- package/apps/lib/components/ColorPicker.tsx +0 -441
- package/apps/lib/components/ConclusionHeader.tsx +0 -148
- package/apps/lib/components/ContextMenu.tsx +0 -571
- package/apps/lib/components/CountBadge.tsx +0 -52
- package/apps/lib/components/DataTable.tsx +0 -213
- package/apps/lib/components/DataViews/badge.ts +0 -49
- package/apps/lib/components/DataViews/cell.tsx +0 -324
- package/apps/lib/components/DataViews/context.ts +0 -144
- package/apps/lib/components/DataViews/data-views.tsx +0 -395
- package/apps/lib/components/DataViews/filters/children.tsx +0 -98
- package/apps/lib/components/DataViews/filters/custom.tsx +0 -34
- package/apps/lib/components/DataViews/filters/filters.tsx +0 -157
- package/apps/lib/components/DataViews/filters/index.ts +0 -4
- package/apps/lib/components/DataViews/filters/labelled.tsx +0 -20
- package/apps/lib/components/DataViews/filters/presets.tsx +0 -65
- package/apps/lib/components/DataViews/filters/sync.tsx +0 -35
- package/apps/lib/components/DataViews/filters/values.ts +0 -173
- package/apps/lib/components/DataViews/header.tsx +0 -220
- package/apps/lib/components/DataViews/hooks/index.ts +0 -5
- package/apps/lib/components/DataViews/hooks/useActiveRow.ts +0 -22
- package/apps/lib/components/DataViews/hooks/useControllable.ts +0 -52
- package/apps/lib/components/DataViews/index.ts +0 -88
- package/apps/lib/components/DataViews/panel/columns.tsx +0 -153
- package/apps/lib/components/DataViews/panel/controls.tsx +0 -106
- package/apps/lib/components/DataViews/panel/index.ts +0 -3
- package/apps/lib/components/DataViews/panel/panel.tsx +0 -164
- package/apps/lib/components/DataViews/panel/saved-views.tsx +0 -67
- package/apps/lib/components/DataViews/panel/section.tsx +0 -81
- package/apps/lib/components/DataViews/panel/sort.tsx +0 -42
- package/apps/lib/components/DataViews/panel/tab.tsx +0 -31
- package/apps/lib/components/DataViews/slots.ts +0 -72
- package/apps/lib/components/DataViews/states.tsx +0 -73
- package/apps/lib/components/DataViews/types.ts +0 -510
- package/apps/lib/components/DataViews/views/board-view.tsx +0 -381
- package/apps/lib/components/DataViews/views/card-rows.tsx +0 -36
- package/apps/lib/components/DataViews/views/inbox-view.tsx +0 -260
- package/apps/lib/components/DataViews/views/pane-views.tsx +0 -196
- package/apps/lib/components/DataViews/views/table-view.tsx +0 -493
- package/apps/lib/components/DataViews/views/tree-view.tsx +0 -367
- package/apps/lib/components/DatePicker.tsx +0 -232
- package/apps/lib/components/Dialog.tsx +0 -116
- package/apps/lib/components/Divider.tsx +0 -28
- package/apps/lib/components/Drawer.tsx +0 -451
- package/apps/lib/components/DropdownMenu.tsx +0 -554
- package/apps/lib/components/FieldHint.tsx +0 -69
- package/apps/lib/components/Form.tsx +0 -182
- package/apps/lib/components/FormBuilder/context.ts +0 -85
- package/apps/lib/components/FormBuilder/field-kind.ts +0 -28
- package/apps/lib/components/FormBuilder/fields/ChoiceFields.tsx +0 -60
- package/apps/lib/components/FormBuilder/fields/ColorField.tsx +0 -59
- package/apps/lib/components/FormBuilder/fields/CustomField.tsx +0 -11
- package/apps/lib/components/FormBuilder/fields/DateField.tsx +0 -32
- package/apps/lib/components/FormBuilder/fields/FieldArray.tsx +0 -74
- package/apps/lib/components/FormBuilder/fields/FieldShell.tsx +0 -168
- package/apps/lib/components/FormBuilder/fields/FileField.tsx +0 -39
- package/apps/lib/components/FormBuilder/fields/OptionListFields.tsx +0 -132
- package/apps/lib/components/FormBuilder/fields/OtpField.tsx +0 -31
- package/apps/lib/components/FormBuilder/fields/PhoneField.tsx +0 -109
- package/apps/lib/components/FormBuilder/fields/RichTextEditorField.tsx +0 -31
- package/apps/lib/components/FormBuilder/fields/SelectField.tsx +0 -114
- package/apps/lib/components/FormBuilder/fields/SignatureField.tsx +0 -157
- package/apps/lib/components/FormBuilder/fields/SliderField.tsx +0 -67
- package/apps/lib/components/FormBuilder/fields/SwitchBoxField.tsx +0 -41
- package/apps/lib/components/FormBuilder/fields/TableField.tsx +0 -336
- package/apps/lib/components/FormBuilder/fields/TextField.tsx +0 -213
- package/apps/lib/components/FormBuilder/fields/TreeSelectField.tsx +0 -43
- package/apps/lib/components/FormBuilder/fields/countries.ts +0 -303
- package/apps/lib/components/FormBuilder/fields/index.ts +0 -25
- package/apps/lib/components/FormBuilder/form-builder.tsx +0 -198
- package/apps/lib/components/FormBuilder/index.ts +0 -31
- package/apps/lib/components/FormBuilder/numberFormat.ts +0 -16
- package/apps/lib/components/FormBuilder/submit.tsx +0 -67
- package/apps/lib/components/FormBuilder/types.ts +0 -316
- package/apps/lib/components/FormRenderer/FormDrawer.tsx +0 -250
- package/apps/lib/components/FormRenderer/detail.tsx +0 -256
- package/apps/lib/components/FormRenderer/form-renderer.tsx +0 -358
- package/apps/lib/components/FormRenderer/header.tsx +0 -88
- package/apps/lib/components/FormRenderer/index.ts +0 -17
- package/apps/lib/components/FormRenderer/notch-action.tsx +0 -64
- package/apps/lib/components/FormRenderer/section.tsx +0 -39
- package/apps/lib/components/FormRenderer/stepper.tsx +0 -393
- package/apps/lib/components/FormRenderer/types.ts +0 -115
- package/apps/lib/components/FormSummary.tsx +0 -282
- package/apps/lib/components/HeaderBar.tsx +0 -117
- package/apps/lib/components/ImageAttachment.tsx +0 -209
- package/apps/lib/components/InnerLabelField.tsx +0 -154
- package/apps/lib/components/Input.tsx +0 -224
- package/apps/lib/components/InputField.tsx +0 -147
- package/apps/lib/components/InputOTP.tsx +0 -84
- package/apps/lib/components/Label.tsx +0 -129
- package/apps/lib/components/LabelField.tsx +0 -76
- package/apps/lib/components/LabeledCheckBox.tsx +0 -51
- package/apps/lib/components/LabeledRadio.tsx +0 -51
- package/apps/lib/components/LinkButton.tsx +0 -94
- package/apps/lib/components/LoginButton.tsx +0 -51
- package/apps/lib/components/PasswordLevel.tsx +0 -58
- package/apps/lib/components/Popover.tsx +0 -312
- package/apps/lib/components/ProfileMenu.tsx +0 -85
- package/apps/lib/components/Radio.tsx +0 -59
- package/apps/lib/components/RadioCard.tsx +0 -50
- package/apps/lib/components/ScrollArea.tsx +0 -54
- package/apps/lib/components/SearchField.tsx +0 -62
- package/apps/lib/components/SearchableSelect.tsx +0 -318
- package/apps/lib/components/SearchableTable.tsx +0 -344
- package/apps/lib/components/SearchableTree.tsx +0 -485
- package/apps/lib/components/SearchableTreeDialog.tsx +0 -502
- package/apps/lib/components/SectionBlock.tsx +0 -168
- package/apps/lib/components/Select.tsx +0 -347
- package/apps/lib/components/SimpleSelect.tsx +0 -225
- package/apps/lib/components/Skeleton.tsx +0 -12
- package/apps/lib/components/SlideDatePicker.tsx +0 -255
- package/apps/lib/components/SpinLoading.tsx +0 -174
- package/apps/lib/components/Stepper.tsx +0 -480
- package/apps/lib/components/Switch.tsx +0 -82
- package/apps/lib/components/TabFormItem.tsx +0 -153
- package/apps/lib/components/TabSwitch.tsx +0 -172
- package/apps/lib/components/Table.tsx +0 -597
- package/apps/lib/components/TextEditor/ChartBlockTool.ts +0 -676
- package/apps/lib/components/TextEditor/RichTextField.tsx +0 -46
- package/apps/lib/components/TextEditor/TableDnDWrapper.ts +0 -462
- package/apps/lib/components/TextEditor/TextEditor.tsx +0 -1164
- package/apps/lib/components/TextEditor/TextEditorToolbar.tsx +0 -429
- package/apps/lib/components/TextEditor/editor-tools/AlignmentTune.ts +0 -70
- package/apps/lib/components/TextEditor/editor-tools/ColorInlineTool.ts +0 -50
- package/apps/lib/components/TextEditor/editor-tools/StrikethroughInlineTool.ts +0 -48
- package/apps/lib/components/TextEditor/editor-tools/inlineFormat.ts +0 -98
- package/apps/lib/components/TextEditor/editorjs.d.ts +0 -60
- package/apps/lib/components/TextEditor/index.ts +0 -7
- package/apps/lib/components/TextEditor/markdownParser.ts +0 -346
- package/apps/lib/components/Textarea.tsx +0 -117
- package/apps/lib/components/Timeline.tsx +0 -263
- package/apps/lib/components/Toast.tsx +0 -87
- package/apps/lib/components/Toggle.tsx +0 -125
- package/apps/lib/components/ToggleButton.tsx +0 -140
- package/apps/lib/components/Tooltip.tsx +0 -116
- package/apps/lib/components/TransparentLabel.tsx +0 -71
- package/apps/lib/components/TreeDropDown.tsx +0 -115
- package/apps/lib/components/TreeFolder/TreeFolder.tsx +0 -380
- package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +0 -75
- package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +0 -354
- package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +0 -60
- package/apps/lib/components/TreeFolder/icons.tsx +0 -60
- package/apps/lib/components/TreeFolder/index.ts +0 -24
- package/apps/lib/components/TreeFolder/treeFolderUtils.ts +0 -109
- package/apps/lib/components/TreeFolder/types.ts +0 -77
- package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +0 -118
- package/apps/lib/hooks/useActiveTreeItem.ts +0 -61
- package/apps/lib/hooks/useClickOutside.ts +0 -27
- package/apps/lib/hooks/useDragDrop.tsx +0 -365
- package/apps/lib/hooks/useHtmlDir.ts +0 -31
- package/apps/lib/hooks/useInfiniteScroll.ts +0 -108
- package/apps/lib/hooks/useIsMobile.ts +0 -21
- package/apps/lib/hooks/useResize.ts +0 -67
- package/apps/lib/hooks/useTagSelection.ts +0 -300
- package/apps/lib/layouts/CNLayout.tsx +0 -372
- package/apps/lib/layouts/DataViewCard.tsx +0 -62
- package/apps/lib/layouts/FieldSection.tsx +0 -91
- package/apps/lib/layouts/TreeSubLayout.tsx +0 -173
- package/apps/lib/providers/ThemeProvider.tsx +0 -84
- package/apps/lib/registry.json +0 -1217
- package/apps/lib/tsconfig.json +0 -9
- package/apps/lib/tsconfig.tsbuildinfo +0 -1
- package/apps/lib/utils/cn.ts +0 -6
- package/apps/lib/utils/color.ts +0 -175
- package/apps/lib/utils/dataViews/path.ts +0 -67
- package/apps/lib/utils/dataViews/query.ts +0 -73
- package/apps/lib/utils/dataViews/types.ts +0 -187
- package/apps/lib/utils/dateFormat.ts +0 -108
- package/apps/lib/utils/resize.ts +0 -31
- package/apps/lib/utils/scroller.ts +0 -26
- package/apps/lib/utils/types.ts +0 -16
- package/docs/BLOCKS.md +0 -129
- package/docs/CHANGELOG-1.1.16.md +0 -108
- package/docs/Cover.png +0 -0
- package/docs/README.md +0 -215
- package/docs/components/action-button.md +0 -638
- package/docs/components/actions-group.md +0 -708
- package/docs/components/alert-dialog.md +0 -920
- package/docs/components/avatar.md +0 -709
- package/docs/components/badge-field.md +0 -738
- package/docs/components/badge.md +0 -301
- package/docs/components/breadcrumb.md +0 -930
- package/docs/components/button-group.md +0 -650
- package/docs/components/button.md +0 -639
- package/docs/components/calendar.md +0 -555
- package/docs/components/card.md +0 -622
- package/docs/components/chart-block-tool.md +0 -129
- package/docs/components/checkbox.md +0 -699
- package/docs/components/cn-layout.md +0 -854
- package/docs/components/color-picker.md +0 -101
- package/docs/components/conclusion-header.md +0 -80
- package/docs/components/context-menu.md +0 -483
- package/docs/components/count-badge.md +0 -560
- package/docs/components/data-table.md +0 -854
- package/docs/components/data-views/backend-response.md +0 -324
- package/docs/components/data-views/examples/a11y-rtl.md +0 -250
- package/docs/components/data-views/examples/api-orders-route.md +0 -130
- package/docs/components/data-views/examples/fields.md +0 -362
- package/docs/components/data-views/examples/filters.md +0 -307
- package/docs/components/data-views/examples/inbox-routing.md +0 -218
- package/docs/components/data-views/examples/index.md +0 -29
- package/docs/components/data-views/examples/overview.md +0 -244
- package/docs/components/data-views/examples/panel.md +0 -212
- package/docs/components/data-views/examples/scale.md +0 -231
- package/docs/components/data-views/examples/server-side.md +0 -210
- package/docs/components/data-views/examples/state.md +0 -250
- package/docs/components/data-views/examples/tree-custom.md +0 -388
- package/docs/components/data-views/examples/view-registry.md +0 -313
- package/docs/components/data-views/examples/views.md +0 -534
- package/docs/components/data-views/guide.md +0 -405
- package/docs/components/data-views/index.md +0 -1521
- package/docs/components/data-views/migration.md +0 -81
- package/docs/components/date-picker.md +0 -857
- package/docs/components/dialog.md +0 -929
- package/docs/components/divider.md +0 -766
- package/docs/components/drawer.md +0 -654
- package/docs/components/dropdown-menu.md +0 -668
- package/docs/components/field-hint.md +0 -898
- package/docs/components/field-section.md +0 -781
- package/docs/components/form-builder.md +0 -284
- package/docs/components/form-renderer.md +0 -396
- package/docs/components/form-summary.md +0 -138
- package/docs/components/form.md +0 -785
- package/docs/components/header-bar.md +0 -188
- package/docs/components/image-attachment.md +0 -906
- package/docs/components/inner-label-field.md +0 -819
- package/docs/components/input-field.md +0 -623
- package/docs/components/input-otp.md +0 -756
- package/docs/components/input.md +0 -634
- package/docs/components/label-field.md +0 -770
- package/docs/components/label.md +0 -761
- package/docs/components/labeled-check-box.md +0 -642
- package/docs/components/labeled-radio.md +0 -796
- package/docs/components/link-button.md +0 -685
- package/docs/components/login-button.md +0 -872
- package/docs/components/password-level.md +0 -803
- package/docs/components/popover.md +0 -649
- package/docs/components/profile-menu.md +0 -656
- package/docs/components/radio-card.md +0 -801
- package/docs/components/radio.md +0 -735
- package/docs/components/scroll-area.md +0 -691
- package/docs/components/search-field.md +0 -702
- package/docs/components/searchable-select.md +0 -368
- package/docs/components/searchable-table.md +0 -438
- package/docs/components/searchable-tree-dialog.md +0 -190
- package/docs/components/searchable-tree.md +0 -200
- package/docs/components/section-block.md +0 -483
- package/docs/components/select.md +0 -709
- package/docs/components/simple-select.md +0 -741
- package/docs/components/skeleton.md +0 -706
- package/docs/components/slide-date-picker.md +0 -837
- package/docs/components/spin-loading.md +0 -696
- package/docs/components/stepper.md +0 -316
- package/docs/components/switch.md +0 -770
- package/docs/components/tab-form-item.md +0 -773
- package/docs/components/tab-switch.md +0 -170
- package/docs/components/table-dnd-wrapper.md +0 -107
- package/docs/components/table.md +0 -1088
- package/docs/components/text-editor.md +0 -735
- package/docs/components/textarea.md +0 -681
- package/docs/components/timeline.md +0 -254
- package/docs/components/toast.md +0 -773
- package/docs/components/toggle-button.md +0 -643
- package/docs/components/toggle.md +0 -882
- package/docs/components/tooltip.md +0 -513
- package/docs/components/transparent-label.md +0 -721
- package/docs/components/tree-drop-down.md +0 -740
- package/docs/components/tree-folder.md +0 -110
- package/docs/components/tree-sub-layout.md +0 -707
- package/docs/explanation/architecture.md +0 -54
- package/docs/explanation/design-system.md +0 -52
- package/docs/how-to/form-and-list-recipes.md +0 -386
- package/docs/how-to/forms-with-form-builder.md +0 -472
- package/docs/how-to/guides.md +0 -1027
- package/docs/migration/changelog.md +0 -60
- package/docs/migration/form-builder-2.5.2.md +0 -113
- package/docs/reference/cli.md +0 -112
- package/docs/reference/components.md +0 -572
- package/docs/reference/hooks.md +0 -1523
- package/docs/reference/providers.md +0 -866
- package/docs/reference/tailwind-plugins.md +0 -942
- package/docs/reference/theme.md +0 -85
- package/docs/reference/types.md +0 -1016
- package/docs/reference/utilities.md +0 -726
- package/docs/tutorials/building-first-form.md +0 -846
- package/docs/tutorials/component-composition.md +0 -882
- package/docs/tutorials/getting-started.md +0 -302
- package/docs/tutorials/theming-basics.md +0 -785
package/docs/components/radio.md
DELETED
|
@@ -1,735 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: Radio
|
|
3
|
-
version: 2.4.5
|
|
4
|
-
status: stable
|
|
5
|
-
category: components/forms
|
|
6
|
-
tags: [form, radio, selection, radix-ui, accessible, group, controlled]
|
|
7
|
-
last-reviewed: 2024-11-05
|
|
8
|
-
bundle-size: 2.0kb
|
|
9
|
-
dependencies:
|
|
10
|
-
- "@radix-ui/react-radio-group": "^1.0.0"
|
|
11
|
-
- "class-variance-authority": "^0.7.0"
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
# Radio
|
|
15
|
-
|
|
16
|
-
> A fully accessible radio button component built on Radix UI primitives. Includes RadioGroup for managing single selection from multiple options with keyboard navigation and ARIA support.
|
|
17
|
-
|
|
18
|
-
## Installation
|
|
19
|
-
|
|
20
|
-
TORCH Glare is a copy-in library: the CLI copies this component's source into your project
|
|
21
|
-
(you do **not** install it from the npm package). Run `init` once, then `add`:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
npx torch-glare@latest init
|
|
25
|
-
npx torch-glare@latest add Radio
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
`add` also copies any components, hooks, and utilities that `Radio` depends on.
|
|
29
|
-
|
|
30
|
-
## Import
|
|
31
|
-
|
|
32
|
-
Import from your project's local path — the alias configured in `glare.json` (e.g. `@/*`):
|
|
33
|
-
|
|
34
|
-
```tsx
|
|
35
|
-
import { Radio } from "@/components/Radio";
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Quick Examples
|
|
39
|
-
|
|
40
|
-
### Basic Radio Group
|
|
41
|
-
|
|
42
|
-
```typescript
|
|
43
|
-
import { Radio, RadioGroup } from '@/components/Radio'
|
|
44
|
-
|
|
45
|
-
function Example() {
|
|
46
|
-
const [value, setValue] = useState('option1')
|
|
47
|
-
|
|
48
|
-
return (
|
|
49
|
-
<RadioGroup value={value} onValueChange={setValue}>
|
|
50
|
-
<div className="flex items-center space-x-2">
|
|
51
|
-
<Radio value="option1" id="r1" />
|
|
52
|
-
<label htmlFor="r1">Option 1</label>
|
|
53
|
-
</div>
|
|
54
|
-
<div className="flex items-center space-x-2">
|
|
55
|
-
<Radio value="option2" id="r2" />
|
|
56
|
-
<label htmlFor="r2">Option 2</label>
|
|
57
|
-
</div>
|
|
58
|
-
<div className="flex items-center space-x-2">
|
|
59
|
-
<Radio value="option3" id="r3" />
|
|
60
|
-
<label htmlFor="r3">Option 3</label>
|
|
61
|
-
</div>
|
|
62
|
-
</RadioGroup>
|
|
63
|
-
)
|
|
64
|
-
}
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### Different Sizes
|
|
68
|
-
|
|
69
|
-
```typescript
|
|
70
|
-
function SizeVariants() {
|
|
71
|
-
const [selected, setSelected] = useState('medium')
|
|
72
|
-
|
|
73
|
-
return (
|
|
74
|
-
<div className="space-y-4">
|
|
75
|
-
<RadioGroup value={selected} onValueChange={setSelected}>
|
|
76
|
-
<div className="flex items-center space-x-2">
|
|
77
|
-
<Radio value="small" id="size-s" size="S" />
|
|
78
|
-
<label htmlFor="size-s" className="text-sm">Small radio</label>
|
|
79
|
-
</div>
|
|
80
|
-
|
|
81
|
-
<div className="flex items-center space-x-2">
|
|
82
|
-
<Radio value="medium" id="size-m" size="M" />
|
|
83
|
-
<label htmlFor="size-m">Medium radio (default)</label>
|
|
84
|
-
</div>
|
|
85
|
-
</RadioGroup>
|
|
86
|
-
</div>
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Horizontal Layout
|
|
92
|
-
|
|
93
|
-
```typescript
|
|
94
|
-
function HorizontalRadioGroup() {
|
|
95
|
-
const [plan, setPlan] = useState('basic')
|
|
96
|
-
|
|
97
|
-
return (
|
|
98
|
-
<RadioGroup
|
|
99
|
-
value={plan}
|
|
100
|
-
onValueChange={setPlan}
|
|
101
|
-
className="flex flex-row space-x-4"
|
|
102
|
-
>
|
|
103
|
-
<div className="flex items-center space-x-2">
|
|
104
|
-
<Radio value="basic" id="plan-basic" />
|
|
105
|
-
<label htmlFor="plan-basic">Basic</label>
|
|
106
|
-
</div>
|
|
107
|
-
|
|
108
|
-
<div className="flex items-center space-x-2">
|
|
109
|
-
<Radio value="pro" id="plan-pro" />
|
|
110
|
-
<label htmlFor="plan-pro">Pro</label>
|
|
111
|
-
</div>
|
|
112
|
-
|
|
113
|
-
<div className="flex items-center space-x-2">
|
|
114
|
-
<Radio value="enterprise" id="plan-enterprise" />
|
|
115
|
-
<label htmlFor="plan-enterprise">Enterprise</label>
|
|
116
|
-
</div>
|
|
117
|
-
</RadioGroup>
|
|
118
|
-
)
|
|
119
|
-
}
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### With Descriptions
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
function RadioWithDescriptions() {
|
|
126
|
-
const [delivery, setDelivery] = useState('standard')
|
|
127
|
-
|
|
128
|
-
const options = [
|
|
129
|
-
{
|
|
130
|
-
value: 'standard',
|
|
131
|
-
label: 'Standard Delivery',
|
|
132
|
-
description: '5-7 business days',
|
|
133
|
-
price: 'Free'
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
value: 'express',
|
|
137
|
-
label: 'Express Delivery',
|
|
138
|
-
description: '2-3 business days',
|
|
139
|
-
price: '$9.99'
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
value: 'overnight',
|
|
143
|
-
label: 'Overnight Delivery',
|
|
144
|
-
description: 'Next business day',
|
|
145
|
-
price: '$24.99'
|
|
146
|
-
}
|
|
147
|
-
]
|
|
148
|
-
|
|
149
|
-
return (
|
|
150
|
-
<RadioGroup value={delivery} onValueChange={setDelivery}>
|
|
151
|
-
{options.map((option) => (
|
|
152
|
-
<div
|
|
153
|
-
key={option.value}
|
|
154
|
-
className="flex items-start space-x-3 p-3 border rounded-lg hover:bg-gray-50"
|
|
155
|
-
>
|
|
156
|
-
<Radio value={option.value} id={option.value} />
|
|
157
|
-
<label htmlFor={option.value} className="flex-1 cursor-pointer">
|
|
158
|
-
<div className="font-medium">{option.label}</div>
|
|
159
|
-
<div className="text-sm text-gray-500">{option.description}</div>
|
|
160
|
-
<div className="text-sm font-semibold">{option.price}</div>
|
|
161
|
-
</label>
|
|
162
|
-
</div>
|
|
163
|
-
))}
|
|
164
|
-
</RadioGroup>
|
|
165
|
-
)
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Disabled Options
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
function RadioWithDisabled() {
|
|
173
|
-
const [selected, setSelected] = useState('active')
|
|
174
|
-
|
|
175
|
-
return (
|
|
176
|
-
<RadioGroup value={selected} onValueChange={setSelected}>
|
|
177
|
-
<div className="flex items-center space-x-2">
|
|
178
|
-
<Radio value="active" id="active" />
|
|
179
|
-
<label htmlFor="active">Active Option</label>
|
|
180
|
-
</div>
|
|
181
|
-
|
|
182
|
-
<div className="flex items-center space-x-2 opacity-50">
|
|
183
|
-
<Radio value="disabled" id="disabled" disabled />
|
|
184
|
-
<label htmlFor="disabled">Disabled Option</label>
|
|
185
|
-
</div>
|
|
186
|
-
|
|
187
|
-
<div className="flex items-center space-x-2">
|
|
188
|
-
<Radio value="another" id="another" />
|
|
189
|
-
<label htmlFor="another">Another Option</label>
|
|
190
|
-
</div>
|
|
191
|
-
</RadioGroup>
|
|
192
|
-
)
|
|
193
|
-
}
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### Form Integration
|
|
197
|
-
|
|
198
|
-
```typescript
|
|
199
|
-
function PaymentMethodForm() {
|
|
200
|
-
const [paymentMethod, setPaymentMethod] = useState('card')
|
|
201
|
-
|
|
202
|
-
const handleSubmit = (e: FormEvent) => {
|
|
203
|
-
e.preventDefault()
|
|
204
|
-
console.log('Selected payment method:', paymentMethod)
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
return (
|
|
208
|
-
<form onSubmit={handleSubmit} className="space-y-4">
|
|
209
|
-
<fieldset>
|
|
210
|
-
<legend className="text-lg font-semibold mb-3">Payment Method</legend>
|
|
211
|
-
<RadioGroup value={paymentMethod} onValueChange={setPaymentMethod}>
|
|
212
|
-
<div className="space-y-2">
|
|
213
|
-
<div className="flex items-center space-x-2">
|
|
214
|
-
<Radio value="card" id="payment-card" />
|
|
215
|
-
<label htmlFor="payment-card">Credit/Debit Card</label>
|
|
216
|
-
</div>
|
|
217
|
-
|
|
218
|
-
<div className="flex items-center space-x-2">
|
|
219
|
-
<Radio value="paypal" id="payment-paypal" />
|
|
220
|
-
<label htmlFor="payment-paypal">PayPal</label>
|
|
221
|
-
</div>
|
|
222
|
-
|
|
223
|
-
<div className="flex items-center space-x-2">
|
|
224
|
-
<Radio value="bank" id="payment-bank" />
|
|
225
|
-
<label htmlFor="payment-bank">Bank Transfer</label>
|
|
226
|
-
</div>
|
|
227
|
-
</div>
|
|
228
|
-
</RadioGroup>
|
|
229
|
-
</fieldset>
|
|
230
|
-
|
|
231
|
-
<button type="submit">Continue to Payment</button>
|
|
232
|
-
</form>
|
|
233
|
-
)
|
|
234
|
-
}
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
## API Reference
|
|
238
|
-
|
|
239
|
-
### RadioGroup Props
|
|
240
|
-
|
|
241
|
-
| Prop | Type | Default | Description |
|
|
242
|
-
|------|------|---------|-------------|
|
|
243
|
-
| `value` | `string` | - | Controlled selected value |
|
|
244
|
-
| `defaultValue` | `string` | - | Uncontrolled default value |
|
|
245
|
-
| `onValueChange` | `(value: string) => void` | - | Called when selection changes |
|
|
246
|
-
| `disabled` | `boolean` | `false` | Disables all radios in group |
|
|
247
|
-
| `required` | `boolean` | `false` | Makes selection required |
|
|
248
|
-
| `name` | `string` | - | Form field name |
|
|
249
|
-
| `orientation` | `'horizontal' \| 'vertical'` | `'vertical'` | Layout orientation |
|
|
250
|
-
| `className` | `string` | - | Additional CSS classes |
|
|
251
|
-
|
|
252
|
-
### Radio Props
|
|
253
|
-
|
|
254
|
-
| Prop | Type | Default | Description |
|
|
255
|
-
|------|------|---------|-------------|
|
|
256
|
-
| `value` | `string` | - | Radio button value |
|
|
257
|
-
| `size` | `'S' \| 'M'` | `'S'` | Size variant |
|
|
258
|
-
| `id` | `string` | - | HTML id for label association |
|
|
259
|
-
| `disabled` | `boolean` | `false` | Disables this radio |
|
|
260
|
-
| `className` | `string` | - | Additional CSS classes |
|
|
261
|
-
|
|
262
|
-
### TypeScript
|
|
263
|
-
|
|
264
|
-
```typescript
|
|
265
|
-
import { RadioGroupProps, RadioGroupItemProps } from '@radix-ui/react-radio-group'
|
|
266
|
-
|
|
267
|
-
// RadioGroup types
|
|
268
|
-
interface RadioGroupProps extends RadioGroupPrimitive.RootProps {
|
|
269
|
-
className?: string
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Radio types
|
|
273
|
-
interface RadioProps extends RadioGroupItemProps {
|
|
274
|
-
size?: 'S' | 'M'
|
|
275
|
-
className?: string
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
export const RadioGroup: React.ForwardRefExoticComponent<RadioGroupProps>
|
|
279
|
-
export const Radio: React.ForwardRefExoticComponent<RadioProps>
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
## Common Patterns
|
|
283
|
-
|
|
284
|
-
### Settings Panel
|
|
285
|
-
|
|
286
|
-
```typescript
|
|
287
|
-
function ThemeSettings() {
|
|
288
|
-
const [theme, setTheme] = useState('auto')
|
|
289
|
-
const [accent, setAccent] = useState('blue')
|
|
290
|
-
|
|
291
|
-
return (
|
|
292
|
-
<div className="space-y-6">
|
|
293
|
-
<div>
|
|
294
|
-
<h3 className="font-semibold mb-3">Theme</h3>
|
|
295
|
-
<RadioGroup value={theme} onValueChange={setTheme}>
|
|
296
|
-
<div className="space-y-2">
|
|
297
|
-
<label className="flex items-center space-x-2">
|
|
298
|
-
<Radio value="light" id="theme-light" />
|
|
299
|
-
<span>Light</span>
|
|
300
|
-
</label>
|
|
301
|
-
|
|
302
|
-
<label className="flex items-center space-x-2">
|
|
303
|
-
<Radio value="dark" id="theme-dark" />
|
|
304
|
-
<span>Dark</span>
|
|
305
|
-
</label>
|
|
306
|
-
|
|
307
|
-
<label className="flex items-center space-x-2">
|
|
308
|
-
<Radio value="auto" id="theme-auto" />
|
|
309
|
-
<span>System</span>
|
|
310
|
-
</label>
|
|
311
|
-
</div>
|
|
312
|
-
</RadioGroup>
|
|
313
|
-
</div>
|
|
314
|
-
|
|
315
|
-
<div>
|
|
316
|
-
<h3 className="font-semibold mb-3">Accent Color</h3>
|
|
317
|
-
<RadioGroup value={accent} onValueChange={setAccent} orientation="horizontal">
|
|
318
|
-
<div className="flex space-x-4">
|
|
319
|
-
<label className="flex items-center space-x-2">
|
|
320
|
-
<Radio value="blue" id="accent-blue" />
|
|
321
|
-
<span className="text-blue-600">Blue</span>
|
|
322
|
-
</label>
|
|
323
|
-
|
|
324
|
-
<label className="flex items-center space-x-2">
|
|
325
|
-
<Radio value="green" id="accent-green" />
|
|
326
|
-
<span className="text-green-600">Green</span>
|
|
327
|
-
</label>
|
|
328
|
-
|
|
329
|
-
<label className="flex items-center space-x-2">
|
|
330
|
-
<Radio value="purple" id="accent-purple" />
|
|
331
|
-
<span className="text-purple-600">Purple</span>
|
|
332
|
-
</label>
|
|
333
|
-
</div>
|
|
334
|
-
</RadioGroup>
|
|
335
|
-
</div>
|
|
336
|
-
</div>
|
|
337
|
-
)
|
|
338
|
-
}
|
|
339
|
-
```
|
|
340
|
-
|
|
341
|
-
### Survey Question
|
|
342
|
-
|
|
343
|
-
```typescript
|
|
344
|
-
function SurveyQuestion() {
|
|
345
|
-
const [satisfaction, setSatisfaction] = useState('')
|
|
346
|
-
const [comment, setComment] = useState('')
|
|
347
|
-
|
|
348
|
-
const levels = [
|
|
349
|
-
{ value: '5', label: 'Very Satisfied', emoji: '😊' },
|
|
350
|
-
{ value: '4', label: 'Satisfied', emoji: '🙂' },
|
|
351
|
-
{ value: '3', label: 'Neutral', emoji: '😐' },
|
|
352
|
-
{ value: '2', label: 'Dissatisfied', emoji: '😕' },
|
|
353
|
-
{ value: '1', label: 'Very Dissatisfied', emoji: '😞' }
|
|
354
|
-
]
|
|
355
|
-
|
|
356
|
-
return (
|
|
357
|
-
<div className="space-y-4">
|
|
358
|
-
<h3>How satisfied are you with our service?</h3>
|
|
359
|
-
|
|
360
|
-
<RadioGroup value={satisfaction} onValueChange={setSatisfaction}>
|
|
361
|
-
{levels.map((level) => (
|
|
362
|
-
<label
|
|
363
|
-
key={level.value}
|
|
364
|
-
className="flex items-center space-x-3 p-2 rounded hover:bg-gray-50"
|
|
365
|
-
>
|
|
366
|
-
<Radio value={level.value} id={`level-${level.value}`} />
|
|
367
|
-
<span className="text-2xl">{level.emoji}</span>
|
|
368
|
-
<span>{level.label}</span>
|
|
369
|
-
</label>
|
|
370
|
-
))}
|
|
371
|
-
</RadioGroup>
|
|
372
|
-
|
|
373
|
-
{satisfaction && satisfaction <= '2' && (
|
|
374
|
-
<textarea
|
|
375
|
-
placeholder="Please tell us how we can improve..."
|
|
376
|
-
value={comment}
|
|
377
|
-
onChange={(e) => setComment(e.target.value)}
|
|
378
|
-
className="w-full p-2 border rounded"
|
|
379
|
-
rows={3}
|
|
380
|
-
/>
|
|
381
|
-
)}
|
|
382
|
-
</div>
|
|
383
|
-
)
|
|
384
|
-
}
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
### Conditional Fields
|
|
388
|
-
|
|
389
|
-
```typescript
|
|
390
|
-
function ConditionalForm() {
|
|
391
|
-
const [contactMethod, setContactMethod] = useState('email')
|
|
392
|
-
|
|
393
|
-
return (
|
|
394
|
-
<form className="space-y-4">
|
|
395
|
-
<fieldset>
|
|
396
|
-
<legend className="font-semibold mb-2">Preferred Contact Method</legend>
|
|
397
|
-
<RadioGroup value={contactMethod} onValueChange={setContactMethod}>
|
|
398
|
-
<div className="space-y-2">
|
|
399
|
-
<label className="flex items-center space-x-2">
|
|
400
|
-
<Radio value="email" id="contact-email" />
|
|
401
|
-
<span>Email</span>
|
|
402
|
-
</label>
|
|
403
|
-
|
|
404
|
-
<label className="flex items-center space-x-2">
|
|
405
|
-
<Radio value="phone" id="contact-phone" />
|
|
406
|
-
<span>Phone</span>
|
|
407
|
-
</label>
|
|
408
|
-
|
|
409
|
-
<label className="flex items-center space-x-2">
|
|
410
|
-
<Radio value="mail" id="contact-mail" />
|
|
411
|
-
<span>Postal Mail</span>
|
|
412
|
-
</label>
|
|
413
|
-
</div>
|
|
414
|
-
</RadioGroup>
|
|
415
|
-
</fieldset>
|
|
416
|
-
|
|
417
|
-
{contactMethod === 'email' && (
|
|
418
|
-
<input
|
|
419
|
-
type="email"
|
|
420
|
-
placeholder="Enter your email address"
|
|
421
|
-
className="w-full p-2 border rounded"
|
|
422
|
-
/>
|
|
423
|
-
)}
|
|
424
|
-
|
|
425
|
-
{contactMethod === 'phone' && (
|
|
426
|
-
<input
|
|
427
|
-
type="tel"
|
|
428
|
-
placeholder="Enter your phone number"
|
|
429
|
-
className="w-full p-2 border rounded"
|
|
430
|
-
/>
|
|
431
|
-
)}
|
|
432
|
-
|
|
433
|
-
{contactMethod === 'mail' && (
|
|
434
|
-
<textarea
|
|
435
|
-
placeholder="Enter your mailing address"
|
|
436
|
-
className="w-full p-2 border rounded"
|
|
437
|
-
rows={3}
|
|
438
|
-
/>
|
|
439
|
-
)}
|
|
440
|
-
|
|
441
|
-
<button type="submit">Save Preference</button>
|
|
442
|
-
</form>
|
|
443
|
-
)
|
|
444
|
-
}
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
## Testing
|
|
448
|
-
|
|
449
|
-
### Unit Test Example
|
|
450
|
-
|
|
451
|
-
```typescript
|
|
452
|
-
import { render, screen, fireEvent } from '@testing-library/react'
|
|
453
|
-
import { Radio, RadioGroup } from '@/components/Radio'
|
|
454
|
-
|
|
455
|
-
describe('Radio', () => {
|
|
456
|
-
it('handles selection changes', () => {
|
|
457
|
-
const handleChange = jest.fn()
|
|
458
|
-
render(
|
|
459
|
-
<RadioGroup onValueChange={handleChange}>
|
|
460
|
-
<Radio value="opt1" id="opt1" />
|
|
461
|
-
<Radio value="opt2" id="opt2" />
|
|
462
|
-
</RadioGroup>
|
|
463
|
-
)
|
|
464
|
-
|
|
465
|
-
const radio2 = screen.getByRole('radio', { name: /opt2/i })
|
|
466
|
-
fireEvent.click(radio2)
|
|
467
|
-
|
|
468
|
-
expect(handleChange).toHaveBeenCalledWith('opt2')
|
|
469
|
-
})
|
|
470
|
-
|
|
471
|
-
it('respects disabled state', () => {
|
|
472
|
-
render(
|
|
473
|
-
<RadioGroup>
|
|
474
|
-
<Radio value="enabled" id="enabled" />
|
|
475
|
-
<Radio value="disabled" id="disabled" disabled />
|
|
476
|
-
</RadioGroup>
|
|
477
|
-
)
|
|
478
|
-
|
|
479
|
-
const disabledRadio = screen.getByRole('radio', { name: /disabled/i })
|
|
480
|
-
expect(disabledRadio).toBeDisabled()
|
|
481
|
-
})
|
|
482
|
-
|
|
483
|
-
it('maintains single selection', () => {
|
|
484
|
-
const { rerender } = render(
|
|
485
|
-
<RadioGroup value="opt1">
|
|
486
|
-
<Radio value="opt1" id="opt1" />
|
|
487
|
-
<Radio value="opt2" id="opt2" />
|
|
488
|
-
</RadioGroup>
|
|
489
|
-
)
|
|
490
|
-
|
|
491
|
-
let radio1 = screen.getByRole('radio', { name: /opt1/i })
|
|
492
|
-
let radio2 = screen.getByRole('radio', { name: /opt2/i })
|
|
493
|
-
|
|
494
|
-
expect(radio1).toBeChecked()
|
|
495
|
-
expect(radio2).not.toBeChecked()
|
|
496
|
-
|
|
497
|
-
rerender(
|
|
498
|
-
<RadioGroup value="opt2">
|
|
499
|
-
<Radio value="opt1" id="opt1" />
|
|
500
|
-
<Radio value="opt2" id="opt2" />
|
|
501
|
-
</RadioGroup>
|
|
502
|
-
)
|
|
503
|
-
|
|
504
|
-
radio1 = screen.getByRole('radio', { name: /opt1/i })
|
|
505
|
-
radio2 = screen.getByRole('radio', { name: /opt2/i })
|
|
506
|
-
|
|
507
|
-
expect(radio1).not.toBeChecked()
|
|
508
|
-
expect(radio2).toBeChecked()
|
|
509
|
-
})
|
|
510
|
-
})
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
### Accessibility Test
|
|
514
|
-
|
|
515
|
-
```typescript
|
|
516
|
-
import { axe } from '@axe-core/react'
|
|
517
|
-
|
|
518
|
-
test('RadioGroup meets WCAG standards', async () => {
|
|
519
|
-
const { container } = render(
|
|
520
|
-
<fieldset>
|
|
521
|
-
<legend>Select an option</legend>
|
|
522
|
-
<RadioGroup defaultValue="opt1">
|
|
523
|
-
<div>
|
|
524
|
-
<Radio value="opt1" id="opt1" />
|
|
525
|
-
<label htmlFor="opt1">Option 1</label>
|
|
526
|
-
</div>
|
|
527
|
-
<div>
|
|
528
|
-
<Radio value="opt2" id="opt2" />
|
|
529
|
-
<label htmlFor="opt2">Option 2</label>
|
|
530
|
-
</div>
|
|
531
|
-
</RadioGroup>
|
|
532
|
-
</fieldset>
|
|
533
|
-
)
|
|
534
|
-
|
|
535
|
-
const results = await axe(container)
|
|
536
|
-
expect(results).toHaveNoViolations()
|
|
537
|
-
})
|
|
538
|
-
```
|
|
539
|
-
|
|
540
|
-
## Accessibility
|
|
541
|
-
|
|
542
|
-
### Keyboard Support
|
|
543
|
-
|
|
544
|
-
- **Tab**: Move focus into radio group
|
|
545
|
-
- **Arrow Down/Right**: Select next radio
|
|
546
|
-
- **Arrow Up/Left**: Select previous radio
|
|
547
|
-
- **Space**: Select focused radio (if not already selected)
|
|
548
|
-
|
|
549
|
-
### ARIA Attributes
|
|
550
|
-
|
|
551
|
-
Radix UI automatically handles:
|
|
552
|
-
|
|
553
|
-
```html
|
|
554
|
-
<!-- Radio group -->
|
|
555
|
-
<div role="radiogroup" aria-required="false" aria-orientation="vertical">
|
|
556
|
-
<!-- Radio buttons -->
|
|
557
|
-
<button role="radio" aria-checked="true" data-state="checked" />
|
|
558
|
-
<button role="radio" aria-checked="false" data-state="unchecked" />
|
|
559
|
-
</div>
|
|
560
|
-
```
|
|
561
|
-
|
|
562
|
-
### Screen Reader Support
|
|
563
|
-
|
|
564
|
-
- Announces radio group role
|
|
565
|
-
- Communicates selected state
|
|
566
|
-
- Reads associated labels
|
|
567
|
-
- Announces total options and position
|
|
568
|
-
|
|
569
|
-
### Best Practices
|
|
570
|
-
|
|
571
|
-
```typescript
|
|
572
|
-
// Always use fieldset/legend for semantic grouping
|
|
573
|
-
<fieldset>
|
|
574
|
-
<legend>Choose your plan</legend>
|
|
575
|
-
<RadioGroup>
|
|
576
|
-
{/* Radio options */}
|
|
577
|
-
</RadioGroup>
|
|
578
|
-
</fieldset>
|
|
579
|
-
|
|
580
|
-
// Always associate labels
|
|
581
|
-
<Radio value="option" id="radio-id" />
|
|
582
|
-
<label htmlFor="radio-id">Option Label</label>
|
|
583
|
-
```
|
|
584
|
-
|
|
585
|
-
## Styling
|
|
586
|
-
|
|
587
|
-
### Custom Styles
|
|
588
|
-
|
|
589
|
-
```typescript
|
|
590
|
-
<Radio
|
|
591
|
-
className="border-blue-500 data-[state=checked]:border-blue-600"
|
|
592
|
-
size="M"
|
|
593
|
-
/>
|
|
594
|
-
|
|
595
|
-
<RadioGroup className="space-y-3 p-4 border rounded">
|
|
596
|
-
{/* Radio options */}
|
|
597
|
-
</RadioGroup>
|
|
598
|
-
```
|
|
599
|
-
|
|
600
|
-
### CSS Variables
|
|
601
|
-
|
|
602
|
-
```css
|
|
603
|
-
/* Custom theme variables */
|
|
604
|
-
:root {
|
|
605
|
-
--radio-size-small: 12px;
|
|
606
|
-
--radio-size-medium: 24px;
|
|
607
|
-
--radio-border: #d1d5db;
|
|
608
|
-
--radio-border-hover: #3b82f6;
|
|
609
|
-
--radio-indicator: #3b82f6;
|
|
610
|
-
--radio-disabled: #f3f4f6;
|
|
611
|
-
}
|
|
612
|
-
```
|
|
613
|
-
|
|
614
|
-
### State Styling
|
|
615
|
-
|
|
616
|
-
```css
|
|
617
|
-
/* Using data attributes from Radix UI */
|
|
618
|
-
.radio[data-state="checked"] {
|
|
619
|
-
border-color: var(--primary);
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
.radio[data-disabled] {
|
|
623
|
-
opacity: 0.5;
|
|
624
|
-
cursor: not-allowed;
|
|
625
|
-
}
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
## Performance
|
|
629
|
-
|
|
630
|
-
| Metric | Value |
|
|
631
|
-
|--------|-------|
|
|
632
|
-
| Bundle size (gzip) | 2.0kb |
|
|
633
|
-
| First render | <6ms |
|
|
634
|
-
| Re-render | <2ms |
|
|
635
|
-
| Interaction | <1ms |
|
|
636
|
-
| Tree-shakeable | ✅ |
|
|
637
|
-
|
|
638
|
-
### Optimization Tips
|
|
639
|
-
|
|
640
|
-
1. Use uncontrolled mode with `defaultValue` when possible
|
|
641
|
-
2. Memoize change handlers with `useCallback`
|
|
642
|
-
3. Use React.memo for radio option components
|
|
643
|
-
4. Keep RadioGroup flat, avoid deep nesting
|
|
644
|
-
|
|
645
|
-
## Migration
|
|
646
|
-
|
|
647
|
-
### From Native Radio
|
|
648
|
-
|
|
649
|
-
```diff
|
|
650
|
-
// From HTML radios
|
|
651
|
-
- <input
|
|
652
|
-
- type="radio"
|
|
653
|
-
- name="group"
|
|
654
|
-
- value="option"
|
|
655
|
-
- checked={selected === 'option'}
|
|
656
|
-
- onChange={(e) => setSelected(e.target.value)}
|
|
657
|
-
- />
|
|
658
|
-
|
|
659
|
-
// To Radio component
|
|
660
|
-
+ <RadioGroup value={selected} onValueChange={setSelected}>
|
|
661
|
-
+ <Radio value="option" id="option" />
|
|
662
|
-
+ </RadioGroup>
|
|
663
|
-
```
|
|
664
|
-
|
|
665
|
-
### From v1.0.x
|
|
666
|
-
|
|
667
|
-
```diff
|
|
668
|
-
// Import path
|
|
669
|
-
- import Radio from 'torch-glare/Radio'
|
|
670
|
-
+ import { Radio, RadioGroup } from '@/components/Radio'
|
|
671
|
-
|
|
672
|
-
// Size prop values
|
|
673
|
-
- <Radio size="M" />
|
|
674
|
-
+ <Radio size="S" />
|
|
675
|
-
```
|
|
676
|
-
|
|
677
|
-
## Troubleshooting
|
|
678
|
-
|
|
679
|
-
### Radios not grouping
|
|
680
|
-
|
|
681
|
-
**Solution:** Ensure all radios are within RadioGroup
|
|
682
|
-
|
|
683
|
-
```typescript
|
|
684
|
-
// ❌ Wrong - radios not grouped
|
|
685
|
-
<Radio value="opt1" />
|
|
686
|
-
<Radio value="opt2" />
|
|
687
|
-
|
|
688
|
-
// ✅ Correct - proper grouping
|
|
689
|
-
<RadioGroup>
|
|
690
|
-
<Radio value="opt1" />
|
|
691
|
-
<Radio value="opt2" />
|
|
692
|
-
</RadioGroup>
|
|
693
|
-
```
|
|
694
|
-
|
|
695
|
-
### Selection not working
|
|
696
|
-
|
|
697
|
-
**Solution:** Use controlled or uncontrolled mode properly
|
|
698
|
-
|
|
699
|
-
```typescript
|
|
700
|
-
// Controlled
|
|
701
|
-
const [value, setValue] = useState('default')
|
|
702
|
-
<RadioGroup value={value} onValueChange={setValue}>
|
|
703
|
-
|
|
704
|
-
// Uncontrolled
|
|
705
|
-
<RadioGroup defaultValue="default">
|
|
706
|
-
```
|
|
707
|
-
|
|
708
|
-
## Related Components
|
|
709
|
-
|
|
710
|
-
- [LabeledRadio](/docs/components/labeled-radio.md) - Radio with integrated label
|
|
711
|
-
- [RadioCard](/docs/components/radio-card.md) - Card-style radio option
|
|
712
|
-
- [Checkbox](/docs/components/checkbox.md) - Multiple selection option
|
|
713
|
-
- [Select](/docs/components/select.md) - Dropdown alternative
|
|
714
|
-
|
|
715
|
-
## Browser Support
|
|
716
|
-
|
|
717
|
-
- Chrome 90+ ✅
|
|
718
|
-
- Firefox 88+ ✅
|
|
719
|
-
- Safari 14+ ✅
|
|
720
|
-
- Edge 90+ ✅
|
|
721
|
-
- Mobile browsers ✅
|
|
722
|
-
|
|
723
|
-
## Changelog
|
|
724
|
-
|
|
725
|
-
### v1.1.15
|
|
726
|
-
- Migrated to Radix UI primitives
|
|
727
|
-
- Added size variants
|
|
728
|
-
- Improved accessibility
|
|
729
|
-
|
|
730
|
-
### v1.1.14
|
|
731
|
-
- Fixed focus styles
|
|
732
|
-
- Performance optimizations
|
|
733
|
-
|
|
734
|
-
### v1.1.0
|
|
735
|
-
- Initial stable release
|