UNPKG

@solid-primitives/context

Version:

Primitives simplifying or extending the SolidJS Context API

69 lines (64 loc) 1.97 kB
import { createContext, createComponent, useContext } from "solid-js"; export function createContextProvider(factoryFn, defaults) { const ctx = createContext(defaults); return [ props => { return createComponent(ctx.Provider, { value: factoryFn(props), get children() { return props.children; }, }); }, () => useContext(ctx), ]; } /* MultiProvider inspired by the preact-multi-provider package from Marvin Hagemeister See https://github.com/marvinhagemeister/preact-multi-provider Type validation of the `values` array thanks to the amazing @otonashixav (https://github.com/otonashixav) */ /** * A component that allows you to provide multiple contexts at once. It will work exactly like nesting multiple providers as separate components, but it will save you from the nesting. * * @param values Array of tuples of `[ContextProviderComponent, value]` or `[Context, value]` or bound `ContextProviderComponent` (that doesn't take a `value` property). * * @example * ```tsx * // before * <CounterCtx.Provider value={1}> * <NameCtx.Provider value="John"> * <App/> * </NameCtx.Provider> * </CounterCtx.Provider> * * // after * <MultiProvider values={[ * [CounterCtx.Provider, 1], * [NameCtx.Provider, "John"] * ]}> * <App/> * </MultiProvider> * ``` */ export function MultiProvider(props) { const { values } = props; const fn = (i) => { let item = values[i]; if (!item) return props.children; const ctxProps = { get children() { return fn(i + 1); }, }; if (Array.isArray(item)) { ctxProps.value = item[1]; item = item[0]; if (typeof item !== "function") item = item.Provider; } return createComponent(item, ctxProps); }; return fn(0); }