The communications platform that puts data protection first.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
Rocket.Chat/apps/meteor/client/hooks/useRouterScrollToHash.ts

39 lines
1.0 KiB

import { usePrefersReducedMotion } from '@rocket.chat/fuselage-hooks';
import type { RouterContextValue } from '@rocket.chat/ui-contexts';
import { useEffect, useRef, useSyncExternalStore } from 'react';
/**
* Scrolls to the element matching the current URL hash on route changes.
*
* @see docs/anchor-navigation.md
*/
export const useRouterScrollToHash = (router: RouterContextValue) => {
const hash = useSyncExternalStore(router.subscribeToRouteChange, router.getLocationHash);
const reducedMotion = usePrefersReducedMotion();
const previousHash = useRef<string | null>(null);
useEffect(() => {
const id = hash.slice(1);
if (!id) {
previousHash.current = hash;
return;
}
if (hash === previousHash.current) {
return;
}
previousHash.current = hash;
const frame = requestAnimationFrame(() => {
document.getElementById(id)?.scrollIntoView({
behavior: reducedMotion ? 'auto' : 'smooth',
block: 'start',
});
});
return () => cancelAnimationFrame(frame);
}, [hash, reducedMotion]);
};