Switch
설정을 켜고 끕니다. 토글 즉시 적용되며 저장 버튼이 없습니다. 저장이 필요한 폼 안에서는 Checkbox 를 씁니다.
1. Default
꺼진 기본 상태입니다.
HTML
<label class="switch"><input type="checkbox" role="switch"><span>실시간 보호</span></label>CSS · .switch
/* JS Design System v0.6 · .switch · 토큰(var(--*))은 assets/style.css :root 참고 */
.switch{display:inline-flex;align-items:center;gap:10px;font-size:14px;cursor:pointer}
.switch input{appearance:none;-webkit-appearance:none;flex:none;width:44px;height:24px;margin:0;border-radius:var(--radius-full);background:var(--border-strong);position:relative;cursor:inherit;transition:background var(--motion-fast)}
.switch input::after{content:"";position:absolute;top:2px;left:2px;width:20px;height:20px;background:var(--static-white);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2224%22 height=%2224%22 viewBox=%220 0 24 24%22 fill=%22black%22 %3E%3Cpath d=%22M7 3.34a10 10 0 1 1 -4.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 4.995 -8.336z%22 /%3E%3C/svg%3E") center/120% no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2224%22 height=%2224%22 viewBox=%220 0 24 24%22 fill=%22black%22 %3E%3Cpath d=%22M7 3.34a10 10 0 1 1 -4.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 4.995 -8.336z%22 /%3E%3C/svg%3E") center/120% no-repeat;transition:left var(--motion-fast)}
.switch input:checked{background:var(--accent)}
.switch input:checked::after{left:22px}
.switch input:disabled{opacity:.4;cursor:not-allowed}
.switch input:disabled+span{color:var(--text-disabled)}
.switch.sm input{width:36px;height:20px}
.switch.sm input::after{width:16px;height:16px}
.switch.sm input:checked::after{left:18px}
.switch.label-left{flex-direction:row-reverse}React · @jiran/ds-react
import { Switch } from "@jiran/ds-react";
export default function Example() {
return <Switch>실시간 보호</Switch>;
}2. State
input[type=checkbox] 에 role=switch. Off · On · Disabled.
HTML
<label class="switch"><input type="checkbox" role="switch"><span>Off</span></label>
<label class="switch"><input type="checkbox" role="switch" checked><span>On</span></label>
<label class="switch"><input type="checkbox" role="switch" disabled><span>Disabled</span></label>
<label class="switch"><input type="checkbox" role="switch" checked disabled><span>Disabled on</span></label>CSS · .switch
/* JS Design System v0.6 · .switch · 토큰(var(--*))은 assets/style.css :root 참고 */
.switch{display:inline-flex;align-items:center;gap:10px;font-size:14px;cursor:pointer}
.switch input{appearance:none;-webkit-appearance:none;flex:none;width:44px;height:24px;margin:0;border-radius:var(--radius-full);background:var(--border-strong);position:relative;cursor:inherit;transition:background var(--motion-fast)}
.switch input::after{content:"";position:absolute;top:2px;left:2px;width:20px;height:20px;background:var(--static-white);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2224%22 height=%2224%22 viewBox=%220 0 24 24%22 fill=%22black%22 %3E%3Cpath d=%22M7 3.34a10 10 0 1 1 -4.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 4.995 -8.336z%22 /%3E%3C/svg%3E") center/120% no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2224%22 height=%2224%22 viewBox=%220 0 24 24%22 fill=%22black%22 %3E%3Cpath d=%22M7 3.34a10 10 0 1 1 -4.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 4.995 -8.336z%22 /%3E%3C/svg%3E") center/120% no-repeat;transition:left var(--motion-fast)}
.switch input:checked{background:var(--accent)}
.switch input:checked::after{left:22px}
.switch input:disabled{opacity:.4;cursor:not-allowed}
.switch input:disabled+span{color:var(--text-disabled)}
.switch.sm input{width:36px;height:20px}
.switch.sm input::after{width:16px;height:16px}
.switch.sm input:checked::after{left:18px}
.switch.label-left{flex-direction:row-reverse}React · @jiran/ds-react
import { Switch } from "@jiran/ds-react";
export default function Example() {
return (
<>
<Switch>Off</Switch>
<Switch defaultChecked>On</Switch>
<Switch disabled>Disabled</Switch>
<Switch defaultChecked disabled>Disabled on</Switch>
</>
);
}3. Size / Label Position
테이블 셀·밀도 높은 목록은 .sm. 설정 행에서는 라벨을 왼쪽에(.label-left).
HTML
<label class="switch sm"><input type="checkbox" role="switch" checked><span>Small</span></label>
<label class="switch label-left"><input type="checkbox" role="switch" checked><span>라벨 왼쪽</span></label>CSS · .switch
/* JS Design System v0.6 · .switch · 토큰(var(--*))은 assets/style.css :root 참고 */
.switch{display:inline-flex;align-items:center;gap:10px;font-size:14px;cursor:pointer}
.switch input{appearance:none;-webkit-appearance:none;flex:none;width:44px;height:24px;margin:0;border-radius:var(--radius-full);background:var(--border-strong);position:relative;cursor:inherit;transition:background var(--motion-fast)}
.switch input::after{content:"";position:absolute;top:2px;left:2px;width:20px;height:20px;background:var(--static-white);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2224%22 height=%2224%22 viewBox=%220 0 24 24%22 fill=%22black%22 %3E%3Cpath d=%22M7 3.34a10 10 0 1 1 -4.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 4.995 -8.336z%22 /%3E%3C/svg%3E") center/120% no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2224%22 height=%2224%22 viewBox=%220 0 24 24%22 fill=%22black%22 %3E%3Cpath d=%22M7 3.34a10 10 0 1 1 -4.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 4.995 -8.336z%22 /%3E%3C/svg%3E") center/120% no-repeat;transition:left var(--motion-fast)}
.switch input:checked{background:var(--accent)}
.switch input:checked::after{left:22px}
.switch input:disabled{opacity:.4;cursor:not-allowed}
.switch input:disabled+span{color:var(--text-disabled)}
.switch.sm input{width:36px;height:20px}
.switch.sm input::after{width:16px;height:16px}
.switch.sm input:checked::after{left:18px}
.switch.label-left{flex-direction:row-reverse}React · @jiran/ds-react
import { Switch } from "@jiran/ds-react";
export default function Example() {
return (
<>
<Switch size="sm" defaultChecked>Small</Switch>
<Switch labelLeft defaultChecked>라벨 왼쪽</Switch>
</>
);
}4. In Settings
정책 설정 행. 라벨·설명은 왼쪽, 스위치는 오른쪽 끝.
실시간 보호파일 실행 시 즉시 검사합니다
USB 자동 검사연결된 저장장치를 검사합니다
HTML
<div class="settings-section" style="max-width:560px">
<div class="setting"><div class="info"><b>실시간 보호</b><span>파일 실행 시 즉시 검사합니다</span></div><div class="ctrl"><label class="switch"><input type="checkbox" role="switch" checked aria-label="실시간 보호"></label></div></div>
<div class="setting"><div class="info"><b>USB 자동 검사</b><span>연결된 저장장치를 검사합니다</span></div><div class="ctrl"><label class="switch"><input type="checkbox" role="switch" aria-label="USB 자동 검사"></label></div></div>
</div>CSS · .switch
/* JS Design System v0.6 · .switch · 토큰(var(--*))은 assets/style.css :root 참고 */
.switch{display:inline-flex;align-items:center;gap:10px;font-size:14px;cursor:pointer}
.switch input{appearance:none;-webkit-appearance:none;flex:none;width:44px;height:24px;margin:0;border-radius:var(--radius-full);background:var(--border-strong);position:relative;cursor:inherit;transition:background var(--motion-fast)}
.switch input::after{content:"";position:absolute;top:2px;left:2px;width:20px;height:20px;background:var(--static-white);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2224%22 height=%2224%22 viewBox=%220 0 24 24%22 fill=%22black%22 %3E%3Cpath d=%22M7 3.34a10 10 0 1 1 -4.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 4.995 -8.336z%22 /%3E%3C/svg%3E") center/120% no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2224%22 height=%2224%22 viewBox=%220 0 24 24%22 fill=%22black%22 %3E%3Cpath d=%22M7 3.34a10 10 0 1 1 -4.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 4.995 -8.336z%22 /%3E%3C/svg%3E") center/120% no-repeat;transition:left var(--motion-fast)}
.switch input:checked{background:var(--accent)}
.switch input:checked::after{left:22px}
.switch input:disabled{opacity:.4;cursor:not-allowed}
.switch input:disabled+span{color:var(--text-disabled)}
.switch.sm input{width:36px;height:20px}
.switch.sm input::after{width:16px;height:16px}
.switch.sm input:checked::after{left:18px}
.switch.label-left{flex-direction:row-reverse}React · @jiran/ds-react
import { Setting, SettingsSection, Switch } from "@jiran/ds-react";
export default function Example() {
return (
<SettingsSection style={{ maxWidth: 560 }}>
<Setting title="실시간 보호" description="파일 실행 시 즉시 검사합니다">
<Switch defaultChecked aria-label="실시간 보호" />
</Setting>
<Setting title="USB 자동 검사" description="연결된 저장장치를 검사합니다">
<Switch aria-label="USB 자동 검사" />
</Setting>
</SettingsSection>
);
}Props
HTML 에서는 클래스와 속성으로, React(@jiran/ds-react)에서는 같은 이름의 prop(variant · size …)으로 변형·상태를 지정합니다.
| Prop / Class | Type · Values | Default | Description |
|---|---|---|---|
| .switch | label wrapper | — | input[type=checkbox][role=switch] + span |
| checked / disabled | attribute | — | 네이티브 상태 |
| size | (md) | sm | md | 44×24 / 36×20 |
| .label-left | boolean | false | 라벨을 왼쪽에 |
Usage
React: @jiran/ds-react 패키지를 설치하고 style.css 를 한 번 import 하면 위 React 탭 코드를 그대로 쓸 수 있습니다(React Package). HTML: assets/style.css 를 연결하고(일부만 필요하면 아래 컴포넌트 CSS 복사), 동작이 필요하면 assets/ds.js 를 함께 넣습니다 — 이 페이지의 프리뷰가 그 스크립트로 동작합니다. 색은 전부 토큰(var(--accent) 등)을 참조하므로 --accent-* 만 제품 컬러로 바꾸면 됩니다.
React @jiran/ds-react
npm i @jiran/ds-react
// main.tsx — 앱 진입점에서 한 번
import "@jiran/ds-react/style.css";
// 컴포넌트
import { Switch } from "@jiran/ds-react";HTML
<!-- 1) 토큰 + 전체 컴포넌트 스타일 한 번에 연결 -->
<link rel="stylesheet" href="assets/style.css">
<!-- 동작(드롭다운·탭·달력·표 정렬/선택·토스트 등) — 순수 JS 한 파일. React 제품은 불필요 -->
<script src="assets/ds.js" defer></script>
<!-- 2) 또는 아래 "Component CSS" 만 프로젝트 CSS 에 붙이고,
:root 토큰은 Foundations › Design Token 에서 복사 -->Component CSS .switch
/* JS Design System v0.6 · .switch · 토큰(var(--*))은 assets/style.css :root 참고 */
.switch{display:inline-flex;align-items:center;gap:10px;font-size:14px;cursor:pointer}
.switch input{appearance:none;-webkit-appearance:none;flex:none;width:44px;height:24px;margin:0;border-radius:var(--radius-full);background:var(--border-strong);position:relative;cursor:inherit;transition:background var(--motion-fast)}
.switch input::after{content:"";position:absolute;top:2px;left:2px;width:20px;height:20px;background:var(--static-white);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2224%22 height=%2224%22 viewBox=%220 0 24 24%22 fill=%22black%22 %3E%3Cpath d=%22M7 3.34a10 10 0 1 1 -4.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 4.995 -8.336z%22 /%3E%3C/svg%3E") center/120% no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2224%22 height=%2224%22 viewBox=%220 0 24 24%22 fill=%22black%22 %3E%3Cpath d=%22M7 3.34a10 10 0 1 1 -4.995 8.984l-.005 -.324l.005 -.324a10 10 0 0 1 4.995 -8.336z%22 /%3E%3C/svg%3E") center/120% no-repeat;transition:left var(--motion-fast)}
.switch input:checked{background:var(--accent)}
.switch input:checked::after{left:22px}
.switch input:disabled{opacity:.4;cursor:not-allowed}
.switch input:disabled+span{color:var(--text-disabled)}
.switch.sm input{width:36px;height:20px}
.switch.sm input::after{width:16px;height:16px}
.switch.sm input:checked::after{left:18px}
.switch.label-left{flex-direction:row-reverse}