Radio
radio从一组互斥选项里选一个,支持方向键操作
用法
基础用法
RadioGroup 包裹多个 Radio,单选互斥,默认纵向排列。
tsx
<RadioGroup defaultValue="b" aria-label="选项">
<Radio value="a" label="选项一" />
<Radio value="b" label="选项二" />
<Radio value="c" label="选项三" />
</RadioGroup>横向排列
设置 orientation="horizontal" 让选项横向排布。
tsx
<RadioGroup orientation="horizontal" defaultValue="m" aria-label="性别">
<Radio value="m" label="男" />
<Radio value="f" label="女" />
</RadioGroup>禁用
单个 Radio 加 disabled 禁用某项;整组 disabled 禁用全部。
tsx
<RadioGroup defaultValue="a" aria-label="套餐">
<Radio value="a" label="标准" />
<Radio value="b" label="专业(暂不可选)" disabled />
<Radio value="c" label="旗舰" />
</RadioGroup>搭配 Field 校验
包进 Field 获得标签与错误提示,校验态会传导到圈描边。
请选择一个套餐
tsx
<Field label="套餐" error="请选择一个套餐" className="w-72">
<RadioGroup defaultValue="">
<Radio value="basic" label="基础版" />
<Radio value="plus" label="增强版" />
</RadioGroup>
</Field>何时用
一组互斥选项里选且只选一个、且选项数少(约 2-6 个)需全部直接可见时用。选项多需收起或搜索改用 Select;多选共存改用 CheckboxGroup;横向二三段且要滑块视觉用 Segmented。
导入
ts
import { RadioGroup, Radio } from "@hulianui/ui"Props
RadioGroup
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| value | string | - | 受控选中值 |
| defaultValue | string | - | 非受控初始选中值 |
| disabled | boolean | false | 整组禁用 |
| required | boolean | - | 表单必选 |
| name | string | - | 原生表单 name |
| orientation | "vertical"|"horizontal" | "vertical" | 仅控布局 |
| className | string | - | - |
| aria-label | string | - | 无可见标题时提供 |
Radio
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| value * | string | - | 必填,标识该选项 |
| disabled | boolean | false | 单项禁用 |
| id | string | - | - |
| size | "sm" | "md" | "md" | 尺寸档,圈与内点一起缩放。md = 20px/10px/text-sm,sm = 16px/8px/text-xs |
| className | string | - | 落在 Radio.Root(圈),够不到文字 |
| labelClassName | string | - | 落在文字 <span>,用来改字号 / 颜色 |
| aria-label | string | - | 无障碍名。不给 `label`、或 `label` 是图标/纯视觉内容时必须给 |
| aria-labelledby | string | - | 用页面上已有元素充当名字(填其 id),与 aria-label 二选一 |
| aria-describedby | string | - | 补充描述(填元素 id),如该选项的说明文字 |
Events
RadioGroup
| 事件 | 类型 | 说明 |
|---|---|---|
| onValueChange | (value: string) => void | 选中变化回调 |
Slots
RadioGroup
| 插槽 | 类型 | 说明 |
|---|---|---|
| children | ReactNode | 内放 Radio 项 |
Radio
| 插槽 | 类型 | 说明 |
|---|---|---|
| label | ReactNode | 可选 inline label(点右,原生 <label> 关联) |
| children | ReactNode | 与 label 等价的写法:<Radio value="1">审核通过</Radio>。两者同时给时 label 优先 |
禁忌 / 坑
- 选中值统一由
RadioGroup管,Radio不自带选中态——别在Radio上找checked。 - 用
value/onValueChange即受控,须自管 state;只给初值用defaultValue,二者不要混用。 - 无可见标题的单选组要给
aria-label,否则无障碍读屏无名。 - 不给 `label` 的 `Radio`(图标卡片、自定义排版)必须自带 `aria-label` 或 `aria-labelledby`,否则读屏只报「单选按钮」,用户不知道自己在选哪一项——这不只是测试不好写,是真实的可访问性缺陷。
label传的是图标之类的非文本ReactNode时同理。 - 自己写
<label>把 Radio 包起来是成立的,不用手写onClick转发:Root 渲染出来是<span role="radio">(不是可被 label 关联的元素),看 DOM 容易以为隐式关联不生效,但 Base UI 在里面留了一个视觉隐藏的原生 input 承载激活。排版特殊到size+labelClassName也收不住时就这么用。 - 但别在包裹的同时再给
<label htmlFor>指向 Root 的id:显式htmlFor会压过隐式关联,两者并存的结果是点文字彻底没反应。 - 放进
Field时每个Radio由自己的label命名,Field的标签命名的是整个RadioGroup(role=radiogroup),description / error 仍到达每一项。
相关
Input · Textarea · Select · Checkbox · CheckboxGroup · Switch
Playground
<RadioGroup orientation="vertical" defaultValue="standard">
<Radio value="standard" label="标准" />
<Radio value="pro" label="专业" />
</RadioGroup>