Files
HMDesign/docs/org-chart/ui-composition.md
T

20 KiB
Raw Blame History

OrgChart UI Composition

P9.5 Full Composition 적응형 앵커 (2026-10-13)

Workdesk 조회 전용 Full Composition은 원본1920×914.5를 디자인 좌표계로 유지한다. 상단 제목·기준일·인원 표, 중앙 대표자·허브·조직/직원·연결선·화살표·장식, 하단 파견/휴직·관계사 바를 논리적 영역으로 표시한다. 상단 앵커는 콘텐츠 내 배치이며 sticky/스크롤 추적이 아니다.

배율은 min(1, 실제 콘텐츠 가용 폭 / 1920, 실제 가용 높이 / 914.5)다. 원본보다 키우지 않는다. 높이가 남으면 Stage의 사용 높이를 가용 높이 / 배율로 확보하고, 상단·하단의 실제 Rect 사이에 중앙 내용 Rect의 중심을 맞춘다. 장식은 원본 크기와 좌표를 유지하고 중앙과 같은 수직 오프셋으로 움직인다. 높이가 부족하면914.5 기준의 기존 상대 좌표를 유지하여 전체를 비례 축소한다. 하단 그룹과 가로 중앙 정렬은 중앙 오프셋에 포함하지 않는다.

파견·휴직은 하단 CSS 앵커를70→82디자인px로 바꾸어 기준에서12px 위로 옮겼다. 관계사 바의55.4px 높이·로고·문자와 하단 앵커는 유지하며 실제 그룹/바 간격은 약14.61디자인px다. 협업 화살표5개는 이미 정상 표시 중이어서 원본4개PNG·5개 배치를 보존했다. management 연결선은 이동된 overlay 원점을 기준으로 계산하여 중앙 이동의 이중 적용을 막는다.

P9.2의 실제 Content Wrapper 기준 가로 중앙 계산과 Expanded/Overview/Department 경로는 유지한다. 기존 P2~P9.4 보고서는 당시 기록으로 보존하고, 현재 측정은 Full Composition P9.5 보고서에서 구분한다.

P3.2 후속 — 대표자 뱃지 미사용 (2026-10-12)

대표자 카드는 모든 실행 경로와 독립 견본에서 직책·역할·상태 뱃지 및 빈 attributes/뱃지 행을 생성하지 않는다. 표시 직위 대표이사, 이름 홍 길 동, 승인 카드 146×74 및 기존 Typography·사진·로고를 유지하며 직위↔이름 간격은 0px이다. 원본 fixture의 대표자 직위는 경영진이므로 대표이사는 카드 표시에만 적용한다. 직원 JSON·정보 팝업 원문·공개 API와 다른 1Depth/2Depth 카드의 뱃지 정책은 그대로 유지한다. 아래 P3.2 및 이전 보고서·검증은 당시 기록으로 보존한다.

P3.2 현재 계약 (2026-10-12)

P3.2 보고서의 카드 Typography·상태 영역·로고 보정이 아래 P3.1 수치보다 우선한다. 과거 검증 기록은 그대로 보존한다.

  • 대표자 Typography는 유지한다. 대형 이름 24px/600/30px, 직위 18px/400/22px; 소형 이름 18px/600/24px, 직위 15px/400/18px이다. 기존 컬러·letter-spacing·Noto Sans KR 및 홍 길 동을 유지한다. 직위·뱃지 공백은 표시 계층에서만 제거한다.
  • readOnly 파견·휴직은 SVG 없이 일반 소형 카드의 공통 콘텐츠 레이아웃과 Typography를 재사용한다. 카드 108×52, 사진 24×44, 사진↔텍스트 4px, 직위↔이름 0px이다. 기존 회색 표면·문자색·로고 grayscale을 유지하며 별도 상태 행은 없다. P3.1의 실제 114×54/사진 28×28에서 이번 요청값으로 보정한다.
  • 상태 타이틀은 일반 2Depth 기본 20px/700/19.7px를 공유하며 회색 Gradient를 유지한다. 경영기획/인재성장 18px/600/16.9px 예외는 보존한다. 타이틀↔첫 카드 Gap 8px를 유지한다.
  • 카드 로고의 실제 contain 표시 영역은 소형 12×12→18×18, 대형·대표자·파견·휴직 14×14→21×21이다. 원본 PNG·승인 SVG 및 하단 관계사 현황 로고는 수정하지 않는다. 직원 카드 selector에만 적용하며 비율·투명 배경을 유지한다.

P3.1 현재 계약 (2026-10-12)

잔여 디자인 보완의 최신 계약은 P3.1 보고서가 우선한다. 아래 P3/P2 및 초기 설계의 검증 기록은 당시 범위 그대로 보존한다.

  • OrgChart 전용 기본 폰트는 Noto Sans KR이다. 기존 public/fonts/NotoSansKR-variable.ttf와 호스트 font-face를 재사용하며 HM Theme는 수정하지 않는다. 한국어 Core shell은 lang="ko"로 HTML/React/Storybook의 글리프 조형을 맞춘다.
  • 이름은 홍 길 동, 직위는 표시에서만 공백을 제거한다. Full Composition은 jobTitle이 경영진인 뱃지만 생성하지 않으며 기타 직책 문자열·원본 데이터·팝업·통계는 유지한다. 원본 position="경영진" 텍스트는 유지한다.
  • 1Depth는 20px/700/36px·헤더 높이 36px이다. 2Depth 경영기획/인재성장은 18px/600/16.9px, 나머지는 기존 20px/700/19.7px다. 114×30.4 표면·Gradient·Radius·Shadow 및 모든 타이틀↔첫 카드 Gap 8px를 보존한다.
  • 허브는 원본 21px/750/24px·아이콘 20px·Gap 8px·좌우 Padding 22/24px·높이 42px를 유지한다. 최대 폭 상속 제약을 해제하고 X 935 중심축을 유지한다.
  • 사진 없음/로드 실패는 공통 person-placeholder.svg를 사용한다. 실제 사진이 있으면 우선한다. 승인 사진 슬롯 36×62/32×56/24×44, P3 상태 카드 슬롯 28×28 및 비원형 처리를 유지한다.
  • 우측 표는 전체 330px 안에서 조직명/경영진 열을 112/46px로 재배분해 한 줄로 표시한다. 나머지 열은 잔여 폭을 나눈다. 숨김/말줄임/폰트 축소 없이 원본 14px, 기존 계산 41명·위치·셀 정렬·행 높이를 보존한다.
  • 대표자 146×74, 1Depth 146×68, 하위 108×52 및 P3 상태 카드 114×54를 유지한다. 확장형 Auto Layout/layoutConfig·메뉴·Navigation·공개 API 추가 없음.

P3 현재 계약 (2026-10-12)

아래 초기 설계와 P2 기록은 보존한다. 충돌하는 표시 계약은 P3 보고서가 우선한다. 범위는 기존 독립 HTML·React 공통 Core와 해당 Storybook 페이지이며 Navigation·Header를 추가하지 않는다. 기존 semantic table/native dialog는 공통 Vanilla Core adapter를 유지하기 위한 선택이다. FilterBar·DataTable의 검색/정렬/페이지 기능은 요구되지 않아 추가하지 않는다.

  • Full Composition 기본 배경 #F5F8FB, 원본 장식·허브 곡선·협업 화살표 유지. 조회 전용 엔진의 하위 연결선 생성 경로는 모두 숨긴다.
  • 대표자 146×74, 1Depth 146×68, 하위 108×52 유지. 모든 조직 타이틀↔첫 카드 간격 8px, 직위/뱃지↔이름 행 0px. 이름만 홍 길 동, 직위·뱃지는 원문.
  • 하위 헤더는 Workdesk 소스의 114×30.4 표면·상위 조직 Gradient·Radius 7.1·Shadow를 적용한다. HR은 18px/600/16.9, 다른 헤더는 20px/700/19.7이다. 허브는 원본 SVG 아이콘 20px·Gap 8px·텍스트 21px/750/24를 사용한다.
  • 사진 없음은 원형 기본 아바타 대신 빈 사각형 예약 영역이다. 원본에 기본 이미지가 없으며 승인 카드의 기존 폭을 유지하는 디자인 조정이다. 실제 직원 사진은 포함하지 않는다.
  • 우측은 직위별 표(주요 조직 하위 포함, 루트 직속, 직위별 열, 소계, 계). 가상 직원 41명·원본 조직 관계·독립 PositionSummary API를 보존한다. 상태 그룹의 카드 하단 상태 문구만 제거한다. 관계사 바는 제목 없는 한 줄이다.
  • 축소는 단일 비례 배율 min(1, 가용 폭 / Stage 폭, 실제 컨테이너 가용 높이 / Stage 높이)다. 연결 후 실제 Shadow/호스트 조상과 viewport를 관찰한다. 임의 Header 높이나 viewport 절반 offset 제한은 없다.
  • organizationLinks가 지정된 1Depth 제목만 링크다. onEmployeeClick이 없으면 Stage 바깥 native modal에서 기존 직원 정보를 조회한다. 닫기·ESC·키보드 Focus를 지원한다.
  • 사용자 메뉴는 Logo · Personnel Summary, Department Colors, Full Composition이다. 이전 단독 Story ID는 내부 태그로 보존한다.

실제 브라우저 측정과 미검증은 P3 보고서에 기록한다. 과거 PASS/FAIL을 이번 상태로 덮어쓰지 않는다.

상태: 콘텐츠 설계, 실행·시각 검증 미수행. README의 확정 범위와 최신 Core 독립성을 따른다. Workdesk 캡처 파일은 이번 첨부에 없어 아래 구성은 사용자 텍스트의 8영역을 기준으로 한다. 실제 이미지와의 배치·색상·카드·곡선 비교는 NOT VERIFIED다.

위 상태와 초기 설계 절은 과거 기록이다. 현재 조회 전용 구현은 3a절과 P2 구현·검증 보고서를 따른다. P2에서는 읽기 전용 Workdesk 로컬 소스와 자산을 확인하고 실제 HTML·React·Storybook을 검증했다. 운영 Workdesk와의 전체 픽셀 일치 여부는 별도 미검증이다.

1. 콘텐츠 구성과 데이터 연결

  1. 제목·설명: PresentationConfig의 title/description과 Metadata 기준일. Header·PageHeader·브랜드 Navigation을 생성하지 않는다.
  2. 최상위 리더 카드: 승인된 root 조직의 leaderId를 Employee에 연결한다. 공석·여러 root·겸직 leader 표현은 TBD다. 같은 직원을 중복 집계하지 않는다.
  3. 중앙 허브: hubText의 콘텐츠. 조직 entity인지 설명 허브인지, 리더와의 연결 방식은 TBD다. 조직장 ID나 직원 ID를 허브에 임의 부여하지 않는다.
  4. 조직별 그룹: Organization parent/type/order로 부문·실·Div를 구성한다. 조직 사이 기본 계층 연결선은 engine가 담당한다.
  5. 셀·팀·구성원: 같은 조직 계약에서 cell/team을 표현하고 직원은 organizationId로 조회한다. 이름·직위·직책·이미지/fallback·상태를 조합한다. 직원 전체를 조직 트리의 nested 원본으로 저장하지 않는다.
  6. 우측 인원 현황: 조직 직접/하위 포함·직위별 등 승인된 집계. 우측은 넓은 컨테이너에서의 배치 후보이며 작은 화면에서는 문서 흐름으로 이동하는 안을 검토한다.
  7. 파견·휴직 영역: 같은 직원 원본의 상태별 그룹. 본 조직 카드와 동시 노출/이동 표시 정책은 TBD이며 표시와 집계를 분리한다.
  8. 관계사별 인원·총원: Affiliation과 승인 정책을 사용하는 집계. 조직별 하위 포함 수를 단순 합산하지 않는다. 집계 정책 미승인 시 미확정 상태를 설명한다.

추가 조직 관계는 OrganizationRelation에서 별도 표시한다. 관계 의미·방향·범례·곡선·anchor는 승인 전 확정하지 않는다. 관계를 parent hierarchy로 오인하지 않도록 텍스트 설명을 함께 제공하는 안을 검토한다. 고정 좌표로 인원 수나 조직 배치를 하드코딩하지 않는다.

2. HM 재사용과 Core DOM 경계

최신 사용자 요구에 따라 Core는 React Component를 import하지 않는다. OrgChart 전용 표준 HTML/CSS가 공통 Component를 대체하는 신규 HM primitive가 되지 않도록 범위를 콘텐츠에 제한한다. 기존 Component·Pattern·Theme·대표 Story는 보존한다.

재사용의 두 경로를 구별한다.

  • Core: HM CSS Custom Properties와 기존 Typography·Spacing·Radius 기준을 참조한다. 노드에는 전용 class를 쓰고 HM data-slot 또는 일반 Card/Avatar selector를 흉내내지 않는다. 이 예외와 기존 React 지침의 충돌은 README에 기록했다.
  • React 소비 앱(Core 콘텐츠 밖): 적합한 주변 콘텐츠에서 공개 @hm-design/ui API를 실제 렌더링하는 방향을 검토한다. Wrapper는 Core summary/loading/error/node를 다른 HM UI로 대체하지 않는다. Core 노드마다 React root를 만드는 설계도 채택하지 않는다. 공통 Core의 콘텐츠·디자인·인터랙션을 유지한다.

확인한 공개 자료:

  • Card 문서, Card All, 구현: surface/content와 Header/Title/Description/Content 조합. Core 외부의 React 콘텐츠 묶음에서 재사용 후보다.
  • Avatar 문서, Avatar All, 구현: 이미지/fallback, sm/default/lg. Core는 <img>/안전한 텍스트 fallback을 사용하고 React 호스트에서는 공개 Avatar 후보를 검토한다.
  • Table 문서, Table All: 정적 표이며 정렬/선택/페이지는 DataTable 책임이다. 요청된 Summary는 동일 Core의 semantic table로 설계한다. React 소비 앱의 별도 주변 표에서 공개 Table을 검토할 수 있지만 Wrapper가 Summary를 중복 구현하지 않는다. 기존 Table 최소 폭 520px은 Core의 확정 최소 폭이 아니며 사용한 주변 표는 390px 내부 스크롤을 확인한다.
  • 공개 인덱스의 Badge/Alert/Skeleton/ScrollArea/Button/Label은 해당 기능 확정 시 문서·대표 Story·Props를 더 확인한다. 현재 import나 재사용 PASS로 보고하지 않는다.

Pattern 선택 근거: FilterBar는 검색·조회 조건용이다. 현재 검색/필터 요구가 없어 추가하지 않는다. DataTable의 정렬/선택/페이지도 요구가 없어 사용하지 않는 방향이다. DashboardLayout/GNB/LNB/PageHeader는 페이지 Shell/Navigation 책임이므로 제외한다. LoadingScreen은 전체 화면용이라 콘텐츠 loading에 바로 사용하지 않는다. 상태 콘텐츠는 Core가 관리하고 React 주변 조합은 기존 Alert/Skeleton을 검토한다. 이는 개발 시 선택 근거이며 구현 재사용 검증은 NOT VERIFIED다.

3. 컨테이너·반응형·Overflow

Core는 부모의 실제 콘텐츠 크기를 사용한다. viewport에서 Header 높이를 빼거나 GNB/LNB/Dashboard 모드를 읽지 않는다. Dashboard 소비자가 960px 내부 콘텐츠를 주는 경우에도 이를 Core 전역 최소 폭으로 일반화하지 않는다.

390/768/1280/1440px 각각에서 콘텐츠 컨테이너를 직접 제한하여 검사한다. 숫자는 검증 기준이며 확정된 breakpoint·카드 폭이 아니다.

  • 390px: 가로 조직도 내부 스크롤·읽을 수 있는 텍스트 배율, 요약/상태 영역 흐름 배치, touch와 focus 접근을 검토한다. 전체 화면을 축소해 텍스트를 읽을 수 없게 하는 기본값은 확정하지 않는다.
  • 768px: 조직 분기 wrap과 가로 스크롤, summary의 옆/아래 배치, 긴 조직명·직위·ID를 검사한다.
  • 1280/1440px: 전체 계층·리더·허브·우측 summary·추가 관계·직원 카드의 겹침과 여백을 검사한다.
  • 조직 수·깊이·직원 수가 증가하면 내부 scroll container가 확장되고 페이지 전체 가로 Overflow는 발생하지 않아야 한다. CSS transform zoom은 layout 크기와 다를 수 있으므로 보이는 영역과 scrollWidth/clientWidth를 함께 측정한다.
  • ResizeObserver·이미지 로드·폰트 로드·노드 확장·줌·스크롤마다 Overlay 좌표가 동일 좌표계에서 갱신돼야 한다. transform 중복 적용과 stale anchor를 검사한다.
  • 모바일 방식은 내부 가로 scroll, branch 축소, 세로 대체 표현 중 PoC로 결정한다. 대체 표현은 승인 전 추가 개발 요구로 만들지 않는다. 최소 콘텐츠 폭·zoom 한계·초기 배율·wheel 우선순위·높이 제약·스크롤 책임은 TBD다.

문서와 내부 컨테이너의 scrollWidth/clientWidth 및 scrollHeight/clientHeight를 기록한다. absolute 알림/overlay의 위치 기준은 해당 인스턴스의 relative 컨테이너여야 한다. 긴 label 줄바꿈과 ID 한 줄 식별 가능성, 접힌 영역에 숨은 focus, 두 인스턴스의 독립 scroll/zoom을 검사한다.

3a. 조회 전용 Full Composition (displayMode: 'readOnly', 2026-10-12)

  • Storybook OrgChart / Full Composition, HTML·React p1.html?mode=readOnly가 사용한다. 기본값 interactive와 내부 검증 Story·독립 컴포넌트는 변경하지 않는다.
  • 생성하지 않는 요소: 하위 조직 접기/펼치기 button, 조직 종류·ID·원본 직원 수·조직장 안내 문구, 제목 설명·추가 관계 안내, 상태 그룹 정책 문구. 조직 그룹 외곽 카드(배경·Border·Radius·Padding)는 CSS로 제거하고 조직/셀·팀 헤더·카드·연결선은 유지한다.
  • 배치: Workdesk 실측 1920 × 914.5 캔버스, 대표자·허브 축 X 935, 조직 헤더 X 32/268/505/858/1336/1689(core/workdesk-layout.ts, organization ID 기준 presentation preset). 통합시스템 Div·디자인기획 하위는 가로, 나머지는 세로. preset이 없는 조직이 있으면 중앙 흐름 배치로 대체한다.
  • 요약: 우측 상단 조직별 인원 현황(루트 직속 + 주요 조직 하위 포함 인원 + 계), 좌하단 파견·휴직(제목 108px pill, 카드 유지), 하단 관계사 바(제목 없음, 로고·회사명·인원·총계). 모두 같은 Summary/selector에서 계산한다.
  • 축소: scale = min(1, 가용 폭 / 1920, (viewport 높이 − 문서 offset) / 914.5)(offset은 viewport 절반까지만 반영). transform scale 1회, 내부 가로 스크롤 없음.
  • P2 카드: 실제 parentId 조상 관계로 Depth를 계산한다. 대표자 146×74, 1Depth 조직장만 146×68, 2Depth 이하 조직장은 해당 부서의 108×52 소형 SVG를 사용한다. semantic leader와 직책 뱃지는 유지하며 interactive·독립 카드 선택은 보존한다. 전달 자산이 없는 조직의 기존 fallback 정책은 유지한다.
  • 최신 확정 표시: 조회 전용 직원 이름은 대표자·파견·휴직을 포함해 모두 홍 길 동. 직위·직책·이름의 연속 한글 사이에는 표시 계층에서 공백을 넣고 접근성 이름은 원문을 사용한다. 원본 JSON 이름·ID·조직·인원 계산은 변경하지 않는다. 기존 font-size/weight/line-height/color와 내부 0px 행 간격을 유지한다.
  • P2 간격: 1Depth 헤더 높이 36px, Y 약 254.19px, 대형 카드 사이 실제 8px. 2Depth 헤더와 첫 카드 사이 실제 10px. 하단 상태/관계사 슬롯은 측정 캔버스 내에서 고정 배치하여 전체 높이 914.5px와 겹침 없는 배치를 유지한다.
  • P2 장식: core/workdesk-artwork.ts가 원본 compact 허브 곡선 3개·중앙선·사업관리 추가 곡선, PNG 협업 화살표 5개와 배경/허브 이미지 5개를 같은 Stage에 렌더한다. 원본 9종 자산은 byte 그대로 복사하고 ESM/IIFE에 포함한다. 기존 상단 pseudo 연결선은 이 preset에서 제거한다. 하위 팀의 실사용 원본 SVG는 없어 기존 engine 관계 경로를 유지한다.
  • P2 검증: HTML HTTP·classic file://·React production·Storybook에서 1920/1440/1280/768/390px 484건 PASS. Guard 원본의 NOT VERIFIED와 런타임 PASS는 별도 증거로 보존한다. 상세 측정·남은 차이·기존 FAIL은 P2 보고서에 기록한다.

4. 접근성·상태·개인정보

Core DOM은 제목 계층·조직/직원 그룹·표의 caption/header를 semantic하게 구성한다. engine 기본 DOM이 완전한 ARIA tree라고 가정하지 않는다. tree 역할 채택 시 키보드 계약 전체를 검증하고, 그렇지 않으면 계층 설명을 제공할 구조를 검토한다.

확장·축소/zoom 조작이 구현될 경우 키보드로 접근 가능한 표준 button과 접근성 이름·focus indicator·disabled 상태를 제공한다. readOnly 데이터 조직도에 수정·drag 메뉴를 추가하지 않는다. 상호작용 후 focus 복귀, 제거된 노드 focus 이동, 오류/로딩 안내의 screen reader 노출과 과도한 알림을 검사한다. 입력 컨트롤이 새로 승인되면 React 호스트는 공개 Label, Core는 framework 독립성 때문에 native label/control 연결을 명시한다.

이미지 접근 실패는 가상 fallback을 보여주며 불필요한 이름 중복 읽기를 피한다. 사진의 origin·권한·실패 정책은 API 연동 시 결정한다. 직원 ID·이름·사진 원본을 로그/오류 메시지에 무분별하게 남기지 않는다. reference의 실제 인물을 fixture로 재사용하지 않는다.

Loading/Empty/Error/Ready, 직원 없는 조직, 공석 leader, 상태 그룹 비어 있음, 정책 없는 집계, 갱신 중 상태를 별도 검증한다. 갱신 중 기존 화면 유지와 부분 오류 허용 정책은 TBD다. 사용자 검토 전에 이러한 설계 후보를 기능 PASS로 표시하지 않는다.