File size: 1,525 Bytes
5f40163 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | import React, { createContext, useContext, ReactNode, RefObject } from "react";
import { useScrollToBottom } from "#/hooks/use-scroll-to-bottom";
interface ScrollContextType {
scrollRef: RefObject<HTMLDivElement | null>;
autoScroll: boolean;
setAutoScroll: (value: boolean) => void;
scrollDomToBottom: () => void;
hitBottom: boolean;
setHitBottom: (value: boolean) => void;
onChatBodyScroll: (e: HTMLElement) => void;
}
export const ScrollContext = createContext<ScrollContextType | undefined>(
undefined,
);
interface ScrollProviderProps {
children: ReactNode;
value?: ScrollContextType;
}
export function ScrollProvider({ children, value }: ScrollProviderProps) {
const scrollHook = useScrollToBottom(React.useRef<HTMLDivElement>(null));
// Use provided value or default to the hook
const contextValue = value || scrollHook;
return (
<ScrollContext.Provider value={contextValue}>
{children}
</ScrollContext.Provider>
);
}
export function useScrollContext() {
const context = useContext(ScrollContext);
if (context === undefined) {
throw new Error("useScrollContext must be used within a ScrollProvider");
}
return context;
}
// Same as useScrollContext but returns undefined when no provider is mounted.
// Use this in components that have valid render paths both inside and outside
// the chat's ScrollProvider (e.g. GitControlBar in production vs. isolated
// test mounts).
export function useOptionalScrollContext() {
return useContext(ScrollContext);
}
|