FormField
레이블, 도움말, 입력과 오류를 접근 가능한 한 단위로 연결합니다.
목적
FormField는 하나의 입력 control에 label, 입력 전 설명, 입력 후 오류를 연결한다. 시각적 배치와 접근성 관계를 함께 제공해 제품마다 id, aria-describedby, aria-errormessage, aria-invalid를 반복해서 구성하지 않게 한다.
선택 기준
Input,Select등 하나의 form control과 label을 묶을 때 사용한다.- 여러 control을 하나의 질문으로 묶어야 하면
fieldset과legend를 제품에서 구성한다. - label이 없는 검색창처럼 보이더라도 접근 가능한 이름은 필요하다. 시각적으로 숨긴 label 구성을 검토한다.
- 도움말과 오류의 역할을 구분한다. 입력 전에 필요한 형식은
description, 현재 수정할 문제는error다.
구조
Label: control의id와 연결된다.- 필수 표식:
required일 때 label 뒤에 시각적으로 표시된다. description: 입력 전 판단에 필요한 보조 정보- 단일
children: 실제 form control 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의htmlFor는FormField의id를 사용한다. 혼선을 막기 위해 두 값을 같게 전달한다. - 서버 오류를 표시할 때 사용자가 입력한 값을 지우지 않는다.
- 검증은 사용자가 입력할 기회를 갖기 전에 소리치지 않는다. 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
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
id | string | 필수 | label과 control 관계의 기준 ID |
label | ReactNode | 필수 | 입력 레이블 |
description | ReactNode | 없음 | 입력 전 도움말 |
error | ReactNode | 없음 | 입력 오류와 복구 안내 |
required | boolean | false | 시각적 필수 표식 표시 여부 |
children | ReactNode | 필수 | 접근성 속성을 받을 단일 control element |
className | string | 없음 | field 컨테이너 클래스 |
FormControlAccessibilityProps도 공개되어 custom control이 받을 최소 접근성 속성을 표현할 수 있다.
예제
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를 오류 상태로 표시
- 오류 발생 시 입력값을 초기화