@m1z23r/ngx-ui 1.1.49 → 1.1.51
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/fesm2022/m1z23r-ngx-ui.mjs +398 -25
- package/fesm2022/m1z23r-ngx-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/m1z23r-ngx-ui.d.ts +102 -9
|
@@ -6710,21 +6710,17 @@ class TreeNodeComponent {
|
|
|
6710
6710
|
node = input.required(...(ngDevMode ? [{ debugName: "node" }] : []));
|
|
6711
6711
|
level = input(0, ...(ngDevMode ? [{ debugName: "level" }] : []));
|
|
6712
6712
|
indent = input(16, ...(ngDevMode ? [{ debugName: "indent" }] : []));
|
|
6713
|
+
parentPath = input([], ...(ngDevMode ? [{ debugName: "parentPath" }] : []));
|
|
6713
6714
|
nodeClick = output();
|
|
6714
6715
|
nodeExpand = output();
|
|
6715
6716
|
nodeCollapse = output();
|
|
6716
6717
|
treeHost = inject(TREE_HOST);
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
if (manualState !== null) {
|
|
6721
|
-
return manualState;
|
|
6722
|
-
}
|
|
6723
|
-
return this.node().expanded ?? false;
|
|
6724
|
-
}, ...(ngDevMode ? [{ debugName: "isExpanded" }] : []));
|
|
6718
|
+
contentRef = viewChild('contentRef', ...(ngDevMode ? [{ debugName: "contentRef" }] : []));
|
|
6719
|
+
path = computed(() => [...this.parentPath(), this.node()], ...(ngDevMode ? [{ debugName: "path" }] : []));
|
|
6720
|
+
isExpanded = computed(() => this.treeHost.isExpanded(this.node()), ...(ngDevMode ? [{ debugName: "isExpanded" }] : []));
|
|
6725
6721
|
hasChildren = computed(() => {
|
|
6726
6722
|
const children = this.node().children;
|
|
6727
|
-
return children && children.length > 0;
|
|
6723
|
+
return !!children && children.length > 0;
|
|
6728
6724
|
}, ...(ngDevMode ? [{ debugName: "hasChildren" }] : []));
|
|
6729
6725
|
indentGuides = computed(() => {
|
|
6730
6726
|
const lvl = this.level();
|
|
@@ -6732,24 +6728,26 @@ class TreeNodeComponent {
|
|
|
6732
6728
|
}, ...(ngDevMode ? [{ debugName: "indentGuides" }] : []));
|
|
6733
6729
|
isDraggable = computed(() => this.treeHost.draggable(), ...(ngDevMode ? [{ debugName: "isDraggable" }] : []));
|
|
6734
6730
|
isDragging = computed(() => this.treeHost._dragNode() === this.node(), ...(ngDevMode ? [{ debugName: "isDragging" }] : []));
|
|
6731
|
+
isFlashing = computed(() => this.treeHost._flashNode() === this.node(), ...(ngDevMode ? [{ debugName: "isFlashing" }] : []));
|
|
6735
6732
|
dropPosition = computed(() => {
|
|
6736
6733
|
if (this.treeHost._dragOverNode() === this.node()) {
|
|
6737
6734
|
return this.treeHost._dropPosition();
|
|
6738
6735
|
}
|
|
6739
6736
|
return null;
|
|
6740
6737
|
}, ...(ngDevMode ? [{ debugName: "dropPosition" }] : []));
|
|
6738
|
+
ngAfterViewInit() {
|
|
6739
|
+
const el = this.contentRef()?.nativeElement;
|
|
6740
|
+
if (el)
|
|
6741
|
+
this.treeHost._registerNode(this.node(), el);
|
|
6742
|
+
}
|
|
6743
|
+
ngOnDestroy() {
|
|
6744
|
+
this.treeHost._unregisterNode(this.node());
|
|
6745
|
+
}
|
|
6741
6746
|
toggle(event) {
|
|
6742
6747
|
event.stopPropagation();
|
|
6743
6748
|
if (!this.hasChildren())
|
|
6744
6749
|
return;
|
|
6745
|
-
|
|
6746
|
-
this._expanded.set(newState);
|
|
6747
|
-
if (newState) {
|
|
6748
|
-
this.nodeExpand.emit(this.node());
|
|
6749
|
-
}
|
|
6750
|
-
else {
|
|
6751
|
-
this.nodeCollapse.emit(this.node());
|
|
6752
|
-
}
|
|
6750
|
+
this.treeHost.setExpanded(this.node(), !this.isExpanded());
|
|
6753
6751
|
}
|
|
6754
6752
|
onClick(event) {
|
|
6755
6753
|
event.stopPropagation();
|
|
@@ -6764,6 +6762,13 @@ class TreeNodeComponent {
|
|
|
6764
6762
|
this.toggle(event);
|
|
6765
6763
|
}
|
|
6766
6764
|
}
|
|
6765
|
+
onContextMenu(event) {
|
|
6766
|
+
if (!this.treeHost.contextMenu())
|
|
6767
|
+
return;
|
|
6768
|
+
event.preventDefault();
|
|
6769
|
+
event.stopPropagation();
|
|
6770
|
+
this.treeHost._openContextMenu(this.node(), this.path(), event.clientX, event.clientY);
|
|
6771
|
+
}
|
|
6767
6772
|
onDragStart(event) {
|
|
6768
6773
|
if (!this.isDraggable())
|
|
6769
6774
|
return;
|
|
@@ -6782,7 +6787,6 @@ class TreeNodeComponent {
|
|
|
6782
6787
|
const dragNode = this.treeHost._dragNode();
|
|
6783
6788
|
if (!dragNode)
|
|
6784
6789
|
return;
|
|
6785
|
-
// Prevent dropping on self or own descendants
|
|
6786
6790
|
if (dragNode === this.node() || isDescendantOf(this.node(), dragNode)) {
|
|
6787
6791
|
return;
|
|
6788
6792
|
}
|
|
@@ -6848,12 +6852,12 @@ class TreeNodeComponent {
|
|
|
6848
6852
|
this.nodeCollapse.emit(node);
|
|
6849
6853
|
}
|
|
6850
6854
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TreeNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6851
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TreeNodeComponent, isStandalone: true, selector: "ui-tree-node", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, indent: { classPropertyName: "indent", publicName: "indent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeClick: "nodeClick", nodeExpand: "nodeExpand", nodeCollapse: "nodeCollapse" }, ngImport: i0, template: "<div\n class=\"ui-tree-node\"\n [class.ui-tree-node--dragging]=\"isDragging()\"\n [attr.draggable]=\"isDraggable()\"\n (dragstart)=\"onDragStart($event)\"\n (dragend)=\"onDragEnd()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n <div class=\"ui-tree-node__guides\">\n @for (guide of indentGuides(); track guide) {\n <span class=\"ui-tree-node__guide\" [style.width.px]=\"indent()\"></span>\n }\n </div>\n <div\n class=\"ui-tree-node__content\"\n [class.ui-tree-node__content--selected]=\"false\"\n [class.ui-tree-node__content--drop-before]=\"dropPosition() === 'before'\"\n [class.ui-tree-node__content--drop-after]=\"dropPosition() === 'after'\"\n [class.ui-tree-node__content--drop-inside]=\"dropPosition() === 'inside'\"\n [style.padding-left.px]=\"level() * indent() + 8\"\n (click)=\"onClick($event)\"\n (dblclick)=\"onDoubleClick($event)\"\n >\n @if (hasChildren()) {\n <button\n type=\"button\"\n class=\"ui-tree-node__toggle\"\n [class.ui-tree-node__toggle--expanded]=\"isExpanded()\"\n (click)=\"toggle($event)\"\n [attr.aria-expanded]=\"isExpanded()\"\n [attr.aria-label]=\"isExpanded() ? 'Collapse' : 'Expand'\"\n >\n <svg\n class=\"ui-tree-node__chevron\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 4L10 8L6 12\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n @if (node().icon) {\n <span class=\"ui-tree-node__icon\">{{ node().icon }}</span>\n }\n <span class=\"ui-tree-node__label\">{{ node().label }}</span>\n </div>\n</div>\n@if (isExpanded() && hasChildren()) {\n @for (child of node().children; track child) {\n <ui-tree-node\n [node]=\"child\"\n [level]=\"level() + 1\"\n [indent]=\"indent()\"\n (nodeClick)=\"_onChildNodeClick($event)\"\n (nodeExpand)=\"_onChildNodeExpand($event)\"\n (nodeCollapse)=\"_onChildNodeCollapse($event)\"\n />\n }\n}\n", styles: [":host{display:block}.ui-tree-node{position:relative}.ui-tree-node__guides{position:absolute;top:0;bottom:0;left:0;display:flex;pointer-events:none}.ui-tree-node__guide{position:relative;flex-shrink:0}.ui-tree-node__guide:after{content:\"\";position:absolute;left:50%;top:0;bottom:0;width:1px;background-color:var(--ui-border-hover)}.ui-tree-node__content{display:flex;align-items:center;gap:var(--ui-spacing-xs);padding:var(--ui-spacing-xs) var(--ui-spacing-sm) var(--ui-spacing-xs) 0;border-radius:var(--ui-radius-sm);cursor:pointer;transition:background-color var(--ui-transition-fast)}.ui-tree-node__content:hover{background-color:var(--ui-bg-hover)}.ui-tree-node__content--selected{background-color:var(--ui-option-selected-bg);color:var(--ui-option-selected-text)}.ui-tree-node__toggle{display:flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;border-radius:var(--ui-radius-sm);background:transparent;color:var(--ui-text-muted);cursor:pointer;flex-shrink:0;transition:color var(--ui-transition-fast),background-color var(--ui-transition-fast)}.ui-tree-node__toggle:hover{background-color:var(--ui-bg-hover);color:var(--ui-text)}.ui-tree-node__toggle:focus-visible{outline:2px solid var(--ui-primary);outline-offset:-2px}.ui-tree-node__chevron{transition:transform var(--ui-transition-fast)}.ui-tree-node__toggle--expanded .ui-tree-node__chevron{transform:rotate(90deg)}.ui-tree-node__icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:18px;height:18px;font-size:var(--ui-font-sm);color:var(--ui-text-muted)}.ui-tree-node__label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.4}.ui-tree-node--dragging{opacity:.4}.ui-tree-node__content--drop-before{position:relative}.ui-tree-node__content--drop-before:before{content:\"\";position:absolute;top:0;left:0;right:0;height:2px;background-color:var(--ui-primary);border-radius:1px;pointer-events:none}.ui-tree-node__content--drop-after{position:relative}.ui-tree-node__content--drop-after:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:2px;background-color:var(--ui-primary);border-radius:1px;pointer-events:none}.ui-tree-node__content--drop-inside{background-color:color-mix(in srgb,var(--ui-primary) 10%,transparent);outline:1px solid var(--ui-primary);outline-offset:-1px;border-radius:var(--ui-radius-sm)}\n"], dependencies: [{ kind: "component", type: TreeNodeComponent, selector: "ui-tree-node", inputs: ["node", "level", "indent"], outputs: ["nodeClick", "nodeExpand", "nodeCollapse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6855
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TreeNodeComponent, isStandalone: true, selector: "ui-tree-node", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null }, level: { classPropertyName: "level", publicName: "level", isSignal: true, isRequired: false, transformFunction: null }, indent: { classPropertyName: "indent", publicName: "indent", isSignal: true, isRequired: false, transformFunction: null }, parentPath: { classPropertyName: "parentPath", publicName: "parentPath", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeClick: "nodeClick", nodeExpand: "nodeExpand", nodeCollapse: "nodeCollapse" }, viewQueries: [{ propertyName: "contentRef", first: true, predicate: ["contentRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"ui-tree-node\"\n [class.ui-tree-node--dragging]=\"isDragging()\"\n [attr.draggable]=\"isDraggable()\"\n (dragstart)=\"onDragStart($event)\"\n (dragend)=\"onDragEnd()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n <div class=\"ui-tree-node__guides\">\n @for (guide of indentGuides(); track guide) {\n <span class=\"ui-tree-node__guide\" [style.width.px]=\"indent()\"></span>\n }\n </div>\n <div\n #contentRef\n class=\"ui-tree-node__content\"\n [class.ui-tree-node__content--selected]=\"false\"\n [class.ui-tree-node__content--flash]=\"isFlashing()\"\n [class.ui-tree-node__content--drop-before]=\"dropPosition() === 'before'\"\n [class.ui-tree-node__content--drop-after]=\"dropPosition() === 'after'\"\n [class.ui-tree-node__content--drop-inside]=\"dropPosition() === 'inside'\"\n [style.padding-left.px]=\"level() * indent() + 8\"\n (click)=\"onClick($event)\"\n (dblclick)=\"onDoubleClick($event)\"\n (contextmenu)=\"onContextMenu($event)\"\n >\n @if (hasChildren()) {\n <button\n type=\"button\"\n class=\"ui-tree-node__toggle\"\n [class.ui-tree-node__toggle--expanded]=\"isExpanded()\"\n (click)=\"toggle($event)\"\n [attr.aria-expanded]=\"isExpanded()\"\n [attr.aria-label]=\"isExpanded() ? 'Collapse' : 'Expand'\"\n >\n <svg\n class=\"ui-tree-node__chevron\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 4L10 8L6 12\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n @if (node().icon) {\n <span class=\"ui-tree-node__icon\">{{ node().icon }}</span>\n }\n <span class=\"ui-tree-node__label\">{{ node().label }}</span>\n </div>\n</div>\n@if (isExpanded() && hasChildren()) {\n @for (child of node().children; track child) {\n <ui-tree-node\n [node]=\"child\"\n [level]=\"level() + 1\"\n [indent]=\"indent()\"\n [parentPath]=\"path()\"\n (nodeClick)=\"_onChildNodeClick($event)\"\n (nodeExpand)=\"_onChildNodeExpand($event)\"\n (nodeCollapse)=\"_onChildNodeCollapse($event)\"\n />\n }\n}\n", styles: [":host{display:block}.ui-tree-node{position:relative}.ui-tree-node__guides{position:absolute;top:0;bottom:0;left:0;display:flex;pointer-events:none}.ui-tree-node__guide{position:relative;flex-shrink:0}.ui-tree-node__guide:after{content:\"\";position:absolute;left:50%;top:0;bottom:0;width:1px;background-color:var(--ui-border-hover)}.ui-tree-node__content{display:flex;align-items:center;gap:var(--ui-spacing-xs);padding:var(--ui-spacing-xs) var(--ui-spacing-sm) var(--ui-spacing-xs) 0;border-radius:var(--ui-radius-sm);cursor:pointer;transition:background-color var(--ui-transition-fast)}.ui-tree-node__content:hover{background-color:var(--ui-bg-hover)}.ui-tree-node__content--selected{background-color:var(--ui-option-selected-bg);color:var(--ui-option-selected-text)}.ui-tree-node__toggle{display:flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;border-radius:var(--ui-radius-sm);background:transparent;color:var(--ui-text-muted);cursor:pointer;flex-shrink:0;transition:color var(--ui-transition-fast),background-color var(--ui-transition-fast)}.ui-tree-node__toggle:hover{background-color:var(--ui-bg-hover);color:var(--ui-text)}.ui-tree-node__toggle:focus-visible{outline:2px solid var(--ui-primary);outline-offset:-2px}.ui-tree-node__chevron{transition:transform var(--ui-transition-fast)}.ui-tree-node__toggle--expanded .ui-tree-node__chevron{transform:rotate(90deg)}.ui-tree-node__icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:18px;height:18px;font-size:var(--ui-font-sm);color:var(--ui-text-muted)}.ui-tree-node__label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.4}.ui-tree-node--dragging{opacity:.4}.ui-tree-node__content--drop-before{position:relative}.ui-tree-node__content--drop-before:before{content:\"\";position:absolute;top:0;left:0;right:0;height:2px;background-color:var(--ui-primary);border-radius:1px;pointer-events:none}.ui-tree-node__content--drop-after{position:relative}.ui-tree-node__content--drop-after:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:2px;background-color:var(--ui-primary);border-radius:1px;pointer-events:none}.ui-tree-node__content--drop-inside{background-color:color-mix(in srgb,var(--ui-primary) 10%,transparent);outline:1px solid var(--ui-primary);outline-offset:-1px;border-radius:var(--ui-radius-sm)}.ui-tree-node__content--flash{animation:ui-tree-node-flash 1s ease-out}@keyframes ui-tree-node-flash{0%{background-color:color-mix(in srgb,var(--ui-primary) 40%,transparent)}to{background-color:transparent}}\n"], dependencies: [{ kind: "component", type: TreeNodeComponent, selector: "ui-tree-node", inputs: ["node", "level", "indent", "parentPath"], outputs: ["nodeClick", "nodeExpand", "nodeCollapse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6852
6856
|
}
|
|
6853
6857
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TreeNodeComponent, decorators: [{
|
|
6854
6858
|
type: Component,
|
|
6855
|
-
args: [{ selector: 'ui-tree-node', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"ui-tree-node\"\n [class.ui-tree-node--dragging]=\"isDragging()\"\n [attr.draggable]=\"isDraggable()\"\n (dragstart)=\"onDragStart($event)\"\n (dragend)=\"onDragEnd()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n <div class=\"ui-tree-node__guides\">\n @for (guide of indentGuides(); track guide) {\n <span class=\"ui-tree-node__guide\" [style.width.px]=\"indent()\"></span>\n }\n </div>\n <div\n class=\"ui-tree-node__content\"\n [class.ui-tree-node__content--selected]=\"false\"\n [class.ui-tree-node__content--drop-before]=\"dropPosition() === 'before'\"\n [class.ui-tree-node__content--drop-after]=\"dropPosition() === 'after'\"\n [class.ui-tree-node__content--drop-inside]=\"dropPosition() === 'inside'\"\n [style.padding-left.px]=\"level() * indent() + 8\"\n (click)=\"onClick($event)\"\n (dblclick)=\"onDoubleClick($event)\"\n >\n @if (hasChildren()) {\n <button\n type=\"button\"\n class=\"ui-tree-node__toggle\"\n [class.ui-tree-node__toggle--expanded]=\"isExpanded()\"\n (click)=\"toggle($event)\"\n [attr.aria-expanded]=\"isExpanded()\"\n [attr.aria-label]=\"isExpanded() ? 'Collapse' : 'Expand'\"\n >\n <svg\n class=\"ui-tree-node__chevron\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 4L10 8L6 12\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n @if (node().icon) {\n <span class=\"ui-tree-node__icon\">{{ node().icon }}</span>\n }\n <span class=\"ui-tree-node__label\">{{ node().label }}</span>\n </div>\n</div>\n@if (isExpanded() && hasChildren()) {\n @for (child of node().children; track child) {\n <ui-tree-node\n [node]=\"child\"\n [level]=\"level() + 1\"\n [indent]=\"indent()\"\n (nodeClick)=\"_onChildNodeClick($event)\"\n (nodeExpand)=\"_onChildNodeExpand($event)\"\n (nodeCollapse)=\"_onChildNodeCollapse($event)\"\n />\n }\n}\n", styles: [":host{display:block}.ui-tree-node{position:relative}.ui-tree-node__guides{position:absolute;top:0;bottom:0;left:0;display:flex;pointer-events:none}.ui-tree-node__guide{position:relative;flex-shrink:0}.ui-tree-node__guide:after{content:\"\";position:absolute;left:50%;top:0;bottom:0;width:1px;background-color:var(--ui-border-hover)}.ui-tree-node__content{display:flex;align-items:center;gap:var(--ui-spacing-xs);padding:var(--ui-spacing-xs) var(--ui-spacing-sm) var(--ui-spacing-xs) 0;border-radius:var(--ui-radius-sm);cursor:pointer;transition:background-color var(--ui-transition-fast)}.ui-tree-node__content:hover{background-color:var(--ui-bg-hover)}.ui-tree-node__content--selected{background-color:var(--ui-option-selected-bg);color:var(--ui-option-selected-text)}.ui-tree-node__toggle{display:flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;border-radius:var(--ui-radius-sm);background:transparent;color:var(--ui-text-muted);cursor:pointer;flex-shrink:0;transition:color var(--ui-transition-fast),background-color var(--ui-transition-fast)}.ui-tree-node__toggle:hover{background-color:var(--ui-bg-hover);color:var(--ui-text)}.ui-tree-node__toggle:focus-visible{outline:2px solid var(--ui-primary);outline-offset:-2px}.ui-tree-node__chevron{transition:transform var(--ui-transition-fast)}.ui-tree-node__toggle--expanded .ui-tree-node__chevron{transform:rotate(90deg)}.ui-tree-node__icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:18px;height:18px;font-size:var(--ui-font-sm);color:var(--ui-text-muted)}.ui-tree-node__label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.4}.ui-tree-node--dragging{opacity:.4}.ui-tree-node__content--drop-before{position:relative}.ui-tree-node__content--drop-before:before{content:\"\";position:absolute;top:0;left:0;right:0;height:2px;background-color:var(--ui-primary);border-radius:1px;pointer-events:none}.ui-tree-node__content--drop-after{position:relative}.ui-tree-node__content--drop-after:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:2px;background-color:var(--ui-primary);border-radius:1px;pointer-events:none}.ui-tree-node__content--drop-inside{background-color:color-mix(in srgb,var(--ui-primary) 10%,transparent);outline:1px solid var(--ui-primary);outline-offset:-1px;border-radius:var(--ui-radius-sm)}\n"] }]
|
|
6856
|
-
}], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: true }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }], indent: [{ type: i0.Input, args: [{ isSignal: true, alias: "indent", required: false }] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }], nodeExpand: [{ type: i0.Output, args: ["nodeExpand"] }], nodeCollapse: [{ type: i0.Output, args: ["nodeCollapse"] }] } });
|
|
6859
|
+
args: [{ selector: 'ui-tree-node', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"ui-tree-node\"\n [class.ui-tree-node--dragging]=\"isDragging()\"\n [attr.draggable]=\"isDraggable()\"\n (dragstart)=\"onDragStart($event)\"\n (dragend)=\"onDragEnd()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n <div class=\"ui-tree-node__guides\">\n @for (guide of indentGuides(); track guide) {\n <span class=\"ui-tree-node__guide\" [style.width.px]=\"indent()\"></span>\n }\n </div>\n <div\n #contentRef\n class=\"ui-tree-node__content\"\n [class.ui-tree-node__content--selected]=\"false\"\n [class.ui-tree-node__content--flash]=\"isFlashing()\"\n [class.ui-tree-node__content--drop-before]=\"dropPosition() === 'before'\"\n [class.ui-tree-node__content--drop-after]=\"dropPosition() === 'after'\"\n [class.ui-tree-node__content--drop-inside]=\"dropPosition() === 'inside'\"\n [style.padding-left.px]=\"level() * indent() + 8\"\n (click)=\"onClick($event)\"\n (dblclick)=\"onDoubleClick($event)\"\n (contextmenu)=\"onContextMenu($event)\"\n >\n @if (hasChildren()) {\n <button\n type=\"button\"\n class=\"ui-tree-node__toggle\"\n [class.ui-tree-node__toggle--expanded]=\"isExpanded()\"\n (click)=\"toggle($event)\"\n [attr.aria-expanded]=\"isExpanded()\"\n [attr.aria-label]=\"isExpanded() ? 'Collapse' : 'Expand'\"\n >\n <svg\n class=\"ui-tree-node__chevron\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 4L10 8L6 12\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n }\n @if (node().icon) {\n <span class=\"ui-tree-node__icon\">{{ node().icon }}</span>\n }\n <span class=\"ui-tree-node__label\">{{ node().label }}</span>\n </div>\n</div>\n@if (isExpanded() && hasChildren()) {\n @for (child of node().children; track child) {\n <ui-tree-node\n [node]=\"child\"\n [level]=\"level() + 1\"\n [indent]=\"indent()\"\n [parentPath]=\"path()\"\n (nodeClick)=\"_onChildNodeClick($event)\"\n (nodeExpand)=\"_onChildNodeExpand($event)\"\n (nodeCollapse)=\"_onChildNodeCollapse($event)\"\n />\n }\n}\n", styles: [":host{display:block}.ui-tree-node{position:relative}.ui-tree-node__guides{position:absolute;top:0;bottom:0;left:0;display:flex;pointer-events:none}.ui-tree-node__guide{position:relative;flex-shrink:0}.ui-tree-node__guide:after{content:\"\";position:absolute;left:50%;top:0;bottom:0;width:1px;background-color:var(--ui-border-hover)}.ui-tree-node__content{display:flex;align-items:center;gap:var(--ui-spacing-xs);padding:var(--ui-spacing-xs) var(--ui-spacing-sm) var(--ui-spacing-xs) 0;border-radius:var(--ui-radius-sm);cursor:pointer;transition:background-color var(--ui-transition-fast)}.ui-tree-node__content:hover{background-color:var(--ui-bg-hover)}.ui-tree-node__content--selected{background-color:var(--ui-option-selected-bg);color:var(--ui-option-selected-text)}.ui-tree-node__toggle{display:flex;align-items:center;justify-content:center;width:20px;height:20px;padding:0;border:none;border-radius:var(--ui-radius-sm);background:transparent;color:var(--ui-text-muted);cursor:pointer;flex-shrink:0;transition:color var(--ui-transition-fast),background-color var(--ui-transition-fast)}.ui-tree-node__toggle:hover{background-color:var(--ui-bg-hover);color:var(--ui-text)}.ui-tree-node__toggle:focus-visible{outline:2px solid var(--ui-primary);outline-offset:-2px}.ui-tree-node__chevron{transition:transform var(--ui-transition-fast)}.ui-tree-node__toggle--expanded .ui-tree-node__chevron{transform:rotate(90deg)}.ui-tree-node__icon{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:18px;height:18px;font-size:var(--ui-font-sm);color:var(--ui-text-muted)}.ui-tree-node__label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.4}.ui-tree-node--dragging{opacity:.4}.ui-tree-node__content--drop-before{position:relative}.ui-tree-node__content--drop-before:before{content:\"\";position:absolute;top:0;left:0;right:0;height:2px;background-color:var(--ui-primary);border-radius:1px;pointer-events:none}.ui-tree-node__content--drop-after{position:relative}.ui-tree-node__content--drop-after:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:2px;background-color:var(--ui-primary);border-radius:1px;pointer-events:none}.ui-tree-node__content--drop-inside{background-color:color-mix(in srgb,var(--ui-primary) 10%,transparent);outline:1px solid var(--ui-primary);outline-offset:-1px;border-radius:var(--ui-radius-sm)}.ui-tree-node__content--flash{animation:ui-tree-node-flash 1s ease-out}@keyframes ui-tree-node-flash{0%{background-color:color-mix(in srgb,var(--ui-primary) 40%,transparent)}to{background-color:transparent}}\n"] }]
|
|
6860
|
+
}], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: true }] }], level: [{ type: i0.Input, args: [{ isSignal: true, alias: "level", required: false }] }], indent: [{ type: i0.Input, args: [{ isSignal: true, alias: "indent", required: false }] }], parentPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentPath", required: false }] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }], nodeExpand: [{ type: i0.Output, args: ["nodeExpand"] }], nodeCollapse: [{ type: i0.Output, args: ["nodeCollapse"] }], contentRef: [{ type: i0.ViewChild, args: ['contentRef', { isSignal: true }] }] } });
|
|
6857
6861
|
|
|
6858
6862
|
const TREE_HOST = new InjectionToken('TREE_HOST');
|
|
6859
6863
|
class TreeComponent {
|
|
@@ -6861,10 +6865,16 @@ class TreeComponent {
|
|
|
6861
6865
|
indent = input(16, ...(ngDevMode ? [{ debugName: "indent" }] : []));
|
|
6862
6866
|
draggable = input(false, ...(ngDevMode ? [{ debugName: "draggable" }] : []));
|
|
6863
6867
|
expandOnClick = input(false, ...(ngDevMode ? [{ debugName: "expandOnClick" }] : []));
|
|
6868
|
+
contextMenu = input(false, ...(ngDevMode ? [{ debugName: "contextMenu" }] : []));
|
|
6869
|
+
pathSeparator = input(' / ', ...(ngDevMode ? [{ debugName: "pathSeparator" }] : []));
|
|
6870
|
+
valueFormatter = input(null, ...(ngDevMode ? [{ debugName: "valueFormatter" }] : []));
|
|
6871
|
+
pathFormatter = input(null, ...(ngDevMode ? [{ debugName: "pathFormatter" }] : []));
|
|
6872
|
+
objectFormatter = input(null, ...(ngDevMode ? [{ debugName: "objectFormatter" }] : []));
|
|
6864
6873
|
nodeClick = output();
|
|
6865
6874
|
nodeExpand = output();
|
|
6866
6875
|
nodeCollapse = output();
|
|
6867
6876
|
nodeDrop = output();
|
|
6877
|
+
nodeContextAction = output();
|
|
6868
6878
|
/** @internal */
|
|
6869
6879
|
_dragNode = signal(null, ...(ngDevMode ? [{ debugName: "_dragNode" }] : []));
|
|
6870
6880
|
/** @internal */
|
|
@@ -6872,6 +6882,53 @@ class TreeComponent {
|
|
|
6872
6882
|
/** @internal */
|
|
6873
6883
|
_dropPosition = signal(null, ...(ngDevMode ? [{ debugName: "_dropPosition" }] : []));
|
|
6874
6884
|
/** @internal */
|
|
6885
|
+
_flashNode = signal(null, ...(ngDevMode ? [{ debugName: "_flashNode" }] : []));
|
|
6886
|
+
/** @internal context-menu target — node and its path (root → node, inclusive) */
|
|
6887
|
+
_menuNode = signal(null, ...(ngDevMode ? [{ debugName: "_menuNode" }] : []));
|
|
6888
|
+
/** @internal */
|
|
6889
|
+
_menuPath = signal([], ...(ngDevMode ? [{ debugName: "_menuPath" }] : []));
|
|
6890
|
+
/** @internal whether the targeted node has children (drives expand/collapse-all visibility) */
|
|
6891
|
+
_menuHasChildren = computed(() => {
|
|
6892
|
+
const n = this._menuNode();
|
|
6893
|
+
return !!n?.children && n.children.length > 0;
|
|
6894
|
+
}, ...(ngDevMode ? [{ debugName: "_menuHasChildren" }] : []));
|
|
6895
|
+
/** @internal whether the targeted node has a parent (drives go-to/collapse-parent visibility) */
|
|
6896
|
+
_menuHasParent = computed(() => this._menuPath().length > 1, ...(ngDevMode ? [{ debugName: "_menuHasParent" }] : []));
|
|
6897
|
+
_expansion = signal(new Map(), ...(ngDevMode ? [{ debugName: "_expansion" }] : []));
|
|
6898
|
+
_nodeElements = new WeakMap();
|
|
6899
|
+
flashTimer = null;
|
|
6900
|
+
menu = viewChild('treeMenu', ...(ngDevMode ? [{ debugName: "menu" }] : []));
|
|
6901
|
+
isExpanded(node) {
|
|
6902
|
+
const override = this._expansion().get(node);
|
|
6903
|
+
return override ?? (node.expanded ?? false);
|
|
6904
|
+
}
|
|
6905
|
+
setExpanded(node, value) {
|
|
6906
|
+
const current = this.isExpanded(node);
|
|
6907
|
+
if (current === value)
|
|
6908
|
+
return;
|
|
6909
|
+
const next = new Map(this._expansion());
|
|
6910
|
+
next.set(node, value);
|
|
6911
|
+
this._expansion.set(next);
|
|
6912
|
+
if (value) {
|
|
6913
|
+
this.nodeExpand.emit(node);
|
|
6914
|
+
}
|
|
6915
|
+
else {
|
|
6916
|
+
this.nodeCollapse.emit(node);
|
|
6917
|
+
}
|
|
6918
|
+
}
|
|
6919
|
+
expandSubtree(node, value) {
|
|
6920
|
+
const next = new Map(this._expansion());
|
|
6921
|
+
const walk = (n) => {
|
|
6922
|
+
if (!n.children?.length)
|
|
6923
|
+
return;
|
|
6924
|
+
next.set(n, value);
|
|
6925
|
+
for (const c of n.children)
|
|
6926
|
+
walk(c);
|
|
6927
|
+
};
|
|
6928
|
+
walk(node);
|
|
6929
|
+
this._expansion.set(next);
|
|
6930
|
+
}
|
|
6931
|
+
/** @internal */
|
|
6875
6932
|
_onNodeClick(node) {
|
|
6876
6933
|
this.nodeClick.emit(node);
|
|
6877
6934
|
}
|
|
@@ -6887,13 +6944,329 @@ class TreeComponent {
|
|
|
6887
6944
|
_emitDrop(event) {
|
|
6888
6945
|
this.nodeDrop.emit(event);
|
|
6889
6946
|
}
|
|
6947
|
+
/** @internal */
|
|
6948
|
+
_registerNode(node, el) {
|
|
6949
|
+
this._nodeElements.set(node, el);
|
|
6950
|
+
}
|
|
6951
|
+
/** @internal */
|
|
6952
|
+
_unregisterNode(node) {
|
|
6953
|
+
this._nodeElements.delete(node);
|
|
6954
|
+
}
|
|
6955
|
+
/** @internal */
|
|
6956
|
+
_openContextMenu(node, path, x, y) {
|
|
6957
|
+
this._menuNode.set(node);
|
|
6958
|
+
this._menuPath.set(path);
|
|
6959
|
+
this.menu()?.openAt(x, y);
|
|
6960
|
+
}
|
|
6961
|
+
/** @internal */
|
|
6962
|
+
_runAction(action) {
|
|
6963
|
+
const node = this._menuNode();
|
|
6964
|
+
const path = this._menuPath();
|
|
6965
|
+
if (!node)
|
|
6966
|
+
return;
|
|
6967
|
+
switch (action) {
|
|
6968
|
+
case 'copyValue': {
|
|
6969
|
+
const text = this.valueFormatter()?.(node, path) ?? node.label;
|
|
6970
|
+
this.copyToClipboard(text);
|
|
6971
|
+
break;
|
|
6972
|
+
}
|
|
6973
|
+
case 'copyPath': {
|
|
6974
|
+
const text = this.pathFormatter()?.(node, path) ??
|
|
6975
|
+
path.map((n) => n.label).join(this.pathSeparator());
|
|
6976
|
+
this.copyToClipboard(text);
|
|
6977
|
+
break;
|
|
6978
|
+
}
|
|
6979
|
+
case 'copyObject': {
|
|
6980
|
+
const text = this.objectFormatter()?.(node, path) ?? this.serializeNode(node);
|
|
6981
|
+
this.copyToClipboard(text);
|
|
6982
|
+
break;
|
|
6983
|
+
}
|
|
6984
|
+
case 'expandAll':
|
|
6985
|
+
this.expandSubtree(node, true);
|
|
6986
|
+
break;
|
|
6987
|
+
case 'collapseAll':
|
|
6988
|
+
this.expandSubtree(node, false);
|
|
6989
|
+
break;
|
|
6990
|
+
case 'goToParent': {
|
|
6991
|
+
const parent = path[path.length - 2];
|
|
6992
|
+
if (parent)
|
|
6993
|
+
this.scrollAndFlash(parent);
|
|
6994
|
+
break;
|
|
6995
|
+
}
|
|
6996
|
+
case 'collapseParent': {
|
|
6997
|
+
const parent = path[path.length - 2];
|
|
6998
|
+
if (parent)
|
|
6999
|
+
this.setExpanded(parent, false);
|
|
7000
|
+
break;
|
|
7001
|
+
}
|
|
7002
|
+
}
|
|
7003
|
+
this.nodeContextAction.emit({ node, path, action });
|
|
7004
|
+
}
|
|
7005
|
+
serializeNode(node) {
|
|
7006
|
+
const value = node.data !== undefined ? node.data : this.sanitize(node);
|
|
7007
|
+
try {
|
|
7008
|
+
return JSON.stringify(value, null, 2);
|
|
7009
|
+
}
|
|
7010
|
+
catch {
|
|
7011
|
+
return String(value);
|
|
7012
|
+
}
|
|
7013
|
+
}
|
|
7014
|
+
sanitize(node) {
|
|
7015
|
+
return {
|
|
7016
|
+
label: node.label,
|
|
7017
|
+
...(node.icon !== undefined ? { icon: node.icon } : {}),
|
|
7018
|
+
...(node.children?.length ? { children: node.children.map((c) => this.sanitize(c)) } : {}),
|
|
7019
|
+
};
|
|
7020
|
+
}
|
|
7021
|
+
scrollAndFlash(node) {
|
|
7022
|
+
const el = this._nodeElements.get(node);
|
|
7023
|
+
if (el) {
|
|
7024
|
+
el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
7025
|
+
}
|
|
7026
|
+
this._flashNode.set(node);
|
|
7027
|
+
if (this.flashTimer)
|
|
7028
|
+
clearTimeout(this.flashTimer);
|
|
7029
|
+
this.flashTimer = setTimeout(() => {
|
|
7030
|
+
this._flashNode.set(null);
|
|
7031
|
+
this.flashTimer = null;
|
|
7032
|
+
}, 1000);
|
|
7033
|
+
}
|
|
7034
|
+
copyToClipboard(text) {
|
|
7035
|
+
if (navigator.clipboard?.writeText) {
|
|
7036
|
+
navigator.clipboard.writeText(text).catch(() => this.execCommandCopy(text));
|
|
7037
|
+
}
|
|
7038
|
+
else {
|
|
7039
|
+
this.execCommandCopy(text);
|
|
7040
|
+
}
|
|
7041
|
+
}
|
|
7042
|
+
execCommandCopy(text) {
|
|
7043
|
+
const ta = document.createElement('textarea');
|
|
7044
|
+
ta.value = text;
|
|
7045
|
+
ta.setAttribute('readonly', '');
|
|
7046
|
+
ta.style.position = 'fixed';
|
|
7047
|
+
ta.style.opacity = '0';
|
|
7048
|
+
document.body.appendChild(ta);
|
|
7049
|
+
ta.select();
|
|
7050
|
+
try {
|
|
7051
|
+
document.execCommand('copy');
|
|
7052
|
+
}
|
|
7053
|
+
finally {
|
|
7054
|
+
document.body.removeChild(ta);
|
|
7055
|
+
}
|
|
7056
|
+
}
|
|
6890
7057
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6891
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TreeComponent, isStandalone: true, selector: "ui-tree", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: false, transformFunction: null }, indent: { classPropertyName: "indent", publicName: "indent", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, expandOnClick: { classPropertyName: "expandOnClick", publicName: "expandOnClick", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeClick: "nodeClick", nodeExpand: "nodeExpand", nodeCollapse: "nodeCollapse", nodeDrop: "nodeDrop" }, providers: [{ provide: TREE_HOST, useExisting: TreeComponent }], ngImport: i0, template: "<div class=\"ui-tree\">\n @for (node of nodes(); track node) {\n <ui-tree-node\n [node]=\"node\"\n [level]=\"0\"\n [indent]=\"indent()\"\n (nodeClick)=\"_onNodeClick($event)\"\n (nodeExpand)=\"_onNodeExpand($event)\"\n (nodeCollapse)=\"_onNodeCollapse($event)\"\n />\n }\n</div>\n", styles: [":host{display:block}.ui-tree{font-size:var(--ui-font-sm);color:var(--ui-text);-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "component", type: TreeNodeComponent, selector: "ui-tree-node", inputs: ["node", "level", "indent"], outputs: ["nodeClick", "nodeExpand", "nodeCollapse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7058
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TreeComponent, isStandalone: true, selector: "ui-tree", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: false, transformFunction: null }, indent: { classPropertyName: "indent", publicName: "indent", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, expandOnClick: { classPropertyName: "expandOnClick", publicName: "expandOnClick", isSignal: true, isRequired: false, transformFunction: null }, contextMenu: { classPropertyName: "contextMenu", publicName: "contextMenu", isSignal: true, isRequired: false, transformFunction: null }, pathSeparator: { classPropertyName: "pathSeparator", publicName: "pathSeparator", isSignal: true, isRequired: false, transformFunction: null }, valueFormatter: { classPropertyName: "valueFormatter", publicName: "valueFormatter", isSignal: true, isRequired: false, transformFunction: null }, pathFormatter: { classPropertyName: "pathFormatter", publicName: "pathFormatter", isSignal: true, isRequired: false, transformFunction: null }, objectFormatter: { classPropertyName: "objectFormatter", publicName: "objectFormatter", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeClick: "nodeClick", nodeExpand: "nodeExpand", nodeCollapse: "nodeCollapse", nodeDrop: "nodeDrop", nodeContextAction: "nodeContextAction" }, providers: [{ provide: TREE_HOST, useExisting: TreeComponent }], viewQueries: [{ propertyName: "menu", first: true, predicate: ["treeMenu"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ui-tree\">\n @for (node of nodes(); track node) {\n <ui-tree-node\n [node]=\"node\"\n [level]=\"0\"\n [indent]=\"indent()\"\n [parentPath]=\"[]\"\n (nodeClick)=\"_onNodeClick($event)\"\n (nodeExpand)=\"_onNodeExpand($event)\"\n (nodeCollapse)=\"_onNodeCollapse($event)\"\n />\n }\n</div>\n\n@if (contextMenu()) {\n <ui-dropdown #treeMenu>\n <ui-dropdown-item (clicked)=\"_runAction('copyValue')\">Copy value</ui-dropdown-item>\n <ui-dropdown-item (clicked)=\"_runAction('copyPath')\">Copy path</ui-dropdown-item>\n <ui-dropdown-item (clicked)=\"_runAction('copyObject')\">Copy object</ui-dropdown-item>\n @if (_menuHasChildren()) {\n <ui-dropdown-divider />\n <ui-dropdown-item (clicked)=\"_runAction('expandAll')\">Expand all</ui-dropdown-item>\n <ui-dropdown-item (clicked)=\"_runAction('collapseAll')\">Collapse all</ui-dropdown-item>\n }\n @if (_menuHasParent()) {\n <ui-dropdown-divider />\n <ui-dropdown-item (clicked)=\"_runAction('goToParent')\">Go to parent</ui-dropdown-item>\n <ui-dropdown-item (clicked)=\"_runAction('collapseParent')\">Collapse parent</ui-dropdown-item>\n }\n </ui-dropdown>\n}\n", styles: [":host{display:block}.ui-tree{font-size:var(--ui-font-sm);color:var(--ui-text);-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "component", type: TreeNodeComponent, selector: "ui-tree-node", inputs: ["node", "level", "indent", "parentPath"], outputs: ["nodeClick", "nodeExpand", "nodeCollapse"] }, { kind: "component", type: DropdownComponent, selector: "ui-dropdown", inputs: ["position", "closeOnSelect", "matchTriggerWidth"] }, { kind: "component", type: DropdownItemComponent, selector: "ui-dropdown-item", inputs: ["disabled", "icon"], outputs: ["clicked"] }, { kind: "component", type: DropdownDividerComponent, selector: "ui-dropdown-divider" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6892
7059
|
}
|
|
6893
7060
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TreeComponent, decorators: [{
|
|
6894
7061
|
type: Component,
|
|
6895
|
-
args: [{ selector: 'ui-tree', standalone: true, imports: [TreeNodeComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: TREE_HOST, useExisting: TreeComponent }], template: "<div class=\"ui-tree\">\n @for (node of nodes(); track node) {\n <ui-tree-node\n [node]=\"node\"\n [level]=\"0\"\n [indent]=\"indent()\"\n (nodeClick)=\"_onNodeClick($event)\"\n (nodeExpand)=\"_onNodeExpand($event)\"\n (nodeCollapse)=\"_onNodeCollapse($event)\"\n />\n }\n</div>\n", styles: [":host{display:block}.ui-tree{font-size:var(--ui-font-sm);color:var(--ui-text);-webkit-user-select:none;user-select:none}\n"] }]
|
|
6896
|
-
}], propDecorators: { nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: false }] }], indent: [{ type: i0.Input, args: [{ isSignal: true, alias: "indent", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], expandOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandOnClick", required: false }] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }], nodeExpand: [{ type: i0.Output, args: ["nodeExpand"] }], nodeCollapse: [{ type: i0.Output, args: ["nodeCollapse"] }], nodeDrop: [{ type: i0.Output, args: ["nodeDrop"] }] } });
|
|
7062
|
+
args: [{ selector: 'ui-tree', standalone: true, imports: [TreeNodeComponent, DropdownComponent, DropdownItemComponent, DropdownDividerComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: TREE_HOST, useExisting: TreeComponent }], template: "<div class=\"ui-tree\">\n @for (node of nodes(); track node) {\n <ui-tree-node\n [node]=\"node\"\n [level]=\"0\"\n [indent]=\"indent()\"\n [parentPath]=\"[]\"\n (nodeClick)=\"_onNodeClick($event)\"\n (nodeExpand)=\"_onNodeExpand($event)\"\n (nodeCollapse)=\"_onNodeCollapse($event)\"\n />\n }\n</div>\n\n@if (contextMenu()) {\n <ui-dropdown #treeMenu>\n <ui-dropdown-item (clicked)=\"_runAction('copyValue')\">Copy value</ui-dropdown-item>\n <ui-dropdown-item (clicked)=\"_runAction('copyPath')\">Copy path</ui-dropdown-item>\n <ui-dropdown-item (clicked)=\"_runAction('copyObject')\">Copy object</ui-dropdown-item>\n @if (_menuHasChildren()) {\n <ui-dropdown-divider />\n <ui-dropdown-item (clicked)=\"_runAction('expandAll')\">Expand all</ui-dropdown-item>\n <ui-dropdown-item (clicked)=\"_runAction('collapseAll')\">Collapse all</ui-dropdown-item>\n }\n @if (_menuHasParent()) {\n <ui-dropdown-divider />\n <ui-dropdown-item (clicked)=\"_runAction('goToParent')\">Go to parent</ui-dropdown-item>\n <ui-dropdown-item (clicked)=\"_runAction('collapseParent')\">Collapse parent</ui-dropdown-item>\n }\n </ui-dropdown>\n}\n", styles: [":host{display:block}.ui-tree{font-size:var(--ui-font-sm);color:var(--ui-text);-webkit-user-select:none;user-select:none}\n"] }]
|
|
7063
|
+
}], propDecorators: { nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: false }] }], indent: [{ type: i0.Input, args: [{ isSignal: true, alias: "indent", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], expandOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandOnClick", required: false }] }], contextMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextMenu", required: false }] }], pathSeparator: [{ type: i0.Input, args: [{ isSignal: true, alias: "pathSeparator", required: false }] }], valueFormatter: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueFormatter", required: false }] }], pathFormatter: [{ type: i0.Input, args: [{ isSignal: true, alias: "pathFormatter", required: false }] }], objectFormatter: [{ type: i0.Input, args: [{ isSignal: true, alias: "objectFormatter", required: false }] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }], nodeExpand: [{ type: i0.Output, args: ["nodeExpand"] }], nodeCollapse: [{ type: i0.Output, args: ["nodeCollapse"] }], nodeDrop: [{ type: i0.Output, args: ["nodeDrop"] }], nodeContextAction: [{ type: i0.Output, args: ["nodeContextAction"] }], menu: [{ type: i0.ViewChild, args: ['treeMenu', { isSignal: true }] }] } });
|
|
7064
|
+
|
|
7065
|
+
const IDENT_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
7066
|
+
function isIdentifier(key) {
|
|
7067
|
+
return IDENT_RE.test(key);
|
|
7068
|
+
}
|
|
7069
|
+
function appendKey(path, key) {
|
|
7070
|
+
return isIdentifier(key) ? (path ? `${path}.${key}` : key) : `${path}[${JSON.stringify(key)}]`;
|
|
7071
|
+
}
|
|
7072
|
+
function appendIndex(path, i) {
|
|
7073
|
+
return `${path}[${i}]`;
|
|
7074
|
+
}
|
|
7075
|
+
function prettyPrimitive(v) {
|
|
7076
|
+
if (v === null)
|
|
7077
|
+
return 'null';
|
|
7078
|
+
if (v === undefined)
|
|
7079
|
+
return 'undefined';
|
|
7080
|
+
if (typeof v === 'string')
|
|
7081
|
+
return JSON.stringify(v);
|
|
7082
|
+
if (typeof v === 'number' || typeof v === 'boolean' || typeof v === 'bigint')
|
|
7083
|
+
return String(v);
|
|
7084
|
+
if (v instanceof Date)
|
|
7085
|
+
return JSON.stringify(v.toISOString());
|
|
7086
|
+
return String(v);
|
|
7087
|
+
}
|
|
7088
|
+
function safeStringify(v) {
|
|
7089
|
+
try {
|
|
7090
|
+
return JSON.stringify(v, replacer(), 2);
|
|
7091
|
+
}
|
|
7092
|
+
catch {
|
|
7093
|
+
return String(v);
|
|
7094
|
+
}
|
|
7095
|
+
}
|
|
7096
|
+
function replacer() {
|
|
7097
|
+
const seen = new WeakSet();
|
|
7098
|
+
return function (_key, value) {
|
|
7099
|
+
if (typeof value === 'bigint')
|
|
7100
|
+
return value.toString();
|
|
7101
|
+
if (typeof value === 'object' && value !== null) {
|
|
7102
|
+
if (seen.has(value))
|
|
7103
|
+
return '[Circular]';
|
|
7104
|
+
seen.add(value);
|
|
7105
|
+
}
|
|
7106
|
+
return value;
|
|
7107
|
+
};
|
|
7108
|
+
}
|
|
7109
|
+
function kindOf(v) {
|
|
7110
|
+
if (Array.isArray(v))
|
|
7111
|
+
return 'array';
|
|
7112
|
+
if (v !== null && typeof v === 'object')
|
|
7113
|
+
return 'object';
|
|
7114
|
+
return 'primitive';
|
|
7115
|
+
}
|
|
7116
|
+
function sizeLabel(kind, value) {
|
|
7117
|
+
if (kind === 'array')
|
|
7118
|
+
return `[${value.length}]`;
|
|
7119
|
+
if (kind === 'object')
|
|
7120
|
+
return `{${Object.keys(value).length}}`;
|
|
7121
|
+
return prettyPrimitive(value);
|
|
7122
|
+
}
|
|
7123
|
+
function makeLabel(keyPart, kind, value, isRoot) {
|
|
7124
|
+
const size = sizeLabel(kind, value);
|
|
7125
|
+
if (kind === 'primitive') {
|
|
7126
|
+
if (isRoot)
|
|
7127
|
+
return keyPart ? `${keyPart}: ${size}` : size;
|
|
7128
|
+
return keyPart ? `${keyPart}: ${size}` : size;
|
|
7129
|
+
}
|
|
7130
|
+
// object / array
|
|
7131
|
+
return keyPart ? `${keyPart} ${size}` : size;
|
|
7132
|
+
}
|
|
7133
|
+
/**
|
|
7134
|
+
* Convert an arbitrary JSON-shaped value into a TreeNode array suitable for
|
|
7135
|
+
* `<ui-tree [nodes]>`. Each generated node carries a `data: JsonNodeMeta`.
|
|
7136
|
+
*
|
|
7137
|
+
* Returns a single-element array containing the root node.
|
|
7138
|
+
*/
|
|
7139
|
+
function jsonToTreeNodes(value, options = {}) {
|
|
7140
|
+
const rootLabel = options.rootLabel ?? '';
|
|
7141
|
+
const pathRoot = options.pathRoot ?? '';
|
|
7142
|
+
const expandDepth = options.expandDepth ?? 1;
|
|
7143
|
+
const ancestors = new WeakSet();
|
|
7144
|
+
const root = build(value, null, rootLabel, pathRoot, 0, expandDepth, ancestors, true);
|
|
7145
|
+
return [root];
|
|
7146
|
+
}
|
|
7147
|
+
function build(value, key, keyPart, path, depth, expandDepth, ancestors, isRoot) {
|
|
7148
|
+
// Detect cycles: only if `value` is one of our ancestors in this DFS path.
|
|
7149
|
+
if (value !== null && typeof value === 'object' && ancestors.has(value)) {
|
|
7150
|
+
const placeholder = '[Circular]';
|
|
7151
|
+
return {
|
|
7152
|
+
label: keyPart ? `${keyPart}: "${placeholder}"` : `"${placeholder}"`,
|
|
7153
|
+
data: {
|
|
7154
|
+
key,
|
|
7155
|
+
value: placeholder,
|
|
7156
|
+
kind: 'primitive',
|
|
7157
|
+
jsonPath: path,
|
|
7158
|
+
},
|
|
7159
|
+
};
|
|
7160
|
+
}
|
|
7161
|
+
const kind = kindOf(value);
|
|
7162
|
+
const label = makeLabel(keyPart, kind, value, isRoot);
|
|
7163
|
+
const expanded = isRoot ? true : depth <= expandDepth;
|
|
7164
|
+
const node = {
|
|
7165
|
+
label,
|
|
7166
|
+
expanded,
|
|
7167
|
+
data: { key, value, kind, jsonPath: path },
|
|
7168
|
+
};
|
|
7169
|
+
if (kind === 'object' || kind === 'array') {
|
|
7170
|
+
ancestors.add(value);
|
|
7171
|
+
if (kind === 'object') {
|
|
7172
|
+
const obj = value;
|
|
7173
|
+
const keys = Object.keys(obj);
|
|
7174
|
+
if (keys.length > 0) {
|
|
7175
|
+
node.children = keys.map((k) => build(obj[k], k, k, appendKey(path, k), depth + 1, expandDepth, ancestors, false));
|
|
7176
|
+
}
|
|
7177
|
+
}
|
|
7178
|
+
else {
|
|
7179
|
+
const arr = value;
|
|
7180
|
+
if (arr.length > 0) {
|
|
7181
|
+
node.children = arr.map((v, i) => build(v, i, `[${i}]`, appendIndex(path, i), depth + 1, expandDepth, ancestors, false));
|
|
7182
|
+
}
|
|
7183
|
+
}
|
|
7184
|
+
ancestors.delete(value);
|
|
7185
|
+
}
|
|
7186
|
+
return node;
|
|
7187
|
+
}
|
|
7188
|
+
|
|
7189
|
+
class JsonTreeComponent {
|
|
7190
|
+
json = input(undefined, ...(ngDevMode ? [{ debugName: "json" }] : []));
|
|
7191
|
+
rootLabel = input('', ...(ngDevMode ? [{ debugName: "rootLabel" }] : []));
|
|
7192
|
+
pathRoot = input('', ...(ngDevMode ? [{ debugName: "pathRoot" }] : []));
|
|
7193
|
+
expandDepth = input(1, ...(ngDevMode ? [{ debugName: "expandDepth" }] : []));
|
|
7194
|
+
indent = input(16, ...(ngDevMode ? [{ debugName: "indent" }] : []));
|
|
7195
|
+
draggable = input(false, ...(ngDevMode ? [{ debugName: "draggable" }] : []));
|
|
7196
|
+
expandOnClick = input(false, ...(ngDevMode ? [{ debugName: "expandOnClick" }] : []));
|
|
7197
|
+
contextMenu = input(true, ...(ngDevMode ? [{ debugName: "contextMenu" }] : []));
|
|
7198
|
+
nodeClick = output();
|
|
7199
|
+
nodeContextAction = output();
|
|
7200
|
+
nodes = computed(() => jsonToTreeNodes(this.json(), {
|
|
7201
|
+
rootLabel: this.rootLabel(),
|
|
7202
|
+
pathRoot: this.pathRoot(),
|
|
7203
|
+
expandDepth: this.expandDepth(),
|
|
7204
|
+
}), ...(ngDevMode ? [{ debugName: "nodes" }] : []));
|
|
7205
|
+
valueFmt = (node) => {
|
|
7206
|
+
const meta = node.data;
|
|
7207
|
+
if (!meta)
|
|
7208
|
+
return null;
|
|
7209
|
+
if (meta.kind === 'primitive') {
|
|
7210
|
+
const v = meta.value;
|
|
7211
|
+
if (v === null)
|
|
7212
|
+
return 'null';
|
|
7213
|
+
if (v === undefined)
|
|
7214
|
+
return 'undefined';
|
|
7215
|
+
if (typeof v === 'string')
|
|
7216
|
+
return v;
|
|
7217
|
+
if (typeof v === 'bigint')
|
|
7218
|
+
return v.toString();
|
|
7219
|
+
return String(v);
|
|
7220
|
+
}
|
|
7221
|
+
return safeStringify(meta.value);
|
|
7222
|
+
};
|
|
7223
|
+
pathFmt = (node) => {
|
|
7224
|
+
const meta = node.data;
|
|
7225
|
+
return meta ? meta.jsonPath : null;
|
|
7226
|
+
};
|
|
7227
|
+
objectFmt = (node) => {
|
|
7228
|
+
const meta = node.data;
|
|
7229
|
+
return meta ? safeStringify(meta.value) : null;
|
|
7230
|
+
};
|
|
7231
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: JsonTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
7232
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.1", type: JsonTreeComponent, isStandalone: true, selector: "ui-json-tree", inputs: { json: { classPropertyName: "json", publicName: "json", isSignal: true, isRequired: false, transformFunction: null }, rootLabel: { classPropertyName: "rootLabel", publicName: "rootLabel", isSignal: true, isRequired: false, transformFunction: null }, pathRoot: { classPropertyName: "pathRoot", publicName: "pathRoot", isSignal: true, isRequired: false, transformFunction: null }, expandDepth: { classPropertyName: "expandDepth", publicName: "expandDepth", isSignal: true, isRequired: false, transformFunction: null }, indent: { classPropertyName: "indent", publicName: "indent", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, expandOnClick: { classPropertyName: "expandOnClick", publicName: "expandOnClick", isSignal: true, isRequired: false, transformFunction: null }, contextMenu: { classPropertyName: "contextMenu", publicName: "contextMenu", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeClick: "nodeClick", nodeContextAction: "nodeContextAction" }, ngImport: i0, template: `
|
|
7233
|
+
<ui-tree
|
|
7234
|
+
[nodes]="nodes()"
|
|
7235
|
+
[indent]="indent()"
|
|
7236
|
+
[draggable]="draggable()"
|
|
7237
|
+
[expandOnClick]="expandOnClick()"
|
|
7238
|
+
[contextMenu]="contextMenu()"
|
|
7239
|
+
[valueFormatter]="valueFmt"
|
|
7240
|
+
[pathFormatter]="pathFmt"
|
|
7241
|
+
[objectFormatter]="objectFmt"
|
|
7242
|
+
(nodeClick)="nodeClick.emit($event)"
|
|
7243
|
+
(nodeContextAction)="nodeContextAction.emit($event)"
|
|
7244
|
+
/>
|
|
7245
|
+
`, isInline: true, dependencies: [{ kind: "component", type: TreeComponent, selector: "ui-tree", inputs: ["nodes", "indent", "draggable", "expandOnClick", "contextMenu", "pathSeparator", "valueFormatter", "pathFormatter", "objectFormatter"], outputs: ["nodeClick", "nodeExpand", "nodeCollapse", "nodeDrop", "nodeContextAction"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
7246
|
+
}
|
|
7247
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: JsonTreeComponent, decorators: [{
|
|
7248
|
+
type: Component,
|
|
7249
|
+
args: [{
|
|
7250
|
+
selector: 'ui-json-tree',
|
|
7251
|
+
standalone: true,
|
|
7252
|
+
imports: [TreeComponent],
|
|
7253
|
+
template: `
|
|
7254
|
+
<ui-tree
|
|
7255
|
+
[nodes]="nodes()"
|
|
7256
|
+
[indent]="indent()"
|
|
7257
|
+
[draggable]="draggable()"
|
|
7258
|
+
[expandOnClick]="expandOnClick()"
|
|
7259
|
+
[contextMenu]="contextMenu()"
|
|
7260
|
+
[valueFormatter]="valueFmt"
|
|
7261
|
+
[pathFormatter]="pathFmt"
|
|
7262
|
+
[objectFormatter]="objectFmt"
|
|
7263
|
+
(nodeClick)="nodeClick.emit($event)"
|
|
7264
|
+
(nodeContextAction)="nodeContextAction.emit($event)"
|
|
7265
|
+
/>
|
|
7266
|
+
`,
|
|
7267
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
7268
|
+
}]
|
|
7269
|
+
}], propDecorators: { json: [{ type: i0.Input, args: [{ isSignal: true, alias: "json", required: false }] }], rootLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "rootLabel", required: false }] }], pathRoot: [{ type: i0.Input, args: [{ isSignal: true, alias: "pathRoot", required: false }] }], expandDepth: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandDepth", required: false }] }], indent: [{ type: i0.Input, args: [{ isSignal: true, alias: "indent", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], expandOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandOnClick", required: false }] }], contextMenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "contextMenu", required: false }] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }], nodeContextAction: [{ type: i0.Output, args: ["nodeContextAction"] }] } });
|
|
6897
7270
|
|
|
6898
7271
|
/** Directive to mark a custom variable popover template */
|
|
6899
7272
|
class VariablePopoverDirective {
|
|
@@ -7294,5 +7667,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
|
|
|
7294
7667
|
* Generated bundle index. Do not edit.
|
|
7295
7668
|
*/
|
|
7296
7669
|
|
|
7297
|
-
export { AccordionComponent, AccordionHeaderDirective, AccordionItemComponent, AlertComponent, BadgeComponent, ButtonComponent, CardComponent, CellTemplateDirective, CellValuePipe, CheckboxComponent, ChipInputComponent, ChipTemplateDirective, CircularProgressComponent, ContentComponent, ContextMenuDirective, DIALOG_DATA, DIALOG_REF, DatepickerComponent, DatetimepickerComponent, DialogRef, DialogService, DropdownComponent, DropdownDividerComponent, DropdownItemComponent, DropdownTriggerDirective, DynamicTabsComponent, FileChooserComponent, FilePreviewPipe, FileSizePipe, FooterComponent, InputComponent, LOADABLE, LoadingDirective, LoadingService, ModalComponent, NavbarComponent, OptionComponent, OptionTemplateDirective, PaginationComponent, ProgressComponent, RadioComponent, RadioGroupComponent, RangeSliderComponent, SelectComponent, ShellComponent, SidebarComponent, SidebarService, SidebarToggleComponent, SliderComponent, SpinnerComponent, SplitComponent, SplitPaneComponent, SwitchComponent, TAB_DATA, TAB_REF, TREE_HOST, TabActivePipe, TabComponent, TabIconDirective, TabRef, TableComponent, TabsComponent, TabsService, TemplateInputComponent, TemplateInputSuffixDirective, TextareaComponent, TimepickerComponent, ToastRef, ToastService, TooltipDirective, TreeComponent, TreeNodeComponent, Validators, VariablePopoverDirective };
|
|
7670
|
+
export { AccordionComponent, AccordionHeaderDirective, AccordionItemComponent, AlertComponent, BadgeComponent, ButtonComponent, CardComponent, CellTemplateDirective, CellValuePipe, CheckboxComponent, ChipInputComponent, ChipTemplateDirective, CircularProgressComponent, ContentComponent, ContextMenuDirective, DIALOG_DATA, DIALOG_REF, DatepickerComponent, DatetimepickerComponent, DialogRef, DialogService, DropdownComponent, DropdownDividerComponent, DropdownItemComponent, DropdownTriggerDirective, DynamicTabsComponent, FileChooserComponent, FilePreviewPipe, FileSizePipe, FooterComponent, InputComponent, JsonTreeComponent, LOADABLE, LoadingDirective, LoadingService, ModalComponent, NavbarComponent, OptionComponent, OptionTemplateDirective, PaginationComponent, ProgressComponent, RadioComponent, RadioGroupComponent, RangeSliderComponent, SelectComponent, ShellComponent, SidebarComponent, SidebarService, SidebarToggleComponent, SliderComponent, SpinnerComponent, SplitComponent, SplitPaneComponent, SwitchComponent, TAB_DATA, TAB_REF, TREE_HOST, TabActivePipe, TabComponent, TabIconDirective, TabRef, TableComponent, TabsComponent, TabsService, TemplateInputComponent, TemplateInputSuffixDirective, TextareaComponent, TimepickerComponent, ToastRef, ToastService, TooltipDirective, TreeComponent, TreeNodeComponent, Validators, VariablePopoverDirective, jsonToTreeNodes };
|
|
7298
7671
|
//# sourceMappingURL=m1z23r-ngx-ui.mjs.map
|