Stat | CoUI

Stat

수치 통계를 레이블, 값, 트렌드와 함께 표시하는 컴포넌트

Stat#

대시보드나 리포트에서 주요 수치를 레이블, 값, 변동 지표와 함께 표시하는 통계 컴포넌트입니다. Flutter / Web 양쪽에서 동일한 Stat API 를 사용합니다.

Live Preview#

Web
Total Revenue
$45,231.89
+20.1%
Flutter
Loading Flutter...
class StatDefaultExample extends StatefulComponent {
  const StatDefaultExample({super.key});

  @override
  State<StatDefaultExample> createState() => _StatDefaultExampleState();
}

class _StatDefaultExampleState extends State<StatDefaultExample> {
  @override
  Component build(BuildContext context) {
    return Stat(
      label: 'Total Revenue',
      value: '$45,231.89',
      change: '+20.1%',
      changeType: CoreStatChangeType.positive,
    );
  }
}
class StatDefaultExample extends StatefulWidget {
  const StatDefaultExample({super.key});

  @override
  State<StatDefaultExample> createState() => _StatDefaultExampleState();
}

class _StatDefaultExampleState extends State<StatDefaultExample> {
  @override
  Widget build(BuildContext context) {
    return const Stat(
      label: 'Total Revenue',
      value: '$45,231.89',
      change: '+20.1%',
      changeType: CoreStatChangeType.positive,
    );
  }
}

사용 시기 (When to Use)#

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

  • 대시보드의 KPI(핵심 성과 지표)를 카드 형태로 표시할 때
  • 매출, 사용자 수, 방문자 수 등 주요 지표를 강조하여 표시할 때
  • 이전 기간 대비 증감 트렌드를 함께 보여줄 때
  • 분석 리포트의 요약 수치를 그리드로 나열할 때

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

  • Progress: 완료율이나 목표 달성률을 시각적으로 표현할 때
  • NumberTicker: 단순히 애니메이션 숫자만 필요할 때 (레이블, 트렌드 불필요)
  • Text: 레이블 없이 수치만 간단히 표시할 때

기본 사용법 (Basic Usage)#

// 기본 통계
Stat(
  label: '총 사용자',
  value: '128,450',
)

// 상승 트렌드
Stat(
  label: '이번 달 매출',
  value: '₩12,450,000',
  change: '+12.5%',
  changeType: CoreStatChangeType.positive,
)

// 하락 트렌드
Stat(
  label: '이탈률',
  value: '3.2%',
  change: '-0.8%',
  changeType: CoreStatChangeType.negative,
)

// 중립 트렌드
Stat(
  label: '평균 응답 시간',
  value: '245ms',
  change: '변동 없음',
  changeType: CoreStatChangeType.neutral,
)
// 기본 통계
Stat(
  label: '총 사용자',
  value: '128,450',
)

// 상승 트렌드
Stat(
  label: '이번 달 매출',
  value: '₩12,450,000',
  change: '+12.5%',
  changeType: CoreStatChangeType.positive,
)

// 하락 트렌드
Stat(
  label: '이탈률',
  value: '3.2%',
  change: '-0.8%',
  changeType: CoreStatChangeType.negative,
)

// 중립 상태
Stat(
  label: '평균 응답 시간',
  value: '245ms',
  change: '변동 없음',
  changeType: CoreStatChangeType.neutral,
)

Props / Parameters#

속성타입기본값설명
labelString필수통계 항목 레이블
valueString필수표시할 수치 텍스트
variant CoreStatVariant outlined 카드 변형
changeString?null변동 텍스트
changeType CoreStatChangeType? null 변동 종류 (positive / negative / neutral) — 색상과 화살표를 결정
icon Widget? / Component? null 우상단 trailing 아이콘
statStyle CoreStatStyle? null per-instance chrome 오버라이드 (padding / borderRadius / colours / typography 등)

변형 (Variants)#

상승 트렌드#

Stat(
  label: '신규 가입',
  value: '1,284',
  change: '+8.2%',
  changeType: CoreStatChangeType.positive,
)

하락 트렌드#

Stat(
  label: '취소율',
  value: '1.4%',
  change: '-0.3%',
  changeType: CoreStatChangeType.negative,
)

중립#

Stat(
  label: '활성 세션',
  value: '892',
  change: '±0%',
  changeType: CoreStatChangeType.neutral,
)

그리드 레이아웃#

여러 Stat 을 그리드로 배치하여 대시보드를 구성합니다.

GridView.count(
  crossAxisCount: 3,
  children: [
    Stat(
      label: '총 사용자',
      value: '128,450',
      change: '+5%',
      changeType: CoreStatChangeType.positive,
    ),
    Stat(
      label: '매출',
      value: '₩12.4M',
      change: '+12%',
      changeType: CoreStatChangeType.positive,
    ),
    Stat(
      label: '이탈률',
      value: '3.2%',
      change: '-0.8%',
      changeType: CoreStatChangeType.negative,
    ),
  ],
)

동작 스펙 (Behavior)#

인터랙션#

  • Stat 은 기본적으로 표시 전용 컴포넌트입니다.

상태 전환#

  • change / changeType 변경 시 아이콘과 색이 즉시 갱신됩니다.
  • changeType.positive → 색 = success, 화살표 =
  • changeType.negative → 색 = error, 화살표 =
  • changeType.neutral → 색 = onSurfaceVariant, 화살표 =

애니메이션#

기본 동작 없음. value 슬롯에 다른 컴포넌트 (예: 숫자 ticker) 를 합성해 표현하려면 호출처에서 별도 위젯과 조합합니다.

사용 가이드라인 (Usage Guidelines)#

✅ Do#

의미 있는 비교 기간을 함께 표시

Stat(
  label: '월간 매출',
  value: '₩12,450,000',
  change: '+11.7% (지난 달 대비)',
  changeType: CoreStatChangeType.positive,
)

어느 기간과 비교한 변화율인지 명시하면 수치의 의미를 정확히 전달할 수 있습니다.


❌ Don't#

changeTypechange 의미가 어긋나지 않게 하세요

// ❌ change 는 양수 표기인데 changeType 은 negative
Stat(
  label: '이탈률',
  value: '3.2%',
  change: '+0.5%',
  changeType: CoreStatChangeType.negative,
)

방향이 일치하지 않으면 사용자가 혼란스러워합니다. 이탈률이 증가했다면 보통 부정적이므로 change: '+0.5%' + changeType.negative 로 일치시키거나, 맥락에 따라 change: '-0.5%' + changeType.negative 로 명확히 합니다.

❌ Don't#

너무 많은 Stat 을 한 화면에 나열 금지

// ❌ 15 개 KPI 한 화면에 나열
GridView.count(
  crossAxisCount: 5,
  children: List.generate(15, (i) => Stat(...)),
)

너무 많은 통계는 인지 과부하를 유발합니다. 한 화면에는 가장 중요한 4 ~ 8 개의 KPI 만 표시하세요.

❌ Don't#

단위 없이 숫자만 표시하지 마세요

// ❌ 단위가 없어 의미를 알 수 없는 숫자
Stat(
  label: '방문자',
  value: '15234',
)

숫자만 있으면 무엇을 기준으로 한 값인지 알 수 없습니다. 단위(명·원·% 등)를 반드시 함께 표시하세요.

접근성 (Accessibility)#

키보드 인터랙션#

해당 없음. Stat 은 기본적으로 인터랙티브 요소가 아닙니다.

스크린 리더#

  • Flutter: 레이블·값·변동을 순서대로 읽도록 Semantics 적용 권장 (예: '총 사용자, 128,450명, 5% 상승').
  • Web: dl/dt/dd 구조 또는 적절한 aria-label 적용 권장.

터치 타겟#

해당 없음. 표시 전용 요소. (클릭 시 상세 보기로 이동하는 경우 48×48dp 보장)

크로스 플랫폼 차이점 (Platform Differences)#

항목FlutterWeb
클래스명StatStat
icon 타입Widget?Component?
변동 화살표 / / 글리프 / / 글리프 (동일)
  • Card: Stat 의 외곽 chrome 을 더 다양하게 표현하고 싶을 때.
  • Progress: 목표 대비 진행률을 바 형태로 표시할 때.
  • NumberTicker: 단순히 애니메이션 숫자만 필요할 때.