Skip to content

Commit 5f4609d

Browse files
committed
fixup! feat(cdk/scrolling): make scroller element configurable for virtual scrolling
1 parent 2fa56ed commit 5f4609d

File tree

6 files changed

+55
-21
lines changed

6 files changed

+55
-21
lines changed

src/cdk/scrolling/scrollable.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,11 @@ export type ExtendedScrollToOptions = _XAxis & _YAxis & ScrollOptions;
4545
selector: '[cdk-scrollable], [cdkScrollable]',
4646
})
4747
export class CdkScrollable implements OnInit, OnDestroy {
48-
private readonly _destroyed = new Subject<void>();
48+
protected readonly _destroyed = new Subject<void>();
4949

50-
private _elementScrolled: Observable<Event> = new Observable((observer: Observer<Event>) =>
50+
protected _elementScrolled: Observable<Event> = new Observable((observer: Observer<Event>) =>
5151
this.ngZone.runOutsideAngular(() =>
52-
/* it seems like scroll-events are not fired on the documentElement, event if it's the actual scrolling element */
53-
fromEvent(
54-
this.elementRef.nativeElement === document.documentElement
55-
? document
56-
: this.elementRef.nativeElement,
57-
'scroll',
58-
)
52+
fromEvent(this.elementRef.nativeElement, 'scroll')
5953
.pipe(takeUntil(this._destroyed))
6054
.subscribe(observer),
6155
),

src/cdk/scrolling/virtual-scroll-viewport.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
OnInit,
2121
Optional,
2222
Output,
23-
Renderer2,
2423
ViewChild,
2524
ViewEncapsulation,
2625
} from '@angular/core';
@@ -69,8 +68,11 @@ const SCROLL_SCHEDULER =
6968
providers: [
7069
{
7170
provide: CdkScrollable,
72-
useFactory: (scrollViewport: CdkVirtualScrollViewport) => scrollViewport.scrollable,
73-
deps: [CdkVirtualScrollViewport],
71+
useFactory: (
72+
virtualScrollable: CdkVirtualScrollable | null,
73+
viewport: CdkVirtualScrollViewport,
74+
) => virtualScrollable || viewport,
75+
deps: [CdkVirtualScrollable, CdkVirtualScrollViewport],
7476
},
7577
],
7678
})
@@ -86,6 +88,7 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
8688
get orientation() {
8789
return this._orientation;
8890
}
91+
8992
set orientation(orientation: 'horizontal' | 'vertical') {
9093
if (this._orientation !== orientation) {
9194
this._orientation = orientation;
@@ -182,7 +185,6 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
182185
@Optional() dir: Directionality,
183186
scrollDispatcher: ScrollDispatcher,
184187
viewportRuler: ViewportRuler,
185-
renderer: Renderer2,
186188
@Optional() @Inject(VIRTUAL_SCROLLABLE) public scrollable: CdkVirtualScrollable,
187189
) {
188190
super(elementRef, scrollDispatcher, ngZone, dir);
@@ -197,7 +199,7 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
197199

198200
if (!this.scrollable) {
199201
// No scrollable is provided, so the virtual-scroll-viewport needs to become a scrollable
200-
renderer.addClass(this.elementRef.nativeElement, 'cdk-virtual-scrollable');
202+
this.elementRef.nativeElement.classList.add('cdk-virtual-scrollable');
201203
this.scrollable = this;
202204
}
203205
}
@@ -292,6 +294,10 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
292294
return this._renderedRange;
293295
}
294296

297+
getBoundingClientRectWithScrollOffset(from: 'left' | 'top' | 'right' | 'bottom'): number {
298+
return this.getElementRef().nativeElement.getBoundingClientRect()[from];
299+
}
300+
295301
/**
296302
* Sets the total size of all content (in pixels), including content that is not currently
297303
* rendered.
@@ -425,9 +431,7 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
425431
fromRect = this.orientation === 'horizontal' ? 'left' : 'top';
426432
}
427433

428-
const scrollerClientRect = this.scrollable
429-
.getElementRef()
430-
.nativeElement.getBoundingClientRect()[fromRect];
434+
const scrollerClientRect = this.scrollable.getBoundingClientRectWithScrollOffset(fromRect);
431435
const viewportClientRect = this.elementRef.nativeElement.getBoundingClientRect()[fromRect];
432436

433437
return viewportClientRect - scrollerClientRect;

src/cdk/scrolling/virtual-scrollable-element.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,11 @@ export class CdkVirtualScrollableElement extends CdkVirtualScrollable {
2727
) {
2828
super(elementRef, scrollDispatcher, ngZone, dir);
2929
}
30+
31+
getBoundingClientRectWithScrollOffset(from: 'left' | 'top' | 'right' | 'bottom'): number {
32+
return (
33+
this.getElementRef().nativeElement.getBoundingClientRect()[from] -
34+
this.measureScrollOffset(from)
35+
);
36+
}
3037
}

src/cdk/scrolling/virtual-scrollable-window.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
import {Directionality} from '@angular/cdk/bidi';
1010
import {Directive, ElementRef, NgZone, Optional} from '@angular/core';
11+
import {fromEvent, Observable, Observer} from 'rxjs';
12+
import {takeUntil} from 'rxjs/operators';
1113
import {ScrollDispatcher} from './scroll-dispatcher';
1214
import {CdkVirtualScrollable, VIRTUAL_SCROLLABLE} from './virtual-scrollable';
1315

@@ -16,7 +18,18 @@ import {CdkVirtualScrollable, VIRTUAL_SCROLLABLE} from './virtual-scrollable';
1618
providers: [{provide: VIRTUAL_SCROLLABLE, useExisting: CdkVirtualScrollableWindow}],
1719
})
1820
export class CdkVirtualScrollableWindow extends CdkVirtualScrollable {
21+
protected override _elementScrolled: Observable<Event> = new Observable(
22+
(observer: Observer<Event>) =>
23+
this.ngZone.runOutsideAngular(() =>
24+
fromEvent(document, 'scroll').pipe(takeUntil(this._destroyed)).subscribe(observer),
25+
),
26+
);
27+
1928
constructor(scrollDispatcher: ScrollDispatcher, ngZone: NgZone, @Optional() dir: Directionality) {
2029
super(new ElementRef(document.documentElement), scrollDispatcher, ngZone, dir);
2130
}
31+
32+
getBoundingClientRectWithScrollOffset(from: 'left' | 'top' | 'right' | 'bottom'): number {
33+
return this.getElementRef().nativeElement.getBoundingClientRect()[from];
34+
}
2235
}

src/cdk/scrolling/virtual-scrollable.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,6 @@ export abstract class CdkVirtualScrollable extends CdkScrollable {
2828
const viewportEl = this.elementRef.nativeElement;
2929
return orientation === 'horizontal' ? viewportEl.clientWidth : viewportEl.clientHeight;
3030
}
31+
32+
abstract getBoundingClientRectWithScrollOffset(from: 'left' | 'top' | 'right' | 'bottom'): number;
3133
}

tools/public_api_guard/cdk/scrolling.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { Directionality } from '@angular/cdk/bidi';
1212
import { DoCheck } from '@angular/core';
1313
import { ElementRef } from '@angular/core';
1414
import * as i0 from '@angular/core';
15-
import * as i5 from '@angular/cdk/bidi';
15+
import * as i7 from '@angular/cdk/bidi';
1616
import { InjectionToken } from '@angular/core';
1717
import { IterableDiffers } from '@angular/core';
1818
import { ListRange } from '@angular/cdk/collections';
@@ -63,10 +63,14 @@ export class CdkFixedSizeVirtualScroll implements OnChanges {
6363
export class CdkScrollable implements OnInit, OnDestroy {
6464
constructor(elementRef: ElementRef<HTMLElement>, scrollDispatcher: ScrollDispatcher, ngZone: NgZone, dir?: Directionality | undefined);
6565
// (undocumented)
66+
protected readonly _destroyed: Subject<void>;
67+
// (undocumented)
6668
protected dir?: Directionality | undefined;
6769
// (undocumented)
6870
protected elementRef: ElementRef<HTMLElement>;
6971
elementScrolled(): Observable<Event>;
72+
// (undocumented)
73+
protected _elementScrolled: Observable<Event>;
7074
getElementRef(): ElementRef<HTMLElement>;
7175
measureScrollOffset(from: 'top' | 'left' | 'right' | 'bottom' | 'start' | 'end'): number;
7276
// (undocumented)
@@ -140,6 +144,8 @@ export type CdkVirtualForOfContext<T> = {
140144
export abstract class CdkVirtualScrollable extends CdkScrollable {
141145
constructor(elementRef: ElementRef<HTMLElement>, scrollDispatcher: ScrollDispatcher, ngZone: NgZone, dir?: Directionality);
142146
// (undocumented)
147+
abstract getBoundingClientRectWithScrollOffset(from: 'left' | 'top' | 'right' | 'bottom'): number;
148+
// (undocumented)
143149
measureViewportSize(orientation: 'horizontal' | 'vertical'): number;
144150
// (undocumented)
145151
static ɵdir: i0.ɵɵDirectiveDeclaration<CdkVirtualScrollable, never, never, {}, {}, never>;
@@ -151,6 +157,8 @@ export abstract class CdkVirtualScrollable extends CdkScrollable {
151157
export class CdkVirtualScrollableElement extends CdkVirtualScrollable {
152158
constructor(elementRef: ElementRef, scrollDispatcher: ScrollDispatcher, ngZone: NgZone, dir: Directionality);
153159
// (undocumented)
160+
getBoundingClientRectWithScrollOffset(from: 'left' | 'top' | 'right' | 'bottom'): number;
161+
// (undocumented)
154162
static ɵdir: i0.ɵɵDirectiveDeclaration<CdkVirtualScrollableElement, "[cdk-virtual-scrollable-element], [cdkVirtualScrollableElement]", never, {}, {}, never>;
155163
// (undocumented)
156164
static ɵfac: i0.ɵɵFactoryDeclaration<CdkVirtualScrollableElement, [null, null, null, { optional: true; }]>;
@@ -160,6 +168,10 @@ export class CdkVirtualScrollableElement extends CdkVirtualScrollable {
160168
export class CdkVirtualScrollableWindow extends CdkVirtualScrollable {
161169
constructor(scrollDispatcher: ScrollDispatcher, ngZone: NgZone, dir: Directionality);
162170
// (undocumented)
171+
protected _elementScrolled: Observable<Event>;
172+
// (undocumented)
173+
getBoundingClientRectWithScrollOffset(from: 'left' | 'top' | 'right' | 'bottom'): number;
174+
// (undocumented)
163175
static ɵdir: i0.ɵɵDirectiveDeclaration<CdkVirtualScrollableWindow, "cdk-virtual-scroll-viewport[scrollable-window]", never, {}, {}, never>;
164176
// (undocumented)
165177
static ɵfac: i0.ɵɵFactoryDeclaration<CdkVirtualScrollableWindow, [null, null, { optional: true; }]>;
@@ -175,7 +187,7 @@ export interface CdkVirtualScrollRepeater<T> {
175187

176188
// @public
177189
export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements OnInit, OnDestroy {
178-
constructor(elementRef: ElementRef<HTMLElement>, _changeDetectorRef: ChangeDetectorRef, ngZone: NgZone, _scrollStrategy: VirtualScrollStrategy, dir: Directionality, scrollDispatcher: ScrollDispatcher, viewportRuler: ViewportRuler, renderer: Renderer2, scrollable: CdkVirtualScrollable);
190+
constructor(elementRef: ElementRef<HTMLElement>, _changeDetectorRef: ChangeDetectorRef, ngZone: NgZone, _scrollStrategy: VirtualScrollStrategy, dir: Directionality, scrollDispatcher: ScrollDispatcher, viewportRuler: ViewportRuler, scrollable: CdkVirtualScrollable);
179191
get appendOnly(): boolean;
180192
set appendOnly(value: BooleanInput);
181193
attach(forOf: CdkVirtualScrollRepeater<any>): void;
@@ -184,6 +196,8 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
184196
detach(): void;
185197
// (undocumented)
186198
elementRef: ElementRef<HTMLElement>;
199+
// (undocumented)
200+
getBoundingClientRectWithScrollOffset(from: 'left' | 'top' | 'right' | 'bottom'): number;
187201
getDataLength(): number;
188202
getOffsetToRenderedContentStart(): number | null;
189203
getRenderedRange(): ListRange;
@@ -213,7 +227,7 @@ export class CdkVirtualScrollViewport extends CdkVirtualScrollable implements On
213227
// (undocumented)
214228
static ɵcmp: i0.ɵɵComponentDeclaration<CdkVirtualScrollViewport, "cdk-virtual-scroll-viewport", never, { "orientation": "orientation"; "appendOnly": "appendOnly"; }, { "scrolledIndexChange": "scrolledIndexChange"; }, never, ["*"]>;
215229
// (undocumented)
216-
static ɵfac: i0.ɵɵFactoryDeclaration<CdkVirtualScrollViewport, [null, null, null, { optional: true; }, { optional: true; }, null, null, null, { optional: true; }]>;
230+
static ɵfac: i0.ɵɵFactoryDeclaration<CdkVirtualScrollViewport, [null, null, null, { optional: true; }, { optional: true; }, null, null, { optional: true; }]>;
217231
}
218232

219233
// @public
@@ -283,7 +297,7 @@ export class ScrollingModule {
283297
// (undocumented)
284298
static ɵinj: i0.ɵɵInjectorDeclaration<ScrollingModule>;
285299
// (undocumented)
286-
static ɵmod: i0.ɵɵNgModuleDeclaration<ScrollingModule, [typeof i2.CdkFixedSizeVirtualScroll, typeof i3.CdkVirtualForOf, typeof i4.CdkVirtualScrollViewport], [typeof i5.BidiModule, typeof CdkScrollableModule], [typeof i5.BidiModule, typeof CdkScrollableModule, typeof i2.CdkFixedSizeVirtualScroll, typeof i3.CdkVirtualForOf, typeof i4.CdkVirtualScrollViewport]>;
300+
static ɵmod: i0.ɵɵNgModuleDeclaration<ScrollingModule, [typeof i2.CdkFixedSizeVirtualScroll, typeof i3.CdkVirtualForOf, typeof i4.CdkVirtualScrollViewport, typeof i5.CdkVirtualScrollableWindow, typeof i6.CdkVirtualScrollableElement], [typeof i7.BidiModule, typeof CdkScrollableModule], [typeof i7.BidiModule, typeof CdkScrollableModule, typeof i2.CdkFixedSizeVirtualScroll, typeof i3.CdkVirtualForOf, typeof i4.CdkVirtualScrollViewport, typeof i5.CdkVirtualScrollableWindow, typeof i6.CdkVirtualScrollableElement]>;
287301
}
288302

289303
// @public (undocumented)

0 commit comments

Comments
 (0)