@tmagic/editor 1.3.1 → 1.3.3

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.
Files changed (51) hide show
  1. package/dist/style.css +50 -0
  2. package/dist/tmagic-editor.js +578 -574
  3. package/dist/tmagic-editor.js.map +1 -1
  4. package/dist/tmagic-editor.umd.cjs +590 -585
  5. package/dist/tmagic-editor.umd.cjs.map +1 -1
  6. package/package.json +15 -13
  7. package/src/components/CodeBlockEditor.vue +6 -4
  8. package/src/fields/DataSourceSelect.vue +15 -9
  9. package/src/hooks/index.ts +1 -0
  10. package/src/hooks/use-code-block-edit.ts +2 -0
  11. package/src/hooks/use-float-box.ts +153 -0
  12. package/src/index.ts +1 -0
  13. package/src/initService.ts +12 -11
  14. package/src/layouts/Framework.vue +10 -1
  15. package/src/layouts/sidebar/Sidebar.vue +90 -5
  16. package/src/layouts/sidebar/code-block/CodeBlockList.vue +2 -1
  17. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +11 -10
  18. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +6 -4
  19. package/src/layouts/sidebar/data-source/DataSourceList.vue +9 -8
  20. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +15 -15
  21. package/src/layouts/sidebar/layer/use-drag.ts +4 -0
  22. package/src/layouts/sidebar/layer/use-node-status.ts +20 -15
  23. package/src/services/dataSource.ts +4 -0
  24. package/src/services/dep.ts +22 -284
  25. package/src/services/ui.ts +15 -0
  26. package/src/theme/code-block.scss +5 -0
  27. package/src/theme/floatbox.scss +48 -0
  28. package/src/theme/sidebar.scss +1 -0
  29. package/src/theme/theme.scss +1 -0
  30. package/src/type.ts +30 -20
  31. package/types/components/CodeBlockEditor.vue.d.ts +3 -0
  32. package/types/fields/DataSourceSelect.vue.d.ts +6 -4
  33. package/types/hooks/index.d.ts +1 -0
  34. package/types/hooks/use-code-block-edit.d.ts +26 -46
  35. package/types/hooks/use-data-source-method.d.ts +26 -46
  36. package/types/hooks/use-float-box.d.ts +15 -0
  37. package/types/index.d.ts +1 -0
  38. package/types/layouts/PropsPanel.vue.d.ts +92 -59
  39. package/types/layouts/sidebar/Sidebar.vue.d.ts +1 -2
  40. package/types/layouts/sidebar/code-block/CodeBlockList.vue.d.ts +1 -1
  41. package/types/layouts/sidebar/code-block/CodeBlockListPanel.vue.d.ts +3 -1
  42. package/types/layouts/sidebar/data-source/DataSourceConfigPanel.vue.d.ts +3 -0
  43. package/types/layouts/sidebar/data-source/DataSourceList.vue.d.ts +1 -1
  44. package/types/layouts/sidebar/data-source/DataSourceListPanel.vue.d.ts +15 -2
  45. package/types/layouts/sidebar/layer/use-click.d.ts +7 -46
  46. package/types/services/dataSource.d.ts +10 -2
  47. package/types/services/dep.d.ts +12 -112
  48. package/types/services/ui.d.ts +8 -0
  49. package/types/type.d.ts +23 -18
  50. package/src/utils/dep.ts +0 -81
  51. package/types/utils/dep.d.ts +0 -6
@@ -38,11 +38,12 @@
38
38
  import { computed, inject, ref } from 'vue';
39
39
  import { Aim, Close, Coin, Edit, View } from '@element-plus/icons-vue';
40
40
 
41
+ import { DepTargetType } from '@tmagic/dep';
41
42
  import { tMagicMessageBox, TMagicTooltip, TMagicTree } from '@tmagic/design';
42
- import { Dep, Id } from '@tmagic/schema';
43
+ import { DepData, Id } from '@tmagic/schema';
43
44
 
44
45
  import Icon from '@editor/components/Icon.vue';
45
- import { type DataSourceListSlots, DepTargetType, type Services } from '@editor/type';
46
+ import type { DataSourceListSlots, Services } from '@editor/type';
46
47
 
47
48
  defineSlots<DataSourceListSlots>();
48
49
 
@@ -65,10 +66,10 @@ const dsDep = computed(() => depService?.getTargets(DepTargetType.DATA_SOURCE) |
65
66
  const dsMethodDep = computed(() => depService?.getTargets(DepTargetType.DATA_SOURCE_METHOD) || {});
66
67
  const dsCondDep = computed(() => depService?.getTargets(DepTargetType.DATA_SOURCE_COND) || {});
67
68
 
68
- const getKeyTreeConfig = (dep: Dep[string], type?: string) =>
69
+ const getKeyTreeConfig = (dep: DepData[string], type?: string) =>
69
70
  dep.keys.map((key) => ({ name: key, id: key, type: 'key', isMethod: type === 'method', isCond: type === 'cond' }));
70
71
 
71
- const getNodeTreeConfig = (id: string, dep: Dep[string], type?: string) => ({
72
+ const getNodeTreeConfig = (id: string, dep: DepData[string], type?: string) => ({
72
73
  name: dep.name,
73
74
  type: 'node',
74
75
  id,
@@ -81,7 +82,7 @@ const getNodeTreeConfig = (id: string, dep: Dep[string], type?: string) => ({
81
82
  * @param deps 依赖
82
83
  * @param type 依赖类型
83
84
  */
84
- const mergeChildren = (children: any[], deps: Dep, type?: string) => {
85
+ const mergeChildren = (children: any[], deps: DepData, type?: string) => {
85
86
  Object.entries(deps).forEach(([id, dep]) => {
86
87
  // 已经生成过的节点
87
88
  const nodeItem = children.find((item) => item.id === id);
@@ -97,9 +98,9 @@ const mergeChildren = (children: any[], deps: Dep, type?: string) => {
97
98
 
98
99
  const list = computed(() =>
99
100
  dataSources.value.map((ds) => {
100
- const dsDeps = dsDep.value[ds.id].deps;
101
- const dsMethodDeps = dsMethodDep.value[ds.id].deps;
102
- const dsCondDeps = dsCondDep.value[ds.id].deps;
101
+ const dsDeps = dsDep.value[ds.id]?.deps || {};
102
+ const dsMethodDeps = dsMethodDep.value[ds.id]?.deps || {};
103
+ const dsCondDeps = dsCondDep.value[ds.id]?.deps || {};
103
104
 
104
105
  const children: any[] = [];
105
106
  // 数据源依赖分为三种类型:key/node、method、cond,是分开存储,这里将其合并展示
@@ -23,20 +23,16 @@
23
23
  </div>
24
24
 
25
25
  <!-- 数据源列表 -->
26
- <DataSourceList @edit="editHandler" @remove="removeHandler">
27
- <template #data-source-panel-tool="{ data }">
28
- <slot name="data-source-panel-tool" :data="data"></slot>
29
- </template>
30
- </DataSourceList>
31
-
32
- <DataSourceConfigPanel
33
- ref="editDialog"
34
- :disabled="!editable"
35
- :values="dataSourceValues"
36
- :title="dialogTitle"
37
- @submit="submitDataSourceHandler"
38
- ></DataSourceConfigPanel>
26
+ <DataSourceList @edit="editHandler" @remove="removeHandler"></DataSourceList>
39
27
  </TMagicScrollbar>
28
+ <DataSourceConfigPanel
29
+ ref="editDialog"
30
+ :disabled="!editable"
31
+ :values="dataSourceValues"
32
+ :title="dialogTitle"
33
+ :slideType="slideType"
34
+ @submit="submitDataSourceHandler"
35
+ ></DataSourceConfigPanel>
40
36
  </template>
41
37
 
42
38
  <script setup lang="ts">
@@ -48,7 +44,7 @@ import type { DataSourceSchema } from '@tmagic/schema';
48
44
 
49
45
  import SearchInput from '@editor/components/SearchInput.vue';
50
46
  import ToolButton from '@editor/components/ToolButton.vue';
51
- import type { DataSourceListSlots, Services } from '@editor/type';
47
+ import type { DataSourceListSlots, Services, SlideType } from '@editor/type';
52
48
 
53
49
  import DataSourceConfigPanel from './DataSourceConfigPanel.vue';
54
50
  import DataSourceList from './DataSourceList.vue';
@@ -59,6 +55,10 @@ defineOptions({
59
55
  name: 'MEditorDataSourceListPanel',
60
56
  });
61
57
 
58
+ defineProps<{
59
+ slideType?: SlideType;
60
+ }>();
61
+
62
62
  const { dataSourceService } = inject<Services>('services') || {};
63
63
 
64
64
  const editDialog = ref<InstanceType<typeof DataSourceConfigPanel>>();
@@ -102,7 +102,7 @@ const editHandler = (id: string) => {
102
102
  ...dataSourceService?.getDataSourceById(id),
103
103
  };
104
104
 
105
- dialogTitle.value = `新增${dataSourceValues.value.title || ''}`;
105
+ dialogTitle.value = `编辑${dataSourceValues.value.title || ''}`;
106
106
 
107
107
  editDialog.value.show();
108
108
  };
@@ -121,6 +121,10 @@ export const useDrag = (services: Services | undefined) => {
121
121
  removeStatusClass(dragState.container);
122
122
 
123
123
  if (node && dragState.dragOverNodeId && dragState.dropType && services) {
124
+ if (dragState.dragOverNodeId === node.id) {
125
+ return;
126
+ }
127
+
124
128
  const targetInfo = services.editorService.getNodeInfo(dragState.dragOverNodeId, false);
125
129
  const targetNode = targetInfo.node;
126
130
  let targetParent = targetInfo.parent;
@@ -7,7 +7,11 @@ import { LayerNodeStatus, Services } from '@editor/type';
7
7
  import { traverseNode } from '@editor/utils';
8
8
  import { updateStatus } from '@editor/utils/tree';
9
9
 
10
- const createPageNodeStatus = (services: Services | undefined, pageId: Id) => {
10
+ const createPageNodeStatus = (
11
+ services: Services | undefined,
12
+ pageId: Id,
13
+ initalLayerNodeStatus?: Map<Id, LayerNodeStatus>,
14
+ ) => {
11
15
  const map = new Map<Id, LayerNodeStatus>();
12
16
 
13
17
  map.set(pageId, {
@@ -19,12 +23,15 @@ const createPageNodeStatus = (services: Services | undefined, pageId: Id) => {
19
23
 
20
24
  services?.editorService.getNodeById(pageId)?.items.forEach((node: MNode) =>
21
25
  traverseNode(node, (node) => {
22
- map.set(node.id, {
23
- visible: true,
24
- expand: false,
25
- selected: false,
26
- draggable: true,
27
- });
26
+ map.set(
27
+ node.id,
28
+ initalLayerNodeStatus?.get(node.id) || {
29
+ visible: true,
30
+ expand: false,
31
+ selected: false,
32
+ draggable: true,
33
+ },
34
+ );
28
35
  }),
29
36
  );
30
37
 
@@ -42,17 +49,15 @@ export const useNodeStatus = (services: Services | undefined, page: ComputedRef<
42
49
  page.value ? nodeStatusMaps.value.get(page.value.id) : new Map<Id, LayerNodeStatus>(),
43
50
  );
44
51
 
45
- // 切换页面,重新生成节点状态
52
+ // 切换页面或者新增页面,重新生成节点状态
46
53
  watch(
47
- () => page.value?.id,
48
- (pageId) => {
49
- // 已经存在,不需要重新生成
50
- if (!pageId || nodeStatusMaps.value.has(pageId)) {
54
+ page,
55
+ (page) => {
56
+ if (!page) {
51
57
  return;
52
58
  }
53
-
54
- // 新增页面,生成节点状态
55
- nodeStatusMaps.value.set(pageId, createPageNodeStatus(services, pageId));
59
+ // 生成节点状态
60
+ nodeStatusMaps.value.set(page.id, createPageNodeStatus(services, page.id, nodeStatusMaps.value.get(page.id)));
56
61
  },
57
62
  {
58
63
  immediate: true,
@@ -82,6 +82,8 @@ class DataSource extends BaseService {
82
82
  this.get('dataSources').push(newConfig);
83
83
 
84
84
  this.emit('add', newConfig);
85
+
86
+ return newConfig;
85
87
  }
86
88
 
87
89
  public update(config: DataSourceSchema) {
@@ -92,6 +94,8 @@ class DataSource extends BaseService {
92
94
  dataSources[index] = cloneDeep(config);
93
95
 
94
96
  this.emit('update', config);
97
+
98
+ return config;
95
99
  }
96
100
 
97
101
  public remove(id: string) {
@@ -15,320 +15,58 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
- import { EventEmitter } from 'events';
19
-
20
18
  import { reactive } from 'vue';
21
19
 
22
- import type { Dep, Id, MNode } from '@tmagic/schema';
23
- import { isObject } from '@tmagic/utils';
24
-
25
- import { DepTargetType } from '@editor/type';
26
-
27
- type IsTarget = (key: string | number, value: any) => boolean;
28
-
29
- interface TargetOptions {
30
- isTarget: IsTarget;
31
- id: string | number;
32
- /** 类型,数据源、代码块或其他 */
33
- type?: DepTargetType | string;
34
- name?: string;
35
- }
36
-
37
- interface TargetList {
38
- [type: DepTargetType | string]: {
39
- [targetId: string | number]: Target;
40
- };
41
- }
42
-
43
- /**
44
- * 需要收集依赖的目标
45
- * 例如:一个代码块可以为一个目标
46
- */
47
- export class Target extends EventEmitter {
48
- /**
49
- * 如何识别目标
50
- */
51
- public isTarget: IsTarget;
52
- /**
53
- * 目标id,不可重复
54
- * 例如目标是代码块,则为代码块id
55
- */
56
- public id: string | number;
57
- /**
58
- * 目标名称,用于显示在依赖列表中
59
- */
60
- public name?: string;
61
- /**
62
- * 不同的目标可以进行分类,例如代码块,数据源可以为两个不同的type
63
- */
64
- public type: DepTargetType | string = DepTargetType.DEFAULT;
65
- /**
66
- * 依赖详情
67
- * 实例:{ 'node_id': { name: 'node_name', keys: [ created, mounted ] } }
68
- */
69
- public deps = reactive<Dep>({});
70
-
71
- constructor(options: TargetOptions) {
72
- super();
73
- this.isTarget = options.isTarget;
74
- this.id = options.id;
75
- this.name = options.name;
76
- if (options.type) {
77
- this.type = options.type;
78
- }
79
- }
80
-
81
- /**
82
- * 更新依赖
83
- * @param node 节点配置
84
- * @param key 哪个key配置了这个目标的id
85
- */
86
- public updateDep(node: MNode, key: string | number) {
87
- const dep = this.deps[node.id] || {
88
- name: node.name,
89
- keys: [],
90
- };
20
+ import { DepTargetType, type Target, Watcher } from '@tmagic/dep';
21
+ import type { Id, MNode } from '@tmagic/schema';
91
22
 
92
- if (node.name) {
93
- dep.name = node.name;
94
- }
23
+ import BaseService from './BaseService';
95
24
 
96
- this.deps[node.id] = dep;
25
+ class Dep extends BaseService {
26
+ private watcher = new Watcher({ initialTargets: reactive({}) });
97
27
 
98
- if (dep.keys.indexOf(key) === -1) {
99
- dep.keys.push(key);
100
- }
28
+ public removeTargets(type: string = DepTargetType.DEFAULT) {
29
+ this.watcher.removeTargets(type);
101
30
 
102
- this.emit('change');
103
- }
104
-
105
- /**
106
- * 删除依赖
107
- * @param node 哪个节点的依赖需要移除,如果为空,则移除所有依赖
108
- * @param key 节点下哪个key需要移除,如果为空,则移除改节点下的所有依赖key
109
- * @returns void
110
- */
111
- public removeDep(node?: MNode, key?: string | number) {
112
- if (!node) {
113
- Object.keys(this.deps).forEach((depKey) => {
114
- delete this.deps[depKey];
115
- });
116
- this.emit('change');
117
- return;
118
- }
119
-
120
- const dep = this.deps[node.id];
121
-
122
- if (!dep) return;
123
-
124
- if (key) {
125
- const index = dep.keys.indexOf(key);
126
- dep.keys.splice(index, 1);
127
-
128
- if (dep.keys.length === 0) {
129
- delete this.deps[node.id];
130
- }
131
- } else {
132
- delete this.deps[node.id];
133
- }
134
-
135
- this.emit('change');
31
+ this.emit('remove-target');
136
32
  }
137
33
 
138
- /**
139
- * 判断指定节点下的指定key是否存在在依赖列表中
140
- * @param node 哪个节点
141
- * @param key 哪个key
142
- * @returns boolean
143
- */
144
- public hasDep(node: MNode, key: string | number) {
145
- const dep = this.deps[node.id];
146
-
147
- return Boolean(dep?.keys.find((d) => d === key));
34
+ public getTargets(type: string = DepTargetType.DEFAULT) {
35
+ return this.watcher.getTargets(type);
148
36
  }
149
37
 
150
- public destroy() {
151
- this.removeAllListeners();
38
+ public getTarget(id: Id) {
39
+ return this.watcher.getTarget(id);
152
40
  }
153
- }
154
-
155
- export class Watcher extends EventEmitter {
156
- private targets = reactive<TargetList>({});
157
41
 
158
- /**
159
- * 获取指定类型中的所有target
160
- * @param type 分类
161
- * @returns Target[]
162
- */
163
- public getTargets(type: DepTargetType | string = DepTargetType.DEFAULT) {
164
- return this.targets[type] || {};
165
- }
166
-
167
- /**
168
- * 添加新的目标
169
- * @param target Target
170
- */
171
42
  public addTarget(target: Target) {
172
- const targets = this.getTargets(target.type) || {};
173
- this.targets[target.type] = targets;
174
- targets[target.id] = target;
175
-
43
+ this.watcher.addTarget(target);
176
44
  this.emit('add-target', target);
177
45
  }
178
46
 
179
- /**
180
- * 获取指定id的target
181
- * @param id target id
182
- * @returns Target
183
- */
184
- public getTarget(id: string | number) {
185
- const allTargets = Object.values(this.targets);
186
- for (const targets of allTargets) {
187
- if (targets[id]) {
188
- return targets[id];
189
- }
190
- }
191
- }
192
-
193
- /**
194
- * 判断是否存在指定id的target
195
- * @param id target id
196
- * @returns boolean
197
- */
198
- public hasTarget(id: string | number) {
199
- const allTargets = Object.values(this.targets);
200
- for (const targets of allTargets) {
201
- if (targets[id]) {
202
- return true;
203
- }
204
- }
205
-
206
- return false;
207
- }
208
-
209
- /**
210
- * 删除指定id的target
211
- * @param id target id
212
- */
213
- public removeTarget(id: string | number) {
214
- const allTargets = Object.values(this.targets);
215
- for (const targets of allTargets) {
216
- if (targets[id]) {
217
- targets[id].destroy();
218
- delete targets[id];
219
- }
220
- }
221
-
222
- this.emit('remove-target');
223
- }
224
-
225
- /**
226
- * 删除指定分类的所有target
227
- * @param type 分类
228
- * @returns void
229
- */
230
- public removeTargets(type: DepTargetType | string = DepTargetType.DEFAULT) {
231
- const targets = this.targets[type];
232
-
233
- if (!targets) return;
234
-
235
- for (const target of Object.values(targets)) {
236
- target.destroy();
237
- }
238
-
239
- delete this.targets[type];
240
-
47
+ public removeTarget(id: Id) {
48
+ this.watcher.removeTarget(id);
241
49
  this.emit('remove-target');
242
50
  }
243
51
 
244
- /**
245
- * 删除所有target
246
- */
247
52
  public clearTargets() {
248
- Object.keys(this.targets).forEach((key) => {
249
- delete this.targets[key];
250
- });
53
+ this.watcher.clearTargets();
251
54
  }
252
55
 
253
- /**
254
- * 收集依赖
255
- * @param nodes 需要收集的节点
256
- * @param deep 是否需要收集子节点
257
- */
258
56
  public collect(nodes: MNode[], deep = false) {
259
- Object.values(this.targets).forEach((targets) => {
260
- Object.values(targets).forEach((target) => {
261
- nodes.forEach((node) => {
262
- // 先删除原有依赖,重新收集
263
- target.removeDep(node);
264
- this.collectItem(node, target, deep);
265
- });
266
- });
267
- });
268
-
57
+ this.watcher.collect(nodes, deep);
269
58
  this.emit('collected', nodes, deep);
270
59
  }
271
60
 
272
- /**
273
- * 清除依赖
274
- * @param nodes 需要清除依赖的节点
275
- */
276
61
  public clear(nodes?: MNode[]) {
277
- const clearedItemsNodeIds: Id[] = [];
278
- Object.values(this.targets).forEach((targets) => {
279
- Object.values(targets).forEach((target) => {
280
- if (nodes) {
281
- nodes.forEach((node) => {
282
- target.removeDep(node);
283
-
284
- if (Array.isArray(node.items) && node.items.length && !clearedItemsNodeIds.includes(node.id)) {
285
- clearedItemsNodeIds.push(node.id);
286
- this.clear(node.items);
287
- }
288
- });
289
- } else {
290
- target.removeDep();
291
- }
292
- });
293
- });
62
+ return this.watcher.clear(nodes);
294
63
  }
295
64
 
296
- private collectItem(node: MNode, target: Target, deep = false) {
297
- const collectTarget = (config: Record<string | number, any>, prop = '') => {
298
- const doCollect = (key: string, value: any) => {
299
- const keyIsItems = key === 'items';
300
- const fullKey = prop ? `${prop}.${key}` : key;
301
-
302
- if (target.isTarget(fullKey, value)) {
303
- target.updateDep(node, fullKey);
304
- this.emit('update-dep', node, fullKey);
305
- } else if (!keyIsItems && Array.isArray(value)) {
306
- value.forEach((item, index) => {
307
- if (isObject(item)) {
308
- collectTarget(item, `${fullKey}.${index}`);
309
- }
310
- });
311
- } else if (isObject(value)) {
312
- collectTarget(value, fullKey);
313
- }
314
-
315
- if (keyIsItems && deep && Array.isArray(value)) {
316
- value.forEach((child) => {
317
- this.collectItem(child, target, deep);
318
- });
319
- }
320
- };
321
-
322
- Object.entries(config).forEach(([key, value]) => {
323
- if (typeof value === 'undefined' || value === '') return;
324
- doCollect(key, value);
325
- });
326
- };
327
-
328
- collectTarget(node);
65
+ public hasTarget(id: Id) {
66
+ return this.watcher.hasTarget(id);
329
67
  }
330
68
  }
331
69
 
332
- export type DepService = Watcher;
70
+ export type DepService = Dep;
333
71
 
334
- export default new Watcher();
72
+ export default new Dep();
@@ -44,6 +44,8 @@ const state = reactive<UiState>({
44
44
  showRule: true,
45
45
  propsPanelSize: 'small',
46
46
  showAddPageButton: true,
47
+ floatBox: new Map(),
48
+ hideSlideBar: false,
47
49
  });
48
50
 
49
51
  class Ui extends BaseService {
@@ -95,6 +97,19 @@ class Ui extends BaseService {
95
97
  return Math.min((width - 60) / stageWidth || 1, (height - 80) / stageHeight || 1);
96
98
  }
97
99
 
100
+ public async setFloatBox(keys: string[]) {
101
+ const map = state.floatBox;
102
+ for (const key of keys) {
103
+ if (map.get(key)) continue;
104
+ map.set(key, {
105
+ status: false,
106
+ zIndex: 99,
107
+ top: 0,
108
+ left: 0,
109
+ });
110
+ }
111
+ }
112
+
98
113
  public resetState() {
99
114
  this.set('showSrc', false);
100
115
  this.set('uiSelectMode', false);
@@ -33,4 +33,9 @@
33
33
  .el-drawer__body {
34
34
  padding: 10px 20px;
35
35
  }
36
+
37
+ &.m-form-box {
38
+ width: 100%;
39
+ min-width: 872px;
40
+ }
36
41
  }
@@ -0,0 +1,48 @@
1
+ .m-editor-float-box-list {
2
+ .m-editor-float-box {
3
+ position: absolute;
4
+ display: flex;
5
+ flex-direction: column;
6
+ width: auto;
7
+ height: 966px;
8
+ top: 240px;
9
+ left: 240px;
10
+ background: #fff;
11
+ box-sizing: border-box;
12
+ z-index: 999;
13
+ max-width: auto;
14
+ min-width: auto;
15
+ max-height: auto;
16
+ min-height: auto;
17
+ border: 1px solid #eee;
18
+ box-shadow: 0 0 72px #ccc;
19
+ &-header {
20
+ display: flex;
21
+ align-items: center;
22
+ padding: 0 16px;
23
+ height: 44px;
24
+ border-bottom: 1px solid #d8dee8;
25
+ &:hover {
26
+ cursor: pointer;
27
+ }
28
+ }
29
+ &-body {
30
+ display: flex;
31
+ flex: 1;
32
+ width: 100%;
33
+ overflow: scroll;
34
+ > *:first-child {
35
+ min-width: 247px;
36
+ border-right: 1px solid #d8dee8;
37
+ }
38
+ }
39
+
40
+ &-close {
41
+ position: absolute;
42
+ right: 16px;
43
+ }
44
+ }
45
+ .moveable-resizable {
46
+ opacity: 0;
47
+ }
48
+ }
@@ -40,6 +40,7 @@
40
40
  .magic-editor-tab-panel-title {
41
41
  font-size: 12px;
42
42
  white-space: normal;
43
+ user-select: none;
43
44
  }
44
45
  }
45
46
 
@@ -22,4 +22,5 @@
22
22
  @import "./data-source-methods.scss";
23
23
  @import "./data-source-input.scss";
24
24
  @import "./key-value.scss";
25
+ @import "./floatbox.scss";
25
26
  @import "./tree.scss";