@tmagic/editor 1.7.12 → 1.7.13-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/Editor.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/es/components/ScrollViewer.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/components/Tree.vue_vue_type_script_setup_true_lang.js +6 -3
- package/dist/es/components/TreeNode.vue_vue_type_script_setup_true_lang.js +12 -7
- package/dist/es/index.js +2 -2
- package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/es/layouts/sidebar/layer/LayerPanel.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/es/layouts/workspace/Breadcrumb.vue_vue_type_script_setup_true_lang.js +87 -12
- package/dist/es/layouts/workspace/Workspace.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/layouts/workspace/viewer/Stage.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/es/services/editor.js +7 -5
- package/dist/es/services/props.js +2 -2
- package/dist/es/style.css +20 -0
- package/dist/es/utils/tree.js +3 -1
- package/dist/style.css +20 -0
- package/dist/tmagic-editor.umd.cjs +136 -35
- package/package.json +7 -7
- package/src/Editor.vue +2 -0
- package/src/components/ScrollViewer.vue +4 -1
- package/src/components/Tree.vue +4 -1
- package/src/components/TreeNode.vue +8 -8
- package/src/editorProps.ts +3 -0
- package/src/layouts/props-panel/PropsPanel.vue +1 -1
- package/src/layouts/sidebar/Sidebar.vue +4 -0
- package/src/layouts/sidebar/layer/LayerPanel.vue +11 -1
- package/src/layouts/workspace/Breadcrumb.vue +87 -6
- package/src/layouts/workspace/Workspace.vue +3 -1
- package/src/layouts/workspace/viewer/Stage.vue +7 -1
- package/src/services/editor.ts +11 -6
- package/src/services/props.ts +2 -2
- package/src/theme/breadcrumb.scss +24 -0
- package/src/type.ts +14 -1
- package/src/utils/tree.ts +5 -1
- package/types/index.d.ts +30 -7
|
@@ -4805,8 +4805,8 @@
|
|
|
4805
4805
|
* @param type 组件类型
|
|
4806
4806
|
* @returns 组件属性表单配置
|
|
4807
4807
|
*/
|
|
4808
|
-
async getPropsConfig(type) {
|
|
4809
|
-
if (type === "area") return await this.getPropsConfig("button");
|
|
4808
|
+
async getPropsConfig(type, data) {
|
|
4809
|
+
if (type === "area") return await this.getPropsConfig("button", data);
|
|
4810
4810
|
return cloneDeep(this.state.propsConfigMap[(0, _tmagic_utils.toLine)(type)] || await this.fillConfig([]));
|
|
4811
4811
|
}
|
|
4812
4812
|
setPropsValues(values) {
|
|
@@ -6103,7 +6103,7 @@
|
|
|
6103
6103
|
if (removedItems.length > 0 && pageForOp) this.pushOpHistory("remove", { removedItems }, pageForOp);
|
|
6104
6104
|
this.emit("remove", nodes);
|
|
6105
6105
|
}
|
|
6106
|
-
async doUpdate(config, { changeRecords = [] } = {}) {
|
|
6106
|
+
async doUpdate(config, { changeRecords = [], selectedAfterUpdate = true } = {}) {
|
|
6107
6107
|
const root = this.get("root");
|
|
6108
6108
|
if (!root) throw new Error("root为空");
|
|
6109
6109
|
if (!config?.id) throw new Error("没有配置或者配置缺少id值");
|
|
@@ -6130,10 +6130,12 @@
|
|
|
6130
6130
|
const layout = await this.getLayout(node);
|
|
6131
6131
|
if (Array.isArray(newConfig.items) && newLayout !== layout) newConfig = setChildrenLayout(newConfig, newLayout);
|
|
6132
6132
|
parentNodeItems[index] = newConfig;
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6133
|
+
if (selectedAfterUpdate) {
|
|
6134
|
+
const nodes = this.get("nodes");
|
|
6135
|
+
const targetIndex = nodes.findIndex((nodeItem) => `${nodeItem.id}` === `${newConfig.id}`);
|
|
6136
|
+
nodes.splice(targetIndex, 1, newConfig);
|
|
6137
|
+
this.set("nodes", [...nodes]);
|
|
6138
|
+
}
|
|
6137
6139
|
if ((0, _tmagic_utils.isPage)(newConfig) || (0, _tmagic_utils.isPageFragment)(newConfig)) this.set("page", newConfig);
|
|
6138
6140
|
this.addModifiedNodeId(newConfig.id);
|
|
6139
6141
|
return {
|
|
@@ -6877,6 +6879,8 @@
|
|
|
6877
6879
|
if (nodeStatus[key] !== void 0 && status[key] !== void 0) nodeStatus[key] = Boolean(status[key]);
|
|
6878
6880
|
});
|
|
6879
6881
|
};
|
|
6882
|
+
/** 默认的组件树节点是否可展开的判断函数:当节点的子项中至少存在一个可见节点时认为可展开 */
|
|
6883
|
+
var defaultIsExpandable = (data, nodeStatusMap) => Array.isArray(data.items) && data.items.some((item) => nodeStatusMap.get(item.id)?.visible);
|
|
6880
6884
|
//#endregion
|
|
6881
6885
|
//#region packages/editor/src/hooks/use-filter.ts
|
|
6882
6886
|
var useFilter = (nodeData, nodeStatusMap, filterNodeMethod) => {
|
|
@@ -9018,7 +9022,7 @@
|
|
|
9018
9022
|
return;
|
|
9019
9023
|
}
|
|
9020
9024
|
const type = node.value.type || (node.value.items ? "container" : "text");
|
|
9021
|
-
curFormConfig.value = await propsService.getPropsConfig(type);
|
|
9025
|
+
curFormConfig.value = await propsService.getPropsConfig(type, { node: node.value });
|
|
9022
9026
|
values.value = node.value;
|
|
9023
9027
|
};
|
|
9024
9028
|
(0, vue.watchEffect)(init);
|
|
@@ -9858,7 +9862,11 @@
|
|
|
9858
9862
|
parentsId: { default: () => [] },
|
|
9859
9863
|
nodeStatusMap: {},
|
|
9860
9864
|
indent: { default: 0 },
|
|
9861
|
-
nextLevelIndentIncrement: { default: 11 }
|
|
9865
|
+
nextLevelIndentIncrement: { default: 11 },
|
|
9866
|
+
isExpandable: {
|
|
9867
|
+
type: Function,
|
|
9868
|
+
default: defaultIsExpandable
|
|
9869
|
+
}
|
|
9862
9870
|
},
|
|
9863
9871
|
emits: [
|
|
9864
9872
|
"node-dragstart",
|
|
@@ -9881,7 +9889,6 @@
|
|
|
9881
9889
|
const selected = (0, vue.computed)(() => nodeStatus.value.selected);
|
|
9882
9890
|
const visible = (0, vue.computed)(() => nodeStatus.value.visible);
|
|
9883
9891
|
const draggable = (0, vue.computed)(() => nodeStatus.value.draggable);
|
|
9884
|
-
const hasChildren = (0, vue.computed)(() => Array.isArray(props.data.items) && props.data.items.some((item) => props.nodeStatusMap.get(item.id)?.visible));
|
|
9885
9892
|
const handleDragStart = (event) => {
|
|
9886
9893
|
treeEmit?.("node-dragstart", event, props.data);
|
|
9887
9894
|
};
|
|
@@ -9925,20 +9932,21 @@
|
|
|
9925
9932
|
onMouseenter: mouseenterHandler
|
|
9926
9933
|
}, [(0, vue.createVNode)(Icon_default, {
|
|
9927
9934
|
class: "expand-icon",
|
|
9928
|
-
style: (0, vue.normalizeStyle)(
|
|
9935
|
+
style: (0, vue.normalizeStyle)(__props.isExpandable(__props.data, __props.nodeStatusMap) ? "" : "color: transparent; cursor: default"),
|
|
9929
9936
|
icon: expanded.value ? (0, vue.unref)(_element_plus_icons_vue.ArrowDown) : (0, vue.unref)(_element_plus_icons_vue.ArrowRight),
|
|
9930
9937
|
onClick: expandHandler
|
|
9931
9938
|
}, null, 8, ["style", "icon"]), (0, vue.createElementVNode)("div", {
|
|
9932
9939
|
class: "tree-node-content",
|
|
9933
9940
|
onClick: nodeClickHandler
|
|
9934
|
-
}, [(0, vue.renderSlot)(_ctx.$slots, "tree-node-content", { data: __props.data }, () => [(0, vue.createElementVNode)("div", _hoisted_2$15, [(0, vue.renderSlot)(_ctx.$slots, "tree-node-label", { data: __props.data }, () => [(0, vue.createTextVNode)((0, vue.toDisplayString)(`${__props.data.name} (${__props.data.id})`), 1)])]), (0, vue.createElementVNode)("div", _hoisted_3$4, [(0, vue.renderSlot)(_ctx.$slots, "tree-node-tool", { data: __props.data })])])])], 38),
|
|
9941
|
+
}, [(0, vue.renderSlot)(_ctx.$slots, "tree-node-content", { data: __props.data }, () => [(0, vue.createElementVNode)("div", _hoisted_2$15, [(0, vue.renderSlot)(_ctx.$slots, "tree-node-label", { data: __props.data }, () => [(0, vue.createTextVNode)((0, vue.toDisplayString)(`${__props.data.name} (${__props.data.id})`), 1)])]), (0, vue.createElementVNode)("div", _hoisted_3$4, [(0, vue.renderSlot)(_ctx.$slots, "tree-node-tool", { data: __props.data })])])])], 38), __props.isExpandable(__props.data, __props.nodeStatusMap) && expanded.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_4$3, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.data.items, (item) => {
|
|
9935
9942
|
return (0, vue.openBlock)(), (0, vue.createBlock)(_component_TreeNode, {
|
|
9936
9943
|
key: item.id,
|
|
9937
9944
|
data: item,
|
|
9938
9945
|
parent: __props.data,
|
|
9939
9946
|
parentsId: [...__props.parentsId, __props.data.id],
|
|
9940
9947
|
"node-status-map": __props.nodeStatusMap,
|
|
9941
|
-
indent: __props.indent + __props.nextLevelIndentIncrement
|
|
9948
|
+
indent: __props.indent + __props.nextLevelIndentIncrement,
|
|
9949
|
+
"is-expandable": __props.isExpandable
|
|
9942
9950
|
}, {
|
|
9943
9951
|
"tree-node-content": (0, vue.withCtx)(({ data: nodeData }) => [(0, vue.renderSlot)(_ctx.$slots, "tree-node-content", { data: nodeData })]),
|
|
9944
9952
|
"tree-node-label": (0, vue.withCtx)(({ data: nodeData }) => [(0, vue.renderSlot)(_ctx.$slots, "tree-node-label", { data: nodeData })]),
|
|
@@ -9949,7 +9957,8 @@
|
|
|
9949
9957
|
"parent",
|
|
9950
9958
|
"parentsId",
|
|
9951
9959
|
"node-status-map",
|
|
9952
|
-
"indent"
|
|
9960
|
+
"indent",
|
|
9961
|
+
"is-expandable"
|
|
9953
9962
|
]);
|
|
9954
9963
|
}), 128))])) : (0, vue.createCommentVNode)("v-if", true)], 40, _hoisted_1$49)), [[vue.vShow, visible.value]]);
|
|
9955
9964
|
};
|
|
@@ -9972,7 +9981,8 @@
|
|
|
9972
9981
|
nodeStatusMap: {},
|
|
9973
9982
|
indent: { default: 0 },
|
|
9974
9983
|
nextLevelIndentIncrement: {},
|
|
9975
|
-
emptyText: { default: "暂无数据" }
|
|
9984
|
+
emptyText: { default: "暂无数据" },
|
|
9985
|
+
isExpandable: {}
|
|
9976
9986
|
},
|
|
9977
9987
|
emits: [
|
|
9978
9988
|
"node-dragover",
|
|
@@ -9999,7 +10009,8 @@
|
|
|
9999
10009
|
data: item,
|
|
10000
10010
|
indent: __props.indent,
|
|
10001
10011
|
"next-level-indent-increment": __props.nextLevelIndentIncrement,
|
|
10002
|
-
"node-status-map": __props.nodeStatusMap
|
|
10012
|
+
"node-status-map": __props.nodeStatusMap,
|
|
10013
|
+
"is-expandable": __props.isExpandable
|
|
10003
10014
|
}, {
|
|
10004
10015
|
"tree-node-content": (0, vue.withCtx)(({ data: nodeData }) => [(0, vue.renderSlot)(_ctx.$slots, "tree-node-content", { data: nodeData })]),
|
|
10005
10016
|
"tree-node-label": (0, vue.withCtx)(({ data: nodeData }) => [(0, vue.renderSlot)(_ctx.$slots, "tree-node-label", { data: nodeData })]),
|
|
@@ -10009,7 +10020,8 @@
|
|
|
10009
10020
|
"data",
|
|
10010
10021
|
"indent",
|
|
10011
10022
|
"next-level-indent-increment",
|
|
10012
|
-
"node-status-map"
|
|
10023
|
+
"node-status-map",
|
|
10024
|
+
"is-expandable"
|
|
10013
10025
|
]);
|
|
10014
10026
|
}), 128)) : ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", _hoisted_1$48, [(0, vue.createElementVNode)("p", null, (0, vue.toDisplayString)(__props.emptyText), 1)]))], 32);
|
|
10015
10027
|
};
|
|
@@ -11444,7 +11456,8 @@
|
|
|
11444
11456
|
layerContentMenu: {},
|
|
11445
11457
|
indent: {},
|
|
11446
11458
|
nextLevelIndentIncrement: {},
|
|
11447
|
-
customContentMenu: { type: Function }
|
|
11459
|
+
customContentMenu: { type: Function },
|
|
11460
|
+
isExpandable: { type: Function }
|
|
11448
11461
|
},
|
|
11449
11462
|
setup(__props) {
|
|
11450
11463
|
const services = useServices();
|
|
@@ -11484,6 +11497,7 @@
|
|
|
11484
11497
|
"node-status-map": (0, vue.unref)(nodeStatusMap),
|
|
11485
11498
|
indent: __props.indent,
|
|
11486
11499
|
"next-level-indent-increment": __props.nextLevelIndentIncrement,
|
|
11500
|
+
"is-expandable": __props.isExpandable,
|
|
11487
11501
|
onNodeDragover: (0, vue.unref)(handleDragOver),
|
|
11488
11502
|
onNodeDragstart: (0, vue.unref)(handleDragStart),
|
|
11489
11503
|
onNodeDragleave: (0, vue.unref)(handleDragLeave),
|
|
@@ -11501,6 +11515,7 @@
|
|
|
11501
11515
|
"node-status-map",
|
|
11502
11516
|
"indent",
|
|
11503
11517
|
"next-level-indent-increment",
|
|
11518
|
+
"is-expandable",
|
|
11504
11519
|
"onNodeDragover",
|
|
11505
11520
|
"onNodeDragstart",
|
|
11506
11521
|
"onNodeDragleave",
|
|
@@ -11676,7 +11691,8 @@
|
|
|
11676
11691
|
layerContentMenu: {},
|
|
11677
11692
|
indent: {},
|
|
11678
11693
|
nextLevelIndentIncrement: {},
|
|
11679
|
-
customContentMenu: {}
|
|
11694
|
+
customContentMenu: {},
|
|
11695
|
+
layerNodeIsExpandable: {}
|
|
11680
11696
|
},
|
|
11681
11697
|
setup(__props, { expose: __expose }) {
|
|
11682
11698
|
const props = __props;
|
|
@@ -11715,7 +11731,8 @@
|
|
|
11715
11731
|
layerContentMenu: props.layerContentMenu,
|
|
11716
11732
|
customContentMenu: props.customContentMenu,
|
|
11717
11733
|
indent: props.indent,
|
|
11718
|
-
nextLevelIndentIncrement: props.nextLevelIndentIncrement
|
|
11734
|
+
nextLevelIndentIncrement: props.nextLevelIndentIncrement,
|
|
11735
|
+
isExpandable: props.layerNodeIsExpandable
|
|
11719
11736
|
},
|
|
11720
11737
|
component: LayerPanel_default,
|
|
11721
11738
|
slots: {}
|
|
@@ -12084,7 +12101,7 @@
|
|
|
12084
12101
|
(0, vue.createElementVNode)("div", {
|
|
12085
12102
|
ref: "target",
|
|
12086
12103
|
style: (0, vue.normalizeStyle)(style.value)
|
|
12087
|
-
}, [(0, vue.renderSlot)(_ctx.$slots, "default")], 4),
|
|
12104
|
+
}, [(0, vue.renderSlot)(_ctx.$slots, "before"), (0, vue.renderSlot)(_ctx.$slots, "default")], 4),
|
|
12088
12105
|
(0, vue.renderSlot)(_ctx.$slots, "content"),
|
|
12089
12106
|
scrollHeight.value > __props.wrapHeight ? ((0, vue.openBlock)(), (0, vue.createBlock)(ScrollBar_default, {
|
|
12090
12107
|
key: 0,
|
|
@@ -12673,6 +12690,7 @@
|
|
|
12673
12690
|
},
|
|
12674
12691
|
onClick: _cache[0] || (_cache[0] = ($event) => stageWrapRef.value?.container?.focus())
|
|
12675
12692
|
}, {
|
|
12693
|
+
before: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "stage-top")]),
|
|
12676
12694
|
content: (0, vue.withCtx)(() => [!__props.disabledStageOverlay ? ((0, vue.openBlock)(), (0, vue.createBlock)(StageOverlay_default, { key: 0 })) : (0, vue.createCommentVNode)("v-if", true), ((0, vue.openBlock)(), (0, vue.createBlock)(vue.Teleport, { to: "body" }, [(0, vue.createVNode)(ViewerMenu_default, {
|
|
12677
12695
|
ref: "menu",
|
|
12678
12696
|
"is-multi-select": isMultiSelect.value,
|
|
@@ -12691,7 +12709,7 @@
|
|
|
12691
12709
|
onDrop: dropHandler,
|
|
12692
12710
|
onDragover: dragoverHandler
|
|
12693
12711
|
}, null, 36), (0, vue.createVNode)(NodeListMenu_default)]),
|
|
12694
|
-
_:
|
|
12712
|
+
_: 3
|
|
12695
12713
|
}, 8, [
|
|
12696
12714
|
"width",
|
|
12697
12715
|
"height",
|
|
@@ -12709,9 +12727,13 @@
|
|
|
12709
12727
|
//#region packages/editor/src/layouts/workspace/Breadcrumb.vue?vue&type=script&setup=true&lang.ts
|
|
12710
12728
|
var _hoisted_1$39 = {
|
|
12711
12729
|
key: 0,
|
|
12712
|
-
class: "m-editor-breadcrumb"
|
|
12730
|
+
class: "m-editor-breadcrumb-ellipsis"
|
|
12731
|
+
};
|
|
12732
|
+
var _hoisted_2$12 = {
|
|
12733
|
+
key: 2,
|
|
12734
|
+
class: "m-editor-breadcrumb-separator"
|
|
12713
12735
|
};
|
|
12714
|
-
var
|
|
12736
|
+
var COLLAPSE_RATIO = .8;
|
|
12715
12737
|
var Breadcrumb_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
|
|
12716
12738
|
name: "MEditorBreadcrumb",
|
|
12717
12739
|
__name: "Breadcrumb",
|
|
@@ -12721,21 +12743,92 @@
|
|
|
12721
12743
|
const nodes = (0, vue.computed)(() => editorService.get("nodes"));
|
|
12722
12744
|
const root = (0, vue.computed)(() => editorService.get("root"));
|
|
12723
12745
|
const path = (0, vue.computed)(() => (0, _tmagic_utils.getNodePath)(node.value?.id || "", root.value?.items || []));
|
|
12746
|
+
const containerRef = (0, vue.ref)(null);
|
|
12747
|
+
const collapsed = (0, vue.ref)(false);
|
|
12748
|
+
const displayPath = (0, vue.computed)(() => {
|
|
12749
|
+
const list = path.value;
|
|
12750
|
+
if (!collapsed.value || list.length <= 3) return list;
|
|
12751
|
+
return [
|
|
12752
|
+
list[0],
|
|
12753
|
+
{
|
|
12754
|
+
isEllipsis: true,
|
|
12755
|
+
id: "__ellipsis__",
|
|
12756
|
+
name: "..."
|
|
12757
|
+
},
|
|
12758
|
+
list[list.length - 2],
|
|
12759
|
+
list[list.length - 1]
|
|
12760
|
+
];
|
|
12761
|
+
});
|
|
12762
|
+
const measureOverflow = async () => {
|
|
12763
|
+
if (collapsed.value) {
|
|
12764
|
+
collapsed.value = false;
|
|
12765
|
+
await (0, vue.nextTick)();
|
|
12766
|
+
}
|
|
12767
|
+
const el = containerRef.value;
|
|
12768
|
+
const parent = el?.parentElement;
|
|
12769
|
+
if (!el || !parent) return;
|
|
12770
|
+
const contentWidth = el.scrollWidth;
|
|
12771
|
+
const parentWidth = parent.clientWidth;
|
|
12772
|
+
if (parentWidth <= 0) return;
|
|
12773
|
+
collapsed.value = contentWidth > parentWidth * COLLAPSE_RATIO;
|
|
12774
|
+
};
|
|
12775
|
+
let resizeObserver = null;
|
|
12776
|
+
const observe = () => {
|
|
12777
|
+
resizeObserver?.disconnect();
|
|
12778
|
+
const el = containerRef.value;
|
|
12779
|
+
if (!el || typeof ResizeObserver === "undefined") return;
|
|
12780
|
+
resizeObserver = new ResizeObserver(() => {
|
|
12781
|
+
measureOverflow();
|
|
12782
|
+
});
|
|
12783
|
+
resizeObserver.observe(el);
|
|
12784
|
+
if (el.parentElement) resizeObserver.observe(el.parentElement);
|
|
12785
|
+
};
|
|
12786
|
+
(0, vue.onMounted)(() => {
|
|
12787
|
+
observe();
|
|
12788
|
+
measureOverflow();
|
|
12789
|
+
});
|
|
12790
|
+
(0, vue.onBeforeUnmount)(() => {
|
|
12791
|
+
resizeObserver?.disconnect();
|
|
12792
|
+
resizeObserver = null;
|
|
12793
|
+
});
|
|
12794
|
+
(0, vue.watch)(() => nodes.value.length, async () => {
|
|
12795
|
+
await (0, vue.nextTick)();
|
|
12796
|
+
observe();
|
|
12797
|
+
measureOverflow();
|
|
12798
|
+
});
|
|
12799
|
+
(0, vue.watch)(path, async () => {
|
|
12800
|
+
await (0, vue.nextTick)();
|
|
12801
|
+
measureOverflow();
|
|
12802
|
+
});
|
|
12724
12803
|
const select = async (node) => {
|
|
12725
12804
|
await editorService.select(node);
|
|
12726
12805
|
editorService.get("stage")?.select(node.id);
|
|
12727
12806
|
};
|
|
12728
12807
|
return (_ctx, _cache) => {
|
|
12729
|
-
return nodes.value.length === 1 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div",
|
|
12730
|
-
|
|
12731
|
-
|
|
12732
|
-
|
|
12733
|
-
|
|
12808
|
+
return nodes.value.length === 1 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
|
|
12809
|
+
key: 0,
|
|
12810
|
+
ref_key: "containerRef",
|
|
12811
|
+
ref: containerRef,
|
|
12812
|
+
class: "m-editor-breadcrumb"
|
|
12813
|
+
}, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(displayPath.value, (item, index) => {
|
|
12814
|
+
return (0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: item.isEllipsis ? `ellipsis-${index}` : item.id }, [item.isEllipsis ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_1$39, "...")) : ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(_tmagic_design.TMagicTooltip), {
|
|
12815
|
+
key: 1,
|
|
12816
|
+
content: item.name,
|
|
12817
|
+
placement: "top",
|
|
12818
|
+
"show-after": 500
|
|
12734
12819
|
}, {
|
|
12735
|
-
default: (0, vue.withCtx)(() => [(0, vue.
|
|
12820
|
+
default: (0, vue.withCtx)(() => [(0, vue.createVNode)((0, vue.unref)(_tmagic_design.TMagicButton), {
|
|
12821
|
+
class: "m-editor-breadcrumb-item",
|
|
12822
|
+
link: "",
|
|
12823
|
+
disabled: item.id === node.value?.id,
|
|
12824
|
+
onClick: ($event) => select(item)
|
|
12825
|
+
}, {
|
|
12826
|
+
default: (0, vue.withCtx)(() => [(0, vue.createTextVNode)((0, vue.toDisplayString)(item.name), 1)]),
|
|
12827
|
+
_: 2
|
|
12828
|
+
}, 1032, ["disabled", "onClick"])]),
|
|
12736
12829
|
_: 2
|
|
12737
|
-
}, 1032, ["
|
|
12738
|
-
}), 128))])) : (0, vue.createCommentVNode)("v-if", true);
|
|
12830
|
+
}, 1032, ["content"])), index < displayPath.value.length - 1 ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("span", _hoisted_2$12, "/")) : (0, vue.createCommentVNode)("v-if", true)], 64);
|
|
12831
|
+
}), 128))], 512)) : (0, vue.createCommentVNode)("v-if", true);
|
|
12739
12832
|
};
|
|
12740
12833
|
}
|
|
12741
12834
|
});
|
|
@@ -12769,7 +12862,10 @@
|
|
|
12769
12862
|
"disabled-stage-overlay": __props.disabledStageOverlay,
|
|
12770
12863
|
"stage-content-menu": __props.stageContentMenu,
|
|
12771
12864
|
"custom-content-menu": __props.customContentMenu
|
|
12772
|
-
},
|
|
12865
|
+
}, {
|
|
12866
|
+
"stage-top": (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "stage-top")]),
|
|
12867
|
+
_: 3
|
|
12868
|
+
}, 8, [
|
|
12773
12869
|
"stage-options",
|
|
12774
12870
|
"disabled-stage-overlay",
|
|
12775
12871
|
"stage-content-menu",
|
|
@@ -14229,6 +14325,7 @@
|
|
|
14229
14325
|
canSelect: { type: Function },
|
|
14230
14326
|
isContainer: { type: Function },
|
|
14231
14327
|
customContentMenu: { type: Function },
|
|
14328
|
+
layerNodeIsExpandable: { type: Function },
|
|
14232
14329
|
beforeDblclick: { type: Function },
|
|
14233
14330
|
extendFormState: { type: Function },
|
|
14234
14331
|
pageBarSortOptions: {},
|
|
@@ -14312,7 +14409,8 @@
|
|
|
14312
14409
|
"layer-content-menu": __props.layerContentMenu,
|
|
14313
14410
|
"custom-content-menu": __props.customContentMenu,
|
|
14314
14411
|
indent: __props.treeIndent,
|
|
14315
|
-
"next-level-indent-increment": __props.treeNextLevelIndentIncrement
|
|
14412
|
+
"next-level-indent-increment": __props.treeNextLevelIndentIncrement,
|
|
14413
|
+
"layer-node-is-expandable": __props.layerNodeIsExpandable
|
|
14316
14414
|
}, {
|
|
14317
14415
|
"layer-panel-header": (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "layer-panel-header")]),
|
|
14318
14416
|
"layer-node-content": (0, vue.withCtx)(({ data }) => [(0, vue.renderSlot)(_ctx.$slots, "layer-node-content", { data })]),
|
|
@@ -14335,13 +14433,15 @@
|
|
|
14335
14433
|
"layer-content-menu",
|
|
14336
14434
|
"custom-content-menu",
|
|
14337
14435
|
"indent",
|
|
14338
|
-
"next-level-indent-increment"
|
|
14436
|
+
"next-level-indent-increment",
|
|
14437
|
+
"layer-node-is-expandable"
|
|
14339
14438
|
])])]),
|
|
14340
14439
|
workspace: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "workspace", { editorService: (0, vue.unref)(editor_default) }, () => [(0, vue.createVNode)(Workspace_default, {
|
|
14341
14440
|
"disabled-stage-overlay": __props.disabledStageOverlay,
|
|
14342
14441
|
"stage-content-menu": __props.stageContentMenu,
|
|
14343
14442
|
"custom-content-menu": __props.customContentMenu
|
|
14344
14443
|
}, {
|
|
14444
|
+
"stage-top": (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "stage-top")]),
|
|
14345
14445
|
stage: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "stage")]),
|
|
14346
14446
|
"workspace-content": (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "workspace-content", { editorService: (0, vue.unref)(editor_default) })]),
|
|
14347
14447
|
_: 3
|
|
@@ -18854,6 +18954,7 @@
|
|
|
18854
18954
|
exports.dataSourceService = dataSource_default;
|
|
18855
18955
|
exports.debug = debug;
|
|
18856
18956
|
exports.default = plugin_default;
|
|
18957
|
+
exports.defaultIsExpandable = defaultIsExpandable;
|
|
18857
18958
|
exports.depService = dep_default;
|
|
18858
18959
|
Object.defineProperty(exports, "designPlugin", {
|
|
18859
18960
|
enumerable: true,
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.7.
|
|
2
|
+
"version": "1.7.13-beta.0",
|
|
3
3
|
"name": "@tmagic/editor",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
@@ -58,11 +58,11 @@
|
|
|
58
58
|
"moveable": "^0.53.0",
|
|
59
59
|
"serialize-javascript": "^7.0.0",
|
|
60
60
|
"sortablejs": "^1.15.6",
|
|
61
|
-
"@tmagic/design": "1.7.
|
|
62
|
-
"@tmagic/form": "1.7.
|
|
63
|
-
"@tmagic/
|
|
64
|
-
"@tmagic/
|
|
65
|
-
"@tmagic/
|
|
61
|
+
"@tmagic/design": "1.7.13-beta.0",
|
|
62
|
+
"@tmagic/form": "1.7.13-beta.0",
|
|
63
|
+
"@tmagic/table": "1.7.13-beta.0",
|
|
64
|
+
"@tmagic/stage": "1.7.13-beta.0",
|
|
65
|
+
"@tmagic/utils": "1.7.13-beta.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@types/events": "^3.0.3",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"type-fest": "^5.2.0",
|
|
77
77
|
"typescript": "^6.0.3",
|
|
78
78
|
"vue": "^3.5.33",
|
|
79
|
-
"@tmagic/core": "1.7.
|
|
79
|
+
"@tmagic/core": "1.7.13-beta.0"
|
|
80
80
|
},
|
|
81
81
|
"peerDependenciesMeta": {
|
|
82
82
|
"typescript": {
|
package/src/Editor.vue
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
:custom-content-menu="customContentMenu"
|
|
27
27
|
:indent="treeIndent"
|
|
28
28
|
:next-level-indent-increment="treeNextLevelIndentIncrement"
|
|
29
|
+
:layer-node-is-expandable="layerNodeIsExpandable"
|
|
29
30
|
>
|
|
30
31
|
<template #layer-panel-header>
|
|
31
32
|
<slot name="layer-panel-header"></slot>
|
|
@@ -85,6 +86,7 @@
|
|
|
85
86
|
:stage-content-menu="stageContentMenu"
|
|
86
87
|
:custom-content-menu="customContentMenu"
|
|
87
88
|
>
|
|
89
|
+
<template #stage-top><slot name="stage-top"></slot></template>
|
|
88
90
|
<template #stage><slot name="stage"></slot></template>
|
|
89
91
|
<template #workspace-content><slot name="workspace-content" :editorService="editorService"></slot></template>
|
|
90
92
|
</Workspace>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="m-editor-scroll-viewer-container" ref="container">
|
|
3
3
|
<div ref="target" :style="style">
|
|
4
|
+
<slot name="before"></slot>
|
|
4
5
|
<slot></slot>
|
|
5
6
|
</div>
|
|
6
7
|
|
|
@@ -29,7 +30,7 @@ import { computed, onBeforeUnmount, onMounted, ref, useTemplateRef, watch } from
|
|
|
29
30
|
|
|
30
31
|
import { isNumber } from '@tmagic/utils';
|
|
31
32
|
|
|
32
|
-
import type { ScrollViewerEvent } from '@editor/type';
|
|
33
|
+
import type { ScrollViewerEvent, ScrollViewerSlots } from '@editor/type';
|
|
33
34
|
import { ScrollViewer } from '@editor/utils/scroll-viewer';
|
|
34
35
|
|
|
35
36
|
import ScrollBar from './ScrollBar.vue';
|
|
@@ -38,6 +39,8 @@ defineOptions({
|
|
|
38
39
|
name: 'MEditorScrollViewer',
|
|
39
40
|
});
|
|
40
41
|
|
|
42
|
+
defineSlots<ScrollViewerSlots>();
|
|
43
|
+
|
|
41
44
|
const props = withDefaults(
|
|
42
45
|
defineProps<{
|
|
43
46
|
width?: number | string;
|
package/src/components/Tree.vue
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
:indent="indent"
|
|
9
9
|
:next-level-indent-increment="nextLevelIndentIncrement"
|
|
10
10
|
:node-status-map="nodeStatusMap"
|
|
11
|
+
:is-expandable="isExpandable"
|
|
11
12
|
>
|
|
12
13
|
<template #tree-node-content="{ data: nodeData }">
|
|
13
14
|
<slot name="tree-node-content" :data="nodeData"> </slot>
|
|
@@ -33,7 +34,7 @@ import { provide } from 'vue';
|
|
|
33
34
|
|
|
34
35
|
import type { Id } from '@tmagic/core';
|
|
35
36
|
|
|
36
|
-
import type { LayerNodeStatus, TreeNodeData } from '@editor/type';
|
|
37
|
+
import type { IsExpandableFunction, LayerNodeStatus, TreeNodeData } from '@editor/type';
|
|
37
38
|
|
|
38
39
|
import TreeNode from './TreeNode.vue';
|
|
39
40
|
|
|
@@ -66,6 +67,8 @@ withDefaults(
|
|
|
66
67
|
indent?: number;
|
|
67
68
|
nextLevelIndentIncrement?: number;
|
|
68
69
|
emptyText?: string;
|
|
70
|
+
/** 自定义判断节点是否可展开(即是否要展示为拥有子节点的形态)的函数 */
|
|
71
|
+
isExpandable?: IsExpandableFunction;
|
|
69
72
|
}>(),
|
|
70
73
|
{
|
|
71
74
|
indent: 0,
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
>
|
|
21
21
|
<MIcon
|
|
22
22
|
class="expand-icon"
|
|
23
|
-
:style="
|
|
23
|
+
:style="isExpandable(data, nodeStatusMap) ? '' : 'color: transparent; cursor: default'"
|
|
24
24
|
:icon="expanded ? ArrowDown : ArrowRight"
|
|
25
25
|
@click="expandHandler"
|
|
26
26
|
></MIcon>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
</div>
|
|
38
38
|
</div>
|
|
39
39
|
|
|
40
|
-
<div v-if="
|
|
40
|
+
<div v-if="isExpandable(data, nodeStatusMap) && expanded" class="m-editor-tree-node-children">
|
|
41
41
|
<TreeNode
|
|
42
42
|
v-for="item in data.items"
|
|
43
43
|
:key="item.id"
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
:parentsId="[...parentsId, data.id]"
|
|
47
47
|
:node-status-map="nodeStatusMap"
|
|
48
48
|
:indent="indent + nextLevelIndentIncrement"
|
|
49
|
+
:is-expandable="isExpandable"
|
|
49
50
|
>
|
|
50
51
|
<template #tree-node-content="{ data: nodeData }">
|
|
51
52
|
<slot name="tree-node-content" :data="nodeData"> </slot>
|
|
@@ -68,8 +69,8 @@ import { ArrowDown, ArrowRight } from '@element-plus/icons-vue';
|
|
|
68
69
|
import type { Id } from '@tmagic/core';
|
|
69
70
|
|
|
70
71
|
import MIcon from '@editor/components/Icon.vue';
|
|
71
|
-
import type { LayerNodeStatus, TreeNodeData } from '@editor/type';
|
|
72
|
-
import { updateStatus } from '@editor/utils/tree';
|
|
72
|
+
import type { IsExpandableFunction, LayerNodeStatus, TreeNodeData } from '@editor/type';
|
|
73
|
+
import { defaultIsExpandable, updateStatus } from '@editor/utils/tree';
|
|
73
74
|
|
|
74
75
|
defineSlots<{
|
|
75
76
|
'tree-node-label'(_props: { data: TreeNodeData }): any;
|
|
@@ -100,11 +101,14 @@ const props = withDefaults(
|
|
|
100
101
|
nodeStatusMap: Map<Id, LayerNodeStatus>;
|
|
101
102
|
indent?: number;
|
|
102
103
|
nextLevelIndentIncrement?: number;
|
|
104
|
+
/** 自定义判断节点是否可展开(即是否要展示为拥有子节点的形态)的函数 */
|
|
105
|
+
isExpandable?: IsExpandableFunction;
|
|
103
106
|
}>(),
|
|
104
107
|
{
|
|
105
108
|
indent: 0,
|
|
106
109
|
nextLevelIndentIncrement: 11,
|
|
107
110
|
parentsId: () => [],
|
|
111
|
+
isExpandable: defaultIsExpandable,
|
|
108
112
|
},
|
|
109
113
|
);
|
|
110
114
|
|
|
@@ -123,10 +127,6 @@ const selected = computed(() => nodeStatus.value.selected);
|
|
|
123
127
|
const visible = computed(() => nodeStatus.value.visible);
|
|
124
128
|
const draggable = computed(() => nodeStatus.value.draggable);
|
|
125
129
|
|
|
126
|
-
const hasChildren = computed(
|
|
127
|
-
() => Array.isArray(props.data.items) && props.data.items.some((item) => props.nodeStatusMap.get(item.id)?.visible),
|
|
128
|
-
);
|
|
129
|
-
|
|
130
130
|
const handleDragStart = (event: DragEvent) => {
|
|
131
131
|
treeEmit?.('node-dragstart', event, props.data);
|
|
132
132
|
};
|
package/src/editorProps.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
ComponentGroup,
|
|
15
15
|
CustomContentMenuFunction,
|
|
16
16
|
DatasourceTypeOption,
|
|
17
|
+
IsExpandableFunction,
|
|
17
18
|
MenuBarData,
|
|
18
19
|
MenuButton,
|
|
19
20
|
MenuComponent,
|
|
@@ -98,6 +99,8 @@ export interface EditorProps {
|
|
|
98
99
|
isContainer?: (el: HTMLElement) => boolean | Promise<boolean>;
|
|
99
100
|
/** 用于自定义组件树与画布的右键菜单 */
|
|
100
101
|
customContentMenu?: CustomContentMenuFunction;
|
|
102
|
+
/** 用于自定义判断组件树节点是否可展开(即是否要展示为拥有子节点的形态) */
|
|
103
|
+
layerNodeIsExpandable?: IsExpandableFunction;
|
|
101
104
|
/** 画布双击前的钩子函数,返回 false 则阻止默认的双击行为 */
|
|
102
105
|
beforeDblclick?: (event: MouseEvent) => Promise<boolean | void> | boolean | void;
|
|
103
106
|
extendFormState?: (state: FormState) => Record<string, any> | Promise<Record<string, any>>;
|
|
@@ -115,7 +115,7 @@ const init = async () => {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
const type = node.value.type || (node.value.items ? 'container' : 'text');
|
|
118
|
-
curFormConfig.value = await propsService.getPropsConfig(type);
|
|
118
|
+
curFormConfig.value = await propsService.getPropsConfig(type, { node: node.value });
|
|
119
119
|
values.value = node.value;
|
|
120
120
|
};
|
|
121
121
|
|
|
@@ -164,6 +164,7 @@ import { useServices } from '@editor/hooks/use-services';
|
|
|
164
164
|
import {
|
|
165
165
|
ColumnLayout,
|
|
166
166
|
CustomContentMenuFunction,
|
|
167
|
+
type IsExpandableFunction,
|
|
167
168
|
type MenuButton,
|
|
168
169
|
type MenuComponent,
|
|
169
170
|
type SideBarData,
|
|
@@ -191,6 +192,8 @@ const props = withDefaults(
|
|
|
191
192
|
indent?: number;
|
|
192
193
|
nextLevelIndentIncrement?: number;
|
|
193
194
|
customContentMenu: CustomContentMenuFunction;
|
|
195
|
+
/** 自定义判断组件树节点是否可展开(即是否要展示为拥有子节点的形态)的函数 */
|
|
196
|
+
layerNodeIsExpandable?: IsExpandableFunction;
|
|
194
197
|
}>(),
|
|
195
198
|
{
|
|
196
199
|
data: () => ({
|
|
@@ -248,6 +251,7 @@ const getItemConfig = (data: SideItem): SideComponent => {
|
|
|
248
251
|
customContentMenu: props.customContentMenu,
|
|
249
252
|
indent: props.indent,
|
|
250
253
|
nextLevelIndentIncrement: props.nextLevelIndentIncrement,
|
|
254
|
+
isExpandable: props.layerNodeIsExpandable,
|
|
251
255
|
},
|
|
252
256
|
component: LayerPanel,
|
|
253
257
|
slots: {},
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
:node-status-map="nodeStatusMap"
|
|
13
13
|
:indent="indent"
|
|
14
14
|
:next-level-indent-increment="nextLevelIndentIncrement"
|
|
15
|
+
:is-expandable="isExpandable"
|
|
15
16
|
@node-dragover="handleDragOver"
|
|
16
17
|
@node-dragstart="handleDragStart"
|
|
17
18
|
@node-dragleave="handleDragLeave"
|
|
@@ -56,7 +57,14 @@ import SearchInput from '@editor/components/SearchInput.vue';
|
|
|
56
57
|
import Tree from '@editor/components/Tree.vue';
|
|
57
58
|
import { useFilter } from '@editor/hooks/use-filter';
|
|
58
59
|
import { useServices } from '@editor/hooks/use-services';
|
|
59
|
-
import type {
|
|
60
|
+
import type {
|
|
61
|
+
CustomContentMenuFunction,
|
|
62
|
+
IsExpandableFunction,
|
|
63
|
+
LayerPanelSlots,
|
|
64
|
+
MenuButton,
|
|
65
|
+
MenuComponent,
|
|
66
|
+
TreeNodeData,
|
|
67
|
+
} from '@editor/type';
|
|
60
68
|
|
|
61
69
|
import LayerMenu from './LayerMenu.vue';
|
|
62
70
|
import LayerNodeTool from './LayerNodeTool.vue';
|
|
@@ -76,6 +84,8 @@ defineProps<{
|
|
|
76
84
|
indent?: number;
|
|
77
85
|
nextLevelIndentIncrement?: number;
|
|
78
86
|
customContentMenu: CustomContentMenuFunction;
|
|
87
|
+
/** 自定义判断组件树节点是否可展开(即是否要展示为拥有子节点的形态)的函数 */
|
|
88
|
+
isExpandable?: IsExpandableFunction;
|
|
79
89
|
}>();
|
|
80
90
|
|
|
81
91
|
const services = useServices();
|