| 1234567891011121314151617181920212223242526272829303132333435363738 |
- 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
- },
- }
- }
|