ValidationBadge | CoUI

ValidationBadge

입력값의 유효성 검증 결과를 아이콘과 텍스트로 표시하는 배지 컴포넌트

ValidationBadge#

폼 필드의 유효성 검증 결과를 아이콘과 텍스트로 시각적으로 표시하는 배지 컴포넌트입니다. 비밀번호 강도, 이메일 형식 등 검증 상태 안내에 적합합니다.

Live Preview#

사용 시기 (When to Use)#

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

  • 비밀번호 설정 시 각 조건(길이, 대문자, 숫자 포함 등)의 충족 여부를 실시간으로 표시할 때
  • 아이디, 이메일 중복 확인 결과를 시각적으로 안내할 때
  • 폼 필드 아래에 여러 검증 규칙을 체크리스트 형태로 나열할 때
  • 입력 진행 중 실시간 유효성 상태를 사용자에게 보여줄 때

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

  • Status: 시스템이나 사용자 상태(온라인/오프라인)를 표시할 때
  • Banner 또는 Toast: 전체 폼 제출 후 오류 메시지를 표시할 때
  • Text: 단순한 에러 메시지 텍스트만 필요할 때

기본 사용법 (Basic Usage)#

// 유효한 상태 (기본)
CoValidationBadge(
  label: '8자 이상',
  state: CoreValidationState.valid,
)

// 무효한 상태
CoValidationBadge(
  label: '숫자 포함',
  state: CoreValidationState.invalid,
)

// 입력 전(pending) 상태
CoValidationBadge(
  label: '대문자 포함',
  state: CoreValidationState.pending,
)

// bool로 간편 생성 (true → valid, false → invalid)
CoValidationBadge.fromBool(
  label: '대문자 포함',
  isValid: hasUpperCase,
)

// hasInput → !hasInput 이면 pending, 그 외엔 isValid 기준
CoValidationBadge.withPending(
  label: '숫자 포함',
  hasInput: password.isNotEmpty,
  isValid: hasNumber,
)
// 유효한 상태 (기본)
CoValidationBadge(
  label: '8자 이상',
  state: CoreValidationState.valid,
)

// 무효한 상태
CoValidationBadge(
  label: '숫자 포함',
  state: CoreValidationState.invalid,
)

// 입력 전(pending) 상태
CoValidationBadge(
  label: '대문자 포함',
  state: CoreValidationState.pending,
)

// bool로 간편 생성
CoValidationBadge.fromBool(
  label: '대문자 포함',
  isValid: hasUpperCase,
)

// hasInput 기반 3-state factory
CoValidationBadge.withPending(
  label: '숫자 포함',
  hasInput: password.isNotEmpty,
  isValid: hasNumber,
)

Props / Parameters#

속성타입기본값설명
labelString필수표시할 검증 조건 텍스트
state CoreValidationState 필수 검증 상태 (pending / valid / invalid)
pendingIcon IconName? CoLucideIcons.dot pending 상태에서 표시할 아이콘 override
validIcon IconName? CoLucideIcons.check valid 상태에서 표시할 아이콘 override
invalidIcon IconName? CoLucideIcons.x invalid 상태에서 표시할 아이콘 override
size CoreValidationBadgeSize? small (token default) 크기 토큰 (extraSmall / small / medium)
style CoreValidationBadgeStyle<Color>? (Flutter) / CoreValidationBadgeStyle<String>? (Web) null 상태별 색상 override (background/foreground/border × 3 state = 9 필드)

변형 (Variants)#

Default (valid)#

가장 흔한 success 상태. soft success tint + check 아이콘.

CoValidationBadge(
  label: '8자 이상',
  state: CoreValidationState.valid,
)

Pending#

입력 전 중립 상태. surface 배경 + 옅은 onSurface 텍스트 + dot 아이콘.

CoValidationBadge(
  label: '대문자 포함',
  state: CoreValidationState.pending,
)

Invalid#

실패 상태. soft error tint + X 아이콘.

CoValidationBadge(
  label: '숫자 포함',
  state: CoreValidationState.invalid,
)

Medium size#

typography 가 한 단계 크고 padding 도 더 넉넉한 변형.

CoValidationBadge(
  label: '대문자 포함',
  state: CoreValidationState.valid,
  size: CoreValidationBadgeSize.medium,
)

크기 (Sizes)#

크기토큰padding (v/h)radius
Extra Small CoreValidationBadgeSize.extraSmall 2 / 4 field (4px)
Small (default) CoreValidationBadgeSize.small 2 / 6 field (4px)
Medium CoreValidationBadgeSize.medium 4 / 8 selector (8px)

동작 스펙 (Behavior)#

인터랙션#

  • 표시 전용. 인터랙션 없음.
  • state prop 변경 시 색상/아이콘 즉시 업데이트.

상태 전환#

  • pendingvalid: 회색 배경 + dot 아이콘 → 옅은 success tint + check.
  • validinvalid: success tint → error tint + X.

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

✅ Do#

실시간 검증 + withPending로 미입력 단계는 중립 표시

Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    CoValidationBadge.withPending(
      label: '8자 이상',
      hasInput: password.isNotEmpty,
      isValid: password.length >= 8,
    ),
    CoValidationBadge.withPending(
      label: '대문자 포함',
      hasInput: password.isNotEmpty,
      isValid: hasUpperCase,
    ),
  ],
)

입력 시작 전엔 pending(중립), 시작 후엔 valid/invalid 로 전환됩니다.


❌ Don't#

입력 전부터 모든 조건을 invalid 로 표시 금지

// ❌ 입력 전부터 모든 조건이 빨간 X
CoValidationBadge(label: '8자 이상', state: CoreValidationState.invalid)
CoValidationBadge(label: '대문자', state: CoreValidationState.invalid)

아직 입력 안 된 상태에서 모두 실패로 표시되면 위압감을 줍니다. pending 상태 또는 withPending factory 를 사용하세요.

✅ Do#

긍정적 메시지로 조건 표현

CoValidationBadge.fromBool(label: '영문 대문자 포함', isValid: hasUpperCase)
CoValidationBadge.fromBool(label: '숫자 1개 이상', isValid: hasNumber)

"대문자 미포함"보다 "영문 대문자 포함"처럼 충족해야 할 조건을 긍정형으로 표현하면 더 명확합니다.


❌ Don't#

너무 많은 조건을 한 번에 표시 금지

5~6개 이내로 핵심 조건만. 그 이상은 사용자에게 부담.

접근성 (Accessibility)#

  • Flutter: Semantics(label: '$label: ${state.name}') 적용 권장.
  • Web: 컨테이너 role="status" 자동 적용 (필요 시 aria-live="polite" 추가).

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

항목FlutterWeb
클래스명CoValidationBadgeCoValidationBadge
색상 colorScheme.success/error + scaleAlpha(0.1/0.2/0.6) bg-${cs.success}/10 등 Tailwind alpha (Card 패턴)
아이콘 CoIcon(CoLucideIcons.*) CoIcon(CoLucideIcons.*) (동일 토큰)
  • Input: ValidationBadge 와 함께 폼 필드 검증 UI 구성.
  • Form: 전체 폼 수준의 검증 관리.
  • Status: 시스템/사용자 상태 표시 (ValidationBadge 와 구분).

조합 예제#

// ValidationBadge + Input 조합으로 비밀번호 설정 UI
Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    CoInput(label: '새 비밀번호', obscureText: true, onChanged: handlePasswordChange),
    CoGap(size: CoreSpace.space12),
    CoValidationBadge.withPending(
      label: '8자 이상',
      hasInput: password.isNotEmpty,
      isValid: password.length >= 8,
    ),
    CoValidationBadge.withPending(
      label: '영문 대문자 1자 이상',
      hasInput: password.isNotEmpty,
      isValid: hasUpperCase,
    ),
    CoValidationBadge.withPending(
      label: '숫자 1자 이상',
      hasInput: password.isNotEmpty,
      isValid: hasNumber,
    ),
  ],
)