/*! * ======================================================================== * @rzl-zone/core-react * ------------------------------------------------------------------------ * Version: `0.0.14` * Author: `Rizalvin Dwiky ` * Repository: `https://github.com/rzl-zone/rzl-zone/tree/main/packages/core-react` * ======================================================================== */ import React, { ReactNode } from "react"; type UnwrapPromise = ContextValue ? U : T>; type ContextValue = T extends undefined ? never : T; type RequiredContextProviderProps = { readonly value: T; readonly children: ReactNode; }; type RequiredContextProvider = { (props: RequiredContextProviderProps): ReactNode; displayName?: string; }; type RequiredContextReturn = { /** ------------------------------------------------------------------------ * * ***React Context instance (advanced usage).*** * ------------------------------------------------------------------------ * * ⚠️ **Advanced usage only** * * - ***This context is exposed for:*** * - Integration with third-party libraries. * - Adapter layers. * - Testing or devtools. * * - ***Important notes:*** * - The value type is `T | undefined`. * - `undefined` is reserved internally to detect missing Providers. * - Consumers SHOULD prefer `use()` or `useSuspense()` instead of * calling `useContext(Context)` directly. * * @example * **1. Adapter / integration layer.** * ```tsx * // Example: integrating with a third-party hook * // that requires a raw React Context instance. * * import { useContext } from "react"; * * type AuthState = { user: { name: string, email: string } }; * * function useAuthFromAdapter(AuthContext: { * Context: React.Context; * }) { * const value = useContext(AuthContext.Context); * * // Adapter is responsible for handling `undefined` * if (value === undefined) { * throw new Error("AuthContext.Provider is missing"); * } * * return value; * } * ``` * * @example * **2. Testing or devtools.** * ```tsx * import { render } from "@testing-library/react"; * * render( * * * * ); * ``` */ Context: React.Context; /** ------------------------------------------------------------------------ * * ***Context Provider component.*** * ------------------------------------------------------------------------ * * Provides the context value to the component subtree. * * - ⚠️ ***Important:*** * - `undefined` is **reserved internally** to detect missing Providers. * - Do **NOT** pass `undefined` as a valid value. * - If you need to represent an “empty” or “not yet available” state, * use `null` instead and handle it explicitly in consumers. * * @example * ```tsx * type AuthState = { user: { name: string } } | null; * * const AuthContext = * createRequiredContext("AuthContext", null); * * function App() { * return ( * * * * ); * } * * function UserComponent() { * const userContext = AuthContext.use(); * * if (userContext === null) throw new Error("UserContext is null"); * * return
{userContext.user.name}
; * } * ``` */ Provider: RequiredContextProvider; /** ------------------------------------------------------------------------ * * ***Classic context consumer (non-Suspense).*** * ------------------------------------------------------------------------ * * Reads the context value synchronously using `useContext`. * * - ***Behavior:*** * - Throws if the Provider is missing. * - Filters **only `undefined`** (used internally to detect missing Provider). * - `null` is treated as a valid value and is **not** filtered. * - Never suspends. * - Does NOT require ``. * * @param missingProviderMessage - Optional custom error message when used outside its Provider. * * @throws {Error} Thrown when used outside its corresponding Provider. * * @returns The context value of type `T`. * * @example * ```tsx * type Theme = { theme: "light" | "dark" }; * * const ThemeContext = createRequiredContext("ThemeContext"); * * function App() { * return ( * * * * ); * } * * function ThemeToggle() { * const { theme } = ThemeContext.use(); * return