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
JavaScript
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: `
(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')">
(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()"
>
(chart.checkboxIconTemplate()) {
<ng-template #icon let-checked>
<ng-container *ngTemplateOutlet="chart.checkboxIconTemplate()!; context: { $implicit: checked, partialChecked: partialSelected() }"></ng-container>
</ng-template>
}
</p-checkbox>
}
(!chart.getTemplateForNode(node()!)) {
<span [class]="cx('label')" [pBind]="ptm('label')">{{ node()!.label }}</span>
} {
<ng-container *ngTemplateOutlet="chart.getTemplateForNode(node()!); context: { $implicit: node() }"></ng-container>
}
</div>
(isCollapsible()) {
(chart.collapseButtonTemplate()) {
<ng-container *ngTemplateOutlet="chart.collapseButtonTemplate()!; context: getCollapseButtonContext()"></ng-container>
} {
<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')">
(!chart.togglerIconTemplate()) {
(collapsed()) {
<svg data-p-icon="chevron-down" />
} {
<svg data-p-icon="chevron-up" />
}
} {
<ng-template *ngTemplateOutlet="chart.togglerIconTemplate()!; context: { $implicit: !collapsed() }"></ng-template>
}
</span>
</button>
}
}
</div>
(hasChildren() && !collapsed()) {
<ul [class]="cx('subtree')" role="group" [pBind]="ptm('subtree')">
(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: `
(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')">
(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()"
>
(chart.checkboxIconTemplate()) {
<ng-template #icon let-checked>
<ng-container *ngTemplateOutlet="chart.checkboxIconTemplate()!; context: { $implicit: checked, partialChecked: partialSelected() }"></ng-container>
</ng-template>
}
</p-checkbox>
}
(!chart.getTemplateForNode(node()!)) {
<span [class]="cx('label')" [pBind]="ptm('label')">{{ node()!.label }}</span>
} {
<ng-container *ngTemplateOutlet="chart.getTemplateForNode(node()!); context: { $implicit: node() }"></ng-container>
}
</div>
(isCollapsible()) {
(chart.collapseButtonTemplate()) {
<ng-container *ngTemplateOutlet="chart.collapseButtonTemplate()!; context: getCollapseButtonContext()"></ng-container>
} {
<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')">
(!chart.togglerIconTemplate()) {
(collapsed()) {
<svg data-p-icon="chevron-down" />
} {
<svg data-p-icon="chevron-up" />
}
} {
<ng-template *ngTemplateOutlet="chart.togglerIconTemplate()!; context: { $implicit: !collapsed() }"></ng-template>
}
</span>
</button>
}
}
</div>
(hasChildren() && !collapsed()) {
<ul [class]="cx('subtree')" role="group" [pBind]="ptm('subtree')">
(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: `
(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: `
(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