From 8e8b9f53c974b918ce120c7327b60e26a88c3ddb Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Wed, 5 Nov 2025 10:02:45 +0100 Subject: [PATCH] fix(material-experimental/column-resize): add null checks for overlay Fixes some null pointer errors that show up in the logs for some internal apps. --- .../column-resize/resizable.ts | 30 ++++++++++--------- src/dev-app/theme-m3.scss | 3 +- .../column-resize/_column-resize-theme.scss | 4 +-- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/cdk-experimental/column-resize/resizable.ts b/src/cdk-experimental/column-resize/resizable.ts index c0fa419b8384..762f27ec0e5c 100644 --- a/src/cdk-experimental/column-resize/resizable.ts +++ b/src/cdk-experimental/column-resize/resizable.ts @@ -182,12 +182,15 @@ export abstract class Resizable private _listenForRowHoverEvents(): void { const element = this.elementRef.nativeElement!; - const takeUntilDestroyed = takeUntil(this.destroyed); this.eventDispatcher .resizeOverlayVisibleForHeaderRow(_closest(element, HEADER_ROW_SELECTOR)!) - .pipe(takeUntilDestroyed) + .pipe(takeUntil(this.destroyed)) .subscribe(hoveringRow => { + if (this._isDestroyed) { + return; + } + if (hoveringRow) { const tooBigToResize = this.maxWidthPxInternal < Number.MAX_SAFE_INTEGER && @@ -195,15 +198,12 @@ export abstract class Resizable element.classList.toggle(RESIZE_DISABLED_CLASS, tooBigToResize); if (!tooBigToResize) { - if (!this.overlayRef) { - this.overlayRef = this._createOverlayForHandle(); - } - + this.overlayRef ??= this._createOverlayForHandle(); this._showHandleOverlay(); } - } else if (this.overlayRef) { + } else { // todo - can't detach during an active resize - need to work that out - this.overlayRef.detach(); + this.overlayRef?.detach(); } }); } @@ -258,7 +258,7 @@ export abstract class Resizable private _cleanUpAfterResize(columnSize: ColumnSizeAction): void { this.elementRef.nativeElement!.classList.remove(OVERLAY_ACTIVE_CLASS); - if (this.overlayRef && this.overlayRef.hasAttached()) { + if (this.overlayRef?.hasAttached()) { this._updateOverlayHandleHeight(); this.overlayRef.updatePosition(); @@ -293,18 +293,20 @@ export abstract class Resizable } private _showHandleOverlay(): void { - this._updateOverlayHandleHeight(); - this.overlayRef!.attach(this._createHandlePortal()); + if (!this._isDestroyed) { + this._updateOverlayHandleHeight(); + this.overlayRef?.attach(this._createHandlePortal()); - // Needed to ensure that all of the lifecycle hooks inside the overlay run immediately. - this.changeDetectorRef.markForCheck(); + // Needed to ensure that all of the lifecycle hooks inside the overlay run immediately. + this.changeDetectorRef.markForCheck(); + } } private _updateOverlayHandleHeight() { runInInjectionContext(this.injector, () => { afterNextRender({ write: () => { - this.overlayRef!.updateSize({height: this.elementRef.nativeElement!.offsetHeight}); + this.overlayRef?.updateSize({height: this.elementRef.nativeElement!.offsetHeight}); }, }); }); diff --git a/src/dev-app/theme-m3.scss b/src/dev-app/theme-m3.scss index c079d88b24d0..9daf464fd72d 100644 --- a/src/dev-app/theme-m3.scss +++ b/src/dev-app/theme-m3.scss @@ -1,4 +1,5 @@ @use '@angular/material' as mat; +@use '@angular/material-experimental' as matx; // Plus imports for other components in your app. @@ -38,7 +39,7 @@ html { @include mat.system-level-colors($light-theme); @include mat.system-level-typography($light-theme); // TODO(mmalerba): Support M3 for experimental components. - // @include matx.column-resize-theme($light-theme); + @include matx.column-resize-theme($light-theme); // @include matx.popover-edit-theme($light-theme); } diff --git a/src/material-experimental/column-resize/_column-resize-theme.scss b/src/material-experimental/column-resize/_column-resize-theme.scss index 0eb01e0522b9..0f623c3df881 100644 --- a/src/material-experimental/column-resize/_column-resize-theme.scss +++ b/src/material-experimental/column-resize/_column-resize-theme.scss @@ -2,8 +2,8 @@ @use 'sass:map'; @mixin color($theme) { - $resizable-hover-divider: mat.get-theme-color($theme, primary, 600); - $resizable-active-divider: mat.get-theme-color($theme, primary, 600); + $resizable-hover-divider: mat.get-theme-color($theme, primary, 60); + $resizable-active-divider: mat.get-theme-color($theme, primary, 60); // TODO: these styles don't really belong in the `color` part of the theme. // We should figure out a better place for them.