@frame-kit/ui-ng 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/COMPONENTS.md +683 -0
  2. package/DEVELOPMENT_GUIDE.md +1102 -0
  3. package/LICENSE +21 -0
  4. package/README.md +69 -0
  5. package/THEMING.md +130 -0
  6. package/core/headline/README.md +121 -0
  7. package/core/icon/README.md +173 -0
  8. package/core/image/README.md +210 -0
  9. package/core/link/README.md +297 -0
  10. package/core/separator/README.md +145 -0
  11. package/core/text/README.md +240 -0
  12. package/directives/infinite-scroll/README.md +102 -0
  13. package/directives/spotlight/README.md +154 -0
  14. package/directives/tooltip/README.md +147 -0
  15. package/docs/endpoint-link/README.md +142 -0
  16. package/docs/method-badge/README.md +154 -0
  17. package/fesm2022/frame-kit-ui-ng-core-headline.mjs +122 -0
  18. package/fesm2022/frame-kit-ui-ng-core-headline.mjs.map +1 -0
  19. package/fesm2022/frame-kit-ui-ng-core-icon.mjs +189 -0
  20. package/fesm2022/frame-kit-ui-ng-core-icon.mjs.map +1 -0
  21. package/fesm2022/frame-kit-ui-ng-core-image.mjs +123 -0
  22. package/fesm2022/frame-kit-ui-ng-core-image.mjs.map +1 -0
  23. package/fesm2022/frame-kit-ui-ng-core-link.mjs +369 -0
  24. package/fesm2022/frame-kit-ui-ng-core-link.mjs.map +1 -0
  25. package/fesm2022/frame-kit-ui-ng-core-separator.mjs +59 -0
  26. package/fesm2022/frame-kit-ui-ng-core-separator.mjs.map +1 -0
  27. package/fesm2022/frame-kit-ui-ng-core-text.mjs +204 -0
  28. package/fesm2022/frame-kit-ui-ng-core-text.mjs.map +1 -0
  29. package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs +74 -0
  30. package/fesm2022/frame-kit-ui-ng-directives-infinite-scroll.mjs.map +1 -0
  31. package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs +76 -0
  32. package/fesm2022/frame-kit-ui-ng-directives-spotlight.mjs.map +1 -0
  33. package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs +425 -0
  34. package/fesm2022/frame-kit-ui-ng-directives-tooltip.mjs.map +1 -0
  35. package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs +63 -0
  36. package/fesm2022/frame-kit-ui-ng-docs-endpoint-link.mjs.map +1 -0
  37. package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs +43 -0
  38. package/fesm2022/frame-kit-ui-ng-docs-method-badge.mjs.map +1 -0
  39. package/fesm2022/frame-kit-ui-ng-forms.mjs +3632 -0
  40. package/fesm2022/frame-kit-ui-ng-forms.mjs.map +1 -0
  41. package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs +239 -0
  42. package/fesm2022/frame-kit-ui-ng-layouts-app-shell.mjs.map +1 -0
  43. package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs +132 -0
  44. package/fesm2022/frame-kit-ui-ng-layouts-content-split.mjs.map +1 -0
  45. package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs +133 -0
  46. package/fesm2022/frame-kit-ui-ng-services-overlay-orchestrator.mjs.map +1 -0
  47. package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs +60 -0
  48. package/fesm2022/frame-kit-ui-ng-services-spotlight.mjs.map +1 -0
  49. package/fesm2022/frame-kit-ui-ng-services-toast.mjs +166 -0
  50. package/fesm2022/frame-kit-ui-ng-services-toast.mjs.map +1 -0
  51. package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs +214 -0
  52. package/fesm2022/frame-kit-ui-ng-ui-accordion.mjs.map +1 -0
  53. package/fesm2022/frame-kit-ui-ng-ui-alert.mjs +82 -0
  54. package/fesm2022/frame-kit-ui-ng-ui-alert.mjs.map +1 -0
  55. package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs +76 -0
  56. package/fesm2022/frame-kit-ui-ng-ui-avatar-stack.mjs.map +1 -0
  57. package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs +81 -0
  58. package/fesm2022/frame-kit-ui-ng-ui-avatar.mjs.map +1 -0
  59. package/fesm2022/frame-kit-ui-ng-ui-badge.mjs +81 -0
  60. package/fesm2022/frame-kit-ui-ng-ui-badge.mjs.map +1 -0
  61. package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs +68 -0
  62. package/fesm2022/frame-kit-ui-ng-ui-breadcrumb.mjs.map +1 -0
  63. package/fesm2022/frame-kit-ui-ng-ui-button.mjs +108 -0
  64. package/fesm2022/frame-kit-ui-ng-ui-button.mjs.map +1 -0
  65. package/fesm2022/frame-kit-ui-ng-ui-callout.mjs +58 -0
  66. package/fesm2022/frame-kit-ui-ng-ui-callout.mjs.map +1 -0
  67. package/fesm2022/frame-kit-ui-ng-ui-card.mjs +70 -0
  68. package/fesm2022/frame-kit-ui-ng-ui-card.mjs.map +1 -0
  69. package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs +113 -0
  70. package/fesm2022/frame-kit-ui-ng-ui-copyable-field.mjs.map +1 -0
  71. package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs +1288 -0
  72. package/fesm2022/frame-kit-ui-ng-ui-data-table.mjs.map +1 -0
  73. package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs +456 -0
  74. package/fesm2022/frame-kit-ui-ng-ui-dialog.mjs.map +1 -0
  75. package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs +398 -0
  76. package/fesm2022/frame-kit-ui-ng-ui-drawer.mjs.map +1 -0
  77. package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs +398 -0
  78. package/fesm2022/frame-kit-ui-ng-ui-dropdown-menu.mjs.map +1 -0
  79. package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs +125 -0
  80. package/fesm2022/frame-kit-ui-ng-ui-editable-field.mjs.map +1 -0
  81. package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs +113 -0
  82. package/fesm2022/frame-kit-ui-ng-ui-icon-badge.mjs.map +1 -0
  83. package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs +111 -0
  84. package/fesm2022/frame-kit-ui-ng-ui-icon-list.mjs.map +1 -0
  85. package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs +103 -0
  86. package/fesm2022/frame-kit-ui-ng-ui-inline-edit.mjs.map +1 -0
  87. package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs +135 -0
  88. package/fesm2022/frame-kit-ui-ng-ui-list-editor.mjs.map +1 -0
  89. package/fesm2022/frame-kit-ui-ng-ui-loader.mjs +81 -0
  90. package/fesm2022/frame-kit-ui-ng-ui-loader.mjs.map +1 -0
  91. package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs +79 -0
  92. package/fesm2022/frame-kit-ui-ng-ui-menu-item.mjs.map +1 -0
  93. package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs +40 -0
  94. package/fesm2022/frame-kit-ui-ng-ui-nav-brand.mjs.map +1 -0
  95. package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs +110 -0
  96. package/fesm2022/frame-kit-ui-ng-ui-nav-group.mjs.map +1 -0
  97. package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs +91 -0
  98. package/fesm2022/frame-kit-ui-ng-ui-nav-separator.mjs.map +1 -0
  99. package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs +86 -0
  100. package/fesm2022/frame-kit-ui-ng-ui-node-tree-breadcrumb.mjs.map +1 -0
  101. package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs +443 -0
  102. package/fesm2022/frame-kit-ui-ng-ui-node-tree.mjs.map +1 -0
  103. package/fesm2022/frame-kit-ui-ng-ui-note.mjs +56 -0
  104. package/fesm2022/frame-kit-ui-ng-ui-note.mjs.map +1 -0
  105. package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs +105 -0
  106. package/fesm2022/frame-kit-ui-ng-ui-numbered-list.mjs.map +1 -0
  107. package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs +110 -0
  108. package/fesm2022/frame-kit-ui-ng-ui-pagination.mjs.map +1 -0
  109. package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs +129 -0
  110. package/fesm2022/frame-kit-ui-ng-ui-progress-bar.mjs.map +1 -0
  111. package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs +42 -0
  112. package/fesm2022/frame-kit-ui-ng-ui-sidenav-link.mjs.map +1 -0
  113. package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs +894 -0
  114. package/fesm2022/frame-kit-ui-ng-ui-tabs.mjs.map +1 -0
  115. package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs +81 -0
  116. package/fesm2022/frame-kit-ui-ng-ui-timeline.mjs.map +1 -0
  117. package/fesm2022/frame-kit-ui-ng-ui-toast.mjs +179 -0
  118. package/fesm2022/frame-kit-ui-ng-ui-toast.mjs.map +1 -0
  119. package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs +143 -0
  120. package/fesm2022/frame-kit-ui-ng-ui-user-menu.mjs.map +1 -0
  121. package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs +191 -0
  122. package/fesm2022/frame-kit-ui-ng-ui-wizard-dialog.mjs.map +1 -0
  123. package/fesm2022/frame-kit-ui-ng.mjs +58 -0
  124. package/fesm2022/frame-kit-ui-ng.mjs.map +1 -0
  125. package/layouts/app-shell/README.md +357 -0
  126. package/layouts/content-split/README.md +180 -0
  127. package/package.json +253 -0
  128. package/services/overlay-orchestrator/README.md +184 -0
  129. package/services/spotlight/README.md +61 -0
  130. package/services/toast/README.md +118 -0
  131. package/types/frame-kit-ui-ng-core-headline.d.ts +38 -0
  132. package/types/frame-kit-ui-ng-core-icon.d.ts +74 -0
  133. package/types/frame-kit-ui-ng-core-image.d.ts +93 -0
  134. package/types/frame-kit-ui-ng-core-link.d.ts +251 -0
  135. package/types/frame-kit-ui-ng-core-separator.d.ts +28 -0
  136. package/types/frame-kit-ui-ng-core-text.d.ts +186 -0
  137. package/types/frame-kit-ui-ng-directives-infinite-scroll.d.ts +42 -0
  138. package/types/frame-kit-ui-ng-directives-spotlight.d.ts +51 -0
  139. package/types/frame-kit-ui-ng-directives-tooltip.d.ts +70 -0
  140. package/types/frame-kit-ui-ng-docs-endpoint-link.d.ts +43 -0
  141. package/types/frame-kit-ui-ng-docs-method-badge.d.ts +30 -0
  142. package/types/frame-kit-ui-ng-forms.d.ts +1674 -0
  143. package/types/frame-kit-ui-ng-layouts-app-shell.d.ts +75 -0
  144. package/types/frame-kit-ui-ng-layouts-content-split.d.ts +43 -0
  145. package/types/frame-kit-ui-ng-services-overlay-orchestrator.d.ts +96 -0
  146. package/types/frame-kit-ui-ng-services-spotlight.d.ts +32 -0
  147. package/types/frame-kit-ui-ng-services-toast.d.ts +100 -0
  148. package/types/frame-kit-ui-ng-ui-accordion.d.ts +86 -0
  149. package/types/frame-kit-ui-ng-ui-alert.d.ts +34 -0
  150. package/types/frame-kit-ui-ng-ui-avatar-stack.d.ts +38 -0
  151. package/types/frame-kit-ui-ng-ui-avatar.d.ts +36 -0
  152. package/types/frame-kit-ui-ng-ui-badge.d.ts +33 -0
  153. package/types/frame-kit-ui-ng-ui-breadcrumb.d.ts +45 -0
  154. package/types/frame-kit-ui-ng-ui-button.d.ts +48 -0
  155. package/types/frame-kit-ui-ng-ui-callout.d.ts +26 -0
  156. package/types/frame-kit-ui-ng-ui-card.d.ts +30 -0
  157. package/types/frame-kit-ui-ng-ui-copyable-field.d.ts +62 -0
  158. package/types/frame-kit-ui-ng-ui-data-table.d.ts +482 -0
  159. package/types/frame-kit-ui-ng-ui-dialog.d.ts +166 -0
  160. package/types/frame-kit-ui-ng-ui-drawer.d.ts +130 -0
  161. package/types/frame-kit-ui-ng-ui-dropdown-menu.d.ts +77 -0
  162. package/types/frame-kit-ui-ng-ui-editable-field.d.ts +65 -0
  163. package/types/frame-kit-ui-ng-ui-icon-badge.d.ts +45 -0
  164. package/types/frame-kit-ui-ng-ui-icon-list.d.ts +67 -0
  165. package/types/frame-kit-ui-ng-ui-inline-edit.d.ts +44 -0
  166. package/types/frame-kit-ui-ng-ui-list-editor.d.ts +56 -0
  167. package/types/frame-kit-ui-ng-ui-loader.d.ts +32 -0
  168. package/types/frame-kit-ui-ng-ui-menu-item.d.ts +27 -0
  169. package/types/frame-kit-ui-ng-ui-nav-brand.d.ts +25 -0
  170. package/types/frame-kit-ui-ng-ui-nav-group.d.ts +60 -0
  171. package/types/frame-kit-ui-ng-ui-nav-separator.d.ts +33 -0
  172. package/types/frame-kit-ui-ng-ui-node-tree-breadcrumb.d.ts +35 -0
  173. package/types/frame-kit-ui-ng-ui-node-tree.d.ts +135 -0
  174. package/types/frame-kit-ui-ng-ui-note.d.ts +22 -0
  175. package/types/frame-kit-ui-ng-ui-numbered-list.d.ts +52 -0
  176. package/types/frame-kit-ui-ng-ui-pagination.d.ts +49 -0
  177. package/types/frame-kit-ui-ng-ui-progress-bar.d.ts +50 -0
  178. package/types/frame-kit-ui-ng-ui-sidenav-link.d.ts +24 -0
  179. package/types/frame-kit-ui-ng-ui-tabs.d.ts +266 -0
  180. package/types/frame-kit-ui-ng-ui-timeline.d.ts +42 -0
  181. package/types/frame-kit-ui-ng-ui-toast.d.ts +56 -0
  182. package/types/frame-kit-ui-ng-ui-user-menu.d.ts +87 -0
  183. package/types/frame-kit-ui-ng-ui-wizard-dialog.d.ts +116 -0
  184. package/types/frame-kit-ui-ng.d.ts +53 -0
  185. package/ui/accordion/README.md +261 -0
  186. package/ui/alert/README.md +211 -0
  187. package/ui/avatar/README.md +167 -0
  188. package/ui/avatar-stack/README.md +164 -0
  189. package/ui/badge/README.md +162 -0
  190. package/ui/breadcrumb/README.md +240 -0
  191. package/ui/button/README.md +184 -0
  192. package/ui/callout/README.md +159 -0
  193. package/ui/card/README.md +174 -0
  194. package/ui/copyable-field/README.md +235 -0
  195. package/ui/data-table/README.md +408 -0
  196. package/ui/dialog/README.md +222 -0
  197. package/ui/drawer/README.md +274 -0
  198. package/ui/dropdown-menu/README.md +336 -0
  199. package/ui/editable-field/README.md +171 -0
  200. package/ui/icon-badge/README.md +131 -0
  201. package/ui/icon-list/README.md +205 -0
  202. package/ui/inline-edit/README.md +135 -0
  203. package/ui/list-editor/README.md +162 -0
  204. package/ui/loader/README.md +160 -0
  205. package/ui/menu-item/README.md +204 -0
  206. package/ui/nav-brand/README.md +111 -0
  207. package/ui/nav-group/README.md +145 -0
  208. package/ui/nav-separator/README.md +44 -0
  209. package/ui/node-tree/README.md +278 -0
  210. package/ui/node-tree-breadcrumb/README.md +164 -0
  211. package/ui/note/README.md +146 -0
  212. package/ui/numbered-list/README.md +187 -0
  213. package/ui/pagination/README.md +174 -0
  214. package/ui/progress-bar/README.md +223 -0
  215. package/ui/sidenav-link/README.md +214 -0
  216. package/ui/tabs/README.md +204 -0
  217. package/ui/timeline/README.md +285 -0
  218. package/ui/toast/README.md +243 -0
  219. package/ui/user-menu/README.md +260 -0
  220. package/ui/wizard-dialog/README.md +283 -0
@@ -0,0 +1,443 @@
1
+ import { CdkDragHandle, CdkDropList, CdkDrag, CdkDragPreview, CdkDragPlaceholder } from '@angular/cdk/drag-drop';
2
+ import * as i0 from '@angular/core';
3
+ import { input, output, computed, HostListener, HostBinding, ChangeDetectionStrategy, Component, inject, TemplateRef, Directive, ElementRef, contentChild, signal } from '@angular/core';
4
+ import { IconComponent } from '@frame-kit/ui-ng/core/icon';
5
+ import { NgTemplateOutlet } from '@angular/common';
6
+
7
+ function isDescendantOf(nodeId, ancestorId, childrenMap) {
8
+ const children = childrenMap.get(ancestorId);
9
+ if (!children) {
10
+ return false;
11
+ }
12
+ for (const child of children) {
13
+ if (child.id === nodeId) {
14
+ return true;
15
+ }
16
+ if (isDescendantOf(nodeId, child.id, childrenMap)) {
17
+ return true;
18
+ }
19
+ }
20
+ return false;
21
+ }
22
+ function buildChildrenMap(nodes) {
23
+ const map = new Map();
24
+ for (const node of nodes) {
25
+ const key = node.parentId ?? null;
26
+ const children = map.get(key);
27
+ if (children) {
28
+ children.push(node);
29
+ }
30
+ else {
31
+ map.set(key, [node]);
32
+ }
33
+ }
34
+ return map;
35
+ }
36
+ function flattenTree(childrenMap, expandedIds, parentId = null, level = 0) {
37
+ const children = childrenMap.get(parentId);
38
+ if (!children) {
39
+ return [];
40
+ }
41
+ const result = [];
42
+ for (const node of children) {
43
+ const expandable = childrenMap.has(node.id);
44
+ const expanded = expandedIds.has(node.id);
45
+ result.push({
46
+ id: node.id,
47
+ label: node.label,
48
+ icon: node.icon,
49
+ level,
50
+ expandable,
51
+ expanded,
52
+ parentId: node.parentId,
53
+ draggable: node.draggable !== false,
54
+ disabled: node.disabled === true,
55
+ });
56
+ if (expandable && expanded) {
57
+ result.push(...flattenTree(childrenMap, expandedIds, node.id, level + 1));
58
+ }
59
+ }
60
+ return result;
61
+ }
62
+
63
+ class FkNodeTreeRowComponent {
64
+ // ===== BASE PROPS =====
65
+ className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
66
+ // ===== INPUTS =====
67
+ /** Flattened node data including level, expandable state, and label. */
68
+ node = input.required(...(ngDevMode ? [{ debugName: "node" }] : /* istanbul ignore next */ []));
69
+ /** Whether this row is the currently selected node. */
70
+ selected = input(false, ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
71
+ /** Current drop position relative to this row during a drag operation. */
72
+ dropPosition = input(null, ...(ngDevMode ? [{ debugName: "dropPosition" }] : /* istanbul ignore next */ []));
73
+ /** When true, this row is the one being dragged (applies ghost styling). */
74
+ isDragSource = input(false, ...(ngDevMode ? [{ debugName: "isDragSource" }] : /* istanbul ignore next */ []));
75
+ /** When true, renders the CDK drag handle affordance. */
76
+ showDragHandle = input(false, ...(ngDevMode ? [{ debugName: "showDragHandle" }] : /* istanbul ignore next */ []));
77
+ /** Optional custom template used to render the row content. */
78
+ customTemplate = input(undefined, ...(ngDevMode ? [{ debugName: "customTemplate" }] : /* istanbul ignore next */ []));
79
+ // ===== OUTPUTS =====
80
+ /** Fires when the user clicks the expand/collapse chevron. */
81
+ toggleNode = output();
82
+ /** Fires when the user clicks the row body to select the node. */
83
+ selectNode = output();
84
+ // ===== COMPUTED =====
85
+ classes = computed(() => {
86
+ const pos = this.dropPosition();
87
+ return [
88
+ 'fk-node-tree-row',
89
+ this.selected() ? 'fk-node-tree-row--selected' : '',
90
+ this.node().disabled ? 'fk-node-tree-row--disabled' : '',
91
+ pos === 'inside' ? 'fk-node-tree-row--drop-inside' : '',
92
+ pos === 'before' ? 'fk-node-tree-row--drop-before' : '',
93
+ pos === 'after' ? 'fk-node-tree-row--drop-after' : '',
94
+ this.isDragSource() ? 'fk-node-tree-row--drag-source' : '',
95
+ this.className(),
96
+ ]
97
+ .filter(Boolean)
98
+ .join(' ');
99
+ }, ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
100
+ templateContext = computed(() => {
101
+ const n = this.node();
102
+ return { $implicit: n, node: n };
103
+ }, ...(ngDevMode ? [{ debugName: "templateContext" }] : /* istanbul ignore next */ []));
104
+ // ===== HOST BINDINGS =====
105
+ get hostClass() {
106
+ return this.classes();
107
+ }
108
+ get dataNodeId() {
109
+ return this.node().id;
110
+ }
111
+ role = 'treeitem';
112
+ get ariaLevel() {
113
+ return this.node().level + 1;
114
+ }
115
+ get ariaExpanded() {
116
+ const n = this.node();
117
+ return n.expandable ? n.expanded : null;
118
+ }
119
+ get ariaSelected() {
120
+ return this.selected();
121
+ }
122
+ tabindex = 0;
123
+ get paddingLeft() {
124
+ return `${this.node().level * 1.5}rem`;
125
+ }
126
+ // ===== HOST LISTENERS =====
127
+ onClick() {
128
+ this.selectNode.emit();
129
+ }
130
+ // ===== METHODS =====
131
+ onToggleClick(event) {
132
+ event.stopPropagation();
133
+ this.toggleNode.emit();
134
+ }
135
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkNodeTreeRowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
136
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: FkNodeTreeRowComponent, isStandalone: true, selector: "fk-node-tree-row", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, dropPosition: { classPropertyName: "dropPosition", publicName: "dropPosition", isSignal: true, isRequired: false, transformFunction: null }, isDragSource: { classPropertyName: "isDragSource", publicName: "isDragSource", isSignal: true, isRequired: false, transformFunction: null }, showDragHandle: { classPropertyName: "showDragHandle", publicName: "showDragHandle", isSignal: true, isRequired: false, transformFunction: null }, customTemplate: { classPropertyName: "customTemplate", publicName: "customTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleNode: "toggleNode", selectNode: "selectNode" }, host: { listeners: { "click": "onClick()" }, properties: { "class": "this.hostClass", "attr.data-node-id": "this.dataNodeId", "attr.role": "this.role", "attr.aria-level": "this.ariaLevel", "attr.aria-expanded": "this.ariaExpanded", "attr.aria-selected": "this.ariaSelected", "attr.tabindex": "this.tabindex", "style.padding-left": "this.paddingLeft" } }, ngImport: i0, template: "@if (customTemplate(); as tmpl) {\n <div class=\"fk-node-tree-row__content\">\n @if (showDragHandle()) {\n <span class=\"fk-node-tree-row__handle\" cdkDragHandle>\n <svg\n width=\"10\"\n height=\"14\"\n viewBox=\"0 0 10 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"3\" cy=\"2\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"2\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"3\" cy=\"7\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"7\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"3\" cy=\"12\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"12\" r=\"1.25\" fill=\"currentColor\" />\n </svg>\n </span>\n }\n @if (node().expandable) {\n <button\n class=\"fk-node-tree-row__toggle\"\n type=\"button\"\n (click)=\"onToggleClick($event)\"\n [attr.aria-label]=\"node().expanded ? 'Collapse' : 'Expand'\"\n >\n <svg\n class=\"fk-node-tree-row__chevron\"\n [class.fk-node-tree-row__chevron--expanded]=\"node().expanded\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 4l4 4-4 4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n } @else {\n <span class=\"fk-node-tree-row__toggle-spacer\"></span>\n }\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"templateContext()\"\n />\n </div>\n} @else {\n <div class=\"fk-node-tree-row__content\">\n @if (showDragHandle()) {\n <span class=\"fk-node-tree-row__handle\" cdkDragHandle>\n <svg\n width=\"10\"\n height=\"14\"\n viewBox=\"0 0 10 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"3\" cy=\"2\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"2\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"3\" cy=\"7\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"7\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"3\" cy=\"12\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"12\" r=\"1.25\" fill=\"currentColor\" />\n </svg>\n </span>\n }\n @if (node().expandable) {\n <button\n class=\"fk-node-tree-row__toggle\"\n type=\"button\"\n (click)=\"onToggleClick($event)\"\n [attr.aria-label]=\"node().expanded ? 'Collapse' : 'Expand'\"\n >\n <svg\n class=\"fk-node-tree-row__chevron\"\n [class.fk-node-tree-row__chevron--expanded]=\"node().expanded\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 4l4 4-4 4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n } @else {\n <span class=\"fk-node-tree-row__toggle-spacer\"></span>\n }\n\n @if (node().icon) {\n <fk-icon class=\"fk-node-tree-row__icon\" [name]=\"node().icon!\" size=\"sm\" />\n }\n\n <span class=\"fk-node-tree-row__label\">{{ node().label }}</span>\n </div>\n}\n\n<ng-content />\n", styles: [":host{display:block;cursor:pointer;outline:none}.fk-node-tree-row__content{display:flex;align-items:center;gap:var(--fk-node-tree-row-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-node-tree-row-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem));border-radius:var(--fk-node-tree-row-radius, var(--fk-radius-md, .375rem));color:var(--fk-node-tree-row-color, var(--fk-color-text, #1f2d3d));transition:background-color .15s ease}.fk-node-tree-row__toggle{display:inline-flex;align-items:center;justify-content:center;width:var(--fk-node-tree-row-toggle-size, 1.25rem);height:var(--fk-node-tree-row-toggle-size, 1.25rem);flex-shrink:0;padding:0;border:none;background:none;color:var(--fk-node-tree-row-toggle-color, var(--fk-color-muted, #8a98a8));cursor:pointer;border-radius:var(--fk-radius-sm, .25rem)}.fk-node-tree-row__toggle:hover{color:var(--fk-node-tree-row-toggle-color-hover, var(--fk-color-text, #1f2d3d));background-color:var(--fk-node-tree-row-toggle-bg-hover, var(--fk-color-surface-muted, #f7f9fb))}.fk-node-tree-row__toggle:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}.fk-node-tree-row__toggle-spacer{display:inline-block;width:var(--fk-node-tree-row-toggle-size, 1.25rem);height:var(--fk-node-tree-row-toggle-size, 1.25rem);flex-shrink:0}.fk-node-tree-row__chevron{display:block;transition:transform .15s ease}.fk-node-tree-row__chevron--expanded{transform:rotate(90deg)}.fk-node-tree-row__icon{flex-shrink:0}.fk-node-tree-row__handle{display:inline-flex;align-items:center;justify-content:center;width:var(--fk-node-tree-row-toggle-size, 1.25rem);height:var(--fk-node-tree-row-toggle-size, 1.25rem);flex-shrink:0;color:var(--fk-node-tree-row-handle-color, var(--fk-color-muted, #8a98a8));cursor:grab;border-radius:var(--fk-radius-sm, .25rem);transition:color .15s ease}.fk-node-tree-row__handle:hover{color:var(--fk-node-tree-row-handle-color-hover, var(--fk-color-text, #1f2d3d))}.fk-node-tree-row__handle:active{cursor:grabbing}.fk-node-tree-row__label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--fk-node-tree-row-font-size, var(--fk-typography-body-font-size, .9375rem))}:host:hover .fk-node-tree-row__content{background-color:var(--fk-node-tree-row-bg-hover, var(--fk-color-surface-muted, #f7f9fb))}:host.fk-node-tree-row--selected .fk-node-tree-row__content{background-color:var(--fk-node-tree-row-bg-selected, var(--fk-overlay-brand, rgba(10, 132, 255, .18)));color:var(--fk-node-tree-row-color-selected, var(--fk-color-primary, #0a84ff));font-weight:var(--fk-node-tree-row-font-weight-selected, var(--fk-font-weight-medium, 500))}:host:focus-visible .fk-node-tree-row__content{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}:host.fk-node-tree-row--drop-inside .fk-node-tree-row__content{background-color:var(--fk-node-tree-row-bg-drop-target, var(--fk-overlay-brand, rgba(10, 132, 255, .18)));outline:2px solid var(--fk-node-tree-row-border-drop-target, var(--fk-color-primary, #0a84ff));outline-offset:-2px}:host.fk-node-tree-row--drop-before{position:relative}:host.fk-node-tree-row--drop-before:before{content:\"\";position:absolute;top:0;left:0;right:0;height:2px;background-color:var(--fk-node-tree-row-border-drop-target, var(--fk-color-primary, #0a84ff));pointer-events:none}:host.fk-node-tree-row--drop-after{position:relative}:host.fk-node-tree-row--drop-after:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:2px;background-color:var(--fk-node-tree-row-border-drop-target, var(--fk-color-primary, #0a84ff));pointer-events:none}:host.fk-node-tree-row--disabled .fk-node-tree-row__content{opacity:.5}:host.fk-node-tree-row--disabled .fk-node-tree-row__label{font-style:italic}:host.fk-node-tree-row--drag-source{opacity:var(--fk-node-tree-row-drag-source-opacity, .4)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: IconComponent, selector: "fk-icon", inputs: ["name", "size", "color", "className", "id", "ariaLabel", "ariaHidden"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
137
+ }
138
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkNodeTreeRowComponent, decorators: [{
139
+ type: Component,
140
+ args: [{ selector: 'fk-node-tree-row', standalone: true, imports: [NgTemplateOutlet, IconComponent, CdkDragHandle], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (customTemplate(); as tmpl) {\n <div class=\"fk-node-tree-row__content\">\n @if (showDragHandle()) {\n <span class=\"fk-node-tree-row__handle\" cdkDragHandle>\n <svg\n width=\"10\"\n height=\"14\"\n viewBox=\"0 0 10 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"3\" cy=\"2\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"2\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"3\" cy=\"7\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"7\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"3\" cy=\"12\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"12\" r=\"1.25\" fill=\"currentColor\" />\n </svg>\n </span>\n }\n @if (node().expandable) {\n <button\n class=\"fk-node-tree-row__toggle\"\n type=\"button\"\n (click)=\"onToggleClick($event)\"\n [attr.aria-label]=\"node().expanded ? 'Collapse' : 'Expand'\"\n >\n <svg\n class=\"fk-node-tree-row__chevron\"\n [class.fk-node-tree-row__chevron--expanded]=\"node().expanded\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 4l4 4-4 4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n } @else {\n <span class=\"fk-node-tree-row__toggle-spacer\"></span>\n }\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"templateContext()\"\n />\n </div>\n} @else {\n <div class=\"fk-node-tree-row__content\">\n @if (showDragHandle()) {\n <span class=\"fk-node-tree-row__handle\" cdkDragHandle>\n <svg\n width=\"10\"\n height=\"14\"\n viewBox=\"0 0 10 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"3\" cy=\"2\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"2\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"3\" cy=\"7\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"7\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"3\" cy=\"12\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"12\" r=\"1.25\" fill=\"currentColor\" />\n </svg>\n </span>\n }\n @if (node().expandable) {\n <button\n class=\"fk-node-tree-row__toggle\"\n type=\"button\"\n (click)=\"onToggleClick($event)\"\n [attr.aria-label]=\"node().expanded ? 'Collapse' : 'Expand'\"\n >\n <svg\n class=\"fk-node-tree-row__chevron\"\n [class.fk-node-tree-row__chevron--expanded]=\"node().expanded\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 4l4 4-4 4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n } @else {\n <span class=\"fk-node-tree-row__toggle-spacer\"></span>\n }\n\n @if (node().icon) {\n <fk-icon class=\"fk-node-tree-row__icon\" [name]=\"node().icon!\" size=\"sm\" />\n }\n\n <span class=\"fk-node-tree-row__label\">{{ node().label }}</span>\n </div>\n}\n\n<ng-content />\n", styles: [":host{display:block;cursor:pointer;outline:none}.fk-node-tree-row__content{display:flex;align-items:center;gap:var(--fk-node-tree-row-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-node-tree-row-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem));border-radius:var(--fk-node-tree-row-radius, var(--fk-radius-md, .375rem));color:var(--fk-node-tree-row-color, var(--fk-color-text, #1f2d3d));transition:background-color .15s ease}.fk-node-tree-row__toggle{display:inline-flex;align-items:center;justify-content:center;width:var(--fk-node-tree-row-toggle-size, 1.25rem);height:var(--fk-node-tree-row-toggle-size, 1.25rem);flex-shrink:0;padding:0;border:none;background:none;color:var(--fk-node-tree-row-toggle-color, var(--fk-color-muted, #8a98a8));cursor:pointer;border-radius:var(--fk-radius-sm, .25rem)}.fk-node-tree-row__toggle:hover{color:var(--fk-node-tree-row-toggle-color-hover, var(--fk-color-text, #1f2d3d));background-color:var(--fk-node-tree-row-toggle-bg-hover, var(--fk-color-surface-muted, #f7f9fb))}.fk-node-tree-row__toggle:focus-visible{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}.fk-node-tree-row__toggle-spacer{display:inline-block;width:var(--fk-node-tree-row-toggle-size, 1.25rem);height:var(--fk-node-tree-row-toggle-size, 1.25rem);flex-shrink:0}.fk-node-tree-row__chevron{display:block;transition:transform .15s ease}.fk-node-tree-row__chevron--expanded{transform:rotate(90deg)}.fk-node-tree-row__icon{flex-shrink:0}.fk-node-tree-row__handle{display:inline-flex;align-items:center;justify-content:center;width:var(--fk-node-tree-row-toggle-size, 1.25rem);height:var(--fk-node-tree-row-toggle-size, 1.25rem);flex-shrink:0;color:var(--fk-node-tree-row-handle-color, var(--fk-color-muted, #8a98a8));cursor:grab;border-radius:var(--fk-radius-sm, .25rem);transition:color .15s ease}.fk-node-tree-row__handle:hover{color:var(--fk-node-tree-row-handle-color-hover, var(--fk-color-text, #1f2d3d))}.fk-node-tree-row__handle:active{cursor:grabbing}.fk-node-tree-row__label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--fk-node-tree-row-font-size, var(--fk-typography-body-font-size, .9375rem))}:host:hover .fk-node-tree-row__content{background-color:var(--fk-node-tree-row-bg-hover, var(--fk-color-surface-muted, #f7f9fb))}:host.fk-node-tree-row--selected .fk-node-tree-row__content{background-color:var(--fk-node-tree-row-bg-selected, var(--fk-overlay-brand, rgba(10, 132, 255, .18)));color:var(--fk-node-tree-row-color-selected, var(--fk-color-primary, #0a84ff));font-weight:var(--fk-node-tree-row-font-weight-selected, var(--fk-font-weight-medium, 500))}:host:focus-visible .fk-node-tree-row__content{outline:none;box-shadow:var(--fk-focus-ring, 0 0 0 3px rgba(10, 132, 255, .18))}:host.fk-node-tree-row--drop-inside .fk-node-tree-row__content{background-color:var(--fk-node-tree-row-bg-drop-target, var(--fk-overlay-brand, rgba(10, 132, 255, .18)));outline:2px solid var(--fk-node-tree-row-border-drop-target, var(--fk-color-primary, #0a84ff));outline-offset:-2px}:host.fk-node-tree-row--drop-before{position:relative}:host.fk-node-tree-row--drop-before:before{content:\"\";position:absolute;top:0;left:0;right:0;height:2px;background-color:var(--fk-node-tree-row-border-drop-target, var(--fk-color-primary, #0a84ff));pointer-events:none}:host.fk-node-tree-row--drop-after{position:relative}:host.fk-node-tree-row--drop-after:after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:2px;background-color:var(--fk-node-tree-row-border-drop-target, var(--fk-color-primary, #0a84ff));pointer-events:none}:host.fk-node-tree-row--disabled .fk-node-tree-row__content{opacity:.5}:host.fk-node-tree-row--disabled .fk-node-tree-row__label{font-style:italic}:host.fk-node-tree-row--drag-source{opacity:var(--fk-node-tree-row-drag-source-opacity, .4)}\n"] }]
141
+ }], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: true }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], dropPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropPosition", required: false }] }], isDragSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDragSource", required: false }] }], showDragHandle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDragHandle", required: false }] }], customTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "customTemplate", required: false }] }], toggleNode: [{ type: i0.Output, args: ["toggleNode"] }], selectNode: [{ type: i0.Output, args: ["selectNode"] }], hostClass: [{
142
+ type: HostBinding,
143
+ args: ['class']
144
+ }], dataNodeId: [{
145
+ type: HostBinding,
146
+ args: ['attr.data-node-id']
147
+ }], role: [{
148
+ type: HostBinding,
149
+ args: ['attr.role']
150
+ }], ariaLevel: [{
151
+ type: HostBinding,
152
+ args: ['attr.aria-level']
153
+ }], ariaExpanded: [{
154
+ type: HostBinding,
155
+ args: ['attr.aria-expanded']
156
+ }], ariaSelected: [{
157
+ type: HostBinding,
158
+ args: ['attr.aria-selected']
159
+ }], tabindex: [{
160
+ type: HostBinding,
161
+ args: ['attr.tabindex']
162
+ }], paddingLeft: [{
163
+ type: HostBinding,
164
+ args: ['style.padding-left']
165
+ }], onClick: [{
166
+ type: HostListener,
167
+ args: ['click']
168
+ }] } });
169
+
170
+ class FkNodeTreeRowDirective {
171
+ templateRef = inject((TemplateRef));
172
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkNodeTreeRowDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
173
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.9", type: FkNodeTreeRowDirective, isStandalone: true, selector: "[fkNodeTreeRow]", ngImport: i0 });
174
+ }
175
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkNodeTreeRowDirective, decorators: [{
176
+ type: Directive,
177
+ args: [{
178
+ selector: '[fkNodeTreeRow]',
179
+ standalone: true,
180
+ }]
181
+ }] });
182
+
183
+ class FkNodeTreeComponent {
184
+ elementRef = inject((ElementRef));
185
+ // ===== BASE PROPS =====
186
+ className = input('', ...(ngDevMode ? [{ debugName: "className" }] : /* istanbul ignore next */ []));
187
+ // ===== INPUTS =====
188
+ /** Flat array of `TreeNode` objects that define the hierarchy via `parentId`. */
189
+ nodes = input.required(...(ngDevMode ? [{ debugName: "nodes" }] : /* istanbul ignore next */ []));
190
+ /** ID of the currently selected node; drives the selected row highlight. */
191
+ selectedNodeId = input(undefined, ...(ngDevMode ? [{ debugName: "selectedNodeId" }] : /* istanbul ignore next */ []));
192
+ /** Controlled set of expanded node IDs; when undefined the tree manages expansion internally. */
193
+ expandedNodeIds = input(undefined, ...(ngDevMode ? [{ debugName: "expandedNodeIds" }] : /* istanbul ignore next */ []));
194
+ /** When true, rows can be dragged to reorder or reparent nodes. */
195
+ draggable = input(false, ...(ngDevMode ? [{ debugName: "draggable" }] : /* istanbul ignore next */ []));
196
+ /** Optional guard called during drag to determine whether a drop at a given position is allowed. */
197
+ canDrop = input(undefined, ...(ngDevMode ? [{ debugName: "canDrop" }] : /* istanbul ignore next */ []));
198
+ // ===== OUTPUTS =====
199
+ /** Fires when the user clicks a node row, emitting the original `TreeNode`. */
200
+ nodeSelect = output();
201
+ /** Fires when a node's expanded state changes, emitting the node id and new expanded boolean. */
202
+ nodeExpand = output();
203
+ /** Fires when the user drops a dragged node onto a target, emitting the drop event. */
204
+ nodeDrop = output();
205
+ // ===== CONTENT CHILDREN =====
206
+ rowTemplate = contentChild(FkNodeTreeRowDirective, ...(ngDevMode ? [{ debugName: "rowTemplate" }] : /* istanbul ignore next */ []));
207
+ // ===== INTERNAL STATE =====
208
+ internalExpandedIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "internalExpandedIds" }] : /* istanbul ignore next */ []));
209
+ dragState = signal({ draggedNodeId: null, dropTargetId: null, dropPosition: null }, ...(ngDevMode ? [{ debugName: "dragState" }] : /* istanbul ignore next */ []));
210
+ autoExpandTimer = null;
211
+ autoExpandNodeId = null;
212
+ // ===== COMPUTED =====
213
+ childrenMap = computed(() => buildChildrenMap(this.nodes()), ...(ngDevMode ? [{ debugName: "childrenMap" }] : /* istanbul ignore next */ []));
214
+ nodeMap = computed(() => {
215
+ const map = new Map();
216
+ for (const node of this.nodes()) {
217
+ map.set(node.id, node);
218
+ }
219
+ return map;
220
+ }, ...(ngDevMode ? [{ debugName: "nodeMap" }] : /* istanbul ignore next */ []));
221
+ effectiveExpandedIds = computed(() => {
222
+ const controlled = this.expandedNodeIds();
223
+ if (controlled !== undefined) {
224
+ return new Set(controlled);
225
+ }
226
+ return this.internalExpandedIds();
227
+ }, ...(ngDevMode ? [{ debugName: "effectiveExpandedIds" }] : /* istanbul ignore next */ []));
228
+ visibleNodes = computed(() => flattenTree(this.childrenMap(), this.effectiveExpandedIds()), ...(ngDevMode ? [{ debugName: "visibleNodes" }] : /* istanbul ignore next */ []));
229
+ draggedNodeId = computed(() => this.dragState().draggedNodeId, ...(ngDevMode ? [{ debugName: "draggedNodeId" }] : /* istanbul ignore next */ []));
230
+ dropTargetId = computed(() => this.dragState().dropTargetId, ...(ngDevMode ? [{ debugName: "dropTargetId" }] : /* istanbul ignore next */ []));
231
+ dropPosition = computed(() => this.dragState().dropPosition, ...(ngDevMode ? [{ debugName: "dropPosition" }] : /* istanbul ignore next */ []));
232
+ classes = computed(() => [
233
+ 'fk-node-tree',
234
+ this.draggedNodeId() ? 'fk-node-tree--dragging' : '',
235
+ this.className(),
236
+ ]
237
+ .filter(Boolean)
238
+ .join(' '), ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
239
+ // ===== HOST BINDINGS =====
240
+ role = 'tree';
241
+ get hostClass() {
242
+ return this.classes();
243
+ }
244
+ // ===== METHODS =====
245
+ onNodeSelect(flatNode) {
246
+ const original = this.nodeMap().get(flatNode.id);
247
+ if (original) {
248
+ this.nodeSelect.emit(original);
249
+ }
250
+ }
251
+ onNodeToggle(flatNode) {
252
+ const newExpanded = !flatNode.expanded;
253
+ this.nodeExpand.emit({ nodeId: flatNode.id, expanded: newExpanded });
254
+ // Only update internal state when uncontrolled
255
+ if (this.expandedNodeIds() === undefined) {
256
+ this.internalExpandedIds.update((prev) => {
257
+ const next = new Set(prev);
258
+ if (newExpanded) {
259
+ next.add(flatNode.id);
260
+ }
261
+ else {
262
+ next.delete(flatNode.id);
263
+ }
264
+ return next;
265
+ });
266
+ }
267
+ }
268
+ onDragStarted(event, flatNode) {
269
+ this.dragState.set({
270
+ draggedNodeId: flatNode.id,
271
+ dropTargetId: null,
272
+ dropPosition: null,
273
+ });
274
+ }
275
+ onDragMoved(event) {
276
+ const result = this.resolveDropTarget(event.pointerPosition.y);
277
+ const currentState = this.dragState();
278
+ if (!result) {
279
+ if (currentState.dropTargetId !== null) {
280
+ this.dragState.set({
281
+ draggedNodeId: currentState.draggedNodeId,
282
+ dropTargetId: null,
283
+ dropPosition: null,
284
+ });
285
+ }
286
+ this.clearAutoExpand();
287
+ return;
288
+ }
289
+ const canDropFn = this.canDrop();
290
+ if (canDropFn) {
291
+ const draggedNode = this.visibleNodes().find((n) => n.id === currentState.draggedNodeId);
292
+ const targetNode = this.visibleNodes().find((n) => n.id === result.nodeId);
293
+ if (draggedNode && targetNode) {
294
+ const allowed = canDropFn(draggedNode, targetNode, result.position);
295
+ if (!allowed) {
296
+ if (currentState.dropTargetId !== null) {
297
+ this.dragState.set({
298
+ draggedNodeId: currentState.draggedNodeId,
299
+ dropTargetId: null,
300
+ dropPosition: null,
301
+ });
302
+ }
303
+ this.clearAutoExpand();
304
+ return;
305
+ }
306
+ }
307
+ }
308
+ if (result.nodeId !== currentState.dropTargetId ||
309
+ result.position !== currentState.dropPosition) {
310
+ this.dragState.set({
311
+ draggedNodeId: currentState.draggedNodeId,
312
+ dropTargetId: result.nodeId,
313
+ dropPosition: result.position,
314
+ });
315
+ }
316
+ if (result.position === 'inside') {
317
+ this.startAutoExpand(result.nodeId);
318
+ }
319
+ else {
320
+ this.clearAutoExpand();
321
+ }
322
+ }
323
+ onDragEnded() {
324
+ const { draggedNodeId, dropTargetId, dropPosition } = this.dragState();
325
+ if (!draggedNodeId || !dropTargetId || !dropPosition) {
326
+ this.resetDragState();
327
+ return;
328
+ }
329
+ // Prevent self-drop
330
+ if (draggedNodeId === dropTargetId) {
331
+ this.resetDragState();
332
+ return;
333
+ }
334
+ // Prevent dropping onto descendant
335
+ if (isDescendantOf(dropTargetId, draggedNodeId, this.childrenMap())) {
336
+ this.resetDragState();
337
+ return;
338
+ }
339
+ const draggedNode = this.nodeMap().get(draggedNodeId);
340
+ const targetNode = this.nodeMap().get(dropTargetId);
341
+ const previousParentId = draggedNode?.parentId ?? null;
342
+ let newParentId;
343
+ if (dropPosition === 'inside') {
344
+ newParentId = dropTargetId;
345
+ }
346
+ else {
347
+ newParentId = targetNode?.parentId ?? null;
348
+ }
349
+ this.nodeDrop.emit({
350
+ nodeId: draggedNodeId,
351
+ newParentId,
352
+ previousParentId,
353
+ position: dropPosition,
354
+ referenceNodeId: dropTargetId,
355
+ });
356
+ this.resetDragState();
357
+ }
358
+ // ===== PRIVATE =====
359
+ resolveDropTarget(pointerY) {
360
+ const rows = this.elementRef.nativeElement.querySelectorAll('fk-node-tree-row');
361
+ const draggedId = this.dragState().draggedNodeId;
362
+ for (let i = 0; i < rows.length; i++) {
363
+ const rect = rows[i].getBoundingClientRect();
364
+ if (pointerY >= rect.top && pointerY <= rect.bottom) {
365
+ const nodeId = rows[i].getAttribute('data-node-id');
366
+ if (!nodeId || nodeId === draggedId) {
367
+ return null;
368
+ }
369
+ const relativeY = pointerY - rect.top;
370
+ const height = rect.height;
371
+ let position;
372
+ if (relativeY < height * 0.25) {
373
+ position = 'before';
374
+ }
375
+ else if (relativeY > height * 0.75) {
376
+ position = 'after';
377
+ }
378
+ else {
379
+ position = 'inside';
380
+ }
381
+ return { nodeId, position };
382
+ }
383
+ }
384
+ return null;
385
+ }
386
+ startAutoExpand(nodeId) {
387
+ if (this.autoExpandTimer && this.autoExpandNodeId === nodeId) {
388
+ return;
389
+ }
390
+ this.clearAutoExpand();
391
+ const flatNode = this.visibleNodes().find((n) => n.id === nodeId);
392
+ if (!flatNode || !flatNode.expandable || flatNode.expanded) {
393
+ return;
394
+ }
395
+ this.autoExpandNodeId = nodeId;
396
+ this.autoExpandTimer = setTimeout(() => {
397
+ this.onNodeToggle(flatNode);
398
+ this.autoExpandTimer = null;
399
+ this.autoExpandNodeId = null;
400
+ }, 800);
401
+ }
402
+ clearAutoExpand() {
403
+ if (this.autoExpandTimer) {
404
+ clearTimeout(this.autoExpandTimer);
405
+ this.autoExpandTimer = null;
406
+ }
407
+ this.autoExpandNodeId = null;
408
+ }
409
+ resetDragState() {
410
+ this.dragState.set({
411
+ draggedNodeId: null,
412
+ dropTargetId: null,
413
+ dropPosition: null,
414
+ });
415
+ this.clearAutoExpand();
416
+ }
417
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkNodeTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
418
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: FkNodeTreeComponent, isStandalone: true, selector: "fk-node-tree", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: true, transformFunction: null }, selectedNodeId: { classPropertyName: "selectedNodeId", publicName: "selectedNodeId", isSignal: true, isRequired: false, transformFunction: null }, expandedNodeIds: { classPropertyName: "expandedNodeIds", publicName: "expandedNodeIds", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, canDrop: { classPropertyName: "canDrop", publicName: "canDrop", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { nodeSelect: "nodeSelect", nodeExpand: "nodeExpand", nodeDrop: "nodeDrop" }, host: { properties: { "attr.role": "this.role", "class": "this.hostClass" } }, queries: [{ propertyName: "rowTemplate", first: true, predicate: FkNodeTreeRowDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div\n cdkDropList\n [cdkDropListDisabled]=\"!draggable()\"\n [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"visibleNodes()\"\n class=\"fk-node-tree__list\"\n>\n @for (flatNode of visibleNodes(); track flatNode.id) {\n <fk-node-tree-row\n cdkDrag\n [cdkDragDisabled]=\"!draggable() || !flatNode.draggable\"\n [cdkDragData]=\"flatNode\"\n (cdkDragStarted)=\"onDragStarted($event, flatNode)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"onDragEnded()\"\n [node]=\"flatNode\"\n [selected]=\"flatNode.id === selectedNodeId()\"\n [dropPosition]=\"flatNode.id === dropTargetId() ? dropPosition() : null\"\n [isDragSource]=\"flatNode.id === draggedNodeId()\"\n [showDragHandle]=\"draggable() && flatNode.draggable\"\n [customTemplate]=\"rowTemplate()?.templateRef\"\n (toggleNode)=\"onNodeToggle(flatNode)\"\n (selectNode)=\"onNodeSelect(flatNode)\"\n >\n <ng-template cdkDragPreview>\n <div class=\"fk-node-tree__drag-preview\">\n @if (flatNode.icon) {\n <fk-icon [name]=\"flatNode.icon\" size=\"sm\" />\n }\n <span>{{ flatNode.label }}</span>\n </div>\n </ng-template>\n\n <ng-template cdkDragPlaceholder>\n <div class=\"fk-node-tree__drag-placeholder\"></div>\n </ng-template>\n </fk-node-tree-row>\n }\n</div>\n", styles: [":host{display:block}.fk-node-tree__drag-preview{display:flex;align-items:center;gap:var(--fk-node-tree-row-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-node-tree-row-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem));background:var(--fk-node-tree-drag-preview-bg, var(--fk-color-surface, #ffffff));border-radius:var(--fk-node-tree-row-radius, var(--fk-radius-md, .375rem));box-shadow:var(--fk-node-tree-drag-preview-shadow, 0 4px 12px rgba(0, 0, 0, .15));font-size:var(--fk-node-tree-row-font-size, var(--fk-typography-body-font-size, .9375rem));color:var(--fk-node-tree-row-color, var(--fk-color-text, #1f2d3d));max-width:280px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.fk-node-tree__drag-placeholder{height:2px;background:var(--fk-node-tree-drag-placeholder-bg, var(--fk-color-primary, #0a84ff));border-radius:1px;margin:var(--fk-rhythm-1, .25rem) 0}\n"], dependencies: [{ kind: "component", type: FkNodeTreeRowComponent, selector: "fk-node-tree-row", inputs: ["className", "node", "selected", "dropPosition", "isDragSource", "showDragHandle", "customTemplate"], outputs: ["toggleNode", "selectNode"] }, { kind: "component", type: IconComponent, selector: "fk-icon", inputs: ["name", "size", "color", "className", "id", "ariaLabel", "ariaHidden"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
419
+ }
420
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: FkNodeTreeComponent, decorators: [{
421
+ type: Component,
422
+ args: [{ selector: 'fk-node-tree', standalone: true, imports: [
423
+ FkNodeTreeRowComponent,
424
+ IconComponent,
425
+ CdkDropList,
426
+ CdkDrag,
427
+ CdkDragPreview,
428
+ CdkDragPlaceholder,
429
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n cdkDropList\n [cdkDropListDisabled]=\"!draggable()\"\n [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"visibleNodes()\"\n class=\"fk-node-tree__list\"\n>\n @for (flatNode of visibleNodes(); track flatNode.id) {\n <fk-node-tree-row\n cdkDrag\n [cdkDragDisabled]=\"!draggable() || !flatNode.draggable\"\n [cdkDragData]=\"flatNode\"\n (cdkDragStarted)=\"onDragStarted($event, flatNode)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"onDragEnded()\"\n [node]=\"flatNode\"\n [selected]=\"flatNode.id === selectedNodeId()\"\n [dropPosition]=\"flatNode.id === dropTargetId() ? dropPosition() : null\"\n [isDragSource]=\"flatNode.id === draggedNodeId()\"\n [showDragHandle]=\"draggable() && flatNode.draggable\"\n [customTemplate]=\"rowTemplate()?.templateRef\"\n (toggleNode)=\"onNodeToggle(flatNode)\"\n (selectNode)=\"onNodeSelect(flatNode)\"\n >\n <ng-template cdkDragPreview>\n <div class=\"fk-node-tree__drag-preview\">\n @if (flatNode.icon) {\n <fk-icon [name]=\"flatNode.icon\" size=\"sm\" />\n }\n <span>{{ flatNode.label }}</span>\n </div>\n </ng-template>\n\n <ng-template cdkDragPlaceholder>\n <div class=\"fk-node-tree__drag-placeholder\"></div>\n </ng-template>\n </fk-node-tree-row>\n }\n</div>\n", styles: [":host{display:block}.fk-node-tree__drag-preview{display:flex;align-items:center;gap:var(--fk-node-tree-row-gap, var(--fk-rhythm-2, .5rem));padding:var(--fk-node-tree-row-padding, var(--fk-rhythm-2, .5rem) var(--fk-rhythm-3, .75rem));background:var(--fk-node-tree-drag-preview-bg, var(--fk-color-surface, #ffffff));border-radius:var(--fk-node-tree-row-radius, var(--fk-radius-md, .375rem));box-shadow:var(--fk-node-tree-drag-preview-shadow, 0 4px 12px rgba(0, 0, 0, .15));font-size:var(--fk-node-tree-row-font-size, var(--fk-typography-body-font-size, .9375rem));color:var(--fk-node-tree-row-color, var(--fk-color-text, #1f2d3d));max-width:280px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.fk-node-tree__drag-placeholder{height:2px;background:var(--fk-node-tree-drag-placeholder-bg, var(--fk-color-primary, #0a84ff));border-radius:1px;margin:var(--fk-rhythm-1, .25rem) 0}\n"] }]
430
+ }], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: true }] }], selectedNodeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedNodeId", required: false }] }], expandedNodeIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedNodeIds", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], canDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "canDrop", required: false }] }], nodeSelect: [{ type: i0.Output, args: ["nodeSelect"] }], nodeExpand: [{ type: i0.Output, args: ["nodeExpand"] }], nodeDrop: [{ type: i0.Output, args: ["nodeDrop"] }], rowTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FkNodeTreeRowDirective), { isSignal: true }] }], role: [{
431
+ type: HostBinding,
432
+ args: ['attr.role']
433
+ }], hostClass: [{
434
+ type: HostBinding,
435
+ args: ['class']
436
+ }] } });
437
+
438
+ /**
439
+ * Generated bundle index. Do not edit.
440
+ */
441
+
442
+ export { FkNodeTreeComponent, FkNodeTreeRowComponent, FkNodeTreeRowDirective, buildChildrenMap, flattenTree, isDescendantOf };
443
+ //# sourceMappingURL=frame-kit-ui-ng-ui-node-tree.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-kit-ui-ng-ui-node-tree.mjs","sources":["../../../../packages/ui-ng/ui/node-tree/node-tree.utils.ts","../../../../packages/ui-ng/ui/node-tree/node-tree-row.component.ts","../../../../packages/ui-ng/ui/node-tree/node-tree-row.component.html","../../../../packages/ui-ng/ui/node-tree/node-tree-row.directive.ts","../../../../packages/ui-ng/ui/node-tree/node-tree.component.ts","../../../../packages/ui-ng/ui/node-tree/node-tree.component.html","../../../../packages/ui-ng/ui/node-tree/frame-kit-ui-ng-ui-node-tree.ts"],"sourcesContent":["import { FlatNode, TreeNode } from './node-tree.types';\n\nexport function isDescendantOf(\n nodeId: string,\n ancestorId: string,\n childrenMap: Map<string | null, TreeNode[]>,\n): boolean {\n const children = childrenMap.get(ancestorId);\n\n if (!children) {\n return false;\n }\n\n for (const child of children) {\n if (child.id === nodeId) {\n return true;\n }\n\n if (isDescendantOf(nodeId, child.id, childrenMap)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function buildChildrenMap(\n nodes: TreeNode[],\n): Map<string | null, TreeNode[]> {\n const map = new Map<string | null, TreeNode[]>();\n\n for (const node of nodes) {\n const key = node.parentId ?? null;\n const children = map.get(key);\n\n if (children) {\n children.push(node);\n } else {\n map.set(key, [node]);\n }\n }\n\n return map;\n}\n\nexport function flattenTree(\n childrenMap: Map<string | null, TreeNode[]>,\n expandedIds: Set<string>,\n parentId: string | null = null,\n level = 0,\n): FlatNode[] {\n const children = childrenMap.get(parentId);\n\n if (!children) {\n return [];\n }\n\n const result: FlatNode[] = [];\n\n for (const node of children) {\n const expandable = childrenMap.has(node.id);\n const expanded = expandedIds.has(node.id);\n\n result.push({\n id: node.id,\n label: node.label,\n icon: node.icon,\n level,\n expandable,\n expanded,\n parentId: node.parentId,\n draggable: node.draggable !== false,\n disabled: node.disabled === true,\n });\n\n if (expandable && expanded) {\n result.push(...flattenTree(childrenMap, expandedIds, node.id, level + 1));\n }\n }\n\n return result;\n}\n","import { CdkDragHandle } from '@angular/cdk/drag-drop';\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n HostBinding,\n HostListener,\n input,\n output,\n TemplateRef,\n} from '@angular/core';\n\nimport { IconComponent } from '@frame-kit/ui-ng/core/icon';\nimport { DropPosition, FlatNode, NodeTreeRowContext } from './node-tree.types';\n\n@Component({\n selector: 'fk-node-tree-row',\n standalone: true,\n imports: [NgTemplateOutlet, IconComponent, CdkDragHandle],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './node-tree-row.component.html',\n styleUrl: './node-tree-row.component.scss',\n})\nexport class FkNodeTreeRowComponent {\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n\n // ===== INPUTS =====\n /** Flattened node data including level, expandable state, and label. */\n readonly node = input.required<FlatNode>();\n /** Whether this row is the currently selected node. */\n readonly selected = input(false);\n /** Current drop position relative to this row during a drag operation. */\n readonly dropPosition = input<DropPosition | null>(null);\n /** When true, this row is the one being dragged (applies ghost styling). */\n readonly isDragSource = input(false);\n /** When true, renders the CDK drag handle affordance. */\n readonly showDragHandle = input(false);\n /** Optional custom template used to render the row content. */\n readonly customTemplate = input<TemplateRef<NodeTreeRowContext> | undefined>(\n undefined,\n );\n\n // ===== OUTPUTS =====\n /** Fires when the user clicks the expand/collapse chevron. */\n readonly toggleNode = output<void>();\n /** Fires when the user clicks the row body to select the node. */\n readonly selectNode = output<void>();\n\n // ===== COMPUTED =====\n readonly classes = computed(() => {\n const pos = this.dropPosition();\n\n return [\n 'fk-node-tree-row',\n this.selected() ? 'fk-node-tree-row--selected' : '',\n this.node().disabled ? 'fk-node-tree-row--disabled' : '',\n pos === 'inside' ? 'fk-node-tree-row--drop-inside' : '',\n pos === 'before' ? 'fk-node-tree-row--drop-before' : '',\n pos === 'after' ? 'fk-node-tree-row--drop-after' : '',\n this.isDragSource() ? 'fk-node-tree-row--drag-source' : '',\n this.className(),\n ]\n .filter(Boolean)\n .join(' ');\n });\n\n readonly templateContext = computed<NodeTreeRowContext>(() => {\n const n = this.node();\n\n return { $implicit: n, node: n };\n });\n\n // ===== HOST BINDINGS =====\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n @HostBinding('attr.data-node-id')\n get dataNodeId() {\n return this.node().id;\n }\n\n @HostBinding('attr.role')\n readonly role = 'treeitem';\n\n @HostBinding('attr.aria-level')\n get ariaLevel() {\n return this.node().level + 1;\n }\n\n @HostBinding('attr.aria-expanded')\n get ariaExpanded() {\n const n = this.node();\n\n return n.expandable ? n.expanded : null;\n }\n\n @HostBinding('attr.aria-selected')\n get ariaSelected() {\n return this.selected();\n }\n\n @HostBinding('attr.tabindex')\n readonly tabindex = 0;\n\n @HostBinding('style.padding-left')\n get paddingLeft() {\n return `${this.node().level * 1.5}rem`;\n }\n\n // ===== HOST LISTENERS =====\n\n @HostListener('click')\n onClick(): void {\n this.selectNode.emit();\n }\n\n // ===== METHODS =====\n\n onToggleClick(event: MouseEvent): void {\n event.stopPropagation();\n\n this.toggleNode.emit();\n }\n}\n","@if (customTemplate(); as tmpl) {\n <div class=\"fk-node-tree-row__content\">\n @if (showDragHandle()) {\n <span class=\"fk-node-tree-row__handle\" cdkDragHandle>\n <svg\n width=\"10\"\n height=\"14\"\n viewBox=\"0 0 10 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"3\" cy=\"2\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"2\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"3\" cy=\"7\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"7\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"3\" cy=\"12\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"12\" r=\"1.25\" fill=\"currentColor\" />\n </svg>\n </span>\n }\n @if (node().expandable) {\n <button\n class=\"fk-node-tree-row__toggle\"\n type=\"button\"\n (click)=\"onToggleClick($event)\"\n [attr.aria-label]=\"node().expanded ? 'Collapse' : 'Expand'\"\n >\n <svg\n class=\"fk-node-tree-row__chevron\"\n [class.fk-node-tree-row__chevron--expanded]=\"node().expanded\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 4l4 4-4 4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n } @else {\n <span class=\"fk-node-tree-row__toggle-spacer\"></span>\n }\n <ng-container\n [ngTemplateOutlet]=\"tmpl\"\n [ngTemplateOutletContext]=\"templateContext()\"\n />\n </div>\n} @else {\n <div class=\"fk-node-tree-row__content\">\n @if (showDragHandle()) {\n <span class=\"fk-node-tree-row__handle\" cdkDragHandle>\n <svg\n width=\"10\"\n height=\"14\"\n viewBox=\"0 0 10 14\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n >\n <circle cx=\"3\" cy=\"2\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"2\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"3\" cy=\"7\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"7\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"3\" cy=\"12\" r=\"1.25\" fill=\"currentColor\" />\n <circle cx=\"7\" cy=\"12\" r=\"1.25\" fill=\"currentColor\" />\n </svg>\n </span>\n }\n @if (node().expandable) {\n <button\n class=\"fk-node-tree-row__toggle\"\n type=\"button\"\n (click)=\"onToggleClick($event)\"\n [attr.aria-label]=\"node().expanded ? 'Collapse' : 'Expand'\"\n >\n <svg\n class=\"fk-node-tree-row__chevron\"\n [class.fk-node-tree-row__chevron--expanded]=\"node().expanded\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M6 4l4 4-4 4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </button>\n } @else {\n <span class=\"fk-node-tree-row__toggle-spacer\"></span>\n }\n\n @if (node().icon) {\n <fk-icon class=\"fk-node-tree-row__icon\" [name]=\"node().icon!\" size=\"sm\" />\n }\n\n <span class=\"fk-node-tree-row__label\">{{ node().label }}</span>\n </div>\n}\n\n<ng-content />\n","import { Directive, inject, TemplateRef } from '@angular/core';\n\nimport { NodeTreeRowContext } from './node-tree.types';\n\n@Directive({\n selector: '[fkNodeTreeRow]',\n standalone: true,\n})\nexport class FkNodeTreeRowDirective {\n readonly templateRef = inject(TemplateRef<NodeTreeRowContext>);\n}\n","import {\n CdkDrag,\n CdkDragMove,\n CdkDragPlaceholder,\n CdkDragPreview,\n CdkDragStart,\n CdkDropList,\n} from '@angular/cdk/drag-drop';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n contentChild,\n ElementRef,\n HostBinding,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\n\nimport { IconComponent } from '@frame-kit/ui-ng/core/icon';\nimport {\n CanDropFn,\n DropPosition,\n FlatNode,\n NodeDropEvent,\n NodeExpandEvent,\n TreeNode,\n} from './node-tree.types';\nimport {\n buildChildrenMap,\n flattenTree,\n isDescendantOf,\n} from './node-tree.utils';\nimport { FkNodeTreeRowComponent } from './node-tree-row.component';\nimport { FkNodeTreeRowDirective } from './node-tree-row.directive';\n\n@Component({\n selector: 'fk-node-tree',\n standalone: true,\n imports: [\n FkNodeTreeRowComponent,\n IconComponent,\n CdkDropList,\n CdkDrag,\n CdkDragPreview,\n CdkDragPlaceholder,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './node-tree.component.html',\n styleUrl: './node-tree.component.scss',\n})\nexport class FkNodeTreeComponent {\n private readonly elementRef = inject(ElementRef<HTMLElement>);\n\n // ===== BASE PROPS =====\n readonly className = input<string>('');\n\n // ===== INPUTS =====\n /** Flat array of `TreeNode` objects that define the hierarchy via `parentId`. */\n readonly nodes = input.required<TreeNode[]>();\n /** ID of the currently selected node; drives the selected row highlight. */\n readonly selectedNodeId = input<string | undefined>(undefined);\n /** Controlled set of expanded node IDs; when undefined the tree manages expansion internally. */\n readonly expandedNodeIds = input<string[] | undefined>(undefined);\n /** When true, rows can be dragged to reorder or reparent nodes. */\n readonly draggable = input(false);\n /** Optional guard called during drag to determine whether a drop at a given position is allowed. */\n readonly canDrop = input<CanDropFn | undefined>(undefined);\n\n // ===== OUTPUTS =====\n /** Fires when the user clicks a node row, emitting the original `TreeNode`. */\n readonly nodeSelect = output<TreeNode>();\n /** Fires when a node's expanded state changes, emitting the node id and new expanded boolean. */\n readonly nodeExpand = output<NodeExpandEvent>();\n /** Fires when the user drops a dragged node onto a target, emitting the drop event. */\n readonly nodeDrop = output<NodeDropEvent>();\n\n // ===== CONTENT CHILDREN =====\n readonly rowTemplate = contentChild(FkNodeTreeRowDirective);\n\n // ===== INTERNAL STATE =====\n private readonly internalExpandedIds = signal<Set<string>>(new Set());\n private readonly dragState = signal<{\n draggedNodeId: string | null;\n dropTargetId: string | null;\n dropPosition: DropPosition | null;\n }>({ draggedNodeId: null, dropTargetId: null, dropPosition: null });\n private autoExpandTimer: ReturnType<typeof setTimeout> | null = null;\n private autoExpandNodeId: string | null = null;\n\n // ===== COMPUTED =====\n readonly childrenMap = computed(() => buildChildrenMap(this.nodes()));\n\n readonly nodeMap = computed(() => {\n const map = new Map<string, TreeNode>();\n\n for (const node of this.nodes()) {\n map.set(node.id, node);\n }\n\n return map;\n });\n\n readonly effectiveExpandedIds = computed(() => {\n const controlled = this.expandedNodeIds();\n\n if (controlled !== undefined) {\n return new Set(controlled);\n }\n\n return this.internalExpandedIds();\n });\n\n readonly visibleNodes = computed(() =>\n flattenTree(this.childrenMap(), this.effectiveExpandedIds()),\n );\n\n readonly draggedNodeId = computed(() => this.dragState().draggedNodeId);\n readonly dropTargetId = computed(() => this.dragState().dropTargetId);\n readonly dropPosition = computed(() => this.dragState().dropPosition);\n\n readonly classes = computed(() =>\n [\n 'fk-node-tree',\n this.draggedNodeId() ? 'fk-node-tree--dragging' : '',\n this.className(),\n ]\n .filter(Boolean)\n .join(' '),\n );\n\n // ===== HOST BINDINGS =====\n\n @HostBinding('attr.role')\n readonly role = 'tree';\n\n @HostBinding('class')\n get hostClass() {\n return this.classes();\n }\n\n // ===== METHODS =====\n\n onNodeSelect(flatNode: FlatNode): void {\n const original = this.nodeMap().get(flatNode.id);\n\n if (original) {\n this.nodeSelect.emit(original);\n }\n }\n\n onNodeToggle(flatNode: FlatNode): void {\n const newExpanded = !flatNode.expanded;\n\n this.nodeExpand.emit({ nodeId: flatNode.id, expanded: newExpanded });\n\n // Only update internal state when uncontrolled\n if (this.expandedNodeIds() === undefined) {\n this.internalExpandedIds.update((prev) => {\n const next = new Set(prev);\n\n if (newExpanded) {\n next.add(flatNode.id);\n } else {\n next.delete(flatNode.id);\n }\n\n return next;\n });\n }\n }\n\n onDragStarted(event: CdkDragStart, flatNode: FlatNode): void {\n this.dragState.set({\n draggedNodeId: flatNode.id,\n dropTargetId: null,\n dropPosition: null,\n });\n }\n\n onDragMoved(event: CdkDragMove): void {\n const result = this.resolveDropTarget(event.pointerPosition.y);\n const currentState = this.dragState();\n\n if (!result) {\n if (currentState.dropTargetId !== null) {\n this.dragState.set({\n draggedNodeId: currentState.draggedNodeId,\n dropTargetId: null,\n dropPosition: null,\n });\n }\n\n this.clearAutoExpand();\n\n return;\n }\n\n const canDropFn = this.canDrop();\n\n if (canDropFn) {\n const draggedNode = this.visibleNodes().find(\n (n) => n.id === currentState.draggedNodeId,\n );\n\n const targetNode = this.visibleNodes().find(\n (n) => n.id === result.nodeId,\n );\n\n if (draggedNode && targetNode) {\n const allowed = canDropFn(draggedNode, targetNode, result.position);\n\n if (!allowed) {\n if (currentState.dropTargetId !== null) {\n this.dragState.set({\n draggedNodeId: currentState.draggedNodeId,\n dropTargetId: null,\n dropPosition: null,\n });\n }\n\n this.clearAutoExpand();\n\n return;\n }\n }\n }\n\n if (\n result.nodeId !== currentState.dropTargetId ||\n result.position !== currentState.dropPosition\n ) {\n this.dragState.set({\n draggedNodeId: currentState.draggedNodeId,\n dropTargetId: result.nodeId,\n dropPosition: result.position,\n });\n }\n\n if (result.position === 'inside') {\n this.startAutoExpand(result.nodeId);\n } else {\n this.clearAutoExpand();\n }\n }\n\n onDragEnded(): void {\n const { draggedNodeId, dropTargetId, dropPosition } = this.dragState();\n\n if (!draggedNodeId || !dropTargetId || !dropPosition) {\n this.resetDragState();\n\n return;\n }\n\n // Prevent self-drop\n if (draggedNodeId === dropTargetId) {\n this.resetDragState();\n\n return;\n }\n\n // Prevent dropping onto descendant\n if (isDescendantOf(dropTargetId, draggedNodeId, this.childrenMap())) {\n this.resetDragState();\n\n return;\n }\n\n const draggedNode = this.nodeMap().get(draggedNodeId);\n const targetNode = this.nodeMap().get(dropTargetId);\n const previousParentId = draggedNode?.parentId ?? null;\n\n let newParentId: string | null;\n\n if (dropPosition === 'inside') {\n newParentId = dropTargetId;\n } else {\n newParentId = targetNode?.parentId ?? null;\n }\n\n this.nodeDrop.emit({\n nodeId: draggedNodeId,\n newParentId,\n previousParentId,\n position: dropPosition,\n referenceNodeId: dropTargetId,\n });\n\n this.resetDragState();\n }\n\n // ===== PRIVATE =====\n\n private resolveDropTarget(\n pointerY: number,\n ): { nodeId: string; position: DropPosition } | null {\n const rows =\n this.elementRef.nativeElement.querySelectorAll('fk-node-tree-row');\n\n const draggedId = this.dragState().draggedNodeId;\n\n for (let i = 0; i < rows.length; i++) {\n const rect = rows[i].getBoundingClientRect();\n\n if (pointerY >= rect.top && pointerY <= rect.bottom) {\n const nodeId = rows[i].getAttribute('data-node-id');\n\n if (!nodeId || nodeId === draggedId) {\n return null;\n }\n\n const relativeY = pointerY - rect.top;\n const height = rect.height;\n\n let position: DropPosition;\n\n if (relativeY < height * 0.25) {\n position = 'before';\n } else if (relativeY > height * 0.75) {\n position = 'after';\n } else {\n position = 'inside';\n }\n\n return { nodeId, position };\n }\n }\n\n return null;\n }\n\n private startAutoExpand(nodeId: string): void {\n if (this.autoExpandTimer && this.autoExpandNodeId === nodeId) {\n return;\n }\n\n this.clearAutoExpand();\n\n const flatNode = this.visibleNodes().find((n) => n.id === nodeId);\n\n if (!flatNode || !flatNode.expandable || flatNode.expanded) {\n return;\n }\n\n this.autoExpandNodeId = nodeId;\n\n this.autoExpandTimer = setTimeout(() => {\n this.onNodeToggle(flatNode);\n this.autoExpandTimer = null;\n this.autoExpandNodeId = null;\n }, 800);\n }\n\n private clearAutoExpand(): void {\n if (this.autoExpandTimer) {\n clearTimeout(this.autoExpandTimer);\n\n this.autoExpandTimer = null;\n }\n\n this.autoExpandNodeId = null;\n }\n\n private resetDragState(): void {\n this.dragState.set({\n draggedNodeId: null,\n dropTargetId: null,\n dropPosition: null,\n });\n\n this.clearAutoExpand();\n }\n}\n","<div\n cdkDropList\n [cdkDropListDisabled]=\"!draggable()\"\n [cdkDropListSortingDisabled]=\"true\"\n [cdkDropListData]=\"visibleNodes()\"\n class=\"fk-node-tree__list\"\n>\n @for (flatNode of visibleNodes(); track flatNode.id) {\n <fk-node-tree-row\n cdkDrag\n [cdkDragDisabled]=\"!draggable() || !flatNode.draggable\"\n [cdkDragData]=\"flatNode\"\n (cdkDragStarted)=\"onDragStarted($event, flatNode)\"\n (cdkDragMoved)=\"onDragMoved($event)\"\n (cdkDragEnded)=\"onDragEnded()\"\n [node]=\"flatNode\"\n [selected]=\"flatNode.id === selectedNodeId()\"\n [dropPosition]=\"flatNode.id === dropTargetId() ? dropPosition() : null\"\n [isDragSource]=\"flatNode.id === draggedNodeId()\"\n [showDragHandle]=\"draggable() && flatNode.draggable\"\n [customTemplate]=\"rowTemplate()?.templateRef\"\n (toggleNode)=\"onNodeToggle(flatNode)\"\n (selectNode)=\"onNodeSelect(flatNode)\"\n >\n <ng-template cdkDragPreview>\n <div class=\"fk-node-tree__drag-preview\">\n @if (flatNode.icon) {\n <fk-icon [name]=\"flatNode.icon\" size=\"sm\" />\n }\n <span>{{ flatNode.label }}</span>\n </div>\n </ng-template>\n\n <ng-template cdkDragPlaceholder>\n <div class=\"fk-node-tree__drag-placeholder\"></div>\n </ng-template>\n </fk-node-tree-row>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}