@wishket/design-system 3.6.0 → 3.8.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.
Files changed (33) hide show
  1. package/dist/ai/components/AutoCompleteList.md +86 -0
  2. package/dist/ai/components/Autocomplete.md +83 -0
  3. package/dist/ai/components/Button.md +205 -0
  4. package/dist/ai/components/Calendar.md +91 -0
  5. package/dist/ai/components/Checkbox.md +96 -0
  6. package/dist/ai/components/CheckboxCard.md +116 -0
  7. package/dist/ai/components/CheckboxList.md +102 -0
  8. package/dist/ai/components/ChoiceChip.md +127 -0
  9. package/dist/ai/components/CommentArea.md +112 -0
  10. package/dist/ai/components/FileUploader.md +146 -0
  11. package/dist/ai/components/FilterChip.md +133 -0
  12. package/dist/ai/components/FilterList.md +75 -0
  13. package/dist/ai/components/IconButton.md +97 -0
  14. package/dist/ai/components/IconButtonDropdown.md +103 -0
  15. package/dist/ai/components/InputChip.md +95 -0
  16. package/dist/ai/components/List.md +104 -0
  17. package/dist/ai/components/MultiColumnList.md +87 -0
  18. package/dist/ai/components/Radio.md +140 -0
  19. package/dist/ai/components/RadioCard.md +134 -0
  20. package/dist/ai/components/RadioList.md +150 -0
  21. package/dist/ai/components/RangeSlider.md +139 -0
  22. package/dist/ai/components/SearchField.md +117 -0
  23. package/dist/ai/components/SegmentedControl.md +131 -0
  24. package/dist/ai/components/Switch.md +114 -0
  25. package/dist/ai/components/TextButton.md +123 -0
  26. package/dist/ai/components/TextButtonDropdown.md +101 -0
  27. package/dist/ai/components/TextField.md +129 -0
  28. package/dist/ai/components/TextFieldDropdown.md +123 -0
  29. package/dist/ai/components/Textarea.md +154 -0
  30. package/dist/ai/components/index.json +324 -0
  31. package/dist/ai/tokens.json +1 -1
  32. package/dist/config/tailwind.config.js +15 -15
  33. package/package.json +5 -2
@@ -0,0 +1,87 @@
1
+ ---
2
+ id: INPUT-04
3
+ component: MultiColumnList
4
+ version: 0.0.1
5
+ status: draft
6
+ figma.componentKey: ebdad70e98b3c5eb59ef1d5eb4dae510872e280f
7
+ ---
8
+
9
+ # 4. MultiColumnList
10
+
11
+ **개정 이력**
12
+
13
+ - v0.0.1 (2026.09.22): 초안 작성
14
+
15
+ ## A. Anatomy
16
+
17
+ MultiColumnList는 하나의 **Container** 안에 두 개의 컬럼을 Divider로 나눠 배치합니다. 왼쪽은 대분류를 고르는 **Item** 목록, 오른쪽은 선택된 대분류에 속한 **Radio List**입니다.
18
+
19
+ | 요소 | 필수 여부 | 설명 |
20
+ | --- | --- | --- |
21
+ | Container | 필수 | 테두리·모서리를 담당하는 영역. 두 컬럼을 감싸는 기준 |
22
+ | Item | 필수 | 왼쪽 컬럼의 대분류 항목. 선택하면 오른쪽 컬럼의 내용이 바뀝니다 |
23
+ | Divider | 필수 | 두 컬럼을 나누는 세로 구분선 |
24
+ | Title | 조건부 | 오른쪽 컬럼에서 항목을 묶는 그룹명. `Recommend` 유형에서만 사용 |
25
+ | Radio List | 필수 | 오른쪽 컬럼의 최종 선택 항목. 단일 선택 |
26
+ | Scrollbar | 선택 | 각 컬럼의 스크롤 위치 표시. 컬럼마다 독립적으로 동작 |
27
+
28
+ > 왼쪽 컬럼의 Item은 **List 문서의 Item과 동일한 컴포넌트**이며, `Leading Icon = False`로 사용합니다.
29
+ >
30
+
31
+ ## B. Description
32
+
33
+ ### 1. 정의
34
+
35
+ 계층형 데이터나 복잡한 카테고리 구조를 리스트 형태로 표시하여 탐색과 선택을 지원하는 컴포넌트입니다.
36
+
37
+ ### 2. 사용 시점
38
+
39
+ - 선택지가 **2단계 계층**으로 나뉘고, 대분류를 고른 뒤 그 안에서 하나를 고르게 할 때 사용합니다.
40
+ - 소분류 항목이 많아 한 번에 나열하면 훑기 어려울 때 사용합니다.
41
+ - 계층이 없는 단일 목록이라면 **List**를 사용합니다.
42
+ - 조건을 여러 개 동시에 선택해야 한다면 **FilterList**를 사용합니다.
43
+
44
+ ### 3. 키워드
45
+
46
+ MultiColumnList, 멀티컬럼, 2단 리스트, 계층 선택, 카테고리 선택, 대분류·소분류, Miller Column
47
+
48
+ ### 4. Do / Don't
49
+
50
+ **Do**
51
+
52
+ - 왼쪽 컬럼에는 **항상 하나의 항목이 선택되어 있게** 합니다. 처음 열릴 때는 첫 번째 항목을 선택합니다.
53
+ - 오른쪽 컬럼에서 선택한 값이 바뀌어도 왼쪽 선택은 유지합니다.
54
+ - 왼쪽 대분류 이름은 짧은 명사로 통일합니다.
55
+ - 선택 불가한 항목은 숨기지 말고 Disabled로 남깁니다.
56
+
57
+ **Don't**
58
+
59
+ - 오른쪽 컬럼에서 여러 개를 선택하게 하지 않습니다. (다중 선택이 필요하면 FilterList)
60
+ - 왼쪽 항목을 클릭했을 때 오른쪽이 비어 있게 두지 않습니다.
61
+ - 컬럼을 3개 이상으로 늘리지 않습니다.
62
+
63
+ ## C. Properties
64
+
65
+ | Property | Type | Values | 비고 |
66
+ | --- | --- | --- | --- |
67
+ | Variant | Variant | Recommend/General ↔ Default/WithRecommendations | 피그마 수정 or 스토리북 수정 |
68
+ | Scrollbar | Boolean | True / False | |
69
+
70
+ ### Item (왼쪽 컬럼)
71
+
72
+ | Property | Type | Values | 비고 |
73
+ | --- | --- | --- | --- |
74
+ | Checked | Boolean | True / False | 피그마 `Checked` → **`Selected`** 로 수정 |
75
+ | Disabled | Boolean | True / False | |
76
+ | State | Variant | Enabled / Hovered | |
77
+ | Leading Icon | Boolean | True / False | MultiColumnList에서는 False 고정 |
78
+
79
+ ### Radio List (오른쪽 컬럼)
80
+
81
+ | Property | Type | Values | 비고 |
82
+ | --- | --- | --- | --- |
83
+ | Checked | Boolean | True / False | |
84
+ | Disabled | Boolean | True / False | |
85
+ | State | Variant | Enabled | |
86
+ | Is Error | Boolean | True / False | MultiColumnList에서는 미사용 |
87
+ | Title | Boolean | True / False | 그룹 타이틀 노출 여부 · 피그마 추가 |
@@ -0,0 +1,140 @@
1
+ ---
2
+ id: INPUT-24
3
+ component: Radio
4
+ version: 0.0.1
5
+ status: draft
6
+ ---
7
+
8
+ # 24. Radio
9
+
10
+ **개정 이력**
11
+
12
+ - v0.0.1 (2026.10.02): 초안 작성
13
+
14
+ ## A. Anatomy
15
+
16
+ Radio는 **원형 Container**와 그 안의 **선택 점**으로 구성됩니다. 개별 컴포넌트로 제공되며, **Label·설명과 함께 쓰면 RadioListItem · RadioList**, 카드 형태로 쓰면 **RadioCard**가 됩니다.
17
+
18
+ | 요소 | 필수 여부 | 설명 |
19
+ | --- | --- | --- |
20
+ | Container | 필수 | 18×18 원형. 배경·테두리를 담당 |
21
+ | System Icons (선택 점) | 조건부 | 선택되었을 때만 나타나는 가운데 점 |
22
+
23
+ **상태별 표시**
24
+
25
+ | 상태 | 테두리 | 배경 | 선택 점 |
26
+ | --- | --- | --- | --- |
27
+ | 기본 | `w-gray-200` | `w-white` | — |
28
+ | Hover · 키보드 포커스 | `primary-500` | `w-white` | — |
29
+ | 선택됨 | `primary-500` | `w-white` | `primary-500` |
30
+ | Error | `w-red-500` | `w-white` | (선택 시) `w-red-500` |
31
+ | Disabled | `w-gray-200` | `w-gray-50` | — |
32
+ | Disabled + 선택됨 | `primary-100` | `w-white` | `primary-100` |
33
+
34
+ > Disabled가 Error보다 우선합니다. Disabled + Error는 Disabled와 같게 보입니다.
35
+
36
+ ## B. Description
37
+
38
+ ### 1. 정의
39
+
40
+ 사용자가 다중 항목 중 하나만 선택할 수 있도록 돕는 컴포넌트입니다. 같은 묶음에서 하나를 고르면 나머지는 자동으로 해제됩니다.
41
+
42
+ ### 2. 사용 시점
43
+
44
+ - 여러 선택지 중 **하나만** 골라야 하고, 선택지를 **모두 펼쳐 보여주는 게** 나을 때 사용합니다. (2~5개)
45
+ - 하나 이상을 골라야 한다면 **Checkbox**를 사용합니다.
46
+ - 선택지가 많아 펼칠 수 없다면 **TextFieldDropdown**을 사용합니다.
47
+ - 켜고 끄는 선택이 하나뿐이고 즉시 반영돼야 한다면 **Switch**를 사용합니다.
48
+ - Label·설명이 필요하면 Radio 단독이 아니라 **RadioListItem** · **RadioList**를, 카드 형태라면 **RadioCard**를 사용합니다.
49
+
50
+ **Radio · Checkbox · ChoiceChip**
51
+
52
+ | 기준 | Radio | Checkbox | ChoiceChip |
53
+ | --- | --- | --- | --- |
54
+ | 선택 개수 | 묶음 안에서 하나만 | 하나 또는 여러 개 | 하나 또는 여러 개 |
55
+ | 선택 해제 | 다른 항목을 고르면 해제. 같은 항목을 다시 눌러도 해제되지 않음 | 다시 누르면 해제 | 다시 누르면 해제 |
56
+ | 항목 텍스트 | 문장도 가능 | 문장도 가능 | 짧은 단어 |
57
+ | 배치 | 세로로 쌓기 | 세로로 쌓기 | 가로로 나란히 |
58
+ | 단독 사용 | 하지 않음 (항상 2개 이상) | 가능 (약관 동의) | 하지 않음 (2개 이상 그룹) |
59
+ | 주로 쓰는 곳 | 폼에서 답 하나 고르기 | 동의, 해당 항목 체크 | 관심 분야·기술 스택, 조건 고르기 |
60
+ | 예시 | 결제 수단, 사업자 유형 | 약관 동의, 알림 수신 항목 | 기술 스택, 업종 태그 |
61
+
62
+ ### 3. 키워드
63
+
64
+ Radio, 라디오, 라디오 버튼, Radio Button, 단일 선택
65
+
66
+ ### 4. 터치 영역
67
+
68
+ Radio 단독으로는 **18×18 원만** 눌립니다. 글자나 행 전체를 눌러도 선택되게 하려면 아래처럼 씁니다.
69
+
70
+ | 구성 | 눌리는 영역 | 방법 |
71
+ | --- | --- | --- |
72
+ | Radio 단독 | 원(18×18)만 | — |
73
+ | Radio + Label | 원 + 글자 | Label을 `id` / `htmlFor`로 연결하거나 `<label>`로 감쌈 |
74
+ | RadioListItem · RadioList | 행 전체 (여백 포함) | 컴포넌트가 알아서 처리 |
75
+ | RadioCard | 카드 전체 | 컴포넌트가 알아서 처리 |
76
+
77
+ > 화면에 Radio를 직접 놓고 Label을 옆에 쓰면, 연결하지 않는 한 글자를 눌러도 선택되지 않습니다. 목록이라면 RadioListItem을 쓰는 것이 가장 안전합니다.
78
+
79
+ ### 5. 가이드라인 (Do / Don't)
80
+
81
+ **하나만 고를 때 쓰기**
82
+
83
+ - Do: 여러 선택지 중 **하나만** 고르게 할 때 씁니다. 한 묶음의 Radio는 같은 `name`을 줍니다.
84
+ - Don't: 여러 개를 고르거나, 항목 하나를 켜고 끄는 데 쓰지 않습니다. 그 경우는 **Checkbox**입니다.
85
+
86
+ **기본값 제공하기**
87
+
88
+ - Do: 가장 많이 쓰거나 권장하는 항목을 미리 선택해 둡니다.
89
+ - Don't: 모두 비워 두지 않습니다. 한 번 고르면 다시 빈 상태로 되돌릴 수 없습니다.
90
+
91
+ **세로로 쌓기**
92
+
93
+ - Do: 세로로 쌓습니다. 가로로 두어야 한다면 항목 사이 간격을 충분히 둡니다.
94
+ - Don't: 좁은 화면에서 가로로 다닥다닥 붙이지 않습니다. Label이 어느 Radio 것인지 헷갈립니다.
95
+
96
+ **Radio는 Label 왼쪽에**
97
+
98
+ - Do: Radio를 왼쪽, Label을 오른쪽에 둡니다. Label을 눌러도 선택되게 연결합니다. (4. 터치 영역)
99
+
100
+ **오류는 문구와 함께**
101
+
102
+ - Do: 오류 사유는 반드시 **Supporting Text**로 함께 제공합니다.
103
+ - Don't: 테두리 색상만으로 오류를 알리지 않습니다.
104
+
105
+ **그 밖에**
106
+
107
+ - 선택 불가한 항목은 숨기지 말고 Disabled로 남깁니다.
108
+ - 18보다 작게 축소하지 않습니다.
109
+
110
+ ## C. Properties
111
+
112
+ 스토리북(코드) 이름 기준입니다. 표의 Property는 읽기 쉽게 첫 글자를 대문자로 적었고, **코드에서는 첫 글자가 소문자**입니다 (`IsError` → `isError`). 화면에 보이는 속성뿐 아니라 **동작용(`on…`)·개발용 prop도 적습니다.** 비고에 피그마 이름을 함께 적었습니다.
113
+
114
+ | Property | Type | Values | 비고 |
115
+ | --- | --- | --- | --- |
116
+ | Checked | Boolean | True / False | 피그마 `Checked` |
117
+ | Disabled | Boolean | True / False | 피그마 `Disabled` |
118
+ | IsError | Boolean | True / False | 피그마 `Is Error` · 피그마에는 선택되지 않은 Error만 있음 (Z-1) |
119
+ | Value | String | | 이 Radio가 나타내는 값 · 개발용 |
120
+ | Name | String | | 한 묶음을 묶는 이름. 같은 묶음은 같은 `name` · 개발용 |
121
+ | OnChange | Function | | 선택이 바뀔 때 호출 · 동작용, 시각 변화 없음 |
122
+ | Id | String | | Label과 연결할 때 사용 (`<label htmlFor>`) · 개발용 |
123
+ | ClassName | String | | 개발용 스타일 지정 |
124
+ | State | Variant | Enabled / Hovered | 피그마에만 존재. Hovered는 마우스 hover로 자동 처리 |
125
+
126
+ > 이 외에도 일반 `<input type="radio">`의 속성(`required`, `aria-*` 등)을 그대로 받습니다.
127
+ >
128
+ > ```tsx
129
+ > <Radio id="pay-card" name="pay" value="card"
130
+ > checked={pay === 'card'} onChange={e => setPay(e.target.value)} />
131
+ > <label htmlFor="pay-card">카드 결제</label>
132
+ > ```
133
+
134
+ ## Z. 미결 (구현하지 말 것)
135
+
136
+ > 아래는 **결정되지 않은 제안**입니다. 구현 기준은 위 A~C입니다. 결정되면 본문으로 옮기고 여기서 지웁니다.
137
+
138
+ 1. **선택됨 + Error 상태 누락**: 코드는 선택된 채로 Error일 때 테두리와 점이 모두 `w-red-500`입니다. 피그마에는 선택되지 않은 Error만 있습니다 → 피그마에 추가할지, 선택된 항목은 Error로 표시하지 않을지 결정
139
+ 2. **키보드 포커스 상태**: 코드는 Tab으로 포커스되면 테두리가 `primary-500`(Hover와 같음)으로 바뀝니다. 피그마 `State`에는 Focused가 없습니다 → 피그마에 추가할지 검토
140
+ 3. **선택 점 이름**: 피그마 Anatomy는 선택 점을 `System Icons (14)`로 부르지만, 코드는 아이콘이 아니라 8×8 원을 직접 그립니다. 생김새는 같아서 이름만 맞출지 검토
@@ -0,0 +1,134 @@
1
+ ---
2
+ id: INPUT-25
3
+ component: RadioCard
4
+ version: 0.0.1
5
+ status: draft
6
+ ---
7
+
8
+ # 25. RadioCard
9
+
10
+ **개정 이력**
11
+
12
+ - v0.0.1 (2026.10.02): 초안 작성
13
+
14
+ ## A. Anatomy
15
+
16
+ RadioCard는 **Container** 안에 **Radio**, **Product Icon**, **Title**, **Supporting Text**가 놓인 카드형 Radio입니다. 기본형(세로)과 가로형(`isWide`, 피그마 Radio Wide Card) 두 가지 배치가 있습니다.
17
+
18
+ | 요소 | 필수 여부 | 설명 |
19
+ | --- | --- | --- |
20
+ | Container | 필수 | 모서리 12, 테두리 1px. **카드 전체가 클릭 영역** |
21
+ | Radio | 필수 | 18×18. 기본형은 카드 좌측 상단(17, 17)에 고정, 가로형은 맨 앞에 놓임 |
22
+ | Product Icon | 기본형 필수 / 가로형 선택 | 60×60 Product Icon. 선택되지 않으면 회색 아이콘으로 바뀜 |
23
+ | Title | 필수 | Body 16 Medium / `w-gray-900` |
24
+ | Supporting Text | 선택 | Body 14 Regular / `w-gray-600`. Title 아래 2px |
25
+
26
+ **배치별 크기**
27
+
28
+ | 배치 | 너비 | 여백 | 정렬 |
29
+ | --- | --- | --- | --- |
30
+ | 기본형 | 224 | 상하 24 · 좌우 16 | 아이콘 · 텍스트 가운데 정렬, 세로로 쌓임 |
31
+ | 가로형 (`isWide`) | 298, 최소 높이 94 | 상하 16 · 좌우 20 | Radio → 아이콘 → 텍스트 가로로, 텍스트 왼쪽 정렬 |
32
+
33
+ **상태별 표시**
34
+
35
+ | 상태 | 테두리 | 배경 | 아이콘 · 텍스트 |
36
+ | --- | --- | --- | --- |
37
+ | 기본 | `w-gray-200` | `w-white` | 회색 아이콘 |
38
+ | Hover · 키보드 포커스 | `primary-500` | `w-white` | 회색 아이콘 |
39
+ | 선택됨 | `primary-500` | `primary-10` | 컬러 아이콘 |
40
+ | Error | `w-red-500` | `w-white` (선택 시 `w-red-10`) | 회색 아이콘 |
41
+ | Disabled | `w-gray-200` | `w-gray-10` | 아이콘 투명도 30%, 텍스트 `w-gray-300` |
42
+ | Disabled + 선택됨 | `primary-100` | `primary-10` | 아이콘 투명도 30%, 텍스트 `w-gray-300` |
43
+
44
+ > 안의 Radio는 카드 상태를 그대로 따릅니다 (Radio 문서의 상태별 표시 참고).
45
+
46
+ ## B. Description
47
+
48
+ ### 1. 정의
49
+
50
+ 라디오와 함께 아이콘, 제목, 설명을 포함하여 사용자가 선택 항목을 명확하게 인식할 수 있도록 돕는 카드형 컴포넌트입니다. Radio와 같이 한 묶음에서 **하나만** 고릅니다.
51
+
52
+ ### 2. 사용 시점
53
+
54
+ - 선택지가 **적고(2~4개) 각각을 그림으로 구분**하면 이해가 빨라질 때 사용합니다. (프로젝트 분야, 결제 수단, 요금제)
55
+ - 선택이 화면의 **주요 결정**이라 강조가 필요할 때 사용합니다.
56
+ - 선택지가 많거나 텍스트만으로 충분하다면 **RadioListItem** · **RadioList**를 사용합니다.
57
+ - 여러 개를 골라야 한다면 **CheckboxCard**를 사용합니다.
58
+
59
+ **기본형과 가로형**
60
+
61
+ | 배치 | 언제 |
62
+ | --- | --- |
63
+ | **기본형** | 데스크톱처럼 넓은 화면에서 카드를 가로로 나란히 둘 때. 아이콘이 가장 눈에 띄는 배치입니다. |
64
+ | **가로형** (`isWide`) | 반응형·모바일처럼 공간이 좁거나, 설명이 길어 한 줄로 읽혀야 할 때. 카드를 세로로 쌓기 좋습니다. 아이콘을 빼도 됩니다. |
65
+
66
+ ### 3. 키워드
67
+
68
+ RadioCard, 라디오 카드, 카드 선택, Radio Wide Card, 가로형 카드, 단일 선택
69
+
70
+ ### 4. 터치 영역
71
+
72
+ **카드 전체**가 눌리는 영역입니다. Radio 원만이 아니라 아이콘·텍스트·여백 어디를 눌러도 선택됩니다. 따로 연결할 필요는 없습니다.
73
+
74
+ ### 5. 가이드라인 (Do / Don't)
75
+
76
+ **넓은 화면에서 기본형**
77
+
78
+ - Do: 기본형은 데스크톱 등 넓은 화면에서 씁니다.
79
+ - Don't: 반응형 화면에서 기본형을 그대로 쓰지 않습니다. 공간 효율이 떨어지니 **가로형**(`isWide`)으로 바꿉니다.
80
+
81
+ **카드 사이 간격 16px 이상**
82
+
83
+ - Do: 카드를 나란히 둘 때 사이 간격을 **최소 16px** 둡니다. 붙어 있으면 옆 카드를 잘못 누르기 쉽습니다.
84
+
85
+ **아이콘은 내용에 맞게**
86
+
87
+ - Do: 선택지의 내용을 바로 떠올리게 하는 Product Icon을 고릅니다. 카드마다 다른 아이콘을 씁니다.
88
+ - Don't: 모든 카드에 같은 아이콘을 넣지 않습니다. 아이콘이 구분에 도움이 안 된다면 가로형에서 아이콘을 뺍니다.
89
+
90
+ **텍스트는 짧게**
91
+
92
+ - Do: Title은 한두 단어, Supporting Text는 한 줄로 씁니다. 설명이 길면 가로형을 씁니다.
93
+
94
+ **그 밖에**
95
+
96
+ - 가능하면 기본값 하나를 선택해 둡니다. 한 번 고르면 빈 상태로 되돌릴 수 없습니다. (Radio와 같음)
97
+ - 한 묶음 안에서 기본형과 가로형을 섞지 않습니다.
98
+ - 오류 사유는 카드 묶음 아래 Supporting Text로 함께 알립니다. 테두리 색만으로 알리지 않습니다.
99
+
100
+ ## C. Properties
101
+
102
+ 스토리북(코드) 이름 기준입니다. 표의 Property는 읽기 쉽게 첫 글자를 대문자로 적었고, **코드에서는 첫 글자가 소문자**입니다 (`IsWide` → `isWide`). 화면에 보이는 속성뿐 아니라 **동작용(`on…`)·개발용 prop도 적습니다.** 비고에 피그마 이름을 함께 적었습니다.
103
+
104
+ | Property | Type | Values | 비고 |
105
+ | --- | --- | --- | --- |
106
+ | Title | String | | **필수.** 피그마 `Title` |
107
+ | Description | String | | 피그마 `Supporting Text`(Boolean) → 코드는 문구를 넣으면 표시 · 이름 다름 |
108
+ | IconName | Instance | Product Icon 이름 (`receipt`, `credit`, `design` …) | 기본형 **필수**, 가로형 선택 · 피그마 `Product Icons (60)` |
109
+ | IsWide | Boolean | True / False | 기본값 False. True면 가로형 · 피그마는 **별도 컴포넌트(Radio Wide Card)** (Z-1) |
110
+ | Checked | Boolean | True / False | 피그마 `Checked` |
111
+ | Disabled | Boolean | True / False | 피그마 `Disabled` · 피그마 `State`에도 Disabled가 있어 중복 (Z-2) |
112
+ | IsError | Boolean | True / False | 피그마 `Is Error` · 피그마에는 선택되지 않은 Error만 있음 (Z-3) |
113
+ | Name | String | | 한 묶음을 묶는 이름. 같은 묶음은 같은 `name` · 개발용 |
114
+ | Value | String | | 이 카드가 나타내는 값 · 개발용 |
115
+ | OnChange | Function | | 선택이 바뀔 때 호출 · 동작용 |
116
+ | ClassName | String | | 개발용 스타일 지정 (Container에 적용) |
117
+ | TestId | String | | 테스트용 ID · 개발용 |
118
+ | State | Variant | Enabled / Hovered / Disabled | 피그마에만 존재. Hovered는 마우스 hover로 자동 처리 |
119
+
120
+ > ```tsx
121
+ > <RadioCard name="field" value="dev" iconName="design"
122
+ > title="개발" description="웹·앱 개발"
123
+ > checked={field === 'dev'} onChange={() => setField('dev')} />
124
+ > ```
125
+
126
+ ## Z. 미결 (구현하지 말 것)
127
+
128
+ > 아래는 **결정되지 않은 제안**입니다. 구현 기준은 위 A~C입니다. 결정되면 본문으로 옮기고 여기서 지웁니다.
129
+
130
+ 1. **Radio Wide Card 이름 매핑**: 피그마는 가로형을 **별도 컴포넌트(Radio Wide Card)**로, 코드는 **RadioCard의 `isWide`**로 다룹니다 → 피그마도 하나로 합칠지, 따로 두고 `mapping.md`에 매핑만 적을지 결정
131
+ 2. **Disabled 중복**: 피그마는 `Disabled`(Boolean)와 `State = Disabled`가 둘 다 있습니다. 코드는 `disabled` 하나입니다 → 피그마 `State`에서 Disabled를 뺄지 검토 (Checkbox와 같은 문제)
132
+ 3. **선택됨 + Error 상태 누락**: 코드는 선택된 채로 Error일 때 테두리 `w-red-500`, 배경 `w-red-10`입니다. 피그마에는 없습니다 → Radio와 함께 결정
133
+ 4. **키보드 포커스 상태**: 코드는 Tab으로 포커스되면 테두리가 `primary-500`(Hover와 같음)입니다. 피그마에는 Focused가 없습니다 → Radio와 함께 검토
134
+ 5. **스토리북 예시 간격**: 피그마 가이드는 카드 사이 **최소 16px**인데, 스토리북 예시(RadioGroup · WideRadioGroup)는 **12px**로 붙어 있습니다 → 예시 수정 요청 (컴포넌트 자체는 간격을 정하지 않음)
@@ -0,0 +1,150 @@
1
+ ---
2
+ id: INPUT-26
3
+ component: RadioList
4
+ version: 0.0.2
5
+ status: draft
6
+ ---
7
+
8
+ # 26. RadioList
9
+
10
+ **개정 이력**
11
+
12
+ - v0.0.1 (2026.10.02): 초안 작성
13
+ - v0.0.2 (2026.10.16): `data` 항목에서 `errorMessage` 제외(타입에 없음, Z-6), RadioListItem `RadioClassName` 추가 (#1299 리뷰 반영)
14
+
15
+ ## A. Anatomy
16
+
17
+ RadioList는 **항목(RadioListItem)**을 세로로 쌓은 묶음입니다. 항목 하나는 **Radio**, **Title**, **Error Text**, **Supporting Text**로 구성됩니다.
18
+
19
+ > 피그마의 **Radio List**는 항목 **하나**를 그린 컴포넌트로, 코드의 **RadioListItem**에 해당합니다. 코드의 **RadioList**는 그 항목을 여러 개 쌓은 묶음입니다. (Z-1)
20
+
21
+ **항목(RadioListItem) 구성**
22
+
23
+ | 요소 | 필수 여부 | 설명 |
24
+ | --- | --- | --- |
25
+ | Radio | 필수 | 18×18. Title 첫 줄과 높이를 맞추려고 위로 4px 띄움 |
26
+ | Title | 필수 | Body 16 Regular / `w-gray-900`. Radio 오른쪽 12px. 길면 줄바꿈 |
27
+ | Error Text | 조건부 | Body 14 / `w-red-500`. `isError`이고 문구가 있을 때만. Title 아래, **Supporting Text 위** |
28
+ | Supporting Text | 선택 | Body 14 / `w-gray-600`. Title 아래 2px, Title과 왼쪽을 맞춤(들여쓰기 30px) |
29
+
30
+ **묶음(RadioList) 구성**
31
+
32
+ | 요소 | 설명 |
33
+ | --- | --- |
34
+ | Container | 항목을 세로로 쌓음. 항목 사이 **12px**, 너비 100% |
35
+
36
+ **상태별 표시**
37
+
38
+ | 상태 | Radio | Title | Supporting Text |
39
+ | --- | --- | --- | --- |
40
+ | 기본 · 선택됨 | Radio 문서와 같음 | `w-gray-900` | `w-gray-600` |
41
+ | Hover · 키보드 포커스 | 테두리 `primary-500` | `w-gray-900` | `w-gray-600` |
42
+ | Error | 테두리 `w-red-500` | `w-gray-900` | `w-gray-600` + 위에 Error Text |
43
+ | Disabled | Radio 문서와 같음 | `w-gray-300` | `w-gray-300` |
44
+
45
+ ## B. Description
46
+
47
+ ### 1. 정의
48
+
49
+ 사용자가 다중 항목 중 하나만 선택할 수 있도록 돕는 리스트 구조의 컴포넌트입니다. 항목 목록(`data`)을 넘기면 Radio + Title + Supporting Text로 세로로 그려 주고, 선택값 하나(`selectedValue`)로 묶음 전체를 제어합니다.
50
+
51
+ ### 2. 사용 시점
52
+
53
+ - 폼에서 **2~5개 선택지 중 하나**를 고르게 할 때 기본으로 사용합니다. (사업자 유형, 미팅 방식)
54
+ - 항목마다 **짧은 설명**이 필요하면 Supporting Text를 붙입니다.
55
+ - 항목을 하나씩 직접 배치하거나 Title을 꾸며야 한다면 **RadioListItem**을 직접 씁니다.
56
+ - 선택지를 그림으로 구분하면 좋다면 **RadioCard**를 사용합니다.
57
+ - 여러 개를 골라야 한다면 **CheckboxList**를, 선택지가 많다면 **TextFieldDropdown**을 사용합니다.
58
+
59
+ **RadioList와 RadioListItem**
60
+
61
+ | | RadioList | RadioListItem |
62
+ | --- | --- | --- |
63
+ | 무엇 | 항목 여러 개를 쌓은 묶음 | 항목 하나 |
64
+ | 내용 넣는 방법 | `data` 배열 (`label` · `value` · `description`) | prop 직접 + `children` |
65
+ | 선택 관리 | `selectedValue` 하나로 자동 | 항목마다 `checked` 직접 |
66
+ | 항목 간격 | 12px 고정 | 배치하는 쪽에서 정함 |
67
+ | Error Text | 넣을 수 없음 (Z-6) | `errorMessage` |
68
+ | 언제 | 대부분의 폼 | 항목 사이에 다른 내용이 끼거나, Title을 꾸미거나, 항목에 Error Text가 필요할 때 |
69
+
70
+ ### 3. 키워드
71
+
72
+ RadioList, RadioListItem, 라디오 리스트, 라디오 목록, Radio Group, 단일 선택
73
+
74
+ ### 4. 터치 영역
75
+
76
+ 항목의 **행 전체**(Radio · Title · Supporting Text)가 눌리는 영역입니다. 따로 연결할 필요는 없습니다. 항목 사이 12px 간격은 눌리지 않습니다.
77
+
78
+ ### 5. 가이드라인 (Do / Don't)
79
+
80
+ **기본값 제공하기**
81
+
82
+ - Do: `selectedValue`에 가장 많이 쓰거나 권장하는 항목을 넣어 둡니다. 한 번 고르면 빈 상태로 되돌릴 수 없습니다. (Radio와 같음)
83
+
84
+ **Title은 필요하면 꾸민다**
85
+
86
+ - Do: Title에 보조 문구나 색을 더해야 하면 RadioListItem의 `children`으로 넣습니다. (예: `상세한 문서가 있습니다.` 뒤에 회색 `(선택)`)
87
+
88
+ **오류는 문구와 함께**
89
+
90
+ - Do: 묶음 전체의 오류는 `isError`로 표시하고, 이유는 리스트 아래 한 곳에 문구로 씁니다.
91
+ - Do: 항목 하나에 Error Text를 붙여야 하면 RadioList 대신 **RadioListItem**을 직접 쓰고 `errorMessage`를 넣습니다. RadioList의 `data`에는 Error Text를 넣을 수 없습니다. (Z-6) Error Text는 Supporting Text 위에 오고, Supporting Text는 그대로 남습니다.
92
+ - Don't: Error Text를 모든 항목에 똑같이 달지 않습니다. 묶음 전체의 오류라면 리스트 아래 한 곳에만 씁니다.
93
+
94
+ **그 밖에**
95
+
96
+ - Title은 한 줄 안쪽으로 짧게 씁니다. 길면 줄바꿈되지만, 설명은 Supporting Text로 나눕니다.
97
+ - 선택 불가한 항목은 숨기지 말고 Disabled로 남깁니다.
98
+
99
+ ## C. Properties
100
+
101
+ 스토리북(코드) 이름 기준입니다. 표의 Property는 읽기 쉽게 첫 글자를 대문자로 적었고, **코드에서는 첫 글자가 소문자**입니다 (`SelectedValue` → `selectedValue`). 화면에 보이는 속성뿐 아니라 **동작용(`on…`)·개발용 prop도 적습니다.** 비고에 피그마 이름을 함께 적었습니다.
102
+
103
+ **RadioList**
104
+
105
+ | Property | Type | Values | 비고 |
106
+ | --- | --- | --- | --- |
107
+ | Data | Array | `{ label, value?, description? }` 목록 | **필수.** 항목 하나 = 피그마 Radio List 하나. `label` = 피그마 `Title`, `description` = 피그마 `Supporting Text` · `errorMessage`는 넣을 수 없음 (Z-6) |
108
+ | SelectedValue | String | | 선택된 항목의 `value` · 피그마 `Checked` |
109
+ | Name | String | | **필수.** 묶음 이름 · 개발용 (Z-2) |
110
+ | Disabled | Boolean | True / False | **묶음 전체**에 적용 · 피그마 `Disabled` (Z-3) |
111
+ | IsError | Boolean | True / False | **묶음 전체**에 적용 · 피그마 `Is Error` |
112
+ | OnChange | Function | | 선택이 바뀔 때 호출 · 동작용 |
113
+ | ClassName | String | | 개발용 스타일 지정 (묶음 Container에 적용) |
114
+ | TestId | String | | 테스트용 ID · 개발용 |
115
+
116
+ **RadioListItem** (항목을 직접 쓸 때)
117
+
118
+ | Property | Type | Values | 비고 |
119
+ | --- | --- | --- | --- |
120
+ | Label | String | | 피그마 `Title` |
121
+ | Description | String | | 피그마 `Supporting Text`(Boolean) → 코드는 문구를 넣으면 표시 |
122
+ | ErrorMessage | String | | `isError`일 때만 표시 · 피그마 `Error Text`(Boolean) |
123
+ | Checked | Boolean | True / False | 피그마 `Checked` |
124
+ | Disabled | Boolean | True / False | 피그마 `Disabled` · 피그마 `State`에도 Disabled가 있어 중복 |
125
+ | IsError | Boolean | True / False | 피그마 `Is Error` |
126
+ | Name · Value · OnChange | — | | Radio와 같음 · 개발용 |
127
+ | Children | Node | | Title 뒤에 붙는 내용. Title을 꾸밈 때 (피그마 Policy) |
128
+ | ClassName | String | | 개발용 스타일 지정 (항목 행에 적용) |
129
+ | RadioClassName | String | | 개발용. **안쪽 Radio**에 스타일을 주는 유일한 통로 · 코드 이름도 **대문자 `R`로 시작**(`RadioClassName`) |
130
+ | State | Variant | Enabled / Hovered / Disabled | 피그마에만 존재. Hovered는 마우스 hover로 자동 처리 |
131
+
132
+ > ```tsx
133
+ > <RadioList name="meeting" selectedValue={type}
134
+ > onChange={e => setType(e.target.value)}
135
+ > data={[
136
+ > { label: '방문 미팅', value: 'visit', description: '서울 · 경기 지역' },
137
+ > { label: '화상 미팅', value: 'online' },
138
+ > ]} />
139
+ > ```
140
+
141
+ ## Z. 미결 (구현하지 말 것)
142
+
143
+ > 아래는 **결정되지 않은 제안**입니다. 구현 기준은 위 A~C입니다. 결정되면 본문으로 옮기고 여기서 지웁니다.
144
+
145
+ 1. **이름 어긋남 (Radio List ↔ RadioListItem)**: 피그마 `Radio List`는 항목 하나이고, 코드에서는 `RadioListItem`입니다. 코드 `RadioList`(묶음)에 해당하는 피그마 컴포넌트는 없습니다 → 피그마 이름을 `Radio List Item`으로 바꿀지 결정 (`mapping.md`에 기록됨)
146
+ 2. **`name`이 항목까지 전달되지 않음 (코드 확인 필요)**: RadioList에 `name`을 넣어도 안의 Radio에는 붙지 않습니다. 선택은 `selectedValue`로 동작하지만, 방향키로 항목 사이를 이동하거나 폼으로 값을 보내는 것이 안 됩니다 → 개발팀 확인 후 이슈로 요청
147
+ 3. **항목 하나만 Disabled 불가 (코드 확인 필요)**: `data`의 항목에 `disabled`를 넣어도 묶음의 `disabled` 값으로 덮어씁니다. "일부 항목만 선택 불가"를 만들 수 없습니다. `isError`도 같습니다 → 항목별 값을 남길지 결정, 지금은 RadioListItem을 직접 써야 함
148
+ 4. **스토리북 Disabled 예시**: 예시가 `isDisabled`를 넘기는데 실제 prop은 `disabled`라, 예시가 비활성으로 보이지 않을 수 있습니다. 코드 주석도 `isDisabled`로 적혀 있음 → 예시·주석 수정 요청
149
+ 5. **선택됨 + Error, 키보드 포커스 상태**: Radio와 같은 문제입니다. 피그마에 없음 → Radio와 함께 결정
150
+ 6. **`data` 항목의 Error Text (코드 확인 필요)**: 화면에는 그려지지만(항목을 그대로 넘김) `RadioListData` 타입에 `errorMessage`가 없어 넣으면 **빌드가 깨집니다**(TS2353). 지금은 RadioListItem을 직접 써야 합니다 → 타입에 `errorMessage?: string`을 추가하도록 개발팀에 요청
@@ -0,0 +1,139 @@
1
+ ---
2
+ id: INPUT-27
3
+ component: RangeSlider
4
+ version: 0.0.1
5
+ status: draft
6
+ ---
7
+
8
+ # 27. RangeSlider
9
+
10
+ **개정 이력**
11
+
12
+ - v0.0.1 (2026.10.02): 초안 작성
13
+
14
+ ## A. Anatomy
15
+
16
+ RangeSlider는 가로 **Inactive Bar**(전체 범위) 위에 **Active Bar**(고른 범위)가 칠해지고, **Handle**을 끌어 값을 정합니다. Medium에는 단계마다 **Marks**(눈금)가 찍힙니다.
17
+
18
+ | 요소 | 필수 여부 | 설명 |
19
+ | --- | --- | --- |
20
+ | Inactive Bar | 필수 | 전체 범위(`min`~`max`). `w-gray-50` |
21
+ | Active Bar | 필수 | 고른 범위. `primary-500`. Single은 왼쪽 끝에서 Handle까지, Dual은 두 Handle 사이 |
22
+ | Handle | 필수 | 끌어서 값을 바꾸는 원. 흰 배경 + 테두리 `w-gray-200` + 그림자. Single 1개, Dual 2개 |
23
+ | Marks | 조건부 | Medium일 때만. Bar 안의 흰 점(4×4), `step`마다 하나 |
24
+
25
+ **크기별**
26
+
27
+ | Size | Bar 높이 | Bar 모서리 | Handle | Marks |
28
+ | --- | --- | --- | --- | --- |
29
+ | Small (`sm`, 기본값) | 4 | 2 | 16×16 | 없음 |
30
+ | Medium (`md`) | 8 | 4 | 20×20 | 있음 |
31
+
32
+ **상태별 표시**
33
+
34
+ | 상태 | Active Bar | Handle |
35
+ | --- | --- | --- |
36
+ | 기본 | `primary-500` | 끌 수 있음 (커서: 잡기) |
37
+ | Disabled | `w-gray-300` | 끌 수 없음 |
38
+
39
+ > 피그마에는 Disabled 상태가 없고, 대신 Dual이 전체를 덮을 때 **연한 파랑(`primary-100`) Full Active Bar**가 있습니다. 코드에는 없습니다. (Z-1)
40
+
41
+ ## B. Description
42
+
43
+ ### 1. 정의
44
+
45
+ 사용자가 최소~최대값 사이에서 단일 값 또는 구간을 드래그 방식으로 조정할 수 있는 컴포넌트입니다. 값은 `step` 단위로만 움직입니다.
46
+
47
+ ### 2. 사용 시점
48
+
49
+ - 정확한 숫자보다 **대략적인 정도·범위**를 빠르게 고를 때 사용합니다. (예산 범위, 기간, 경력 연차) 값이 `step` 단위로만 움직이므로, 정해진 단계로 나뉘는 값에 맞습니다. (예산 1,000만 원 단위, 경력 1년 단위, 할인율 5% 단위)
50
+ - 값 하나를 고르면 **Single**, 최소와 최대를 함께 고르면 **Dual**을 씁니다.
51
+ - 정확한 값을 입력해야 한다면 **TextField**를 함께 두거나 TextField만 씁니다.
52
+ - 고를 값이 몇 개 안 되고 단계가 값이 아니라 이름이라면(`초급` / `중급` / `고급`) **SegmentedControl**이나 **Radio**를 사용합니다.
53
+
54
+ **유형**
55
+
56
+ | 유형 | 설명 |
57
+ | --- | --- |
58
+ | **Single** (`variant = single`, 기본값) | Handle 1개. 왼쪽 끝(`min`)부터 Handle까지가 Active Bar입니다. 값은 `value.max` 하나만 씁니다. |
59
+ | **Dual** (`variant = dual`) | Handle 2개. 두 Handle 사이가 Active Bar입니다. 두 Handle은 서로를 넘어가지 못하고, 같은 위치에 겹칠 수는 있습니다. |
60
+
61
+ ### 3. 키워드
62
+
63
+ RangeSlider, 슬라이더, Slider, 범위 선택, 구간, 예산 범위, Dual Range, Single Point
64
+
65
+ ### 4. 터치 영역
66
+
67
+ | 유형 | 눌리는 영역 |
68
+ | --- | --- |
69
+ | Single | Handle을 끌거나, **Bar 아무 곳이나 눌러도** Handle이 그 위치로 이동 |
70
+ | Dual | Handle을 끌거나, **Bar를 누르면 가까운 Handle이** 그 위치로 이동 · **현재 코드는 Handle만 끌 수 있음 → 수정 요청 필요** |
71
+
72
+ > 키보드로는 Tab으로 Handle에 포커스한 뒤 방향키로 `step`만큼 움직입니다. Home · End로 양 끝(최소 · 최대)으로 바로 이동합니다.
73
+
74
+ ### 5. 가이드라인 (Do / Don't)
75
+
76
+ **기본값 제공하기**
77
+
78
+ - Do: 처음부터 가장 흔하거나 권장하는 값에 Handle을 두어 사용자가 조금만 조정하면 되게 합니다. (예: 예산 300만~500만 원 위치에서 시작)
79
+ - Don't: 최소값과 최대값을 양 끝에 그대로 두지 않습니다. "아무것도 안 고른 상태"와 "전체를 고른 상태"가 구분되지 않습니다.
80
+
81
+ **값을 숫자로도 보여주기**
82
+
83
+ - Do: 슬라이더 옆이나 아래에 현재 값을 텍스트로 표시합니다. 컴포넌트는 값을 글자로 보여주지 않습니다. (예: `300만 원 ~ 500만 원`) 범위가 눈에 분명하면(예: 0~100% 중 절반) 생략해도 됩니다.
84
+ - Do: 정확한 값이 중요하면 TextField를 함께 두고 둘을 연동합니다. (위시켓 예산 입력)
85
+ - Don't: 값을 Handle과 동떨어진 곳에 두지 않습니다. 어느 Handle의 값인지 유추할 수 없습니다.
86
+
87
+ **step은 사용자가 구분할 수 있게**
88
+
89
+ - Do: 사용자가 의미 있게 구분하는 단위로 `step`을 정합니다. (예산 1,000만 원 단위) 범위(`min`~`max`)가 너무 넓으면 한 칸이 작아져 원하는 값에 맞추기 어렵습니다. 범위와 `step`을 함께 정합니다.
90
+ - Don't: Medium에서 단계를 너무 잘게 나누지 않습니다. 단계마다 Marks가 찍혀 점이 빽빽해집니다. 단계가 많으면 Small을 씁니다.
91
+
92
+ **범위 양 끝을 알려주기**
93
+
94
+ - Do: Bar 양 끝에 `min` · `max` 값을 적어 어디부터 어디까지인지 보여줍니다.
95
+
96
+ **그 밖에**
97
+
98
+ - 입력을 막을 때는 숨기지 말고 Disabled로 둡니다. (예: `아직 정해지지 않았습니다` 체크 시)
99
+ - 한 화면에서 Small과 Medium을 섞지 않습니다.
100
+
101
+ ## C. Properties
102
+
103
+ 스토리북(코드) 이름 기준입니다. 표의 Property는 읽기 쉽게 첫 글자를 대문자로 적었고, **코드에서는 첫 글자가 소문자**입니다 (`OnChange` → `onChange`). 화면에 보이는 속성뿐 아니라 **동작용(`on…`)·개발용 prop도 적습니다.** 비고에 피그마 이름을 함께 적었습니다.
104
+
105
+ | Property | Type | Values | 비고 |
106
+ | --- | --- | --- | --- |
107
+ | Variant | Variant | `single` / `dual` | 기본값 `single`. 피그마 `Variant` (Single Point / Dual Range) → 값 이름 다름 |
108
+ | Size | Variant | `sm` / `md` | 기본값 `sm`. 피그마 `Size` (Small / Medium) |
109
+ | Value | Object | `{ min, max }` | 현재 값. Single은 `max`만 씁니다 · 피그마 `Percentage`(0% / 50% / 100%)는 미리보기용 |
110
+ | Min | Number | | 기본값 `0`. 범위의 왼쪽 끝 |
111
+ | Max | Number | | 기본값 `100`. 범위의 오른쪽 끝 |
112
+ | Step | Number | | 기본값 `10`. 한 번에 움직이는 단위. Medium에서는 Marks 개수도 정함 (Z-2) |
113
+ | Disabled | Boolean | True / False | Active Bar `w-gray-300`, 끌 수 없음 · 피그마에 없음 (Z-1) |
114
+ | OnChange | Function | | 값이 바뀔 때 `{ min, max }`를 넘김 · 동작용 |
115
+ | ClassName | String | | 개발용 스타일 지정 |
116
+ | Marks | Boolean | True / False | 피그마에만 존재. 코드는 `size = md`일 때 항상 표시, 끌 수 없음 |
117
+
118
+ > 이 외에도 일반 `<input type="range">`의 속성(`name`, `aria-*` 등)을 받습니다. Dual에서는 두 Handle에 똑같이 들어갑니다.
119
+ >
120
+ > ```tsx
121
+ > <RangeSlider variant="dual" size="md" min={0} max={20000} step={1000}
122
+ > value={budget} onChange={setBudget} />
123
+ > ```
124
+
125
+ ## Z. 미결 (구현하지 말 것)
126
+
127
+ > 아래는 **결정되지 않은 제안**입니다. 구현 기준은 위 A~C입니다. 결정되면 본문으로 옮기고 여기서 지웁니다.
128
+
129
+ 1. **Full Active Bar와 Disabled**: 피그마는 Dual이 전체 범위를 덮을 때 Active Bar를 연한 파랑(`primary-100`)으로 그렸고, Disabled 상태는 없습니다. 코드는 전체를 덮어도 `primary-500` 그대로이고, Disabled일 때 `w-gray-300`입니다 → Full Active Bar가 무슨 뜻인지("범위 미지정"? Disabled?) 확인하고, 피그마에 Disabled를 추가할지 결정
130
+ 2. **Marks 개수 계산 (코드 확인 필요)**: 코드는 Marks 개수를 `max ÷ step + 1`로 구해서 `min`을 무시합니다. `min`이 0이 아니면 눈금과 실제 단계가 어긋납니다 (예: 1,000~20,000 / 1,000 단위 → 단계 20개인데 눈금 21개) → 개발팀 확인 후 이슈로 요청
131
+ 3. **Handle 그림자 토큰**: 피그마는 `Shadow/Gray Small`, 코드는 `shadow-graymedium`입니다 → 어느 쪽에 맞출지 결정
132
+ 4. **Small의 Marks**: 피그마 Bar(Item) 컴포넌트에는 Small용 Marks(2×2) 옵션이 있지만, 코드는 Small에 Marks가 없습니다 → 피그마 옵션을 뺄지, 코드에 넣을지 결정
133
+ 5. **값 표시 방식**: 컴포넌트가 현재 값·양 끝 값을 글자로 보여주지 않아 화면마다 따로 그립니다. 다른 디자인 시스템은 아래 방식을 컴포넌트에 넣습니다 → 어느 방식을 추가할지, 아니면 화면 패턴으로만 정해 둘지 결정
134
+ - **Heading** (Montage): 슬라이더 위에 제목과 선택한 값 요약 (예: `경력 3년~7년`)
135
+ - **Value Indicator** (SEED) / **Label** (Montage): Handle 위·옆에 현재 값. SEED는 끄는 동안만 말풍선으로 띄우고, Bar 끝에서는 안쪽으로 밀어 잘리지 않게 함
136
+ - **Marker** (SEED): Bar 아래에 최소·최대 등 기준값 라벨
137
+ 6. **눌림(Active) 상태**: 코드·피그마 모두 Handle을 누르고 있을 때의 변화가 없습니다(커서만 바뀜).
138
+ 7. **Marks를 보여줄 단계 수 기준**: 코드는 Medium이면 단계 수와 상관없이 항상 Marks를 찍습니다. 다른 단계가 적을 때(2~5개)만 눈금을 보여줄지 결정. 피그마 예시는 11개(0~100, 10 단위) → "단계 N개 이하일 때만 Medium(Marks)" 기준 숫자를 정할지 결정
139
+ 8. **Dual Handle 사이 최소 간격**: 코드는 두 Handle이 같은 값에 겹칠 수 있습니다(min = max). Montage는 두 Handle 사이 최소 몇 단계를 띄울지 정하는 옵션(`minStepBetweenThumbs`)이 있습니다 → 예산처럼 "300만~300만 원"이 의미 없는 경우 막을지 결정 (코드 변경 필요)