amis-editor 4.1.0-beta.4 → 4.2.0-beta.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (218) hide show
  1. package/dist/component/Breadcrumb.d.ts +23 -2
  2. package/dist/component/ClassNameControl.d.ts +1 -1
  3. package/dist/component/Control/APIControl.d.ts +2 -2
  4. package/dist/component/Control/OptionControl.d.ts +3 -3
  5. package/dist/component/Control/PopoverEdit.d.ts +4 -4
  6. package/dist/component/Control/ValidationControl.d.ts +1 -1
  7. package/dist/component/Editor.d.ts +20 -1
  8. package/dist/component/IFramePreview.d.ts +2 -1
  9. package/dist/component/NodeWrapper.d.ts +1 -1
  10. package/dist/component/Panel/RenderersPanel.d.ts +1 -2
  11. package/dist/component/Preview.d.ts +3 -1
  12. package/dist/component/RegionWrapper.d.ts +4 -0
  13. package/dist/component/ScaffoldModal.d.ts +1 -1
  14. package/dist/component/VRenderer.d.ts +4 -0
  15. package/dist/component/base/InputComponentName.d.ts +1 -1
  16. package/dist/component/base/SearchCustomRendererPanel.d.ts +15 -0
  17. package/dist/component/base/SearchPanel.d.ts +83 -0
  18. package/dist/component/base/SearchRendererPanel.d.ts +2 -42
  19. package/dist/component/base/ShortcutKey.d.ts +23 -0
  20. package/dist/env.d.ts +1 -1
  21. package/dist/exports.min.js +1 -1
  22. package/dist/index.d.ts +5 -1
  23. package/dist/index.min.js +1 -1
  24. package/dist/manager.d.ts +16 -4
  25. package/dist/plugin/Alert.d.ts +1 -1
  26. package/dist/plugin/Button.d.ts +1 -1
  27. package/dist/plugin/Card.d.ts +1 -0
  28. package/dist/plugin/Cards.d.ts +2 -1
  29. package/dist/plugin/Carousel.d.ts +1 -0
  30. package/dist/plugin/Chart.d.ts +1 -0
  31. package/dist/plugin/Collapse.d.ts +1 -0
  32. package/dist/plugin/Custom.d.ts +3 -0
  33. package/dist/plugin/CustomRegion.d.ts +40 -0
  34. package/dist/plugin/Dialog.d.ts +1 -1
  35. package/dist/plugin/Drawer.d.ts +1 -1
  36. package/dist/plugin/DropDownButton.d.ts +1 -1
  37. package/dist/plugin/Each.d.ts +1 -1
  38. package/dist/plugin/Flex.d.ts +1 -0
  39. package/dist/plugin/Form/Control.d.ts +1 -0
  40. package/dist/plugin/Form/Form.d.ts +19 -3
  41. package/dist/plugin/Form/Formula.d.ts +3 -3
  42. package/dist/plugin/Form/InputURL.d.ts +1 -0
  43. package/dist/plugin/Form/Switch.d.ts +2 -0
  44. package/dist/plugin/Grid.d.ts +1 -0
  45. package/dist/plugin/HBox.d.ts +1 -0
  46. package/dist/plugin/IFrame.d.ts +3 -3
  47. package/dist/plugin/Json.d.ts +1 -0
  48. package/dist/plugin/List.d.ts +2 -1
  49. package/dist/plugin/Mapping.d.ts +1 -0
  50. package/dist/plugin/Markdown.d.ts +1 -0
  51. package/dist/plugin/Nav.d.ts +1 -0
  52. package/dist/plugin/Page.d.ts +1 -1
  53. package/dist/plugin/Panel/Outline.d.ts +8 -0
  54. package/dist/plugin/Progress.d.ts +1 -0
  55. package/dist/plugin/QRCode.d.ts +1 -0
  56. package/dist/plugin/Reset.d.ts +0 -1
  57. package/dist/plugin/Service.d.ts +1 -0
  58. package/dist/plugin/Sparkline.d.ts +1 -0
  59. package/dist/plugin/Status.d.ts +1 -0
  60. package/dist/plugin/Steps.d.ts +1 -0
  61. package/dist/plugin/Submit.d.ts +0 -1
  62. package/dist/plugin/Table.d.ts +1 -1
  63. package/dist/plugin/TableView.d.ts +1 -0
  64. package/dist/plugin/Tasks.d.ts +1 -0
  65. package/dist/plugin/TooltipWrapper.d.ts +1 -0
  66. package/dist/plugin/Video.d.ts +1 -0
  67. package/dist/plugin/WebComponent.d.ts +1 -0
  68. package/dist/plugin/Wizard.d.ts +11 -2
  69. package/dist/plugin/Wrapper.d.ts +1 -0
  70. package/dist/plugin.d.ts +8 -7
  71. package/dist/store/editor.d.ts +58 -22
  72. package/dist/store/node.d.ts +6 -0
  73. package/dist/style.css +1 -1
  74. package/dist/util.d.ts +1 -1
  75. package/package.json +9 -3
  76. package/src/component/schemaTpl.tsx +2157 -0
  77. package/src/plugin/Alert.tsx +87 -0
  78. package/src/plugin/AnchorNav.tsx +233 -0
  79. package/src/plugin/Audio.tsx +154 -0
  80. package/src/plugin/Avatar.tsx +77 -0
  81. package/src/plugin/Breadcrumb.tsx +107 -0
  82. package/src/plugin/Button.tsx +281 -0
  83. package/src/plugin/ButtonGroup.tsx +85 -0
  84. package/src/plugin/ButtonToolbar.tsx +87 -0
  85. package/src/plugin/CRUD.tsx +1835 -0
  86. package/src/plugin/Card.tsx +290 -0
  87. package/src/plugin/Cards.tsx +318 -0
  88. package/src/plugin/Carousel.tsx +377 -0
  89. package/src/plugin/Chart.tsx +218 -0
  90. package/src/plugin/CodeView.tsx +60 -0
  91. package/src/plugin/Collapse.tsx +136 -0
  92. package/src/plugin/CollapseGroup.tsx +167 -0
  93. package/src/plugin/Container.tsx +40 -0
  94. package/src/plugin/Custom.tsx +128 -0
  95. package/src/plugin/CustomRegion.tsx +156 -0
  96. package/src/plugin/Date.tsx +74 -0
  97. package/src/plugin/Datetime.tsx +68 -0
  98. package/src/plugin/Dialog.tsx +176 -0
  99. package/src/plugin/Divider.tsx +36 -0
  100. package/src/plugin/Drawer.tsx +214 -0
  101. package/src/plugin/DropDownButton.tsx +235 -0
  102. package/src/plugin/Each.tsx +150 -0
  103. package/src/plugin/ErrorRenderer.tsx +15 -0
  104. package/src/plugin/Flex.tsx +151 -0
  105. package/src/plugin/Form/ButtonGroupSelect.tsx +75 -0
  106. package/src/plugin/Form/ButtonToolbar.tsx +110 -0
  107. package/src/plugin/Form/ChainedSelect.tsx +70 -0
  108. package/src/plugin/Form/Checkbox.tsx +87 -0
  109. package/src/plugin/Form/Checkboxes.tsx +167 -0
  110. package/src/plugin/Form/CodeEditor.tsx +81 -0
  111. package/src/plugin/Form/Combo.tsx +582 -0
  112. package/src/plugin/Form/ConditionBuilder.tsx +315 -0
  113. package/src/plugin/Form/Control.tsx +139 -0
  114. package/src/plugin/Form/DiffEditor.tsx +111 -0
  115. package/src/plugin/Form/FieldSet.tsx +163 -0
  116. package/src/plugin/Form/Form.tsx +687 -0
  117. package/src/plugin/Form/Formula.tsx +79 -0
  118. package/src/plugin/Form/Group.tsx +295 -0
  119. package/src/plugin/Form/Hidden.tsx +44 -0
  120. package/src/plugin/Form/InputArray.tsx +228 -0
  121. package/src/plugin/Form/InputCity.tsx +93 -0
  122. package/src/plugin/Form/InputColor.tsx +123 -0
  123. package/src/plugin/Form/InputDate.tsx +175 -0
  124. package/src/plugin/Form/InputDateRange.tsx +225 -0
  125. package/src/plugin/Form/InputDateTime.tsx +183 -0
  126. package/src/plugin/Form/InputDateTimeRange.tsx +221 -0
  127. package/src/plugin/Form/InputEmail.tsx +33 -0
  128. package/src/plugin/Form/InputExcel.tsx +85 -0
  129. package/src/plugin/Form/InputFile.tsx +221 -0
  130. package/src/plugin/Form/InputGroup.tsx +96 -0
  131. package/src/plugin/Form/InputImage.tsx +266 -0
  132. package/src/plugin/Form/InputKV.tsx +72 -0
  133. package/src/plugin/Form/InputMonth.tsx +35 -0
  134. package/src/plugin/Form/InputMonthRange.tsx +195 -0
  135. package/src/plugin/Form/InputNumber.tsx +89 -0
  136. package/src/plugin/Form/InputPassword.tsx +33 -0
  137. package/src/plugin/Form/InputQuarter.tsx +35 -0
  138. package/src/plugin/Form/InputQuarterRange.tsx +195 -0
  139. package/src/plugin/Form/InputRange.tsx +121 -0
  140. package/src/plugin/Form/InputRating.tsx +78 -0
  141. package/src/plugin/Form/InputRepeat.tsx +57 -0
  142. package/src/plugin/Form/InputRichText.tsx +186 -0
  143. package/src/plugin/Form/InputSubForm.tsx +189 -0
  144. package/src/plugin/Form/InputTable.tsx +434 -0
  145. package/src/plugin/Form/InputTag.tsx +70 -0
  146. package/src/plugin/Form/InputText.tsx +186 -0
  147. package/src/plugin/Form/InputTime.tsx +85 -0
  148. package/src/plugin/Form/InputTree.tsx +229 -0
  149. package/src/plugin/Form/InputURL.tsx +34 -0
  150. package/src/plugin/Form/InputYear.tsx +35 -0
  151. package/src/plugin/Form/Item.tsx +327 -0
  152. package/src/plugin/Form/ListSelect.tsx +73 -0
  153. package/src/plugin/Form/LocationPicker.tsx +62 -0
  154. package/src/plugin/Form/MatrixCheckboxes.tsx +136 -0
  155. package/src/plugin/Form/NestedSelect.tsx +211 -0
  156. package/src/plugin/Form/Picker.tsx +209 -0
  157. package/src/plugin/Form/Radios.tsx +119 -0
  158. package/src/plugin/Form/Select.tsx +233 -0
  159. package/src/plugin/Form/Static.tsx +322 -0
  160. package/src/plugin/Form/Switch.tsx +107 -0
  161. package/src/plugin/Form/TabsTransfer.tsx +259 -0
  162. package/src/plugin/Form/Textarea.tsx +83 -0
  163. package/src/plugin/Form/Transfer.tsx +368 -0
  164. package/src/plugin/Form/TreeSelect.tsx +263 -0
  165. package/src/plugin/Form/UUID.tsx +48 -0
  166. package/src/plugin/Grid.tsx +798 -0
  167. package/src/plugin/HBox.tsx +727 -0
  168. package/src/plugin/IFrame.tsx +70 -0
  169. package/src/plugin/Image.tsx +314 -0
  170. package/src/plugin/Images.tsx +231 -0
  171. package/src/plugin/Json.tsx +69 -0
  172. package/src/plugin/Link.tsx +93 -0
  173. package/src/plugin/List.tsx +278 -0
  174. package/src/plugin/ListItem.tsx +229 -0
  175. package/src/plugin/Log.tsx +52 -0
  176. package/src/plugin/Mapping.tsx +149 -0
  177. package/src/plugin/Markdown.tsx +47 -0
  178. package/src/plugin/Nav.tsx +184 -0
  179. package/src/plugin/Operation.tsx +95 -0
  180. package/src/plugin/Others/Action.tsx +426 -0
  181. package/src/plugin/Others/BasicToolbar.tsx +585 -0
  182. package/src/plugin/Others/DataDebug.tsx +134 -0
  183. package/src/plugin/Others/TableCell.tsx +480 -0
  184. package/src/plugin/Others/Unknown.tsx +37 -0
  185. package/src/plugin/Page.tsx +306 -0
  186. package/src/plugin/Panel/AvailableRenderers.tsx +41 -0
  187. package/src/plugin/Panel/Code.tsx +44 -0
  188. package/src/plugin/Panel/Name.tsx +26 -0
  189. package/src/plugin/Panel/Outline.tsx +40 -0
  190. package/src/plugin/Panel.tsx +243 -0
  191. package/src/plugin/Plain.tsx +84 -0
  192. package/src/plugin/Progress.tsx +125 -0
  193. package/src/plugin/Property.tsx +139 -0
  194. package/src/plugin/QRCode.tsx +96 -0
  195. package/src/plugin/Reset.tsx +23 -0
  196. package/src/plugin/Service.tsx +162 -0
  197. package/src/plugin/Sparkline.tsx +40 -0
  198. package/src/plugin/Status.tsx +76 -0
  199. package/src/plugin/Steps.tsx +128 -0
  200. package/src/plugin/Submit.tsx +23 -0
  201. package/src/plugin/Table.tsx +428 -0
  202. package/src/plugin/TableView.tsx +709 -0
  203. package/src/plugin/Tabs.tsx +362 -0
  204. package/src/plugin/Tasks.tsx +274 -0
  205. package/src/plugin/Time.tsx +68 -0
  206. package/src/plugin/TooltipWrapper.tsx +193 -0
  207. package/src/plugin/Tpl.tsx +158 -0
  208. package/src/plugin/Video.tsx +158 -0
  209. package/src/plugin/WebComponent.tsx +53 -0
  210. package/src/plugin/Wizard.tsx +740 -0
  211. package/src/plugin/Wrapper.tsx +107 -0
  212. package/src/plugin.ts +1050 -0
  213. package/dist/150a58f3318ca7541ed9.png +0 -0
  214. package/dist/471adb97c322b226e589.png +0 -0
  215. package/dist/4de5f42360bc5946c3c2.png +0 -0
  216. package/dist/4e9968bba3855f088fed.png +0 -0
  217. package/dist/7f09c38ebc687fea847a.png +0 -0
  218. package/dist/c94073576487510314ea.png +0 -0
package/src/plugin.ts ADDED
@@ -0,0 +1,1050 @@
1
+ /**
2
+ * @file 定义插件的 interface,以及提供一个 BasePlugin 基类,把一些通用的方法放在这。
3
+ */
4
+
5
+ import {RegionWrapperProps} from './component/RegionWrapper';
6
+ import {EditorManager} from './manager';
7
+ import {EditorStoreType} from './store/editor';
8
+ import {EditorNodeType} from './store/node';
9
+ import {DNDModeInterface} from './dnd/interface';
10
+ import {EditorDNDManager} from './dnd';
11
+ import React from 'react';
12
+ import {DiffChange} from './util';
13
+ import find from 'lodash/find';
14
+ import type {RendererConfig} from 'amis-core/lib/factory';
15
+ import type {MenuDivider, MenuItem} from 'amis-ui/lib/components/ContextMenu';
16
+ import type {BaseSchema} from 'amis/lib/Schema';
17
+
18
+ /**
19
+ * 区域的定义,容器渲染器都需要定义区域信息。
20
+ */
21
+ export interface RegionConfig {
22
+ /**
23
+ * 简单情况,如果区域直接用的 render('region', subSchema)
24
+ * 这种只需要配置 key 就能简单插入 Region 节点。
25
+ */
26
+ key: string;
27
+
28
+ /**
29
+ * 区域用来显示的名字。
30
+ */
31
+ label: string;
32
+
33
+ /**
34
+ * 区域占位字符,用于提示
35
+ */
36
+ placeholder?: string;
37
+
38
+ /**
39
+ * 对于复杂的控件需要用到这个配置。
40
+ * 如果配置了,则遍历 react dom 直到目标节点调换成 Region 节点
41
+ *
42
+ * 如果没有配置这个,但是又配置了 renderMethod 方法,
43
+ * 那就直接将 renderMethod 里面返回的 react dom 直接包一层 Region
44
+ */
45
+ matchRegion?: (
46
+ elem: JSX.Element | undefined | null,
47
+ component: JSX.Element
48
+ ) => boolean;
49
+
50
+ /**
51
+ * 指定要覆盖哪个方法。
52
+ */
53
+ renderMethod?: string;
54
+
55
+ /**
56
+ * 通常是hack 当前渲染器,单有时候当前渲染器其实是组合的别的渲染器。
57
+ */
58
+ rendererName?: string;
59
+
60
+ /**
61
+ * 当配置 renderMethod 的时候会自动把 Region 插入进去。
62
+ * 默认是 outter 模式,有时候可能需要配置成 inner,
63
+ * 比如 renderMethod 为 render 的时候。
64
+ */
65
+ insertPosition?: 'outter' | 'inner';
66
+
67
+ /**
68
+ * 是否为可选容器,如果是可选容器,不会强制自动创建成员
69
+ */
70
+ optional?: boolean;
71
+
72
+ /**
73
+ * 有时候有些包括是需要其他条件的,所以要自己写包裹逻辑。
74
+ * 比如 Panel 里面的 renderBody
75
+ */
76
+ renderMethodOverride?: (
77
+ regions: Array<RegionConfig>,
78
+ insertRegion: (
79
+ component: JSX.Element,
80
+ dom: JSX.Element,
81
+ regions: Array<RegionConfig>,
82
+ info: RendererInfo,
83
+ manager: EditorManager
84
+ ) => JSX.Element
85
+ ) => Function;
86
+
87
+ /**
88
+ * 偏好什么类型的组件?比如表单里面,controls 容器偏向表单项。
89
+ */
90
+ preferTag?: string;
91
+
92
+ /**
93
+ * 用来指定用什么组件包裹,默认是 RegionWrapper
94
+ */
95
+ wrapper?: React.ComponentType<RegionWrapperProps>;
96
+
97
+ /**
98
+ * 返回需要添加 data-region 的 dom 节点。
99
+ */
100
+ wrapperResolve?: (dom: HTMLElement) => HTMLElement;
101
+
102
+ /**
103
+ * 当拖入到这个容器时,是否需要修改一下 ghost 结构?
104
+ */
105
+ modifyGhost?: (ghost: HTMLElement, schema?: any) => void;
106
+
107
+ /**
108
+ * dnd 拖拽模式。比如 table 那种需要配置成 position-h
109
+ */
110
+ dndMode?:
111
+ | 'default'
112
+ | 'position-h'
113
+ | 'position-v'
114
+ | (new (dnd: EditorDNDManager) => DNDModeInterface);
115
+
116
+ /**
117
+ * 可以用来判断是否允许拖入当前节点。
118
+ */
119
+ accept?: (json: any) => boolean;
120
+ }
121
+
122
+ export interface VRendererConfig {
123
+ /**
124
+ * 配置了这些会自动创建编辑面板。
125
+ */
126
+ panelIcon?: string;
127
+ panelTitle?: string;
128
+ /**
129
+ * @deprecated 用 panelBody 代替
130
+ */
131
+ panelControls?: Array<any>;
132
+ panelDefinitions?: any;
133
+ /**
134
+ * @deprecated 用panelBodyCreator 代替
135
+ */
136
+ panelControlsCreator?: (context: BaseEventContext) => Array<any>;
137
+ panelBody?: Array<any>;
138
+ panelBodyCreator?: (context: BaseEventContext) => Array<any>;
139
+
140
+ /**
141
+ * 配置了,要是不在 overides 里面使用也是没用的。
142
+ */
143
+ regions?: {
144
+ [propName: string]: RegionConfig;
145
+ };
146
+ }
147
+
148
+ export interface RendererScaffoldInfo {
149
+ /**
150
+ * 组件名称
151
+ */
152
+ name: string;
153
+
154
+ // 图标
155
+ icon?: string;
156
+
157
+ // 组件描述信息
158
+ description?: string;
159
+
160
+ // 文档链接
161
+ docLink?: string;
162
+
163
+ // 用来生成预览图
164
+ previewSchema?: any;
165
+
166
+ // 分类
167
+ tags?: string | Array<string>;
168
+
169
+ // type 和 scaffold 二选一
170
+ type?: string;
171
+ scaffold?: any;
172
+ }
173
+
174
+ /**
175
+ * 渲染器信息。
176
+ */
177
+ export interface RendererInfo extends RendererScaffoldInfo {
178
+ scaffolds?: Array<Partial<RendererScaffoldInfo>>;
179
+
180
+ rendererName?: string;
181
+
182
+ /**
183
+ * json schema 协议
184
+ */
185
+ $schema?: string;
186
+
187
+ isBaseComponent?: boolean;
188
+
189
+ disabledRendererPlugin?: boolean;
190
+
191
+ /**
192
+ * 配置区域。
193
+ */
194
+ regions?: Array<RegionConfig>;
195
+
196
+ /**
197
+ * 哪些容器属性需要自动转成数组的。如果不配置默认就从 regions 里面读取。
198
+ */
199
+ patchContainers?: Array<string>;
200
+
201
+ /**
202
+ * 覆盖的目标渲染器名称
203
+ */
204
+ overrideTargetRendererName?: string;
205
+
206
+ /**
207
+ * 覆写某些方法,一般用来插入虚拟的渲染器编辑器。
208
+ */
209
+ overrides?: {
210
+ [propName: string]: Function;
211
+ };
212
+
213
+ /**
214
+ * 虚拟渲染器的配置项,有时候需要给那些并不是渲染器的组件添加点选编辑功能。
215
+ * 比如: Tabs 下面的 Tab, 这个并不是个渲染器,但是需要可以点选修改内容。
216
+ */
217
+ vRendererConfig?: VRendererConfig;
218
+
219
+ /**
220
+ * 默认为 BaseWrapper, 容器类的指定为 BaseContainerWrapper 或者再实现一个
221
+ * 暂时没有需要配置的所以注释掉。
222
+ * wrapper?: React.ComponentType<NodeWrapperProps>;
223
+ *
224
+ * 返回哪些 dom 节点,需要自动加上 data-editor-id 属性
225
+ * 目前只有 TableCell 里面用到了,就它需要同时给某一列下所有 td 都加上那个属性。
226
+ */
227
+ wrapperResolve?: (dom: HTMLElement) => HTMLElement | Array<HTMLElement>;
228
+
229
+ /**
230
+ * 默认下发哪些属性,如果要动态下发,请使用 filterProps
231
+ */
232
+ wrapperProps?: any;
233
+
234
+ /**
235
+ * 修改一些属性,一般用来干掉 $$id
236
+ * 这样它的孩子节点就不能直接点选编辑了,比如 Combo。
237
+ */
238
+ filterProps?: (props: any, node: EditorNodeType) => any;
239
+
240
+ /**
241
+ * 有些没有视图的组件,可以自己输出点内容,否则没办法点选编辑。
242
+ */
243
+ renderRenderer?: (props: any, info: RendererInfo) => JSX.Element;
244
+
245
+ /**
246
+ * 是否有多重身份?
247
+ * 比如 CRUD 即是 CRUD 又可能是 Table
248
+ *
249
+ * 表格的列,即是表格列,也可能是其他文本框。
250
+ *
251
+ * 配置了这个后会自动添加多个 Panel 面板来编辑。
252
+ */
253
+ multifactor?: boolean;
254
+
255
+ /**
256
+ * 右键的时候是否出现重新构建,靠这个。
257
+ */
258
+ scaffoldForm?: ScaffoldForm;
259
+
260
+ // 自动填入,不用配置
261
+ id: string;
262
+ plugin: PluginInterface;
263
+ extraPlugin?: PluginInterface; // 辅助插件,看需求。
264
+ renderer: RendererConfig;
265
+ schemaPath: string;
266
+
267
+ // 给 subEditor 用的,别直接配置
268
+ editable?: boolean; // 是否可编辑。
269
+ removable?: boolean; // 是否可被删除
270
+ draggable?: boolean; // 是否可被拖动
271
+ movable?: boolean; // 是否可被移动
272
+ replaceable?: boolean; // 是否可被替换
273
+ duplicatable?: boolean; // 是否可以重复一份
274
+ memberImmutable?: boolean | Array<string>; // 成员节点固定,意味着不能新增成员
275
+ typeMutable?: boolean; // 类型是否可被修改
276
+
277
+ // 如果是虚拟的渲染器
278
+ hostId?: string;
279
+ memberIndex?: number;
280
+ }
281
+
282
+ export type BasicRendererInfo = Omit<
283
+ RendererInfo,
284
+ 'id' | 'plugin' | 'renderer' | 'schemaPath'
285
+ >;
286
+
287
+ export interface PopOverForm {
288
+ title?: string;
289
+
290
+ /**
291
+ * 脚手架配置项。
292
+ */
293
+ body: Array<any>;
294
+
295
+ /**
296
+ * @deprecated 改用 body 代替
297
+ */
298
+ controls?: Array<any>;
299
+ }
300
+
301
+ export interface ScaffoldForm extends PopOverForm {
302
+ mode?: 'normal' | 'horizontal' | 'inline';
303
+
304
+ size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full';
305
+ initApi?: any;
306
+ api?: any;
307
+
308
+ /**
309
+ * 整体验证脚手架配置,如果有错误返回错误对象。
310
+ * key 是配置的字段名。
311
+ * value 是具体错误信息。
312
+ */
313
+ validate?: (
314
+ values: any
315
+ ) =>
316
+ | void
317
+ | {[propName: string]: string}
318
+ | Promise<void | {[propName: string]: string}>;
319
+
320
+ /**
321
+ * schema 配置转脚手架配置
322
+ */
323
+ pipeIn?: (value: any) => any;
324
+
325
+ /**
326
+ * 脚手架配置转 schema 配置。
327
+ */
328
+ pipeOut?: (value: any) => any;
329
+
330
+ /**
331
+ * 是否允许重新构建;
332
+ */
333
+ canRebuild?: boolean;
334
+ }
335
+
336
+ /**
337
+ * 子渲染器信息
338
+ */
339
+ export interface SubRendererInfo extends RendererScaffoldInfo {
340
+ /**
341
+ * 用于判断是否是平台预置组件,平台预置组件为true。
342
+ */
343
+ isBaseComponent?: boolean;
344
+
345
+ rendererName?: string;
346
+ /**
347
+ * 首次拖入的时候可以用来配置个表单。
348
+ */
349
+ scaffoldForm?: ScaffoldForm;
350
+ /**
351
+ * 新增属性,用于判断是否出现在组件面板中,默认为false,为ture则不展示
352
+ */
353
+ disabledRendererPlugin?: boolean;
354
+
355
+ // 自动填入,不用配置
356
+ plugin: PluginInterface;
357
+ parent: RendererInfo;
358
+ id: string;
359
+ order: number;
360
+ }
361
+
362
+ export type BasicSubRenderInfo = Omit<
363
+ SubRendererInfo,
364
+ 'plugin' | 'parent' | 'id' | 'order'
365
+ > &
366
+ Partial<Pick<SubRendererInfo, 'order'>>;
367
+
368
+ /**
369
+ * 工具按钮信息。
370
+ */
371
+ export interface ToolbarItem {
372
+ label?: string;
373
+ id?: string;
374
+ order: number;
375
+ level?: 'primary' | 'secondary' | 'special';
376
+ className?: string;
377
+ draggable?: boolean;
378
+ onDragStart?: (e: any) => void;
379
+ icon?: string;
380
+ iconSvg?: string; // 自定义icon(svg格式)
381
+ onClick?: (e: any) => void;
382
+ tooltip?: string;
383
+ placement?: 'top' | 'bottom' | 'right' | 'left';
384
+ }
385
+
386
+ export type BasicToolbarItem = Partial<ToolbarItem>;
387
+
388
+ export type ContextMenuItem = MenuItem | MenuDivider;
389
+
390
+ /**
391
+ * 面板的属性定义
392
+ */
393
+ export interface PanelProps {
394
+ id?: string;
395
+ info?: RendererInfo;
396
+ path?: string;
397
+ node?: EditorNodeType;
398
+ value: BaseSchema;
399
+ onChange: (value: BaseSchema, diff?: Array<DiffChange>) => void;
400
+ store: EditorStoreType;
401
+ manager: EditorManager;
402
+ popOverContainer?: () => HTMLElement | void;
403
+ }
404
+
405
+ /**
406
+ * 面板信息定义
407
+ */
408
+ export interface PanelItem {
409
+ nodeId?: string;
410
+ key: string;
411
+ icon: string;
412
+ title: string | JSX.Element; // 标题
413
+ component?: React.ComponentType<PanelProps | any>;
414
+ order: number;
415
+ position?: 'left' | 'right';
416
+ render?: (props: PanelProps) => JSX.Element;
417
+ menus?: Array<any>;
418
+ }
419
+
420
+ export type BasicPanelItem = Omit<PanelItem, 'order'> &
421
+ Partial<Pick<PanelItem, 'order'>>;
422
+
423
+ export interface EventContext {
424
+ data?: any;
425
+ [propName: string]: any;
426
+ }
427
+
428
+ /**
429
+ * 事件上下文
430
+ */
431
+ export interface BaseEventContext extends EventContext {
432
+ node: EditorNodeType;
433
+ id: string;
434
+ info: RendererInfo;
435
+ path: string;
436
+ schema: any;
437
+ schemaPath: string;
438
+ secondFactor?: boolean;
439
+ }
440
+
441
+ export interface RendererInfoResolveEventContext extends EventContext {
442
+ renderer: RendererConfig;
443
+ path: string;
444
+ schema: any;
445
+ schemaPath: string;
446
+ data?: RendererInfo;
447
+ }
448
+
449
+ export interface RendererJSONSchemaResolveEventContext
450
+ extends BaseEventContext {
451
+ data: string;
452
+ }
453
+
454
+ /**
455
+ * 右键菜单事件的上下文。
456
+ */
457
+ export interface ContextMenuEventContext extends BaseEventContext {
458
+ region: string;
459
+ selections: Array<BaseEventContext>;
460
+ data: Array<ContextMenuItem>;
461
+ }
462
+
463
+ export interface SelectionEventContext extends BaseEventContext {
464
+ selections: Array<BaseEventContext>;
465
+ data: Array<string>;
466
+ }
467
+
468
+ export interface RendererEventContext extends BaseEventContext {
469
+ region?: string;
470
+ }
471
+
472
+ export interface ActiveEventContext extends Partial<BaseEventContext> {
473
+ active?: boolean;
474
+ }
475
+
476
+ export interface DeleteEventContext extends BaseEventContext {
477
+ data?: Array<string>;
478
+ }
479
+
480
+ /**
481
+ * 插入节点的事件上下文信息
482
+ */
483
+ export interface InsertEventContext extends BaseEventContext {
484
+ region: string;
485
+ beforeId?: string;
486
+ index: number;
487
+ data: any;
488
+ subRenderer?: SubRendererInfo;
489
+ dragInfo?: {
490
+ id: string;
491
+ type: string;
492
+ data: any;
493
+ };
494
+ }
495
+
496
+ export interface ReplaceEventContext extends BaseEventContext {
497
+ data: any;
498
+ subRenderer?: SubRendererInfo;
499
+ region?: string;
500
+ }
501
+
502
+ export interface MoveEventContext extends BaseEventContext {
503
+ region: string;
504
+ sourceId: string;
505
+ beforeId?: string;
506
+ direction?: 'up' | 'down';
507
+ }
508
+
509
+ /**
510
+ * 更新节点的事件上下文
511
+ */
512
+ export interface ChangeEventContext extends BaseEventContext {
513
+ value: any;
514
+ readonly diff: Array<DiffChange>;
515
+ }
516
+
517
+ export interface DragEventContext extends EventContext {
518
+ mode: 'move' | 'copy';
519
+ sourceType: 'schema' | 'subrenderer' | string;
520
+ sourceId: string;
521
+ data: any;
522
+
523
+ targetId?: string;
524
+ targetRegion?: string;
525
+ }
526
+
527
+ export interface BuildPanelEventContext extends BaseEventContext {
528
+ data: Array<BasicPanelItem>;
529
+ selections: Array<BaseEventContext>;
530
+ }
531
+
532
+ export interface PreventClickEventContext extends EventContext {
533
+ data: MouseEvent;
534
+ }
535
+
536
+ export interface ResizeMoveEventContext extends EventContext {
537
+ data: Object;
538
+ nativeEvent: MouseEvent;
539
+ dom: HTMLElement;
540
+ resizer: HTMLElement;
541
+ node: EditorNodeType;
542
+ }
543
+
544
+ /**
545
+ * 将事件上下文转成事件对象。
546
+ */
547
+ export type PluginEvent<T, P = any> = {
548
+ context: T;
549
+ type: string;
550
+ preventDefault: () => void;
551
+ stopPropagation: () => void;
552
+ setData: (data: P) => void;
553
+
554
+ // 是否被阻止?
555
+ prevented?: boolean;
556
+ stoped?: boolean;
557
+
558
+ // 当前值
559
+ data?: P;
560
+ };
561
+
562
+ export type PluginEventFn = (e: PluginEvent<EventContext>) => false | void;
563
+
564
+ /**
565
+ * 创建事件。
566
+ * @param type
567
+ * @param context
568
+ */
569
+ export function createEvent<T extends EventContext>(
570
+ type: string,
571
+ context: T
572
+ ): PluginEvent<T> {
573
+ const event = {
574
+ context,
575
+ type,
576
+ prevented: false,
577
+ stoped: false,
578
+ preventDefault() {
579
+ event.prevented = true;
580
+ },
581
+ stopPropagation() {
582
+ event.stoped = true;
583
+ },
584
+ get data() {
585
+ return event.context.data;
586
+ },
587
+ setData(data: any) {
588
+ event.context.data = data;
589
+ }
590
+ };
591
+
592
+ return event;
593
+ }
594
+
595
+ export interface PluginEventListener {
596
+ onActive?: (event: PluginEvent<ActiveEventContext>) => void;
597
+
598
+ /**
599
+ * 事件,当有配置项插入前调用。通过 event.preventDefault() 可以干预。
600
+ */
601
+ beforeInsert?: (event: PluginEvent<InsertEventContext>) => false | void;
602
+ afterInsert?: (event: PluginEvent<InsertEventContext>) => void;
603
+
604
+ /**
605
+ * 面板里面编辑修改的事件。
606
+ */
607
+ beforeUpdate?: (event: PluginEvent<ChangeEventContext>) => false | void;
608
+ afterUpdate?: (event: PluginEvent<ChangeEventContext>) => void;
609
+
610
+ /**
611
+ * 更新渲染器,或者右键粘贴配置。
612
+ */
613
+ beforeReplace?: (event: PluginEvent<ReplaceEventContext>) => false | void;
614
+ afterReplace?: (event: PluginEvent<ReplaceEventContext>) => void;
615
+
616
+ /**
617
+ * 移动节点的时候触发,包括上移,下移
618
+ */
619
+ beforeMove?: (event: PluginEvent<MoveEventContext>) => false | void;
620
+ aftterMove?: (event: PluginEvent<MoveEventContext>) => void;
621
+
622
+ /**
623
+ * 删除的时候触发
624
+ */
625
+ beforeDelete?: (event: PluginEvent<DeleteEventContext>) => false | void;
626
+ afterDelete?: (event: PluginEvent<DeleteEventContext>) => void;
627
+
628
+ beforeResolveEditorInfo?: (
629
+ event: PluginEvent<RendererInfoResolveEventContext>
630
+ ) => false | void;
631
+ afterResolveEditorInfo?: (
632
+ event: PluginEvent<RendererInfoResolveEventContext>
633
+ ) => void;
634
+
635
+ beforeResolveJsonSchema?: (
636
+ event: PluginEvent<RendererJSONSchemaResolveEventContext>
637
+ ) => false | void;
638
+ afterResolveJsonSchema?: (
639
+ event: PluginEvent<RendererJSONSchemaResolveEventContext>
640
+ ) => void;
641
+
642
+ onDndAccept?: (event: PluginEvent<DragEventContext>) => false | void;
643
+
644
+ onBuildPanels?: (event: PluginEvent<BuildPanelEventContext>) => void;
645
+
646
+ onBuildContextMenus?: (event: PluginEvent<ContextMenuEventContext>) => void;
647
+
648
+ onBuildToolbars?: (event: PluginEvent<BaseEventContext>) => void;
649
+
650
+ onSelectionChange?: (event: PluginEvent<SelectionEventContext>) => void;
651
+
652
+ onPreventClick?: (
653
+ event: PluginEvent<PreventClickEventContext>
654
+ ) => false | void;
655
+
656
+ onWidthChangeStart?: (
657
+ event: PluginEvent<
658
+ ResizeMoveEventContext,
659
+ {
660
+ onMove(e: MouseEvent): void;
661
+ onEnd(e: MouseEvent): void;
662
+ }
663
+ >
664
+ ) => void;
665
+
666
+ onHeightChangeStart?: (
667
+ event: PluginEvent<
668
+ ResizeMoveEventContext,
669
+ {
670
+ onMove(e: MouseEvent): void;
671
+ onEnd(e: MouseEvent): void;
672
+ }
673
+ >
674
+ ) => void;
675
+
676
+ onSizeChangeStart?: (
677
+ event: PluginEvent<
678
+ ResizeMoveEventContext,
679
+ {
680
+ onMove(e: MouseEvent): void;
681
+ onEnd(e: MouseEvent): void;
682
+ }
683
+ >
684
+ ) => void;
685
+ }
686
+
687
+ /**
688
+ * 插件的 interface 定义
689
+ */
690
+ export interface PluginInterface
691
+ extends Partial<BasicRendererInfo>,
692
+ Partial<BasicSubRenderInfo>,
693
+ PluginEventListener {
694
+ readonly manager: EditorManager;
695
+
696
+ order?: number;
697
+
698
+ /**
699
+ * 渲染器的名字,关联后不用自己实现 getRendererInfo 了。
700
+ */
701
+ rendererName?: string;
702
+
703
+ /**
704
+ * 默认的配置面板信息
705
+ */
706
+ panelIcon?: string;
707
+ panelTitle?: string;
708
+
709
+ /**
710
+ * 新增属性,用于判断是否出现在组件面板中,默认为false,为ture则不展示
711
+ */
712
+ disabledRendererPlugin?: boolean;
713
+
714
+ /**
715
+ * @deprecated 用 panelBody
716
+ */
717
+ panelControls?: Array<any>;
718
+ panelBody?: Array<any>;
719
+ panelDefinitions?: any;
720
+ panelApi?: any;
721
+ panelSubmitOnChange?: boolean;
722
+
723
+ /**
724
+ * @deprecated 用 panelBodyCreator
725
+ */
726
+ panelControlsCreator?: (context: BaseEventContext) => Array<any>;
727
+ panelBodyCreator?: (context: BaseEventContext) => Array<any>;
728
+
729
+ popOverBody?: Array<any>;
730
+ popOverBodyCreator?: (context: BaseEventContext) => Array<any>;
731
+
732
+ /**
733
+ * 返回渲染器信息。不是每个插件都需要。
734
+ */
735
+ getRendererInfo?: (
736
+ context: RendererInfoResolveEventContext
737
+ ) => BasicRendererInfo | void;
738
+
739
+ /**
740
+ * 生成节点的 JSON Schema 的 uri 地址。
741
+ */
742
+ buildJSONSchema?: (
743
+ context: RendererJSONSchemaResolveEventContext
744
+ ) => void | string;
745
+
746
+ /**
747
+ * 构建右上角功能按钮集合
748
+ */
749
+ buildEditorToolbar?: (
750
+ context: BaseEventContext,
751
+ toolbars: Array<BasicToolbarItem>
752
+ ) => void;
753
+
754
+ /**
755
+ * 构建右键菜单项
756
+ */
757
+ buildEditorContextMenu?: (
758
+ context: ContextMenuEventContext,
759
+ menus: Array<ContextMenuItem>
760
+ ) => void;
761
+
762
+ /**
763
+ * 构建编辑器面板。
764
+ */
765
+ buildEditorPanel?: (
766
+ context: BuildPanelEventContext,
767
+ panels: Array<BasicPanelItem>
768
+ ) => void;
769
+
770
+ /**
771
+ * 构建子渲染器信息集合。
772
+ */
773
+ buildSubRenderers?: (
774
+ context: RendererEventContext,
775
+ subRenderers: Array<SubRendererInfo>,
776
+ renderers: Array<RendererConfig>
777
+ ) => BasicSubRenderInfo | Array<BasicSubRenderInfo> | void;
778
+
779
+ /**
780
+ * 更新NPM自定义组件分类和排序[异步方法]
781
+ * 备注:目前主要在npm自定义组件的分类和排序更新中使用
782
+ */
783
+ asyncUpdateCustomSubRenderersInfo?: (
784
+ context: RendererEventContext,
785
+ subRenderers: Array<SubRendererInfo>,
786
+ renderers: Array<RendererConfig>
787
+ ) => void;
788
+
789
+ markDom?: (dom: HTMLElement | Array<HTMLElement>, props: any) => void;
790
+ }
791
+
792
+ /**
793
+ * 基类,所有插件都继承这个好了,可以少写些逻辑。
794
+ */
795
+ export abstract class BasePlugin implements PluginInterface {
796
+ constructor(readonly manager: EditorManager) {}
797
+
798
+ /**
799
+ * 如果配置里面有 rendererName 自动返回渲染器信息。
800
+ * @param renderer
801
+ */
802
+ getRendererInfo({
803
+ renderer,
804
+ schema
805
+ }: RendererInfoResolveEventContext): BasicRendererInfo | void {
806
+ const plugin: PluginInterface = this;
807
+
808
+ if (
809
+ schema.$$id &&
810
+ plugin.name &&
811
+ plugin.rendererName &&
812
+ plugin.rendererName === renderer.name // renderer.name 会从 renderer.type 中取值
813
+ ) {
814
+ // 复制部分信息出去
815
+ return {
816
+ name: plugin.name,
817
+ regions: plugin.regions,
818
+ patchContainers: plugin.patchContainers,
819
+ // wrapper: plugin.wrapper,
820
+ vRendererConfig: plugin.vRendererConfig,
821
+ wrapperProps: plugin.wrapperProps,
822
+ wrapperResolve: plugin.wrapperResolve,
823
+ filterProps: plugin.filterProps,
824
+ $schema: plugin.$schema,
825
+ renderRenderer: plugin.renderRenderer,
826
+ multifactor: plugin.multifactor,
827
+ scaffoldForm: plugin.scaffoldForm,
828
+ disabledRendererPlugin: plugin.disabledRendererPlugin,
829
+ isBaseComponent: plugin.isBaseComponent,
830
+ rendererName: plugin.rendererName
831
+ };
832
+ }
833
+ }
834
+
835
+ /**
836
+ * 配置了 panelControls 自动生成配置面板
837
+ * @param context
838
+ * @param panels
839
+ */
840
+ buildEditorPanel(
841
+ context: BuildPanelEventContext,
842
+ panels: Array<BasicPanelItem>
843
+ ) {
844
+ const plugin: PluginInterface = this;
845
+ const store = this.manager.store;
846
+
847
+ // 没有选中元素 或者 多选时不处理
848
+ if (!store.activeId || context.selections.length) {
849
+ return;
850
+ }
851
+
852
+ if (
853
+ !context.info.hostId &&
854
+ (plugin.panelControls ||
855
+ plugin.panelControlsCreator ||
856
+ plugin.panelBody ||
857
+ plugin.panelBodyCreator) &&
858
+ context.info.plugin === this
859
+ ) {
860
+ panels.push({
861
+ key: 'config',
862
+ icon: plugin.panelIcon || plugin.icon || 'fa fa-cog',
863
+ title: plugin.panelTitle || '设置',
864
+ render: this.manager.makeSchemaFormRender({
865
+ definitions: plugin.panelDefinitions,
866
+ submitOnChange: plugin.panelSubmitOnChange,
867
+ api: plugin.panelApi,
868
+ body: plugin.panelBodyCreator
869
+ ? plugin.panelBodyCreator(context)
870
+ : plugin.panelBody!,
871
+ controls: plugin.panelControlsCreator
872
+ ? plugin.panelControlsCreator(context)
873
+ : plugin.panelControls!
874
+ })
875
+ });
876
+ } else if (
877
+ context.info.plugin === this &&
878
+ context.info.hostId &&
879
+ (plugin.vRendererConfig?.panelControls ||
880
+ plugin.vRendererConfig?.panelControlsCreator ||
881
+ plugin.vRendererConfig?.panelBody ||
882
+ plugin.vRendererConfig?.panelBodyCreator)
883
+ ) {
884
+ panels.push({
885
+ key: context.info.multifactor ? 'vconfig' : 'config',
886
+ icon: plugin.vRendererConfig.panelIcon || 'fa fa-cog',
887
+ title: plugin.vRendererConfig.panelTitle || '设置',
888
+ render: this.manager.makeSchemaFormRender({
889
+ submitOnChange: plugin.panelSubmitOnChange,
890
+ api: plugin.panelApi,
891
+ definitions: plugin.vRendererConfig.panelDefinitions,
892
+ controls: plugin.vRendererConfig.panelControlsCreator
893
+ ? plugin.vRendererConfig.panelControlsCreator(context)
894
+ : plugin.vRendererConfig.panelControls!,
895
+ body: plugin.vRendererConfig.panelBodyCreator
896
+ ? plugin.vRendererConfig.panelBodyCreator(context)
897
+ : plugin.vRendererConfig.panelBody!
898
+ })
899
+ });
900
+ }
901
+
902
+ // 如果是个多重身份证
903
+ if (context.info.plugin === this && context.info.multifactor) {
904
+ const sameIdChild: EditorNodeType = context.node.sameIdChild;
905
+
906
+ if (sameIdChild) {
907
+ const subPanels = this.manager.collectPanels(sameIdChild, false, true);
908
+ subPanels.forEach(panel => {
909
+ if (panel.key === 'code') {
910
+ const exists = panels.some(panel => panel.key === 'code');
911
+ exists || panels.push(panel);
912
+ } else if (panel.key === 'renderers') {
913
+ const exists = panels.some(panel => panel.key === 'renderers');
914
+ exists || panels.push(panel);
915
+ } else if (
916
+ panel.key === 'outline' ||
917
+ panel.key === 'commonConfig' ||
918
+ panel.key === 'name-list'
919
+ ) {
920
+ // do nothing
921
+ } else {
922
+ panels.push({
923
+ ...panel,
924
+ key: `sub-${panel.key}`,
925
+ icon: sameIdChild.info?.plugin?.icon || panel.icon
926
+ });
927
+ }
928
+ });
929
+ }
930
+ }
931
+ }
932
+
933
+ /**
934
+ * 默认什么组件都加入的子组件里面,子类里面可以复写这个改变行为。
935
+ * @param context
936
+ * @param subRenderers
937
+ */
938
+ buildSubRenderers(
939
+ context: RendererEventContext,
940
+ subRenderers: Array<SubRendererInfo>,
941
+ renderers: Array<RendererConfig>
942
+ ): BasicSubRenderInfo | Array<BasicSubRenderInfo> | void {
943
+ const plugin: PluginInterface = this;
944
+
945
+ if (Array.isArray(plugin.scaffolds)) {
946
+ return plugin.scaffolds.map(scaffold => ({
947
+ name: (scaffold.name ?? plugin.name)!,
948
+ icon: scaffold.icon ?? plugin.icon,
949
+ description: scaffold.description ?? plugin.description,
950
+ previewSchema: scaffold.previewSchema ?? plugin.previewSchema,
951
+ tags: scaffold.tags ?? plugin.tags,
952
+ docLink: scaffold.docLink ?? plugin.docLink,
953
+ type: scaffold.type ?? plugin.type,
954
+ scaffold: scaffold.scaffold ?? plugin.scaffold,
955
+ scaffoldForm: plugin.scaffoldForm,
956
+ disabledRendererPlugin: plugin.disabledRendererPlugin,
957
+ isBaseComponent: plugin.isBaseComponent,
958
+ rendererName: plugin.rendererName
959
+ }));
960
+ } else if (plugin.name && plugin.description) {
961
+ return {
962
+ name: plugin.name,
963
+ icon: plugin.icon,
964
+ description: plugin.description,
965
+ previewSchema: plugin.previewSchema,
966
+ tags: plugin.tags,
967
+ docLink: plugin.docLink,
968
+ type: plugin.type,
969
+ scaffold: plugin.scaffold,
970
+ scaffoldForm: plugin.scaffoldForm,
971
+ disabledRendererPlugin: plugin.disabledRendererPlugin,
972
+ isBaseComponent: plugin.isBaseComponent,
973
+ rendererName: plugin.rendererName
974
+ };
975
+ }
976
+ }
977
+
978
+ /**
979
+ * 构建当前选中组件的右键菜单
980
+ * @param id
981
+ * @param schema
982
+ * @param region
983
+ * @param info
984
+ * @param menus
985
+ */
986
+ buildEditorContextMenu(
987
+ {id, schema, region, info, selections}: ContextMenuEventContext,
988
+ menus: Array<ContextMenuItem>
989
+ ) {
990
+ const plugin: PluginInterface = this;
991
+ if (
992
+ info.plugin === plugin &&
993
+ !selections.length &&
994
+ (plugin.scaffoldForm?.canRebuild || info.scaffoldForm?.canRebuild)
995
+ ) {
996
+ menus.push({
997
+ label: `快速构建「${info.plugin.name}」`,
998
+ disabled: schema.$$commonSchema,
999
+ onSelect: () =>
1000
+ this.manager.reScaffold(
1001
+ id,
1002
+ info.scaffoldForm || plugin.scaffoldForm!,
1003
+ schema
1004
+ )
1005
+ });
1006
+ }
1007
+ }
1008
+
1009
+ buildEditorToolbar(
1010
+ {id, schema, info}: BaseEventContext,
1011
+ toolbars: Array<BasicToolbarItem>
1012
+ ) {
1013
+ const plugin: PluginInterface = this;
1014
+ if (
1015
+ info.plugin === plugin &&
1016
+ (plugin.scaffoldForm?.canRebuild || info.scaffoldForm?.canRebuild)
1017
+ ) {
1018
+ toolbars.push({
1019
+ iconSvg: 'harmmer',
1020
+ tooltip: `快速构建「${info.plugin.name}」`,
1021
+ placement: 'bottom',
1022
+ onClick: () =>
1023
+ this.manager.reScaffold(
1024
+ id,
1025
+ info.scaffoldForm || plugin.scaffoldForm!,
1026
+ schema
1027
+ )
1028
+ });
1029
+ }
1030
+ }
1031
+
1032
+ renderPlaceholder(text: string, key?: any) {
1033
+ return React.createElement('div', {
1034
+ key,
1035
+ className: 'wrapper-sm b-a b-light m-b-sm',
1036
+ children: React.createElement('span', {
1037
+ className: 'text-muted',
1038
+ children: text
1039
+ })
1040
+ });
1041
+ }
1042
+
1043
+ getPlugin(rendererNameOrKlass: string | typeof BasePlugin) {
1044
+ return find(this.manager.plugins, plugin =>
1045
+ typeof rendererNameOrKlass === 'string'
1046
+ ? plugin.rendererName === rendererNameOrKlass
1047
+ : plugin instanceof rendererNameOrKlass
1048
+ );
1049
+ }
1050
+ }