import { Variant, AnimatePresence, m } from "framer-motion"; import React from "react"; const SwitchableComponentContext = React.createContext< SwitchableComponentContextType | undefined >(undefined); export const SwitchableComponentProvider = ({ children, }: React.PropsWithChildren) => { const [visibleComponent, setVisibleComponent] = React.useState(); return ( {children} ); }; export function useSwitchableComponent(initialValue?: SwitchableComponentType) { const contextValue = React.useContext(SwitchableComponentContext); if (contextValue === undefined) { throw new Error( "useSwitchableComponent hook is being used outside of its context. Please ensure that it is wrapped within a .", ); } React.useEffect(() => { // Set the initial value if it's provided if (initialValue && contextValue.visibleComponent) { contextValue.setVisibleComponent(initialValue); } }, [initialValue]); return contextValue; } const variants: Record = { hidden: { y: 50, opacity: 0, position: "absolute" }, show: { y: 0, x: 0, opacity: 1, position: "relative", transition: { type: "tween", ease: "easeInOut", }, }, exit: { y: -50, opacity: 0, position: "absolute" }, }; export const SwitchableComponent = ({ children, index, }: React.PropsWithChildren<{ index: string }>) => { const [width, setWidth] = React.useState(); return ( setWidth(e.currentTarget.getBoundingClientRect().width!) }> {children} ); }; type SwitchableComponentType = { index: string; render: (props: T | any) => ReturnType; }; type SwitchableComponentContextType = { visibleComponent: SwitchableComponentType; setVisibleComponent: React.Dispatch< React.SetStateAction< SwitchableComponentType | undefined > >; }; const DEFAULT_COMPONENT = { render: () => undefined, index: Symbol("DEFAULT_COMPONENT").toString(), }; // Factory function export function makeSwitchable( Component: React.FC, index: string, ) { return { render(props: T) { return ; }, index: index || Symbol(Component.name).toString(), }; }