Button
우선순위와 상태가 분명한 주요·보조 행동.
- 출시 화면에서 사용
개요
미리보기
예시
상태
기본
진행 중
비활성
아이콘
가장 긴 라벨 (es)
쓰임 예
주요
보조
조용한
삭제
작게
이동(href)
크게
이렇게 · 이렇게 하지 않기
- 이렇게 라벨은 누른 뒤 일어날 일을 동사로 말하고 es 18자 이하로 쓴다. 한 영역에 주요 버튼은 하나다. 시스템 행동 라벨에 “검증”, “확인”을 쓰지 않는다.
- 이렇게 화면마다 primary는 하나만 둔다. 나머지 행동은 secondary나 quiet로.
- 이렇게 라벨은 결과를 말하는 동사로 쓴다: “가져오기”, “연결 해제”.
- 이렇게 하지 않기 onClick + router.push로 이동을 흉내 내지 않는다. 이동이면 href를 준다(또는 Link).
- 이렇게 하지 않기 “확인했어요”처럼 시스템이 검토한 것처럼 읽히는 라벨을 쓰지 않는다. 시스템은 “읽음”만 한다.
- 이렇게 하지 않기 진행 중에 버튼을 disabled로 바꾸지 않는다. loading을 쓰면 초점이 유지된다.
토큰과 속성
| 이름 | 타입 | 기본값 | 설명 |
|---|---|---|---|
variant? | 'primary' | 'secondary' | 'quiet' | 'destructive' | primary | 강조 수준. primary는 화면당 하나. |
size? | 'sm' | 'md' | 'lg' | md | 높이 36 / 44 / 52px. sm도 누르는 영역은 44px. |
loading? | boolean | false | 진행 중. 폭을 유지하고 aria-busy를 켜며 다시 눌러도 실행하지 않는다. |
disabled? | boolean | false | 실제 disabled. 이유를 버튼 가까이에 적는다. |
icon? | ReactNode | none | 라벨 앞 장식 아이콘. 보조기술에는 숨긴다. |
fullWidth? | boolean | false | 부모 폭을 채운다. 좁은 화면의 주요 행동에만. |
href? | string | | 이동이면 목적지. <a>(next/link)로 렌더하고 모양은 같다. 비우면 <button>. disabled면 이동할 수 없으므로 <button disabled>로 남는다. |
children | ReactNode | 가져오기 | 보이는 라벨. 동사로 시작한다. |
ref | — | — | ref는 렌더된 <button> 또는 <a>로 전달된다. 초점 복귀에 쓴다. |
| 그 밖의 속성 | — | — | type(기본 "button"), onClick, name, value, form, aria-* 등 네이티브 button 속성은 그대로 전달된다. className·style은 받지 않는다. |
접근성
키보드: Tab으로 이동, Enter·Space로 실행. 초점 링 2px.
- loading은 aria-busy와 aria-disabled를 켜지만 실제 disabled는 아니어서 초점을 잃지 않는다.
- 아이콘만 있는 버튼은 만들지 않는다. IconButton은 aria-label을 요구한다.
- forced-colors에서 테두리를 ButtonText로 그려 모양을 유지한다.