@tmagic/editor 1.3.10 → 1.3.11

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/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.10",
2
+ "version": "1.3.11",
3
3
  "name": "@tmagic/editor",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -42,14 +42,14 @@
42
42
  "dependencies": {
43
43
  "@babel/core": "^7.18.0",
44
44
  "@element-plus/icons-vue": "^2.3.1",
45
- "@tmagic/core": "1.3.10",
46
- "@tmagic/dep": "1.3.10",
47
- "@tmagic/design": "1.3.10",
48
- "@tmagic/form": "1.3.10",
49
- "@tmagic/schema": "1.3.10",
50
- "@tmagic/stage": "1.3.10",
51
- "@tmagic/table": "1.3.10",
52
- "@tmagic/utils": "1.3.10",
45
+ "@tmagic/core": "1.3.11",
46
+ "@tmagic/dep": "1.3.11",
47
+ "@tmagic/design": "1.3.11",
48
+ "@tmagic/form": "1.3.11",
49
+ "@tmagic/schema": "1.3.11",
50
+ "@tmagic/stage": "1.3.11",
51
+ "@tmagic/table": "1.3.11",
52
+ "@tmagic/utils": "1.3.11",
53
53
  "buffer": "^6.0.3",
54
54
  "color": "^3.1.3",
55
55
  "emmet-monaco-es": "^5.3.0",
@@ -63,8 +63,8 @@
63
63
  "vue": "^3.3.8"
64
64
  },
65
65
  "peerDependencies": {
66
- "@tmagic/design": "1.3.10",
67
- "@tmagic/form": "1.3.10",
66
+ "@tmagic/design": "1.3.11",
67
+ "@tmagic/form": "1.3.11",
68
68
  "monaco-editor": "^0.41.0",
69
69
  "vue": "^3.3.8"
70
70
  },
@@ -4,11 +4,13 @@
4
4
  <slot></slot>
5
5
  </div>
6
6
 
7
+ <slot name="content"></slot>
8
+
7
9
  <ScrollBar
8
10
  v-if="scrollHeight > wrapHeight"
9
11
  :scroll-size="scrollHeight"
10
- :size="wrapHeight"
11
12
  :pos="vOffset"
13
+ :size="wrapHeight"
12
14
  @scroll="vScrollHandler"
13
15
  ></ScrollBar>
14
16
  <ScrollBar
@@ -5,14 +5,14 @@ import type { Id, MNode } from '@tmagic/schema';
5
5
  import { LayerNodeStatus, TreeNodeData } from '@editor/type';
6
6
  import { traverseNode } from '@editor/utils';
7
7
 
8
- const createPageNodeStatus = (nodeData: TreeNodeData[], initalLayerNodeStatus?: Map<Id, LayerNodeStatus>) => {
8
+ const createPageNodeStatus = (nodeData: TreeNodeData[], initialLayerNodeStatus?: Map<Id, LayerNodeStatus>) => {
9
9
  const map = new Map<Id, LayerNodeStatus>();
10
10
 
11
11
  nodeData.forEach((node: MNode) =>
12
12
  traverseNode(node, (node) => {
13
13
  map.set(
14
14
  node.id,
15
- initalLayerNodeStatus?.get(node.id) || {
15
+ initialLayerNodeStatus?.get(node.id) || {
16
16
  visible: true,
17
17
  expand: false,
18
18
  selected: false,
@@ -0,0 +1,158 @@
1
+ import { computed, inject, nextTick, ref, watch } from 'vue';
2
+
3
+ import type StageCore from '@tmagic/stage';
4
+
5
+ import type { Services, StageOptions } from '@editor/type';
6
+
7
+ import { useStage } from './use-stage';
8
+
9
+ export const useStageOverlay = () => {
10
+ const services = inject<Services>('services');
11
+ const stageOptions = inject<StageOptions>('stageOptions');
12
+
13
+ const wrapWidth = ref(0);
14
+ const wrapHeight = ref(0);
15
+ const stageOverlayVisible = ref(false);
16
+ const stageOverlay = ref<HTMLDivElement>();
17
+
18
+ const stage = computed(() => services?.editorService.get('stage'));
19
+
20
+ let subStage: StageCore | null = null;
21
+
22
+ const div = document.createElement('div');
23
+ let selectEl: HTMLElement | null = null;
24
+
25
+ const render = () => {
26
+ if (!selectEl) return;
27
+
28
+ const content = selectEl.cloneNode(true) as HTMLElement;
29
+ content.style.position = 'static';
30
+ Array.from(div.children).forEach((element) => {
31
+ element.remove();
32
+ });
33
+ div.appendChild(content);
34
+
35
+ subStage?.renderer.contentWindow?.magic.onPageElUpdate(div);
36
+
37
+ subStage?.select(content);
38
+ };
39
+
40
+ const copyDocumentElement = () => {
41
+ const doc = subStage?.renderer.getDocument();
42
+ const documentElement = stage.value?.renderer.getDocument()?.documentElement;
43
+
44
+ if (doc && documentElement) {
45
+ doc.replaceChild(documentElement.cloneNode(true), doc.documentElement);
46
+ }
47
+ };
48
+
49
+ const updateOverlay = () => {
50
+ if (!selectEl) return;
51
+
52
+ const { scrollWidth, scrollHeight } = selectEl;
53
+
54
+ stageOverlay.value!.style.width = `${scrollWidth}px`;
55
+ stageOverlay.value!.style.height = `${scrollHeight}px`;
56
+
57
+ wrapWidth.value = scrollWidth;
58
+ wrapHeight.value = scrollHeight;
59
+ };
60
+
61
+ const updateHandler = () => {
62
+ render();
63
+ updateOverlay();
64
+ };
65
+
66
+ const addHandler = () => {
67
+ render();
68
+ updateOverlay();
69
+ };
70
+
71
+ const removeHandler = () => {
72
+ render();
73
+ updateOverlay();
74
+ };
75
+
76
+ const openOverlay = async (el: HTMLElement) => {
77
+ selectEl = el;
78
+
79
+ stageOverlayVisible.value = true;
80
+
81
+ if (!stageOverlay.value) {
82
+ await nextTick();
83
+ }
84
+
85
+ if (!stageOptions) {
86
+ return;
87
+ }
88
+
89
+ subStage = useStage({
90
+ ...stageOptions,
91
+ runtimeUrl: '',
92
+ autoScrollIntoView: false,
93
+ render(stage: StageCore) {
94
+ copyDocumentElement();
95
+
96
+ const rootEl = stage.renderer.getDocument()?.getElementById('app');
97
+ if (rootEl) {
98
+ rootEl.remove();
99
+ }
100
+
101
+ div.style.cssText = `
102
+ width: ${el.scrollWidth}px;
103
+ height: ${el.scrollHeight}px;
104
+ background-color: #fff;
105
+ `;
106
+
107
+ render();
108
+
109
+ return div;
110
+ },
111
+ });
112
+ subStage.mount(stageOverlay.value!);
113
+
114
+ const { mask, renderer } = subStage;
115
+
116
+ const { contentWindow } = renderer;
117
+ mask.showRule(false);
118
+
119
+ updateOverlay();
120
+
121
+ contentWindow?.magic.onRuntimeReady({});
122
+
123
+ services?.editorService.on('update', updateHandler);
124
+ services?.editorService.on('add', addHandler);
125
+ services?.editorService.on('remove', removeHandler);
126
+ };
127
+
128
+ const closeOverlay = () => {
129
+ stageOverlayVisible.value = false;
130
+ subStage?.destroy();
131
+ subStage = null;
132
+
133
+ services?.editorService.off('update', updateHandler);
134
+ services?.editorService.off('add', addHandler);
135
+ services?.editorService.off('remove', removeHandler);
136
+ };
137
+
138
+ watch(stage, (stage) => {
139
+ if (stage) {
140
+ stage.on('dblclick', async (event: MouseEvent) => {
141
+ const el = await stage.actionManager.getElementFromPoint(event);
142
+ if (el) {
143
+ openOverlay(el);
144
+ }
145
+ });
146
+ } else if (subStage) {
147
+ closeOverlay();
148
+ }
149
+ });
150
+
151
+ return {
152
+ wrapWidth,
153
+ wrapHeight,
154
+ stageOverlayVisible,
155
+ stageOverlay,
156
+ closeOverlay,
157
+ };
158
+ };
@@ -22,16 +22,21 @@
22
22
  @drop="dropHandler"
23
23
  @dragover="dragoverHandler"
24
24
  ></div>
25
+
25
26
  <NodeListMenu></NodeListMenu>
26
27
 
27
- <Teleport to="body">
28
- <ViewerMenu
29
- ref="menu"
30
- :is-multi-select="isMultiSelect"
31
- :stage-content-menu="stageContentMenu"
32
- :custom-content-menu="customContentMenu"
33
- ></ViewerMenu>
34
- </Teleport>
28
+ <template #content>
29
+ <StageOverlay></StageOverlay>
30
+
31
+ <Teleport to="body">
32
+ <ViewerMenu
33
+ ref="menu"
34
+ :is-multi-select="isMultiSelect"
35
+ :stage-content-menu="stageContentMenu"
36
+ :custom-content-menu="customContentMenu"
37
+ ></ViewerMenu>
38
+ </Teleport>
39
+ </template>
35
40
  </ScrollViewer>
36
41
  </template>
37
42
 
@@ -49,6 +54,7 @@ import { getConfig } from '@editor/utils/config';
49
54
  import { KeyBindingContainerKey } from '@editor/utils/keybinding-config';
50
55
 
51
56
  import NodeListMenu from './NodeListMenu.vue';
57
+ import StageOverlay from './StageOverlay.vue';
52
58
  import ViewerMenu from './ViewerMenu.vue';
53
59
 
54
60
  defineOptions({
@@ -93,10 +99,13 @@ watchEffect(() => {
93
99
 
94
100
  services?.editorService.set('stage', markRaw(stage));
95
101
 
96
- stage?.mount(stageContainer.value);
102
+ stage.mount(stageContainer.value);
103
+
104
+ if (!node.value?.id) {
105
+ return;
106
+ }
97
107
 
98
- if (!node.value?.id) return;
99
- stage?.on('runtime-ready', (rt) => {
108
+ stage.on('runtime-ready', (rt) => {
100
109
  runtime = rt;
101
110
  // toRaw返回的值是一个引用而非快照,需要cloneDeep
102
111
  root.value && runtime?.updateRootConfig?.(cloneDeep(toRaw(root.value)));
@@ -210,8 +219,8 @@ const dropHandler = async (e: DragEvent) => {
210
219
 
211
220
  if (parentEl && doc) {
212
221
  const { left: parentLeft, top: parentTop } = getOffset(parentEl);
213
- left = left - calcValueByFontsize(doc, parentLeft);
214
- top = top - calcValueByFontsize(doc, parentTop);
222
+ left = left - calcValueByFontsize(doc, parentLeft) * zoom.value;
223
+ top = top - calcValueByFontsize(doc, parentTop) * zoom.value;
215
224
  }
216
225
  }
217
226
 
@@ -0,0 +1,16 @@
1
+ <template>
2
+ <div v-if="stageOverlayVisible" class="m-editor-stage-overlay" @click="closeOverlay">
3
+ <TMagicIcon class="m-editor-stage-overlay-close" :size="20" @click="closeOverlay"><CloseBold /></TMagicIcon>
4
+ <div ref="stageOverlay" class="m-editor-stage-overlay-container" @click.stop></div>
5
+ </div>
6
+ </template>
7
+
8
+ <script setup lang="ts">
9
+ import { CloseBold } from '@element-plus/icons-vue';
10
+
11
+ import { TMagicIcon } from '@tmagic/design';
12
+
13
+ import { useStageOverlay } from '@editor/hooks/use-stage-overlay';
14
+
15
+ const { stageOverlayVisible, stageOverlay, closeOverlay } = useStageOverlay();
16
+ </script>
@@ -26,6 +26,30 @@
26
26
  }
27
27
  }
28
28
 
29
+ .m-editor-stage-overlay {
30
+ position: absolute;
31
+ left: 0;
32
+ top: 0;
33
+ width: 100%;
34
+ height: 100%;
35
+ background-color: rgba(0, 0, 0, 0.6);
36
+ display: flex;
37
+ z-index: 20;
38
+ overflow: auto;
39
+ }
40
+
41
+ .m-editor-stage-overlay-container {
42
+ position: relative;
43
+ flex-shrink: 0;
44
+ margin: auto;
45
+ }
46
+
47
+ .m-editor-stage-overlay-close.tmagic-design-icon {
48
+ position: fixed;
49
+ right: 10px;
50
+ top: 10px;
51
+ }
52
+
29
53
  .m-editor-stage-float-button {
30
54
  cursor: pointer;
31
55
  transform: translateY(-50%);
@@ -52,6 +52,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
52
52
  };
53
53
  }, {}>, {
54
54
  default?(_: {}): any;
55
+ content?(_: {}): any;
55
56
  }>;
56
57
  export default _default;
57
58
  type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
@@ -0,0 +1,7 @@
1
+ export declare const useStageOverlay: () => {
2
+ wrapWidth: import("vue").Ref<number>;
3
+ wrapHeight: import("vue").Ref<number>;
4
+ stageOverlayVisible: import("vue").Ref<boolean>;
5
+ stageOverlay: import("vue").Ref<HTMLDivElement | undefined>;
6
+ closeOverlay: () => void;
7
+ };
@@ -0,0 +1,2 @@
1
+ declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
2
+ export default _default;