# RadioGroup 单选框组 · HeroUI

> 用于从列表中选择单个选项的单选组。

- 页面: https://jiguang132.com/zh/systems/heroui/docs/components/radio-group
- 改编自: HeroUI 文档 (Apache-2.0) @ 60edd8ed751b1d2a270623fbb182bbcfa8baa9af

## 引入

```tsx
import { RadioGroup, Radio } from '@heroui/react';
```

### 用法


> 示例 `radio-group-basic`: 交互预览见 https://jiguang132.com/zh/systems/heroui/docs/components/radio-group


### 组件结构

导入 RadioGroup 组件后，可通过点号访问各个子部分。

```tsx
import {RadioGroup, Radio, Label, Description, FieldError} from '@heroui/react';

export default () => (
  <RadioGroup>
    <Label />
    <Description />
    <Radio value="option1">
      <Radio.Content> {/* 可点击区域：control + label */}
        <Radio.Control>
          <Radio.Indicator>
            <span>✓</span> {/* Custom indicator (optional) */}
          </Radio.Indicator>
        </Radio.Control>
        Label {/* 纯文本 —— 可点击的标签 */}
      </Radio.Content>
      <Description /> {/* 兄弟节点 — 位于按钮外部（通过 aria-describedby 关联） */}
      <FieldError /> {/* 可选 — 单选项校验错误信息 */}
    </Radio>
    <FieldError /> {/* 可选 — 组级校验 */}
  </RadioGroup>
)
```

### 自定义指示器


> 示例 `radio-group-custom-indicator`: 交互预览见 https://jiguang132.com/zh/systems/heroui/docs/components/radio-group


### 水平排列


> 示例 `radio-group-horizontal`: 交互预览见 https://jiguang132.com/zh/systems/heroui/docs/components/radio-group


### 受控


> 示例 `radio-group-controlled`: 交互预览见 https://jiguang132.com/zh/systems/heroui/docs/components/radio-group


### 非受控

当你只需要响应更新时，可组合使用 `defaultValue` 与 `onChange`。


> 示例 `radio-group-uncontrolled`: 交互预览见 https://jiguang132.com/zh/systems/heroui/docs/components/radio-group


### 校验


> 示例 `radio-group-validation`: 交互预览见 https://jiguang132.com/zh/systems/heroui/docs/components/radio-group


### 禁用


> 示例 `radio-group-disabled`: 交互预览见 https://jiguang132.com/zh/systems/heroui/docs/components/radio-group


### 变体

RadioGroup 支持两种视觉变体：

- **`primary`**（默认）— 带默认背景的标准样式，适用于大多数场景
- **`secondary`** — 低强调变体，适合用在 Surface 组件内


> 示例 `radio-group-variants`: 交互预览见 https://jiguang132.com/zh/systems/heroui/docs/components/radio-group


### 在 Surface 内

在 [Surface](/systems/heroui/docs/components/surface) 内使用时，请使用 `variant="secondary"`，以应用适合表面背景的低强调变体。


> 示例 `radio-group-on-surface`: 交互预览见 https://jiguang132.com/zh/systems/heroui/docs/components/radio-group


### 配送与支付


> 示例 `radio-group-delivery-and-payment`: 交互预览见 https://jiguang132.com/zh/systems/heroui/docs/components/radio-group


### 自定义渲染函数


> 示例 `radio-group-custom-render-function`: 交互预览见 https://jiguang132.com/zh/systems/heroui/docs/components/radio-group


## 样式

### 传入 Tailwind CSS 类

```tsx
import { RadioGroup, Radio } from '@heroui/react';

export default () => (
  <RadioGroup defaultValue="premium" name="plan">
    <Radio
      className="border-border group cursor-pointer rounded-xl border-2 p-4 hover:border-blue-300 data-[selected=true]:border-blue-500 data-[selected=true]:bg-blue-500/10"
      value="basic"
    >
      <Radio.Indicator className="border-border border-2 group-hover:border-blue-400 group-data-[selected=true]:border-blue-500 group-data-[selected=true]:bg-blue-500" />
      Basic Plan
    </Radio>
    <Radio
      className="border-border group cursor-pointer rounded-xl border-2 p-4 hover:border-purple-300 data-[selected=true]:border-purple-500 data-[selected=true]:bg-purple-500/10"
      value="premium"
    >
      <Radio.Indicator className="border-border border-2 group-hover:border-purple-400 group-data-[selected=true]:border-purple-500 group-data-[selected=true]:bg-purple-500" />
      Premium Plan
    </Radio>
    <Radio
      className="border-border group cursor-pointer rounded-xl border-2 p-4 hover:border-emerald-300 data-[selected=true]:border-emerald-500 data-[selected=true]:bg-emerald-500/10"
      value="business"
    >
      <Radio.Indicator className="border-border border-2 group-hover:border-emerald-400 group-data-[selected=true]:border-emerald-500 group-data-[selected=true]:bg-emerald-500" />
      Business Plan
    </Radio>
  </RadioGroup>
);
```

### 自定义组件类

要自定义 RadioGroup 的组件类，可使用 `@layer components` 指令。
  
[了解更多](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes)。

```css
@layer components {
  .radio-group {
    @apply gap-2;
  }

  .radio {
    @apply gap-4 rounded-lg border border-border p-3 hover:bg-surface-hovered;
  }

  .radio__control {
    @apply border-2 border-primary;
  }

  .radio__indicator {
    @apply bg-primary;
  }

  .radio__content {
    @apply gap-1;
  }
}
```

HeroUI 遵循 [BEM](https://getbem.com/) 方法论，以确保组件变体与状态可复用且易于自定义。

### CSS 类

RadioGroup 使用以下 CSS 类（[查看源码样式](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/radio-group.css)）：

#### 基础类
- `.radio-group` - 单选组基础容器
- `.radio` - 单个单选项
- `.radio__control` - 单选控件（圆形按钮）
- `.radio__indicator` - 单选指示器（内部圆点）
- `.radio__content` - 单选内容包裹层

#### 修饰类
- `.radio--disabled` - 禁用状态

### 交互状态

单选项同时支持 CSS 伪类与 data 属性，便于灵活定制：

- **Selected**：`[aria-checked="true"]` 或 `[data-selected="true"]`（显示指示器）
- **Hover**：`:hover` 或 `[data-hovered="true"]`（边框颜色变化）
- **Focus**：`:focus-visible` 或 `[data-focus-visible="true"]`（显示焦点环）
- **Pressed**：`:active` 或 `[data-pressed="true"]`（缩放变换）
- **Disabled**：`:disabled` 或 `[aria-disabled="true"]`（降低透明度并禁用指针事件）
- **Invalid**：`[data-invalid="true"]` 或 `[aria-invalid="true"]`（错误边框颜色）

## API 参考

### RadioGroup Props

| Prop | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| `value` | `string` | - | 当前值（受控） |
| `defaultValue` | `string` | - | 默认值（非受控） |
| `onChange` | `(value: string) => void` | - | 值变化时触发的事件处理函数 |
| `isDisabled` | `boolean` | `false` | 是否禁用整个单选组 |
| `isRequired` | `boolean` | `false` | 是否必填 |
| `isReadOnly` | `boolean` | `false` | 是否只读 |
| `isInvalid` | `boolean` | `false` | 是否处于无效状态 |
| `variant` | `"primary" \| "secondary"` | `"primary"` | 组件的视觉变体。`primary` 为默认带阴影样式。`secondary` 为低强调、无阴影变体，适合用在 surface 上。 |
| `name` | `string` | - | 单选组的名称，用于提交 HTML 表单 |
| `orientation` | `'horizontal' \| 'vertical'` | `'vertical'` | 单选组的排列方向 |
| `children` | `React.ReactNode \| (values: RadioGroupRenderProps) => React.ReactNode` | - | 单选组内容或渲染 prop |
| `render` | `DOMRenderFunction<keyof React.JSX.IntrinsicElements, RadioGroupRenderProps>` | - | 使用自定义渲染函数覆盖默认 DOM 元素。|

### Radio Props

| Prop | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| `value` | `string` | - | 单选项的值 |
| `isDisabled` | `boolean` | `false` | 是否禁用该单选项 |
| `name` | `string` | - | 单选项名称，用于提交 HTML 表单 |
| `children` | `React.ReactNode \| (values: RadioFieldRenderProps) => React.ReactNode` | - | 单选内容或字段级渲染 prop |
| `render` | `DOMRenderFunction<keyof React.JSX.IntrinsicElements, RadioFieldRenderProps>` | - | 使用自定义渲染函数覆盖默认 DOM 元素。|

### Radio.Control Props

继承 `React.HTMLAttributes`。

| Prop | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| `children` | `React.ReactNode` | - | 控件包裹层内要渲染的内容（通常为 Radio.Indicator） |

### Radio.Indicator Props

继承 `React.HTMLAttributes`。

| Prop | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| `children` | `React.ReactNode \| (values: RadioButtonRenderProps) => React.ReactNode` | - | 可选内容或接收当前单选按钮状态的渲染 prop。 |

### Radio.Content Props

单选项的可点击区域（包裹隐藏 input 的 `<label>`）。请将 `Radio.Control` 与 `Label` 放在其中。`className` 支持接收 `RadioButtonRenderProps` 的渲染函数。

| Prop | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| `children` | `React.ReactNode \| (values: RadioButtonRenderProps) => React.ReactNode` | - | 可点击内容（通常为 Radio.Control 与 Label） |

### RadioFieldRenderProps

在根级 `Radio` 上使用渲染 prop 时，会提供以下字段级值：

| Prop | 类型 | 描述 |
|------|------|------|
| `isSelected` | `boolean` | 单选项是否已选中 |
| `isDisabled` | `boolean` | 是否禁用 |
| `isReadOnly` | `boolean` | 是否只读 |
| `isInvalid` | `boolean` | 是否无效 |
| `isRequired` | `boolean` | 是否必填 |

### RadioButtonRenderProps

`Radio.Control` 和 `Radio.Indicator` 使用按钮级渲染 prop（`isHovered`、`isPressed`、`isFocusVisible` 等）。将函数作为 `Radio.Control` 子节点或传给 `Radio.Indicator` 即可访问它们。

---

JGuang 全部资源索引: https://jiguang132.com/llms.txt
