Component
Button
Stable클릭으로 동작을 일으키는 가장 기본적인 인터랙션 단위.
01 Preview
실제 모습.
02 Rationale
왜 이렇게 만들었나.
- Variant는 3개로 한정했습니다. Material의 5개 이상에서 의사결정 비용을 의식적으로 줄였습니다.
- Size도 sm/md/lg 세 단계. 흔한 4단계에서 한 단계 줄였습니다. 대부분 md로 끝납니다.
- Disabled는 opacity 곱이 아니라 별도 토큰을 씁니다. 곱셈은 대비비를 깨뜨립니다.
- Focus ring은 컴포넌트 안에 들어있습니다. 외부 페이지 스타일에 의존하지 않습니다.
03 Anatomy
어떻게 구성되는가.
- 01 Container — radius-md, border 1px, padding-sm/md/lg
- 02 Label — font-sans 600 weight (가운데 정렬)
- 03 Focus ring — :focus-visible 시 shadow-focus-ring
04 Props
속성.
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "primary" | "secondary" | "ghost" | primary | accent 배경 / 보더만 / hover-only |
size | "sm" | "md" | "lg" | md | 패딩과 폰트 크기 |
disabled | boolean | false | surface-subtle bg + text-disabled (대비 5.7:1 유지) |
type | string | "button" | 기본 button, 폼 안에서 submit 등 |
05 Usage
가져다 쓰기.
import Button from '@/components/Button.astro'; 06 Accessibility
접근성 체크리스트.
- 키보드 Tab으로 도달 가능, Enter/Space로 실행
- :focus-visible 시 3px primary 30% alpha ring
- 아이콘 전용 버튼은 aria-label 필수
- disabled 상태에서도 텍스트 대비 5.7:1 유지 (opacity 곱이 아니라 별도 토큰 사용)
07 Decision
언제 쓰고, 언제 쓰지 않는가.
When to use
- 명확한 액션 (저장, 보내기, 닫기)
- 폼 제출
- 주요 CTA
When not to
- 단순 페이지 이동 — Link 사용
- 토글 상태 표시 — Chip variant="active" 사용
- 6개 이상의 옵션 — Dropdown 검토
08 States
상태별 시각.
3가지 상태를 같은 자리에서 비교. 각 상태가 토큰을 어떻게 다르게 쓰는지.
| State | Primary | Secondary | Ghost |
|---|---|---|---|
| Idle | |||
| Focus | Primary button, focused state (visual demo) | Secondary button, focused state (visual demo) | Ghost button, focused state (visual demo) |
| Disabled |
09 Related