@class-kit/vue 0.1.3 → 0.1.4

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 (239) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/components/affix.cjs.map +1 -1
  3. package/dist/components/affix.js.map +1 -1
  4. package/dist/components/backtop.cjs +61 -0
  5. package/dist/components/backtop.cjs.map +1 -1
  6. package/dist/components/backtop.js +61 -0
  7. package/dist/components/backtop.js.map +1 -1
  8. package/dist/components/badge.cjs.map +1 -1
  9. package/dist/components/badge.js.map +1 -1
  10. package/dist/components/barcode.cjs.map +1 -1
  11. package/dist/components/barcode.js.map +1 -1
  12. package/dist/components/breadcrumb.cjs.map +1 -1
  13. package/dist/components/breadcrumb.js.map +1 -1
  14. package/dist/components/button.cjs.map +1 -1
  15. package/dist/components/button.js.map +1 -1
  16. package/dist/components/calendar.cjs +61 -0
  17. package/dist/components/calendar.cjs.map +1 -1
  18. package/dist/components/calendar.js +61 -0
  19. package/dist/components/calendar.js.map +1 -1
  20. package/dist/components/canvas-editor.cjs.map +1 -1
  21. package/dist/components/canvas-editor.js.map +1 -1
  22. package/dist/components/canvas-image.cjs.map +1 -1
  23. package/dist/components/canvas-image.js.map +1 -1
  24. package/dist/components/chat-textarea.cjs +61 -0
  25. package/dist/components/chat-textarea.cjs.map +1 -1
  26. package/dist/components/chat-textarea.js +61 -0
  27. package/dist/components/chat-textarea.js.map +1 -1
  28. package/dist/components/chat-virtual-list.cjs.map +1 -1
  29. package/dist/components/chat-virtual-list.js.map +1 -1
  30. package/dist/components/checkbox.cjs.map +1 -1
  31. package/dist/components/checkbox.js.map +1 -1
  32. package/dist/components/checked.cjs.map +1 -1
  33. package/dist/components/checked.js.map +1 -1
  34. package/dist/components/code-preview.cjs.map +1 -1
  35. package/dist/components/code-preview.js.map +1 -1
  36. package/dist/components/color-picker.cjs.map +1 -1
  37. package/dist/components/color-picker.js.map +1 -1
  38. package/dist/components/comic-reader.cjs.map +1 -1
  39. package/dist/components/comic-reader.js.map +1 -1
  40. package/dist/components/config-provider.cjs.map +1 -1
  41. package/dist/components/config-provider.js.map +1 -1
  42. package/dist/components/config-table.cjs +61 -0
  43. package/dist/components/config-table.cjs.map +1 -1
  44. package/dist/components/config-table.js +61 -0
  45. package/dist/components/config-table.js.map +1 -1
  46. package/dist/components/countdown.cjs.map +1 -1
  47. package/dist/components/countdown.js.map +1 -1
  48. package/dist/components/danmaku.cjs.map +1 -1
  49. package/dist/components/danmaku.js.map +1 -1
  50. package/dist/components/date-picker.cjs +61 -0
  51. package/dist/components/date-picker.cjs.map +1 -1
  52. package/dist/components/date-picker.js +61 -0
  53. package/dist/components/date-picker.js.map +1 -1
  54. package/dist/components/date-range-picker.cjs +61 -0
  55. package/dist/components/date-range-picker.cjs.map +1 -1
  56. package/dist/components/date-range-picker.js +61 -0
  57. package/dist/components/date-range-picker.js.map +1 -1
  58. package/dist/components/design-effect.cjs.map +1 -1
  59. package/dist/components/design-effect.js.map +1 -1
  60. package/dist/components/drag-drop-board.cjs.map +1 -1
  61. package/dist/components/drag-drop-board.js.map +1 -1
  62. package/dist/components/draggable.cjs.map +1 -1
  63. package/dist/components/draggable.js.map +1 -1
  64. package/dist/components/ellipsis-text.cjs.map +1 -1
  65. package/dist/components/ellipsis-text.js.map +1 -1
  66. package/dist/components/empty.cjs.map +1 -1
  67. package/dist/components/empty.js.map +1 -1
  68. package/dist/components/field.cjs +61 -0
  69. package/dist/components/field.cjs.map +1 -1
  70. package/dist/components/field.js +61 -0
  71. package/dist/components/field.js.map +1 -1
  72. package/dist/components/file-preview.cjs.map +1 -1
  73. package/dist/components/file-preview.js.map +1 -1
  74. package/dist/components/floating-ball.cjs.map +1 -1
  75. package/dist/components/floating-ball.js.map +1 -1
  76. package/dist/components/form.cjs +5 -1
  77. package/dist/components/form.cjs.map +1 -1
  78. package/dist/components/form.js +5 -1
  79. package/dist/components/form.js.map +1 -1
  80. package/dist/components/gradient-text.cjs.map +1 -1
  81. package/dist/components/gradient-text.js.map +1 -1
  82. package/dist/components/height-transition.cjs.map +1 -1
  83. package/dist/components/height-transition.js.map +1 -1
  84. package/dist/components/input.cjs +61 -0
  85. package/dist/components/input.cjs.map +1 -1
  86. package/dist/components/input.js +61 -0
  87. package/dist/components/input.js.map +1 -1
  88. package/dist/components/lazy-image.cjs.map +1 -1
  89. package/dist/components/lazy-image.js.map +1 -1
  90. package/dist/components/live-room.cjs.map +1 -1
  91. package/dist/components/live-room.js.map +1 -1
  92. package/dist/components/loading.cjs.map +1 -1
  93. package/dist/components/loading.js.map +1 -1
  94. package/dist/components/marquee.cjs.map +1 -1
  95. package/dist/components/marquee.js.map +1 -1
  96. package/dist/components/masonry-virtual-list.cjs.map +1 -1
  97. package/dist/components/masonry-virtual-list.js.map +1 -1
  98. package/dist/components/menu.cjs +61 -0
  99. package/dist/components/menu.cjs.map +1 -1
  100. package/dist/components/menu.js +61 -0
  101. package/dist/components/menu.js.map +1 -1
  102. package/dist/components/modal.cjs +61 -0
  103. package/dist/components/modal.cjs.map +1 -1
  104. package/dist/components/modal.js +61 -0
  105. package/dist/components/modal.js.map +1 -1
  106. package/dist/components/multi-column-picker.cjs.map +1 -1
  107. package/dist/components/multi-column-picker.js.map +1 -1
  108. package/dist/components/novel-reader.cjs.map +1 -1
  109. package/dist/components/novel-reader.js.map +1 -1
  110. package/dist/components/number-input.cjs +61 -0
  111. package/dist/components/number-input.cjs.map +1 -1
  112. package/dist/components/number-input.js +61 -0
  113. package/dist/components/number-input.js.map +1 -1
  114. package/dist/components/orbital-sphere.cjs.map +1 -1
  115. package/dist/components/orbital-sphere.js.map +1 -1
  116. package/dist/components/pagination.cjs +61 -0
  117. package/dist/components/pagination.cjs.map +1 -1
  118. package/dist/components/pagination.js +61 -0
  119. package/dist/components/pagination.js.map +1 -1
  120. package/dist/components/password-input.cjs +67 -12
  121. package/dist/components/password-input.cjs.map +1 -1
  122. package/dist/components/password-input.js +67 -12
  123. package/dist/components/password-input.js.map +1 -1
  124. package/dist/components/popconfirm.cjs.map +1 -1
  125. package/dist/components/popconfirm.js.map +1 -1
  126. package/dist/components/popup.cjs +61 -0
  127. package/dist/components/popup.cjs.map +1 -1
  128. package/dist/components/popup.js +61 -0
  129. package/dist/components/popup.js.map +1 -1
  130. package/dist/components/progress-bar.cjs.map +1 -1
  131. package/dist/components/progress-bar.js.map +1 -1
  132. package/dist/components/qr-code.cjs.map +1 -1
  133. package/dist/components/qr-code.js.map +1 -1
  134. package/dist/components/radio-group.cjs.map +1 -1
  135. package/dist/components/radio-group.js.map +1 -1
  136. package/dist/components/rating.cjs +61 -0
  137. package/dist/components/rating.cjs.map +1 -1
  138. package/dist/components/rating.js +61 -0
  139. package/dist/components/rating.js.map +1 -1
  140. package/dist/components/rich-editor.cjs +1341 -0
  141. package/dist/components/rich-editor.cjs.map +1 -0
  142. package/dist/components/rich-editor.d.ts +2 -0
  143. package/dist/components/rich-editor.d.ts.map +1 -0
  144. package/dist/components/rich-editor.js +1339 -0
  145. package/dist/components/rich-editor.js.map +1 -0
  146. package/dist/components/rolling-number.cjs.map +1 -1
  147. package/dist/components/rolling-number.js.map +1 -1
  148. package/dist/components/select.cjs +61 -0
  149. package/dist/components/select.cjs.map +1 -1
  150. package/dist/components/select.js +61 -0
  151. package/dist/components/select.js.map +1 -1
  152. package/dist/components/signature.cjs.map +1 -1
  153. package/dist/components/signature.js.map +1 -1
  154. package/dist/components/skeleton.cjs.map +1 -1
  155. package/dist/components/skeleton.js.map +1 -1
  156. package/dist/components/slide-captcha.cjs +61 -0
  157. package/dist/components/slide-captcha.cjs.map +1 -1
  158. package/dist/components/slide-captcha.js +61 -0
  159. package/dist/components/slide-captcha.js.map +1 -1
  160. package/dist/components/swiper.cjs +61 -0
  161. package/dist/components/swiper.cjs.map +1 -1
  162. package/dist/components/swiper.js +61 -0
  163. package/dist/components/swiper.js.map +1 -1
  164. package/dist/components/switch.cjs.map +1 -1
  165. package/dist/components/switch.js.map +1 -1
  166. package/dist/components/table.cjs +61 -0
  167. package/dist/components/table.cjs.map +1 -1
  168. package/dist/components/table.js +61 -0
  169. package/dist/components/table.js.map +1 -1
  170. package/dist/components/tabs.cjs.map +1 -1
  171. package/dist/components/tabs.js.map +1 -1
  172. package/dist/components/tag.cjs +61 -0
  173. package/dist/components/tag.cjs.map +1 -1
  174. package/dist/components/tag.js +61 -0
  175. package/dist/components/tag.js.map +1 -1
  176. package/dist/components/textarea.cjs +61 -0
  177. package/dist/components/textarea.cjs.map +1 -1
  178. package/dist/components/textarea.js +61 -0
  179. package/dist/components/textarea.js.map +1 -1
  180. package/dist/components/theme-box.cjs.map +1 -1
  181. package/dist/components/theme-box.js.map +1 -1
  182. package/dist/components/tilt-card.cjs.map +1 -1
  183. package/dist/components/tilt-card.js.map +1 -1
  184. package/dist/components/timeline.cjs.map +1 -1
  185. package/dist/components/timeline.js.map +1 -1
  186. package/dist/components/toast.cjs +61 -0
  187. package/dist/components/toast.cjs.map +1 -1
  188. package/dist/components/toast.js +61 -0
  189. package/dist/components/toast.js.map +1 -1
  190. package/dist/components/tooltip.cjs.map +1 -1
  191. package/dist/components/tooltip.js.map +1 -1
  192. package/dist/components/typewriter-text.cjs.map +1 -1
  193. package/dist/components/typewriter-text.js.map +1 -1
  194. package/dist/components/upload.cjs +61 -0
  195. package/dist/components/upload.cjs.map +1 -1
  196. package/dist/components/upload.js +61 -0
  197. package/dist/components/upload.js.map +1 -1
  198. package/dist/components/verification-code.cjs.map +1 -1
  199. package/dist/components/verification-code.js.map +1 -1
  200. package/dist/components/video-detail-transition.cjs +61 -0
  201. package/dist/components/video-detail-transition.cjs.map +1 -1
  202. package/dist/components/video-detail-transition.js +61 -0
  203. package/dist/components/video-detail-transition.js.map +1 -1
  204. package/dist/components/video-player.cjs.map +1 -1
  205. package/dist/components/video-player.js.map +1 -1
  206. package/dist/components/virtual-list.cjs.map +1 -1
  207. package/dist/components/virtual-list.js.map +1 -1
  208. package/dist/components/virtual-select.cjs +61 -0
  209. package/dist/components/virtual-select.cjs.map +1 -1
  210. package/dist/components/virtual-select.js +61 -0
  211. package/dist/components/virtual-select.js.map +1 -1
  212. package/dist/components/virtual-table.cjs +61 -0
  213. package/dist/components/virtual-table.cjs.map +1 -1
  214. package/dist/components/virtual-table.js +61 -0
  215. package/dist/components/virtual-table.js.map +1 -1
  216. package/dist/components/width-transition.cjs.map +1 -1
  217. package/dist/components/width-transition.js.map +1 -1
  218. package/dist/import-transform-BJDUXanp.js +153 -0
  219. package/dist/import-transform-BJDUXanp.js.map +1 -0
  220. package/dist/import-transform-yUes6fHV.js +151 -0
  221. package/dist/import-transform-yUes6fHV.js.map +1 -0
  222. package/dist/import-transform.d.ts.map +1 -1
  223. package/dist/index.cjs +817 -13
  224. package/dist/index.cjs.map +1 -1
  225. package/dist/index.d.ts +80 -26
  226. package/dist/index.d.ts.map +1 -1
  227. package/dist/index.js +816 -17
  228. package/dist/index.js.map +1 -1
  229. package/dist/styles/components/password-input.css +4 -4
  230. package/dist/styles/components/rich-editor.css +511 -0
  231. package/dist/styles/components/tooltip.css +24 -0
  232. package/dist/styles/components.css +513 -4
  233. package/dist/styles/themes/dark-tech.css +34 -0
  234. package/dist/styles.css +513 -4
  235. package/dist/vite.cjs +1 -1
  236. package/dist/vite.js +1 -1
  237. package/dist/webpack-loader.cjs +1 -1
  238. package/dist/webpack-loader.js +1 -1
  239. package/package.json +11 -3
package/dist/index.cjs CHANGED
@@ -9,11 +9,56 @@ const rollingDigits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
9
9
  let tooltipIdSeed = 0;
10
10
  const defaultToastManager = /*#__PURE__*/ new core.ToastManager();
11
11
  const classIconPaths = {
12
+ alignCenter: ["M6 6h12", "M4 12h16", "M7 18h10"],
13
+ alignLeft: ["M4 6h16", "M4 12h12", "M4 18h16"],
14
+ alignRight: ["M4 6h16", "M8 12h12", "M4 18h16"],
15
+ bold: ["M7 5h6a3.5 3.5 0 0 1 0 7H7z", "M7 12h7a3.5 3.5 0 0 1 0 7H7z"],
12
16
  chevronDown: ["M6 9l6 6 6-6"],
13
17
  chevronLeft: ["M15 18l-6-6 6-6"],
14
18
  chevronRight: ["M9 18l6-6-6-6"],
15
19
  chevronUp: ["M18 15l-6-6-6 6"],
16
20
  check: ["M20 6 9 17l-5-5"],
21
+ code: ["M9 18 3 12l6-6", "M15 6l6 6-6 6"],
22
+ eraser: ["M7 21h10", "M17 3 4 16l5 5 13-13z", "M14 6l4 4"],
23
+ fileCode: [
24
+ "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z",
25
+ "M14 2v6h6",
26
+ "M10 13l-2 2 2 2",
27
+ "M14 17l2-2-2-2",
28
+ ],
29
+ heading: ["M6 5v14", "M18 5v14", "M6 12h12"],
30
+ image: ["M5 5h14v14H5z", "M8 15l3-3 2 2 3-4 3 5", "M9 9h.01"],
31
+ italic: ["M10 5h8", "M6 19h8", "M14 5l-4 14"],
32
+ link: [
33
+ "M10 13a5 5 0 0 0 7.07 0l2-2a5 5 0 0 0-7.07-7.07l-1.1 1.1",
34
+ "M14 11a5 5 0 0 0-7.07 0l-2 2A5 5 0 0 0 12 20.07l1.1-1.1",
35
+ ],
36
+ list: [
37
+ "M8 6h13",
38
+ "M8 12h13",
39
+ "M8 18h13",
40
+ "M3 6h.01",
41
+ "M3 12h.01",
42
+ "M3 18h.01",
43
+ ],
44
+ listOrdered: [
45
+ "M10 6h11",
46
+ "M10 12h11",
47
+ "M10 18h11",
48
+ "M4 6h1v4",
49
+ "M4 10h2",
50
+ "M4 14a2 2 0 0 1 2 2c0 1-2 2-2 4h3",
51
+ ],
52
+ palette: [
53
+ "M12 3a9 9 0 0 0 0 18h1.5a1.8 1.8 0 0 0 1.2-3.1 1.8 1.8 0 0 1 1.2-3.1H18a6 6 0 0 0 0-12z",
54
+ "M7.5 10h.01",
55
+ "M10 6.5h.01",
56
+ "M14 6.5h.01",
57
+ "M16.5 10h.01",
58
+ ],
59
+ paragraph: ["M13 5v14", "M17 5v14", "M7 5h8a4 4 0 0 1 0 8H7z"],
60
+ quote: ["M8 11H5a3 3 0 0 1 3-3v8", "M19 11h-3a3 3 0 0 1 3-3v8"],
61
+ redo: ["M21 7v6h-6", "M21 13a8 8 0 1 1-2.34-5.66"],
17
62
  settings: [
18
63
  "M12 15.5A3.5 3.5 0 1 0 12 8a3.5 3.5 0 0 0 0 7.5Z",
19
64
  "M19.4 15a1.8 1.8 0 0 0 .36 1.98l.04.04a2.18 2.18 0 0 1-3.08 3.08l-.04-.04a1.8 1.8 0 0 0-1.98-.36 1.8 1.8 0 0 0-1 1.62V21a2.2 2.2 0 0 1-4.4 0v-.06a1.8 1.8 0 0 0-1-1.62 1.8 1.8 0 0 0-1.98.36l-.04.04A2.18 2.18 0 0 1 3.2 16.64l.04-.04A1.8 1.8 0 0 0 3.6 14.6a1.8 1.8 0 0 0-1.62-1H2a2.2 2.2 0 0 1 0-4.4h.06a1.8 1.8 0 0 0 1.62-1 1.8 1.8 0 0 0-.36-1.98l-.04-.04A2.18 2.18 0 0 1 6.36 3.1l.04.04a1.8 1.8 0 0 0 1.98.36h.08A1.8 1.8 0 0 0 9.4 1.88V1.8a2.2 2.2 0 0 1 4.4 0v.06a1.8 1.8 0 0 0 1 1.62 1.8 1.8 0 0 0 1.98-.36l.04-.04A2.18 2.18 0 0 1 19.9 6.16l-.04.04a1.8 1.8 0 0 0-.36 1.98v.08a1.8 1.8 0 0 0 1.62.94h.08a2.2 2.2 0 0 1 0 4.4h-.06A1.8 1.8 0 0 0 19.4 15Z",
@@ -21,6 +66,22 @@ const classIconPaths = {
21
66
  star: [
22
67
  "M12 2l3.09 6.26 6.91 1-5 4.87 1.18 6.87L12 17.77 5.82 21 7 14.13l-5-4.87 6.91-1L12 2Z",
23
68
  ],
69
+ strikethrough: [
70
+ "M5 12h14",
71
+ "M16 6.5A4 4 0 0 0 12.5 5H11a3 3 0 0 0-.7 5.9",
72
+ "M8 17.5A4.2 4.2 0 0 0 11.5 19H13a3 3 0 0 0 .7-5.9",
73
+ ],
74
+ table: ["M4 5h16v14H4z", "M4 11h16", "M10 5v14"],
75
+ trash: ["M3 6h18", "M8 6V4h8v2", "M6 6l1 15h10l1-15", "M10 11v6", "M14 11v6"],
76
+ type: ["M4 7V5h16v2", "M12 5v14", "M8 19h8"],
77
+ underline: ["M7 5v6a5 5 0 0 0 10 0V5", "M5 21h14"],
78
+ undo: ["M3 7v6h6", "M3 13a8 8 0 1 0 2.34-5.66"],
79
+ uploadCloud: [
80
+ "M16 16l-4-4-4 4",
81
+ "M12 12v9",
82
+ "M20 16.6A5 5 0 0 0 18 7h-1.26A8 8 0 1 0 4 15.25",
83
+ ],
84
+ video: ["M4 6h11v12H4z", "M15 10l5-3v10l-5-3z"],
24
85
  x: ["M18 6 6 18", "M6 6l12 12"],
25
86
  };
26
87
  function getClassKitGlobal() {
@@ -386,6 +447,7 @@ const ClassForm = /*#__PURE__*/ vue.defineComponent({
386
447
  },
387
448
  setup(props, { slots }) {
388
449
  var _a;
450
+ const ownsController = !props.form;
389
451
  const controller = (_a = props.form) !== null && _a !== void 0 ? _a : new core.FormController({
390
452
  initialValues: props.initialValues,
391
453
  onSubmit: props.onSubmit,
@@ -396,7 +458,10 @@ const ClassForm = /*#__PURE__*/ vue.defineComponent({
396
458
  disabled: vue.computed(() => props.disabled),
397
459
  readOnly: vue.computed(() => props.readOnly || props.readonly),
398
460
  });
399
- vue.onBeforeUnmount(() => controller.destroy());
461
+ vue.onBeforeUnmount(() => {
462
+ if (ownsController)
463
+ controller.destroy();
464
+ });
400
465
  return () => {
401
466
  var _a;
402
467
  return vue.h("form", {
@@ -638,22 +703,16 @@ const ClassPasswordInput = /*#__PURE__*/ vue.defineComponent({
638
703
  viewBox: "0 0 24 24",
639
704
  }, [
640
705
  vue.h("path", {
641
- d: "M2.4 12s3.2-6.2 9.6-6.2S21.6 12 21.6 12s-3.2 6.2-9.6 6.2S2.4 12 2.4 12Z",
706
+ d: "M3.2 12.1c1.9-3.35 4.75-5.05 8.8-5.05s6.9 1.7 8.8 5.05c-1.9 3.35-4.75 5.05-8.8 5.05s-6.9-1.7-8.8-5.05Z",
642
707
  }),
643
708
  vue.h("path", {
644
- d: "M12 8.8a3.2 3.2 0 1 1 0 6.4 3.2 3.2 0 0 1 0-6.4Z",
709
+ d: "M12 9.45a2.65 2.65 0 1 1 0 5.3 2.65 2.65 0 0 1 0-5.3Z",
645
710
  }),
646
711
  !state.visible
647
- ? [
648
- vue.h("path", {
649
- class: "cc-password-field__eye-mask",
650
- d: "M6.2 5.1 18.9 17.8",
651
- }),
652
- vue.h("path", {
653
- class: "cc-password-field__eye-mask",
654
- d: "M3.7 3.9 20.3 20.1",
655
- }),
656
- ]
712
+ ? vue.h("path", {
713
+ class: "cc-password-field__eye-mask",
714
+ d: "M4.8 4.9 19.2 19.1",
715
+ })
657
716
  : null,
658
717
  ]);
659
718
  }
@@ -730,6 +789,746 @@ const ClassPasswordInput = /*#__PURE__*/ vue.defineComponent({
730
789
  };
731
790
  },
732
791
  });
792
+ const dynamicImportModule = (name) => new Function("name", "return import(name)")(name);
793
+ function normalizeRichEditorUrl(value) {
794
+ var _a;
795
+ const url = (_a = value === null || value === void 0 ? void 0 : value.trim()) !== null && _a !== void 0 ? _a : "";
796
+ if (!url)
797
+ return "";
798
+ try {
799
+ const parsed = new URL(url);
800
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:")
801
+ return "";
802
+ return parsed.toString();
803
+ }
804
+ catch (_b) {
805
+ return "";
806
+ }
807
+ }
808
+ function createRichEditorTableHtml() {
809
+ return [
810
+ '<table style="width: 100%; border-collapse: collapse;">',
811
+ "<tbody>",
812
+ "<tr><td>标题</td><td>内容</td></tr>",
813
+ "<tr><td>示例</td><td>可继续编辑</td></tr>",
814
+ "</tbody>",
815
+ "</table><p><br></p>",
816
+ ].join("");
817
+ }
818
+ function getRichEditorImageFiles(files) {
819
+ return Array.from(files !== null && files !== void 0 ? files : []).filter((file) => file.type.startsWith("image/"));
820
+ }
821
+ function resolveRichEditorUploadUrl(payload) {
822
+ var _a, _b, _c, _d, _e, _f, _g, _h;
823
+ if (typeof payload === "string")
824
+ return payload;
825
+ if (!payload || typeof payload !== "object")
826
+ return "";
827
+ const record = payload;
828
+ const data = record.data;
829
+ return String((_h = (_g = (_f = (_e = (_d = (_c = (_b = (_a = record.url) !== null && _a !== void 0 ? _a : record.href) !== null && _b !== void 0 ? _b : record.src) !== null && _c !== void 0 ? _c : record.path) !== null && _d !== void 0 ? _d : data === null || data === void 0 ? void 0 : data.url) !== null && _e !== void 0 ? _e : data === null || data === void 0 ? void 0 : data.href) !== null && _f !== void 0 ? _f : data === null || data === void 0 ? void 0 : data.src) !== null && _g !== void 0 ? _g : data === null || data === void 0 ? void 0 : data.path) !== null && _h !== void 0 ? _h : "");
830
+ }
831
+ async function postRichEditorImage(file, uploadUrl, uploadHeaders) {
832
+ const formData = new FormData();
833
+ formData.append("file", file);
834
+ const response = await fetch(uploadUrl, {
835
+ body: formData,
836
+ credentials: "include",
837
+ headers: uploadHeaders,
838
+ method: "POST",
839
+ });
840
+ if (!response.ok) {
841
+ throw new Error("图片上传失败,请重试");
842
+ }
843
+ const payload = await response.json().catch(() => undefined);
844
+ const url = resolveRichEditorUploadUrl(payload);
845
+ if (!url) {
846
+ throw new Error("图片上传失败,请重试");
847
+ }
848
+ return { url };
849
+ }
850
+ const ClassRichEditor = /*#__PURE__*/ vue.defineComponent({
851
+ name: "ClassRichEditor",
852
+ props: {
853
+ className: String,
854
+ disabled: Boolean,
855
+ height: {
856
+ type: Number,
857
+ default: 400,
858
+ },
859
+ onError: Function,
860
+ placeholder: {
861
+ type: String,
862
+ default: "请输入内容",
863
+ },
864
+ readOnly: Boolean,
865
+ uploadHeaders: Object,
866
+ uploadImage: Function,
867
+ uploadUrl: String,
868
+ value: {
869
+ type: String,
870
+ default: "",
871
+ },
872
+ },
873
+ emits: ["update:value", "change", "error"],
874
+ setup(props, { emit }) {
875
+ const controller = new core.RichEditorController({ html: props.value });
876
+ const html = vue.ref(controller.getState().html);
877
+ const sourceMode = vue.ref(false);
878
+ const uploading = vue.ref(false);
879
+ const notice = vue.ref(null);
880
+ const wang = vue.shallowRef(null);
881
+ const editor = vue.shallowRef(null);
882
+ const fallbackEditor = vue.ref(null);
883
+ const fileInput = vue.ref(null);
884
+ const urlDialogInput = vue.ref(null);
885
+ const fallbackSelection = vue.shallowRef(null);
886
+ const urlDialog = vue.ref(null);
887
+ const toastManager = new core.ToastManager();
888
+ const syncFallbackEditor = () => {
889
+ var _a;
890
+ const element = fallbackEditor.value;
891
+ if (!element || sourceMode.value || ((_a = wang.value) === null || _a === void 0 ? void 0 : _a.Editor))
892
+ return;
893
+ if (document.activeElement === element)
894
+ return;
895
+ if (element.innerHTML !== html.value)
896
+ element.innerHTML = html.value;
897
+ };
898
+ const emitError = (message) => {
899
+ var _a;
900
+ toastManager.show({ message, tone: "danger" });
901
+ (_a = props.onError) === null || _a === void 0 ? void 0 : _a.call(props, message);
902
+ emit("error", message);
903
+ };
904
+ const commitHtml = (nextHtml) => {
905
+ const state = controller.setHtml(nextHtml);
906
+ html.value = state.html;
907
+ emit("update:value", state.html);
908
+ emit("change", state.html);
909
+ return state.html;
910
+ };
911
+ const uploadHandler = async (file) => {
912
+ if (props.uploadImage)
913
+ return props.uploadImage(file);
914
+ if (props.uploadUrl) {
915
+ return postRichEditorImage(file, props.uploadUrl, props.uploadHeaders);
916
+ }
917
+ throw new Error("请配置图片上传接口");
918
+ };
919
+ const saveFallbackSelection = () => {
920
+ const element = fallbackEditor.value;
921
+ const selection = window.getSelection();
922
+ if (!element || !selection || selection.rangeCount === 0)
923
+ return;
924
+ const range = selection.getRangeAt(0);
925
+ if (!element.contains(range.commonAncestorContainer))
926
+ return;
927
+ fallbackSelection.value = range.cloneRange();
928
+ };
929
+ const restoreFallbackSelection = () => {
930
+ if (!fallbackSelection.value)
931
+ return;
932
+ const selection = window.getSelection();
933
+ selection === null || selection === void 0 ? void 0 : selection.removeAllRanges();
934
+ selection === null || selection === void 0 ? void 0 : selection.addRange(fallbackSelection.value);
935
+ };
936
+ const insertFallbackHtml = (nextHtml) => {
937
+ var _a;
938
+ (_a = fallbackEditor.value) === null || _a === void 0 ? void 0 : _a.focus();
939
+ restoreFallbackSelection();
940
+ document.execCommand("insertHTML", false, nextHtml);
941
+ if (fallbackEditor.value)
942
+ commitHtml(fallbackEditor.value.innerHTML);
943
+ };
944
+ const runFallbackCommand = (command, value) => {
945
+ var _a;
946
+ (_a = fallbackEditor.value) === null || _a === void 0 ? void 0 : _a.focus();
947
+ restoreFallbackSelection();
948
+ document.execCommand(command, false, value);
949
+ if (fallbackEditor.value)
950
+ commitHtml(fallbackEditor.value.innerHTML);
951
+ };
952
+ const deleteSelectedContent = () => {
953
+ var _a, _b, _c;
954
+ if (props.disabled)
955
+ return;
956
+ const currentEditor = editor.value;
957
+ if (currentEditor === null || currentEditor === void 0 ? void 0 : currentEditor.deleteFragment) {
958
+ (_a = currentEditor.focus) === null || _a === void 0 ? void 0 : _a.call(currentEditor);
959
+ currentEditor.deleteFragment();
960
+ const nextHtml = (_b = currentEditor.getHtml) === null || _b === void 0 ? void 0 : _b.call(currentEditor);
961
+ if (typeof nextHtml === "string")
962
+ commitHtml(nextHtml);
963
+ return;
964
+ }
965
+ (_c = fallbackEditor.value) === null || _c === void 0 ? void 0 : _c.focus();
966
+ restoreFallbackSelection();
967
+ document.execCommand("delete");
968
+ if (fallbackEditor.value)
969
+ commitHtml(fallbackEditor.value.innerHTML);
970
+ };
971
+ const handleFallbackUpload = async (files) => {
972
+ const images = getRichEditorImageFiles(files);
973
+ if (images.length === 0)
974
+ return;
975
+ uploading.value = true;
976
+ notice.value = { text: "图片上传中...", type: "loading" };
977
+ try {
978
+ for (const file of images) {
979
+ const result = await controller.uploadImage(file, uploadHandler);
980
+ insertFallbackHtml(`<p><img src="${result.url}" alt="${file.name}" /></p>`);
981
+ }
982
+ notice.value = { text: "图片上传完成", type: "success" };
983
+ }
984
+ catch (error) {
985
+ emitError(error instanceof Error ? error.message : "图片上传失败,请重试");
986
+ }
987
+ finally {
988
+ uploading.value = false;
989
+ if (fileInput.value)
990
+ fileInput.value.value = "";
991
+ }
992
+ };
993
+ const openFallbackUrlDialog = (kind) => {
994
+ saveFallbackSelection();
995
+ const locale = core.getClassComponentsLocale();
996
+ const dialogMap = {
997
+ image: {
998
+ icon: "image",
999
+ placeholder: locale.richEditorInsertImagePlaceholder,
1000
+ title: locale.richEditorInsertImageTitle,
1001
+ },
1002
+ link: {
1003
+ icon: "link",
1004
+ placeholder: locale.richEditorInsertLinkPlaceholder,
1005
+ title: locale.richEditorInsertLinkTitle,
1006
+ },
1007
+ video: {
1008
+ icon: "video",
1009
+ placeholder: locale.richEditorInsertVideoPlaceholder,
1010
+ title: locale.richEditorInsertVideoTitle,
1011
+ },
1012
+ };
1013
+ urlDialog.value = { ...dialogMap[kind], kind, value: "" };
1014
+ void vue.nextTick(() => { var _a; return (_a = urlDialogInput.value) === null || _a === void 0 ? void 0 : _a.focus(); });
1015
+ };
1016
+ const closeFallbackUrlDialog = () => {
1017
+ urlDialog.value = null;
1018
+ };
1019
+ const submitFallbackUrlDialog = () => {
1020
+ var _a;
1021
+ if (!urlDialog.value)
1022
+ return;
1023
+ const dialog = urlDialog.value;
1024
+ const url = normalizeRichEditorUrl(dialog.value);
1025
+ if (!url) {
1026
+ emitError(core.getClassComponentsLocale().richEditorInvalidUrlText);
1027
+ return;
1028
+ }
1029
+ if (dialog.kind === "image") {
1030
+ insertFallbackHtml(`<p><img src="${url}" alt="" /></p>`);
1031
+ }
1032
+ else if (dialog.kind === "video") {
1033
+ insertFallbackHtml(`<p><video controls src="${url}"></video></p>`);
1034
+ }
1035
+ else {
1036
+ restoreFallbackSelection();
1037
+ const text = ((_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.toString()) || url;
1038
+ insertFallbackHtml(`<a href="${url}" target="_blank" rel="noopener noreferrer">${text}</a>`);
1039
+ }
1040
+ urlDialog.value = null;
1041
+ };
1042
+ vue.watch(() => props.value, (nextValue) => {
1043
+ const nextHtml = controller.setHtml(nextValue !== null && nextValue !== void 0 ? nextValue : "").html;
1044
+ if (html.value !== nextHtml)
1045
+ html.value = nextHtml;
1046
+ });
1047
+ vue.watch(html, () => void vue.nextTick(syncFallbackEditor), { flush: "post" });
1048
+ vue.watch(() => { var _a; return [sourceMode.value, (_a = wang.value) === null || _a === void 0 ? void 0 : _a.Editor]; }, () => void vue.nextTick(syncFallbackEditor), { flush: "post" });
1049
+ vue.watch(() => [props.disabled, props.readOnly], () => {
1050
+ var _a, _b, _c, _d;
1051
+ if (props.disabled || props.readOnly)
1052
+ (_b = (_a = editor.value) === null || _a === void 0 ? void 0 : _a.disable) === null || _b === void 0 ? void 0 : _b.call(_a);
1053
+ else
1054
+ (_d = (_c = editor.value) === null || _c === void 0 ? void 0 : _c.enable) === null || _d === void 0 ? void 0 : _d.call(_c);
1055
+ });
1056
+ vue.onMounted(() => {
1057
+ syncFallbackEditor();
1058
+ dynamicImportModule("@wangeditor/editor-for-vue")
1059
+ .then((module) => {
1060
+ wang.value = module;
1061
+ })
1062
+ .catch(() => {
1063
+ wang.value = null;
1064
+ });
1065
+ });
1066
+ vue.onBeforeUnmount(() => {
1067
+ var _a, _b;
1068
+ (_b = (_a = editor.value) === null || _a === void 0 ? void 0 : _a.destroy) === null || _b === void 0 ? void 0 : _b.call(_a);
1069
+ editor.value = null;
1070
+ });
1071
+ const toolbarConfig = {
1072
+ toolbarKeys: [
1073
+ "bold",
1074
+ "italic",
1075
+ "underline",
1076
+ "through",
1077
+ "color",
1078
+ "bgColor",
1079
+ "fontSize",
1080
+ "justifyLeft",
1081
+ "justifyCenter",
1082
+ "justifyRight",
1083
+ "justifyJustify",
1084
+ "numberedList",
1085
+ "bulletedList",
1086
+ "lineHeight",
1087
+ "indent",
1088
+ "delIndent",
1089
+ "blockquote",
1090
+ "codeBlock",
1091
+ "uploadImage",
1092
+ "insertImage",
1093
+ "insertVideo",
1094
+ "insertTable",
1095
+ "insertLink",
1096
+ "unLink",
1097
+ "undo",
1098
+ "redo",
1099
+ "clearStyle",
1100
+ ],
1101
+ };
1102
+ const editorConfig = {
1103
+ MENU_CONF: {
1104
+ uploadImage: {
1105
+ allowedFileTypes: [
1106
+ "image/jpeg",
1107
+ "image/jpg",
1108
+ "image/png",
1109
+ "image/gif",
1110
+ "image/webp",
1111
+ ],
1112
+ customUpload: async (file, insertFn) => {
1113
+ uploading.value = true;
1114
+ notice.value = { text: "图片上传中...", type: "loading" };
1115
+ try {
1116
+ const result = await controller.uploadImage(file, uploadHandler);
1117
+ insertFn(result.url, file.name, result.url);
1118
+ notice.value = { text: "图片上传完成", type: "success" };
1119
+ }
1120
+ catch (error) {
1121
+ emitError(error instanceof Error ? error.message : "图片上传失败,请重试");
1122
+ }
1123
+ finally {
1124
+ uploading.value = false;
1125
+ }
1126
+ },
1127
+ },
1128
+ },
1129
+ autoFocus: false,
1130
+ placeholder: props.placeholder,
1131
+ readOnly: props.disabled,
1132
+ customPaste: (_editor, event) => {
1133
+ var _a;
1134
+ const pastedHtml = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData("text/html");
1135
+ if (!pastedHtml)
1136
+ return true;
1137
+ event.preventDefault();
1138
+ _editor.dangerouslyInsertHtml(controller.sanitize(pastedHtml));
1139
+ return false;
1140
+ },
1141
+ };
1142
+ const toolTip = (content, child) => vue.h(ClassTooltip, { content, placement: "bottom" }, { default: () => child });
1143
+ const toolIcon = (icon) => vue.h("span", { class: "cc-rich-editor__summary-icon" }, [
1144
+ classIcon(icon),
1145
+ classIcon("chevronDown", "cc-rich-editor__chevron"),
1146
+ ]);
1147
+ const toolGroup = (label, icon, children) => vue.h("div", {
1148
+ class: "cc-rich-editor__tool-group",
1149
+ "data-disabled": props.disabled ? "true" : "false",
1150
+ }, [
1151
+ toolTip(label, vue.h("button", {
1152
+ "aria-haspopup": "menu",
1153
+ "aria-label": label,
1154
+ class: "cc-rich-editor__tool-trigger",
1155
+ disabled: props.disabled,
1156
+ type: "button",
1157
+ }, [toolIcon(icon)])),
1158
+ vue.h("div", { class: "cc-rich-editor__tool-menu", role: "menu" }, children),
1159
+ ]);
1160
+ return () => {
1161
+ var _a, _b, _c;
1162
+ const locale = core.getClassComponentsLocale();
1163
+ const rootClass = [
1164
+ "cc-rich-editor",
1165
+ props.readOnly ? "cc-rich-editor--readonly" : "",
1166
+ props.disabled ? "cc-rich-editor--disabled" : "",
1167
+ (_a = props.className) !== null && _a !== void 0 ? _a : "",
1168
+ ]
1169
+ .filter(Boolean)
1170
+ .join(" ");
1171
+ if (props.readOnly) {
1172
+ return vue.h("div", { class: rootClass }, [
1173
+ vue.h("div", {
1174
+ class: "cc-rich-editor__preview",
1175
+ innerHTML: html.value,
1176
+ style: { minHeight: `${props.height}px` },
1177
+ }),
1178
+ ]);
1179
+ }
1180
+ const toolbar = ((_b = wang.value) === null || _b === void 0 ? void 0 : _b.Toolbar) && editor.value
1181
+ ? vue.h(wang.value.Toolbar, {
1182
+ defaultConfig: toolbarConfig,
1183
+ editor: editor.value,
1184
+ mode: "default",
1185
+ })
1186
+ : vue.h("div", { class: "cc-rich-editor__fallback-toolbar" }, [
1187
+ toolTip("加粗", vue.h("button", {
1188
+ "aria-label": "加粗",
1189
+ class: "cc-rich-editor__tool",
1190
+ disabled: props.disabled,
1191
+ type: "button",
1192
+ onClick: () => runFallbackCommand("bold"),
1193
+ }, [classIcon("bold")])),
1194
+ toolTip("斜体", vue.h("button", {
1195
+ "aria-label": "斜体",
1196
+ class: "cc-rich-editor__tool",
1197
+ disabled: props.disabled,
1198
+ type: "button",
1199
+ onClick: () => runFallbackCommand("italic"),
1200
+ }, [classIcon("italic")])),
1201
+ toolTip("下划线", vue.h("button", {
1202
+ "aria-label": "下划线",
1203
+ class: "cc-rich-editor__tool",
1204
+ disabled: props.disabled,
1205
+ type: "button",
1206
+ onClick: () => runFallbackCommand("underline"),
1207
+ }, [classIcon("underline")])),
1208
+ toolTip("删除线", vue.h("button", {
1209
+ "aria-label": "删除线",
1210
+ class: "cc-rich-editor__tool",
1211
+ disabled: props.disabled,
1212
+ type: "button",
1213
+ onClick: () => runFallbackCommand("strikeThrough"),
1214
+ }, [classIcon("strikethrough")])),
1215
+ toolTip("文字色", vue.h("label", {
1216
+ "aria-label": "文字色",
1217
+ class: "cc-rich-editor__color-tool",
1218
+ "data-disabled": props.disabled ? "true" : "false",
1219
+ }, [
1220
+ classIcon("type"),
1221
+ vue.h("input", {
1222
+ disabled: props.disabled,
1223
+ type: "color",
1224
+ onChange: (event) => runFallbackCommand("foreColor", event.currentTarget.value),
1225
+ }),
1226
+ ])),
1227
+ toolTip("背景色", vue.h("label", {
1228
+ "aria-label": "背景色",
1229
+ class: "cc-rich-editor__color-tool cc-rich-editor__color-tool--background",
1230
+ "data-disabled": props.disabled ? "true" : "false",
1231
+ }, [
1232
+ classIcon("palette"),
1233
+ vue.h("input", {
1234
+ disabled: props.disabled,
1235
+ type: "color",
1236
+ onChange: (event) => runFallbackCommand("hiliteColor", event.currentTarget.value),
1237
+ }),
1238
+ ])),
1239
+ toolGroup("段落和字号", "type", [
1240
+ vue.h("button", {
1241
+ disabled: props.disabled,
1242
+ type: "button",
1243
+ onClick: () => runFallbackCommand("formatBlock", "p"),
1244
+ }, [classIcon("paragraph"), vue.h("span", "正文")]),
1245
+ vue.h("button", {
1246
+ disabled: props.disabled,
1247
+ type: "button",
1248
+ onClick: () => runFallbackCommand("formatBlock", "h2"),
1249
+ }, [classIcon("heading"), vue.h("span", "标题")]),
1250
+ vue.h("button", {
1251
+ disabled: props.disabled,
1252
+ type: "button",
1253
+ onClick: () => runFallbackCommand("fontSize", "2"),
1254
+ }, [classIcon("type"), vue.h("span", "小字")]),
1255
+ vue.h("button", {
1256
+ disabled: props.disabled,
1257
+ type: "button",
1258
+ onClick: () => runFallbackCommand("fontSize", "4"),
1259
+ }, [classIcon("type"), vue.h("span", "大字")]),
1260
+ ]),
1261
+ toolGroup("对齐", "alignLeft", [
1262
+ vue.h("button", {
1263
+ disabled: props.disabled,
1264
+ type: "button",
1265
+ onClick: () => runFallbackCommand("justifyLeft"),
1266
+ }, [classIcon("alignLeft"), vue.h("span", "左对齐")]),
1267
+ vue.h("button", {
1268
+ disabled: props.disabled,
1269
+ type: "button",
1270
+ onClick: () => runFallbackCommand("justifyCenter"),
1271
+ }, [classIcon("alignCenter"), vue.h("span", "居中")]),
1272
+ vue.h("button", {
1273
+ disabled: props.disabled,
1274
+ type: "button",
1275
+ onClick: () => runFallbackCommand("justifyRight"),
1276
+ }, [classIcon("alignRight"), vue.h("span", "右对齐")]),
1277
+ ]),
1278
+ toolGroup("段落功能", "list", [
1279
+ vue.h("button", {
1280
+ disabled: props.disabled,
1281
+ type: "button",
1282
+ onClick: () => runFallbackCommand("insertOrderedList"),
1283
+ }, [classIcon("listOrdered"), vue.h("span", "有序列表")]),
1284
+ vue.h("button", {
1285
+ disabled: props.disabled,
1286
+ type: "button",
1287
+ onClick: () => runFallbackCommand("insertUnorderedList"),
1288
+ }, [classIcon("list"), vue.h("span", "无序列表")]),
1289
+ vue.h("button", {
1290
+ disabled: props.disabled,
1291
+ type: "button",
1292
+ onClick: () => runFallbackCommand("formatBlock", "blockquote"),
1293
+ }, [classIcon("quote"), vue.h("span", "引用")]),
1294
+ vue.h("button", {
1295
+ disabled: props.disabled,
1296
+ type: "button",
1297
+ onClick: () => runFallbackCommand("formatBlock", "pre"),
1298
+ }, [classIcon("code"), vue.h("span", "代码块")]),
1299
+ ]),
1300
+ toolGroup("插入", "image", [
1301
+ vue.h("button", {
1302
+ disabled: props.disabled || uploading.value,
1303
+ type: "button",
1304
+ onClick: () => { var _a; return (_a = fileInput.value) === null || _a === void 0 ? void 0 : _a.click(); },
1305
+ }, [
1306
+ classIcon("uploadCloud"),
1307
+ vue.h("span", uploading.value ? "上传中" : "本地图片"),
1308
+ ]),
1309
+ vue.h("button", {
1310
+ disabled: props.disabled,
1311
+ type: "button",
1312
+ onClick: () => openFallbackUrlDialog("image"),
1313
+ }, [classIcon("image"), vue.h("span", "网络图片")]),
1314
+ vue.h("button", {
1315
+ disabled: props.disabled,
1316
+ type: "button",
1317
+ onClick: () => openFallbackUrlDialog("video"),
1318
+ }, [classIcon("video"), vue.h("span", "视频链接")]),
1319
+ vue.h("button", {
1320
+ disabled: props.disabled,
1321
+ type: "button",
1322
+ onClick: () => insertFallbackHtml(createRichEditorTableHtml()),
1323
+ }, [classIcon("table"), vue.h("span", "表格")]),
1324
+ vue.h("button", {
1325
+ disabled: props.disabled,
1326
+ type: "button",
1327
+ onClick: () => openFallbackUrlDialog("link"),
1328
+ }, [classIcon("link"), vue.h("span", "链接")]),
1329
+ ]),
1330
+ toolTip("清除格式", vue.h("button", {
1331
+ "aria-label": "清除格式",
1332
+ class: "cc-rich-editor__tool",
1333
+ disabled: props.disabled,
1334
+ type: "button",
1335
+ onClick: () => runFallbackCommand("removeFormat"),
1336
+ }, [classIcon("eraser")])),
1337
+ toolTip("撤销", vue.h("button", {
1338
+ "aria-label": "撤销",
1339
+ class: "cc-rich-editor__tool",
1340
+ disabled: props.disabled,
1341
+ type: "button",
1342
+ onClick: () => runFallbackCommand("undo"),
1343
+ }, [classIcon("undo")])),
1344
+ toolTip("恢复撤销", vue.h("button", {
1345
+ "aria-label": "恢复撤销",
1346
+ class: "cc-rich-editor__tool",
1347
+ disabled: props.disabled,
1348
+ type: "button",
1349
+ onClick: () => runFallbackCommand("redo"),
1350
+ }, [classIcon("redo")])),
1351
+ vue.h("input", {
1352
+ accept: "image/jpeg,image/jpg,image/png,image/gif,image/webp",
1353
+ hidden: true,
1354
+ multiple: true,
1355
+ ref: fileInput,
1356
+ type: "file",
1357
+ onChange: (event) => void handleFallbackUpload(event.currentTarget.files),
1358
+ }),
1359
+ ]);
1360
+ return vue.h("div", { class: rootClass }, [
1361
+ vue.h("div", { class: "cc-rich-editor__toolbar-row" }, [
1362
+ toolbar,
1363
+ vue.h("div", { class: "cc-rich-editor__toolbar-actions" }, [
1364
+ toolTip("删除选中", vue.h("button", {
1365
+ "aria-label": "删除选中",
1366
+ class: "cc-rich-editor__source-toggle",
1367
+ disabled: props.disabled,
1368
+ type: "button",
1369
+ onClick: deleteSelectedContent,
1370
+ onMousedown: (event) => event.preventDefault(),
1371
+ }, [classIcon("x")])),
1372
+ toolTip(sourceMode.value ? "预览" : "源码", vue.h("button", {
1373
+ "aria-label": sourceMode.value ? "预览" : "源码",
1374
+ class: "cc-rich-editor__source-toggle",
1375
+ disabled: props.disabled,
1376
+ type: "button",
1377
+ onClick: () => {
1378
+ sourceMode.value = !sourceMode.value;
1379
+ },
1380
+ }, [classIcon(sourceMode.value ? "image" : "fileCode")])),
1381
+ toolTip("清空", vue.h("button", {
1382
+ "aria-label": "清空",
1383
+ class: "cc-rich-editor__source-toggle",
1384
+ disabled: props.disabled,
1385
+ type: "button",
1386
+ onClick: () => commitHtml(""),
1387
+ }, [classIcon("trash")])),
1388
+ ]),
1389
+ ]),
1390
+ notice.value
1391
+ ? vue.h("div", {
1392
+ class: "cc-rich-editor__notice",
1393
+ "data-type": notice.value.type,
1394
+ role: "status",
1395
+ }, notice.value.text)
1396
+ : null,
1397
+ vue.h(ClassToastViewport, {
1398
+ className: "cc-toast-viewport cc-rich-editor__toast-viewport",
1399
+ manager: toastManager,
1400
+ maxVisible: 3,
1401
+ position: "top-right",
1402
+ }),
1403
+ urlDialog.value
1404
+ ? vue.h("div", {
1405
+ "aria-modal": "true",
1406
+ class: "cc-rich-editor__url-modal",
1407
+ role: "dialog",
1408
+ }, [
1409
+ vue.h("div", { class: "cc-rich-editor__url-panel" }, [
1410
+ vue.h("div", { class: "cc-rich-editor__url-header" }, [
1411
+ vue.h("span", { class: "cc-rich-editor__url-title" }, [
1412
+ classIcon(urlDialog.value.icon),
1413
+ urlDialog.value.title,
1414
+ ]),
1415
+ vue.h("button", {
1416
+ "aria-label": "关闭",
1417
+ class: "cc-rich-editor__url-close",
1418
+ type: "button",
1419
+ onClick: closeFallbackUrlDialog,
1420
+ }, [classIcon("x")]),
1421
+ ]),
1422
+ vue.h("label", { class: "cc-rich-editor__url-field" }, [
1423
+ vue.h("span", locale.richEditorUrlFieldLabel),
1424
+ vue.h("input", {
1425
+ ref: urlDialogInput,
1426
+ placeholder: urlDialog.value.placeholder,
1427
+ type: "url",
1428
+ value: urlDialog.value.value,
1429
+ onInput: (event) => {
1430
+ if (!urlDialog.value)
1431
+ return;
1432
+ urlDialog.value = {
1433
+ ...urlDialog.value,
1434
+ value: event.currentTarget
1435
+ .value,
1436
+ };
1437
+ },
1438
+ onKeydown: (event) => {
1439
+ if (event.key === "Enter")
1440
+ submitFallbackUrlDialog();
1441
+ if (event.key === "Escape")
1442
+ closeFallbackUrlDialog();
1443
+ },
1444
+ }),
1445
+ ]),
1446
+ vue.h("div", { class: "cc-rich-editor__url-actions" }, [
1447
+ vue.h("button", {
1448
+ type: "button",
1449
+ onClick: closeFallbackUrlDialog,
1450
+ }, locale.richEditorCancelText),
1451
+ vue.h("button", {
1452
+ type: "button",
1453
+ onClick: submitFallbackUrlDialog,
1454
+ }, locale.richEditorInsertText),
1455
+ ]),
1456
+ ]),
1457
+ ])
1458
+ : null,
1459
+ sourceMode.value
1460
+ ? vue.h("textarea", {
1461
+ class: "cc-rich-editor__source",
1462
+ disabled: props.disabled,
1463
+ onInput: (event) => commitHtml(event.target.value),
1464
+ placeholder: props.placeholder,
1465
+ style: { height: `${props.height}px` },
1466
+ value: html.value,
1467
+ })
1468
+ : ((_c = wang.value) === null || _c === void 0 ? void 0 : _c.Editor)
1469
+ ? vue.h(wang.value.Editor, {
1470
+ defaultConfig: editorConfig,
1471
+ mode: "default",
1472
+ onChange: (nextEditor) => commitHtml(nextEditor.getHtml()),
1473
+ onCreated: (nextEditor) => {
1474
+ var _a;
1475
+ editor.value = nextEditor;
1476
+ if (props.disabled)
1477
+ (_a = nextEditor.disable) === null || _a === void 0 ? void 0 : _a.call(nextEditor);
1478
+ },
1479
+ "onUpdate:modelValue": (nextHtml) => commitHtml(nextHtml),
1480
+ modelValue: html.value,
1481
+ style: { height: `${props.height}px`, overflowY: "auto" },
1482
+ })
1483
+ : vue.h("div", {
1484
+ class: "cc-rich-editor__fallback-editor",
1485
+ contenteditable: !props.disabled,
1486
+ "data-placeholder": props.placeholder,
1487
+ onBlur: (event) => commitHtml(event.currentTarget.innerHTML),
1488
+ onKeyup: saveFallbackSelection,
1489
+ onMouseup: saveFallbackSelection,
1490
+ onDragover: (event) => {
1491
+ var _a;
1492
+ if (props.disabled ||
1493
+ getRichEditorImageFiles((_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.files)
1494
+ .length === 0)
1495
+ return;
1496
+ event.preventDefault();
1497
+ },
1498
+ onDrop: (event) => {
1499
+ var _a;
1500
+ const files = (_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.files;
1501
+ if (props.disabled ||
1502
+ getRichEditorImageFiles(files).length === 0)
1503
+ return;
1504
+ event.preventDefault();
1505
+ void handleFallbackUpload(files !== null && files !== void 0 ? files : null);
1506
+ },
1507
+ onInput: (event) => commitHtml(event.currentTarget.innerHTML),
1508
+ onPaste: (event) => {
1509
+ var _a, _b, _c, _d;
1510
+ const imageFiles = getRichEditorImageFiles((_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.files);
1511
+ if (imageFiles.length > 0) {
1512
+ event.preventDefault();
1513
+ void handleFallbackUpload((_c = (_b = event.clipboardData) === null || _b === void 0 ? void 0 : _b.files) !== null && _c !== void 0 ? _c : null);
1514
+ return;
1515
+ }
1516
+ const pastedHtml = (_d = event.clipboardData) === null || _d === void 0 ? void 0 : _d.getData("text/html");
1517
+ if (!pastedHtml)
1518
+ return;
1519
+ event.preventDefault();
1520
+ document.execCommand("insertHTML", false, controller.sanitize(pastedHtml));
1521
+ if (fallbackEditor.value)
1522
+ commitHtml(fallbackEditor.value.innerHTML);
1523
+ },
1524
+ ref: fallbackEditor,
1525
+ role: "textbox",
1526
+ style: { minHeight: `${props.height}px` },
1527
+ }),
1528
+ ]);
1529
+ };
1530
+ },
1531
+ });
733
1532
  const ClassField = ClassInput;
734
1533
  const ClassColorPicker = /*#__PURE__*/ vue.defineComponent({
735
1534
  name: "ClassColorPicker",
@@ -12519,6 +13318,10 @@ Object.defineProperty(exports, "ProgressController", {
12519
13318
  enumerable: true,
12520
13319
  get: function () { return core.ProgressController; }
12521
13320
  });
13321
+ Object.defineProperty(exports, "RichEditorController", {
13322
+ enumerable: true,
13323
+ get: function () { return core.RichEditorController; }
13324
+ });
12522
13325
  Object.defineProperty(exports, "SignatureController", {
12523
13326
  enumerable: true,
12524
13327
  get: function () { return core.SignatureController; }
@@ -12668,6 +13471,7 @@ exports.ClassProgressBar = ClassProgressBar;
12668
13471
  exports.ClassQRCode = ClassQRCode;
12669
13472
  exports.ClassRadioGroup = ClassRadioGroup;
12670
13473
  exports.ClassRating = ClassRating;
13474
+ exports.ClassRichEditor = ClassRichEditor;
12671
13475
  exports.ClassRollingNumber = ClassRollingNumber;
12672
13476
  exports.ClassSelect = ClassSelect;
12673
13477
  exports.ClassSignature = ClassSignature;