@acorex/components 21.0.0-next.37 → 21.0.0-next.38
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/accordion/index.d.ts +1 -0
- package/button-group/index.d.ts +4 -6
- package/chips/index.d.ts +8 -3
- package/dialog/index.d.ts +1 -1
- package/fesm2022/acorex-components-accordion.mjs +21 -16
- package/fesm2022/acorex-components-accordion.mjs.map +1 -1
- package/fesm2022/acorex-components-action-sheet.mjs +12 -12
- package/fesm2022/acorex-components-action-sheet.mjs.map +1 -1
- package/fesm2022/acorex-components-alert.mjs +13 -13
- package/fesm2022/acorex-components-alert.mjs.map +1 -1
- package/fesm2022/acorex-components-aspect-ratio.mjs +3 -3
- package/fesm2022/acorex-components-aspect-ratio.mjs.map +1 -1
- package/fesm2022/acorex-components-audio-wave.mjs +10 -11
- package/fesm2022/acorex-components-audio-wave.mjs.map +1 -1
- package/fesm2022/acorex-components-autocomplete.mjs +7 -7
- package/fesm2022/acorex-components-autocomplete.mjs.map +1 -1
- package/fesm2022/acorex-components-avatar.mjs +12 -12
- package/fesm2022/acorex-components-avatar.mjs.map +1 -1
- package/fesm2022/acorex-components-badge.mjs +9 -9
- package/fesm2022/acorex-components-badge.mjs.map +1 -1
- package/fesm2022/acorex-components-bottom-navigation.mjs +11 -11
- package/fesm2022/acorex-components-bottom-navigation.mjs.map +1 -1
- package/fesm2022/acorex-components-breadcrumbs.mjs +11 -11
- package/fesm2022/acorex-components-breadcrumbs.mjs.map +1 -1
- package/fesm2022/acorex-components-button-group.mjs +19 -23
- package/fesm2022/acorex-components-button-group.mjs.map +1 -1
- package/fesm2022/acorex-components-button.mjs +18 -18
- package/fesm2022/acorex-components-button.mjs.map +1 -1
- package/fesm2022/acorex-components-calendar.mjs +17 -17
- package/fesm2022/acorex-components-calendar.mjs.map +1 -1
- package/fesm2022/acorex-components-check-box.mjs +10 -10
- package/fesm2022/acorex-components-check-box.mjs.map +1 -1
- package/fesm2022/acorex-components-chips.mjs +14 -12
- package/fesm2022/acorex-components-chips.mjs.map +1 -1
- package/fesm2022/acorex-components-circular-progress.mjs +10 -12
- package/fesm2022/acorex-components-circular-progress.mjs.map +1 -1
- package/fesm2022/acorex-components-code-editor.mjs +10 -10
- package/fesm2022/acorex-components-code-editor.mjs.map +1 -1
- package/fesm2022/acorex-components-collapse.mjs +13 -13
- package/fesm2022/acorex-components-collapse.mjs.map +1 -1
- package/fesm2022/acorex-components-color-box.mjs +9 -9
- package/fesm2022/acorex-components-color-box.mjs.map +1 -1
- package/fesm2022/acorex-components-color-palette.mjs +30 -30
- package/fesm2022/acorex-components-color-palette.mjs.map +1 -1
- package/fesm2022/acorex-components-command.mjs +9 -9
- package/fesm2022/acorex-components-command.mjs.map +1 -1
- package/fesm2022/acorex-components-comment.mjs +32 -32
- package/fesm2022/acorex-components-comment.mjs.map +1 -1
- package/fesm2022/acorex-components-conversation.mjs +51 -51
- package/fesm2022/acorex-components-conversation.mjs.map +1 -1
- package/fesm2022/acorex-components-conversation2.mjs +186 -186
- package/fesm2022/acorex-components-conversation2.mjs.map +1 -1
- package/fesm2022/acorex-components-cron-job.mjs +46 -46
- package/fesm2022/acorex-components-cron-job.mjs.map +1 -1
- package/fesm2022/acorex-components-data-list.mjs +3 -3
- package/fesm2022/acorex-components-data-list.mjs.map +1 -1
- package/fesm2022/acorex-components-data-pager.mjs +33 -33
- package/fesm2022/acorex-components-data-pager.mjs.map +1 -1
- package/fesm2022/acorex-components-data-table.mjs +43 -43
- package/fesm2022/acorex-components-data-table.mjs.map +1 -1
- package/fesm2022/acorex-components-datetime-box.mjs +9 -9
- package/fesm2022/acorex-components-datetime-box.mjs.map +1 -1
- package/fesm2022/acorex-components-datetime-input.mjs +9 -9
- package/fesm2022/acorex-components-datetime-input.mjs.map +1 -1
- package/fesm2022/acorex-components-datetime-picker.mjs +9 -9
- package/fesm2022/acorex-components-datetime-picker.mjs.map +1 -1
- package/fesm2022/acorex-components-decorators.mjs +36 -43
- package/fesm2022/acorex-components-decorators.mjs.map +1 -1
- package/fesm2022/acorex-components-dialog.mjs +14 -15
- package/fesm2022/acorex-components-dialog.mjs.map +1 -1
- package/fesm2022/acorex-components-drawer-legacy.mjs +13 -13
- package/fesm2022/acorex-components-drawer-legacy.mjs.map +1 -1
- package/fesm2022/acorex-components-drawer.mjs +16 -15
- package/fesm2022/acorex-components-drawer.mjs.map +1 -1
- package/fesm2022/acorex-components-dropdown-button.mjs +9 -9
- package/fesm2022/acorex-components-dropdown-button.mjs.map +1 -1
- package/fesm2022/acorex-components-dropdown.mjs +16 -18
- package/fesm2022/acorex-components-dropdown.mjs.map +1 -1
- package/fesm2022/acorex-components-editor.mjs +11 -11
- package/fesm2022/acorex-components-editor.mjs.map +1 -1
- package/fesm2022/acorex-components-file-explorer.mjs +32 -32
- package/fesm2022/acorex-components-file-explorer.mjs.map +1 -1
- package/fesm2022/acorex-components-flow-chart.mjs +16 -16
- package/fesm2022/acorex-components-flow-chart.mjs.map +1 -1
- package/fesm2022/acorex-components-form.mjs +24 -32
- package/fesm2022/acorex-components-form.mjs.map +1 -1
- package/fesm2022/acorex-components-grid-layout-builder.mjs +13 -12
- package/fesm2022/acorex-components-grid-layout-builder.mjs.map +1 -1
- package/fesm2022/acorex-components-image-editor.mjs +47 -46
- package/fesm2022/acorex-components-image-editor.mjs.map +1 -1
- package/fesm2022/acorex-components-image.mjs +9 -9
- package/fesm2022/acorex-components-image.mjs.map +1 -1
- package/fesm2022/acorex-components-json-viewer.mjs +8 -8
- package/fesm2022/acorex-components-json-viewer.mjs.map +1 -1
- package/fesm2022/acorex-components-kanban.mjs +6 -8
- package/fesm2022/acorex-components-kanban.mjs.map +1 -1
- package/fesm2022/acorex-components-kbd.mjs +7 -7
- package/fesm2022/acorex-components-kbd.mjs.map +1 -1
- package/fesm2022/acorex-components-label.mjs +9 -9
- package/fesm2022/acorex-components-label.mjs.map +1 -1
- package/fesm2022/acorex-components-list.mjs +9 -9
- package/fesm2022/acorex-components-list.mjs.map +1 -1
- package/fesm2022/acorex-components-loading-dialog.mjs +12 -12
- package/fesm2022/acorex-components-loading-dialog.mjs.map +1 -1
- package/fesm2022/acorex-components-loading.mjs +23 -23
- package/fesm2022/acorex-components-loading.mjs.map +1 -1
- package/fesm2022/acorex-components-map.mjs +289 -31
- package/fesm2022/acorex-components-map.mjs.map +1 -1
- package/fesm2022/acorex-components-media-viewer.mjs +41 -41
- package/fesm2022/acorex-components-media-viewer.mjs.map +1 -1
- package/fesm2022/acorex-components-menu.mjs +21 -21
- package/fesm2022/acorex-components-menu.mjs.map +1 -1
- package/fesm2022/{acorex-components-modal-acorex-components-modal-BmmAkCKJ.mjs → acorex-components-modal-acorex-components-modal-iYSPzoLn.mjs} +22 -22
- package/fesm2022/acorex-components-modal-acorex-components-modal-iYSPzoLn.mjs.map +1 -0
- package/fesm2022/acorex-components-modal-modal-content.component-sZWKhYM-.mjs +212 -0
- package/fesm2022/acorex-components-modal-modal-content.component-sZWKhYM-.mjs.map +1 -0
- package/fesm2022/acorex-components-modal.mjs +1 -1
- package/fesm2022/acorex-components-navbar.mjs +9 -9
- package/fesm2022/acorex-components-navbar.mjs.map +1 -1
- package/fesm2022/acorex-components-notification.mjs +23 -16
- package/fesm2022/acorex-components-notification.mjs.map +1 -1
- package/fesm2022/acorex-components-number-box-legacy.mjs +9 -9
- package/fesm2022/acorex-components-number-box-legacy.mjs.map +1 -1
- package/fesm2022/acorex-components-number-box.mjs +9 -9
- package/fesm2022/acorex-components-number-box.mjs.map +1 -1
- package/fesm2022/acorex-components-otp.mjs +9 -9
- package/fesm2022/acorex-components-otp.mjs.map +1 -1
- package/fesm2022/acorex-components-page.mjs +10 -10
- package/fesm2022/acorex-components-page.mjs.map +1 -1
- package/fesm2022/acorex-components-paint.mjs +39 -34
- package/fesm2022/acorex-components-paint.mjs.map +1 -1
- package/fesm2022/acorex-components-password-box.mjs +12 -12
- package/fesm2022/acorex-components-password-box.mjs.map +1 -1
- package/fesm2022/acorex-components-pdf-reader.mjs +8 -8
- package/fesm2022/acorex-components-pdf-reader.mjs.map +1 -1
- package/fesm2022/acorex-components-phone-box.mjs +9 -9
- package/fesm2022/acorex-components-phone-box.mjs.map +1 -1
- package/fesm2022/acorex-components-picker.mjs +15 -15
- package/fesm2022/acorex-components-picker.mjs.map +1 -1
- package/fesm2022/acorex-components-popover.mjs +11 -11
- package/fesm2022/acorex-components-popover.mjs.map +1 -1
- package/fesm2022/acorex-components-popup.mjs +13 -13
- package/fesm2022/acorex-components-popup.mjs.map +1 -1
- package/fesm2022/acorex-components-progress-bar.mjs +9 -11
- package/fesm2022/acorex-components-progress-bar.mjs.map +1 -1
- package/fesm2022/acorex-components-qrcode.mjs +7 -7
- package/fesm2022/acorex-components-qrcode.mjs.map +1 -1
- package/fesm2022/acorex-components-query-builder.mjs +8 -8
- package/fesm2022/acorex-components-query-builder.mjs.map +1 -1
- package/fesm2022/acorex-components-radio.mjs +7 -7
- package/fesm2022/acorex-components-radio.mjs.map +1 -1
- package/fesm2022/acorex-components-rail-navigation.mjs +36 -38
- package/fesm2022/acorex-components-rail-navigation.mjs.map +1 -1
- package/fesm2022/acorex-components-range-slider.mjs +10 -10
- package/fesm2022/acorex-components-range-slider.mjs.map +1 -1
- package/fesm2022/acorex-components-rate-picker.mjs +35 -20
- package/fesm2022/acorex-components-rate-picker.mjs.map +1 -1
- package/fesm2022/acorex-components-rest-api-generator.mjs +22 -22
- package/fesm2022/acorex-components-rest-api-generator.mjs.map +1 -1
- package/fesm2022/acorex-components-result.mjs +8 -8
- package/fesm2022/acorex-components-result.mjs.map +1 -1
- package/fesm2022/acorex-components-routing-progress.mjs +8 -8
- package/fesm2022/acorex-components-routing-progress.mjs.map +1 -1
- package/fesm2022/acorex-components-rrule.mjs +9 -9
- package/fesm2022/acorex-components-rrule.mjs.map +1 -1
- package/fesm2022/acorex-components-scheduler-picker.mjs +56 -56
- package/fesm2022/acorex-components-scheduler-picker.mjs.map +1 -1
- package/fesm2022/acorex-components-scheduler.mjs +43 -43
- package/fesm2022/acorex-components-scheduler.mjs.map +1 -1
- package/fesm2022/acorex-components-scss.mjs +4 -4
- package/fesm2022/acorex-components-scss.mjs.map +1 -1
- package/fesm2022/acorex-components-search-box.mjs +10 -16
- package/fesm2022/acorex-components-search-box.mjs.map +1 -1
- package/fesm2022/acorex-components-select-box.mjs +9 -11
- package/fesm2022/acorex-components-select-box.mjs.map +1 -1
- package/fesm2022/acorex-components-selection-list-2.mjs +11 -11
- package/fesm2022/acorex-components-selection-list-2.mjs.map +1 -1
- package/fesm2022/acorex-components-selection-list.mjs +9 -9
- package/fesm2022/acorex-components-selection-list.mjs.map +1 -1
- package/fesm2022/acorex-components-side-menu.mjs +14 -14
- package/fesm2022/acorex-components-side-menu.mjs.map +1 -1
- package/fesm2022/acorex-components-skeleton.mjs +8 -8
- package/fesm2022/acorex-components-skeleton.mjs.map +1 -1
- package/fesm2022/acorex-components-slider.mjs +10 -10
- package/fesm2022/acorex-components-slider.mjs.map +1 -1
- package/fesm2022/acorex-components-sliding-item.mjs +14 -14
- package/fesm2022/acorex-components-sliding-item.mjs.map +1 -1
- package/fesm2022/acorex-components-step-wizard.mjs +14 -14
- package/fesm2022/acorex-components-step-wizard.mjs.map +1 -1
- package/fesm2022/acorex-components-switch.mjs +14 -14
- package/fesm2022/acorex-components-switch.mjs.map +1 -1
- package/fesm2022/acorex-components-tabs.mjs +15 -15
- package/fesm2022/acorex-components-tabs.mjs.map +1 -1
- package/fesm2022/acorex-components-tag-box.mjs +9 -9
- package/fesm2022/acorex-components-tag-box.mjs.map +1 -1
- package/fesm2022/acorex-components-tag.mjs +9 -9
- package/fesm2022/acorex-components-tag.mjs.map +1 -1
- package/fesm2022/acorex-components-text-area.mjs +9 -9
- package/fesm2022/acorex-components-text-area.mjs.map +1 -1
- package/fesm2022/acorex-components-text-box.mjs +12 -12
- package/fesm2022/acorex-components-text-box.mjs.map +1 -1
- package/fesm2022/acorex-components-time-duration.mjs +7 -7
- package/fesm2022/acorex-components-time-duration.mjs.map +1 -1
- package/fesm2022/acorex-components-time-line.mjs +12 -12
- package/fesm2022/acorex-components-time-line.mjs.map +1 -1
- package/fesm2022/acorex-components-toast.mjs +14 -14
- package/fesm2022/acorex-components-toast.mjs.map +1 -1
- package/fesm2022/acorex-components-toolbar.mjs +8 -8
- package/fesm2022/acorex-components-toolbar.mjs.map +1 -1
- package/fesm2022/acorex-components-tooltip.mjs +11 -11
- package/fesm2022/acorex-components-tooltip.mjs.map +1 -1
- package/fesm2022/acorex-components-tree-view-legacy.mjs +511 -0
- package/fesm2022/acorex-components-tree-view-legacy.mjs.map +1 -0
- package/fesm2022/acorex-components-tree-view.mjs +1126 -400
- package/fesm2022/acorex-components-tree-view.mjs.map +1 -1
- package/fesm2022/acorex-components-uploader.mjs +16 -16
- package/fesm2022/acorex-components-uploader.mjs.map +1 -1
- package/fesm2022/acorex-components-video-player.mjs +7 -7
- package/fesm2022/acorex-components-video-player.mjs.map +1 -1
- package/fesm2022/acorex-components-wysiwyg.mjs +42 -42
- package/fesm2022/acorex-components-wysiwyg.mjs.map +1 -1
- package/fesm2022/acorex-components.mjs.map +1 -1
- package/file-explorer/index.d.ts +6 -6
- package/grid-layout-builder/index.d.ts +2 -1
- package/loading/index.d.ts +1 -1
- package/map/index.d.ts +28 -1
- package/notification/index.d.ts +2 -0
- package/package.json +6 -6
- package/paint/index.d.ts +6 -1
- package/rate-picker/index.d.ts +15 -5
- package/tree-view/index.d.ts +499 -168
- package/tree-view-legacy/README.md +3 -0
- package/tree-view-legacy/index.d.ts +184 -0
- package/fesm2022/acorex-components-modal-acorex-components-modal-BmmAkCKJ.mjs.map +0 -1
- package/fesm2022/acorex-components-modal-modal-content.component-5GqTzNOs.mjs +0 -214
- package/fesm2022/acorex-components-modal-modal-content.component-5GqTzNOs.mjs.map +0 -1
- package/fesm2022/acorex-components-tree2.mjs +0 -730
- package/fesm2022/acorex-components-tree2.mjs.map +0 -1
- package/tree2/README.md +0 -3
- package/tree2/index.d.ts +0 -346
|
@@ -1,505 +1,1231 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { moveItemInArray, transferArrayItem, AXDragDirective, AXDragHandleDirective, AXDropListDirective } from '@acorex/cdk/drag-drop';
|
|
2
|
+
import { AXFocusTrapDirective } from '@acorex/cdk/focus-trap';
|
|
3
|
+
import { AXBadgeComponent } from '@acorex/components/badge';
|
|
4
|
+
import { AXButtonComponent } from '@acorex/components/button';
|
|
5
|
+
import { AXCheckBoxComponent } from '@acorex/components/check-box';
|
|
6
|
+
import { AXDecoratorIconComponent } from '@acorex/components/decorators';
|
|
4
7
|
import { AXPlatform } from '@acorex/core/platform';
|
|
5
|
-
import { AXTranslatorPipe } from '@acorex/core/translation';
|
|
6
8
|
import * as i1 from '@angular/common';
|
|
7
|
-
import { CommonModule, NgTemplateOutlet
|
|
9
|
+
import { CommonModule, NgTemplateOutlet } from '@angular/common';
|
|
8
10
|
import * as i0 from '@angular/core';
|
|
9
|
-
import { inject,
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import * as i1$1 from '@angular/forms';
|
|
11
|
+
import { Injectable, inject, DestroyRef, model, input, output, signal, computed, effect, afterNextRender, ViewEncapsulation, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
|
|
12
|
+
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
13
|
+
import * as i2 from '@angular/forms';
|
|
13
14
|
import { FormsModule } from '@angular/forms';
|
|
14
|
-
import {
|
|
15
|
+
import { map } from 'rxjs/operators';
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (this.isExpanded()) {
|
|
38
|
-
return `${baseClasses} ax-icon-chevron-down`;
|
|
17
|
+
/**
|
|
18
|
+
* Service for tree node operations
|
|
19
|
+
* Handles all business logic for tree node manipulation
|
|
20
|
+
*/
|
|
21
|
+
class AXTreeViewService {
|
|
22
|
+
// ==================== Constants ====================
|
|
23
|
+
static { this.ROOT_LIST_ID = 'ax-tree-view-root-list'; }
|
|
24
|
+
static { this.NODE_DROP_PREFIX = 'ax-tree-view-node-drop-'; }
|
|
25
|
+
static { this.LIST_PREFIX = 'ax-tree-view-list-'; }
|
|
26
|
+
// ==================== Node Finding & Traversal ====================
|
|
27
|
+
/**
|
|
28
|
+
* Find a node by ID in the tree
|
|
29
|
+
*/
|
|
30
|
+
findNodeById(nodes, id) {
|
|
31
|
+
for (const node of nodes) {
|
|
32
|
+
if (node.id === id)
|
|
33
|
+
return node;
|
|
34
|
+
if (node.children) {
|
|
35
|
+
const found = this.findNodeById(node.children, id);
|
|
36
|
+
if (found)
|
|
37
|
+
return found;
|
|
39
38
|
}
|
|
40
|
-
return this.platformService.isRtl()
|
|
41
|
-
? `${baseClasses} ax-icon-chevron-left`
|
|
42
|
-
: `${baseClasses} ax-icon-chevron-right`;
|
|
43
|
-
}, ...(ngDevMode ? [{ debugName: "arrowIcon" }] : []));
|
|
44
|
-
}
|
|
45
|
-
handleArrowNodeClick() {
|
|
46
|
-
if (this.item()[this.treeView.disableField()] || this.isLoading() || this.treeView.expandOn() === 'dbClick') {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
this.isExpanded.set(!this.isExpanded());
|
|
50
|
-
if (this.treeView.itemsPromise && this.isExpanded() && !this.item()[this.treeView.childrenField()]?.length) {
|
|
51
|
-
this.treeView.fetchData(this.item());
|
|
52
|
-
this.treeView.setNodeLoading(this.item()[this.treeView.valueField()], true);
|
|
53
39
|
}
|
|
54
|
-
|
|
40
|
+
return null;
|
|
55
41
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Find parent node of a given node
|
|
44
|
+
*/
|
|
45
|
+
findParentNode(nodes, targetNode) {
|
|
46
|
+
for (const node of nodes) {
|
|
47
|
+
if (node.children?.some((child) => child.id === targetNode.id)) {
|
|
48
|
+
return node;
|
|
49
|
+
}
|
|
50
|
+
if (node.children) {
|
|
51
|
+
const found = this.findParentNode(node.children, targetNode);
|
|
52
|
+
if (found)
|
|
53
|
+
return found;
|
|
54
|
+
}
|
|
59
55
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check if targetNode is a descendant of ancestorNode (or the same node)
|
|
60
|
+
* Prevents circular references by checking if target exists in ancestor's children tree
|
|
61
|
+
*/
|
|
62
|
+
isValidDropTarget(movedNode, targetNode) {
|
|
63
|
+
if (movedNode.id === targetNode.id || this.isNodeDescendantOf(targetNode, movedNode)) {
|
|
64
|
+
return false;
|
|
63
65
|
}
|
|
64
|
-
|
|
66
|
+
return true;
|
|
65
67
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Check if targetNode is a descendant of ancestorNode
|
|
70
|
+
*/
|
|
71
|
+
isNodeDescendantOf(targetNode, ancestorNode) {
|
|
72
|
+
if (targetNode.id === ancestorNode.id) {
|
|
73
|
+
return true;
|
|
69
74
|
}
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
if (!ancestorNode.children || ancestorNode.children.length === 0) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
for (const child of ancestorNode.children) {
|
|
79
|
+
if (child.id === targetNode.id) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
if (this.isNodeDescendantOf(targetNode, child)) {
|
|
83
|
+
return true;
|
|
75
84
|
}
|
|
76
85
|
}
|
|
77
|
-
|
|
78
|
-
this.treeView.onCollapsedChanged.emit({ component: this, data: this.item(), nativeElement: this.nativeElement });
|
|
86
|
+
return false;
|
|
79
87
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
this.items = input(...(ngDevMode ? [undefined, { debugName: "items" }] : []));
|
|
93
|
-
this.showCheckbox = input(true, ...(ngDevMode ? [{ debugName: "showCheckbox" }] : []));
|
|
94
|
-
this.hasCheckboxField = input('hasCheckbox', ...(ngDevMode ? [{ debugName: "hasCheckboxField" }] : []));
|
|
95
|
-
this.selectionMode = input('single', ...(ngDevMode ? [{ debugName: "selectionMode" }] : []));
|
|
96
|
-
this.selectionBehavior = input(...(ngDevMode ? [undefined, { debugName: "selectionBehavior" }] : []));
|
|
97
|
-
this.selectionScope = input('all', ...(ngDevMode ? [{ debugName: "selectionScope" }] : []));
|
|
98
|
-
this.focusNodeEnabled = input(true, ...(ngDevMode ? [{ debugName: "focusNodeEnabled" }] : []));
|
|
99
|
-
this.valueField = input('id', ...(ngDevMode ? [{ debugName: "valueField" }] : []));
|
|
100
|
-
this.textField = input('text', ...(ngDevMode ? [{ debugName: "textField" }] : []));
|
|
101
|
-
this.visibleField = input('visible', ...(ngDevMode ? [{ debugName: "visibleField" }] : []));
|
|
102
|
-
this.disableField = input('disabled', ...(ngDevMode ? [{ debugName: "disableField" }] : []));
|
|
103
|
-
this.hasChildField = input('hasChild', ...(ngDevMode ? [{ debugName: "hasChildField" }] : []));
|
|
104
|
-
this.selectedField = input('selected', ...(ngDevMode ? [{ debugName: "selectedField" }] : []));
|
|
105
|
-
this.expandedField = input('expanded', ...(ngDevMode ? [{ debugName: "expandedField" }] : []));
|
|
106
|
-
this.tooltipField = input('tooltip', ...(ngDevMode ? [{ debugName: "tooltipField" }] : []));
|
|
107
|
-
this.childrenField = input('children', ...(ngDevMode ? [{ debugName: "childrenField" }] : []));
|
|
108
|
-
this.activeField = input('active', ...(ngDevMode ? [{ debugName: "activeField" }] : []));
|
|
109
|
-
this.indeterminateField = input('indeterminate', ...(ngDevMode ? [{ debugName: "indeterminateField" }] : []));
|
|
110
|
-
this.parentField = input('parentId', ...(ngDevMode ? [{ debugName: "parentField" }] : []));
|
|
111
|
-
this.iconField = input('icon', ...(ngDevMode ? [{ debugName: "iconField" }] : []));
|
|
112
|
-
this.toggleIcons = input(...(ngDevMode ? [undefined, { debugName: "toggleIcons" }] : []));
|
|
113
|
-
this.look = input('defult', ...(ngDevMode ? [{ debugName: "look" }] : []));
|
|
114
|
-
this.showEmptyNodeMassage = input(false, ...(ngDevMode ? [{ debugName: "showEmptyNodeMassage" }] : []));
|
|
115
|
-
this.onSelectionChanged = output();
|
|
116
|
-
this.onItemSelectedChanged = output();
|
|
117
|
-
this.onNodeClick = output();
|
|
118
|
-
this.onCollapsedChanged = output();
|
|
119
|
-
this.onNodedbClick = output();
|
|
120
|
-
this.executorChanges = signal(null, ...(ngDevMode ? [{ debugName: "executorChanges" }] : []));
|
|
121
|
-
this.platformService = inject(AXPlatform);
|
|
122
|
-
this.#effect = effect(() => {
|
|
123
|
-
const itemsInput = this.items();
|
|
124
|
-
if (typeof itemsInput === 'function') {
|
|
125
|
-
const result = itemsInput();
|
|
126
|
-
if (result instanceof Promise) {
|
|
127
|
-
this.itemsPromise = (options) => itemsInput(options);
|
|
128
|
-
this.fetchData();
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
this.itemsSignal.set(result);
|
|
132
|
-
this.itemsPromise = null;
|
|
88
|
+
/**
|
|
89
|
+
* Build a flat list of all visible focusable nodes
|
|
90
|
+
*/
|
|
91
|
+
buildFlatNodeList(nodes) {
|
|
92
|
+
const flatList = [];
|
|
93
|
+
const traverse = (nodeList, level, parent) => {
|
|
94
|
+
for (const node of nodeList) {
|
|
95
|
+
if (node.visible !== false && !node.disabled) {
|
|
96
|
+
flatList.push({ node, level, parent });
|
|
97
|
+
if (node.expanded && node.children) {
|
|
98
|
+
traverse(node.children, level + 1, node);
|
|
99
|
+
}
|
|
133
100
|
}
|
|
134
101
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
}, ...(ngDevMode ? [{ debugName: "#effect" }] : []));
|
|
140
|
-
this.expandOn = input('defult', ...(ngDevMode ? [{ debugName: "expandOn" }] : []));
|
|
141
|
-
this.loadingState = signal({}, ...(ngDevMode ? [{ debugName: "loadingState" }] : []));
|
|
102
|
+
};
|
|
103
|
+
traverse(nodes, 0);
|
|
104
|
+
return flatList;
|
|
142
105
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
106
|
+
// ==================== Node State Checks ====================
|
|
107
|
+
/**
|
|
108
|
+
* Check if node has children
|
|
109
|
+
*/
|
|
110
|
+
hasChildren(node) {
|
|
111
|
+
return Boolean(node.children?.length);
|
|
146
112
|
}
|
|
147
|
-
|
|
148
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Check if node can be lazy loaded
|
|
115
|
+
*/
|
|
116
|
+
canLazyLoad(node, isLazyDataSource) {
|
|
117
|
+
return isLazyDataSource && Boolean(node.childrenCount && node.childrenCount > 0 && !this.hasChildren(node));
|
|
149
118
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
if (event.value !== null) {
|
|
161
|
-
switch (this.selectionBehavior()) {
|
|
162
|
-
case 'autoExpand':
|
|
163
|
-
if (event.value) {
|
|
164
|
-
if (this.itemsPromise && item[this.hasChildField()] && !item?.[this.childrenField()]?.length) {
|
|
165
|
-
this.setNodeLoading(item[this.valueField()], true);
|
|
166
|
-
this.fetchData(item);
|
|
167
|
-
}
|
|
168
|
-
this.toggleExpand(item);
|
|
169
|
-
}
|
|
170
|
-
break;
|
|
171
|
-
case 'cascade':
|
|
172
|
-
this.expandAndToggleSelection(item, event.value);
|
|
173
|
-
break;
|
|
174
|
-
case 'indeterminate':
|
|
175
|
-
if (item?.[this.childrenField()]?.length) {
|
|
176
|
-
this.applySelectionToChildren(item, event.value, item[this.valueField()]);
|
|
177
|
-
}
|
|
178
|
-
this.updateParentSelection(item, event.value);
|
|
179
|
-
break;
|
|
180
|
-
default:
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
119
|
+
// ==================== Selection Management ====================
|
|
120
|
+
/**
|
|
121
|
+
* Recursively select/deselect all children
|
|
122
|
+
*/
|
|
123
|
+
selectAllChildren(children, selected) {
|
|
124
|
+
for (const child of children) {
|
|
125
|
+
child.selected = selected;
|
|
126
|
+
child.indeterminate = false;
|
|
127
|
+
if (child.children) {
|
|
128
|
+
this.selectAllChildren(child.children, selected);
|
|
183
129
|
}
|
|
184
|
-
this.onItemSelectedChanged.emit({
|
|
185
|
-
component: this,
|
|
186
|
-
data: item,
|
|
187
|
-
nativeElement: this.nativeElement,
|
|
188
|
-
});
|
|
189
|
-
const result = this.findSelectedNodes(this.itemsSignal());
|
|
190
|
-
this.onSelectionChanged.emit({
|
|
191
|
-
component: this,
|
|
192
|
-
data: result,
|
|
193
|
-
nativeElement: this.nativeElement,
|
|
194
|
-
});
|
|
195
130
|
}
|
|
196
131
|
}
|
|
197
132
|
/**
|
|
198
|
-
*
|
|
199
|
-
* auto expand
|
|
200
|
-
*
|
|
133
|
+
* Get selection state of children
|
|
201
134
|
*/
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
135
|
+
getChildrenSelectionState(children) {
|
|
136
|
+
let selectedCount = 0;
|
|
137
|
+
let indeterminateCount = 0;
|
|
138
|
+
for (const child of children) {
|
|
139
|
+
if (child.selected && !child.indeterminate) {
|
|
140
|
+
selectedCount++;
|
|
141
|
+
}
|
|
142
|
+
if (child.indeterminate) {
|
|
143
|
+
indeterminateCount++;
|
|
144
|
+
}
|
|
205
145
|
}
|
|
146
|
+
return {
|
|
147
|
+
allSelected: selectedCount === children.length,
|
|
148
|
+
someSelected: selectedCount > 0 || indeterminateCount > 0,
|
|
149
|
+
};
|
|
206
150
|
}
|
|
207
151
|
/**
|
|
208
|
-
*
|
|
209
|
-
* expand and change value parent change
|
|
210
|
-
*
|
|
152
|
+
* Update parent node states based on children selection (with intermediate state support)
|
|
211
153
|
*/
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
154
|
+
updateParentStates(nodes, changedNode, intermediateState) {
|
|
155
|
+
const parent = this.findParentNode(nodes, changedNode);
|
|
156
|
+
if (!parent || !parent.children)
|
|
157
|
+
return;
|
|
158
|
+
const { allSelected, someSelected } = this.getChildrenSelectionState(parent.children);
|
|
159
|
+
if (allSelected) {
|
|
160
|
+
parent.selected = true;
|
|
161
|
+
parent.indeterminate = false;
|
|
216
162
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
163
|
+
else if (someSelected) {
|
|
164
|
+
if (intermediateState) {
|
|
165
|
+
parent.selected = true;
|
|
166
|
+
parent.indeterminate = true;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
parent.selected = false;
|
|
170
|
+
parent.indeterminate = false;
|
|
171
|
+
}
|
|
220
172
|
}
|
|
173
|
+
else {
|
|
174
|
+
parent.selected = false;
|
|
175
|
+
parent.indeterminate = false;
|
|
176
|
+
}
|
|
177
|
+
this.updateParentStates(nodes, parent, intermediateState);
|
|
221
178
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
this.
|
|
179
|
+
/**
|
|
180
|
+
* Recursively deselect all nodes
|
|
181
|
+
*/
|
|
182
|
+
deselectAllNodes(nodes) {
|
|
183
|
+
for (const node of nodes) {
|
|
184
|
+
node.selected = false;
|
|
185
|
+
node.indeterminate = false;
|
|
186
|
+
if (node.children) {
|
|
187
|
+
this.deselectAllNodes(node.children);
|
|
231
188
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Recursively set selection state for all nodes
|
|
193
|
+
*/
|
|
194
|
+
setAllSelection(nodes, selected) {
|
|
195
|
+
for (const node of nodes) {
|
|
196
|
+
node.selected = selected;
|
|
197
|
+
node.indeterminate = false;
|
|
198
|
+
if (node.children) {
|
|
199
|
+
this.setAllSelection(node.children, selected);
|
|
236
200
|
}
|
|
237
|
-
}
|
|
201
|
+
}
|
|
238
202
|
}
|
|
239
203
|
/**
|
|
240
|
-
*
|
|
241
|
-
* indeterminate logic
|
|
242
|
-
*
|
|
204
|
+
* Recursively count selected nodes
|
|
243
205
|
*/
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
parent[this.selectedField()] = false;
|
|
252
|
-
parent[this.indeterminateField()] = null;
|
|
206
|
+
countSelected(nodes) {
|
|
207
|
+
let count = 0;
|
|
208
|
+
for (const node of nodes) {
|
|
209
|
+
if (node.selected)
|
|
210
|
+
count++;
|
|
211
|
+
if (node.children) {
|
|
212
|
+
count += this.countSelected(node.children);
|
|
253
213
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
214
|
+
}
|
|
215
|
+
return count;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Recursively collect selected nodes
|
|
219
|
+
*/
|
|
220
|
+
collectSelected(nodes, result) {
|
|
221
|
+
for (const node of nodes) {
|
|
222
|
+
if (node.selected)
|
|
223
|
+
result.push(node);
|
|
224
|
+
if (node.children) {
|
|
225
|
+
this.collectSelected(node.children, result);
|
|
257
226
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Recursively remove selected nodes
|
|
231
|
+
*/
|
|
232
|
+
removeSelected(nodes) {
|
|
233
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
234
|
+
if (nodes[i].selected && !nodes[i].indeterminate) {
|
|
235
|
+
nodes.splice(i, 1);
|
|
261
236
|
}
|
|
262
|
-
else {
|
|
263
|
-
|
|
264
|
-
parent[this.selectedField()] = true;
|
|
237
|
+
else if (nodes[i].children) {
|
|
238
|
+
this.removeSelected(nodes[i].children ?? []);
|
|
265
239
|
}
|
|
266
|
-
parent = this.findParent(parent, this.itemsSignal());
|
|
267
240
|
}
|
|
268
241
|
}
|
|
269
|
-
|
|
242
|
+
/**
|
|
243
|
+
* Recursively update all parent states in the tree (used after deletion)
|
|
244
|
+
*/
|
|
245
|
+
updateAllParentStates(nodes, intermediateState) {
|
|
270
246
|
for (const node of nodes) {
|
|
271
|
-
if (node
|
|
272
|
-
|
|
247
|
+
if (node.children && node.children.length > 0) {
|
|
248
|
+
this.updateAllParentStates(node.children, intermediateState);
|
|
249
|
+
const { allSelected, someSelected } = this.getChildrenSelectionState(node.children);
|
|
250
|
+
if (allSelected) {
|
|
251
|
+
node.selected = true;
|
|
252
|
+
node.indeterminate = false;
|
|
253
|
+
}
|
|
254
|
+
else if (someSelected) {
|
|
255
|
+
if (intermediateState) {
|
|
256
|
+
node.selected = true;
|
|
257
|
+
node.indeterminate = true;
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
node.selected = false;
|
|
261
|
+
node.indeterminate = false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
node.selected = false;
|
|
266
|
+
node.indeterminate = false;
|
|
267
|
+
}
|
|
273
268
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// ==================== Expansion Management ====================
|
|
272
|
+
/**
|
|
273
|
+
* Recursively set expanded state (with lazy loading)
|
|
274
|
+
*/
|
|
275
|
+
async setExpandedState(nodes, expanded, isLazyDataSource, loadNodeChildren) {
|
|
276
|
+
for (const node of nodes) {
|
|
277
|
+
const hasChildren = this.hasChildren(node);
|
|
278
|
+
const canLazyLoad = this.canLazyLoad(node, isLazyDataSource);
|
|
279
|
+
if (hasChildren || canLazyLoad) {
|
|
280
|
+
if (expanded && canLazyLoad) {
|
|
281
|
+
await loadNodeChildren(node);
|
|
282
|
+
}
|
|
283
|
+
node.expanded = expanded;
|
|
284
|
+
if (node.children) {
|
|
285
|
+
await this.setExpandedState(node.children, expanded, isLazyDataSource, loadNodeChildren);
|
|
286
|
+
}
|
|
278
287
|
}
|
|
279
288
|
}
|
|
280
|
-
|
|
289
|
+
}
|
|
290
|
+
// ==================== Drag & Drop Helpers ====================
|
|
291
|
+
/**
|
|
292
|
+
* Get array reference by drop list ID
|
|
293
|
+
*/
|
|
294
|
+
getArrayByListId(nodes, listId) {
|
|
295
|
+
if (listId === AXTreeViewService.ROOT_LIST_ID) {
|
|
296
|
+
return nodes;
|
|
297
|
+
}
|
|
298
|
+
if (listId.startsWith(AXTreeViewService.NODE_DROP_PREFIX)) {
|
|
299
|
+
const nodeId = listId.replace(AXTreeViewService.NODE_DROP_PREFIX, '');
|
|
300
|
+
const node = this.findNodeById(nodes, nodeId);
|
|
301
|
+
return node ? [node] : null;
|
|
302
|
+
}
|
|
303
|
+
const nodeId = listId.replace(AXTreeViewService.LIST_PREFIX, '');
|
|
304
|
+
const node = this.findNodeById(nodes, nodeId);
|
|
305
|
+
return node?.children ?? null;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Find parent node by list ID
|
|
309
|
+
*/
|
|
310
|
+
findParentByListId(nodes, listId) {
|
|
311
|
+
if (listId === AXTreeViewService.ROOT_LIST_ID) {
|
|
312
|
+
return undefined;
|
|
313
|
+
}
|
|
314
|
+
const prefix = listId.startsWith(AXTreeViewService.NODE_DROP_PREFIX)
|
|
315
|
+
? AXTreeViewService.NODE_DROP_PREFIX
|
|
316
|
+
: AXTreeViewService.LIST_PREFIX;
|
|
317
|
+
const nodeId = listId.replace(prefix, '');
|
|
318
|
+
return this.findNodeById(nodes, nodeId) ?? undefined;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Generate unique list ID for each node
|
|
322
|
+
*/
|
|
323
|
+
getListId(node) {
|
|
324
|
+
return node ? `${AXTreeViewService.LIST_PREFIX}${node.id}` : AXTreeViewService.ROOT_LIST_ID;
|
|
281
325
|
}
|
|
282
326
|
/**
|
|
283
|
-
*
|
|
284
|
-
* find node selected true for emit Selections
|
|
285
|
-
*
|
|
327
|
+
* Get root list ID constant
|
|
286
328
|
*/
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
329
|
+
getRootListId() {
|
|
330
|
+
return AXTreeViewService.ROOT_LIST_ID;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Get node drop prefix constant
|
|
334
|
+
*/
|
|
335
|
+
getNodeDropPrefix() {
|
|
336
|
+
return AXTreeViewService.NODE_DROP_PREFIX;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Get list prefix constant
|
|
340
|
+
*/
|
|
341
|
+
getListPrefix() {
|
|
342
|
+
return AXTreeViewService.LIST_PREFIX;
|
|
343
|
+
}
|
|
344
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXTreeViewService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
345
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXTreeViewService }); }
|
|
346
|
+
}
|
|
347
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXTreeViewService, decorators: [{
|
|
348
|
+
type: Injectable
|
|
349
|
+
}] });
|
|
350
|
+
|
|
351
|
+
class AXTreeViewComponent {
|
|
352
|
+
constructor() {
|
|
353
|
+
// ==================== Dependencies ====================
|
|
354
|
+
this.treeService = inject(AXTreeViewService);
|
|
355
|
+
this.platformService = inject(AXPlatform);
|
|
356
|
+
this.destroyRef = inject(DestroyRef);
|
|
357
|
+
// ==================== Inputs ====================
|
|
358
|
+
/** Tree data source - can be static array or lazy loading function */
|
|
359
|
+
this.datasource = model.required(...(ngDevMode ? [{ debugName: "datasource" }] : []));
|
|
360
|
+
/** Selection mode: 'single' (click to select) or 'multiple' (checkbox selection) */
|
|
361
|
+
this.selectMode = input('multiple', ...(ngDevMode ? [{ debugName: "selectMode" }] : []));
|
|
362
|
+
/** Whether to show checkboxes for selection (only applies to multiple mode) */
|
|
363
|
+
this.showCheckbox = input(true, ...(ngDevMode ? [{ debugName: "showCheckbox" }] : []));
|
|
364
|
+
/** When true, selecting a parent also selects all loaded children (only for multiple mode) */
|
|
365
|
+
this.checkChildrenOnSelect = input(true, ...(ngDevMode ? [{ debugName: "checkChildrenOnSelect" }] : []));
|
|
366
|
+
/** When true, selecting a child makes parents indeterminate (only for multiple mode) */
|
|
367
|
+
this.intermediateState = input(true, ...(ngDevMode ? [{ debugName: "intermediateState" }] : []));
|
|
368
|
+
/** When true, clicking on a node toggles its selection (works for both single and multiple modes) */
|
|
369
|
+
this.checkOnClick = input(false, ...(ngDevMode ? [{ debugName: "checkOnClick" }] : []));
|
|
370
|
+
/** Drag and drop mode: 'none' (disabled), 'handler' (drag handle), 'item' (entire item) */
|
|
371
|
+
this.dragMode = input('handler', ...(ngDevMode ? [{ debugName: "dragMode" }] : []));
|
|
372
|
+
/** Drag operation type: 'order-only' (reorder only), 'move' (move between parents), 'both' (allow both) */
|
|
373
|
+
this.dragOperationType = input('both', ...(ngDevMode ? [{ debugName: "dragOperationType" }] : []));
|
|
374
|
+
/** Whether to show icons */
|
|
375
|
+
this.showIcons = input(true, ...(ngDevMode ? [{ debugName: "showIcons" }] : []));
|
|
376
|
+
/** Whether to show children count badge */
|
|
377
|
+
this.showChildrenBadge = input(true, ...(ngDevMode ? [{ debugName: "showChildrenBadge" }] : []));
|
|
378
|
+
/** Custom icon for expanded nodes */
|
|
379
|
+
this.expandedIcon = input('fa-solid fa-chevron-down', ...(ngDevMode ? [{ debugName: "expandedIcon" }] : []));
|
|
380
|
+
/** Custom icon for collapsed nodes */
|
|
381
|
+
this.collapsedIcon = input('fa-solid fa-chevron-right', ...(ngDevMode ? [{ debugName: "collapsedIcon" }] : []));
|
|
382
|
+
/** Indent size in pixels for each level */
|
|
383
|
+
this.indentSize = input(12, ...(ngDevMode ? [{ debugName: "indentSize" }] : []));
|
|
384
|
+
/** Node height in pixels */
|
|
385
|
+
this.nodeHeight = input('normal', ...(ngDevMode ? [{ debugName: "nodeHeight" }] : []));
|
|
386
|
+
/** Visual style variant */
|
|
387
|
+
this.look = input('default', ...(ngDevMode ? [{ debugName: "look" }] : []));
|
|
388
|
+
/** Custom template for tree items */
|
|
389
|
+
this.itemTemplate = input(...(ngDevMode ? [undefined, { debugName: "itemTemplate" }] : []));
|
|
390
|
+
// ==================== Outputs ====================
|
|
391
|
+
/** Emitted before a drop operation - set canceled to true to prevent drop */
|
|
392
|
+
this.onBeforeDrop = output();
|
|
393
|
+
/** Emitted when a node is toggled (expanded/collapsed) */
|
|
394
|
+
this.onNodeToggle = output();
|
|
395
|
+
/** Emitted when a node is selected/deselected */
|
|
396
|
+
this.onNodeSelect = output();
|
|
397
|
+
/** Emitted when nodes are reordered within the same parent */
|
|
398
|
+
this.onOrderChange = output();
|
|
399
|
+
/** Emitted when a node is moved to a different parent */
|
|
400
|
+
this.onMoveChange = output();
|
|
401
|
+
/** Emitted for any item change (order or move) */
|
|
402
|
+
this.onItemsChange = output();
|
|
403
|
+
// ==================== Internal State ====================
|
|
404
|
+
/** Internal signal for tree nodes */
|
|
405
|
+
this.nodes = signal([], ...(ngDevMode ? [{ debugName: "nodes" }] : []));
|
|
406
|
+
/** Internal signal for tracking loading state */
|
|
407
|
+
this.loadingNodes = signal(new Set(), ...(ngDevMode ? [{ debugName: "loadingNodes" }] : []));
|
|
408
|
+
/** Currently focused node ID for keyboard navigation */
|
|
409
|
+
this.focusedNodeId = signal(null, ...(ngDevMode ? [{ debugName: "focusedNodeId" }] : []));
|
|
410
|
+
/** RTL detection signal */
|
|
411
|
+
this.isRtl = signal(this.platformService.isRtl(), ...(ngDevMode ? [{ debugName: "isRtl" }] : []));
|
|
412
|
+
/** Computed chevron icons that flip for RTL */
|
|
413
|
+
this.directionExpandedIcon = computed(() => this.expandedIcon(), ...(ngDevMode ? [{ debugName: "directionExpandedIcon" }] : []));
|
|
414
|
+
this.directionCollapsedIcon = computed(() => {
|
|
415
|
+
const isRtlDirection = this.isRtl();
|
|
416
|
+
const defaultIcon = this.collapsedIcon();
|
|
417
|
+
if (isRtlDirection && defaultIcon === 'fa-solid fa-chevron-right') {
|
|
418
|
+
return 'fa-solid fa-chevron-left';
|
|
419
|
+
}
|
|
420
|
+
if (!isRtlDirection && defaultIcon === 'fa-solid fa-chevron-left') {
|
|
421
|
+
return 'fa-solid fa-chevron-right';
|
|
422
|
+
}
|
|
423
|
+
return defaultIcon;
|
|
424
|
+
}, ...(ngDevMode ? [{ debugName: "directionCollapsedIcon" }] : []));
|
|
425
|
+
/** Flag to prevent infinite loops when syncing datasource */
|
|
426
|
+
this.isUpdatingFromDatasource = false;
|
|
427
|
+
/** Computed to check if datasource is a function */
|
|
428
|
+
this.isLazyDataSource = computed(() => typeof this.datasource() === 'function', ...(ngDevMode ? [{ debugName: "isLazyDataSource" }] : []));
|
|
429
|
+
// ==================== Effects ====================
|
|
430
|
+
/** Effect to handle datasource changes */
|
|
431
|
+
this.#datasourceEffect = effect(() => {
|
|
432
|
+
if (this.isUpdatingFromDatasource)
|
|
433
|
+
return;
|
|
434
|
+
const ds = this.datasource();
|
|
435
|
+
if (Array.isArray(ds)) {
|
|
436
|
+
this.nodes.set([...ds]);
|
|
292
437
|
}
|
|
293
|
-
if (
|
|
294
|
-
|
|
438
|
+
else if (typeof ds === 'function') {
|
|
439
|
+
this.loadRootItems(ds).catch((error) => {
|
|
440
|
+
this.handleError('Failed to load root items', error);
|
|
441
|
+
});
|
|
295
442
|
}
|
|
443
|
+
}, ...(ngDevMode ? [{ debugName: "#datasourceEffect" }] : []));
|
|
444
|
+
/** Initialize direction change listener */
|
|
445
|
+
this.#initDirectionListener = afterNextRender(() => {
|
|
446
|
+
this.platformService.directionChange
|
|
447
|
+
.pipe(map((event) => event.data === 'rtl'), takeUntilDestroyed(this.destroyRef))
|
|
448
|
+
.subscribe((isRtl) => this.isRtl.set(isRtl));
|
|
296
449
|
});
|
|
297
|
-
return selectedNodes;
|
|
298
450
|
}
|
|
451
|
+
// ==================== Effects ====================
|
|
452
|
+
/** Effect to handle datasource changes */
|
|
453
|
+
#datasourceEffect;
|
|
454
|
+
/** Initialize direction change listener */
|
|
455
|
+
#initDirectionListener;
|
|
456
|
+
// ==================== Public API ====================
|
|
299
457
|
/**
|
|
300
|
-
*
|
|
301
|
-
* find for emit Selections single mode
|
|
302
|
-
*
|
|
458
|
+
* Expand all nodes in the tree (with lazy loading support)
|
|
303
459
|
*/
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
if (child?.[this.childrenField()]?.length) {
|
|
308
|
-
this.handleUnSelectNode(child[this.childrenField()]);
|
|
309
|
-
}
|
|
310
|
-
});
|
|
460
|
+
async expandAll() {
|
|
461
|
+
await this.treeService.setExpandedState(this.nodes(), true, this.isLazyDataSource(), (node) => this.loadNodeChildren(node));
|
|
462
|
+
this.refreshNodes();
|
|
311
463
|
}
|
|
312
464
|
/**
|
|
313
|
-
*
|
|
314
|
-
* lazy load logic
|
|
315
|
-
*
|
|
465
|
+
* Collapse all nodes in the tree
|
|
316
466
|
*/
|
|
317
|
-
|
|
318
|
-
this.
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
467
|
+
collapseAll() {
|
|
468
|
+
this.treeService.setExpandedState(this.nodes(), false, this.isLazyDataSource(), (node) => this.loadNodeChildren(node));
|
|
469
|
+
this.refreshNodes();
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Get count of selected nodes
|
|
473
|
+
*/
|
|
474
|
+
getSelectedCount() {
|
|
475
|
+
return this.treeService.countSelected(this.nodes());
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Check if any nodes are selected
|
|
479
|
+
*/
|
|
480
|
+
hasSelection() {
|
|
481
|
+
return this.getSelectedCount() > 0;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Get all selected nodes
|
|
485
|
+
*/
|
|
486
|
+
getSelectedNodes() {
|
|
487
|
+
const selected = [];
|
|
488
|
+
this.treeService.collectSelected(this.nodes(), selected);
|
|
489
|
+
return selected;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Delete selected nodes from the tree
|
|
493
|
+
*/
|
|
494
|
+
deleteSelected() {
|
|
495
|
+
this.treeService.removeSelected(this.nodes());
|
|
496
|
+
this.treeService.updateAllParentStates(this.nodes(), this.intermediateState());
|
|
497
|
+
this.refreshNodes();
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Select all nodes in the tree
|
|
501
|
+
*/
|
|
502
|
+
selectAll() {
|
|
503
|
+
this.treeService.setAllSelection(this.nodes(), true);
|
|
504
|
+
this.refreshNodes();
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Deselect all nodes in the tree
|
|
508
|
+
*/
|
|
509
|
+
deselectAll() {
|
|
510
|
+
this.treeService.setAllSelection(this.nodes(), false);
|
|
511
|
+
this.refreshNodes();
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Find a node by ID in the tree
|
|
515
|
+
*/
|
|
516
|
+
findNode(id) {
|
|
517
|
+
return this.treeService.findNodeById(this.nodes(), id);
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Refresh the tree to trigger change detection
|
|
521
|
+
*/
|
|
522
|
+
refresh() {
|
|
523
|
+
this.refreshNodes();
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Check if a node is currently loading
|
|
527
|
+
*/
|
|
528
|
+
isNodeLoading(nodeId) {
|
|
529
|
+
return this.loadingNodes().has(nodeId);
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Get template context for a node
|
|
533
|
+
*/
|
|
534
|
+
getTemplateContext(node, level = 0) {
|
|
535
|
+
return {
|
|
536
|
+
$implicit: node,
|
|
537
|
+
node,
|
|
538
|
+
level,
|
|
539
|
+
expanded: node.expanded ?? false,
|
|
540
|
+
childrenCount: node.childrenCount ?? node.children?.length ?? 0,
|
|
541
|
+
loading: node.loading ?? false,
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Calculate padding-inline for a node based on its level
|
|
546
|
+
*/
|
|
547
|
+
getNodePaddingInline(level) {
|
|
548
|
+
const indent = this.indentSize();
|
|
549
|
+
const currentLook = this.look();
|
|
550
|
+
const multiplier = currentLook === 'with-line' ? 1 / 3 : 1;
|
|
551
|
+
return level * indent * multiplier;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Check if node should show expand toggle
|
|
555
|
+
*/
|
|
556
|
+
shouldShowExpandToggle(node) {
|
|
557
|
+
return this.treeService.hasChildren(node) || this.treeService.canLazyLoad(node, this.isLazyDataSource());
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Check if checkboxes should be shown (only for multiple mode)
|
|
561
|
+
*/
|
|
562
|
+
shouldShowCheckbox() {
|
|
563
|
+
return this.selectMode() === 'multiple' && this.showCheckbox();
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Generate unique list ID for each node
|
|
567
|
+
*/
|
|
568
|
+
getListId(node) {
|
|
569
|
+
return this.treeService.getListId(node);
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Check if a node is currently focused
|
|
573
|
+
*/
|
|
574
|
+
isNodeFocused(nodeId) {
|
|
575
|
+
return this.focusedNodeId() === nodeId;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Get ARIA level for a node
|
|
579
|
+
*/
|
|
580
|
+
getNodeAriaLevel(level) {
|
|
581
|
+
return level + 1;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Get ARIA expanded state for a node
|
|
585
|
+
*/
|
|
586
|
+
getNodeAriaExpanded(node) {
|
|
587
|
+
if (!this.shouldShowExpandToggle(node)) {
|
|
588
|
+
return null;
|
|
589
|
+
}
|
|
590
|
+
return node.expanded ? 'true' : 'false';
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Get ARIA selected state for a node
|
|
594
|
+
*/
|
|
595
|
+
getNodeAriaSelected(node) {
|
|
596
|
+
if (this.selectMode() === 'single') {
|
|
597
|
+
return node.selected ? 'true' : 'false';
|
|
598
|
+
}
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
// ==================== Event Handlers ====================
|
|
602
|
+
/**
|
|
603
|
+
* Handle node click - for single selection mode or multiple mode with checkOnClick enabled
|
|
604
|
+
*/
|
|
605
|
+
onNodeClick(node, event) {
|
|
606
|
+
if (node.disabled)
|
|
607
|
+
return;
|
|
608
|
+
const mode = this.selectMode();
|
|
609
|
+
const shouldCheckOnClick = this.checkOnClick();
|
|
610
|
+
if (mode === 'single') {
|
|
611
|
+
this.handleSingleSelection(node, event);
|
|
612
|
+
}
|
|
613
|
+
else if (mode === 'multiple' && shouldCheckOnClick) {
|
|
614
|
+
this.handleMultipleSelection(node, event);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Toggle node expansion state with lazy loading support
|
|
619
|
+
*/
|
|
620
|
+
async toggleNode(node, event) {
|
|
621
|
+
if (node.disabled)
|
|
622
|
+
return;
|
|
623
|
+
if (this.isEvent(event) && typeof event.stopPropagation === 'function') {
|
|
624
|
+
event.stopPropagation();
|
|
625
|
+
}
|
|
626
|
+
const hasChildren = this.treeService.hasChildren(node);
|
|
627
|
+
const canLazyLoad = this.treeService.canLazyLoad(node, this.isLazyDataSource());
|
|
628
|
+
if (hasChildren || canLazyLoad) {
|
|
629
|
+
const willExpand = !node.expanded;
|
|
630
|
+
if (willExpand && canLazyLoad) {
|
|
631
|
+
await this.loadNodeChildren(node);
|
|
331
632
|
}
|
|
332
|
-
|
|
333
|
-
.
|
|
334
|
-
this.
|
|
633
|
+
node.expanded = willExpand;
|
|
634
|
+
this.refreshNodes();
|
|
635
|
+
this.onNodeToggle.emit({ component: this, node, nativeEvent: event });
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Toggle node selection state with indeterminate support (for multiple mode)
|
|
640
|
+
*/
|
|
641
|
+
toggleSelection(node, event) {
|
|
642
|
+
if (!event.isUserInteraction)
|
|
643
|
+
return;
|
|
644
|
+
const mode = this.selectMode();
|
|
645
|
+
if (mode !== 'multiple')
|
|
646
|
+
return;
|
|
647
|
+
const newValue = event.value === null ? true : event.value;
|
|
648
|
+
node.selected = newValue;
|
|
649
|
+
node.indeterminate = false;
|
|
650
|
+
if (this.checkChildrenOnSelect() && node.children) {
|
|
651
|
+
this.treeService.selectAllChildren(node.children, newValue);
|
|
652
|
+
}
|
|
653
|
+
if (this.intermediateState()) {
|
|
654
|
+
this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
|
|
655
|
+
}
|
|
656
|
+
this.refreshNodes();
|
|
657
|
+
this.onNodeSelect.emit({
|
|
658
|
+
component: this,
|
|
659
|
+
node,
|
|
660
|
+
isUserInteraction: event.isUserInteraction,
|
|
335
661
|
});
|
|
336
662
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
663
|
+
/**
|
|
664
|
+
* Handle drop events for tree nodes
|
|
665
|
+
*/
|
|
666
|
+
onDrop(event, parentNode) {
|
|
667
|
+
const targetArray = parentNode?.children ?? this.nodes();
|
|
668
|
+
const isReordering = event.previousContainer === event.container;
|
|
669
|
+
if (isReordering) {
|
|
670
|
+
this.handleReorder(event, targetArray, parentNode);
|
|
671
|
+
}
|
|
672
|
+
else {
|
|
673
|
+
this.handleMove(event, targetArray, parentNode);
|
|
674
|
+
}
|
|
675
|
+
this.refreshNodes();
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Handle drop events when dropping directly onto a node (to make it a child)
|
|
679
|
+
*/
|
|
680
|
+
onDropOntoNode(event, targetNode) {
|
|
681
|
+
if (!this.canMoveToParent())
|
|
682
|
+
return;
|
|
683
|
+
const sourceListId = event.previousContainer.element.id;
|
|
684
|
+
const sourceArray = this.getArrayByListId(sourceListId);
|
|
685
|
+
if (!sourceArray)
|
|
686
|
+
return;
|
|
687
|
+
const movedNode = sourceArray[event.previousIndex];
|
|
688
|
+
if (!this.treeService.isValidDropTarget(movedNode, targetNode))
|
|
689
|
+
return;
|
|
690
|
+
if (!this.emitBeforeDropEvent(movedNode, sourceListId, targetNode, event.previousIndex, 0))
|
|
691
|
+
return;
|
|
692
|
+
targetNode.children ??= [];
|
|
693
|
+
sourceArray.splice(event.previousIndex, 1);
|
|
694
|
+
targetNode.children.unshift(movedNode);
|
|
695
|
+
targetNode.expanded = true;
|
|
696
|
+
this.emitDropEvents(movedNode, this.findParentByListId(sourceListId), targetNode, event.previousIndex, 0, false);
|
|
697
|
+
this.refreshNodes();
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Handle node focus event
|
|
701
|
+
*/
|
|
702
|
+
onNodeFocus(nodeId) {
|
|
703
|
+
this.focusedNodeId.set(nodeId);
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Handle tree container focus - focus first node if none is focused
|
|
707
|
+
*/
|
|
708
|
+
onTreeFocus(event) {
|
|
709
|
+
if (event.target === event.currentTarget) {
|
|
710
|
+
afterNextRender(() => {
|
|
711
|
+
const flatList = this.treeService.buildFlatNodeList(this.nodes());
|
|
712
|
+
if (flatList.length > 0) {
|
|
713
|
+
const focusedId = this.focusedNodeId();
|
|
714
|
+
if (focusedId) {
|
|
715
|
+
this.focusNodeById(focusedId);
|
|
716
|
+
}
|
|
717
|
+
else {
|
|
718
|
+
this.focusNodeById(flatList[0].node.id);
|
|
343
719
|
}
|
|
344
|
-
element[this.childrenField()] = _children;
|
|
345
|
-
}
|
|
346
|
-
else {
|
|
347
|
-
if (element?.[this.childrenField()])
|
|
348
|
-
this.findNode(parentId, _children, element[this.childrenField()]);
|
|
349
720
|
}
|
|
350
721
|
});
|
|
351
722
|
}
|
|
352
723
|
}
|
|
353
724
|
/**
|
|
354
|
-
*
|
|
355
|
-
|
|
356
|
-
|
|
725
|
+
* Handle tree container blur
|
|
726
|
+
*/
|
|
727
|
+
onTreeBlur(event) {
|
|
728
|
+
if (event.relatedTarget && !event.currentTarget.contains(event.relatedTarget)) {
|
|
729
|
+
this.focusedNodeId.set(null);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Handle keyboard navigation
|
|
734
|
+
*/
|
|
735
|
+
handleKeyDown(event) {
|
|
736
|
+
const flatList = this.treeService.buildFlatNodeList(this.nodes());
|
|
737
|
+
if (flatList.length === 0)
|
|
738
|
+
return;
|
|
739
|
+
const currentFocused = this.getFocusedNode();
|
|
740
|
+
let currentIndex = currentFocused ? flatList.findIndex((item) => item.node.id === currentFocused.id) : -1;
|
|
741
|
+
if (currentIndex === -1 && event.target === event.currentTarget) {
|
|
742
|
+
currentIndex = 0;
|
|
743
|
+
}
|
|
744
|
+
const navigationResult = this.handleNavigationKey(event, flatList, currentIndex, currentFocused);
|
|
745
|
+
if (navigationResult.handled) {
|
|
746
|
+
if (navigationResult.shouldPreventDefault) {
|
|
747
|
+
event.preventDefault();
|
|
748
|
+
event.stopPropagation();
|
|
749
|
+
}
|
|
750
|
+
if (navigationResult.targetIndex !== null &&
|
|
751
|
+
navigationResult.targetIndex >= 0 &&
|
|
752
|
+
navigationResult.targetIndex < flatList.length) {
|
|
753
|
+
this.focusNodeById(flatList[navigationResult.targetIndex].node.id);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
// ==================== Private Methods ====================
|
|
758
|
+
/**
|
|
759
|
+
* Load root items when datasource is a function
|
|
760
|
+
*/
|
|
761
|
+
async loadRootItems(loadFn) {
|
|
762
|
+
try {
|
|
763
|
+
const result = loadFn();
|
|
764
|
+
const rootNodes = result instanceof Promise ? await result : result;
|
|
765
|
+
this.nodes.set(rootNodes);
|
|
766
|
+
}
|
|
767
|
+
catch (error) {
|
|
768
|
+
this.handleError('Failed to load root items', error);
|
|
769
|
+
this.nodes.set([]);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* Load children for a node using lazy loading
|
|
774
|
+
*/
|
|
775
|
+
async loadNodeChildren(node) {
|
|
776
|
+
if (!this.isLazyDataSource() || node.loading)
|
|
777
|
+
return;
|
|
778
|
+
if (this.treeService.hasChildren(node) || !node.childrenCount || node.childrenCount === 0) {
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
const ds = this.datasource();
|
|
782
|
+
if (typeof ds !== 'function')
|
|
783
|
+
return;
|
|
784
|
+
try {
|
|
785
|
+
node.loading = true;
|
|
786
|
+
this.loadingNodes.update((set) => new Set(set).add(node.id));
|
|
787
|
+
this.refreshNodes();
|
|
788
|
+
const result = ds(node.id);
|
|
789
|
+
const children = result instanceof Promise ? await result : result;
|
|
790
|
+
node.children = children;
|
|
791
|
+
node.childrenCount = children.length;
|
|
792
|
+
}
|
|
793
|
+
catch (error) {
|
|
794
|
+
this.handleError('Failed to load children', error);
|
|
795
|
+
node.childrenCount = 0;
|
|
796
|
+
}
|
|
797
|
+
finally {
|
|
798
|
+
node.loading = false;
|
|
799
|
+
this.loadingNodes.update((set) => {
|
|
800
|
+
const newSet = new Set(set);
|
|
801
|
+
newSet.delete(node.id);
|
|
802
|
+
return newSet;
|
|
803
|
+
});
|
|
804
|
+
this.refreshNodes();
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Internal method to refresh nodes signal and sync back to datasource if it's an array
|
|
809
|
+
* Creates new array references for all nested children to ensure reactivity
|
|
357
810
|
*/
|
|
358
|
-
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
811
|
+
refreshNodes() {
|
|
812
|
+
const currentNodes = this.nodes();
|
|
813
|
+
// Create new array references for all nested children to ensure reactivity
|
|
814
|
+
// This ensures Angular's change detection picks up changes even with callback datasource
|
|
815
|
+
this.ensureNewArrayReferences(currentNodes);
|
|
816
|
+
this.nodes.set([...currentNodes]);
|
|
817
|
+
if (!this.isLazyDataSource() && !this.isUpdatingFromDatasource) {
|
|
818
|
+
this.isUpdatingFromDatasource = true;
|
|
819
|
+
this.datasource.set([...currentNodes]);
|
|
820
|
+
setTimeout(() => {
|
|
821
|
+
this.isUpdatingFromDatasource = false;
|
|
822
|
+
}, 0);
|
|
363
823
|
}
|
|
364
|
-
this.onCollapsedChanged.emit({ component: this, data: node.data, nativeElement: this.nativeElement });
|
|
365
824
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
825
|
+
/**
|
|
826
|
+
* Recursively ensure all children arrays have new references to trigger change detection
|
|
827
|
+
* Mutates the tree structure by replacing children arrays with new array references
|
|
828
|
+
*/
|
|
829
|
+
ensureNewArrayReferences(nodes) {
|
|
830
|
+
for (const node of nodes) {
|
|
831
|
+
if (node.children && node.children.length > 0) {
|
|
832
|
+
// Create new array reference for children
|
|
833
|
+
node.children = [...node.children];
|
|
834
|
+
// Recursively process nested children
|
|
835
|
+
this.ensureNewArrayReferences(node.children);
|
|
371
836
|
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
/**
|
|
840
|
+
* Handle single selection mode
|
|
841
|
+
*/
|
|
842
|
+
handleSingleSelection(node, event) {
|
|
843
|
+
this.treeService.deselectAllNodes(this.nodes());
|
|
844
|
+
node.selected = true;
|
|
845
|
+
node.indeterminate = false;
|
|
846
|
+
this.refreshNodes();
|
|
847
|
+
this.onNodeSelect.emit({
|
|
848
|
+
component: this,
|
|
849
|
+
node,
|
|
850
|
+
nativeEvent: event,
|
|
851
|
+
isUserInteraction: true,
|
|
372
852
|
});
|
|
373
853
|
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
854
|
+
/**
|
|
855
|
+
* Handle multiple selection mode with checkOnClick
|
|
856
|
+
*/
|
|
857
|
+
handleMultipleSelection(node, event) {
|
|
858
|
+
const newValue = !node.selected;
|
|
859
|
+
node.selected = newValue;
|
|
860
|
+
node.indeterminate = false;
|
|
861
|
+
if (this.checkChildrenOnSelect() && node.children) {
|
|
862
|
+
this.treeService.selectAllChildren(node.children, newValue);
|
|
863
|
+
}
|
|
864
|
+
if (this.intermediateState()) {
|
|
865
|
+
this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
|
|
866
|
+
}
|
|
867
|
+
this.refreshNodes();
|
|
868
|
+
this.onNodeSelect.emit({
|
|
869
|
+
component: this,
|
|
870
|
+
node,
|
|
871
|
+
nativeEvent: event,
|
|
872
|
+
isUserInteraction: true,
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
/**
|
|
876
|
+
* Get array reference by drop list ID
|
|
877
|
+
*/
|
|
878
|
+
getArrayByListId(listId) {
|
|
879
|
+
return this.treeService.getArrayByListId(this.nodes(), listId);
|
|
880
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
* Find parent node by list ID
|
|
883
|
+
*/
|
|
884
|
+
findParentByListId(listId) {
|
|
885
|
+
return this.treeService.findParentByListId(this.nodes(), listId);
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* Check if move operation is allowed based on dragOperationType
|
|
889
|
+
*/
|
|
890
|
+
canMoveToParent() {
|
|
891
|
+
return this.dragOperationType() !== 'order-only';
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Check if reorder operation is allowed based on dragOperationType
|
|
895
|
+
*/
|
|
896
|
+
canReorder() {
|
|
897
|
+
return this.dragOperationType() !== 'move';
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* Handle reordering within the same list */
|
|
901
|
+
handleReorder(event, targetArray, parentNode) {
|
|
902
|
+
if (!this.canReorder())
|
|
903
|
+
return;
|
|
904
|
+
const movedNode = targetArray[event.previousIndex];
|
|
905
|
+
moveItemInArray(targetArray, event.previousIndex, event.currentIndex);
|
|
906
|
+
this.emitDropEvents(movedNode, parentNode, parentNode, event.previousIndex, event.currentIndex, true);
|
|
907
|
+
}
|
|
908
|
+
/**
|
|
909
|
+
* Handle moving between different lists
|
|
910
|
+
*/
|
|
911
|
+
handleMove(event, targetArray, parentNode) {
|
|
912
|
+
if (!this.canMoveToParent())
|
|
913
|
+
return;
|
|
914
|
+
const sourceListId = event.previousContainer.element.id;
|
|
915
|
+
const sourceArray = this.getArrayByListId(sourceListId);
|
|
916
|
+
if (!sourceArray)
|
|
917
|
+
return;
|
|
918
|
+
const movedNode = sourceArray[event.previousIndex];
|
|
919
|
+
if (parentNode && !this.treeService.isValidDropTarget(movedNode, parentNode))
|
|
920
|
+
return;
|
|
921
|
+
if (!this.emitBeforeDropEvent(movedNode, sourceListId, parentNode, event.previousIndex, event.currentIndex)) {
|
|
922
|
+
return;
|
|
923
|
+
}
|
|
924
|
+
transferArrayItem(sourceArray, targetArray, event.previousIndex, event.currentIndex);
|
|
925
|
+
this.emitDropEvents(movedNode, this.findParentByListId(sourceListId), parentNode, event.previousIndex, event.currentIndex, false);
|
|
926
|
+
}
|
|
927
|
+
/**
|
|
928
|
+
* Emit beforeDrop event and return whether to continue
|
|
929
|
+
*/
|
|
930
|
+
emitBeforeDropEvent(movedNode, sourceListId, currentParent, previousIndex, currentIndex) {
|
|
931
|
+
const beforeDropEvent = {
|
|
932
|
+
component: this,
|
|
933
|
+
movedNode,
|
|
934
|
+
previousParent: this.findParentByListId(sourceListId),
|
|
935
|
+
currentParent,
|
|
936
|
+
previousIndex,
|
|
937
|
+
currentIndex,
|
|
938
|
+
canceled: false,
|
|
939
|
+
};
|
|
940
|
+
this.onBeforeDrop.emit(beforeDropEvent);
|
|
941
|
+
return !beforeDropEvent.canceled;
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Emit drop events based on operation type
|
|
945
|
+
*/
|
|
946
|
+
emitDropEvents(node, previousParent, currentParent, previousIndex, currentIndex, isReorder) {
|
|
947
|
+
const dropEvent = {
|
|
948
|
+
component: this,
|
|
949
|
+
node,
|
|
950
|
+
previousParent,
|
|
951
|
+
currentParent,
|
|
952
|
+
previousIndex,
|
|
953
|
+
currentIndex,
|
|
954
|
+
};
|
|
955
|
+
if (isReorder) {
|
|
956
|
+
this.onOrderChange.emit(dropEvent);
|
|
957
|
+
}
|
|
958
|
+
else {
|
|
959
|
+
this.onMoveChange.emit(dropEvent);
|
|
960
|
+
}
|
|
961
|
+
this.onItemsChange.emit(dropEvent);
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* Get the currently focused node
|
|
965
|
+
*/
|
|
966
|
+
getFocusedNode() {
|
|
967
|
+
const focusedId = this.focusedNodeId();
|
|
968
|
+
if (!focusedId)
|
|
969
|
+
return null;
|
|
970
|
+
return this.treeService.findNodeById(this.nodes(), focusedId);
|
|
971
|
+
}
|
|
972
|
+
/**
|
|
973
|
+
* Set focus to a node by ID
|
|
974
|
+
*/
|
|
975
|
+
focusNodeById(nodeId) {
|
|
976
|
+
this.focusedNodeId.set(nodeId);
|
|
977
|
+
setTimeout(() => {
|
|
978
|
+
const element = document.querySelector(`[data-tree-node-id="${nodeId}"]`);
|
|
979
|
+
if (element) {
|
|
980
|
+
element.focus();
|
|
981
|
+
element.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
|
|
982
|
+
}
|
|
983
|
+
}, 0);
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* Handle keyboard navigation keys
|
|
987
|
+
*/
|
|
988
|
+
handleNavigationKey(event, flatList, currentIndex, currentFocused) {
|
|
989
|
+
let targetIndex = currentIndex;
|
|
990
|
+
let shouldPreventDefault = true;
|
|
991
|
+
let handled = true;
|
|
992
|
+
switch (event.key) {
|
|
993
|
+
case 'ArrowUp':
|
|
994
|
+
if (currentIndex > 0) {
|
|
995
|
+
targetIndex = currentIndex - 1;
|
|
996
|
+
}
|
|
997
|
+
else {
|
|
998
|
+
shouldPreventDefault = false;
|
|
999
|
+
}
|
|
387
1000
|
break;
|
|
388
|
-
case '
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
1001
|
+
case 'ArrowDown':
|
|
1002
|
+
if (currentIndex < flatList.length - 1) {
|
|
1003
|
+
targetIndex = currentIndex + 1;
|
|
1004
|
+
}
|
|
1005
|
+
else if (currentIndex === -1) {
|
|
1006
|
+
targetIndex = 0;
|
|
1007
|
+
}
|
|
1008
|
+
else {
|
|
1009
|
+
shouldPreventDefault = false;
|
|
392
1010
|
}
|
|
393
1011
|
break;
|
|
394
|
-
case '
|
|
395
|
-
|
|
1012
|
+
case 'ArrowLeft':
|
|
1013
|
+
if (currentFocused) {
|
|
1014
|
+
if (currentFocused.expanded && this.shouldShowExpandToggle(currentFocused)) {
|
|
1015
|
+
this.toggleNode(currentFocused, event);
|
|
1016
|
+
return { handled: true, shouldPreventDefault: true, targetIndex: null };
|
|
1017
|
+
}
|
|
1018
|
+
else {
|
|
1019
|
+
const currentItem = flatList[currentIndex];
|
|
1020
|
+
if (currentItem?.parent) {
|
|
1021
|
+
targetIndex = flatList.findIndex((item) => item.node.id === currentItem.parent.id);
|
|
1022
|
+
}
|
|
1023
|
+
else {
|
|
1024
|
+
shouldPreventDefault = false;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
else {
|
|
1029
|
+
shouldPreventDefault = false;
|
|
1030
|
+
}
|
|
396
1031
|
break;
|
|
397
|
-
case '
|
|
398
|
-
|
|
1032
|
+
case 'ArrowRight':
|
|
1033
|
+
if (currentFocused) {
|
|
1034
|
+
if (!currentFocused.expanded && this.shouldShowExpandToggle(currentFocused)) {
|
|
1035
|
+
this.toggleNode(currentFocused, event);
|
|
1036
|
+
return { handled: true, shouldPreventDefault: true, targetIndex: null };
|
|
1037
|
+
}
|
|
1038
|
+
else if (currentFocused.expanded &&
|
|
1039
|
+
this.treeService.hasChildren(currentFocused) &&
|
|
1040
|
+
currentFocused.children) {
|
|
1041
|
+
const children = currentFocused.children;
|
|
1042
|
+
if (children.length > 0) {
|
|
1043
|
+
const firstChild = children[0];
|
|
1044
|
+
targetIndex = flatList.findIndex((item) => item.node.id === firstChild.id);
|
|
1045
|
+
if (targetIndex === -1) {
|
|
1046
|
+
const updatedFlatList = this.treeService.buildFlatNodeList(this.nodes());
|
|
1047
|
+
targetIndex = updatedFlatList.findIndex((item) => item.node.id === firstChild.id);
|
|
1048
|
+
if (targetIndex >= 0 && targetIndex < updatedFlatList.length) {
|
|
1049
|
+
this.focusNodeById(updatedFlatList[targetIndex].node.id);
|
|
1050
|
+
return { handled: true, shouldPreventDefault: true, targetIndex: null };
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
else {
|
|
1055
|
+
shouldPreventDefault = false;
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
else {
|
|
1059
|
+
shouldPreventDefault = false;
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
else {
|
|
1063
|
+
shouldPreventDefault = false;
|
|
1064
|
+
}
|
|
1065
|
+
break;
|
|
1066
|
+
case 'Home':
|
|
1067
|
+
targetIndex = 0;
|
|
1068
|
+
break;
|
|
1069
|
+
case 'End':
|
|
1070
|
+
targetIndex = flatList.length - 1;
|
|
1071
|
+
break;
|
|
1072
|
+
case ' ':
|
|
1073
|
+
case 'Space':
|
|
1074
|
+
if (currentFocused && this.selectMode() === 'multiple') {
|
|
1075
|
+
event.preventDefault();
|
|
1076
|
+
this.handleSpaceKeySelection(currentFocused, event);
|
|
1077
|
+
return { handled: true, shouldPreventDefault: true, targetIndex: null };
|
|
1078
|
+
}
|
|
1079
|
+
shouldPreventDefault = false;
|
|
1080
|
+
break;
|
|
1081
|
+
case 'Enter':
|
|
1082
|
+
if (currentFocused) {
|
|
1083
|
+
event.preventDefault();
|
|
1084
|
+
this.handleEnterKeySelection(currentFocused, event);
|
|
1085
|
+
return { handled: true, shouldPreventDefault: true, targetIndex: null };
|
|
1086
|
+
}
|
|
1087
|
+
shouldPreventDefault = false;
|
|
399
1088
|
break;
|
|
400
1089
|
default:
|
|
1090
|
+
if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') {
|
|
1091
|
+
if (currentFocused && this.selectMode() === 'multiple') {
|
|
1092
|
+
event.preventDefault();
|
|
1093
|
+
this.handleCtrlEnterSelection(currentFocused, event);
|
|
1094
|
+
return { handled: true, shouldPreventDefault: true, targetIndex: null };
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
handled = false;
|
|
1098
|
+
shouldPreventDefault = false;
|
|
401
1099
|
break;
|
|
402
1100
|
}
|
|
403
|
-
|
|
404
|
-
*
|
|
405
|
-
* for detect changes treeviewitem
|
|
406
|
-
*
|
|
407
|
-
*/
|
|
408
|
-
this.executorChanges.set(operation);
|
|
1101
|
+
return { handled, shouldPreventDefault, targetIndex };
|
|
409
1102
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
1103
|
+
/**
|
|
1104
|
+
* Handle Space key selection
|
|
1105
|
+
*/
|
|
1106
|
+
handleSpaceKeySelection(node, event) {
|
|
1107
|
+
const newValue = !node.selected;
|
|
1108
|
+
node.selected = newValue;
|
|
1109
|
+
node.indeterminate = false;
|
|
1110
|
+
if (this.checkChildrenOnSelect() && node.children) {
|
|
1111
|
+
this.treeService.selectAllChildren(node.children, newValue);
|
|
413
1112
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
const nodesToExpand = [];
|
|
417
|
-
for (const valueField of valueFields) {
|
|
418
|
-
const foundNodes = this.findNodesByValueField(this.itemsSignal(), valueField);
|
|
419
|
-
nodesToExpand.push(...foundNodes);
|
|
1113
|
+
if (this.intermediateState()) {
|
|
1114
|
+
this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
|
|
420
1115
|
}
|
|
421
|
-
|
|
1116
|
+
this.refreshNodes();
|
|
1117
|
+
this.onNodeSelect.emit({
|
|
1118
|
+
component: this,
|
|
1119
|
+
node,
|
|
1120
|
+
nativeEvent: event,
|
|
1121
|
+
isUserInteraction: true,
|
|
1122
|
+
});
|
|
422
1123
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
1124
|
+
/**
|
|
1125
|
+
* Handle Enter key selection
|
|
1126
|
+
*/
|
|
1127
|
+
handleEnterKeySelection(node, event) {
|
|
1128
|
+
const mode = this.selectMode();
|
|
1129
|
+
this.treeService.deselectAllNodes(this.nodes());
|
|
1130
|
+
node.selected = true;
|
|
1131
|
+
node.indeterminate = false;
|
|
1132
|
+
if (mode === 'multiple') {
|
|
1133
|
+
if (this.checkChildrenOnSelect() && node.children) {
|
|
1134
|
+
this.treeService.selectAllChildren(node.children, true);
|
|
428
1135
|
}
|
|
429
|
-
if (
|
|
430
|
-
|
|
1136
|
+
if (this.intermediateState()) {
|
|
1137
|
+
this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
|
|
431
1138
|
}
|
|
432
1139
|
}
|
|
433
|
-
|
|
1140
|
+
this.refreshNodes();
|
|
1141
|
+
this.onNodeSelect.emit({
|
|
1142
|
+
component: this,
|
|
1143
|
+
node,
|
|
1144
|
+
nativeEvent: event,
|
|
1145
|
+
isUserInteraction: true,
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
/**
|
|
1149
|
+
* Handle Ctrl/Cmd + Enter key selection
|
|
1150
|
+
*/
|
|
1151
|
+
handleCtrlEnterSelection(node, event) {
|
|
1152
|
+
const newValue = !node.selected;
|
|
1153
|
+
node.selected = newValue;
|
|
1154
|
+
node.indeterminate = false;
|
|
1155
|
+
if (this.checkChildrenOnSelect() && node.children) {
|
|
1156
|
+
this.treeService.selectAllChildren(node.children, newValue);
|
|
1157
|
+
}
|
|
1158
|
+
if (this.intermediateState()) {
|
|
1159
|
+
this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
|
|
1160
|
+
}
|
|
1161
|
+
this.refreshNodes();
|
|
1162
|
+
this.onNodeSelect.emit({
|
|
1163
|
+
component: this,
|
|
1164
|
+
node,
|
|
1165
|
+
nativeEvent: event,
|
|
1166
|
+
isUserInteraction: true,
|
|
1167
|
+
});
|
|
434
1168
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
1169
|
+
/**
|
|
1170
|
+
* Type guard to check if value is an Event
|
|
1171
|
+
*/
|
|
1172
|
+
isEvent(value) {
|
|
1173
|
+
return value instanceof Event;
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Handle errors consistently
|
|
1177
|
+
*/
|
|
1178
|
+
handleError(message, error) {
|
|
1179
|
+
if (error instanceof Error) {
|
|
1180
|
+
console.error(`${message}:`, error.message);
|
|
440
1181
|
}
|
|
441
|
-
|
|
442
|
-
|
|
1182
|
+
else {
|
|
1183
|
+
console.error(`${message}:`, error);
|
|
443
1184
|
}
|
|
444
1185
|
}
|
|
445
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
446
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXTreeViewComponent, isStandalone: true, selector: "ax-tree-view", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, showCheckbox: { classPropertyName: "showCheckbox", publicName: "showCheckbox", isSignal: true, isRequired: false, transformFunction: null }, hasCheckboxField: { classPropertyName: "hasCheckboxField", publicName: "hasCheckboxField", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selectionBehavior: { classPropertyName: "selectionBehavior", publicName: "selectionBehavior", isSignal: true, isRequired: false, transformFunction: null }, selectionScope: { classPropertyName: "selectionScope", publicName: "selectionScope", isSignal: true, isRequired: false, transformFunction: null }, focusNodeEnabled: { classPropertyName: "focusNodeEnabled", publicName: "focusNodeEnabled", isSignal: true, isRequired: false, transformFunction: null }, valueField: { classPropertyName: "valueField", publicName: "valueField", isSignal: true, isRequired: false, transformFunction: null }, textField: { classPropertyName: "textField", publicName: "textField", isSignal: true, isRequired: false, transformFunction: null }, visibleField: { classPropertyName: "visibleField", publicName: "visibleField", isSignal: true, isRequired: false, transformFunction: null }, disableField: { classPropertyName: "disableField", publicName: "disableField", isSignal: true, isRequired: false, transformFunction: null }, hasChildField: { classPropertyName: "hasChildField", publicName: "hasChildField", isSignal: true, isRequired: false, transformFunction: null }, selectedField: { classPropertyName: "selectedField", publicName: "selectedField", isSignal: true, isRequired: false, transformFunction: null }, expandedField: { classPropertyName: "expandedField", publicName: "expandedField", isSignal: true, isRequired: false, transformFunction: null }, tooltipField: { classPropertyName: "tooltipField", publicName: "tooltipField", isSignal: true, isRequired: false, transformFunction: null }, childrenField: { classPropertyName: "childrenField", publicName: "childrenField", isSignal: true, isRequired: false, transformFunction: null }, activeField: { classPropertyName: "activeField", publicName: "activeField", isSignal: true, isRequired: false, transformFunction: null }, indeterminateField: { classPropertyName: "indeterminateField", publicName: "indeterminateField", isSignal: true, isRequired: false, transformFunction: null }, parentField: { classPropertyName: "parentField", publicName: "parentField", isSignal: true, isRequired: false, transformFunction: null }, iconField: { classPropertyName: "iconField", publicName: "iconField", isSignal: true, isRequired: false, transformFunction: null }, toggleIcons: { classPropertyName: "toggleIcons", publicName: "toggleIcons", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, showEmptyNodeMassage: { classPropertyName: "showEmptyNodeMassage", publicName: "showEmptyNodeMassage", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: false, isRequired: false, transformFunction: null }, emptyTemplate: { classPropertyName: "emptyTemplate", publicName: "emptyTemplate", isSignal: false, isRequired: false, transformFunction: null }, expandOn: { classPropertyName: "expandOn", publicName: "expandOn", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSelectionChanged: "onSelectionChanged", onItemSelectedChanged: "onItemSelectedChanged", onNodeClick: "onNodeClick", onCollapsedChanged: "onCollapsedChanged", onNodedbClick: "onNodedbClick" }, host: { properties: { "class": "this.__hostClass" } }, providers: [
|
|
447
|
-
{ provide: AXComponent, useExisting: AXTreeViewComponent },
|
|
448
|
-
{ provide: AXTreeViewBase, useExisting: AXTreeViewComponent },
|
|
449
|
-
], usesInheritance: true, ngImport: i0, template: "@if (resolvedItems?.length) {\n @for (node of resolvedItems; track $index) {\n <ng-container [ngTemplateOutlet]=\"recursion\" [ngTemplateOutletContext]=\"{ $implicit: node }\"></ng-container>\n }\n} @else {\n <ng-container [ngTemplateOutlet]=\"emptyTemplate || empty\"></ng-container>\n}\n\n<ng-template #recursion let-item>\n @if (item[visibleField()] !== false) {\n <ax-tree-view-item\n [item]=\"item\"\n [isExpanded]=\"item[expandedField()]\"\n [(isActive)]=\"item[activeField()]\"\n [isLoading]=\"isNodeLoading(item[valueField()])\"\n [executorChanges]=\"executorChanges()\"\n >\n @if (\n (showCheckbox() && selectionScope() === 'all' && item[hasCheckboxField()] !== false) ||\n (showCheckbox() &&\n selectionScope() === 'parent' &&\n item[childrenField()]?.length &&\n item[hasCheckboxField()]) !== false ||\n (showCheckbox() &&\n selectionScope() === 'children' &&\n !item[childrenField()]?.length &&\n item[hasCheckboxField()] !== false)\n ) {\n <ax-check-box\n [disabled]=\"item[disableField()]\"\n [indeterminate]=\"item[indeterminateField()]\"\n [(ngModel)]=\"item[selectedField()]\"\n (onValueChanged)=\"handleNodeSelectionClick($event, item)\"\n ></ax-check-box>\n }\n @if (item[iconField()]) {\n <ax-prefix>\n <ax-icon [icon]=\"item[iconField()]\"></ax-icon>\n </ax-prefix>\n }\n @if (item[textField()]) {\n <ax-text>{{ item[textField()] }}</ax-text>\n }\n\n @for (child of item?.[childrenField()]; track $index) {\n <ng-container [ngTemplateOutlet]=\"recursion\" [ngTemplateOutletContext]=\"{ $implicit: child }\"></ng-container>\n }\n </ax-tree-view-item>\n }\n</ng-template>\n\n<ng-template #empty>\n {{ '@acorex:common.general.no-result-found' | translate | async }}\n</ng-template>\n", styles: ["ax-tree-view{--ax-comp-tree-view-arrow-size: .875rem;--ax-comp-tree-view-text-size: .875rem;--ax-comp-tree-view-active-bg-color: var(--ax-sys-color-primary-surface);--ax-comp-tree-view-active-text-color: var(--ax-sys-color-on-primary-surface);--ax-comp-tree-view-hover-bg-color: var(--ax-sys-color-dark-surface);--ax-comp-tree-view-indicator-size: 2px}ax-tree-view:has(>ax-tree-view-item i) ax-tree-view-item .ax-tree-view-container:not(:has(i)){padding-inline-start:1.5rem}ax-tree-view.ax-look-with-line ax-tree-view-item{position:relative}ax-tree-view.ax-look-with-line ax-tree-view-item:before{content:\"\";position:absolute;top:0;inset-inline-start:.625rem;width:1px;height:100%;background-color:#ccc}ax-tree-view.ax-look-with-line ax-tree-view-item .ax-tree-view-container{padding-inline-start:1.25rem}ax-tree-view.ax-look-with-line ax-tree-view-item .ax-tree-view-container .ax-tree-view-icon-container{padding:.25rem}ax-tree-view ax-tree-view-item ax-check-box{margin-inline-start:.5rem}ax-tree-view ax-tree-view-item .ax-tree-view-container{display:flex;align-items:center;margin-bottom:.125rem}ax-tree-view ax-tree-view-item .ax-tree-view-container ax-text{font-size:var(--ax-comp-tree-view-text-size)}ax-tree-view ax-tree-view-item .ax-tree-view-container{cursor:pointer}ax-tree-view ax-tree-view-item .ax-tree-view-container .ax-checkbox-end-side{display:none!important}ax-tree-view ax-tree-view-item .ax-tree-view-container .ax-tree-view-arrow{font-size:var(--ax-comp-tree-view-arrow-size)!important}ax-tree-view ax-tree-view-item .ax-tree-view-container ax-suffix:empty{display:none}ax-tree-view ax-tree-view-item .ax-tree-view-container .ax-tree-view-icon-container{width:1.5rem;height:1.5rem;display:flex;align-items:center;justify-content:center}ax-tree-view ax-tree-view-item .ax-tree-view-container .ax-tree-view-items{display:flex;align-items:center}ax-tree-view ax-tree-view-item .ax-tree-view-container .ax-tree-view-items .ax-tree-view-items-prefix{display:flex;align-items:center;gap:.5rem;padding:.25rem .5rem;border-radius:.25rem;overflow-x:auto;margin-inline-start:.25rem}ax-tree-view ax-tree-view-item .ax-tree-view-container .ax-tree-view-items .ax-tree-view-items-prefix.ax-noselect-tree-view{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}ax-tree-view ax-tree-view-item .ax-tree-view-container .ax-tree-view-items .ax-tree-view-items-prefix.ax-state-tree-view-active{background-color:rgba(var(--ax-comp-tree-view-active-bg-color));color:rgba(var(--ax-comp-tree-view-active-text-color))}ax-tree-view ax-tree-view-item .ax-tree-view-container .ax-tree-view-items .ax-tree-view-items-prefix:hover:not(.ax-state-tree-view-active){background-color:rgba(var(--ax-comp-tree-view-hover-bg-color))}ax-tree-view ax-tree-view-item .ax-tree-view-child{padding-inline-start:1rem}ax-tree-view ax-tree-view-item .ax-tree-view-child .ax-tree-view-container:not(:has(.ax-tree-view-icon-container i)){padding-inline-start:1.5rem}ax-tree-view ax-tree-view-item .ax-tree-view-child.ax-tree-view-empty-child{padding-inline-start:2rem}ax-tree-view ax-tree-view-item .ax-state-disabled{cursor:not-allowed!important;opacity:.5!important}@keyframes fadeSlideIn{0%{opacity:0;max-height:0}to{opacity:1;max-height:50px}}@keyframes fadeSlideOut{0%{opacity:1;max-height:50px}to{opacity:0;max-height:0}}ax-tree-view ax-tree-view-item .ax-fade-slide-in{animation:fadeSlideIn var(--ax-sys-transition-duration) var(--ax-sys-transition-timing-function)}ax-tree-view ax-tree-view-item .ax-fade-slide-out{animation:fadeSlideOut var(--ax-sys-transition-duration) var(--ax-sys-transition-timing-function)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AXTreeViewItemComponent, selector: "ax-tree-view-item", inputs: ["item", "isExpanded", "isActive", "isLoading", "executorChanges"], outputs: ["isExpandedChange", "isActiveChange"] }, { kind: "component", type: AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1186
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXTreeViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1187
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: AXTreeViewComponent, isStandalone: true, selector: "ax-tree-view", inputs: { datasource: { classPropertyName: "datasource", publicName: "datasource", isSignal: true, isRequired: true, transformFunction: null }, selectMode: { classPropertyName: "selectMode", publicName: "selectMode", isSignal: true, isRequired: false, transformFunction: null }, showCheckbox: { classPropertyName: "showCheckbox", publicName: "showCheckbox", isSignal: true, isRequired: false, transformFunction: null }, checkChildrenOnSelect: { classPropertyName: "checkChildrenOnSelect", publicName: "checkChildrenOnSelect", isSignal: true, isRequired: false, transformFunction: null }, intermediateState: { classPropertyName: "intermediateState", publicName: "intermediateState", isSignal: true, isRequired: false, transformFunction: null }, checkOnClick: { classPropertyName: "checkOnClick", publicName: "checkOnClick", isSignal: true, isRequired: false, transformFunction: null }, dragMode: { classPropertyName: "dragMode", publicName: "dragMode", isSignal: true, isRequired: false, transformFunction: null }, dragOperationType: { classPropertyName: "dragOperationType", publicName: "dragOperationType", isSignal: true, isRequired: false, transformFunction: null }, showIcons: { classPropertyName: "showIcons", publicName: "showIcons", isSignal: true, isRequired: false, transformFunction: null }, showChildrenBadge: { classPropertyName: "showChildrenBadge", publicName: "showChildrenBadge", isSignal: true, isRequired: false, transformFunction: null }, expandedIcon: { classPropertyName: "expandedIcon", publicName: "expandedIcon", isSignal: true, isRequired: false, transformFunction: null }, collapsedIcon: { classPropertyName: "collapsedIcon", publicName: "collapsedIcon", isSignal: true, isRequired: false, transformFunction: null }, indentSize: { classPropertyName: "indentSize", publicName: "indentSize", isSignal: true, isRequired: false, transformFunction: null }, nodeHeight: { classPropertyName: "nodeHeight", publicName: "nodeHeight", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { datasource: "datasourceChange", onBeforeDrop: "onBeforeDrop", onNodeToggle: "onNodeToggle", onNodeSelect: "onNodeSelect", onOrderChange: "onOrderChange", onMoveChange: "onMoveChange", onItemsChange: "onItemsChange" }, host: { attributes: { "role": "tree", "tabindex": "0" }, listeners: { "keydown": "handleKeyDown($event)", "focus": "onTreeFocus($event)", "blur": "onTreeBlur($event)" }, properties: { "class.ax-tree-view-default": "look() === 'default'", "class.ax-tree-view-card": "look() === 'card'", "class.ax-tree-view-with-line": "look() === 'with-line'", "class.ax-tree-view-rtl": "isRtl", "style.--ax-tree-view-indent-size": "indentSize() + 'px'", "style.--ax-tree-view-line-offset": "(indentSize() / 2) + 'px'", "attr.aria-label": "\"Tree navigation\"" }, classAttribute: "ax-tree-view" }, providers: [AXTreeViewService], ngImport: i0, template: "<!-- Root drop list -->\n<div\n axFocusTrap\n [axDropList]=\"dragMode() !== 'none'\"\n [sortingDisabled]=\"false\"\n [id]=\"getListId()\"\n [attr.data-node-id]=\"null\"\n dropListGroup=\"ax-tree-view-nodes\"\n (dropListDropped)=\"onDrop($event)\"\n class=\"ax-tree-view-drop-list\"\n [class.ax-tree-view-card]=\"look() === 'card'\"\n [class.ax-tree-view-with-lines]=\"look() === 'with-line'\"\n [class.ax-tree-view-compact]=\"nodeHeight() === 'compact'\"\n [class.ax-tree-view-comfortable]=\"nodeHeight() === 'comfortable'\"\n role=\"group\"\n>\n @for (node of nodes(); track node.id) {\n @if (node.visible !== false) {\n <div\n [axDrag]=\"dragMode() !== 'none'\"\n [dragDisabled]=\"node.disabled\"\n [dragData]=\"node\"\n class=\"ax-tree-view-node\"\n [class.ax-tree-view-node-selected]=\"node.selected\"\n [class.ax-tree-view-node-disabled]=\"node.disabled\"\n [class.ax-tree-view-node-loading]=\"node.loading\"\n role=\"treeitem\"\n [attr.aria-level]=\"getNodeAriaLevel(0)\"\n [attr.aria-expanded]=\"getNodeAriaExpanded(node)\"\n [attr.aria-selected]=\"getNodeAriaSelected(node)\"\n [attr.aria-disabled]=\"node.disabled ? 'true' : null\"\n >\n <div\n class=\"ax-tree-view-node-content\"\n [axDropList]=\"dragMode() !== 'none'\"\n [id]=\"'ax-tree-view-node-drop-' + node.id\"\n [attr.data-node-id]=\"node.id\"\n [attr.data-tree-node-id]=\"node.id\"\n [attr.data-drop-type]=\"'onto-node'\"\n dropListGroup=\"ax-tree-view-nodes\"\n (dropListDropped)=\"onDropOntoNode($event, node)\"\n (click)=\"\n (selectMode() === 'single' || (selectMode() === 'multiple' && checkOnClick())) && onNodeClick(node, $event)\n \"\n (focus)=\"onNodeFocus(node.id)\"\n [tabindex]=\"isNodeFocused(node.id) ? 0 : -1\"\n >\n @if (dragMode() === 'handler') {\n <span class=\"ax-tree-view-drag-handle\" axDragHandle title=\"Drag to reorder\"> \u22EE\u22EE </span>\n }\n <ax-button\n class=\"ax-tree-view-expand-toggle ax-sm\"\n (onClick)=\"toggleNode(node, $any($event))\"\n [class.ax-tree-view-has-children]=\"shouldShowExpandToggle(node)\"\n [class.ax-tree-view-expanded]=\"node.expanded\"\n [disabled]=\"node.disabled || node.loading\"\n [style.visibility]=\"shouldShowExpandToggle(node) ? 'visible' : 'hidden'\"\n >\n @if (node.loading) {\n <ax-icon>\n <i class=\"fa-solid fa-spinner fa-spin ax-tree-view-loading-spinner\"></i>\n </ax-icon>\n } @else {\n <ax-icon>\n <i\n [class]=\"node.expanded ? directionExpandedIcon() : directionCollapsedIcon()\"\n class=\"ax-tree-view-toggle-icon\"\n ></i>\n </ax-icon>\n }\n </ax-button>\n @if (itemTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate()!\"\n [ngTemplateOutletContext]=\"getTemplateContext(node, 0)\"\n ></ng-container>\n } @else {\n @if (shouldShowCheckbox()) {\n <ax-check-box\n class=\"ax-tree-view-checkbox\"\n [ngModel]=\"node.indeterminate ? null : node.selected || false\"\n [indeterminate]=\"node.indeterminate || false\"\n (onValueChanged)=\"toggleSelection(node, $event)\"\n ></ax-check-box>\n }\n @if (showIcons() && node.icon) {\n <i [class]=\"node.icon\" class=\"ax-tree-view-node-icon\"></i>\n }\n <span class=\"ax-tree-view-node-label\">{{ node.label }}</span>\n @if (showChildrenBadge() && (node.childrenCount || (node.children && node.children.length > 0))) {\n <ax-badge\n class=\"ax-tree-view-children-badge\"\n [text]=\"(node.childrenCount ?? node.children?.length ?? 0).toString()\"\n ></ax-badge>\n }\n }\n </div>\n </div>\n @if (node.expanded && node.children && node.children.length > 0) {\n <div class=\"ax-tree-view-children\" role=\"group\">\n <ng-container\n [ngTemplateOutlet]=\"childrenList\"\n [ngTemplateOutletContext]=\"{ children: node.children, parent: node, level: 1 }\"\n ></ng-container>\n </div>\n }\n }\n }\n</div>\n\n<!-- Recursive children template -->\n<ng-template #childrenList let-children=\"children\" let-parent=\"parent\" let-level=\"level\">\n <div\n [axDropList]=\"dragMode() !== 'none'\"\n [id]=\"getListId(parent)\"\n [attr.data-node-id]=\"parent.id\"\n dropListGroup=\"ax-tree-view-nodes\"\n (dropListDropped)=\"onDrop($event, parent)\"\n class=\"ax-tree-view-drop-list\"\n role=\"group\"\n >\n @for (node of children; track node.id) {\n @if (node.visible !== false) {\n <div\n [axDrag]=\"dragMode() !== 'none'\"\n [dragDisabled]=\"node.disabled\"\n [dragData]=\"node\"\n class=\"ax-tree-view-node\"\n [class.ax-tree-view-node-selected]=\"node.selected\"\n [class.ax-tree-view-node-disabled]=\"node.disabled\"\n [class.ax-tree-view-node-loading]=\"node.loading\"\n [class.ax-tree-view-node-focused]=\"isNodeFocused(node.id)\"\n role=\"treeitem\"\n [attr.aria-level]=\"getNodeAriaLevel(level)\"\n [attr.aria-expanded]=\"getNodeAriaExpanded(node)\"\n [attr.aria-selected]=\"getNodeAriaSelected(node)\"\n [attr.aria-disabled]=\"node.disabled ? 'true' : null\"\n >\n <div\n class=\"ax-tree-view-node-content\"\n [style.padding-inline-start.px]=\"getNodePaddingInline(level)\"\n [axDropList]=\"dragMode() !== 'none'\"\n [id]=\"'ax-tree-view-node-drop-' + node.id\"\n [attr.data-node-id]=\"node.id\"\n [attr.data-tree-node-id]=\"node.id\"\n [attr.data-drop-type]=\"'onto-node'\"\n dropListGroup=\"ax-tree-view-nodes\"\n (dropListDropped)=\"onDropOntoNode($event, node)\"\n (click)=\"\n (selectMode() === 'single' || (selectMode() === 'multiple' && checkOnClick())) &&\n onNodeClick(node, $event)\n \"\n (focus)=\"onNodeFocus(node.id)\"\n (blur)=\"focusedNodeId.set(null)\"\n [tabindex]=\"isNodeFocused(node.id) ? 0 : -1\"\n >\n @if (dragMode() === 'handler') {\n <span class=\"ax-tree-view-drag-handle\" axDragHandle title=\"Drag to reorder\"> \u22EE\u22EE </span>\n }\n <ax-button\n class=\"ax-tree-view-expand-toggle ax-sm\"\n (onClick)=\"toggleNode(node, $any($event))\"\n [class.ax-tree-view-has-children]=\"shouldShowExpandToggle(node)\"\n [class.ax-tree-view-expanded]=\"node.expanded\"\n [disabled]=\"node.disabled || node.loading\"\n [style.visibility]=\"shouldShowExpandToggle(node) ? 'visible' : 'hidden'\"\n >\n @if (node.loading) {\n <ax-icon>\n <i class=\"fa-solid fa-spinner fa-spin ax-tree-view-loading-spinner\"></i>\n </ax-icon>\n } @else {\n <ax-icon>\n <i\n [class]=\"node.expanded ? directionExpandedIcon() : directionCollapsedIcon()\"\n class=\"ax-tree-view-toggle-icon\"\n ></i>\n </ax-icon>\n }\n </ax-button>\n\n @if (itemTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate()!\"\n [ngTemplateOutletContext]=\"getTemplateContext(node, level)\"\n ></ng-container>\n } @else {\n @if (shouldShowCheckbox()) {\n <ax-check-box\n class=\"ax-tree-view-checkbox\"\n [ngModel]=\"node.indeterminate ? null : node.selected || false\"\n [indeterminate]=\"node.indeterminate || false\"\n (onValueChanged)=\"toggleSelection(node, $event)\"\n ></ax-check-box>\n }\n @if (showIcons() && node.icon) {\n <i [class]=\"node.icon\" class=\"ax-tree-view-node-icon\"></i>\n }\n <span class=\"ax-tree-view-node-label\">{{ node.label }}</span>\n @if (showChildrenBadge() && (node.childrenCount || (node.children && node.children.length > 0))) {\n <ax-badge\n class=\"ax-tree-view-children-badge\"\n [text]=\"(node.childrenCount ?? node.children?.length ?? 0).toString()\"\n ></ax-badge>\n }\n }\n </div>\n </div>\n @if (node.expanded && node.children && node.children.length > 0) {\n <div class=\"ax-tree-view-children\" role=\"group\">\n <ng-container\n [ngTemplateOutlet]=\"childrenList\"\n [ngTemplateOutletContext]=\"{ children: node.children, parent: node, level: level + 1 }\"\n ></ng-container>\n </div>\n }\n }\n }\n </div>\n</ng-template>\n", styles: [".ax-tree-view{display:block;width:100%;--ax-comp-tree-view-indent-size: 12px;--ax-comp-tree-view-node-hover-bg: rgba(var(--ax-sys-color-on-lightest-surface), .04);--ax-comp-tree-view-node-selected-bg: rgba(var(--ax-sys-color-primary-500), .12);--ax-comp-tree-view-node-border-radius: 6px;--ax-comp-tree-view-node-margin: .25rem;--ax-comp-tree-view-line-color: rgba(var(--ax-sys-color-on-lightest-surface), .15);--ax-comp-tree-view-drag-preview-opacity: .9;--ax-comp-tree-view-drag-placeholder-bg: rgba(var(--ax-sys-color-on-lightest-surface), .02);--ax-comp-tree-view-drop-active-bg: rgba(var(--ax-sys-color-primary-500), .08);--ax-comp-tree-view-drop-active-outline: rgba(var(--ax-sys-color-primary-500), .3);--ax-comp-tree-view-content-padding: 0;--ax-comp-tree-view-content-gap: .5rem;--ax-comp-tree-view-drop-list-min-height: 2rem;--ax-comp-tree-view-drag-handle-padding: .25rem;--ax-comp-tree-view-expand-toggle-padding: .25rem;--ax-comp-tree-view-card-node-margin: .5rem;--ax-comp-tree-view-card-content-padding: 1rem;--ax-comp-tree-view-outline-offset: 2px;--ax-comp-tree-view-outline-offset-negative: -2px}.ax-tree-view-drop-list{min-height:var(--ax-comp-tree-view-drop-list-min-height)}.ax-tree-view-compact .ax-tree-view-node-content{padding:var(--ax-comp-tree-view-content-padding, .25rem .5rem);gap:var(--ax-comp-tree-view-content-gap, .375rem);font-size:.8125rem}.ax-tree-view-comfortable .ax-tree-view-node-content{padding:var(--ax-comp-tree-view-content-padding, .75rem .625rem);gap:var(--ax-comp-tree-view-content-gap, .625rem);font-size:.9375rem}.ax-tree-view-node{position:relative;margin:var(--ax-comp-tree-view-node-margin) 0;border-radius:var(--ax-comp-tree-view-node-border-radius);border:1px solid transparent;cursor:move}.ax-tree-view-node:hover:not(.ax-dragging){background:var(--ax-comp-tree-view-node-hover-bg)}.ax-tree-view-node.ax-tree-view-node-selected{background:var(--ax-comp-tree-view-node-selected-bg);border-color:currentColor}.ax-tree-view-node.ax-dragging{opacity:var(--ax-comp-tree-view-drag-placeholder-opacity);cursor:grabbing!important}.ax-tree-view-node.ax-drag-placeholder{background:var(--ax-comp-tree-view-drag-placeholder-bg)}.ax-drag-preview{opacity:var(--ax-comp-tree-view-drag-preview-opacity)!important;box-shadow:0 4px 12px rgba(var(--ax-sys-color-on-lightest-surface),.2)!important;cursor:grabbing!important;border:2px dashed currentColor!important}.ax-tree-view-node-content.ax-drop-list-sorting-active{background:var(--ax-comp-tree-view-drop-active-bg);border-radius:var(--ax-comp-tree-view-node-border-radius);outline:2px dashed var(--ax-comp-tree-view-drop-active-outline);outline-offset:var(--ax-comp-tree-view-outline-offset-negative)}.ax-tree-view-node-content{display:flex;align-items:center;gap:var(--ax-comp-tree-view-content-gap);padding:var(--ax-comp-tree-view-content-padding);cursor:pointer;-webkit-user-select:none;user-select:none;outline:none;border:1px solid transparent;border-radius:var(--ax-comp-tree-view-node-border-radius)}.ax-tree-view-node-content:focus{outline:none}.ax-tree-view-node-content:focus-visible{outline:2px solid rgba(var(--ax-sys-color-primary-500),.8);outline-offset:var(--ax-comp-tree-view-outline-offset);border-radius:var(--ax-comp-tree-view-node-border-radius)}.ax-tree-view-drag-handle{cursor:grab;opacity:.6;padding:var(--ax-comp-tree-view-drag-handle-padding)}.ax-tree-view-drag-handle:hover{opacity:1}.ax-tree-view-drag-handle:active{cursor:grabbing}.ax-tree-view-expand-toggle{background:none;border:none;cursor:pointer;padding:var(--ax-comp-tree-view-expand-toggle-padding);min-width:1.5rem;height:1.5rem}.ax-tree-view-expand-toggle:not(.ax-tree-view-has-children){opacity:0;pointer-events:none}.ax-tree-view-toggle-icon{font-size:.75rem}.ax-tree-view-node-icon{font-size:1.125rem;flex-shrink:0}.ax-tree-view-node-label{flex:1;font-size:.875rem;line-height:1rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ax-tree-view-children{padding-inline-start:var(--ax-tree-view-indent-size, var(--ax-comp-tree-view-indent-size))}.ax-tree-view-node-disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.ax-tree-view-node-loading{opacity:.7}.ax-tree-view-card .ax-tree-view-node{border:1px solid rgba(var(--ax-sys-color-border-lightest-surface),1);margin:var(--ax-comp-tree-view-card-node-margin) 0}.ax-tree-view-card .ax-tree-view-node-content{padding:var(--ax-comp-tree-view-card-content-padding)}.ax-tree-view-with-lines .ax-tree-view-children{position:relative;padding-inline-start:var(--ax-tree-view-indent-size, var(--ax-comp-tree-view-indent-size))}.ax-tree-view-with-lines .ax-tree-view-children:before{content:\"\";position:absolute;inset-inline-start:var(--ax-tree-view-line-offset, calc(var(--ax-comp-tree-view-indent-size) / 2));top:0;height:calc(100% - .875rem);width:1px;background:var(--ax-tree-view-line-color, var(--ax-comp-tree-view-line-color))}.ax-tree-view-with-lines .ax-tree-view-node{position:relative}.ax-tree-view-with-lines .ax-tree-view-node:before{content:\"\";position:absolute;inset-inline-start:calc(-1 * var(--ax-tree-view-line-offset, calc(var(--ax-comp-tree-view-indent-size) / 2)));top:60%;width:var(--ax-tree-view-line-offset, calc(var(--ax-comp-tree-view-indent-size) / 2));height:1px;background:var(--ax-tree-view-line-color, var(--ax-comp-tree-view-line-color))}.ax-tree-view-with-lines>.ax-tree-view-drop-list>.ax-tree-view-node:before,.ax-tree-view-with-lines>.ax-tree-view-node:before{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: AXDragDirective, selector: "[axDrag]", inputs: ["axDrag", "dragData", "dragDisabled", "dragTransition", "dragElementClone", "dropZoneGroup", "dragStartDelay", "dragResetOnDblClick", "dragLockAxis", "dragClonedTemplate", "dragCursor", "dragBoundary", "dragTransitionDuration"], outputs: ["dragPositionChanged"] }, { kind: "directive", type: AXDragHandleDirective, selector: "[axDragHandle]" }, { kind: "directive", type: AXDropListDirective, selector: "[axDropList]", inputs: ["axDropList", "sortingDisabled", "dropListGroup", "dropListOrientation"], outputs: ["dropListDropped"], exportAs: ["axDropList"] }, { kind: "directive", type: AXFocusTrapDirective, selector: "[axFocusTrap]" }, { kind: "component", type: AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: AXCheckBoxComponent, selector: "ax-check-box", inputs: ["disabled", "tabIndex", "readonly", "color", "value", "name", "id", "isLoading", "indeterminate"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged"] }, { kind: "component", type: AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "component", type: AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
450
1188
|
}
|
|
451
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1189
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXTreeViewComponent, decorators: [{
|
|
452
1190
|
type: Component,
|
|
453
|
-
args: [{ selector: 'ax-tree-view', encapsulation: ViewEncapsulation.None,
|
|
1191
|
+
args: [{ selector: 'ax-tree-view', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [AXTreeViewService], imports: [
|
|
1192
|
+
CommonModule,
|
|
1193
|
+
FormsModule,
|
|
1194
|
+
AXDragDirective,
|
|
1195
|
+
AXDragHandleDirective,
|
|
1196
|
+
AXDropListDirective,
|
|
1197
|
+
AXFocusTrapDirective,
|
|
454
1198
|
NgTemplateOutlet,
|
|
455
|
-
|
|
1199
|
+
AXButtonComponent,
|
|
456
1200
|
AXCheckBoxComponent,
|
|
457
|
-
|
|
458
|
-
AXDecoratorGenericComponent,
|
|
1201
|
+
AXBadgeComponent,
|
|
459
1202
|
AXDecoratorIconComponent,
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
1203
|
+
], host: {
|
|
1204
|
+
class: 'ax-tree-view',
|
|
1205
|
+
'[class.ax-tree-view-default]': "look() === 'default'",
|
|
1206
|
+
'[class.ax-tree-view-card]': "look() === 'card'",
|
|
1207
|
+
'[class.ax-tree-view-with-line]': "look() === 'with-line'",
|
|
1208
|
+
'[class.ax-tree-view-rtl]': 'isRtl',
|
|
1209
|
+
'[style.--ax-tree-view-indent-size]': "indentSize() + 'px'",
|
|
1210
|
+
'[style.--ax-tree-view-line-offset]': "(indentSize() / 2) + 'px'",
|
|
1211
|
+
role: 'tree',
|
|
1212
|
+
'[attr.aria-label]': '"Tree navigation"',
|
|
1213
|
+
'(keydown)': 'handleKeyDown($event)',
|
|
1214
|
+
'(focus)': 'onTreeFocus($event)',
|
|
1215
|
+
'(blur)': 'onTreeBlur($event)',
|
|
1216
|
+
tabindex: '0',
|
|
1217
|
+
}, template: "<!-- Root drop list -->\n<div\n axFocusTrap\n [axDropList]=\"dragMode() !== 'none'\"\n [sortingDisabled]=\"false\"\n [id]=\"getListId()\"\n [attr.data-node-id]=\"null\"\n dropListGroup=\"ax-tree-view-nodes\"\n (dropListDropped)=\"onDrop($event)\"\n class=\"ax-tree-view-drop-list\"\n [class.ax-tree-view-card]=\"look() === 'card'\"\n [class.ax-tree-view-with-lines]=\"look() === 'with-line'\"\n [class.ax-tree-view-compact]=\"nodeHeight() === 'compact'\"\n [class.ax-tree-view-comfortable]=\"nodeHeight() === 'comfortable'\"\n role=\"group\"\n>\n @for (node of nodes(); track node.id) {\n @if (node.visible !== false) {\n <div\n [axDrag]=\"dragMode() !== 'none'\"\n [dragDisabled]=\"node.disabled\"\n [dragData]=\"node\"\n class=\"ax-tree-view-node\"\n [class.ax-tree-view-node-selected]=\"node.selected\"\n [class.ax-tree-view-node-disabled]=\"node.disabled\"\n [class.ax-tree-view-node-loading]=\"node.loading\"\n role=\"treeitem\"\n [attr.aria-level]=\"getNodeAriaLevel(0)\"\n [attr.aria-expanded]=\"getNodeAriaExpanded(node)\"\n [attr.aria-selected]=\"getNodeAriaSelected(node)\"\n [attr.aria-disabled]=\"node.disabled ? 'true' : null\"\n >\n <div\n class=\"ax-tree-view-node-content\"\n [axDropList]=\"dragMode() !== 'none'\"\n [id]=\"'ax-tree-view-node-drop-' + node.id\"\n [attr.data-node-id]=\"node.id\"\n [attr.data-tree-node-id]=\"node.id\"\n [attr.data-drop-type]=\"'onto-node'\"\n dropListGroup=\"ax-tree-view-nodes\"\n (dropListDropped)=\"onDropOntoNode($event, node)\"\n (click)=\"\n (selectMode() === 'single' || (selectMode() === 'multiple' && checkOnClick())) && onNodeClick(node, $event)\n \"\n (focus)=\"onNodeFocus(node.id)\"\n [tabindex]=\"isNodeFocused(node.id) ? 0 : -1\"\n >\n @if (dragMode() === 'handler') {\n <span class=\"ax-tree-view-drag-handle\" axDragHandle title=\"Drag to reorder\"> \u22EE\u22EE </span>\n }\n <ax-button\n class=\"ax-tree-view-expand-toggle ax-sm\"\n (onClick)=\"toggleNode(node, $any($event))\"\n [class.ax-tree-view-has-children]=\"shouldShowExpandToggle(node)\"\n [class.ax-tree-view-expanded]=\"node.expanded\"\n [disabled]=\"node.disabled || node.loading\"\n [style.visibility]=\"shouldShowExpandToggle(node) ? 'visible' : 'hidden'\"\n >\n @if (node.loading) {\n <ax-icon>\n <i class=\"fa-solid fa-spinner fa-spin ax-tree-view-loading-spinner\"></i>\n </ax-icon>\n } @else {\n <ax-icon>\n <i\n [class]=\"node.expanded ? directionExpandedIcon() : directionCollapsedIcon()\"\n class=\"ax-tree-view-toggle-icon\"\n ></i>\n </ax-icon>\n }\n </ax-button>\n @if (itemTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate()!\"\n [ngTemplateOutletContext]=\"getTemplateContext(node, 0)\"\n ></ng-container>\n } @else {\n @if (shouldShowCheckbox()) {\n <ax-check-box\n class=\"ax-tree-view-checkbox\"\n [ngModel]=\"node.indeterminate ? null : node.selected || false\"\n [indeterminate]=\"node.indeterminate || false\"\n (onValueChanged)=\"toggleSelection(node, $event)\"\n ></ax-check-box>\n }\n @if (showIcons() && node.icon) {\n <i [class]=\"node.icon\" class=\"ax-tree-view-node-icon\"></i>\n }\n <span class=\"ax-tree-view-node-label\">{{ node.label }}</span>\n @if (showChildrenBadge() && (node.childrenCount || (node.children && node.children.length > 0))) {\n <ax-badge\n class=\"ax-tree-view-children-badge\"\n [text]=\"(node.childrenCount ?? node.children?.length ?? 0).toString()\"\n ></ax-badge>\n }\n }\n </div>\n </div>\n @if (node.expanded && node.children && node.children.length > 0) {\n <div class=\"ax-tree-view-children\" role=\"group\">\n <ng-container\n [ngTemplateOutlet]=\"childrenList\"\n [ngTemplateOutletContext]=\"{ children: node.children, parent: node, level: 1 }\"\n ></ng-container>\n </div>\n }\n }\n }\n</div>\n\n<!-- Recursive children template -->\n<ng-template #childrenList let-children=\"children\" let-parent=\"parent\" let-level=\"level\">\n <div\n [axDropList]=\"dragMode() !== 'none'\"\n [id]=\"getListId(parent)\"\n [attr.data-node-id]=\"parent.id\"\n dropListGroup=\"ax-tree-view-nodes\"\n (dropListDropped)=\"onDrop($event, parent)\"\n class=\"ax-tree-view-drop-list\"\n role=\"group\"\n >\n @for (node of children; track node.id) {\n @if (node.visible !== false) {\n <div\n [axDrag]=\"dragMode() !== 'none'\"\n [dragDisabled]=\"node.disabled\"\n [dragData]=\"node\"\n class=\"ax-tree-view-node\"\n [class.ax-tree-view-node-selected]=\"node.selected\"\n [class.ax-tree-view-node-disabled]=\"node.disabled\"\n [class.ax-tree-view-node-loading]=\"node.loading\"\n [class.ax-tree-view-node-focused]=\"isNodeFocused(node.id)\"\n role=\"treeitem\"\n [attr.aria-level]=\"getNodeAriaLevel(level)\"\n [attr.aria-expanded]=\"getNodeAriaExpanded(node)\"\n [attr.aria-selected]=\"getNodeAriaSelected(node)\"\n [attr.aria-disabled]=\"node.disabled ? 'true' : null\"\n >\n <div\n class=\"ax-tree-view-node-content\"\n [style.padding-inline-start.px]=\"getNodePaddingInline(level)\"\n [axDropList]=\"dragMode() !== 'none'\"\n [id]=\"'ax-tree-view-node-drop-' + node.id\"\n [attr.data-node-id]=\"node.id\"\n [attr.data-tree-node-id]=\"node.id\"\n [attr.data-drop-type]=\"'onto-node'\"\n dropListGroup=\"ax-tree-view-nodes\"\n (dropListDropped)=\"onDropOntoNode($event, node)\"\n (click)=\"\n (selectMode() === 'single' || (selectMode() === 'multiple' && checkOnClick())) &&\n onNodeClick(node, $event)\n \"\n (focus)=\"onNodeFocus(node.id)\"\n (blur)=\"focusedNodeId.set(null)\"\n [tabindex]=\"isNodeFocused(node.id) ? 0 : -1\"\n >\n @if (dragMode() === 'handler') {\n <span class=\"ax-tree-view-drag-handle\" axDragHandle title=\"Drag to reorder\"> \u22EE\u22EE </span>\n }\n <ax-button\n class=\"ax-tree-view-expand-toggle ax-sm\"\n (onClick)=\"toggleNode(node, $any($event))\"\n [class.ax-tree-view-has-children]=\"shouldShowExpandToggle(node)\"\n [class.ax-tree-view-expanded]=\"node.expanded\"\n [disabled]=\"node.disabled || node.loading\"\n [style.visibility]=\"shouldShowExpandToggle(node) ? 'visible' : 'hidden'\"\n >\n @if (node.loading) {\n <ax-icon>\n <i class=\"fa-solid fa-spinner fa-spin ax-tree-view-loading-spinner\"></i>\n </ax-icon>\n } @else {\n <ax-icon>\n <i\n [class]=\"node.expanded ? directionExpandedIcon() : directionCollapsedIcon()\"\n class=\"ax-tree-view-toggle-icon\"\n ></i>\n </ax-icon>\n }\n </ax-button>\n\n @if (itemTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate()!\"\n [ngTemplateOutletContext]=\"getTemplateContext(node, level)\"\n ></ng-container>\n } @else {\n @if (shouldShowCheckbox()) {\n <ax-check-box\n class=\"ax-tree-view-checkbox\"\n [ngModel]=\"node.indeterminate ? null : node.selected || false\"\n [indeterminate]=\"node.indeterminate || false\"\n (onValueChanged)=\"toggleSelection(node, $event)\"\n ></ax-check-box>\n }\n @if (showIcons() && node.icon) {\n <i [class]=\"node.icon\" class=\"ax-tree-view-node-icon\"></i>\n }\n <span class=\"ax-tree-view-node-label\">{{ node.label }}</span>\n @if (showChildrenBadge() && (node.childrenCount || (node.children && node.children.length > 0))) {\n <ax-badge\n class=\"ax-tree-view-children-badge\"\n [text]=\"(node.childrenCount ?? node.children?.length ?? 0).toString()\"\n ></ax-badge>\n }\n }\n </div>\n </div>\n @if (node.expanded && node.children && node.children.length > 0) {\n <div class=\"ax-tree-view-children\" role=\"group\">\n <ng-container\n [ngTemplateOutlet]=\"childrenList\"\n [ngTemplateOutletContext]=\"{ children: node.children, parent: node, level: level + 1 }\"\n ></ng-container>\n </div>\n }\n }\n }\n </div>\n</ng-template>\n", styles: [".ax-tree-view{display:block;width:100%;--ax-comp-tree-view-indent-size: 12px;--ax-comp-tree-view-node-hover-bg: rgba(var(--ax-sys-color-on-lightest-surface), .04);--ax-comp-tree-view-node-selected-bg: rgba(var(--ax-sys-color-primary-500), .12);--ax-comp-tree-view-node-border-radius: 6px;--ax-comp-tree-view-node-margin: .25rem;--ax-comp-tree-view-line-color: rgba(var(--ax-sys-color-on-lightest-surface), .15);--ax-comp-tree-view-drag-preview-opacity: .9;--ax-comp-tree-view-drag-placeholder-bg: rgba(var(--ax-sys-color-on-lightest-surface), .02);--ax-comp-tree-view-drop-active-bg: rgba(var(--ax-sys-color-primary-500), .08);--ax-comp-tree-view-drop-active-outline: rgba(var(--ax-sys-color-primary-500), .3);--ax-comp-tree-view-content-padding: 0;--ax-comp-tree-view-content-gap: .5rem;--ax-comp-tree-view-drop-list-min-height: 2rem;--ax-comp-tree-view-drag-handle-padding: .25rem;--ax-comp-tree-view-expand-toggle-padding: .25rem;--ax-comp-tree-view-card-node-margin: .5rem;--ax-comp-tree-view-card-content-padding: 1rem;--ax-comp-tree-view-outline-offset: 2px;--ax-comp-tree-view-outline-offset-negative: -2px}.ax-tree-view-drop-list{min-height:var(--ax-comp-tree-view-drop-list-min-height)}.ax-tree-view-compact .ax-tree-view-node-content{padding:var(--ax-comp-tree-view-content-padding, .25rem .5rem);gap:var(--ax-comp-tree-view-content-gap, .375rem);font-size:.8125rem}.ax-tree-view-comfortable .ax-tree-view-node-content{padding:var(--ax-comp-tree-view-content-padding, .75rem .625rem);gap:var(--ax-comp-tree-view-content-gap, .625rem);font-size:.9375rem}.ax-tree-view-node{position:relative;margin:var(--ax-comp-tree-view-node-margin) 0;border-radius:var(--ax-comp-tree-view-node-border-radius);border:1px solid transparent;cursor:move}.ax-tree-view-node:hover:not(.ax-dragging){background:var(--ax-comp-tree-view-node-hover-bg)}.ax-tree-view-node.ax-tree-view-node-selected{background:var(--ax-comp-tree-view-node-selected-bg);border-color:currentColor}.ax-tree-view-node.ax-dragging{opacity:var(--ax-comp-tree-view-drag-placeholder-opacity);cursor:grabbing!important}.ax-tree-view-node.ax-drag-placeholder{background:var(--ax-comp-tree-view-drag-placeholder-bg)}.ax-drag-preview{opacity:var(--ax-comp-tree-view-drag-preview-opacity)!important;box-shadow:0 4px 12px rgba(var(--ax-sys-color-on-lightest-surface),.2)!important;cursor:grabbing!important;border:2px dashed currentColor!important}.ax-tree-view-node-content.ax-drop-list-sorting-active{background:var(--ax-comp-tree-view-drop-active-bg);border-radius:var(--ax-comp-tree-view-node-border-radius);outline:2px dashed var(--ax-comp-tree-view-drop-active-outline);outline-offset:var(--ax-comp-tree-view-outline-offset-negative)}.ax-tree-view-node-content{display:flex;align-items:center;gap:var(--ax-comp-tree-view-content-gap);padding:var(--ax-comp-tree-view-content-padding);cursor:pointer;-webkit-user-select:none;user-select:none;outline:none;border:1px solid transparent;border-radius:var(--ax-comp-tree-view-node-border-radius)}.ax-tree-view-node-content:focus{outline:none}.ax-tree-view-node-content:focus-visible{outline:2px solid rgba(var(--ax-sys-color-primary-500),.8);outline-offset:var(--ax-comp-tree-view-outline-offset);border-radius:var(--ax-comp-tree-view-node-border-radius)}.ax-tree-view-drag-handle{cursor:grab;opacity:.6;padding:var(--ax-comp-tree-view-drag-handle-padding)}.ax-tree-view-drag-handle:hover{opacity:1}.ax-tree-view-drag-handle:active{cursor:grabbing}.ax-tree-view-expand-toggle{background:none;border:none;cursor:pointer;padding:var(--ax-comp-tree-view-expand-toggle-padding);min-width:1.5rem;height:1.5rem}.ax-tree-view-expand-toggle:not(.ax-tree-view-has-children){opacity:0;pointer-events:none}.ax-tree-view-toggle-icon{font-size:.75rem}.ax-tree-view-node-icon{font-size:1.125rem;flex-shrink:0}.ax-tree-view-node-label{flex:1;font-size:.875rem;line-height:1rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ax-tree-view-children{padding-inline-start:var(--ax-tree-view-indent-size, var(--ax-comp-tree-view-indent-size))}.ax-tree-view-node-disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.ax-tree-view-node-loading{opacity:.7}.ax-tree-view-card .ax-tree-view-node{border:1px solid rgba(var(--ax-sys-color-border-lightest-surface),1);margin:var(--ax-comp-tree-view-card-node-margin) 0}.ax-tree-view-card .ax-tree-view-node-content{padding:var(--ax-comp-tree-view-card-content-padding)}.ax-tree-view-with-lines .ax-tree-view-children{position:relative;padding-inline-start:var(--ax-tree-view-indent-size, var(--ax-comp-tree-view-indent-size))}.ax-tree-view-with-lines .ax-tree-view-children:before{content:\"\";position:absolute;inset-inline-start:var(--ax-tree-view-line-offset, calc(var(--ax-comp-tree-view-indent-size) / 2));top:0;height:calc(100% - .875rem);width:1px;background:var(--ax-tree-view-line-color, var(--ax-comp-tree-view-line-color))}.ax-tree-view-with-lines .ax-tree-view-node{position:relative}.ax-tree-view-with-lines .ax-tree-view-node:before{content:\"\";position:absolute;inset-inline-start:calc(-1 * var(--ax-tree-view-line-offset, calc(var(--ax-comp-tree-view-indent-size) / 2)));top:60%;width:var(--ax-tree-view-line-offset, calc(var(--ax-comp-tree-view-indent-size) / 2));height:1px;background:var(--ax-tree-view-line-color, var(--ax-comp-tree-view-line-color))}.ax-tree-view-with-lines>.ax-tree-view-drop-list>.ax-tree-view-node:before,.ax-tree-view-with-lines>.ax-tree-view-node:before{display:none}\n"] }]
|
|
1218
|
+
}], propDecorators: { datasource: [{ type: i0.Input, args: [{ isSignal: true, alias: "datasource", required: true }] }, { type: i0.Output, args: ["datasourceChange"] }], selectMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectMode", required: false }] }], showCheckbox: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCheckbox", required: false }] }], checkChildrenOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "checkChildrenOnSelect", required: false }] }], intermediateState: [{ type: i0.Input, args: [{ isSignal: true, alias: "intermediateState", required: false }] }], checkOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "checkOnClick", required: false }] }], dragMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragMode", required: false }] }], dragOperationType: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragOperationType", required: false }] }], showIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIcons", required: false }] }], showChildrenBadge: [{ type: i0.Input, args: [{ isSignal: true, alias: "showChildrenBadge", required: false }] }], expandedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedIcon", required: false }] }], collapsedIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsedIcon", required: false }] }], indentSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "indentSize", required: false }] }], nodeHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeHeight", required: false }] }], look: [{ type: i0.Input, args: [{ isSignal: true, alias: "look", required: false }] }], itemTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemTemplate", required: false }] }], onBeforeDrop: [{ type: i0.Output, args: ["onBeforeDrop"] }], onNodeToggle: [{ type: i0.Output, args: ["onNodeToggle"] }], onNodeSelect: [{ type: i0.Output, args: ["onNodeSelect"] }], onOrderChange: [{ type: i0.Output, args: ["onOrderChange"] }], onMoveChange: [{ type: i0.Output, args: ["onMoveChange"] }], onItemsChange: [{ type: i0.Output, args: ["onItemsChange"] }] } });
|
|
474
1219
|
|
|
475
|
-
const COMPONENT = [AXTreeViewComponent, AXTreeViewItemComponent];
|
|
476
|
-
const MODULES = [
|
|
477
|
-
CommonModule,
|
|
478
|
-
AXCommonModule,
|
|
479
|
-
AXDecoratorModule,
|
|
480
|
-
AXCheckBoxModule,
|
|
481
|
-
AXFormModule,
|
|
482
|
-
FormsModule,
|
|
483
|
-
AXTooltipModule,
|
|
484
|
-
AXLoadingModule,
|
|
485
|
-
];
|
|
486
1220
|
class AXTreeViewModule {
|
|
487
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.
|
|
488
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.
|
|
489
|
-
|
|
490
|
-
AXDecoratorModule,
|
|
491
|
-
AXCheckBoxModule,
|
|
492
|
-
AXFormModule,
|
|
493
|
-
FormsModule,
|
|
494
|
-
AXTooltipModule,
|
|
495
|
-
AXLoadingModule], exports: [AXTreeViewComponent, AXTreeViewItemComponent] }); }
|
|
496
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXTreeViewModule, imports: [COMPONENT, MODULES] }); }
|
|
1221
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXTreeViewModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1222
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.9", ngImport: i0, type: AXTreeViewModule, imports: [AXTreeViewComponent] }); }
|
|
1223
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXTreeViewModule, imports: [AXTreeViewComponent] }); }
|
|
497
1224
|
}
|
|
498
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.
|
|
1225
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AXTreeViewModule, decorators: [{
|
|
499
1226
|
type: NgModule,
|
|
500
1227
|
args: [{
|
|
501
|
-
imports: [
|
|
502
|
-
exports: [...COMPONENT],
|
|
1228
|
+
imports: [AXTreeViewComponent],
|
|
503
1229
|
}]
|
|
504
1230
|
}] });
|
|
505
1231
|
|
|
@@ -507,5 +1233,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImpo
|
|
|
507
1233
|
* Generated bundle index. Do not edit.
|
|
508
1234
|
*/
|
|
509
1235
|
|
|
510
|
-
export {
|
|
1236
|
+
export { AXTreeViewComponent, AXTreeViewModule, AXTreeViewService };
|
|
511
1237
|
//# sourceMappingURL=acorex-components-tree-view.mjs.map
|