switch · glass-apple · 灵感来源:iOS 设置页的 UISwitch
Wi-Fi
已连接 · UI-Echo-5G
蓝牙
已关闭
飞行模式
演示禁用态
小号尺寸
点击 / 空格切换 · 文案随状态联动
iOS UISwitch · 玻璃开关 · 开关 / Glass
做一个 iOS UISwitch(玻璃开关):
- role=switch + aria-checked,Space / Enter 切换
- 旋钮平移与轨道变色同步(200ms)
- 轨道高度 ≥24px(指针目标 ≥24×24,SC 2.5.8)
- 按压有缩放反馈
用这些 CSS 变量:--color-accent --color-surface --color-text-muted --dur-fast --ease-standard --glass-border --glass-switch-off --shadow-sm
灵感参考:iOS 设置页的 UISwitch--color-accent --color-surface --color-text-muted --dur-fast --ease-standard --glass-border --glass-switch-off --shadow-sm
焦点 / 按压 / 禁用
/r/switch--glass-apple.json
免外壳的 markdown 版:/llms/components/switch--glass-apple.md--glass-switch-off),开启 = accent 填充--dur-fast)平移,曲线 --ease-standard——与分段控件同一条曲线checked 走受控;只传 defaultChecked 走内部状态——Astro 静态页不写状态胶水也能用role="switch" + aria-checked,button 元素天然支持空格/回车切换变量:--glass-switch-off(ink 15%)/ 开启 --color-accent。
import { useState } from 'react';
interface Props {
checked?: boolean;
defaultChecked?: boolean;
onChange?: (checked: boolean) => void;
disabled?: boolean;
size?: 'sm' | 'md';
'aria-label'?: string;
}
// 轨道高度都 ≥24px:SC 2.5.8 要求指针目标至少 24×24 CSS 像素
const dims = {
sm: { track: 'w-8 h-6', thumb: 'size-4', on: 'translateX(12px)' },
md: { track: 'w-11 h-[26px]', thumb: 'size-[22px]', on: 'translateX(18px)' },
};
export function GlassAppleSwitch({
checked,
defaultChecked,
onChange,
disabled,
size = 'md',
...rest
}: Props) {
const isControlled = checked !== undefined;
const [internal, setInternal] = useState(defaultChecked ?? false);
const on = isControlled ? checked : internal;
const d = dims[size];
const toggle = () => {
const next = !on;
if (!isControlled) setInternal(next);
onChange?.(next);
};
return (
<button
type="button"
role="switch"
aria-checked={on}
disabled={disabled}
onClick={toggle}
className={`
press-feedback
relative inline-flex items-center shrink-0
${d.track} rounded-full p-[2px]
transition-colors duration-[var(--dur-fast)] ease-[var(--ease-standard)]
cursor-pointer
${on ? 'bg-[var(--color-accent)]' : 'bg-[var(--glass-switch-off)]'}
disabled:opacity-40 disabled:cursor-not-allowed
`}
{...rest}
>
<span
aria-hidden="true"
className={`
${d.thumb} rounded-full
bg-[var(--color-surface)] border border-[var(--glass-border)]
shadow-[var(--shadow-sm)]
transition-transform duration-[var(--dur-fast)] ease-[var(--ease-standard)]
`}
style={{ transform: on ? d.on : 'translateX(0)' }}
/>
</button>
);
}
src/components/switch/glass-apple/