변형 (variant)
filter (선택 토글) / choice (단일 선택) / status-filter (상태 tone) / removable (X 버튼)
톤 (tone)
neutral / accent / success / warning / danger / muted — context별 시각 구분
pressed 색감
tone=accent pressed → 선택 시 wash 패턴 — light: deep olive 14% 배경 + olive 전경/보더, dark: lime 16% 배경 + lime 전경/보더. count slot은 별도로 --accent-solid + --accent-on-solid solid 유지.
Tag와 차이
Chip은 interactive (클릭/토글/제거 가능). Tag는 정적 라벨 (Badge variant=pill alias). interactivity 기준 분리
크기
sm (26px) · md (30px, 기본) · lg (34px)
count slot
count prop으로 숫자 배지 추가 — 필터 결과 수 표시 등

필터 toolbar

라이브 (선택 토글 · tone=accent pressed solid fill)
코드 보기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>
  );
}

단일 선택

라이브 (choice variant · neutral tone)
코드 보기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>
  );
}

제거 가능

라이브 (variant=removable · X 버튼 제거)
코드 보기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>
  );
}

크기

정적 (sm · md · lg 3종 · 26/30/34px)
코드 보기tsx
import { Chip } from "@olundot/ui";

// Chip size 3종 — compact 화면(sm=26px) · 기본(md=30px) · 여유 있는 toolbar(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>
  );
}

색조 비교

정적 (6 tone · status-filter variant)
코드 보기tsx
import { Chip } from "@olundot/ui";

// status-filter variant + 6 tone: 상태 분류 chip — 색으로 context 구분.
// 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>
  );
}