docs(org-chart): finalize expanded chart accessibility and usage

Document the shared Vanilla/React Auto API, company selection, styling ownership and preserved card design. Preserve P5-2/P5-3 and P5-4 implementation reports and their historical verification boundaries.
This commit is contained in:
shkim4 committed 2026-10-12 22:00:10 +09:00
1 parent 064517ec46
commit d2b76e7664
5 files changed
+482 -19

No files matched your search

+11 -4
View File
@@ -44,8 +44,15 @@ Named runtime export: `OrgChart`. Type exports: `OrgChartProps` and the Core's p
- Required `dataSource`: the same Core `OrgChartDataSource` interface, `load(options?: { signal?: AbortSignal }): Promise<unknown>`.
- Required `stylesheetUrls`: `{ engine: string; core: string }`, the exact Core asset contract.
- Optional `displayMode`: `'interactive'` (default) or `'readOnly'`, passed to the Core composition. Changing it recreates the Core handle.
- Optional `layoutMode`: `'fixed'` (default) or `'auto'`, independent of `displayMode`. Auto is the P5-1A initial-group preview; automatic recursive layout, collapse and Zoom/Pan remain deferred. Changing it recreates the same Core handle.
- Optional `companyId`: existing Expanded company preset ID (default `hanmac`). Changing it recreates the handle; Fixed ignores company colors. Unknown Auto IDs report a Core construction lifecycle error. All seven IDs and preview limits are documented in the [Core README](../org-chart/README.md#layout-boundary-p5-1a).
- Optional `layoutMode`: `'fixed'` (default) or `'auto'`, independent of `displayMode`. Auto renders company forests, collapse and Zoom/Pan/Fit. P5-4 retains the current Expanded card presentation by user decision; external SVG matching is no longer required. Changing mode recreates the Core handle.
See [Expanded usage and styling](../../docs/org-chart/expanded-usage.md) for company
selection, top nodes, JSON sources, popup ownership and Auto-only CSS examples.
Keyboard focus reveals offscreen controls at the current Zoom; group-title Hover
feedback and drag/keyboard activation are implemented in the shared Core.
- Optional `companyId`: legacy Auto fallback company preset (default `hanmac`). Explicit/inherited organization company identity takes priority; Fixed ignores company colors. Changing it recreates the handle. See [Core README](../org-chart/README.md#layout-boundary-p5-2--p5-3).
- Optional `selectedCompanyIds`: undefined selects all, [] selects none. Changes call Core selection on the existing instance, preserving per-company collapse state and source counts.
- Optional `companyTopNodes`, `employeeConnections`, `zoom`: immutable Core configuration maps/range. Identity changes recreate the handle; memoize these objects. Names, positions and profile overrides affect only Auto presentation, not callback data.
- Optional `organizationLinks`: existing organization-ID-to-URL map, applied only to original 1Depth titles. Missing/blank values retain plain titles. Core validates HTTP(S)/relative URLs and rejects invalid URLs, other schemes and credentials. Treat the map as immutable and memoize it; a new map recreates the handle.
- Optional `onEmployeeClick(employee, context)`: host-owned information UI, replacing the Core's built-in popup. `context` contains the existing `organization`, `affiliation`, focusable `trigger` card and `originalEvent`. It works in both modes and receives untouched Employee data.
- Optional `aggregationPolicy`: the Core's `ApprovedAggregationPolicy`.
@@ -79,7 +86,7 @@ Changing callback identity updates the latest committed callback without reload
Cleanup invalidates the wrapper generation, unsubscribes, calls Core's terminal `destroy()` and clears its handle reference. React Strict Mode's setup → cleanup → setup uses a fresh handle. Old generations cannot deliver state/lifecycle callbacks to the new instance; superseded operation rejection handlers are also ignored. Cleanup runs before replacement, leaving at most one active Core per wrapper container. The wrapper does not repeat engine disposal or DOM removal itself.
Core regeneration resets expansion/scroll state according to the existing Core contract. Source errors can recover by replacing the source; Core validation/summary/node behavior remains identical to Vanilla. Invalid runtime Props that prevent Core construction are lifecycle usage errors: fix them and remount the component (for example by changing its React key). No rendered fallback silently replaces an invalid configuration.
Auto retains valid organization collapse state on source/selection updates, fits reloads/selection and restores toggle focus. Fixed retains its previous regeneration policy. Source errors can recover by replacing the source; Core validation/summary/node behavior remains identical to Vanilla. Invalid runtime Props that prevent Core construction are lifecycle usage errors: fix them and remount the component (for example by changing its React key). No rendered fallback silently replaces an invalid configuration.
Committed callback publication, Core ownership and source updates use layout effects in that order. Cleanup/reload runs synchronously with React commit, so a pending old response cannot notify in a gap before passive cleanup. Server rendering produces only the outer container; SSR/hydration remains outside the verified scope.
@@ -94,4 +101,4 @@ npm run typecheck --workspace @hm-design/org-chart-react
npm run build --workspace @hm-design/org-chart-react
```
Storybook is one React host, not proof of every consumer deployment. This adapter does not add pan/zoom, advanced mobile reflow, additional relation overlays or reserved Core presentation sections. SSR/hydration, full screen reader behavior, complete heap/GC recovery, Theme-less rendering, Workdesk reference visual approval and production consumers require their own evidence. Public ESM import without a DOM does not establish SSR/hydration support. Consult the final integration report for the actual typecheck/build/browser/consumer results.
Storybook is one React host, not proof of every consumer deployment. The adapter delegates Auto Pan/Zoom to Core; it adds no alternate layout, additional relation overlays or API client. SSR/hydration, full screen reader behavior, physical touch, complete heap/GC recovery, Theme-less rendering, Workdesk reference visual approval and production consumers require their own evidence. Public ESM import without a DOM does not establish SSR/hydration support. Consult the final integration report for the actual typecheck/build/browser/consumer results.
+82 -15
View File
@@ -24,25 +24,61 @@ chart.destroy();
## Organization links and employee information (P3)
### Layout boundary (P5-1A)
### Layout boundary (P5-2 / P5-3)
`layoutMode?: 'fixed' | 'auto'` is independent of `displayMode`. The default
`'fixed'` keeps the existing Workdesk composition and its display-mode behavior.
`'auto'` currently selects the **P5-1A initial preview**, showing the representative
and immediate organization groups from the validated hierarchy. Descendants stay
in the dataset and statistics but are not placed in this preview. Automatic
recursive placement/recalculation/collision prevention belongs to P5-1B;
collapse controls and Zoom/Pan remain deferred. No preview readiness state claims
those later features are complete.
`'auto'` renders the complete validated hierarchy through dabeng 6.0.0.
Root and same-parent siblings remain in their real hierarchy; the engine allocates
recursive subtree widths. The Auto-only presenter reserves the tallest content
height at each depth and observes article resizing so variable staff counts and
font loading keep child rows and connectors aligned. Update/reload regenerate the
same layout and dispose old observers. Auto has a transformed forest, initial Fit,
5–300% configurable Zoom, Ctrl/Command wheel Zoom, pointer Pan and keyboard Pan.
Ordinary wheel scrolling remains with the page. Dialogs stay outside the forest.
Use `companyId` with Auto to select an existing company preset (default `hanmac`).
Set optional `Organization.companyId` on company roots; descendants inherit it.
Child company changes are rejected instead of mixing independent trees.
Legacy roots resolve from a known leader affiliation, then the `companyId` fallback
(default `hanmac`). `companyId` is no longer a global recoloring selector.
The seven IDs are `hanmac`, `saman`, `jangheon-industry`, `jangheon`, `ptc`, `halla`,
and `baron`. Main colors style only Expanded group headers; indexed secondary
and `baron`. Main colors style Expanded group headers and card accents; indexed secondary
variables come from that same preset. Fixed ignores this option and preserves
its organization gradients. Unknown Auto IDs reject construction with `TypeError`.
The preview reuses approved Workdesk card presentation, the same data/engine and
employee dialog; it has an independent wrapper without Fixed coordinates or scaling.
Choose `displayMode: 'readOnly'` for the matching read-only popup name policy.
The Auto presenter shares photo/position/name and employee dialog behavior without
Fixed SVG cards, coordinates or scaling. Group title DOM carries the organization
ID; the full title is a native toggle with aria-expanded and disabled empty groups.
Separate link icons preserve page navigation. Child collapse state survives parent
collapse and company reselection. Auto uses actual Employee names/positions;
three-character Korean names display with spaces; position whitespace is removed
only for display, preserving raw data. P5-4 retains the current Expanded cards
by user decision; the two external SVG references are no longer required.
Auto geometry variables live under
`.hm-orgchart-expanded`; there is no new public `layoutConfig` API.
The existing employee popup still uses its displayMode policy and receives raw data.
P5-4 adds group-title Hover feedback and reveals offscreen keyboard-focused cards
without changing Zoom. Drag click suppression does not block Enter/Space activation.
See [Expanded usage and styling](../../docs/org-chart/expanded-usage.md) for complete
Vanilla/React examples, Shadow DOM CSS ownership and verification boundaries.
`selectedCompanyIds` / `setSelectedCompanies(ids?)` filter the view: undefined
means all, [] means empty. Summary raw counts always describe the unmodified source;
the Auto selection label reports selected company/employee counts separately.
`getSelectedCompanies`, `zoomTo`, `panBy`, `fitToView`, `getViewportState` expose
view operations. Selection requires a mounted Auto handle; Fixed rejects it.
`companyTopNodes` maps company IDs to optional employeeId, title, name, profileImage,
organizationName and display (`card`, `titleOnly`, `hidden`). An explicit employee
must belong to that company's root; null removes top-card assignment. Overrides
affect presentation only, preserving employee IDs, popup data and parentId.
`employeeConnections` maps organization IDs to top/left/right staff routes (default
top). Leaders connect from their title above. SVG paths use actual article/card
coordinates; each endpoint shares its direction with the corresponding single-side
border accent. Employee preset follows its known affiliation, otherwise its tree.
All remaining borders are neutral; an inset accent width variable preserves size.
Width/height/padding/radius/photo/font/spacing variables are scoped to Auto.
```js
const chart = createOrgChart({
@@ -50,12 +86,43 @@ const chart = createOrgChart({
layoutMode: 'auto',
displayMode: 'readOnly',
companyId: 'hanmac',
selectedCompanyIds: ['hanmac', 'saman'],
companyTopNodes: { hanmac: { title: '회장', display: 'card' } },
employeeConnections: { 'hanmac-office-0': 'left' },
});
```
Options are captured at construction: create a new handle to change the layout or
company. Standalone Tree/Summary factories keep their existing rendering paths.
company/top-node/connection/zoom configuration. Selection uses its own setter.
Standalone Tree/Summary factories keep their existing rendering paths.
`examples/org-chart/data-expanded-{small,medium,large}.json` contain exactly
20/100/300 unique virtual employees and 3/5/7 companies. Run
`node examples/org-chart/create-expanded-fixtures.mjs` to reproduce them.
After build/prepare, open `http://127.0.0.1:4178/expanded.html`.
Expanded OrgChart is one of the same four public Stories; it offers fixture and
company controls without filtering JSON in the Story. Native Core controls are
the explicit framework-independent HTML adapter, not imitations of HM React UI.
### Historical P5-1B verification and local runtime
Core/React builds and Typechecks pass. Focused browser evidence covers the
complete four-depth hierarchy, unequal employee counts, updates/reload, all seven
company presets, shared HTML/React cards and popup focus, viewport overflow, and
minimal Fixed baseline regression. Evidence is generated under
`test-results/org-chart-p5-1b`; the authored runner is
`examples/org-chart/verify-p5-1b.mjs`. Its baseline must be copied from a known
pre-change build before rebuilding. The runner uses configurable
`ORGCHART_STORY_ORIGIN`, `ORGCHART_PLAYWRIGHT_MODULE`, and `ORGCHART_CHROME`.
Do not assume another PC's localhost or generated dist exists.
Use npm with `package-lock.json`; a fresh install uses `npm ci`. The existing
package test runner imports Node's `globSync`, so use a runtime providing that API, such as the verified Node 24,
for focused unit tests. This PC's Node 20.20.1 built the packages successfully;
the installed Codex Node 24.19.0 ran the unit tests without changing the runner.
Final reference SVG design, collapse/Zoom/Pan, real screen-reader speech/touch and
historical full regression suites are not verified by this phase.
### P3.2 follow-up: representative badges
@@ -93,7 +160,7 @@ Omit `onEmployeeClick` to use the default popup. Vanilla options are captured at
`mount(container)` also accepts the container at mount time. Constructing a handle and importing the ESM facade require no DOM. Mount requires a connected HTMLElement. One handle owns one container, preserving host siblings. Duplicate mount and update/reload before mount or after destroy reject with a usage error. Data/Source failures become structured `error` states and resolve the operation. Destroy is synchronous, idempotent and terminal; use a new handle to mount again. `subscribe(listener)` returns an unsubscribe function; `getState()` returns the immutable current state. Consumer callback errors do not break the Core.
`update` captures its input immediately and preserves the current Source. `reload(source?)` optionally replaces it. The last started operation wins; earlier requests are aborted, and stale responses cannot commit. Call completion means the operation was applied, superseded, or produced a controlled error, rather than that every image/font finished loading. Regeneration resets expand/scroll state; removed keyboard focus moves to the scroll region.
`update` captures its input immediately and preserves the current Source. `reload(source?)` optionally replaces it. The last started operation wins; earlier requests are aborted, and stale responses cannot commit. Call completion means the operation was applied, superseded, or produced a controlled error, rather than that every image/font finished loading. Fixed keeps its prior regeneration policy. Auto preserves valid organization collapse IDs and transform state on toggles; reload/selection fits the new visible forest. Removed toggle focus is restored to the same organization, with viewport fallback.
## Data contract
@@ -130,4 +197,4 @@ Open `http://127.0.0.1:4178/index.html` for bundled ESM + external JSON. Open `e
`npm run test:org-chart-browser` expects Playwright supplied by the verification environment. If not installed locally, set `ORGCHART_PLAYWRIGHT_MODULE` to its absolute `index.mjs`/`index.js` and optionally `ORGCHART_CHROME` to a Chrome executable. Production has no browser-test dependency. Evidence is written under `test-results/org-chart-browser/`.
The React wrapper owns only ref/effect lifecycle, source/props updates and cleanup, including forwarding the additive P3 lookup options; HTML and React render the same Core. Standalone `createOrgChartTree`, `createPositionSummary`, `createAffiliationSummary` and `createStatusSummary` factories are exported at the package root and return the existing `OrgChartHandle`. The three public OrgChart Stories are Logo · Personnel Summary, Department Colors and Full Composition. Original verification Stories and independent component Stories remain available under the excluded `internal` tag.
The React wrapper owns only ref/effect lifecycle, source/props updates and cleanup, including forwarding lookup and Auto view options; HTML and React render the same Core. Standalone `createOrgChartTree`, `createPositionSummary`, `createAffiliationSummary` and `createStatusSummary` factories are exported at the package root and return the existing `OrgChartHandle`. The four public OrgChart Stories are Logo · Personnel Summary, Department Colors, Full Composition and Expanded OrgChart. Original verification Stories and independent component Stories remain available under the excluded `internal` tag.