import { type Spec, uniqueId, EventDisposable, createCallback } from '@alilc/lowcode-shared'; import { clone } from 'lodash-es'; import { IComponentTreeModel } from '../component-tree-model'; export interface WidgetBuildContext { key: string; node: Spec.NodeType; model: IComponentTreeModel; children?: IWidget[]; } export interface IWidget { readonly key: string; readonly node: Spec.NodeType; children?: IWidget[]; beforeBuild(beforeGuard: (node: T) => T): EventDisposable; build( builder: (context: WidgetBuildContext) => Element, ): Element; } export class Widget implements IWidget { private beforeGuardCallbacks = createCallback(); public __raw: Spec.NodeType; public node: Spec.NodeType; public key: string; public children?: IWidget[] | undefined; constructor( node: Spec.NodeType, private model: IComponentTreeModel, ) { this.node = clone(node); this.__raw = node; this.key = (node as Spec.ComponentNode)?.id ?? uniqueId(); } beforeBuild(beforeGuard: (node: T) => T): EventDisposable { return this.beforeGuardCallbacks.add(beforeGuard); } build( builder: (context: WidgetBuildContext) => Element, ): Element { const beforeGuards = this.beforeGuardCallbacks.list(); const finalNode = beforeGuards.reduce((prev, cb) => cb(prev), this.node); return builder({ key: this.key, node: finalNode, model: this.model, children: this.children, }); } }