import { useState } from "react";
import { Switch } from "@cloudflare/kumo";

export function SwitchBasicDemo() {
  const [checked, setChecked] = useState(false);
  return (
    <Switch label="Switch" checked={checked} onCheckedChange={setChecked} />
  );
}

安装

桶式导出

import { Switch } from "@cloudflare/kumo";

细粒度导入

import { Switch } from "@cloudflare/kumo/components/switch";

用法

import { Switch } from "@cloudflare/kumo";
import { useState } from "react";

export default function Example() {
  const [checked, setChecked] = useState(false);

  return (
    <Switch checked={checked} onCheckedChange={(val) => setChecked(val)} />
  );
}

示例

关闭状态

import { Switch } from "@cloudflare/kumo";

export function SwitchOffDemo() {
  return <Switch label="Switch" checked={false} onCheckedChange={() => {}} />;
}

开启状态

import { Switch } from "@cloudflare/kumo";

export function SwitchOnDemo() {
  return <Switch label="Switch" checked={true} onCheckedChange={() => {}} />;
}

禁用状态

import { Switch } from "@cloudflare/kumo";

export function SwitchDisabledDemo() {
  return <Switch label="Disabled" checked={false} disabled />;
}

变体

Switch 支持两种变体:default(开启时为蓝色)和 neutral(单色)。 两者都采用 squircle 形状。

import { Switch } from "@cloudflare/kumo";

/** All variants comparison — 2×2 grid showing off/on for default and neutral */
export function SwitchVariantsDemo() {
  return (
    <div className="grid grid-cols-2 gap-x-8 gap-y-4">
      <Switch label="Default off" checked={false} onCheckedChange={() => {}} />
      <Switch label="Default on" checked={true} onCheckedChange={() => {}} />
      <Switch
        label="Neutral off"
        variant="neutral"
        checked={false}
        onCheckedChange={() => {}}
      />
      <Switch
        label="Neutral on"
        variant="neutral"
        checked={true}
        onCheckedChange={() => {}}
      />
    </div>
  );
}

中性变体

中性变体采用单色配色和 squircle 形状,适合 低调、不显眼的开关。

import { useState } from "react";
import { Switch } from "@cloudflare/kumo";

/** Neutral variant - monochrome switch for subtle, less prominent toggles */
export function SwitchNeutralDemo() {
  const [checked, setChecked] = useState(false);
  return (
    <Switch
      label="Neutral switch"
      variant="neutral"
      checked={checked}
      onCheckedChange={setChecked}
    />
  );
}

中性状态

import { Switch } from "@cloudflare/kumo";

/** Neutral variant in different states */
export function SwitchNeutralStatesDemo() {
  return (
    <div className="flex flex-col gap-4">
      <Switch
        label="Neutral off"
        variant="neutral"
        checked={false}
        onCheckedChange={() => {}}
      />
      <Switch
        label="Neutral on"
        variant="neutral"
        checked={true}
        onCheckedChange={() => {}}
      />
      <Switch
        label="Neutral disabled"
        variant="neutral"
        checked={false}
        disabled
      />
    </div>
  );
}

尺寸

共有三种尺寸:sm、base(默认)和 lg。

import { Switch } from "@cloudflare/kumo";

/** All sizes comparison */
export function SwitchSizesDemo() {
  return (
    <div className="flex flex-col gap-4">
      <Switch
        label="Small"
        size="sm"
        checked={true}
        onCheckedChange={() => {}}
      />
      <Switch
        label="Base (default)"
        size="base"
        checked={true}
        onCheckedChange={() => {}}
      />
      <Switch
        label="Large"
        size="lg"
        checked={true}
        onCheckedChange={() => {}}
      />
    </div>
  );
}

自定义 ID

提供自定义 id 时,点击标签仍会切换开关。id 会转发给 Base UI, 使标签的 htmlFor 与之保持同步。

import { useState } from "react";
import { Switch } from "@cloudflare/kumo";

/** Switch with a custom id prop — clicking the label should still toggle the switch. */
export function SwitchCustomIdDemo() {
  const [checked, setChecked] = useState(false);
  return (
    <Switch
      id="my-custom-switch"
      label="Custom ID"
      checked={checked}
      onCheckedChange={setChecked}
    />
  );
}

开关组

使用 Switch.Group 将相关开关组合在一起。为整个组提供共用的图例、 描述和错误提示。

Notification settings
import { Switch } from "@cloudflare/kumo";

/** Shows a Switch.Group with a legend for grouping related switches */
export function SwitchGroupDemo() {
  return (
    <Switch.Group legend="Notification settings">
      <Switch.Item label="Email notifications" />
      <Switch.Item label="SMS notifications" />
      <Switch.Item label="Push notifications" />
    </Switch.Group>
  );
}

视觉隐藏的图例

使用带 className="sr-only" 的 Switch.Legend,可以在视觉上隐藏图例的同时 保持其为屏幕阅读器可读。当组已由父级 Field 或标题提供了标签, 再显示图例会形成冗余标签时, 这一用法很有用。

Notification settings
import { Switch } from "@cloudflare/kumo";

/** Shows Switch.Legend with sr-only to visually hide the legend while keeping it accessible, useful when a parent Field already provides a visible label */
export function SwitchLegendSrOnlyDemo() {
  return (
    <Switch.Group>
      <Switch.Legend className="sr-only">Notification settings</Switch.Legend>
      <Switch.Item label="Email notifications" />
      <Switch.Item label="SMS notifications" />
      <Switch.Item label="Push notifications" />
    </Switch.Group>
  );
}

自定义图例样式

Switch.Legend 接受 className,可完全控制图例的呈现方式。当你需要 自定义排版、颜色或布局时,请用它替代 legend 字符串属性。

Notification settings
import { Switch } from "@cloudflare/kumo";

/** Shows Switch.Legend with custom styling for full control over legend presentation */
export function SwitchLegendCustomDemo() {
  return (
    <Switch.Group>
      <Switch.Legend className="text-sm font-normal text-kumo-subtle">
        Notification settings
      </Switch.Legend>
      <Switch.Item label="Email notifications" />
      <Switch.Item label="SMS notifications" />
      <Switch.Item label="Push notifications" />
    </Switch.Group>
  );
}

API 参考

Switch

内置标签的单个开关切换控件。

PropTypeDefaultDescription
variant"default" | "neutral""default"

视觉变体:"default"(胶囊形,品牌色)或 "neutral"(圆角方形,单色)

labelReactNode-

开关的标签内容(Field 包装器为内置)— 可以是字符串或任意 React 节点。单独用于纯视觉目的时可选。

labelTooltipReactNode-

通过信息图标显示在标签旁边的 Tooltip 内容。

requiredboolean-

开关是否为必填项。当明确为 false 时,在标签后显示“(可选)”文本。

controlFirstboolean-

当 true(默认)时,开关显示在标签前。当 false 时,标签显示在开关前。

size"sm" | "base" | "lg""base"-
checkedboolean--
disabledboolean--
transitioningboolean--
namestring--
type"submit" | "reset" | "button"--
valuestring | string[] | number--
classNamestring--
idstring--
langstring--
titlestring--
onClick*(event: React.MouseEvent) => void-

开关被点击时的回调

Switch.Group

包含多个开关的容器,支持图例、描述和错误提示。

PropTypeDefaultDescription
legendstring-

分组的图例文本。若需更精细地控制图例样式,请省略此属性,改用 <Switch.Legend> 作为子元素。

children*ReactNode-

子 Switch.Item 组件(可选配 Switch.Legend)

errorstring-

组的错误消息(仅出现在组中,不适用于单个开关)

descriptionReactNode-

组的帮助文本

disabledboolean-

是否禁用组中的所有开关

controlFirstboolean-

当 true(默认)时,开关显示在标签前。当 false 时,标签显示在开关前。

classNamestring-

额外的 CSS 类

Switch.Legend

可组合的 Switch.Group 图例子组件。接受 className 以完全控制样式 (例如 className="sr-only" 实现视觉隐藏)。当你需要自定义图例样式时, 用它替代 legend 字符串属性。

PropTypeDefaultDescription
children*ReactNode-

图例内容

classNamestring-

额外的 CSS 类(例如用 "sr-only" 视觉隐藏图例)

Switch.Item

Switch.Group 中的单个开关。

PropTypeDefault

No component-specific props. Accepts standard HTML attributes.