import BaseText from "../../blocks/BaseText"; import * as React from "react"; import {} from "react-native"; import { useState, useEffect } from "react"; export type BlockProps = { block: BuilderBlock; context: BuilderContextInterface; registeredComponents: RegisteredComponents; linkComponent: any; }; import { TARGET } from "../../constants/target"; import type { BuilderContextInterface, RegisteredComponents, } from "../../context/types"; import { getBlockComponentOptions } from "../../functions/get-block-component-options"; import { getProcessedBlock } from "../../functions/get-processed-block"; import { isPreviewing } from "../../server-index"; import type { BuilderBlock } from "../../types/builder-block"; import DynamicDiv from "../dynamic-div"; import { bindAnimations } from "./animator"; import { generateKey, getComponent, getInheritedStyles, getRepeatItemData, provideBuilderBlock, provideBuilderContext, provideLinkComponent, provideRegisteredComponents, } from "./block.helpers"; import BlockWrapper from "./components/block-wrapper"; import type { ComponentProps } from "./components/component-ref/component-ref.helpers"; import ComponentRef from "./components/component-ref/component-ref"; import RepeatedBlock from "./components/repeated-block"; import StyleWrapper from "./components/style-wrapper"; import { memo } from "react"; import { View } from "react-native"; function Block(props: BlockProps) { function repeatItem() { return getRepeatItemData({ block: props.block, context: props.context, }); } const [_processedBlock, set_processedBlock] = useState(() => ({ value: null as BuilderBlock | null, update: false, })); function processedBlock() { if (_processedBlock.value && !_processedBlock.update && !isPreviewing()) { return _processedBlock.value; } const blockToUse = props.block.repeat?.collection ? props.block : getProcessedBlock({ block: props.block, localState: props.context.localState, rootState: props.context.rootState, rootSetState: props.context.rootSetState, context: props.context.context, }); _processedBlock.value = blockToUse; _processedBlock.update = false; return blockToUse; } function blockComponent() { return getComponent({ block: processedBlock(), registeredComponents: props.registeredComponents, model: props.context.model, }); } function Tag() { const shouldUseLink = props.block.tagName === "a" || processedBlock().properties?.href || processedBlock().href; if (shouldUseLink) { return props.linkComponent || BaseText; } return View; } function canShowBlock() { if (props.block.repeat?.collection) { if (repeatItem?.()?.length) return true; return false; } const shouldHide = "hide" in processedBlock() ? processedBlock().hide : false; const shouldShow = "show" in processedBlock() ? processedBlock().show : true; return shouldShow && !shouldHide; } function childrenWithoutParentComponent() { /** * When there is no `componentRef`, there might still be children that need to be rendered. In this case, * we render them outside of `componentRef`. * NOTE: We make sure not to render this if `repeatItemData` is non-null, because that means we are rendering an array of * blocks, and the children will be repeated within those blocks. */ const shouldRenderChildrenOutsideRef = !blockComponent?.()?.component && !repeatItem(); return shouldRenderChildrenOutsideRef ? processedBlock().children ?? [] : []; } function componentRefProps() { return { blockChildren: processedBlock().children ?? [], componentRef: blockComponent?.()?.component, componentOptions: { ...getBlockComponentOptions(processedBlock(), props.context), ...provideBuilderBlock(blockComponent(), processedBlock()), ...provideBuilderContext(blockComponent(), props.context), ...provideLinkComponent(blockComponent(), props.linkComponent), ...provideRegisteredComponents( blockComponent(), props.registeredComponents, props.context.model ), }, context: { ...props.context, inheritedStyles: getInheritedStyles({ block: processedBlock(), context: props.context, }), } as any, linkComponent: props.linkComponent, registeredComponents: props.registeredComponents, builderBlock: processedBlock(), includeBlockProps: blockComponent?.()?.noWrap === true, isInteractive: !(blockComponent?.()?.isRSC && TARGET === "rsc"), }; } useEffect(() => {}, []); useEffect(() => { _processedBlock.update = true; }); return ( <> {canShowBlock() ? ( <> {!blockComponent?.()?.noWrap ? ( <> {!repeatItem() ? ( {childrenWithoutParentComponent()?.map((child) => ( ))} ) : ( <> {repeatItem()?.map((data, index) => ( ))} )} ) : !repeatItem() ? ( ) : ( <> {repeatItem()?.map((data, index) => ( ))} )} ) : null} ); } export default memo(Block);