@loke/ui
Version:
2 lines (1 loc) • 2.7 kB
JavaScript
import{createContext as reactCreateContext,useContext as reactUseContext,useMemo}from"react";import{jsx}from"react/jsx-runtime";function createContext(rootComponentName,defaultContext){let LokeContext=reactCreateContext(defaultContext),Provider=(props)=>{let{children,...context}=props,value=useMemo(()=>context,Object.values(context));return jsx(LokeContext.Provider,{value,children})};Provider.displayName=`${rootComponentName}Provider`;function useContext(consumerName){let context=reactUseContext(LokeContext);if(context)return context;if(defaultContext!==void 0)return defaultContext;throw Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``)}return[Provider,useContext]}function createContextScope(scopeName,createContextScopeDeps=[]){let defaultContexts=[];function createScopedContext(rootComponentName,defaultContext){let BaseContext=reactCreateContext(defaultContext),index=defaultContexts.length;defaultContexts=[...defaultContexts,defaultContext];let Provider=(props)=>{let{scope,children,...context}=props,LokeContext=scope?.[scopeName]?.[index]||BaseContext,value=useMemo(()=>context,Object.values(context));return jsx(LokeContext.Provider,{value,children})};Provider.displayName=`${rootComponentName}Provider`;function useContext(consumerName,scope){let LokeContext=scope?.[scopeName]?.[index]||BaseContext,context=reactUseContext(LokeContext);if(context)return context;if(defaultContext!==void 0)return defaultContext;throw Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``)}return[Provider,useContext]}let createScope=()=>{let scopeContexts=defaultContexts.map((defaultContext)=>{return reactCreateContext(defaultContext)});return function(scope){let contexts=scope?.[scopeName]||scopeContexts;return useMemo(()=>({[`__scope${scopeName}`]:{...scope,[scopeName]:contexts}}),[scope,contexts])}};return createScope.scopeName=scopeName,[createScopedContext,composeContextScopes(createScope,...createContextScopeDeps)]}function composeContextScopes(...scopes){let baseScope=scopes[0];if(!baseScope)throw Error("composeContextScopes must be called with at least one scope");if(scopes.length===1)return baseScope;let createScope=()=>{let scopeHooks=scopes.map((scopeFactory)=>({scopeName:scopeFactory.scopeName,useScope:scopeFactory()}));return function(overrideScopes){let nextScopes=scopeHooks.reduce((accumulatedScopes,{useScope,scopeName})=>{let currentScope=useScope(overrideScopes)[`__scope${scopeName}`];return{...accumulatedScopes,...currentScope}},{});return useMemo(()=>({[`__scope${baseScope.scopeName}`]:nextScopes}),[nextScopes])}};return createScope.scopeName=baseScope.scopeName,createScope}export{createContextScope,createContext};