mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-12 03:01:16 +00:00
feat: add get advanced api for ComponentMeta
This commit is contained in:
parent
5cf395957c
commit
810ccbd03e
@ -76,7 +76,7 @@ export class BorderDetecting extends Component<{ host: BuiltinSimulatorHost }> {
|
||||
const { host } = this.props;
|
||||
const { current } = this;
|
||||
|
||||
const canHoverHook = current?.componentMeta.getMetadata()?.configure.advanced?.callbacks?.onHoverHook;
|
||||
const canHoverHook = current?.componentMeta.advanced.callbacks?.onHoverHook;
|
||||
const canHover = (canHoverHook && typeof canHoverHook === 'function') ? canHoverHook(current.internalToShellNode()) : true;
|
||||
|
||||
if (!canHover || !current || host.viewport.scrolling || host.liveEditing.editing) {
|
||||
|
||||
@ -136,40 +136,40 @@ export class BoxResizingInstance extends Component<{
|
||||
this.willBind();
|
||||
|
||||
const resize = (e: MouseEvent, direction: string, node: any, moveX: number, moveY: number) => {
|
||||
const metadata = node.componentMeta.getMetadata();
|
||||
const { advanced } = node.componentMeta;
|
||||
if (
|
||||
metadata.configure?.advanced?.callbacks &&
|
||||
typeof metadata.configure.advanced.callbacks.onResize === 'function'
|
||||
advanced.callbacks &&
|
||||
typeof advanced.callbacks.onResize === 'function'
|
||||
) {
|
||||
(e as any).trigger = direction;
|
||||
(e as any).deltaX = moveX;
|
||||
(e as any).deltaY = moveY;
|
||||
const cbNode = node?.isNode ? node.internalToShellNode() : node;
|
||||
metadata.configure.advanced.callbacks.onResize(e, cbNode);
|
||||
advanced.callbacks.onResize(e, cbNode);
|
||||
}
|
||||
};
|
||||
|
||||
const resizeStart = (e: MouseEvent, direction: string, node: any) => {
|
||||
const metadata = node.componentMeta.getMetadata();
|
||||
const { advanced } = node.componentMeta;
|
||||
if (
|
||||
metadata.configure?.advanced?.callbacks &&
|
||||
typeof metadata.configure.advanced.callbacks.onResizeStart === 'function'
|
||||
advanced.callbacks &&
|
||||
typeof advanced.callbacks.onResizeStart === 'function'
|
||||
) {
|
||||
(e as any).trigger = direction;
|
||||
const cbNode = node?.isNode ? node.internalToShellNode() : node;
|
||||
metadata.configure.advanced.callbacks.onResizeStart(e, cbNode);
|
||||
advanced.callbacks.onResizeStart(e, cbNode);
|
||||
}
|
||||
};
|
||||
|
||||
const resizeEnd = (e: MouseEvent, direction: string, node: any) => {
|
||||
const metadata = node.componentMeta.getMetadata();
|
||||
const { advanced } = node.componentMeta;
|
||||
if (
|
||||
metadata.configure?.advanced?.callbacks &&
|
||||
typeof metadata.configure.advanced.callbacks.onResizeEnd === 'function'
|
||||
advanced.callbacks &&
|
||||
typeof advanced.callbacks.onResizeEnd === 'function'
|
||||
) {
|
||||
(e as any).trigger = direction;
|
||||
const cbNode = node?.isNode ? node.internalToShellNode() : node;
|
||||
metadata.configure.advanced.callbacks.onResizeEnd(e, cbNode);
|
||||
advanced.callbacks.onResizeEnd(e, cbNode);
|
||||
}
|
||||
|
||||
const workspace = globalContext.get('workspace');
|
||||
@ -242,9 +242,9 @@ export class BoxResizingInstance extends Component<{
|
||||
|
||||
const { node, offsetWidth, offsetHeight, offsetTop, offsetLeft } = observed;
|
||||
let triggerVisible: any = [];
|
||||
const metadata = node.componentMeta.getMetadata();
|
||||
if (metadata.configure?.advanced?.getResizingHandlers) {
|
||||
triggerVisible = metadata.configure.advanced.getResizingHandlers(node.internalToShellNode());
|
||||
const { advanced } = node.componentMeta;
|
||||
if (advanced.getResizingHandlers) {
|
||||
triggerVisible = advanced.getResizingHandlers(node.internalToShellNode());
|
||||
}
|
||||
|
||||
triggerVisible = normalizeTriggers(triggerVisible);
|
||||
|
||||
@ -46,7 +46,7 @@ export class BorderSelectingInstance extends Component<{
|
||||
dragging,
|
||||
});
|
||||
|
||||
const hideSelectTools = observed.node.componentMeta.getMetadata().configure.advanced?.hideSelectTools;
|
||||
const { hideSelectTools } = observed.node.componentMeta.advanced;
|
||||
|
||||
if (hideSelectTools) {
|
||||
return null;
|
||||
|
||||
@ -121,7 +121,7 @@ export class InsertionView extends Component<{ host: BuiltinSimulatorHost }> {
|
||||
return null;
|
||||
}
|
||||
// 如果是个绝对定位容器,不需要渲染插入标记
|
||||
if (loc.target.componentMeta.getMetadata().configure.advanced?.isAbsoluteLayoutContainer) {
|
||||
if (loc.target?.componentMeta?.advanced.isAbsoluteLayoutContainer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -99,6 +99,7 @@ export interface BuiltinSimulatorProps {
|
||||
simulatorUrl?: Asset;
|
||||
theme?: Asset;
|
||||
componentsAsset?: Asset;
|
||||
// eslint-disable-next-line @typescript-eslint/member-ordering
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
@ -184,40 +185,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
*/
|
||||
autoRender = true;
|
||||
|
||||
stopAutoRepaintNode() {
|
||||
this.renderer?.stopAutoRepaintNode();
|
||||
}
|
||||
|
||||
enableAutoRepaintNode() {
|
||||
this.renderer?.enableAutoRepaintNode();
|
||||
}
|
||||
|
||||
constructor(project: Project, designer: Designer) {
|
||||
makeObservable(this);
|
||||
this.project = project;
|
||||
this.designer = designer;
|
||||
this.scroller = this.designer.createScroller(this.viewport);
|
||||
this.autoRender = !engineConfig.get('disableAutoRender', false);
|
||||
this.componentsConsumer = new ResourceConsumer<Asset | undefined>(() => this.componentsAsset);
|
||||
this.injectionConsumer = new ResourceConsumer(() => {
|
||||
return {
|
||||
appHelper: engineConfig.get('appHelper'),
|
||||
};
|
||||
});
|
||||
|
||||
this.i18nConsumer = new ResourceConsumer(() => this.project.i18n);
|
||||
|
||||
transactionManager.onStartTransaction(() => {
|
||||
this.stopAutoRepaintNode();
|
||||
}, IPublicEnumTransitionType.REPAINT);
|
||||
// 防止批量调用 transaction 时,执行多次 rerender
|
||||
const rerender = debounce(this.rerender.bind(this), 28);
|
||||
transactionManager.onEndTransaction(() => {
|
||||
rerender();
|
||||
this.enableAutoRepaintNode();
|
||||
}, IPublicEnumTransitionType.REPAINT);
|
||||
}
|
||||
|
||||
get currentDocument() {
|
||||
return this.project.currentDocument;
|
||||
}
|
||||
@ -285,6 +252,87 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
|
||||
@obx.ref _props: BuiltinSimulatorProps = {};
|
||||
|
||||
@obx.ref private _contentWindow?: Window;
|
||||
|
||||
get contentWindow() {
|
||||
return this._contentWindow;
|
||||
}
|
||||
|
||||
@obx.ref private _contentDocument?: Document;
|
||||
|
||||
get contentDocument() {
|
||||
return this._contentDocument;
|
||||
}
|
||||
|
||||
private _renderer?: BuiltinSimulatorRenderer;
|
||||
|
||||
get renderer() {
|
||||
return this._renderer;
|
||||
}
|
||||
|
||||
readonly asyncLibraryMap: { [key: string]: {} } = {};
|
||||
|
||||
readonly libraryMap: { [key: string]: string } = {};
|
||||
|
||||
private _iframe?: HTMLIFrameElement;
|
||||
|
||||
private disableHovering?: () => void;
|
||||
|
||||
private disableDetecting?: () => void;
|
||||
|
||||
readonly liveEditing = new LiveEditing();
|
||||
|
||||
@obx private instancesMap: {
|
||||
[docId: string]: Map<string, IPublicTypeComponentInstance[]>;
|
||||
} = {};
|
||||
|
||||
private tryScrollAgain: number | null = null;
|
||||
|
||||
private _sensorAvailable = true;
|
||||
|
||||
/**
|
||||
* @see IPublicModelSensor
|
||||
*/
|
||||
get sensorAvailable(): boolean {
|
||||
return this._sensorAvailable;
|
||||
}
|
||||
|
||||
private sensing = false;
|
||||
|
||||
constructor(project: Project, designer: Designer) {
|
||||
makeObservable(this);
|
||||
this.project = project;
|
||||
this.designer = designer;
|
||||
this.scroller = this.designer.createScroller(this.viewport);
|
||||
this.autoRender = !engineConfig.get('disableAutoRender', false);
|
||||
this.componentsConsumer = new ResourceConsumer<Asset | undefined>(() => this.componentsAsset);
|
||||
this.injectionConsumer = new ResourceConsumer(() => {
|
||||
return {
|
||||
appHelper: engineConfig.get('appHelper'),
|
||||
};
|
||||
});
|
||||
|
||||
this.i18nConsumer = new ResourceConsumer(() => this.project.i18n);
|
||||
|
||||
transactionManager.onStartTransaction(() => {
|
||||
this.stopAutoRepaintNode();
|
||||
}, IPublicEnumTransitionType.REPAINT);
|
||||
// 防止批量调用 transaction 时,执行多次 rerender
|
||||
const rerender = debounce(this.rerender.bind(this), 28);
|
||||
transactionManager.onEndTransaction(() => {
|
||||
rerender();
|
||||
this.enableAutoRepaintNode();
|
||||
}, IPublicEnumTransitionType.REPAINT);
|
||||
}
|
||||
|
||||
stopAutoRepaintNode() {
|
||||
this.renderer?.stopAutoRepaintNode();
|
||||
}
|
||||
|
||||
enableAutoRepaintNode() {
|
||||
this.renderer?.enableAutoRepaintNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ISimulator
|
||||
*/
|
||||
@ -337,30 +385,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
this.viewport.mount(viewport);
|
||||
}
|
||||
|
||||
@obx.ref private _contentWindow?: Window;
|
||||
|
||||
get contentWindow() {
|
||||
return this._contentWindow;
|
||||
}
|
||||
|
||||
@obx.ref private _contentDocument?: Document;
|
||||
|
||||
get contentDocument() {
|
||||
return this._contentDocument;
|
||||
}
|
||||
|
||||
private _renderer?: BuiltinSimulatorRenderer;
|
||||
|
||||
get renderer() {
|
||||
return this._renderer;
|
||||
}
|
||||
|
||||
readonly asyncLibraryMap: { [key: string]: {} } = {};
|
||||
|
||||
readonly libraryMap: { [key: string]: string } = {};
|
||||
|
||||
private _iframe?: HTMLIFrameElement;
|
||||
|
||||
/**
|
||||
* {
|
||||
* "title":"BizCharts",
|
||||
@ -544,7 +568,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
return;
|
||||
}
|
||||
// 触发 onMouseDownHook 钩子
|
||||
const onMouseDownHook = node.componentMeta?.getMetadata()?.configure.advanced?.callbacks?.onMouseDownHook;
|
||||
const onMouseDownHook = node.componentMeta.advanced.callbacks?.onMouseDownHook;
|
||||
if (onMouseDownHook) {
|
||||
onMouseDownHook(downEvent, node.internalToShellNode());
|
||||
}
|
||||
@ -689,10 +713,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
);
|
||||
}
|
||||
|
||||
private disableHovering?: () => void;
|
||||
|
||||
private disableDetecting?: () => void;
|
||||
|
||||
/**
|
||||
* 设置悬停处理
|
||||
*/
|
||||
@ -742,8 +762,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
// };
|
||||
}
|
||||
|
||||
readonly liveEditing = new LiveEditing();
|
||||
|
||||
setupLiveEditing() {
|
||||
const doc = this.contentDocument!;
|
||||
// cause edit
|
||||
@ -880,9 +898,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
// return this.renderer?.createComponent(schema) || null;
|
||||
}
|
||||
|
||||
@obx private instancesMap: {
|
||||
[docId: string]: Map<string, IPublicTypeComponentInstance[]>;
|
||||
} = {};
|
||||
setInstance(docId: string, id: string, instances: IPublicTypeComponentInstance[] | null) {
|
||||
if (!hasOwnProperty(this.instancesMap, docId)) {
|
||||
this.instancesMap[docId] = new Map();
|
||||
@ -1045,8 +1060,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
};
|
||||
}
|
||||
|
||||
private tryScrollAgain: number | null = null;
|
||||
|
||||
/**
|
||||
* @see ISimulator
|
||||
*/
|
||||
@ -1107,15 +1120,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
this.renderer?.clearState();
|
||||
}
|
||||
|
||||
private _sensorAvailable = true;
|
||||
|
||||
/**
|
||||
* @see IPublicModelSensor
|
||||
*/
|
||||
get sensorAvailable(): boolean {
|
||||
return this._sensorAvailable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see IPublicModelSensor
|
||||
*/
|
||||
@ -1160,8 +1164,6 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
);
|
||||
}
|
||||
|
||||
private sensing = false;
|
||||
|
||||
/**
|
||||
* @see IPublicModelSensor
|
||||
*/
|
||||
@ -1180,7 +1182,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
const { nodes } = dragObject as IPublicTypeDragNodeObject;
|
||||
|
||||
const operationalNodes = nodes?.filter((node) => {
|
||||
const onMoveHook = node.componentMeta?.getMetadata()?.configure.advanced?.callbacks?.onMoveHook;
|
||||
const onMoveHook = node.componentMeta?.advanced.callbacks?.onMoveHook;
|
||||
const canMove = onMoveHook && typeof onMoveHook === 'function' ? onMoveHook(node.internalToShellNode()) : true;
|
||||
|
||||
let parentContainerNode: Node | null = null;
|
||||
@ -1195,7 +1197,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||
parentNode = parentNode.parent;
|
||||
}
|
||||
|
||||
const onChildMoveHook = parentContainerNode?.componentMeta?.getMetadata()?.configure.advanced?.callbacks?.onChildMoveHook;
|
||||
const onChildMoveHook = parentContainerNode?.componentMeta?.advanced.callbacks?.onChildMoveHook;
|
||||
|
||||
const childrenCanMove = onChildMoveHook && parentContainerNode && typeof onChildMoveHook === 'function' ? onChildMoveHook(node.internalToShellNode(), parentContainerNode.internalToShellNode()) : true;
|
||||
|
||||
|
||||
@ -10,8 +10,8 @@ import {
|
||||
IPublicTypeI18nData,
|
||||
IPublicTypePluginConfig,
|
||||
IPublicTypeFieldConfig,
|
||||
IPublicTypeMetadataTransducer,
|
||||
IPublicModelComponentMeta,
|
||||
IPublicTypeAdvanced,
|
||||
} from '@alilc/lowcode-types';
|
||||
import { deprecate, isRegExp, isTitleConfig, isNode } from '@alilc/lowcode-utils';
|
||||
import { computed, createModuleEventBus, IEventBus } from '@alilc/lowcode-editor-core';
|
||||
@ -57,7 +57,6 @@ export function buildFilter(rule?: string | string[] | RegExp | IPublicTypeNesti
|
||||
}
|
||||
|
||||
export interface IComponentMeta extends IPublicModelComponentMeta {
|
||||
|
||||
}
|
||||
|
||||
export class ComponentMeta implements IComponentMeta {
|
||||
@ -140,7 +139,7 @@ export class ComponentMeta implements IComponentMeta {
|
||||
// string | i18nData | ReactElement
|
||||
// TitleConfig title.label
|
||||
if (isTitleConfig(this._title)) {
|
||||
return (this._title.label as any) || this.componentName;
|
||||
return (this._title?.label as any) || this.componentName;
|
||||
}
|
||||
return this._title || this.componentName;
|
||||
}
|
||||
@ -161,7 +160,14 @@ export class ComponentMeta implements IComponentMeta {
|
||||
return this._acceptable!;
|
||||
}
|
||||
|
||||
// compatiable vision
|
||||
get advanced(): IPublicTypeAdvanced {
|
||||
return this.getMetadata().configure.advanced || {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @legacy compatiable for vision
|
||||
* @deprecated
|
||||
*/
|
||||
prototype?: any;
|
||||
|
||||
constructor(readonly designer: Designer, metadata: IPublicTypeComponentMetadata) {
|
||||
@ -214,7 +220,7 @@ export class ComponentMeta implements IComponentMeta {
|
||||
: title;
|
||||
}
|
||||
|
||||
const liveTextEditing = this._transformedMetadata.configure.advanced?.liveTextEditing || [];
|
||||
const liveTextEditing = this.advanced.liveTextEditing || [];
|
||||
|
||||
function collectLiveTextEditing(items: IPublicTypeFieldConfig[]) {
|
||||
items.forEach((config) => {
|
||||
@ -234,7 +240,7 @@ export class ComponentMeta implements IComponentMeta {
|
||||
collectLiveTextEditing(this.configure);
|
||||
this._liveTextEditing = liveTextEditing.length > 0 ? liveTextEditing : undefined;
|
||||
|
||||
const isTopFixed = this._transformedMetadata.configure.advanced?.isTopFixed;
|
||||
const isTopFixed = this.advanced.isTopFixed;
|
||||
|
||||
if (isTopFixed) {
|
||||
this._isTopFixed = isTopFixed;
|
||||
|
||||
@ -567,7 +567,7 @@ export class Designer implements IDesigner {
|
||||
if (metaData.devMode === 'lowCode') {
|
||||
maps[key] = metaData.schema;
|
||||
} else {
|
||||
const view = metaData.configure.advanced?.view;
|
||||
const { view } = config.advanced;
|
||||
if (view) {
|
||||
maps[key] = view;
|
||||
} else {
|
||||
|
||||
@ -39,7 +39,7 @@ export default class DragGhost extends Component<{ designer: Designer }> {
|
||||
this.y = e.globalY;
|
||||
if (isSimulatorHost(e.sensor)) {
|
||||
const container = e.sensor.getDropContainer(e);
|
||||
if (container?.container.componentMeta.getMetadata().configure.advanced?.isAbsoluteLayoutContainer) {
|
||||
if (container?.container.componentMeta.advanced.isAbsoluteLayoutContainer) {
|
||||
this.isAbsoluteLayoutContainer = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -502,7 +502,7 @@ export class NodeChildren implements INodeChildren {
|
||||
if (node.isRootNode) {
|
||||
return;
|
||||
}
|
||||
const callbacks = owner.componentMeta?.getMetadata().configure.advanced?.callbacks;
|
||||
const callbacks = owner.componentMeta?.advanced.callbacks;
|
||||
if (callbacks?.onSubtreeModified) {
|
||||
try {
|
||||
callbacks?.onSubtreeModified.call(
|
||||
|
||||
@ -371,7 +371,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||
}
|
||||
|
||||
private setupAutoruns() {
|
||||
const autoruns = this.componentMeta.getMetadata().configure.advanced?.autoruns;
|
||||
const { autoruns } = this.componentMeta.advanced;
|
||||
if (!autoruns || autoruns.length < 1) {
|
||||
return;
|
||||
}
|
||||
@ -385,7 +385,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||
private initialChildren(children: any): IPublicTypeNodeData[] {
|
||||
// FIXME! this is dirty code
|
||||
if (children == null) {
|
||||
const initialChildren = this.componentMeta.getMetadata().configure.advanced?.initialChildren;
|
||||
const { initialChildren } = this.componentMeta.advanced;
|
||||
if (initialChildren) {
|
||||
if (typeof initialChildren === 'function') {
|
||||
return initialChildren(this as any) || [];
|
||||
@ -471,7 +471,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||
}
|
||||
|
||||
private didDropIn(dragment: Node) {
|
||||
const callbacks = this.componentMeta.getMetadata().configure.advanced?.callbacks;
|
||||
const { callbacks } = this.componentMeta.advanced;
|
||||
if (callbacks?.onNodeAdd) {
|
||||
const cbThis = this.internalToShellNode();
|
||||
callbacks?.onNodeAdd.call(cbThis, dragment.internalToShellNode(), cbThis);
|
||||
@ -482,7 +482,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||
}
|
||||
|
||||
private didDropOut(dragment: Node) {
|
||||
const callbacks = this.componentMeta.getMetadata().configure.advanced?.callbacks;
|
||||
const { callbacks } = this.componentMeta.advanced;
|
||||
if (callbacks?.onNodeRemove) {
|
||||
const cbThis = this.internalToShellNode();
|
||||
callbacks?.onNodeRemove.call(cbThis, dragment.internalToShellNode(), cbThis);
|
||||
|
||||
@ -17,6 +17,9 @@ jest.mock('../../../src/designer/designer', () => {
|
||||
getMetadata() {
|
||||
return { configure: { advanced: null } };
|
||||
},
|
||||
get advanced() {
|
||||
return {};
|
||||
},
|
||||
};
|
||||
},
|
||||
transformProps(props) { return props; },
|
||||
@ -506,7 +509,7 @@ describe('schema 生成节点模型测试', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('场景二:插入 Node 实例,指定 index', () => {
|
||||
it.only('场景二:插入 Node 实例,指定 index', () => {
|
||||
expect(project).toBeTruthy();
|
||||
const ids = getIdsFromSchema(formSchema);
|
||||
const { currentDocument } = project;
|
||||
|
||||
@ -14,6 +14,9 @@ jest.mock('../../../src/designer/designer', () => {
|
||||
getMetadata() {
|
||||
return { configure: { advanced: null } };
|
||||
},
|
||||
get advanced() {
|
||||
return {};
|
||||
},
|
||||
};
|
||||
},
|
||||
transformProps(props) { return props; },
|
||||
|
||||
@ -16,6 +16,9 @@ jest.mock('../../../src/designer/designer', () => {
|
||||
getMetadata() {
|
||||
return { configure: { advanced: null } };
|
||||
},
|
||||
get advanced() {
|
||||
return {};
|
||||
},
|
||||
};
|
||||
},
|
||||
transformProps(props) { return props; },
|
||||
|
||||
@ -473,7 +473,7 @@ describe('Node 方法测试', () => {
|
||||
const form = doc.getNode('node_k1ow3cbo');
|
||||
designer.createComponentMeta(divMetadata);
|
||||
designer.createComponentMeta(formMetadata);
|
||||
const callbacks = form.componentMeta.getMetadata().configure.advanced?.callbacks;
|
||||
const callbacks = form.componentMeta.advanced.callbacks;
|
||||
const fn1 = callbacks.onNodeAdd = jest.fn();
|
||||
const fn2 = callbacks.onNodeRemove = jest.fn();
|
||||
const textField = doc.getNode('node_k1ow3cc9');
|
||||
|
||||
@ -17,6 +17,9 @@ jest.mock('../../src/designer/designer', () => {
|
||||
getMetadata() {
|
||||
return { configure: { advanced: null } };
|
||||
},
|
||||
get advanced() {
|
||||
return {};
|
||||
},
|
||||
};
|
||||
},
|
||||
transformProps(props) { return props; },
|
||||
|
||||
@ -17,6 +17,9 @@ jest.mock('../../src/designer/designer', () => {
|
||||
getMetadata() {
|
||||
return { configure: { advanced: null } };
|
||||
},
|
||||
get advanced() {
|
||||
return {};
|
||||
},
|
||||
};
|
||||
},
|
||||
transformProps(props) { return props; },
|
||||
|
||||
@ -31,6 +31,75 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicMo
|
||||
|
||||
readonly id = uniqueId('outline');
|
||||
|
||||
private indentTrack = new IndentTrack();
|
||||
|
||||
private _sensorAvailable = false;
|
||||
|
||||
/**
|
||||
* @see IPublicModelSensor
|
||||
*/
|
||||
get sensorAvailable() {
|
||||
return this._sensorAvailable;
|
||||
}
|
||||
|
||||
private dwell = new DwellTimer((target, event) => {
|
||||
const { canvas, project } = this.pluginContext;
|
||||
const document = project.getCurrentDocument();
|
||||
let index: any;
|
||||
let focus: any;
|
||||
let valid = true;
|
||||
if (target.hasSlots()) {
|
||||
index = null;
|
||||
focus = { type: 'slots' };
|
||||
} else {
|
||||
index = 0;
|
||||
valid = !!document?.checkNesting(target, event.dragObject as any);
|
||||
}
|
||||
canvas.createLocation({
|
||||
target,
|
||||
source: this.id,
|
||||
event,
|
||||
detail: {
|
||||
type: IPublicTypeLocationDetailType.Children,
|
||||
index,
|
||||
focus,
|
||||
valid,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @see ITreeBoard
|
||||
*/
|
||||
readonly at: string | symbol;
|
||||
|
||||
private tryScrollAgain: number | null = null;
|
||||
|
||||
private sensing = false;
|
||||
|
||||
/**
|
||||
* @see IScrollable
|
||||
*/
|
||||
get bounds(): DOMRect | null {
|
||||
if (!this._shell) {
|
||||
return null;
|
||||
}
|
||||
return this._shell.getBoundingClientRect();
|
||||
}
|
||||
|
||||
private _scrollTarget?: IPublicModelScrollTarget;
|
||||
|
||||
/**
|
||||
* @see IScrollable
|
||||
*/
|
||||
get scrollTarget() {
|
||||
return this._scrollTarget;
|
||||
}
|
||||
|
||||
private scroller?: IPublicModelScroller;
|
||||
|
||||
private _shell: HTMLDivElement | null = null;
|
||||
|
||||
constructor(at: string | symbol, pluginContext: IPublicModelPluginContext, treeMaster: TreeMaster) {
|
||||
this.pluginContext = pluginContext;
|
||||
this.treeMaster = treeMaster;
|
||||
@ -52,8 +121,6 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicMo
|
||||
|
||||
/** -------------------- IPublicModelSensor begin -------------------- */
|
||||
|
||||
private indentTrack = new IndentTrack();
|
||||
|
||||
/**
|
||||
* @see IPublicModelSensor
|
||||
*/
|
||||
@ -91,7 +158,7 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicMo
|
||||
}
|
||||
|
||||
const operationalNodes = nodes?.filter((node: any) => {
|
||||
const onMoveHook = node.componentMeta?.getMetadata().configure?.advanced?.callbacks?.onMoveHook;
|
||||
const onMoveHook = node.componentMeta?.advanced.callbacks?.onMoveHook;
|
||||
const canMove = onMoveHook && typeof onMoveHook === 'function' ? onMoveHook(node) : true;
|
||||
|
||||
return canMove;
|
||||
@ -233,24 +300,10 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicMo
|
||||
this.indentTrack.reset();
|
||||
}
|
||||
|
||||
private _sensorAvailable = false;
|
||||
|
||||
/**
|
||||
* @see IPublicModelSensor
|
||||
*/
|
||||
get sensorAvailable() {
|
||||
return this._sensorAvailable;
|
||||
}
|
||||
|
||||
/** -------------------- IPublicModelSensor end -------------------- */
|
||||
|
||||
/** -------------------- ITreeBoard begin -------------------- */
|
||||
|
||||
/**
|
||||
* @see ITreeBoard
|
||||
*/
|
||||
readonly at: string | symbol;
|
||||
|
||||
/**
|
||||
* @see ITreeBoard
|
||||
*/
|
||||
@ -295,32 +348,6 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicMo
|
||||
|
||||
/** -------------------- ITreeBoard end -------------------- */
|
||||
|
||||
private dwell = new DwellTimer((target, event) => {
|
||||
const { canvas, project } = this.pluginContext;
|
||||
const document = project.getCurrentDocument();
|
||||
let index: any;
|
||||
let focus: any;
|
||||
let valid = true;
|
||||
if (target.hasSlots()) {
|
||||
index = null;
|
||||
focus = { type: 'slots' };
|
||||
} else {
|
||||
index = 0;
|
||||
valid = !!document?.checkNesting(target, event.dragObject as any);
|
||||
}
|
||||
canvas.createLocation({
|
||||
target,
|
||||
source: this.id,
|
||||
event,
|
||||
detail: {
|
||||
type: IPublicTypeLocationDetailType.Children,
|
||||
index,
|
||||
focus,
|
||||
valid,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
private getNear(treeNode: TreeNode, e: IPublicModelLocateEvent, originalIndex?: number, originalRect?: DOMRect) {
|
||||
const { canvas, project } = this.pluginContext;
|
||||
const document = project.getCurrentDocument();
|
||||
@ -541,39 +568,12 @@ export class PaneController implements IPublicModelSensor, ITreeBoard, IPublicMo
|
||||
return canvas.createLocation(locationData);
|
||||
}
|
||||
|
||||
private tryScrollAgain: number | null = null;
|
||||
|
||||
private sensing = false;
|
||||
|
||||
/**
|
||||
* @see IScrollable
|
||||
*/
|
||||
get bounds(): DOMRect | null {
|
||||
if (!this._shell) {
|
||||
return null;
|
||||
}
|
||||
return this._shell.getBoundingClientRect();
|
||||
}
|
||||
|
||||
private _scrollTarget?: IPublicModelScrollTarget;
|
||||
|
||||
/**
|
||||
* @see IScrollable
|
||||
*/
|
||||
get scrollTarget() {
|
||||
return this._scrollTarget;
|
||||
}
|
||||
|
||||
private scroller?: IPublicModelScroller;
|
||||
|
||||
purge() {
|
||||
const { canvas } = this.pluginContext;
|
||||
canvas.dragon?.removeSensor(this);
|
||||
this.treeMaster?.removeBoard(this);
|
||||
}
|
||||
|
||||
private _shell: HTMLDivElement | null = null;
|
||||
|
||||
mount(shell: HTMLDivElement | null) {
|
||||
if (this._shell === shell) {
|
||||
return;
|
||||
|
||||
@ -2,7 +2,7 @@ import {
|
||||
IComponentMeta as InnerComponentMeta,
|
||||
INode,
|
||||
} from '@alilc/lowcode-designer';
|
||||
import { IPublicTypeNodeData, IPublicTypeNodeSchema, IPublicModelComponentMeta, IPublicTypeI18nData, IPublicTypeIconType, IPublicTypeNpmInfo, IPublicTypeTransformedComponentMetadata, IPublicModelNode } from '@alilc/lowcode-types';
|
||||
import { IPublicTypeNodeData, IPublicTypeNodeSchema, IPublicModelComponentMeta, IPublicTypeI18nData, IPublicTypeIconType, IPublicTypeNpmInfo, IPublicTypeTransformedComponentMetadata, IPublicModelNode, IPublicTypeAdvanced } from '@alilc/lowcode-types';
|
||||
import { componentMetaSymbol, nodeSymbol } from '../symbols';
|
||||
import { ReactElement } from 'react';
|
||||
|
||||
@ -92,6 +92,10 @@ export class ComponentMeta implements IPublicModelComponentMeta {
|
||||
return this[componentMetaSymbol].availableActions;
|
||||
}
|
||||
|
||||
get advanced(): IPublicTypeAdvanced {
|
||||
return this[componentMetaSymbol].advanced;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 npm 信息
|
||||
* @param npm
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { IPublicTypeNodeSchema, IPublicTypeNodeData, IPublicTypeIconType, IPublicTypeTransformedComponentMetadata, IPublicTypeI18nData, IPublicTypeNpmInfo } from '../type';
|
||||
import { IPublicTypeNodeSchema, IPublicTypeNodeData, IPublicTypeIconType, IPublicTypeTransformedComponentMetadata, IPublicTypeI18nData, IPublicTypeNpmInfo, IPublicTypeAdvanced } from '../type';
|
||||
import { ReactElement } from 'react';
|
||||
import { IPublicModelNode } from './node';
|
||||
|
||||
@ -49,6 +49,12 @@ export interface IPublicModelComponentMeta {
|
||||
|
||||
get availableActions(): any;
|
||||
|
||||
/**
|
||||
* configure.advanced
|
||||
* @since v1.1.0
|
||||
*/
|
||||
get advanced(): IPublicTypeAdvanced;
|
||||
|
||||
/**
|
||||
* 设置 npm 信息
|
||||
* @param npm
|
||||
|
||||
@ -2,6 +2,7 @@ import { IPublicApiSetters } from '../api';
|
||||
import { IPublicModelEditor } from './';
|
||||
|
||||
export interface IPublicModelSettingTarget {
|
||||
|
||||
/**
|
||||
* 同样类型的节点
|
||||
*/
|
||||
@ -39,7 +40,6 @@ export interface IPublicModelSettingTarget {
|
||||
*/
|
||||
readonly parent: IPublicModelSettingTarget;
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前值
|
||||
*/
|
||||
|
||||
@ -5,58 +5,24 @@ import { IPublicModelSettingTarget } from '../model';
|
||||
/**
|
||||
* 高级特性配置
|
||||
*/
|
||||
|
||||
export interface IPublicTypeAdvanced {
|
||||
/**
|
||||
* @todo 待补充文档
|
||||
*/
|
||||
context?: { [contextInfoName: string]: any };
|
||||
/**
|
||||
* @deprecated 使用组件 metadata 上的 snippets 字段即可
|
||||
*/
|
||||
snippets?: IPublicTypeSnippet[];
|
||||
/**
|
||||
* @todo 待补充文档
|
||||
*/
|
||||
view?: ComponentType<any>;
|
||||
/**
|
||||
* @todo 待补充文档
|
||||
*/
|
||||
transducers?: any;
|
||||
/**
|
||||
* @deprecated 用于动态初始化拖拽到设计器里的组件的 prop 的值
|
||||
*/
|
||||
initials?: IPublicTypeInitialItem[];
|
||||
/**
|
||||
* @todo 待补充文档
|
||||
*/
|
||||
filters?: IPublicTypeFilterItem[];
|
||||
/**
|
||||
* @todo 待补充文档
|
||||
*/
|
||||
autoruns?: IPublicTypeAutorunItem[];
|
||||
|
||||
/**
|
||||
* 配置 callbacks 可捕获引擎抛出的一些事件,例如 onNodeAdd、onResize 等
|
||||
* callbacks/hooks which can be used to do
|
||||
* things on some special ocations like onNodeAdd or onResize
|
||||
*/
|
||||
callbacks?: IPublicTypeCallbacks;
|
||||
|
||||
/**
|
||||
* 拖入容器时,自动带入 children 列表
|
||||
*/
|
||||
initialChildren?: IPublicTypeNodeData[] | ((target: IPublicModelSettingTarget) => IPublicTypeNodeData[]);
|
||||
/**
|
||||
* @todo 待补充文档
|
||||
*/
|
||||
isAbsoluteLayoutContainer?: boolean;
|
||||
/**
|
||||
* @todo 待补充文档
|
||||
*/
|
||||
hideSelectTools?: boolean;
|
||||
|
||||
/**
|
||||
* 样式 及 位置,handle 上必须有明确的标识以便事件路由判断,或者主动设置事件独占模式
|
||||
* NWSE 是交给引擎计算放置位置,ReactElement 必须自己控制初始位置
|
||||
*/
|
||||
/**
|
||||
*
|
||||
* 用于配置设计器中组件 resize 操作工具的样式和内容
|
||||
* - hover 时控制柄高亮
|
||||
* - mousedown 时请求独占
|
||||
@ -73,13 +39,67 @@ export interface IPublicTypeAdvanced {
|
||||
}> |
|
||||
ReactElement[]);
|
||||
|
||||
/**
|
||||
* @deprecated 用于动态初始化拖拽到设计器里的组件的 prop 的值
|
||||
*/
|
||||
initials?: IPublicTypeInitialItem[];
|
||||
|
||||
/**
|
||||
* @deprecated 使用组件 metadata 上的 snippets 字段即可
|
||||
*/
|
||||
snippets?: IPublicTypeSnippet[];
|
||||
|
||||
/**
|
||||
* 是否绝对布局容器,还未进入协议
|
||||
* @experimental not in spec yet
|
||||
*/
|
||||
isAbsoluteLayoutContainer?: boolean;
|
||||
|
||||
/**
|
||||
* hide bem tools when selected
|
||||
* @experimental not in spec yet
|
||||
*/
|
||||
hideSelectTools?: boolean;
|
||||
|
||||
/**
|
||||
* Live Text Editing:如果 children 内容是纯文本,支持双击直接编辑
|
||||
* @experimental not in spec yet
|
||||
*/
|
||||
liveTextEditing?: IPublicTypeLiveTextEditingConfig[];
|
||||
|
||||
/**
|
||||
* @deprecated 暂未使用
|
||||
* TODO: 补充文档
|
||||
* @experimental not in spec yet
|
||||
*/
|
||||
view?: ComponentType<any>;
|
||||
|
||||
/**
|
||||
* @legacy capability for vision
|
||||
* @deprecated
|
||||
*/
|
||||
isTopFixed?: boolean;
|
||||
|
||||
/**
|
||||
* TODO: 补充文档 或 删除
|
||||
* @deprecated not used anywhere, dont know what is it for
|
||||
*/
|
||||
context?: { [contextInfoName: string]: any };
|
||||
|
||||
/**
|
||||
* @legacy capability for vision
|
||||
* @deprecated
|
||||
*/
|
||||
filters?: IPublicTypeFilterItem[];
|
||||
|
||||
/**
|
||||
* @legacy capability for vision
|
||||
* @deprecated
|
||||
*/
|
||||
autoruns?: IPublicTypeAutorunItem[];
|
||||
|
||||
/**
|
||||
* @legacy capability for vision
|
||||
* @deprecated
|
||||
*/
|
||||
transducers?: any;
|
||||
}
|
||||
|
||||
@ -4,18 +4,22 @@ import { IPublicTypeComponentConfigure, ConfigureSupport, IPublicTypeFieldConfig
|
||||
* 编辑体验配置
|
||||
*/
|
||||
export interface IPublicTypeConfigure {
|
||||
|
||||
/**
|
||||
* 属性面板配置
|
||||
*/
|
||||
props?: IPublicTypeFieldConfig[];
|
||||
|
||||
/**
|
||||
* 组件能力配置
|
||||
*/
|
||||
component?: IPublicTypeComponentConfigure;
|
||||
|
||||
/**
|
||||
* 通用扩展面板支持性配置
|
||||
*/
|
||||
supports?: ConfigureSupport;
|
||||
|
||||
/**
|
||||
* 高级特性配置
|
||||
*/
|
||||
|
||||
@ -23,7 +23,7 @@ export const getClosestNode = (
|
||||
* @returns {boolean} 是否可点击,true表示可点击
|
||||
*/
|
||||
export const canClickNode = (node: IPublicModelNode, e: unknown): boolean => {
|
||||
const onClickHook = node.componentMeta?.getMetadata().configure?.advanced?.callbacks?.onClickHook;
|
||||
const onClickHook = node.componentMeta?.advanced.callbacks?.onClickHook;
|
||||
const canClick = typeof onClickHook === 'function' ? onClickHook(e as MouseEvent, node) : true;
|
||||
return canClick;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user