import { TabsProps } from "antd"; import React from "react"; import type { ComponentData } from "../parsers/index"; import type { ObjectEditors } from "maishu-jueying/component-editors"; import type { ComponentInfo } from "../type"; import ImportDialog from "./import-dialog"; import type { ComponentTypes, LibraryImport, ModuleTypes } from "../type"; import "./designer.scss"; import "./collapsible-panel.scss"; interface Props { componentData?: ComponentData; activeKey?: string; toolbar?: React.ReactNode; children?: React.ReactNode; title?: string; moduleTypes?: ModuleTypes; componentTypes?: ComponentTypes; componentEditors: ObjectEditors; tabChanged?: (key: string) => void; /** 追加的标签页,可分别携带显示在右上角工具栏的按钮 */ tabs?: DesignerTabItem[]; onChanged?: (componentData: ComponentData, componentId?: string, propName?: string, value?: any) => void; } interface State { activeKey: string; /** 各标签页注册到右上角工具栏的按钮,key 为标签页 key */ toolbars: Record; changedData?: ChangedData; componentViewData?: ComponentData; componentPanelData?: ComponentData; componentPanelDataKey: string; /** 右侧属性面板是否折叠(折叠后画布占满宽度) */ propertyPanelCollapsed: boolean; } /** 标签页配置:在 antd TabItem 基础上增加 toolbar,用于在右上角显示该标签页专属按钮 */ export type DesignerTabItem = NonNullable[number] & { toolbar?: React.ReactNode; }; interface DesignerToolbarContextValue { setToolbar: (key: string, toolbar: React.ReactNode) => void; clearToolbar: (key: string) => void; } /** 供自定义标签页内容把按钮注册到右上角工具栏;不在 Designer 内时返回 null */ export declare function useDesignerToolbar(): DesignerToolbarContextValue | null; type ChangedData = { componentId: string; propName: string; value: any; }; /** * 为可挂 ref 的组件补上 props.ref = id(若尚未设置),使 runtime-parser 在解析时 * 能按 id 把组件实例暴露到当前窗口 globalThis[componentId](供设计器按 id 取回实例)。 * Designer 与 iframe 设计画布(DesignComponentView)共用此逻辑;refMapping 由 Designer 自行维护。 */ export declare function fillComponentRefs(componentData: ComponentData, componentTypes: ComponentTypes): Record; export declare class Designer extends React.Component { private codeEditor; private jsxEditor; private componentPanel; private PANEL_SIZE; private panelSize; private child1; private child2; private orginalComponentData; private importDialog; private undoStack; private redoStack; private static MAX_HISTORY; private resizeHandler; private keydownHandler; /** 供标签页内容动态注册右上角工具栏按钮;实例级稳定引用,避免子组件 effect 反复触发 */ private toolbarContext; constructor(props: Props); static getDerivedStateFromProps(nextProps: Props, prevState: State): { componentPanelData: ComponentData | undefined; componentViewData: ComponentData | undefined; } | null; getComponentData(): ComponentData | undefined; getActiveTab(): string; getCode(): string | undefined; getJSX(): string | undefined; canUndo(): boolean; canRedo(): boolean; undo(): void; redo(): void; private applyComponentData; private pushHistory; onComponentChanged(componentData: ComponentData, componentId?: string, propName?: string, value?: any): void; /** 选中组件:把 selected 标记移动到目标组件后提交,属性面板经数据同步跟随选中(设计区点击选中) */ selectComponent(componentId: string): void; /** 取消选择:清除选中组件的 selected 标记后提交(与 selectComponent 对称,传入同一 componentId) */ deselectComponent(componentId: string): void; /** * 上移/下移组件:在父节点持有该组件的同级数组中交换相邻位置。 * 组件已是首个/末位、或未挂在数组属性上时不动。 */ moveComponent(componentId: string, direction: "up" | "down"): void; /** * 删除组件:从父节点持有它的属性中移除(数组过滤,单值属性置空)。 * 被删除的组件若正被选中,选中标记转移到其父组件,属性面板回退到父组件。 */ removeComponent(componentId: string): void; /** * 添加组件(组件库面板拖放/点击):按 componentInfo 新建组件节点, * 插入根组件的顶层 children 中 targetComponentId 之前/之后,缺省(或目标不在顶层时)追加到末尾。 * 新组件 id 重新生成,defaultProps 合并进 props 但不覆盖 id。 */ addComponent(componentInfo: ComponentInfo, targetComponentId?: string, position?: "before" | "after"): void; private onTabChange; private onSplitterResize; /** 折叠/展开右侧属性面板;状态持久化到 localStorage */ private togglePropertyPanel; private setPanelHeight; showImportsDialog(globalImports: LibraryImport[] | undefined, pageImports: LibraryImport[] | undefined, callback: Parameters[2]): void; componentDidMount(): void; componentWillUnmount(): void; render(): React.JSX.Element; } export default Designer;