Tiro
Tiro Design
Components

Button

사용자의 액션을 트리거하는 컴포넌트. Type과 Layout을 조합해 다양한 형태를 구성할 수 있다.

Preview


Anatomy

Button
├─ Type    primary / secondary / outlined / ghost / text / destructive
└─ Layout  text-only / icon+text / text+icon / icon-only

Type은 컨테이너의 시각적 강조 수준을 결정하고, Layout은 내부 요소(아이콘·텍스트)의 구성을 결정한다. 두 축은 독립적으로 조합된다.


Type

Type언제
primary화면 내 주요 CTA. 페이지당 하나
secondaryPrimary와 나란히 쓰는 대안 액션. "저장/취소", "확인/닫기"처럼 두 선택지를 동등하게 제시할 때. 배경 fill로 버튼의 무게감을 맞춤
outlinedPrimary 없이 단독으로 쓰는 보조 액션. 테이블 행·리스트 아이템처럼 밀도 높은 UI에서 반복 등장하거나, 강조도가 secondary보다 낮아야 할 때
ghost툴바·헤더·네비 등 컨테이너 없이 아이콘/텍스트만으로 충분한 맥락에서 사용
text문장 안에 자연스럽게 녹아드는 인라인 링크성 액션. 독립 버튼 영역 없이 흐름 내에서만
destructive삭제·초기화 등 되돌릴 수 없는 액션. 반드시 확인 단계와 함께 사용

secondaryoutlined는 역할이 다른 별도 type이다. secondary outlined 같은 hybrid는 만들지 않는다.

outlined는 기본 상태에서 transparent를 유지한다. hover/pressed에서만 현재 surface에 맞는 약한 fill을 받는다.


Layout

Layout은 버튼 내부의 요소 구성을 결정한다. Type과 독립적으로 조합된다.

텍스트만


아이콘 + 텍스트

아이콘을 **좌측(Prefix)**에 배치한다. 아이콘이 액션의 의미를 보강할 때 사용한다.

  • 아이콘 크기: Foundations/Iconography 기준 — icon+text는 md 16px 기본
  • 아이콘과 텍스트 간격: size별로 다름 — xs/smgap-1.5 (6px), md/lg/xlgap-2 (8px). 자세한 값은 아래 Sizes 표 참조
  • strokeWidth={1.75} 필수 (Tiro 기본값)

텍스트 + 아이콘

아이콘을 **우측(Suffix)**에 배치한다. Chevron(방향 이동)과 외부 링크 아이콘에 한정한다.

  • text type과 함께 주로 사용
  • Suffix 아이콘을 일반 의미 전달에 사용하지 않는다 — 그 경우는 Prefix

아이콘만

라벨 없이 아이콘만으로 의미가 명확한 액션에 사용한다. 툴바, 헤더, 리스트 행 등.

  • 정사각형: sm 32×32 / md 40×40 / lg 44×44
  • aria-label 필수
  • 실면적이 32px 미만이면 invisible padding으로 최소 44pt 확보 (iOS HIG)

States

State처리
hovertype별 bg/color 변경
pressedbrown-900 (primary) / stone-300 (secondary)
focus-visiblering-2 ring-offset-2 ring-brown-800
disabledopacity-50 + pointer-events-none
loadinginline Spinner · aria-busy="true"
selected (icon-only)bg-brown-50 배경

Disabled

모든 type에 동일하게 opacity-50 pointer-events-none을 적용한다. 색상을 type별로 따로 오버라이드하지 않는다.

  • disabled HTML 속성과 함께 사용 (aria-disabled="true" 대안 가능)
  • 비활성 이유가 사용자에게 불명확할 때는 Tooltip으로 이유 제공

Sizes

SizeHeightSquare (icon-only)아이콘 — icon+text아이콘 — icon-onlypx / pygap (icon+text)TextPrimary useMobile (≥44pt hit area)
xs28px28×28xs 12pxsm 14px12 / 6gap-1.5 (6px)caption1Regular 12/16 (medium override)태그·칩·인라인 액션 · rounded-full 전용hitSlop으로 hit area 44pt 확장 필수
sm32px32×32sm 14pxmd 16px10 / 6gap-1.5 (6px)button2Medium 13/20Dense UI (form primary 금지)hitSlop으로 hit area 44pt 확장 필수
md40px40×40md 16pxlg 20px16 / 10gap-2 (8px)button2Medium 13/20Default (web)hitSlop 4pt 권장
lg44px44×44lg 20pxxl 24px20 / 10gap-2 (8px)button1Medium 15/24Mobile primary CTA✓ 기본 충족
xl52pxlg 20px24 / 14gap-2 (8px)button1Medium 15/24Desktop Hero primary사용 안 함 (모바일은 lg까지)

Platform defaults

  • Default size: md — 일반 UI 액션의 표준
  • xl은 Hero CTA(랜딩, 마케팅 페이지의 단일 메인 액션) 전용
  • sm 32×32 icon-only는 마우스/트랙패드 입력에서 충분한 hit area
  • xsrounded-full(pill) 전용 — 태그·필터·인라인 선택형 액션에만 사용
  • xl은 icon-only 레이아웃 없음
  • 아이콘 크기 기준: Foundations/Iconography (xs 12 / sm 14 / md 16 / lg 20 / xl 24)
  • smxl Radius: r2rounded-lg (8px)

Spec

Typebgbg (hover)textborder
primarybrown-800brown-700white
secondarystone-50stone-100brown-800
outlinedstone-50brown-800stone-200
ghoststone-50brown-800
ghost (muted)stone-50 (icon-only) / — (text)stone-400stone-600
textbrown-600brown-900
destructiverose-600rose-700white

Muted Ghost / Icon-only

툴바 · 헤더 · 보조 컨트롤 등에서 ghost 버튼이 주변 요소에 비해 시각적으로 더 물러서야 할 때는 텍스트 · 아이콘 색상을 stone-400으로 낮춘다. hover 시에는 stone-600으로 진하게 올려 인터랙티브함을 전달한다.

배경 fill이 필요하면 icon-only에 한해 hover:bg-stone-50을 추가한다. 텍스트만인 muted ghost는 hover 시 배경 없이 color 변화만으로 충분하다.


Destructive Ghost / Icon-only

텍스트나 아이콘이 rose-* 계열이면 hover 배경도 rose-50을 사용한다. stone-50을 사용하지 않는다.


Usage

// 텍스트만 — primary
<Button>기록 시작</Button>

// 아이콘 + 텍스트
<Button layout="icon-text" prefixIcon={<Mic size={16} />}>녹음 시작</Button>

// 텍스트 + 아이콘 (text type + chevron)
<Button type="text" layout="text-icon" suffixIcon={<ChevronRight size={16} />}>
  최근 2주간의 미팅을 요약해줘
</Button>

// 아이콘만 — ghost
<Button layout="icon-only" aria-label="닫기"><X size={20} /></Button>

// Loading
<Button loading disabled>저장 중...</Button>

A11y

  • icon-only 레이아웃: aria-label (web) / accessibilityLabel (mobile) 필수 — 옵션 아님
  • 툴바 그룹 내 icon-only 버튼은 순차 focus 가능해야 함
  • text type은 링크처럼 보이지만 <button> 유지 — 페이지 이동이면 <a> 사용
  • loading 상태에서 aria-busy="true" 추가 권장

Do / Don't

  • Do: 리스트 행 또는 Item 컴포넌트 내부에 버튼을 배치할 때는 한 단계 작은 사이즈를 사용한다 — 기본 맥락이 md이면 sm, sm이면 xs로 낮춘다. 행의 밀도에 맞게 크기를 줄여 시각적 균형을 유지한다.
  • Do: Primary는 화면당 하나의 주요 액션에만
  • Do: Suffix 아이콘은 Chevron·외부 링크에만 — 의미 전달용 아이콘은 Prefix
  • Do: icon-only 레이아웃에는 aria-label 항상 제공
  • Do: text type은 흐름 내 보조 액션에만 — 주요 CTA 금지
  • Do: Ghost 버튼이 주변 요소보다 시각적으로 물러서야 할 때는 stone-400 (muted) 사용 — hover 시 stone-600으로 올림
  • Don't: Ghost를 주요 CTA로 사용 금지
  • Don't: Primary 여러 개를 한 화면에 배치 금지
  • Don't: brown 외 액센트 컬러 도입 금지
  • Don't: 텍스트 없이 의미 전달이 불확실한 경우 icon-only 사용 금지
  • Don't: 선택·활성 상태를 아이콘 색상만으로 표현하지 않음 — 배경색·테두리 병행
  • Don't: rose 텍스트·아이콘 버튼에 hover:bg-stone-50 사용 금지 — 반드시 hover:bg-rose-50

On this page