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);