13 KiB
HMDesignSystem 전체 정합성 감사 — 2026-10-06
HISTORICAL_RECORD: 2026-10-06 감사 시점의 저장소 상태·실측·보류 판단을 보존한다. 이후 상태 정책과 구현을 이 기록으로 대체하지 않는다. 현재 Component/Pattern 상태는 각 Component 문서/Pattern 문서, Runtime 적용은 Runtime Theme, Designer 사용은 Theme 가이드를 따른다.
현재 Production 코드와 실제 Storybook을 1차 기준으로 새로 대조했다. 문서/CLAUDE.md는 비교 대상이며 과거 작업 보고서의 검증 수치를 이번 결과로 재사용하지 않았다. 수정 전 분류를 먼저 보고한 뒤 명백한 불일치만 수정했다.
범위와 현재 구조
packages/ui: private source export 패키지. Component, 7개 Pattern, CSS Theme와@hm-design/ui/themeRuntime API를 소유한다.packages/center-graphic: UI와 서로 의존하지 않는 private source export 패키지. 통합 Storybook에서 별도 그룹으로 제공한다.- 루트
src,.storybook: Demo와 Component/Pattern/Theme/CENTER Story. UI 44개 그룹, Pattern 6개 그룹(Page Header는 Dashboard에서 조합), 전체 56개 Story 파일을 확인했다. - 대조 문서: Component 45개(Field 소비 가이드 포함), Pattern 7개, 기존 guideline 9개 및 CLAUDE.md/README.md. 현재 API·상태·Token·Story 경로를 비교하고 날짜가 있는 과거 검증 기록은 이력으로 읽었다.
- 현재 루트에
.git이 없다. Git diff/커밋 검증 대신 수정 전 확보한 파일과 로컬 변경 기록을 사용했다. 과거 기준 화면 snapshot과 보고서/CSV를 재생성하지 않았다.
Theme 흐름은 primitives.css → default.css의 Semantic/Theme palette 및 shadcn adapter → Component Mapping → CSS selector/utility → 실제 UI다. theme.css가 Default를 먼저 import한다. Component Mapping은 :root, [data-hm-theme]에서 다시 계산된다.
Runtime 계약은 contract.ts의 73개 입력이며 runtime.ts가 unknown 입력 전체를 검증한다. 색상은 6자리 불투명 HEX, input/container radius는 2–12px 정수, gradient는 세트 전체 또는 미지정이다. Partial/empty, atomic invalid fallback, 교체/cleanup, host inline value/priority 복원을 지원한다. Global 아래 명시적 Scoped Theme는 독립 HM Default + 자기 override이며 미지정 값이 Global override를 이어받지 않는다. 네트워크 Loader와 운영 Publish는 아직 없다.
MATCHED — 유지한 구현
- Active / Focus 분리: Checkbox/Radio/Switch/Slider/Progress/Calendar selected·range edge는 Active, 일반 focus border/ring은 Focus를 사용한다. Runtime에서 Primary
#6837a8, Active#007f73, Focus#c75b00을 분리해 기존 자동 검증을 새로 실행했고 실제 Checkbox/Calendar 채움과 Focus shadow 검사를 통과했다. Default에서는 Active/일반 Focus 모두#266651이나 서로 alias하지 않는다. - Calendar / Date Picker: selected와 range edge는 Active, hover/range middle은 Accent 45%, today는 Subtle Surface다. Global External에서 실제 Date Picker를 열면 body Portal의 selected day가
rgb(0,127,115)이고, 10/16 선택 후 닫히며 트리거로 Focus가 복귀했다. Wrapper Scoped popup의 제한은 아래 FOLLOW_UP이다. - Badge / Pagination: Default Badge와 Pagination Current는 Primary Green(Default
#123328). Global External에서는 둘 다 Primary purple로 바뀌고 Active teal과 구분된다. 실제 Pagination 일반 링크 hover는 Accent yellow 45%, Current는 Primary를 유지했다. - Table / Data Table: row hover/selected는 공통 Accent 45%. Global Table에서 실제 hover/selected를 같은
color(srgb 1 0.827451 0.427451 / 0.45)로 확인했다. Data Table에서 행 선택 후 선택 면은 Default Accent 45%, Checkbox는 전환 종료 후rgb(38,102,81)(Active), Current 페이지는rgb(18,51,40)(Primary), 선택 요약은1개 선택됨 · 전체 47개였다. Header 팔레트 장식은 별도 정책이다. - LNB 3Depth: 기존 LNBGroup 중첩/Collapsible 조합을 유지한다. 3Depth 행 48px, padding-start 88px, weight 500/current 700, connector 40%와 current 배경·상위 노랑을 코드 및 실제 DOM으로 대조했다. Enter/Space 접기·펼치기와 소비자가 제어하는 중첩 open 상태가 유지된다.
- Brand / Mobile / Scroll: GNB+LNB는 GNBBrand 1개와 LNBBrand 0개. Standalone은 desktop LNBBrand, mobile Local bar의 서비스명으로 대체한다. 1023px에서는 GNB 56px/LNB hidden, 1024px에서는 GNB 70px/LNB 표시, 문서 폭은 viewport와 같다. 높이 700에서 LNB nav는 y=98→610, client 512/scroll 526; 실제 scrollTop=14에도 Profile y=610, GNB y=0을 유지했다. nav RTL/내용 LTR로 scrollbar를 시작 쪽에 배치한다. Standalone Mobile Sheet의 지역 3Depth 메뉴, Escape 닫힘과
서비스 메뉴트리거 Focus 복귀를 확인했다. - Dashboard composition: header/sidebar/children slot과 main scroll 소유권, desktop GNB/LNB 접점 및 mobile 전환이 현재 문서와 일치한다. KPI/Filter Bar/Data Table은 공개 primitive/pattern 조합이다. GNB+LNB 조립은 이미 구현되어 있다.
- Dialog Wide Table: 390px viewport에서 Dialog 358px, 문서 scrollWidth 390px, Table container client 308px/scrollWidth 1600px/overflow-x auto. 가로 스크롤은 내부 Table container가 소유한다. Header 13/20, Cell 14/20, padding 14/12를 유지하고 Escape 후
넓은 표트리거 Focus 복귀를 확인했다. - Filter Bar Search Input: 기본 padding-start 36px, focus 상태 35.5px 보정으로 아이콘 뒤 텍스트 시작점을 유지한다. 실제 검색 입력/조건 수/지우기와 좁은 화면 overflow를 확인했다. Input 구현/CSS는 수정하지 않았다.
- Storybook: favicon override는 실제 Manager DOM에서 icon link 1개, href
data:,로 확인했다. 최종 빌드 index는 254개 Story/56개 그룹이며 UI 44개와 Pattern 6개 그룹은 각각 대표 Story 하나다. Theme 4개 Story는 verification으로 기본 숨김. 새 Progress NonDefaultMax도 숨김 verification이며 대표 Story에 같은 specimen이 있다.
DOC_FIX — 수정 완료
- Component/Pattern의 오래된 Story 경로를 현재 category/title로 갱신했다. Page Header는 별도 Story 없이
Patterns/Layout/Dashboard Layout에서 사용한다. - Primitive 직접 참조 설명을 현재 Semantic/Theme palette 연결에 맞췄다. Input/Textarea/Radio의 Destructive, Table/Subtle, Slider/Progress track, Tabs/Separator/Scroll Area, GNB/LNB/Loading Screen을 대조했다.
- Button의 로컬 HEX 잔존 설명, Select indicator 리터럴 설명, Select/Menu/Command의 full Accent 설명을 실제 palette/Accent 45% 연결로 고쳤다. Toggle on/full Accent와 Select selected/45%의 차이를 명시했다.
- Runtime API 미구현/Preview 전용, root 아래 Production 경로, toolbar 전환, 초기 5개 Component 상태를 현재 workspaces/API/Story 구조로 정정했다. Library build/registry/Loader/Publish 목표 절차와 현재 구현을 구분했다.
- CLAUDE.md의 Portal container API 설명을 실제 HM popup API 제한으로 바로잡았다. general Focus 설명에 기존 Slider/GNB/LNB 예외를 명시했다.
- Data Table의 With Filter Bar를 두 번째 대표 Story라고 한 설명을 숨김 verification으로 정정했다. Filter Bar 문서의 연동 대상도 Data Table로 유지했다.
- 과거 검증 절의 당시 색상·측정·실패/미확인 기록은 현재 결과로 덮지 않았다. Progress의 이전 max 제한에는 이번 수정 기록을 추가했다.
CODE_FIX — 수정 완료
Progress의 max 비율 계산 한 곳을 수정했다(packages/ui/src/components/ui/progress.tsx). 이전에는 value를 백분율로 간주하므로 max=200/value=50에서 ARIA는 50/200인데 채움은 50%였다. 이제 유효 value/max 비율로 25% 채우며 Radix 기본 max/유효 범위 및 값 없음 상태를 따른다. 디자인/CSS/공개 API는 유지했다.
src/components/progress.stories.tsx에 max=200의 0/50/200/값 없음 specimen과 ARIA/Indicator 회귀 검증을 추가했다. 실제 DOM은 각각 transform -100%/-75%/0%/-100%, ARIA 0/50/200/valuenow 없음으로 일치했다. 기존 max=100 대표 상태와 interactive specimen도 유지했다.
Production 수정은 위 파일 1개, Story 수정은 Progress 파일 1개다. 기존 문서는 58개 파일에 경로/Token/현재 상태를 정정했으며 Component·Pattern 구현을 재작성하지 않았다.
STALE — 현재 설명에서 정리
- 초기 5개 Component/Medium Preview만 구현된 상태.
- Storybook toolbar Default/Draft 전환과 Runtime API 공개 여부를 미래 결정으로 적은 설명.
- Dashboard가 다음 작업이거나 GNB+LNB 조립 자체가 아직 없는 상태.
- Alert Dialog 미구현, Dialog 이후 구조 안정화 대기, Select의 근거 없는 동시 작업 추측.
날짜가 있는 이전 작업 보고서, CSV, ui-viz 비교표는 폐기하지 않았다. 현재 구현 증거로 재사용하지 않고 당시 이력으로 구분했다.
AMBIGUOUS — 이번에 변경하지 않음
- Slider Primary 20% halo, desktop GNB/LNB inverse outline(current는 Primary)까지 일반 Focus Semantic으로 통합할지. 현재 component 문서와 Runtime 문서는 예외를 명시하지만 일반 Focus 표현을 한 가지로 확대하면 디자인 결정이 필요하다. 일반 Focus의 Light 2 자체도 가이드에 시험 적용값으로 남아 있다.
- GNB+LNB gradient 이음새/콘텐츠 모서리의 최종 시각 승인. 조립과 Brand ownership은 구현/확정되었고, 이 부분은 Dashboard/GNB 문서에서 확정 대기로 남아 있다.
- 선택 경로 전체 connector 강조와 모바일 LNB의 14px 지역 메뉴/상위 current 표현 등 기존 미확정 Layout 항목. 현재 문서에 없는 최종 정책을 추정해 바꾸지 않았다.
FOLLOW_UP — 별도 작업
- HM SelectContent/PopoverContent/DatePicker의 wrapper Scoped Theme 전달 API. 현재 body Portal은 Global Theme를 따르며 자동 Scoped 전달을 제공하지 않는다.
- Date Picker/Combobox를 undefined로 비우는 controlled reset 제약(현재 문서대로 key remount 사용). 새 API/상태 모델 작업으로 분리한다.
- FilterBarSearch에 disabled/readOnly를 전달할 때 별도 지우기 버튼의 활성 정책. 현재 input props는 Input에 전달되고 clear callback은 독립적으로 실행된다. 이번에 새 상태 계약을 만들지 않았다.
- Center Graphic/Facility의 7개 노출 Story는 서로 다른 시설물 export를 묶은 그룹이다. UI와 같은 단일 집계 대표 Story로 정리할지 검수 구조를 별도로 결정한다. 기존 CENTER 구현은 이번에 변경하지 않았다.
- 문서 예시를 자동 탐색해 생기는 CSS warning, Storybook chunk size와 docgen callback 성능 안내. 빌드 실패는 아니며 source 탐색/번들 최적화는 별도 범위다.
- Library 산출물/Registry, 네트워크 Loader, Theme Publish 운영은 아직 미구현이다.
최종 통합 검증
npm run typecheck: PASS / exit 0. 루트와 두 workspace 포함.npm run build: PASS / exit 0. CSS 예시 warning 1개 유지.npm run build-storybook: PASS / exit 0. CSS 예시 warning, 500kB chunk 안내 및 PLUGIN_TIMINGS 성능 안내가 출력되었다.- 현재 실제 Storybook Runtime 자동 검증: PASS — 136 checks; 63 rendered parts. Default parity, 73개 공개 입력, 의미 독립성, partial/empty/invalid, switching/cleanup, Global/Scoped, geometry를 새로 실행했다.
- CSS 변수 의존성/현재 문서 Token·Story 경로/73개 계약표를 정적으로 대조했다. Loading spinner index는 TSX inline style로 선언되며 LNB collapsed-width는 문서에서 명시적으로 없는 변수다.
- 최종 빌드 index에서 대표/verification 태그와 신규 NonDefaultMax 포함을 확인했다. 전체 254개 Story의 모든 play/interaction을 실행했다는 의미는 아니다. 실제 동작 검수는 위 핵심 대상에 집중했으며 다른 브라우저/실기기는 미검증이다.
로그/변경 기록: _local/consistency-typecheck.log, consistency-build.log, consistency-storybook-build.log, consistency-audit-data.json, consistency-audit-diff.txt. 로컬 비교용 파일은 _local/consistency-audit-before/에 확보 시점 기준으로 보관했다. Page Header 경로 및 Loading Screen Token의 단일 문구 수동 수정은 위 수정 범위에 별도로 기록했다.
화면 증거: _local/consistency-progress.png, _local/consistency-progress-final.png(실제 Manager에서 대표 Story 하나와 max=200), _local/consistency-dialog-mobile.png. Runtime 검증의 PASS 수치는 현재 브라우저의 result output에서 직접 읽었다.
작업 시간 (KST)
- Started At: 2026-10-06 15:03:01
- Estimated Duration: 40–60분(분석 20–30 / 최소 수정 10–15 / 통합 검증 10–15)
- Completed At: 2026-10-06 15:25:46
- Actual Duration: 22분 45초
- Variance: 예상보다 17분 15초–37분 15초 단축