@mozaic-ds/angular 2.0.33 → 2.0.35
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.
|
@@ -2935,20 +2935,26 @@ class MozSegmentedControlComponent {
|
|
|
2935
2935
|
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
2936
2936
|
size = input('s', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
2937
2937
|
full = input(false, { ...(ngDevMode ? { debugName: "full" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
2938
|
+
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
2938
2939
|
ariaLabel = input('Segmented control', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
2939
2940
|
selectedIndex = model(0, ...(ngDevMode ? [{ debugName: "selectedIndex" }] : /* istanbul ignore next */ []));
|
|
2940
2941
|
change = output();
|
|
2941
2942
|
classes = computed(() => ({
|
|
2942
2943
|
'segmented-control': true,
|
|
2944
|
+
'segmented-control--disabled': this.disabled(),
|
|
2943
2945
|
'segmented-control--m': this.size() === 'm',
|
|
2944
2946
|
'segmented-control--full': this.full(),
|
|
2945
2947
|
}), ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
2946
2948
|
segmentClasses = (index) => computed(() => ({
|
|
2949
|
+
'segmented-control__segment--disabled': this.disabled() || !!this.items()[index]?.disabled,
|
|
2947
2950
|
'segmented-control__segment': true,
|
|
2948
2951
|
'segmented-control__segment--selected': index === this.selectedIndex(),
|
|
2949
2952
|
}));
|
|
2950
2953
|
buttons = viewChildren('segBtn', ...(ngDevMode ? [{ debugName: "buttons" }] : /* istanbul ignore next */ []));
|
|
2951
2954
|
onSelect(index) {
|
|
2955
|
+
if (this.disabled() || this.items()[index]?.disabled) {
|
|
2956
|
+
return;
|
|
2957
|
+
}
|
|
2952
2958
|
const item = this.items()[index];
|
|
2953
2959
|
this.selectedIndex.set(index);
|
|
2954
2960
|
this.change.emit({ index, value: item.value });
|
|
@@ -2960,12 +2966,12 @@ class MozSegmentedControlComponent {
|
|
|
2960
2966
|
btn?.focus();
|
|
2961
2967
|
}
|
|
2962
2968
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: MozSegmentedControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2963
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: MozSegmentedControlComponent, isStandalone: true, selector: "moz-segmented-control", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, full: { classPropertyName: "full", publicName: "full", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedIndex: "selectedIndexChange", change: "change" }, viewQueries: [{ propertyName: "buttons", predicate: ["segBtn"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [class]=\"classes()\" role=\"tablist\" [attr.aria-label]=\"ariaLabel()\">\n @for (item of items(); track item.value; let i = $index) {\n
|
|
2969
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: MozSegmentedControlComponent, isStandalone: true, selector: "moz-segmented-control", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, full: { classPropertyName: "full", publicName: "full", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedIndex: "selectedIndexChange", change: "change" }, viewQueries: [{ propertyName: "buttons", predicate: ["segBtn"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [class]=\"classes()\" role=\"tablist\" [attr.aria-label]=\"ariaLabel()\">\n @for (item of items(); track item.value; let i = $index) {\n <button\n #segBtn\n type=\"button\"\n [class]=\"segmentClasses(i)()\"\n role=\"tab\"\n [attr.aria-selected]=\"i === selectedIndex()\"\n [attr.aria-disabled]=\"disabled() || !!item.disabled\"\n [attr.tabindex]=\"i === selectedIndex() ? 0 : -1\"\n [disabled]=\"disabled() || !!item.disabled\"\n (click)=\"onSelect(i)\"\n >\n {{ item.label }}\n </button>\n }\n</div>\n", styles: [".mc-segmented-control,.segmented-control{display:inline-flex;background-color:var(--segmented-control-color-background-default, #ffffff);border:1px solid var(--segmented-control-color-border, #cccccc);border-radius:3rem;height:2rem;padding:.25rem;box-sizing:border-box;gap:.25rem}.mc-segmented-control__segment,.segmented-control__segment{display:flex;align-items:center;justify-content:center;background-color:transparent;border:none;color:var(--segmented-control-color-text-default, #666666);cursor:pointer;font-family:inherit;font-weight:var(--font-weight-semi-bold, 600);font-size:var(--font-size-100, .875rem);padding:0 1rem;border-radius:3rem;height:1.5rem;width:100%;transition:background-color .3s ease;white-space:nowrap}.mc-segmented-control__segment:not(.mc-segmented-control__segment--selected):not(.segmented-control__segment--selected):hover,.segmented-control__segment:not(.mc-segmented-control__segment--selected):not(.segmented-control__segment--selected):hover{background-color:var(--segmented-control-color-background-hover, rgba(0, 0, 0, .05))}.mc-segmented-control__segment--selected,.segmented-control__segment--selected{color:var(--segmented-control-color-text-selected, #ffffff);background-color:var(--segmented-control-color-background-selected, #464e63)}.mc-segmented-control__segment:focus-visible,.segmented-control__segment:focus-visible{box-shadow:0 0 0 .125rem var(--focus-color-mid, var(--focus-color-outline-mid, #ffffff)),0 0 0 .25rem var(--focus-color-outer, var(--focus-color-outline-outer, #000000));outline:.125rem solid transparent;outline-offset:.125rem}.mc-segmented-control--m,.segmented-control--m{height:3rem;padding:.5rem}.mc-segmented-control--m .mc-segmented-control__segment,.segmented-control--m .mc-segmented-control__segment,.mc-segmented-control--m .segmented-control__segment,.segmented-control--m .segmented-control__segment{height:2rem}.mc-segmented-control--full,.segmented-control--full{display:flex}.segmented-control--disabled{cursor:not-allowed}.segmented-control__segment:disabled{color:var(--button-state-disabled-color, #737373);cursor:not-allowed}.segmented-control__segment:disabled:not(.segmented-control__segment--selected):hover{background-color:transparent}.segmented-control__segment:disabled.segmented-control__segment--selected{background-color:var(--button-state-disabled-background, #d9d9d9);color:var(--button-state-disabled-color, #737373)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2964
2970
|
}
|
|
2965
2971
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: MozSegmentedControlComponent, decorators: [{
|
|
2966
2972
|
type: Component,
|
|
2967
|
-
args: [{ selector: 'moz-segmented-control', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"classes()\" role=\"tablist\" [attr.aria-label]=\"ariaLabel()\">\n @for (item of items(); track item.value; let i = $index) {\n
|
|
2968
|
-
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], full: [{ type: i0.Input, args: [{ isSignal: true, alias: "full", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], selectedIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIndex", required: false }] }, { type: i0.Output, args: ["selectedIndexChange"] }], change: [{ type: i0.Output, args: ["change"] }], buttons: [{ type: i0.ViewChildren, args: ['segBtn', { isSignal: true }] }] } });
|
|
2973
|
+
args: [{ selector: 'moz-segmented-control', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"classes()\" role=\"tablist\" [attr.aria-label]=\"ariaLabel()\">\n @for (item of items(); track item.value; let i = $index) {\n <button\n #segBtn\n type=\"button\"\n [class]=\"segmentClasses(i)()\"\n role=\"tab\"\n [attr.aria-selected]=\"i === selectedIndex()\"\n [attr.aria-disabled]=\"disabled() || !!item.disabled\"\n [attr.tabindex]=\"i === selectedIndex() ? 0 : -1\"\n [disabled]=\"disabled() || !!item.disabled\"\n (click)=\"onSelect(i)\"\n >\n {{ item.label }}\n </button>\n }\n</div>\n", styles: [".mc-segmented-control,.segmented-control{display:inline-flex;background-color:var(--segmented-control-color-background-default, #ffffff);border:1px solid var(--segmented-control-color-border, #cccccc);border-radius:3rem;height:2rem;padding:.25rem;box-sizing:border-box;gap:.25rem}.mc-segmented-control__segment,.segmented-control__segment{display:flex;align-items:center;justify-content:center;background-color:transparent;border:none;color:var(--segmented-control-color-text-default, #666666);cursor:pointer;font-family:inherit;font-weight:var(--font-weight-semi-bold, 600);font-size:var(--font-size-100, .875rem);padding:0 1rem;border-radius:3rem;height:1.5rem;width:100%;transition:background-color .3s ease;white-space:nowrap}.mc-segmented-control__segment:not(.mc-segmented-control__segment--selected):not(.segmented-control__segment--selected):hover,.segmented-control__segment:not(.mc-segmented-control__segment--selected):not(.segmented-control__segment--selected):hover{background-color:var(--segmented-control-color-background-hover, rgba(0, 0, 0, .05))}.mc-segmented-control__segment--selected,.segmented-control__segment--selected{color:var(--segmented-control-color-text-selected, #ffffff);background-color:var(--segmented-control-color-background-selected, #464e63)}.mc-segmented-control__segment:focus-visible,.segmented-control__segment:focus-visible{box-shadow:0 0 0 .125rem var(--focus-color-mid, var(--focus-color-outline-mid, #ffffff)),0 0 0 .25rem var(--focus-color-outer, var(--focus-color-outline-outer, #000000));outline:.125rem solid transparent;outline-offset:.125rem}.mc-segmented-control--m,.segmented-control--m{height:3rem;padding:.5rem}.mc-segmented-control--m .mc-segmented-control__segment,.segmented-control--m .mc-segmented-control__segment,.mc-segmented-control--m .segmented-control__segment,.segmented-control--m .segmented-control__segment{height:2rem}.mc-segmented-control--full,.segmented-control--full{display:flex}.segmented-control--disabled{cursor:not-allowed}.segmented-control__segment:disabled{color:var(--button-state-disabled-color, #737373);cursor:not-allowed}.segmented-control__segment:disabled:not(.segmented-control__segment--selected):hover{background-color:transparent}.segmented-control__segment:disabled.segmented-control__segment--selected{background-color:var(--button-state-disabled-background, #d9d9d9);color:var(--button-state-disabled-color, #737373)}\n"] }]
|
|
2974
|
+
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], full: [{ type: i0.Input, args: [{ isSignal: true, alias: "full", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], selectedIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIndex", required: false }] }, { type: i0.Output, args: ["selectedIndexChange"] }], change: [{ type: i0.Output, args: ["change"] }], buttons: [{ type: i0.ViewChildren, args: ['segBtn', { isSignal: true }] }] } });
|
|
2969
2975
|
|
|
2970
2976
|
class MozAccordionHeaderComponent {
|
|
2971
2977
|
tpl = viewChild('tpl', { ...(ngDevMode ? { debugName: "tpl" } : /* istanbul ignore next */ {}), read: TemplateRef });
|
|
@@ -11433,7 +11439,8 @@ class TreeStateService {
|
|
|
11433
11439
|
this.toggleExpanded(node.id);
|
|
11434
11440
|
if (!wasExpanded) {
|
|
11435
11441
|
const loadFn = this.loadChildrenFn();
|
|
11436
|
-
|
|
11442
|
+
const resolved = this.findNode(node.id) ?? node;
|
|
11443
|
+
if (loadFn && resolved.children === undefined) {
|
|
11437
11444
|
this.addLoading(node.id);
|
|
11438
11445
|
return loadFn(node).pipe(take(1), tap((children) => {
|
|
11439
11446
|
this.patchChildren(node.id, children);
|
|
@@ -11495,6 +11502,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
|
|
|
11495
11502
|
}] });
|
|
11496
11503
|
|
|
11497
11504
|
class TreeSelectionService {
|
|
11505
|
+
stateService = inject(TreeStateService);
|
|
11498
11506
|
selectedIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "selectedIds" }] : /* istanbul ignore next */ []));
|
|
11499
11507
|
selectionMode = signal('none', ...(ngDevMode ? [{ debugName: "selectionMode" }] : /* istanbul ignore next */ []));
|
|
11500
11508
|
rootNodes = signal([], ...(ngDevMode ? [{ debugName: "rootNodes" }] : /* istanbul ignore next */ []));
|
|
@@ -11515,40 +11523,62 @@ class TreeSelectionService {
|
|
|
11515
11523
|
return true;
|
|
11516
11524
|
return ancestors.some((a) => a.disabled);
|
|
11517
11525
|
}
|
|
11526
|
+
/**
|
|
11527
|
+
* A node is indeterminate when it has loaded children AND
|
|
11528
|
+
* some (but not all) of its leaf-level descendants are selected.
|
|
11529
|
+
*/
|
|
11518
11530
|
isIndeterminate(node) {
|
|
11519
|
-
|
|
11531
|
+
const resolved = this._resolveNode(node);
|
|
11532
|
+
const leaves = this._collectLeafIds(resolved);
|
|
11533
|
+
if (leaves.length === 0)
|
|
11520
11534
|
return false;
|
|
11521
|
-
|
|
11522
|
-
|
|
11523
|
-
const enabledIds = this._collectEnabledDescendantIds(node);
|
|
11524
|
-
if (enabledIds.length === 0)
|
|
11525
|
-
return false;
|
|
11526
|
-
const selectedCount = enabledIds.filter((id) => this.selectedIds().has(id)).length;
|
|
11527
|
-
return selectedCount > 0 && selectedCount < enabledIds.length;
|
|
11535
|
+
const selectedCount = leaves.filter((id) => this.selectedIds().has(id)).length;
|
|
11536
|
+
return selectedCount > 0 && selectedCount < leaves.length;
|
|
11528
11537
|
}
|
|
11538
|
+
/**
|
|
11539
|
+
* A node is checked when:
|
|
11540
|
+
* - Leaf node (no children or children not loaded): its ID is in selectedIds
|
|
11541
|
+
* - Parent with loaded children: ALL leaf descendants are selected
|
|
11542
|
+
*/
|
|
11529
11543
|
isCheckedComputed(node) {
|
|
11530
11544
|
if (this.selectionMode() === 'radio') {
|
|
11531
11545
|
return this.selectedIds().has(node.id);
|
|
11532
11546
|
}
|
|
11533
|
-
|
|
11547
|
+
const resolved = this._resolveNode(node);
|
|
11548
|
+
const leaves = this._collectLeafIds(resolved);
|
|
11549
|
+
// Node is a leaf or has no loaded children
|
|
11550
|
+
if (leaves.length === 0) {
|
|
11534
11551
|
return this.selectedIds().has(node.id);
|
|
11535
11552
|
}
|
|
11536
|
-
|
|
11537
|
-
if (enabledIds.length === 0)
|
|
11538
|
-
return this.selectedIds().has(node.id);
|
|
11539
|
-
return enabledIds.every((id) => this.selectedIds().has(id));
|
|
11553
|
+
return leaves.every((id) => this.selectedIds().has(id));
|
|
11540
11554
|
}
|
|
11555
|
+
/**
|
|
11556
|
+
* Select a node: add all leaf descendant IDs (or the node's own ID if leaf).
|
|
11557
|
+
*/
|
|
11541
11558
|
selectNode(node) {
|
|
11542
11559
|
if (this.selectionMode() === 'radio') {
|
|
11543
11560
|
this.selectedIds.set(new Set([node.id]));
|
|
11544
11561
|
return;
|
|
11545
11562
|
}
|
|
11563
|
+
const resolved = this._resolveNode(node);
|
|
11546
11564
|
this.selectedIds.update((current) => {
|
|
11547
11565
|
const next = new Set(current);
|
|
11548
|
-
|
|
11566
|
+
const leaves = this._collectLeafIds(resolved);
|
|
11567
|
+
if (leaves.length === 0) {
|
|
11568
|
+
// Node is a leaf
|
|
11569
|
+
if (!node.disabled)
|
|
11570
|
+
next.add(node.id);
|
|
11571
|
+
}
|
|
11572
|
+
else {
|
|
11573
|
+
leaves.forEach((id) => next.add(id));
|
|
11574
|
+
}
|
|
11549
11575
|
return next;
|
|
11550
11576
|
});
|
|
11551
11577
|
}
|
|
11578
|
+
/**
|
|
11579
|
+
* Deselect a node: remove all leaf descendant IDs (or the node's own ID if leaf).
|
|
11580
|
+
* Also remove the node's own ID in case it's in the set from external sources.
|
|
11581
|
+
*/
|
|
11552
11582
|
deselectNode(node) {
|
|
11553
11583
|
if (this.selectionMode() === 'radio') {
|
|
11554
11584
|
this.selectedIds.update((current) => {
|
|
@@ -11558,9 +11588,13 @@ class TreeSelectionService {
|
|
|
11558
11588
|
});
|
|
11559
11589
|
return;
|
|
11560
11590
|
}
|
|
11591
|
+
const resolved = this._resolveNode(node);
|
|
11561
11592
|
this.selectedIds.update((current) => {
|
|
11562
11593
|
const next = new Set(current);
|
|
11563
|
-
|
|
11594
|
+
// Always remove the node itself
|
|
11595
|
+
next.delete(node.id);
|
|
11596
|
+
// Remove all known descendants (leaf + parents)
|
|
11597
|
+
this._collectAllDescendantIds(resolved).forEach((id) => next.delete(id));
|
|
11564
11598
|
return next;
|
|
11565
11599
|
});
|
|
11566
11600
|
}
|
|
@@ -11572,30 +11606,83 @@ class TreeSelectionService {
|
|
|
11572
11606
|
this.selectNode(node);
|
|
11573
11607
|
}
|
|
11574
11608
|
}
|
|
11575
|
-
|
|
11576
|
-
|
|
11609
|
+
/**
|
|
11610
|
+
* Called when children are loaded for a node.
|
|
11611
|
+
* - If parent ID was in selectedIds: replace it with children's leaf IDs (propagate down).
|
|
11612
|
+
* - If parent ID was NOT in selectedIds: remove any orphan children IDs that
|
|
11613
|
+
* may have been left from a prior bulk operation (e.g. Select All → deselect parent).
|
|
11614
|
+
*/
|
|
11615
|
+
propagateOnChildrenLoaded(parentId) {
|
|
11616
|
+
const parent = this._resolveNode({ id: parentId });
|
|
11617
|
+
if (!parent || !parent.children || parent.children.length === 0)
|
|
11618
|
+
return;
|
|
11619
|
+
const selected = this.selectedIds();
|
|
11620
|
+
const next = new Set(selected);
|
|
11621
|
+
if (selected.has(parentId)) {
|
|
11622
|
+
// Parent was selected → replace with leaf children
|
|
11623
|
+
next.delete(parentId);
|
|
11624
|
+
for (const child of parent.children) {
|
|
11625
|
+
if (!child.disabled) {
|
|
11626
|
+
const childLeaves = this._collectLeafIds(this._resolveNode(child));
|
|
11627
|
+
if (childLeaves.length === 0) {
|
|
11628
|
+
next.add(child.id);
|
|
11629
|
+
}
|
|
11630
|
+
else {
|
|
11631
|
+
childLeaves.forEach((id) => next.add(id));
|
|
11632
|
+
}
|
|
11633
|
+
}
|
|
11634
|
+
}
|
|
11635
|
+
}
|
|
11636
|
+
else {
|
|
11637
|
+
// Parent was NOT selected → clean up any orphan descendant IDs
|
|
11638
|
+
this._collectAllDescendantIds(parent).forEach((id) => next.delete(id));
|
|
11639
|
+
}
|
|
11640
|
+
this.selectedIds.set(next);
|
|
11641
|
+
}
|
|
11642
|
+
/**
|
|
11643
|
+
* Collect leaf-level IDs (terminal nodes that have no loaded children).
|
|
11644
|
+
* Returns empty array if the node itself is a leaf.
|
|
11645
|
+
*/
|
|
11646
|
+
_collectLeafIds(node) {
|
|
11647
|
+
const resolved = this._resolveNode(node);
|
|
11648
|
+
if (!resolved.children || resolved.children.length === 0) {
|
|
11577
11649
|
return [];
|
|
11578
|
-
|
|
11579
|
-
|
|
11580
|
-
|
|
11581
|
-
|
|
11650
|
+
}
|
|
11651
|
+
const ids = [];
|
|
11652
|
+
for (const child of resolved.children) {
|
|
11653
|
+
if (child.disabled)
|
|
11654
|
+
continue;
|
|
11655
|
+
const resolvedChild = this._resolveNode(child);
|
|
11656
|
+
const childLeaves = this._collectLeafIds(resolvedChild);
|
|
11657
|
+
if (childLeaves.length === 0) {
|
|
11658
|
+
// This child is a leaf
|
|
11659
|
+
ids.push(resolvedChild.id);
|
|
11660
|
+
}
|
|
11661
|
+
else {
|
|
11662
|
+
ids.push(...childLeaves);
|
|
11582
11663
|
}
|
|
11583
11664
|
}
|
|
11584
11665
|
return ids;
|
|
11585
11666
|
}
|
|
11586
|
-
|
|
11667
|
+
/**
|
|
11668
|
+
* Collect ALL descendant IDs (both parents and leaves) for thorough cleanup on deselect.
|
|
11669
|
+
*/
|
|
11670
|
+
_collectAllDescendantIds(node) {
|
|
11671
|
+
const resolved = this._resolveNode(node);
|
|
11587
11672
|
const ids = [];
|
|
11588
|
-
if (!
|
|
11673
|
+
if (!resolved.children)
|
|
11589
11674
|
return ids;
|
|
11590
|
-
for (const child of
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
}
|
|
11675
|
+
for (const child of resolved.children) {
|
|
11676
|
+
const resolvedChild = this._resolveNode(child);
|
|
11677
|
+
ids.push(resolvedChild.id);
|
|
11678
|
+
ids.push(...this._collectAllDescendantIds(resolvedChild));
|
|
11595
11679
|
}
|
|
11596
11680
|
return ids;
|
|
11597
11681
|
}
|
|
11598
11682
|
allSelectedIds = computed(() => new Set(this.selectedIds()), ...(ngDevMode ? [{ debugName: "allSelectedIds" }] : /* istanbul ignore next */ []));
|
|
11683
|
+
_resolveNode(node) {
|
|
11684
|
+
return this.stateService.findNode(node.id) ?? node;
|
|
11685
|
+
}
|
|
11599
11686
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: TreeSelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
11600
11687
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: TreeSelectionService });
|
|
11601
11688
|
}
|
|
@@ -11826,7 +11913,7 @@ class MozTreeNodeComponent {
|
|
|
11826
11913
|
return null;
|
|
11827
11914
|
}
|
|
11828
11915
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: MozTreeNodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11829
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: MozTreeNodeComponent, isStandalone: true, selector: "moz-tree-node", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null }, depth: { classPropertyName: "depth", publicName: "depth", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, indentSize: { classPropertyName: "indentSize", publicName: "indentSize", isSignal: true, isRequired: false, transformFunction: null }, nodeTemplate: { classPropertyName: "nodeTemplate", publicName: "nodeTemplate", isSignal: true, isRequired: false, transformFunction: null }, nodeTemplates: { classPropertyName: "nodeTemplates", publicName: "nodeTemplates", isSignal: true, isRequired: false, transformFunction: null }, loadChildren: { classPropertyName: "loadChildren", publicName: "loadChildren", isSignal: true, isRequired: false, transformFunction: null }, ancestors: { classPropertyName: "ancestors", publicName: "ancestors", isSignal: true, isRequired: false, transformFunction: null }, flat: { classPropertyName: "flat", publicName: "flat", isSignal: true, isRequired: false, transformFunction: null }, noResultText: { classPropertyName: "noResultText", publicName: "noResultText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expandChange: "expandChange", selectionChange: "selectionChange" }, host: { styleAttribute: "display: block" }, ngImport: i0, template: "<li\n class=\"tree-node\"\n [class.tree-node--selected]=\"isSelected()\"\n [class.tree-node--disabled]=\"isDisabled()\"\n [class.tree-node--focused]=\"isFocused()\"\n role=\"treeitem\"\n [id]=\"'tree-node-' + node().id\"\n [attr.aria-level]=\"depth() + 1\"\n [attr.aria-expanded]=\"hasChildren() ? isExpanded() : null\"\n [attr.aria-selected]=\"selectionMode() !== 'none' ? isSelected() : null\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.data-tree-node-id]=\"node().id\"\n [tabindex]=\"isFocused() ? 0 : -1\"\n>\n <div\n class=\"tree-node__header\"\n [class.tree-node__header--expandable]=\"hasChildren()\"\n (click)=\"onHeaderClick()\"\n >\n <div class=\"tree-node__indent\" [style.width.px]=\"indentPx()\"></div>\n\n <span class=\"tree-node__chevron\" [class.tree-node__chevron--leaf]=\"!hasChildren()\">\n
|
|
11916
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: MozTreeNodeComponent, isStandalone: true, selector: "moz-tree-node", inputs: { node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null }, depth: { classPropertyName: "depth", publicName: "depth", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, indentSize: { classPropertyName: "indentSize", publicName: "indentSize", isSignal: true, isRequired: false, transformFunction: null }, nodeTemplate: { classPropertyName: "nodeTemplate", publicName: "nodeTemplate", isSignal: true, isRequired: false, transformFunction: null }, nodeTemplates: { classPropertyName: "nodeTemplates", publicName: "nodeTemplates", isSignal: true, isRequired: false, transformFunction: null }, loadChildren: { classPropertyName: "loadChildren", publicName: "loadChildren", isSignal: true, isRequired: false, transformFunction: null }, ancestors: { classPropertyName: "ancestors", publicName: "ancestors", isSignal: true, isRequired: false, transformFunction: null }, flat: { classPropertyName: "flat", publicName: "flat", isSignal: true, isRequired: false, transformFunction: null }, noResultText: { classPropertyName: "noResultText", publicName: "noResultText", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expandChange: "expandChange", selectionChange: "selectionChange" }, host: { styleAttribute: "display: block" }, ngImport: i0, template: "<li\n class=\"tree-node\"\n [class.tree-node--selected]=\"isSelected()\"\n [class.tree-node--disabled]=\"isDisabled()\"\n [class.tree-node--focused]=\"isFocused()\"\n role=\"treeitem\"\n [id]=\"'tree-node-' + node().id\"\n [attr.aria-level]=\"depth() + 1\"\n [attr.aria-expanded]=\"hasChildren() ? isExpanded() : null\"\n [attr.aria-selected]=\"selectionMode() !== 'none' ? isSelected() : null\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.data-tree-node-id]=\"node().id\"\n [tabindex]=\"isFocused() ? 0 : -1\"\n>\n <div\n class=\"tree-node__header\"\n [class.tree-node__header--expandable]=\"hasChildren()\"\n (click)=\"onHeaderClick()\"\n >\n <div class=\"tree-node__indent\" [style.width.px]=\"indentPx()\"></div>\n\n <div class=\"tree-node__row\">\n <span class=\"tree-node__chevron\" [class.tree-node__chevron--leaf]=\"!hasChildren()\">\n @if (hasChildren()) { @if (isExpanded()) {\n <ChevronDown20 />\n } @else {\n <ChevronRight20 />\n } }\n </span>\n\n <div class=\"tree-node__content\">\n @if (resolvedTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"resolvedTemplate()!\"\n [ngTemplateOutletContext]=\"templateContext()\"\n />\n } @else {\n <span class=\"tree-node__label\">{{ node().id }}</span>\n }\n </div>\n\n @if (selectionMode() === 'checkbox') {\n <moz-checkbox\n class=\"tree-node__selection\"\n [id]=\"'tree-checkbox-' + node().id\"\n [indeterminate]=\"isIndeterminate()\"\n [disabled]=\"isDisabled()\"\n [ngModel]=\"isSelected()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"onCheckboxChange($event)\"\n />\n } @else if (selectionMode() === 'radio') {\n <moz-radio\n class=\"tree-node__selection\"\n [id]=\"'tree-radio-' + node().id\"\n [name]=\"radioName\"\n [disabled]=\"isDisabled()\"\n [ngModel]=\"isSelected()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"onRadioChange($event)\"\n />\n }\n </div>\n </div>\n\n @if (isExpanded() && !flat()) {\n <ul class=\"tree-node__children\" role=\"group\">\n @if (isLoading()) {\n <li class=\"tree-node__loading\" role=\"presentation\">\n <moz-loader size=\"s\" [appearance]=\"'accent'\" />\n </li>\n } @else { @if (resolvedChildren().length === 0) {\n <li class=\"tree-node__empty\" role=\"presentation\">\n <span>{{ noResultText() }}</span>\n </li>\n } @for (child of resolvedChildren(); track child.id) {\n <moz-tree-node\n [node]=\"child\"\n [depth]=\"depth() + 1\"\n [selectionMode]=\"selectionMode()\"\n [indentSize]=\"indentSize()\"\n [nodeTemplate]=\"nodeTemplate()\"\n [nodeTemplates]=\"nodeTemplates()\"\n [loadChildren]=\"loadChildren()\"\n [ancestors]=\"ancestorsWithSelf()\"\n (expandChange)=\"expandChange.emit($event)\"\n (selectionChange)=\"selectionChange.emit($event)\"\n />\n } }\n </ul>\n }\n</li>\n", styles: [".tree-node{list-style:none;margin:0;padding:0;outline:none;display:flex;flex-direction:column;gap:4px}.tree-node--selected>.tree-node__header>.tree-node__row{background:var(--color-background-accent);border-radius:var(--border-radius-m, 8px)}.tree-node--disabled{pointer-events:none;color:var(--color-text-disabled)}.tree-node--disabled>.tree-node__header{opacity:.5}.tree-node--focused>.tree-node__header>.tree-node__row,.tree-node:focus-visible>.tree-node__header>.tree-node__row{outline:2px solid var(--color-background-accent-inverse);outline-offset:-2px;border-radius:var(--border-radius-m, 8px)}.tree-node__header{display:flex;align-items:center;width:100%;min-height:57px;-webkit-user-select:none;user-select:none}.tree-node__header--expandable{cursor:pointer}.tree-node__row{display:flex;align-items:center;height:57px;flex:1;min-width:0;border-radius:var(--border-radius-m, 8px);transition:background .15s ease}.tree-node__header:hover>.tree-node__row{background:var(--color-background-secondary)}.tree-node--selected>.tree-node__header:hover>.tree-node__row{background:var(--color-background-accent)}.tree-node__indent{flex-shrink:0}.tree-node__chevron{display:flex;align-items:center;justify-content:center;flex-shrink:0;padding-left:16px;color:var(--color-text-primary)}.tree-node__chevron--leaf{width:0;padding-left:0;overflow:hidden}.tree-node__content{flex:1;min-width:0;display:flex;align-items:center;padding:4px 8px}.tree-node__selection{flex-shrink:0;margin-left:auto;margin-right:8px}.tree-node__label{font-size:var(--font-size-m, 16px);color:var(--color-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tree-node__children{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:4px}.tree-node__loading{display:flex;align-items:center;justify-content:center;padding:8px 16px}.tree-node__empty{display:flex;align-items:center;padding:8px 16px;font-size:var(--font-size-s, 14px);color:var(--color-text-secondary)}\n"], dependencies: [{ kind: "component", type: MozTreeNodeComponent, selector: "moz-tree-node", inputs: ["node", "depth", "selectionMode", "indentSize", "nodeTemplate", "nodeTemplates", "loadChildren", "ancestors", "flat", "noResultText"], outputs: ["expandChange", "selectionChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: MozCheckboxComponent, selector: "moz-checkbox", inputs: ["id", "name", "label", "indeterminate", "isInvalid", "disabled", "indented"] }, { kind: "component", type: MozRadioComponent, selector: "moz-radio", inputs: ["id", "name", "label", "isInvalid", "disabled"] }, { kind: "component", type: MozLoaderComponent, selector: "moz-loader", inputs: ["appearance", "size", "text"] }, { kind: "component", type: ChevronDown20, selector: "ChevronDown20", inputs: ["hostClass"] }, { kind: "component", type: ChevronRight20, selector: "ChevronRight20", inputs: ["hostClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
11830
11917
|
}
|
|
11831
11918
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: MozTreeNodeComponent, decorators: [{
|
|
11832
11919
|
type: Component,
|
|
@@ -11838,7 +11925,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
|
|
|
11838
11925
|
MozLoaderComponent,
|
|
11839
11926
|
ChevronDown20,
|
|
11840
11927
|
ChevronRight20,
|
|
11841
|
-
], template: "<li\n class=\"tree-node\"\n [class.tree-node--selected]=\"isSelected()\"\n [class.tree-node--disabled]=\"isDisabled()\"\n [class.tree-node--focused]=\"isFocused()\"\n role=\"treeitem\"\n [id]=\"'tree-node-' + node().id\"\n [attr.aria-level]=\"depth() + 1\"\n [attr.aria-expanded]=\"hasChildren() ? isExpanded() : null\"\n [attr.aria-selected]=\"selectionMode() !== 'none' ? isSelected() : null\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.data-tree-node-id]=\"node().id\"\n [tabindex]=\"isFocused() ? 0 : -1\"\n>\n <div\n class=\"tree-node__header\"\n [class.tree-node__header--expandable]=\"hasChildren()\"\n (click)=\"onHeaderClick()\"\n >\n <div class=\"tree-node__indent\" [style.width.px]=\"indentPx()\"></div>\n\n <span class=\"tree-node__chevron\" [class.tree-node__chevron--leaf]=\"!hasChildren()\">\n
|
|
11928
|
+
], template: "<li\n class=\"tree-node\"\n [class.tree-node--selected]=\"isSelected()\"\n [class.tree-node--disabled]=\"isDisabled()\"\n [class.tree-node--focused]=\"isFocused()\"\n role=\"treeitem\"\n [id]=\"'tree-node-' + node().id\"\n [attr.aria-level]=\"depth() + 1\"\n [attr.aria-expanded]=\"hasChildren() ? isExpanded() : null\"\n [attr.aria-selected]=\"selectionMode() !== 'none' ? isSelected() : null\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.data-tree-node-id]=\"node().id\"\n [tabindex]=\"isFocused() ? 0 : -1\"\n>\n <div\n class=\"tree-node__header\"\n [class.tree-node__header--expandable]=\"hasChildren()\"\n (click)=\"onHeaderClick()\"\n >\n <div class=\"tree-node__indent\" [style.width.px]=\"indentPx()\"></div>\n\n <div class=\"tree-node__row\">\n <span class=\"tree-node__chevron\" [class.tree-node__chevron--leaf]=\"!hasChildren()\">\n @if (hasChildren()) { @if (isExpanded()) {\n <ChevronDown20 />\n } @else {\n <ChevronRight20 />\n } }\n </span>\n\n <div class=\"tree-node__content\">\n @if (resolvedTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"resolvedTemplate()!\"\n [ngTemplateOutletContext]=\"templateContext()\"\n />\n } @else {\n <span class=\"tree-node__label\">{{ node().id }}</span>\n }\n </div>\n\n @if (selectionMode() === 'checkbox') {\n <moz-checkbox\n class=\"tree-node__selection\"\n [id]=\"'tree-checkbox-' + node().id\"\n [indeterminate]=\"isIndeterminate()\"\n [disabled]=\"isDisabled()\"\n [ngModel]=\"isSelected()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"onCheckboxChange($event)\"\n />\n } @else if (selectionMode() === 'radio') {\n <moz-radio\n class=\"tree-node__selection\"\n [id]=\"'tree-radio-' + node().id\"\n [name]=\"radioName\"\n [disabled]=\"isDisabled()\"\n [ngModel]=\"isSelected()\"\n (click)=\"$event.stopPropagation()\"\n (change)=\"onRadioChange($event)\"\n />\n }\n </div>\n </div>\n\n @if (isExpanded() && !flat()) {\n <ul class=\"tree-node__children\" role=\"group\">\n @if (isLoading()) {\n <li class=\"tree-node__loading\" role=\"presentation\">\n <moz-loader size=\"s\" [appearance]=\"'accent'\" />\n </li>\n } @else { @if (resolvedChildren().length === 0) {\n <li class=\"tree-node__empty\" role=\"presentation\">\n <span>{{ noResultText() }}</span>\n </li>\n } @for (child of resolvedChildren(); track child.id) {\n <moz-tree-node\n [node]=\"child\"\n [depth]=\"depth() + 1\"\n [selectionMode]=\"selectionMode()\"\n [indentSize]=\"indentSize()\"\n [nodeTemplate]=\"nodeTemplate()\"\n [nodeTemplates]=\"nodeTemplates()\"\n [loadChildren]=\"loadChildren()\"\n [ancestors]=\"ancestorsWithSelf()\"\n (expandChange)=\"expandChange.emit($event)\"\n (selectionChange)=\"selectionChange.emit($event)\"\n />\n } }\n </ul>\n }\n</li>\n", styles: [".tree-node{list-style:none;margin:0;padding:0;outline:none;display:flex;flex-direction:column;gap:4px}.tree-node--selected>.tree-node__header>.tree-node__row{background:var(--color-background-accent);border-radius:var(--border-radius-m, 8px)}.tree-node--disabled{pointer-events:none;color:var(--color-text-disabled)}.tree-node--disabled>.tree-node__header{opacity:.5}.tree-node--focused>.tree-node__header>.tree-node__row,.tree-node:focus-visible>.tree-node__header>.tree-node__row{outline:2px solid var(--color-background-accent-inverse);outline-offset:-2px;border-radius:var(--border-radius-m, 8px)}.tree-node__header{display:flex;align-items:center;width:100%;min-height:57px;-webkit-user-select:none;user-select:none}.tree-node__header--expandable{cursor:pointer}.tree-node__row{display:flex;align-items:center;height:57px;flex:1;min-width:0;border-radius:var(--border-radius-m, 8px);transition:background .15s ease}.tree-node__header:hover>.tree-node__row{background:var(--color-background-secondary)}.tree-node--selected>.tree-node__header:hover>.tree-node__row{background:var(--color-background-accent)}.tree-node__indent{flex-shrink:0}.tree-node__chevron{display:flex;align-items:center;justify-content:center;flex-shrink:0;padding-left:16px;color:var(--color-text-primary)}.tree-node__chevron--leaf{width:0;padding-left:0;overflow:hidden}.tree-node__content{flex:1;min-width:0;display:flex;align-items:center;padding:4px 8px}.tree-node__selection{flex-shrink:0;margin-left:auto;margin-right:8px}.tree-node__label{font-size:var(--font-size-m, 16px);color:var(--color-text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tree-node__children{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:4px}.tree-node__loading{display:flex;align-items:center;justify-content:center;padding:8px 16px}.tree-node__empty{display:flex;align-items:center;padding:8px 16px;font-size:var(--font-size-s, 14px);color:var(--color-text-secondary)}\n"] }]
|
|
11842
11929
|
}], propDecorators: { node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: true }] }], depth: [{ type: i0.Input, args: [{ isSignal: true, alias: "depth", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], indentSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "indentSize", required: false }] }], nodeTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeTemplate", required: false }] }], nodeTemplates: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeTemplates", required: false }] }], loadChildren: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadChildren", required: false }] }], ancestors: [{ type: i0.Input, args: [{ isSignal: true, alias: "ancestors", required: false }] }], flat: [{ type: i0.Input, args: [{ isSignal: true, alias: "flat", required: false }] }], noResultText: [{ type: i0.Input, args: [{ isSignal: true, alias: "noResultText", required: false }] }], expandChange: [{ type: i0.Output, args: ["expandChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }] } });
|
|
11843
11930
|
|
|
11844
11931
|
class MozTreeNodeTemplateDirective {
|
|
@@ -11907,9 +11994,44 @@ class MozTreeComponent {
|
|
|
11907
11994
|
effect(() => {
|
|
11908
11995
|
this.stateService.loadChildrenFn.set(this.loadChildren());
|
|
11909
11996
|
});
|
|
11997
|
+
// When children load for a node whose ID is in selectedIds,
|
|
11998
|
+
// replace the parent ID with its children's leaf IDs.
|
|
11999
|
+
let prevChildMap = new Map();
|
|
12000
|
+
effect(() => {
|
|
12001
|
+
const nodes = this.stateService.internalNodes();
|
|
12002
|
+
if (this.selectionService.selectionMode() !== 'checkbox')
|
|
12003
|
+
return;
|
|
12004
|
+
const newChildMap = new Map();
|
|
12005
|
+
const newlyLoadedParentIds = [];
|
|
12006
|
+
const visit = (list) => {
|
|
12007
|
+
for (const n of list) {
|
|
12008
|
+
const hadChildren = prevChildMap.get(n.id) ?? false;
|
|
12009
|
+
const hasChildrenNow = !!(n.children && n.children.length > 0);
|
|
12010
|
+
newChildMap.set(n.id, hasChildrenNow);
|
|
12011
|
+
if (!hadChildren && hasChildrenNow) {
|
|
12012
|
+
newlyLoadedParentIds.push(n.id);
|
|
12013
|
+
}
|
|
12014
|
+
if (n.children)
|
|
12015
|
+
visit(n.children);
|
|
12016
|
+
}
|
|
12017
|
+
};
|
|
12018
|
+
visit(nodes);
|
|
12019
|
+
prevChildMap = newChildMap;
|
|
12020
|
+
for (const parentId of newlyLoadedParentIds) {
|
|
12021
|
+
this.selectionService.propagateOnChildrenLoaded(parentId);
|
|
12022
|
+
}
|
|
12023
|
+
if (newlyLoadedParentIds.length > 0) {
|
|
12024
|
+
this.selectionChange.emit(this.selectionService.allSelectedIds());
|
|
12025
|
+
}
|
|
12026
|
+
});
|
|
11910
12027
|
}
|
|
11911
12028
|
onTreeKeydown(event) {
|
|
12029
|
+
const prevSelection = this.selectionService.allSelectedIds();
|
|
11912
12030
|
this.keyboardService.handleKeydown(event);
|
|
12031
|
+
const newSelection = this.selectionService.allSelectedIds();
|
|
12032
|
+
if (prevSelection !== newSelection) {
|
|
12033
|
+
this.selectionChange.emit(newSelection);
|
|
12034
|
+
}
|
|
11913
12035
|
}
|
|
11914
12036
|
onTreeFocus() {
|
|
11915
12037
|
this.keyboardService.initFocus();
|