"use client"; import { createContext, type ReactNode, useContext } from "react"; import type { FlagKey, FlagRegistry, FlagSnapshot } from "../define-flags"; /** * Creates typed React helpers for a flag registry. * * Call once with your registry type, then export the returned `FlagProvider`, * `Flag`, and `useFlag` from an application-local module. * * @example * ```tsx * export const { Flag, FlagProvider, useFlag } = * createFlagContext(); * ``` */ export function createFlagContext() { type Snapshot = FlagSnapshot; const FlagContext = createContext(null); /** * Provides a resolved flag snapshot to `Flag` and `useFlag`. * * @example * ```tsx * {children} * ``` */ function FlagProvider({ children, flags, }: { readonly children: ReactNode; readonly flags: Snapshot; }) { return {children}; } /** * Reads a typed flag value from the nearest `FlagProvider`. * * @example * ```tsx * const enabled = useFlag("NEW_CHECKOUT"); * ``` */ function useFlag(flag: FlagKey): boolean { const flags = useContext(FlagContext); return flags?.[flag] === true; } /** * Renders children when a typed flag is enabled, otherwise renders fallback. * * @example * ```tsx * Enabled content * ``` */ function Flag({ children, fallback = null, flag, }: { readonly children: ReactNode; readonly fallback?: ReactNode; readonly flag: FlagKey; }) { return useFlag(flag) ? children : fallback; } return { Flag, FlagProvider, useFlag }; }