@sdcorejs/angular 20.1.3 → 20.1.5

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 (168) hide show
  1. package/README.md +19 -14
  2. package/components/audit-diff/index.d.ts +74 -0
  3. package/components/badge/index.d.ts +1 -1
  4. package/components/breadcrumb/index.d.ts +53 -0
  5. package/components/data-state/index.d.ts +44 -0
  6. package/components/document-builder/index.d.ts +5 -5
  7. package/components/form-generic/index.d.ts +67 -104
  8. package/components/import-excel/index.d.ts +4 -14
  9. package/components/index.d.ts +4 -0
  10. package/components/job-progress/index.d.ts +38 -0
  11. package/components/mini-editor/index.d.ts +9 -9
  12. package/components/modal/index.d.ts +7 -1
  13. package/components/preview/index.d.ts +181 -28
  14. package/components/side-drawer/index.d.ts +7 -1
  15. package/components/tab/index.d.ts +9 -2
  16. package/components/table/index.d.ts +8 -7
  17. package/components/tree/index.d.ts +24 -2
  18. package/components/upload-file/index.d.ts +5 -4
  19. package/directives/index.d.ts +10 -8
  20. package/fesm2022/sdcorejs-angular-components-anchor.mjs +14 -14
  21. package/fesm2022/sdcorejs-angular-components-anchor.mjs.map +1 -1
  22. package/fesm2022/sdcorejs-angular-components-audit-diff.mjs +332 -0
  23. package/fesm2022/sdcorejs-angular-components-audit-diff.mjs.map +1 -0
  24. package/fesm2022/sdcorejs-angular-components-badge.mjs +1 -0
  25. package/fesm2022/sdcorejs-angular-components-badge.mjs.map +1 -1
  26. package/fesm2022/sdcorejs-angular-components-breadcrumb.mjs +121 -0
  27. package/fesm2022/sdcorejs-angular-components-breadcrumb.mjs.map +1 -0
  28. package/fesm2022/sdcorejs-angular-components-data-state.mjs +68 -0
  29. package/fesm2022/sdcorejs-angular-components-data-state.mjs.map +1 -0
  30. package/fesm2022/sdcorejs-angular-components-document-builder.mjs +18 -23
  31. package/fesm2022/sdcorejs-angular-components-document-builder.mjs.map +1 -1
  32. package/fesm2022/sdcorejs-angular-components-editor.mjs +6 -4
  33. package/fesm2022/sdcorejs-angular-components-editor.mjs.map +1 -1
  34. package/fesm2022/sdcorejs-angular-components-form-generic.mjs +495 -838
  35. package/fesm2022/sdcorejs-angular-components-form-generic.mjs.map +1 -1
  36. package/fesm2022/sdcorejs-angular-components-import-excel.mjs +24 -34
  37. package/fesm2022/sdcorejs-angular-components-import-excel.mjs.map +1 -1
  38. package/fesm2022/sdcorejs-angular-components-job-progress.mjs +97 -0
  39. package/fesm2022/sdcorejs-angular-components-job-progress.mjs.map +1 -0
  40. package/fesm2022/sdcorejs-angular-components-mini-editor.mjs +10 -20
  41. package/fesm2022/sdcorejs-angular-components-mini-editor.mjs.map +1 -1
  42. package/fesm2022/sdcorejs-angular-components-modal.mjs +61 -4
  43. package/fesm2022/sdcorejs-angular-components-modal.mjs.map +1 -1
  44. package/fesm2022/sdcorejs-angular-components-preview.mjs +1438 -218
  45. package/fesm2022/sdcorejs-angular-components-preview.mjs.map +1 -1
  46. package/fesm2022/sdcorejs-angular-components-query-bar.mjs +4 -4
  47. package/fesm2022/sdcorejs-angular-components-query-bar.mjs.map +1 -1
  48. package/fesm2022/sdcorejs-angular-components-query-builder.mjs +1 -1
  49. package/fesm2022/sdcorejs-angular-components-query-builder.mjs.map +1 -1
  50. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs +39 -2
  51. package/fesm2022/sdcorejs-angular-components-side-drawer.mjs.map +1 -1
  52. package/fesm2022/sdcorejs-angular-components-tab-router.mjs +16 -22
  53. package/fesm2022/sdcorejs-angular-components-tab-router.mjs.map +1 -1
  54. package/fesm2022/sdcorejs-angular-components-tab.mjs +48 -4
  55. package/fesm2022/sdcorejs-angular-components-tab.mjs.map +1 -1
  56. package/fesm2022/sdcorejs-angular-components-table.mjs +96 -63
  57. package/fesm2022/sdcorejs-angular-components-table.mjs.map +1 -1
  58. package/fesm2022/sdcorejs-angular-components-tree.mjs +186 -17
  59. package/fesm2022/sdcorejs-angular-components-tree.mjs.map +1 -1
  60. package/fesm2022/sdcorejs-angular-components-upload-file.mjs +15 -22
  61. package/fesm2022/sdcorejs-angular-components-upload-file.mjs.map +1 -1
  62. package/fesm2022/sdcorejs-angular-components.mjs +4 -0
  63. package/fesm2022/sdcorejs-angular-components.mjs.map +1 -1
  64. package/fesm2022/sdcorejs-angular-directives.mjs +29 -41
  65. package/fesm2022/sdcorejs-angular-directives.mjs.map +1 -1
  66. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs +7 -7
  67. package/fesm2022/sdcorejs-angular-forms-autocomplete.mjs.map +1 -1
  68. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs +20 -83
  69. package/fesm2022/sdcorejs-angular-forms-checkbox.mjs.map +1 -1
  70. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs +6 -3
  71. package/fesm2022/sdcorejs-angular-forms-chip-calendar.mjs.map +1 -1
  72. package/fesm2022/sdcorejs-angular-forms-chip.mjs +6 -3
  73. package/fesm2022/sdcorejs-angular-forms-chip.mjs.map +1 -1
  74. package/fesm2022/sdcorejs-angular-forms-date-range.mjs +16 -13
  75. package/fesm2022/sdcorejs-angular-forms-date-range.mjs.map +1 -1
  76. package/fesm2022/sdcorejs-angular-forms-date.mjs +42 -65
  77. package/fesm2022/sdcorejs-angular-forms-date.mjs.map +1 -1
  78. package/fesm2022/sdcorejs-angular-forms-datetime.mjs +51 -66
  79. package/fesm2022/sdcorejs-angular-forms-datetime.mjs.map +1 -1
  80. package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs +384 -0
  81. package/fesm2022/sdcorejs-angular-forms-entity-picker.mjs.map +1 -0
  82. package/fesm2022/sdcorejs-angular-forms-input-color.mjs +1 -1
  83. package/fesm2022/sdcorejs-angular-forms-input-color.mjs.map +1 -1
  84. package/fesm2022/sdcorejs-angular-forms-input-number.mjs +7 -5
  85. package/fesm2022/sdcorejs-angular-forms-input-number.mjs.map +1 -1
  86. package/fesm2022/sdcorejs-angular-forms-input.mjs +290 -56
  87. package/fesm2022/sdcorejs-angular-forms-input.mjs.map +1 -1
  88. package/fesm2022/sdcorejs-angular-forms-models.mjs +155 -2
  89. package/fesm2022/sdcorejs-angular-forms-models.mjs.map +1 -1
  90. package/fesm2022/sdcorejs-angular-forms-radio.mjs +44 -78
  91. package/fesm2022/sdcorejs-angular-forms-radio.mjs.map +1 -1
  92. package/fesm2022/sdcorejs-angular-forms-select.mjs +6 -20
  93. package/fesm2022/sdcorejs-angular-forms-select.mjs.map +1 -1
  94. package/fesm2022/sdcorejs-angular-forms-switch.mjs +19 -76
  95. package/fesm2022/sdcorejs-angular-forms-switch.mjs.map +1 -1
  96. package/fesm2022/sdcorejs-angular-forms-textarea.mjs +6 -5
  97. package/fesm2022/sdcorejs-angular-forms-textarea.mjs.map +1 -1
  98. package/fesm2022/sdcorejs-angular-forms-time-range.mjs +280 -0
  99. package/fesm2022/sdcorejs-angular-forms-time-range.mjs.map +1 -0
  100. package/fesm2022/sdcorejs-angular-forms-time.mjs +310 -0
  101. package/fesm2022/sdcorejs-angular-forms-time.mjs.map +1 -0
  102. package/fesm2022/sdcorejs-angular-forms-tree-select.mjs +210 -0
  103. package/fesm2022/sdcorejs-angular-forms-tree-select.mjs.map +1 -0
  104. package/fesm2022/sdcorejs-angular-forms.mjs +73 -4
  105. package/fesm2022/sdcorejs-angular-forms.mjs.map +1 -1
  106. package/fesm2022/sdcorejs-angular-i18n.mjs +375 -10
  107. package/fesm2022/sdcorejs-angular-i18n.mjs.map +1 -1
  108. package/fesm2022/sdcorejs-angular-interceptors.mjs +12 -17
  109. package/fesm2022/sdcorejs-angular-interceptors.mjs.map +1 -1
  110. package/fesm2022/sdcorejs-angular-modules-layout.mjs +994 -168
  111. package/fesm2022/sdcorejs-angular-modules-layout.mjs.map +1 -1
  112. package/fesm2022/sdcorejs-angular-pipes.mjs +5 -7
  113. package/fesm2022/sdcorejs-angular-pipes.mjs.map +1 -1
  114. package/fesm2022/sdcorejs-angular-services-api.mjs +407 -137
  115. package/fesm2022/sdcorejs-angular-services-api.mjs.map +1 -1
  116. package/fesm2022/sdcorejs-angular-services-cache.mjs +515 -105
  117. package/fesm2022/sdcorejs-angular-services-cache.mjs.map +1 -1
  118. package/fesm2022/sdcorejs-angular-services-confirm.mjs +5 -7
  119. package/fesm2022/sdcorejs-angular-services-confirm.mjs.map +1 -1
  120. package/fesm2022/sdcorejs-angular-services-docx.mjs +7 -10
  121. package/fesm2022/sdcorejs-angular-services-docx.mjs.map +1 -1
  122. package/fesm2022/sdcorejs-angular-services-loading.mjs +339 -74
  123. package/fesm2022/sdcorejs-angular-services-loading.mjs.map +1 -1
  124. package/fesm2022/sdcorejs-angular-services-notify.mjs +7 -10
  125. package/fesm2022/sdcorejs-angular-services-notify.mjs.map +1 -1
  126. package/fesm2022/sdcorejs-angular-services-persistence.mjs +899 -0
  127. package/fesm2022/sdcorejs-angular-services-persistence.mjs.map +1 -0
  128. package/fesm2022/sdcorejs-angular-services-storage.mjs +324 -122
  129. package/fesm2022/sdcorejs-angular-services-storage.mjs.map +1 -1
  130. package/fesm2022/sdcorejs-angular-services-task.mjs +389 -0
  131. package/fesm2022/sdcorejs-angular-services-task.mjs.map +1 -0
  132. package/fesm2022/sdcorejs-angular-services-unsaved-changes.mjs +255 -0
  133. package/fesm2022/sdcorejs-angular-services-unsaved-changes.mjs.map +1 -0
  134. package/fesm2022/sdcorejs-angular-services-viewport.mjs +76 -0
  135. package/fesm2022/sdcorejs-angular-services-viewport.mjs.map +1 -0
  136. package/fesm2022/sdcorejs-angular-services.mjs +4 -0
  137. package/fesm2022/sdcorejs-angular-services.mjs.map +1 -1
  138. package/forms/autocomplete/index.d.ts +3 -4
  139. package/forms/checkbox/index.d.ts +4 -8
  140. package/forms/date/index.d.ts +2 -2
  141. package/forms/date-range/index.d.ts +6 -7
  142. package/forms/datetime/index.d.ts +2 -2
  143. package/forms/entity-picker/index.d.ts +128 -0
  144. package/forms/index.d.ts +15 -5
  145. package/forms/input/index.d.ts +74 -11
  146. package/forms/input-number/index.d.ts +1 -1
  147. package/forms/models/index.d.ts +86 -3
  148. package/forms/radio/index.d.ts +12 -8
  149. package/forms/switch/index.d.ts +4 -7
  150. package/forms/time/index.d.ts +117 -0
  151. package/forms/time-range/index.d.ts +98 -0
  152. package/forms/tree-select/index.d.ts +76 -0
  153. package/i18n/index.d.ts +72 -2
  154. package/interceptors/index.d.ts +5 -6
  155. package/modules/layout/index.d.ts +354 -17
  156. package/package.json +49 -1
  157. package/pipes/index.d.ts +2 -2
  158. package/services/api/index.d.ts +68 -24
  159. package/services/cache/index.d.ts +52 -16
  160. package/services/confirm/index.d.ts +3 -2
  161. package/services/docx/index.d.ts +2 -3
  162. package/services/index.d.ts +4 -0
  163. package/services/loading/index.d.ts +16 -8
  164. package/services/persistence/index.d.ts +159 -0
  165. package/services/storage/index.d.ts +26 -8
  166. package/services/task/index.d.ts +104 -0
  167. package/services/unsaved-changes/index.d.ts +83 -0
  168. package/services/viewport/index.d.ts +42 -0
@@ -1,7 +1,7 @@
1
1
  import * as i1 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { inject, TemplateRef, Directive, input, booleanAttribute, output, contentChild, computed, signal, effect, isSignal, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
4
+ import { inject, TemplateRef, Directive, ElementRef, input, booleanAttribute, output, contentChild, computed, signal, effect, isSignal, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
5
5
  import * as i2 from '@angular/material/button';
6
6
  import { MatButtonModule } from '@angular/material/button';
7
7
  import * as i3 from '@angular/material/checkbox';
@@ -13,6 +13,7 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
13
13
  import { MatTooltipModule } from '@angular/material/tooltip';
14
14
  import { SdButton } from '@sdcorejs/angular/components/button';
15
15
  import { SdQuickAction } from '@sdcorejs/angular/components/quick-action';
16
+ import { TranslatePipe } from '@sdcorejs/angular/i18n';
16
17
  import { SdIcon } from '@sdcorejs/angular/modules/icon';
17
18
 
18
19
  class SdTreeItemDefDirective {
@@ -34,6 +35,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
34
35
  const DEFAULT_STATIC_TREE = { loadType: 'static' };
35
36
  const EMPTY_TREE_ITEMS = [];
36
37
  class SdTree {
38
+ #host = inject(ElementRef);
37
39
  autoIdInput = input(undefined, ...(ngDevMode ? [{ debugName: "autoIdInput", alias: 'autoId' }] : [{ alias: 'autoId' }]));
38
40
  option = input(undefined, ...(ngDevMode ? [{ debugName: "option" }] : []));
39
41
  /** Migration bridge. New usage should put the data source in `option.items`. */
@@ -49,6 +51,7 @@ class SdTree {
49
51
  selectChange = output();
50
52
  expandChange = output();
51
53
  collapseChange = output();
54
+ loadError = output();
52
55
  itemDef = contentChild((SdTreeItemDefDirective), ...(ngDevMode ? [{ debugName: "itemDef" }] : []));
53
56
  resolvedItemsSource = computed(() => {
54
57
  return this.option()?.items ?? this.items() ?? EMPTY_TREE_ITEMS;
@@ -69,13 +72,19 @@ class SdTree {
69
72
  #expandedState = signal({}, ...(ngDevMode ? [{ debugName: "#expandedState" }] : []));
70
73
  #loadingState = signal({}, ...(ngDevMode ? [{ debugName: "#loadingState" }] : []));
71
74
  #lazyChildren = signal({}, ...(ngDevMode ? [{ debugName: "#lazyChildren" }] : []));
75
+ #lazyErrorState = signal({}, ...(ngDevMode ? [{ debugName: "#lazyErrorState" }] : []));
72
76
  #selectedIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "#selectedIds" }] : []));
73
77
  #filterText = signal('', ...(ngDevMode ? [{ debugName: "#filterText" }] : []));
74
78
  #reloadTick = signal(0, ...(ngDevMode ? [{ debugName: "#reloadTick" }] : []));
79
+ rootLoading = signal(false, ...(ngDevMode ? [{ debugName: "rootLoading" }] : []));
80
+ rootError = signal(null, ...(ngDevMode ? [{ debugName: "rootError" }] : []));
81
+ activeNodeId = signal(null, ...(ngDevMode ? [{ debugName: "activeNodeId" }] : []));
75
82
  #rootLoadId = 0;
76
83
  #lastSource;
77
84
  #lastSourceValue;
78
85
  #lastReloadTick = -1;
86
+ #treeGeneration = 0;
87
+ #lazyLoadIds = new Map();
79
88
  normalizedFilterText = computed(() => normalizeText(this.#filterText()), ...(ngDevMode ? [{ debugName: "normalizedFilterText" }] : []));
80
89
  selectionVisible = computed(() => this.resolvedSelectable() && this.resolvedSelector()?.visible === true, ...(ngDevMode ? [{ debugName: "selectionVisible" }] : []));
81
90
  selectedIdSet = computed(() => {
@@ -136,7 +145,10 @@ class SdTree {
136
145
  const selectedItems = this.selectedItems();
137
146
  const selector = this.resolvedSelector();
138
147
  const commands = this.resolvedCommands();
139
- return this.visibleNodes().map(node => this.#toViewNode(node, selectedIds, selectedItems, selector, commands));
148
+ const nodes = this.visibleNodes();
149
+ const requestedActiveId = this.activeNodeId();
150
+ const activeId = nodes.some(node => node.id === requestedActiveId) ? requestedActiveId : nodes[0]?.id;
151
+ return nodes.map(node => this.#toViewNode(node, selectedIds, selectedItems, selector, commands, node.id === activeId));
140
152
  }, ...(ngDevMode ? [{ debugName: "visibleViewNodes" }] : []));
141
153
  trackByNode = (_index, node) => node.id;
142
154
  constructor() {
@@ -203,7 +215,7 @@ class SdTree {
203
215
  }
204
216
  await this.#ensureLazyChildren(currentNode);
205
217
  const nextNode = this.#findNode(currentNode.id) ?? currentNode;
206
- if (!nextNode.hasChildren)
218
+ if (!nextNode.hasChildren || nextNode.loadError)
207
219
  return;
208
220
  this.#expandedState.update(state => ({ ...state, [currentNode.id]: true }));
209
221
  const toggleEvent = { item: currentNode.data, expanded: true, node: { ...nextNode, isExpanded: true } };
@@ -214,9 +226,19 @@ class SdTree {
214
226
  event?.stopPropagation();
215
227
  if (!this.selectionVisible() || this.isSelectionDisabled(node))
216
228
  return;
229
+ const selector = this.resolvedSelector();
217
230
  const selectedIds = new Set(this.selectedIdSet());
218
- const nextSelected = !selectedIds.has(node.id);
219
- if (nextSelected) {
231
+ const shouldSelect = !selectedIds.has(node.id);
232
+ if (selector?.single) {
233
+ selectedIds.clear();
234
+ if (shouldSelect)
235
+ selectedIds.add(node.id);
236
+ }
237
+ else if (selector?.cascade === 'descendants') {
238
+ this.#setNodeAndDescendants(node, shouldSelect, selectedIds);
239
+ this.#reconcileAncestors(node.parent, selectedIds);
240
+ }
241
+ else if (shouldSelect) {
220
242
  selectedIds.add(node.id);
221
243
  }
222
244
  else {
@@ -226,7 +248,7 @@ class SdTree {
226
248
  const selectedItems = this.#selectedItemsFromIds(selectedIds);
227
249
  this.option()?.onSelectedItemsChange?.(selectedItems);
228
250
  this.selectedItemsChange.emit(selectedItems);
229
- const selectionEvent = { item: node.data, selected: nextSelected, selectedItems };
251
+ const selectionEvent = { item: node.data, selected: selectedIds.has(node.id), selectedItems };
230
252
  this.option()?.onSelect?.(selectionEvent);
231
253
  this.selectChange.emit(selectionEvent);
232
254
  }
@@ -238,6 +260,74 @@ class SdTree {
238
260
  onSelectionAction(action) {
239
261
  action.click(this.selectedItems());
240
262
  }
263
+ retry() {
264
+ this.reload();
265
+ }
266
+ retryNode(node, event) {
267
+ event?.stopPropagation();
268
+ this.#lazyErrorState.update(state => {
269
+ const next = { ...state };
270
+ delete next[node.id];
271
+ return next;
272
+ });
273
+ void this.toggle(node);
274
+ }
275
+ errorMessage(error) {
276
+ return error instanceof Error ? error.message : String(error || 'Unable to load tree data');
277
+ }
278
+ onRowFocus(node) {
279
+ this.activeNodeId.set(node.id);
280
+ }
281
+ onRowKeydown(node, event) {
282
+ if (event.target !== event.currentTarget)
283
+ return;
284
+ const nodes = this.visibleNodes();
285
+ const index = nodes.findIndex(item => item.id === node.id);
286
+ if (index < 0)
287
+ return;
288
+ switch (event.key) {
289
+ case 'ArrowDown':
290
+ event.preventDefault();
291
+ this.#focusVisibleNode(Math.min(nodes.length - 1, index + 1));
292
+ return;
293
+ case 'ArrowUp':
294
+ event.preventDefault();
295
+ this.#focusVisibleNode(Math.max(0, index - 1));
296
+ return;
297
+ case 'Home':
298
+ event.preventDefault();
299
+ this.#focusVisibleNode(0);
300
+ return;
301
+ case 'End':
302
+ event.preventDefault();
303
+ this.#focusVisibleNode(nodes.length - 1);
304
+ return;
305
+ case 'ArrowRight':
306
+ if (!node.hasChildren)
307
+ return;
308
+ event.preventDefault();
309
+ if (!node.isExpanded)
310
+ void this.toggle(node);
311
+ else if (nodes[index + 1]?.parent?.id === node.id)
312
+ this.#focusVisibleNode(index + 1);
313
+ return;
314
+ case 'ArrowLeft':
315
+ if (!node.isExpanded && !node.parent)
316
+ return;
317
+ event.preventDefault();
318
+ if (node.isExpanded)
319
+ void this.toggle(node);
320
+ else
321
+ this.#focusVisibleNode(nodes.findIndex(item => item.id === node.parent?.id));
322
+ return;
323
+ case 'Enter':
324
+ case ' ':
325
+ if (!this.selectionVisible())
326
+ return;
327
+ event.preventDefault();
328
+ this.toggleSelection(node);
329
+ }
330
+ }
241
331
  createContext(node) {
242
332
  return this.#createContext(node, this.isSelected(node));
243
333
  }
@@ -252,13 +342,20 @@ class SdTree {
252
342
  #applySignalSource(source, items, reloadTick) {
253
343
  if (source === this.#lastSource && items === this.#lastSourceValue && reloadTick === this.#lastReloadTick)
254
344
  return;
345
+ // A signal source takes ownership immediately. Any promise started by the
346
+ // previous source must no longer be allowed to replace its current value.
347
+ this.#rootLoadId += 1;
255
348
  this.#lastSource = source;
256
349
  this.#lastSourceValue = items;
257
350
  this.#lastReloadTick = reloadTick;
351
+ this.rootLoading.set(false);
352
+ this.rootError.set(null);
258
353
  this.#setRootItems(items);
259
354
  }
260
355
  #loadRootItems(source) {
261
356
  const loadId = ++this.#rootLoadId;
357
+ this.rootLoading.set(true);
358
+ this.rootError.set(null);
262
359
  try {
263
360
  const result = this.#readItemsSource(source);
264
361
  if (isPromiseLike(result)) {
@@ -268,20 +365,30 @@ class SdTree {
268
365
  this.#setRootItems(items);
269
366
  }
270
367
  })
271
- .catch(() => {
272
- if (loadId === this.#rootLoadId) {
273
- this.#setRootItems([]);
274
- }
368
+ .catch(error => {
369
+ if (loadId !== this.#rootLoadId)
370
+ return;
371
+ this.rootError.set(error);
372
+ this.#setRootItems([]);
373
+ this.loadError.emit({ error });
374
+ })
375
+ .finally(() => {
376
+ if (loadId === this.#rootLoadId)
377
+ this.rootLoading.set(false);
275
378
  });
276
379
  return;
277
380
  }
278
381
  if (loadId === this.#rootLoadId) {
279
382
  this.#setRootItems(result);
383
+ this.rootLoading.set(false);
280
384
  }
281
385
  }
282
- catch {
386
+ catch (error) {
283
387
  if (loadId === this.#rootLoadId) {
388
+ this.rootError.set(error);
284
389
  this.#setRootItems([]);
390
+ this.rootLoading.set(false);
391
+ this.loadError.emit({ error });
285
392
  }
286
393
  }
287
394
  }
@@ -293,11 +400,14 @@ class SdTree {
293
400
  return source;
294
401
  }
295
402
  #setRootItems(items) {
403
+ this.#treeGeneration += 1;
404
+ this.#lazyLoadIds.clear();
296
405
  this.#rootItems.set([...(items ?? [])]);
297
406
  this.#lazyChildren.set({});
298
407
  this.#loadingState.set({});
408
+ this.#lazyErrorState.set({});
299
409
  }
300
- #toViewNode(node, selectedIds, selectedItems, selector, commands) {
410
+ #toViewNode(node, selectedIds, selectedItems, selector, commands, active) {
301
411
  const selected = selectedIds.has(node.id);
302
412
  const selectionDisabled = selector?.disabled ? selector.disabled(node.data, selectedItems) : false;
303
413
  const viewNode = {
@@ -305,12 +415,14 @@ class SdTree {
305
415
  icon: this.#iconOf(node),
306
416
  selected,
307
417
  selectionDisabled,
418
+ selectionIndeterminate: this.#isSelectionIndeterminate(node, selectedIds, selector),
308
419
  toggleDisabled: !node.hasChildren || node.isLoading,
309
- toggleLabel: node.isExpanded ? 'Collapse tree item' : 'Expand tree item',
420
+ toggleLabel: node.loadError ? 'Retry loading tree item' : node.isExpanded ? 'Collapse tree item' : 'Expand tree item',
310
421
  ariaExpanded: node.hasChildren ? node.isExpanded : null,
311
422
  autoIds: this.#nodeAutoIds(node),
312
423
  commands: this.#commandViews(node, commands),
313
424
  context: undefined,
425
+ tabIndex: active ? 0 : -1,
314
426
  };
315
427
  viewNode.context = this.#createContext(viewNode, selected);
316
428
  return viewNode;
@@ -340,10 +452,12 @@ class SdTree {
340
452
  expanded: node.isExpanded,
341
453
  selected,
342
454
  loading: node.isLoading,
455
+ loadError: node.loadError,
343
456
  hasChildren: node.hasChildren,
344
457
  isLeaf: !node.hasChildren,
345
458
  toggle: () => void this.toggle(node),
346
459
  select: () => this.toggleSelection(node),
460
+ retry: () => this.retryNode(node),
347
461
  };
348
462
  }
349
463
  #nodeAutoIds(node) {
@@ -380,6 +494,7 @@ class SdTree {
380
494
  hasChildren,
381
495
  isExpanded,
382
496
  isLoading: this.#loadingState()[item.id] ?? false,
497
+ loadError: this.#lazyErrorState()[item.id],
383
498
  };
384
499
  node.children = this.#buildNodes(rawChildren, level + 1, node);
385
500
  return node;
@@ -424,17 +539,70 @@ class SdTree {
424
539
  const option = this.resolvedTree();
425
540
  if (option.loadType !== 'lazy' || node.children.length > 0 || this.#lazyChildren()[node.id])
426
541
  return;
542
+ const generation = this.#treeGeneration;
543
+ const loadId = (this.#lazyLoadIds.get(node.id) ?? 0) + 1;
544
+ this.#lazyLoadIds.set(node.id, loadId);
427
545
  this.#loadingState.update(state => ({ ...state, [node.id]: true }));
546
+ this.#lazyErrorState.update(state => {
547
+ const next = { ...state };
548
+ delete next[node.id];
549
+ return next;
550
+ });
428
551
  try {
429
552
  const lazyItem = node.treeItem;
430
553
  const children = await Promise.resolve(option.onExpandChildren(lazyItem));
554
+ if (generation !== this.#treeGeneration || this.#lazyLoadIds.get(node.id) !== loadId)
555
+ return;
431
556
  this.#lazyChildren.update(state => ({ ...state, [node.id]: children }));
432
557
  // Do not write `children` onto lazy items; that field belongs to static items only.
433
558
  lazyItem.hasChildren = children.length > 0;
434
559
  }
560
+ catch (error) {
561
+ if (generation !== this.#treeGeneration || this.#lazyLoadIds.get(node.id) !== loadId)
562
+ return;
563
+ this.#lazyErrorState.update(state => ({ ...state, [node.id]: error }));
564
+ this.loadError.emit({ item: node.data, error });
565
+ }
435
566
  finally {
436
- this.#loadingState.update(state => ({ ...state, [node.id]: false }));
567
+ if (generation === this.#treeGeneration && this.#lazyLoadIds.get(node.id) === loadId) {
568
+ this.#loadingState.update(state => ({ ...state, [node.id]: false }));
569
+ }
570
+ }
571
+ }
572
+ #setNodeAndDescendants(node, selected, selectedIds) {
573
+ if (!this.isSelectionDisabled(node)) {
574
+ if (selected)
575
+ selectedIds.add(node.id);
576
+ else
577
+ selectedIds.delete(node.id);
437
578
  }
579
+ node.children.forEach(child => this.#setNodeAndDescendants(child, selected, selectedIds));
580
+ }
581
+ #reconcileAncestors(node, selectedIds) {
582
+ let current = node;
583
+ while (current) {
584
+ const selectableChildren = current.children.filter(child => !this.isSelectionDisabled(child));
585
+ if (selectableChildren.length > 0 && selectableChildren.every(child => selectedIds.has(child.id)))
586
+ selectedIds.add(current.id);
587
+ else
588
+ selectedIds.delete(current.id);
589
+ current = current.parent;
590
+ }
591
+ }
592
+ #isSelectionIndeterminate(node, selectedIds, selector) {
593
+ if (selector?.cascade !== 'descendants' || selectedIds.has(node.id))
594
+ return false;
595
+ return this.#flattenAll(node.children).some(child => selectedIds.has(child.id));
596
+ }
597
+ #focusVisibleNode(index) {
598
+ if (index < 0)
599
+ return;
600
+ const node = this.visibleNodes()[index];
601
+ const row = this.#host.nativeElement.querySelectorAll('[role="treeitem"]')[index];
602
+ if (!node || !row)
603
+ return;
604
+ this.activeNodeId.set(node.id);
605
+ row.focus();
438
606
  }
439
607
  #findNode(id) {
440
608
  return this.#flattenAll(this.rootNodes()).find(node => node.id === id);
@@ -484,7 +652,7 @@ class SdTree {
484
652
  return typeof resolver === 'function' ? resolver(item) : !!resolver;
485
653
  }
486
654
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdTree, deps: [], target: i0.ɵɵFactoryTarget.Component });
487
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdTree, isStandalone: true, selector: "sd-tree", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, option: { classPropertyName: "option", publicName: "option", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, tree: { classPropertyName: "tree", publicName: "tree", isSignal: true, isRequired: false, transformFunction: null }, selectedItemsInput: { classPropertyName: "selectedItemsInput", publicName: "selectedItems", isSignal: true, isRequired: false, transformFunction: null }, commands: { classPropertyName: "commands", publicName: "commands", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, selector: { classPropertyName: "selector", publicName: "selector", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedItemsChange: "selectedItemsChange", selectChange: "selectChange", expandChange: "expandChange", collapseChange: "collapseChange" }, host: { properties: { "attr.data-autoid": "autoId()" } }, queries: [{ propertyName: "itemDef", first: true, predicate: (SdTreeItemDefDirective), descendants: true, isSignal: true }], ngImport: i0, template: "@let _resolvedItemTemplate = resolvedItemTemplate();\n@let _selectionVisible = selectionVisible();\n@let _selectedCount = selectedCount();\n@let _selectionMessage = selectionMessage();\n@let _selectionActionViews = selectionActionViews();\n\n<div class=\"sd-tree\" role=\"tree\" [style.--sd-tree-indent-size]=\"indentSize() + 'px'\">\n @for (node of visibleViewNodes(); track node.id) {\n <div\n class=\"sd-tree__row\"\n role=\"treeitem\"\n [class.sd-tree__row--selected]=\"node.selected\"\n [style.--sd-tree-level]=\"node.level\"\n [attr.aria-expanded]=\"node.ariaExpanded\"\n [attr.aria-selected]=\"_selectionVisible ? node.selected : null\"\n [attr.data-autoid]=\"node.autoIds.row\">\n <div class=\"sd-tree__main\">\n <button\n type=\"button\"\n class=\"sd-tree__toggle\"\n [class.sd-tree__toggle--placeholder]=\"!node.hasChildren\"\n [disabled]=\"node.toggleDisabled\"\n [attr.aria-label]=\"node.toggleLabel\"\n [attr.data-autoid]=\"node.autoIds.toggle\"\n (click)=\"toggle(node, $event)\">\n @if (node.isLoading) {\n <mat-progress-spinner diameter=\"16\" mode=\"indeterminate\" />\n } @else if (node.hasChildren) {\n <sd-icon [name]=\"node.isExpanded ? 'expand_more' : 'chevron_right'\"></sd-icon>\n }\n </button>\n\n @if (_selectionVisible) {\n <mat-checkbox\n class=\"sd-tree__checkbox\"\n [checked]=\"node.selected\"\n [disabled]=\"node.selectionDisabled\"\n [attr.data-autoid]=\"node.autoIds.checkbox\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleSelection(node)\" />\n }\n\n @if (node.icon) {\n <sd-icon class=\"sd-tree__item-icon\" color=\"primary\" [attr.data-autoid]=\"node.autoIds.icon\" [name]=\"node.icon\"></sd-icon>\n }\n\n <div class=\"sd-tree__content\" [class.sd-tree__content--custom]=\"_resolvedItemTemplate\" [attr.data-autoid]=\"node.autoIds.label\">\n @if (_resolvedItemTemplate) {\n <ng-container *ngTemplateOutlet=\"_resolvedItemTemplate; context: node.context\" />\n } @else {\n <span class=\"sd-tree__label\">{{ node.label }}</span>\n }\n </div>\n </div>\n\n @if (node.commands.length) {\n <button\n type=\"button\"\n class=\"sd-tree__command-trigger\"\n mat-icon-button\n [matMenuTriggerFor]=\"commandMenu\"\n [attr.data-autoid]=\"node.autoIds.command\"\n (click)=\"$event.stopPropagation()\">\n <sd-icon class=\"c-icon\" name=\"more_vert\"></sd-icon>\n </button>\n <mat-menu #commandMenu=\"matMenu\" class=\"sd-tree__command-menu\">\n @for (command of node.commands; track command.key) {\n <button\n type=\"button\"\n class=\"sd-tree__command-menu-item\"\n mat-menu-item\n [disabled]=\"command.disabled\"\n [attr.data-autoid]=\"command.autoId\"\n (click)=\"command.command.click(node.data)\">\n <span class=\"sd-tree__command-menu-content\">\n <sd-icon class=\"c-icon sd-tree__command-menu-icon\"\n [class.sd-tree__command-menu-icon--default]=\"command.defaultColor\"\n [color]=\"command.color\"\n [fontSet]=\"command.fontSet\" [name]=\"command.icon\"></sd-icon>\n <span class=\"sd-tree__command-title\">{{ command.title }}</span>\n </span>\n </button>\n }\n </mat-menu>\n }\n </div>\n }\n</div>\n\n<sd-quick-action [opened]=\"_selectedCount > 0\">\n <div class=\"d-flex align-items-center\" sdMessage>\n <div class=\"c-bg-length\">\n <span class=\"c-length sd-tree__qa-count\">{{ _selectedCount }}</span>\n </div>\n <div class=\"c-message\">\n {{ _selectionMessage }}\n </div>\n </div>\n\n <div class=\"d-flex align-items-center mr-8 sd-tree__qa-actions\" sdAction>\n @for (actionView of _selectionActionViews; track $index) {\n <sd-button\n [autoId]=\"actionView.autoId\"\n class=\"ml-4\"\n [tooltip]=\"actionView.action.tooltip\"\n [prefixIcon]=\"actionView.action.icon\"\n [color]=\"actionView.action.color || 'primary'\"\n [type]=\"actionView.action.type || 'light'\"\n [fontSet]=\"actionView.action.fontSet\"\n [title]=\"actionView.action.title\"\n (click)=\"onSelectionAction(actionView.action)\" />\n }\n <sd-button\n [autoId]=\"clearSelectionAutoId()\"\n class=\"ml-4\"\n prefixIcon=\"close\"\n color=\"secondary\"\n type=\"outline\"\n width=\"35px\"\n (click)=\"clearSelection()\" />\n </div>\n</sd-quick-action>\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-primary-contrast{color:var(--sd-primary-contrast)!important}.bg-primary-contrast{background:var(--sd-primary-contrast)!important}.border-primary-contrast{border-color:var(--sd-primary-contrast)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-secondary-contrast{color:var(--sd-secondary-contrast)!important}.bg-secondary-contrast{background:var(--sd-secondary-contrast)!important}.border-secondary-contrast{border-color:var(--sd-secondary-contrast)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-info-contrast{color:var(--sd-info-contrast)!important}.bg-info-contrast{background:var(--sd-info-contrast)!important}.border-info-contrast{border-color:var(--sd-info-contrast)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-success-contrast{color:var(--sd-success-contrast)!important}.bg-success-contrast{background:var(--sd-success-contrast)!important}.border-success-contrast{border-color:var(--sd-success-contrast)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-warning-contrast{color:var(--sd-warning-contrast)!important}.bg-warning-contrast{background:var(--sd-warning-contrast)!important}.border-warning-contrast{border-color:var(--sd-warning-contrast)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-error-contrast{color:var(--sd-error-contrast)!important}.bg-error-contrast{background:var(--sd-error-contrast)!important}.border-error-contrast{border-color:var(--sd-error-contrast)!important}.text-surface{color:var(--sd-surface)!important}.bg-surface{background:var(--sd-surface)!important}.border-surface{border-color:var(--sd-surface)!important}.text-surface-muted{color:var(--sd-surface-muted)!important}.bg-surface-muted{background:var(--sd-surface-muted)!important}.border-surface-muted{border-color:var(--sd-surface-muted)!important}.text-text{color:var(--sd-text)!important}.bg-text{background:var(--sd-text)!important}.border-text{border-color:var(--sd-text)!important}.text-text-secondary{color:var(--sd-text-secondary)!important}.bg-text-secondary{background:var(--sd-text-secondary)!important}.border-text-secondary{border-color:var(--sd-text-secondary)!important}.text-text-muted{color:var(--sd-text-muted)!important}.bg-text-muted{background:var(--sd-text-muted)!important}.border-text-muted{border-color:var(--sd-text-muted)!important}.text-border{color:var(--sd-border)!important}.bg-border{background:var(--sd-border)!important}.border-border{border-color:var(--sd-border)!important}.text-border-strong{color:var(--sd-border-strong)!important}.bg-border-strong{background:var(--sd-border-strong)!important}.border-border-strong{border-color:var(--sd-border-strong)!important}.text-disabled-bg{color:var(--sd-disabled-bg)!important}.bg-disabled-bg{background:var(--sd-disabled-bg)!important}.border-disabled-bg{border-color:var(--sd-disabled-bg)!important}.text-disabled-text{color:var(--sd-disabled-text)!important}.bg-disabled-text{background:var(--sd-disabled-text)!important}.border-disabled-text{border-color:var(--sd-disabled-text)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}.text-secondary{color:var(--sd-text-secondary)!important}.text-muted{color:var(--sd-text-muted)!important}.text-body{color:var(--sd-text)!important}.bg-muted{background:var(--sd-surface-muted)!important}:host{--sd-tree-row-height: 44px;--sd-tree-control-size: 28px;--sd-tree-indent-size: 20px;--sd-tree-selected-bg: color-mix(in srgb, var(--sd-primary, #005cbb) 12%, #ffffff);--sd-tree-hover-bg: rgba(15, 23, 42, .04);--sd-tree-text: #102047;--sd-tree-muted: #5f6f89;display:block}.sd-tree{display:flex;flex-direction:column;width:100%}.sd-tree__row{position:relative;display:flex;align-items:center;min-height:var(--sd-tree-row-height);box-sizing:border-box;padding:6px 4px 6px calc(4px + var(--sd-tree-level) * var(--sd-tree-indent-size));color:var(--sd-tree-text);border-radius:0}.sd-tree__row:hover{background:var(--sd-tree-hover-bg)}.sd-tree__row--selected{background:var(--sd-tree-selected-bg)}.sd-tree__main{display:flex;align-items:center;min-width:0;flex:1 1 auto}.sd-tree__toggle{display:inline-flex;align-items:center;justify-content:center;flex:0 0 var(--sd-tree-control-size);width:var(--sd-tree-control-size);height:var(--sd-tree-control-size);padding:0;color:var(--sd-tree-muted);background:transparent;border:0;border-radius:4px;cursor:pointer}.sd-tree__toggle:disabled{cursor:default}.sd-tree__toggle--placeholder{visibility:hidden}.sd-tree__toggle sd-icon{width:20px;height:20px;font-size:20px;line-height:20px}.sd-tree__checkbox{flex:0 0 auto;height:var(--sd-tree-control-size);margin:0 4px 0 0;transform:scale(.85);transform-origin:center;--mdc-checkbox-selected-checkmark-color: #ffffff;--mdc-checkbox-selected-focus-icon-color: var(--sd-primary, #005cbb);--mdc-checkbox-selected-hover-icon-color: var(--sd-primary, #005cbb);--mdc-checkbox-selected-icon-color: var(--sd-primary, #005cbb);--mdc-checkbox-selected-pressed-icon-color: var(--sd-primary, #005cbb)}.sd-tree__item-icon{flex:0 0 auto;width:20px;height:20px;margin:0 8px 0 0;font-size:20px;line-height:20px}.sd-tree__content{display:-webkit-box;min-width:0;min-height:var(--sd-tree-control-size);padding:4px 0;overflow:hidden;overflow-wrap:anywhere;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-height:20px}.sd-tree__content--custom{display:block;max-height:none;-webkit-line-clamp:unset}.sd-tree__label{font-size:14px;font-weight:500}.sd-tree__command-trigger{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;align-self:center;width:24px;height:24px;padding:0;margin-left:8px;line-height:24px;opacity:0;transition:opacity .12s ease}.sd-tree__row:hover .sd-tree__command-trigger,.sd-tree__command-trigger[aria-expanded=true]{opacity:1}.sd-tree__command-trigger sd-icon.c-icon,.sd-tree__command-menu-icon{width:16px;height:16px;font-size:16px;line-height:16px}.sd-tree__command-trigger sd-icon.c-icon,.sd-tree__command-menu-icon--default{color:var(--sd-text-secondary)!important}::ng-deep .mat-mdc-menu-panel.sd-tree__command-menu .mat-mdc-menu-item.sd-tree__command-menu-item,::ng-deep .mat-menu-panel.sd-tree__command-menu .mat-menu-item.sd-tree__command-menu-item{min-height:40px;padding:0 12px}::ng-deep .mat-mdc-menu-panel.sd-tree__command-menu .mat-mdc-menu-item.sd-tree__command-menu-item .mat-mdc-menu-item-text,::ng-deep .mat-mdc-menu-panel.sd-tree__command-menu .mat-mdc-menu-item.sd-tree__command-menu-item .mdc-list-item__primary-text,::ng-deep .mat-menu-panel.sd-tree__command-menu .mat-menu-item.sd-tree__command-menu-item{width:100%;min-width:0}.sd-tree__command-menu-content{display:flex;align-items:center;gap:6px;width:100%;min-width:0;line-height:20px}.sd-tree__command-menu-icon{display:flex;align-items:center;justify-content:center;flex:0 0 16px;margin:0!important;padding:0;text-align:center;overflow:hidden}.sd-tree__command-title{display:block;min-width:0;line-height:20px}.c-bg-length{display:flex;flex-direction:column;align-items:flex-start;position:static;width:auto;min-width:48px;height:48px;padding:12px 8px;background:var(--sd-primary);border-radius:4px 0 0 4px}.c-bg-length .c-length{position:static;width:auto;min-width:32px;height:24px;color:#fff;font-family:Roboto,sans-serif;font-size:16px;font-style:normal;font-weight:500;line-height:24px;text-align:center}.c-message{position:static;min-width:200px;height:20px;margin:0 0 0 8px;color:#000;font-family:Roboto,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:20px}.sd-tree__qa-actions{align-items:center;gap:4px;margin-right:8px}\n"], dependencies: [{ kind: "component", type: SdIcon, selector: "sd-icon", inputs: ["name", "fontIcon", "color", "set", "fontSet", "size", "strokeWidth", "absoluteStrokeWidth", "ariaLabel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i3.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i5.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: SdQuickAction, selector: "sd-quick-action", inputs: ["opened"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
655
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdTree, isStandalone: true, selector: "sd-tree", inputs: { autoIdInput: { classPropertyName: "autoIdInput", publicName: "autoId", isSignal: true, isRequired: false, transformFunction: null }, option: { classPropertyName: "option", publicName: "option", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, tree: { classPropertyName: "tree", publicName: "tree", isSignal: true, isRequired: false, transformFunction: null }, selectedItemsInput: { classPropertyName: "selectedItemsInput", publicName: "selectedItems", isSignal: true, isRequired: false, transformFunction: null }, commands: { classPropertyName: "commands", publicName: "commands", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, selector: { classPropertyName: "selector", publicName: "selector", isSignal: true, isRequired: false, transformFunction: null }, itemTemplate: { classPropertyName: "itemTemplate", publicName: "itemTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedItemsChange: "selectedItemsChange", selectChange: "selectChange", expandChange: "expandChange", collapseChange: "collapseChange", loadError: "loadError" }, host: { properties: { "attr.data-autoid": "autoId()" } }, queries: [{ propertyName: "itemDef", first: true, predicate: (SdTreeItemDefDirective), descendants: true, isSignal: true }], ngImport: i0, template: "@let _resolvedItemTemplate = resolvedItemTemplate();\n@let _selectionVisible = selectionVisible();\n@let _selectedCount = selectedCount();\n@let _selectionMessage = selectionMessage();\n@let _selectionActionViews = selectionActionViews();\n@let _rootError = rootError();\n\n@if (rootLoading()) {\n <div class=\"sd-tree__root-loading\" role=\"status\" aria-live=\"polite\">\n <mat-progress-spinner diameter=\"24\" mode=\"indeterminate\" />\n </div>\n} @else if (_rootError) {\n <div class=\"sd-tree__root-error\" role=\"alert\">\n <span>{{ errorMessage(_rootError) }}</span>\n <button type=\"button\" data-tree-retry (click)=\"retry()\">{{ 'core.component.tree.retry' | translate }}</button>\n </div>\n} @else {\n <div class=\"sd-tree\" role=\"tree\" [attr.aria-busy]=\"rootLoading()\" [style.--sd-tree-indent-size]=\"indentSize() + 'px'\">\n @for (node of visibleViewNodes(); track node.id) {\n <div\n class=\"sd-tree__row\"\n role=\"treeitem\"\n [tabIndex]=\"node.tabIndex\"\n [class.sd-tree__row--selected]=\"node.selected\"\n [style.--sd-tree-level]=\"node.level\"\n [attr.aria-level]=\"node.level + 1\"\n [attr.aria-expanded]=\"node.ariaExpanded\"\n [attr.aria-selected]=\"_selectionVisible ? node.selected : null\"\n [attr.aria-checked]=\"_selectionVisible ? (node.selectionIndeterminate ? 'mixed' : node.selected) : null\"\n [attr.data-autoid]=\"node.autoIds.row\"\n (focus)=\"onRowFocus(node)\"\n (keydown)=\"onRowKeydown(node, $event)\">\n <div class=\"sd-tree__main\">\n <button\n type=\"button\"\n class=\"sd-tree__toggle\"\n [class.sd-tree__toggle--placeholder]=\"!node.hasChildren\"\n [disabled]=\"node.toggleDisabled\"\n [attr.aria-label]=\"node.toggleLabel\"\n [attr.data-autoid]=\"node.autoIds.toggle\"\n [attr.data-tree-node-retry]=\"node.loadError ? node.id : null\"\n (click)=\"toggle(node, $event)\">\n @if (node.isLoading) {\n <mat-progress-spinner diameter=\"16\" mode=\"indeterminate\" />\n } @else if (node.loadError) {\n <sd-icon name=\"refresh\"></sd-icon>\n } @else if (node.hasChildren) {\n <sd-icon [name]=\"node.isExpanded ? 'expand_more' : 'chevron_right'\"></sd-icon>\n }\n </button>\n\n @if (_selectionVisible) {\n <mat-checkbox\n class=\"sd-tree__checkbox\"\n [checked]=\"node.selected\"\n [indeterminate]=\"node.selectionIndeterminate\"\n [disabled]=\"node.selectionDisabled\"\n [attr.data-autoid]=\"node.autoIds.checkbox\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleSelection(node)\" />\n }\n\n @if (node.icon) {\n <sd-icon class=\"sd-tree__item-icon\" color=\"primary\" [attr.data-autoid]=\"node.autoIds.icon\" [name]=\"node.icon\"></sd-icon>\n }\n\n <div class=\"sd-tree__content\" [class.sd-tree__content--custom]=\"_resolvedItemTemplate\" [attr.data-autoid]=\"node.autoIds.label\">\n @if (_resolvedItemTemplate) {\n <ng-container *ngTemplateOutlet=\"_resolvedItemTemplate; context: node.context\" />\n } @else {\n <span class=\"sd-tree__label\">{{ node.label }}</span>\n }\n </div>\n </div>\n\n @if (node.commands.length) {\n <button\n type=\"button\"\n class=\"sd-tree__command-trigger\"\n mat-icon-button\n [matMenuTriggerFor]=\"commandMenu\"\n [attr.data-autoid]=\"node.autoIds.command\"\n (click)=\"$event.stopPropagation()\">\n <sd-icon class=\"c-icon\" name=\"more_vert\"></sd-icon>\n </button>\n <mat-menu #commandMenu=\"matMenu\" class=\"sd-tree__command-menu\">\n @for (command of node.commands; track command.key) {\n <button\n type=\"button\"\n class=\"sd-tree__command-menu-item\"\n mat-menu-item\n [disabled]=\"command.disabled\"\n [attr.data-autoid]=\"command.autoId\"\n (click)=\"command.command.click(node.data)\">\n <span class=\"sd-tree__command-menu-content\">\n <sd-icon\n class=\"c-icon sd-tree__command-menu-icon\"\n [class.sd-tree__command-menu-icon--default]=\"command.defaultColor\"\n [color]=\"command.color\"\n [fontSet]=\"command.fontSet\"\n [name]=\"command.icon\"></sd-icon>\n <span class=\"sd-tree__command-title\">{{ command.title }}</span>\n </span>\n </button>\n }\n </mat-menu>\n }\n </div>\n }\n </div>\n}\n\n<sd-quick-action [opened]=\"_selectedCount > 0\">\n <div class=\"d-flex align-items-center\" sdMessage>\n <div class=\"c-bg-length\">\n <span class=\"c-length sd-tree__qa-count\">{{ _selectedCount }}</span>\n </div>\n <div class=\"c-message\">\n {{ _selectionMessage }}\n </div>\n </div>\n\n <div class=\"d-flex align-items-center mr-8 sd-tree__qa-actions\" sdAction>\n @for (actionView of _selectionActionViews; track $index) {\n <sd-button\n [autoId]=\"actionView.autoId\"\n class=\"ml-4\"\n [tooltip]=\"actionView.action.tooltip\"\n [prefixIcon]=\"actionView.action.icon\"\n [color]=\"actionView.action.color || 'primary'\"\n [type]=\"actionView.action.type || 'light'\"\n [fontSet]=\"actionView.action.fontSet\"\n [title]=\"actionView.action.title\"\n (click)=\"onSelectionAction(actionView.action)\" />\n }\n <sd-button\n [autoId]=\"clearSelectionAutoId()\"\n class=\"ml-4\"\n prefixIcon=\"close\"\n color=\"secondary\"\n type=\"outline\"\n width=\"35px\"\n (click)=\"clearSelection()\" />\n </div>\n</sd-quick-action>\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-primary-contrast{color:var(--sd-primary-contrast)!important}.bg-primary-contrast{background:var(--sd-primary-contrast)!important}.border-primary-contrast{border-color:var(--sd-primary-contrast)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-secondary-contrast{color:var(--sd-secondary-contrast)!important}.bg-secondary-contrast{background:var(--sd-secondary-contrast)!important}.border-secondary-contrast{border-color:var(--sd-secondary-contrast)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-info-contrast{color:var(--sd-info-contrast)!important}.bg-info-contrast{background:var(--sd-info-contrast)!important}.border-info-contrast{border-color:var(--sd-info-contrast)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-success-contrast{color:var(--sd-success-contrast)!important}.bg-success-contrast{background:var(--sd-success-contrast)!important}.border-success-contrast{border-color:var(--sd-success-contrast)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-warning-contrast{color:var(--sd-warning-contrast)!important}.bg-warning-contrast{background:var(--sd-warning-contrast)!important}.border-warning-contrast{border-color:var(--sd-warning-contrast)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-error-contrast{color:var(--sd-error-contrast)!important}.bg-error-contrast{background:var(--sd-error-contrast)!important}.border-error-contrast{border-color:var(--sd-error-contrast)!important}.text-surface{color:var(--sd-surface)!important}.bg-surface{background:var(--sd-surface)!important}.border-surface{border-color:var(--sd-surface)!important}.text-surface-muted{color:var(--sd-surface-muted)!important}.bg-surface-muted{background:var(--sd-surface-muted)!important}.border-surface-muted{border-color:var(--sd-surface-muted)!important}.text-text{color:var(--sd-text)!important}.bg-text{background:var(--sd-text)!important}.border-text{border-color:var(--sd-text)!important}.text-text-secondary{color:var(--sd-text-secondary)!important}.bg-text-secondary{background:var(--sd-text-secondary)!important}.border-text-secondary{border-color:var(--sd-text-secondary)!important}.text-text-muted{color:var(--sd-text-muted)!important}.bg-text-muted{background:var(--sd-text-muted)!important}.border-text-muted{border-color:var(--sd-text-muted)!important}.text-border{color:var(--sd-border)!important}.bg-border{background:var(--sd-border)!important}.border-border{border-color:var(--sd-border)!important}.text-border-strong{color:var(--sd-border-strong)!important}.bg-border-strong{background:var(--sd-border-strong)!important}.border-border-strong{border-color:var(--sd-border-strong)!important}.text-disabled-bg{color:var(--sd-disabled-bg)!important}.bg-disabled-bg{background:var(--sd-disabled-bg)!important}.border-disabled-bg{border-color:var(--sd-disabled-bg)!important}.text-disabled-text{color:var(--sd-disabled-text)!important}.bg-disabled-text{background:var(--sd-disabled-text)!important}.border-disabled-text{border-color:var(--sd-disabled-text)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}.text-secondary{color:var(--sd-text-secondary)!important}.text-muted{color:var(--sd-text-muted)!important}.text-body{color:var(--sd-text)!important}.bg-muted{background:var(--sd-surface-muted)!important}:host{--sd-tree-row-height: 44px;--sd-tree-control-size: 28px;--sd-tree-indent-size: 20px;--sd-tree-selected-bg: color-mix(in srgb, var(--sd-primary, #005cbb) 12%, #ffffff);--sd-tree-hover-bg: rgba(15, 23, 42, .04);--sd-tree-text: #102047;--sd-tree-muted: #5f6f89;display:block}.sd-tree{display:flex;flex-direction:column;width:100%}.sd-tree__row{position:relative;display:flex;align-items:center;min-height:var(--sd-tree-row-height);box-sizing:border-box;padding:6px 4px 6px calc(4px + var(--sd-tree-level) * var(--sd-tree-indent-size));color:var(--sd-tree-text);border-radius:0}.sd-tree__row:hover{background:var(--sd-tree-hover-bg)}.sd-tree__row:focus-visible{z-index:1;outline:2px solid var(--sd-primary, #005cbb);outline-offset:-2px}.sd-tree__row--selected{background:var(--sd-tree-selected-bg)}.sd-tree__main{display:flex;align-items:center;min-width:0;flex:1 1 auto}.sd-tree__toggle{display:inline-flex;align-items:center;justify-content:center;flex:0 0 var(--sd-tree-control-size);width:var(--sd-tree-control-size);height:var(--sd-tree-control-size);padding:0;color:var(--sd-tree-muted);background:transparent;border:0;border-radius:4px;cursor:pointer}.sd-tree__toggle:disabled{cursor:default}.sd-tree__toggle--placeholder{visibility:hidden}.sd-tree__toggle sd-icon{width:20px;height:20px;font-size:20px;line-height:20px}.sd-tree__checkbox{flex:0 0 auto;height:var(--sd-tree-control-size);margin:0 4px 0 0;transform:scale(.85);transform-origin:center;--mdc-checkbox-selected-checkmark-color: #ffffff;--mdc-checkbox-selected-focus-icon-color: var(--sd-primary, #005cbb);--mdc-checkbox-selected-hover-icon-color: var(--sd-primary, #005cbb);--mdc-checkbox-selected-icon-color: var(--sd-primary, #005cbb);--mdc-checkbox-selected-pressed-icon-color: var(--sd-primary, #005cbb)}.sd-tree__item-icon{flex:0 0 auto;width:20px;height:20px;margin:0 8px 0 0;font-size:20px;line-height:20px}.sd-tree__content{display:-webkit-box;min-width:0;min-height:var(--sd-tree-control-size);padding:4px 0;overflow:hidden;overflow-wrap:anywhere;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-height:20px}.sd-tree__content--custom{display:block;max-height:none;-webkit-line-clamp:unset}.sd-tree__label{font-size:14px;font-weight:500}.sd-tree__command-trigger{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;align-self:center;width:24px;height:24px;padding:0;margin-left:8px;line-height:24px;opacity:0;transition:opacity .12s ease}.sd-tree__row:hover .sd-tree__command-trigger,.sd-tree__command-trigger[aria-expanded=true]{opacity:1}.sd-tree__command-trigger sd-icon.c-icon,.sd-tree__command-menu-icon{width:16px;height:16px;font-size:16px;line-height:16px}.sd-tree__command-trigger sd-icon.c-icon,.sd-tree__command-menu-icon--default{color:var(--sd-text-secondary)!important}::ng-deep .mat-mdc-menu-panel.sd-tree__command-menu .mat-mdc-menu-item.sd-tree__command-menu-item,::ng-deep .mat-menu-panel.sd-tree__command-menu .mat-menu-item.sd-tree__command-menu-item{min-height:40px;padding:0 12px}::ng-deep .mat-mdc-menu-panel.sd-tree__command-menu .mat-mdc-menu-item.sd-tree__command-menu-item .mat-mdc-menu-item-text,::ng-deep .mat-mdc-menu-panel.sd-tree__command-menu .mat-mdc-menu-item.sd-tree__command-menu-item .mdc-list-item__primary-text,::ng-deep .mat-menu-panel.sd-tree__command-menu .mat-menu-item.sd-tree__command-menu-item{width:100%;min-width:0}.sd-tree__command-menu-content{display:flex;align-items:center;gap:6px;width:100%;min-width:0;line-height:20px}.sd-tree__command-menu-icon{display:flex;align-items:center;justify-content:center;flex:0 0 16px;margin:0!important;padding:0;text-align:center;overflow:hidden}.sd-tree__command-title{display:block;min-width:0;line-height:20px}.c-bg-length{display:flex;flex-direction:column;align-items:flex-start;position:static;width:auto;min-width:48px;height:48px;padding:12px 8px;background:var(--sd-primary);border-radius:4px 0 0 4px}.c-bg-length .c-length{position:static;width:auto;min-width:32px;height:24px;color:#fff;font-family:Roboto,sans-serif;font-size:16px;font-style:normal;font-weight:500;line-height:24px;text-align:center}.c-message{position:static;min-width:200px;height:20px;margin:0 0 0 8px;color:#000;font-family:Roboto,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:20px}.sd-tree__qa-actions{align-items:center;gap:4px;margin-right:8px}.sd-tree__root-loading,.sd-tree__root-error{display:flex;align-items:center;justify-content:center;gap:8px;min-height:120px;padding:16px}.sd-tree__root-error{flex-direction:column;color:var(--sd-error, #d92d20)}.sd-tree__root-error button{min-height:36px;padding:6px 12px;border:1px solid currentcolor;border-radius:6px;background:transparent;color:inherit;font:inherit;cursor:pointer}\n"], dependencies: [{ kind: "component", type: SdIcon, selector: "sd-icon", inputs: ["name", "fontIcon", "color", "set", "fontSet", "size", "strokeWidth", "absoluteStrokeWidth", "ariaLabel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i3.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i4.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i5.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "component", type: SdButton, selector: "sd-button", inputs: ["autoId", "type", "color", "size", "fontSet", "title", "width", "tooltip", "prefixIcon", "suffixIcon", "disabled", "loading", "block", "htmlType"], outputs: ["click"] }, { kind: "component", type: SdQuickAction, selector: "sd-quick-action", inputs: ["opened"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
488
656
  }
489
657
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdTree, decorators: [{
490
658
  type: Component,
@@ -498,10 +666,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
498
666
  MatTooltipModule,
499
667
  SdButton,
500
668
  SdQuickAction,
669
+ TranslatePipe,
501
670
  ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
502
671
  '[attr.data-autoid]': 'autoId()',
503
- }, template: "@let _resolvedItemTemplate = resolvedItemTemplate();\n@let _selectionVisible = selectionVisible();\n@let _selectedCount = selectedCount();\n@let _selectionMessage = selectionMessage();\n@let _selectionActionViews = selectionActionViews();\n\n<div class=\"sd-tree\" role=\"tree\" [style.--sd-tree-indent-size]=\"indentSize() + 'px'\">\n @for (node of visibleViewNodes(); track node.id) {\n <div\n class=\"sd-tree__row\"\n role=\"treeitem\"\n [class.sd-tree__row--selected]=\"node.selected\"\n [style.--sd-tree-level]=\"node.level\"\n [attr.aria-expanded]=\"node.ariaExpanded\"\n [attr.aria-selected]=\"_selectionVisible ? node.selected : null\"\n [attr.data-autoid]=\"node.autoIds.row\">\n <div class=\"sd-tree__main\">\n <button\n type=\"button\"\n class=\"sd-tree__toggle\"\n [class.sd-tree__toggle--placeholder]=\"!node.hasChildren\"\n [disabled]=\"node.toggleDisabled\"\n [attr.aria-label]=\"node.toggleLabel\"\n [attr.data-autoid]=\"node.autoIds.toggle\"\n (click)=\"toggle(node, $event)\">\n @if (node.isLoading) {\n <mat-progress-spinner diameter=\"16\" mode=\"indeterminate\" />\n } @else if (node.hasChildren) {\n <sd-icon [name]=\"node.isExpanded ? 'expand_more' : 'chevron_right'\"></sd-icon>\n }\n </button>\n\n @if (_selectionVisible) {\n <mat-checkbox\n class=\"sd-tree__checkbox\"\n [checked]=\"node.selected\"\n [disabled]=\"node.selectionDisabled\"\n [attr.data-autoid]=\"node.autoIds.checkbox\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleSelection(node)\" />\n }\n\n @if (node.icon) {\n <sd-icon class=\"sd-tree__item-icon\" color=\"primary\" [attr.data-autoid]=\"node.autoIds.icon\" [name]=\"node.icon\"></sd-icon>\n }\n\n <div class=\"sd-tree__content\" [class.sd-tree__content--custom]=\"_resolvedItemTemplate\" [attr.data-autoid]=\"node.autoIds.label\">\n @if (_resolvedItemTemplate) {\n <ng-container *ngTemplateOutlet=\"_resolvedItemTemplate; context: node.context\" />\n } @else {\n <span class=\"sd-tree__label\">{{ node.label }}</span>\n }\n </div>\n </div>\n\n @if (node.commands.length) {\n <button\n type=\"button\"\n class=\"sd-tree__command-trigger\"\n mat-icon-button\n [matMenuTriggerFor]=\"commandMenu\"\n [attr.data-autoid]=\"node.autoIds.command\"\n (click)=\"$event.stopPropagation()\">\n <sd-icon class=\"c-icon\" name=\"more_vert\"></sd-icon>\n </button>\n <mat-menu #commandMenu=\"matMenu\" class=\"sd-tree__command-menu\">\n @for (command of node.commands; track command.key) {\n <button\n type=\"button\"\n class=\"sd-tree__command-menu-item\"\n mat-menu-item\n [disabled]=\"command.disabled\"\n [attr.data-autoid]=\"command.autoId\"\n (click)=\"command.command.click(node.data)\">\n <span class=\"sd-tree__command-menu-content\">\n <sd-icon class=\"c-icon sd-tree__command-menu-icon\"\n [class.sd-tree__command-menu-icon--default]=\"command.defaultColor\"\n [color]=\"command.color\"\n [fontSet]=\"command.fontSet\" [name]=\"command.icon\"></sd-icon>\n <span class=\"sd-tree__command-title\">{{ command.title }}</span>\n </span>\n </button>\n }\n </mat-menu>\n }\n </div>\n }\n</div>\n\n<sd-quick-action [opened]=\"_selectedCount > 0\">\n <div class=\"d-flex align-items-center\" sdMessage>\n <div class=\"c-bg-length\">\n <span class=\"c-length sd-tree__qa-count\">{{ _selectedCount }}</span>\n </div>\n <div class=\"c-message\">\n {{ _selectionMessage }}\n </div>\n </div>\n\n <div class=\"d-flex align-items-center mr-8 sd-tree__qa-actions\" sdAction>\n @for (actionView of _selectionActionViews; track $index) {\n <sd-button\n [autoId]=\"actionView.autoId\"\n class=\"ml-4\"\n [tooltip]=\"actionView.action.tooltip\"\n [prefixIcon]=\"actionView.action.icon\"\n [color]=\"actionView.action.color || 'primary'\"\n [type]=\"actionView.action.type || 'light'\"\n [fontSet]=\"actionView.action.fontSet\"\n [title]=\"actionView.action.title\"\n (click)=\"onSelectionAction(actionView.action)\" />\n }\n <sd-button\n [autoId]=\"clearSelectionAutoId()\"\n class=\"ml-4\"\n prefixIcon=\"close\"\n color=\"secondary\"\n type=\"outline\"\n width=\"35px\"\n (click)=\"clearSelection()\" />\n </div>\n</sd-quick-action>\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-primary-contrast{color:var(--sd-primary-contrast)!important}.bg-primary-contrast{background:var(--sd-primary-contrast)!important}.border-primary-contrast{border-color:var(--sd-primary-contrast)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-secondary-contrast{color:var(--sd-secondary-contrast)!important}.bg-secondary-contrast{background:var(--sd-secondary-contrast)!important}.border-secondary-contrast{border-color:var(--sd-secondary-contrast)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-info-contrast{color:var(--sd-info-contrast)!important}.bg-info-contrast{background:var(--sd-info-contrast)!important}.border-info-contrast{border-color:var(--sd-info-contrast)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-success-contrast{color:var(--sd-success-contrast)!important}.bg-success-contrast{background:var(--sd-success-contrast)!important}.border-success-contrast{border-color:var(--sd-success-contrast)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-warning-contrast{color:var(--sd-warning-contrast)!important}.bg-warning-contrast{background:var(--sd-warning-contrast)!important}.border-warning-contrast{border-color:var(--sd-warning-contrast)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-error-contrast{color:var(--sd-error-contrast)!important}.bg-error-contrast{background:var(--sd-error-contrast)!important}.border-error-contrast{border-color:var(--sd-error-contrast)!important}.text-surface{color:var(--sd-surface)!important}.bg-surface{background:var(--sd-surface)!important}.border-surface{border-color:var(--sd-surface)!important}.text-surface-muted{color:var(--sd-surface-muted)!important}.bg-surface-muted{background:var(--sd-surface-muted)!important}.border-surface-muted{border-color:var(--sd-surface-muted)!important}.text-text{color:var(--sd-text)!important}.bg-text{background:var(--sd-text)!important}.border-text{border-color:var(--sd-text)!important}.text-text-secondary{color:var(--sd-text-secondary)!important}.bg-text-secondary{background:var(--sd-text-secondary)!important}.border-text-secondary{border-color:var(--sd-text-secondary)!important}.text-text-muted{color:var(--sd-text-muted)!important}.bg-text-muted{background:var(--sd-text-muted)!important}.border-text-muted{border-color:var(--sd-text-muted)!important}.text-border{color:var(--sd-border)!important}.bg-border{background:var(--sd-border)!important}.border-border{border-color:var(--sd-border)!important}.text-border-strong{color:var(--sd-border-strong)!important}.bg-border-strong{background:var(--sd-border-strong)!important}.border-border-strong{border-color:var(--sd-border-strong)!important}.text-disabled-bg{color:var(--sd-disabled-bg)!important}.bg-disabled-bg{background:var(--sd-disabled-bg)!important}.border-disabled-bg{border-color:var(--sd-disabled-bg)!important}.text-disabled-text{color:var(--sd-disabled-text)!important}.bg-disabled-text{background:var(--sd-disabled-text)!important}.border-disabled-text{border-color:var(--sd-disabled-text)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}.text-secondary{color:var(--sd-text-secondary)!important}.text-muted{color:var(--sd-text-muted)!important}.text-body{color:var(--sd-text)!important}.bg-muted{background:var(--sd-surface-muted)!important}:host{--sd-tree-row-height: 44px;--sd-tree-control-size: 28px;--sd-tree-indent-size: 20px;--sd-tree-selected-bg: color-mix(in srgb, var(--sd-primary, #005cbb) 12%, #ffffff);--sd-tree-hover-bg: rgba(15, 23, 42, .04);--sd-tree-text: #102047;--sd-tree-muted: #5f6f89;display:block}.sd-tree{display:flex;flex-direction:column;width:100%}.sd-tree__row{position:relative;display:flex;align-items:center;min-height:var(--sd-tree-row-height);box-sizing:border-box;padding:6px 4px 6px calc(4px + var(--sd-tree-level) * var(--sd-tree-indent-size));color:var(--sd-tree-text);border-radius:0}.sd-tree__row:hover{background:var(--sd-tree-hover-bg)}.sd-tree__row--selected{background:var(--sd-tree-selected-bg)}.sd-tree__main{display:flex;align-items:center;min-width:0;flex:1 1 auto}.sd-tree__toggle{display:inline-flex;align-items:center;justify-content:center;flex:0 0 var(--sd-tree-control-size);width:var(--sd-tree-control-size);height:var(--sd-tree-control-size);padding:0;color:var(--sd-tree-muted);background:transparent;border:0;border-radius:4px;cursor:pointer}.sd-tree__toggle:disabled{cursor:default}.sd-tree__toggle--placeholder{visibility:hidden}.sd-tree__toggle sd-icon{width:20px;height:20px;font-size:20px;line-height:20px}.sd-tree__checkbox{flex:0 0 auto;height:var(--sd-tree-control-size);margin:0 4px 0 0;transform:scale(.85);transform-origin:center;--mdc-checkbox-selected-checkmark-color: #ffffff;--mdc-checkbox-selected-focus-icon-color: var(--sd-primary, #005cbb);--mdc-checkbox-selected-hover-icon-color: var(--sd-primary, #005cbb);--mdc-checkbox-selected-icon-color: var(--sd-primary, #005cbb);--mdc-checkbox-selected-pressed-icon-color: var(--sd-primary, #005cbb)}.sd-tree__item-icon{flex:0 0 auto;width:20px;height:20px;margin:0 8px 0 0;font-size:20px;line-height:20px}.sd-tree__content{display:-webkit-box;min-width:0;min-height:var(--sd-tree-control-size);padding:4px 0;overflow:hidden;overflow-wrap:anywhere;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-height:20px}.sd-tree__content--custom{display:block;max-height:none;-webkit-line-clamp:unset}.sd-tree__label{font-size:14px;font-weight:500}.sd-tree__command-trigger{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;align-self:center;width:24px;height:24px;padding:0;margin-left:8px;line-height:24px;opacity:0;transition:opacity .12s ease}.sd-tree__row:hover .sd-tree__command-trigger,.sd-tree__command-trigger[aria-expanded=true]{opacity:1}.sd-tree__command-trigger sd-icon.c-icon,.sd-tree__command-menu-icon{width:16px;height:16px;font-size:16px;line-height:16px}.sd-tree__command-trigger sd-icon.c-icon,.sd-tree__command-menu-icon--default{color:var(--sd-text-secondary)!important}::ng-deep .mat-mdc-menu-panel.sd-tree__command-menu .mat-mdc-menu-item.sd-tree__command-menu-item,::ng-deep .mat-menu-panel.sd-tree__command-menu .mat-menu-item.sd-tree__command-menu-item{min-height:40px;padding:0 12px}::ng-deep .mat-mdc-menu-panel.sd-tree__command-menu .mat-mdc-menu-item.sd-tree__command-menu-item .mat-mdc-menu-item-text,::ng-deep .mat-mdc-menu-panel.sd-tree__command-menu .mat-mdc-menu-item.sd-tree__command-menu-item .mdc-list-item__primary-text,::ng-deep .mat-menu-panel.sd-tree__command-menu .mat-menu-item.sd-tree__command-menu-item{width:100%;min-width:0}.sd-tree__command-menu-content{display:flex;align-items:center;gap:6px;width:100%;min-width:0;line-height:20px}.sd-tree__command-menu-icon{display:flex;align-items:center;justify-content:center;flex:0 0 16px;margin:0!important;padding:0;text-align:center;overflow:hidden}.sd-tree__command-title{display:block;min-width:0;line-height:20px}.c-bg-length{display:flex;flex-direction:column;align-items:flex-start;position:static;width:auto;min-width:48px;height:48px;padding:12px 8px;background:var(--sd-primary);border-radius:4px 0 0 4px}.c-bg-length .c-length{position:static;width:auto;min-width:32px;height:24px;color:#fff;font-family:Roboto,sans-serif;font-size:16px;font-style:normal;font-weight:500;line-height:24px;text-align:center}.c-message{position:static;min-width:200px;height:20px;margin:0 0 0 8px;color:#000;font-family:Roboto,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:20px}.sd-tree__qa-actions{align-items:center;gap:4px;margin-right:8px}\n"] }]
504
- }], ctorParameters: () => [], propDecorators: { autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], option: [{ type: i0.Input, args: [{ isSignal: true, alias: "option", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], tree: [{ type: i0.Input, args: [{ isSignal: true, alias: "tree", required: false }] }], selectedItemsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItems", required: false }] }], commands: [{ type: i0.Input, args: [{ isSignal: true, alias: "commands", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], selector: [{ type: i0.Input, args: [{ isSignal: true, alias: "selector", required: false }] }], itemTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemTemplate", required: false }] }], selectedItemsChange: [{ type: i0.Output, args: ["selectedItemsChange"] }], selectChange: [{ type: i0.Output, args: ["selectChange"] }], expandChange: [{ type: i0.Output, args: ["expandChange"] }], collapseChange: [{ type: i0.Output, args: ["collapseChange"] }], itemDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdTreeItemDefDirective), { isSignal: true }] }] } });
672
+ }, template: "@let _resolvedItemTemplate = resolvedItemTemplate();\n@let _selectionVisible = selectionVisible();\n@let _selectedCount = selectedCount();\n@let _selectionMessage = selectionMessage();\n@let _selectionActionViews = selectionActionViews();\n@let _rootError = rootError();\n\n@if (rootLoading()) {\n <div class=\"sd-tree__root-loading\" role=\"status\" aria-live=\"polite\">\n <mat-progress-spinner diameter=\"24\" mode=\"indeterminate\" />\n </div>\n} @else if (_rootError) {\n <div class=\"sd-tree__root-error\" role=\"alert\">\n <span>{{ errorMessage(_rootError) }}</span>\n <button type=\"button\" data-tree-retry (click)=\"retry()\">{{ 'core.component.tree.retry' | translate }}</button>\n </div>\n} @else {\n <div class=\"sd-tree\" role=\"tree\" [attr.aria-busy]=\"rootLoading()\" [style.--sd-tree-indent-size]=\"indentSize() + 'px'\">\n @for (node of visibleViewNodes(); track node.id) {\n <div\n class=\"sd-tree__row\"\n role=\"treeitem\"\n [tabIndex]=\"node.tabIndex\"\n [class.sd-tree__row--selected]=\"node.selected\"\n [style.--sd-tree-level]=\"node.level\"\n [attr.aria-level]=\"node.level + 1\"\n [attr.aria-expanded]=\"node.ariaExpanded\"\n [attr.aria-selected]=\"_selectionVisible ? node.selected : null\"\n [attr.aria-checked]=\"_selectionVisible ? (node.selectionIndeterminate ? 'mixed' : node.selected) : null\"\n [attr.data-autoid]=\"node.autoIds.row\"\n (focus)=\"onRowFocus(node)\"\n (keydown)=\"onRowKeydown(node, $event)\">\n <div class=\"sd-tree__main\">\n <button\n type=\"button\"\n class=\"sd-tree__toggle\"\n [class.sd-tree__toggle--placeholder]=\"!node.hasChildren\"\n [disabled]=\"node.toggleDisabled\"\n [attr.aria-label]=\"node.toggleLabel\"\n [attr.data-autoid]=\"node.autoIds.toggle\"\n [attr.data-tree-node-retry]=\"node.loadError ? node.id : null\"\n (click)=\"toggle(node, $event)\">\n @if (node.isLoading) {\n <mat-progress-spinner diameter=\"16\" mode=\"indeterminate\" />\n } @else if (node.loadError) {\n <sd-icon name=\"refresh\"></sd-icon>\n } @else if (node.hasChildren) {\n <sd-icon [name]=\"node.isExpanded ? 'expand_more' : 'chevron_right'\"></sd-icon>\n }\n </button>\n\n @if (_selectionVisible) {\n <mat-checkbox\n class=\"sd-tree__checkbox\"\n [checked]=\"node.selected\"\n [indeterminate]=\"node.selectionIndeterminate\"\n [disabled]=\"node.selectionDisabled\"\n [attr.data-autoid]=\"node.autoIds.checkbox\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"toggleSelection(node)\" />\n }\n\n @if (node.icon) {\n <sd-icon class=\"sd-tree__item-icon\" color=\"primary\" [attr.data-autoid]=\"node.autoIds.icon\" [name]=\"node.icon\"></sd-icon>\n }\n\n <div class=\"sd-tree__content\" [class.sd-tree__content--custom]=\"_resolvedItemTemplate\" [attr.data-autoid]=\"node.autoIds.label\">\n @if (_resolvedItemTemplate) {\n <ng-container *ngTemplateOutlet=\"_resolvedItemTemplate; context: node.context\" />\n } @else {\n <span class=\"sd-tree__label\">{{ node.label }}</span>\n }\n </div>\n </div>\n\n @if (node.commands.length) {\n <button\n type=\"button\"\n class=\"sd-tree__command-trigger\"\n mat-icon-button\n [matMenuTriggerFor]=\"commandMenu\"\n [attr.data-autoid]=\"node.autoIds.command\"\n (click)=\"$event.stopPropagation()\">\n <sd-icon class=\"c-icon\" name=\"more_vert\"></sd-icon>\n </button>\n <mat-menu #commandMenu=\"matMenu\" class=\"sd-tree__command-menu\">\n @for (command of node.commands; track command.key) {\n <button\n type=\"button\"\n class=\"sd-tree__command-menu-item\"\n mat-menu-item\n [disabled]=\"command.disabled\"\n [attr.data-autoid]=\"command.autoId\"\n (click)=\"command.command.click(node.data)\">\n <span class=\"sd-tree__command-menu-content\">\n <sd-icon\n class=\"c-icon sd-tree__command-menu-icon\"\n [class.sd-tree__command-menu-icon--default]=\"command.defaultColor\"\n [color]=\"command.color\"\n [fontSet]=\"command.fontSet\"\n [name]=\"command.icon\"></sd-icon>\n <span class=\"sd-tree__command-title\">{{ command.title }}</span>\n </span>\n </button>\n }\n </mat-menu>\n }\n </div>\n }\n </div>\n}\n\n<sd-quick-action [opened]=\"_selectedCount > 0\">\n <div class=\"d-flex align-items-center\" sdMessage>\n <div class=\"c-bg-length\">\n <span class=\"c-length sd-tree__qa-count\">{{ _selectedCount }}</span>\n </div>\n <div class=\"c-message\">\n {{ _selectionMessage }}\n </div>\n </div>\n\n <div class=\"d-flex align-items-center mr-8 sd-tree__qa-actions\" sdAction>\n @for (actionView of _selectionActionViews; track $index) {\n <sd-button\n [autoId]=\"actionView.autoId\"\n class=\"ml-4\"\n [tooltip]=\"actionView.action.tooltip\"\n [prefixIcon]=\"actionView.action.icon\"\n [color]=\"actionView.action.color || 'primary'\"\n [type]=\"actionView.action.type || 'light'\"\n [fontSet]=\"actionView.action.fontSet\"\n [title]=\"actionView.action.title\"\n (click)=\"onSelectionAction(actionView.action)\" />\n }\n <sd-button\n [autoId]=\"clearSelectionAutoId()\"\n class=\"ml-4\"\n prefixIcon=\"close\"\n color=\"secondary\"\n type=\"outline\"\n width=\"35px\"\n (click)=\"clearSelection()\" />\n </div>\n</sd-quick-action>\n", styles: [".text-primary{color:var(--sd-primary)!important}.bg-primary{background:var(--sd-primary)!important}.border-primary{border-color:var(--sd-primary)!important}.text-primary-light{color:var(--sd-primary-light)!important}.bg-primary-light{background:var(--sd-primary-light)!important}.border-primary-light{border-color:var(--sd-primary-light)!important}.text-primary-dark{color:var(--sd-primary-dark)!important}.bg-primary-dark{background:var(--sd-primary-dark)!important}.border-primary-dark{border-color:var(--sd-primary-dark)!important}.text-primary-contrast{color:var(--sd-primary-contrast)!important}.bg-primary-contrast{background:var(--sd-primary-contrast)!important}.border-primary-contrast{border-color:var(--sd-primary-contrast)!important}.text-secondary{color:var(--sd-secondary)!important}.bg-secondary{background:var(--sd-secondary)!important}.border-secondary{border-color:var(--sd-secondary)!important}.text-secondary-light{color:var(--sd-secondary-light)!important}.bg-secondary-light{background:var(--sd-secondary-light)!important}.border-secondary-light{border-color:var(--sd-secondary-light)!important}.text-secondary-dark{color:var(--sd-secondary-dark)!important}.bg-secondary-dark{background:var(--sd-secondary-dark)!important}.border-secondary-dark{border-color:var(--sd-secondary-dark)!important}.text-secondary-contrast{color:var(--sd-secondary-contrast)!important}.bg-secondary-contrast{background:var(--sd-secondary-contrast)!important}.border-secondary-contrast{border-color:var(--sd-secondary-contrast)!important}.text-info{color:var(--sd-info)!important}.bg-info{background:var(--sd-info)!important}.border-info{border-color:var(--sd-info)!important}.text-info-light{color:var(--sd-info-light)!important}.bg-info-light{background:var(--sd-info-light)!important}.border-info-light{border-color:var(--sd-info-light)!important}.text-info-dark{color:var(--sd-info-dark)!important}.bg-info-dark{background:var(--sd-info-dark)!important}.border-info-dark{border-color:var(--sd-info-dark)!important}.text-info-contrast{color:var(--sd-info-contrast)!important}.bg-info-contrast{background:var(--sd-info-contrast)!important}.border-info-contrast{border-color:var(--sd-info-contrast)!important}.text-success{color:var(--sd-success)!important}.bg-success{background:var(--sd-success)!important}.border-success{border-color:var(--sd-success)!important}.text-success-light{color:var(--sd-success-light)!important}.bg-success-light{background:var(--sd-success-light)!important}.border-success-light{border-color:var(--sd-success-light)!important}.text-success-dark{color:var(--sd-success-dark)!important}.bg-success-dark{background:var(--sd-success-dark)!important}.border-success-dark{border-color:var(--sd-success-dark)!important}.text-success-contrast{color:var(--sd-success-contrast)!important}.bg-success-contrast{background:var(--sd-success-contrast)!important}.border-success-contrast{border-color:var(--sd-success-contrast)!important}.text-warning{color:var(--sd-warning)!important}.bg-warning{background:var(--sd-warning)!important}.border-warning{border-color:var(--sd-warning)!important}.text-warning-light{color:var(--sd-warning-light)!important}.bg-warning-light{background:var(--sd-warning-light)!important}.border-warning-light{border-color:var(--sd-warning-light)!important}.text-warning-dark{color:var(--sd-warning-dark)!important}.bg-warning-dark{background:var(--sd-warning-dark)!important}.border-warning-dark{border-color:var(--sd-warning-dark)!important}.text-warning-contrast{color:var(--sd-warning-contrast)!important}.bg-warning-contrast{background:var(--sd-warning-contrast)!important}.border-warning-contrast{border-color:var(--sd-warning-contrast)!important}.text-error{color:var(--sd-error)!important}.bg-error{background:var(--sd-error)!important}.border-error{border-color:var(--sd-error)!important}.text-error-light{color:var(--sd-error-light)!important}.bg-error-light{background:var(--sd-error-light)!important}.border-error-light{border-color:var(--sd-error-light)!important}.text-error-dark{color:var(--sd-error-dark)!important}.bg-error-dark{background:var(--sd-error-dark)!important}.border-error-dark{border-color:var(--sd-error-dark)!important}.text-error-contrast{color:var(--sd-error-contrast)!important}.bg-error-contrast{background:var(--sd-error-contrast)!important}.border-error-contrast{border-color:var(--sd-error-contrast)!important}.text-surface{color:var(--sd-surface)!important}.bg-surface{background:var(--sd-surface)!important}.border-surface{border-color:var(--sd-surface)!important}.text-surface-muted{color:var(--sd-surface-muted)!important}.bg-surface-muted{background:var(--sd-surface-muted)!important}.border-surface-muted{border-color:var(--sd-surface-muted)!important}.text-text{color:var(--sd-text)!important}.bg-text{background:var(--sd-text)!important}.border-text{border-color:var(--sd-text)!important}.text-text-secondary{color:var(--sd-text-secondary)!important}.bg-text-secondary{background:var(--sd-text-secondary)!important}.border-text-secondary{border-color:var(--sd-text-secondary)!important}.text-text-muted{color:var(--sd-text-muted)!important}.bg-text-muted{background:var(--sd-text-muted)!important}.border-text-muted{border-color:var(--sd-text-muted)!important}.text-border{color:var(--sd-border)!important}.bg-border{background:var(--sd-border)!important}.border-border{border-color:var(--sd-border)!important}.text-border-strong{color:var(--sd-border-strong)!important}.bg-border-strong{background:var(--sd-border-strong)!important}.border-border-strong{border-color:var(--sd-border-strong)!important}.text-disabled-bg{color:var(--sd-disabled-bg)!important}.bg-disabled-bg{background:var(--sd-disabled-bg)!important}.border-disabled-bg{border-color:var(--sd-disabled-bg)!important}.text-disabled-text{color:var(--sd-disabled-text)!important}.bg-disabled-text{background:var(--sd-disabled-text)!important}.border-disabled-text{border-color:var(--sd-disabled-text)!important}.text-white{color:#fff!important}.bg-white{background:#fff!important}.border-white{border-color:#fff!important}.text-black{color:#000!important}.bg-black{background:#000!important}.border-black{border-color:#000!important}.text-secondary{color:var(--sd-text-secondary)!important}.text-muted{color:var(--sd-text-muted)!important}.text-body{color:var(--sd-text)!important}.bg-muted{background:var(--sd-surface-muted)!important}:host{--sd-tree-row-height: 44px;--sd-tree-control-size: 28px;--sd-tree-indent-size: 20px;--sd-tree-selected-bg: color-mix(in srgb, var(--sd-primary, #005cbb) 12%, #ffffff);--sd-tree-hover-bg: rgba(15, 23, 42, .04);--sd-tree-text: #102047;--sd-tree-muted: #5f6f89;display:block}.sd-tree{display:flex;flex-direction:column;width:100%}.sd-tree__row{position:relative;display:flex;align-items:center;min-height:var(--sd-tree-row-height);box-sizing:border-box;padding:6px 4px 6px calc(4px + var(--sd-tree-level) * var(--sd-tree-indent-size));color:var(--sd-tree-text);border-radius:0}.sd-tree__row:hover{background:var(--sd-tree-hover-bg)}.sd-tree__row:focus-visible{z-index:1;outline:2px solid var(--sd-primary, #005cbb);outline-offset:-2px}.sd-tree__row--selected{background:var(--sd-tree-selected-bg)}.sd-tree__main{display:flex;align-items:center;min-width:0;flex:1 1 auto}.sd-tree__toggle{display:inline-flex;align-items:center;justify-content:center;flex:0 0 var(--sd-tree-control-size);width:var(--sd-tree-control-size);height:var(--sd-tree-control-size);padding:0;color:var(--sd-tree-muted);background:transparent;border:0;border-radius:4px;cursor:pointer}.sd-tree__toggle:disabled{cursor:default}.sd-tree__toggle--placeholder{visibility:hidden}.sd-tree__toggle sd-icon{width:20px;height:20px;font-size:20px;line-height:20px}.sd-tree__checkbox{flex:0 0 auto;height:var(--sd-tree-control-size);margin:0 4px 0 0;transform:scale(.85);transform-origin:center;--mdc-checkbox-selected-checkmark-color: #ffffff;--mdc-checkbox-selected-focus-icon-color: var(--sd-primary, #005cbb);--mdc-checkbox-selected-hover-icon-color: var(--sd-primary, #005cbb);--mdc-checkbox-selected-icon-color: var(--sd-primary, #005cbb);--mdc-checkbox-selected-pressed-icon-color: var(--sd-primary, #005cbb)}.sd-tree__item-icon{flex:0 0 auto;width:20px;height:20px;margin:0 8px 0 0;font-size:20px;line-height:20px}.sd-tree__content{display:-webkit-box;min-width:0;min-height:var(--sd-tree-control-size);padding:4px 0;overflow:hidden;overflow-wrap:anywhere;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-height:20px}.sd-tree__content--custom{display:block;max-height:none;-webkit-line-clamp:unset}.sd-tree__label{font-size:14px;font-weight:500}.sd-tree__command-trigger{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;align-self:center;width:24px;height:24px;padding:0;margin-left:8px;line-height:24px;opacity:0;transition:opacity .12s ease}.sd-tree__row:hover .sd-tree__command-trigger,.sd-tree__command-trigger[aria-expanded=true]{opacity:1}.sd-tree__command-trigger sd-icon.c-icon,.sd-tree__command-menu-icon{width:16px;height:16px;font-size:16px;line-height:16px}.sd-tree__command-trigger sd-icon.c-icon,.sd-tree__command-menu-icon--default{color:var(--sd-text-secondary)!important}::ng-deep .mat-mdc-menu-panel.sd-tree__command-menu .mat-mdc-menu-item.sd-tree__command-menu-item,::ng-deep .mat-menu-panel.sd-tree__command-menu .mat-menu-item.sd-tree__command-menu-item{min-height:40px;padding:0 12px}::ng-deep .mat-mdc-menu-panel.sd-tree__command-menu .mat-mdc-menu-item.sd-tree__command-menu-item .mat-mdc-menu-item-text,::ng-deep .mat-mdc-menu-panel.sd-tree__command-menu .mat-mdc-menu-item.sd-tree__command-menu-item .mdc-list-item__primary-text,::ng-deep .mat-menu-panel.sd-tree__command-menu .mat-menu-item.sd-tree__command-menu-item{width:100%;min-width:0}.sd-tree__command-menu-content{display:flex;align-items:center;gap:6px;width:100%;min-width:0;line-height:20px}.sd-tree__command-menu-icon{display:flex;align-items:center;justify-content:center;flex:0 0 16px;margin:0!important;padding:0;text-align:center;overflow:hidden}.sd-tree__command-title{display:block;min-width:0;line-height:20px}.c-bg-length{display:flex;flex-direction:column;align-items:flex-start;position:static;width:auto;min-width:48px;height:48px;padding:12px 8px;background:var(--sd-primary);border-radius:4px 0 0 4px}.c-bg-length .c-length{position:static;width:auto;min-width:32px;height:24px;color:#fff;font-family:Roboto,sans-serif;font-size:16px;font-style:normal;font-weight:500;line-height:24px;text-align:center}.c-message{position:static;min-width:200px;height:20px;margin:0 0 0 8px;color:#000;font-family:Roboto,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:20px}.sd-tree__qa-actions{align-items:center;gap:4px;margin-right:8px}.sd-tree__root-loading,.sd-tree__root-error{display:flex;align-items:center;justify-content:center;gap:8px;min-height:120px;padding:16px}.sd-tree__root-error{flex-direction:column;color:var(--sd-error, #d92d20)}.sd-tree__root-error button{min-height:36px;padding:6px 12px;border:1px solid currentcolor;border-radius:6px;background:transparent;color:inherit;font:inherit;cursor:pointer}\n"] }]
673
+ }], ctorParameters: () => [], propDecorators: { autoIdInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoId", required: false }] }], option: [{ type: i0.Input, args: [{ isSignal: true, alias: "option", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], tree: [{ type: i0.Input, args: [{ isSignal: true, alias: "tree", required: false }] }], selectedItemsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItems", required: false }] }], commands: [{ type: i0.Input, args: [{ isSignal: true, alias: "commands", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], selector: [{ type: i0.Input, args: [{ isSignal: true, alias: "selector", required: false }] }], itemTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemTemplate", required: false }] }], selectedItemsChange: [{ type: i0.Output, args: ["selectedItemsChange"] }], selectChange: [{ type: i0.Output, args: ["selectChange"] }], expandChange: [{ type: i0.Output, args: ["expandChange"] }], collapseChange: [{ type: i0.Output, args: ["collapseChange"] }], loadError: [{ type: i0.Output, args: ["loadError"] }], itemDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdTreeItemDefDirective), { isSignal: true }] }] } });
505
674
  function normalizeText(value) {
506
675
  return value
507
676
  .normalize('NFD')