@solid-primitives/context
Version:
Primitives simplifying or extending the SolidJS Context API
69 lines (64 loc) • 1.97 kB
JavaScript
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);
}