import { Variant, AnimatePresence, m } from "framer-motion"; import React from "react"; const SwitchableComponentContext = React.createContext(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 | 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() }; };