Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b7d3f3d

Browse files
atscottmmalerba
authored andcommitted
feat(common): Allow passing ScrollOptions to ViewportScroller (#61002)
Adds ScrollOptions as an option second argument to ViewportScroller scrollTo* functions. Part of changes needed to address #58258 PR Close #61002
1 parent 3735d55 commit b7d3f3d

File tree

3 files changed

+28
-11
lines changed

3 files changed

+28
-11
lines changed

‎goldens/public-api/common/index.api.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -959,8 +959,8 @@ export const VERSION: Version;
959959
// @public
960960
export abstract class ViewportScroller {
961961
abstract getScrollPosition(): [number, number];
962-
abstract scrollToAnchor(anchor: string): void;
963-
abstract scrollToPosition(position: [number, number]): void;
962+
abstract scrollToAnchor(anchor: string, options?: ScrollOptions): void;
963+
abstract scrollToPosition(position: [number, number], options?: ScrollOptions): void;
964964
abstract setHistoryScrollRestoration(scrollRestoration: 'auto' | 'manual'): void;
965965
abstract setOffset(offset: [number, number] | (() => [number, number])): void;
966966
// (undocumented)

‎packages/common/src/viewport_scroller.ts‎

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ export abstract class ViewportScroller {
4444
* Scrolls to a specified position.
4545
* @param position A position in screen coordinates (a tuple with x and y values).
4646
*/
47-
abstract scrollToPosition(position: [number, number]): void;
47+
abstract scrollToPosition(position: [number, number], options?: ScrollOptions): void;
4848

4949
/**
5050
* Scrolls to an anchor element.
5151
* @param anchor The ID of the anchor element.
5252
*/
53-
abstract scrollToAnchor(anchor: string): void;
53+
abstract scrollToAnchor(anchor: string, options?: ScrollOptions): void;
5454

5555
/**
5656
* Disables automatic scroll restoration provided by the browser.
@@ -97,8 +97,8 @@ export class BrowserViewportScroller implements ViewportScroller {
9797
* Sets the scroll position.
9898
* @param position The new position in screen coordinates.
9999
*/
100-
scrollToPosition(position: [number, number]): void {
101-
this.window.scrollTo(position[0], position[1]);
100+
scrollToPosition(position: [number, number], options?: ScrollOptions): void {
101+
this.window.scrollTo({...options, left: position[0], top: position[1]});
102102
}
103103

104104
/**
@@ -112,11 +112,11 @@ export class BrowserViewportScroller implements ViewportScroller {
112112
* @see https://html.spec.whatwg.org/#the-indicated-part-of-the-document
113113
* @see https://html.spec.whatwg.org/#scroll-to-fragid
114114
*/
115-
scrollToAnchor(target: string): void {
115+
scrollToAnchor(target: string, options?: ScrollOptions): void {
116116
const elSelected = findAnchorFromDocument(this.document, target);
117117

118118
if (elSelected) {
119-
this.scrollToElement(elSelected);
119+
this.scrollToElement(elSelected, options);
120120
// After scrolling to the element, the spec dictates that we follow the focus steps for the
121121
// target. Rather than following the robust steps, simply attempt focus.
122122
//
@@ -140,12 +140,16 @@ export class BrowserViewportScroller implements ViewportScroller {
140140
* The offset can be used when we know that there is a floating header and scrolling naively to an
141141
* element (ex: `scrollIntoView`) leaves the element hidden behind the floating header.
142142
*/
143-
private scrollToElement(el: HTMLElement): void {
143+
private scrollToElement(el: HTMLElement, options?: ScrollOptions): void {
144144
const rect = el.getBoundingClientRect();
145145
const left = rect.left + this.window.pageXOffset;
146146
const top = rect.top + this.window.pageYOffset;
147147
const offset = this.offset();
148-
this.window.scrollTo(left - offset[0], top - offset[1]);
148+
this.window.scrollTo({
149+
...options,
150+
left: left - offset[0],
151+
top: top - offset[1],
152+
});
149153
}
150154
}
151155

‎packages/common/test/viewport_scroller_spec.ts‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,15 @@ describe('BrowserViewportScroller', () => {
3636
expect(() => scroller.setHistoryScrollRestoration('manual')).not.toThrow();
3737
});
3838

39+
it('should not allow overwriting position with options', () => {
40+
scroller.scrollToPosition([10, 10], {top: 0, left: 0} as any);
41+
expect(windowSpy.scrollTo).toHaveBeenCalledWith({top: 10, left: 10});
42+
});
43+
3944
it('should still allow scrolling if scrollRestoration is not writable', () => {
4045
createNonWritableScrollRestoration();
4146
scroller.scrollToPosition([10, 10]);
42-
expect(windowSpy.scrollTo as jasmine.Spy).toHaveBeenCalledWith(10, 10);
47+
expect(windowSpy.scrollTo).toHaveBeenCalledWith({top: 10, left: 10});
4348
});
4449
});
4550

@@ -98,6 +103,14 @@ describe('BrowserViewportScroller', () => {
98103
cleanup();
99104
});
100105

106+
it('should not allow overwriting position with options', () => {
107+
const {anchorNode, cleanup} = createTallElementWithShadowRoot();
108+
anchorNode.name = anchor;
109+
scroller.scrollToAnchor(anchor, {top: 0, left: 0} as any);
110+
expect(scroller.getScrollPosition()[1]).not.toEqual(0);
111+
cleanup();
112+
});
113+
101114
function createTallElement() {
102115
const tallItem = document.createElement('div');
103116
tallItem.style.height = '3000px';

0 commit comments

Comments
 (0)