폼
입력 컴포넌트(Input · Textarea · Field), 라벨과 입력을 배치하는 컴포넌트, 입력 클래스입니다.
입력은 파인 칸입니다. 흰 면에 컨트롤 경계(바닥 위에서도 3:1)와 위쪽 안쪽 그늘이 있습니다. 손을 올리면 경계가 짙어지고, 포커스는 2px 링을 1px 띄워 그립니다. 오류(aria-invalid)는 빨간 경계이고, 색만이 아니라 Field 의 오류 아이콘과 문장이 함께 말합니다.
읽기 전용은 그늘 없는 파인 면에 본문색 글자라 복사할 값이 읽힙니다. 비활성은 투명도를 낮추지 않고 파인 면과 흐린 글자로 바꿉니다. select 는 네이티브 요소를 써서 FormData · 서버 액션과 바로 연결되고, 꺾쇠는 CSS 가 그립니다.
Input · Textarea 는 inputClass · inputSmClass 를 그대로 씁니다. 모양은 요소의 속성(aria-invalid · readonly · disabled)을 보고 CSS 가 고르므로 클래스 상수만 붙인 입력도 같은 모양입니다. textarea 는 클래스가 같아도 최소 88px 로 늘어납니다.
- import
- import { Field, Input, Textarea, NativeSelect } from "@uyoolabs/ui/ui";
- 쓰는 경우
- 라벨 · 도움말 · 오류가 붙은 입력은 Field 로 묶습니다. 설정 · 생성 화면처럼 라벨을 왼쪽 열에 두는 배치는 FormRow, 맨 아래 제출 버튼과 오류 요약은 FormField 를 씁니다.
- 검증 시점
- 입력하는 동안에는 검사하지 않고 칸을 떠날 때 검사합니다. 오류가 난 뒤 고치는 동안에는 맞는 값이 되는 즉시 오류를 지웁니다. 제출할 때는 FormField 가 오류를 한 번에 알립니다.
- 쓰지 않는 경우
- 필터 영역이나 표 행 안의 입력에는 FormRow 없이 inputSmClass 만 씁니다. 값 하나를 고르는 입력에 커스텀 드롭다운을 만들지 않고 NativeSelect 를 씁니다. 오류를 빨간 경계만으로 알리지 않습니다(Field 의 error 문장과 함께).
- 폐기 예고
- FormRow · FormField 는 v2.x 에서 지웁니다. 왼쪽 라벨 배치는 Field 로, 제출 영역 · 오류 요약은 따로 나뉜 컴포넌트로 옮깁니다. 2.0 에서는 모양만 카톤으로 바뀌고 동작은 같습니다.
Input · Textarea
size 는 sm · md(기본값)입니다. invalid 를 주면 aria-invalid 가 붙습니다.
Field
라벨 · 컨트롤 · 도움말 · 오류 한 묶음입니다. id · htmlFor · aria-describedby 를 대신 잇습니다.
주소를 고친 뒤 칸을 떠나 보세요. 오류는 칸을 떠날 때 나타나고, 고치는 즉시 사라집니다.
주소에 쓰입니다. 나중에 바꿀 수 있습니다.
팀 이름은 2자 이상입니다. 한 글자 이상 더 씁니다.
API 호출에 씁니다.
- import
- import { Field, Input, Textarea } from "@uyoolabs/ui/ui";
- children
- 컨트롤을 그리는 함수입니다. 받은 id · aria-describedby · aria-invalid · aria-required 를 컨트롤에 펼칩니다.
- error
- 무엇이 문제인지와 어떻게 고치는지를 한 문장으로 씁니다. 아이콘과 함께 보이고 aria-describedby 로 연결됩니다. '잘못된 입력입니다' 같은 문장은 쓰지 않습니다.
- required
- 라벨 옆에 * 를 보이고 aria-required 를 답니다.
- announce
- 오류를 바로 읽어 줍니다(role=alert). 기본값은 꺼져 있습니다. 칸을 떠날 때 켜진 알림은 다음 칸의 라벨을 가로막기 때문입니다. 제출 없이 서버 확인만으로 오류가 생기는 칸에만 켭니다.
props
소스의 타입과 JSDoc 에서 생성한 표입니다. 컴포넌트를 고치면 pnpm gen 으로 다시 만듭니다.
Input
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| size | "sm" | "md" | "md" | sm 은 필터 바 · 표 행 안의 작은 입력(28px, inputSmClass), md 는 기본(36px, inputClass). 네이티브 size(글자 수 폭)는 받지 않는다 |
| invalid | boolean | — | aria-invalid 를 달아 빨간 경계를 그린다. 오류 문장은 Field 의 error 로 연결한다 |
이 밖에 <input> props(size 제외)를 그대로 받습니다.
Textarea
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| invalid | boolean | — | aria-invalid 를 달아 빨간 경계를 그린다 |
이 밖에 <textarea> props를 그대로 받습니다.
Field
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| label필수 | ReactNode | — | |
| hint | ReactNode | — | 무엇을 넣는지 · 어디에 쓰이는지. 컨트롤 아래에 두고 aria-describedby 로 연결한다 |
| error | ReactNode | — | 무엇이 문제인지 + 어떻게 고치는지 한 문장(스펙 보드 C-Input). 있으면 aria-invalid 를 단다 |
| required | boolean | — | 라벨 옆에 * 를 보이고 aria-required 를 단다. 네이티브 required 는 브라우저 말풍선이 오류 요약과 겹쳐 쓰지 않는다 |
| announce | boolean | — | 오류가 생기는 즉시 읽어 준다(role="alert"). 기본값은 끈다. 스펙 보드는 칸을 떠날 때 검사하므로, alert 를 켜 두면 Tab 으로 다음 칸에 들어가는 순간 그 칸의 라벨 대신 앞 칸의 오류를 끼어들어 읽는다. 오류 안내는 제출할 때 오류 요약이 한 번에 맡는다. 제출 없이 서버 확인(주소 중복 등)만으로 오류가 생기는 칸에만 켠다. |
| count | { value: number; max: number } | — | 글자 수. 힌트 오른쪽에 “3 / 40” 을 보이고 aria-describedby 로 잇는다. 넘으면 숫자만 오류 색 500 이 된다. 입력하는 동안 검사하지 않는다(C-Form 검증 시점). 넘은 것은 칸을 떠날 때 error 로 알린다 |
| layout | "top" | "start" | "top" | 라벨 자리. top(기본)은 칸 위, start 는 왼쪽 144px 열(칸이 많은 설정 화면, FormRow 대신). start 는 폼 폭 480 미만(uyoo-form 컨테이너, 없으면 화면 폭)에서 위로 접힌다 |
| id | string | — | 컨트롤 id. 주지 않으면 useId 로 만든다 |
| className | string | — | |
| children필수 | (control: FieldControlProps) => ReactNode | — | 컨트롤을 그리는 함수. cloneElement 대신 render-prop 을 고른 이유: - 검색 · 단위 · 복사 버튼이 붙은 입력처럼 컨트롤이 감싸져 있어도 props 가 정확히 그 입력에 간다. cloneElement 는 바깥 div 에 id 를 붙인다. - 받는 props 가 타입으로 드러나고, 어떤 컨트롤(Input · NativeSelect · textarea)이든 같은 방식이다. |
키보드
| 키 | 동작 |
|---|---|
| Tab | 다음 칸으로 옮깁니다. 읽기 전용 칸은 포커스를 받고(값을 복사할 수 있게), 비활성 칸은 건너뜁니다. |
| Enter | 한 줄 입력에서는 폼을 제출합니다(브라우저 기본). 한 · 일 조합 중의 Enter 는 글자를 확정하는 키라 제출 · 추가로 처리하지 않습니다(isComposing). Textarea 에서는 줄을 바꿉니다. |
Enter 와 한글 조합
한글 · 일본어를 조합하는 중에 누른 Enter 는 글자를 확정하는 키입니다. 제출 · 추가로 처리하지 않습니다.
Enter 로 더합니다. 한글을 조합하는 중에 누른 Enter 는 글자만 확정합니다.
FormRow
라벨 · 입력 · 도움말(hint) 한 줄입니다.
화면에 보이는 이름입니다.
입력 클래스
inputClass · inputSmClass · selectClass · labelClass. 컴포넌트를 쓸 수 없는 자리에 붙이는 클래스 API 입니다.
FormField
폼 하단의 제출 영역입니다. 오류가 있으면 버튼 위에 빨간 틴트 상자로 표시됩니다. v2.x 에서 폐기 예정입니다.
이름은 2자 이상이어야 합니다.
전체 예시
서버 액션과 연결한 폼 전체 구성입니다.
체크박스 · 라디오
브라우저 기본 파랑 대신 primary 컬러를 쓰고 크기는 16px 입니다. 클래스 없이 전역 스타일로 적용됩니다.