@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.
Files changed (240) hide show
  1. package/accordion/index.d.ts +1 -0
  2. package/button-group/index.d.ts +4 -6
  3. package/chips/index.d.ts +8 -3
  4. package/dialog/index.d.ts +1 -1
  5. package/fesm2022/acorex-components-accordion.mjs +21 -16
  6. package/fesm2022/acorex-components-accordion.mjs.map +1 -1
  7. package/fesm2022/acorex-components-action-sheet.mjs +12 -12
  8. package/fesm2022/acorex-components-action-sheet.mjs.map +1 -1
  9. package/fesm2022/acorex-components-alert.mjs +13 -13
  10. package/fesm2022/acorex-components-alert.mjs.map +1 -1
  11. package/fesm2022/acorex-components-aspect-ratio.mjs +3 -3
  12. package/fesm2022/acorex-components-aspect-ratio.mjs.map +1 -1
  13. package/fesm2022/acorex-components-audio-wave.mjs +10 -11
  14. package/fesm2022/acorex-components-audio-wave.mjs.map +1 -1
  15. package/fesm2022/acorex-components-autocomplete.mjs +7 -7
  16. package/fesm2022/acorex-components-autocomplete.mjs.map +1 -1
  17. package/fesm2022/acorex-components-avatar.mjs +12 -12
  18. package/fesm2022/acorex-components-avatar.mjs.map +1 -1
  19. package/fesm2022/acorex-components-badge.mjs +9 -9
  20. package/fesm2022/acorex-components-badge.mjs.map +1 -1
  21. package/fesm2022/acorex-components-bottom-navigation.mjs +11 -11
  22. package/fesm2022/acorex-components-bottom-navigation.mjs.map +1 -1
  23. package/fesm2022/acorex-components-breadcrumbs.mjs +11 -11
  24. package/fesm2022/acorex-components-breadcrumbs.mjs.map +1 -1
  25. package/fesm2022/acorex-components-button-group.mjs +19 -23
  26. package/fesm2022/acorex-components-button-group.mjs.map +1 -1
  27. package/fesm2022/acorex-components-button.mjs +18 -18
  28. package/fesm2022/acorex-components-button.mjs.map +1 -1
  29. package/fesm2022/acorex-components-calendar.mjs +17 -17
  30. package/fesm2022/acorex-components-calendar.mjs.map +1 -1
  31. package/fesm2022/acorex-components-check-box.mjs +10 -10
  32. package/fesm2022/acorex-components-check-box.mjs.map +1 -1
  33. package/fesm2022/acorex-components-chips.mjs +14 -12
  34. package/fesm2022/acorex-components-chips.mjs.map +1 -1
  35. package/fesm2022/acorex-components-circular-progress.mjs +10 -12
  36. package/fesm2022/acorex-components-circular-progress.mjs.map +1 -1
  37. package/fesm2022/acorex-components-code-editor.mjs +10 -10
  38. package/fesm2022/acorex-components-code-editor.mjs.map +1 -1
  39. package/fesm2022/acorex-components-collapse.mjs +13 -13
  40. package/fesm2022/acorex-components-collapse.mjs.map +1 -1
  41. package/fesm2022/acorex-components-color-box.mjs +9 -9
  42. package/fesm2022/acorex-components-color-box.mjs.map +1 -1
  43. package/fesm2022/acorex-components-color-palette.mjs +30 -30
  44. package/fesm2022/acorex-components-color-palette.mjs.map +1 -1
  45. package/fesm2022/acorex-components-command.mjs +9 -9
  46. package/fesm2022/acorex-components-command.mjs.map +1 -1
  47. package/fesm2022/acorex-components-comment.mjs +32 -32
  48. package/fesm2022/acorex-components-comment.mjs.map +1 -1
  49. package/fesm2022/acorex-components-conversation.mjs +51 -51
  50. package/fesm2022/acorex-components-conversation.mjs.map +1 -1
  51. package/fesm2022/acorex-components-conversation2.mjs +186 -186
  52. package/fesm2022/acorex-components-conversation2.mjs.map +1 -1
  53. package/fesm2022/acorex-components-cron-job.mjs +46 -46
  54. package/fesm2022/acorex-components-cron-job.mjs.map +1 -1
  55. package/fesm2022/acorex-components-data-list.mjs +3 -3
  56. package/fesm2022/acorex-components-data-list.mjs.map +1 -1
  57. package/fesm2022/acorex-components-data-pager.mjs +33 -33
  58. package/fesm2022/acorex-components-data-pager.mjs.map +1 -1
  59. package/fesm2022/acorex-components-data-table.mjs +43 -43
  60. package/fesm2022/acorex-components-data-table.mjs.map +1 -1
  61. package/fesm2022/acorex-components-datetime-box.mjs +9 -9
  62. package/fesm2022/acorex-components-datetime-box.mjs.map +1 -1
  63. package/fesm2022/acorex-components-datetime-input.mjs +9 -9
  64. package/fesm2022/acorex-components-datetime-input.mjs.map +1 -1
  65. package/fesm2022/acorex-components-datetime-picker.mjs +9 -9
  66. package/fesm2022/acorex-components-datetime-picker.mjs.map +1 -1
  67. package/fesm2022/acorex-components-decorators.mjs +36 -43
  68. package/fesm2022/acorex-components-decorators.mjs.map +1 -1
  69. package/fesm2022/acorex-components-dialog.mjs +14 -15
  70. package/fesm2022/acorex-components-dialog.mjs.map +1 -1
  71. package/fesm2022/acorex-components-drawer-legacy.mjs +13 -13
  72. package/fesm2022/acorex-components-drawer-legacy.mjs.map +1 -1
  73. package/fesm2022/acorex-components-drawer.mjs +16 -15
  74. package/fesm2022/acorex-components-drawer.mjs.map +1 -1
  75. package/fesm2022/acorex-components-dropdown-button.mjs +9 -9
  76. package/fesm2022/acorex-components-dropdown-button.mjs.map +1 -1
  77. package/fesm2022/acorex-components-dropdown.mjs +16 -18
  78. package/fesm2022/acorex-components-dropdown.mjs.map +1 -1
  79. package/fesm2022/acorex-components-editor.mjs +11 -11
  80. package/fesm2022/acorex-components-editor.mjs.map +1 -1
  81. package/fesm2022/acorex-components-file-explorer.mjs +32 -32
  82. package/fesm2022/acorex-components-file-explorer.mjs.map +1 -1
  83. package/fesm2022/acorex-components-flow-chart.mjs +16 -16
  84. package/fesm2022/acorex-components-flow-chart.mjs.map +1 -1
  85. package/fesm2022/acorex-components-form.mjs +24 -32
  86. package/fesm2022/acorex-components-form.mjs.map +1 -1
  87. package/fesm2022/acorex-components-grid-layout-builder.mjs +13 -12
  88. package/fesm2022/acorex-components-grid-layout-builder.mjs.map +1 -1
  89. package/fesm2022/acorex-components-image-editor.mjs +47 -46
  90. package/fesm2022/acorex-components-image-editor.mjs.map +1 -1
  91. package/fesm2022/acorex-components-image.mjs +9 -9
  92. package/fesm2022/acorex-components-image.mjs.map +1 -1
  93. package/fesm2022/acorex-components-json-viewer.mjs +8 -8
  94. package/fesm2022/acorex-components-json-viewer.mjs.map +1 -1
  95. package/fesm2022/acorex-components-kanban.mjs +6 -8
  96. package/fesm2022/acorex-components-kanban.mjs.map +1 -1
  97. package/fesm2022/acorex-components-kbd.mjs +7 -7
  98. package/fesm2022/acorex-components-kbd.mjs.map +1 -1
  99. package/fesm2022/acorex-components-label.mjs +9 -9
  100. package/fesm2022/acorex-components-label.mjs.map +1 -1
  101. package/fesm2022/acorex-components-list.mjs +9 -9
  102. package/fesm2022/acorex-components-list.mjs.map +1 -1
  103. package/fesm2022/acorex-components-loading-dialog.mjs +12 -12
  104. package/fesm2022/acorex-components-loading-dialog.mjs.map +1 -1
  105. package/fesm2022/acorex-components-loading.mjs +23 -23
  106. package/fesm2022/acorex-components-loading.mjs.map +1 -1
  107. package/fesm2022/acorex-components-map.mjs +289 -31
  108. package/fesm2022/acorex-components-map.mjs.map +1 -1
  109. package/fesm2022/acorex-components-media-viewer.mjs +41 -41
  110. package/fesm2022/acorex-components-media-viewer.mjs.map +1 -1
  111. package/fesm2022/acorex-components-menu.mjs +21 -21
  112. package/fesm2022/acorex-components-menu.mjs.map +1 -1
  113. package/fesm2022/{acorex-components-modal-acorex-components-modal-BmmAkCKJ.mjs → acorex-components-modal-acorex-components-modal-iYSPzoLn.mjs} +22 -22
  114. package/fesm2022/acorex-components-modal-acorex-components-modal-iYSPzoLn.mjs.map +1 -0
  115. package/fesm2022/acorex-components-modal-modal-content.component-sZWKhYM-.mjs +212 -0
  116. package/fesm2022/acorex-components-modal-modal-content.component-sZWKhYM-.mjs.map +1 -0
  117. package/fesm2022/acorex-components-modal.mjs +1 -1
  118. package/fesm2022/acorex-components-navbar.mjs +9 -9
  119. package/fesm2022/acorex-components-navbar.mjs.map +1 -1
  120. package/fesm2022/acorex-components-notification.mjs +23 -16
  121. package/fesm2022/acorex-components-notification.mjs.map +1 -1
  122. package/fesm2022/acorex-components-number-box-legacy.mjs +9 -9
  123. package/fesm2022/acorex-components-number-box-legacy.mjs.map +1 -1
  124. package/fesm2022/acorex-components-number-box.mjs +9 -9
  125. package/fesm2022/acorex-components-number-box.mjs.map +1 -1
  126. package/fesm2022/acorex-components-otp.mjs +9 -9
  127. package/fesm2022/acorex-components-otp.mjs.map +1 -1
  128. package/fesm2022/acorex-components-page.mjs +10 -10
  129. package/fesm2022/acorex-components-page.mjs.map +1 -1
  130. package/fesm2022/acorex-components-paint.mjs +39 -34
  131. package/fesm2022/acorex-components-paint.mjs.map +1 -1
  132. package/fesm2022/acorex-components-password-box.mjs +12 -12
  133. package/fesm2022/acorex-components-password-box.mjs.map +1 -1
  134. package/fesm2022/acorex-components-pdf-reader.mjs +8 -8
  135. package/fesm2022/acorex-components-pdf-reader.mjs.map +1 -1
  136. package/fesm2022/acorex-components-phone-box.mjs +9 -9
  137. package/fesm2022/acorex-components-phone-box.mjs.map +1 -1
  138. package/fesm2022/acorex-components-picker.mjs +15 -15
  139. package/fesm2022/acorex-components-picker.mjs.map +1 -1
  140. package/fesm2022/acorex-components-popover.mjs +11 -11
  141. package/fesm2022/acorex-components-popover.mjs.map +1 -1
  142. package/fesm2022/acorex-components-popup.mjs +13 -13
  143. package/fesm2022/acorex-components-popup.mjs.map +1 -1
  144. package/fesm2022/acorex-components-progress-bar.mjs +9 -11
  145. package/fesm2022/acorex-components-progress-bar.mjs.map +1 -1
  146. package/fesm2022/acorex-components-qrcode.mjs +7 -7
  147. package/fesm2022/acorex-components-qrcode.mjs.map +1 -1
  148. package/fesm2022/acorex-components-query-builder.mjs +8 -8
  149. package/fesm2022/acorex-components-query-builder.mjs.map +1 -1
  150. package/fesm2022/acorex-components-radio.mjs +7 -7
  151. package/fesm2022/acorex-components-radio.mjs.map +1 -1
  152. package/fesm2022/acorex-components-rail-navigation.mjs +36 -38
  153. package/fesm2022/acorex-components-rail-navigation.mjs.map +1 -1
  154. package/fesm2022/acorex-components-range-slider.mjs +10 -10
  155. package/fesm2022/acorex-components-range-slider.mjs.map +1 -1
  156. package/fesm2022/acorex-components-rate-picker.mjs +35 -20
  157. package/fesm2022/acorex-components-rate-picker.mjs.map +1 -1
  158. package/fesm2022/acorex-components-rest-api-generator.mjs +22 -22
  159. package/fesm2022/acorex-components-rest-api-generator.mjs.map +1 -1
  160. package/fesm2022/acorex-components-result.mjs +8 -8
  161. package/fesm2022/acorex-components-result.mjs.map +1 -1
  162. package/fesm2022/acorex-components-routing-progress.mjs +8 -8
  163. package/fesm2022/acorex-components-routing-progress.mjs.map +1 -1
  164. package/fesm2022/acorex-components-rrule.mjs +9 -9
  165. package/fesm2022/acorex-components-rrule.mjs.map +1 -1
  166. package/fesm2022/acorex-components-scheduler-picker.mjs +56 -56
  167. package/fesm2022/acorex-components-scheduler-picker.mjs.map +1 -1
  168. package/fesm2022/acorex-components-scheduler.mjs +43 -43
  169. package/fesm2022/acorex-components-scheduler.mjs.map +1 -1
  170. package/fesm2022/acorex-components-scss.mjs +4 -4
  171. package/fesm2022/acorex-components-scss.mjs.map +1 -1
  172. package/fesm2022/acorex-components-search-box.mjs +10 -16
  173. package/fesm2022/acorex-components-search-box.mjs.map +1 -1
  174. package/fesm2022/acorex-components-select-box.mjs +9 -11
  175. package/fesm2022/acorex-components-select-box.mjs.map +1 -1
  176. package/fesm2022/acorex-components-selection-list-2.mjs +11 -11
  177. package/fesm2022/acorex-components-selection-list-2.mjs.map +1 -1
  178. package/fesm2022/acorex-components-selection-list.mjs +9 -9
  179. package/fesm2022/acorex-components-selection-list.mjs.map +1 -1
  180. package/fesm2022/acorex-components-side-menu.mjs +14 -14
  181. package/fesm2022/acorex-components-side-menu.mjs.map +1 -1
  182. package/fesm2022/acorex-components-skeleton.mjs +8 -8
  183. package/fesm2022/acorex-components-skeleton.mjs.map +1 -1
  184. package/fesm2022/acorex-components-slider.mjs +10 -10
  185. package/fesm2022/acorex-components-slider.mjs.map +1 -1
  186. package/fesm2022/acorex-components-sliding-item.mjs +14 -14
  187. package/fesm2022/acorex-components-sliding-item.mjs.map +1 -1
  188. package/fesm2022/acorex-components-step-wizard.mjs +14 -14
  189. package/fesm2022/acorex-components-step-wizard.mjs.map +1 -1
  190. package/fesm2022/acorex-components-switch.mjs +14 -14
  191. package/fesm2022/acorex-components-switch.mjs.map +1 -1
  192. package/fesm2022/acorex-components-tabs.mjs +15 -15
  193. package/fesm2022/acorex-components-tabs.mjs.map +1 -1
  194. package/fesm2022/acorex-components-tag-box.mjs +9 -9
  195. package/fesm2022/acorex-components-tag-box.mjs.map +1 -1
  196. package/fesm2022/acorex-components-tag.mjs +9 -9
  197. package/fesm2022/acorex-components-tag.mjs.map +1 -1
  198. package/fesm2022/acorex-components-text-area.mjs +9 -9
  199. package/fesm2022/acorex-components-text-area.mjs.map +1 -1
  200. package/fesm2022/acorex-components-text-box.mjs +12 -12
  201. package/fesm2022/acorex-components-text-box.mjs.map +1 -1
  202. package/fesm2022/acorex-components-time-duration.mjs +7 -7
  203. package/fesm2022/acorex-components-time-duration.mjs.map +1 -1
  204. package/fesm2022/acorex-components-time-line.mjs +12 -12
  205. package/fesm2022/acorex-components-time-line.mjs.map +1 -1
  206. package/fesm2022/acorex-components-toast.mjs +14 -14
  207. package/fesm2022/acorex-components-toast.mjs.map +1 -1
  208. package/fesm2022/acorex-components-toolbar.mjs +8 -8
  209. package/fesm2022/acorex-components-toolbar.mjs.map +1 -1
  210. package/fesm2022/acorex-components-tooltip.mjs +11 -11
  211. package/fesm2022/acorex-components-tooltip.mjs.map +1 -1
  212. package/fesm2022/acorex-components-tree-view-legacy.mjs +511 -0
  213. package/fesm2022/acorex-components-tree-view-legacy.mjs.map +1 -0
  214. package/fesm2022/acorex-components-tree-view.mjs +1126 -400
  215. package/fesm2022/acorex-components-tree-view.mjs.map +1 -1
  216. package/fesm2022/acorex-components-uploader.mjs +16 -16
  217. package/fesm2022/acorex-components-uploader.mjs.map +1 -1
  218. package/fesm2022/acorex-components-video-player.mjs +7 -7
  219. package/fesm2022/acorex-components-video-player.mjs.map +1 -1
  220. package/fesm2022/acorex-components-wysiwyg.mjs +42 -42
  221. package/fesm2022/acorex-components-wysiwyg.mjs.map +1 -1
  222. package/fesm2022/acorex-components.mjs.map +1 -1
  223. package/file-explorer/index.d.ts +6 -6
  224. package/grid-layout-builder/index.d.ts +2 -1
  225. package/loading/index.d.ts +1 -1
  226. package/map/index.d.ts +28 -1
  227. package/notification/index.d.ts +2 -0
  228. package/package.json +6 -6
  229. package/paint/index.d.ts +6 -1
  230. package/rate-picker/index.d.ts +15 -5
  231. package/tree-view/index.d.ts +499 -168
  232. package/tree-view-legacy/README.md +3 -0
  233. package/tree-view-legacy/index.d.ts +184 -0
  234. package/fesm2022/acorex-components-modal-acorex-components-modal-BmmAkCKJ.mjs.map +0 -1
  235. package/fesm2022/acorex-components-modal-modal-content.component-5GqTzNOs.mjs +0 -214
  236. package/fesm2022/acorex-components-modal-modal-content.component-5GqTzNOs.mjs.map +0 -1
  237. package/fesm2022/acorex-components-tree2.mjs +0 -730
  238. package/fesm2022/acorex-components-tree2.mjs.map +0 -1
  239. package/tree2/README.md +0 -3
  240. package/tree2/index.d.ts +0 -346
@@ -1,505 +1,1231 @@
1
- import { AXClickEvent, NXComponent, AXComponent, AXCommonModule } from '@acorex/cdk/common';
2
- import { AXLoadingComponent, AXLoadingModule } from '@acorex/components/loading';
3
- import { AXTooltipDirective, AXTooltipModule } from '@acorex/components/tooltip';
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, AsyncPipe } from '@angular/common';
9
+ import { CommonModule, NgTemplateOutlet } from '@angular/common';
8
10
  import * as i0 from '@angular/core';
9
- import { inject, input, model, computed, ChangeDetectionStrategy, ViewEncapsulation, Component, signal, output, effect, Input, HostBinding, NgModule } from '@angular/core';
10
- import { AXCheckBoxComponent, AXCheckBoxModule } from '@acorex/components/check-box';
11
- import { AXDecoratorGenericComponent, AXDecoratorIconComponent, AXDecoratorModule } from '@acorex/components/decorators';
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 { AXFormModule } from '@acorex/components/form';
15
+ import { map } from 'rxjs/operators';
15
16
 
16
- class AXTreeItemClickBaseEvent extends AXClickEvent {
17
- }
18
- class AXTreeViewBase {
19
- }
20
-
21
- class AXTreeViewItemComponent extends NXComponent {
22
- constructor() {
23
- super();
24
- this.treeView = inject(AXTreeViewBase);
25
- this.item = input(...(ngDevMode ? [undefined, { debugName: "item" }] : []));
26
- this.isExpanded = model(false, ...(ngDevMode ? [{ debugName: "isExpanded" }] : []));
27
- this.isActive = model(false, ...(ngDevMode ? [{ debugName: "isActive" }] : []));
28
- this.isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
29
- this.executorChanges = input(...(ngDevMode ? [undefined, { debugName: "executorChanges" }] : []));
30
- this.platformService = inject(AXPlatform);
31
- this.arrowIcon = computed(() => {
32
- const baseClasses = 'ax-tree-view-arrow ax-icon ax-icon-solid';
33
- const toggleIcons = this.treeView.toggleIcons();
34
- if (toggleIcons) {
35
- return this.isExpanded() ? `${baseClasses} ${toggleIcons.expanded}` : `${baseClasses} ${toggleIcons.collapsed}`;
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
- this.treeView.onCollapsedChanged.emit({ component: this, data: this.item(), nativeElement: this.nativeElement });
40
+ return null;
55
41
  }
56
- handleTextClick() {
57
- if (this.item()[this.treeView.disableField()]) {
58
- return;
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
- if (this.treeView.focusNodeEnabled()) {
61
- this.treeView.handleUnActiveNode(this.treeView.itemsSignal());
62
- this.item()[this.treeView.activeField()] = true;
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
- this.treeView.onNodeClick.emit({ component: this, data: this.item(), nativeElement: this.nativeElement });
66
+ return true;
65
67
  }
66
- handleTextDbClick() {
67
- if (this.item()[this.treeView.disableField()] || this.treeView.expandOn() === 'click') {
68
- return;
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 (this.item()?.[this.treeView.childrenField()] || this.item()[this.treeView.hasChildField()]) {
71
- this.isExpanded.set(!this.isExpanded());
72
- if (this.treeView.itemsPromise && this.isExpanded()) {
73
- this.treeView.fetchData(this.item());
74
- this.treeView.setNodeLoading(this.item()[this.treeView.valueField()], true);
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
- this.treeView.onNodedbClick.emit({ component: this, data: this.item(), nativeElement: this.nativeElement });
78
- this.treeView.onCollapsedChanged.emit({ component: this, data: this.item(), nativeElement: this.nativeElement });
86
+ return false;
79
87
  }
80
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXTreeViewItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
81
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.12", type: AXTreeViewItemComponent, isStandalone: true, selector: "ax-tree-view-item", inputs: { item: { classPropertyName: "item", publicName: "item", isSignal: true, isRequired: false, transformFunction: null }, isExpanded: { classPropertyName: "isExpanded", publicName: "isExpanded", isSignal: true, isRequired: false, transformFunction: null }, isActive: { classPropertyName: "isActive", publicName: "isActive", isSignal: true, isRequired: false, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, executorChanges: { classPropertyName: "executorChanges", publicName: "executorChanges", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isExpanded: "isExpandedChange", isActive: "isActiveChange" }, providers: [{ provide: AXComponent, useExisting: AXTreeViewItemComponent }], usesInheritance: true, ngImport: i0, template: "<div class=\"ax-tree-view-container\">\n @if (\n (treeView.showEmptyNodeMassage() && item().hasOwnProperty(treeView.childrenField())) ||\n (item()[this.treeView.childrenField()]?.length && !isLoading()) ||\n (item()[treeView.hasChildField()] && !isLoading())\n ) {\n <div class=\"ax-tree-view-icon-container\" (click)=\"handleArrowNodeClick()\">\n <i [class.ax-state-disabled]=\"item()[treeView.disableField()]\" class=\"{{ arrowIcon() }}\"></i>\n </div>\n } @else if (isLoading()) {\n <ax-loading></ax-loading>\n }\n\n <div class=\"ax-tree-view-items\">\n <ng-content select=\"ax-check-box\"></ng-content>\n <div\n [class.ax-state-disabled]=\"item()[treeView.disableField()]\"\n [axTooltip]=\"item()[treeView.tooltipField()]\"\n axTooltipPlacement=\"end-bottom\"\n (click)=\"handleTextClick()\"\n (dblclick)=\"handleTextDbClick()\"\n class=\"ax-tree-view-items-prefix ax-noselect-tree-view\"\n [class.ax-state-tree-view-active]=\"item()[treeView.activeField()]\"\n >\n @if (treeView.itemTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"treeView.itemTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item() }\"\n ></ng-container>\n } @else {\n <ng-content select=\"ax-prefix\"></ng-content>\n <ng-content select=\"ax-text\"></ng-content>\n <ng-content select=\"ax-suffix\"></ng-content>\n }\n </div>\n </div>\n</div>\n\n@if (isExpanded()) {\n <div\n animate.enter=\"ax-fade-slide-in\"\n animate.leave=\"ax-fade-slide-out\"\n class=\"ax-tree-view-child\"\n [class.ax-tree-view-empty-child]=\"\n treeView.showEmptyNodeMassage() &&\n item().hasOwnProperty(treeView.childrenField()) &&\n !item()[treeView.childrenField()]?.length\n \"\n >\n @if (\n treeView.showEmptyNodeMassage() &&\n item().hasOwnProperty(treeView.childrenField()) &&\n !item()[treeView.childrenField()]?.length\n ) {\n <ng-container [ngTemplateOutlet]=\"empty\"></ng-container>\n } @else {\n <ng-content></ng-content>\n }\n </div>\n}\n\n<ng-template #empty>\n {{ '@acorex:common.general.no-result-found' | translate | async }}\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: AXLoadingComponent, selector: "ax-loading", inputs: ["visible", "type", "context"], outputs: ["visibleChange"] }, { kind: "directive", type: AXTooltipDirective, selector: "[axTooltip]", inputs: ["axTooltipDisabled", "axTooltip", "axTooltipContext", "axTooltipPlacement", "axTooltipOffsetX", "axTooltipOffsetY", "axTooltipOpenAfter", "axTooltipCloseAfter"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
82
- }
83
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXTreeViewItemComponent, decorators: [{
84
- type: Component,
85
- args: [{ selector: 'ax-tree-view-item', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, AXLoadingComponent, AXTooltipDirective, NgTemplateOutlet, AXTranslatorPipe, AsyncPipe], providers: [{ provide: AXComponent, useExisting: AXTreeViewItemComponent }], template: "<div class=\"ax-tree-view-container\">\n @if (\n (treeView.showEmptyNodeMassage() && item().hasOwnProperty(treeView.childrenField())) ||\n (item()[this.treeView.childrenField()]?.length && !isLoading()) ||\n (item()[treeView.hasChildField()] && !isLoading())\n ) {\n <div class=\"ax-tree-view-icon-container\" (click)=\"handleArrowNodeClick()\">\n <i [class.ax-state-disabled]=\"item()[treeView.disableField()]\" class=\"{{ arrowIcon() }}\"></i>\n </div>\n } @else if (isLoading()) {\n <ax-loading></ax-loading>\n }\n\n <div class=\"ax-tree-view-items\">\n <ng-content select=\"ax-check-box\"></ng-content>\n <div\n [class.ax-state-disabled]=\"item()[treeView.disableField()]\"\n [axTooltip]=\"item()[treeView.tooltipField()]\"\n axTooltipPlacement=\"end-bottom\"\n (click)=\"handleTextClick()\"\n (dblclick)=\"handleTextDbClick()\"\n class=\"ax-tree-view-items-prefix ax-noselect-tree-view\"\n [class.ax-state-tree-view-active]=\"item()[treeView.activeField()]\"\n >\n @if (treeView.itemTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"treeView.itemTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: item() }\"\n ></ng-container>\n } @else {\n <ng-content select=\"ax-prefix\"></ng-content>\n <ng-content select=\"ax-text\"></ng-content>\n <ng-content select=\"ax-suffix\"></ng-content>\n }\n </div>\n </div>\n</div>\n\n@if (isExpanded()) {\n <div\n animate.enter=\"ax-fade-slide-in\"\n animate.leave=\"ax-fade-slide-out\"\n class=\"ax-tree-view-child\"\n [class.ax-tree-view-empty-child]=\"\n treeView.showEmptyNodeMassage() &&\n item().hasOwnProperty(treeView.childrenField()) &&\n !item()[treeView.childrenField()]?.length\n \"\n >\n @if (\n treeView.showEmptyNodeMassage() &&\n item().hasOwnProperty(treeView.childrenField()) &&\n !item()[treeView.childrenField()]?.length\n ) {\n <ng-container [ngTemplateOutlet]=\"empty\"></ng-container>\n } @else {\n <ng-content></ng-content>\n }\n </div>\n}\n\n<ng-template #empty>\n {{ '@acorex:common.general.no-result-found' | translate | async }}\n</ng-template>\n" }]
86
- }], ctorParameters: () => [], propDecorators: { item: [{ type: i0.Input, args: [{ isSignal: true, alias: "item", required: false }] }], isExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "isExpanded", required: false }] }, { type: i0.Output, args: ["isExpandedChange"] }], isActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "isActive", required: false }] }, { type: i0.Output, args: ["isActiveChange"] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], executorChanges: [{ type: i0.Input, args: [{ isSignal: true, alias: "executorChanges", required: false }] }] } });
87
-
88
- class AXTreeViewComponent extends NXComponent {
89
- constructor() {
90
- super(...arguments);
91
- this.itemsSignal = signal([], ...(ngDevMode ? [{ debugName: "itemsSignal" }] : []));
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
- else {
136
- this.itemsSignal.set(itemsInput);
137
- this.itemsPromise = null;
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
- /** @ignore */
144
- get __hostClass() {
145
- return [`ax-look-${this.look()}`];
106
+ // ==================== Node State Checks ====================
107
+ /**
108
+ * Check if node has children
109
+ */
110
+ hasChildren(node) {
111
+ return Boolean(node.children?.length);
146
112
  }
147
- get resolvedItems() {
148
- return this.itemsSignal();
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
- #effect;
151
- handleNodeSelectionClick(event, item) {
152
- if (item[this.disableField()] || this.isNodeLoading(item[this.valueField()])) {
153
- return;
154
- }
155
- if (this.selectionMode() === 'single' && event.isUserInteraction) {
156
- this.handleUnSelectNode(this.itemsSignal());
157
- }
158
- if (event.isUserInteraction) {
159
- item[this.selectedField()] = event.value;
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
- toggleExpand(item) {
203
- if (!item[this.expandedField()]) {
204
- item[this.expandedField()] = true;
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
- async expandAndToggleSelection(item, selected) {
213
- if (this.itemsPromise && item[this.hasChildField()] && !item?.[this.childrenField()]?.length) {
214
- await this.setNodeLoading(item[this.valueField()], true);
215
- await this.fetchData(item);
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
- this.toggleExpand(item);
218
- if (item[this.childrenField()]?.length) {
219
- this.applySelectionToChildren(item, selected, item[this.valueField()]);
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
- applySelectionToChildren(item, isSelected, parentId) {
223
- item[this.childrenField()].forEach(async (child) => {
224
- if (this.itemsPromise &&
225
- child[this.hasChildField()] &&
226
- !child?.[this.childrenField()]?.length &&
227
- this.selectionBehavior() === 'cascade') {
228
- await this.setNodeLoading(child[this.valueField()], true);
229
- await this.fetchData(child);
230
- this.toggleExpand(child);
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
- child[this.parentField()] = parentId;
233
- child[this.selectedField()] = isSelected;
234
- if (child[this.childrenField()]?.length) {
235
- this.applySelectionToChildren(child, isSelected, child[this.valueField()]);
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
- updateParentSelection(item, selected) {
245
- item[this.selectedField()] = selected;
246
- let parent = this.findParent(item, this.itemsSignal());
247
- while ((parent && parent[this.selectedField()] != false) || (parent && item[this.selectedField()])) {
248
- const allSelected = parent?.[this.childrenField()]?.every((child) => child[this.selectedField()]);
249
- const someSelected = parent?.[this.childrenField()]?.some((child) => child[this.selectedField()] || child[this.indeterminateField()]);
250
- if (!allSelected && !someSelected) {
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
- else if (!allSelected) {
255
- parent[this.indeterminateField()] = true;
256
- parent[this.selectedField()] = null;
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
- else if (allSelected) {
259
- parent[this.selectedField()] = true;
260
- parent[this.indeterminateField()] = false;
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
- parent[this.indeterminateField()] = false;
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
- findParent(item, nodes) {
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[this.childrenField()]?.includes(item)) {
272
- return node;
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
- else if (node[this.childrenField()]) {
275
- const parent = this.findParent(item, node[this.childrenField()]);
276
- if (parent)
277
- return parent;
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
- return null;
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
- findSelectedNodes(nodes) {
288
- let selectedNodes = [];
289
- nodes.forEach((node) => {
290
- if (node[this.selectedField()]) {
291
- selectedNodes.push(node);
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 (node[this.childrenField()]) {
294
- selectedNodes = selectedNodes.concat(this.findSelectedNodes(node[this.childrenField()]));
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
- handleUnSelectNode(items) {
305
- items.forEach((child) => {
306
- child[this.selectedField()] = false;
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
- fetchData(selectedNode) {
318
- this.itemsPromise(selectedNode?.[this.valueField()])
319
- .then((data) => {
320
- if (Array.isArray(data)) {
321
- if (selectedNode?.[this.valueField()]) {
322
- this.findNode(selectedNode[this.valueField()], data, this.itemsSignal());
323
- }
324
- else {
325
- const isNodeExpanded = data.filter((child) => child[this.expandedField()]);
326
- isNodeExpanded.forEach((child) => {
327
- this.fetchData(child);
328
- });
329
- this.itemsSignal.set(data);
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
- .finally(() => {
334
- this.setNodeLoading(selectedNode?.[this.valueField()], false);
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
- findNode(parentId, _children, source) {
338
- if (source.length) {
339
- source.forEach((element) => {
340
- if (element[this.valueField()] == parentId) {
341
- if (this.selectionBehavior() === 'indeterminate' && element[this.selectedField()]) {
342
- _children.forEach((child) => (child[this.selectedField()] = true));
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
- * emit when arrow click
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
- handleNodeExpandClick(node) {
359
- const selectedNode = node.data;
360
- if (this.itemsPromise && node.data[this.expandedField()] && !node?.data[this.childrenField()]?.length) {
361
- this.setNodeLoading(selectedNode[this.valueField()], true);
362
- this.fetchData(selectedNode);
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
- handleUnActiveNode(unActiveSource) {
367
- unActiveSource.forEach((child) => {
368
- child[this.activeField()] = false;
369
- if (child?.[this.childrenField()]?.length) {
370
- this.handleUnActiveNode(child[this.childrenField()]);
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
- isNodeLoading(nodeId) {
375
- return this.loadingState()[nodeId] || false;
376
- }
377
- setNodeLoading(nodeId, isLoading) {
378
- this.loadingState.update((state) => ({
379
- ...state,
380
- [nodeId]: isLoading,
381
- }));
382
- }
383
- executeOnTreeNode(node, operation, value) {
384
- switch (operation) {
385
- case 'active':
386
- node[this.activeField()] = value;
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 'expand':
389
- node[this.expandedField()] = true;
390
- if (this.itemsPromise && node[this.hasChildField()] && !node[this.childrenField()]?.length) {
391
- this.handleNodeExpandClick({ data: node, nativeElement: this.nativeElement, component: this });
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 'visible':
395
- node[this.visibleField()] = value;
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 'disabled':
398
- node[this.disableField()] = value;
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
- refresh() {
411
- if (this.itemsPromise) {
412
- this.fetchData();
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
- async setNodeExpandAndChildren(valueFields, value) {
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
- await Promise.all(nodesToExpand.map((node) => this.expandNodeAndAllChildren(node, value)));
1116
+ this.refreshNodes();
1117
+ this.onNodeSelect.emit({
1118
+ component: this,
1119
+ node,
1120
+ nativeEvent: event,
1121
+ isUserInteraction: true,
1122
+ });
422
1123
  }
423
- findNodesByValueField(nodes, valueField) {
424
- const results = [];
425
- for (const node of nodes) {
426
- if (node[this.valueField()] === valueField) {
427
- results.push(node);
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 (node[this.childrenField()]?.length) {
430
- results.push(...this.findNodesByValueField(node[this.childrenField()], valueField));
1136
+ if (this.intermediateState()) {
1137
+ this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
431
1138
  }
432
1139
  }
433
- return results;
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
- async expandNodeAndAllChildren(node, value) {
436
- node[this.expandedField()] = value;
437
- if (value && this.itemsPromise && node[this.hasChildField()] && !node[this.childrenField()]?.length) {
438
- await this.setNodeLoading(node[this.valueField()], true);
439
- await this.fetchData(node);
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
- if (node[this.childrenField()]?.length) {
442
- await Promise.all(node[this.childrenField()].map((child) => this.expandNodeAndAllChildren(child, value)));
1182
+ else {
1183
+ console.error(`${message}:`, error);
443
1184
  }
444
1185
  }
445
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.12", ngImport: i0, type: AXTreeViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
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.12", ngImport: i0, type: AXTreeViewComponent, decorators: [{
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, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
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
- AXTreeViewItemComponent,
1199
+ AXButtonComponent,
456
1200
  AXCheckBoxComponent,
457
- FormsModule,
458
- AXDecoratorGenericComponent,
1201
+ AXBadgeComponent,
459
1202
  AXDecoratorIconComponent,
460
- AXTranslatorPipe,
461
- AsyncPipe,
462
- ], providers: [
463
- { provide: AXComponent, useExisting: AXTreeViewComponent },
464
- { provide: AXTreeViewBase, useExisting: AXTreeViewComponent },
465
- ], 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"] }]
466
- }], propDecorators: { __hostClass: [{
467
- type: HostBinding,
468
- args: ['class']
469
- }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], showCheckbox: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCheckbox", required: false }] }], hasCheckboxField: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasCheckboxField", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], selectionBehavior: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionBehavior", required: false }] }], selectionScope: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionScope", required: false }] }], focusNodeEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusNodeEnabled", required: false }] }], valueField: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueField", required: false }] }], textField: [{ type: i0.Input, args: [{ isSignal: true, alias: "textField", required: false }] }], visibleField: [{ type: i0.Input, args: [{ isSignal: true, alias: "visibleField", required: false }] }], disableField: [{ type: i0.Input, args: [{ isSignal: true, alias: "disableField", required: false }] }], hasChildField: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasChildField", required: false }] }], selectedField: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedField", required: false }] }], expandedField: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedField", required: false }] }], tooltipField: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipField", required: false }] }], childrenField: [{ type: i0.Input, args: [{ isSignal: true, alias: "childrenField", required: false }] }], activeField: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeField", required: false }] }], indeterminateField: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminateField", required: false }] }], parentField: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentField", required: false }] }], iconField: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconField", required: false }] }], toggleIcons: [{ type: i0.Input, args: [{ isSignal: true, alias: "toggleIcons", required: false }] }], look: [{ type: i0.Input, args: [{ isSignal: true, alias: "look", required: false }] }], showEmptyNodeMassage: [{ type: i0.Input, args: [{ isSignal: true, alias: "showEmptyNodeMassage", required: false }] }], onSelectionChanged: [{ type: i0.Output, args: ["onSelectionChanged"] }], onItemSelectedChanged: [{ type: i0.Output, args: ["onItemSelectedChanged"] }], onNodeClick: [{ type: i0.Output, args: ["onNodeClick"] }], onCollapsedChanged: [{ type: i0.Output, args: ["onCollapsedChanged"] }], onNodedbClick: [{ type: i0.Output, args: ["onNodedbClick"] }], itemTemplate: [{
470
- type: Input
471
- }], emptyTemplate: [{
472
- type: Input
473
- }], expandOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandOn", required: false }] }] } });
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.12", ngImport: i0, type: AXTreeViewModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
488
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.12", ngImport: i0, type: AXTreeViewModule, imports: [AXTreeViewComponent, AXTreeViewItemComponent, CommonModule,
489
- AXCommonModule,
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.12", ngImport: i0, type: AXTreeViewModule, decorators: [{
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: [...COMPONENT, ...MODULES],
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 { AXTreeItemClickBaseEvent, AXTreeViewBase, AXTreeViewComponent, AXTreeViewItemComponent, AXTreeViewModule };
1236
+ export { AXTreeViewComponent, AXTreeViewModule, AXTreeViewService };
511
1237
  //# sourceMappingURL=acorex-components-tree-view.mjs.map