import { StrictMode, useLayoutEffect, useMemo, useRef, useState } from 'react'; import type { Meta, StoryObj } from '@storybook/react-vite'; import { OrgChart } from '@hm-design/org-chart-react/hm-dialog'; import { companyColorPresets, createOrgChartExampleDataset, JsonOrgChartDataSource, type CompanyId, type OrgChartAutoLayoutOptions, type OrgChartDataset, type OrgChartInteractionOptions, } from '@hm-design/org-chart'; import engineUrl from '@hm-design/org-chart/engine.css?url'; import coreUrl from '@hm-design/org-chart/style.css?url'; import { StoryPage, StoryPageHeader } from '@/components/story-page'; import large from '../../examples/org-chart/data-expanded-large.json'; import './org-chart-stories.css'; import '../center/center-stories.css'; import './org-chart-expanded-story.css'; const template = large as OrgChartDataset; const allCompanies = Object.values(companyColorPresets).map(company => company.companyId as CompanyId); const compositionStylesheets = { engine: engineUrl, core: coreUrl }; const topNodes = { ptc: { title: '기술총괄', name: '가상책임자 5' } }; // Preview only: fixed sample (7 companies × 20 = 140) with the former default settings. const layout: OrgChartAutoLayoutOptions = { type: 'tb', hybridStartDepth: 2, initialVisibleDepth: 'all' }; const interactions: OrgChartInteractionOptions = { collapse: true, zoom: true, pan: true }; // Story-only: hides Core's explanatory toolbar text (as-of date, selection count, Drag & Drop guide) on screen. // The elements stay in the shadow DOM: the move feedback remains the cards' aria-describedby / live status // (visually hidden), and the OrgChart browser checks still read their text. const previewText = new CSSStyleSheet(); previewText.replaceSync(` .hm-orgchart-date, .hm-orgchart-expanded-selection { display: none; } .hm-orgchart-move-feedback { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; } `); function hidePreviewText(container: HTMLElement): () => void { const adopt = () => { const shadow = container.querySelector('.hm-orgchart-host')?.shadowRoot; if (shadow && !shadow.adoptedStyleSheets.includes(previewText)) shadow.adoptedStyleSheets = [...shadow.adoptedStyleSheets, previewText]; }; const observer = new MutationObserver(adopt); observer.observe(container, { childList: true, subtree: true }); adopt(); return () => observer.disconnect(); } /** Existing Expanded Story only: a chart preview without setting panels. */ function ExpandedPreview() { const [error, setError] = useState(null); const preview = useRef(null); useLayoutEffect(() => hidePreviewText(preview.current!), []); const source = useMemo(() => new JsonOrgChartDataSource(createOrgChartExampleDataset(template, { scope: 'per-company', employeeCount: 20, companyIds: allCompanies, })), []); return {/* Preview first: the chart sits right under the page title; its own header already names it, so no section header. */}
{error ?

{error}

: null}
setError(cause instanceof Error ? cause.message : '조직도 설정을 적용할 수 없습니다.')} onStateChange={state => { if (state.status === 'error') setError(state.issues.map(issue => issue.message).join(' / ')); }} />
; } const meta = { title: '조직도/확장 조직도', component: ExpandedPreview, parameters: { layout: 'fullscreen', controls: { disable: true } }, decorators: [(Story) => ] } satisfies Meta; export default meta; type Story = StoryObj; export const ExpandedOrgChart: Story = { name: '확장 조직도', parameters: { __id: 'orgchart--expanded-org-chart' } };