Initial commit
This commit is contained in:
80
src/contexts/ScrollHandlerContext.tsx
Normal file
80
src/contexts/ScrollHandlerContext.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
import {
|
||||
createContext,
|
||||
Dispatch,
|
||||
ReactNode,
|
||||
SetStateAction,
|
||||
useCallback,
|
||||
useContext,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
/**
|
||||
*
|
||||
*/
|
||||
interface ScrollHandlerContextType {
|
||||
categoryRefs: React.RefObject<{ [key: number]: HTMLDivElement | null }>;
|
||||
showScrollTop: boolean;
|
||||
setShowScrollTop: Dispatch<SetStateAction<boolean>>;
|
||||
isCategoriesSticky: boolean;
|
||||
setIsCategoriesSticky: Dispatch<SetStateAction<boolean>>;
|
||||
categoriesContainerRef: React.RefObject<HTMLDivElement>;
|
||||
scrollToCategory: (categoryId: number) => void;
|
||||
activeCategory: number | null;
|
||||
setActiveCategory: Dispatch<SetStateAction<number | null>>;
|
||||
}
|
||||
|
||||
const ScrollHandlerContext = createContext<
|
||||
ScrollHandlerContextType | undefined
|
||||
>(undefined);
|
||||
|
||||
export function ScrollHandlerProvider({ children }: { children: ReactNode }) {
|
||||
const categoryRefs = useRef<{ [key: number]: HTMLDivElement | null }>({});
|
||||
const [showScrollTop, setShowScrollTop] = useState(false);
|
||||
|
||||
// Handle scroll to show/hide scroll-to-top button and sticky categories
|
||||
const [isCategoriesSticky, setIsCategoriesSticky] = useState(false);
|
||||
const categoriesContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// Active category state
|
||||
const [activeCategory, setActiveCategory] = useState<number | null>(null);
|
||||
|
||||
// Function to scroll to a specific category
|
||||
const scrollToCategory = useCallback((categoryId: number) => {
|
||||
const categoryRef = categoryRefs.current?.[categoryId];
|
||||
if (categoryRef) {
|
||||
categoryRef.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "start",
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ScrollHandlerContext.Provider
|
||||
value={{
|
||||
categoryRefs,
|
||||
categoriesContainerRef,
|
||||
showScrollTop,
|
||||
setShowScrollTop,
|
||||
isCategoriesSticky,
|
||||
setIsCategoriesSticky,
|
||||
scrollToCategory,
|
||||
activeCategory,
|
||||
setActiveCategory,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ScrollHandlerContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-refresh/only-export-components
|
||||
export function useScrollHandler() {
|
||||
const context = useContext(ScrollHandlerContext);
|
||||
if (context === undefined) {
|
||||
throw new Error(
|
||||
"useScrollHandler must be used within a ScrollHandlerProvider"
|
||||
);
|
||||
}
|
||||
return context;
|
||||
}
|
||||
Reference in New Issue
Block a user