Skip to content

Commit 9497b02

Browse files
crisbetoandrewseguin
authored andcommitted
fix(material-experimental/mdc-slider): update layout when container resizes (#24648)
Currently the layout of the slider can look broken, because the thumb positions don't update when the size of the container changes. These changes add some extra logic to trigger the resize in such cases. Fixes #24590. (cherry picked from commit 87ab4f4)
1 parent 6999af2 commit 9497b02

File tree

1 file changed

+35
-0
lines changed
  • src/material-experimental/mdc-slider

1 file changed

+35
-0
lines changed

src/material-experimental/mdc-slider/slider.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,12 @@ export class MatSlider
693693
/** Subscription to changes to the directionality (LTR / RTL) context for the application. */
694694
private _dirChangeSubscription: Subscription;
695695

696+
/** Observer used to monitor size changes in the slider. */
697+
private _resizeObserver: ResizeObserver | null;
698+
699+
/** Timeout used to debounce resize listeners. */
700+
private _resizeTimer: number;
701+
696702
constructor(
697703
readonly _ngZone: NgZone,
698704
readonly _cdr: ChangeDetectorRef,
@@ -727,6 +733,7 @@ export class MatSlider
727733
this._foundation.init();
728734
this._foundation.layout();
729735
this._initialized = true;
736+
this._observeHostResize();
730737
}
731738
// The MDC foundation requires access to the view and content children of the MatSlider. In
732739
// order to access the view and content children of MatSlider we need to wait until change
@@ -746,6 +753,9 @@ export class MatSlider
746753
this._foundation.destroy();
747754
}
748755
this._dirChangeSubscription.unsubscribe();
756+
this._resizeObserver?.disconnect();
757+
this._resizeObserver = null;
758+
clearTimeout(this._resizeTimer);
749759
this._removeUISyncEventListener();
750760
}
751761

@@ -919,6 +929,31 @@ export class MatSlider
919929
_isRippleDisabled(): boolean {
920930
return this.disabled || this.disableRipple || !!this._globalRippleOptions?.disabled;
921931
}
932+
933+
/** Starts observing and updating the slider if the host changes its size. */
934+
private _observeHostResize() {
935+
if (typeof ResizeObserver === 'undefined' || !ResizeObserver) {
936+
return;
937+
}
938+
939+
// MDC only updates the slider when the window is resized which
940+
// doesn't capture changes of the container itself. We use a resize
941+
// observer to ensure that the layout is correct (see #24590).
942+
this._ngZone.runOutsideAngular(() => {
943+
// The callback will fire as soon as an element is observed and
944+
// we only want to know after the initial layout.
945+
let hasResized = false;
946+
this._resizeObserver = new ResizeObserver(() => {
947+
if (hasResized) {
948+
// Debounce the layouts since they can happen frequently.
949+
clearTimeout(this._resizeTimer);
950+
this._resizeTimer = setTimeout(this._layout, 50);
951+
}
952+
hasResized = true;
953+
});
954+
this._resizeObserver.observe(this._elementRef.nativeElement);
955+
});
956+
}
922957
}
923958

924959
/** The MDCSliderAdapter implementation. */

0 commit comments

Comments
 (0)