From 7131e7eefaaac6a9ad8d9b7870bd4f9fa3a1ecce Mon Sep 17 00:00:00 2001 From: lskramarov Date: Thu, 2 Jul 2026 16:17:00 +0300 Subject: [PATCH] fix(tree-select): add missing takeUntil to prevent subscription leaks (#DS-5143) --- .../tree-select/tree-select.component.ts | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/packages/components/tree-select/tree-select.component.ts b/packages/components/tree-select/tree-select.component.ts index ec2cd0f4d..3ac2b7ec4 100644 --- a/packages/components/tree-select/tree-select.component.ts +++ b/packages/components/tree-select/tree-select.component.ts @@ -712,7 +712,7 @@ export class KbqTreeSelect this.selectionModel = tree.selectionModel = new SelectionModel(this.multiSelection); - this.selectionModel.changed.subscribe(() => { + this.selectionModel.changed.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => { this.onChange(this.selectedValues); if (this.multiSelection) { @@ -720,7 +720,9 @@ export class KbqTreeSelect } }); - this.selectionModel.changed.pipe(delay(0)).subscribe(() => this.setOverlayPosition()); + this.selectionModel.changed + .pipe(delay(0), takeUntilDestroyed(this.destroyRef)) + .subscribe(() => this.setOverlayPosition()); // eslint-disable-next-line @angular-eslint/no-lifecycle-call tree.ngAfterContentInit(); @@ -1119,6 +1121,12 @@ export class KbqTreeSelect const itemsCounter = this.trigger().nativeElement.querySelector('.kbq-select__match-hidden-text'); const matcherList = this.trigger().nativeElement.querySelector('.kbq-select__match-list'); + if (!itemsCounter || !matcherList) { + this.changeDetectorRef.markForCheck(); + + return; + } + const itemsCounterShowed = itemsCounter.offsetTop < itemsCounter.offsetHeight; const itemsCounterWidth: number = Math.floor(itemsCounter.getBoundingClientRect().width); @@ -1286,7 +1294,12 @@ export class KbqTreeSelect private getTotalVisibleItems(): [number, number] { const triggerClone = this.buildTriggerClone(); - this.renderer.setStyle(triggerClone.querySelector('.kbq-select__match-hidden-text'), 'display', 'block'); + const hiddenText = triggerClone.querySelector('.kbq-select__match-hidden-text'); + + if (hiddenText) { + this.renderer.setStyle(hiddenText, 'display', 'block'); + } + this.renderer.appendChild(this.trigger().nativeElement, triggerClone); let visibleItemsCount: number = 0; @@ -1437,9 +1450,14 @@ export class KbqTreeSelect if (!search?.ngControl.valueChanges) return; - search.ngControl.valueChanges.pipe(audit(() => this.tree()!.unorderedOptions.changes)).subscribe((value) => { - this.isEmptySearchResult = !!value && this.tree()!.isEmpty; - this.changeDetectorRef.markForCheck(); - }); + search.ngControl.valueChanges + .pipe( + audit(() => this.tree()!.unorderedOptions.changes), + takeUntilDestroyed(this.destroyRef) + ) + .subscribe((value) => { + this.isEmptySearchResult = !!value && this.tree()!.isEmpty; + this.changeDetectorRef.markForCheck(); + }); } }