상태
off · on · loading · disabled (즉시 적용)
loading
spinner overlay + disabled 강제 + aria-busy (원격 저장 모의)
접근성 기준
role=switch + aria-checked + visible label + aria-required/aria-busy

기본

라이브 토글
코드 보기tsx
import { useState } from "react";
import { Switch } from "@olundot/ui";

export function NotificationsSwitch() {
  const [on, setOn] = useState(false);
  return <Switch name="notify" label="감독관 알림" checked={on} onCheckedChange={setOn} />;
}

상태

라이브 토글 (off · on · disabled)
코드 보기tsx
import { useState } from "react";
import { Switch } from "@olundot/ui";

export function SwitchStates() {
  const [a, setA] = useState(false);
  const [b, setB] = useState(true);
  return (
    <div style={{ display: "grid", gap: "12px" }}>
      <Switch name="off" label="기본 off" checked={a} onCheckedChange={setA} />
      <Switch name="on" label="기본 on" checked={b} onCheckedChange={setB} />
      <Switch name="d-off" label="비활성 off" checked={false} onCheckedChange={() => {}} disabled />
      <Switch name="d-on" label="비활성 on" checked={true} onCheckedChange={() => {}} disabled />
    </div>
  );
}

설명형

라이브 토글 + description sibling

학생이 도움을 요청하면 즉시 알립니다.

코드 보기tsx
import { useState } from "react";
import { Switch } from "@olundot/ui";

export function ProctorNotificationsSwitch() {
  const [on, setOn] = useState(true);
  return (
    <Switch
      name="notify"
      label="감독관 알림"
      description="학생이 도움을 요청하면 즉시 알립니다."
      checked={on}
      onCheckedChange={setOn}
    />
  );
}

저장 중 (loading state)

라이브 토글 + spinner + aria-busy

토글 시 서버에 즉시 저장됩니다.

코드 보기tsx
import { useState } from "react";
import { Switch } from "@olundot/ui";

// loading prop → disabled 강제 + spinner overlay + aria-busy.
// 토글 시 1.2초 후 서버 저장 완료를 모의합니다.
export function RemoteSaveSwitch() {
  const [on, setOn] = useState(false);
  const [saving, setSaving] = useState(false);
  return (
    <Switch
      name="notify"
      label="원격 저장"
      description={saving ? "저장 중..." : "토글 시 서버에 즉시 저장됩니다."}
      checked={on}
      loading={saving}
      onCheckedChange={(c) => {
        setSaving(true);
        setTimeout(() => {
          setOn(c === true);
          setSaving(false);
        }, 1200);
      }}
    />
  );
}