@olundot/ui · Indicators
Tag
Short removable or static label for categories, filters, ownership, and content attributes.
- 구현
- 정적 태그는 Badge(variant=pill), 제거 가능 태그는 Chip(variant=removable)으로 표현합니다.
- 정적 태그
- Badge variant=pill — non-interactive 카테고리 레이블
- 제거 가능 태그
- Chip variant=removable — removeLabel로 접근성 명칭 지정 필수
- 필터 토글
- Chip pressed prop — aria-pressed 자동 적용
정적 태그 (Badge pill)
정적 (Badge variant=pill 데모)CardiologyPharmacologyAnatomyPathology
코드 보기tsx
import { Badge } from "@olundot/ui";
// 정적 태그는 Badge variant="pill"로 표현합니다.
// 제거 가능한 태그는 Chip variant="removable"을 사용합니다.
export function TagStatic() {
return (
<div style={{ display: "flex", gap: "8px", flexWrap: "wrap" }}>
<Badge variant="pill">Cardiology</Badge>
<Badge variant="pill">Pharmacology</Badge>
<Badge variant="pill">Anatomy</Badge>
<Badge variant="pill">Pathology</Badge>
</div>
);
}제거 가능 (Chip)
라이브 (Chip variant=removable — 클릭 시 제거)코드 보기tsx
import { useState } from "react";
import { Chip } from "@olundot/ui";
// 제거 가능 태그는 Chip variant="removable"로 표현합니다.
// removeLabel은 스크린리더 접근성을 위해 구체적으로 작성합니다.
export function TagRemovable() {
const initial = ["Cardiology", "Pharmacology", "Anatomy", "Pathology"];
const [tags, setTags] = useState(initial);
return (
<div role="group" aria-label="선택된 과목 필터" style={{ display: "flex", gap: "8px", flexWrap: "wrap" }}>
{tags.map((tag) => (
<Chip
key={tag}
variant="removable"
removeLabel={`${tag} 제거`}
onClick={() => setTags(tags.filter((t) => t !== tag))}
>
{tag}
</Chip>
))}
{tags.length === 0 && (
<button onClick={() => setTags(initial)} style={{ fontSize: "0.875rem", color: "var(--text-tertiary)" }}>
초기화
</button>
)}
</div>
);
}필터 토글 (Chip)
라이브 (Chip pressed 토글 — 선택/해제)코드 보기tsx
import { useState } from "react";
import { Chip } from "@olundot/ui";
const SUBJECTS = ["전체", "내과", "외과", "소아과", "산부인과"];
export function TagFilter() {
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"
pressed={selected === subject}
onClick={() => setSelected(subject)}
aria-pressed={selected === subject}
>
{subject}
</Chip>
))}
</div>
);
}