feat(org-chart): implement expandable layout and multi-company navigation
Integrate P5-1B through P5-4 shared Core layout, collapse, zoom/pan/fit, company roots and keyboard accessibility. Include React/HTML examples, virtual 20/100/300 employee fixtures, focused checks and the additive data contract.
This commit is contained in:
1 parent
a92913d6bc
commit
064517ec46
30 files changed
+7532
-183
No files matched your search
@@ -5,6 +5,8 @@ import { applyOrganizationStyle, organizationStylePresets } from './style-preset
|
||||
import { getDepartmentCardAsset } from './department-card-assets.js';
|
||||
import type { OrgChartOrganizationLinks } from './types.js';
|
||||
import type { CompanyColorPreset } from '../company-color-presets.js';
|
||||
import { decorateExpandedNode } from './expanded-content.js';
|
||||
import type { OrgChartConnectionDirection, OrgChartTopNode } from './types.js';
|
||||
|
||||
const organizationNames = { root: '최상위 조직', division: '부문', office: '실', div: 'Div', cell: '셀', team: '팀' } as const;
|
||||
|
||||
@@ -19,6 +21,11 @@ export interface RenderContext {
|
||||
organizationLinks?: OrgChartOrganizationLinks;
|
||||
/** Only the Expanded presenter supplies company header colors. */
|
||||
expandedCompanyPreset?: CompanyColorPreset;
|
||||
organizationCompanies?: ReadonlyMap<string, string>;
|
||||
collapsedOrganizations?: ReadonlySet<string>;
|
||||
companyTopNodes?: Readonly<Record<string, OrgChartTopNode>>;
|
||||
employeeConnections?: Readonly<Record<string, OrgChartConnectionDirection>>;
|
||||
toggleExpanded?: (organizationId: string) => void;
|
||||
}
|
||||
|
||||
export function engineTree(roots: OrganizationTreeNode[], prefix: string, context: RenderContext, startDepth = 0): RenderEngineNode[] {
|
||||
@@ -28,7 +35,7 @@ export function engineTree(roots: OrganizationTreeNode[], prefix: string, contex
|
||||
context.orderedOrganizations.push(tree.organization);
|
||||
return {
|
||||
id: `${prefix}-org-${index}`, name: '', organizationIndex: index, depth, groupVariant: variant,
|
||||
...(tree.children.length ? { children: tree.children.map((child, childIndex) => convert(child, depth + 1, context.readOnly ? variant : depth === startDepth ? childIndex % 6 : variant)) } : {}),
|
||||
...(tree.children.length && !context.collapsedOrganizations?.has(tree.organization.id) ? { children: tree.children.map((child, childIndex) => convert(child, depth + 1, context.readOnly ? variant : depth === startDepth ? childIndex % 6 : variant)) } : {}),
|
||||
};
|
||||
}
|
||||
// Multiple actual roots stay independent; no fictitious organizational parent.
|
||||
@@ -48,6 +55,10 @@ export function decorateNode(
|
||||
): void {
|
||||
const organization = context.orderedOrganizations[Number(value.organizationIndex)];
|
||||
if (!organization) return;
|
||||
if (context.expandedCompanyPreset) {
|
||||
decorateExpandedNode(node, value, context, signal);
|
||||
return;
|
||||
}
|
||||
const document = node.ownerDocument;
|
||||
const card = node.querySelector('.hm-orgchart-organization')!;
|
||||
node.dataset.organizationId = organization.id;
|
||||
@@ -64,14 +75,6 @@ export function decorateNode(
|
||||
}
|
||||
node.dataset.organizationDepth = String(organizationDepth);
|
||||
applyOrganizationStyle(node, Number(value.groupVariant));
|
||||
if (context.expandedCompanyPreset) {
|
||||
const preset = context.expandedCompanyPreset;
|
||||
node.dataset.companyId = preset.companyId;
|
||||
node.style.setProperty('--hm-orgchart-current-gradient', preset.primary);
|
||||
node.style.setProperty('--hm-orgchart-expanded-primary', preset.primary);
|
||||
// Preserve every existing secondary value for the later Expanded theme.
|
||||
preset.secondary.forEach((color, index) => node.style.setProperty(`--hm-orgchart-expanded-secondary-${index + 1}`, color));
|
||||
}
|
||||
node.dataset.organizationType = organization.type;
|
||||
// Header role is styling-only: depth 0-1 are organization titles, deeper nodes are cell/team headers.
|
||||
node.dataset.headerRole = (context.readOnly ? organizationDepth : Number(value.depth)) <= 1 ? 'organization' : 'group';
|
||||
|
||||
Reference in new issue
Block a user