mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-09 17:33:55 +00:00
1849b4d39f
* chore: migrate eslint to oxlint * chore: migrate prettier to oxfmt * chore: migrate typescript * chore: toThrow should have a expected value * chore: cast test value as Day * chore: small title fix * chore: mocks should be hoisted * chore: incorrect async useage * chore: test should be inside description * chore: test sohuld include an expeced * chore: oxfmt --------- Co-authored-by: alex-Arc <omnivox@LAPTOP-RC5SNBVV.localdomain>
66 lines
2.1 KiB
TypeScript
66 lines
2.1 KiB
TypeScript
import { MaybeString } from 'ontime-types';
|
|
import { RefObject, useCallback, useEffect } from 'react';
|
|
|
|
function scrollToComponent<ComponentRef extends HTMLElement, ScrollRef extends HTMLElement>(
|
|
componentRef: RefObject<ComponentRef>,
|
|
scrollRef: RefObject<ScrollRef>,
|
|
topOffset: number,
|
|
) {
|
|
if (!componentRef.current || !scrollRef.current) {
|
|
return;
|
|
}
|
|
|
|
const componentRect = componentRef.current.getBoundingClientRect();
|
|
const scrollRect = scrollRef.current.getBoundingClientRect();
|
|
const top = componentRect.top - scrollRect.top + scrollRef.current.scrollTop - topOffset;
|
|
|
|
scrollRef.current.scrollTo({ top, behavior: 'smooth' });
|
|
}
|
|
|
|
interface UseFollowComponentProps {
|
|
followRef: RefObject<HTMLElement | null>;
|
|
scrollRef: RefObject<HTMLElement | null>;
|
|
doFollow: boolean;
|
|
topOffset?: number;
|
|
setScrollFlag?: (newValue: boolean) => void;
|
|
followTrigger?: MaybeString; // this would be an entry id or null
|
|
}
|
|
|
|
export default function useFollowComponent({
|
|
followRef,
|
|
scrollRef,
|
|
doFollow,
|
|
topOffset = 100,
|
|
setScrollFlag,
|
|
followTrigger,
|
|
}: UseFollowComponentProps) {
|
|
// when trigger moves, view should follow
|
|
useEffect(() => {
|
|
if (!doFollow || !followTrigger) {
|
|
return;
|
|
}
|
|
|
|
if (followRef.current && scrollRef.current) {
|
|
setScrollFlag?.(true);
|
|
// Use requestAnimationFrame to ensure the component is fully loaded
|
|
window.requestAnimationFrame(() => {
|
|
scrollToComponent(followRef as RefObject<HTMLElement>, scrollRef as RefObject<HTMLElement>, topOffset);
|
|
setScrollFlag?.(false);
|
|
});
|
|
}
|
|
}, [followTrigger, doFollow, followRef, scrollRef, setScrollFlag, topOffset]);
|
|
|
|
const scrollToRefComponent = useCallback(
|
|
(componentRef = followRef, containerRef = scrollRef, offset = topOffset) => {
|
|
if (componentRef && containerRef) {
|
|
// @ts-expect-error -- we know this are not null
|
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
scrollToComponent(componentRef!, containerRef!, offset);
|
|
}
|
|
},
|
|
[followRef, scrollRef, topOffset],
|
|
);
|
|
|
|
return scrollToRefComponent;
|
|
}
|