@olundot/ui · Selection
ModeToggle
같은 수준의 보기 방식, 밀도, 테마처럼 즉시 전환되는 모드를 고르는 segmented control입니다.
- 상태
- active · inactive · disabled
- API
- options + value + onChange controlled pattern
- 접근성 기준
- role=group + aria-label + 각 항목 aria-pressed
테마 모드 선택
라이트 / 다크 / 시스템코드 보기tsx
import { useState } from "react";
import { Monitor, Moon, Sun } from "lucide-react";
import { ModeToggle } from "@olundot/ui";
const themeOptions = [
{ value: "light", label: "라이트", icon: Sun },
{ value: "dark", label: "다크", icon: Moon },
{ value: "system", label: "시스템", icon: Monitor },
] as const;
export function ThemeModeToggle() {
const [mode, setMode] = useState<(typeof themeOptions)[number]["value"]>("system");
return (
<ModeToggle
aria-label="테마 모드"
options={[...themeOptions]}
value={mode}
onChange={setMode}
/>
);
}보기 방식 전환
아이콘과 텍스트를 함께 제공코드 보기tsx
import { useState } from "react";
import { LayoutGrid, Table2 } from "lucide-react";
import { ModeToggle } from "@olundot/ui";
const viewOptions = [
{ value: "table", label: "표", icon: Table2 },
{ value: "card", label: "카드", icon: LayoutGrid },
] as const;
export function QuestionViewToggle() {
const [view, setView] = useState<(typeof viewOptions)[number]["value"]>("table");
return (
<ModeToggle
aria-label="문항 보기 방식"
options={[...viewOptions]}
value={view}
onChange={setView}
/>
);
}비활성 옵션
선택 불가 항목과 cursor 처리코드 보기tsx
import { useState } from "react";
import { LayoutGrid, Table2 } from "lucide-react";
import { ModeToggle } from "@olundot/ui";
const viewOptions = [
{ value: "table", label: "표", icon: Table2 },
{ value: "card", label: "카드", icon: LayoutGrid },
{ value: "analysis", label: "분석", disabled: true },
] as const;
export function DisabledModeToggle() {
const [view, setView] = useState<(typeof viewOptions)[number]["value"]>("table");
return (
<ModeToggle
aria-label="문항 보기 방식"
options={[...viewOptions]}
value={view}
onChange={setView}
/>
);
}제어 상태
onChange로 외부 상태 갱신현재 밀도: 넓게
코드 보기tsx
import { useState } from "react";
import { ModeToggle } from "@olundot/ui";
const densityOptions = [
{ value: "comfortable", label: "넓게" },
{ value: "compact", label: "조밀" },
] as const;
export function ControlledModeToggle() {
const [density, setDensity] = useState<(typeof densityOptions)[number]["value"]>("comfortable");
return (
<div className="grid gap-2">
<ModeToggle
aria-label="목록 밀도"
options={[...densityOptions]}
value={density}
onChange={setDensity}
/>
<p role="status" className="text-sm text-text-secondary">
현재 밀도: {density === "comfortable" ? "넓게" : "조밀"}
</p>
</div>
);
}