@wishket/design-system 3.6.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/components/AutoCompleteList.md +85 -0
- package/dist/ai/components/Autocomplete.md +82 -0
- package/dist/ai/components/Button.md +205 -0
- package/dist/ai/components/Calendar.md +84 -0
- package/dist/ai/components/Checkbox.md +86 -0
- package/dist/ai/components/CheckboxCard.md +114 -0
- package/dist/ai/components/CheckboxList.md +94 -0
- package/dist/ai/components/ChoiceChip.md +126 -0
- package/dist/ai/components/CommentArea.md +111 -0
- package/dist/ai/components/FileUploader.md +145 -0
- package/dist/ai/components/FilterChip.md +132 -0
- package/dist/ai/components/FilterList.md +74 -0
- package/dist/ai/components/IconButton.md +89 -0
- package/dist/ai/components/InputChip.md +94 -0
- package/dist/ai/components/List.md +103 -0
- package/dist/ai/components/MultiColumnList.md +86 -0
- package/dist/ai/components/SearchField.md +116 -0
- package/dist/ai/components/TextButton.md +111 -0
- package/dist/ai/components/TextField.md +128 -0
- package/dist/ai/components/Textarea.md +154 -0
- package/dist/ai/components/index.json +165 -0
- package/dist/ai/tokens.json +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: INPUT-18
|
|
3
|
+
component: TextField
|
|
4
|
+
version: 0.0.3
|
|
5
|
+
status: draft
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 18. TextField
|
|
9
|
+
|
|
10
|
+
**개정 이력**
|
|
11
|
+
|
|
12
|
+
- v0.0.1 (2026.09.28): 초안 작성
|
|
13
|
+
- v0.0.2 (2026.10.01): 프론트매터 추가, Properties를 코드(`TextFieldProps`)·스토리북 기준으로 정리, Error Text 위치 정정(Supporting Text와 별도 줄), Error Text·Supporting Text 동시 표시 규칙을 "함께 표시"로 변경(코드·피그마 기준), 여러 줄 입력 안내를 Textarea로 정정, "나중"을 `Z. 미결`로 분리
|
|
14
|
+
- v0.0.3 (2026.10.02): Properties 안내 문구 통일, `value` · `onChange` · `onBlur` · `name` · `className` · `testId` 추가 (#1295 리뷰 반영)
|
|
15
|
+
|
|
16
|
+
## A. Anatomy
|
|
17
|
+
|
|
18
|
+
TextField는 **Container** 안에 입력 텍스트와 보조 요소들이 가로로 놓이고, 그 아래에 **Supporting Text** 줄이 붙는 구조입니다.
|
|
19
|
+
|
|
20
|
+
| 요소 | 필수 여부 | 설명 |
|
|
21
|
+
| --- | --- | --- |
|
|
22
|
+
| Container | 필수 | 배경·테두리·패딩을 담당. 클릭/포커스 영역의 기준 |
|
|
23
|
+
| Label | 조건부 | `variant = label`일 때 필드 **안쪽 상단**에 얹히는 항목명 |
|
|
24
|
+
| Placeholder / Text | 필수 | 입력 전에는 Placeholder, 입력 중에는 입력값 |
|
|
25
|
+
| Leading Icon | 선택 | 입력값 앞 아이콘 |
|
|
26
|
+
| Measure (단위) | 선택 | 입력값 뒤에 붙는 **단위 텍스트** (`원`, `명`) |
|
|
27
|
+
| Trailing Icon | 선택 | 우측 아이콘. 안내·비밀번호 보기 등 |
|
|
28
|
+
| Error Text | 조건부 | 오류 문구. 필드 하단, **Supporting Text 위에 별도 줄**로 표시 |
|
|
29
|
+
| Supporting Text | 선택 | 필드 하단 좌측의 도움말 |
|
|
30
|
+
| Max Length | 선택 | 필드 하단 우측의 글자 수 (`0/20`) |
|
|
31
|
+
|
|
32
|
+
## B. Description
|
|
33
|
+
|
|
34
|
+
### 1. 정의
|
|
35
|
+
|
|
36
|
+
사용자가 텍스트 입력 및 확인 시 사용되는 컴포넌트입니다.
|
|
37
|
+
|
|
38
|
+
### 2. 사용 시점
|
|
39
|
+
|
|
40
|
+
- 사용자가 **자유롭게 값을 입력**해야 할 때 사용합니다. (이름, 금액, 메모)
|
|
41
|
+
- 항목이 여러 개인 폼에서 **어떤 값을 넣는 칸인지 계속 보여야** 한다면 `variant = label`을 사용합니다.
|
|
42
|
+
- 항목명이 필드 바깥에 이미 있다면 `variant = default`로 사용합니다.
|
|
43
|
+
- 타이핑이 아니라 **클릭해서 모달·패널을 여는 필드**라면 **TextFieldTrigger**를 사용합니다.
|
|
44
|
+
- 입력하는 동안 제안 목록을 띄워 고르게 한다면 **Autocomplete**를 사용합니다.
|
|
45
|
+
- 검색어를 입력해 결과를 찾는 것이라면 **SearchField**를 사용합니다.
|
|
46
|
+
- 여러 줄을 입력받아야 한다면 **Textarea**를 사용합니다. (댓글·답글 작성은 **CommentArea**)
|
|
47
|
+
|
|
48
|
+
**유형**
|
|
49
|
+
|
|
50
|
+
| 유형 | 설명 |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| **Default** | 가장 기본적인 TextField입니다. Placeholder를 통해 입력 힌트를 제공하며, 간단한 텍스트 입력에 적합합니다. |
|
|
53
|
+
| **Fixed Label** | 고정 라벨이 있는 TextField입니다. **Placeholder가 있을 때** 라벨이 위쪽에 고정되어 표시됩니다. 라벨과 Placeholder를 모두 표시하여 명확한 안내가 필요한 경우에 사용하세요. |
|
|
54
|
+
| **Label** | 라벨이 플로팅되는 TextField입니다. **Placeholder가 없을 때** 라벨이 입력 필드 안에 위치하다가, 입력을 시작하면 위로 이동하여 애니메이션 효과를 제공합니다. |
|
|
55
|
+
| **Error State** | 에러 메시지를 표시하여 사용자에게 오류를 알립니다. |
|
|
56
|
+
| **Disabled** | 사용자가 입력할 수 없는 상태입니다. |
|
|
57
|
+
|
|
58
|
+
> Fixed Label과 Label은 별도 값이 아니라 **`variant = label` + Placeholder 유무**로 자동으로 갈립니다.
|
|
59
|
+
|
|
60
|
+
### 3. 키워드
|
|
61
|
+
|
|
62
|
+
TextField, 텍스트 필드, 입력, 입력창, Input, 폼, 레이블, Label, 플로팅 라벨
|
|
63
|
+
|
|
64
|
+
### 4. 에러 문구
|
|
65
|
+
|
|
66
|
+
- 에러 텍스트는 **`하세요`로 끝맺습니다.** (`이메일 형식을 확인하세요`)
|
|
67
|
+
- 무엇이 잘못됐는지가 아니라 **무엇을 하면 되는지**를 적습니다.
|
|
68
|
+
- 행동 지시형으로 간결하게 작성합니다. (`휴대폰 번호 10-11자리로 입력해 주세요`)
|
|
69
|
+
|
|
70
|
+
### 5. Do / Don't
|
|
71
|
+
|
|
72
|
+
**Do**
|
|
73
|
+
|
|
74
|
+
- Placeholder에는 **입력 형식의 예시**를 적습니다. (`010-0000-0000`)
|
|
75
|
+
- Supporting Text는 **최대 2줄**까지만 보이게 하고, 더 긴 메시지는 말줄임(`…`)으로 축약합니다. Error Text도 같습니다.
|
|
76
|
+
- 한 폼 안에서 Text Field와 Label Text Field를 섞지 않습니다.
|
|
77
|
+
- **Min + Max 모두 있는 경우**: 서포팅 텍스트에는 최소 글자 수, 입력 제한에는 최대 글자 수를 표시합니다.
|
|
78
|
+
- **Max 값만 있는 경우**: 서포팅 텍스트와 입력 제한 모두 동일하게 표시합니다.
|
|
79
|
+
- **Min 값만 있는 경우**: 서포팅 텍스트에 최소 글자 수를 표시합니다.
|
|
80
|
+
- **Error Text와 Supporting Text가 동시에 있으면 둘 다 표시합니다.** Error Text를 위에, Supporting Text를 아래에 둡니다. 오류가 났다고 도움말을 지우지 않습니다.
|
|
81
|
+
|
|
82
|
+
**Don't**
|
|
83
|
+
|
|
84
|
+
- Leading Icon과 Measure를 동시에 쓰지 않습니다.
|
|
85
|
+
- Placeholder를 항목명 대신 쓰지 않습니다. 입력을 시작하면 사라집니다.
|
|
86
|
+
- 입력값을 2줄로 표시하지 않습니다.
|
|
87
|
+
- `type = password`에 Trailing Icon을 추가하지 않습니다. 비밀번호 보기(눈 아이콘)가 자동으로 붙습니다.
|
|
88
|
+
|
|
89
|
+
## C. Properties
|
|
90
|
+
|
|
91
|
+
스토리북(코드) 이름 기준입니다. 표의 Property는 읽기 쉽게 첫 글자를 대문자로 적었고, **코드에서는 첫 글자가 소문자**입니다 (`IsError` → `isError`). 화면에 보이는 속성뿐 아니라 **동작용(`on…`)·개발용 prop도 적습니다.** 비고에 피그마 쪽 상태를 함께 적었습니다.
|
|
92
|
+
|
|
93
|
+
| Property | Type | Values | 비고 |
|
|
94
|
+
| --- | --- | --- | --- |
|
|
95
|
+
| Variant | Variant | `default` / `label` | 피그마는 **별도 컴포넌트 2개**(Text Field / Label Text Field)로 나뉘어 있음 (Z-1) |
|
|
96
|
+
| Type | Variant | `text` / `password` / `email` / `number` | 피그마에 없음 · 추가 필요 |
|
|
97
|
+
| Placeholder | String | | 피그마 추가 |
|
|
98
|
+
| Label | String | | `variant = label`일 때 사용 |
|
|
99
|
+
| Disabled | Boolean | True / False | 피그마 Label Text Field는 **State의 값**으로 되어 있음 → Boolean으로 통일 |
|
|
100
|
+
| IsError | Boolean | True / False | 오류 테두리. 피그마 `Is Error` |
|
|
101
|
+
| ErrorMessage | String | | 오류 문구. 필드 하단 Supporting Text **위**에 표시 |
|
|
102
|
+
| SupportMessage | String | | 도움말 문구 · 피그마 `Supporting Text`(Boolean) → 이름·타입 통일 필요 |
|
|
103
|
+
| MaxLength | Number | | 값을 넣으면 하단 우측에 글자 수(`0/20`) 표시 · 피그마는 Boolean → 숫자로 변경 필요 |
|
|
104
|
+
| Measure | String | | 단위 텍스트(`원`, `명`) · 피그마 `Caret` → **`Measure`로 개명 필요** |
|
|
105
|
+
| LeadingIcon | Instance | System Icon 이름 (Medium) | 피그마는 Boolean → Instance로 변경 필요 |
|
|
106
|
+
| TrailingIcon | Instance | System Icon 이름 (Medium) | 피그마는 Boolean → Instance로 변경 필요 |
|
|
107
|
+
| Value | String | | 입력값 |
|
|
108
|
+
| OnChange | Function | | 입력값이 바뀔 때 호출 · 동작용 |
|
|
109
|
+
| OnBlur | Function | | 입력 칸에서 벗어날 때 호출 · 동작용 |
|
|
110
|
+
| Name | String | | 폼 전송용 이름 · 개발용 |
|
|
111
|
+
| ClassName | String | | 개발용 스타일 지정 |
|
|
112
|
+
| TestId | String | | 테스트용 ID · 개발용 |
|
|
113
|
+
|
|
114
|
+
> 피그마의 `Variant`(Empty / Placeholder / Text)와 `State`(Enabled / Hovered / Focused)는 **코드에 따로 넣는 값이 없고 자동으로** 정해집니다. Empty·Placeholder·Text는 입력 내용에 따라, Hovered·Focused는 마우스·입력 상태에 따라 바뀝니다.
|
|
115
|
+
>
|
|
116
|
+
> ```tsx
|
|
117
|
+
> <TextField variant="label" label="예산" measure="원" maxLength={20}
|
|
118
|
+
> supportMessage="숫자만 입력하세요" isError={!!error} errorMessage={error}
|
|
119
|
+
> value={value} onChange={onChange} />
|
|
120
|
+
> ```
|
|
121
|
+
|
|
122
|
+
## Z. 미결 (구현하지 말 것)
|
|
123
|
+
|
|
124
|
+
> 아래는 **결정되지 않은 제안**입니다. 구현 기준은 위 A~C입니다. 결정되면 본문으로 옮기고 여기서 지웁니다.
|
|
125
|
+
|
|
126
|
+
1. **피그마 컴포넌트 통합**: 피그마는 Text Field와 Label Text Field가 별도 컴포넌트입니다. 코드처럼 하나로 합치고 `Variant = default / label`로 둘지 결정
|
|
127
|
+
2. **Leading Icon은 양쪽 모두 가질 수 있습니다**: 스토리북은 `variant`와 무관하게 `leadingIcon`을 지원합니다. 피그마의 Label Text Field에만 없는 것은 그리지 않았기 때문으로 보입니다 → 피그마 추가 검토
|
|
128
|
+
3. **피그마 오타**: Label Text Field Anatomy에 `Lable Text` 오타가 있습니다
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: INPUT-19
|
|
3
|
+
component: Textarea
|
|
4
|
+
version: 0.0.3
|
|
5
|
+
status: draft
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 19. Textarea
|
|
9
|
+
|
|
10
|
+
**개정 이력**
|
|
11
|
+
|
|
12
|
+
- v0.0.1 (2026.09.28): 초안 작성
|
|
13
|
+
- v0.0.2 (2026.10.01): 프론트매터 추가, 이름을 코드 기준 `Textarea`로 통일, Properties를 코드(`TextareaProps`)·스토리북 기준으로 정리(`resize` · `supportText` · `errorText`, Size `full` 추가), Error Text·Supporting Text "함께 표시"로 변경(TextField와 동일), 피그마 ↔ 코드 대응표 추가, "나중확인"을 `Z. 미결`로 분리
|
|
14
|
+
- v0.0.3 (2026.10.02): Anatomy의 Scrollbar를 "항상 표시"로 정정, Properties 안내 문구 통일, `value` · `onChange` · `onBlur` · `name` 추가, Z절 색 표기를 코드 토큰명으로 (#1295 리뷰 반영)
|
|
15
|
+
|
|
16
|
+
## A. Anatomy
|
|
17
|
+
|
|
18
|
+
Textarea는 **Container** 안에 여러 줄 입력 영역이 있고, 그 아래에 **Supporting Text** 줄이 붙는 구조입니다.
|
|
19
|
+
|
|
20
|
+
| 요소 | 필수 여부 | 설명 |
|
|
21
|
+
| --- | --- | --- |
|
|
22
|
+
| Container | 필수 | 배경·테두리·패딩을 담당. 클릭/포커스 영역의 기준 |
|
|
23
|
+
| Placeholder / Text | 필수 | 입력 전에는 Placeholder, 입력 중에는 입력값 |
|
|
24
|
+
| Scrollbar | 필수 | 입력 영역 우측의 스크롤 표시. 내용 양과 관계없이 **항상** 표시됩니다 |
|
|
25
|
+
| Resizer | 선택 | 우측 하단의 크기 조절 손잡이 |
|
|
26
|
+
| Error Text | 조건부 | 오류 문구. 필드 하단, **Supporting Text 위에 별도 줄**로 표시 |
|
|
27
|
+
| Supporting Text | 선택 | 필드 하단 좌측의 도움말 |
|
|
28
|
+
| Max Length | 선택 | 필드 하단 우측의 글자 수 (`0/20`) |
|
|
29
|
+
|
|
30
|
+
## B. Description
|
|
31
|
+
|
|
32
|
+
### 1. 정의
|
|
33
|
+
|
|
34
|
+
사용자가 여러 줄의 텍스트를 길게 작성할 때 사용하는 컴포넌트입니다.
|
|
35
|
+
|
|
36
|
+
### 2. 사용 시점
|
|
37
|
+
|
|
38
|
+
- 사용자가 **여러 줄에 걸쳐 긴 글**을 써야 할 때 사용합니다. (소개, 요청 사항, 상세 설명)
|
|
39
|
+
- 입력 길이를 **미리 가늠할 수 없을 때** 사용합니다.
|
|
40
|
+
- 한 줄이면 충분한 값이라면 **TextField**를 사용합니다.
|
|
41
|
+
- 게시물에 대한 **의견·답글**을 남기는 자리라면 **CommentArea**를 사용합니다.
|
|
42
|
+
- 검색어를 입력해 결과를 찾는 것이라면 **SearchField**를 사용합니다.
|
|
43
|
+
|
|
44
|
+
### 3. 키워드
|
|
45
|
+
|
|
46
|
+
Textarea, 텍스트 에어리어, 여러 줄 입력, 장문 입력, 본문 입력, TextArea
|
|
47
|
+
|
|
48
|
+
### 4. Size
|
|
49
|
+
|
|
50
|
+
Size는 **입력 영역의 높이**만 다릅니다. 그 외 규격은 모두 같습니다.
|
|
51
|
+
|
|
52
|
+
| Size | 코드 값 | 입력 영역 Height | 전체 Height (Supporting 포함) | 전체 Height (Error 포함) |
|
|
53
|
+
| --- | --- | --- | --- | --- |
|
|
54
|
+
| **Small** | `sm` | 120 | 152 | 184 |
|
|
55
|
+
| **Medium** (기본) | `md` | 240 | 272 | 304 |
|
|
56
|
+
| **Large** | `lg` | 360 | 392 | 424 |
|
|
57
|
+
| **Full** | `full` | 부모 높이를 꽉 채움 | — | — |
|
|
58
|
+
|
|
59
|
+
### 4-1. Size 선택 기준
|
|
60
|
+
|
|
61
|
+
| Size | 사용 상황 |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| **Small** | 한두 문장 정도의 짧은 보충 설명 |
|
|
64
|
+
| **Medium** | 한 문단 분량의 일반적인 장문 입력 |
|
|
65
|
+
| **Large** | 여러 문단을 쓰는 본문 성격의 입력 (프로젝트 상세 설명 등) |
|
|
66
|
+
| **Full** | 화면·패널의 남은 높이를 모두 입력 영역으로 쓸 때 (에디터형 화면) |
|
|
67
|
+
|
|
68
|
+
- Size는 **예상 입력량**에 맞춰 고릅니다. 화면 여백을 채우려고 키우지 않습니다.
|
|
69
|
+
- 한 폼 안에서는 같은 Size로 통일합니다.
|
|
70
|
+
- 입력 내용이 영역을 넘으면 **스크롤을 반드시 노출**합니다. 내용이 더 있다는 것을 사용자가 알 수 있어야 합니다.
|
|
71
|
+
|
|
72
|
+
1. Resizer는 **세로 방향 확대만** 허용합니다.
|
|
73
|
+
2. Resizer를 끄는 경우, Size 선택만으로 충분한 높이가 확보되는지 확인합니다.
|
|
74
|
+
3. `Full`과 Resizer를 함께 쓰면 부모 영역에 최소 높이가 정해져 있어야 합니다 (개발 시 grid + min-height 필요).
|
|
75
|
+
|
|
76
|
+
### 4-2. Width
|
|
77
|
+
|
|
78
|
+
- Textarea는 **부모 컨테이너 너비를 100% 채웁니다.** Figma의 `400`은 예시 값입니다.
|
|
79
|
+
- 가로 스크롤은 사용하지 않습니다. 긴 줄은 자동 줄바꿈합니다.
|
|
80
|
+
|
|
81
|
+
### 4-3. Supporting Text · Max Length · Error Text
|
|
82
|
+
|
|
83
|
+
1. Supporting Text는 **최대 2줄**까지만 보이고, 더 긴 메시지는 **말줄임(`…`)** 처리합니다.
|
|
84
|
+
2. Error Text도 영역을 초과하면 말줄임으로 축약합니다.
|
|
85
|
+
3. Max Length는 항상 **우측 정렬**하며 `현재/최대` 형식으로 표기합니다. (`0/20`)
|
|
86
|
+
4. **입력 글자 수는 5000자까지만 사용합니다.** 자동 제한이 없으므로 `maxLength`를 `5000` 이하로 반드시 지정합니다.
|
|
87
|
+
5. Supporting Text 자리는 오류 여부와 무관하게 **항상 확보**합니다.
|
|
88
|
+
6. **Error Text와 Supporting Text가 동시에 있으면 둘 다 표시합니다.** Error Text를 위에, Supporting Text를 아래에 둡니다. (TextField와 동일)
|
|
89
|
+
|
|
90
|
+
### 5. Do / Don't
|
|
91
|
+
|
|
92
|
+
**Do**
|
|
93
|
+
|
|
94
|
+
- Placeholder에는 **무엇을 쓰는 칸인지** 적습니다. (`프로젝트 내용을 자세히 적어주세요`)
|
|
95
|
+
- 입력 내용이 영역을 넘으면 스크롤을 노출합니다.
|
|
96
|
+
- 예상 입력량에 맞는 Size를 고릅니다.
|
|
97
|
+
- 글자 수 제한이 있으면 Max Length를 함께 노출합니다.
|
|
98
|
+
|
|
99
|
+
**Don't**
|
|
100
|
+
|
|
101
|
+
- 한 줄이면 충분한 값에 Textarea를 쓰지 않습니다.
|
|
102
|
+
- 입력 내용에 따라 높이를 무한정 늘리지 않습니다. 스크롤로 처리합니다.
|
|
103
|
+
- 가로 스크롤을 만들지 않습니다.
|
|
104
|
+
- 5000자를 넘는 입력을 허용하지 않습니다.
|
|
105
|
+
|
|
106
|
+
## C. Properties
|
|
107
|
+
|
|
108
|
+
스토리북(코드) 이름 기준입니다. 표의 Property는 읽기 쉽게 첫 글자를 대문자로 적었고, **코드에서는 첫 글자가 소문자**입니다 (`IsError` → `isError`). 화면에 보이는 속성뿐 아니라 **동작용(`on…`)·개발용 prop도 적습니다.** 비고에 피그마 이름을 함께 적었습니다.
|
|
109
|
+
|
|
110
|
+
| Property | Type | Values | 비고 |
|
|
111
|
+
| --- | --- | --- | --- |
|
|
112
|
+
| Placeholder | String | | 피그마 추가 |
|
|
113
|
+
| Size | Variant | `sm` / `md` / `lg` / `full` | 기본값 `md` · 피그마는 **Small / Medium / Large 세 컴포넌트로 분리**되어 있고 `full`이 없음 (Z-1) |
|
|
114
|
+
| MaxLength | Number | | 최대 글자 수 (5000 이하) · 피그마는 Boolean → 숫자로 변경 필요 |
|
|
115
|
+
| IsLengthVisible | Boolean | True / False | 글자 수(`0/20`) 표시 여부 (동작 주의: Z-4) |
|
|
116
|
+
| IsError | Boolean | True / False | 오류 테두리 |
|
|
117
|
+
| ErrorText | String | | 오류 문구 · 피그마 `Error Text`(Boolean) → 텍스트 속성 추가 |
|
|
118
|
+
| SupportText | String | | 도움말 문구 · 피그마 `Supporting Text`(Boolean) → 텍스트 속성 추가 |
|
|
119
|
+
| Resize | Boolean | True / False | 세로 크기 조절 + Resizer 아이콘 표시. 기본값 False · 피그마 `resizer` |
|
|
120
|
+
| Disabled | Boolean | True / False | 피그마는 **State의 값** → TextField와 맞춰 Boolean으로 분리 검토 |
|
|
121
|
+
| Value | String | | 입력값. 글자 수(`현재/최대`) 계산에도 쓰입니다 |
|
|
122
|
+
| OnChange | Function | | 입력값이 바뀔 때 호출 · 동작용 |
|
|
123
|
+
| OnBlur | Function | | 입력 칸에서 벗어날 때 호출 · 동작용 |
|
|
124
|
+
| Name | String | | 폼 전송용 이름 · 개발용 |
|
|
125
|
+
|
|
126
|
+
**피그마 ↔ 코드 대응**
|
|
127
|
+
|
|
128
|
+
피그마의 `Variant`·`State`·`Scrollbar`는 코드에 따로 넣는 값이 없고, **자동으로** 정해집니다.
|
|
129
|
+
|
|
130
|
+
| 피그마 | 코드 | 모습 |
|
|
131
|
+
| --- | --- | --- |
|
|
132
|
+
| `Variant = Empty / Placeholder / Text` | 입력 내용에 따라 자동 | 빈 칸 / 회색 안내 문구 / 입력값 |
|
|
133
|
+
| `State = Enabled` | 기본 | 회색 테두리 |
|
|
134
|
+
| `State = Hovered` | 마우스 hover (자동) | Primary 테두리 |
|
|
135
|
+
| `State = Focused` | 입력 중 (자동) | Primary 테두리 |
|
|
136
|
+
| `State = Disabled` | `disabled` | 회색 배경, 입력·크기 조절 불가 |
|
|
137
|
+
| `Is Error = True` | `isError` | Red 테두리 |
|
|
138
|
+
| `Scrollbar` | 항상 표시 | 입력 영역 우측 |
|
|
139
|
+
|
|
140
|
+
> ```tsx
|
|
141
|
+
> <Textarea size="lg" placeholder="프로젝트 내용을 자세히 적어주세요" resize
|
|
142
|
+
> maxLength={5000} isLengthVisible supportText="최대 5000자"
|
|
143
|
+
> isError={!!error} errorText={error} value={value} onChange={onChange} />
|
|
144
|
+
> ```
|
|
145
|
+
|
|
146
|
+
## Z. 미결 (구현하지 말 것)
|
|
147
|
+
|
|
148
|
+
> 아래는 **결정되지 않은 제안**입니다. 구현 기준은 위 A~C입니다. 결정되면 본문으로 옮기고 여기서 지웁니다.
|
|
149
|
+
|
|
150
|
+
1. **피그마 컴포넌트 통합**: 피그마는 Text Area (Small / Medium / Large)가 별도 컴포넌트입니다. 하나로 합치고 `Size` 속성으로 둘지, 코드의 `full`을 피그마에 추가할지 결정
|
|
151
|
+
2. **Disabled 텍스트 색 불일치 (피그마)**: Textarea는 **`w-gray-200`(`#E0E0E0`)**, TextField는 `w-gray-300`(`#BDBDBD`). 한쪽으로 통일 (`w-gray-300` 권장 — 너무 흐리면 읽히지 않음)
|
|
152
|
+
3. **Disabled의 패딩 구조가 다름 (피그마)**: 다른 변형은 `좌 16 / 우 8 / 상하 10`, Disabled는 `좌우 17 / 상하 11`. Disabled만 이전 구조로 남아 있음 — 통일 필요
|
|
153
|
+
4. **글자 수 표시 동작 (개발팀 전달)**: `isLengthVisible`을 꺼도 `supportText`와 `maxLength`가 있으면 글자 수가 보이고, `supportText`가 없으면 `maxLength`만으로는 보이지 않습니다. 이름과 실제 동작이 맞지 않습니다
|
|
154
|
+
5. **prop 이름 불일치 (개발팀 전달)**: TextField는 `supportMessage` · `errorMessage`, Textarea는 `supportText` · `errorText`를 씁니다. 통일하려면 코드 이름을 바꿔야 하므로(사용처가 깨지는 변경) 개발팀과 결정
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "빌드 산출물이다. 손으로 고치지 않는다 — scripts/generate-ai-components.mjs 가 docs/component/ 에서 만든다.",
|
|
3
|
+
"components": [
|
|
4
|
+
{
|
|
5
|
+
"id": "INPUT-01",
|
|
6
|
+
"component": "AutoCompleteList",
|
|
7
|
+
"version": "0.0.2",
|
|
8
|
+
"status": "draft",
|
|
9
|
+
"path": "components/AutoCompleteList.md",
|
|
10
|
+
"source": "docs/component/Input/List/AutoCompleteList.md"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"id": "INPUT-02",
|
|
14
|
+
"component": "FilterList",
|
|
15
|
+
"version": "0.0.1",
|
|
16
|
+
"status": "draft",
|
|
17
|
+
"path": "components/FilterList.md",
|
|
18
|
+
"source": "docs/component/Input/List/FilterList.md"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "INPUT-03",
|
|
22
|
+
"component": "List",
|
|
23
|
+
"version": "0.0.2",
|
|
24
|
+
"status": "draft",
|
|
25
|
+
"path": "components/List.md",
|
|
26
|
+
"source": "docs/component/Input/List/List.md"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"id": "INPUT-04",
|
|
30
|
+
"component": "MultiColumnList",
|
|
31
|
+
"version": "0.0.1",
|
|
32
|
+
"status": "draft",
|
|
33
|
+
"path": "components/MultiColumnList.md",
|
|
34
|
+
"source": "docs/component/Input/List/MultiColumnList.md"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "INPUT-05",
|
|
38
|
+
"component": "Autocomplete",
|
|
39
|
+
"version": "0.0.2",
|
|
40
|
+
"status": "draft",
|
|
41
|
+
"path": "components/Autocomplete.md",
|
|
42
|
+
"source": "docs/component/Input/Autocomplete.md"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "INPUT-06",
|
|
46
|
+
"component": "Button",
|
|
47
|
+
"version": "0.0.3",
|
|
48
|
+
"status": "draft",
|
|
49
|
+
"path": "components/Button.md",
|
|
50
|
+
"source": "docs/component/Input/Button/Button.md"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"id": "INPUT-07",
|
|
54
|
+
"component": "IconButton",
|
|
55
|
+
"version": "0.0.3",
|
|
56
|
+
"status": "draft",
|
|
57
|
+
"path": "components/IconButton.md",
|
|
58
|
+
"source": "docs/component/Input/Button/IconButton.md"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": "INPUT-08",
|
|
62
|
+
"component": "TextButton",
|
|
63
|
+
"version": "0.0.1",
|
|
64
|
+
"status": "draft",
|
|
65
|
+
"path": "components/TextButton.md",
|
|
66
|
+
"source": "docs/component/Input/Button/TextButton.md"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "INPUT-09",
|
|
70
|
+
"component": "Calendar",
|
|
71
|
+
"version": "0.0.2",
|
|
72
|
+
"status": "draft",
|
|
73
|
+
"path": "components/Calendar.md",
|
|
74
|
+
"source": "docs/component/Input/Calendar.md"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "INPUT-10",
|
|
78
|
+
"component": "CheckboxList",
|
|
79
|
+
"version": "0.0.2",
|
|
80
|
+
"status": "draft",
|
|
81
|
+
"path": "components/CheckboxList.md",
|
|
82
|
+
"source": "docs/component/Input/Checkbox/CheckboxList.md"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"id": "INPUT-11",
|
|
86
|
+
"component": "Checkbox",
|
|
87
|
+
"version": "0.0.3",
|
|
88
|
+
"status": "draft",
|
|
89
|
+
"path": "components/Checkbox.md",
|
|
90
|
+
"source": "docs/component/Input/Checkbox/Checkbox.md"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"id": "INPUT-12",
|
|
94
|
+
"component": "CheckboxCard",
|
|
95
|
+
"version": "0.0.3",
|
|
96
|
+
"status": "draft",
|
|
97
|
+
"path": "components/CheckboxCard.md",
|
|
98
|
+
"source": "docs/component/Input/Checkbox/CheckboxCard.md"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"id": "INPUT-13",
|
|
102
|
+
"component": "ChoiceChip",
|
|
103
|
+
"version": "0.0.3",
|
|
104
|
+
"status": "draft",
|
|
105
|
+
"path": "components/ChoiceChip.md",
|
|
106
|
+
"source": "docs/component/Input/Chip/ChoiceChip.md"
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"id": "INPUT-14",
|
|
110
|
+
"component": "FilterChip",
|
|
111
|
+
"version": "0.0.3",
|
|
112
|
+
"status": "draft",
|
|
113
|
+
"path": "components/FilterChip.md",
|
|
114
|
+
"source": "docs/component/Input/Chip/FilterChip.md"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"id": "INPUT-15",
|
|
118
|
+
"component": "InputChip",
|
|
119
|
+
"version": "0.0.3",
|
|
120
|
+
"status": "draft",
|
|
121
|
+
"path": "components/InputChip.md",
|
|
122
|
+
"source": "docs/component/Input/Chip/InputChip.md"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"id": "INPUT-16",
|
|
126
|
+
"component": "CommentArea",
|
|
127
|
+
"version": "0.0.3",
|
|
128
|
+
"status": "draft",
|
|
129
|
+
"path": "components/CommentArea.md",
|
|
130
|
+
"source": "docs/component/Input/TextField/CommentArea.md"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"id": "INPUT-17",
|
|
134
|
+
"component": "SearchField",
|
|
135
|
+
"version": "0.0.3",
|
|
136
|
+
"status": "draft",
|
|
137
|
+
"path": "components/SearchField.md",
|
|
138
|
+
"source": "docs/component/Input/TextField/SearchField.md"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"id": "INPUT-18",
|
|
142
|
+
"component": "TextField",
|
|
143
|
+
"version": "0.0.3",
|
|
144
|
+
"status": "draft",
|
|
145
|
+
"path": "components/TextField.md",
|
|
146
|
+
"source": "docs/component/Input/TextField/TextField.md"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"id": "INPUT-19",
|
|
150
|
+
"component": "Textarea",
|
|
151
|
+
"version": "0.0.3",
|
|
152
|
+
"status": "draft",
|
|
153
|
+
"path": "components/Textarea.md",
|
|
154
|
+
"source": "docs/component/Input/TextField/Textarea.md"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"id": "INPUT-20",
|
|
158
|
+
"component": "FileUploader",
|
|
159
|
+
"version": "0.0.3",
|
|
160
|
+
"status": "draft",
|
|
161
|
+
"path": "components/FileUploader.md",
|
|
162
|
+
"source": "docs/component/Input/FileUploader.md"
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
}
|
package/dist/ai/tokens.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wishket/design-system",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Wishket Design System",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -46,7 +46,10 @@
|
|
|
46
46
|
"prettier:check": "prettier --cache --check .",
|
|
47
47
|
"prettier:write": "prettier --cache --write .",
|
|
48
48
|
"chromatic": "chromatic --exit-zero-on-changes",
|
|
49
|
-
"build:ai-tokens": "node scripts/generate-ai-tokens.mjs && node scripts/check-ai-tokens.mjs"
|
|
49
|
+
"build:ai-tokens": "node scripts/generate-ai-tokens.mjs && node scripts/check-ai-tokens.mjs && yarn build:ai-components",
|
|
50
|
+
"build:ai-components": "node scripts/generate-ai-components.mjs",
|
|
51
|
+
"check:component-docs": "node scripts/check-component-docs.mjs",
|
|
52
|
+
"test:component-docs": "node scripts/__tests__/check-component-docs.test.mjs && node scripts/__tests__/generate-ai-components.test.mjs"
|
|
50
53
|
},
|
|
51
54
|
"dependencies": {
|
|
52
55
|
"@wishket/yogokit": "^0.2.2",
|