본문으로 건너뛰기
Dot Design System
v0.3.1

FormField

레이블, 도움말, 입력과 오류를 접근 가능한 한 단위로 연결합니다.

목적

FormField는 하나의 입력 control에 label, 입력 전 설명, 입력 후 오류를 연결한다. 시각적 배치와 접근성 관계를 함께 제공해 제품마다 id, aria-describedby, aria-errormessage, aria-invalid를 반복해서 구성하지 않게 한다.

선택 기준

  • Input, Select 등 하나의 form control과 label을 묶을 때 사용한다.
  • 여러 control을 하나의 질문으로 묶어야 하면 fieldsetlegend를 제품에서 구성한다.
  • label이 없는 검색창처럼 보이더라도 접근 가능한 이름은 필요하다. 시각적으로 숨긴 label 구성을 검토한다.
  • 도움말과 오류의 역할을 구분한다. 입력 전에 필요한 형식은 description, 현재 수정할 문제는 error다.

구조

  1. Label: control의 id와 연결된다.
  2. 필수 표식: required일 때 label 뒤에 시각적으로 표시된다.
  3. description: 입력 전 판단에 필요한 보조 정보
  4. 단일 children: 실제 form control
  5. error: 입력 후 발견된 문제와 복구 방법

children은 접근성 속성을 받을 수 있는 유효한 React element 하나여야 한다. 그렇지 않으면 오류를 발생시켜 잘못된 관계를 조용히 만들지 않는다.

변형과 크기

  • 별도 variant와 size prop은 없다.
  • control의 크기와 상태는 전달한 primitive가 소유한다.
  • className으로 field 사이 간격이나 grid 배치를 조정할 수 있다.
  • 한 폼 안에서는 control density를 일관되게 유지한다.

상태와 동작

  • error가 있으면 control에 aria-invalid=true와 error ID가 자동 연결된다.
  • 기존 control의 aria-describedby가 있으면 description ID와 합쳐 보존한다.
  • control에 id가 이미 있으면 그 값을 유지하지만, label의 htmlForFormFieldid를 사용한다. 혼선을 막기 위해 두 값을 같게 전달한다.
  • 서버 오류를 표시할 때 사용자가 입력한 값을 지우지 않는다.
  • 검증은 사용자가 입력할 기회를 갖기 전에 소리치지 않는다. blur, submit 또는 의미 있는 완료 시점에 표시한다.

콘텐츠

  • label은 사용자가 입력할 정보의 이름을 쓴다.
  • description은 제한, 단위, 공개 범위처럼 입력 전에 필요한 정보만 담는다.
  • placeholder를 label 대신 사용하지 않는다.
  • 오류는 올바르지 않아요보다 문제와 해결 방법을 함께 쓴다.
  • 필수 표식만으로 폼 전체의 필수 정책을 설명하지 말고, 폼 시작 부분에서 필수 항목 규칙을 안내한다.

접근성

  • label, description, error가 control과 programmatically 연결된다.
  • 오류 문구는 role="alert"로 렌더된다. 입력할 때마다 오류 문자열을 바꿔 과도하게 반복 낭독되지 않게 한다.
  • 필수 별표는 시각적 표식이다. 실제 control의 required 또는 aria-required는 소비 제품이 함께 전달해야 한다.
  • 오류를 색상만으로 전달하지 않는다.
  • focus 순서는 실제 control이 결정하며 FormField가 별도 tab stop을 만들지 않는다.

좁은 화면과 긴 콘텐츠

  • label과 설명은 control 위에 쌓여 좁은 화면에서도 연결 관계를 유지한다.
  • 긴 description은 핵심 판단을 첫 문장에 둔다. 정책 전문은 인접한 상세 도움말로 분리한다.
  • 두 필드를 한 행에 놓을 때 작은 화면에서는 한 열로 전환한다.
  • 오류가 두 줄 이상이 되어도 다음 field와 겹치지 않아야 한다.

공개 API

속성타입기본값설명
idstring필수label과 control 관계의 기준 ID
labelReactNode필수입력 레이블
descriptionReactNode없음입력 전 도움말
errorReactNode없음입력 오류와 복구 안내
requiredbooleanfalse시각적 필수 표식 표시 여부
childrenReactNode필수접근성 속성을 받을 단일 control element
classNamestring없음field 컨테이너 클래스

FormControlAccessibilityProps도 공개되어 custom control이 받을 최소 접근성 속성을 표현할 수 있다.

예제

사용 코드 · TSX
import { FormField, Input } from '@classum/dot-design-system/ui';

export function WorkspaceNameField({ error }: { error?: string }) {
  return (
    <FormField
      id="workspace-name"
      label="워크스페이스 이름"
      description="운영자와 검토자에게 함께 보여요."
      error={error}
      required
    >
      <Input name="workspaceName" required autoComplete="organization" />
    </FormField>
  );
}

피해야 할 사용

  • placeholder만 두고 label을 생략
  • 여러 input을 하나의 FormField children에 전달
  • required 표식만 켜고 실제 required 제약을 생략
  • description에 오류를 미리 표시하거나 error에 일반 도움말을 반복
  • 사용자가 입력하기 전부터 모든 field를 오류 상태로 표시
  • 오류 발생 시 입력값을 초기화

관련 항목