38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
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)
|
|
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
|
|
},
|
|
}
|
|
}
|