import * as React from 'react'; // https://github.com/reach/reach-ui/blob/dev/packages/utils/src/context.tsx type ContextProvider = React.FC>; export function createContext( rootComponentName: string, defaultContext?: ContextValueType ): [ContextProvider, (callerComponentName: string) => ContextValueType] { const Ctx = React.createContext(defaultContext); function Provider(props: React.PropsWithChildren) { const { children, ...context } = props; const value = React.useMemo( () => context, // eslint-disable-next-line react-hooks/exhaustive-deps Object.values(context) ) as ContextValueType; return {children}; } function useContext(callerComponentName: string) { const context = React.useContext(Ctx); if (context) { return context; } if (defaultContext) { return defaultContext; } throw Error( `${callerComponentName} must be rendered inside of a ${rootComponentName} component.` ); } Ctx.displayName = `${rootComponentName}Context`; Provider.displayName = `${rootComponentName}Provider`; return [Provider, useContext]; }