import { ReactVisualEditorBlock, ReactVisualEditorConfig } from './ReactVisualEditor.utils'; import React,{ useEffect, useMemo, useRef } from 'react'; import { useUpdate } from './../hook/useUpdate'; import classNames from 'classnames'; import style from './ReactVisualEditor.less'; export const ReactVisualBlock: React.FC<{ block: ReactVisualEditorBlock; config: ReactVisualEditorConfig; onMouseDown?: (e: React.MouseEvent) => void; onContextMenu?: (e: React.MouseEvent) => void; formData?: Record; onFormDataChange?: (formData: Record) => void; customProps?: Record>; click:(pre:any)=>void }> = (props) => { const elRef = useRef({} as HTMLDivElement); const { forceUpdate } = useUpdate(); const styles = useMemo(() => { return { top: `${props.block.top}px`, left: `${props.block.left}px`, zIndex: props.block.zIndex, opacity: props.block.adjustPosition ? '0' : '', }; }, [props.block.top, props.block.left, props.block.zIndex, props.block.adjustPosition]); const classes = useMemo( () => classNames([ style.reactVisualEditorBlock, props.block.focus && style.reactVisualEditorBlockFocus, ]), [props.block.focus], ); let render: any; const component = props.config.componentMap[props.block.componentKey]; if (!!component) { render = component.render({ block: props.block, custom: !props.block.slotName || !props.customProps ? {} : props.customProps[props.block.slotName] || {}, size: props.block.hasResize && component.resize ? (() => { let styles = { height: undefined as undefined | string, width: undefined as undefined | string, }; !!component.resize.width && (styles.width = `${props.block.width}px`); !!component.resize.height && (styles.height = `${props.block.height}px`); return styles; })() : {}, props: props.block.props || {}, model: Object.entries(component.model || {}).reduce((prev, item) => { const [modelProp] = item; prev[modelProp] = { value:null, onChange: (e) => { if (!props.block.model || !props.block.model[modelProp]) { return; } let val: any; if (!e) { val = e; } else { if (typeof e === 'object' && 'target' in e) { val = e.target.value; } else { val = e; } } props.onFormDataChange && props.onFormDataChange({ ...props.formData, [props.block.model[modelProp]]: val, }); }, }; return prev; }, {} as Record void }>), }); } useEffect(() => { if (props.block.adjustPosition) { const { top, left } = props.block; const { height, width } = elRef.current.getBoundingClientRect(); props.block.adjustPosition = false; props.block.top = top - height / 2; props.block.left = left - width / 2; props.block.width = elRef.current.offsetWidth; props.block.height = elRef.current.offsetHeight; forceUpdate(); } }, []); return (
{ props.click(props.block.props) }} > {render} {props.children}
); };