ValidatorHint | CoUI
본문으로 건너뛰기
LogoCoUI

ValidatorHint

폼 입력 아래 표시하는 유효성 메시지 (심각도 아이콘 포함)

목차

폼 입력 아래에 유효성 메시지(error / warning / info / success)를 선두 심각도 아이콘과 함께 표시합니다. visible 이 false 면 0 크기로 접히고, type 이 per-type 강조 색(아이콘·메시지 모두)과 기본 선두 아이콘을 결정합니다. Flutter / Web 1:1 동일 API 입니다.

Live Preview#

사용법#

ValidatorHint(
  message: const Text('비밀번호는 8자 이상이어야 합니다.'),
  type: CoreValidatorHintType.error,
)

빠른 오버라이드 (Chain)#

이미 만든 ValidatorHint 인스턴스에 스타일을 빠르게 덧붙이고 싶다면 withStyle 체인을 쓸 수 있습니다. 생성자의 style 슬롯 인자와 동일하게 동작하지만, 이미 구성된 위젯 위에서 바로 이어 쓸 수 있습니다.

class ValidatorHintChainExample extends StatelessWidget {
  const ValidatorHintChainExample({super.key});

  @override
  Widget build(BuildContext context) {
    return ValidatorHint(
      message: const Text('비밀번호는 8자 이상이어야 합니다.'),
      type: CoreValidatorHintType.error,
    ).withStyle(
      const CoreValidatorHintStyle(
        accentColor: CoreColor.token(CoreColors.warning),
        messageTextStyle: CoreTextStyle.token(CoreTextStyles.bodySmall),
        iconStyle: CoreIconStyle(size: CoreIconSize.size16),
        iconLabelGapStyle: CoreGapStyle(size: CoreSpace.space12),
      ),
    );
  }
}
class ValidatorHintChainExample extends StatelessComponent {
  const ValidatorHintChainExample({super.key});

  @override
  Component build(BuildContext context) {
    return ValidatorHint(
      message: Text('비밀번호는 8자 이상이어야 합니다.'),
      type: CoreValidatorHintType.error,
    ).withStyle(
      const CoreValidatorHintStyle(
        accentColor: CoreColor.token(CoreColors.warning),
        messageTextStyle: CoreTextStyle.token(CoreTextStyles.bodySmall),
        iconStyle: CoreIconStyle(size: CoreIconSize.size16),
        iconLabelGapStyle: CoreGapStyle(size: CoreSpace.space12),
      ),
    );
  }
}

Props / Parameters#

W는 합성 슬롯 타입으로 Flutter의 Widget, Web의 Component입니다. Flutter의 message는 nullable 타입이지만 named 인자를 반드시 전달해야 하며 Web은 생략할 수 있습니다. Web이 더 관대한 requiredness는 수용된 호환 예외이며 공통 호출에는 message를 명시합니다.

파라미터타입기본값설명
message W? Flutter: 필수 인자 / Web: null 유효성 메시지
type CoreValidatorHintType defaultType 심각도 ( error / warning / info / success / neutral ) — 강조 색·기본 아이콘 결정
visible bool true false 면 0 크기로 접힘
icon W? null 커스텀 선두 아이콘 (기본: type 별 아이콘)
validatorHintStyle CoreValidatorHintStyle? null chrome / 타이포 단일 진입점

스타일 시스템 (Style System)#

CoreValidatorHintTypeStyle 필드#

필드타입설명
accentColor CoreColor Accent colour applied to the icon and message text.

동작 스펙 (Behavior)#

visible: false면 메시지와 아이콘을 렌더하지 않습니다. 표시 중에는 type이 강조 색·기본 아이콘·통보 역할을 결정하고 icon이 있으면 기본 아이콘을 대체합니다. error·warning·info·success·neutral named constructor는 그 톤을 고정하는 편의 API입니다. 자체 검증·상태 변경·클릭 콜백은 없으며 필드 값과 표시 여부는 호출자가 관리합니다.

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

메시지 한 줄에는 ValidatorHint를, 필드와 메시지를 묶어 상태를 전파할 때는 Validated를 사용합니다. 규칙별 검증 상태 배지는 ValidationBadge, 필드 입력값 이외의 요청 실패 안내는 Alert로 구분합니다.

✅ Do#

의도에 맞는 named constructor 사용

ValidatorHint.success(message: const Text('저장되었습니다.'))

type 을 직접 넘기는 대신 ValidatorHint.error / .warning / .info / .success 를 쓰면 Alert.success 같은 다른 컴포넌트의 관례와 일치하고, 의도가 코드에서 바로 드러납니다.


❌ Don't#

성공/안내 메시지에 type 생략하지 않기

// ❌ type 생략 → 기본값 error 로 렌더링됨
ValidatorHint(message: const Text('저장되었습니다.'))

type 의 기본값은 CoreValidatorHintType.defaultType(= error)입니다. 성공 메시지에 type 을 생략하면 에러 색과 아이콘으로 렌더링됩니다.

접근성 (Accessibility)#

역할#

힌트는 나타나는 순간 통보됩니다 — 검증 메시지는 대개 사용자가 제출하거나 필드를 떠난 뒤에 나타나고, 그때 포커스는 옮겨지지 않으므로 통보가 없으면 리더는 그 줄을 읽을 이유가 없습니다(WCAG 3.3.1).

얼마나 급하게 끼어드는지는 type 이 정합니다. 매핑은 CoreValidatorHintType.toSemanticRole() 한 곳에 있고 두 플랫폼이 같이 읽습니다.

typeWebFlutter
errorrole="alert" — 읽던 문장을 끊는다live region
warning · info · success role="status" — 차례를 기다린다 live region
neutral역할 없음live region 아님

neutral 은 아무것도 보고하지 않는 줄(아직 충족되지 않은 체크리스트 규칙)이라, live region 을 붙이면 로드 시점에 대기 중인 규칙을 전부 읽게 됩니다. Flutter 에는 통보 축이 하나뿐이라(live region 이거나 아니거나) 급함의 구분은 Web 만 표현합니다 — 미구현이 아니라 플랫폼 capability 차이입니다. Web 에서 호출자가 attributes 로 role 을 넘기면 그 값이 이깁니다.

Flutter 는 힌트를 자기 시맨틱 노드(container)로 둡니다 — live region 이 감싸는 필드 전체가 아니라 이 한 줄이 되도록.

심각도 아이콘은 양쪽 다 의도적으로 침묵시킵니다 — Flutter 는 ExcludeSemantics, Web 은 아이콘 <span> 의 aria-hidden="true".

키보드#

키 입력을 처리하지 않습니다. 표시 전용 컴포넌트라 활성화·이동 키가 없습니다.

포커스 관리#

포커스를 받지 않습니다 — FocusNode(Flutter) 도 tabindex(Web) 도 없고 포커스 링도 그리지 않습니다. Tab 순서에 나타나지 않으므로 키보드 사용자는 주변 텍스트를 읽어 나가다 마주치게 됩니다.

visible: false 일 때의 처리는 플랫폼마다 다릅니다 — Flutter 는 SizedBox.shrink() 로 0 크기 노드를 트리에 남기고, Web 은 DOM 을 아예 만들지 않습니다.

스크린 리더#

읽히는 것은 호출자가 넘긴 message 텍스트입니다. 심각도 접두사는 붙지 않습니다. type 은 통보의 급함(위 표)과 강조 색·아이콘 글리프로 표현되고 그 아이콘은 숨겨져 있으므로, 리더에게 warning 힌트와 success 힌트는 문구로만 구분됩니다.

알려진 제약#

  • 심각도의 종류는 문구로만 전달됩니다. 통보의 급함은 type 을 따르지만 오류인지 성공인지는 읽히지 않습니다 — 알려야 한다면 message 문구 자체에 담으세요 (예: '오류: 비밀번호는 8자 이상이어야 합니다.'). 심각도가 색으로만 남아 있다는 것은 전역 접근성 축의 색 강제 모드에서도 문제가 됩니다 — 시맨틱 색이 시스템 색으로 접히면 남는 단서가 없습니다.
  • 설명 대상 필드와 연결되어 있지 않습니다. aria-describedby 나 그에 준하는 연결이 없으므로, 입력에 포커스했을 때 이 힌트가 함께 읽히길 원한다면 호출자가 배선해야 합니다.

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

항목FlutterWeb
숨김SizedBox.shrink()빈 fragment로 DOM 생략
레이아웃 Row와 Flexible 메시지 <p> 안의 아이콘 <span>과 메시지
톤 통보 error/warning/info/success는 live region error는 alert, warning/info/success는 status; neutral은 역할 없음
메시지 인자nullable이지만 인자 전달 필수생략 가능