{
- const nodes = this.state.parentNodes || [];
+ const nodes = this.state.parentNodes;
+ if (!nodes || nodes.length < 1) {
+ return null;
+ }
const children = nodes.map((node, key) => {
return (
Node;
onMount?: (designer: Designer) => void;
onDragstart?: (e: LocateEvent) => void;
onDrag?: (e: LocateEvent) => void;
@@ -328,19 +322,20 @@ export class Designer {
target: activedDoc.rootNode as ParentalNode,
};
}
+ const focusNode = activedDoc.focusNode;
const nodes = activedDoc.selection.getNodes();
+ const refNode = nodes.find(item => focusNode.contains(item));
let target;
let index: number | undefined;
- if (!nodes || nodes.length < 1) {
- target = activedDoc.rootNode;
+ if (!refNode || refNode === focusNode) {
+ target = focusNode;
} else {
- const node = nodes[0];
- if (isRootNode(node) || node.componentMeta.isContainer) {
- target = node;
+ if (refNode.componentMeta.isContainer) {
+ target = refNode;
} else {
// FIXME!!, parent maybe null
- target = node.parent!;
- index = node.index + 1;
+ target = refNode.parent!;
+ index = refNode.index + 1;
}
}
diff --git a/packages/designer/src/designer/offset-observer.ts b/packages/designer/src/designer/offset-observer.ts
index 7b4b8bebf..85dfca9db 100644
--- a/packages/designer/src/designer/offset-observer.ts
+++ b/packages/designer/src/designer/offset-observer.ts
@@ -105,7 +105,8 @@ export class OffsetObserver {
this.node = node;
const doc = node.document;
const host = doc.simulator!;
- this.isRoot = isRootNode(node);
+ const focusNode = doc.focusNode;
+ this.isRoot = node.contains(focusNode);
this.viewport = host.viewport;
if (this.isRoot) {
this.hasOffset = true;
diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts
index 342e4d9db..0462952ea 100644
--- a/packages/designer/src/document/document-model.ts
+++ b/packages/designer/src/document/document-model.ts
@@ -93,6 +93,23 @@ export class DocumentModel {
this.rootNode?.getExtraProp('fileName', true)?.setValue(fileName);
}
+ @computed get focusNode() {
+ if (this._drillDownNode) {
+ return this._drillDownNode;
+ }
+ const selector = this.designer.get('focusNodeSelector');
+ if (typeof selector === 'function') {
+ return selector(this.rootNode);
+ }
+ return this.rootNode;
+ }
+
+ @obx.ref private _drillDownNode: Node | null = null;
+
+ drillDown(node: Node | null) {
+ this._drillDownNode = node;
+ }
+
private _modalNode?: ParentalNode;
private _blank?: boolean;
@@ -151,7 +168,7 @@ export class DocumentModel {
}
get currentRoot() {
- return this.modalNode || this.rootNode;
+ return this.modalNode || this.focusNode;
}
addWillPurge(node: Node) {
@@ -346,6 +363,7 @@ export class DocumentModel {
}
import(schema: RootSchema, checkId = false) {
+ const drillDownNodeId = this._drillDownNode?.id;
// TODO: 暂时用饱和式删除,原因是 Slot 节点并不是树节点,无法正常递归删除
this.nodes.forEach(node => {
if (node.isRoot()) return;
@@ -363,6 +381,9 @@ export class DocumentModel {
}
// todo: select added and active track added
+ if (drillDownNodeId) {
+ this.drillDown(this.getNode(drillDownNodeId));
+ }
}
export(stage: TransformStage = TransformStage.Serilize) {
diff --git a/packages/designer/src/document/selection.ts b/packages/designer/src/document/selection.ts
index c62f4be08..3a1a416f8 100644
--- a/packages/designer/src/document/selection.ts
+++ b/packages/designer/src/document/selection.ts
@@ -102,7 +102,7 @@ export class Selection {
containsNode(node: Node, excludeRoot = false) {
for (const id of this._selected) {
const parent = this.doc.getNode(id);
- if (excludeRoot && parent === this.doc.rootNode) {
+ if (excludeRoot && parent?.contains(this.doc.focusNode)) {
continue;
}
if (parent?.contains(node)) {
@@ -134,7 +134,7 @@ export class Selection {
for (const id of this._selected) {
const node = this.doc.getNode(id);
// 排除根节点
- if (!node || (!includeRoot && node === this.doc.rootNode)) {
+ if (!node || (!includeRoot && node.contains(this.doc.focusNode))) {
continue;
}
let i = nodes.length;
diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx
index ec3aed989..5a8015d0b 100644
--- a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx
+++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx
@@ -64,13 +64,18 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any
const designer = editor.get(Designer);
const current = designer?.currentSelection?.getNodes()?.[0];
let node: Node | null = settings.first;
+ const focusNode = node.document.focusNode;
+
const items = [];
let l = 3;
while (l-- > 0 && node) {
const _node = node;
+ // dirty code: should remove
if (shouldIgnoreRoot && node.isRoot()) {
- node = null;
- continue;
+ break;
+ }
+ if (node.contains(focusNode)) {
+ l = 0;
}
const props =
l === 2
diff --git a/packages/plugin-outline-pane/src/main.ts b/packages/plugin-outline-pane/src/main.ts
index 6f2c74cef..383b3f7ad 100644
--- a/packages/plugin-outline-pane/src/main.ts
+++ b/packages/plugin-outline-pane/src/main.ts
@@ -164,7 +164,7 @@ export class OutlineMain implements ISensor, ITreeBoard, IScrollable {
const componentMeta = e.dragObject.nodes ? e.dragObject.nodes[0].componentMeta : null;
if (e.dragObject.type === 'node' && componentMeta && componentMeta.isModal) {
return designer.createLocation({
- target: document.rootNode,
+ target: document.focusNode,
detail: {
type: LocationDetailType.Children,
index: 0,
@@ -229,7 +229,7 @@ export class OutlineMain implements ISensor, ITreeBoard, IScrollable {
}
}
if (p !== node) {
- node = p || document.rootNode;
+ node = p || document.focusNode;
treeNode = tree.getTreeNode(node);
focusSlots = false;
}
diff --git a/packages/plugin-outline-pane/src/tree.ts b/packages/plugin-outline-pane/src/tree.ts
index a34bdfd21..bef37699d 100644
--- a/packages/plugin-outline-pane/src/tree.ts
+++ b/packages/plugin-outline-pane/src/tree.ts
@@ -1,18 +1,17 @@
import { DocumentModel, Node } from '@ali/lowcode-designer';
+import { computed } from '@ali/lowcode-editor-core';
import TreeNode from './tree-node';
export class Tree {
private treeNodesMap = new Map();
- readonly root: TreeNode;
-
readonly id: string;
- readonly document: DocumentModel;
+ @computed get root(): TreeNode {
+ return this.getTreeNode(this.document.focusNode);
+ }
- constructor(document: DocumentModel) {
- this.document = document;
- this.root = this.getTreeNode(document.rootNode);
+ constructor(readonly document: DocumentModel) {
this.id = document.id;
}
diff --git a/packages/plugin-outline-pane/src/views/tree.tsx b/packages/plugin-outline-pane/src/views/tree.tsx
index 4f7871e96..f1b2c5c9b 100644
--- a/packages/plugin-outline-pane/src/views/tree.tsx
+++ b/packages/plugin-outline-pane/src/views/tree.tsx
@@ -51,11 +51,11 @@ export default class TreeView extends Component<{ tree: Tree }> {
const { node } = treeNode;
const { designer } = treeNode;
const doc = node.document;
- const { selection } = doc;
+ const { selection, focusNode } = doc;
const { id } = node;
const isMulti = e.metaKey || e.ctrlKey || e.shiftKey;
designer.activeTracker.track(node);
- if (isMulti && !isRootNode(node) && selection.has(id)) {
+ if (isMulti && !node.contains(focusNode) && selection.has(id)) {
if (!isFormEvent(e.nativeEvent)) {
selection.remove(id);
}
@@ -107,13 +107,13 @@ export default class TreeView extends Component<{ tree: Tree }> {
const { node } = treeNode;
const { designer } = treeNode;
const doc = node.document;
- const { selection } = doc;
+ const { selection, focusNode } = doc;
// TODO: shift selection
const isMulti = e.metaKey || e.ctrlKey || e.shiftKey;
const isLeftButton = e.button === 0;
- if (isLeftButton && !isRootNode(node)) {
+ if (isLeftButton && !node.contains(focusNode)) {
let nodes: Node[] = [node];
this.ignoreUpSelected = false;
if (isMulti) {
@@ -123,7 +123,8 @@ export default class TreeView extends Component<{ tree: Tree }> {
selection.add(node.id);
this.ignoreUpSelected = true;
}
- selection.remove(doc.rootNode.id);
+ // todo: remove rootNodes id
+ selection.remove(focusNode.id);
// 获得顶层 nodes
nodes = selection.getTopNodes();
} else if (selection.has(node.id)) {