Skip to Content

Form

입력 컨트롤을 24칸 격자로 배치하고 라벨 설정을 한 번에 적용하는 폼 컨테이너 컴포넌트


개요

Cals Form은 Foundation Form을 래핑하여 24칸 CSS Grid 레이아웃을 제공하는 컴포넌트입니다. Form.Col로 칸을 나누고, 컨트롤이 label·required·description·error prop으로 라벨과 오류를 직접 그립니다. orientation, labelWidth 같은 라벨 설정을 Form에 한 번 주면 하위 컨트롤에 적용되고, 컨트롤에 같은 prop을 주면 컨트롤 값이 이깁니다.

주요 특징

  • ✅ 24칸 격자: Form.Col의 span·offset으로 칸 배치, colGap·rowGap으로 간격 지정
  • ✅ 라벨 일괄 설정: orientation·labelWidth·labelAlign·labelVerticalAlign·required를 Form에서 한 번에 지정, 컨트롤 prop이 우선
  • ✅ 컨트롤 내장 라벨: 컨트롤의 label·description·error prop으로 라벨·설명·오류 표시
  • ✅ 제출 보호: action이 없으면 제출 시 페이지 이동을 막은 뒤 onSubmit 호출
  • ✅ 칸 숨김: span={0}, className="hidden", 조건부 렌더로 칸 영역과 DOM 제어
  • ✅ 표준 form 속성: onSubmit·role·id·aria-* 등을 <form>에 그대로 전달

기본 사용

Form.Col로 칸 수를 정하고 컨트롤에 label을 줍니다. 컨트롤이 라벨을 직접 그리므로 FormItem으로 한 번 더 감싸지 않습니다. FormItem은 InputGroup처럼 label prop이 없는 내용에만 씁니다.


칸 나누기 (span / colGap / rowGap)

Form.Col의 span으로 칸 수를 정합니다. 칸 사이 가로 간격은 colGap(기본 15), 줄 사이 세로 간격은 rowGap(기본 20), 줄 기준 시작 위치는 offset으로 정합니다.


라벨 설정 (orientation / labelWidth)

Form의 orientation, labelWidth, labelAlign, labelVerticalAlign, required는 하위 컨트롤 라벨에 한 번에 적용됩니다. 컨트롤에 같은 prop을 주면 컨트롤 값이 Form 값을 이깁니다.


필수 입력 / 오류 표시

required로 필수 표시(*)를, description으로 보조 설명을, error로 입력 아래 오류 문구를 표시합니다. error가 있으면 description은 그려지지 않습니다.

영문·숫자 4~12자

제출 시 검사

onSubmit에서 직접 검사하고 error를 지정합니다. action이 없으면 Form이 제출의 기본 동작(페이지 이동)을 막은 뒤 onSubmit을 부릅니다. required는 입력에 HTML required를 붙이므로 직접 검사하려면 noValidate로 브라우저 검사를 끕니다. Enter로 제출하려면 제출 버튼(type="submit")이 필요하고, 제출 버튼이 없으면 입력이 하나일 때만 제출됩니다.


읽기 전용 (readOnly)

readOnly는 컨트롤마다 줍니다. Form의 readOnly는 하위 컨트롤에 내려가고 컨트롤에 준 readOnly가 이깁니다(지금은 Text만 읽습니다). ZipCodeKR(입력란이 늘 읽기 전용), ImageView, Button에는 readOnly prop이 없습니다.


칸 숨기기 (className / span)

칸을 숨기는 방법은 세 가지이며 모두 영역을 차지하지 않습니다. 입력값을 남길지에 따라 고릅니다.

방법DOM다시 보일 때
className="hidden"유지값 유지
조건부 렌더 ({show && …})없음새로 마운트
span={0}유지값 유지

API Reference

Props

Foundation FormProps를 받습니다. 표준 form 속성은 <form>에 그대로 갑니다.

PropTypeDefaultDescription
childrenReactNode-폼 격자 안에 둘 내용 (Form.Col)
columnsnumber24격자 칸 수
colGapnumber15칸 사이 가로 간격 (px)
rowGapnumber20줄 사이 세로 간격 (px). 마지막 줄 뒤에는 없음
readOnlybooleanfalse하위 컨트롤에 내림. 컨트롤 값이 이김 (지금은 Text만 읽음)
orientation"vertical" | "horizontal" | "responsive"-하위 컨트롤 라벨 배치
labelWidthnumber-하위 컨트롤 라벨 너비 (px, horizontal일 때)
labelAlign"start" | "center" | "end"-하위 컨트롤 라벨 가로 정렬
labelVerticalAlign"start" | "center" | "end"-하위 컨트롤 라벨 세로 정렬
align"start" | "center" | "end"-하위 컨트롤 본문 정렬
requiredboolean-하위 컨트롤 필수 표시(*)
requiredPosition"left" | "right"-필수 표시 위치
requiredOffsetXnumber-필수 표시 가로 오프셋 (px)
requiredOffsetYnumber-필수 표시 세로 오프셋 (px)
classNamestring-<form> className. 마운트를 유지하며 숨기려면 hidden
styleReact.CSSProperties-인라인 스타일. 격자 스타일 뒤에 합쳐집니다
(그 밖)foundation FormProps-role·id·aria-label·noValidate 등 표준 form 속성

컨트롤에 같은 라벨 설정 prop을 주면 컨트롤 값이 이깁니다. 안쪽 Form은 바깥 Form의 설정을 병합하지 않고 통째로 바꿉니다.

Form.Col

PropTypeDefaultDescription
childrenReactNode-칸 안에 둘 내용
spannumber24차지할 칸 수 (0 이상). 0이면 자리를 차지하지 않습니다 (DOM 유지)
offsetnumber0줄의 몇 번째 칸 뒤에서 시작할지 (줄 기준 절대 위치)
classNamestring-칸 className. 마운트를 유지하며 숨기려면 hidden

Events

EventTypeDescription
onSubmit(event: FormEvent<HTMLFormElement>) => void제출 시 호출. action이 없으면 기본 동작(페이지 이동)을 막은 뒤 호출

Ref

ref는 <form> 요소(HTMLFormElement)로 연결됩니다.


접근성

권장 사항

  • ✅ 네이티브 <form> 요소를 씁니다
  • ✅ aria-label로 폼 식별자 제공 가능
  • ✅ 제출은 제출 버튼(type="submit")으로 하며, Enter 제출도 같은 버튼으로 동작

관련 컴포넌트

  • FormItem: label prop이 없는 내용에 라벨을 붙이는 래퍼
  • ToolbarForm: 제목·도구 모음이 있는 접이식 폼
Last updated on