# Input 현재 HM 구현의 기준 문서. 공통 원칙은 `docs/guidelines/프로젝트-지침.md`(§6, §7), Token 구조 원칙은 `테마-토큰-가이드.md`를 따른다. 이 문서는 Input 고유의 API·Token·상태·결정만 기록한다. ## 1. 상태 | 항목 | 내용 | |---|---| | 구현 상태 | HM 스타일 적용 완료 (`hm-input` class 없음) | | 기준일 | 2026-10-02 | | 기반 | shadcn/ui Input (native ``) | | 대표 Story | `Components/Form/Input` → `All` (이름 "Input") | | 보류 | 아래 §11 | ## 2. 적용 근거 - **ui_viz Confirmed**: size·padding-x(input.md §24, §16), border/radius/색(§10, §11, D-005), Focus/Error 표현. - **ui_viz owner decision**: size별 value·placeholder 글자(§9, §21 `INPUT_VALUE_ROLE_FOLLOWS_SIZE`). - **HM 사용자 결정**: Disabled opacity `0.6`(2026-10-02, §10). - **shadcn 유지**: native input 동작, `file:` 스타일 class, disabled 포인터/커서 처리. - **ui_viz 미정의**: 아래 §11 참조. ## 3. 기본 규격 | Size | Height(min) | Padding-x | Font / Line-height | |---|---|---|---| | `small` | 28 | 10 | 12 / 18 | | `medium` | 34 | 12 | 14 / 20 | | `large` (기본) | 42 | 12 | 16 / 24 | - 높이는 `min-height`, 한 줄 텍스트는 가운데. - Border 1px(`--hm-sem-stroke-input-default`), radius `--hm-radius-input`, face `--hm-sem-bg-surface`, 글자색 `--hm-sem-fg-primary`, weight 400. - Placeholder: `--hm-sem-fg-placeholder`, `opacity: 1`. ## 4. 상태 규격 | 상태 | 값 | 근거 | |---|---|---| | Default | 위 기본 규격 | ui_viz Confirmed | | Focus (`:focus-visible`) | border 1.5px `--hm-sem-stroke-input-focus`, shadow/glow 없음, padding으로 0.5px 보정해 값이 움직이지 않음 | ui_viz Confirmed | | Error (`[aria-invalid="true"]`) | border 1.5px `--hm-sem-action-destructive`, ring 없음 | ui_viz Confirmed | | Error + Keyboard Focus | Destructive border 유지 + HM Focus Semantic 3px / 50% outer ring, `outline: none` | 2026-10-06 사용자 결정 | | Disabled | White face 유지, `opacity: 0.6`, `cursor: not-allowed`, `pointer-events: none` | face: ui_viz Confirmed / opacity: 사용자 결정 | | Readonly (`[readonly]`) | 박스 없음(border 0, padding-x 0, 투명 face), dim 없음, 항상 Large 치수 | ui_viz | | Hover / Active | 정의 없음(별도 스타일 없음) | ui_viz 미정의 | Focus ring chain은 `--ring` → `--hm-sem-stroke-input-focus` → `--hm-color-border-focus`다. Error border는 `--hm-input-error-border-color` → `--hm-sem-action-destructive`를 따른다. 일반 Focus / Readonly의 기존 표현은 유지하며, editable Invalid + Focus에서 UA outline 의존을 제거했다. ## 5. API ``` Input: size?: native (number) → size?: "small" | "medium" | "large" 기본 "large" ``` - native `size`(글자 수 폭)를 대체한다. native 속성이 CSS 폭과 무관해 쓰임이 없다는 판단(지침 §6.7). - 출력 속성: `data-slot="input"`, `data-size`. - 상태는 새 prop이 아니라 native 속성으로 준다: `aria-invalid`, `disabled`, `readOnly`. - Field(Label, Required 별표, Helper/Error 문구)는 Input에 포함하지 않는다. 소비 조합이다. ## 6. Token Component Mapping 위치: `packages/ui/src/theme/input.css` (`--hm-input-*`). - 재사용한 공통 Semantic: `--hm-radius-input`, `--hm-sem-bg-surface`, `--hm-sem-fg-primary`, `--hm-sem-fg-placeholder`, `--hm-sem-stroke-input-default`, `--hm-sem-stroke-input-focus`, `--hm-sem-action-destructive`(Semantic 참조). - Input 전용 값: `--hm-input-height-{sm,md,lg}`, `--hm-input-padding-x-*`, `--hm-input-font-size-*`, `--hm-input-line-height-*`, `--hm-input-state-border-width`(1.5px). - Primitive 신규 추가 없음. - Button의 높이 Token(`--hm-button-height-*`)·Select 높이와 값이 겹쳐도 alias하지 않는다. 각 ui_viz 규격이 따로 확정한 값이다. - Disabled opacity는 Token이 아니라 `ui/input.tsx`의 `disabled:opacity-60`으로 적용된다(§11). ## 7. shadcn / Radix에서 유지한 항목 native `` 동작 전체(`type`, `file:` 스타일 class, `placeholder`), `data-slot`, `cn(..., className)`, `transition-colors`, `outline-none`, disabled의 `pointer-events-none`/`cursor-not-allowed`. Radix 사용 없음. ## 8. HM에서 변경한 항목 - `size` API 교체, 기본 Large, `data-size` 추가. - shadcn의 기본 높이/padding/border/ring/dark class 제거 → theme CSS가 담당. - 일반 Focus는 border 1.5px로 표시, Error 단독은 ring 없음. Error + `:focus-visible`만 독립 Focus ring을 표시한다. - Readonly 전용 표현 추가. - `hm-input` class 제거. ## 9. Storybook - 대표 Story `All`("Input"): 구역 `sizes`, `default`, `focus`, `error`, `error-message`, `disabled`, `readonly`. Focus는 `play` 함수로 실제 focus를 준다. - verification(`tags: ["verification"]`): `Default`, `Focus`, `Error`, `InvalidFocus`, `ErrorMessage`, `Required`, `Disabled`, `Readonly`, `Sizes`("Compare Sizes"), `Small`, `Medium`, `Large`, `Playground`(HM 전용). - Error Message·Required 표시는 Story 안의 조합 예시이며 Input 컴포넌트의 일부가 아니다. - sidebar는 `All` 하나만 보이는 1뎁스. 운영 규칙은 지침 §6.3, §7 참조. ## 10. 사용자 확정 결정 **2026-10-02** - Input Disabled opacity `0.6` 확정. - ui_viz에서 Temporary로 기록된 이력이 있으나, 현재 HM 구현에서는 사용자 결정이 우선한다. 이전의 "Temporary → 미적용" 판단은 이 결정으로 superseded. - 이 값은 Input에 대한 현재 최종값이다. 전체 디자인 시스템 공통 Disabled opacity로 자동 확대하지 않는다. - 근거: Select 작업에서 확정된 Disabled 시각 intent와의 정합. Select Trigger도 `0.6`(select.md 참조). ## 11. 미확정 / 보류 - ui_viz 미정의: Hover, Active 표현, Error 메시지 컴포넌트, Input 내부 아이콘/clear 버튼. - Disabled opacity `0.6`은 Input 한정 사용자 결정이다. 다른 컴포넌트에 적용하지 않는다. - `file:` 타입 스타일은 shadcn 기본이며 HM 규격 없음. - Readonly에서 Disabled 조합 동작은 별도로 확인하지 않았다. ## 12. 관련 파일 ``` packages/ui/src/components/ui/input.tsx packages/ui/src/theme/input.css src/components/input.stories.tsx src/components/story-board.tsx ``` ## 13. 검증 상태 - TypeScript, `npm run build`: 통과(2026-10-02). - Storybook computed style: `Components/Form/Input` Disabled `opacity` = `0.6` 확인. - Story: `All`의 구역 7개와 verification Story ID 존재 확인. - 2026-10-06 ui_viz Storybook 화면 비교(1280/768/390, Chromium): 대표 Story 7구역의 컨트롤·Label·Error 문구 computed style 일치, placeholder 색, Focus·Error 경계, Error+Focus의 outline 유지, 긴 값 가로 스크롤 일치. Readonly는 ui_viz `

` 대신 native `input[readonly]`로 같은 42px·16/24 표시. Error Message·Required Story에 ui_viz처럼 placeholder를 넣음(Story만 변경). - 미확인: 브라우저별 렌더(Chromium 외). ### Invalid + Focus 검증 (2026-10-07) - Focus ring: `--ring` → `--hm-sem-stroke-input-focus` → `--hm-color-border-focus`. Invalid border: 기존 `--hm-sem-action-destructive`. 새 Runtime Role / Production Error prop / 메시지 컴포넌트 없음. - Chromium computed style: Invalid border `rgb(211, 47, 47)`, Invalid + Keyboard Focus box-shadow `color(srgb 0.14902 0.4 0.317647 / 0.5) 0px 0px 0px 3px`, `outline-style: none`. Invalid 단독은 `box-shadow: none`. - Theme Designer UI에서 Focus `#c75b00`, Destructive `#d41466`, Active `#007f73`, Accent `#ffd36d`로 분리. Invalid border `rgb(212, 20, 102)` + Focus shadow `color(srgb 0.780392 0.356863 0 / 0.5) 0px 0px 0px 3px` 확인. - `npm run typecheck`, `npm run build`, `npm run build-storybook` 통과. 기존 문서 예시 CSS warning 및 Storybook chunk 크기 / plugin timing warning 유지. - 검증 범위: Chromium 환경. 다른 브라우저의 렌더링은 별도 확인이 필요하다. - 대표 `All`과 숨김 `InvalidFocus` 확인. 일반 Focus는 border만 변경, Small/Medium/Large 28/34/42px 및 12/14/16px 유지. Readonly border 0 / padding 0, Disabled opacity 0.6 유지. Border CSS 계약 1.5px, 이 브라우저 환경의 computed border-width는 1px으로 정규화; padding 보정은 11.5px 유지. 기존 non-invalid Readonly의 UA outline 정책은 이번 범위에서 유지.