import type { FC, ReactElement } from "react"; import React, { Fragment } from "react"; import { Else } from "./Else"; import { Fallback } from "./Fallback"; import { getConditionResult } from "./getConditionResults"; import { IfAsync } from "./IfAsync"; import { isThenable } from "./isThenable"; import { Then } from "./Then"; import { tinyWarning } from "./tinyWarning"; import type { ComponentWithConditionPropsAsyncSupport, ExtendablePromise } from "./types"; import { _memo, _shallowFn } from "./utils"; /** * If condition evaluates to true, renders the `` block will be rendered, * otherwise renders the `` block. Either block may be omitted. * * This component can contain any number of `` or `` blocks, * but only the first block of the right type (either Then or Else, depending on the condition) will be rendered. * @param __namedParameters The props to pass down to the `` component, see {@link ComponentWithConditionProps} */ const IfFn: FC = ({ condition, keepAlive = false, children }) => { if (!children) { return null; } tinyWarning( (!Array.isArray(children) && !((children as ReactElement).type === Else || (children as ReactElement).type === Then)) || !(React.Children.toArray(children) as ReactElement[]).every( (child) => child.type === Else || child.type === Then || child.type === Fallback ), "The component should contain or components as its children" ); if (isThenable(condition)) { return ( } keepAlive={keepAlive}> {children} ); } const conditionResult = getConditionResult(condition); return ( {(React.Children.toArray(children) as ReactElement[]).find((c) => (c.type !== Else) !== !conditionResult) || null} ); }; export const If = _memo(IfFn, _shallowFn);