@ehfuse/chip
v0.2.0
Published
Dependency-free React chip & count badge with correct optical vertical centering (pill / rounded / square)
Readme
@ehfuse/chip
의존성 없는 React 칩·숫자 배지. 알약(pill)·둥근 사각(rounded)·각진 사각(square) 모양을 지원한다.
react 하나만 peer dependency 이고, CSS 파일을 따로 불러올 필요가 없다(인라인 스타일).
npm i @ehfuse/chip왜 만들었나 — 세로정렬
칩 안의 글자가 위아래로 미묘하게 어긋나는 문제는 모양과 무관하게 늘 같은 원인에서 온다. 곳곳에 칩을 따로 만들면 그 보정도 곳곳에서 제각각 어긋난다. 규칙을 한 곳에 못 박으려고 분리했다.
실측으로 확인한 결론 셋:
line-height: 1로 못 박는다. 기본값normal이면 글꼴이 위아래로 서로 다른 여백을 붙이고, 가운데 정렬은 그 줄 상자를 기준으로 잡히므로 글자가 한쪽으로 쏠린다.line-height를 칩 높이와 같게 주지 않는다. 줄 상자가 칩을 꽉 채워 flex 세로 중앙정렬이 무력화되고, 글자 위치를 글꼴 baseline 이 정해 버린다.- 픽셀 보정(padding 으로 밀기)을 두지 않는다. 캔버스 메트릭으로 "잉크 상자 중심 = 칩 중심"을 맞추면 오히려 눈에는 위로 뜬 것처럼 보인다 — 글자는 baseline 아래 오버슛(둥근 3·8 등)까지 잉크에 들어가는데, 사람이 느끼는 중심은 그 아래 획을 뺀 자리이기 때문이다.
그래서 세로 여백을 주지 않고 높이만 고정한 뒤 line-height: 1 + flex 중앙정렬에만 맡긴다.
새 글꼴에서 다시 어긋나 보이더라도 메트릭 계산보다 실제 화면을 믿는 편이 정확했다.
사용
import { Chip, CountBadge } from "@ehfuse/chip";
// 숫자 배지 — 99 를 넘으면 "99+"
<CountBadge count={12} background="#d32f2f" />
<CountBadge count={0} /> // 0 이면 그리지 않는다
<CountBadge count={128} max={99} shape="rounded" background="#1d4ed8" />
// 분류 태그
<Chip label="공지사항" background="#1d4ed8" />
<Chip label="보관함" variant="outlined" background="#64748b" />
<Chip label="연동됨" variant="soft" background="#dcfce7" color="#166534" />
// 누를 수 있는 필터 칩 — onClick 을 주면 <button> 으로 그려진다
<Chip label="전체" size="md" variant="outlined" background="#0f2a5c"
selected={selected} onClick={() => setSelected(true)} />API
<Chip>
| prop | 기본값 | 설명 |
| --- | --- | --- |
| label / children | — | 칩 내용 |
| shape | "pill" | pill | rounded | square |
| variant | "filled" | filled | outlined | soft |
| size | "sm" | sm(18) | md(24) | lg(32) — md·lg 는 MUI Chip 의 small·medium 과 같은 치수 |
| background | currentColor | 배경·테두리 기준색 |
| color | variant 기본 | 글자색 |
| borderColor | background | 테두리색만 따로 줄 때 |
| selected | false | 누른 상태 — filled 로 반전 |
| onClick | — | 주면 <button>, 없으면 <span> |
| weight | 700 | 글자 굵기 — 숫자 배지는 굵게, 분류 태그는 400~500 |
| radius | shape 기준 | 모서리 반지름을 직접 줄 때(px) |
| onDelete | — | 주면 오른쪽에 지우기(×). 칩 onClick 과 따로 동작한다 |
| disabled | false | |
| className / style | — | style 은 마지막에 병합돼 무엇이든 덮어쓴다 |
<CountBadge>
Chip 의 모든 prop에 더해:
| prop | 기본값 | 설명 |
| --- | --- | --- |
| count | — | 표시할 개수 |
| max | 99 | 넘으면 99+ 로 자른다 |
| showZero | false | 0 일 때도 그릴지 |
라이선스
MIT
