/*! * ======================================================================== * @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 { ReactNode } from "react"; /** --------------------------------------------------------- * * **Utility: `isReactNode`** * ---------------------------------------------------------- * **Determines whether a given value is a valid** * **[`ReactNode`](https://react-typescript-cheatsheet.netlify.app/docs/react-types/reactnode/)** **and therefore safely render-able by React.** * * - **ReactNode includes:** * - `null` and `undefined` * - Primitive renderables: `string`, `number`, `boolean` * (booleans are ignored by React but allowed as children) * - Any valid `ReactElement` (JSX, Fragment, memo, forwardRef, etc.) * - React Portals * - Arrays of ReactNode (nested arbitrarily deep) * - Generic **iterables** whose elements are ReactNode * (e.g. `Set`, `Map.values()`, generators) * * - **❌ Values that are **NOT** valid ReactNode:** * - `bigint`, `symbol`, `function` (including async components as raw functions) * - Plain objects (`{}`), unless they are valid ReactElement * - `Date`, `RegExp`, `Promise`, `Map`, `WeakMap`, `WeakSet` * - Any iterable whose items contain invalid ReactNode entries * * - **✔️ Behavior:** * - Performs **deep recursive** validation for arrays and nested iterables. * - Detects React portals via the internal `$$typeof` symbol. * - Gracefully handles iteration errors—if iteration fails, returns `false`. * - Fully compatible with **React 18 & 19** (including concurrent & streaming mode). * * @param {unknown} value - The input to test for ReactNode compatibility. * * @returns {boolean} - `true` if the value can be safely rendered by React, otherwise `false`. * * @example * isReactNode(null); // ➔ true * isReactNode(undefined); // ➔ true * isReactNode(<>); // ➔ true * isReactNode("hello"); // ➔ true * isReactNode(123); // ➔ true * isReactNode(
); // ➔ true * isReactNode([]); // ➔ true * isReactNode(new Set(["a", "b"])); // ➔ true * * @example * isReactNode({}); // ➔ false * isReactNode(Symbol("x")); // ➔ false * isReactNode(() =>
); // ➔ false (functions are not nodes) * isReactNode(async () =>
); // ➔ false (async components are functions) * isReactNode(new Date()); // ➔ false * isReactNode(Promise.resolve(1)); // ➔ false * * @example * // Iterable example: * const items = { * *[Symbol.iterator]() { * yield "a"; * yield
; * } * }; * isReactNode(items); // ➔ true */ declare function isReactNode(value: unknown): value is ReactNode; export { isReactNode };