fix: 전화번호는 숫자만 받는다
칸에 들어오는 값에서 숫자가 아닌 글자를 걸러낸 뒤 자릿수를 자른다. 붙여넣기로 하이픈·공백이 섞여 와도 걸리고, 한 칸에 `010-1234`를 붙여도 넘치지 않는다. 밖에서 받은 value도 같은 방식으로 읽는다 — `010-1234-5678`처럼 꾸며진 값을 넣어도 칸이 맞게 갈리고, 내보낼 때는 숫자만 남는다. Co-Authored-By: Claude Opus 5
@90169d163db93fe99b57466ee86a26ab34d42ffe
--- @fox/core/components/fox-phone-number/fox-phone-number.tsx
+++ @fox/core/components/fox-phone-number/fox-phone-number.tsx
... | ... | @@ -24,7 +24,7 @@ |
| 24 | 24 |
type?: FoxPhoneNumberType; |
| 25 | 25 |
/** |
| 26 | 26 |
* 숫자만 담긴 값. 하이픈은 화면에만 있고 값에는 들어가지 않는다 — `"01012345678"`. |
| 27 |
- * 주면 제어 컴포넌트가 된다. |
|
| 27 |
+ * 꾸며진 값을 넣어도 숫자만 남겨 읽는다. 주면 제어 컴포넌트가 된다. |
|
| 28 | 28 |
*/ |
| 29 | 29 |
value?: string; |
| 30 | 30 |
defaultValue?: string; |
... | ... | @@ -63,6 +63,11 @@ |
| 63 | 63 |
const DEFAULT_MAX_LENGTHS: Lengths = [3, 4, 4]; |
| 64 | 64 |
const SEGMENT_LABELS: Parts = ["전화번호 앞자리", "전화번호 가운데자리", "전화번호 뒷자리"]; |
| 65 | 65 |
|
| 66 |
+/** 숫자가 아닌 글자는 버린다 — 붙여넣기로 들어온 하이픈·공백도 여기서 걸린다. */ |
|
| 67 |
+function onlyDigits(text: string): string {
|
|
| 68 |
+ return text.replace(/\D/g, ""); |
|
| 69 |
+} |
|
| 70 |
+ |
|
| 66 | 71 |
/** |
| 67 | 72 |
* 숫자만 담긴 값을 화면의 세 칸으로 나눈다. |
| 68 | 73 |
* |
... | ... | @@ -71,7 +76,8 @@ |
| 71 | 76 |
* 둘 다 맞게 갈린다. 남은 글자가 그보다 짧으면 아직 입력 중이라 보고 가운데에 둔다. |
| 72 | 77 |
*/ |
| 73 | 78 |
function splitValue(value: string, prefixOptions: string[], maxLengths: Lengths): Parts {
|
| 74 |
- const digits = value ?? ""; |
|
| 79 |
+ // 밖에서 `010-1234-5678`처럼 꾸며진 값이 와도 받아 준다 — 내보낼 때는 숫자만 남는다. |
|
| 80 |
+ const digits = onlyDigits(value ?? ""); |
|
| 75 | 81 |
const matched = prefixOptions |
| 76 | 82 |
.filter((option) => option && digits.startsWith(option)) |
| 77 | 83 |
.sort((a, b) => b.length - a.length)[0]; |
... | ... | @@ -151,9 +157,12 @@ |
| 151 | 157 |
tailRefs.current[index]?.focus(); |
| 152 | 158 |
}; |
| 153 | 159 |
|
| 160 |
+ // 숫자가 아닌 입력은 아예 들어오지 못한다. 붙여넣기로 하이픈이 섞여 와도 여기서 걸리고, |
|
| 161 |
+ // 그 뒤에 자릿수를 자르므로 `010-1234`를 한 칸에 붙여도 넘치지 않는다. |
|
| 154 | 162 |
const handleSegmentChange = (index: number) => (next: string) => {
|
| 155 |
- commit(index, next); |
|
| 156 |
- if (autoAdvance && index < 2 && next.length >= maxLengths[index]) {
|
|
| 163 |
+ const digits = onlyDigits(next).slice(0, maxLengths[index]); |
|
| 164 |
+ commit(index, digits); |
|
| 165 |
+ if (autoAdvance && index < 2 && digits.length >= maxLengths[index]) {
|
|
| 157 | 166 |
focusSegment(index + 1); |
| 158 | 167 |
} |
| 159 | 168 |
}; |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?