UNPKG

@recrafter/ctx

Version:

A simple wrapper around React.createContext that makes it easy to use hooks and context together

141 lines (140 loc) 5.12 kB
import React from 'react'; /** * Interface that defines the properties for the context component. * * @typeParam Value - The type of value that the context will provide. * * @public */ export interface CtxProps<Value> { /** * Children can be either a render function that receives the context value * or standard React children nodes. */ children?: ((value: Value) => React.ReactNode) | React.ReactNode; } /** Checks component props compatibility with injected props * * @public */ export type CompatibleComponentType<T, U> = { [K in keyof T & keyof U]: T[K] extends U[K] ? never : K; }[keyof T & keyof U] extends never ? React.ComponentType<U> : never; /** * Interface defining the context injection functionality. * Allows injecting context values into components either directly or through a mapping function. * * @typeParam Value - The type of value that the context provides * * @public */ export interface InjectCtx<Value> { <ComponentProps>(Component: CompatibleComponentType<Value, ComponentProps>): React.ComponentType<Omit<ComponentProps, keyof Value>>; <InjectedProps, ComponentProps, ExtraProps = {}>(useMappedValue: (value: Value, props: ExtraProps) => InjectedProps, Component: CompatibleComponentType<InjectedProps & ExtraProps, ComponentProps>): React.ComponentType<Omit<ComponentProps, keyof InjectedProps | keyof ExtraProps> & ExtraProps>; } /** * Interface that defines a context component with associated properties and methods. * * @typeParam Value - The type of value that the context will provide. * @typeParam Props - Additional properties that can be passed to the context provider (defaults to an empty object). * * @public */ export interface CtxComponent<Value, Props = {}> { /** * Component function that renders the context provider. * * @param props - The component props * @returns React element or null */ (props: Omit<Props, 'children'> & CtxProps<Value>): React.ReactElement<any, any> | null; /** * Display name for debugging purposes. */ displayName: string; /** * Hook function to access the context value. * * @throws {@link MissingCtxProviderError} * Throws an error if the context provider is not found in the component tree. * @returns The context value */ use: UseCtx<Value>; inject: InjectCtx<Value>; } /** * Type for context hook functions that return a context value. * * @typeParam Value - The type of value that the context will provide. * @returns The context value * * @public */ export type UseCtx<Value> = () => Value; /** * Type for hook functions that use props to create a context value. * * @typeParam Value - The type of value that the context will provide. * @typeParam Props - Type of properties passed to the hook function. * @param props - Properties used to create the context value. * @returns The context value derived from props. * * @public */ export type UseValue<Value, Props> = (props: Props) => Value; /** * Type for the factory function that creates context components. * * @typeParam Value - The type of value that the context will provide. * @typeParam Props - Type of properties that can be passed to the context provider. * @param useValue - Hook function that creates the context value from props. * @param displayName - Optional name for the context, used for debugging purposes. * @returns A context component with the use() method for accessing context values. * * @public */ export type CreateCtx = <Value, Props>(useValue: UseValue<Value, Props>, displayName?: string) => CtxComponent<Value, Props>; /** * Error thrown when trying to use a context without a provider in the component tree. * * @public */ export declare class MissingCtxProviderError extends Error { constructor(displayName: string); } /** * Factory function that creates a context component with associated helper methods. * * This function simplifies the React Context API by creating a component that: * - Automatically provides a context value using the given hook * - Supports both regular children and render functions * - Includes a use() method for consuming the context * * @example * ```tsx * // Create a context for a string value * const Ctx = createCtx(() => React.useState('')); * * // Use the context in components * const TextInput = () => { * const [value, setValue] = Ctx.use(); * return <input value={value} onChange={(e) => setValue(e.target.value)} />; * }; * * // Wrap components with the context provider * const App = () => ( * <Ctx> * <TextInput /> * </Ctx> * ); * ``` * * @typeParam Value - The type of value that the context will provide. * @typeParam Props - Type of properties that can be passed to the context provider. * @param useValue - Hook function that creates the context value from props passed to the context provider. * @param displayName - Optional name for the context, used for debugging and error messages. * @returns A context component * * @public */ export declare const createCtx: CreateCtx;