跳到内容

开关

一个用于即时设置(通知、深色模式、功能开关)的开关按钮,采用新粗野主义风格的边框与阴影设计。

import { Label } from "@/components/ui/label"
import { Switch } from "@/components/ui/switch"

开关是一个双状态切换控件——开或关,一拨就立即生效,不需要提交按钮。它基于 Base UI Switch 组件构建,并按新粗野主义的配方设计:粗边框、硬阴影、加粗字体。

适合以下场景:

  • 设置面板——通知、深色模式、自动播放,这类立刻生效的偏好项。
  • 功能开关——启用某个 Beta 功能,或在按月与按年计费之间切换。
  • 行级控件——在表格或列表里启用、暂停某一项,不必打开表单。

安装

pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/switch.json
npx shadcn@latest add https://neobrutalism.com/r/base/switch.json
yarn dlx shadcn@latest add https://neobrutalism.com/r/base/switch.json
bunx --bun shadcn@latest add https://neobrutalism.com/r/base/switch.json

安装以下依赖:

pnpm add @base-ui/react
npm install @base-ui/react
yarn add @base-ui/react
bun add @base-ui/react

将以下代码复制并粘贴到您的项目中。

components/ui/switch.tsx
"use client"

import * as React from "react"
import { Switch as SwitchPrimitive } from "radix-ui"

import { cn } from "@/lib/utils"

function Switch({
  className,
  size = "default",
  ...props
}: React.ComponentProps<typeof SwitchPrimitive.Root> & {
  size?: "sm" | "default"
}) {
  return (
    <SwitchPrimitive.Root
      data-slot="switch"
      data-size={size}
      className={cn(
        "peer group/switch relative inline-flex shrink-0 cursor-pointer items-center border-2 border-foreground transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary aria-invalid:border-destructive data-[size=default]:h-6 data-[size=default]:w-11 data-[size=sm]:h-5 data-[size=sm]:w-9 data-checked:bg-primary data-disabled:cursor-not-allowed data-disabled:opacity-50",
        className
      )}
      {...props}
    >
      <SwitchPrimitive.Thumb
        data-slot="switch-thumb"
        className="pointer-events-none mx-0.5 block border-2 border-foreground bg-primary transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-5 group-data-[size=sm]/switch:data-checked:translate-x-4 data-checked:bg-background data-unchecked:translate-x-0"
      />
    </SwitchPrimitive.Root>
  )
}

export { Switch }

更新导入路径以匹配您的项目设置。

用法

import { Switch } from "@/components/ui/switch"
<Switch />

示例

描述

import {
  Field,
  FieldContent,

选择卡片

卡片式的选择方式,FieldLabel 包裹整个 Field,实现可点击的卡片模式。

import {
  Field,
  FieldContent,

禁用

Switch 组件上添加 disabled 属性以禁用开关。在 Field 组件上添加 data-disabled 属性以应用样式。

import { Field, FieldLabel } from "@/components/ui/field"
import { Switch } from "@/components/ui/switch"

无效

Switch 组件上添加 aria-invalid 属性以表示无效状态。在 Field 组件上添加 data-invalid 属性以应用样式。

import {
  Field,
  FieldContent,

尺寸

使用 size 属性来更改开关的尺寸。

import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"
import { Switch } from "@/components/ui/switch"

RTL

要在 Neobrutalism 中启用 RTL 支持,请参阅 RTL 配置指南

"use client"

import * as React from "react"

无障碍

开关遵循 WAI-ARIA Switch 模式:它渲染出一个真正的按钮,带 role="switch"aria-checked,另外还有一个隐藏的 input,好让取值随外层表单一起提交。

键盘交互:

按键操作
Tab / Shift + Tab把焦点移到开关上或移开
Space切换开关
Enter切换开关

API 参考

请参阅 Base UI Switch 文档。