@olundot/ui · Selection
Chip
선택 가능한 작은 라벨 — 필터, 카테고리, 제거 가능 태그 등 선택하거나 제거할 수 있는 분류에 사용합니다.
- 변형 (variant)
- filter (선택 토글) / choice (단일 선택) / status-filter (상태 tone) / removable (X 버튼)
- 톤 (tone)
- neutral / accent / success / warning / danger / muted — 맥락별 시각 구분
- pressed 상태
- pressed prop으로 선택 상태를 표시합니다. accent tone은 선택 wash를 사용하고 수량 표시는 solid 배지를 유지합니다.
- 정적 라벨과 차이
- Chip은 클릭, 토글, 제거가 가능한 선택 라벨입니다. 상호작용이 없는 분류 라벨은 Badge variant=pill을 사용합니다.
- 크기
- sm (26px) · md (30px, 기본) · lg (34px)
- 수량 표시
- count prop으로 숫자 배지를 추가해 필터 결과 수 등을 표시합니다.
필터 도구줄
필터 선택 상태를 즉시 전환코드 보기tsx
import { useState } from "react";
import { Chip } from "@olundot/ui";
const SUBJECTS = ["전체", "내과", "외과", "소아과", "산부인과"];
// filter variant: 단일 선택 토글 그룹. pressed=true 시 accent solid fill.
// tone="accent" + pressed=true → --accent-solid 배경 + --accent-on-solid 텍스트.
export function ChipFilter() {
const [selected, setSelected] = useState<string>("전체");
return (
<div role="group" aria-label="과목 필터" style={{ display: "flex", gap: "8px", flexWrap: "wrap" }}>
{SUBJECTS.map((subject) => (
<Chip
key={subject}
variant="filter"
tone="accent"
pressed={selected === subject}
onClick={() => setSelected(subject)}
aria-pressed={selected === subject}
>
{subject}
</Chip>
))}
</div>
);
}단일 선택
라디오 대신 조밀한 단일 선택코드 보기tsx
import { useState } from "react";
import { Chip } from "@olundot/ui";
const TYPES = ["객관식", "단답형", "서술형", "OX"];
// choice variant: 라디오 버튼 대체 — 단일 선택.
// neutral tone: 기본 surface 배경 · pressed → action-selected.
export function ChipChoice() {
const [selected, setSelected] = useState<string>("객관식");
return (
<div role="group" aria-label="문항 유형 선택" style={{ display: "flex", gap: "8px", flexWrap: "wrap" }}>
{TYPES.map((type) => (
<Chip
key={type}
variant="choice"
pressed={selected === type}
onClick={() => setSelected(type)}
aria-pressed={selected === type}
>
{type}
</Chip>
))}
</div>
);
}제거 가능
선택된 필터를 바로 제거내과외과소아과
코드 보기tsx
import { useState } from "react";
import { Chip } from "@olundot/ui";
// removable variant: X 버튼 자동 추가. removeLabel로 스크린리더 이름 지정 필수.
// onClick 핸들러가 chip 전체(X 포함)의 클릭을 처리 → 목록에서 해당 항목 제거.
export function ChipRemovable() {
const initial = ["내과", "외과", "소아과"];
const [chips, setChips] = useState(initial);
return (
<div role="group" aria-label="선택된 필터" style={{ display: "flex", gap: "8px", flexWrap: "wrap" }}>
{chips.map((chip) => (
<Chip
key={chip}
variant="removable"
removeLabel={`${chip} 제거`}
onClick={() => setChips(chips.filter((c) => c !== chip))}
>
{chip}
</Chip>
))}
</div>
);
}크기
화면 밀도와 도구줄 높이에 맞춰 크기 선택코드 보기tsx
import { Chip } from "@olundot/ui";
// Chip size 3종 — 조밀한 화면(sm=26px) · 기본(md=30px) · 여유 있는 도구줄(lg=34px).
export function ChipSizes() {
return (
<div style={{ display: "flex", gap: "12px", alignItems: "center", flexWrap: "wrap" }}>
<Chip size="sm">sm 26px</Chip>
<Chip size="md">md 30px (기본)</Chip>
<Chip size="lg">lg 34px</Chip>
</div>
);
}색조 비교
상태 필터의 의미에 맞춰 색조 선택코드 보기tsx
import { Chip } from "@olundot/ui";
// status-filter variant + 6 tone: 상태 분류 chip — 색으로 맥락 구분.
// neutral / accent / success / warning / danger / muted 각각 semantic token 사용.
export function ChipTones() {
return (
<div style={{ display: "flex", gap: "8px", flexWrap: "wrap", alignItems: "center" }}>
<Chip tone="neutral" variant="status-filter">중립</Chip>
<Chip tone="accent" variant="status-filter">브랜드</Chip>
<Chip tone="success" variant="status-filter">성공</Chip>
<Chip tone="warning" variant="status-filter">경고</Chip>
<Chip tone="danger" variant="status-filter">위험</Chip>
<Chip tone="muted" variant="status-filter">음소거</Chip>
</div>
);
}비활성
사용할 수 없는 필터를 낮은 강조로 표시코드 보기tsx
import { Chip } from "@olundot/ui";
export function ChipDisabled() {
return (
<div style={{ display: "flex", gap: "8px", flexWrap: "wrap", alignItems: "center" }}>
<Chip disabled>잠긴 필터</Chip>
</div>
);
}