xkit-editor 2.0.0-alpha.0

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 (479) hide show
  1. package/lib/index.d.ts +2 -0
  2. package/lib/packages/editor/env.d.ts +7 -0
  3. package/lib/packages/editor/src/component-configs/__tests__/config.test.d.ts +2 -0
  4. package/lib/packages/editor/src/component-configs/__tests__/config.test.d.ts.map +1 -0
  5. package/lib/packages/editor/src/component-configs/__tests__/group.test.d.ts +2 -0
  6. package/lib/packages/editor/src/component-configs/__tests__/group.test.d.ts.map +1 -0
  7. package/lib/packages/editor/src/component-configs/cascader.d.ts +3 -0
  8. package/lib/packages/editor/src/component-configs/cascader.d.ts.map +1 -0
  9. package/lib/packages/editor/src/component-configs/checkbox.d.ts +4 -0
  10. package/lib/packages/editor/src/component-configs/checkbox.d.ts.map +1 -0
  11. package/lib/packages/editor/src/component-configs/common-props.d.ts +16 -0
  12. package/lib/packages/editor/src/component-configs/common-props.d.ts.map +1 -0
  13. package/lib/packages/editor/src/component-configs/date-picker.d.ts +3 -0
  14. package/lib/packages/editor/src/component-configs/date-picker.d.ts.map +1 -0
  15. package/lib/packages/editor/src/component-configs/date-range-picker.d.ts +4 -0
  16. package/lib/packages/editor/src/component-configs/date-range-picker.d.ts.map +1 -0
  17. package/lib/packages/editor/src/component-configs/group.d.ts +3 -0
  18. package/lib/packages/editor/src/component-configs/group.d.ts.map +1 -0
  19. package/lib/packages/editor/src/component-configs/icon-select.d.ts +3 -0
  20. package/lib/packages/editor/src/component-configs/icon-select.d.ts.map +1 -0
  21. package/lib/packages/editor/src/component-configs/input-array.d.ts +4 -0
  22. package/lib/packages/editor/src/component-configs/input-array.d.ts.map +1 -0
  23. package/lib/packages/editor/src/component-configs/input-number-range.d.ts +3 -0
  24. package/lib/packages/editor/src/component-configs/input-number-range.d.ts.map +1 -0
  25. package/lib/packages/editor/src/component-configs/input-number.d.ts +3 -0
  26. package/lib/packages/editor/src/component-configs/input-number.d.ts.map +1 -0
  27. package/lib/packages/editor/src/component-configs/input-table.d.ts +3 -0
  28. package/lib/packages/editor/src/component-configs/input-table.d.ts.map +1 -0
  29. package/lib/packages/editor/src/component-configs/input-upload.d.ts +3 -0
  30. package/lib/packages/editor/src/component-configs/input-upload.d.ts.map +1 -0
  31. package/lib/packages/editor/src/component-configs/input.d.ts +3 -0
  32. package/lib/packages/editor/src/component-configs/input.d.ts.map +1 -0
  33. package/lib/packages/editor/src/component-configs/layout-sections.d.ts +11 -0
  34. package/lib/packages/editor/src/component-configs/layout-sections.d.ts.map +1 -0
  35. package/lib/packages/editor/src/component-configs/options-config.d.ts +3 -0
  36. package/lib/packages/editor/src/component-configs/options-config.d.ts.map +1 -0
  37. package/lib/packages/editor/src/component-configs/radio.d.ts +3 -0
  38. package/lib/packages/editor/src/component-configs/radio.d.ts.map +1 -0
  39. package/lib/packages/editor/src/component-configs/select.d.ts +3 -0
  40. package/lib/packages/editor/src/component-configs/select.d.ts.map +1 -0
  41. package/lib/packages/editor/src/component-configs/switch.d.ts +3 -0
  42. package/lib/packages/editor/src/component-configs/switch.d.ts.map +1 -0
  43. package/lib/packages/editor/src/component-configs/textarea.d.ts +3 -0
  44. package/lib/packages/editor/src/component-configs/textarea.d.ts.map +1 -0
  45. package/lib/packages/editor/src/component-configs/types.d.ts +33 -0
  46. package/lib/packages/editor/src/component-configs/types.d.ts.map +1 -0
  47. package/lib/packages/editor/src/components/condition-editor.vue.d.ts +19 -0
  48. package/lib/packages/editor/src/components/condition-editor.vue.d.ts.map +1 -0
  49. package/lib/packages/editor/src/components/design-renderers/input-array-design.vue.d.ts +17 -0
  50. package/lib/packages/editor/src/components/design-renderers/input-array-design.vue.d.ts.map +1 -0
  51. package/lib/packages/editor/src/components/design-renderers/input-table-design.vue.d.ts +15 -0
  52. package/lib/packages/editor/src/components/design-renderers/input-table-design.vue.d.ts.map +1 -0
  53. package/lib/packages/editor/src/components/form-item-layout-editor.vue.d.ts +14 -0
  54. package/lib/packages/editor/src/components/form-item-layout-editor.vue.d.ts.map +1 -0
  55. package/lib/packages/editor/src/components/form-item-span-editor.vue.d.ts +18 -0
  56. package/lib/packages/editor/src/components/form-item-span-editor.vue.d.ts.map +1 -0
  57. package/lib/packages/editor/src/components/form-layout-editor.vue.d.ts +21 -0
  58. package/lib/packages/editor/src/components/form-layout-editor.vue.d.ts.map +1 -0
  59. package/lib/packages/editor/src/components/group-title-color-select.vue.d.ts +10 -0
  60. package/lib/packages/editor/src/components/group-title-color-select.vue.d.ts.map +1 -0
  61. package/lib/packages/editor/src/components/group-title-style-picker.vue.d.ts +10 -0
  62. package/lib/packages/editor/src/components/group-title-style-picker.vue.d.ts.map +1 -0
  63. package/lib/packages/editor/src/components/input-number-range-binding-editor.vue.d.ts +25 -0
  64. package/lib/packages/editor/src/components/input-number-range-binding-editor.vue.d.ts.map +1 -0
  65. package/lib/packages/editor/src/components/input-table-default-rows-editor.vue.d.ts +11 -0
  66. package/lib/packages/editor/src/components/input-table-default-rows-editor.vue.d.ts.map +1 -0
  67. package/lib/packages/editor/src/components/input-table-operation-editor.vue.d.ts +11 -0
  68. package/lib/packages/editor/src/components/input-table-operation-editor.vue.d.ts.map +1 -0
  69. package/lib/packages/editor/src/components/json-code-editor.vue.d.ts +18 -0
  70. package/lib/packages/editor/src/components/json-code-editor.vue.d.ts.map +1 -0
  71. package/lib/packages/editor/src/components/object-section-editor.vue.d.ts +23 -0
  72. package/lib/packages/editor/src/components/object-section-editor.vue.d.ts.map +1 -0
  73. package/lib/packages/editor/src/components/options/default-dict-options-panel.vue.d.ts +10 -0
  74. package/lib/packages/editor/src/components/options/default-dict-options-panel.vue.d.ts.map +1 -0
  75. package/lib/packages/editor/src/components/options/options-editor.vue.d.ts +12 -0
  76. package/lib/packages/editor/src/components/options/options-editor.vue.d.ts.map +1 -0
  77. package/lib/packages/editor/src/components/validation-rules-editor.vue.d.ts +12 -0
  78. package/lib/packages/editor/src/components/validation-rules-editor.vue.d.ts.map +1 -0
  79. package/lib/packages/editor/src/config.d.ts +8 -0
  80. package/lib/packages/editor/src/config.d.ts.map +1 -0
  81. package/lib/packages/editor/src/editor-item-wrapper.vue.d.ts +39 -0
  82. package/lib/packages/editor/src/editor-item-wrapper.vue.d.ts.map +1 -0
  83. package/lib/packages/editor/src/group-title-styles.d.ts +9 -0
  84. package/lib/packages/editor/src/group-title-styles.d.ts.map +1 -0
  85. package/lib/packages/editor/src/index.d.ts +7 -0
  86. package/lib/packages/editor/src/index.d.ts.map +1 -0
  87. package/lib/packages/editor/src/option-sources.d.ts +10 -0
  88. package/lib/packages/editor/src/option-sources.d.ts.map +1 -0
  89. package/lib/packages/editor/src/root-configs.d.ts +12 -0
  90. package/lib/packages/editor/src/root-configs.d.ts.map +1 -0
  91. package/lib/packages/editor/src/shims-vue.d.ts +5 -0
  92. package/lib/packages/editor/src/utils/__tests__/component-replace.test.d.ts +2 -0
  93. package/lib/packages/editor/src/utils/__tests__/component-replace.test.d.ts.map +1 -0
  94. package/lib/packages/editor/src/utils/__tests__/editor-schema.test.d.ts +2 -0
  95. package/lib/packages/editor/src/utils/__tests__/editor-schema.test.d.ts.map +1 -0
  96. package/lib/packages/editor/src/utils/__tests__/form-item-width.test.d.ts +2 -0
  97. package/lib/packages/editor/src/utils/__tests__/form-item-width.test.d.ts.map +1 -0
  98. package/lib/packages/editor/src/utils/__tests__/group-drag-path.test.d.ts +2 -0
  99. package/lib/packages/editor/src/utils/__tests__/group-drag-path.test.d.ts.map +1 -0
  100. package/lib/packages/editor/src/utils/__tests__/record-field.test.d.ts +2 -0
  101. package/lib/packages/editor/src/utils/__tests__/record-field.test.d.ts.map +1 -0
  102. package/lib/packages/editor/src/utils/component-replace.d.ts +8 -0
  103. package/lib/packages/editor/src/utils/component-replace.d.ts.map +1 -0
  104. package/lib/packages/editor/src/utils/editor-schema.d.ts +28 -0
  105. package/lib/packages/editor/src/utils/editor-schema.d.ts.map +1 -0
  106. package/lib/packages/editor/src/utils/form-item-width.d.ts +6 -0
  107. package/lib/packages/editor/src/utils/form-item-width.d.ts.map +1 -0
  108. package/lib/packages/editor/src/utils/local-dict-center.d.ts +11 -0
  109. package/lib/packages/editor/src/utils/local-dict-center.d.ts.map +1 -0
  110. package/lib/packages/editor/src/utils/record-field.d.ts +7 -0
  111. package/lib/packages/editor/src/utils/record-field.d.ts.map +1 -0
  112. package/lib/packages/editor/src/validation-rules.d.ts +10 -0
  113. package/lib/packages/editor/src/validation-rules.d.ts.map +1 -0
  114. package/lib/packages/editor/src/x-editor.vue.d.ts +107 -0
  115. package/lib/packages/editor/src/x-editor.vue.d.ts.map +1 -0
  116. package/lib/packages/ui/src/assets/icon-add-circle-fill.vue.d.ts +3 -0
  117. package/lib/packages/ui/src/assets/icon-add-circle-fill.vue.d.ts.map +1 -0
  118. package/lib/packages/ui/src/assets/icon-close-line.vue.d.ts +3 -0
  119. package/lib/packages/ui/src/assets/icon-close-line.vue.d.ts.map +1 -0
  120. package/lib/packages/ui/src/assets/icon-drag.vue.d.ts +3 -0
  121. package/lib/packages/ui/src/assets/icon-drag.vue.d.ts.map +1 -0
  122. package/lib/packages/ui/src/assets/icon-minus-circle.vue.d.ts +3 -0
  123. package/lib/packages/ui/src/assets/icon-minus-circle.vue.d.ts.map +1 -0
  124. package/lib/packages/ui/src/components/_public/form-item-cols.vue.d.ts +17 -0
  125. package/lib/packages/ui/src/components/_public/form-item-cols.vue.d.ts.map +1 -0
  126. package/lib/packages/ui/src/components/button/type.d.ts +85 -0
  127. package/lib/packages/ui/src/components/button/type.d.ts.map +1 -0
  128. package/lib/packages/ui/src/components/cascader/index.vue.d.ts +66 -0
  129. package/lib/packages/ui/src/components/cascader/index.vue.d.ts.map +1 -0
  130. package/lib/packages/ui/src/components/cascader/type.d.ts +125 -0
  131. package/lib/packages/ui/src/components/cascader/type.d.ts.map +1 -0
  132. package/lib/packages/ui/src/components/checkbox/index.vue.d.ts +30 -0
  133. package/lib/packages/ui/src/components/checkbox/index.vue.d.ts.map +1 -0
  134. package/lib/packages/ui/src/components/checkbox/type.d.ts +36 -0
  135. package/lib/packages/ui/src/components/checkbox/type.d.ts.map +1 -0
  136. package/lib/packages/ui/src/components/checkboxes/index.vue.d.ts +42 -0
  137. package/lib/packages/ui/src/components/checkboxes/index.vue.d.ts.map +1 -0
  138. package/lib/packages/ui/src/components/checkboxes/type.d.ts +56 -0
  139. package/lib/packages/ui/src/components/checkboxes/type.d.ts.map +1 -0
  140. package/lib/packages/ui/src/components/component/index.d.ts +7 -0
  141. package/lib/packages/ui/src/components/component/index.d.ts.map +1 -0
  142. package/lib/packages/ui/src/components/condition-builder/condition-node.vue.d.ts +32 -0
  143. package/lib/packages/ui/src/components/condition-builder/condition-node.vue.d.ts.map +1 -0
  144. package/lib/packages/ui/src/components/condition-builder/group-bracket.vue.d.ts +19 -0
  145. package/lib/packages/ui/src/components/condition-builder/group-bracket.vue.d.ts.map +1 -0
  146. package/lib/packages/ui/src/components/condition-builder/group-indent.vue.d.ts +19 -0
  147. package/lib/packages/ui/src/components/condition-builder/group-indent.vue.d.ts.map +1 -0
  148. package/lib/packages/ui/src/components/condition-builder/index.vue.d.ts +160 -0
  149. package/lib/packages/ui/src/components/condition-builder/index.vue.d.ts.map +1 -0
  150. package/lib/packages/ui/src/components/condition-builder/type.d.ts +88 -0
  151. package/lib/packages/ui/src/components/condition-builder/type.d.ts.map +1 -0
  152. package/lib/packages/ui/src/components/crud/action-type.d.ts +80 -0
  153. package/lib/packages/ui/src/components/crud/action-type.d.ts.map +1 -0
  154. package/lib/packages/ui/src/components/crud/index.vue.d.ts +78 -0
  155. package/lib/packages/ui/src/components/crud/index.vue.d.ts.map +1 -0
  156. package/lib/packages/ui/src/components/crud/multi-action.vue.d.ts +8 -0
  157. package/lib/packages/ui/src/components/crud/multi-action.vue.d.ts.map +1 -0
  158. package/lib/packages/ui/src/components/crud/single-action.vue.d.ts +7 -0
  159. package/lib/packages/ui/src/components/crud/single-action.vue.d.ts.map +1 -0
  160. package/lib/packages/ui/src/components/crud/type.d.ts +171 -0
  161. package/lib/packages/ui/src/components/crud/type.d.ts.map +1 -0
  162. package/lib/packages/ui/src/components/crud-form/index.vue.d.ts +22 -0
  163. package/lib/packages/ui/src/components/crud-form/index.vue.d.ts.map +1 -0
  164. package/lib/packages/ui/src/components/crud-form/type.d.ts +65 -0
  165. package/lib/packages/ui/src/components/crud-form/type.d.ts.map +1 -0
  166. package/lib/packages/ui/src/components/date-picker/index.vue.d.ts +35 -0
  167. package/lib/packages/ui/src/components/date-picker/index.vue.d.ts.map +1 -0
  168. package/lib/packages/ui/src/components/date-picker/type.d.ts +139 -0
  169. package/lib/packages/ui/src/components/date-picker/type.d.ts.map +1 -0
  170. package/lib/packages/ui/src/components/date-range-picker/index.vue.d.ts +15 -0
  171. package/lib/packages/ui/src/components/date-range-picker/index.vue.d.ts.map +1 -0
  172. package/lib/packages/ui/src/components/date-range-picker/type.d.ts +137 -0
  173. package/lib/packages/ui/src/components/date-range-picker/type.d.ts.map +1 -0
  174. package/lib/packages/ui/src/components/date-range-picker-v2/index.vue.d.ts +22 -0
  175. package/lib/packages/ui/src/components/date-range-picker-v2/index.vue.d.ts.map +1 -0
  176. package/lib/packages/ui/src/components/date-range-picker-v2/type.d.ts +37 -0
  177. package/lib/packages/ui/src/components/date-range-picker-v2/type.d.ts.map +1 -0
  178. package/lib/packages/ui/src/components/description/index.vue.d.ts +28 -0
  179. package/lib/packages/ui/src/components/description/index.vue.d.ts.map +1 -0
  180. package/lib/packages/ui/src/components/description/type.d.ts +120 -0
  181. package/lib/packages/ui/src/components/description/type.d.ts.map +1 -0
  182. package/lib/packages/ui/src/components/dialog/type.d.ts +100 -0
  183. package/lib/packages/ui/src/components/dialog/type.d.ts.map +1 -0
  184. package/lib/packages/ui/src/components/dropdown/type.d.ts +62 -0
  185. package/lib/packages/ui/src/components/dropdown/type.d.ts.map +1 -0
  186. package/lib/packages/ui/src/components/ellipsis/index.vue.d.ts +34 -0
  187. package/lib/packages/ui/src/components/ellipsis/index.vue.d.ts.map +1 -0
  188. package/lib/packages/ui/src/components/ellipsis/type.d.ts +26 -0
  189. package/lib/packages/ui/src/components/ellipsis/type.d.ts.map +1 -0
  190. package/lib/packages/ui/src/components/event-menu/index.vue.d.ts +25 -0
  191. package/lib/packages/ui/src/components/event-menu/index.vue.d.ts.map +1 -0
  192. package/lib/packages/ui/src/components/form/form-item.type.d.ts +304 -0
  193. package/lib/packages/ui/src/components/form/form-item.type.d.ts.map +1 -0
  194. package/lib/packages/ui/src/components/form/form-item.vue.d.ts +50 -0
  195. package/lib/packages/ui/src/components/form/form-item.vue.d.ts.map +1 -0
  196. package/lib/packages/ui/src/components/form/form-layout-renderer.vue.d.ts +71 -0
  197. package/lib/packages/ui/src/components/form/form-layout-renderer.vue.d.ts.map +1 -0
  198. package/lib/packages/ui/src/components/form/index.vue.d.ts +220 -0
  199. package/lib/packages/ui/src/components/form/index.vue.d.ts.map +1 -0
  200. package/lib/packages/ui/src/components/form/query-form.d.ts +4 -0
  201. package/lib/packages/ui/src/components/form/query-form.d.ts.map +1 -0
  202. package/lib/packages/ui/src/components/form/type.d.ts +312 -0
  203. package/lib/packages/ui/src/components/form/type.d.ts.map +1 -0
  204. package/lib/packages/ui/src/components/group/group-item.vue.d.ts +9 -0
  205. package/lib/packages/ui/src/components/group/group-item.vue.d.ts.map +1 -0
  206. package/lib/packages/ui/src/components/group/index.vue.d.ts +24 -0
  207. package/lib/packages/ui/src/components/group/index.vue.d.ts.map +1 -0
  208. package/lib/packages/ui/src/components/group/type.d.ts +119 -0
  209. package/lib/packages/ui/src/components/group/type.d.ts.map +1 -0
  210. package/lib/packages/ui/src/components/icon-select/__tests__/icon-sources.test.d.ts +2 -0
  211. package/lib/packages/ui/src/components/icon-select/__tests__/icon-sources.test.d.ts.map +1 -0
  212. package/lib/packages/ui/src/components/icon-select/icon-parser.vue.d.ts +41 -0
  213. package/lib/packages/ui/src/components/icon-select/icon-parser.vue.d.ts.map +1 -0
  214. package/lib/packages/ui/src/components/icon-select/icon-sources.d.ts +22 -0
  215. package/lib/packages/ui/src/components/icon-select/icon-sources.d.ts.map +1 -0
  216. package/lib/packages/ui/src/components/icon-select/index.vue.d.ts +15 -0
  217. package/lib/packages/ui/src/components/icon-select/index.vue.d.ts.map +1 -0
  218. package/lib/packages/ui/src/components/icon-select/type.d.ts +24 -0
  219. package/lib/packages/ui/src/components/icon-select/type.d.ts.map +1 -0
  220. package/lib/packages/ui/src/components/index.d.ts +107 -0
  221. package/lib/packages/ui/src/components/index.d.ts.map +1 -0
  222. package/lib/packages/ui/src/components/input/index.vue.d.ts +20 -0
  223. package/lib/packages/ui/src/components/input/index.vue.d.ts.map +1 -0
  224. package/lib/packages/ui/src/components/input/type.d.ts +121 -0
  225. package/lib/packages/ui/src/components/input/type.d.ts.map +1 -0
  226. package/lib/packages/ui/src/components/input-array/__tests__/layout.test.d.ts +2 -0
  227. package/lib/packages/ui/src/components/input-array/__tests__/layout.test.d.ts.map +1 -0
  228. package/lib/packages/ui/src/components/input-array/index.vue.d.ts +28 -0
  229. package/lib/packages/ui/src/components/input-array/index.vue.d.ts.map +1 -0
  230. package/lib/packages/ui/src/components/input-array/layout.d.ts +11 -0
  231. package/lib/packages/ui/src/components/input-array/layout.d.ts.map +1 -0
  232. package/lib/packages/ui/src/components/input-array/type.d.ts +89 -0
  233. package/lib/packages/ui/src/components/input-array/type.d.ts.map +1 -0
  234. package/lib/packages/ui/src/components/input-collapse/index.vue.d.ts +7 -0
  235. package/lib/packages/ui/src/components/input-collapse/index.vue.d.ts.map +1 -0
  236. package/lib/packages/ui/src/components/input-collapse/type.d.ts +50 -0
  237. package/lib/packages/ui/src/components/input-collapse/type.d.ts.map +1 -0
  238. package/lib/packages/ui/src/components/input-linked/index.vue.d.ts +13 -0
  239. package/lib/packages/ui/src/components/input-linked/index.vue.d.ts.map +1 -0
  240. package/lib/packages/ui/src/components/input-linked/type.d.ts +32 -0
  241. package/lib/packages/ui/src/components/input-linked/type.d.ts.map +1 -0
  242. package/lib/packages/ui/src/components/input-number/index.vue.d.ts +29 -0
  243. package/lib/packages/ui/src/components/input-number/index.vue.d.ts.map +1 -0
  244. package/lib/packages/ui/src/components/input-number/type.d.ts +57 -0
  245. package/lib/packages/ui/src/components/input-number/type.d.ts.map +1 -0
  246. package/lib/packages/ui/src/components/input-number-range/index.vue.d.ts +28 -0
  247. package/lib/packages/ui/src/components/input-number-range/index.vue.d.ts.map +1 -0
  248. package/lib/packages/ui/src/components/input-number-range/type.d.ts +49 -0
  249. package/lib/packages/ui/src/components/input-number-range/type.d.ts.map +1 -0
  250. package/lib/packages/ui/src/components/input-table/index.vue.d.ts +25 -0
  251. package/lib/packages/ui/src/components/input-table/index.vue.d.ts.map +1 -0
  252. package/lib/packages/ui/src/components/input-table/type.d.ts +37 -0
  253. package/lib/packages/ui/src/components/input-table/type.d.ts.map +1 -0
  254. package/lib/packages/ui/src/components/input-upload/index.vue.d.ts +11 -0
  255. package/lib/packages/ui/src/components/input-upload/index.vue.d.ts.map +1 -0
  256. package/lib/packages/ui/src/components/input-upload/type.d.ts +59 -0
  257. package/lib/packages/ui/src/components/input-upload/type.d.ts.map +1 -0
  258. package/lib/packages/ui/src/components/json/index.vue.d.ts +10 -0
  259. package/lib/packages/ui/src/components/json/index.vue.d.ts.map +1 -0
  260. package/lib/packages/ui/src/components/link/index.vue.d.ts +21 -0
  261. package/lib/packages/ui/src/components/link/index.vue.d.ts.map +1 -0
  262. package/lib/packages/ui/src/components/link/type.d.ts +28 -0
  263. package/lib/packages/ui/src/components/link/type.d.ts.map +1 -0
  264. package/lib/packages/ui/src/components/radios/index.vue.d.ts +42 -0
  265. package/lib/packages/ui/src/components/radios/index.vue.d.ts.map +1 -0
  266. package/lib/packages/ui/src/components/radios/type.d.ts +36 -0
  267. package/lib/packages/ui/src/components/radios/type.d.ts.map +1 -0
  268. package/lib/packages/ui/src/components/search-bar/index.vue.d.ts +37 -0
  269. package/lib/packages/ui/src/components/search-bar/index.vue.d.ts.map +1 -0
  270. package/lib/packages/ui/src/components/select/index.vue.d.ts +48 -0
  271. package/lib/packages/ui/src/components/select/index.vue.d.ts.map +1 -0
  272. package/lib/packages/ui/src/components/select/type.d.ts +222 -0
  273. package/lib/packages/ui/src/components/select/type.d.ts.map +1 -0
  274. package/lib/packages/ui/src/components/static/options-viewer.vue.d.ts +16 -0
  275. package/lib/packages/ui/src/components/static/options-viewer.vue.d.ts.map +1 -0
  276. package/lib/packages/ui/src/components/static/rich-text-viewer.vue.d.ts +8 -0
  277. package/lib/packages/ui/src/components/static/rich-text-viewer.vue.d.ts.map +1 -0
  278. package/lib/packages/ui/src/components/static/textarea-viewer.vue.d.ts +6 -0
  279. package/lib/packages/ui/src/components/static/textarea-viewer.vue.d.ts.map +1 -0
  280. package/lib/packages/ui/src/components/switch/index.vue.d.ts +38 -0
  281. package/lib/packages/ui/src/components/switch/index.vue.d.ts.map +1 -0
  282. package/lib/packages/ui/src/components/switch/type.d.ts +72 -0
  283. package/lib/packages/ui/src/components/switch/type.d.ts.map +1 -0
  284. package/lib/packages/ui/src/components/table/index.vue.d.ts +1317 -0
  285. package/lib/packages/ui/src/components/table/index.vue.d.ts.map +1 -0
  286. package/lib/packages/ui/src/components/table/table-column.vue.d.ts +44 -0
  287. package/lib/packages/ui/src/components/table/table-column.vue.d.ts.map +1 -0
  288. package/lib/packages/ui/src/components/table/type.d.ts +306 -0
  289. package/lib/packages/ui/src/components/table/type.d.ts.map +1 -0
  290. package/lib/packages/ui/src/components/table-select/const.d.ts +14 -0
  291. package/lib/packages/ui/src/components/table-select/const.d.ts.map +1 -0
  292. package/lib/packages/ui/src/components/table-select/index.vue.d.ts +21871 -0
  293. package/lib/packages/ui/src/components/table-select/index.vue.d.ts.map +1 -0
  294. package/lib/packages/ui/src/components/table-select/table-selector-main.vue.d.ts +4795 -0
  295. package/lib/packages/ui/src/components/table-select/table-selector-main.vue.d.ts.map +1 -0
  296. package/lib/packages/ui/src/components/table-select/type.d.ts +71 -0
  297. package/lib/packages/ui/src/components/table-select/type.d.ts.map +1 -0
  298. package/lib/packages/ui/src/components/tabs/index.vue.d.ts +6 -0
  299. package/lib/packages/ui/src/components/tabs/index.vue.d.ts.map +1 -0
  300. package/lib/packages/ui/src/components/tabs/type.d.ts +23 -0
  301. package/lib/packages/ui/src/components/tabs/type.d.ts.map +1 -0
  302. package/lib/packages/ui/src/components/text/index.vue.d.ts +7 -0
  303. package/lib/packages/ui/src/components/text/index.vue.d.ts.map +1 -0
  304. package/lib/packages/ui/src/components/text/type.d.ts +7 -0
  305. package/lib/packages/ui/src/components/text/type.d.ts.map +1 -0
  306. package/lib/packages/ui/src/components/textarea/type.d.ts +79 -0
  307. package/lib/packages/ui/src/components/textarea/type.d.ts.map +1 -0
  308. package/lib/packages/ui/src/components/toolbar/index.vue.d.ts +15 -0
  309. package/lib/packages/ui/src/components/toolbar/index.vue.d.ts.map +1 -0
  310. package/lib/packages/ui/src/components/transitions/TransitionHeight.vue.d.ts +30 -0
  311. package/lib/packages/ui/src/components/transitions/TransitionHeight.vue.d.ts.map +1 -0
  312. package/lib/packages/ui/src/components/tree/index.vue.d.ts +17 -0
  313. package/lib/packages/ui/src/components/tree/index.vue.d.ts.map +1 -0
  314. package/lib/packages/ui/src/components/tree/tree-node.vue.d.ts +8 -0
  315. package/lib/packages/ui/src/components/tree/tree-node.vue.d.ts.map +1 -0
  316. package/lib/packages/ui/src/components/tree/tree-state.d.ts +35 -0
  317. package/lib/packages/ui/src/components/tree/tree-state.d.ts.map +1 -0
  318. package/lib/packages/ui/src/components/tree/type.d.ts +50 -0
  319. package/lib/packages/ui/src/components/tree/type.d.ts.map +1 -0
  320. package/lib/packages/ui/src/components/tree-select/index.vue.d.ts +94 -0
  321. package/lib/packages/ui/src/components/tree-select/index.vue.d.ts.map +1 -0
  322. package/lib/packages/ui/src/components/tree-select/type.d.ts +156 -0
  323. package/lib/packages/ui/src/components/tree-select/type.d.ts.map +1 -0
  324. package/lib/packages/ui/src/components/tree-select-crud/index.vue.d.ts +3102 -0
  325. package/lib/packages/ui/src/components/tree-select-crud/index.vue.d.ts.map +1 -0
  326. package/lib/packages/ui/src/components/tree-select-crud/type.d.ts +88 -0
  327. package/lib/packages/ui/src/components/tree-select-crud/type.d.ts.map +1 -0
  328. package/lib/packages/ui/src/components/upload/index.vue.d.ts +54 -0
  329. package/lib/packages/ui/src/components/upload/index.vue.d.ts.map +1 -0
  330. package/lib/packages/ui/src/composables/__tests__/use-option-static.test.d.ts +2 -0
  331. package/lib/packages/ui/src/composables/__tests__/use-option-static.test.d.ts.map +1 -0
  332. package/lib/packages/ui/src/composables/index.d.ts +3 -0
  333. package/lib/packages/ui/src/composables/index.d.ts.map +1 -0
  334. package/lib/packages/ui/src/composables/use-action.d.ts +21 -0
  335. package/lib/packages/ui/src/composables/use-action.d.ts.map +1 -0
  336. package/lib/packages/ui/src/composables/use-component.d.ts +74 -0
  337. package/lib/packages/ui/src/composables/use-component.d.ts.map +1 -0
  338. package/lib/packages/ui/src/composables/use-config.d.ts +76 -0
  339. package/lib/packages/ui/src/composables/use-config.d.ts.map +1 -0
  340. package/lib/packages/ui/src/composables/use-draggable.d.ts +22 -0
  341. package/lib/packages/ui/src/composables/use-draggable.d.ts.map +1 -0
  342. package/lib/packages/ui/src/composables/use-input-array.d.ts +45 -0
  343. package/lib/packages/ui/src/composables/use-input-array.d.ts.map +1 -0
  344. package/lib/packages/ui/src/composables/use-label.d.ts +2 -0
  345. package/lib/packages/ui/src/composables/use-label.d.ts.map +1 -0
  346. package/lib/packages/ui/src/composables/use-loading.d.ts +6 -0
  347. package/lib/packages/ui/src/composables/use-loading.d.ts.map +1 -0
  348. package/lib/packages/ui/src/composables/use-option-static.d.ts +51 -0
  349. package/lib/packages/ui/src/composables/use-option-static.d.ts.map +1 -0
  350. package/lib/packages/ui/src/composables/use-options.d.ts +66 -0
  351. package/lib/packages/ui/src/composables/use-options.d.ts.map +1 -0
  352. package/lib/packages/ui/src/composables/use-paging.d.ts +134 -0
  353. package/lib/packages/ui/src/composables/use-paging.d.ts.map +1 -0
  354. package/lib/packages/ui/src/composables/use-scaffold.d.ts +54 -0
  355. package/lib/packages/ui/src/composables/use-scaffold.d.ts.map +1 -0
  356. package/lib/packages/ui/src/composables/use-toggle.d.ts +11 -0
  357. package/lib/packages/ui/src/composables/use-toggle.d.ts.map +1 -0
  358. package/lib/packages/ui/src/composables/use-tree-static-path.d.ts +45 -0
  359. package/lib/packages/ui/src/composables/use-tree-static-path.d.ts.map +1 -0
  360. package/lib/packages/ui/src/composables/use-visible.d.ts +11 -0
  361. package/lib/packages/ui/src/composables/use-visible.d.ts.map +1 -0
  362. package/lib/packages/ui/src/config/layout.d.ts +9 -0
  363. package/lib/packages/ui/src/config/layout.d.ts.map +1 -0
  364. package/lib/packages/ui/src/constants/injection.d.ts +11 -0
  365. package/lib/packages/ui/src/constants/injection.d.ts.map +1 -0
  366. package/lib/packages/ui/src/directives/highlight.d.ts +7 -0
  367. package/lib/packages/ui/src/directives/highlight.d.ts.map +1 -0
  368. package/lib/packages/ui/src/directives/index.d.ts +2 -0
  369. package/lib/packages/ui/src/directives/index.d.ts.map +1 -0
  370. package/lib/packages/ui/src/index.d.ts +59 -0
  371. package/lib/packages/ui/src/index.d.ts.map +1 -0
  372. package/lib/packages/ui/src/types/api.d.ts +8 -0
  373. package/lib/packages/ui/src/types/api.d.ts.map +1 -0
  374. package/lib/packages/ui/src/types/base.d.ts +306 -0
  375. package/lib/packages/ui/src/types/base.d.ts.map +1 -0
  376. package/lib/packages/ui/src/types/form.d.ts +82 -0
  377. package/lib/packages/ui/src/types/form.d.ts.map +1 -0
  378. package/lib/packages/ui/src/types/index.d.ts +6 -0
  379. package/lib/packages/ui/src/types/index.d.ts.map +1 -0
  380. package/lib/packages/ui/src/types/option.d.ts +115 -0
  381. package/lib/packages/ui/src/types/option.d.ts.map +1 -0
  382. package/lib/packages/ui/src/types/pagination.d.ts +35 -0
  383. package/lib/packages/ui/src/types/pagination.d.ts.map +1 -0
  384. package/lib/packages/ui/src/types/table.d.ts +34 -0
  385. package/lib/packages/ui/src/types/table.d.ts.map +1 -0
  386. package/lib/packages/ui/src/types/util.d.ts +6 -0
  387. package/lib/packages/ui/src/types/util.d.ts.map +1 -0
  388. package/lib/packages/ui/src/utils/__tests__/condition.test.d.ts +2 -0
  389. package/lib/packages/ui/src/utils/__tests__/condition.test.d.ts.map +1 -0
  390. package/lib/packages/ui/src/utils/__tests__/editor-container.test.d.ts +2 -0
  391. package/lib/packages/ui/src/utils/__tests__/editor-container.test.d.ts.map +1 -0
  392. package/lib/packages/ui/src/utils/__tests__/form.test.d.ts +2 -0
  393. package/lib/packages/ui/src/utils/__tests__/form.test.d.ts.map +1 -0
  394. package/lib/packages/ui/src/utils/__tests__/tree.test.d.ts +2 -0
  395. package/lib/packages/ui/src/utils/__tests__/tree.test.d.ts.map +1 -0
  396. package/lib/packages/ui/src/utils/common.d.ts +13 -0
  397. package/lib/packages/ui/src/utils/common.d.ts.map +1 -0
  398. package/lib/packages/ui/src/utils/computed-state-manager.d.ts +3 -0
  399. package/lib/packages/ui/src/utils/computed-state-manager.d.ts.map +1 -0
  400. package/lib/packages/ui/src/utils/condition.d.ts +4 -0
  401. package/lib/packages/ui/src/utils/condition.d.ts.map +1 -0
  402. package/lib/packages/ui/src/utils/editor-container.d.ts +25 -0
  403. package/lib/packages/ui/src/utils/editor-container.d.ts.map +1 -0
  404. package/lib/packages/ui/src/utils/form-item.d.ts +23 -0
  405. package/lib/packages/ui/src/utils/form-item.d.ts.map +1 -0
  406. package/lib/packages/ui/src/utils/form.d.ts +75 -0
  407. package/lib/packages/ui/src/utils/form.d.ts.map +1 -0
  408. package/lib/packages/ui/src/utils/id.d.ts +24 -0
  409. package/lib/packages/ui/src/utils/id.d.ts.map +1 -0
  410. package/lib/packages/ui/src/utils/options.d.ts +14 -0
  411. package/lib/packages/ui/src/utils/options.d.ts.map +1 -0
  412. package/lib/packages/ui/src/utils/reactive.d.ts +13 -0
  413. package/lib/packages/ui/src/utils/reactive.d.ts.map +1 -0
  414. package/lib/packages/ui/src/utils/style.d.ts +5 -0
  415. package/lib/packages/ui/src/utils/style.d.ts.map +1 -0
  416. package/lib/packages/ui/src/utils/tree.d.ts +51 -0
  417. package/lib/packages/ui/src/utils/tree.d.ts.map +1 -0
  418. package/lib/xkit-editor.css +2 -0
  419. package/lib/xkit-editor.js +78741 -0
  420. package/lib/xkit-editor.umd.cjs +99 -0
  421. package/package.json +50 -0
  422. package/src/component-configs/__tests__/config.test.ts +288 -0
  423. package/src/component-configs/__tests__/group.test.ts +104 -0
  424. package/src/component-configs/cascader.ts +20 -0
  425. package/src/component-configs/checkbox.ts +43 -0
  426. package/src/component-configs/common-props.ts +130 -0
  427. package/src/component-configs/date-picker.ts +153 -0
  428. package/src/component-configs/date-range-picker.ts +185 -0
  429. package/src/component-configs/group.ts +196 -0
  430. package/src/component-configs/icon-select.ts +56 -0
  431. package/src/component-configs/input-array.ts +184 -0
  432. package/src/component-configs/input-number-range.ts +143 -0
  433. package/src/component-configs/input-number.ts +111 -0
  434. package/src/component-configs/input-table.ts +191 -0
  435. package/src/component-configs/input-upload.ts +123 -0
  436. package/src/component-configs/input.ts +48 -0
  437. package/src/component-configs/layout-sections.ts +546 -0
  438. package/src/component-configs/options-config.ts +12 -0
  439. package/src/component-configs/radio.ts +26 -0
  440. package/src/component-configs/select.ts +42 -0
  441. package/src/component-configs/switch.ts +19 -0
  442. package/src/component-configs/textarea.ts +84 -0
  443. package/src/component-configs/types.ts +37 -0
  444. package/src/components/condition-editor.vue +641 -0
  445. package/src/components/design-renderers/input-array-design.vue +283 -0
  446. package/src/components/design-renderers/input-table-design.vue +311 -0
  447. package/src/components/form-item-layout-editor.vue +291 -0
  448. package/src/components/form-item-span-editor.vue +328 -0
  449. package/src/components/form-layout-editor.vue +263 -0
  450. package/src/components/group-title-color-select.vue +75 -0
  451. package/src/components/group-title-style-picker.vue +125 -0
  452. package/src/components/input-number-range-binding-editor.vue +226 -0
  453. package/src/components/input-table-default-rows-editor.vue +147 -0
  454. package/src/components/input-table-operation-editor.vue +168 -0
  455. package/src/components/json-code-editor.vue +219 -0
  456. package/src/components/object-section-editor.vue +342 -0
  457. package/src/components/options/default-dict-options-panel.vue +197 -0
  458. package/src/components/options/options-editor.vue +161 -0
  459. package/src/components/table-columns-editor.vue +353 -0
  460. package/src/components/validation-rules-editor.vue +321 -0
  461. package/src/config.ts +51 -0
  462. package/src/editor-item-wrapper.vue +254 -0
  463. package/src/group-title-styles.ts +82 -0
  464. package/src/index.ts +6 -0
  465. package/src/option-sources.ts +45 -0
  466. package/src/root-configs.ts +278 -0
  467. package/src/shims-vue.d.ts +5 -0
  468. package/src/utils/__tests__/component-replace.test.ts +129 -0
  469. package/src/utils/__tests__/editor-schema.test.ts +429 -0
  470. package/src/utils/__tests__/form-item-width.test.ts +53 -0
  471. package/src/utils/__tests__/group-drag-path.test.ts +84 -0
  472. package/src/utils/__tests__/record-field.test.ts +34 -0
  473. package/src/utils/component-replace.ts +67 -0
  474. package/src/utils/editor-schema.ts +374 -0
  475. package/src/utils/form-item-width.ts +40 -0
  476. package/src/utils/local-dict-center.ts +81 -0
  477. package/src/utils/record-field.ts +30 -0
  478. package/src/validation-rules.ts +104 -0
  479. package/src/x-editor.vue +1300 -0
@@ -0,0 +1,1300 @@
1
+ <template>
2
+ <div class="x-editor">
3
+ <div class="x-editor__header">
4
+ <div class="x-editor__header-left">
5
+ <span class="x-editor__title">在线表单编辑器</span>
6
+ </div>
7
+ <div class="x-editor__header-center">
8
+ <div class="x-editor__modes">
9
+ <span class="x-editor__mode" :class="{ active: activeMode === 'design' }" @click="activeMode = 'design'">设计</span>
10
+ <span class="x-editor__mode" :class="{ active: activeMode === 'preview' }" @click="activeMode = 'preview'">预览</span>
11
+ <span class="x-editor__mode" :class="{ active: activeMode === 'json' }" @click="activeMode = 'json'">JSON</span>
12
+ </div>
13
+ </div>
14
+ <div class="x-editor__header-right">
15
+ <slot name="actions">
16
+ <button class="x-editor__btn" @click="handleReset">重置</button>
17
+ <button class="x-editor__btn primary" @click="handleSubmit">保存</button>
18
+ </slot>
19
+ </div>
20
+ </div>
21
+ <div class="x-editor__body" :class="`is-mode-${activeMode}`">
22
+ <!-- 左侧组件库:仅在设计模式下显示 -->
23
+ <div v-if="activeMode === 'design'" class="x-editor__panel x-editor__panel--left">
24
+ <div class="x-editor__panel-title">组件库</div>
25
+ <ElScrollbar class="x-editor__panel-scrollbar">
26
+ <div class="x-editor__component-palette" ref="componentGridRef">
27
+ <div v-for="group in componentPaletteGroups" :key="group.label" class="x-editor__component-section">
28
+ <div class="x-editor__component-section-title">{{ group.label }}</div>
29
+ <div class="x-editor__component-grid">
30
+ <div class="x-editor__component-item" v-for="item in group.items" :key="item.value" :data-type="item.value">
31
+ <i :class="[item.icon, 'x-editor__component-icon']"></i>
32
+ <span class="x-editor__component-label">{{ item.label }}</span>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </ElScrollbar>
38
+ </div>
39
+
40
+ <!-- 中间主区域 -->
41
+ <div class="x-editor__panel x-editor__panel--center">
42
+ <ElScrollbar class="x-editor__panel-scrollbar x-editor__panel-scrollbar--center">
43
+ <div class="x-editor__center-content">
44
+ <div class="x-editor__canvas" ref="canvasRef">
45
+ <!-- 设计模式 -->
46
+ <template v-if="activeMode === 'design'">
47
+ <EditorItemWrapper
48
+ class="editor-canvas-root"
49
+ :node="rootNode"
50
+ :node-id="ROOT_NODE_ID"
51
+ tag="x-form"
52
+ variant="container"
53
+ :show-actions="false"
54
+ :show-drag="false"
55
+ :emit-custom-event="handleEditorEvent"
56
+ >
57
+ <x-form v-bind="props.modelValue" :wrapper-component="EditorItemWrapper" @custom-event="handleEditorEvent" class="editor-canvas-form" />
58
+ </EditorItemWrapper>
59
+ <div v-if="!props.modelValue?.body?.length" class="x-editor__canvas-empty">从左侧拖拽组件到这里</div>
60
+ </template>
61
+
62
+ <!-- 预览模式 -->
63
+ <div v-else-if="activeMode === 'preview'" class="x-editor__preview-container">
64
+ <x-form v-bind="props.modelValue" />
65
+ </div>
66
+
67
+ <!-- JSON 模式 -->
68
+ <div v-else-if="activeMode === 'json'" class="x-editor__json-container">
69
+ <template v-if="props.editableJson">
70
+ <div class="x-editor__json-toolbar">
71
+ <button class="x-editor__btn primary" @click="handleJsonApply">应用 JSON</button>
72
+ <button class="x-editor__btn" @click="formatJsonText">格式化</button>
73
+ <button class="x-editor__btn" @click="resetJsonText">重置</button>
74
+ <span v-if="jsonError" class="x-editor__json-error">{{ jsonError }}</span>
75
+ </div>
76
+ <JsonCodeEditor ref="jsonCodeEditorRef" v-model="jsonText" class="x-editor__json-editor" @update:modelValue="jsonError = ''" />
77
+ </template>
78
+ <JsonCodeEditor v-else :model-value="readonlyFormJsonText" readonly class="x-editor__json-editor" />
79
+ </div>
80
+ </div>
81
+ </div>
82
+ </ElScrollbar>
83
+ </div>
84
+
85
+ <!-- 右侧配置区:仅在设计模式下显示 -->
86
+ <div v-if="activeMode === 'design'" class="x-editor__panel x-editor__panel--right">
87
+ <div class="x-editor__panel-title x-editor__panel-title--config">
88
+ <button class="x-editor__mode-switch" :title="rightPanelModeSwitchTitle" type="button" @click="toggleRightPanelMode">
89
+ <i :class="rightPanelModeIcon"></i>
90
+ </button>
91
+ <div class="x-editor__panel-title-main">
92
+ <span>{{ rightPanelMode === 'ui' ? '属性配置' : 'JSON 配置' }}</span>
93
+ <button v-if="canReplaceSelected && currentConfigTargetLabel" class="x-editor__target-action" type="button" title="替换组件" @click="openReplaceDialog">
94
+ <i class="ri-arrow-left-right-line"></i>
95
+ {{ currentConfigTargetLabel }}
96
+ </button>
97
+ <small v-else-if="currentConfigTargetLabel">{{ currentConfigTargetLabel }}</small>
98
+ </div>
99
+ </div>
100
+ <div v-if="selectedItem && rightPanelMode === 'ui' && currentConfigTabs.length > 1" class="x-editor__config-tabs">
101
+ <button
102
+ v-for="tab in currentConfigTabs"
103
+ :key="tab.key"
104
+ class="x-editor__config-tab"
105
+ :class="{ active: activeConfigTabKey === tab.key }"
106
+ type="button"
107
+ @click="activeConfigTabKey = tab.key"
108
+ >
109
+ {{ tab.label }}
110
+ </button>
111
+ </div>
112
+ <ElScrollbar class="x-editor__panel-scrollbar">
113
+ <div class="x-editor__config-panel" v-if="selectedItem">
114
+ <x-form
115
+ v-if="rightPanelMode === 'ui'"
116
+ :key="selectedItem.__editorId"
117
+ v-model="selectedItem"
118
+ v-bind="currentConfigSchema"
119
+ value-reactive
120
+ label-position="left"
121
+ auto-submit
122
+ :show-button-group="false"
123
+ @update:modelValue="handleConfigChange"
124
+ class="x-editor__config-form"
125
+ />
126
+ <div v-else class="x-editor__config-json">
127
+ <JsonCodeEditor :model-value="readonlySelectedJsonText" readonly line-numbers="off" class="x-editor__config-json-editor" />
128
+ </div>
129
+ </div>
130
+ <div class="x-editor__config-empty" v-else>请选择画布中的组件</div>
131
+ </ElScrollbar>
132
+ </div>
133
+ </div>
134
+ <ElDialog v-model="replaceDialogVisible" title="替换组件" width="520px" append-to-body>
135
+ <div class="x-editor__replace-grid">
136
+ <button v-for="item in replacementTargets" :key="item.value" class="x-editor__replace-item" type="button" @click="handleReplaceComponent(item)">
137
+ <i :class="[item.icon, 'x-editor__replace-icon']"></i>
138
+ <span>{{ item.label }}</span>
139
+ </button>
140
+ </div>
141
+ </ElDialog>
142
+ <ConditionEditor
143
+ :model-value="selectedItem?.visible"
144
+ state-kind="visible"
145
+ :inline-visible="false"
146
+ :auto-open-key="visibleConditionOpenKey"
147
+ @update:modelValue="handleVisibleConditionChange"
148
+ />
149
+ </div>
150
+ </template>
151
+
152
+ <script setup lang="ts">
153
+ import { ref, onMounted, onBeforeUnmount, provide, nextTick, watch, computed } from 'vue'
154
+ import { componentList, componentPaletteGroups } from './config'
155
+ import { XForm, genId, type XFormProps, X_DESIGN_MODE_KEY } from 'xkit-ui'
156
+ import { ElDialog, ElMessage, ElScrollbar } from 'element-plus'
157
+ import Sortable from 'sortablejs'
158
+ import EditorItemWrapper from './editor-item-wrapper.vue'
159
+ import { rootComponentConfigMap } from './root-configs'
160
+ import type { ComponentConfig, EditorConfigTab, EditorConfigTabKey } from './component-configs/types'
161
+ import JsonCodeEditor from './components/json-code-editor.vue'
162
+ import ConditionEditor from './components/condition-editor.vue'
163
+ import InputTableDesign from './components/design-renderers/input-table-design.vue'
164
+ import InputArrayDesign from './components/design-renderers/input-array-design.vue'
165
+ import { createReplacementNode, isReplaceableComponentConfig } from './utils/component-replace'
166
+ import {
167
+ EDITOR_ID_FIELD,
168
+ assignNewEditorIdsDeep,
169
+ cloneSchemaValue,
170
+ type EditorPath,
171
+ findByEditorId,
172
+ getEditorId,
173
+ getByEditorPath,
174
+ insertAtEditorPath,
175
+ insertAfterEditorId,
176
+ moveAcrossEditorPaths,
177
+ moveWithinEditorPath,
178
+ normalizeEditorIds,
179
+ preserveUneditedChildCollections,
180
+ removeByEditorId,
181
+ stripEditorMetaDeep,
182
+ stripRuntimeMetaDeep,
183
+ updateByEditorId
184
+ } from './utils/editor-schema'
185
+
186
+ defineOptions({
187
+ name: 'XEditor'
188
+ })
189
+
190
+ const props = withDefaults(
191
+ defineProps<{
192
+ modelValue: XFormProps
193
+ editableJson?: boolean
194
+ }>(),
195
+ {
196
+ editableJson: false
197
+ }
198
+ )
199
+
200
+ const emit = defineEmits<{
201
+ (e: 'update:modelValue', value: any): void
202
+ (e: 'submit', value: any): void
203
+ (e: 'reset'): void
204
+ }>()
205
+
206
+ // 编辑模式:design / preview / json
207
+ const activeMode = ref<'design' | 'preview' | 'json'>('design')
208
+ const rightPanelMode = ref<'ui' | 'json'>('ui')
209
+ const activeConfigTabKey = ref<EditorConfigTabKey>('basic')
210
+
211
+ const componentGridRef = ref<HTMLElement>()
212
+ const canvasRef = ref<HTMLElement>()
213
+ const jsonCodeEditorRef = ref<InstanceType<typeof JsonCodeEditor>>()
214
+ const jsonText = ref('')
215
+ const jsonError = ref('')
216
+ const replaceDialogVisible = ref(false)
217
+ const visibleConditionOpenKey = ref(0)
218
+
219
+ // 选中的组件
220
+ const selectedId = ref<string | number>()
221
+ const selectedItem = ref<any>()
222
+ provide('selectedId', selectedId)
223
+ provide(
224
+ X_DESIGN_MODE_KEY,
225
+ computed(() => activeMode.value === 'design')
226
+ )
227
+ provide(
228
+ 'x-editor-context',
229
+ computed(() => ({
230
+ form: props.modelValue,
231
+ selectedItem: selectedItem.value
232
+ }))
233
+ )
234
+ provide('editorDesignRenderers', {
235
+ 'x-input-table': InputTableDesign,
236
+ 'x-input-array': InputArrayDesign
237
+ })
238
+
239
+ const ROOT_NODE_ID = '__root__'
240
+
241
+ const rootType = computed(() => 'x-form')
242
+ const rootNode = computed(() => ({
243
+ ...props.modelValue,
244
+ [EDITOR_ID_FIELD]: ROOT_NODE_ID,
245
+ type: rootType.value
246
+ }))
247
+
248
+ const createEditorId = () => genId('editor')
249
+
250
+ // 获取当前选中组件对应的属性配置 Schema
251
+ const configTabLabels: Record<EditorConfigTabKey, string> = {
252
+ basic: '基础',
253
+ layout: '布局',
254
+ data: '数据',
255
+ operation: '操作',
256
+ validation: '校验',
257
+ advanced: '高级'
258
+ }
259
+
260
+ const configTabOrder: EditorConfigTabKey[] = ['basic', 'layout', 'data', 'operation', 'validation', 'advanced']
261
+
262
+ const normalizeConfigTabs = (tabs: EditorConfigTab[] | undefined, fallbackBody: any[] = []) => {
263
+ const sourceTabs: EditorConfigTab[] = tabs?.length
264
+ ? tabs
265
+ : [
266
+ {
267
+ key: 'basic',
268
+ body: fallbackBody
269
+ }
270
+ ]
271
+ return sourceTabs
272
+ .filter((tab) => tab.body?.length)
273
+ .map((tab) => ({
274
+ ...tab,
275
+ label: tab.label || configTabLabels[tab.key]
276
+ }))
277
+ .sort((left, right) => configTabOrder.indexOf(left.key) - configTabOrder.indexOf(right.key))
278
+ }
279
+
280
+ const currentConfig = computed(() => {
281
+ if (!selectedItem.value) return undefined
282
+ if (selectedId.value === ROOT_NODE_ID) {
283
+ return rootComponentConfigMap[rootType.value]
284
+ }
285
+ return componentList.find((c) => c.value === selectedItem.value.type) as ComponentConfig | undefined
286
+ })
287
+
288
+ const currentConfigTabs = computed(() => {
289
+ const config = currentConfig.value
290
+ const tabs = normalizeConfigTabs(config?.configTabs, config?.configSchema?.body || [])
291
+ if (!isSelectedInputTableColumn.value) return tabs
292
+ return tabs.map((tab) => (tab.key === 'layout' ? { ...tab, label: '列' } : tab))
293
+ })
294
+
295
+ const currentConfigSchema = computed(() => {
296
+ const tab = currentConfigTabs.value.find((item) => item.key === activeConfigTabKey.value) || currentConfigTabs.value[0]
297
+ let body = tab?.body || []
298
+ if (selectedItem.value?.type === 'x-input-array' && tab?.key === 'layout' && !selectedItem.value.useLayout) {
299
+ body = body.filter((item: any) => item.name !== 'layout')
300
+ }
301
+ if (!isSelectedInputTableColumn.value || tab?.key !== 'basic') {
302
+ return { body }
303
+ }
304
+ return {
305
+ body: body.filter((item: any) => item.name !== 'labelPosition')
306
+ }
307
+ })
308
+
309
+ const collectConfigFieldNames = (items: any[] = []) => {
310
+ const names = new Set<string>()
311
+ const visit = (itemList: any[] = []) => {
312
+ itemList.forEach((item) => {
313
+ if (item?.name) names.add(String(item.name))
314
+ if (Array.isArray(item?.body)) visit(item.body)
315
+ if (Array.isArray(item?.sync)) {
316
+ item.sync.forEach((syncItem: any) => {
317
+ if (syncItem?.name) names.add(String(syncItem.name))
318
+ })
319
+ }
320
+ })
321
+ }
322
+ visit(items)
323
+ return names
324
+ }
325
+
326
+ const currentConfigTargetLabel = computed(() => {
327
+ if (!selectedItem.value) return ''
328
+ if (selectedId.value === ROOT_NODE_ID) return '表单'
329
+ return currentConfig.value?.label || selectedItem.value.type || ''
330
+ })
331
+
332
+ const canReplaceSelected = computed(() => {
333
+ if (!selectedItem.value || selectedId.value === ROOT_NODE_ID) return false
334
+ const config = currentConfig.value as ComponentConfig | undefined
335
+ if (config?.editorKind === 'container') {
336
+ return Boolean(config.replace?.groups?.includes('collection'))
337
+ }
338
+ return isReplaceableComponentConfig(config)
339
+ })
340
+
341
+ const canReplaceWithTarget = (sourceConfig: ComponentConfig | undefined, targetConfig: ComponentConfig) => {
342
+ if (!sourceConfig || targetConfig.value === selectedItem.value?.type) return false
343
+ const sourceIsContainer = sourceConfig.editorKind === 'container'
344
+ const targetIsContainer = targetConfig.editorKind === 'container'
345
+ if (sourceIsContainer || targetIsContainer) {
346
+ return Boolean(sourceIsContainer && targetIsContainer && sourceConfig.replace?.groups?.includes('collection') && targetConfig.replace?.groups?.includes('collection'))
347
+ }
348
+ return isReplaceableComponentConfig(targetConfig)
349
+ }
350
+
351
+ const replacementTargets = computed(() => {
352
+ if (!canReplaceSelected.value) return []
353
+ return componentList.filter((component) => canReplaceWithTarget(currentConfig.value as ComponentConfig | undefined, component))
354
+ })
355
+
356
+ const toJsonText = (value: any) => JSON.stringify(value ?? {}, null, 2)
357
+
358
+ const readonlyFormJsonText = computed(() => toJsonText(props.modelValue))
359
+
360
+ const readonlySelectedJsonText = computed(() => toJsonText(selectedItem.value))
361
+
362
+ const findParentByEditorId = (items: any[] = [], editorId: unknown, parent?: any): any | undefined => {
363
+ if (editorId === undefined || editorId === null) return undefined
364
+
365
+ for (const item of items) {
366
+ if (getEditorId(item) === editorId) return parent
367
+
368
+ for (const childKey of ['body', 'items']) {
369
+ if (!Array.isArray(item?.[childKey])) continue
370
+ const result = findParentByEditorId(item[childKey], editorId, item)
371
+ if (result) return result
372
+ }
373
+ }
374
+ }
375
+
376
+ const isSelectedInputTableColumn = computed(() => {
377
+ const parent = findParentByEditorId(props.modelValue?.body || [], selectedId.value)
378
+ return parent?.type === 'x-input-table'
379
+ })
380
+
381
+ const rightPanelModeIcon = computed(() => (rightPanelMode.value === 'ui' ? 'ri-code-s-slash-line' : 'ri-settings-3-line'))
382
+ const rightPanelModeSwitchTitle = computed(() => (rightPanelMode.value === 'ui' ? '切换到 JSON' : '切换到可视化配置'))
383
+
384
+ const toggleRightPanelMode = () => {
385
+ rightPanelMode.value = rightPanelMode.value === 'ui' ? 'json' : 'ui'
386
+ }
387
+
388
+ const openReplaceDialog = () => {
389
+ if (!canReplaceSelected.value) return
390
+ replaceDialogVisible.value = true
391
+ }
392
+
393
+ const handleReplaceComponent = (targetConfig: ComponentConfig) => {
394
+ if (!selectedItem.value || !currentConfig.value || !canReplaceSelected.value) return
395
+
396
+ const replacement = createReplacementNode({
397
+ source: selectedItem.value,
398
+ sourceConfig: currentConfig.value as ComponentConfig,
399
+ targetConfig
400
+ })
401
+ const updatedBody = updateByEditorId(props.modelValue?.body || [], selectedId.value, replacement)
402
+ if (!updatedBody.changed) return
403
+
404
+ selectedItem.value = replacement
405
+ activeConfigTabKey.value = 'basic'
406
+ replaceDialogVisible.value = false
407
+ updateBody(updatedBody.items)
408
+ ElMessage.success(`已替换为${targetConfig.label}`)
409
+ }
410
+
411
+ watch(selectedId, () => {
412
+ activeConfigTabKey.value = 'basic'
413
+ })
414
+
415
+ watch(
416
+ currentConfigTabs,
417
+ (tabs) => {
418
+ if (!tabs.length) {
419
+ activeConfigTabKey.value = 'basic'
420
+ return
421
+ }
422
+ if (!tabs.some((tab) => tab.key === activeConfigTabKey.value)) {
423
+ activeConfigTabKey.value = tabs[0].key
424
+ }
425
+ },
426
+ { immediate: true }
427
+ )
428
+
429
+ const stripEditorMeta = (value: any) => {
430
+ if (!value) return value
431
+ const { [EDITOR_ID_FIELD]: _editorId, type, ...rest } = value
432
+ return rest
433
+ }
434
+
435
+ // 处理属性配置变化
436
+ const handleConfigChange = (newValues: any) => {
437
+ if (selectedId.value === ROOT_NODE_ID) {
438
+ emit('update:modelValue', {
439
+ ...props.modelValue,
440
+ ...stripEditorMeta(newValues)
441
+ })
442
+ return
443
+ }
444
+
445
+ const previousNode = findByEditorId(props.modelValue?.body || [], selectedId.value)
446
+ const editedKeys = collectConfigFieldNames(currentConfigSchema.value.body)
447
+ const nextNode = preserveUneditedChildCollections(previousNode, stripRuntimeMetaDeep(newValues), editedKeys)
448
+ const updatedBody = updateByEditorId(props.modelValue?.body || [], selectedId.value, nextNode)
449
+ if (updatedBody.changed) {
450
+ const nextId = getEditorId(newValues)
451
+ if (nextId !== selectedId.value) selectedId.value = nextId
452
+ updateBody(updatedBody.items)
453
+ }
454
+ }
455
+
456
+ const handleVisibleConditionChange = (value: any) => {
457
+ if (!selectedItem.value || selectedId.value === ROOT_NODE_ID) return
458
+ const nextItem = {
459
+ ...selectedItem.value,
460
+ visible: value
461
+ }
462
+ selectedItem.value = nextItem
463
+ handleConfigChange(nextItem)
464
+ }
465
+
466
+ // 处理编辑器内部事件 (选中/复制/删除)
467
+ const handleEditorEvent = (event: any) => {
468
+ const { name, payload } = event
469
+ if (name === 'select') {
470
+ const nextId = getEditorId(payload)
471
+ if (selectedId.value === nextId) return
472
+ selectedId.value = nextId
473
+ // 必须深拷贝,断开引用
474
+ selectedItem.value = stripRuntimeMetaDeep(cloneSchemaValue(payload))
475
+ } else if (name === 'delete') {
476
+ const payloadId = getEditorId(payload)
477
+ const updatedBody = removeByEditorId(props.modelValue?.body || [], payloadId)
478
+ if (updatedBody.changed) {
479
+ if (selectedId.value === payloadId) {
480
+ selectedId.value = undefined
481
+ selectedItem.value = undefined
482
+ }
483
+ updateBody(updatedBody.items)
484
+ }
485
+ } else if (name === 'copy') {
486
+ const payloadId = getEditorId(payload)
487
+ if (payloadId !== undefined) {
488
+ const newField = assignNewEditorIdsDeep(payload, createEditorId)
489
+ // 复制时通常也要改一下 name,防止业务字段冲突
490
+ if (newField.name) newField.name = `${newField.name}_copy`
491
+
492
+ const updatedBody = insertAfterEditorId(props.modelValue?.body || [], payloadId, newField)
493
+ if (updatedBody.changed) updateBody(updatedBody.items)
494
+ }
495
+ } else if (name === 'edit-visible-condition') {
496
+ if (getEditorId(payload) !== selectedId.value) {
497
+ selectedId.value = getEditorId(payload)
498
+ selectedItem.value = stripRuntimeMetaDeep(cloneSchemaValue(payload))
499
+ }
500
+ rightPanelMode.value = 'ui'
501
+ visibleConditionOpenKey.value += 1
502
+ nextTick(() => {
503
+ activeConfigTabKey.value = 'advanced'
504
+ })
505
+ }
506
+ }
507
+
508
+ const updateBody = (newBody: any[]) => {
509
+ emit('update:modelValue', {
510
+ ...props.modelValue,
511
+ body: newBody
512
+ })
513
+ }
514
+
515
+ const handleSubmit = () => {
516
+ emit('submit', stripEditorMetaDeep(props.modelValue))
517
+ }
518
+
519
+ const handleReset = () => {
520
+ emit('reset')
521
+ }
522
+
523
+ const resetJsonText = () => {
524
+ jsonText.value = JSON.stringify(props.modelValue ?? {}, null, 2)
525
+ jsonError.value = ''
526
+ }
527
+
528
+ const handleJsonApply = () => {
529
+ try {
530
+ const parsed = JSON.parse(jsonText.value)
531
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
532
+ jsonError.value = 'JSON 根节点必须是对象'
533
+ return
534
+ }
535
+ emit('update:modelValue', parsed)
536
+ jsonText.value = JSON.stringify(parsed, null, 2)
537
+ jsonError.value = ''
538
+ } catch (error) {
539
+ jsonError.value = error instanceof Error ? error.message : 'JSON 格式错误'
540
+ }
541
+ }
542
+
543
+ const formatJsonText = async () => {
544
+ try {
545
+ jsonText.value = JSON.stringify(JSON.parse(jsonText.value), null, 2)
546
+ jsonError.value = ''
547
+ await nextTick()
548
+ await jsonCodeEditorRef.value?.formatDocument()
549
+ } catch (error) {
550
+ jsonError.value = error instanceof Error ? error.message : 'JSON 格式错误'
551
+ }
552
+ }
553
+
554
+ const componentSortableInstances = ref<Sortable[]>([])
555
+ const canvasSortableInstances = ref<Sortable[]>([])
556
+
557
+ const parseEditorPath = (value: string | null): EditorPath => {
558
+ if (!value) return []
559
+ try {
560
+ const parsed = JSON.parse(value)
561
+ return Array.isArray(parsed) ? parsed : []
562
+ } catch {
563
+ return []
564
+ }
565
+ }
566
+
567
+ const createFieldFromComponentType = (type: string | null) => {
568
+ if (!type) return undefined
569
+ const component = getComponentConfig(type)
570
+ if (!component) return undefined
571
+
572
+ const newField = cloneSchemaValue(component.scaffold)
573
+ newField[EDITOR_ID_FIELD] = createEditorId()
574
+ return newField
575
+ }
576
+
577
+ const getComponentConfig = (type: unknown) => componentList.find((component) => component.value === type)
578
+
579
+ const isLeafEditorNode = (node: any) => {
580
+ return getComponentConfig(node?.type)?.editorKind !== 'container'
581
+ }
582
+
583
+ const isInputTableItemsPath = (path: EditorPath) => {
584
+ if (path[path.length - 1] !== 'items') return false
585
+ const owner = getByEditorPath(props.modelValue?.body || [], path.slice(0, -1))
586
+ return owner?.type === 'x-input-table'
587
+ }
588
+
589
+ const canDropNodeAtPath = (node: any, path: EditorPath) => {
590
+ if (!isInputTableItemsPath(path)) return true
591
+ return isLeafEditorNode(node)
592
+ }
593
+
594
+ const showUnsupportedTableColumnDrop = () => {
595
+ ElMessage.warning('表格输入器暂不支持容器组件,请选择普通组件。')
596
+ }
597
+
598
+ const restoreDraggedDom = (evt: Sortable.SortableEvent) => {
599
+ const oldIndex = evt.oldIndex ?? 0
600
+ const reference = evt.from.children[oldIndex] ?? null
601
+ evt.from.insertBefore(evt.item, reference)
602
+ }
603
+
604
+ const destroySortables = () => {
605
+ componentSortableInstances.value.forEach((instance) => instance.destroy())
606
+ componentSortableInstances.value = []
607
+ canvasSortableInstances.value.forEach((instance) => instance.destroy())
608
+ canvasSortableInstances.value = []
609
+ }
610
+
611
+ const initSortable = () => {
612
+ componentSortableInstances.value.forEach((instance) => instance.destroy())
613
+ componentSortableInstances.value = []
614
+ if (componentGridRef.value) {
615
+ const componentGrids = Array.from(componentGridRef.value.querySelectorAll<HTMLElement>('.x-editor__component-grid'))
616
+ componentSortableInstances.value = componentGrids.map((grid) =>
617
+ Sortable.create(grid, {
618
+ group: {
619
+ name: 'components',
620
+ pull: 'clone',
621
+ put: false
622
+ },
623
+ sort: false,
624
+ draggable: '.x-editor__component-item'
625
+ })
626
+ )
627
+ }
628
+
629
+ canvasSortableInstances.value.forEach((instance) => instance.destroy())
630
+ canvasSortableInstances.value = []
631
+
632
+ const containers = Array.from(canvasRef.value?.querySelectorAll<HTMLElement>('[data-editor-drop-path]') || [])
633
+ canvasSortableInstances.value = containers.map((container) => {
634
+ return Sortable.create(container, {
635
+ group: 'components',
636
+ draggable: '[data-editor-item-path], .x-editor__component-item',
637
+ animation: 150,
638
+ ghostClass: 'x-editor__ghost',
639
+ handle: '.editor-item-drag',
640
+ onAdd: (evt) => {
641
+ const newField = createFieldFromComponentType(evt.item.getAttribute('data-type'))
642
+ if (newField) {
643
+ const toContainerPath = parseEditorPath(evt.to.getAttribute('data-editor-drop-path'))
644
+ if (!canDropNodeAtPath(newField, toContainerPath)) {
645
+ showUnsupportedTableColumnDrop()
646
+ if (evt.item.parentNode) {
647
+ evt.item.parentNode.removeChild(evt.item)
648
+ }
649
+ return
650
+ }
651
+ const updatedBody = insertAtEditorPath(props.modelValue?.body || [], toContainerPath, evt.newIndex ?? 0, newField)
652
+ if (updatedBody.changed) updateBody(updatedBody.items)
653
+
654
+ // 立即移除拖入的原始 DOM,由 Vue 接管渲染
655
+ if (evt.item.parentNode) {
656
+ evt.item.parentNode.removeChild(evt.item)
657
+ }
658
+ }
659
+ },
660
+ onEnd: (evt) => {
661
+ if (evt.item.classList.contains('x-editor__component-item')) return
662
+ const fromContainerPath = parseEditorPath(evt.from.getAttribute('data-editor-drop-path'))
663
+ const toContainerPath = parseEditorPath(evt.to.getAttribute('data-editor-drop-path'))
664
+ if (evt.from === evt.to && evt.oldIndex !== evt.newIndex) {
665
+ const updatedBody = moveWithinEditorPath(props.modelValue?.body || [], fromContainerPath, evt.oldIndex!, evt.newIndex!)
666
+ if (updatedBody.changed) updateBody(updatedBody.items)
667
+ } else if (evt.from !== evt.to) {
668
+ const movingItem = getByEditorPath(props.modelValue?.body || [], [...fromContainerPath, evt.oldIndex ?? 0])
669
+ if (!canDropNodeAtPath(movingItem, toContainerPath)) {
670
+ showUnsupportedTableColumnDrop()
671
+ restoreDraggedDom(evt)
672
+ return
673
+ }
674
+ const updatedBody = moveAcrossEditorPaths(props.modelValue?.body || [], fromContainerPath, evt.oldIndex ?? 0, toContainerPath, evt.newIndex ?? 0)
675
+ if (updatedBody.changed) updateBody(updatedBody.items)
676
+ }
677
+ }
678
+ })
679
+ })
680
+ }
681
+
682
+ onMounted(() => {
683
+ initSortable()
684
+ })
685
+
686
+ onBeforeUnmount(() => {
687
+ destroySortables()
688
+ })
689
+
690
+ watch(
691
+ () => props.modelValue.body,
692
+ (body) => {
693
+ const normalized = normalizeEditorIds(body || [], createEditorId)
694
+ if (normalized.changed) {
695
+ updateBody(normalized.items)
696
+ }
697
+ },
698
+ { immediate: true, deep: true }
699
+ )
700
+
701
+ // 监听 body 变化,重新初始化 Sortable (因为 XForm 重新渲染可能导致 DOM 变化)
702
+ watch(
703
+ () => props.modelValue.body,
704
+ () => {
705
+ nextTick(() => {
706
+ initSortable()
707
+ })
708
+ },
709
+ { deep: true }
710
+ )
711
+
712
+ // 监听模式切换,回到设计模式时重新初始化 Sortable
713
+ watch(activeMode, (mode) => {
714
+ if (mode === 'design') {
715
+ nextTick(() => {
716
+ initSortable()
717
+ })
718
+ } else if (mode === 'json') {
719
+ resetJsonText()
720
+ }
721
+ })
722
+
723
+ watch(
724
+ () => props.modelValue,
725
+ () => {
726
+ if (activeMode.value === 'json' && props.editableJson && !jsonError.value) {
727
+ resetJsonText()
728
+ }
729
+ },
730
+ { deep: true }
731
+ )
732
+ </script>
733
+
734
+ <style scoped lang="scss">
735
+ .x-editor {
736
+ display: flex;
737
+ flex-direction: column;
738
+ height: 100%;
739
+ min-height: 0;
740
+ overflow: hidden;
741
+ background: #f5f7fa;
742
+ border: 1px solid #dcdfe6;
743
+ color: #303133;
744
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
745
+ }
746
+
747
+ /* Header Styles */
748
+ .x-editor__header {
749
+ height: 48px;
750
+ flex: 0 0 48px;
751
+ display: flex;
752
+ align-items: center;
753
+ justify-content: space-between;
754
+ padding: 0 16px;
755
+ background: #fff;
756
+ border-bottom: 1px solid #dcdfe6;
757
+ z-index: 10;
758
+ }
759
+
760
+ .x-editor__title {
761
+ font-size: 16px;
762
+ font-weight: 600;
763
+ color: #1f2f3d;
764
+ }
765
+
766
+ .x-editor__modes {
767
+ display: flex;
768
+ background: #f0f2f5;
769
+ padding: 2px;
770
+ border-radius: 4px;
771
+ }
772
+
773
+ .x-editor__mode {
774
+ padding: 4px 16px;
775
+ font-size: 13px;
776
+ cursor: pointer;
777
+ border-radius: 3px;
778
+ transition: all 0.2s;
779
+ color: #606266;
780
+ }
781
+
782
+ .x-editor__mode.active {
783
+ background: #fff;
784
+ color: #409eff;
785
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
786
+ }
787
+
788
+ .x-editor__btn {
789
+ padding: 6px 16px;
790
+ font-size: 13px;
791
+ border: 1px solid #dcdfe6;
792
+ background: #fff;
793
+ border-radius: 4px;
794
+ cursor: pointer;
795
+ margin-left: 8px;
796
+ transition: all 0.2s;
797
+ }
798
+
799
+ .x-editor__btn:hover {
800
+ color: #409eff;
801
+ border-color: #c6e2ff;
802
+ background-color: #ecf5ff;
803
+ }
804
+
805
+ .x-editor__btn.primary {
806
+ background: #409eff;
807
+ border-color: #409eff;
808
+ color: #fff;
809
+ }
810
+
811
+ .x-editor__btn.primary:hover {
812
+ background: #66b1ff;
813
+ border-color: #66b1ff;
814
+ }
815
+
816
+ /* Body Styles */
817
+ .x-editor__body {
818
+ flex: 1;
819
+ min-height: 0;
820
+ display: grid;
821
+ grid-template-columns: 260px 1fr 300px;
822
+ overflow: hidden;
823
+ transition: all 0.3s ease;
824
+ }
825
+
826
+ .x-editor__body.is-mode-preview,
827
+ .x-editor__body.is-mode-json {
828
+ grid-template-columns: 1fr;
829
+ }
830
+
831
+ .x-editor__panel {
832
+ display: flex;
833
+ flex-direction: column;
834
+ background: #fff;
835
+ min-width: 0;
836
+ min-height: 0;
837
+ /* 防止内容撑开 grid */
838
+ overflow: hidden;
839
+ }
840
+
841
+ .x-editor__panel--center {
842
+ background: #f5f7fa;
843
+ display: flex;
844
+ flex-direction: column;
845
+ }
846
+
847
+ .x-editor__panel--left {
848
+ border-right: 1px solid #dcdfe6;
849
+ }
850
+
851
+ .x-editor__panel--right {
852
+ border-left: 1px solid #dcdfe6;
853
+ }
854
+
855
+ .x-editor__panel-title {
856
+ height: 40px;
857
+ flex: 0 0 40px;
858
+ line-height: 40px;
859
+ padding: 0 16px;
860
+ font-size: 14px;
861
+ font-weight: 500;
862
+ border-bottom: 1px solid #f0f2f5;
863
+ color: #1f2f3d;
864
+ }
865
+
866
+ .x-editor__panel-title--config {
867
+ display: flex;
868
+ align-items: center;
869
+ gap: 8px;
870
+ }
871
+
872
+ .x-editor__panel-title-main {
873
+ min-width: 0;
874
+ display: flex;
875
+ flex: 1;
876
+ align-items: baseline;
877
+ justify-content: space-between;
878
+ gap: 8px;
879
+ }
880
+
881
+ .x-editor__panel-title-main span {
882
+ min-width: 0;
883
+ overflow: hidden;
884
+ text-overflow: ellipsis;
885
+ white-space: nowrap;
886
+ }
887
+
888
+ .x-editor__panel-title-main small {
889
+ min-width: 0;
890
+ overflow: hidden;
891
+ color: #909399;
892
+ font-size: 12px;
893
+ font-weight: 400;
894
+ text-overflow: ellipsis;
895
+ white-space: nowrap;
896
+ }
897
+
898
+ .x-editor__target-action {
899
+ min-width: 0;
900
+ max-width: 120px;
901
+ display: inline-flex;
902
+ align-items: center;
903
+ gap: 3px;
904
+ padding: 2px 6px;
905
+ overflow: hidden;
906
+ color: #409eff;
907
+ font-size: 12px;
908
+ font-weight: 400;
909
+ line-height: 18px;
910
+ text-overflow: ellipsis;
911
+ white-space: nowrap;
912
+ background: #ecf5ff;
913
+ border: 1px solid #c6e2ff;
914
+ border-radius: 4px;
915
+ cursor: pointer;
916
+ transition: all 0.2s;
917
+ }
918
+
919
+ .x-editor__target-action i {
920
+ flex: 0 0 auto;
921
+ font-size: 13px;
922
+ }
923
+
924
+ .x-editor__target-action:hover {
925
+ color: #fff;
926
+ background: #409eff;
927
+ border-color: #409eff;
928
+ }
929
+
930
+ .x-editor__mode-switch {
931
+ width: 26px;
932
+ height: 26px;
933
+ flex: 0 0 26px;
934
+ display: flex;
935
+ align-items: center;
936
+ justify-content: center;
937
+ padding: 0;
938
+ color: #606266;
939
+ background: #f5f7fa;
940
+ border: 1px solid transparent;
941
+ border-radius: 4px;
942
+ cursor: pointer;
943
+ transition: all 0.2s;
944
+ }
945
+
946
+ .x-editor__mode-switch:hover {
947
+ color: #409eff;
948
+ background: #ecf5ff;
949
+ border-color: #c6e2ff;
950
+ }
951
+
952
+ .x-editor__mode-switch i {
953
+ font-size: 15px;
954
+ }
955
+
956
+ .x-editor__config-tabs {
957
+ flex: 0 0 auto;
958
+ display: flex;
959
+ gap: 4px;
960
+ padding: 8px 10px;
961
+ background: #fff;
962
+ border-bottom: 1px solid #f0f2f5;
963
+ }
964
+
965
+ .x-editor__config-tab {
966
+ min-width: 0;
967
+ flex: 1;
968
+ padding: 5px 4px;
969
+ line-height: 18px;
970
+ font-size: 12px;
971
+ text-align: center;
972
+ border: 1px solid transparent;
973
+ border-radius: 4px;
974
+ cursor: pointer;
975
+ color: #606266;
976
+ background: #f5f7fa;
977
+ transition: all 0.2s;
978
+ }
979
+
980
+ .x-editor__config-tab:hover,
981
+ .x-editor__config-tab.active {
982
+ color: #409eff;
983
+ background: #ecf5ff;
984
+ border-color: #c6e2ff;
985
+ }
986
+
987
+ .x-editor__panel-scrollbar {
988
+ flex: 1;
989
+ min-height: 0;
990
+ }
991
+
992
+ .x-editor__panel-scrollbar :deep(.el-scrollbar__view) {
993
+ min-height: 100%;
994
+ }
995
+
996
+ .x-editor__panel--right .x-editor__panel-scrollbar :deep(.el-scrollbar__view) {
997
+ height: 100%;
998
+ display: flex;
999
+ flex-direction: column;
1000
+ }
1001
+
1002
+ .x-editor__panel-scrollbar--center :deep(.el-scrollbar__view) {
1003
+ min-height: 100%;
1004
+ display: flex;
1005
+ flex-direction: column;
1006
+ }
1007
+
1008
+ .x-editor__center-content {
1009
+ flex: 1;
1010
+ min-height: 100%;
1011
+ padding: 16px;
1012
+ display: flex;
1013
+ flex-direction: column;
1014
+ }
1015
+
1016
+ .x-editor__body.is-mode-preview .x-editor__center-content,
1017
+ .x-editor__body.is-mode-json .x-editor__center-content {
1018
+ padding: 0;
1019
+ }
1020
+
1021
+ /* Component Palette (Left Panel) */
1022
+ .x-editor__component-palette {
1023
+ padding: 12px;
1024
+ }
1025
+
1026
+ .x-editor__component-section + .x-editor__component-section {
1027
+ margin-top: 16px;
1028
+ }
1029
+
1030
+ .x-editor__component-section-title {
1031
+ display: flex;
1032
+ align-items: center;
1033
+ height: 20px;
1034
+ margin-bottom: 8px;
1035
+ color: #909399;
1036
+ font-size: 12px;
1037
+ font-weight: 600;
1038
+ }
1039
+
1040
+ .x-editor__component-grid {
1041
+ display: grid;
1042
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1043
+ gap: 10px;
1044
+ }
1045
+
1046
+ .x-editor__component-item {
1047
+ display: flex;
1048
+ flex-direction: column;
1049
+ align-items: center;
1050
+ justify-content: center;
1051
+ padding: 12px 8px;
1052
+ background: #f9fafb;
1053
+ border: 1px solid #f0f2f5;
1054
+ border-radius: 4px;
1055
+ cursor: move;
1056
+ transition: all 0.2s;
1057
+ }
1058
+
1059
+ .x-editor__component-item:hover {
1060
+ border-color: #409eff;
1061
+ color: #409eff;
1062
+ background: #ecf5ff;
1063
+ }
1064
+
1065
+ .x-editor__component-icon {
1066
+ font-size: 20px;
1067
+ margin-bottom: 6px;
1068
+ }
1069
+
1070
+ .x-editor__component-label {
1071
+ font-size: 12px;
1072
+ }
1073
+
1074
+ /* Canvas area */
1075
+ .x-editor__canvas {
1076
+ position: relative;
1077
+ flex: 1;
1078
+ min-height: 100%;
1079
+ background: #fff;
1080
+ border-radius: 4px;
1081
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
1082
+ display: flex;
1083
+ flex-direction: column;
1084
+ }
1085
+
1086
+ .editor-canvas-form {
1087
+ flex: 1;
1088
+ display: flex;
1089
+ flex-direction: column;
1090
+ }
1091
+
1092
+ .editor-canvas-root {
1093
+ flex: 1;
1094
+ display: flex;
1095
+ flex-direction: column;
1096
+ }
1097
+
1098
+ .editor-canvas-form :deep(.el-form) {
1099
+ flex: 1;
1100
+ display: flex;
1101
+ flex-direction: column;
1102
+ }
1103
+
1104
+ .editor-canvas-form :deep(.el-row) {
1105
+ flex: 1;
1106
+ align-content: flex-start;
1107
+ padding: 10px;
1108
+ // min-height: 500px;
1109
+ /* 确保空的时候也是一个大的拖拽目标 */
1110
+ }
1111
+
1112
+ .x-editor__canvas-empty {
1113
+ position: absolute;
1114
+ top: 50%;
1115
+ left: 50%;
1116
+ transform: translate(-50%, -50%);
1117
+ color: #909399;
1118
+ font-size: 14px;
1119
+ border: 2px dashed #dcdfe6;
1120
+ padding: 40px;
1121
+ border-radius: 4px;
1122
+ pointer-events: none;
1123
+ /* 关键:不遮挡拖拽事件 */
1124
+ z-index: 0;
1125
+ }
1126
+
1127
+ .x-editor__preview-container {
1128
+ padding: 40px;
1129
+ width: 100%;
1130
+ max-width: 1000px;
1131
+ /* 预览时居中显示,更美观 */
1132
+ margin: 0 auto;
1133
+ }
1134
+
1135
+ .x-editor__json-container {
1136
+ padding: 24px;
1137
+ width: 100%;
1138
+ flex: 1;
1139
+ min-height: 100%;
1140
+ background: #fff;
1141
+ display: flex;
1142
+ flex-direction: column;
1143
+ }
1144
+
1145
+ .x-editor__json-toolbar {
1146
+ display: flex;
1147
+ align-items: center;
1148
+ gap: 8px;
1149
+ margin-bottom: 12px;
1150
+ }
1151
+
1152
+ .x-editor__json-error {
1153
+ min-width: 0;
1154
+ color: #f56c6c;
1155
+ font-size: 13px;
1156
+ }
1157
+
1158
+ .x-editor__json-editor {
1159
+ width: 100%;
1160
+ flex: 1;
1161
+ height: auto;
1162
+ min-height: 520px;
1163
+ }
1164
+
1165
+ .x-editor__canvas-item {
1166
+ padding: 12px;
1167
+ border: 1px solid transparent;
1168
+ background: #fff;
1169
+ margin-bottom: 10px;
1170
+ border-radius: 4px;
1171
+ cursor: pointer;
1172
+ transition: all 0.2s;
1173
+ }
1174
+
1175
+ .x-editor__canvas-item:hover {
1176
+ background: #f0f7ff;
1177
+ border: 1px dashed #409eff;
1178
+ }
1179
+
1180
+ .x-editor__field-preview {
1181
+ display: flex;
1182
+ align-items: center;
1183
+ gap: 8px;
1184
+ }
1185
+
1186
+ .x-editor__field-label {
1187
+ font-weight: 500;
1188
+ font-size: 14px;
1189
+ }
1190
+
1191
+ .x-editor__field-type {
1192
+ color: #909399;
1193
+ font-size: 12px;
1194
+ }
1195
+
1196
+ .x-editor__ghost {
1197
+ opacity: 0.5;
1198
+ background: #c8ebfb;
1199
+ }
1200
+
1201
+ /* Config area */
1202
+ .x-editor__config-panel {
1203
+ flex: 1;
1204
+ display: flex;
1205
+ flex-direction: column;
1206
+ padding: 16px;
1207
+ min-height: 100%;
1208
+ }
1209
+
1210
+ .x-editor__config-json {
1211
+ flex: 1;
1212
+ min-height: 0;
1213
+ display: flex;
1214
+ background: #fff;
1215
+ }
1216
+
1217
+ .x-editor__config-json-editor {
1218
+ flex: 1;
1219
+ min-height: 0;
1220
+ }
1221
+
1222
+ .x-editor__config-panel :deep(.el-form-item) {
1223
+ margin-bottom: 16px;
1224
+ }
1225
+
1226
+ .x-editor__config-panel :deep(.config-group-title) {
1227
+ font-size: 13px;
1228
+ font-weight: 600;
1229
+ color: #303133;
1230
+ padding: 8px;
1231
+ border-radius: 4px;
1232
+ border-left: 3px solid #409eff;
1233
+ margin: 8px 0;
1234
+ line-height: 1;
1235
+ background: #eee;
1236
+ }
1237
+
1238
+ .x-editor__config-panel :deep(.el-group) {
1239
+ margin-bottom: 24px;
1240
+ background: #fcfcfc;
1241
+ border-radius: 4px;
1242
+ }
1243
+
1244
+ .x-editor__config-empty {
1245
+ min-height: 100%;
1246
+ display: flex;
1247
+ align-items: center;
1248
+ justify-content: center;
1249
+ color: #909399;
1250
+ font-size: 13px;
1251
+ }
1252
+
1253
+ .x-editor__config-form {
1254
+ :deep(.el-form-item__content) {
1255
+ justify-content: flex-end;
1256
+ }
1257
+ }
1258
+
1259
+ .x-editor__replace-grid {
1260
+ display: grid;
1261
+ grid-template-columns: repeat(3, minmax(0, 1fr));
1262
+ gap: 10px;
1263
+ }
1264
+
1265
+ .x-editor__replace-item {
1266
+ min-width: 0;
1267
+ min-height: 72px;
1268
+ display: flex;
1269
+ flex-direction: column;
1270
+ align-items: center;
1271
+ justify-content: center;
1272
+ gap: 6px;
1273
+ padding: 10px 8px;
1274
+ color: #303133;
1275
+ background: #f9fafb;
1276
+ border: 1px solid #ebeef5;
1277
+ border-radius: 4px;
1278
+ cursor: pointer;
1279
+ transition: all 0.2s;
1280
+ }
1281
+
1282
+ .x-editor__replace-item:hover {
1283
+ color: #409eff;
1284
+ background: #ecf5ff;
1285
+ border-color: #c6e2ff;
1286
+ }
1287
+
1288
+ .x-editor__replace-icon {
1289
+ font-size: 20px;
1290
+ }
1291
+
1292
+ .x-editor__replace-item span {
1293
+ max-width: 100%;
1294
+ overflow: hidden;
1295
+ font-size: 12px;
1296
+ line-height: 18px;
1297
+ text-overflow: ellipsis;
1298
+ white-space: nowrap;
1299
+ }
1300
+ </style>