**FoxPhoneNumber** — `unit` 모드에서 `prefixOptions`가 비면 앞자리를 셀렉트가 아니라 입력 칸으로
그린다. 항목 없는 셀렉트는 placeholder "010"이 이미 고른 값처럼 보이는데 실제 값은 비어 있어,
뒷자리만 채운 번호가 조용히 만들어졌다(관리자 등록이 막힌 원인). 세 칸을 한 map으로 돌게
정리하면서 combine 분기와 모양을 맞췄다.
**FoxEmail** — 시안(form-email 5543:9940)은 줄이 나뉜다: [아이디] @ [도메인] 한 줄, 그 아래
도메인 드롭다운, 그 아래 확인 버튼. 종전에는 넷을 한 줄에 두고 넘치면 접히게 했는데, 좁은 곳에서
드롭다운이 도메인 칸보다 먼저 접혀 순서가 어긋났다(320px 팝업에서 세 줄로 흩어졌다).
`__body`(4px 간격) 안에 form-group·select·btn을 쌓고, 칸의 `min-inline-size: 24rem`을 0으로 바꿔
좁은 폭에서도 두 칸이 나눠 갖게 했다. 라벨의 필수 표시(`requirement`)도 다른 폼 컴포넌트와 같은
규약으로 추가했다.
**관리자 등록 팝업** — 손으로 짜 두었던 이메일 칸(아이디·도메인·직접입력 상태 세 개)을 `FoxEmail`
하나로 바꿨다. 시안 5227:2036 그대로이고, 아이디 placeholder는 "ID"(종전 "1234-5678"은 전화번호
칸에서 복사된 값이었다), 도메인은 첫 항목이 골라진 채로 시작한다.
검증 — 시안 대조 실측: 아이디 149×40 · 도메인 149×40(readOnly, "naver.com") · 셀렉트 320×40 ·
그룹↔셀렉트 간격 4 · 라벨 "이메일*"(시안 149/149/320/4와 일치).
동작: 직접입력 고르면 도메인 칸의 readOnly가 풀린다. prefixOptions 없이 쓴 FoxPhoneNumber는
앞자리가 입력 칸이 되고 "02"를 적으면 값에 실린다(종전에는 아무리 눌러도 빈 값이었다).
Co-Authored-By: Claude Opus 5
develop에서 온 FoxFormLabel과 내가 두었던 form-field의 label 믹스인이 같은 일을
두 갈래로 하고 있었다. 라벨 모양을 아는 곳을 하나로 줄인다.
- FoxFormLabel에 `as` 프롭 추가 — 칸 하나를 가리킬 때는 label, 칸 여러 개를 묶은
필드에서는 span. 가리킬 대상이 하나가 아니라 htmlFor를 쓸 수 없고, 아무것도
가리키지 않는
Figma form-email(136:3092)과 form-address(5346:5823)를 옮긴다. 두 시안 모두
상자가 input·select 인스턴스이고 버튼도 btn 인스턴스라 FoxInput·FoxSelect·
FoxButton을 그대로 조합했다 — 두 SCSS는 배치와 `@` 구분자만 갖는다.
FoxEmail
값은 아이디@도메인이 합쳐진 문자열 하나다. 도메인을 목록에서 고르면 옆 칸이
그 값으로 덮이고 읽기 전용이 되며, "직접입력"을 고르면 잠금만 풀린다.
확인 버튼은 onVerify를 넘겼을 때만 렌더된다.
칸은 시안의 240px을 최소폭으로 두고 남는 폭을 나눠 갖는다 — 좁아지면 줄이
넘어간다(사용자 승인). 토큰 스케일에 240이 없어 이 한 줄만 리터럴이다.
FoxAddress
우편번호와 주소는 검색 결과로만 채워지는 읽기 전용이고 상세주소만 입력한다.
어떤 우편번호 서비스를 쓰는지 @fox는 모른다 — 호출부가 onSearch에서
FoxAddressSearchResult(zipCode·address·선택 detail)로 바꿔 돌려주고, 취소는
null이다. detail을 안 넘기면 사용자가 적어 둔 상세주소를 건드리지 않는다.
Co-Authored-By: Claude Opus 5