UNPKG

primeng

Version:

PrimeNG is a premium UI library for Angular featuring a rich set of 90+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeBlock,

832 lines (824 loc) 43.5 kB
export * from 'primeng/types/organizationchart'; import * as i0 from '@angular/core'; import { InjectionToken, Injectable, input, booleanAttribute, inject, computed, ChangeDetectionStrategy, ViewEncapsulation, Component, model, output, contentChild, effect, untracked, NgModule } from '@angular/core'; import { BaseComponent, PARENT_INSTANCE } from 'primeng/basecomponent'; import * as i1$1 from 'primeng/bind'; import { BindModule, Bind } from 'primeng/bind'; import { NgTemplateOutlet } from '@angular/common'; import * as i1 from '@angular/forms'; import { FormsModule } from '@angular/forms'; import { Checkbox } from 'primeng/checkbox'; import { ChevronDown } from '@primeicons/angular/chevron-down'; import { ChevronUp } from '@primeicons/angular/chevron-up'; import { style } from '@primeuix/styles/organizationchart'; import { BaseStyle } from 'primeng/base'; const ORGANIZATIONCHART_INSTANCE = new InjectionToken('ORGANIZATIONCHART_INSTANCE'); const extendedStyle = /*css*/ ` ${style} /* For PrimeNG */ .p-organizationchart-node-content { gap: 0.5rem; } `; const classes = { root: 'p-organizationchart p-component', subtree: ({ root }) => ['p-organizationchart-subtree', { 'p-organizationchart-subtree-root': root }], tree: 'p-organizationchart-tree', node: 'p-organizationchart-node', nodeContent: 'p-organizationchart-node-content', label: 'p-organizationchart-node-label', collapseButton: 'p-organizationchart-node-toggle-button', collapseButtonIcon: 'p-organizationchart-node-toggle-button-icon' }; class OrganizationChartStyle extends BaseStyle { name = 'organizationchart'; style = extendedStyle; classes = classes; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: OrganizationChartStyle, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: OrganizationChartStyle }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: OrganizationChartStyle, decorators: [{ type: Injectable }] }); /** * * OrganizationChart visualizes hierarchical organization data. * * [Live Demo](https://www.primeng.org/organizationchart) * * @module organizationchartstyle * */ var OrganizationChartClasses; (function (OrganizationChartClasses) { /** * Class name of the root element */ OrganizationChartClasses["root"] = "p-organizationchart"; /** * Class name of the subtree element */ OrganizationChartClasses["subtree"] = "p-organizationchart-subtree"; /** * Class name of the tree element */ OrganizationChartClasses["tree"] = "p-organizationchart-tree"; /** * Class name of the node element */ OrganizationChartClasses["node"] = "p-organizationchart-node"; /** * Class name of the node content element */ OrganizationChartClasses["nodeContent"] = "p-organizationchart-node-content"; /** * Class name of the node label element */ OrganizationChartClasses["label"] = "p-organizationchart-node-label"; /** * Class name of the collapse button element */ OrganizationChartClasses["collapseButton"] = "p-organizationchart-node-toggle-button"; /** * Class name of the collapse button icon element */ OrganizationChartClasses["collapseButtonIcon"] = "p-organizationchart-node-toggle-button-icon"; })(OrganizationChartClasses || (OrganizationChartClasses = {})); class OrganizationChartNode extends BaseComponent { node = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "node" }] : /* istanbul ignore next */ [])); root = input(undefined, { ...(ngDevMode ? { debugName: "root" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); level = input(1, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "level" }] : /* istanbul ignore next */ [])); chart = inject(ORGANIZATIONCHART_INSTANCE); _componentStyle = inject(OrganizationChartStyle); children = computed(() => this.node()?.children ?? [], /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "children" }] : /* istanbul ignore next */ [])); hasChildren = computed(() => this.children().length > 0, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "hasChildren" }] : /* istanbul ignore next */ [])); toggleNodeFn = this.toggleNode.bind(this); isSelectable = computed(() => { if (!this.chart.selectionMode()) return false; const flag = this.node()?.selectable; if (flag === false) return false; if (flag === true) return true; return !!this.chart.selectable(); }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "isSelectable" }] : /* istanbul ignore next */ [])); isCollapsible = computed(() => { if (!this.hasChildren()) return false; const flag = this.node()?.collapsible; if (flag === false) return false; if (flag === true) return true; return !!this.chart.collapsible(); }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "isCollapsible" }] : /* istanbul ignore next */ [])); checkboxMode = computed(() => this.chart.selectionMode() === 'checkbox', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "checkboxMode" }] : /* istanbul ignore next */ [])); selected = computed(() => this.chart.isSelected(this.node()), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ [])); partialSelected = computed(() => this.chart.isPartialSelected(this.node()), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "partialSelected" }] : /* istanbul ignore next */ [])); collapsed = computed(() => this.isCollapsible() && this.chart.isCollapsed(this.node()), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ [])); dataSelectable = computed(() => this.isSelectable() || null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "dataSelectable" }] : /* istanbul ignore next */ [])); dataSelected = computed(() => this.selected() || null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "dataSelected" }] : /* istanbul ignore next */ [])); dataPartialSelected = computed(() => this.partialSelected() || null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "dataPartialSelected" }] : /* istanbul ignore next */ [])); dataCollapsible = computed(() => this.isCollapsible() || null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "dataCollapsible" }] : /* istanbul ignore next */ [])); dataCollapsed = computed(() => this.collapsed() || null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "dataCollapsed" }] : /* istanbul ignore next */ [])); nodeTabIndex = computed(() => (this.isSelectable() ? 0 : -1), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "nodeTabIndex" }] : /* istanbul ignore next */ [])); toggleButtonAriaLabel = computed(() => { const aria = this.config?.translation?.aria; return this.collapsed() ? (aria?.expand ?? 'Expand') : (aria?.collapse ?? 'Collapse'); }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "toggleButtonAriaLabel" }] : /* istanbul ignore next */ [])); getCollapseButtonContext() { return { $implicit: this.node(), expanded: !this.collapsed(), collapsed: this.collapsed(), childCount: this.children().length, toggle: this.toggleNodeFn }; } getPTOptions(key) { return this.ptm(key, { context: { expanded: !this.collapsed(), selectable: this.isSelectable(), selected: this.selected(), toggleable: this.isCollapsible(), collapsed: this.collapsed(), active: this.selected() } }); } onNodeClick(event, node) { if (!this.isSelectable()) { return; } this.chart.onNodeClick(event, node); } onNodeKeyDown(event, node) { if (!this.isSelectable()) { return; } event.preventDefault(); this.chart.onNodeClick(event, node); } toggleNode(event, node) { this.chart.onNodeToggle(event, node); event.preventDefault(); event.stopPropagation(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: OrganizationChartNode, deps: null, target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: OrganizationChartNode, isStandalone: true, selector: "[pOrganizationChartNode]", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: false, transformFunction: null }, root: { classPropertyName: "root", publicName: "root", isSignal: true, isRequired: false, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null } }, providers: [OrganizationChartStyle, { provide: PARENT_INSTANCE, useExisting: OrganizationChartNode }], usesInheritance: true, ngImport: i0, template: ` @if (node()) { <div [class]="cn(cx('node'), node()!.styleClass)" [style]="node()!.style" [attr.data-selectable]="dataSelectable()" [attr.data-selected]="dataSelected()" [attr.data-partial-selected]="dataPartialSelected()" [attr.data-collapsible]="dataCollapsible()" [attr.data-collapsed]="dataCollapsed()" [attr.tabindex]="nodeTabIndex()" (click)="onNodeClick($event, node()!)" (keydown.enter)="onNodeKeyDown($event, node()!)" (keydown.space)="onNodeKeyDown($event, node()!)" [pBind]="getPTOptions('node')" > <div [class]="cx('nodeContent')" [pBind]="ptm('nodeContent')"> @if (checkboxMode()) { <p-checkbox [binary]="true" [ngModel]="selected()" [indeterminate]="partialSelected()" size="small" [tabindex]="-1" [readonly]="true" [unstyled]="unstyled()" [pt]="ptm('pcCheckbox')" [attr.data-p-partialchecked]="partialSelected()" > @if (chart.checkboxIconTemplate()) { <ng-template #icon let-checked> <ng-container *ngTemplateOutlet="chart.checkboxIconTemplate()!; context: { $implicit: checked, partialChecked: partialSelected() }"></ng-container> </ng-template> } </p-checkbox> } @if (!chart.getTemplateForNode(node()!)) { <span [class]="cx('label')" [pBind]="ptm('label')">{{ node()!.label }}</span> } @else { <ng-container *ngTemplateOutlet="chart.getTemplateForNode(node()!); context: { $implicit: node() }"></ng-container> } </div> @if (isCollapsible()) { @if (chart.collapseButtonTemplate()) { <ng-container *ngTemplateOutlet="chart.collapseButtonTemplate()!; context: getCollapseButtonContext()"></ng-container> } @else { <button type="button" [class]="cx('collapseButton')" [attr.aria-expanded]="!collapsed()" [attr.aria-label]="toggleButtonAriaLabel()" (click)="toggleNode($event, node()!)" (keydown.enter)="toggleNode($event, node()!)" (keydown.space)="toggleNode($event, node()!)" [pBind]="getPTOptions('collapseButton')" > <span [class]="cx('collapseButtonIcon')" [pBind]="ptm('collapseButtonIcon')"> @if (!chart.togglerIconTemplate()) { @if (collapsed()) { <svg data-p-icon="chevron-down" /> } @else { <svg data-p-icon="chevron-up" /> } } @else { <ng-template *ngTemplateOutlet="chart.togglerIconTemplate()!; context: { $implicit: !collapsed() }"></ng-template> } </span> </button> } } </div> @if (hasChildren() && !collapsed()) { <ul [class]="cx('subtree')" role="group" [pBind]="ptm('subtree')"> @for (child of children(); track child.key ?? $index) { <li [class]="cx('tree')" role="treeitem" [attr.data-level]="level() + 1" [attr.aria-level]="level() + 1" [attr.aria-expanded]="chart.getAriaExpanded(child)" [attr.aria-selected]="chart.getAriaSelected(child)" pOrganizationChartNode [node]="child" [level]="level() + 1" [unstyled]="unstyled()" [pt]="pt" [pBind]="ptm('tree')" ></li> } </ul> } } `, isInline: true, dependencies: [{ kind: "component", type: OrganizationChartNode, selector: "[pOrganizationChartNode]", inputs: ["node", "root", "level"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: Checkbox, selector: "p-checkbox, p-check-box", inputs: ["value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "component", type: ChevronDown, selector: "svg[data-p-icon=\"chevron-down\"]" }, { kind: "component", type: ChevronUp, selector: "svg[data-p-icon=\"chevron-up\"]" }, { kind: "ngmodule", type: BindModule }, { kind: "directive", type: i1$1.Bind, selector: "[pBind]", inputs: ["pBind"] }], changeDetection: i0.ChangeDetectionStrategy.Eager, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: OrganizationChartNode, decorators: [{ type: Component, args: [{ selector: '[pOrganizationChartNode]', standalone: true, imports: [NgTemplateOutlet, FormsModule, Checkbox, ChevronDown, ChevronUp, BindModule], template: ` @if (node()) { <div [class]="cn(cx('node'), node()!.styleClass)" [style]="node()!.style" [attr.data-selectable]="dataSelectable()" [attr.data-selected]="dataSelected()" [attr.data-partial-selected]="dataPartialSelected()" [attr.data-collapsible]="dataCollapsible()" [attr.data-collapsed]="dataCollapsed()" [attr.tabindex]="nodeTabIndex()" (click)="onNodeClick($event, node()!)" (keydown.enter)="onNodeKeyDown($event, node()!)" (keydown.space)="onNodeKeyDown($event, node()!)" [pBind]="getPTOptions('node')" > <div [class]="cx('nodeContent')" [pBind]="ptm('nodeContent')"> @if (checkboxMode()) { <p-checkbox [binary]="true" [ngModel]="selected()" [indeterminate]="partialSelected()" size="small" [tabindex]="-1" [readonly]="true" [unstyled]="unstyled()" [pt]="ptm('pcCheckbox')" [attr.data-p-partialchecked]="partialSelected()" > @if (chart.checkboxIconTemplate()) { <ng-template #icon let-checked> <ng-container *ngTemplateOutlet="chart.checkboxIconTemplate()!; context: { $implicit: checked, partialChecked: partialSelected() }"></ng-container> </ng-template> } </p-checkbox> } @if (!chart.getTemplateForNode(node()!)) { <span [class]="cx('label')" [pBind]="ptm('label')">{{ node()!.label }}</span> } @else { <ng-container *ngTemplateOutlet="chart.getTemplateForNode(node()!); context: { $implicit: node() }"></ng-container> } </div> @if (isCollapsible()) { @if (chart.collapseButtonTemplate()) { <ng-container *ngTemplateOutlet="chart.collapseButtonTemplate()!; context: getCollapseButtonContext()"></ng-container> } @else { <button type="button" [class]="cx('collapseButton')" [attr.aria-expanded]="!collapsed()" [attr.aria-label]="toggleButtonAriaLabel()" (click)="toggleNode($event, node()!)" (keydown.enter)="toggleNode($event, node()!)" (keydown.space)="toggleNode($event, node()!)" [pBind]="getPTOptions('collapseButton')" > <span [class]="cx('collapseButtonIcon')" [pBind]="ptm('collapseButtonIcon')"> @if (!chart.togglerIconTemplate()) { @if (collapsed()) { <svg data-p-icon="chevron-down" /> } @else { <svg data-p-icon="chevron-up" /> } } @else { <ng-template *ngTemplateOutlet="chart.togglerIconTemplate()!; context: { $implicit: !collapsed() }"></ng-template> } </span> </button> } } </div> @if (hasChildren() && !collapsed()) { <ul [class]="cx('subtree')" role="group" [pBind]="ptm('subtree')"> @for (child of children(); track child.key ?? $index) { <li [class]="cx('tree')" role="treeitem" [attr.data-level]="level() + 1" [attr.aria-level]="level() + 1" [attr.aria-expanded]="chart.getAriaExpanded(child)" [attr.aria-selected]="chart.getAriaSelected(child)" pOrganizationChartNode [node]="child" [level]="level() + 1" [unstyled]="unstyled()" [pt]="pt" [pBind]="ptm('tree')" ></li> } </ul> } } `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, providers: [OrganizationChartStyle, { provide: PARENT_INSTANCE, useExisting: OrganizationChartNode }] }] }], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: false }] }], root: [{ type: i0.Input, args: [{ isSignal: true, alias: "root", required: false }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }] } }); /** * OrganizationChart visualizes hierarchical organization data. * @group Components */ class OrganizationChart extends BaseComponent { componentName = 'OrganizationChart'; /** * An array of nested OrgChartNodes. * @group Props */ value = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ [])); /** * Defines the selection mode. * @group Props */ selectionMode = input(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "selectionMode" }] : /* istanbul ignore next */ [])); /** * Whether the nodes can be expanded or toggled. * @defaultValue false * @group Props */ collapsible = input(false, { ...(ngDevMode ? { debugName: "collapsible" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Whether the nodes can be selected when a `selectionMode` is defined. Can be overridden per node with `OrgChartNode.selectable`. * @defaultValue true * @group Props */ selectable = input(true, { ...(ngDevMode ? { debugName: "selectable" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Defines the gap between nodes. Can be a single number or a tuple [gapX, gapY]. * @group Props */ gap = input(40, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "gap" }] : /* istanbul ignore next */ [])); /** * A map of node keys whose values are `true` for the selected nodes. Two-way bindable. * When omitted, it is seeded from each node's `selectedByDefault` flag. * @group Props */ selectionKeys = model(null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "selectionKeys" }] : /* istanbul ignore next */ [])); /** * A map of node keys whose values are `true` for the collapsed nodes. Two-way bindable. * When omitted, it is seeded from each node's `collapsedByDefault` flag. * @group Props */ collapsedKeys = model(null, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "collapsedKeys" }] : /* istanbul ignore next */ [])); /** * Callback to invoke when a node is selected. * @param {OrganizationChartNodeSelectEvent} event - custom node select event. * @group Emits */ onNodeSelect = output(); /** * Callback to invoke when a node is unselected. * @param {OrganizationChartNodeUnSelectEvent} event - custom node unselect event. * @group Emits */ onNodeUnselect = output(); /** * Callback to invoke when a node is expanded. * @param {OrganizationChartNodeExpandEvent} event - custom node expand event. * @group Emits */ onNodeExpand = output(); /** * Callback to invoke when a node is collapsed. * @param {OrganizationChartNodeCollapseEvent} event - custom node collapse event. * @group Emits */ onNodeCollapse = output(); /** * Custom toggler icon template. * @param {Object} context - item data. * @group Templates */ togglerIconTemplate = contentChild('togglericon', { ...(ngDevMode ? { debugName: "togglerIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom collapse button template. * @param {Object} context - collapse button data. * @group Templates */ collapseButtonTemplate = contentChild('collapsebutton', { ...(ngDevMode ? { debugName: "collapseButtonTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom checkbox icon template for `checkbox` selection mode. * @param {Object} context - checkbox icon data. * @group Templates */ checkboxIconTemplate = contentChild('checkboxicon', { ...(ngDevMode ? { debugName: "checkboxIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * Custom node template. * @group Templates */ nodeTemplate = contentChild('node', { ...(ngDevMode ? { debugName: "nodeTemplate" } : /* istanbul ignore next */ {}), descendants: false }); _componentStyle = inject(OrganizationChartStyle); bindDirectiveInstance = inject(Bind, { self: true }); $pcOrganizationChart = inject(ORGANIZATIONCHART_INSTANCE, { optional: true, skipSelf: true }) ?? undefined; /** * The active selection map, normalized so consumers never deal with `null`. */ _selectionKeys = computed(() => this.selectionKeys() ?? {}, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "_selectionKeys" }] : /* istanbul ignore next */ [])); /** * The active collapsed map, normalized so consumers never deal with `null`. */ _collapsedKeys = computed(() => this.collapsedKeys() ?? {}, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "_collapsedKeys" }] : /* istanbul ignore next */ [])); constructor() { super(); effect(() => { const value = this.value(); if (!value || !value.length) { return; } // Seed the key maps from the deprecated node defaults; reads of the key signals are untracked // so the effect only re-runs on value changes (and never loops when seeding writes the maps). untracked(() => this.syncDefaultKeyState(value)); }); } ngAfterViewChecked() { this.bindDirectiveInstance.setAttrs(this.ptms(['host', 'root'])); } root = computed(() => { const value = this.value(); return value && value.length ? value[0] : null; }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "root" }] : /* istanbul ignore next */ [])); gapX = computed(() => { const g = this.gap(); return Array.isArray(g) ? g[0] : g; }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "gapX" }] : /* istanbul ignore next */ [])); gapY = computed(() => { const g = this.gap(); return Array.isArray(g) ? (g.length > 1 ? g[1] : g[0]) : g; }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "gapY" }] : /* istanbul ignore next */ [])); getTemplateForNode(_node) { return this.nodeTemplate() ?? null; } isSelected(node) { const key = node?.key; if (key == null) { return false; } const value = this._selectionKeys()[key]; if (this.selectionMode() === 'checkbox') { return value?.checked === true; } return value === true; } isPartialSelected(node) { if (this.selectionMode() !== 'checkbox') { return false; } const key = node?.key; if (key == null) { return false; } return this._selectionKeys()[key]?.partialChecked === true; } isCollapsed(node) { const key = node?.key; return key != null && this._collapsedKeys()[key] === true; } getAriaExpanded(node) { return node.children && node.children.length > 0 ? !this.isCollapsed(node) : undefined; } getAriaSelected(node) { return this.selectionMode() ? this.isSelected(node) : undefined; } onNodeClick(event, node) { const selectionMode = this.selectionMode(); if (!selectionMode || node.key == null) { return; } const selectable = node.selectable === true || (node.selectable !== false && this.selectable()); if (!selectable) { return; } if (selectionMode === 'checkbox') { this.onCheckboxNodeClick(event, node); return; } const key = node.key; const current = this._selectionKeys(); const selected = current[key] === true; let next; if (selected) { next = selectionMode === 'single' ? {} : { ...current }; if (selectionMode !== 'single') { delete next[key]; } this.onNodeUnselect.emit({ originalEvent: event, node }); } else { next = selectionMode === 'single' ? {} : { ...current }; next[key] = true; this.onNodeSelect.emit({ originalEvent: event, node }); } this.selectionKeys.set(next); } onCheckboxNodeClick(event, node) { const key = node.key; const next = { ...this._selectionKeys() }; const selecting = next[key]?.checked !== true; const descendantKeys = [key, ...this.getDescendantKeys(node)]; for (const descendantKey of descendantKeys) { if (selecting) { next[descendantKey] = { checked: true, partialChecked: false }; } else { delete next[descendantKey]; } } const ancestorKeys = this.getAncestorKeys(key) ?? []; for (const ancestorKey of [...ancestorKeys].reverse()) { const ancestor = this.findNodeByKey(ancestorKey); const childKeys = ancestor?.children?.map((child) => child.key) ?? []; const allChecked = childKeys.length > 0 && childKeys.every((childKey) => next[childKey]?.checked === true); const someChecked = childKeys.some((childKey) => { const value = next[childKey]; return value?.checked === true || value?.partialChecked === true; }); if (allChecked) { next[ancestorKey] = { checked: true, partialChecked: false }; } else if (someChecked) { next[ancestorKey] = { checked: false, partialChecked: true }; } else { delete next[ancestorKey]; } } this.selectionKeys.set(next); if (selecting) { this.onNodeSelect.emit({ originalEvent: event, node }); } else { this.onNodeUnselect.emit({ originalEvent: event, node }); } } findNodeByKey(key, nodes = this.value()) { if (!nodes) { return null; } for (const node of nodes) { if (node.key === key) { return node; } const match = node.children ? this.findNodeByKey(key, node.children) : null; if (match) { return match; } } return null; } getDescendantKeys(node) { return (node.children ?? []).flatMap((child) => [child.key, ...this.getDescendantKeys(child)]); } getAncestorKeys(key, nodes = this.value(), trail = []) { if (!nodes) { return null; } for (const node of nodes) { if (node.key === key) { return trail; } const path = node.children ? this.getAncestorKeys(key, node.children, [...trail, node.key]) : null; if (path) { return path; } } return null; } onNodeToggle(event, node) { if (node.key == null) { return; } const key = node.key; const next = { ...this._collapsedKeys() }; if (next[key]) { delete next[key]; this.onNodeExpand.emit({ originalEvent: event, node }); } else { next[key] = true; this.onNodeCollapse.emit({ originalEvent: event, node }); } this.collapsedKeys.set(next); } syncDefaultKeyState(value) { const nodes = this.flattenNodes(value); if (this.collapsedKeys() == null) { const seeded = this.resolveCollapsedKeys(nodes); if (!this.isSameKeyState(this._collapsedKeys(), seeded)) { this.collapsedKeys.set(seeded); } } if (this.selectionKeys() == null) { const seeded = this.resolveSelectionKeys(nodes); if (!this.isSameKeyState(this._selectionKeys(), seeded)) { this.selectionKeys.set(seeded); } } } flattenNodes(nodes) { const result = []; const walk = (list) => { if (!list) return; for (const node of list) { result.push(node); if (node.children?.length) { walk(node.children); } } }; walk(nodes); return result; } resolveCollapsedKeys(nodes) { const seeded = {}; const chartCollapsible = this.collapsible(); for (const node of nodes) { if (!node.collapsedByDefault || node.key == null) continue; const hasChildren = !!node.children?.length; const collapsible = node.collapsible === true || (node.collapsible !== false && chartCollapsible); if (hasChildren && collapsible) { seeded[node.key] = true; } } return seeded; } resolveSelectionKeys(nodes) { const seeded = {}; const chartSelectable = this.selectable(); const single = this.selectionMode() === 'single'; const checkbox = this.selectionMode() === 'checkbox'; for (const node of nodes) { if (!node.selectedByDefault || node.key == null) continue; const selectable = node.selectable === true || (node.selectable !== false && chartSelectable); if (!selectable) continue; seeded[node.key] = checkbox ? { checked: true, partialChecked: false } : true; if (single) break; } return seeded; } isSameKeyState(current, next) { const currentKeys = Object.keys(current || {}); const nextKeys = Object.keys(next || {}); if (currentKeys.length !== nextKeys.length) { return false; } return currentKeys.every((key) => current[key] === next[key]); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: OrganizationChart, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: OrganizationChart, isStandalone: true, selector: "p-organization-chart, p-organizationchart", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, selectionKeys: { classPropertyName: "selectionKeys", publicName: "selectionKeys", isSignal: true, isRequired: false, transformFunction: null }, collapsedKeys: { classPropertyName: "collapsedKeys", publicName: "collapsedKeys", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionKeys: "selectionKeysChange", collapsedKeys: "collapsedKeysChange", onNodeSelect: "onNodeSelect", onNodeUnselect: "onNodeUnselect", onNodeExpand: "onNodeExpand", onNodeCollapse: "onNodeCollapse" }, host: { properties: { "class": "cx('root')", "style.--px-gap-x.px": "gapX()", "style.--px-gap-y.px": "gapY()" } }, providers: [OrganizationChartStyle, { provide: ORGANIZATIONCHART_INSTANCE, useExisting: OrganizationChart }, { provide: PARENT_INSTANCE, useExisting: OrganizationChart }], queries: [{ propertyName: "togglerIconTemplate", first: true, predicate: ["togglericon"], isSignal: true }, { propertyName: "collapseButtonTemplate", first: true, predicate: ["collapsebutton"], isSignal: true }, { propertyName: "checkboxIconTemplate", first: true, predicate: ["checkboxicon"], isSignal: true }, { propertyName: "nodeTemplate", first: true, predicate: ["node"], isSignal: true }], usesInheritance: true, hostDirectives: [{ directive: i1$1.Bind }], ngImport: i0, template: ` @if (root()) { <ul [class]="cx('subtree', { root: true })" role="tree" [attr.aria-multiselectable]="selectionMode() === 'multiple' || selectionMode() === 'checkbox' ? true : undefined" [pBind]="ptm('subtree')"> <li [class]="cx('tree')" role="treeitem" [attr.data-level]="1" [attr.aria-level]="1" [attr.aria-expanded]="getAriaExpanded(root()!)" [attr.aria-selected]="getAriaSelected(root()!)" pOrganizationChartNode [node]="root()" [root]="true" [level]="1" [pt]="pt" [unstyled]="unstyled()" [pBind]="ptm('tree')" ></li> </ul> } `, isInline: true, dependencies: [{ kind: "component", type: OrganizationChartNode, selector: "[pOrganizationChartNode]", inputs: ["node", "root", "level"] }, { kind: "ngmodule", type: BindModule }, { kind: "directive", type: i1$1.Bind, selector: "[pBind]", inputs: ["pBind"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: OrganizationChart, decorators: [{ type: Component, args: [{ selector: 'p-organization-chart, p-organizationchart', standalone: true, imports: [OrganizationChartNode, BindModule], template: ` @if (root()) { <ul [class]="cx('subtree', { root: true })" role="tree" [attr.aria-multiselectable]="selectionMode() === 'multiple' || selectionMode() === 'checkbox' ? true : undefined" [pBind]="ptm('subtree')"> <li [class]="cx('tree')" role="treeitem" [attr.data-level]="1" [attr.aria-level]="1" [attr.aria-expanded]="getAriaExpanded(root()!)" [attr.aria-selected]="getAriaSelected(root()!)" pOrganizationChartNode [node]="root()" [root]="true" [level]="1" [pt]="pt" [unstyled]="unstyled()" [pBind]="ptm('tree')" ></li> </ul> } `, changeDetection: ChangeDetectionStrategy.Default, providers: [OrganizationChartStyle, { provide: ORGANIZATIONCHART_INSTANCE, useExisting: OrganizationChart }, { provide: PARENT_INSTANCE, useExisting: OrganizationChart }], host: { '[class]': "cx('root')", '[style.--px-gap-x.px]': 'gapX()', '[style.--px-gap-y.px]': 'gapY()' }, hostDirectives: [Bind] }] }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], selectionKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionKeys", required: false }] }, { type: i0.Output, args: ["selectionKeysChange"] }], collapsedKeys: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsedKeys", required: false }] }, { type: i0.Output, args: ["collapsedKeysChange"] }], onNodeSelect: [{ type: i0.Output, args: ["onNodeSelect"] }], onNodeUnselect: [{ type: i0.Output, args: ["onNodeUnselect"] }], onNodeExpand: [{ type: i0.Output, args: ["onNodeExpand"] }], onNodeCollapse: [{ type: i0.Output, args: ["onNodeCollapse"] }], togglerIconTemplate: [{ type: i0.ContentChild, args: ['togglericon', { ...{ descendants: false }, isSignal: true }] }], collapseButtonTemplate: [{ type: i0.ContentChild, args: ['collapsebutton', { ...{ descendants: false }, isSignal: true }] }], checkboxIconTemplate: [{ type: i0.ContentChild, args: ['checkboxicon', { ...{ descendants: false }, isSignal: true }] }], nodeTemplate: [{ type: i0.ContentChild, args: ['node', { ...{ descendants: false }, isSignal: true }] }] } }); class OrganizationChartModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: OrganizationChartModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.6", ngImport: i0, type: OrganizationChartModule, imports: [OrganizationChart], exports: [OrganizationChart] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: OrganizationChartModule, imports: [OrganizationChart] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: OrganizationChartModule, decorators: [{ type: NgModule, args: [{ imports: [OrganizationChart], exports: [OrganizationChart] }] }] }); /** * Generated bundle index. Do not edit. */ export { OrganizationChart, OrganizationChartClasses, OrganizationChartModule, OrganizationChartStyle }; //# sourceMappingURL=primeng-organizationchart.mjs.map