'use client'; import { useBreakpoints } from '@/internal/hooks/useBreakpoints'; import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from 'react'; import type { ReactNode, Dispatch, SetStateAction } from 'react'; import type { WalletAdvancedFeature } from '../types'; import { getAnimations } from '../utils/getAnimations'; import { calculateSubComponentPosition } from '../utils/getWalletSubComponentPosition'; export type WalletContextType = { /** The breakpoint of the current device */ breakpoint: string | undefined; /** Whether the connect modal is open */ isConnectModalOpen: boolean; setIsConnectModalOpen: Dispatch>; isSubComponentOpen: boolean; setIsSubComponentOpen: Dispatch>; isSubComponentClosing: boolean; setIsSubComponentClosing: Dispatch>; handleClose: () => void; connectRef: React.RefObject; showSubComponentAbove: boolean; alignSubComponentRight: boolean; activeFeature: WalletAdvancedFeature | null; setActiveFeature: Dispatch>; isActiveFeatureClosing: boolean; setIsActiveFeatureClosing: Dispatch>; animations: { container: string; content: string; }; /** Whether to sponsor transactions for Send feature of advanced wallet implementation */ isSponsored?: boolean; }; export const WalletContext = createContext(null); type WalletProviderProps = { children: ReactNode; /** Whether to sponsor transactions for Send feature of advanced wallet implementation */ isSponsored?: boolean; }; export function WalletProvider({ children, isSponsored }: WalletProviderProps) { const [isConnectModalOpen, setIsConnectModalOpen] = useState(false); const [isSubComponentOpen, setIsSubComponentOpen] = useState(false); const [isSubComponentClosing, setIsSubComponentClosing] = useState(false); const [showSubComponentAbove, setShowSubComponentAbove] = useState(false); const [alignSubComponentRight, setAlignSubComponentRight] = useState(false); const connectRef = useRef(null); const breakpoint = useBreakpoints(); const [activeFeature, setActiveFeature] = useState(null); const [isActiveFeatureClosing, setIsActiveFeatureClosing] = useState(false); const animations = useMemo(() => { return getAnimations(isSubComponentClosing, showSubComponentAbove); }, [isSubComponentClosing, showSubComponentAbove]); const handleClose = useCallback(() => { if (!isSubComponentOpen) { return; } setIsSubComponentClosing(true); }, [isSubComponentOpen]); useEffect(() => { if (isSubComponentOpen && connectRef?.current) { const connectRect = connectRef.current.getBoundingClientRect(); const position = calculateSubComponentPosition(connectRect); setShowSubComponentAbove(position.showAbove); setAlignSubComponentRight(position.alignRight); } }, [isSubComponentOpen]); const value = useMemo(() => { return { breakpoint, isConnectModalOpen, setIsConnectModalOpen, isSubComponentOpen, setIsSubComponentOpen, isSubComponentClosing, setIsSubComponentClosing, handleClose, connectRef, showSubComponentAbove, alignSubComponentRight, activeFeature, setActiveFeature, isActiveFeatureClosing, setIsActiveFeatureClosing, animations, isSponsored, __hasContext: true, }; }, [ breakpoint, isConnectModalOpen, isSubComponentOpen, isSubComponentClosing, handleClose, showSubComponentAbove, alignSubComponentRight, activeFeature, isActiveFeatureClosing, animations, isSponsored, ]); return ( {children} ); } export function useWalletContext() { const context = useContext(WalletContext); if (!context) { throw new Error('useWalletContext must be used within a WalletProvider'); } return context; }