Files
shkim4 4c29894e56 refactor(storybook): simplify component and preview examples
Drop page / section descriptions, state notes and repeated captions from
the representative Stories of 44 components, the Patterns, Center
Graphic and OrgChart pages. Value readouts, spec lists and captions hide
only on the representative page; hidden verification Stories keep them.
Tabs Default API and the Filter Bar draft / applied counts move to the
hidden DefaultApi and DraftApplied Stories; Center Overview is hidden
with its direct URL kept. Story IDs are unchanged.

Align the component, pattern and OrgChart docs with the pages, point the
quality reference check at the DraftApplied Story, and make the P8
styles check expect no section header on the preview-only Expanded page.
2026-10-23 00:28:05 +09:00

11 KiB

Input

현재 HM 구현의 기준 문서. 공통 원칙은 docs/guidelines/프로젝트-지침.md(§6, §7), Token 구조 원칙은 테마-토큰-가이드.md를 따른다. 이 문서는 Input 고유의 API·Token·상태·결정만 기록한다.

1. 상태

항목 내용
구현 상태 HM 스타일 적용 완료 (hm-input class 없음)
기준일 2026-10-02
기반 shadcn/ui Input (native <input>)
대표 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 <input size> (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 <input> 동작 전체(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(Small / Medium / Large 비교) → States(focus, disabled, readonly) → Validation(error, error-message). Focus는 play 함수로 실제 focus를 준다. 2026-10-22 Overview(default, size 생략 = Large)는 Sizes의 Large와 같아 대표 화면에서 뺐고, 크기별 수치 목록·설명은 숨김 Sizes("Compare Sizes")에 남겼다. size 생략 시 Large(§5)는 그대로다.
  • 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-11 최종 사용자 결정 — Disabled Input Label

  • Input Story 소비 조합(src/components/input.stories.tsx의 Specimen)의 Disabled Label은 기존 text-muted-foreground → --muted-foreground → --hm-sem-fg-secondary 색(#6E6759)을 유지하고, input.disabled일 때만 opacity-60을 적용한다. HEX·Semantic Token·공개 Input API는 변경하지 않는다.
  • Disabled Input 컨트롤 0.6, 소비 Label 0.6, 부모 Field 1이다. 형제 요소에 각각 적용하여 중첩 opacity를 만들지 않는다. 기본·readOnly·Error Label은 기존 1을 유지한다(Disabled가 아닌 경우).
  • 공통 Label Component의 Disabled 0.5는 유지한다. Helper Text(#6E6759)와 Error Message(#D32F2F)도 기존 구현을 유지하며 이번 변경 대상이 아니다.
  • 이전 검토의 “Label 100% 유지”는 당시 선택이며 현재 최종 결정은 Disabled Input Story Label 60%다. 아래 2026-10-02 승인과 2026-10-06 검증은 당시 기록으로 보존하며, 이번 Label 정책의 현재 검증을 대신하지 않는다.
  • 실제 소비 화면은 자동으로 확대 수정하지 않는다. 신규 화면의 공개 Label 재사용·control 연결 계약은 유지하며, 공통 Label의 Disabled 정책을 이 Story 결정으로 대체하지 않는다.

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 <p> 대신 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 정책은 이번 범위에서 유지.

Disabled Input Label 검증 (2026-10-11)

  • 실제 Storybook(Chromium/Edge): Disabled Label rgb(110, 103, 89) / opacity 0.6, Input 0.6, 부모와 모든 조상 opacity 1. 공통 Label Disabled 0.5, Input Default/readOnly/Error Label 1 유지.
  • 실제 배경 rgb(245, 240, 229)에서 합성색 약 #A49E91, 대비 약 2.35:1(원본 100% 약 4.93:1). 일반 텍스트 4.5:1보다 낮으며, 실제 disabled 컨트롤에 연결된 비활성 UI 라벨의 WCAG 1.4.3 예외와 구분한다. 사용자 확정 정책은 유지하고 가독성 우려를 기록한다.
  • Default/Disabled/Readonly/Error/Error Message/Playground 및 대표 All 390/768/1280/1440px, htmlFor/control 연결·편집·readOnly·disabled focus·문서 overflow 확인. Typecheck, UI build, Storybook build 통과. Guard FAIL 0, 원본 NOT VERIFIED 보존. 검증 범위와 제한.