Icon | CoUI

Icon

CoUI 디자인 시스템의 아이콘 컴포넌트

Icon#

CoUI 디자인 시스템의 통일된 아이콘 컴포넌트입니다. Iconify 생태계(Lucide, Radix, Bootstrap, HeroIcons) 아이콘을 IconName 참조로 렌더합니다. Flutter와 Web이 동일한 API동일한 아이콘 레퍼런스를 사용합니다.

Live Preview#

사용 시기 (When to Use)#

이 컴포넌트를 사용하세요:

  • 버튼, 메뉴, 네비게이션 항목에 시각적 힌트가 필요할 때
  • 텍스트 없이 아이콘만으로 의미를 전달해야 할 때 (접근성 레이블 필수)
  • CoUI 디자인 시스템의 통일된 아이콘 세트를 사용할 때

대신 다른 컴포넌트를 사용하세요:

  • Badge: 아이콘 위에 숫자나 상태 표시가 필요할 때 IconBadge를 조합
  • Fab: 아이콘 버튼을 강조된 액션 버튼으로 표시할 때

기본 사용법 (Basic Usage)#

Icon의 모든 시각 커스터마이징은 iconStyle: CoreIconStyle(...)로 단일화되어 있습니다 (Epic #1302 — nested Style API).

// 기본 아이콘 (디자인 시스템 default — 24px / onSurface)
const Icon(LucideIcons.house);

// 크기 지정
const Icon(
  LucideIcons.house,
  iconStyle: CoreIconStyle(size: 28),
);

// 다른 아이콘 세트
const Icon(RadixIcons.chevronLeft, iconStyle: CoreIconStyle(size: 16));
const Icon(BootstrapIcons.gear, iconStyle: CoreIconStyle(size: 20));

// HeroIcons 스타일 선택
const Icon(HeroIcons.arrowLeft.outline, iconStyle: CoreIconStyle(size: 24));
const Icon(HeroIcons.arrowLeft.solid, iconStyle: CoreIconStyle(size: 24));

// 크기 + 색상
Icon(
  LucideIcons.heart,
  iconStyle: CoreIconStyle(
    size: 28,
    color: Theme.of(context).colorScheme.tertiary,
  ),
);

// 같은 스타일을 여러 인스턴스에 재사용
final dangerIcon = CoreIconStyle<Color>(
  size: 20,
  color: Theme.of(context).colorScheme.error,
);

Icon(LucideIcons.alertTriangle, iconStyle: dangerIcon);
Icon(LucideIcons.x, iconStyle: dangerIcon);
// 기본 아이콘
const Icon(LucideIcons.house);

// 크기 지정
const Icon(
  LucideIcons.house,
  iconStyle: CoreIconStyle(size: 28),
);

// 다른 아이콘 세트
const Icon(RadixIcons.chevronLeft, iconStyle: CoreIconStyle(size: 16));
const Icon(BootstrapIcons.gear, iconStyle: CoreIconStyle(size: 20));

// HeroIcons 스타일 선택
const Icon(HeroIcons.arrowLeft.outline, iconStyle: CoreIconStyle(size: 24));
const Icon(HeroIcons.arrowLeft.solid, iconStyle: CoreIconStyle(size: 24));

// 크기 + 색상 — Web 의 color 는 Tailwind colour token 문자열
Icon(
  LucideIcons.heart,
  iconStyle: CoreIconStyle(
    size: 28,
    color: context.colorScheme.tertiary, // 'tertiary' 토큰
  ),
);

Props / Parameters#

속성타입 (Flutter)타입 (Web)기본값설명
icon IconName IconName 필수 (positional) 표시할 아이콘 (LucideIcons.* 등)
iconStyle CoreIconStyle<Color>? CoreIconStyle<String>? null 아이콘 크기/색상 (Style 시스템 참조)

스타일 시스템 (Style System)#

Icon 의 모든 시각 오버라이드는 단일 iconStyle (CoreIconStyle<C>) 으로 흐릅니다 (Epic #1302 원칙 6/7/8). IconName 식별자만 위젯 파라미터로 직접 전달합니다.

CoreIconStyle<C> 슬롯#

Slot타입 (Flutter)타입 (Web)설명
size double? double? 아이콘 크기 (logical px). null → 다음 단계 inherit
color Color? String? (Tailwind colour token) 아이콘 색상. null → 다음 단계 inherit

CoreIconStyle.merge(other) — non-null 필드만 덮어씌우는 비파괴 합성. resolve chain의 핵심.

Resolve chain#

design system default
  → CoreIconTheme.style                        // 프로젝트 공통
  → parent component slot override             // 예: CoreButtonStyle.leadingIconStyle
  → widget.iconStyle                           // 인스턴스별

각 레이어는 CoreIconStyle 의 어떤 필드든 부분적으로 채울 수 있습니다. null 인 필드는 다음 레이어로 넘겨주고, non-null 인 필드는 해당 레이어에서 확정됩니다.

색상 처리 차이점#

  • Flutter: Color 객체로 받아 ColorFilter.mode(color, BlendMode.srcIn)으로 tint
  • Web: Tailwind colour token 문자열('tertiary' 등)로 받아 text-${token} class 적용
  • 양쪽 모두 currentColor 기반 SVG를 tint하는 결과는 동일

테마 연동#

프로젝트 레벨 기본값은 CoreComponentTheme.iconCoreIconTheme.style로 지정합니다.

CoUIApp(
  theme: CoreComponentTheme(
    icon: CoreIconTheme(
      style: CoreIconStyle(
        size: 20,
        color: Theme.of(context).colorScheme.onSurfaceVariant,
      ),
    ),
  ),
  child: ...,
)

이후 iconStyle이 null이거나 size/color가 null인 모든 Icon은 위 default를 따릅니다.

크기 권장값#

용도크기
인라인 텍스트16.0
버튼 내 아이콘20.0
기본 아이콘24.0
강조 아이콘32.0
히어로 아이콘48.0

접근성 (Accessibility)#

  • 아이콘은 시각적 요소이므로, 텍스트 레이블이 없는 독립 아이콘에는 tooltip 또는 부모 aria-label을 제공하세요
  • Flutter: Semantics wrapper 사용
  • Web: <iconify-icon>은 기본적으로 aria-hidden 상태 — 의미 전달이 필요하면 부모 요소에 aria-label 지정
  • Button: 아이콘을 액션 버튼 내에 포함할 때 — CoreButtonStyle.leadingIconStyle / trailingIconStyle로 nested
  • Badge: 아이콘 위에 알림 카운트 표시
  • Fab: 아이콘을 주요 액션 FAB로 표시