@tmagic/editor 1.5.0-beta.11 → 1.5.0-beta.12

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.
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="m-editor-page-bar-item m-editor-page-bar-item-icon m-editor-page-bar-search">
3
+ <Icon :icon="Search" @click="visible = !visible" :class="{ 'icon-active': visible }"></Icon>
4
+ <Teleport to=".m-editor-page-bar-tabs" v-if="visible">
5
+ <MForm
6
+ v-if="query"
7
+ class="m-editor-page-bar-search-panel"
8
+ :inline="true"
9
+ :config="formConfig"
10
+ :init-values="query"
11
+ @change="onFormChange"
12
+ ></MForm>
13
+ </Teleport>
14
+ </div>
15
+ </template>
16
+
17
+ <script setup lang="ts">
18
+ import { ref } from 'vue';
19
+ import { Search } from '@element-plus/icons-vue';
20
+
21
+ import { NodeType } from '@tmagic/core';
22
+ import { createForm, MForm } from '@tmagic/form';
23
+
24
+ import Icon from '@editor/components/Icon.vue';
25
+
26
+ interface Query {
27
+ pageType: NodeType[];
28
+ keyword: string;
29
+ }
30
+
31
+ const emit = defineEmits<{
32
+ search: [value: Query];
33
+ }>();
34
+
35
+ const query = defineModel<Query>('query');
36
+
37
+ const formConfig = createForm([
38
+ {
39
+ type: 'checkbox-group',
40
+ name: 'pageType',
41
+ options: [
42
+ {
43
+ value: NodeType.PAGE,
44
+ text: '页面',
45
+ },
46
+ {
47
+ value: NodeType.PAGE_FRAGMENT,
48
+ text: '页面片段',
49
+ },
50
+ ],
51
+ },
52
+ {
53
+ name: 'keyword',
54
+ placeholder: '请输入关键字',
55
+ },
56
+ ]);
57
+
58
+ const visible = ref(false);
59
+
60
+ const onFormChange = (values: Query) => {
61
+ query.value = values;
62
+ emit('search', values);
63
+ };
64
+ </script>
@@ -132,9 +132,20 @@ watch(zoom, (zoom) => {
132
132
  stage.setZoom(zoom);
133
133
  });
134
134
 
135
+ let timeoutId: NodeJS.Timeout | null = null;
135
136
  watch(page, (page) => {
136
137
  if (runtime && page) {
137
138
  services?.editorService.set('stageLoading', true);
139
+
140
+ if (timeoutId) {
141
+ globalThis.clearTimeout(timeoutId);
142
+ }
143
+
144
+ timeoutId = globalThis.setTimeout(() => {
145
+ services?.editorService.set('stageLoading', false);
146
+ timeoutId = null;
147
+ }, 3000);
148
+
138
149
  runtime.updatePageId?.(page.id);
139
150
  nextTick(() => {
140
151
  stage?.select(page.id);
@@ -92,8 +92,11 @@ class Dep extends BaseService {
92
92
  );
93
93
  });
94
94
 
95
- idleTask.once('finish', () => {
96
- this.emit('collected', nodes, deep);
95
+ return new Promise<void>((resolve) => {
96
+ idleTask.once('finish', () => {
97
+ this.emit('collected', nodes, deep);
98
+ resolve();
99
+ });
97
100
  });
98
101
  }
99
102
 
@@ -20,10 +20,19 @@ import { reactive, toRaw } from 'vue';
20
20
  import { cloneDeep, get, isObject, mergeWith, uniq } from 'lodash-es';
21
21
  import type { Writable } from 'type-fest';
22
22
 
23
- import type { Id, MApp, MComponent, MContainer, MNode, MPage, MPageFragment, TargetOptions } from '@tmagic/core';
23
+ import type { Id, MApp, MContainer, MNode, MPage, MPageFragment, TargetOptions } from '@tmagic/core';
24
24
  import { NodeType, Target, Watcher } from '@tmagic/core';
25
25
  import { isFixed } from '@tmagic/stage';
26
- import { calcValueByFontsize, getElById, getNodePath, isNumber, isPage, isPageFragment, isPop } from '@tmagic/utils';
26
+ import {
27
+ calcValueByFontsize,
28
+ getElById,
29
+ getNodeInfo,
30
+ getNodePath,
31
+ isNumber,
32
+ isPage,
33
+ isPageFragment,
34
+ isPop,
35
+ } from '@tmagic/utils';
27
36
 
28
37
  import BaseService from '@editor/services//BaseService';
29
38
  import propsService from '@editor/services//props';
@@ -175,36 +184,7 @@ class Editor extends BaseService {
175
184
  root = toRaw(root);
176
185
  }
177
186
 
178
- const info: EditorNodeInfo = {
179
- node: null,
180
- parent: null,
181
- page: null,
182
- };
183
-
184
- if (!root) return info;
185
-
186
- if (id === root.id) {
187
- info.node = root;
188
- return info;
189
- }
190
-
191
- const path = getNodePath(id, root.items);
192
-
193
- if (!path.length) return info;
194
-
195
- path.unshift(root);
196
-
197
- info.node = path[path.length - 1] as MComponent;
198
- info.parent = path[path.length - 2] as MContainer;
199
-
200
- path.forEach((item) => {
201
- if (isPage(item) || isPageFragment(item)) {
202
- info.page = item as MPage | MPageFragment;
203
- return;
204
- }
205
- });
206
-
207
- return info;
187
+ return getNodeInfo(id, root);
208
188
  }
209
189
 
210
190
  /**
@@ -494,11 +474,11 @@ class Editor extends BaseService {
494
474
  if (isPage(node)) {
495
475
  this.state.pageLength -= 1;
496
476
 
497
- await selectDefault(getPageList(root));
477
+ await selectDefault(rootItems);
498
478
  } else if (isPageFragment(node)) {
499
479
  this.state.pageFragmentLength -= 1;
500
480
 
501
- await selectDefault(getPageFragmentList(root));
481
+ await selectDefault(rootItems);
502
482
  } else {
503
483
  await this.select(parent);
504
484
  stage?.select(parent.id);
@@ -586,11 +566,7 @@ class Editor extends BaseService {
586
566
  nodes.splice(targetIndex, 1, newConfig);
587
567
  this.set('nodes', [...nodes]);
588
568
 
589
- this.get('stage')?.update({
590
- config: cloneDeep(newConfig),
591
- parentId: parent.id,
592
- root: cloneDeep(root),
593
- });
569
+ // update后会触发依赖收集,收集完后会掉stage.update方法
594
570
 
595
571
  if (isPage(newConfig) || isPageFragment(newConfig)) {
596
572
  this.set('page', newConfig as MPage | MPageFragment);
@@ -875,7 +851,11 @@ class Editor extends BaseService {
875
851
  await stage.select(targetId);
876
852
 
877
853
  const targetParent = this.getParentById(target.id);
878
- await stage.update({ config: cloneDeep(target), parentId: targetParent?.id, root: cloneDeep(root) });
854
+ await stage.update({
855
+ config: cloneDeep(target),
856
+ parentId: targetParent?.id,
857
+ root: cloneDeep(root),
858
+ });
879
859
 
880
860
  await this.select(newConfig);
881
861
  stage.select(newConfig.id);
@@ -3,19 +3,13 @@
3
3
  bottom: 0;
4
4
  left: 0;
5
5
  width: 100%;
6
+ user-select: none;
7
+ }
6
8
 
7
- .tmagic-design-button.m-editor-page-bar-switch-type-button {
8
- margin-left: 10px;
9
- position: relative;
10
- top: 1px;
11
- border-radius: 3px 3px 0 0;
12
- border: 1px solid $--border-color;
13
- border-bottom: 1px solid transparent;
14
- padding: 5px 10px;
15
-
16
- &.active {
17
- background-color: #f3f3f3;
18
- }
9
+ .m-editor-page-bar-item-icon {
10
+ .icon-active {
11
+ font-weight: bold;
12
+ color: $--theme-color;
19
13
  }
20
14
  }
21
15
 
@@ -101,3 +95,16 @@
101
95
  }
102
96
  }
103
97
  }
98
+
99
+ .m-editor-page-bar-search-panel {
100
+ position: absolute;
101
+ bottom: $--page-bar-height;
102
+ border: 1px solid $--border-color;
103
+ padding: 6px 10px;
104
+ width: 100%;
105
+ box-sizing: border-box;
106
+
107
+ .tmagic-design-form-item {
108
+ margin-bottom: 0;
109
+ }
110
+ }
package/src/type.ts CHANGED
@@ -77,9 +77,10 @@ export interface FrameworkSlots {
77
77
  'props-panel'(props: {}): any;
78
78
  'footer'(props: {}): any;
79
79
  'page-bar'(props: {}): any;
80
+ 'page-bar-add-button'(props: {}): any;
80
81
  'page-bar-title'(props: { page: MPage | MPageFragment }): any;
81
82
  'page-bar-popover'(props: { page: MPage | MPageFragment }): any;
82
- 'page-list-popover'(props: { list: MPage[] | MPageFragment[] }): any;
83
+ 'page-list-popover'(props: { list: (MPage | MPageFragment)[] }): any;
83
84
  }
84
85
 
85
86
  export interface WorkspaceSlots {
@@ -56,13 +56,14 @@ export class IdleTask<T = any> extends EventEmitter {
56
56
  }
57
57
 
58
58
  private runTaskQueue(deadline: IdleDeadline) {
59
- while ((deadline.timeRemaining() > 15 || deadline.didTimeout) && this.taskList.length) {
59
+ // 动画会占用空闲时间,当任务一直无法执行时,看看是否有动画正在播放
60
+ while ((deadline.timeRemaining() > 10 || deadline.didTimeout) && this.taskList.length) {
60
61
  const task = this.taskList.shift();
61
62
  task!.handler(task!.data);
62
63
  }
63
64
 
64
65
  if (this.taskList.length) {
65
- this.taskHandle = globalThis.requestIdleCallback(this.runTaskQueue.bind(this), { timeout: 10000 });
66
+ this.taskHandle = globalThis.requestIdleCallback(this.runTaskQueue.bind(this), { timeout: 300 });
66
67
  } else {
67
68
  this.taskHandle = 0;
68
69
 
package/types/index.d.ts CHANGED
@@ -306,7 +306,7 @@ declare class Dep extends export_default {
306
306
  removeTarget(id: Id, type?: string): void;
307
307
  clearTargets(): void;
308
308
  collect(nodes: MNode[], depExtendedData?: DepExtendedData, deep?: boolean, type?: DepTargetType): void;
309
- collectIdle(nodes: MNode[], depExtendedData?: DepExtendedData, deep?: boolean, type?: DepTargetType): void;
309
+ collectIdle(nodes: MNode[], depExtendedData?: DepExtendedData, deep?: boolean, type?: DepTargetType): Promise<void>;
310
310
  collectNode(node: MNode, target: Target, depExtendedData?: DepExtendedData, deep?: boolean): void;
311
311
  clear(nodes?: MNode[]): void;
312
312
  clearByType(type: DepTargetType, nodes?: MNode[]): void;
@@ -840,6 +840,7 @@ interface FrameworkSlots {
840
840
  'props-panel'(props: {}): any;
841
841
  'footer'(props: {}): any;
842
842
  'page-bar'(props: {}): any;
843
+ 'page-bar-add-button'(props: {}): any;
843
844
  'page-bar-title'(props: {
844
845
  page: MPage | MPageFragment;
845
846
  }): any;
@@ -847,7 +848,7 @@ interface FrameworkSlots {
847
848
  page: MPage | MPageFragment;
848
849
  }): any;
849
850
  'page-list-popover'(props: {
850
- list: MPage[] | MPageFragment[];
851
+ list: (MPage | MPageFragment)[];
851
852
  }): any;
852
853
  }
853
854
  interface WorkspaceSlots {
@@ -1,45 +0,0 @@
1
- <template>
2
- <TMagicButton
3
- v-for="item in data"
4
- class="m-editor-page-bar-switch-type-button"
5
- size="small"
6
- :key="item.type"
7
- link
8
- :class="{ active: modelValue === item.type }"
9
- :type="modelValue === item.type ? 'primary' : ''"
10
- @click="clickHandler(item.type)"
11
- >{{ item.text }}</TMagicButton
12
- >
13
- </template>
14
-
15
- <script setup lang="ts">
16
- import { NodeType } from '@tmagic/core';
17
- import { TMagicButton } from '@tmagic/design';
18
-
19
- defineOptions({
20
- name: 'MEditorPageBarSwitchTypeButton',
21
- });
22
-
23
- defineProps<{
24
- modelValue: NodeType.PAGE | NodeType.PAGE_FRAGMENT;
25
- }>();
26
-
27
- const data: { type: NodeType.PAGE | NodeType.PAGE_FRAGMENT; text: string }[] = [
28
- {
29
- type: NodeType.PAGE,
30
- text: '页面',
31
- },
32
- {
33
- type: NodeType.PAGE_FRAGMENT,
34
- text: '页面片',
35
- },
36
- ];
37
-
38
- const emit = defineEmits<{
39
- 'update:modelValue': [value: NodeType.PAGE | NodeType.PAGE_FRAGMENT];
40
- }>();
41
-
42
- const clickHandler = (value: NodeType.PAGE | NodeType.PAGE_FRAGMENT) => {
43
- emit('update:modelValue', value);
44
- };
45
- </script>