File size: 1,255 Bytes
eb1202c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import { createContext, createMemo, Show, useContext, type ParentProps, type Accessor } from "solid-js"
export function createSimpleContext<T, Props extends Record<string, any>>(
input: {
name: string
init: ((input: Props) => T) | (() => T)
} & (T extends { ready: unknown } ? { gate: boolean } : { gate?: boolean }),
) {
const ctx = createContext<T>()
return {
provider: (props: ParentProps<Props>) => {
const init = input.init(props)
const gate = input.gate ?? true
if (!gate) {
return <ctx.Provider value={init}>{props.children}</ctx.Provider>
}
// Access init.ready inside the memo to make it reactive for getter properties
const isReady = createMemo(() => {
// @ts-expect-error
const ready = init.ready as Accessor<boolean> | boolean | undefined
return ready === undefined || (typeof ready === "function" ? ready() : ready)
})
return (
<Show when={isReady()}>
<ctx.Provider value={init}>{props.children}</ctx.Provider>
</Show>
)
},
use() {
const value = useContext(ctx)
if (!value) throw new Error(`${input.name} context must be used within a context provider`)
return value
},
}
}
|