@tmagic/editor 1.8.0-beta.11 → 1.8.0-beta.13

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 (119) hide show
  1. package/dist/es/Editor.vue_vue_type_script_setup_true_lang.js +7 -4
  2. package/dist/es/components/CodeBlockEditor.vue_vue_type_script_setup_true_lang.js +5 -1
  3. package/dist/es/components/CodeParams.vue_vue_type_script_setup_true_lang.js +2 -1
  4. package/dist/es/components/CompareForm.vue_vue_type_script_setup_true_lang.js +18 -123
  5. package/dist/es/components/FloatingBox.vue_vue_type_script_setup_true_lang.js +60 -14
  6. package/dist/es/components/ScrollBar.js +0 -1
  7. package/dist/es/components/ViewForm.js +5 -0
  8. package/dist/es/components/ViewForm.vue_vue_type_script_setup_true_lang.js +58 -0
  9. package/dist/es/editorProps.js +6 -1
  10. package/dist/es/fields/CodeSelect.vue_vue_type_script_setup_true_lang.js +15 -3
  11. package/dist/es/fields/CondOpSelect.vue_vue_type_script_setup_true_lang.js +2 -17
  12. package/dist/es/fields/DataSourceFieldSelect/FieldSelect.vue_vue_type_script_setup_true_lang.js +2 -1
  13. package/dist/es/fields/DataSourceFields.vue_vue_type_script_setup_true_lang.js +7 -0
  14. package/dist/es/fields/DataSourceInput.vue_vue_type_script_setup_true_lang.js +5 -17
  15. package/dist/es/fields/DataSourceMocks.vue_vue_type_script_setup_true_lang.js +4 -0
  16. package/dist/es/fields/DisplayConds.vue_vue_type_script_setup_true_lang.js +29 -3
  17. package/dist/es/fields/EventSelect.vue_vue_type_script_setup_true_lang.js +50 -88
  18. package/dist/es/fields/StyleSetter/Index.vue_vue_type_script_setup_true_lang.js +2 -5
  19. package/dist/es/fields/StyleSetter/pro/Background.vue_vue_type_script_setup_true_lang.js +48 -23
  20. package/dist/es/fields/StyleSetter/pro/Border.vue_vue_type_script_setup_true_lang.js +6 -3
  21. package/dist/es/fields/StyleSetter/pro/Font.vue_vue_type_script_setup_true_lang.js +28 -22
  22. package/dist/es/fields/StyleSetter/pro/Layout.vue_vue_type_script_setup_true_lang.js +28 -22
  23. package/dist/es/fields/StyleSetter/pro/Position.vue_vue_type_script_setup_true_lang.js +28 -22
  24. package/dist/es/fields/StyleSetter/pro/Transform.vue_vue_type_script_setup_true_lang.js +6 -3
  25. package/dist/es/fields/UISelect.js +0 -1
  26. package/dist/es/hooks/use-compare-form.js +119 -0
  27. package/dist/es/index.js +13 -8
  28. package/dist/es/layouts/CodeEditor.vue_vue_type_script_setup_true_lang.js +21 -6
  29. package/dist/es/layouts/Framework.vue_vue_type_script_setup_true_lang.js +9 -6
  30. package/dist/es/layouts/history-list/HistoryDiffDialog.vue_vue_type_script_setup_true_lang.js +4 -1
  31. package/dist/es/layouts/history-list/composables.js +1 -1
  32. package/dist/es/layouts/history-list/useHistoryRevert.js +7 -3
  33. package/dist/es/layouts/props-panel/FormPanel.vue_vue_type_script_setup_true_lang.js +44 -5
  34. package/dist/es/layouts/props-panel/PropsPanel.vue_vue_type_script_setup_true_lang.js +15 -8
  35. package/dist/es/layouts/props-panel/use-style-panel.js +3 -2
  36. package/dist/es/layouts/sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +15 -31
  37. package/dist/es/layouts/sidebar/code-block/CodeBlockListPanel.vue_vue_type_script_setup_true_lang.js +2 -2
  38. package/dist/es/layouts/sidebar/code-block/useContentMenu.js +18 -3
  39. package/dist/es/layouts/sidebar/data-source/DataSourceConfigPanel.vue_vue_type_script_setup_true_lang.js +4 -0
  40. package/dist/es/layouts/sidebar/data-source/DataSourceListPanel.vue_vue_type_script_setup_true_lang.js +2 -2
  41. package/dist/es/layouts/sidebar/data-source/useContentMenu.js +18 -3
  42. package/dist/es/layouts/sidebar/layer/LayerNodeContent.js +5 -0
  43. package/dist/es/layouts/sidebar/layer/LayerNodeContent.vue_vue_type_script_setup_true_lang.js +46 -0
  44. package/dist/es/layouts/sidebar/layer/LayerPanel.vue_vue_type_script_setup_true_lang.js +2 -1
  45. package/dist/es/layouts/workspace/viewer/NodeListMenu.vue_vue_type_script_setup_true_lang.js +8 -2
  46. package/dist/es/plugin.js +3 -1
  47. package/dist/es/services/codeBlock.js +1 -1
  48. package/dist/es/services/editor.js +104 -5
  49. package/dist/es/services/history.js +1 -1
  50. package/dist/es/services/props.js +3 -2
  51. package/dist/es/services/storage.js +2 -2
  52. package/dist/es/services/ui.js +3 -0
  53. package/dist/es/style.css +104 -55
  54. package/dist/es/utils/data-source/index.js +30 -11
  55. package/dist/es/utils/event.js +123 -0
  56. package/dist/es/utils/monaco-editor.js +22 -6
  57. package/dist/es/utils/props.js +119 -8
  58. package/dist/es/utils/type-match-rules.js +360 -0
  59. package/dist/style.css +104 -55
  60. package/dist/tmagic-editor.umd.cjs +16996 -15806
  61. package/package.json +8 -8
  62. package/src/Editor.vue +3 -1
  63. package/src/components/CodeBlockEditor.vue +3 -0
  64. package/src/components/CompareForm.vue +16 -196
  65. package/src/components/FloatingBox.vue +77 -8
  66. package/src/components/ScrollBar.vue +0 -67
  67. package/src/components/ViewForm.vue +55 -0
  68. package/src/editorProps.ts +13 -0
  69. package/src/fields/CodeSelect.vue +4 -1
  70. package/src/fields/CondOpSelect.vue +2 -24
  71. package/src/fields/DataSourceFields.vue +5 -0
  72. package/src/fields/DataSourceInput.vue +7 -25
  73. package/src/fields/DataSourceMocks.vue +3 -0
  74. package/src/fields/DisplayConds.vue +14 -0
  75. package/src/fields/EventSelect.vue +84 -129
  76. package/src/fields/StyleSetter/Index.vue +2 -8
  77. package/src/fields/StyleSetter/pro/Background.vue +94 -55
  78. package/src/fields/StyleSetter/pro/Border.vue +9 -11
  79. package/src/fields/StyleSetter/pro/Font.vue +66 -64
  80. package/src/fields/StyleSetter/pro/Layout.vue +140 -138
  81. package/src/fields/StyleSetter/pro/Position.vue +69 -67
  82. package/src/fields/StyleSetter/pro/Transform.vue +23 -25
  83. package/src/fields/UISelect.vue +0 -12
  84. package/src/hooks/index.ts +1 -0
  85. package/src/hooks/use-compare-form.ts +187 -0
  86. package/src/index.ts +2 -0
  87. package/src/layouts/CodeEditor.vue +32 -6
  88. package/src/layouts/Framework.vue +7 -6
  89. package/src/layouts/history-list/HistoryDiffDialog.vue +11 -1
  90. package/src/layouts/history-list/useHistoryRevert.ts +4 -0
  91. package/src/layouts/props-panel/FormPanel.vue +66 -5
  92. package/src/layouts/props-panel/PropsPanel.vue +20 -6
  93. package/src/layouts/props-panel/use-style-panel.ts +4 -3
  94. package/src/layouts/sidebar/Sidebar.vue +2 -0
  95. package/src/layouts/sidebar/code-block/CodeBlockListPanel.vue +4 -1
  96. package/src/layouts/sidebar/code-block/useContentMenu.ts +13 -1
  97. package/src/layouts/sidebar/data-source/DataSourceConfigPanel.vue +3 -0
  98. package/src/layouts/sidebar/data-source/DataSourceListPanel.vue +2 -2
  99. package/src/layouts/sidebar/data-source/useContentMenu.ts +13 -1
  100. package/src/layouts/sidebar/layer/LayerNodeContent.vue +57 -0
  101. package/src/layouts/sidebar/layer/LayerPanel.vue +4 -1
  102. package/src/layouts/workspace/viewer/NodeListMenu.vue +4 -1
  103. package/src/plugin.ts +3 -1
  104. package/src/services/editor.ts +168 -3
  105. package/src/services/ui.ts +6 -0
  106. package/src/theme/event.scss +8 -0
  107. package/src/theme/floating-box.scss +9 -1
  108. package/src/theme/layer-node-content.scss +14 -0
  109. package/src/theme/scroll-bar.scss +64 -0
  110. package/src/theme/theme.scss +3 -0
  111. package/src/theme/ui-select.scss +9 -0
  112. package/src/type.ts +105 -2
  113. package/src/utils/data-source/index.ts +30 -12
  114. package/src/utils/event.ts +224 -0
  115. package/src/utils/index.ts +2 -0
  116. package/src/utils/monaco-editor.ts +27 -0
  117. package/src/utils/props.ts +189 -2
  118. package/src/utils/type-match-rules.ts +678 -0
  119. package/types/index.d.ts +558 -213
@@ -17,14 +17,28 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
+ import type { AppContext } from 'vue';
21
+
20
22
  import {
23
+ HookType,
21
24
  NODE_CONDS_KEY,
22
25
  NODE_CONDS_RESULT_KEY,
23
26
  NODE_DISABLE_CODE_BLOCK_KEY,
24
27
  NODE_DISABLE_DATA_SOURCE_KEY,
25
28
  } from '@tmagic/core';
26
29
  import { tMagicMessage } from '@tmagic/design';
27
- import type { ChildConfig, DisplayCondsConfig, FormConfig, TabConfig, TabPaneConfig } from '@tmagic/form';
30
+ import type {
31
+ ChildConfig,
32
+ DisplayCondsConfig,
33
+ FormConfig,
34
+ FormState,
35
+ FormValue,
36
+ TabConfig,
37
+ TabPaneConfig,
38
+ } from '@tmagic/form';
39
+ import { validateForm } from '@tmagic/form';
40
+
41
+ import type { Services } from '@editor/type';
28
42
 
29
43
  export const arrayOptions = [
30
44
  { text: '包含', value: 'include' },
@@ -45,10 +59,36 @@ export const numberOptions = [
45
59
  { text: '不在范围内', value: 'not_between' },
46
60
  ];
47
61
 
62
+ export const booleanOptions = [
63
+ { text: '是', value: 'is' },
64
+ { text: '不是', value: 'not' },
65
+ ];
66
+
67
+ /** 按字段类型返回条件运算符选项(UI 与 typeMatch 校验共用) */
68
+ export const getCondOpOptionsByFieldType = (type: string) => {
69
+ if (type === 'array') {
70
+ return arrayOptions;
71
+ }
72
+
73
+ if (type === 'boolean' || type === 'null') {
74
+ return booleanOptions;
75
+ }
76
+
77
+ if (type === 'number') {
78
+ return [...eqOptions, ...numberOptions];
79
+ }
80
+
81
+ if (type === 'string') {
82
+ return [...arrayOptions, ...eqOptions];
83
+ }
84
+
85
+ return [...arrayOptions, ...eqOptions, ...numberOptions];
86
+ };
87
+
48
88
  export const styleTabConfig: TabPaneConfig = {
49
89
  title: '样式',
50
90
  lazy: true,
51
- display: ({ services }: any) => !(services.uiService.get('showStylePanel') ?? true),
91
+ display: ({ services }: any) => !(services?.uiService?.get('showStylePanel') ?? true),
52
92
  items: [
53
93
  {
54
94
  name: 'style',
@@ -127,6 +167,7 @@ export const eventTabConfig: TabPaneConfig = {
127
167
  src: 'component',
128
168
  labelWidth: '100px',
129
169
  type: 'event-select',
170
+ rules: [{ typeMatch: true }],
130
171
  },
131
172
  ],
132
173
  };
@@ -155,6 +196,17 @@ export const advancedTabConfig: TabPaneConfig = {
155
196
  labelPosition: 'top',
156
197
  type: 'code-select',
157
198
  extra: '组件初始化时执行',
199
+ rules: [
200
+ { typeMatch: true, trigger: 'change' },
201
+ {
202
+ validator: ({ value, callback }: any) => {
203
+ if (value && value.hookType !== HookType.CODE) {
204
+ return callback('hookType 必须是 code');
205
+ }
206
+ callback();
207
+ },
208
+ },
209
+ ],
158
210
  },
159
211
  {
160
212
  name: 'mounted',
@@ -162,6 +214,17 @@ export const advancedTabConfig: TabPaneConfig = {
162
214
  labelPosition: 'top',
163
215
  type: 'code-select',
164
216
  extra: '组件挂载到dom时执行',
217
+ rules: [
218
+ { typeMatch: true, trigger: 'change' },
219
+ {
220
+ validator: ({ value, callback }: any) => {
221
+ if (value && value.hookType !== HookType.CODE) {
222
+ return callback('hookType 必须是 code');
223
+ }
224
+ callback();
225
+ },
226
+ },
227
+ ],
165
228
  },
166
229
  {
167
230
  name: 'display',
@@ -169,6 +232,17 @@ export const advancedTabConfig: TabPaneConfig = {
169
232
  extra: '控制组件是否渲染,关系的代码块返回值为false时不渲染',
170
233
  labelPosition: 'top',
171
234
  type: 'code-select',
235
+ rules: [
236
+ { typeMatch: true, trigger: 'change' },
237
+ {
238
+ validator: ({ value, callback }: any) => {
239
+ if (value && value.hookType !== HookType.CODE) {
240
+ return callback('hookType 必须是 code');
241
+ }
242
+ callback();
243
+ },
244
+ },
245
+ ],
172
246
  },
173
247
  ],
174
248
  };
@@ -194,6 +268,7 @@ export const displayTabConfig: TabPaneConfig<DisplayCondsConfig> = {
194
268
  name: NODE_CONDS_KEY,
195
269
  titlePrefix: '条件组',
196
270
  defaultValue: [],
271
+ rules: [{ typeMatch: true }],
197
272
  },
198
273
  ],
199
274
  };
@@ -286,3 +361,115 @@ export const fillConfig = (
286
361
 
287
362
  return [tabConfig];
288
363
  };
364
+
365
+ /**
366
+ * 将属性表单配置中「样式」tab-pane 的 `display` 强制置为 `true`。
367
+ *
368
+ * `propsService.getPropsConfig` 返回的样式 tab 默认带有
369
+ * `display: ({ services }) => !(services?.uiService?.get('showStylePanel') ?? true)`,
370
+ * 在对比 / 只读展示场景(CompareForm / ViewForm)下并不需要跟随 uiService 状态隐藏,
371
+ * 这里统一放开,保证样式 tab 始终可见。
372
+ *
373
+ * @param formConfig 组件属性表单配置
374
+ * @returns 处理后的表单配置(不修改入参,返回浅拷贝)
375
+ */
376
+ export const removeStyleDisplayConfig = (formConfig: FormConfig): FormConfig =>
377
+ formConfig.map((item) => {
378
+ if (!('type' in item)) return item;
379
+ if (item?.type !== 'tab' || !Array.isArray(item.items)) return item;
380
+
381
+ return {
382
+ ...item,
383
+ items: item.items.map((tabPane) => {
384
+ if (tabPane?.title !== '样式' || !Array.isArray(tabPane.items)) return tabPane;
385
+
386
+ return {
387
+ ...tabPane,
388
+ display: true,
389
+ };
390
+ }),
391
+ };
392
+ });
393
+
394
+ // #region ValidatePropsFormOptions
395
+ /**
396
+ * validatePropsForm 参数
397
+ */
398
+ export interface ValidatePropsFormOptions {
399
+ /** 组件属性表单配置 */
400
+ config: FormConfig;
401
+ /** 待校验的表单值 */
402
+ values: FormValue;
403
+ /**
404
+ * 当前组件实例的 appContext(通常为 `getCurrentInstance()?.appContext`)。
405
+ * 会与 services 一并合入临时 MForm 的 appContext,使编辑器字段组件(DataSourceInput 等)能正常 inject。
406
+ */
407
+ appContext?: AppContext | null;
408
+ /** 编辑器服务集合,注入到临时表单的 formState */
409
+ services?: Services;
410
+ /** stage 实例,注入到临时表单的 formState */
411
+ stage?: any;
412
+ /** 外部扩展的 formState */
413
+ extendState?: (_state: FormState) => Record<string, any> | Promise<Record<string, any>>;
414
+ /**
415
+ * 调试模式,默认 `true`:以弹层形式可见地渲染表单,点击「确定」才触发校验。
416
+ * 置为 `false` 时静默挂载后自动校验。
417
+ */
418
+ debug?: boolean;
419
+ typeMatchValid?: boolean;
420
+ }
421
+ // #endregion ValidatePropsFormOptions
422
+
423
+ /**
424
+ * 对一份「组件属性表单配置 + 值」做一次独立的校验,**不复用也不污染页面上正在展示的表单**。
425
+ *
426
+ * 内部基于 `@tmagic/form` 的 `validateForm` 另建一个独立的 MForm 实例完成校验,并统一处理
427
+ * 编辑器场景所需的上下文注入:将当前组件实例的 provides 合入 appContext,并向 formState 注入
428
+ * stage / services 及外部扩展状态,保证校验规则依赖的上下文可用。
429
+ *
430
+ * 常用于源码编辑器保存后,对最新配置做一次校验,并将校验结果(错误信息)随提交一并抛给上层记录,
431
+ * 使源码保存的错误状态与表单编辑保持一致。
432
+ *
433
+ * @returns 校验通过返回空字符串 `''`,否则返回以 `<br>` 拼接的错误文案。
434
+ * 仅在初始化超时或挂载失败等异常情况下才会 reject。
435
+ *
436
+ * @example
437
+ * ```ts
438
+ * const error = await validatePropsForm({
439
+ * config,
440
+ * values,
441
+ * appContext: getCurrentInstance()?.appContext,
442
+ * services,
443
+ * stage: editorService.get('stage'),
444
+ * extendState,
445
+ * });
446
+ * if (error) {
447
+ * // 配置不合法,error 为错误文案
448
+ * }
449
+ * ```
450
+ */
451
+ export const validatePropsForm = ({
452
+ config,
453
+ values,
454
+ appContext = null,
455
+ services,
456
+ stage,
457
+ extendState,
458
+ debug,
459
+ typeMatchValid,
460
+ }: ValidatePropsFormOptions): Promise<string> =>
461
+ validateForm({
462
+ config,
463
+ debug,
464
+ typeMatchValid,
465
+ initValues: values,
466
+ // 将当前组件实例的 provides(含 Editor 顶层的 services / codeOptions 等组件级 provide)
467
+ // 合入 appContext,使临时 MForm 中的编辑器字段组件(DataSourceInput 等)能正常 inject
468
+ appContext: appContext ? { ...appContext, provides: { services } } : null,
469
+ // 与页面表单保持一致:注入 stage/services 及外部扩展状态,保证校验规则依赖的上下文可用
470
+ extendState: async (state) => ({
471
+ ...((await extendState?.(state)) || {}),
472
+ stage,
473
+ services,
474
+ }),
475
+ });