/** * This file is part of the NocoBase (R) project. * Copyright (c) 2020-2024 NocoBase Co., Ltd. * Authors: NocoBase Team. * * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. * For more information, please refer to: https://www.nocobase.com/agreement. */ import { App, ConfigProvider } from 'antd'; import React from 'react'; import { Root, RootOptions, createRoot } from 'react-dom/client'; import { FlowEngine } from './flowEngine'; import { FlowEngineProvider } from './provider'; function Provider({ config, engine, children }) { return ( {children} ); } export class ReactView { private refreshCallback: (() => void) | null = null; constructor(private flowEngine: FlowEngine) {} createRoot(container: HTMLElement, options: RootOptions = {}): Root { const root = createRoot(container, options); let currentChildren: React.ReactNode; const doRender = () => { root.render( {currentChildren} , ); }; const flowRoot = { render: (children: React.ReactNode) => { currentChildren = children; this.refreshCallback = doRender; doRender(); }, unmount: () => { this.refreshCallback = null; currentChildren = null; root.unmount(); }, }; return flowRoot; } // 重新渲染当前根 refresh() { if (this.refreshCallback) { this.refreshCallback(); } } render(children: React.ReactNode | ((root: Root) => React.ReactNode), options: any = {}) { const container = document.createElement('span'); const { onRendered } = options; let root: Root; const renderContent = (root: Root) => { const content = typeof children === 'function' ? (children as (root: Root) => React.ReactNode)(root) : children; return ( {content} ); }; if (onRendered) { onRendered(() => { root = createRoot(container); root.render(renderContent(root)); }); } else { root = createRoot(container); root.render(renderContent(root)); } (container as any)._reactRoot = root; return container; } onRefReady(ref: React.RefObject, cb: (el: T) => void, timeout = 10000) { const start = Date.now(); function check() { if (ref.current) return cb(ref.current); if (Date.now() - start > timeout) return; setTimeout(check, 30); } check(); } }