Form | CoUI

Form

폼 유효성 검증 컴포넌트

Form#

여러 입력 필드를 묶어 유효성 검증을 수행하는 폼 컴포넌트입니다.

Live Preview#

Web
Flutter
Loading Flutter...
class FormDefaultExample extends StatelessComponent {
  const FormDefaultExample({super.key});

  @override
  Component build(BuildContext context) {
    return CoForm(
      children: [
        CoFormField(
          label: 'Username',
          child: CoTextField(
            placeholder: Component.text('Username'),
            onChanged: (_) {},
          ),
        ),
        CoFormField(
          label: 'Email',
          child: CoTextField(
            placeholder: Component.text('Email'),
            onChanged: (_) {},
          ),
        ),
        CoButton(
          variant: CoreButtonVariant.primary,
          onPressed: () {},
          child: Component.text('Submit'),
        ),
      ],
    );
  }
}
class FormDefaultExample extends StatelessWidget {
  const FormDefaultExample({super.key});

  @override
  Widget build(BuildContext context) {
    return CoForm(
      children: [
        CoFormField(
          label: 'Username',
          child: CoTextField(placeholder: const Text('Username')),
        ),
        CoFormField(
          label: 'Email',
          child: CoTextField(placeholder: const Text('Email')),
        ),
        CoButton(
          variant: CoreButtonVariant.primary,
          onPressed: () {},
          child: const Text('Submit'),
        ),
      ],
    );
  }
}

사용 시기 (When to Use)#

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

  • 여러 입력 필드의 유효성 검증을 한꺼번에 관리할 때
  • 제출 전 사용자 입력을 검증하고 에러 피드백을 제공할 때
  • 필드 간 상호 의존적인 검증이 필요할 때 (비밀번호 확인 등)

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

  • Input: 단일 입력 필드만 필요하고 폼 검증이 불필요할 때
  • Dialog: 간단한 확인 입력은 다이얼로그 내에서 직접 처리할 때

기본 사용법 (Basic Usage)#

CoForm(
  children: [
    CoFormField(
      label: '이름',
      required: true,
      child: CoTextField(placeholder: Text('홍길동')),
    ),
    CoFormField(
      label: '이메일',
      child: CoTextField(placeholder: Text('example@email.com')),
    ),
    CoButton(
      variant: CoreButtonVariant.primary,
      onPressed: handleSubmit,
      child: Text('제출'),
    ),
  ],
)
CoForm(
  onSubmit: handleSubmit,
  children: [
    CoFormField(
      label: '이름',
      required: true,
      child: CoTextField(placeholder: text('홍길동')),
    ),
    CoFormField(
      label: '이메일',
      child: CoTextField(placeholder: text('example@email.com')),
    ),
    CoButton(
      variant: CoreButtonVariant.primary,
      onPressed: handleSubmit,
      child: text('제출'),
    ),
  ],
)

Props / Parameters#

CoForm#

속성타입기본값설명
children List<Widget>? / List<Component>? null 폼 내용
onSubmit VoidCallback? null 폼 제출 콜백
gap double? CoreSpace.space24 필드 간 간격
controller FormController? null 폼 상태 컨트롤러 (Flutter)

CoFormField#

속성타입기본값설명
labelString?null필드 라벨 텍스트
labelWidget Widget? / Component? null 커스텀 라벨 위젯
child Widget? / Component? null 입력 위젯
errorString?null에러 메시지
description String? null 도움말 텍스트
requiredboolfalse필수 입력 표시
enabledbooltrue활성화 여부
gap double? CoreSpace.space8 라벨/입력/에러 간 간격

변형 (Variants)#

에러 상태#

CoFormField(
  label: '이메일',
  error: '올바른 이메일을 입력하세요',
  required: true,
  child: CoTextField(placeholder: Text('이메일')),
)

설명 텍스트#

CoFormField(
  label: '비밀번호',
  description: '8자 이상, 대소문자 및 숫자를 포함하세요',
  child: CoTextField(placeholder: Text('비밀번호')),
)

비활성화#

CoFormField(
  label: '이름',
  enabled: false,
  child: CoTextField(placeholder: Text('수정 불가')),
)

동작 스펙 (Behavior)#

유효성 검증 모드 (Flutter)#

모드설명
initial필드 생성 시 즉시 검증
changed사용자가 값을 변경할 때 검증
submitted폼 제출 시 검증

FormController (Flutter)#

FormController로 폼 상태를 프로그래밍 방식으로 관리할 수 있습니다.

final controller = FormController();

// 값 접근
final name = controller.getValue(nameKey);
final allValues = controller.values;

// 에러 확인
final errors = controller.errors;
final nameError = controller.getSyncError(nameKey);

// 재검증
controller.revalidate(context, FormValidationMode.submitted);

Validator 시스템 (Flutter)#

검증기를 연산자로 조합할 수 있습니다.

// AND: 모든 조건 충족
final validator = NotEmptyValidator() & LengthValidator(min: 8);

// OR: 하나 이상 충족
final validator = EmailValidator() | PhoneValidator();

// NOT: 조건 반전
final validator = ~ForbiddenWordsValidator();

내장 검증기: NotEmptyValidator, LengthValidator, SafePasswordValidator, CompareWith<T> (크로스 필드 비교), ConditionalValidator<T> (커스텀 조건)

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

✅ Do#

필수 필드를 명확히 표시하세요.

CoFormField(
  label: '이름',
  required: true,
  child: CoTextField(placeholder: Text('홍길동')),
)

어떤 필드가 필수인지 미리 알려주면 제출 실패를 줄일 수 있습니다.


❌ Don't#

필수/선택 구분 없이 필드를 나열하지 마세요.

CoFormField(
  label: '이름',
  // required 표시 없음
  child: CoTextField(placeholder: Text('이름')),
)

사용자가 어떤 필드를 채워야 하는지 알 수 없어 제출 실패가 반복됩니다.

✅ Do#

에러 메시지에 수정 방법을 안내하세요.

CoFormField(
  label: '비밀번호',
  error: '8자 이상, 대소문자 및 숫자를 포함하세요',
  child: CoTextField(placeholder: Text('비밀번호')),
)

구체적인 기준을 알려주면 사용자가 즉시 수정할 수 있습니다.


❌ Don't#

모호한 에러 메시지를 사용하지 마세요.

CoFormField(
  label: '비밀번호',
  error: '유효하지 않은 비밀번호',
  child: CoTextField(placeholder: Text('비밀번호')),
)

무엇이 틀렸는지 알 수 없으면 여러 번 시도해야 합니다.

접근성 (Accessibility)#

키보드 인터랙션#

동작
Tab다음 폼 필드로 이동
Shift+Tab이전 폼 필드로 이동
Enter폼 제출 (단일 라인 입력 필드에서)

스크린 리더#

  • Flutter: CoFormFieldlabel이 입력 필드와 자동 연결. 에러 발생 시 에러 메시지가 실시간으로 읽힘
  • Web: <label> 요소의 네이티브 접근성 자동 처리

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

항목FlutterWeb
클래스명 CoForm + CoFormField CoForm + CoFormField
상태 관리FormController로 중앙 관리HTML 폼 이벤트 기반
유효성 검증Validator<T> 시스템기본 패턴 검증기
크로스 필드 검증CompareWith, shouldRevalidate패턴 검증기만
검증기 조합연산자 (&, `, ~`)
  • Input: 텍스트 입력 필드. CoFormField로 감싸 라벨/에러 표시
  • Select: 드롭다운 선택. 폼 필드로 사용 가능
  • Checkbox: 체크박스 입력. 약관 동의 등에 활용
  • Button: 폼 제출 버튼

조합 예제#

// 회원가입 폼 패턴
CoForm(
  children: [
    CoFormField(
      label: '이름',
      required: true,
      child: CoTextField(placeholder: Text('홍길동')),
    ),
    CoFormField(
      label: '이메일',
      required: true,
      child: CoTextField(placeholder: Text('example@email.com')),
    ),
    CoFormField(
      label: '비밀번호',
      required: true,
      description: '8자 이상, 대소문자 및 숫자를 포함하세요',
      child: CoTextField(placeholder: Text('비밀번호')),
    ),
    CoButton(
      variant: CoreButtonVariant.primary,
      onPressed: handleSignUp,
      child: Text('가입하기'),
    ),
  ],
)