Upgrade React 18.3.1 → 19.2.4 with full type compatibility. Changes: - react, react-dom → ^19.0.0 - @types/react, @types/react-dom → ^19.0.0 - lucide-react → ^0.577.0 (React 19 type fixes) - @tiptap/* → ^3.20.4 (React 19 support) - useRef calls now require explicit initial value (undefined) - RefObject types updated for React 19 (includes null) - MutableRefObject → RefObject (deprecated in 19) - act() import moved from react-dom/test-utils to react - Scoped JSX namespace imports added where needed
50 lines
1.3 KiB
TypeScript
50 lines
1.3 KiB
TypeScript
import { type RefObject, useCallback, useRef } from 'react';
|
|
|
|
import { waitForScrollEnd } from '@renderer/hooks/navigation/utils';
|
|
|
|
interface UseContinuousScrollNavOptions {
|
|
scrollContainerRef: RefObject<HTMLElement | null>;
|
|
}
|
|
|
|
interface UseContinuousScrollNavReturn {
|
|
scrollToFile: (filePath: string) => void;
|
|
isProgrammaticScroll: RefObject<boolean | null>;
|
|
}
|
|
|
|
export function useContinuousScrollNav(
|
|
options: UseContinuousScrollNavOptions
|
|
): UseContinuousScrollNavReturn {
|
|
const { scrollContainerRef } = options;
|
|
|
|
const isProgrammaticScroll = useRef(false);
|
|
const scrollGeneration = useRef(0);
|
|
|
|
const scrollToFile = useCallback(
|
|
(filePath: string) => {
|
|
const container = scrollContainerRef.current;
|
|
if (!container) return;
|
|
|
|
const section = container.querySelector<HTMLElement>(
|
|
`[data-file-path="${CSS.escape(filePath)}"]`
|
|
);
|
|
if (!section) return;
|
|
|
|
const gen = ++scrollGeneration.current;
|
|
isProgrammaticScroll.current = true;
|
|
|
|
section.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
|
|
void waitForScrollEnd(container, 500).then(() => {
|
|
if (scrollGeneration.current === gen) {
|
|
isProgrammaticScroll.current = false;
|
|
}
|
|
});
|
|
},
|
|
[scrollContainerRef]
|
|
);
|
|
|
|
return {
|
|
scrollToFile,
|
|
isProgrammaticScroll,
|
|
};
|
|
}
|