@acorex/components 21.0.0-next.4 → 21.0.0-next.40

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 (279) hide show
  1. package/accordion/index.d.ts +0 -1
  2. package/autocomplete/index.d.ts +23 -9
  3. package/button/index.d.ts +38 -17
  4. package/button-group/index.d.ts +6 -4
  5. package/calendar/index.d.ts +4 -0
  6. package/chips/index.d.ts +3 -8
  7. package/code-editor/README.md +291 -1
  8. package/code-editor/index.d.ts +260 -12
  9. package/command/index.d.ts +1 -0
  10. package/conversation2/README.md +426 -0
  11. package/conversation2/index.d.ts +6139 -0
  12. package/data-table/index.d.ts +79 -7
  13. package/dialog/index.d.ts +1 -1
  14. package/drawer/README.md +2 -2
  15. package/drawer/index.d.ts +33 -57
  16. package/drawer-legacy/README.md +3 -0
  17. package/drawer-legacy/index.d.ts +86 -0
  18. package/editor/README.md +3 -0
  19. package/editor/index.d.ts +79 -0
  20. package/fesm2022/acorex-components-accordion.mjs +19 -24
  21. package/fesm2022/acorex-components-accordion.mjs.map +1 -1
  22. package/fesm2022/acorex-components-action-sheet.mjs +12 -12
  23. package/fesm2022/acorex-components-action-sheet.mjs.map +1 -1
  24. package/fesm2022/acorex-components-alert.mjs +14 -14
  25. package/fesm2022/acorex-components-alert.mjs.map +1 -1
  26. package/fesm2022/acorex-components-aspect-ratio.mjs +4 -4
  27. package/fesm2022/acorex-components-aspect-ratio.mjs.map +1 -1
  28. package/fesm2022/acorex-components-audio-wave.mjs +12 -11
  29. package/fesm2022/acorex-components-audio-wave.mjs.map +1 -1
  30. package/fesm2022/acorex-components-autocomplete.mjs +30 -13
  31. package/fesm2022/acorex-components-autocomplete.mjs.map +1 -1
  32. package/fesm2022/acorex-components-avatar.mjs +13 -13
  33. package/fesm2022/acorex-components-avatar.mjs.map +1 -1
  34. package/fesm2022/acorex-components-badge.mjs +10 -10
  35. package/fesm2022/acorex-components-badge.mjs.map +1 -1
  36. package/fesm2022/acorex-components-bottom-navigation.mjs +12 -12
  37. package/fesm2022/acorex-components-bottom-navigation.mjs.map +1 -1
  38. package/fesm2022/acorex-components-breadcrumbs.mjs +12 -12
  39. package/fesm2022/acorex-components-breadcrumbs.mjs.map +1 -1
  40. package/fesm2022/acorex-components-button-group.mjs +25 -21
  41. package/fesm2022/acorex-components-button-group.mjs.map +1 -1
  42. package/fesm2022/acorex-components-button.mjs +68 -28
  43. package/fesm2022/acorex-components-button.mjs.map +1 -1
  44. package/fesm2022/acorex-components-calendar.mjs +33 -18
  45. package/fesm2022/acorex-components-calendar.mjs.map +1 -1
  46. package/fesm2022/acorex-components-check-box.mjs +11 -11
  47. package/fesm2022/acorex-components-check-box.mjs.map +1 -1
  48. package/fesm2022/acorex-components-chips.mjs +12 -14
  49. package/fesm2022/acorex-components-chips.mjs.map +1 -1
  50. package/fesm2022/acorex-components-circular-progress.mjs +13 -11
  51. package/fesm2022/acorex-components-circular-progress.mjs.map +1 -1
  52. package/fesm2022/acorex-components-code-editor.mjs +494 -162
  53. package/fesm2022/acorex-components-code-editor.mjs.map +1 -1
  54. package/fesm2022/acorex-components-collapse.mjs +13 -28
  55. package/fesm2022/acorex-components-collapse.mjs.map +1 -1
  56. package/fesm2022/acorex-components-color-box.mjs +11 -11
  57. package/fesm2022/acorex-components-color-box.mjs.map +1 -1
  58. package/fesm2022/acorex-components-color-palette.mjs +32 -32
  59. package/fesm2022/acorex-components-color-palette.mjs.map +1 -1
  60. package/fesm2022/acorex-components-command.mjs +18 -11
  61. package/fesm2022/acorex-components-command.mjs.map +1 -1
  62. package/fesm2022/acorex-components-comment.mjs +34 -34
  63. package/fesm2022/acorex-components-comment.mjs.map +1 -1
  64. package/fesm2022/acorex-components-conversation.mjs +56 -65
  65. package/fesm2022/acorex-components-conversation.mjs.map +1 -1
  66. package/fesm2022/acorex-components-conversation2.mjs +17641 -0
  67. package/fesm2022/acorex-components-conversation2.mjs.map +1 -0
  68. package/fesm2022/acorex-components-cron-job.mjs +53 -53
  69. package/fesm2022/acorex-components-cron-job.mjs.map +1 -1
  70. package/fesm2022/acorex-components-data-list.mjs +5 -5
  71. package/fesm2022/acorex-components-data-list.mjs.map +1 -1
  72. package/fesm2022/acorex-components-data-pager.mjs +56 -41
  73. package/fesm2022/acorex-components-data-pager.mjs.map +1 -1
  74. package/fesm2022/acorex-components-data-table.mjs +462 -105
  75. package/fesm2022/acorex-components-data-table.mjs.map +1 -1
  76. package/fesm2022/acorex-components-datetime-box.mjs +10 -10
  77. package/fesm2022/acorex-components-datetime-box.mjs.map +1 -1
  78. package/fesm2022/acorex-components-datetime-input.mjs +10 -10
  79. package/fesm2022/acorex-components-datetime-input.mjs.map +1 -1
  80. package/fesm2022/acorex-components-datetime-picker.mjs +11 -11
  81. package/fesm2022/acorex-components-datetime-picker.mjs.map +1 -1
  82. package/fesm2022/acorex-components-decorators.mjs +96 -54
  83. package/fesm2022/acorex-components-decorators.mjs.map +1 -1
  84. package/fesm2022/acorex-components-dialog.mjs +26 -16
  85. package/fesm2022/acorex-components-dialog.mjs.map +1 -1
  86. package/fesm2022/acorex-components-drawer-legacy.mjs +218 -0
  87. package/fesm2022/acorex-components-drawer-legacy.mjs.map +1 -0
  88. package/fesm2022/acorex-components-drawer.mjs +66 -150
  89. package/fesm2022/acorex-components-drawer.mjs.map +1 -1
  90. package/fesm2022/acorex-components-dropdown-button.mjs +9 -9
  91. package/fesm2022/acorex-components-dropdown-button.mjs.map +1 -1
  92. package/fesm2022/acorex-components-dropdown.mjs +20 -18
  93. package/fesm2022/acorex-components-dropdown.mjs.map +1 -1
  94. package/fesm2022/acorex-components-editor.mjs +195 -0
  95. package/fesm2022/acorex-components-editor.mjs.map +1 -0
  96. package/fesm2022/acorex-components-file-explorer.mjs +34 -34
  97. package/fesm2022/acorex-components-file-explorer.mjs.map +1 -1
  98. package/fesm2022/acorex-components-flow-chart.mjs +18 -18
  99. package/fesm2022/acorex-components-flow-chart.mjs.map +1 -1
  100. package/fesm2022/acorex-components-form.mjs +62 -37
  101. package/fesm2022/acorex-components-form.mjs.map +1 -1
  102. package/fesm2022/acorex-components-grid-layout-builder.mjs +14 -15
  103. package/fesm2022/acorex-components-grid-layout-builder.mjs.map +1 -1
  104. package/fesm2022/acorex-components-image-editor.mjs +206 -156
  105. package/fesm2022/acorex-components-image-editor.mjs.map +1 -1
  106. package/fesm2022/acorex-components-image.mjs +10 -10
  107. package/fesm2022/acorex-components-image.mjs.map +1 -1
  108. package/fesm2022/acorex-components-json-viewer.mjs +9 -9
  109. package/fesm2022/acorex-components-json-viewer.mjs.map +1 -1
  110. package/fesm2022/acorex-components-kanban.mjs +9 -7
  111. package/fesm2022/acorex-components-kanban.mjs.map +1 -1
  112. package/fesm2022/acorex-components-kbd.mjs +29 -11
  113. package/fesm2022/acorex-components-kbd.mjs.map +1 -1
  114. package/fesm2022/acorex-components-label.mjs +9 -9
  115. package/fesm2022/acorex-components-label.mjs.map +1 -1
  116. package/fesm2022/acorex-components-list.mjs +10 -10
  117. package/fesm2022/acorex-components-list.mjs.map +1 -1
  118. package/fesm2022/acorex-components-loading-dialog.mjs +23 -14
  119. package/fesm2022/acorex-components-loading-dialog.mjs.map +1 -1
  120. package/fesm2022/acorex-components-loading.mjs +23 -23
  121. package/fesm2022/acorex-components-loading.mjs.map +1 -1
  122. package/fesm2022/acorex-components-map.mjs +290 -31
  123. package/fesm2022/acorex-components-map.mjs.map +1 -1
  124. package/fesm2022/acorex-components-media-viewer.mjs +83 -82
  125. package/fesm2022/acorex-components-media-viewer.mjs.map +1 -1
  126. package/fesm2022/acorex-components-menu.mjs +24 -24
  127. package/fesm2022/acorex-components-menu.mjs.map +1 -1
  128. package/fesm2022/{acorex-components-modal-acorex-components-modal-h5Y-qcbh.mjs → acorex-components-modal-acorex-components-modal-CjHPRiZD.mjs} +24 -24
  129. package/fesm2022/acorex-components-modal-acorex-components-modal-CjHPRiZD.mjs.map +1 -0
  130. package/fesm2022/acorex-components-modal-modal-content.component-j-bS0WGj.mjs +214 -0
  131. package/fesm2022/acorex-components-modal-modal-content.component-j-bS0WGj.mjs.map +1 -0
  132. package/fesm2022/acorex-components-modal.mjs +1 -1
  133. package/fesm2022/acorex-components-navbar.mjs +9 -9
  134. package/fesm2022/acorex-components-navbar.mjs.map +1 -1
  135. package/fesm2022/acorex-components-notification.mjs +16 -23
  136. package/fesm2022/acorex-components-notification.mjs.map +1 -1
  137. package/fesm2022/acorex-components-number-box-legacy.mjs +412 -0
  138. package/fesm2022/acorex-components-number-box-legacy.mjs.map +1 -0
  139. package/fesm2022/acorex-components-number-box.mjs +112 -331
  140. package/fesm2022/acorex-components-number-box.mjs.map +1 -1
  141. package/fesm2022/acorex-components-otp.mjs +10 -10
  142. package/fesm2022/acorex-components-otp.mjs.map +1 -1
  143. package/fesm2022/acorex-components-page.mjs +10 -10
  144. package/fesm2022/acorex-components-page.mjs.map +1 -1
  145. package/fesm2022/acorex-components-paint.mjs +35 -40
  146. package/fesm2022/acorex-components-paint.mjs.map +1 -1
  147. package/fesm2022/acorex-components-password-box.mjs +13 -13
  148. package/fesm2022/acorex-components-password-box.mjs.map +1 -1
  149. package/fesm2022/acorex-components-pdf-reader.mjs +9 -9
  150. package/fesm2022/acorex-components-pdf-reader.mjs.map +1 -1
  151. package/fesm2022/acorex-components-phone-box.mjs +47 -10
  152. package/fesm2022/acorex-components-phone-box.mjs.map +1 -1
  153. package/fesm2022/acorex-components-picker.mjs +17 -17
  154. package/fesm2022/acorex-components-picker.mjs.map +1 -1
  155. package/fesm2022/acorex-components-popover.mjs +12 -12
  156. package/fesm2022/acorex-components-popover.mjs.map +1 -1
  157. package/fesm2022/acorex-components-popup.mjs +13 -13
  158. package/fesm2022/acorex-components-popup.mjs.map +1 -1
  159. package/fesm2022/acorex-components-progress-bar.mjs +11 -9
  160. package/fesm2022/acorex-components-progress-bar.mjs.map +1 -1
  161. package/fesm2022/acorex-components-qrcode.mjs +8 -8
  162. package/fesm2022/acorex-components-qrcode.mjs.map +1 -1
  163. package/fesm2022/acorex-components-query-builder.mjs +9 -9
  164. package/fesm2022/acorex-components-query-builder.mjs.map +1 -1
  165. package/fesm2022/acorex-components-radio.mjs +7 -7
  166. package/fesm2022/acorex-components-radio.mjs.map +1 -1
  167. package/fesm2022/acorex-components-rail-navigation.mjs +40 -38
  168. package/fesm2022/acorex-components-rail-navigation.mjs.map +1 -1
  169. package/fesm2022/acorex-components-range-slider.mjs +11 -11
  170. package/fesm2022/acorex-components-range-slider.mjs.map +1 -1
  171. package/fesm2022/acorex-components-rate-picker.mjs +20 -35
  172. package/fesm2022/acorex-components-rate-picker.mjs.map +1 -1
  173. package/fesm2022/acorex-components-rest-api-generator.mjs +23 -23
  174. package/fesm2022/acorex-components-rest-api-generator.mjs.map +1 -1
  175. package/fesm2022/acorex-components-result.mjs +8 -8
  176. package/fesm2022/acorex-components-result.mjs.map +1 -1
  177. package/fesm2022/acorex-components-routing-progress.mjs +8 -8
  178. package/fesm2022/acorex-components-routing-progress.mjs.map +1 -1
  179. package/fesm2022/acorex-components-rrule.mjs +111 -16
  180. package/fesm2022/acorex-components-rrule.mjs.map +1 -1
  181. package/fesm2022/acorex-components-scheduler-picker.mjs +2339 -0
  182. package/fesm2022/acorex-components-scheduler-picker.mjs.map +1 -0
  183. package/fesm2022/acorex-components-scheduler.mjs +52 -52
  184. package/fesm2022/acorex-components-scheduler.mjs.map +1 -1
  185. package/fesm2022/acorex-components-scss.mjs +4 -4
  186. package/fesm2022/acorex-components-scss.mjs.map +1 -1
  187. package/fesm2022/acorex-components-search-box.mjs +23 -12
  188. package/fesm2022/acorex-components-search-box.mjs.map +1 -1
  189. package/fesm2022/acorex-components-select-box.mjs +36 -17
  190. package/fesm2022/acorex-components-select-box.mjs.map +1 -1
  191. package/fesm2022/acorex-components-selection-list-2.mjs +12 -12
  192. package/fesm2022/acorex-components-selection-list-2.mjs.map +1 -1
  193. package/fesm2022/acorex-components-selection-list.mjs +10 -10
  194. package/fesm2022/acorex-components-selection-list.mjs.map +1 -1
  195. package/fesm2022/acorex-components-side-menu.mjs +31 -38
  196. package/fesm2022/acorex-components-side-menu.mjs.map +1 -1
  197. package/fesm2022/acorex-components-skeleton.mjs +8 -8
  198. package/fesm2022/acorex-components-skeleton.mjs.map +1 -1
  199. package/fesm2022/acorex-components-slider.mjs +11 -11
  200. package/fesm2022/acorex-components-slider.mjs.map +1 -1
  201. package/fesm2022/acorex-components-sliding-item.mjs +17 -17
  202. package/fesm2022/acorex-components-sliding-item.mjs.map +1 -1
  203. package/fesm2022/acorex-components-step-wizard.mjs +16 -16
  204. package/fesm2022/acorex-components-step-wizard.mjs.map +1 -1
  205. package/fesm2022/acorex-components-switch.mjs +14 -14
  206. package/fesm2022/acorex-components-switch.mjs.map +1 -1
  207. package/fesm2022/acorex-components-tabs.mjs +28 -20
  208. package/fesm2022/acorex-components-tabs.mjs.map +1 -1
  209. package/fesm2022/acorex-components-tag-box.mjs +51 -21
  210. package/fesm2022/acorex-components-tag-box.mjs.map +1 -1
  211. package/fesm2022/acorex-components-tag.mjs +47 -11
  212. package/fesm2022/acorex-components-tag.mjs.map +1 -1
  213. package/fesm2022/acorex-components-text-area.mjs +9 -9
  214. package/fesm2022/acorex-components-text-area.mjs.map +1 -1
  215. package/fesm2022/acorex-components-text-box.mjs +13 -13
  216. package/fesm2022/acorex-components-text-box.mjs.map +1 -1
  217. package/fesm2022/acorex-components-time-duration.mjs +54 -14
  218. package/fesm2022/acorex-components-time-duration.mjs.map +1 -1
  219. package/fesm2022/acorex-components-time-line.mjs +14 -29
  220. package/fesm2022/acorex-components-time-line.mjs.map +1 -1
  221. package/fesm2022/acorex-components-toast.mjs +14 -14
  222. package/fesm2022/acorex-components-toast.mjs.map +1 -1
  223. package/fesm2022/acorex-components-toolbar.mjs +9 -9
  224. package/fesm2022/acorex-components-toolbar.mjs.map +1 -1
  225. package/fesm2022/acorex-components-tooltip.mjs +12 -12
  226. package/fesm2022/acorex-components-tooltip.mjs.map +1 -1
  227. package/fesm2022/acorex-components-tree-view-legacy.mjs +511 -0
  228. package/fesm2022/acorex-components-tree-view-legacy.mjs.map +1 -0
  229. package/fesm2022/acorex-components-tree-view.mjs +1668 -424
  230. package/fesm2022/acorex-components-tree-view.mjs.map +1 -1
  231. package/fesm2022/acorex-components-uploader.mjs +28 -641
  232. package/fesm2022/acorex-components-uploader.mjs.map +1 -1
  233. package/fesm2022/acorex-components-video-player.mjs +8 -8
  234. package/fesm2022/acorex-components-video-player.mjs.map +1 -1
  235. package/fesm2022/acorex-components-wysiwyg.mjs +213 -462
  236. package/fesm2022/acorex-components-wysiwyg.mjs.map +1 -1
  237. package/fesm2022/acorex-components.mjs.map +1 -1
  238. package/file-explorer/index.d.ts +6 -6
  239. package/form/index.d.ts +3 -3
  240. package/grid-layout-builder/index.d.ts +1 -2
  241. package/image-editor/index.d.ts +11 -13
  242. package/kbd/index.d.ts +13 -7
  243. package/loading/index.d.ts +1 -1
  244. package/map/index.d.ts +28 -1
  245. package/media-viewer/index.d.ts +2 -1
  246. package/notification/index.d.ts +0 -2
  247. package/number-box/README.md +2 -2
  248. package/number-box/index.d.ts +32 -171
  249. package/number-box-legacy/README.md +3 -0
  250. package/number-box-legacy/index.d.ts +191 -0
  251. package/package.json +41 -14
  252. package/paint/index.d.ts +1 -6
  253. package/phone-box/index.d.ts +5 -4
  254. package/rate-picker/index.d.ts +5 -15
  255. package/rrule/index.d.ts +96 -1
  256. package/scheduler-picker/README.md +15 -0
  257. package/scheduler-picker/index.d.ts +1360 -0
  258. package/search-box/index.d.ts +6 -1
  259. package/select-box/index.d.ts +15 -10
  260. package/side-menu/index.d.ts +3 -2
  261. package/tag/index.d.ts +8 -2
  262. package/tag-box/index.d.ts +12 -3
  263. package/time-duration/index.d.ts +19 -3
  264. package/tree-view/index.d.ts +658 -168
  265. package/tree-view-legacy/README.md +3 -0
  266. package/tree-view-legacy/index.d.ts +184 -0
  267. package/uploader/index.d.ts +4 -331
  268. package/wysiwyg/index.d.ts +57 -159
  269. package/drawer-2/README.md +0 -3
  270. package/drawer-2/index.d.ts +0 -62
  271. package/fesm2022/acorex-components-drawer-2.mjs +0 -134
  272. package/fesm2022/acorex-components-drawer-2.mjs.map +0 -1
  273. package/fesm2022/acorex-components-modal-acorex-components-modal-h5Y-qcbh.mjs.map +0 -1
  274. package/fesm2022/acorex-components-modal-modal-content.component-B6tyMLdU.mjs +0 -235
  275. package/fesm2022/acorex-components-modal-modal-content.component-B6tyMLdU.mjs.map +0 -1
  276. package/fesm2022/acorex-components-number-box-2.mjs +0 -183
  277. package/fesm2022/acorex-components-number-box-2.mjs.map +0 -1
  278. package/number-box-2/README.md +0 -3
  279. package/number-box-2/index.d.ts +0 -41
@@ -1,534 +1,1778 @@
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
- import { trigger, state, transition, style, animate } from '@angular/animations';
7
8
  import * as i1 from '@angular/common';
8
- import { CommonModule, NgTemplateOutlet, AsyncPipe } from '@angular/common';
9
+ import { CommonModule, NgTemplateOutlet } from '@angular/common';
9
10
  import * as i0 from '@angular/core';
10
- import { inject, input, model, computed, ChangeDetectionStrategy, ViewEncapsulation, Component, signal, output, effect, Input, HostBinding, NgModule } from '@angular/core';
11
- import { AXCheckBoxComponent, AXCheckBoxModule } from '@acorex/components/check-box';
12
- import { AXDecoratorGenericComponent, AXDecoratorIconComponent, AXDecoratorModule } from '@acorex/components/decorators';
13
- 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';
14
14
  import { FormsModule } from '@angular/forms';
15
- import { AXFormModule } from '@acorex/components/form';
15
+ import { map } from 'rxjs/operators';
16
16
 
17
- class AXTreeItemClickBaseEvent extends AXClickEvent {
18
- }
19
- class AXTreeViewBase {
20
- }
21
-
22
- class AXTreeViewItemComponent extends NXComponent {
23
- constructor() {
24
- super();
25
- this.treeView = inject(AXTreeViewBase);
26
- this.item = input(...(ngDevMode ? [undefined, { debugName: "item" }] : []));
27
- this.isExpanded = model(false, ...(ngDevMode ? [{ debugName: "isExpanded" }] : []));
28
- this.isActive = model(false, ...(ngDevMode ? [{ debugName: "isActive" }] : []));
29
- this.isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
30
- this.executorChanges = input(...(ngDevMode ? [undefined, { debugName: "executorChanges" }] : []));
31
- this.platformService = inject(AXPlatform);
32
- this.arrowIcon = computed(() => {
33
- const baseClasses = 'ax-tree-view-arrow ax-icon ax-icon-solid';
34
- const toggleIcons = this.treeView.toggleIcons();
35
- if (toggleIcons) {
36
- return this.isExpanded() ? `${baseClasses} ${toggleIcons.expanded}` : `${baseClasses} ${toggleIcons.collapsed}`;
37
- }
38
- if (this.isExpanded()) {
39
- return `${baseClasses} ax-icon-chevron-down`;
40
- }
41
- return this.platformService.isRtl()
42
- ? `${baseClasses} ax-icon-chevron-left`
43
- : `${baseClasses} ax-icon-chevron-right`;
44
- }, ...(ngDevMode ? [{ debugName: "arrowIcon" }] : []));
45
- }
46
- handleArrowNodeClick() {
47
- if (this.item()[this.treeView.disableField()] || this.isLoading() || this.treeView.expandOn() === 'dbClick') {
48
- return;
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;
38
+ }
39
+ }
40
+ return null;
41
+ }
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
+ }
49
55
  }
50
- this.isExpanded.set(!this.isExpanded());
51
- if (this.treeView.itemsPromise && this.isExpanded() && !this.item()[this.treeView.childrenField()]?.length) {
52
- this.treeView.fetchData(this.item());
53
- this.treeView.setNodeLoading(this.item()[this.treeView.valueField()], 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;
54
65
  }
55
- this.treeView.onCollapsedChanged.emit({ component: this, data: this.item(), nativeElement: this.nativeElement });
66
+ return true;
56
67
  }
57
- handleTextClick() {
58
- if (this.item()[this.treeView.disableField()]) {
59
- 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;
74
+ }
75
+ if (!ancestorNode.children || ancestorNode.children.length === 0) {
76
+ return false;
77
+ }
78
+ for (const child of ancestorNode.children) {
79
+ if (child.id === targetNode.id) {
80
+ return true;
81
+ }
82
+ if (this.isNodeDescendantOf(targetNode, child)) {
83
+ return true;
84
+ }
60
85
  }
61
- if (this.treeView.focusNodeEnabled()) {
62
- this.treeView.handleUnActiveNode(this.treeView.itemsSignal());
63
- this.item()[this.treeView.activeField()] = true;
86
+ return false;
87
+ }
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
+ }
100
+ }
101
+ }
102
+ };
103
+ traverse(nodes, 0);
104
+ return flatList;
105
+ }
106
+ // ==================== Node State Checks ====================
107
+ /**
108
+ * Check if node has children
109
+ */
110
+ hasChildren(node) {
111
+ return Boolean(node.children?.length);
112
+ }
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));
118
+ }
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);
129
+ }
64
130
  }
65
- this.treeView.onNodeClick.emit({ component: this, data: this.item(), nativeElement: this.nativeElement });
66
131
  }
67
- handleTextDbClick() {
68
- if (this.item()[this.treeView.disableField()] || this.treeView.expandOn() === 'click') {
132
+ /**
133
+ * Get selection state of children
134
+ */
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
+ }
145
+ }
146
+ return {
147
+ allSelected: selectedCount === children.length,
148
+ someSelected: selectedCount > 0 || indeterminateCount > 0,
149
+ };
150
+ }
151
+ /**
152
+ * Update parent node states based on children selection (with intermediate state support)
153
+ */
154
+ updateParentStates(nodes, changedNode, intermediateState) {
155
+ const parent = this.findParentNode(nodes, changedNode);
156
+ if (!parent || !parent.children)
69
157
  return;
158
+ const { allSelected, someSelected } = this.getChildrenSelectionState(parent.children);
159
+ if (allSelected) {
160
+ parent.selected = true;
161
+ parent.indeterminate = false;
70
162
  }
71
- if (this.item()?.[this.treeView.childrenField()] || this.item()[this.treeView.hasChildField()]) {
72
- this.isExpanded.set(!this.isExpanded());
73
- if (this.treeView.itemsPromise && this.isExpanded()) {
74
- this.treeView.fetchData(this.item());
75
- this.treeView.setNodeLoading(this.item()[this.treeView.valueField()], true);
76
- }
77
- }
78
- this.treeView.onNodedbClick.emit({ component: this, data: this.item(), nativeElement: this.nativeElement });
79
- this.treeView.onCollapsedChanged.emit({ component: this, data: this.item(), nativeElement: this.nativeElement });
80
- }
81
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXTreeViewItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
82
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.3", 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<div\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 [@collapseExpand]=\"isExpanded() ? 'expanded' : 'collapsed'\"\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<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" }], animations: [
83
- trigger('collapseExpand', [
84
- state('collapsed', style({
85
- height: '0',
86
- overflow: 'hidden',
87
- opacity: 0,
88
- })),
89
- state('expanded', style({
90
- height: '*',
91
- overflow: 'hidden',
92
- opacity: 1,
93
- })),
94
- transition('collapsed <=> expanded', [animate('300ms ease-in-out')]),
95
- ]),
96
- ], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
97
- }
98
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXTreeViewItemComponent, decorators: [{
99
- type: Component,
100
- args: [{ selector: 'ax-tree-view-item', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, animations: [
101
- trigger('collapseExpand', [
102
- state('collapsed', style({
103
- height: '0',
104
- overflow: 'hidden',
105
- opacity: 0,
106
- })),
107
- state('expanded', style({
108
- height: '*',
109
- overflow: 'hidden',
110
- opacity: 1,
111
- })),
112
- transition('collapsed <=> expanded', [animate('300ms ease-in-out')]),
113
- ]),
114
- ], 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<div\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 [@collapseExpand]=\"isExpanded() ? 'expanded' : 'collapsed'\"\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<ng-template #empty>\n {{ '@acorex:common.general.no-result-found' | translate | async }}\n</ng-template>\n" }]
115
- }], ctorParameters: () => [] });
116
-
117
- class AXTreeViewComponent extends NXComponent {
118
- constructor() {
119
- super(...arguments);
120
- this.itemsSignal = signal([], ...(ngDevMode ? [{ debugName: "itemsSignal" }] : []));
121
- this.items = input(...(ngDevMode ? [undefined, { debugName: "items" }] : []));
122
- this.showCheckbox = input(true, ...(ngDevMode ? [{ debugName: "showCheckbox" }] : []));
123
- this.hasCheckboxField = input('hasCheckbox', ...(ngDevMode ? [{ debugName: "hasCheckboxField" }] : []));
124
- this.selectionMode = input('single', ...(ngDevMode ? [{ debugName: "selectionMode" }] : []));
125
- this.selectionBehavior = input(...(ngDevMode ? [undefined, { debugName: "selectionBehavior" }] : []));
126
- this.selectionScope = input('all', ...(ngDevMode ? [{ debugName: "selectionScope" }] : []));
127
- this.focusNodeEnabled = input(true, ...(ngDevMode ? [{ debugName: "focusNodeEnabled" }] : []));
128
- this.valueField = input('id', ...(ngDevMode ? [{ debugName: "valueField" }] : []));
129
- this.textField = input('text', ...(ngDevMode ? [{ debugName: "textField" }] : []));
130
- this.visibleField = input('visible', ...(ngDevMode ? [{ debugName: "visibleField" }] : []));
131
- this.disableField = input('disabled', ...(ngDevMode ? [{ debugName: "disableField" }] : []));
132
- this.hasChildField = input('hasChild', ...(ngDevMode ? [{ debugName: "hasChildField" }] : []));
133
- this.selectedField = input('selected', ...(ngDevMode ? [{ debugName: "selectedField" }] : []));
134
- this.expandedField = input('expanded', ...(ngDevMode ? [{ debugName: "expandedField" }] : []));
135
- this.tooltipField = input('tooltip', ...(ngDevMode ? [{ debugName: "tooltipField" }] : []));
136
- this.childrenField = input('children', ...(ngDevMode ? [{ debugName: "childrenField" }] : []));
137
- this.activeField = input('active', ...(ngDevMode ? [{ debugName: "activeField" }] : []));
138
- this.indeterminateField = input('indeterminate', ...(ngDevMode ? [{ debugName: "indeterminateField" }] : []));
139
- this.parentField = input('parentId', ...(ngDevMode ? [{ debugName: "parentField" }] : []));
140
- this.iconField = input('icon', ...(ngDevMode ? [{ debugName: "iconField" }] : []));
141
- this.toggleIcons = input(...(ngDevMode ? [undefined, { debugName: "toggleIcons" }] : []));
142
- this.look = input('defult', ...(ngDevMode ? [{ debugName: "look" }] : []));
143
- this.showEmptyNodeMassage = input(false, ...(ngDevMode ? [{ debugName: "showEmptyNodeMassage" }] : []));
144
- this.onSelectionChanged = output();
145
- this.onItemSelectedChanged = output();
146
- this.onNodeClick = output();
147
- this.onCollapsedChanged = output();
148
- this.onNodedbClick = output();
149
- this.executorChanges = signal(null, ...(ngDevMode ? [{ debugName: "executorChanges" }] : []));
150
- this.platformService = inject(AXPlatform);
151
- this.#effect = effect(() => {
152
- const itemsInput = this.items();
153
- if (typeof itemsInput === 'function') {
154
- const result = itemsInput();
155
- if (result instanceof Promise) {
156
- this.itemsPromise = (options) => itemsInput(options);
157
- this.fetchData();
158
- }
159
- else {
160
- this.itemsSignal.set(result);
161
- this.itemsPromise = null;
162
- }
163
+ else if (someSelected) {
164
+ if (intermediateState) {
165
+ parent.selected = true;
166
+ parent.indeterminate = true;
163
167
  }
164
168
  else {
165
- this.itemsSignal.set(itemsInput);
166
- this.itemsPromise = null;
169
+ parent.selected = false;
170
+ parent.indeterminate = false;
167
171
  }
168
- }, ...(ngDevMode ? [{ debugName: "#effect" }] : []));
169
- this.expandOn = input('defult', ...(ngDevMode ? [{ debugName: "expandOn" }] : []));
170
- this.loadingState = signal({}, ...(ngDevMode ? [{ debugName: "loadingState" }] : []));
172
+ }
173
+ else {
174
+ parent.selected = false;
175
+ parent.indeterminate = false;
176
+ }
177
+ this.updateParentStates(nodes, parent, intermediateState);
171
178
  }
172
- /** @ignore */
173
- get __hostClass() {
174
- return [`ax-look-${this.look()}`];
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);
188
+ }
189
+ }
175
190
  }
176
- get resolvedItems() {
177
- return this.itemsSignal();
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);
200
+ }
201
+ }
178
202
  }
179
- #effect;
180
- handleNodeSelectionClick(event, item) {
181
- if (item[this.disableField()] || this.isNodeLoading(item[this.valueField()])) {
182
- return;
203
+ /**
204
+ * Recursively count selected nodes
205
+ */
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);
213
+ }
183
214
  }
184
- if (this.selectionMode() === 'single' && event.isUserInteraction) {
185
- this.handleUnSelectNode(this.itemsSignal());
186
- }
187
- if (event.isUserInteraction) {
188
- item[this.selectedField()] = event.value;
189
- if (event.value !== null) {
190
- switch (this.selectionBehavior()) {
191
- case 'autoExpand':
192
- if (event.value) {
193
- if (this.itemsPromise && item[this.hasChildField()] && !item?.[this.childrenField()]?.length) {
194
- this.setNodeLoading(item[this.valueField()], true);
195
- this.fetchData(item);
196
- }
197
- this.toggleExpand(item);
198
- }
199
- break;
200
- case 'cascade':
201
- this.expandAndToggleSelection(item, event.value);
202
- break;
203
- case 'indeterminate':
204
- if (item?.[this.childrenField()]?.length) {
205
- this.applySelectionToChildren(item, event.value, item[this.valueField()]);
206
- }
207
- this.updateParentSelection(item, event.value);
208
- break;
209
- default:
210
- break;
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);
226
+ }
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);
236
+ }
237
+ else if (nodes[i].children) {
238
+ this.removeSelected(nodes[i].children ?? []);
239
+ }
240
+ }
241
+ }
242
+ /**
243
+ * Recursively update all parent states in the tree (used after deletion)
244
+ */
245
+ updateAllParentStates(nodes, intermediateState) {
246
+ for (const node of nodes) {
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;
211
267
  }
212
268
  }
213
- this.onItemSelectedChanged.emit({
214
- component: this,
215
- data: item,
216
- nativeElement: this.nativeElement,
217
- });
218
- const result = this.findSelectedNodes(this.itemsSignal());
219
- this.onSelectionChanged.emit({
220
- component: this,
221
- data: result,
222
- nativeElement: this.nativeElement,
223
- });
224
269
  }
225
270
  }
271
+ // ==================== Expansion Management ====================
226
272
  /**
227
- *
228
- * auto expand
229
- *
273
+ * Recursively set expanded state (with lazy loading)
230
274
  */
231
- toggleExpand(item) {
232
- if (!item[this.expandedField()]) {
233
- item[this.expandedField()] = true;
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
+ }
287
+ }
234
288
  }
235
289
  }
290
+ // ==================== Drag & Drop Helpers ====================
236
291
  /**
237
- *
238
- * expand and change value parent change
239
- *
292
+ * Get array reference by drop list ID
240
293
  */
241
- async expandAndToggleSelection(item, selected) {
242
- if (this.itemsPromise && item[this.hasChildField()] && !item?.[this.childrenField()]?.length) {
243
- await this.setNodeLoading(item[this.valueField()], true);
244
- await this.fetchData(item);
294
+ getArrayByListId(nodes, listId) {
295
+ if (listId === AXTreeViewService.ROOT_LIST_ID) {
296
+ return nodes;
245
297
  }
246
- this.toggleExpand(item);
247
- if (item[this.childrenField()]?.length) {
248
- this.applySelectionToChildren(item, selected, item[this.valueField()]);
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;
249
302
  }
303
+ const nodeId = listId.replace(AXTreeViewService.LIST_PREFIX, '');
304
+ const node = this.findNodeById(nodes, nodeId);
305
+ return node?.children ?? null;
250
306
  }
251
- applySelectionToChildren(item, isSelected, parentId) {
252
- item[this.childrenField()].forEach(async (child) => {
253
- if (this.itemsPromise &&
254
- child[this.hasChildField()] &&
255
- !child?.[this.childrenField()]?.length &&
256
- this.selectionBehavior() === 'cascade') {
257
- await this.setNodeLoading(child[this.valueField()], true);
258
- await this.fetchData(child);
259
- this.toggleExpand(child);
260
- }
261
- child[this.parentField()] = parentId;
262
- child[this.selectedField()] = isSelected;
263
- if (child[this.childrenField()]?.length) {
264
- this.applySelectionToChildren(child, isSelected, child[this.valueField()]);
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;
325
+ }
326
+ /**
327
+ * Get root list ID constant
328
+ */
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
+ // ==================== Node Utilities ====================
345
+ /**
346
+ * Get all nodes in a flat array
347
+ */
348
+ getAllNodes(nodes) {
349
+ const allNodes = [];
350
+ const traverse = (nodeList) => {
351
+ for (const node of nodeList) {
352
+ allNodes.push(node);
353
+ if (node.children) {
354
+ traverse(node.children);
355
+ }
265
356
  }
266
- });
357
+ };
358
+ traverse(nodes);
359
+ return allNodes;
360
+ }
361
+ /**
362
+ * Get the path to a node (array of parent nodes from root to node)
363
+ */
364
+ getNodePath(nodes, nodeId) {
365
+ const path = [];
366
+ const node = this.findNodeById(nodes, nodeId);
367
+ if (!node) {
368
+ return path;
369
+ }
370
+ let current = node;
371
+ while (current) {
372
+ path.unshift(current);
373
+ const parent = this.findParentNode(nodes, current);
374
+ current = parent ?? null;
375
+ }
376
+ return path;
377
+ }
378
+ /**
379
+ * Get the level/depth of a node (0 = root level)
380
+ */
381
+ getNodeLevel(nodes, nodeId) {
382
+ const path = this.getNodePath(nodes, nodeId);
383
+ return path.length > 0 ? path.length - 1 : -1;
384
+ }
385
+ /**
386
+ * Get sibling nodes of a given node
387
+ */
388
+ getSiblings(nodes, nodeId) {
389
+ const node = this.findNodeById(nodes, nodeId);
390
+ if (!node) {
391
+ return [];
392
+ }
393
+ const parent = this.findParentNode(nodes, node);
394
+ const siblingsArray = parent?.children ?? nodes;
395
+ return siblingsArray.filter((n) => n.id !== nodeId);
396
+ }
397
+ /**
398
+ * Clone a node (creates a deep copy)
399
+ */
400
+ cloneNode(node) {
401
+ const cloned = {
402
+ id: `${node.id}-clone-${Date.now()}`,
403
+ label: node.label,
404
+ icon: node.icon,
405
+ expanded: node.expanded,
406
+ selected: false, // Cloned nodes are not selected by default
407
+ indeterminate: false,
408
+ disabled: node.disabled,
409
+ visible: node.visible,
410
+ childrenCount: node.childrenCount,
411
+ loading: false, // Cloned nodes are not loading
412
+ data: node.data ? JSON.parse(JSON.stringify(node.data)) : undefined,
413
+ };
414
+ if (node.children && node.children.length > 0) {
415
+ cloned.children = node.children.map((child) => this.cloneNode(child));
416
+ cloned.childrenCount = cloned.children.length;
417
+ }
418
+ return cloned;
267
419
  }
268
420
  /**
269
- *
270
- * indeterminate logic
271
- *
421
+ * Validate node structure (check for required fields and circular references)
272
422
  */
273
- updateParentSelection(item, selected) {
274
- item[this.selectedField()] = selected;
275
- let parent = this.findParent(item, this.itemsSignal());
276
- while ((parent && parent[this.selectedField()] != false) || (parent && item[this.selectedField()])) {
277
- const allSelected = parent?.[this.childrenField()]?.every((child) => child[this.selectedField()]);
278
- const someSelected = parent?.[this.childrenField()]?.some((child) => child[this.selectedField()] || child[this.indeterminateField()]);
279
- if (!allSelected && !someSelected) {
280
- parent[this.selectedField()] = false;
281
- parent[this.indeterminateField()] = null;
423
+ validateNode(node, visitedIds = new Set()) {
424
+ const errors = [];
425
+ if (!node.id) {
426
+ errors.push('Node must have an id');
427
+ }
428
+ if (!node.label) {
429
+ errors.push('Node must have a label');
430
+ }
431
+ if (visitedIds.has(node.id)) {
432
+ errors.push(`Circular reference detected: node ${node.id} appears multiple times in the tree`);
433
+ }
434
+ if (node.children) {
435
+ const newVisited = new Set(visitedIds);
436
+ newVisited.add(node.id);
437
+ for (const child of node.children) {
438
+ const childValidation = this.validateNode(child, newVisited);
439
+ if (!childValidation.valid) {
440
+ errors.push(...childValidation.errors.map((e) => `Child of ${node.id}: ${e}`));
441
+ }
442
+ }
443
+ if (node.childrenCount !== undefined && node.childrenCount !== node.children.length) {
444
+ errors.push(`Node ${node.id}: childrenCount (${node.childrenCount}) does not match children array length (${node.children.length})`);
445
+ }
446
+ }
447
+ return {
448
+ valid: errors.length === 0,
449
+ errors,
450
+ };
451
+ }
452
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AXTreeViewService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
453
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AXTreeViewService }); }
454
+ }
455
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AXTreeViewService, decorators: [{
456
+ type: Injectable
457
+ }] });
458
+
459
+ class AXTreeViewComponent {
460
+ constructor() {
461
+ // ==================== Dependencies ====================
462
+ this.treeService = inject(AXTreeViewService);
463
+ this.platformService = inject(AXPlatform);
464
+ this.destroyRef = inject(DestroyRef);
465
+ // ==================== Inputs ====================
466
+ /** Tree data source - can be static array or lazy loading function */
467
+ this.datasource = model.required(...(ngDevMode ? [{ debugName: "datasource" }] : []));
468
+ /** Selection mode: 'single' (click to select) or 'multiple' (checkbox selection) */
469
+ this.selectMode = input('multiple', ...(ngDevMode ? [{ debugName: "selectMode" }] : []));
470
+ /** Whether to show checkboxes for selection (only applies to multiple mode) */
471
+ this.showCheckbox = input(true, ...(ngDevMode ? [{ debugName: "showCheckbox" }] : []));
472
+ /** When true, selecting a parent also selects all loaded children (only for multiple mode) */
473
+ this.checkChildrenOnSelect = input(true, ...(ngDevMode ? [{ debugName: "checkChildrenOnSelect" }] : []));
474
+ /** When true, selecting a child makes parents indeterminate (only for multiple mode) */
475
+ this.intermediateState = input(true, ...(ngDevMode ? [{ debugName: "intermediateState" }] : []));
476
+ /** When true, clicking on a node toggles its selection (works for both single and multiple modes) */
477
+ this.checkOnClick = input(false, ...(ngDevMode ? [{ debugName: "checkOnClick" }] : []));
478
+ /** Drag and drop mode: 'none' (disabled), 'handler' (drag handle), 'item' (entire item) */
479
+ this.dragMode = input('handler', ...(ngDevMode ? [{ debugName: "dragMode" }] : []));
480
+ /** Drag operation type: 'order-only' (reorder only), 'move' (move between parents), 'both' (allow both) */
481
+ this.dragOperationType = input('both', ...(ngDevMode ? [{ debugName: "dragOperationType" }] : []));
482
+ /** Whether to show icons */
483
+ this.showIcons = input(true, ...(ngDevMode ? [{ debugName: "showIcons" }] : []));
484
+ /** Whether to show children count badge */
485
+ this.showChildrenBadge = input(true, ...(ngDevMode ? [{ debugName: "showChildrenBadge" }] : []));
486
+ /** Custom icon for expanded nodes */
487
+ this.expandedIcon = input('fa-solid fa-chevron-down', ...(ngDevMode ? [{ debugName: "expandedIcon" }] : []));
488
+ /** Custom icon for collapsed nodes */
489
+ this.collapsedIcon = input('fa-solid fa-chevron-right', ...(ngDevMode ? [{ debugName: "collapsedIcon" }] : []));
490
+ /** Indent size in pixels for each level */
491
+ this.indentSize = input(12, ...(ngDevMode ? [{ debugName: "indentSize" }] : []));
492
+ /** Node height in pixels */
493
+ this.nodeHeight = input('normal', ...(ngDevMode ? [{ debugName: "nodeHeight" }] : []));
494
+ /** Visual style variant */
495
+ this.look = input('default', ...(ngDevMode ? [{ debugName: "look" }] : []));
496
+ /** Custom template for tree items */
497
+ this.itemTemplate = input(...(ngDevMode ? [undefined, { debugName: "itemTemplate" }] : []));
498
+ // ==================== Outputs ====================
499
+ /** Emitted before a drop operation - set canceled to true to prevent drop */
500
+ this.onBeforeDrop = output();
501
+ /** Emitted when a node is toggled (expanded/collapsed) */
502
+ this.onNodeToggle = output();
503
+ /** Emitted when a node is selected/deselected */
504
+ this.onNodeSelect = output();
505
+ /** Emitted when nodes are reordered within the same parent */
506
+ this.onOrderChange = output();
507
+ /** Emitted when a node is moved to a different parent */
508
+ this.onMoveChange = output();
509
+ /** Emitted for any item change (order or move) */
510
+ this.onItemsChange = output();
511
+ // ==================== Internal State ====================
512
+ /** Internal signal for tree nodes */
513
+ this.nodes = signal([], ...(ngDevMode ? [{ debugName: "nodes" }] : []));
514
+ /** Internal signal for tracking loading state */
515
+ this.loadingNodes = signal(new Set(), ...(ngDevMode ? [{ debugName: "loadingNodes" }] : []));
516
+ /** Currently focused node ID for keyboard navigation */
517
+ this.focusedNodeId = signal(null, ...(ngDevMode ? [{ debugName: "focusedNodeId" }] : []));
518
+ /** RTL detection signal */
519
+ this.isRtl = signal(this.platformService.isRtl(), ...(ngDevMode ? [{ debugName: "isRtl" }] : []));
520
+ /** Computed chevron icons that flip for RTL */
521
+ this.directionExpandedIcon = computed(() => this.expandedIcon(), ...(ngDevMode ? [{ debugName: "directionExpandedIcon" }] : []));
522
+ this.directionCollapsedIcon = computed(() => {
523
+ const isRtlDirection = this.isRtl();
524
+ const defaultIcon = this.collapsedIcon();
525
+ if (isRtlDirection && defaultIcon === 'fa-solid fa-chevron-right') {
526
+ return 'fa-solid fa-chevron-left';
282
527
  }
283
- else if (!allSelected) {
284
- parent[this.indeterminateField()] = true;
285
- parent[this.selectedField()] = null;
528
+ if (!isRtlDirection && defaultIcon === 'fa-solid fa-chevron-left') {
529
+ return 'fa-solid fa-chevron-right';
286
530
  }
287
- else if (allSelected) {
288
- parent[this.selectedField()] = true;
289
- parent[this.indeterminateField()] = false;
531
+ return defaultIcon;
532
+ }, ...(ngDevMode ? [{ debugName: "directionCollapsedIcon" }] : []));
533
+ /** Flag to prevent infinite loops when syncing datasource */
534
+ this.isUpdatingFromDatasource = false;
535
+ /** Computed to check if datasource is a function */
536
+ this.isLazyDataSource = computed(() => typeof this.datasource() === 'function', ...(ngDevMode ? [{ debugName: "isLazyDataSource" }] : []));
537
+ // ==================== Effects ====================
538
+ /** Effect to handle datasource changes */
539
+ this.#datasourceEffect = effect(() => {
540
+ if (this.isUpdatingFromDatasource)
541
+ return;
542
+ const ds = this.datasource();
543
+ if (Array.isArray(ds)) {
544
+ this.nodes.set([...ds]);
290
545
  }
291
- else {
292
- parent[this.indeterminateField()] = false;
293
- parent[this.selectedField()] = true;
546
+ else if (typeof ds === 'function') {
547
+ this.loadRootItems(ds).catch((error) => {
548
+ this.handleError('Failed to load root items', error);
549
+ });
294
550
  }
295
- parent = this.findParent(parent, this.itemsSignal());
551
+ }, ...(ngDevMode ? [{ debugName: "#datasourceEffect" }] : []));
552
+ /** Initialize direction change listener */
553
+ this.#initDirectionListener = afterNextRender(() => {
554
+ this.platformService.directionChange
555
+ .pipe(map((event) => event.data === 'rtl'), takeUntilDestroyed(this.destroyRef))
556
+ .subscribe((isRtl) => this.isRtl.set(isRtl));
557
+ });
558
+ }
559
+ // ==================== Effects ====================
560
+ /** Effect to handle datasource changes */
561
+ #datasourceEffect;
562
+ /** Initialize direction change listener */
563
+ #initDirectionListener;
564
+ // ==================== Public API ====================
565
+ /**
566
+ * Expand all nodes in the tree (with lazy loading support)
567
+ */
568
+ async expandAll() {
569
+ await this.treeService.setExpandedState(this.nodes(), true, this.isLazyDataSource(), (node) => this.loadNodeChildren(node));
570
+ this.refreshNodes();
571
+ }
572
+ /**
573
+ * Collapse all nodes in the tree
574
+ */
575
+ collapseAll() {
576
+ this.treeService.setExpandedState(this.nodes(), false, this.isLazyDataSource(), (node) => this.loadNodeChildren(node));
577
+ this.refreshNodes();
578
+ }
579
+ /**
580
+ * Get count of selected nodes
581
+ */
582
+ getSelectedCount() {
583
+ return this.treeService.countSelected(this.nodes());
584
+ }
585
+ /**
586
+ * Check if any nodes are selected
587
+ */
588
+ hasSelection() {
589
+ return this.getSelectedCount() > 0;
590
+ }
591
+ /**
592
+ * Get all selected nodes
593
+ */
594
+ getSelectedNodes() {
595
+ const selected = [];
596
+ this.treeService.collectSelected(this.nodes(), selected);
597
+ return selected;
598
+ }
599
+ /**
600
+ * Delete selected nodes from the tree
601
+ */
602
+ deleteSelected() {
603
+ this.treeService.removeSelected(this.nodes());
604
+ this.treeService.updateAllParentStates(this.nodes(), this.intermediateState());
605
+ this.refreshNodes();
606
+ }
607
+ /**
608
+ * Select all nodes in the tree
609
+ */
610
+ selectAll() {
611
+ this.treeService.setAllSelection(this.nodes(), true);
612
+ this.refreshNodes();
613
+ }
614
+ /**
615
+ * Deselect all nodes in the tree
616
+ */
617
+ deselectAll() {
618
+ this.treeService.setAllSelection(this.nodes(), false);
619
+ this.refreshNodes();
620
+ }
621
+ /**
622
+ * Find a node by ID in the tree
623
+ */
624
+ findNode(id) {
625
+ return this.treeService.findNodeById(this.nodes(), id);
626
+ }
627
+ /**
628
+ * Refresh the tree to trigger change detection
629
+ */
630
+ refresh() {
631
+ this.refreshNodes();
632
+ }
633
+ /**
634
+ * Check if a node is currently loading
635
+ */
636
+ isNodeLoading(nodeId) {
637
+ return this.loadingNodes().has(nodeId);
638
+ }
639
+ /**
640
+ * Edit/update a node's properties
641
+ * @param nodeId - The ID of the node to edit
642
+ * @param updates - Partial node object with properties to update
643
+ * @returns true if node was found and updated, false otherwise
644
+ */
645
+ editNode(nodeId, updates) {
646
+ const node = this.findNode(nodeId);
647
+ if (!node) {
648
+ return false;
649
+ }
650
+ // Update node properties
651
+ Object.assign(node, updates);
652
+ // If children array is provided, ensure it exists
653
+ if (updates.children !== undefined) {
654
+ node.children = updates.children;
296
655
  }
656
+ // Update childrenCount if children array is provided
657
+ if (updates.children !== undefined) {
658
+ node.childrenCount = updates.children.length;
659
+ }
660
+ this.refreshNodes();
661
+ return true;
297
662
  }
298
- findParent(item, nodes) {
299
- for (const node of nodes) {
300
- if (node[this.childrenField()]?.includes(item)) {
301
- return node;
663
+ /**
664
+ * Add a child node to a parent node
665
+ * @param parentId - The ID of the parent node
666
+ * @param childNode - The child node to add
667
+ * @param index - Optional index to insert at (default: append to end)
668
+ * @returns true if parent was found and child was added, false otherwise
669
+ */
670
+ addChild(parentId, childNode, index) {
671
+ const parent = this.findNode(parentId);
672
+ if (!parent) {
673
+ return false;
674
+ }
675
+ // Ensure children array exists
676
+ if (!parent.children) {
677
+ parent.children = [];
678
+ }
679
+ // Insert or append child
680
+ if (index !== undefined && index >= 0 && index <= parent.children.length) {
681
+ parent.children.splice(index, 0, childNode);
682
+ }
683
+ else {
684
+ parent.children.push(childNode);
685
+ }
686
+ // Update childrenCount
687
+ parent.childrenCount = parent.children.length;
688
+ // Auto-expand parent if it was collapsed
689
+ if (!parent.expanded) {
690
+ parent.expanded = true;
691
+ }
692
+ this.refreshNodes();
693
+ return true;
694
+ }
695
+ /**
696
+ * Remove a node from the tree
697
+ * @param nodeId - The ID of the node to remove
698
+ * @returns The removed node if found, null otherwise
699
+ */
700
+ removeNode(nodeId) {
701
+ const node = this.findNode(nodeId);
702
+ if (!node) {
703
+ return null;
704
+ }
705
+ // Find parent to remove from its children array
706
+ const parent = this.treeService.findParentNode(this.nodes(), node);
707
+ const targetArray = parent?.children ?? this.nodes();
708
+ // Find and remove the node
709
+ const index = targetArray.findIndex((n) => n.id === nodeId);
710
+ if (index !== -1) {
711
+ const removed = targetArray.splice(index, 1)[0];
712
+ // Update parent's childrenCount if it exists
713
+ if (parent) {
714
+ parent.childrenCount = parent.children?.length ?? 0;
302
715
  }
303
- else if (node[this.childrenField()]) {
304
- const parent = this.findParent(item, node[this.childrenField()]);
305
- if (parent)
306
- return parent;
716
+ // Update parent states if needed
717
+ if (this.intermediateState()) {
718
+ this.treeService.updateAllParentStates(this.nodes(), this.intermediateState());
307
719
  }
720
+ this.refreshNodes();
721
+ return removed;
308
722
  }
309
723
  return null;
310
724
  }
311
725
  /**
312
- *
313
- * find node selected true for emit Selections
314
- *
726
+ * Expand a specific node
727
+ * @param nodeId - The ID of the node to expand
728
+ * @returns Promise that resolves when expansion is complete (if lazy loading)
315
729
  */
316
- findSelectedNodes(nodes) {
317
- let selectedNodes = [];
318
- nodes.forEach((node) => {
319
- if (node[this.selectedField()]) {
320
- selectedNodes.push(node);
730
+ async expandNode(nodeId) {
731
+ const node = this.findNode(nodeId);
732
+ if (!node) {
733
+ return;
734
+ }
735
+ const hasChildren = this.treeService.hasChildren(node);
736
+ const canLazyLoad = this.treeService.canLazyLoad(node, this.isLazyDataSource());
737
+ if (hasChildren || canLazyLoad) {
738
+ if (canLazyLoad) {
739
+ await this.loadNodeChildren(node);
321
740
  }
322
- if (node[this.childrenField()]) {
323
- selectedNodes = selectedNodes.concat(this.findSelectedNodes(node[this.childrenField()]));
741
+ node.expanded = true;
742
+ this.refreshNodes();
743
+ this.onNodeToggle.emit({ component: this, node, nativeEvent: new Event('expand') });
744
+ }
745
+ }
746
+ /**
747
+ * Collapse a specific node
748
+ * @param nodeId - The ID of the node to collapse
749
+ */
750
+ collapseNode(nodeId) {
751
+ const node = this.findNode(nodeId);
752
+ if (!node) {
753
+ return;
754
+ }
755
+ if (node.expanded) {
756
+ node.expanded = false;
757
+ this.refreshNodes();
758
+ this.onNodeToggle.emit({ component: this, node, nativeEvent: new Event('collapse') });
759
+ }
760
+ }
761
+ /**
762
+ * Toggle expansion state of a specific node
763
+ * @param nodeId - The ID of the node to toggle
764
+ * @returns Promise that resolves when toggle is complete (if lazy loading)
765
+ */
766
+ async toggleNodeExpansion(nodeId) {
767
+ const node = this.findNode(nodeId);
768
+ if (!node) {
769
+ return;
770
+ }
771
+ if (node.expanded) {
772
+ this.collapseNode(nodeId);
773
+ }
774
+ else {
775
+ await this.expandNode(nodeId);
776
+ }
777
+ }
778
+ /**
779
+ * Programmatically select a node
780
+ * @param nodeId - The ID of the node to select
781
+ * @returns true if node was found and selected, false otherwise
782
+ */
783
+ selectNode(nodeId) {
784
+ const node = this.findNode(nodeId);
785
+ if (!node || node.disabled) {
786
+ return false;
787
+ }
788
+ const mode = this.selectMode();
789
+ if (mode === 'single') {
790
+ this.treeService.deselectAllNodes(this.nodes());
791
+ node.selected = true;
792
+ node.indeterminate = false;
793
+ }
794
+ else {
795
+ node.selected = true;
796
+ node.indeterminate = false;
797
+ if (this.checkChildrenOnSelect() && node.children) {
798
+ this.treeService.selectAllChildren(node.children, true);
799
+ }
800
+ if (this.intermediateState()) {
801
+ this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
324
802
  }
803
+ }
804
+ this.refreshNodes();
805
+ this.onNodeSelect.emit({
806
+ component: this,
807
+ node,
808
+ isUserInteraction: false,
325
809
  });
326
- return selectedNodes;
810
+ return true;
327
811
  }
328
812
  /**
329
- *
330
- * find for emit Selections single mode
331
- *
813
+ * Programmatically deselect a node
814
+ * @param nodeId - The ID of the node to deselect
815
+ * @returns true if node was found and deselected, false otherwise
332
816
  */
333
- handleUnSelectNode(items) {
334
- items.forEach((child) => {
335
- child[this.selectedField()] = false;
336
- if (child?.[this.childrenField()]?.length) {
337
- this.handleUnSelectNode(child[this.childrenField()]);
338
- }
817
+ deselectNode(nodeId) {
818
+ const node = this.findNode(nodeId);
819
+ if (!node) {
820
+ return false;
821
+ }
822
+ node.selected = false;
823
+ node.indeterminate = false;
824
+ if (this.checkChildrenOnSelect() && node.children) {
825
+ this.treeService.selectAllChildren(node.children, false);
826
+ }
827
+ if (this.intermediateState()) {
828
+ this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
829
+ }
830
+ this.refreshNodes();
831
+ this.onNodeSelect.emit({
832
+ component: this,
833
+ node,
834
+ isUserInteraction: false,
339
835
  });
836
+ return true;
340
837
  }
341
838
  /**
342
- *
343
- * lazy load logic
344
- *
839
+ * Get parent node of a given node
840
+ * @param nodeId - The ID of the node
841
+ * @returns The parent node if found, null otherwise
345
842
  */
346
- fetchData(selectedNode) {
347
- this.itemsPromise(selectedNode?.[this.valueField()])
348
- .then((data) => {
349
- if (Array.isArray(data)) {
350
- if (selectedNode?.[this.valueField()]) {
351
- this.findNode(selectedNode[this.valueField()], data, this.itemsSignal());
843
+ getParent(nodeId) {
844
+ const node = this.findNode(nodeId);
845
+ if (!node) {
846
+ return null;
847
+ }
848
+ return this.treeService.findParentNode(this.nodes(), node) ?? null;
849
+ }
850
+ /**
851
+ * Get children of a node
852
+ * @param nodeId - The ID of the parent node
853
+ * @returns Array of child nodes, or null if node not found
854
+ */
855
+ getChildren(nodeId) {
856
+ const node = this.findNode(nodeId);
857
+ if (!node) {
858
+ return null;
859
+ }
860
+ return node.children ?? [];
861
+ }
862
+ /**
863
+ * Get all root nodes
864
+ * @returns Array of root nodes
865
+ */
866
+ getRootNodes() {
867
+ return [...this.nodes()];
868
+ }
869
+ /**
870
+ * Get all nodes in a flat array
871
+ * @returns Array of all nodes in the tree
872
+ */
873
+ getAllNodes() {
874
+ const allNodes = [];
875
+ const traverse = (nodes) => {
876
+ for (const node of nodes) {
877
+ allNodes.push(node);
878
+ if (node.children) {
879
+ traverse(node.children);
352
880
  }
353
- else {
354
- const isNodeExpanded = data.filter((child) => child[this.expandedField()]);
355
- isNodeExpanded.forEach((child) => {
356
- this.fetchData(child);
357
- });
358
- this.itemsSignal.set(data);
881
+ }
882
+ };
883
+ traverse(this.nodes());
884
+ return allNodes;
885
+ }
886
+ /**
887
+ * Get the path to a node (array of parent IDs from root to node)
888
+ * @param nodeId - The ID of the node
889
+ * @returns Array of node IDs representing the path, or empty array if node not found
890
+ */
891
+ getNodePath(nodeId) {
892
+ const path = [];
893
+ const node = this.findNode(nodeId);
894
+ if (!node) {
895
+ return path;
896
+ }
897
+ let current = node;
898
+ while (current) {
899
+ path.unshift(current.id);
900
+ const parent = this.treeService.findParentNode(this.nodes(), current);
901
+ current = parent ?? null;
902
+ }
903
+ return path;
904
+ }
905
+ /**
906
+ * Get the level/depth of a node (0 = root level)
907
+ * @param nodeId - The ID of the node
908
+ * @returns The level of the node, or -1 if node not found
909
+ */
910
+ getNodeLevel(nodeId) {
911
+ const path = this.getNodePath(nodeId);
912
+ return path.length > 0 ? path.length - 1 : -1;
913
+ }
914
+ /**
915
+ * Programmatically move a node to a new parent
916
+ * @param nodeId - The ID of the node to move
917
+ * @param newParentId - The ID of the new parent (undefined for root level)
918
+ * @param index - Optional index to insert at (default: append to end)
919
+ * @returns true if move was successful, false otherwise
920
+ */
921
+ moveNode(nodeId, newParentId, index) {
922
+ const node = this.findNode(nodeId);
923
+ if (!node) {
924
+ return false;
925
+ }
926
+ // Find current parent
927
+ const currentParent = this.treeService.findParentNode(this.nodes(), node);
928
+ const currentArray = currentParent?.children ?? this.nodes();
929
+ // Find and remove from current location
930
+ const currentIndex = currentArray.findIndex((n) => n.id === nodeId);
931
+ if (currentIndex === -1) {
932
+ return false;
933
+ }
934
+ const movedNode = currentArray.splice(currentIndex, 1)[0];
935
+ // Find new parent
936
+ let targetArray;
937
+ let newParent;
938
+ if (newParentId) {
939
+ newParent = this.findNode(newParentId);
940
+ if (!newParent) {
941
+ // Restore node if new parent not found
942
+ currentArray.splice(currentIndex, 0, movedNode);
943
+ return false;
944
+ }
945
+ // Validate drop target
946
+ if (!this.treeService.isValidDropTarget(movedNode, newParent)) {
947
+ // Restore node if invalid drop target
948
+ currentArray.splice(currentIndex, 0, movedNode);
949
+ return false;
950
+ }
951
+ if (!newParent.children) {
952
+ newParent.children = [];
953
+ }
954
+ targetArray = newParent.children;
955
+ }
956
+ else {
957
+ targetArray = this.nodes();
958
+ }
959
+ // Calculate new index before inserting
960
+ const newIndex = index !== undefined && index >= 0 && index <= targetArray.length ? index : targetArray.length;
961
+ // Insert at new location
962
+ if (index !== undefined && index >= 0 && index <= targetArray.length) {
963
+ targetArray.splice(index, 0, movedNode);
964
+ }
965
+ else {
966
+ targetArray.push(movedNode);
967
+ }
968
+ // Update childrenCount
969
+ if (currentParent) {
970
+ currentParent.childrenCount = currentParent.children?.length ?? 0;
971
+ }
972
+ if (newParent) {
973
+ newParent.childrenCount = newParent.children?.length ?? 0;
974
+ newParent.expanded = true; // Auto-expand new parent
975
+ }
976
+ // Emit drop events
977
+ this.emitDropEvents(movedNode, currentParent, newParent, currentIndex, newIndex, false);
978
+ this.refreshNodes();
979
+ return true;
980
+ }
981
+ /**
982
+ * Clone a node (creates a deep copy)
983
+ * @param nodeId - The ID of the node to clone
984
+ * @returns The cloned node, or null if node not found
985
+ */
986
+ cloneNode(nodeId) {
987
+ const node = this.findNode(nodeId);
988
+ if (!node) {
989
+ return null;
990
+ }
991
+ return this.treeService.cloneNode(node);
992
+ }
993
+ /**
994
+ * Focus a specific node by ID
995
+ * @param nodeId - The ID of the node to focus
996
+ * @returns true if node was found and focused, false otherwise
997
+ */
998
+ focusNode(nodeId) {
999
+ const node = this.findNode(nodeId);
1000
+ if (!node || node.visible === false || node.disabled) {
1001
+ return false;
1002
+ }
1003
+ this.focusNodeById(nodeId);
1004
+ return true;
1005
+ }
1006
+ /**
1007
+ * Get all expanded nodes
1008
+ * @returns Array of expanded nodes
1009
+ */
1010
+ getExpandedNodes() {
1011
+ const expanded = [];
1012
+ const traverse = (nodes) => {
1013
+ for (const node of nodes) {
1014
+ if (node.expanded) {
1015
+ expanded.push(node);
1016
+ }
1017
+ if (node.children) {
1018
+ traverse(node.children);
1019
+ }
1020
+ }
1021
+ };
1022
+ traverse(this.nodes());
1023
+ return expanded;
1024
+ }
1025
+ /**
1026
+ * Get all collapsed nodes that have children
1027
+ * @returns Array of collapsed nodes with children
1028
+ */
1029
+ getCollapsedNodes() {
1030
+ const collapsed = [];
1031
+ const traverse = (nodes) => {
1032
+ for (const node of nodes) {
1033
+ if (!node.expanded && (node.children?.length || node.childrenCount)) {
1034
+ collapsed.push(node);
1035
+ }
1036
+ if (node.children) {
1037
+ traverse(node.children);
359
1038
  }
360
1039
  }
361
- })
362
- .finally(() => {
363
- this.setNodeLoading(selectedNode?.[this.valueField()], false);
1040
+ };
1041
+ traverse(this.nodes());
1042
+ return collapsed;
1043
+ }
1044
+ /**
1045
+ * Check if a node is expanded
1046
+ * @param nodeId - The ID of the node
1047
+ * @returns true if node is expanded, false otherwise
1048
+ */
1049
+ isNodeExpanded(nodeId) {
1050
+ const node = this.findNode(nodeId);
1051
+ return node?.expanded ?? false;
1052
+ }
1053
+ /**
1054
+ * Check if a node is selected
1055
+ * @param nodeId - The ID of the node
1056
+ * @returns true if node is selected, false otherwise
1057
+ */
1058
+ isNodeSelected(nodeId) {
1059
+ const node = this.findNode(nodeId);
1060
+ return node?.selected ?? false;
1061
+ }
1062
+ /**
1063
+ * Check if a node has children
1064
+ * @param nodeId - The ID of the node
1065
+ * @returns true if node has children, false otherwise
1066
+ */
1067
+ hasChildren(nodeId) {
1068
+ const node = this.findNode(nodeId);
1069
+ return this.treeService.hasChildren(node ?? { id: '', label: '' });
1070
+ }
1071
+ /**
1072
+ * Get template context for a node
1073
+ */
1074
+ getTemplateContext(node, level = 0) {
1075
+ return {
1076
+ $implicit: node,
1077
+ node,
1078
+ level,
1079
+ expanded: node.expanded ?? false,
1080
+ childrenCount: node.childrenCount ?? node.children?.length ?? 0,
1081
+ loading: node.loading ?? false,
1082
+ };
1083
+ }
1084
+ /**
1085
+ * Calculate padding-inline for a node based on its level
1086
+ */
1087
+ getNodePaddingInline(level) {
1088
+ const indent = this.indentSize();
1089
+ const currentLook = this.look();
1090
+ const multiplier = currentLook === 'with-line' ? 1 / 3 : 1;
1091
+ return level * indent * multiplier;
1092
+ }
1093
+ /**
1094
+ * Check if node should show expand toggle
1095
+ */
1096
+ shouldShowExpandToggle(node) {
1097
+ return this.treeService.hasChildren(node) || this.treeService.canLazyLoad(node, this.isLazyDataSource());
1098
+ }
1099
+ /**
1100
+ * Check if checkboxes should be shown (only for multiple mode)
1101
+ */
1102
+ shouldShowCheckbox() {
1103
+ return this.selectMode() === 'multiple' && this.showCheckbox();
1104
+ }
1105
+ /**
1106
+ * Generate unique list ID for each node
1107
+ */
1108
+ getListId(node) {
1109
+ return this.treeService.getListId(node);
1110
+ }
1111
+ /**
1112
+ * Check if a node is currently focused
1113
+ */
1114
+ isNodeFocused(nodeId) {
1115
+ return this.focusedNodeId() === nodeId;
1116
+ }
1117
+ /**
1118
+ * Get ARIA level for a node
1119
+ */
1120
+ getNodeAriaLevel(level) {
1121
+ return level + 1;
1122
+ }
1123
+ /**
1124
+ * Get ARIA expanded state for a node
1125
+ */
1126
+ getNodeAriaExpanded(node) {
1127
+ if (!this.shouldShowExpandToggle(node)) {
1128
+ return null;
1129
+ }
1130
+ return node.expanded ? 'true' : 'false';
1131
+ }
1132
+ /**
1133
+ * Get ARIA selected state for a node
1134
+ */
1135
+ getNodeAriaSelected(node) {
1136
+ if (this.selectMode() === 'single') {
1137
+ return node.selected ? 'true' : 'false';
1138
+ }
1139
+ return null;
1140
+ }
1141
+ // ==================== Event Handlers ====================
1142
+ /**
1143
+ * Handle node click - for single selection mode or multiple mode with checkOnClick enabled
1144
+ */
1145
+ onNodeClick(node, event) {
1146
+ if (node.disabled)
1147
+ return;
1148
+ const mode = this.selectMode();
1149
+ const shouldCheckOnClick = this.checkOnClick();
1150
+ if (mode === 'single') {
1151
+ this.handleSingleSelection(node, event);
1152
+ }
1153
+ else if (mode === 'multiple' && shouldCheckOnClick) {
1154
+ this.handleMultipleSelection(node, event);
1155
+ }
1156
+ }
1157
+ /**
1158
+ * Toggle node expansion state with lazy loading support
1159
+ */
1160
+ async toggleNode(node, event) {
1161
+ if (node.disabled)
1162
+ return;
1163
+ if (this.isEvent(event) && typeof event.stopPropagation === 'function') {
1164
+ event.stopPropagation();
1165
+ }
1166
+ const hasChildren = this.treeService.hasChildren(node);
1167
+ const canLazyLoad = this.treeService.canLazyLoad(node, this.isLazyDataSource());
1168
+ if (hasChildren || canLazyLoad) {
1169
+ const willExpand = !node.expanded;
1170
+ if (willExpand && canLazyLoad) {
1171
+ await this.loadNodeChildren(node);
1172
+ }
1173
+ node.expanded = willExpand;
1174
+ this.refreshNodes();
1175
+ this.onNodeToggle.emit({ component: this, node, nativeEvent: event });
1176
+ }
1177
+ }
1178
+ /**
1179
+ * Toggle node selection state with indeterminate support (for multiple mode)
1180
+ */
1181
+ toggleSelection(node, event) {
1182
+ if (!event.isUserInteraction)
1183
+ return;
1184
+ const mode = this.selectMode();
1185
+ if (mode !== 'multiple')
1186
+ return;
1187
+ const newValue = event.value === null ? true : event.value;
1188
+ node.selected = newValue;
1189
+ node.indeterminate = false;
1190
+ if (this.checkChildrenOnSelect() && node.children) {
1191
+ this.treeService.selectAllChildren(node.children, newValue);
1192
+ }
1193
+ if (this.intermediateState()) {
1194
+ this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
1195
+ }
1196
+ this.refreshNodes();
1197
+ this.onNodeSelect.emit({
1198
+ component: this,
1199
+ node,
1200
+ isUserInteraction: event.isUserInteraction,
364
1201
  });
365
1202
  }
366
- findNode(parentId, _children, source) {
367
- if (source.length) {
368
- source.forEach((element) => {
369
- if (element[this.valueField()] == parentId) {
370
- if (this.selectionBehavior() === 'indeterminate' && element[this.selectedField()]) {
371
- _children.forEach((child) => (child[this.selectedField()] = true));
1203
+ /**
1204
+ * Handle drop events for tree nodes
1205
+ */
1206
+ onDrop(event, parentNode) {
1207
+ const targetArray = parentNode?.children ?? this.nodes();
1208
+ const isReordering = event.previousContainer === event.container;
1209
+ if (isReordering) {
1210
+ this.handleReorder(event, targetArray, parentNode);
1211
+ }
1212
+ else {
1213
+ this.handleMove(event, targetArray, parentNode);
1214
+ }
1215
+ this.refreshNodes();
1216
+ }
1217
+ /**
1218
+ * Handle drop events when dropping directly onto a node (to make it a child)
1219
+ */
1220
+ onDropOntoNode(event, targetNode) {
1221
+ if (!this.canMoveToParent())
1222
+ return;
1223
+ const sourceListId = event.previousContainer.element.id;
1224
+ const sourceArray = this.getArrayByListId(sourceListId);
1225
+ if (!sourceArray)
1226
+ return;
1227
+ const movedNode = sourceArray[event.previousIndex];
1228
+ if (!this.treeService.isValidDropTarget(movedNode, targetNode))
1229
+ return;
1230
+ if (!this.emitBeforeDropEvent(movedNode, sourceListId, targetNode, event.previousIndex, 0))
1231
+ return;
1232
+ targetNode.children ??= [];
1233
+ sourceArray.splice(event.previousIndex, 1);
1234
+ targetNode.children.unshift(movedNode);
1235
+ targetNode.expanded = true;
1236
+ this.emitDropEvents(movedNode, this.findParentByListId(sourceListId), targetNode, event.previousIndex, 0, false);
1237
+ this.refreshNodes();
1238
+ }
1239
+ /**
1240
+ * Handle node focus event
1241
+ */
1242
+ onNodeFocus(nodeId) {
1243
+ this.focusedNodeId.set(nodeId);
1244
+ }
1245
+ /**
1246
+ * Handle tree container focus - focus first node if none is focused
1247
+ */
1248
+ onTreeFocus(event) {
1249
+ if (event.target === event.currentTarget) {
1250
+ const flatList = this.treeService.buildFlatNodeList(this.nodes());
1251
+ if (flatList.length > 0) {
1252
+ const focusedId = this.focusedNodeId();
1253
+ if (focusedId) {
1254
+ // Check if the focused node still exists and is visible
1255
+ const focusedNode = this.treeService.findNodeById(this.nodes(), focusedId);
1256
+ if (focusedNode && focusedNode.visible !== false) {
1257
+ this.focusNodeById(focusedId);
1258
+ }
1259
+ else {
1260
+ // Focused node no longer exists, focus first node
1261
+ this.focusNodeById(flatList[0].node.id);
372
1262
  }
373
- element[this.childrenField()] = _children;
374
1263
  }
375
1264
  else {
376
- if (element?.[this.childrenField()])
377
- this.findNode(parentId, _children, element[this.childrenField()]);
1265
+ // No node is focused, focus first node
1266
+ this.focusNodeById(flatList[0].node.id);
378
1267
  }
1268
+ }
1269
+ }
1270
+ }
1271
+ /**
1272
+ * Handle tree container blur
1273
+ */
1274
+ onTreeBlur(event) {
1275
+ if (event.relatedTarget && !event.currentTarget.contains(event.relatedTarget)) {
1276
+ this.focusedNodeId.set(null);
1277
+ }
1278
+ }
1279
+ /**
1280
+ * Handle keyboard navigation
1281
+ */
1282
+ handleKeyDown(event) {
1283
+ const flatList = this.treeService.buildFlatNodeList(this.nodes());
1284
+ if (flatList.length === 0)
1285
+ return;
1286
+ const currentFocused = this.getFocusedNode();
1287
+ let currentIndex = currentFocused ? flatList.findIndex((item) => item.node.id === currentFocused.id) : -1;
1288
+ if (currentIndex === -1 && event.target === event.currentTarget) {
1289
+ currentIndex = 0;
1290
+ }
1291
+ const navigationResult = this.handleNavigationKey(event, flatList, currentIndex, currentFocused);
1292
+ if (navigationResult.handled) {
1293
+ if (navigationResult.shouldPreventDefault) {
1294
+ event.preventDefault();
1295
+ event.stopPropagation();
1296
+ }
1297
+ if (navigationResult.targetIndex !== null &&
1298
+ navigationResult.targetIndex >= 0 &&
1299
+ navigationResult.targetIndex < flatList.length) {
1300
+ this.focusNodeById(flatList[navigationResult.targetIndex].node.id);
1301
+ }
1302
+ }
1303
+ }
1304
+ // ==================== Private Methods ====================
1305
+ /**
1306
+ * Load root items when datasource is a function
1307
+ */
1308
+ async loadRootItems(loadFn) {
1309
+ try {
1310
+ const result = loadFn();
1311
+ const rootNodes = result instanceof Promise ? await result : result;
1312
+ this.nodes.set(rootNodes);
1313
+ }
1314
+ catch (error) {
1315
+ this.handleError('Failed to load root items', error);
1316
+ this.nodes.set([]);
1317
+ }
1318
+ }
1319
+ /**
1320
+ * Load children for a node using lazy loading
1321
+ */
1322
+ async loadNodeChildren(node) {
1323
+ if (!this.isLazyDataSource() || node.loading)
1324
+ return;
1325
+ if (this.treeService.hasChildren(node) || !node.childrenCount || node.childrenCount === 0) {
1326
+ return;
1327
+ }
1328
+ const ds = this.datasource();
1329
+ if (typeof ds !== 'function')
1330
+ return;
1331
+ try {
1332
+ node.loading = true;
1333
+ this.loadingNodes.update((set) => new Set(set).add(node.id));
1334
+ this.refreshNodes();
1335
+ const result = ds(node.id);
1336
+ const children = result instanceof Promise ? await result : result;
1337
+ node.children = children;
1338
+ node.childrenCount = children.length;
1339
+ }
1340
+ catch (error) {
1341
+ this.handleError('Failed to load children', error);
1342
+ node.childrenCount = 0;
1343
+ }
1344
+ finally {
1345
+ node.loading = false;
1346
+ this.loadingNodes.update((set) => {
1347
+ const newSet = new Set(set);
1348
+ newSet.delete(node.id);
1349
+ return newSet;
379
1350
  });
1351
+ this.refreshNodes();
380
1352
  }
381
1353
  }
382
1354
  /**
383
- *
384
- * emit when arrow click
385
- *
1355
+ * Internal method to refresh nodes signal and sync back to datasource if it's an array
1356
+ * Creates new array references for all nested children to ensure reactivity
386
1357
  */
387
- handleNodeExpandClick(node) {
388
- const selectedNode = node.data;
389
- if (this.itemsPromise && node.data[this.expandedField()] && !node?.data[this.childrenField()]?.length) {
390
- this.setNodeLoading(selectedNode[this.valueField()], true);
391
- this.fetchData(selectedNode);
1358
+ refreshNodes() {
1359
+ const currentNodes = this.nodes();
1360
+ // Create new array references for all nested children to ensure reactivity
1361
+ // This ensures Angular's change detection picks up changes even with callback datasource
1362
+ this.ensureNewArrayReferences(currentNodes);
1363
+ this.nodes.set([...currentNodes]);
1364
+ if (!this.isLazyDataSource() && !this.isUpdatingFromDatasource) {
1365
+ this.isUpdatingFromDatasource = true;
1366
+ this.datasource.set([...currentNodes]);
1367
+ setTimeout(() => {
1368
+ this.isUpdatingFromDatasource = false;
1369
+ }, 0);
392
1370
  }
393
- this.onCollapsedChanged.emit({ component: this, data: node.data, nativeElement: this.nativeElement });
394
1371
  }
395
- handleUnActiveNode(unActiveSource) {
396
- unActiveSource.forEach((child) => {
397
- child[this.activeField()] = false;
398
- if (child?.[this.childrenField()]?.length) {
399
- this.handleUnActiveNode(child[this.childrenField()]);
1372
+ /**
1373
+ * Recursively ensure all children arrays have new references to trigger change detection
1374
+ * Mutates the tree structure by replacing children arrays with new array references
1375
+ */
1376
+ ensureNewArrayReferences(nodes) {
1377
+ for (const node of nodes) {
1378
+ if (node.children && node.children.length > 0) {
1379
+ // Create new array reference for children
1380
+ node.children = [...node.children];
1381
+ // Recursively process nested children
1382
+ this.ensureNewArrayReferences(node.children);
400
1383
  }
1384
+ }
1385
+ }
1386
+ /**
1387
+ * Handle single selection mode
1388
+ */
1389
+ handleSingleSelection(node, event) {
1390
+ this.treeService.deselectAllNodes(this.nodes());
1391
+ node.selected = true;
1392
+ node.indeterminate = false;
1393
+ this.refreshNodes();
1394
+ this.onNodeSelect.emit({
1395
+ component: this,
1396
+ node,
1397
+ nativeEvent: event,
1398
+ isUserInteraction: true,
401
1399
  });
402
1400
  }
403
- isNodeLoading(nodeId) {
404
- return this.loadingState()[nodeId] || false;
405
- }
406
- setNodeLoading(nodeId, isLoading) {
407
- this.loadingState.update((state) => ({
408
- ...state,
409
- [nodeId]: isLoading,
410
- }));
411
- }
412
- executeOnTreeNode(node, operation, value) {
413
- switch (operation) {
414
- case 'active':
415
- node[this.activeField()] = value;
1401
+ /**
1402
+ * Handle multiple selection mode with checkOnClick
1403
+ */
1404
+ handleMultipleSelection(node, event) {
1405
+ const newValue = !node.selected;
1406
+ node.selected = newValue;
1407
+ node.indeterminate = false;
1408
+ if (this.checkChildrenOnSelect() && node.children) {
1409
+ this.treeService.selectAllChildren(node.children, newValue);
1410
+ }
1411
+ if (this.intermediateState()) {
1412
+ this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
1413
+ }
1414
+ this.refreshNodes();
1415
+ this.onNodeSelect.emit({
1416
+ component: this,
1417
+ node,
1418
+ nativeEvent: event,
1419
+ isUserInteraction: true,
1420
+ });
1421
+ }
1422
+ /**
1423
+ * Get array reference by drop list ID
1424
+ */
1425
+ getArrayByListId(listId) {
1426
+ return this.treeService.getArrayByListId(this.nodes(), listId);
1427
+ }
1428
+ /**
1429
+ * Find parent node by list ID
1430
+ */
1431
+ findParentByListId(listId) {
1432
+ return this.treeService.findParentByListId(this.nodes(), listId);
1433
+ }
1434
+ /**
1435
+ * Check if move operation is allowed based on dragOperationType
1436
+ */
1437
+ canMoveToParent() {
1438
+ return this.dragOperationType() !== 'order-only';
1439
+ }
1440
+ /**
1441
+ * Check if reorder operation is allowed based on dragOperationType
1442
+ */
1443
+ canReorder() {
1444
+ return this.dragOperationType() !== 'move';
1445
+ }
1446
+ /**
1447
+ * Handle reordering within the same list */
1448
+ handleReorder(event, targetArray, parentNode) {
1449
+ if (!this.canReorder())
1450
+ return;
1451
+ const movedNode = targetArray[event.previousIndex];
1452
+ moveItemInArray(targetArray, event.previousIndex, event.currentIndex);
1453
+ this.emitDropEvents(movedNode, parentNode, parentNode, event.previousIndex, event.currentIndex, true);
1454
+ }
1455
+ /**
1456
+ * Handle moving between different lists
1457
+ */
1458
+ handleMove(event, targetArray, parentNode) {
1459
+ if (!this.canMoveToParent())
1460
+ return;
1461
+ const sourceListId = event.previousContainer.element.id;
1462
+ const sourceArray = this.getArrayByListId(sourceListId);
1463
+ if (!sourceArray)
1464
+ return;
1465
+ const movedNode = sourceArray[event.previousIndex];
1466
+ if (parentNode && !this.treeService.isValidDropTarget(movedNode, parentNode))
1467
+ return;
1468
+ if (!this.emitBeforeDropEvent(movedNode, sourceListId, parentNode, event.previousIndex, event.currentIndex)) {
1469
+ return;
1470
+ }
1471
+ transferArrayItem(sourceArray, targetArray, event.previousIndex, event.currentIndex);
1472
+ this.emitDropEvents(movedNode, this.findParentByListId(sourceListId), parentNode, event.previousIndex, event.currentIndex, false);
1473
+ }
1474
+ /**
1475
+ * Emit beforeDrop event and return whether to continue
1476
+ */
1477
+ emitBeforeDropEvent(movedNode, sourceListId, currentParent, previousIndex, currentIndex) {
1478
+ const beforeDropEvent = {
1479
+ component: this,
1480
+ movedNode,
1481
+ previousParent: this.findParentByListId(sourceListId),
1482
+ currentParent,
1483
+ previousIndex,
1484
+ currentIndex,
1485
+ canceled: false,
1486
+ };
1487
+ this.onBeforeDrop.emit(beforeDropEvent);
1488
+ return !beforeDropEvent.canceled;
1489
+ }
1490
+ /**
1491
+ * Emit drop events based on operation type
1492
+ */
1493
+ emitDropEvents(node, previousParent, currentParent, previousIndex, currentIndex, isReorder) {
1494
+ const dropEvent = {
1495
+ component: this,
1496
+ node,
1497
+ previousParent,
1498
+ currentParent,
1499
+ previousIndex,
1500
+ currentIndex,
1501
+ };
1502
+ if (isReorder) {
1503
+ this.onOrderChange.emit(dropEvent);
1504
+ }
1505
+ else {
1506
+ this.onMoveChange.emit(dropEvent);
1507
+ }
1508
+ this.onItemsChange.emit(dropEvent);
1509
+ }
1510
+ /**
1511
+ * Get the currently focused node
1512
+ */
1513
+ getFocusedNode() {
1514
+ const focusedId = this.focusedNodeId();
1515
+ if (!focusedId)
1516
+ return null;
1517
+ return this.treeService.findNodeById(this.nodes(), focusedId);
1518
+ }
1519
+ /**
1520
+ * Set focus to a node by ID
1521
+ */
1522
+ focusNodeById(nodeId) {
1523
+ this.focusedNodeId.set(nodeId);
1524
+ setTimeout(() => {
1525
+ const element = document.querySelector(`[data-tree-node-id="${nodeId}"]`);
1526
+ if (element) {
1527
+ element.focus();
1528
+ element.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
1529
+ }
1530
+ }, 0);
1531
+ }
1532
+ /**
1533
+ * Handle keyboard navigation keys
1534
+ */
1535
+ handleNavigationKey(event, flatList, currentIndex, currentFocused) {
1536
+ let targetIndex = currentIndex;
1537
+ let shouldPreventDefault = true;
1538
+ let handled = true;
1539
+ switch (event.key) {
1540
+ case 'ArrowUp':
1541
+ if (currentIndex > 0) {
1542
+ targetIndex = currentIndex - 1;
1543
+ }
1544
+ else {
1545
+ shouldPreventDefault = false;
1546
+ }
416
1547
  break;
417
- case 'expand':
418
- node[this.expandedField()] = true;
419
- if (this.itemsPromise && node[this.hasChildField()] && !node[this.childrenField()]?.length) {
420
- this.handleNodeExpandClick({ data: node, nativeElement: this.nativeElement, component: this });
1548
+ case 'ArrowDown':
1549
+ if (currentIndex < flatList.length - 1) {
1550
+ targetIndex = currentIndex + 1;
1551
+ }
1552
+ else if (currentIndex === -1) {
1553
+ targetIndex = 0;
1554
+ }
1555
+ else {
1556
+ shouldPreventDefault = false;
421
1557
  }
422
1558
  break;
423
- case 'visible':
424
- node[this.visibleField()] = value;
1559
+ case 'ArrowLeft':
1560
+ if (currentFocused) {
1561
+ if (currentFocused.expanded && this.shouldShowExpandToggle(currentFocused)) {
1562
+ this.toggleNode(currentFocused, event);
1563
+ return { handled: true, shouldPreventDefault: true, targetIndex: null };
1564
+ }
1565
+ else {
1566
+ const currentItem = flatList[currentIndex];
1567
+ if (currentItem?.parent) {
1568
+ targetIndex = flatList.findIndex((item) => item.node.id === currentItem.parent.id);
1569
+ }
1570
+ else {
1571
+ shouldPreventDefault = false;
1572
+ }
1573
+ }
1574
+ }
1575
+ else {
1576
+ shouldPreventDefault = false;
1577
+ }
425
1578
  break;
426
- case 'disabled':
427
- node[this.disableField()] = value;
1579
+ case 'ArrowRight':
1580
+ if (currentFocused) {
1581
+ if (!currentFocused.expanded && this.shouldShowExpandToggle(currentFocused)) {
1582
+ this.toggleNode(currentFocused, event);
1583
+ return { handled: true, shouldPreventDefault: true, targetIndex: null };
1584
+ }
1585
+ else if (currentFocused.expanded &&
1586
+ this.treeService.hasChildren(currentFocused) &&
1587
+ currentFocused.children) {
1588
+ const children = currentFocused.children;
1589
+ if (children.length > 0) {
1590
+ const firstChild = children[0];
1591
+ targetIndex = flatList.findIndex((item) => item.node.id === firstChild.id);
1592
+ if (targetIndex === -1) {
1593
+ const updatedFlatList = this.treeService.buildFlatNodeList(this.nodes());
1594
+ targetIndex = updatedFlatList.findIndex((item) => item.node.id === firstChild.id);
1595
+ if (targetIndex >= 0 && targetIndex < updatedFlatList.length) {
1596
+ this.focusNodeById(updatedFlatList[targetIndex].node.id);
1597
+ return { handled: true, shouldPreventDefault: true, targetIndex: null };
1598
+ }
1599
+ }
1600
+ }
1601
+ else {
1602
+ shouldPreventDefault = false;
1603
+ }
1604
+ }
1605
+ else {
1606
+ shouldPreventDefault = false;
1607
+ }
1608
+ }
1609
+ else {
1610
+ shouldPreventDefault = false;
1611
+ }
1612
+ break;
1613
+ case 'Home':
1614
+ targetIndex = 0;
1615
+ break;
1616
+ case 'End':
1617
+ targetIndex = flatList.length - 1;
1618
+ break;
1619
+ case ' ':
1620
+ case 'Space':
1621
+ if (currentFocused && this.selectMode() === 'multiple') {
1622
+ event.preventDefault();
1623
+ this.handleSpaceKeySelection(currentFocused, event);
1624
+ return { handled: true, shouldPreventDefault: true, targetIndex: null };
1625
+ }
1626
+ shouldPreventDefault = false;
1627
+ break;
1628
+ case 'Enter':
1629
+ if (currentFocused) {
1630
+ event.preventDefault();
1631
+ this.handleEnterKeySelection(currentFocused, event);
1632
+ return { handled: true, shouldPreventDefault: true, targetIndex: null };
1633
+ }
1634
+ shouldPreventDefault = false;
428
1635
  break;
429
1636
  default:
1637
+ if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') {
1638
+ if (currentFocused && this.selectMode() === 'multiple') {
1639
+ event.preventDefault();
1640
+ this.handleCtrlEnterSelection(currentFocused, event);
1641
+ return { handled: true, shouldPreventDefault: true, targetIndex: null };
1642
+ }
1643
+ }
1644
+ handled = false;
1645
+ shouldPreventDefault = false;
430
1646
  break;
431
1647
  }
432
- /**
433
- *
434
- * for detect changes treeviewitem
435
- *
436
- */
437
- this.executorChanges.set(operation);
1648
+ return { handled, shouldPreventDefault, targetIndex };
438
1649
  }
439
- refresh() {
440
- if (this.itemsPromise) {
441
- this.fetchData();
1650
+ /**
1651
+ * Handle Space key selection
1652
+ */
1653
+ handleSpaceKeySelection(node, event) {
1654
+ const newValue = !node.selected;
1655
+ node.selected = newValue;
1656
+ node.indeterminate = false;
1657
+ if (this.checkChildrenOnSelect() && node.children) {
1658
+ this.treeService.selectAllChildren(node.children, newValue);
442
1659
  }
443
- }
444
- async setNodeExpandAndChildren(valueFields, value) {
445
- const nodesToExpand = [];
446
- for (const valueField of valueFields) {
447
- const foundNodes = this.findNodesByValueField(this.itemsSignal(), valueField);
448
- nodesToExpand.push(...foundNodes);
1660
+ if (this.intermediateState()) {
1661
+ this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
449
1662
  }
450
- await Promise.all(nodesToExpand.map((node) => this.expandNodeAndAllChildren(node, value)));
1663
+ this.refreshNodes();
1664
+ this.onNodeSelect.emit({
1665
+ component: this,
1666
+ node,
1667
+ nativeEvent: event,
1668
+ isUserInteraction: true,
1669
+ });
451
1670
  }
452
- findNodesByValueField(nodes, valueField) {
453
- const results = [];
454
- for (const node of nodes) {
455
- if (node[this.valueField()] === valueField) {
456
- results.push(node);
1671
+ /**
1672
+ * Handle Enter key selection
1673
+ */
1674
+ handleEnterKeySelection(node, event) {
1675
+ const mode = this.selectMode();
1676
+ this.treeService.deselectAllNodes(this.nodes());
1677
+ node.selected = true;
1678
+ node.indeterminate = false;
1679
+ if (mode === 'multiple') {
1680
+ if (this.checkChildrenOnSelect() && node.children) {
1681
+ this.treeService.selectAllChildren(node.children, true);
457
1682
  }
458
- if (node[this.childrenField()]?.length) {
459
- results.push(...this.findNodesByValueField(node[this.childrenField()], valueField));
1683
+ if (this.intermediateState()) {
1684
+ this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
460
1685
  }
461
1686
  }
462
- return results;
1687
+ this.refreshNodes();
1688
+ this.onNodeSelect.emit({
1689
+ component: this,
1690
+ node,
1691
+ nativeEvent: event,
1692
+ isUserInteraction: true,
1693
+ });
463
1694
  }
464
- async expandNodeAndAllChildren(node, value) {
465
- node[this.expandedField()] = value;
466
- if (value && this.itemsPromise && node[this.hasChildField()] && !node[this.childrenField()]?.length) {
467
- await this.setNodeLoading(node[this.valueField()], true);
468
- await this.fetchData(node);
1695
+ /**
1696
+ * Handle Ctrl/Cmd + Enter key selection
1697
+ */
1698
+ handleCtrlEnterSelection(node, event) {
1699
+ const newValue = !node.selected;
1700
+ node.selected = newValue;
1701
+ node.indeterminate = false;
1702
+ if (this.checkChildrenOnSelect() && node.children) {
1703
+ this.treeService.selectAllChildren(node.children, newValue);
469
1704
  }
470
- if (node[this.childrenField()]?.length) {
471
- await Promise.all(node[this.childrenField()].map((child) => this.expandNodeAndAllChildren(child, value)));
1705
+ if (this.intermediateState()) {
1706
+ this.treeService.updateParentStates(this.nodes(), node, this.intermediateState());
472
1707
  }
1708
+ this.refreshNodes();
1709
+ this.onNodeSelect.emit({
1710
+ component: this,
1711
+ node,
1712
+ nativeEvent: event,
1713
+ isUserInteraction: true,
1714
+ });
1715
+ }
1716
+ /**
1717
+ * Type guard to check if value is an Event
1718
+ */
1719
+ isEvent(value) {
1720
+ return value instanceof Event;
473
1721
  }
474
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXTreeViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
475
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.3", 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: [
476
- { provide: AXComponent, useExisting: AXTreeViewComponent },
477
- { provide: AXTreeViewBase, useExisting: AXTreeViewComponent },
478
- ], 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}\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 }); }
1722
+ /**
1723
+ * Handle errors consistently
1724
+ */
1725
+ handleError(message, error) {
1726
+ if (error instanceof Error) {
1727
+ console.error(`${message}:`, error.message);
1728
+ }
1729
+ else {
1730
+ console.error(`${message}:`, error);
1731
+ }
1732
+ }
1733
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AXTreeViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1734
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.14", 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 }); }
479
1735
  }
480
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXTreeViewComponent, decorators: [{
1736
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AXTreeViewComponent, decorators: [{
481
1737
  type: Component,
482
- args: [{ selector: 'ax-tree-view', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
1738
+ args: [{ selector: 'ax-tree-view', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [AXTreeViewService], imports: [
1739
+ CommonModule,
1740
+ FormsModule,
1741
+ AXDragDirective,
1742
+ AXDragHandleDirective,
1743
+ AXDropListDirective,
1744
+ AXFocusTrapDirective,
483
1745
  NgTemplateOutlet,
484
- AXTreeViewItemComponent,
1746
+ AXButtonComponent,
485
1747
  AXCheckBoxComponent,
486
- FormsModule,
487
- AXDecoratorGenericComponent,
1748
+ AXBadgeComponent,
488
1749
  AXDecoratorIconComponent,
489
- AXTranslatorPipe,
490
- AsyncPipe,
491
- ], providers: [
492
- { provide: AXComponent, useExisting: AXTreeViewComponent },
493
- { provide: AXTreeViewBase, useExisting: AXTreeViewComponent },
494
- ], 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}\n"] }]
495
- }], propDecorators: { __hostClass: [{
496
- type: HostBinding,
497
- args: ['class']
498
- }], itemTemplate: [{
499
- type: Input
500
- }], emptyTemplate: [{
501
- type: Input
502
- }] } });
1750
+ ], host: {
1751
+ class: 'ax-tree-view',
1752
+ '[class.ax-tree-view-default]': "look() === 'default'",
1753
+ '[class.ax-tree-view-card]': "look() === 'card'",
1754
+ '[class.ax-tree-view-with-line]': "look() === 'with-line'",
1755
+ '[class.ax-tree-view-rtl]': 'isRtl',
1756
+ '[style.--ax-tree-view-indent-size]': "indentSize() + 'px'",
1757
+ '[style.--ax-tree-view-line-offset]': "(indentSize() / 2) + 'px'",
1758
+ role: 'tree',
1759
+ '[attr.aria-label]': '"Tree navigation"',
1760
+ '(keydown)': 'handleKeyDown($event)',
1761
+ '(focus)': 'onTreeFocus($event)',
1762
+ '(blur)': 'onTreeBlur($event)',
1763
+ tabindex: '0',
1764
+ }, 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"] }]
1765
+ }], 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"] }] } });
503
1766
 
504
- const COMPONENT = [AXTreeViewComponent, AXTreeViewItemComponent];
505
- const MODULES = [
506
- CommonModule,
507
- AXCommonModule,
508
- AXDecoratorModule,
509
- AXCheckBoxModule,
510
- AXFormModule,
511
- FormsModule,
512
- AXTooltipModule,
513
- AXLoadingModule,
514
- ];
515
1767
  class AXTreeViewModule {
516
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXTreeViewModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
517
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.3", ngImport: i0, type: AXTreeViewModule, imports: [AXTreeViewComponent, AXTreeViewItemComponent, CommonModule,
518
- AXCommonModule,
519
- AXDecoratorModule,
520
- AXCheckBoxModule,
521
- AXFormModule,
522
- FormsModule,
523
- AXTooltipModule,
524
- AXLoadingModule], exports: [AXTreeViewComponent, AXTreeViewItemComponent] }); }
525
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXTreeViewModule, imports: [COMPONENT, MODULES] }); }
1768
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AXTreeViewModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1769
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.14", ngImport: i0, type: AXTreeViewModule, imports: [AXTreeViewComponent] }); }
1770
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AXTreeViewModule, imports: [AXTreeViewComponent] }); }
526
1771
  }
527
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImport: i0, type: AXTreeViewModule, decorators: [{
1772
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.14", ngImport: i0, type: AXTreeViewModule, decorators: [{
528
1773
  type: NgModule,
529
1774
  args: [{
530
- imports: [...COMPONENT, ...MODULES],
531
- exports: [...COMPONENT],
1775
+ imports: [AXTreeViewComponent],
532
1776
  }]
533
1777
  }] });
534
1778
 
@@ -536,5 +1780,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.3", ngImpor
536
1780
  * Generated bundle index. Do not edit.
537
1781
  */
538
1782
 
539
- export { AXTreeItemClickBaseEvent, AXTreeViewBase, AXTreeViewComponent, AXTreeViewItemComponent, AXTreeViewModule };
1783
+ export { AXTreeViewComponent, AXTreeViewModule, AXTreeViewService };
540
1784
  //# sourceMappingURL=acorex-components-tree-view.mjs.map