핵심 개념
@ilokesto/form은 정규화된 필드 기록을 다루는 작은 컨트롤러로 이해하면 쉽습니다. CreateForm 인스턴스는 초기 값을 받고, 말단 값을 FieldState 기록으로 나누어 저장하며, getValues()를 호출할 때 다시 객체로 조립합니다. 프레임워크 어댑터는 이 컨트롤러를 구독하고 각 렌더러에 어울리는 바인딩 형태를 제공합니다.
프레임워크 독립성
루트 패키지는 CreateForm과 코어 타입을 내보냅니다. React, Vue, Solid, Svelte, DOM 런타임을 가져오지 않습니다. 이 분리 덕분에 공유 모듈에서 폼을 만들고, 코어를 직접 테스트하고, 컴포넌트 경계에서만 프레임워크 어댑터를 선택할 수 있습니다. 어댑터는 Form<TValues> 인터페이스에 의존합니다. 여기에는 getState, subscribe, 값 조작, 검증 조작, 배열 조작, submit/reset 명령이 포함됩니다.
점 문자열이 아니라 튜플 경로
FieldPathInput은 string | FieldPath입니다. 문자열은 그대로 하나의 이름입니다. 튜플은 중첩 경로입니다. 이 규칙은 점을 자동으로 해석하는 방식보다 명시적이고, user.email 같은 이름이 실제로 하나의 필드여야 할 때 놀라운 동작을 줄입니다.
form.setValue(['user', 'email'], 'ada@example.com');
form.setValue('user.email', 'literal top-level value');필드 상태와 메타데이터
모든 필드에는 value, errors, touched, dirty, modified, isFocused가 있습니다. dirty는 현재 값과 초기 값을 비교합니다. modified는 사용자에서 온 쓰기가 있었는지를 기록합니다. focus()와 blur()는 포커스 상태를 갱신하고, blur()는 touched도 설정합니다. 이 플래그들 덕분에 각 프레임워크 어댑터가 서로 다른 메타데이터 모델을 만들 필요 없이 UI 판단을 할 수 있습니다.
검증과 Standard Schema
폼 전체 schema와 field-local 스키마는 모두 StandardSchemaV1을 사용합니다. field-local 스키마는 어댑터 옵션이나 registerFieldSchema로 등록하며, 해당 필드에서는 폼 전체 스키마보다 우선합니다. validateOn은 change, blur, submit, manual을 지원하고, 직접 검증은 언제든 trigger()로 실행할 수 있습니다.
배열과 재배치
array(path)는 배열 값을 바꾸고 자식 필드 메타데이터를 함께 옮기는 명령을 반환합니다. move, swap, insert, remove를 실행하면 오류와 touched 상태가 숫자 인덱스에 고정되지 않고 논리적인 항목을 따라가야 합니다. keys()는 이런 재배치가 일어나는 동안 목록 렌더링에 쓸 안정적인 키를 제공합니다.
다음 단계
정확한 컨트롤러 메서드와 상태 구조는 CreateForm 레퍼런스에서 확인하세요. 검증 시점을 정할 때는 검증 흐름, 동적 목록을 렌더링하기 전에는 배열 필드를 읽으세요.