agent-ecosystem/src/renderer/hooks/useContinuousScrollNav.ts
iliya 47dac2e8b5 feat: migrate to React 19
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
2026-03-24 17:11:55 +02:00

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,
};
}