Skip to content

Commit

Permalink
fix(material-experimental/mdc-slider): update layout when container r…
Browse files Browse the repository at this point in the history
…esizes (#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.
  • Loading branch information
crisbeto authored Mar 27, 2022
1 parent 0d6244a commit 87ab4f4
Showing 1 changed file with 35 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/material-experimental/mdc-slider/slider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,12 @@ export class MatSlider
/** Subscription to changes to the directionality (LTR / RTL) context for the application. */
private _dirChangeSubscription: Subscription;

/** Observer used to monitor size changes in the slider. */
private _resizeObserver: ResizeObserver | null;

/** Timeout used to debounce resize listeners. */
private _resizeTimer: number;

constructor(
readonly _ngZone: NgZone,
readonly _cdr: ChangeDetectorRef,
Expand Down Expand Up @@ -727,6 +733,7 @@ export class MatSlider
this._foundation.init();
this._foundation.layout();
this._initialized = true;
this._observeHostResize();
}
// The MDC foundation requires access to the view and content children of the MatSlider. In
// order to access the view and content children of MatSlider we need to wait until change
Expand All @@ -746,6 +753,9 @@ export class MatSlider
this._foundation.destroy();
}
this._dirChangeSubscription.unsubscribe();
this._resizeObserver?.disconnect();
this._resizeObserver = null;
clearTimeout(this._resizeTimer);
this._removeUISyncEventListener();
}

Expand Down Expand Up @@ -919,6 +929,31 @@ export class MatSlider
_isRippleDisabled(): boolean {
return this.disabled || this.disableRipple || !!this._globalRippleOptions?.disabled;
}

/** Starts observing and updating the slider if the host changes its size. */
private _observeHostResize() {
if (typeof ResizeObserver === 'undefined' || !ResizeObserver) {
return;
}

// MDC only updates the slider when the window is resized which
// doesn't capture changes of the container itself. We use a resize
// observer to ensure that the layout is correct (see #24590).
this._ngZone.runOutsideAngular(() => {
// The callback will fire as soon as an element is observed and
// we only want to know after the initial layout.
let hasResized = false;
this._resizeObserver = new ResizeObserver(() => {
if (hasResized) {
// Debounce the layouts since they can happen frequently.
clearTimeout(this._resizeTimer);
this._resizeTimer = setTimeout(this._layout, 50);
}
hasResized = true;
});
this._resizeObserver.observe(this._elementRef.nativeElement);
});
}
}

/** The MDCSliderAdapter implementation. */
Expand Down

0 comments on commit 87ab4f4

Please sign in to comment.