@eherve/angular-material-organigram 22.0.0 → 22.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 22.0.1 — 2026-10-18
4
+
5
+ - Use consistent 2px connectors and center vertical segments on their branch axis.
6
+
3
7
  ## 22.0.0 — 2026-10-18
4
8
 
5
9
  - Extract the reusable Angular 22 organigram from sésiO.
@@ -313,7 +313,7 @@ var OrganigramComponent = class OrganigramComponent {
313
313
  }],
314
314
  ngImport: i0,
315
315
  template: "<!-- @format -->\n\n<div\n id=\"scroll\"\n #scroll\n [class.dragging]=\"dragging\">\n @if (tree) {\n <div id=\"container\" [class.hide-root]=\"hideRoot\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeBlock;\n context: { depth: 0, node: tree, class: { top: true, bottom: true, left: true, right: true } }\n \"></ng-container>\n </div>\n }\n</div>\n\n<ng-template #nodeBlock let-depth=\"depth\" let-node=\"node\" let-class=\"class\">\n <div class=\"node-block\" [class.depth-even]=\"depth % 2\">\n <div class=\"node-block-top\" [class]=\"class\"></div>\n <div class=\"node-block-left\" [class]=\"class\"></div>\n <div\n [id]=\"node.id\"\n class=\"node-container\"\n [class]=\"class\"\n [attr.role]=\"node.hasChildren || node.onClick || clickHandler ? 'button' : null\"\n [attr.tabindex]=\"node.hasChildren || node.onClick || clickHandler ? 0 : null\"\n [attr.aria-expanded]=\"node.hasChildren ? !node.hideChildren : null\"\n [attr.aria-busy]=\"pendingNodes().has(node)\"\n (mouseenter)=\"highlightParents(node)\"\n (mouseleave)=\"highlightParents(null)\"\n (keydown)=\"onKeydown($event, node)\"\n (click)=\"onClick(node, $event)\">\n <ng-container *ngTemplateOutlet=\"nodeTmpl; context: { node: node }\"></ng-container>\n @if (!node.hideChildren && node.children?.length) {\n <div @toggleTreeNode class=\"node-container-bottom\" [class]=\"class\"></div>\n }\n </div>\n @if (nodeErrors().get(node); as message) {\n <div class=\"node-error\" role=\"alert\">\n <span>{{ message }}</span>\n <button type=\"button\" (click)=\"onClick(node)\">{{ intl.messages().retry }}</button>\n </div>\n }\n @if (!node.hideChildren && node.children?.length) {\n <div @toggleTreeNode class=\"node-block-children\" [class.depth-even]=\"depth % 2\">\n <div class=\"node-block-children-top\" [class]=\"class\" [class.multiple-row]=\"node.children.length > 4\"></div>\n @for (\n row of node.children | organigramRows: nbChildByRow;\n track row;\n let rowIndex = $index;\n let top = $first;\n let bottom = $last\n ) {\n <div class=\"node-block-children-row\" [class.top]=\"top\" [class.bottom]=\"bottom\">\n @for (child of row; track child; let index = $index; let left = $first; let right = $last) {\n <ng-container\n *ngTemplateOutlet=\"\n nodeBlock;\n context: {\n depth: depth + 1,\n node: child,\n class: {\n rowIndex: rowIndex,\n index: index,\n even: index % 2,\n top: top,\n bottom: bottom,\n left: left,\n right: right,\n },\n }\n \">\n </ng-container>\n }\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n",
316
- styles: [":host{max-height:100%;max-width:100%;height:100%;width:100%}#scroll{display:flex;align-items:flex-start;justify-content:flex-start;position:relative;overflow:auto;height:100%;width:100%}#scroll.dragging{cursor:move!important}#scroll.dragging ::ng-deep *{cursor:move!important}#container{position:relative;padding:8px;margin:0 auto}#container.hide-root>.node-block{display:flex;flex-direction:column;align-items:center}#container.hide-root>.node-block>.node-container,#container.hide-root>.node-block>.node-block-top,#container.hide-root>.node-block>.node-block-left{display:none}#container.hide-root>.node-block>.node-block-children>.node-block-children-top{display:none}#container.hide-root>.node-block>.node-block-children>.node-block-children-row>.node-block>.node-block-top.left.right.top.bottom{display:none}.node-block{display:flex;flex-direction:column;align-items:center;position:relative}.node-block-top{position:absolute;top:0;left:0;right:0}.node-block-top:after{content:\"\";position:absolute;top:0;left:50%;width:1px;height:8px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-block-top.left.right:after{top:0;height:8px}.node-block-top:not(.top.bottom.left.right):before{content:\"\";position:absolute;top:0;left:0;right:0;height:1px;background:var(--path-horizontal-color, var(--ngx-mat-organigram-connector, #09293c))}.node-block-top:not(.top.bottom.left.right).left.top.bottom:before{left:50%}.node-block-top:not(.top.bottom.left.right).right:before{right:50%}.node-block-left{position:absolute;top:0;left:0;bottom:0}.node-block-left.left:not(.bottom):before{content:\"\";position:absolute;top:0;left:0;bottom:0;width:1px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-container{position:relative;padding:8px;width:calc(var(--ngx-mat-organigram-node-width, 200px) + 16px);box-sizing:content-box}.node-container:focus-visible{outline:2px solid var(--ngx-mat-organigram-focus, #09293c);outline-offset:-2px}.node-container-bottom{position:absolute;bottom:0;left:0;right:0;width:100%}.node-container-bottom:after{content:\"\";position:absolute;bottom:-8px;left:50%;width:1px;height:16px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-block-children{position:relative;background-color:#fff;border-radius:8px;padding:8px;margin:8px;overflow:hidden}.node-block-children.depth-even{background-color:#f9f9f9}.node-block-children-top{position:absolute;top:0;left:0;right:0;width:100%}.node-block-children-top:after{content:\"\";position:absolute;top:0;left:50%;width:1px;height:8px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-block-children-top.multiple-row:not(.bottom):before{content:\"\";position:absolute;top:8px;left:8px;right:50%;height:1px;background:var(--path-horizontal-color, var(--ngx-mat-organigram-connector, #09293c))}.node-error{max-width:var(--ngx-mat-organigram-node-width, 200px);padding:8px;display:flex;flex-direction:column;gap:8px;color:var(--ngx-mat-organigram-error, #e9396b)}.node-block-top.path-vertical:after,.node-container-bottom.path-vertical:after,.node-block-children-top.path-vertical:after,.node-block-left.path-vertical:before{background-color:var(--ngx-mat-organigram-highlight, #e73452)}.node-block-children-row{display:flex;flex-direction:row}\n"],
316
+ styles: [":host{max-height:100%;max-width:100%;height:100%;width:100%}#scroll{display:flex;align-items:flex-start;justify-content:flex-start;position:relative;overflow:auto;height:100%;width:100%}#scroll.dragging{cursor:move!important}#scroll.dragging ::ng-deep *{cursor:move!important}#container{position:relative;padding:8px;margin:0 auto}#container.hide-root>.node-block{display:flex;flex-direction:column;align-items:center}#container.hide-root>.node-block>.node-container,#container.hide-root>.node-block>.node-block-top,#container.hide-root>.node-block>.node-block-left{display:none}#container.hide-root>.node-block>.node-block-children>.node-block-children-top{display:none}#container.hide-root>.node-block>.node-block-children>.node-block-children-row>.node-block>.node-block-top.left.right.top.bottom{display:none}.node-block{display:flex;flex-direction:column;align-items:center;position:relative}.node-block-top{position:absolute;top:0;left:0;right:0}.node-block-top:after{content:\"\";position:absolute;top:0;left:calc(50% - 1px);width:2px;height:8px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-block-top.left.right:after{top:0;height:8px}.node-block-top:not(.top.bottom.left.right):before{content:\"\";position:absolute;top:0;left:0;right:0;height:2px;background:var(--path-horizontal-color, var(--ngx-mat-organigram-connector, #09293c))}.node-block-top:not(.top.bottom.left.right).left.top.bottom:before{left:50%}.node-block-top:not(.top.bottom.left.right).right:before{right:50%}.node-block-left{position:absolute;top:0;left:0;bottom:0}.node-block-left.left:not(.bottom):before{content:\"\";position:absolute;top:0;left:0;bottom:0;width:2px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-container{position:relative;padding:8px;width:calc(var(--ngx-mat-organigram-node-width, 200px) + 16px);box-sizing:content-box}.node-container:focus-visible{outline:2px solid var(--ngx-mat-organigram-focus, #09293c);outline-offset:-2px}.node-container-bottom{position:absolute;bottom:0;left:0;right:0;width:100%}.node-container-bottom:after{content:\"\";position:absolute;bottom:-8px;left:calc(50% - 1px);width:2px;height:16px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-block-children{position:relative;background-color:#fff;border-radius:8px;padding:8px;margin:8px;overflow:hidden}.node-block-children.depth-even{background-color:#f9f9f9}.node-block-children-top{position:absolute;top:0;left:0;right:0;width:100%}.node-block-children-top:after{content:\"\";position:absolute;top:0;left:calc(50% - 1px);width:2px;height:8px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-block-children-top.multiple-row:not(.bottom):before{content:\"\";position:absolute;top:8px;left:8px;right:50%;height:2px;background:var(--path-horizontal-color, var(--ngx-mat-organigram-connector, #09293c))}.node-error{max-width:var(--ngx-mat-organigram-node-width, 200px);padding:8px;display:flex;flex-direction:column;gap:8px;color:var(--ngx-mat-organigram-error, #e9396b)}.node-block-top.path-vertical:after,.node-container-bottom.path-vertical:after,.node-block-children-top.path-vertical:after,.node-block-left.path-vertical:before{background-color:var(--ngx-mat-organigram-highlight, #e73452)}.node-block-children-row{display:flex;flex-direction:row}\n"],
317
317
  dependencies: [
318
318
  {
319
319
  kind: "ngmodule",
@@ -396,7 +396,7 @@ i0.ɵɵngDeclareClassMetadata({
396
396
  changeDetection: ChangeDetectionStrategy.Eager,
397
397
  imports: [CommonModule, OrganigramRowsPipe],
398
398
  template: "<!-- @format -->\n\n<div\n id=\"scroll\"\n #scroll\n [class.dragging]=\"dragging\">\n @if (tree) {\n <div id=\"container\" [class.hide-root]=\"hideRoot\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeBlock;\n context: { depth: 0, node: tree, class: { top: true, bottom: true, left: true, right: true } }\n \"></ng-container>\n </div>\n }\n</div>\n\n<ng-template #nodeBlock let-depth=\"depth\" let-node=\"node\" let-class=\"class\">\n <div class=\"node-block\" [class.depth-even]=\"depth % 2\">\n <div class=\"node-block-top\" [class]=\"class\"></div>\n <div class=\"node-block-left\" [class]=\"class\"></div>\n <div\n [id]=\"node.id\"\n class=\"node-container\"\n [class]=\"class\"\n [attr.role]=\"node.hasChildren || node.onClick || clickHandler ? 'button' : null\"\n [attr.tabindex]=\"node.hasChildren || node.onClick || clickHandler ? 0 : null\"\n [attr.aria-expanded]=\"node.hasChildren ? !node.hideChildren : null\"\n [attr.aria-busy]=\"pendingNodes().has(node)\"\n (mouseenter)=\"highlightParents(node)\"\n (mouseleave)=\"highlightParents(null)\"\n (keydown)=\"onKeydown($event, node)\"\n (click)=\"onClick(node, $event)\">\n <ng-container *ngTemplateOutlet=\"nodeTmpl; context: { node: node }\"></ng-container>\n @if (!node.hideChildren && node.children?.length) {\n <div @toggleTreeNode class=\"node-container-bottom\" [class]=\"class\"></div>\n }\n </div>\n @if (nodeErrors().get(node); as message) {\n <div class=\"node-error\" role=\"alert\">\n <span>{{ message }}</span>\n <button type=\"button\" (click)=\"onClick(node)\">{{ intl.messages().retry }}</button>\n </div>\n }\n @if (!node.hideChildren && node.children?.length) {\n <div @toggleTreeNode class=\"node-block-children\" [class.depth-even]=\"depth % 2\">\n <div class=\"node-block-children-top\" [class]=\"class\" [class.multiple-row]=\"node.children.length > 4\"></div>\n @for (\n row of node.children | organigramRows: nbChildByRow;\n track row;\n let rowIndex = $index;\n let top = $first;\n let bottom = $last\n ) {\n <div class=\"node-block-children-row\" [class.top]=\"top\" [class.bottom]=\"bottom\">\n @for (child of row; track child; let index = $index; let left = $first; let right = $last) {\n <ng-container\n *ngTemplateOutlet=\"\n nodeBlock;\n context: {\n depth: depth + 1,\n node: child,\n class: {\n rowIndex: rowIndex,\n index: index,\n even: index % 2,\n top: top,\n bottom: bottom,\n left: left,\n right: right,\n },\n }\n \">\n </ng-container>\n }\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n",
399
- styles: [":host{max-height:100%;max-width:100%;height:100%;width:100%}#scroll{display:flex;align-items:flex-start;justify-content:flex-start;position:relative;overflow:auto;height:100%;width:100%}#scroll.dragging{cursor:move!important}#scroll.dragging ::ng-deep *{cursor:move!important}#container{position:relative;padding:8px;margin:0 auto}#container.hide-root>.node-block{display:flex;flex-direction:column;align-items:center}#container.hide-root>.node-block>.node-container,#container.hide-root>.node-block>.node-block-top,#container.hide-root>.node-block>.node-block-left{display:none}#container.hide-root>.node-block>.node-block-children>.node-block-children-top{display:none}#container.hide-root>.node-block>.node-block-children>.node-block-children-row>.node-block>.node-block-top.left.right.top.bottom{display:none}.node-block{display:flex;flex-direction:column;align-items:center;position:relative}.node-block-top{position:absolute;top:0;left:0;right:0}.node-block-top:after{content:\"\";position:absolute;top:0;left:50%;width:1px;height:8px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-block-top.left.right:after{top:0;height:8px}.node-block-top:not(.top.bottom.left.right):before{content:\"\";position:absolute;top:0;left:0;right:0;height:1px;background:var(--path-horizontal-color, var(--ngx-mat-organigram-connector, #09293c))}.node-block-top:not(.top.bottom.left.right).left.top.bottom:before{left:50%}.node-block-top:not(.top.bottom.left.right).right:before{right:50%}.node-block-left{position:absolute;top:0;left:0;bottom:0}.node-block-left.left:not(.bottom):before{content:\"\";position:absolute;top:0;left:0;bottom:0;width:1px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-container{position:relative;padding:8px;width:calc(var(--ngx-mat-organigram-node-width, 200px) + 16px);box-sizing:content-box}.node-container:focus-visible{outline:2px solid var(--ngx-mat-organigram-focus, #09293c);outline-offset:-2px}.node-container-bottom{position:absolute;bottom:0;left:0;right:0;width:100%}.node-container-bottom:after{content:\"\";position:absolute;bottom:-8px;left:50%;width:1px;height:16px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-block-children{position:relative;background-color:#fff;border-radius:8px;padding:8px;margin:8px;overflow:hidden}.node-block-children.depth-even{background-color:#f9f9f9}.node-block-children-top{position:absolute;top:0;left:0;right:0;width:100%}.node-block-children-top:after{content:\"\";position:absolute;top:0;left:50%;width:1px;height:8px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-block-children-top.multiple-row:not(.bottom):before{content:\"\";position:absolute;top:8px;left:8px;right:50%;height:1px;background:var(--path-horizontal-color, var(--ngx-mat-organigram-connector, #09293c))}.node-error{max-width:var(--ngx-mat-organigram-node-width, 200px);padding:8px;display:flex;flex-direction:column;gap:8px;color:var(--ngx-mat-organigram-error, #e9396b)}.node-block-top.path-vertical:after,.node-container-bottom.path-vertical:after,.node-block-children-top.path-vertical:after,.node-block-left.path-vertical:before{background-color:var(--ngx-mat-organigram-highlight, #e73452)}.node-block-children-row{display:flex;flex-direction:row}\n"]
399
+ styles: [":host{max-height:100%;max-width:100%;height:100%;width:100%}#scroll{display:flex;align-items:flex-start;justify-content:flex-start;position:relative;overflow:auto;height:100%;width:100%}#scroll.dragging{cursor:move!important}#scroll.dragging ::ng-deep *{cursor:move!important}#container{position:relative;padding:8px;margin:0 auto}#container.hide-root>.node-block{display:flex;flex-direction:column;align-items:center}#container.hide-root>.node-block>.node-container,#container.hide-root>.node-block>.node-block-top,#container.hide-root>.node-block>.node-block-left{display:none}#container.hide-root>.node-block>.node-block-children>.node-block-children-top{display:none}#container.hide-root>.node-block>.node-block-children>.node-block-children-row>.node-block>.node-block-top.left.right.top.bottom{display:none}.node-block{display:flex;flex-direction:column;align-items:center;position:relative}.node-block-top{position:absolute;top:0;left:0;right:0}.node-block-top:after{content:\"\";position:absolute;top:0;left:calc(50% - 1px);width:2px;height:8px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-block-top.left.right:after{top:0;height:8px}.node-block-top:not(.top.bottom.left.right):before{content:\"\";position:absolute;top:0;left:0;right:0;height:2px;background:var(--path-horizontal-color, var(--ngx-mat-organigram-connector, #09293c))}.node-block-top:not(.top.bottom.left.right).left.top.bottom:before{left:50%}.node-block-top:not(.top.bottom.left.right).right:before{right:50%}.node-block-left{position:absolute;top:0;left:0;bottom:0}.node-block-left.left:not(.bottom):before{content:\"\";position:absolute;top:0;left:0;bottom:0;width:2px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-container{position:relative;padding:8px;width:calc(var(--ngx-mat-organigram-node-width, 200px) + 16px);box-sizing:content-box}.node-container:focus-visible{outline:2px solid var(--ngx-mat-organigram-focus, #09293c);outline-offset:-2px}.node-container-bottom{position:absolute;bottom:0;left:0;right:0;width:100%}.node-container-bottom:after{content:\"\";position:absolute;bottom:-8px;left:calc(50% - 1px);width:2px;height:16px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-block-children{position:relative;background-color:#fff;border-radius:8px;padding:8px;margin:8px;overflow:hidden}.node-block-children.depth-even{background-color:#f9f9f9}.node-block-children-top{position:absolute;top:0;left:0;right:0;width:100%}.node-block-children-top:after{content:\"\";position:absolute;top:0;left:calc(50% - 1px);width:2px;height:8px;background-color:var(--ngx-mat-organigram-connector, #09293c)}.node-block-children-top.multiple-row:not(.bottom):before{content:\"\";position:absolute;top:8px;left:8px;right:50%;height:2px;background:var(--path-horizontal-color, var(--ngx-mat-organigram-connector, #09293c))}.node-error{max-width:var(--ngx-mat-organigram-node-width, 200px);padding:8px;display:flex;flex-direction:column;gap:8px;color:var(--ngx-mat-organigram-error, #e9396b)}.node-block-top.path-vertical:after,.node-container-bottom.path-vertical:after,.node-block-children-top.path-vertical:after,.node-block-left.path-vertical:before{background-color:var(--ngx-mat-organigram-highlight, #e73452)}.node-block-children-row{display:flex;flex-direction:row}\n"]
400
400
  }]
401
401
  }],
402
402
  propDecorators: {
@@ -1 +1 @@
1
- {"version":3,"file":"eherve-angular-material-organigram.mjs","names":[],"sources":["../../../projects/organigram/src/lib/organigram-tree-node.ts","../../../projects/organigram/src/lib/organigram-rows.pipe.ts","../../../projects/organigram/src/lib/organigram-intl.ts","../../../projects/organigram/src/lib/organigram.component.ts","../../../projects/organigram/src/lib/organigram.component.html","../../../projects/organigram/src/lib/organigram.module.ts"],"sourcesContent":["export interface OrganigramNode<T = unknown> {\n type: string;\n entity?: T | null;\n hasChildren?: boolean;\n children?: readonly OrganigramNode<T>[];\n hideChildren?: boolean;\n selected?: boolean;\n onClick?: (node: OrganigramTreeNode<T>) => Promise<readonly OrganigramNode<T>[] | void>;\n}\n\nlet nextNodeId = 0;\n\nexport class OrganigramTreeNode<T = unknown> implements OrganigramNode<T> {\n readonly id: string;\n type: string;\n entity?: T | null;\n hasChildren?: boolean;\n hideChildren?: boolean;\n selected?: boolean;\n parent?: OrganigramTreeNode<T>;\n depth: number;\n children: OrganigramTreeNode<T>[] = [];\n onClick?: (node: OrganigramTreeNode<T>) => Promise<readonly OrganigramNode<T>[] | void>;\n\n constructor(node: OrganigramNode<T>, depth = 0) {\n Object.assign(this, node);\n this.id = `ngx-mat-organigram-node-${nextNodeId++}`;\n this.type = node.type;\n this.parent = undefined;\n this.depth = depth;\n this.children = [];\n for (const child of node.children ?? []) this.addChild(child);\n }\n\n addChild(node: OrganigramNode<T>): void {\n const child = node instanceof OrganigramTreeNode ? node : new OrganigramTreeNode(node, this.depth + 1);\n child.parent = this;\n child.setDepth(this.depth + 1);\n this.children = [...this.children, child];\n }\n\n private setDepth(depth: number): void {\n this.depth = depth;\n for (const child of this.children) child.setDepth(depth + 1);\n }\n\n getParent(index = 0): OrganigramTreeNode<T> | null {\n const parents: OrganigramTreeNode<T>[] = [];\n for (let parent = this.parent; parent; parent = parent.parent) parents.unshift(parent);\n const position = index < 0 ? Math.abs(index) - 1 : parents.length - 1 - index;\n return parents[position] ?? null;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({ name: 'organigramRows' })\nexport class OrganigramRowsPipe implements PipeTransform {\n transform<T>(nodes: readonly T[], size = 5): T[][] {\n const rows: T[][] = [];\n for (let i = 0; i < nodes.length; i += size) rows.push(nodes.slice(i, i + size));\n return rows;\n }\n}\n","import { Injectable, signal } from '@angular/core';\n\nexport interface OrganigramMessages {\n loadError: string;\n retry: string;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class OrganigramIntl {\n readonly messages = signal<OrganigramMessages>({\n loadError: 'Impossible de charger cette rubrique.',\n retry: 'Réessayer',\n });\n}\n","/** @format */\n\nimport { animate, style, transition, trigger } from '@angular/animations';\nimport { CommonModule } from '@angular/common';\nimport {\n afterNextRender,\n AfterRenderRef,\n Injector,\n signal,\n Component,\n ElementRef,\n HostListener,\n inject,\n Input,\n OnDestroy,\n TemplateRef,\n ViewChild,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport { OrganigramNode, OrganigramTreeNode } from './organigram-tree-node';\nimport { OrganigramRowsPipe } from './organigram-rows.pipe';\nimport { OrganigramIntl } from './organigram-intl';\n\n@Component({\n selector: 'app-organigram',\n templateUrl: './organigram.component.html',\n styleUrls: ['./organigram.component.scss'],\n animations: [\n trigger('toggleTreeNode', [\n transition(':enter', [\n style({ height: 0, width: 0, opacity: 0 }),\n animate('0.2s', style({ height: '*', width: '*' })),\n animate('0.2s 0.2s', style({ opacity: 1 })),\n ]),\n transition(':leave', [\n style({ height: '*', width: '*', opacity: 1 }),\n animate('0.2s', style({ opacity: 0 })),\n animate('0.2s 0.2s', style({ height: 0, width: 0 })),\n ]),\n ]),\n ],\n changeDetection: ChangeDetectionStrategy.Eager,\n imports: [CommonModule, OrganigramRowsPipe],\n})\nexport class OrganigramComponent<T = unknown> implements OnDestroy {\n readonly intl = inject(OrganigramIntl);\n dragging = false;\n private dragOrigin: { x: number; y: number } | null = null;\n private suppressClick = false;\n private destroyed = false;\n private treeVersion = 0;\n private scrollRender?: AfterRenderRef;\n readonly pendingNodes = signal<ReadonlySet<OrganigramTreeNode<T>>>(new Set());\n readonly nodeErrors = signal<ReadonlyMap<OrganigramTreeNode<T>, string>>(new Map());\n private readonly highlightedConnectors = new Set<HTMLElement>();\n private pathObserver?: ResizeObserver;\n private hoveredNode: OrganigramTreeNode<T> | null = null;\n private readonly injector = inject(Injector);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n\n @HostListener('mousedown', ['$event'])\n onMouseDown(event: MouseEvent): void {\n this.suppressClick = false;\n if (event.button !== 0 || (event.target as HTMLElement).closest('button, input, a, mat-checkbox')) return;\n this.dragOrigin = { x: event.clientX, y: event.clientY };\n }\n\n @HostListener('mousemove', ['$event'])\n onMouseMove(event: MouseEvent): void {\n if (!this.dragOrigin) return;\n if (!this.dragging && Math.hypot(event.clientX - this.dragOrigin.x, event.clientY - this.dragOrigin.y) < 5) return;\n this.dragging = true;\n this.suppressClick = true;\n this.scrollRef?.nativeElement.scrollBy({ top: -event.movementY, left: -event.movementX });\n event.preventDefault();\n }\n\n @HostListener('document:mouseup')\n @HostListener('window:blur')\n onMouseUp(): void {\n this.dragOrigin = null;\n this.dragging = false;\n }\n\n @ViewChild('scroll')\n scrollRef?: ElementRef<HTMLElement>;\n\n @Input('hideRoot')\n set setHideRoot(hideRoot: unknown) {\n this.hideRoot = hideRoot !== false;\n }\n hideRoot = false;\n\n @Input('tree')\n set setTree(tree: OrganigramNode<T> | OrganigramTreeNode<T> | null | undefined) {\n this.treeVersion++;\n this.scrollRender?.destroy();\n this.pendingNodes.set(new Set());\n this.nodeErrors.set(new Map());\n this.highlightParents(null);\n this.tree = !tree ? null : tree instanceof OrganigramTreeNode ? tree : new OrganigramTreeNode<T>(tree);\n }\n tree: OrganigramTreeNode<T> | null = null;\n\n @Input()\n nodeTmpl!: TemplateRef<{ node: OrganigramTreeNode<T> }>;\n\n @Input('click')\n clickHandler?: (node: OrganigramTreeNode<T>) => Promise<unknown>;\n\n nbChildByRow = 5;\n\n highlightParents(node: OrganigramTreeNode<T> | null): void {\n this.pathObserver?.disconnect();\n this.hoveredNode = node;\n this.paintParentPath();\n if (!node) return;\n this.pathObserver ??= new ResizeObserver(() => this.paintParentPath());\n for (const connector of this.highlightedConnectors) {\n this.pathObserver.observe(connector.parentElement!);\n }\n }\n\n private paintParentPath(): void {\n for (const element of this.highlightedConnectors) {\n element.classList.remove('path-vertical');\n element.style.removeProperty('--path-horizontal-color');\n }\n this.highlightedConnectors.clear();\n for (let child = this.hoveredNode; child?.parent; child = child.parent) {\n const childElement = document.getElementById(child.id);\n const parentElement = document.getElementById(child.parent.id);\n if (!childElement || !parentElement || !this.host.nativeElement.contains(parentElement) ||\n !parentElement.offsetParent) break;\n const row = childElement.closest<HTMLElement>('.node-block-children-row');\n const group = row?.parentElement;\n if (!row || !group) break;\n const rows = Array.from(group.querySelectorAll<HTMLElement>(':scope > .node-block-children-row'));\n const rowIndex = rows.indexOf(row);\n const parentX = parentElement.getBoundingClientRect().left + parentElement.offsetWidth / 2;\n const childX = childElement.getBoundingClientRect().left + childElement.offsetWidth / 2;\n this.colorVertical(childElement.parentElement?.querySelector<HTMLElement>(':scope > .node-block-top'));\n this.colorVertical(parentElement.querySelector<HTMLElement>(':scope > .node-container-bottom'));\n const groupTop = group.querySelector<HTMLElement>(':scope > .node-block-children-top');\n this.colorVertical(groupTop);\n if (rowIndex === 0) {\n this.colorRow(row, parentX, childX);\n if (groupTop) this.colorHorizontal(groupTop, parentX, childX);\n } else {\n const railX = rows[0].getBoundingClientRect().left;\n this.colorRow(rows[0], parentX, railX);\n if (groupTop) this.colorHorizontal(groupTop, parentX, railX);\n for (const previousRow of rows.slice(0, rowIndex)) {\n this.colorVertical(previousRow.querySelector<HTMLElement>(':scope > .node-block > .node-block-left'));\n }\n this.colorRow(row, railX, childX);\n }\n }\n }\n\n private colorVertical(element: HTMLElement | null | undefined): void {\n if (!element) return;\n element.classList.add('path-vertical');\n this.highlightedConnectors.add(element);\n }\n\n private colorRow(row: HTMLElement, from: number, to: number): void {\n for (const element of row.querySelectorAll<HTMLElement>(':scope > .node-block > .node-block-top')) {\n this.colorHorizontal(element, from, to);\n }\n }\n\n private colorHorizontal(element: HTMLElement, from: number, to: number): void {\n const style = getComputedStyle(element, '::before');\n if (style.content === 'none') return;\n const bounds = element.getBoundingClientRect();\n const offset = style.left.endsWith('%') ? parseFloat(style.left) * bounds.width / 100 : parseFloat(style.left);\n const width = parseFloat(style.width);\n const start = Math.max(0, Math.min(from, to) - bounds.left - offset);\n const end = Math.min(width, Math.max(from, to) - bounds.left - offset);\n if (end <= start || !Number.isFinite(width)) return;\n element.style.setProperty('--path-horizontal-color', `linear-gradient(to right,\n var(--ngx-mat-organigram-connector, #09293c) ${start}px, var(--ngx-mat-organigram-highlight, #e73452) ${start}px,\n var(--ngx-mat-organigram-highlight, #e73452) ${end}px, var(--ngx-mat-organigram-connector, #09293c) ${end}px)`);\n this.highlightedConnectors.add(element);\n }\n\n ngOnDestroy(): void {\n this.highlightParents(null);\n this.destroyed = true;\n this.treeVersion++;\n this.scrollRender?.destroy();\n }\n\n onKeydown(event: KeyboardEvent, node: OrganigramTreeNode<T>): void {\n if (event.target !== event.currentTarget || (event.key !== 'Enter' && event.key !== ' ')) return;\n event.preventDefault();\n void this.onClick(node);\n }\n\n async onClick(node: OrganigramTreeNode<T>, event?: MouseEvent): Promise<void> {\n if (event && (this.suppressClick || (event.target as HTMLElement).closest('button, input, a, mat-checkbox'))) return;\n if (this.destroyed || this.pendingNodes().has(node)) return;\n const version = this.treeVersion;\n this.pendingNodes.update(pending => new Set([...pending, node]));\n this.nodeErrors.update(errors => { const next = new Map(errors); next.delete(node); return next; });\n try {\n if (node.onClick) {\n const children = await node.onClick(node);\n if (this.destroyed || version !== this.treeVersion) return;\n if (Array.isArray(children)) {\n for (const child of children) node.addChild(child);\n node.hasChildren = node.children.length > 0;\n node.hideChildren = false;\n }\n } else if (this.clickHandler) {\n await this.clickHandler(node);\n } else if (node.hasChildren) node.hideChildren = !node.hideChildren;\n if (this.destroyed || version !== this.treeVersion) return;\n this.scrollToNode(node);\n } catch {\n if (!this.destroyed && version === this.treeVersion) {\n this.nodeErrors.update(errors => new Map(errors).set(node, this.intl.messages().loadError));\n }\n } finally {\n if (!this.destroyed && version === this.treeVersion) {\n this.pendingNodes.update(pending => { const next = new Set(pending); next.delete(node); return next; });\n }\n }\n }\n\n private scrollToNode(node: OrganigramTreeNode<T>): void {\n this.scrollRender?.destroy();\n this.scrollRender = afterNextRender(() => {\n if (this.destroyed) return;\n if (this.hoveredNode) this.highlightParents(this.hoveredNode);\n const element = document.getElementById(node.id);\n if (element && this.host.nativeElement.contains(element)) {\n element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });\n }\n }, { injector: this.injector });\n }\n}\n","<!-- @format -->\n\n<div\n id=\"scroll\"\n #scroll\n [class.dragging]=\"dragging\">\n @if (tree) {\n <div id=\"container\" [class.hide-root]=\"hideRoot\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeBlock;\n context: { depth: 0, node: tree, class: { top: true, bottom: true, left: true, right: true } }\n \"></ng-container>\n </div>\n }\n</div>\n\n<ng-template #nodeBlock let-depth=\"depth\" let-node=\"node\" let-class=\"class\">\n <div class=\"node-block\" [class.depth-even]=\"depth % 2\">\n <div class=\"node-block-top\" [class]=\"class\"></div>\n <div class=\"node-block-left\" [class]=\"class\"></div>\n <div\n [id]=\"node.id\"\n class=\"node-container\"\n [class]=\"class\"\n [attr.role]=\"node.hasChildren || node.onClick || clickHandler ? 'button' : null\"\n [attr.tabindex]=\"node.hasChildren || node.onClick || clickHandler ? 0 : null\"\n [attr.aria-expanded]=\"node.hasChildren ? !node.hideChildren : null\"\n [attr.aria-busy]=\"pendingNodes().has(node)\"\n (mouseenter)=\"highlightParents(node)\"\n (mouseleave)=\"highlightParents(null)\"\n (keydown)=\"onKeydown($event, node)\"\n (click)=\"onClick(node, $event)\">\n <ng-container *ngTemplateOutlet=\"nodeTmpl; context: { node: node }\"></ng-container>\n @if (!node.hideChildren && node.children?.length) {\n <div @toggleTreeNode class=\"node-container-bottom\" [class]=\"class\"></div>\n }\n </div>\n @if (nodeErrors().get(node); as message) {\n <div class=\"node-error\" role=\"alert\">\n <span>{{ message }}</span>\n <button type=\"button\" (click)=\"onClick(node)\">{{ intl.messages().retry }}</button>\n </div>\n }\n @if (!node.hideChildren && node.children?.length) {\n <div @toggleTreeNode class=\"node-block-children\" [class.depth-even]=\"depth % 2\">\n <div class=\"node-block-children-top\" [class]=\"class\" [class.multiple-row]=\"node.children.length > 4\"></div>\n @for (\n row of node.children | organigramRows: nbChildByRow;\n track row;\n let rowIndex = $index;\n let top = $first;\n let bottom = $last\n ) {\n <div class=\"node-block-children-row\" [class.top]=\"top\" [class.bottom]=\"bottom\">\n @for (child of row; track child; let index = $index; let left = $first; let right = $last) {\n <ng-container\n *ngTemplateOutlet=\"\n nodeBlock;\n context: {\n depth: depth + 1,\n node: child,\n class: {\n rowIndex: rowIndex,\n index: index,\n even: index % 2,\n top: top,\n bottom: bottom,\n left: left,\n right: right,\n },\n }\n \">\n </ng-container>\n }\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n","import { NgModule } from '@angular/core';\nimport { OrganigramComponent } from './organigram.component';\n\n@NgModule({ imports: [OrganigramComponent], exports: [OrganigramComponent] })\nexport class OrganigramModule {}\n"],"mappings":"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"}
1
+ {"version":3,"file":"eherve-angular-material-organigram.mjs","names":[],"sources":["../../../projects/organigram/src/lib/organigram-tree-node.ts","../../../projects/organigram/src/lib/organigram-rows.pipe.ts","../../../projects/organigram/src/lib/organigram-intl.ts","../../../projects/organigram/src/lib/organigram.component.ts","../../../projects/organigram/src/lib/organigram.component.html","../../../projects/organigram/src/lib/organigram.module.ts"],"sourcesContent":["export interface OrganigramNode<T = unknown> {\n type: string;\n entity?: T | null;\n hasChildren?: boolean;\n children?: readonly OrganigramNode<T>[];\n hideChildren?: boolean;\n selected?: boolean;\n onClick?: (node: OrganigramTreeNode<T>) => Promise<readonly OrganigramNode<T>[] | void>;\n}\n\nlet nextNodeId = 0;\n\nexport class OrganigramTreeNode<T = unknown> implements OrganigramNode<T> {\n readonly id: string;\n type: string;\n entity?: T | null;\n hasChildren?: boolean;\n hideChildren?: boolean;\n selected?: boolean;\n parent?: OrganigramTreeNode<T>;\n depth: number;\n children: OrganigramTreeNode<T>[] = [];\n onClick?: (node: OrganigramTreeNode<T>) => Promise<readonly OrganigramNode<T>[] | void>;\n\n constructor(node: OrganigramNode<T>, depth = 0) {\n Object.assign(this, node);\n this.id = `ngx-mat-organigram-node-${nextNodeId++}`;\n this.type = node.type;\n this.parent = undefined;\n this.depth = depth;\n this.children = [];\n for (const child of node.children ?? []) this.addChild(child);\n }\n\n addChild(node: OrganigramNode<T>): void {\n const child = node instanceof OrganigramTreeNode ? node : new OrganigramTreeNode(node, this.depth + 1);\n child.parent = this;\n child.setDepth(this.depth + 1);\n this.children = [...this.children, child];\n }\n\n private setDepth(depth: number): void {\n this.depth = depth;\n for (const child of this.children) child.setDepth(depth + 1);\n }\n\n getParent(index = 0): OrganigramTreeNode<T> | null {\n const parents: OrganigramTreeNode<T>[] = [];\n for (let parent = this.parent; parent; parent = parent.parent) parents.unshift(parent);\n const position = index < 0 ? Math.abs(index) - 1 : parents.length - 1 - index;\n return parents[position] ?? null;\n }\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({ name: 'organigramRows' })\nexport class OrganigramRowsPipe implements PipeTransform {\n transform<T>(nodes: readonly T[], size = 5): T[][] {\n const rows: T[][] = [];\n for (let i = 0; i < nodes.length; i += size) rows.push(nodes.slice(i, i + size));\n return rows;\n }\n}\n","import { Injectable, signal } from '@angular/core';\n\nexport interface OrganigramMessages {\n loadError: string;\n retry: string;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class OrganigramIntl {\n readonly messages = signal<OrganigramMessages>({\n loadError: 'Impossible de charger cette rubrique.',\n retry: 'Réessayer',\n });\n}\n","/** @format */\n\nimport { animate, style, transition, trigger } from '@angular/animations';\nimport { CommonModule } from '@angular/common';\nimport {\n afterNextRender,\n AfterRenderRef,\n Injector,\n signal,\n Component,\n ElementRef,\n HostListener,\n inject,\n Input,\n OnDestroy,\n TemplateRef,\n ViewChild,\n ChangeDetectionStrategy,\n} from '@angular/core';\nimport { OrganigramNode, OrganigramTreeNode } from './organigram-tree-node';\nimport { OrganigramRowsPipe } from './organigram-rows.pipe';\nimport { OrganigramIntl } from './organigram-intl';\n\n@Component({\n selector: 'app-organigram',\n templateUrl: './organigram.component.html',\n styleUrls: ['./organigram.component.scss'],\n animations: [\n trigger('toggleTreeNode', [\n transition(':enter', [\n style({ height: 0, width: 0, opacity: 0 }),\n animate('0.2s', style({ height: '*', width: '*' })),\n animate('0.2s 0.2s', style({ opacity: 1 })),\n ]),\n transition(':leave', [\n style({ height: '*', width: '*', opacity: 1 }),\n animate('0.2s', style({ opacity: 0 })),\n animate('0.2s 0.2s', style({ height: 0, width: 0 })),\n ]),\n ]),\n ],\n changeDetection: ChangeDetectionStrategy.Eager,\n imports: [CommonModule, OrganigramRowsPipe],\n})\nexport class OrganigramComponent<T = unknown> implements OnDestroy {\n readonly intl = inject(OrganigramIntl);\n dragging = false;\n private dragOrigin: { x: number; y: number } | null = null;\n private suppressClick = false;\n private destroyed = false;\n private treeVersion = 0;\n private scrollRender?: AfterRenderRef;\n readonly pendingNodes = signal<ReadonlySet<OrganigramTreeNode<T>>>(new Set());\n readonly nodeErrors = signal<ReadonlyMap<OrganigramTreeNode<T>, string>>(new Map());\n private readonly highlightedConnectors = new Set<HTMLElement>();\n private pathObserver?: ResizeObserver;\n private hoveredNode: OrganigramTreeNode<T> | null = null;\n private readonly injector = inject(Injector);\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n\n @HostListener('mousedown', ['$event'])\n onMouseDown(event: MouseEvent): void {\n this.suppressClick = false;\n if (event.button !== 0 || (event.target as HTMLElement).closest('button, input, a, mat-checkbox')) return;\n this.dragOrigin = { x: event.clientX, y: event.clientY };\n }\n\n @HostListener('mousemove', ['$event'])\n onMouseMove(event: MouseEvent): void {\n if (!this.dragOrigin) return;\n if (!this.dragging && Math.hypot(event.clientX - this.dragOrigin.x, event.clientY - this.dragOrigin.y) < 5) return;\n this.dragging = true;\n this.suppressClick = true;\n this.scrollRef?.nativeElement.scrollBy({ top: -event.movementY, left: -event.movementX });\n event.preventDefault();\n }\n\n @HostListener('document:mouseup')\n @HostListener('window:blur')\n onMouseUp(): void {\n this.dragOrigin = null;\n this.dragging = false;\n }\n\n @ViewChild('scroll')\n scrollRef?: ElementRef<HTMLElement>;\n\n @Input('hideRoot')\n set setHideRoot(hideRoot: unknown) {\n this.hideRoot = hideRoot !== false;\n }\n hideRoot = false;\n\n @Input('tree')\n set setTree(tree: OrganigramNode<T> | OrganigramTreeNode<T> | null | undefined) {\n this.treeVersion++;\n this.scrollRender?.destroy();\n this.pendingNodes.set(new Set());\n this.nodeErrors.set(new Map());\n this.highlightParents(null);\n this.tree = !tree ? null : tree instanceof OrganigramTreeNode ? tree : new OrganigramTreeNode<T>(tree);\n }\n tree: OrganigramTreeNode<T> | null = null;\n\n @Input()\n nodeTmpl!: TemplateRef<{ node: OrganigramTreeNode<T> }>;\n\n @Input('click')\n clickHandler?: (node: OrganigramTreeNode<T>) => Promise<unknown>;\n\n nbChildByRow = 5;\n\n highlightParents(node: OrganigramTreeNode<T> | null): void {\n this.pathObserver?.disconnect();\n this.hoveredNode = node;\n this.paintParentPath();\n if (!node) return;\n this.pathObserver ??= new ResizeObserver(() => this.paintParentPath());\n for (const connector of this.highlightedConnectors) {\n this.pathObserver.observe(connector.parentElement!);\n }\n }\n\n private paintParentPath(): void {\n for (const element of this.highlightedConnectors) {\n element.classList.remove('path-vertical');\n element.style.removeProperty('--path-horizontal-color');\n }\n this.highlightedConnectors.clear();\n for (let child = this.hoveredNode; child?.parent; child = child.parent) {\n const childElement = document.getElementById(child.id);\n const parentElement = document.getElementById(child.parent.id);\n if (!childElement || !parentElement || !this.host.nativeElement.contains(parentElement) ||\n !parentElement.offsetParent) break;\n const row = childElement.closest<HTMLElement>('.node-block-children-row');\n const group = row?.parentElement;\n if (!row || !group) break;\n const rows = Array.from(group.querySelectorAll<HTMLElement>(':scope > .node-block-children-row'));\n const rowIndex = rows.indexOf(row);\n const parentX = parentElement.getBoundingClientRect().left + parentElement.offsetWidth / 2;\n const childX = childElement.getBoundingClientRect().left + childElement.offsetWidth / 2;\n this.colorVertical(childElement.parentElement?.querySelector<HTMLElement>(':scope > .node-block-top'));\n this.colorVertical(parentElement.querySelector<HTMLElement>(':scope > .node-container-bottom'));\n const groupTop = group.querySelector<HTMLElement>(':scope > .node-block-children-top');\n this.colorVertical(groupTop);\n if (rowIndex === 0) {\n this.colorRow(row, parentX, childX);\n if (groupTop) this.colorHorizontal(groupTop, parentX, childX);\n } else {\n const railX = rows[0].getBoundingClientRect().left;\n this.colorRow(rows[0], parentX, railX);\n if (groupTop) this.colorHorizontal(groupTop, parentX, railX);\n for (const previousRow of rows.slice(0, rowIndex)) {\n this.colorVertical(previousRow.querySelector<HTMLElement>(':scope > .node-block > .node-block-left'));\n }\n this.colorRow(row, railX, childX);\n }\n }\n }\n\n private colorVertical(element: HTMLElement | null | undefined): void {\n if (!element) return;\n element.classList.add('path-vertical');\n this.highlightedConnectors.add(element);\n }\n\n private colorRow(row: HTMLElement, from: number, to: number): void {\n for (const element of row.querySelectorAll<HTMLElement>(':scope > .node-block > .node-block-top')) {\n this.colorHorizontal(element, from, to);\n }\n }\n\n private colorHorizontal(element: HTMLElement, from: number, to: number): void {\n const style = getComputedStyle(element, '::before');\n if (style.content === 'none') return;\n const bounds = element.getBoundingClientRect();\n const offset = style.left.endsWith('%') ? parseFloat(style.left) * bounds.width / 100 : parseFloat(style.left);\n const width = parseFloat(style.width);\n const start = Math.max(0, Math.min(from, to) - bounds.left - offset);\n const end = Math.min(width, Math.max(from, to) - bounds.left - offset);\n if (end <= start || !Number.isFinite(width)) return;\n element.style.setProperty('--path-horizontal-color', `linear-gradient(to right,\n var(--ngx-mat-organigram-connector, #09293c) ${start}px, var(--ngx-mat-organigram-highlight, #e73452) ${start}px,\n var(--ngx-mat-organigram-highlight, #e73452) ${end}px, var(--ngx-mat-organigram-connector, #09293c) ${end}px)`);\n this.highlightedConnectors.add(element);\n }\n\n ngOnDestroy(): void {\n this.highlightParents(null);\n this.destroyed = true;\n this.treeVersion++;\n this.scrollRender?.destroy();\n }\n\n onKeydown(event: KeyboardEvent, node: OrganigramTreeNode<T>): void {\n if (event.target !== event.currentTarget || (event.key !== 'Enter' && event.key !== ' ')) return;\n event.preventDefault();\n void this.onClick(node);\n }\n\n async onClick(node: OrganigramTreeNode<T>, event?: MouseEvent): Promise<void> {\n if (event && (this.suppressClick || (event.target as HTMLElement).closest('button, input, a, mat-checkbox'))) return;\n if (this.destroyed || this.pendingNodes().has(node)) return;\n const version = this.treeVersion;\n this.pendingNodes.update(pending => new Set([...pending, node]));\n this.nodeErrors.update(errors => { const next = new Map(errors); next.delete(node); return next; });\n try {\n if (node.onClick) {\n const children = await node.onClick(node);\n if (this.destroyed || version !== this.treeVersion) return;\n if (Array.isArray(children)) {\n for (const child of children) node.addChild(child);\n node.hasChildren = node.children.length > 0;\n node.hideChildren = false;\n }\n } else if (this.clickHandler) {\n await this.clickHandler(node);\n } else if (node.hasChildren) node.hideChildren = !node.hideChildren;\n if (this.destroyed || version !== this.treeVersion) return;\n this.scrollToNode(node);\n } catch {\n if (!this.destroyed && version === this.treeVersion) {\n this.nodeErrors.update(errors => new Map(errors).set(node, this.intl.messages().loadError));\n }\n } finally {\n if (!this.destroyed && version === this.treeVersion) {\n this.pendingNodes.update(pending => { const next = new Set(pending); next.delete(node); return next; });\n }\n }\n }\n\n private scrollToNode(node: OrganigramTreeNode<T>): void {\n this.scrollRender?.destroy();\n this.scrollRender = afterNextRender(() => {\n if (this.destroyed) return;\n if (this.hoveredNode) this.highlightParents(this.hoveredNode);\n const element = document.getElementById(node.id);\n if (element && this.host.nativeElement.contains(element)) {\n element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });\n }\n }, { injector: this.injector });\n }\n}\n","<!-- @format -->\n\n<div\n id=\"scroll\"\n #scroll\n [class.dragging]=\"dragging\">\n @if (tree) {\n <div id=\"container\" [class.hide-root]=\"hideRoot\">\n <ng-container\n *ngTemplateOutlet=\"\n nodeBlock;\n context: { depth: 0, node: tree, class: { top: true, bottom: true, left: true, right: true } }\n \"></ng-container>\n </div>\n }\n</div>\n\n<ng-template #nodeBlock let-depth=\"depth\" let-node=\"node\" let-class=\"class\">\n <div class=\"node-block\" [class.depth-even]=\"depth % 2\">\n <div class=\"node-block-top\" [class]=\"class\"></div>\n <div class=\"node-block-left\" [class]=\"class\"></div>\n <div\n [id]=\"node.id\"\n class=\"node-container\"\n [class]=\"class\"\n [attr.role]=\"node.hasChildren || node.onClick || clickHandler ? 'button' : null\"\n [attr.tabindex]=\"node.hasChildren || node.onClick || clickHandler ? 0 : null\"\n [attr.aria-expanded]=\"node.hasChildren ? !node.hideChildren : null\"\n [attr.aria-busy]=\"pendingNodes().has(node)\"\n (mouseenter)=\"highlightParents(node)\"\n (mouseleave)=\"highlightParents(null)\"\n (keydown)=\"onKeydown($event, node)\"\n (click)=\"onClick(node, $event)\">\n <ng-container *ngTemplateOutlet=\"nodeTmpl; context: { node: node }\"></ng-container>\n @if (!node.hideChildren && node.children?.length) {\n <div @toggleTreeNode class=\"node-container-bottom\" [class]=\"class\"></div>\n }\n </div>\n @if (nodeErrors().get(node); as message) {\n <div class=\"node-error\" role=\"alert\">\n <span>{{ message }}</span>\n <button type=\"button\" (click)=\"onClick(node)\">{{ intl.messages().retry }}</button>\n </div>\n }\n @if (!node.hideChildren && node.children?.length) {\n <div @toggleTreeNode class=\"node-block-children\" [class.depth-even]=\"depth % 2\">\n <div class=\"node-block-children-top\" [class]=\"class\" [class.multiple-row]=\"node.children.length > 4\"></div>\n @for (\n row of node.children | organigramRows: nbChildByRow;\n track row;\n let rowIndex = $index;\n let top = $first;\n let bottom = $last\n ) {\n <div class=\"node-block-children-row\" [class.top]=\"top\" [class.bottom]=\"bottom\">\n @for (child of row; track child; let index = $index; let left = $first; let right = $last) {\n <ng-container\n *ngTemplateOutlet=\"\n nodeBlock;\n context: {\n depth: depth + 1,\n node: child,\n class: {\n rowIndex: rowIndex,\n index: index,\n even: index % 2,\n top: top,\n bottom: bottom,\n left: left,\n right: right,\n },\n }\n \">\n </ng-container>\n }\n </div>\n }\n </div>\n }\n </div>\n</ng-template>\n","import { NgModule } from '@angular/core';\nimport { OrganigramComponent } from './organigram.component';\n\n@NgModule({ imports: [OrganigramComponent], exports: [OrganigramComponent] })\nexport class OrganigramModule {}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eherve/angular-material-organigram",
3
- "version": "22.0.0",
3
+ "version": "22.0.1",
4
4
  "author": "Eric Herve <eric.herve.95@gmail.com>",
5
5
  "repository": {
6
6
  "type": "git",