Tiro
Tiro Design
Foundations

Iconography

Tiro UI 아이콘 시스템. Lucide를 단일 소스로 사용합니다.

Tiro의 아이콘은 기능을 빠르게 인식시키는 기능적 도구입니다. 장식이 아니라 의미를 전달하고, 텍스트를 보조하며, 인터페이스를 조용하게 만드는 역할을 합니다.

Tiro 디자인 언어의 "조용한 권위"에 맞게, 아이콘도 강하게 주장하지 않습니다. Stroke-width를 Lucide 기본(2)보다 한 단계 낮춰 1.75를 기본으로 사용하는 것이 그 반영입니다.

Library

Lucide — Tiro UI 아이콘의 유일한 소스.

브라우저lucide.dev/icons
Web / Desktoplucide-react
Mobilelucide-react-native
라이선스ISC (사용·수정·재배포 자유)

Lucide에 없을 때만 Custom SVG를 추가합니다. 다른 라이브러리(Font Awesome, Heroicons, Material Icons)는 금지입니다.

Visual Style

Grid & Size

Lucide 아이콘은 24 × 24px viewBox 기준으로 설계되어 있습니다. UI에서는 크기를 4종으로 제한합니다.

SizepxPrimary use
sm14 × 14Dense UI, 인라인 텍스트 옆
md16 × 16Default — 대부분의 UI
lg20 × 20리스트 leading, 강조 아이콘
xl24 × 24AppBar, 툴바, hero 아이콘

새 크기 추가는 DS Owner 협의 필요. 현재 4단계로 충분합니다.

Rendering Box

아이콘이 찌그러지거나 서로 다른 크기로 보이는 문제를 막기 위해, slot sizeglyph size를 분리합니다.

  • Slot: 레이아웃에서 아이콘이 차지하는 고정 정사각형 영역
  • Glyph: slot 중앙에 렌더되는 실제 Lucide 아이콘 크기

아이콘은 SVG 자체로 레이아웃을 잡지 않습니다. 항상 고정된 slot 안에 중앙 정렬합니다.

ContextSlotGlyphUse
Inline text16 × 1614 × 14문장·chip·dense label 옆
Menu/List prefix24 × 2416 × 16menu item, list row leading icon
Header action32 × 3224 × 24app bar, top navigation
Icon-only buttoncomponent sizesize별 glyphButton 문서의 icon-only size 사용
Media icon container40 × 4018–20 × 18–20Item media, settings row
// Web
<span className="grid h-6 w-6 shrink-0 place-items-center text-stone-500">
  <Folder className="h-4 w-4" strokeWidth={1.75} aria-hidden />
</span>

// React Native
<View className="h-[24px] w-[24px] shrink-0 items-center justify-center">
  <Folder size={16} strokeWidth={1.75} color={color} />
</View>

SVG에는 stretch, flex-1, w-full, h-full, aspect-auto를 적용하지 않습니다. 부모가 flex-row일 때도 slot은 반드시 shrink-0 / flex: 0 0 auto여야 합니다.

// Good — slot과 glyph 크기 분리
<span className="grid h-6 w-6 shrink-0 place-items-center">
  <Search className="h-4 w-4" strokeWidth={1.75} />
</span>

// Bad — SVG 자체가 flex item 크기를 담당
<Search className="flex-1 w-full h-full" />

인라인 SVG를 직접 작성해야 하는 경우에도 viewBox="0 0 24 24"와 실제 width/height 비율은 1:1로 유지합니다.

// Good
<svg width="16" height="16" viewBox="0 0 24 24" />

// Bad — 비율이 달라져 찌그러짐
<svg width="20" height="16" viewBox="0 0 24 24" />

Custom Shape Fit

Folder, TeamFolder, logo-like mark처럼 fill이 들어가거나 시각적 무게가 큰 custom SVG는 Lucide보다 크게 보일 수 있습니다. 이 경우 SVG를 늘리거나 납작하게 만들지 말고, 같은 slot 안에서 glyph만 1단계 줄입니다.

// 24px slot에서 heavy custom glyph는 14px로 조정
<span className="grid h-6 w-6 shrink-0 place-items-center">
  <TeamFolderIcon size={14} color={thread.color} />
</span>

Stroke

용도strokeWidth
Default (Tiro)1.75
Decorative (배경/일러스트)1.5
강조 (heavy, 드물게)2.0

Lucide 기본값은 2.0이지만 Tiro는 1.75로 톤다운합니다. Lucide 아이콘을 그대로 쓰면 strokeWidth={1.75} prop을 명시해야 합니다.

Style — Line only

Tiro는 Line(stroke) 스타일만 사용합니다. Fill 아이콘은 단 하나의 예외를 제외하면 사용하지 않습니다.

Style사용
Line (default)모든 UI 아이콘
Fill녹음 중 dot (Circle fill-rose-600) 단일 예외

Color

아이콘은 항상 currentColor를 상속합니다. 색상 하드코딩은 금지입니다. 부모의 텍스트 색상을 따르므로 disabled, muted, primary 맥락에서 자동으로 적절한 톤을 갖습니다.

// ✅
<Search size={20} strokeWidth={1.75} />         // currentColor 상속

// ❌
<Search size={20} color="#3A2018" />             // 하드코딩 금지

Naming Convention

Lucide는 kebab-case URL을 제공합니다. React import 시 PascalCase로 변환합니다.

Lucide URLImport
lucide.dev/icons/searchSearch
lucide.dev/icons/chevron-rightChevronRight
lucide.dev/icons/more-horizontalMoreHorizontal
lucide.dev/icons/file-audioFileAudio

모르면 Lucide 사이트에서 "Copy as React" 버튼 사용.

Usage in UI

Decorative vs. Semantic

용도처리
텍스트 옆 보조 아이콘aria-hidden={true}
의미 전달 단독 아이콘aria-label 또는 accessibilityLabel 필수
// Decorative — 텍스트와 함께
<Search aria-hidden size={16} strokeWidth={1.75} />
<span>검색</span>

// Semantic — 아이콘만
<Trash2 size={16} strokeWidth={1.75} aria-label="삭제" />

Interactive Icons

클릭 가능한 아이콘은 반드시 IconButton 컴포넌트로 감쌉니다. 아이콘에 직접 onClick을 붙이지 않습니다. 터치 영역, focus ring, a11y가 IconButton에서 처리됩니다.

Tiro 빈출 아이콘

제품 내 자주 쓰이는 아이콘 레퍼런스. 아이콘명이 헷갈릴 때 참고.

용도Lucide
검색Search
설정Settings
더보기 (메뉴)MoreHorizontal (수평) · MoreVertical (리스트 행)
닫기X
뒤로 / 앞으로ChevronLeft · ChevronRight
펼치기 / 접기ChevronDown · ChevronUp
추가Plus
편집PencilLine
삭제Trash2
공유Share2
다운로드 / 업로드Download · Upload
복사Copy
즐겨찾기Star
알림Bell
사용자User · UserPlus · Users
파일 / 노트FileText
마이크Mic · MicOff
재생 / 일시정지 / 정지Play · Pause · Square
녹음 중 dotCircle (fill-rose-600)
정보Info
경고AlertTriangle · AlertCircle
성공CheckCircle2
외부 링크ExternalLink
언어 / 번역Languages
필터 / 정렬Filter · SlidersHorizontal · ArrowUpDown

항상 Lucide 사이트를 최종 레퍼런스로 사용합니다. 이 표는 빠른 참고용입니다.

Custom SVG

Lucide에 없는 글리프가 필요할 때만 추가합니다.

추가 전 체크리스트:

  • Lucide에서 유사 아이콘 없는지 재확인 (lucide.dev/icons/?search=...)
  • 24 × 24 viewBox, stroke-based, 1.75 strokeWidth 기준 준수
  • viewBox 비율과 렌더링 width/height 비율이 동일한지 확인
  • slot 없이 SVG 자체가 flex/grid item 크기를 담당하지 않는지 확인
  • stroke/fill이 viewBox 가장자리에 닿지 않도록 최소 1–2px optical padding 확보
  • Lucide 스타일(라운드 캡/조인)과 시각적으로 일관된지 확인
  • DS Owner 리뷰

저장 위치:

플랫폼경로
Web / Desktoppackages/tds/icons/*.tsx
Mobileapps/mobile/src/components/icons/*.tsx

포맷: SVG → React 컴포넌트. Lucide와 동일한 props API(size, strokeWidth, color) 노출.

네이밍: 기능 기반 PascalCase — TiroLogoMark, SpeakerDiarizationIcon.

Installation

# Web / Desktop
npm install lucide-react

# Mobile (React Native)
npm install lucide-react-native
# react-native-svg 피어 디펜던시 필요 (Expo는 내장)

Do / Don't

  • Do: Lucide에서 먼저 찾기 — 1,500+ 아이콘 대부분 커버됨
  • Do: strokeWidth={1.75} 기본 사용
  • Do: 색상은 currentColor 상속
  • Do: slot size와 glyph size를 분리해 고정 정사각형 slot 안에 중앙 정렬
  • Do: 클릭 가능한 아이콘은 IconButton으로 감싸기
  • Do: 의미 전달 단독 아이콘에 aria-label 필수
  • Don't: Font Awesome · Heroicons · Material Icons 등 혼용 금지
  • Don't: 색상 하드코딩 금지 (color="#3A2018")
  • Don't: SVG에 flex-1, w-full h-full, 비정사각 width/height를 적용해 늘리기 금지
  • Don't: Lucide 아이콘 수정 사용 금지 — 필요하면 Custom SVG로 추가
  • Don't: 아이콘 색상만으로 상태 전달 금지 — 텍스트 병행

On this page