* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { scrollHorizontally, scrollToElement } from '../scrolling';
+import { scrollToElement } from '../scrolling';
beforeAll(() => {
jest.useFakeTimers();
});
});
-describe('scrollHorizontally', () => {
- it('should scroll parent left to element', () => {
- const element = document.createElement('a');
- element.getBoundingClientRect = mockGetBoundingClientRect({ left: 25, right: 42 });
-
- const parent = document.createElement('div');
- parent.getBoundingClientRect = mockGetBoundingClientRect({ width: 67, left: 46 });
- parent.scrollTop = 12;
- parent.scrollLeft = 38;
- parent.appendChild(element);
-
- document.body.appendChild(parent);
-
- scrollHorizontally(element, { parent, smooth: false });
-
- expect(parent.scrollTop).toEqual(12);
- expect(parent.scrollLeft).toEqual(17);
- });
-
- it('should scroll parent right to element', () => {
- const element = document.createElement('a');
- element.getBoundingClientRect = mockGetBoundingClientRect({ left: 25, right: 99 });
-
- const parent = document.createElement('div');
- parent.getBoundingClientRect = mockGetBoundingClientRect({ width: 67, left: 20 });
- parent.scrollTop = 12;
- parent.scrollLeft = 20;
- parent.appendChild(element);
-
- document.body.appendChild(parent);
-
- scrollHorizontally(element, { parent, smooth: false });
-
- expect(parent.scrollTop).toEqual(12);
- expect(parent.scrollLeft).toEqual(32);
- });
-
- it('should scroll window right to element', () => {
- const element = document.createElement('a');
- element.getBoundingClientRect = mockGetBoundingClientRect({ left: 840, right: 845 });
-
- Object.defineProperty(window, 'innerWidth', { value: 400 });
- window.scrollTo = jest.fn();
-
- document.body.appendChild(element);
-
- scrollHorizontally(element, { smooth: false });
-
- expect(window.scrollTo).toHaveBeenCalledWith(445, 0);
- });
-
- it('should scroll window left to element', () => {
- const element = document.createElement('a');
- element.getBoundingClientRect = mockGetBoundingClientRect({ left: -10, right: 10 });
-
- Object.defineProperty(window, 'innerWidth', { value: 50 });
- window.scrollTo = jest.fn();
-
- document.body.appendChild(element);
-
- scrollHorizontally(element, { smooth: false });
-
- expect(window.scrollTo).toHaveBeenCalledWith(-10, 0);
- });
-
- it('should scroll window right to element smoothly', () => {
- const element = document.createElement('a');
- element.getBoundingClientRect = mockGetBoundingClientRect({ left: 840, right: 845 });
-
- Object.defineProperty(window, 'innerWidth', { value: 400 });
- window.scrollTo = jest.fn();
-
- document.body.appendChild(element);
-
- scrollHorizontally(element, {});
-
- jest.runAllTimers();
-
- expect(window.scrollTo).toHaveBeenCalledTimes(10);
- });
-});
-
-it('correctly queues and processes multiple scroll calls', async () => {
- const element1 = document.createElement('a');
- const element2 = document.createElement('a');
- document.body.appendChild(element1);
- document.body.appendChild(element2);
- element1.getBoundingClientRect = mockGetBoundingClientRect({ left: 840, right: 845 });
- element2.getBoundingClientRect = mockGetBoundingClientRect({ top: -10, bottom: 10 });
-
- window.scrollTo = jest.fn();
-
- scrollHorizontally(element1, {});
- scrollToElement(element2, { smooth: false });
-
- jest.runAllTimers();
- await Promise.resolve(setImmediate);
- await Promise.resolve(setImmediate);
-
- expect(window.scrollTo).toHaveBeenCalledTimes(11);
-
- scrollHorizontally(element1, {});
- jest.runAllTimers();
- expect(window.scrollTo).toHaveBeenCalledTimes(21);
-});
-
const mockGetBoundingClientRect = (overrides: Partial<ClientRect>) => () =>
({
bottom: 0,
return smoothScroll(position, scroll.y, (position) => scrollElement(parent, scroll.x, position));
}
-function smoothScrollLeft(parent: Element | Window, position: number) {
- const scroll = getScroll(parent);
- return smoothScroll(position, scroll.x, (position) => scrollElement(parent, position, scroll.y));
-}
-
/**
* @deprecated use scrollIntoView instead
*/
}
}
-/**
- * @deprecated use scrollIntoView instead
- */
-export function scrollHorizontally(
- element: Element,
- options: {
- leftOffset?: number;
- rightOffset?: number;
- parent?: Element;
- smooth?: boolean;
- }
-): void {
- const opts = { leftOffset: 0, rightOffset: 0, parent: window, smooth: true, ...options };
- const { parent } = opts;
-
- const { left, right } = element.getBoundingClientRect();
-
- const scroll = getScroll(parent);
-
- const { left: parentLeft, width } = isWindow(parent)
- ? { left: 0, width: window.innerWidth }
- : parent.getBoundingClientRect();
-
- if (left - parentLeft < opts.leftOffset) {
- const goal = scroll.x - opts.leftOffset + left - parentLeft;
- if (opts.smooth) {
- addToScrollQueue(smoothScrollLeft, parent, goal);
- } else {
- addToScrollQueue(scrollElement, parent, goal, scroll.y);
- }
- }
-
- if (right - parentLeft > width - opts.rightOffset) {
- const goal = scroll.x + right - parentLeft - width + opts.rightOffset;
- if (opts.smooth) {
- addToScrollQueue(smoothScrollLeft, parent, goal);
- } else {
- addToScrollQueue(scrollElement, parent, goal, scroll.y);
- }
- }
-}
-
type ScrollFunction = (element: Element | Window, x: number, y?: number) => Promise<void>;
interface ScrollQueueItem {