mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-07 05:12:31 +02:00
fix(theme-common): use native scrolling when smooth behavior set in CSS (#7057)
* fix(theme-common): use native scrolling when smooth behavior set in CSS * fix * fix again * fix again
This commit is contained in:
parent
77662260f8
commit
4e45e14fdd
1 changed files with 17 additions and 16 deletions
|
@ -16,6 +16,7 @@ import React, {
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {useDynamicCallback, ReactContextError} from './reactUtils';
|
import {useDynamicCallback, ReactContextError} from './reactUtils';
|
||||||
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
||||||
|
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||||
|
|
||||||
type ScrollController = {
|
type ScrollController = {
|
||||||
/** A boolean ref tracking whether scroll events are enabled. */
|
/** A boolean ref tracking whether scroll events are enabled. */
|
||||||
|
@ -233,14 +234,6 @@ export function useScrollPositionBlocker(): {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not all have support for smooth scrolling (particularly Safari mobile iOS)
|
|
||||||
// TODO proper detection is currently unreliable!
|
|
||||||
// see https://github.com/wessberg/scroll-behavior-polyfill/issues/16
|
|
||||||
const SupportsNativeSmoothScrolling = false;
|
|
||||||
// const SupportsNativeSmoothScrolling =
|
|
||||||
// ExecutionEnvironment.canUseDOM &&
|
|
||||||
// 'scrollBehavior' in document.documentElement.style;
|
|
||||||
|
|
||||||
type CancelScrollTop = () => void;
|
type CancelScrollTop = () => void;
|
||||||
|
|
||||||
function smoothScrollNative(top: number): CancelScrollTop {
|
function smoothScrollNative(top: number): CancelScrollTop {
|
||||||
|
@ -260,10 +253,7 @@ function smoothScrollPolyfill(top: number): CancelScrollTop {
|
||||||
(!isUpScroll && currentScroll < top)
|
(!isUpScroll && currentScroll < top)
|
||||||
) {
|
) {
|
||||||
raf = requestAnimationFrame(rafRecursion);
|
raf = requestAnimationFrame(rafRecursion);
|
||||||
window.scrollTo(
|
window.scrollTo(0, Math.floor((currentScroll - top) * 0.85) + top);
|
||||||
0,
|
|
||||||
Math.floor(Math.abs(currentScroll - top) * 0.85) + top,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rafRecursion();
|
rafRecursion();
|
||||||
|
@ -275,8 +265,9 @@ function smoothScrollPolyfill(top: number): CancelScrollTop {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A "smart polyfill" of `window.scrollTo({ top, behavior: "smooth" })`.
|
* A "smart polyfill" of `window.scrollTo({ top, behavior: "smooth" })`.
|
||||||
* This currently always uses a polyfilled implementation, because native
|
* This currently always uses a polyfilled implementation unless
|
||||||
* support detection seems unreliable.
|
* `scroll-behavior: smooth` has been set in CSS, because native support
|
||||||
|
* detection for scroll behavior seems unreliable.
|
||||||
*
|
*
|
||||||
* This hook does not do anything by itself: it returns a start and a stop
|
* This hook does not do anything by itself: it returns a start and a stop
|
||||||
* handle. You can execute either handle at any time.
|
* handle. You can execute either handle at any time.
|
||||||
|
@ -296,12 +287,22 @@ export function useSmoothScrollTo(): {
|
||||||
cancelScroll: CancelScrollTop;
|
cancelScroll: CancelScrollTop;
|
||||||
} {
|
} {
|
||||||
const cancelRef = useRef<CancelScrollTop | null>(null);
|
const cancelRef = useRef<CancelScrollTop | null>(null);
|
||||||
|
const isBrowser = useIsBrowser();
|
||||||
|
// Not all have support for smooth scrolling (particularly Safari mobile iOS)
|
||||||
|
// TODO proper detection is currently unreliable!
|
||||||
|
// see https://github.com/wessberg/scroll-behavior-polyfill/issues/16
|
||||||
|
// For now, we only use native scroll behavior if smooth is already set,
|
||||||
|
// because otherwise the polyfill produces a weird UX when both CSS and JS try
|
||||||
|
// to scroll a page, and they cancel each other.
|
||||||
|
const supportsNativeSmoothScrolling =
|
||||||
|
isBrowser &&
|
||||||
|
getComputedStyle(document.documentElement).scrollBehavior === 'smooth';
|
||||||
return {
|
return {
|
||||||
startScroll: (top: number) => {
|
startScroll: (top: number) => {
|
||||||
cancelRef.current = SupportsNativeSmoothScrolling
|
cancelRef.current = supportsNativeSmoothScrolling
|
||||||
? smoothScrollNative(top)
|
? smoothScrollNative(top)
|
||||||
: smoothScrollPolyfill(top);
|
: smoothScrollPolyfill(top);
|
||||||
},
|
},
|
||||||
cancelScroll: () => cancelRef?.current,
|
cancelScroll: () => cancelRef.current?.(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue