docs(storybook): preview-first Expanded OrgChart and leaner Tabs / Button pages
Deploy Storybook / deploy (push) Successful in 54s

- Expanded OrgChart: the chart moves right under the page title; data, layout
  and interaction settings stay below it. Setting notes, section descriptions,
  hidden legends and the Drag & Drop ON/OFF text are removed; the example
  counts stay only as a hidden data hook for the OrgChart browser checks, and
  the pending note shows only while the employee count differs.
- Tabs: drop the text-only Do / Don't section (rules live in tabs.md §16).
- Button: the representative page hides the Brand / Standard state notes
  (story-only showNote); the hidden States Stories keep them.
- Report: the follow-up simplification and its verification.
This commit is contained in:
shkim4 committed 2026-10-22 17:25:00 +09:00
1 parent c5c6fed38e
commit 4a54cfbeb2
5 files changed
+48 -53

No files matched your search

+6 -12
View File
@@ -7,6 +7,12 @@
--hm-orgchart-expanded-preview-radius: var(--sb-center-card-radius);
padding: 0;
}
/* Preview first: the chart follows the page header with the header's own 24px rhythm. */
.hm-orgchart-story-expanded .hm-orgchart-story-lead {
display: grid;
gap: 0.75rem;
margin-top: 24px;
}
.hm-orgchart-story-expanded .hm-orgchart-story-settings {
display: grid;
@@ -16,18 +22,6 @@
border: 0;
min-width: 0;
}
/* StorySection supplies the visible heading; keep each fieldset named for assistive technology. */
.hm-orgchart-story-expanded .hm-orgchart-story-section-legend {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.hm-orgchart-story-expanded .hm-orgchart-story-controls {
align-items: flex-start;
}
+20 -28
View File
@@ -116,9 +116,15 @@ function ExpandedPreview() {
title="Expanded OrgChart"
description="모든 직원은 가상 데이터"
/>
<StorySection title="데이터 설정" description="직원 수 변경은 데이터 적용으로 반영">
{/* Preview first: the chart sits right under the page title; its own header already names it, so no section header. */}
<div className="hm-orgchart-story hm-orgchart-story-lead">
{error ? <p role="alert" className="hm-orgchart-story-note">{error}</p> : null}
<div className="hm-orgchart-story-preview sb-center">
<OrgChart dataSource={source} stylesheetUrls={compositionStylesheets} displayMode="readOnly" layoutMode="auto" autoLayout={layout} interactions={interactions} dragDropEnabled={dragDropEnabled} selectedCompanyIds={applied.companyIds} companyTopNodes={topNodes} employeePopup={popup} className="hm-orgchart-story-chart" onMove={result => { if (result.moved) setSession({ baseline: dataset, current: result.data }); }} onLifecycleError={cause => setError(cause instanceof Error ? cause.message : '조직도 설정을 적용할 수 없습니다.')} onStateChange={state => { if (state.status === 'error') setError(state.issues.map(issue => issue.message).join(' / ')); }} />
</div>
</div>
<StorySection title="데이터 설정">
<fieldset className="hm-orgchart-story-settings">
<legend className="hm-orgchart-story-section-legend">데이터 설정</legend>
<FilterBar layout="list-extended">
<div className="hm-orgchart-story-instance">
<Label id={`${id}-companies-label`} htmlFor={`${id}-companies`}>회사 선택</Label>
@@ -160,15 +166,19 @@ function ExpandedPreview() {
<Button variant="cancel" appearance="outline" onClick={() => { setError(null); setDraft(initialSettings); setApplied(initialSettings); setDataRevision(current => current + 1); }}>초기화</Button>
</FilterBarActions>
</FilterBar>
{/* Not shown: kept only as the data hook that the OrgChart browser checks (P8, P9-2/3/4) read. */}
<p hidden data-component="OrgChartExampleCounts">
표시 중: {applied.companyIds.length}개 회사 · 현재 소속 기준 직원 합계 {displayedTotal.toLocaleString('ko-KR')}명 / 전체 {sessionTotal.toLocaleString('ko-KR')}명
{companyCountSummary ? ` · ${companyCountSummary}` : ''}
</p>
{/* Live feedback only while the employee count differs from the applied data. */}
<p className="hm-orgchart-story-note" role="status" aria-live="polite">
{pending ? '적용 예정' : '예시 생성 기준'}: {draft.companyIds.length}개 회사 · 회사당 {draft.employeeCount}명 · 총 {predicted.toLocaleString('ko-KR')}명{pending ? ' · 데이터 적용을 눌러 반영하세요.' : ''}
{pending ? `적용 예정: ${draft.companyIds.length}개 회사 · 회사당 ${draft.employeeCount}명 · 총 ${predicted.toLocaleString('ko-KR')}명 · 데이터 적용을 눌러 반영하세요.` : ''}
</p>
<p className="hm-orgchart-story-note">회사 숨김·다시 표시는 현재 소속 변경을 유지합니다. 데이터 적용은 선택한 조건의 예시를 새로 만들고, 초기화는 최초 데이터 설정과 소속으로 돌아갑니다.</p>
</fieldset>
</StorySection>
<StorySection title="레이아웃 설정" description="표시 유형 · 초기 Depth">
<StorySection title="레이아웃 설정">
<fieldset className="hm-orgchart-story-settings">
<legend className="hm-orgchart-story-section-legend">레이아웃 설정</legend>
<div className="hm-orgchart-story-controls">
<div className="hm-orgchart-story-instance">
<Label id={`${id}-layout-label`} htmlFor={`${id}-layout`}>조직도 표시 유형</Label>
@@ -180,18 +190,16 @@ function ExpandedPreview() {
<div className="hm-orgchart-story-instance">
<Label id={`${id}-hybrid-label`} htmlFor={`${id}-hybrid`}>혼합형 시작 Depth</Label>
<Select value={String(layout.hybridStartDepth)} disabled={layout.type !== 'hybrid'} onValueChange={value => setLayout(current => ({ ...current, hybridStartDepth: Number(value) as 2 | 3 | 4 }))}>
<SelectTrigger id={`${id}-hybrid`} aria-labelledby={`${id}-hybrid-label`} aria-describedby={`${id}-hybrid-help`} size="medium"><SelectValue /></SelectTrigger>
<SelectTrigger id={`${id}-hybrid`} aria-labelledby={`${id}-hybrid-label`} size="medium"><SelectValue /></SelectTrigger>
<SelectContent>{[2, 3, 4].map(depth => <SelectItem key={depth} value={String(depth)}>Depth {depth}부터 세로 배치</SelectItem>)}</SelectContent>
</Select>
<span id={`${id}-hybrid-help`} className="hm-orgchart-story-note">Hybrid에만 적용합니다.</span>
</div>
<div className="hm-orgchart-story-instance">
<Label id={`${id}-group-hybrid-label`} htmlFor={`${id}-group-hybrid`}>특정 그룹 세로 배치</Label>
<Select value={layout.hybridOrganizationIds?.[0] ?? 'none'} disabled={layout.type !== 'tb' || !applied.companyIds.length} onValueChange={value => setLayout(current => ({ ...current, hybridOrganizationIds: value === 'none' ? [] : [value] }))}>
<SelectTrigger id={`${id}-group-hybrid`} aria-labelledby={`${id}-group-hybrid-label`} aria-describedby={`${id}-group-hybrid-help`} size="medium"><SelectValue /></SelectTrigger>
<SelectTrigger id={`${id}-group-hybrid`} aria-labelledby={`${id}-group-hybrid-label`} size="medium"><SelectValue /></SelectTrigger>
<SelectContent><SelectItem value="none">사용 안 함</SelectItem>{groupChoices.map(organization => <SelectItem key={organization.id} value={organization.id}>{organization.name}</SelectItem>)}</SelectContent>
</Select>
<span id={`${id}-group-hybrid-help`} className="hm-orgchart-story-note">TB에서 선택한 그룹 아래만 적용합니다. LR·Hybrid 전환 시 해제됩니다.</span>
</div>
<div className="hm-orgchart-story-instance">
<Label id={`${id}-depth-label`} htmlFor={`${id}-depth`}>초기 표시 Depth</Label>
@@ -201,17 +209,14 @@ function ExpandedPreview() {
</Select>
</div>
</div>
<p className="hm-orgchart-story-note">Compact: 미지원. 기존 직원 카드 디자인을 보존하며, 압축 배치 선택은 제공하지 않습니다.</p>
</fieldset>
</StorySection>
<StorySection title="인터랙션·직원 정보" description="Drag & Drop · 탐색 · 팝업 방식">
<StorySection title="인터랙션·직원 정보">
<div className="hm-orgchart-story-settings">
<fieldset className="hm-orgchart-story-companies">
<legend>독립 기능 설정 · 모든 표시 유형에서 개별 선택</legend>
<div className="hm-orgchart-story-company">
<Switch id={`${id}-drag-drop`} checked={dragDropEnabled} onCheckedChange={setDragDropEnabled} aria-describedby={`${id}-drag-drop-state`} />
<Switch id={`${id}-drag-drop`} checked={dragDropEnabled} onCheckedChange={setDragDropEnabled} />
<Label htmlFor={`${id}-drag-drop`}>Drag &amp; Drop</Label>
<span id={`${id}-drag-drop-state`}>{dragDropEnabled ? 'ON' : 'OFF'}</span>
</div>
{([
['collapse', '접기·펼치기 사용'], ['zoom', 'Zoom 사용'], ['pan', 'Pan 사용'],
@@ -231,19 +236,6 @@ function ExpandedPreview() {
</div>
</div>
</StorySection>
<StorySection title="조직도 미리보기" description="직원 카드를 눌러 정보 확인">
<div className="hm-orgchart-story">
<p className="hm-orgchart-story-note">빈 공간 드래그는 Pan입니다. {dragDropEnabled ? '직원 카드·그룹 타이틀 드래그로 회사 안팎의 소속을 변경합니다. 키보드: Alt+M → 방향키 → Enter / ESC 취소.' : '소속 변경은 Drag & Drop을 ON으로 설정하면 사용할 수 있습니다.'} 클릭은 직원 정보·그룹 접기입니다.</p>
<p className="hm-orgchart-story-note" data-component="OrgChartExampleCounts" aria-live="polite">
표시 중: {applied.companyIds.length}개 회사 · 현재 소속 기준 직원 합계 {displayedTotal.toLocaleString('ko-KR')}명 / 전체 {sessionTotal.toLocaleString('ko-KR')}명
{companyCountSummary ? ` · ${companyCountSummary}` : ''}
</p>
{error ? <p role="alert" className="hm-orgchart-story-note">{error}</p> : null}
<div className="hm-orgchart-story-preview sb-center">
<OrgChart dataSource={source} stylesheetUrls={compositionStylesheets} displayMode="readOnly" layoutMode="auto" autoLayout={layout} interactions={interactions} dragDropEnabled={dragDropEnabled} selectedCompanyIds={applied.companyIds} companyTopNodes={topNodes} employeePopup={popup} className="hm-orgchart-story-chart" onMove={result => { if (result.moved) setSession({ baseline: dataset, current: result.data }); }} onLifecycleError={cause => setError(cause instanceof Error ? cause.message : '조직도 설정을 적용할 수 없습니다.')} onStateChange={state => { if (state.status === 'error') setError(state.issues.map(issue => issue.message).join(' / ')); }} />
</div>
</div>
</StorySection>
</StoryPage>;
}