mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-07 06:07:42 +02:00
* feat(v2): add back to top button * Test on mobiles * Use clean-btn class * Fix case * clearer useScrollPosition() hook * fix useScrollPosition typing + dangerous 0 fallback value + refactor a bit backToTop button * useless fallback * Handle both browsers with/without native smooth scrollBehavior support * fix SupportsNativeSmoothScrolling using document on SSR * revert to smoothScrollTopPolyfill usage Co-authored-by: slorber <lorber.sebastien@gmail.com>
52 lines
1.3 KiB
TypeScript
52 lines
1.3 KiB
TypeScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
import {useEffect, useRef} from 'react';
|
|
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
|
import type {ScrollPosition} from '@theme/hooks/useScrollPosition';
|
|
|
|
const getScrollPosition = (): ScrollPosition | null => {
|
|
return ExecutionEnvironment.canUseDOM
|
|
? {
|
|
scrollX: window.pageXOffset,
|
|
scrollY: window.pageYOffset,
|
|
}
|
|
: null;
|
|
};
|
|
|
|
const useScrollPosition = (
|
|
effect: (
|
|
position: ScrollPosition,
|
|
lastPosition: ScrollPosition | null,
|
|
) => void,
|
|
deps = [],
|
|
): void => {
|
|
const lastPositionRef = useRef<ScrollPosition | null>(getScrollPosition());
|
|
|
|
const handleScroll = () => {
|
|
const currentPosition = getScrollPosition()!;
|
|
|
|
if (effect) {
|
|
effect(currentPosition, lastPositionRef.current);
|
|
}
|
|
|
|
lastPositionRef.current = currentPosition;
|
|
};
|
|
|
|
useEffect(() => {
|
|
const opts: AddEventListenerOptions & EventListenerOptions = {
|
|
passive: true,
|
|
};
|
|
|
|
handleScroll();
|
|
window.addEventListener('scroll', handleScroll, opts);
|
|
|
|
return () => window.removeEventListener('scroll', handleScroll, opts);
|
|
}, deps);
|
|
};
|
|
|
|
export default useScrollPosition;
|