ProComponents, templates & AI tooling
HeroUI
27.7k

RadioGroup 单选框组

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

引入

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

用法

选择套餐选择最适合你的套餐
import {Description, Label, Radio, RadioGroup} from "@heroui/react";

export function Basic() {
  return (
    <RadioGroup defaultValue="premium" name="plan">

组件结构

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

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

export default () => (
  <RadioGroup>
    <Label />
    <Description />
    <Radio value="option1">
      <Radio.Control>
        <Radio.Indicator>
          <span>✓</span> {/* Custom indicator (optional) */}
        </Radio.Indicator>
      </Radio.Control>
      <Radio.Content>
        <Label />
        <Description />
      </Radio.Content>
    </Radio>
    <FieldError />
  </RadioGroup>
)

自定义指示器

选择套餐选择最适合你的套餐
"use client";

import {Description, Label, Radio, RadioGroup} from "@heroui/react";

export function CustomIndicator() {

水平排列

import {Description, Label, Radio, RadioGroup} from "@heroui/react";

export function Horizontal() {
  return (
    <div className="flex flex-col gap-4">

受控

订阅套餐

已选套餐: pro

"use client";

import {Description, Label, Radio, RadioGroup} from "@heroui/react";
import React from "react";

非受控

当你只需要响应更新时,可组合使用 defaultValueonChange

订阅套餐

上次选择的套餐: pro

"use client";

import {Description, Label, Radio, RadioGroup} from "@heroui/react";
import React from "react";

校验

订阅套餐
"use client";

import {Button, Description, FieldError, Form, Label, Radio, RadioGroup} from "@heroui/react";
import React from "react";

禁用

订阅套餐我们正在发布更新,暂时无法更改套餐。
import {Description, Label, Radio, RadioGroup} from "@heroui/react";

export function Disabled() {
  return (
    <RadioGroup isDisabled defaultValue="pro" name="plan-disabled">

变体

RadioGroup 支持两种视觉变体:

  • primary(默认)— 带默认背景的标准样式,适用于大多数场景
  • secondary — 低强调变体,适合用在 Surface 组件内

主要变体

次要变体

import {Description, Label, Radio, RadioGroup} from "@heroui/react";

export function Variants() {
  return (
    <div className="flex flex-col gap-8">

在 Surface 内

Surface 内使用时,请使用 variant="secondary",以应用适合表面背景的低强调变体。

选择套餐选择最适合你的套餐
import {Description, Label, Radio, RadioGroup, Surface} from "@heroui/react";

export function OnSurface() {
  return (
    <Surface className="w-full rounded-3xl p-6">

配送与支付

配送方式
支付方式
import {Description, Label, Radio, RadioGroup} from "@heroui/react";
import {Icon} from "@iconify/react";
import clsx from "clsx";

export function DeliveryAndPayment() {

自定义渲染函数

选择套餐选择最适合你的套餐
"use client";

import {Description, Label, Radio, RadioGroup} from "@heroui/react";

export function CustomRenderFunction() {

样式

传入 Tailwind CSS 类

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 指令。
了解更多

@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 方法论,以确保组件变体与状态可复用且易于自定义。

CSS 类

RadioGroup 使用以下 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类型默认值描述
valuestring-当前值(受控)
defaultValuestring-默认值(非受控)
onChange(value: string) => void-值变化时触发的事件处理函数
isDisabledbooleanfalse是否禁用整个单选组
isRequiredbooleanfalse是否必填
isReadOnlybooleanfalse是否只读
isInvalidbooleanfalse是否处于无效状态
variant"primary" | "secondary""primary"组件的视觉变体。primary 为默认带阴影样式。secondary 为低强调、无阴影变体,适合用在 surface 上。
namestring-单选组的名称,用于提交 HTML 表单
orientation'horizontal' | 'vertical''vertical'单选组的排列方向
childrenReact.ReactNode | (values: RadioGroupRenderProps) => React.ReactNode-单选组内容或渲染 prop
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, RadioGroupRenderProps>-使用自定义渲染函数覆盖默认 DOM 元素。

Radio Props

Prop类型默认值描述
valuestring-单选项的值
isDisabledbooleanfalse是否禁用该单选项
namestring-单选项名称,用于提交 HTML 表单
childrenReact.ReactNode | (values: RadioRenderProps) => React.ReactNode-单选内容或渲染 prop
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, RadioRenderProps>-使用自定义渲染函数覆盖默认 DOM 元素。

Radio.Control Props

继承 React.HTMLAttributes<HTMLSpanElement>

Prop类型默认值描述
childrenReact.ReactNode-控件包裹层内要渲染的内容(通常为 Radio.Indicator)

Radio.Indicator Props

继承 React.HTMLAttributes<HTMLSpanElement>

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

Radio.Content Props

继承 React.HTMLAttributes<HTMLDivElement>

Prop类型默认值描述
childrenReact.ReactNode-内容包裹层内要渲染的内容(通常为 Label 与 Description)

RadioRenderProps

使用渲染 prop 模式时,会提供以下值:

Prop类型描述
isSelectedboolean单选项是否已选中
isHoveredboolean是否悬停
isPressedboolean是否按下
isFocusedboolean是否聚焦
isFocusVisibleboolean是否为键盘可见焦点
isDisabledboolean是否禁用
isReadOnlyboolean是否只读
isInvalidboolean是否无效

本页目录