# Date Picker > 현재 접근성 보완(2026-10-10): 흰 Trigger의 빈 값 안내는 기존 `--hm-sem-fg-secondary`를 사용한다. 기본 Theme에서 #6e6759/흰색이며 공통 placeholder Token과 Disabled opacity는 보존한다. 아래 과거 검증의 #999 실측은 당시 기록이다. 현재 HM 구현의 기준 문서. 공통 원칙은 `docs/guidelines/프로젝트-지침.md`(§6, §7), Token 구조 원칙은 `테마-토큰-가이드.md`를 따른다. 이 문서는 Date Picker 고유의 API·Token·상태·결정만 기록한다. ## 1. 상태와 성격 | 항목 | 내용 | |---|---| | 성격 | **Reusable component, Popover + Calendar 조합** (새 날짜 engine 없음) | | 구현 상태 | 구현 완료 (single-date, 현재 HM 규격) | | 기준일 | 2026-10-02 | | 기반 | `Popover`(public API) + `Calendar`(public API) 조합. shadcn 공식 Date Picker는 예시 조합이다 | | 대표 Story | `Components/Search & Date/Date Picker` → `All` (이름 "Date Picker") | | 보류 | 아래 §11 | ## 2. 적용 근거 - **참고 근거**: 외부 ui_viz Reference (ZIP 미포함)의 기존 테스트 규격에는 Date Picker가 이름뿐이고 규격이 없다. 참고할 수치가 없었다. - **Component로 만든 이유**: 서비스의 모든 날짜 선택이 같은 trigger 텍스트 형식, 선택 후 닫힘, 값 처리, focus 복귀를 필요로 해 반복 사용이 확실하다고 판단했다. 값 처리(`value`/`defaultValue`/`onValueChange`)는 패키지가 소유한다. - **구현 방식**: Popover(Portal, collision, Escape, focus 복귀)와 Calendar(날짜 모델, 키보드)를 그대로 조합한다. Popover 내부 구현을 복제하지 않았다. - **Trigger**: Button이 아니라 Input/Select의 field language를 따르는 필드형 버튼이다. Button/Input/Select Token은 참조하지 않고 `--hm-date-picker-*`로 관리한다. - **보류**: §11. ## 3. 기본 규격 (현재 HM 규격) | 항목 | 값 | |---|---| | Size | `large`(기본, 안쪽 42px + 1px border = 44px, 16 / 24), `medium`(안쪽 32px = 34px, 14 / 20) — Select와 같은 두 크기 | | Trigger | 폭 100%(부모 폭), padding-x 12px, 1px `--hm-sem-stroke-input-default`, radius 4px, 흰 면, 오른쪽 달력 아이콘 18px `--hm-sem-fg-secondary` | | 값 / placeholder | 선택값은 `--hm-sem-fg-primary`, placeholder("날짜 선택")는 `--hm-sem-fg-secondary`, 길면 말줄임 | | 날짜 표시 | 로컬 `Date`의 연·월·일 → `YYYY.MM.DD` (예: `2026.01.09`, `2026.10.06`). `format` prop으로 교체 | | Popup | Popover 면(흰 면, 1px pale border, 4px radius, 그림자)에 Popover padding 0, 폭 `auto`로 Calendar에 맞춤 | ## 4. 상태 규격 | 상태 | 값 | |---|---| | Empty / Selected | `data-empty`가 있으면 placeholder 색 | | Focus / Open | 테두리 전체가 `--hm-sem-stroke-input-focus`(ring 없음, Input·Select와 같은 방식). 열림은 Radix `data-state="open"` | | Invalid (`aria-invalid="true"`) | Trigger border 1px `--hm-sem-action-destructive`. 새 `invalid` / `error` / `status` prop 없음 | | Invalid + Keyboard Focus (`:focus-visible`) | Destructive border 유지 + Focus Semantic 3px / 50% outer ring | | Invalid + Open | Trigger Error border 유지. Calendar Selected는 기존 Active, 날짜 Keyboard Focus는 기존 Focus Semantic 유지 | | Disabled | opacity 0.6(이 컴포넌트 값, 전역 Disabled 규칙으로 승격 안 함), cursor not-allowed, 열리지 않음 | | 선택 후 | 값 갱신, Popover 닫힘, focus가 trigger로 복귀 | ## 5. API export: `DatePicker`, type `DatePickerSize`. - `value`/`defaultValue`(Date), `onValueChange(date)`, `placeholder`, `size` `"medium" | "large"`(기본 `large`), `disabled`, `format(date) => string`, `calendarProps`(`disabled`, `startMonth`, `endMonth`, `locale`, `captionLayout`, `weekStartsOn`, `today`), 그리고 `button` props(`id`, `aria-label`, `className`…). - 선택은 `required`라 선택된 날짜를 다시 눌러도 해제되지 않는다(해제/clear UI는 없음). - **접근성**: Trigger는 `button`에 Radix Popover의 `aria-haspopup="dialog"`, `aria-expanded`, 팝업은 `role="dialog"`. 접근 가능한 이름은 `