크기
sm · md
상태
unchecked · checked · indeterminate · disabled
접근성 기준
전체 행 클릭 영역 + visible label + aria-checked=mixed (indeterminate 시)

기본

토글과 설명 텍스트

입장 전 필수 확인 항목입니다.

코드 보기tsx
import { Checkbox } from "@olundot/ui";

export function PolicyCheckbox() {
  return (
    <Checkbox
      name="confirm"
      description="입장 전 필수 확인 항목입니다."
    >
      시험 정책을 확인했습니다.
    </Checkbox>
  );
}

체크리스트

체크리스트와 비활성 항목

응시 직후 즉시 전송됩니다.

기관 정책으로 잠겨 있습니다.

코드 보기tsx
import { Checkbox } from "@olundot/ui";

export function FilterChecklist() {
  return (
    <div style={{ display: "grid", gap: "12px" }}>
      <Checkbox name="f1" defaultChecked>자동 제출</Checkbox>
      <Checkbox name="f2" description="응시 직후 즉시 전송됩니다.">결과 메일 발송</Checkbox>
      <Checkbox name="f3" disabled description="기관 정책으로 잠겨 있습니다.">외부 공유</Checkbox>
    </div>
  );
}

상태

off · on · indeterminate 순환과 disabled
코드 보기tsx
import { useState } from "react";
import { Checkbox, type CheckboxCheckedState } from "@olundot/ui";

// off/on은 uncontrolled defaultChecked로 전환하고, indeterminate는 controlled
// 3-cycle (off → indeterminate → on → off) — 사용자가 클릭하며 3 상태 학습.
// disabled 항목은 선택할 수 없다.
export function CheckboxStates() {
  const [tri, setTri] = useState<CheckboxCheckedState>("indeterminate");
  return (
    <div style={{ display: "grid", gap: "12px" }}>
      <Checkbox name="off">기본 (off)</Checkbox>
      <Checkbox name="on" defaultChecked>선택됨</Checkbox>
      <Checkbox
        name="mix"
        checked={tri}
        onCheckedChange={(next) => {
          // 3-cycle: indeterminate → on → off → indeterminate
          if (tri === "indeterminate") setTri(true);
          else if (tri === true) setTri(false);
          else setTri("indeterminate");
          void next; // controlled indeterminate 패턴에서는 다음 상태를 직접 결정
        }}
      >
        부분 선택 (클릭하면 3-cycle)
      </Checkbox>
      <Checkbox name="d-off" disabled>비활성 off</Checkbox>
      <Checkbox name="d-on" defaultChecked disabled>비활성 on</Checkbox>
    </div>
  );
}

필수 동의 + 검증

required marker, submit 검증, error 표시

등록 전 필수 확인입니다.

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

// required prop → label 옆 * marker 자동 (aria-hidden, Input/Select 정합).
// submit 미체크 시 error prop 노출 — description 자리에 빨강 메시지 표시 (a11y 표준).
// 체크 시 error 즉시 해제 (FormField 패턴과 동일한 description ↔ error 교체).
export function CheckboxRequiredLive() {
  const [agreed, setAgreed] = useState(false);
  const [error, setError] = useState<string | undefined>();
  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (!agreed) setError("필수 동의 항목입니다.");
    else setError(undefined);
  };
  return (
    <form onSubmit={handleSubmit} style={{ display: "grid", gap: "12px" }}>
      <Checkbox
        name="agree"
        description="등록 전 필수 확인입니다."
        required
        checked={agreed}
        onCheckedChange={(c) => { setAgreed(c === true); if (c) setError(undefined); }}
        error={error}
      >
        시험 정책에 동의합니다.
      </Checkbox>
      <Button type="submit">제출</Button>
    </form>
  );
}