ProComponents, templates & AI tooling
HeroUI
27.7k

Switch

Switch 从 HeroUI v2 到 v3 的迁移指南。

完整的 API 参考、样式指南与高级示例请参阅 v3 Switch 文档。本指南只关注从 HeroUI v2 的迁移。

结构变化

在 v2 中,Switch 结构简单,children 作为标签:

import { Switch } from "@heroui/react";

export default function App() {
  return <Switch>Enable notifications</Switch>;
}

在 v3 中,Switch 需要复合组件:

import { Switch, Label } from "@heroui/react";

export default function App() {
  return (
    <Switch>
      <Switch.Content>
        <Switch.Control>
          <Switch.Thumb />
        </Switch.Control>
        Enable notifications
      </Switch.Content>
    </Switch>
  );
}

主要变化

1. 组件结构

v2: children 作为标签的简单 Switch
v3: 复合组件(Switch.ContentSwitch.ControlSwitch.Thumb)与 Label 组件

2. Prop 变更

v2 propv3 位置说明
onValueChangeonChange事件处理函数已重命名
sizesize仍在根上(sm | md | lg
label请使用 Label 组件
color已移除(请使用 Tailwind CSS)
thumbIcon请在 Switch.Thumb 内使用 Switch.Icon
startContent请直接自定义控件
endContent请直接自定义控件
classNames请在各子组件上使用 className
disableAnimation已移除(动画机制已不同)

3. 新组件

  • SwitchGroup — 用于将多个 Switch 成组
  • Switch.Content — 可点击的标签,包裹控件与 Label
  • Switch.Icon — 拇指(Thumb)内的图标

迁移示例

受控 Switch

import { useState } from "react";

const [isSelected, setIsSelected] = useState(true);

<Switch isSelected={isSelected} onValueChange={setIsSelected}>
  Airplane mode
</Switch>
import { useState } from "react";

const [isSelected, setIsSelected] = useState(true);

<Switch isSelected={isSelected} onChange={setIsSelected}>
  <Switch.Content>
    <Switch.Control>
      <Switch.Thumb />
    </Switch.Control>
    Airplane mode
  </Switch.Content>
</Switch>

无标签

<Switch defaultSelected aria-label="Automatic updates" />
<Switch defaultSelected aria-label="Automatic updates">
  <Switch.Content>
    <Switch.Control>
      <Switch.Thumb />
    </Switch.Control>
  </Switch.Content>
</Switch>

带拇指图标

<Switch thumbIcon={<CheckIcon />}>Enable notifications</Switch>
<Switch>
  <Switch.Content>
    <Switch.Control>
      <Switch.Thumb>
        <Switch.Icon>
          <CheckIcon />
        </Switch.Icon>
      </Switch.Thumb>
    </Switch.Control>
    Enable notifications
  </Switch.Content>
</Switch>

带起始 / 结束内容

<Switch
  startContent={<SunIcon />}
  endContent={<MoonIcon />}
>
  Dark mode
</Switch>
<Switch>
  <Switch.Content>
    <Switch.Control className="flex items-center gap-2">
      <SunIcon />
      <Switch.Thumb />
      <MoonIcon />
    </Switch.Control>
    Dark mode
  </Switch.Content>
</Switch>

带标签与描述

<Switch description="You will receive notifications for all activity">
  Enable notifications
</Switch>
import { Switch, Label, Description } from "@heroui/react";

<Switch>
  <Switch.Content>
    <Switch.Control>
      <Switch.Thumb />
    </Switch.Control>
    Enable notifications
  </Switch.Content>
  <Description>You will receive notifications for all activity</Description>
</Switch>

尺寸与颜色

{/* Sizes */}
<div className="flex gap-4">
  <Switch size="sm">Small</Switch>
  <Switch size="md">Medium</Switch>
  <Switch size="lg">Large</Switch>
</div>

{/* Colors */}
<Switch color="primary">Primary</Switch>
<Switch color="success">Success</Switch>
<Switch color="danger">Danger</Switch>
{/* Sizes */}
<div className="flex gap-4">
  <Switch size="sm">
    <Switch.Content>
      <Switch.Control>
        <Switch.Thumb />
      </Switch.Control>
      Small
    </Switch.Content>
  </Switch>
  <Switch size="md">
    <Switch.Content>
      <Switch.Control>
        <Switch.Thumb />
      </Switch.Control>
      Medium
    </Switch.Content>
  </Switch>
  <Switch size="lg">
    <Switch.Content>
      <Switch.Control>
        <Switch.Thumb />
      </Switch.Control>
      Large
    </Switch.Content>
  </Switch>
</div>

{/* Colors - Use Tailwind CSS classes */}
<Switch>
  <Switch.Content>
    <Switch.Control className="data-[selected=true]:bg-accent">
      <Switch.Thumb />
    </Switch.Control>
    Primary
  </Switch.Content>
</Switch>
<Switch>
  <Switch.Content>
    <Switch.Control className="data-[selected=true]:bg-success">
      <Switch.Thumb />
    </Switch.Control>
    Success
  </Switch.Content>
</Switch>
<Switch>
  <Switch.Content>
    <Switch.Control className="data-[selected=true]:bg-danger">
      <Switch.Thumb />
    </Switch.Control>
    Danger
  </Switch.Content>
</Switch>

Switch 组

{/* No built-in group component in v2 */}
<div className="flex flex-col gap-2">
  <Switch name="notifications">Allow Notifications</Switch>
  <Switch name="marketing">Marketing emails</Switch>
</div>
import { SwitchGroup } from "@heroui/react";

<SwitchGroup>
  <Switch name="notifications">
    <Switch.Content>
      <Switch.Control>
        <Switch.Thumb />
      </Switch.Control>
      Allow Notifications
    </Switch.Content>
  </Switch>
  <Switch name="marketing">
    <Switch.Content>
      <Switch.Control>
        <Switch.Thumb />
      </Switch.Control>
      Marketing emails
    </Switch.Content>
  </Switch>
</SwitchGroup>

组件组成

v3 Switch 的结构如下:

Switch (Root)
  ├── Switch.Content (the clickable label)
  │   ├── Switch.Control
  │   │   └── Switch.Thumb
  │   │       └── Switch.Icon (optional)
  │   └── Label
  ├── Description (optional, sibling)
  └── FieldError (optional, sibling)

分组时:

SwitchGroup
  ├── Switch
  │   ├── Switch.Content
  │   │   ├── Switch.Control
  │   │   │   └── Switch.Thumb
  │   │   └── Label
  │   └── Description (optional)
  └── Switch
      ├── Switch.Content
      │   ├── Switch.Control
      │   │   └── Switch.Thumb
      │   └── Label
      └── Description (optional)

说明

事件处理函数

  • v2: onValueChange prop
  • v3: onChange prop(签名相同:(isSelected: boolean) => void

标签

  • v2: children 作为标签
  • v3: Label 放在 Switch.Content(可点击的标签)内;Description / FieldError 作为 Switch.Content 的同级元素

图标

  • v2: thumbIcon 用于拇指内图标,startContent / endContent 用于外侧图标
  • v3: 拇指内图标用 Switch.Icon(置于 Switch.Thumb 内);起始 / 结束内容请自定义 Switch.Control

总结

  1. 组件结构:必须使用复合组件(Switch.ContentSwitch.ControlSwitch.Thumb
  2. 可点击的标签:用 Switch.Content 包裹 Switch.ControlLabel;将 Description / FieldError 作为 Switch.Content 的同级元素
  3. 标签:不再用 children 作为标签 — 请在 Switch.Content 内使用 Label
  4. 事件处理函数onValueChangeonChange
  5. 样式相关 prop 已移除color — 请使用 Tailwind CSS
  6. 图标相关 prop 已移除thumbIconstartContentendContent — 请用子组件或直接自定义
  7. classNames 已移除:请在各子组件上使用 className prop
  8. 新组件SwitchGroup 用于成组;Switch.Content 作为可点击的标签,包裹控件与 Label

本页目录