@kungal/editor-vue 0.17.0 → 0.19.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,72 @@
1
1
  # @kungal/editor-vue
2
2
 
3
+ ## 0.19.0
4
+
5
+ ### Minor Changes
6
+
7
+ - f111b82: Add a desktop **split view** for long-form writing.
8
+
9
+ `<KunEditor>` now has a third view mode, `split`, alongside WYSIWYG and Markdown:
10
+ an editable markdown source pane + a live **read-only WYSIWYG preview**, side by
11
+ side and left/right swappable. The markdown string stays the single source of
12
+ truth and the preview is derived — the industry-standard model (VS Code /
13
+ StackEdit / Dillinger), so there's no two-editor bidirectional-sync problem.
14
+
15
+ - **editor-vue**: the view mode gains `'split'`; `KunEditorViewSwitchApi` gains
16
+ `swap()` / `swapped` and `labels.split` / `labels.swap`. The WYSIWYG becomes a
17
+ read-only preview in split (its editability now reacts to the `readonly` prop).
18
+ The default hand-rolled view switch gets a 分栏 tab + a ⇄ swap button.
19
+ - **editor-nuxt**: `<KunEditorViewSwitch>` gets the 分栏 KunTab + a KunUI swap
20
+ button (shown in split).
21
+ - **Headless**: the layout is class hooks only — `.kun-editor__panes` /
22
+ `.kun-editor__pane` under `[data-mode='split']` (+ `[data-swap]`). Styled by the
23
+ reference `kun-editor.css`: stacked on narrow screens, side-by-side (swappable)
24
+ from `md` up. editor-vue still ships zero CSS.
25
+
26
+ Verified in the docs production build (headless + KunUI view switches): 分栏 shows
27
+ both panes side by side, typing markdown in the source updates the preview live,
28
+ the WYSIWYG preview is `contenteditable=false`, swap reverses the panes; 0 console
29
+ errors. (Synced scrolling between panes is a possible follow-up.)
30
+
31
+ ### Patch Changes
32
+
33
+ - @kungal/editor-core@0.19.0
34
+
35
+ ## 0.18.0
36
+
37
+ ### Minor Changes
38
+
39
+ - 6545866: Toolbar image upload now shows an in-document "uploading…" placeholder.
40
+
41
+ Previously only paste/drop showed the in-flight placeholder (Milkdown's `upload`
42
+ plugin); the toolbar image button uploaded silently — the image just popped in
43
+ when the adapter resolved. Now the toolbar path uses the same placeholder UX
44
+ (ProseMirror's official upload-example pattern).
45
+
46
+ - **editor-core**: `startImageUpload(view, file, { uploadImage, notify, locale })`
47
+ - the `imageUploadPlaceholder` decoration plugin (exported from `/preset`;
48
+ wired by the preset when `uploadImage` is present). Inserts a
49
+ `.kun-editor__uploading` widget at the caret, uploads, then replaces it with the
50
+ image (or removes it + notifies on failure); not an undo step. The paste/drop
51
+ placeholder now uses the same `.kun-editor__uploading` class so both look
52
+ identical.
53
+ - **editor-vue**: `KunEditorToolbarApi` gains `uploadImage(file)`; both the
54
+ headless `EditorToolbar` and the `#toolbar` slot API route uploads through
55
+ `startImageUpload`.
56
+ - **editor-nuxt**: `<KunEditorToolbar>`'s image button uses it.
57
+ - **Headless kept**: the placeholder is a class + widget hook only; style it via
58
+ `.kun-editor__uploading` in the reference `kun-editor.css` (primary-colored).
59
+
60
+ Customizable: style the placeholder via `.kun-editor__uploading`; the text is
61
+ localized (zh/en). Verified in the docs production build: uploading via either
62
+ toolbar inserts the image; the unit tests confirm the placeholder shows during a
63
+ pending upload and is replaced on success / removed on failure.
64
+
65
+ ### Patch Changes
66
+
67
+ - Updated dependencies [6545866]
68
+ - @kungal/editor-core@0.18.0
69
+
3
70
  ## 0.17.0
4
71
 
5
72
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"EditorToolbar.vue.d.ts","sourceRoot":"","sources":["../../src/components/EditorToolbar.vue"],"names":[],"mappings":"AAmcA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"EditorToolbar.vue.d.ts","sourceRoot":"","sources":["../../src/components/EditorToolbar.vue"],"names":[],"mappings":"AAycA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -14,17 +14,22 @@ type __VLS_Props = {
14
14
  /** Placeholder text shown while the editor is empty. */
15
15
  placeholder?: string;
16
16
  };
17
- type ViewMode = 'wysiwyg' | 'source';
17
+ type ViewMode = 'wysiwyg' | 'source' | 'split';
18
18
  declare var __VLS_1: {
19
19
  mode: ViewMode;
20
20
  setMode: (m: ViewMode) => void;
21
21
  labels: {
22
22
  wysiwyg: string;
23
23
  source: string;
24
+ split: string;
25
+ swap: string;
24
26
  };
27
+ swapped: boolean;
28
+ swap: () => void;
25
29
  }, __VLS_22: {
26
30
  run: <T>(key: import("@milkdown/kit/core").CmdKey<T>, payload?: T) => void;
27
31
  insertText: (text: string) => void;
32
+ uploadImage: (file: File) => void;
28
33
  insertQuote: (payload: {
29
34
  refId: string;
30
35
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"KunEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/KunEditor.vue"],"names":[],"mappings":"AAsLA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAM5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,KAAK,WAAW,GAAG;IACf,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,iBAAiB,CAAA;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,iBAAiB,CAAA;IAC5B,qDAAqD;IACrD,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAC;AAqCJ,KAAK,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;AA8MpC,QAAA,IAAI,OAAO;;iBA5MS,QAAQ;;;;;CA4MP,EAAE,QAAQ;iEA/Q/B,CAzKwB;;;;;;;;;;;;;;CAwbwC,CAAE;AAClE,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAClD;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAOhD,QAAA,MAAM,UAAU;;;;;cAtQD,iBAAiB;cAEjB,iBAAiB;YAEnB,eAAe;cAEb,OAAO;iBAEJ,MAAM;6EAmQtB,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"KunEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/KunEditor.vue"],"names":[],"mappings":"AA6NA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAM5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,KAAK,WAAW,GAAG;IACf,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,iBAAiB,CAAA;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,iBAAiB,CAAA;IAC5B,qDAAqD;IACrD,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAC;AAqCJ,KAAK,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;AAkQ9C,QAAA,IAAI,OAAO;;iBAhQS,QAAQ;;;;;;;;;CAgQP,EAAE,QAAQ;iEAnU/B,CAjNuE;;;;;;;;;;;;;;;CAohBP,CAAE;AAClE,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAClD;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAOhD,QAAA,MAAM,UAAU;;;;;cA1TD,iBAAiB;cAEjB,iBAAiB;YAEnB,eAAe;cAEb,OAAO;iBAEJ,MAAM;6EAuTtB,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MilkdownEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/MilkdownEditor.vue"],"names":[],"mappings":"AA0KA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAG5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,MAAM,EAAE,eAAe,CAAA;IACvB,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAC;AA8HF,QAAA,MAAM,YAAY;;;;kFAIhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"MilkdownEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/MilkdownEditor.vue"],"names":[],"mappings":"AAwLA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAG5B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAE/C,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,MAAM,EAAE,eAAe,CAAA;IACvB,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAC;AA4IF,QAAA,MAAM,YAAY;;;;kFAIhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -2,6 +2,7 @@ import type { CmdKey } from '@milkdown/kit/core';
2
2
  declare var __VLS_1: {
3
3
  run: <T>(key: CmdKey<T>, payload?: T) => void;
4
4
  insertText: (text: string) => void;
5
+ uploadImage: (file: File) => void;
5
6
  insertQuote: (payload: {
6
7
  refId: string;
7
8
  label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ToolbarHost.vue.d.ts","sourceRoot":"","sources":["../../src/components/ToolbarHost.vue"],"names":[],"mappings":"AAyEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAuEhD,QAAA,IAAI,OAAO;oCAxEX,CA9De;;;;;;;;;;;;;;CAsIO,CAAE;AACxB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,CAAC;AAG/C,QAAA,MAAM,UAAU,+QACd,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AACzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"ToolbarHost.vue.d.ts","sourceRoot":"","sources":["../../src/components/ToolbarHost.vue"],"names":[],"mappings":"AAyFA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAuFhD,QAAA,IAAI,OAAO;oCAxFX,CA9Ee;;;;;;;;;;;;;;;CAsKO,CAAE;AACxB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,CAAC;AAG/C,QAAA,MAAM,UAAU,+QACd,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AACzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
package/dist/index.js CHANGED
@@ -4,33 +4,33 @@ import { ProsemirrorAdapterProvider as k, usePluginViewContext as A, usePluginVi
4
4
  import { Editor as M, defaultValueCtx as N, editorViewCtx as P, editorViewOptionsCtx as F, rootCtx as I } from "@milkdown/kit/core";
5
5
  import { listenerCtx as L } from "@milkdown/kit/plugin/listener";
6
6
  import { SlashProvider as ee, slashFactory as te } from "@milkdown/kit/plugin/slash";
7
- import { callCommand as R, replaceAll as z } from "@milkdown/kit/utils";
8
- import { createKunEditorPlugins as ne, insertKunSpoilerCommand as re, insertMentionCommand as B, insertQuoteCommand as V, kunCM as ie, mentionId as ae, setHeadingCommand as oe } from "@kungal/editor-core/preset";
9
- import { TextSelection as se } from "@milkdown/kit/prose/state";
10
- import { createCodeBlockCommand as ce, insertHrCommand as H, insertImageCommand as U, toggleEmphasisCommand as W, toggleInlineCodeCommand as G, toggleStrongCommand as le, wrapInBlockquoteCommand as ue, wrapInBulletListCommand as de, wrapInOrderedListCommand as fe } from "@milkdown/kit/preset/commonmark";
11
- import { toggleStrikethroughCommand as pe } from "@milkdown/kit/preset/gfm";
12
- import { EditorState as me } from "@codemirror/state";
7
+ import { callCommand as R, replaceAll as ne } from "@milkdown/kit/utils";
8
+ import { createKunEditorPlugins as re, insertKunSpoilerCommand as ie, insertMentionCommand as z, insertQuoteCommand as B, kunCM as ae, mentionId as oe, setHeadingCommand as se, startImageUpload as V } from "@kungal/editor-core/preset";
9
+ import { TextSelection as ce } from "@milkdown/kit/prose/state";
10
+ import { createCodeBlockCommand as H, insertHrCommand as U, insertImageCommand as W, toggleEmphasisCommand as G, toggleInlineCodeCommand as le, toggleStrongCommand as ue, wrapInBlockquoteCommand as de, wrapInBulletListCommand as fe, wrapInOrderedListCommand as pe } from "@milkdown/kit/preset/commonmark";
11
+ import { toggleStrikethroughCommand as me } from "@milkdown/kit/preset/gfm";
12
+ import { EditorState as he } from "@codemirror/state";
13
13
  import { EditorView as K } from "@codemirror/view";
14
- import { markdown as he } from "@codemirror/lang-markdown";
15
- import { basicSetup as ge } from "codemirror";
14
+ import { markdown as ge } from "@codemirror/lang-markdown";
15
+ import { basicSetup as _e } from "codemirror";
16
16
  //#region src/context.ts
17
- var q = Symbol("kun-editor-context"), _e = [
17
+ var q = Symbol("kun-editor-context"), ve = [
18
18
  "data-active",
19
19
  "onMousedown",
20
20
  "onMouseenter"
21
- ], ve = ["src", "alt"], ye = {
21
+ ], ye = ["src", "alt"], be = {
22
22
  key: 1,
23
23
  class: "kun-mention-dropdown__avatar kun-mention-dropdown__avatar--fallback"
24
- }, be = { class: "kun-mention-dropdown__name" }, xe = {
24
+ }, xe = { class: "kun-mention-dropdown__name" }, Se = {
25
25
  key: 1,
26
26
  class: "kun-mention-dropdown__hint"
27
- }, Se = {
27
+ }, Ce = {
28
28
  key: 2,
29
29
  class: "kun-mention-dropdown__hint"
30
- }, Ce = {
30
+ }, we = {
31
31
  key: 3,
32
32
  class: "kun-mention-dropdown__hint"
33
- }, we = /* @__PURE__ */ s({
33
+ }, Te = /* @__PURE__ */ s({
34
34
  __name: "MentionDropdown",
35
35
  setup(n) {
36
36
  let r = /(?:^|\s)@([^\s@]{0,30})$/, o = l(q), s = o?.adapters.searchMentionUsers, c = t(() => (o?.locale ?? "zh-cn").toLowerCase().startsWith("en")), u = t(() => c.value ? {
@@ -73,13 +73,13 @@ var q = Symbol("kun-editor-context"), _e = [
73
73
  }, I = (e) => {
74
74
  let t = m.value;
75
75
  if (!t || !O) return;
76
- let n = t.state.schema.nodes[ae];
76
+ let n = t.state.schema.nodes[oe];
77
77
  if (!n) return;
78
78
  let r = n.create({
79
79
  userId: e.id,
80
80
  name: e.name
81
81
  }), { from: i, to: a } = O, o = t.state.tr.replaceWith(i, a, r), s = i + r.nodeSize;
82
- o.insertText(" ", s), o.setSelection(se.create(o.doc, s + 1)), t.dispatch(o.scrollIntoView()), t.focus(), b.hide();
82
+ o.insertText(" ", s), o.setSelection(ce.create(o.doc, s + 1)), t.dispatch(o.scrollIntoView()), t.focus(), b.hide();
83
83
  }, L = (e) => {
84
84
  if (!S.value || !T.value.length) {
85
85
  S.value && e.key === "Escape" && (e.preventDefault(), b.hide());
@@ -136,9 +136,9 @@ var q = Symbol("kun-editor-context"), _e = [
136
136
  src: e.avatar,
137
137
  alt: e.name,
138
138
  class: "kun-mention-dropdown__avatar"
139
- }, null, 8, ve)) : (p(), i("span", ye, v(e.name.charAt(0)), 1)), a("span", be, v(e.name), 1)], 40, _e))), 128)) : D.value ? (p(), i("div", xe, v(u.value.searching), 1)) : C.value ? (p(), i("div", Se, v(u.value.empty), 1)) : (p(), i("div", Ce, v(u.value.prompt), 1))], 512));
139
+ }, null, 8, ye)) : (p(), i("span", be, v(e.name.charAt(0)), 1)), a("span", xe, v(e.name), 1)], 40, ve))), 128)) : D.value ? (p(), i("div", Se, v(u.value.searching), 1)) : C.value ? (p(), i("div", Ce, v(u.value.empty), 1)) : (p(), i("div", we, v(u.value.prompt), 1))], 512));
140
140
  }
141
- }), Te = /* @__PURE__ */ s({
141
+ }), Ee = /* @__PURE__ */ s({
142
142
  __name: "MilkdownEditor",
143
143
  props: {
144
144
  modelValue: {},
@@ -157,25 +157,30 @@ var q = Symbol("kun-editor-context"), _e = [
157
157
  }), t.update(F, (e) => ({
158
158
  ...e,
159
159
  editable: () => !i.readonly
160
- })), l && t.set(c.key, { view: s({ component: we }) });
161
- }).use(ne(i.adapters, i.features, {
160
+ })), l && t.set(c.key, { view: s({ component: Te }) });
161
+ }).use(re(i.adapters, i.features, {
162
162
  locale: i.locale,
163
163
  placeholder: i.placeholder
164
164
  }));
165
165
  return l && t.use(c), t;
166
166
  });
167
167
  x(() => i.modelValue, (e) => {
168
- e !== o && (o = e, u.get()?.action(z(e)));
168
+ e !== o && (o = e, u.get()?.action(ne(e)));
169
+ }), x(() => i.readonly, () => {
170
+ u.get()?.action((e) => {
171
+ let t = e.get(P);
172
+ t.dispatch(t.state.tr);
173
+ });
169
174
  });
170
175
  let d = () => {
171
176
  u.get()?.action((e) => e.get(P).focus());
172
177
  };
173
178
  return t({
174
179
  insertQuote: (e) => {
175
- u.get()?.action(R(V.key, e)), d();
180
+ u.get()?.action(R(B.key, e)), d();
176
181
  },
177
182
  insertMention: (e) => {
178
- u.get()?.action(R(B.key, e)), d();
183
+ u.get()?.action(R(z.key, e)), d();
179
184
  },
180
185
  focus: d
181
186
  }), (e, t) => (p(), n(y(T)));
@@ -197,21 +202,21 @@ var q = Symbol("kun-editor-context"), _e = [
197
202
  spoiler: J("<path d=\"M9.9 4.24A9.1 9.1 0 0 1 12 4c7 0 10 8 10 8a13.2 13.2 0 0 1-1.67 2.68\"/><path d=\"M6.6 6.6A13.5 13.5 0 0 0 2 12s3 8 10 8a9.7 9.7 0 0 0 5.4-1.6\"/><line x1=\"2\" y1=\"2\" x2=\"22\" y2=\"22\"/>"),
198
203
  latex: Y("Σ", 15),
199
204
  smile: J("<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M8 14s1.5 2 4 2 4-2 4-2\"/><line x1=\"9\" y1=\"9\" x2=\"9.01\" y2=\"9\"/><line x1=\"15\" y1=\"9\" x2=\"15.01\" y2=\"9\"/>")
200
- }, Z = /* @__PURE__ */ "😀.😃.😄.😁.😆.😅.🤣.😂.🙂.🙃.😉.😊.😇.🥰.😍.🤩.😘.😗.😚.😋.😛.😜.🤪.😝.🤗.🤭.🤔.🤐.😐.😑.😶.😏.😒.🙄.😬.😌.😔.😪.🤤.😴.😷.🤒.🤕.🥵.🥶.🥴.😵.🤯.🤠.🥳.😎.🤓.🧐.😕.😟.🙁.😮.😯.😲.😳.🥺.😦.😧.😨.😰.😥.😢.😭.😱.😖.😣.😞.😓.😩.😫.🥱.😤.😡.😠.🤬.😈.👿.💀.💩.🤡.👻.👽.🤖.😺.😸.👍.👎.👌.🤌.🤏.✌️.🤞.🤟.🤘.👋.🤚.🖐️.✋.👏.🙌.🤝.🙏.💪.👀.👁️.❤️.🧡.💛.💚.💙.💜.🖤.🤍.💔.💕.💞.💓.💗.💖.💘.💝.💯.✨.⭐.🌟.🔥.💥.💫.⚡.☀️.🌈.🎉.🎊.🎁.🏆.🐶.🐱.🐭.🦊.🐻.🐼.🐨.🦄.🐢.🐳.🍎.🍑.🍓.🍉.🍰.🍺.🍵.☕.🍜.🍙.✅.❌.❓.❗.💤.👑.🎮.🎵.📌.🔖".split("."), Ee = [
205
+ }, Z = /* @__PURE__ */ "😀.😃.😄.😁.😆.😅.🤣.😂.🙂.🙃.😉.😊.😇.🥰.😍.🤩.😘.😗.😚.😋.😛.😜.🤪.😝.🤗.🤭.🤔.🤐.😐.😑.😶.😏.😒.🙄.😬.😌.😔.😪.🤤.😴.😷.🤒.🤕.🥵.🥶.🥴.😵.🤯.🤠.🥳.😎.🤓.🧐.😕.😟.🙁.😮.😯.😲.😳.🥺.😦.😧.😨.😰.😥.😢.😭.😱.😖.😣.😞.😓.😩.😫.🥱.😤.😡.😠.🤬.😈.👿.💀.💩.🤡.👻.👽.🤖.😺.😸.👍.👎.👌.🤌.🤏.✌️.🤞.🤟.🤘.👋.🤚.🖐️.✋.👏.🙌.🤝.🙏.💪.👀.👁️.❤️.🧡.💛.💚.💙.💜.🖤.🤍.💔.💕.💞.💓.💗.💖.💘.💝.💯.✨.⭐.🌟.🔥.💥.💫.⚡.☀️.🌈.🎉.🎊.🎁.🏆.🐶.🐱.🐭.🦊.🐻.🐼.🐨.🦄.🐢.🐳.🍎.🍑.🍓.🍉.🍰.🍺.🍵.☕.🍜.🍙.✅.❌.❓.❗.💤.👑.🎮.🎵.📌.🔖".split("."), De = [
201
206
  "title",
202
207
  "aria-label",
203
208
  "aria-expanded"
204
- ], De = ["innerHTML"], Oe = { class: "kun-editor__picker-panel" }, ke = {
209
+ ], Oe = ["innerHTML"], ke = { class: "kun-editor__picker-panel" }, Ae = {
205
210
  key: 0,
206
211
  class: "kun-editor__picker-tabs",
207
212
  role: "tablist"
208
- }, Ae = ["data-active"], je = ["data-active"], Me = { class: "kun-editor__emoji-grid" }, Ne = ["onClick"], Pe = {
213
+ }, je = ["data-active"], Me = ["data-active"], Ne = { class: "kun-editor__emoji-grid" }, Pe = ["onClick"], Fe = {
209
214
  key: 1,
210
215
  class: "kun-editor__sticker-body"
211
- }, Fe = { class: "kun-editor__pack-name" }, Ie = { class: "kun-editor__sticker-grid" }, Le = ["title", "onClick"], Re = ["src", "alt"], ze = {
216
+ }, Ie = { class: "kun-editor__pack-name" }, Le = { class: "kun-editor__sticker-grid" }, Re = ["title", "onClick"], ze = ["src", "alt"], Be = {
212
217
  key: 1,
213
218
  class: "kun-editor__picker-hint"
214
- }, Be = /* @__PURE__ */ s({
219
+ }, Ve = /* @__PURE__ */ s({
215
220
  __name: "StickerPicker",
216
221
  setup(n) {
217
222
  let [, o] = O(), s = l(q), c = s?.adapters.stickerSource, u = !!c, m = t(() => (s?.locale ?? "zh-cn").toLowerCase().startsWith("en")), _ = t(() => m.value ? {
@@ -247,7 +252,7 @@ var q = Symbol("kun-editor-context"), _e = [
247
252
  n.dispatch(r.tr.insertText(e, r.selection.from));
248
253
  });
249
254
  }, N = (e, t) => {
250
- o()?.action(R(U.key, {
255
+ o()?.action(R(W.key, {
251
256
  src: e,
252
257
  title: t,
253
258
  alt: t
@@ -267,28 +272,28 @@ var q = Symbol("kun-editor-context"), _e = [
267
272
  }, [a("span", {
268
273
  class: "kun-editor__icon",
269
274
  innerHTML: y(X).smile
270
- }, null, 8, De)], 8, Ee), C(a("div", Oe, [
271
- u ? (p(), i("div", ke, [a("button", {
275
+ }, null, 8, Oe)], 8, De), C(a("div", ke, [
276
+ u ? (p(), i("div", Ae, [a("button", {
272
277
  type: "button",
273
278
  class: "kun-editor__picker-tab",
274
279
  "data-active": w.value === "emoji",
275
280
  onClick: n[0] ||= (e) => w.value = "emoji"
276
- }, v(_.value.emoji), 9, Ae), a("button", {
281
+ }, v(_.value.emoji), 9, je), a("button", {
277
282
  type: "button",
278
283
  class: "kun-editor__picker-tab",
279
284
  "data-active": w.value === "sticker",
280
285
  onClick: n[1] ||= (e) => w.value = "sticker"
281
- }, v(_.value.sticker), 9, je)])) : r("", !0),
282
- C(a("div", Me, [(p(!0), i(e, null, g(y(Z), (e, t) => (p(), i("button", {
286
+ }, v(_.value.sticker), 9, Me)])) : r("", !0),
287
+ C(a("div", Ne, [(p(!0), i(e, null, g(y(Z), (e, t) => (p(), i("button", {
283
288
  key: t,
284
289
  type: "button",
285
290
  class: "kun-editor__emoji",
286
291
  onClick: (t) => M(e)
287
- }, v(e), 9, Ne))), 128))], 512), [[b, !u || w.value === "emoji"]]),
288
- u ? C((p(), i("div", Pe, [T.value.length ? (p(!0), i(e, { key: 0 }, g(T.value, (t) => (p(), i("div", {
292
+ }, v(e), 9, Pe))), 128))], 512), [[b, !u || w.value === "emoji"]]),
293
+ u ? C((p(), i("div", Fe, [T.value.length ? (p(!0), i(e, { key: 0 }, g(T.value, (t) => (p(), i("div", {
289
294
  key: t.name,
290
295
  class: "kun-editor__pack"
291
- }, [a("div", Fe, v(t.name), 1), a("div", Ie, [(p(!0), i(e, null, g(t.stickers, (e, t) => (p(), i("button", {
296
+ }, [a("div", Ie, v(t.name), 1), a("div", Le, [(p(!0), i(e, null, g(t.stickers, (e, t) => (p(), i("button", {
292
297
  key: t,
293
298
  type: "button",
294
299
  class: "kun-editor__sticker",
@@ -298,27 +303,27 @@ var q = Symbol("kun-editor-context"), _e = [
298
303
  src: e.src,
299
304
  alt: e.name,
300
305
  loading: "lazy"
301
- }, null, 8, Re)], 8, Le))), 128))])]))), 128)) : (p(), i("div", ze, v(D.value ? _.value.failed : _.value.empty), 1))], 512)), [[b, w.value === "sticker"]]) : r("", !0)
306
+ }, null, 8, ze)], 8, Re))), 128))])]))), 128)) : (p(), i("div", Be, v(D.value ? _.value.failed : _.value.empty), 1))], 512)), [[b, w.value === "sticker"]]) : r("", !0)
302
307
  ], 512), [[b, x.value]])], 512));
303
308
  }
304
- }), Ve = {
309
+ }), He = {
305
310
  class: "kun-editor__format-toolbar",
306
311
  role: "toolbar"
307
- }, He = ["aria-label"], Q = {
312
+ }, Ue = ["aria-label"], We = {
308
313
  value: "",
309
314
  disabled: "",
310
315
  selected: ""
311
- }, Ue = ["value"], We = [
316
+ }, Ge = ["value"], Ke = [
312
317
  "title",
313
318
  "aria-label",
314
319
  "onClick"
315
- ], Ge = ["innerHTML"], Ke = ["title", "aria-label"], qe = ["innerHTML"], Je = /* @__PURE__ */ s({
320
+ ], qe = ["innerHTML"], Je = ["title", "aria-label"], Ye = ["innerHTML"], Q = /* @__PURE__ */ s({
316
321
  __name: "EditorToolbar",
317
322
  setup(n) {
318
- let [, s] = O(), c = l(q), u = t(() => c?.adapters.uploadImage), d = () => c?.adapters.notify, f = t(() => c?.features.sticker !== !1), m = t(() => (c?.locale ?? "zh-cn").toLowerCase().startsWith("en")), _ = (e, t) => {
323
+ let [, s] = O(), c = l(q), u = t(() => c?.adapters.uploadImage), d = t(() => c?.features.sticker !== !1), f = t(() => (c?.locale ?? "zh-cn").toLowerCase().startsWith("en")), m = (e, t) => {
319
324
  s()?.action(R(e, t));
320
- }, b = t(() => {
321
- let e = m.value;
325
+ }, _ = t(() => {
326
+ let e = f.value;
322
327
  return {
323
328
  textSize: e ? "Text size" : "文本大小",
324
329
  bold: e ? "Bold" : "加粗",
@@ -333,8 +338,8 @@ var q = Symbol("kun-editor-context"), _e = [
333
338
  spoiler: e ? "Spoiler" : "隐藏文本",
334
339
  image: e ? "Upload image" : "上传图片"
335
340
  };
336
- }), x = t(() => {
337
- let e = m.value;
341
+ }), b = t(() => {
342
+ let e = f.value;
338
343
  return [
339
344
  "正文",
340
345
  "一级标题",
@@ -347,89 +352,86 @@ var q = Symbol("kun-editor-context"), _e = [
347
352
  level: n,
348
353
  label: e ? n === 0 ? "Paragraph" : `Heading ${n}` : t
349
354
  }));
350
- }), S = (e) => {
355
+ }), x = (e) => {
351
356
  let t = e.target;
352
- _(oe.key, Number(t.value)), t.selectedIndex = 0;
353
- }, C = t(() => [
357
+ m(se.key, Number(t.value)), t.selectedIndex = 0;
358
+ }, S = t(() => [
354
359
  [
355
360
  {
356
361
  svg: X.bold,
357
- title: b.value.bold,
358
- run: () => _(le.key)
362
+ title: _.value.bold,
363
+ run: () => m(ue.key)
359
364
  },
360
365
  {
361
366
  svg: X.italic,
362
- title: b.value.italic,
363
- run: () => _(W.key)
367
+ title: _.value.italic,
368
+ run: () => m(G.key)
364
369
  },
365
370
  {
366
371
  svg: X.strike,
367
- title: b.value.strike,
368
- run: () => _(pe.key)
372
+ title: _.value.strike,
373
+ run: () => m(me.key)
369
374
  },
370
375
  {
371
376
  svg: X.code,
372
- title: b.value.code,
373
- run: () => _(G.key)
377
+ title: _.value.code,
378
+ run: () => m(le.key)
374
379
  }
375
380
  ],
376
381
  [
377
382
  {
378
383
  svg: X.bulletList,
379
- title: b.value.bulletList,
380
- run: () => _(de.key)
384
+ title: _.value.bulletList,
385
+ run: () => m(fe.key)
381
386
  },
382
387
  {
383
388
  svg: X.orderedList,
384
- title: b.value.orderedList,
385
- run: () => _(fe.key)
389
+ title: _.value.orderedList,
390
+ run: () => m(pe.key)
386
391
  },
387
392
  {
388
393
  svg: X.quote,
389
- title: b.value.quote,
390
- run: () => _(ue.key)
394
+ title: _.value.quote,
395
+ run: () => m(de.key)
391
396
  },
392
397
  {
393
398
  svg: X.codeBlock,
394
- title: b.value.codeBlock,
395
- run: () => _(ce.key, "")
399
+ title: _.value.codeBlock,
400
+ run: () => m(H.key, "")
396
401
  },
397
402
  {
398
403
  svg: X.hr,
399
- title: b.value.hr,
400
- run: () => _(H.key)
404
+ title: _.value.hr,
405
+ run: () => m(U.key)
401
406
  }
402
407
  ],
403
408
  [{
404
409
  svg: X.spoiler,
405
- title: b.value.spoiler,
406
- run: () => _(re.key)
410
+ title: _.value.spoiler,
411
+ run: () => m(ie.key)
407
412
  }]
408
- ]), w = h(null), T = () => w.value?.click(), E = async (e) => {
413
+ ]), C = h(null), w = () => C.value?.click(), T = (e) => {
409
414
  let t = e.target, n = t.files?.[0];
410
415
  t.value = "";
411
416
  let r = u.value;
412
- if (!(!n || !r)) try {
413
- let e = await r(n);
414
- _(U.key, {
415
- src: e,
416
- title: n.name,
417
- alt: n.name
417
+ !n || !r || s()?.action((e) => {
418
+ V(e.get(P), n, {
419
+ uploadImage: r,
420
+ notify: c?.adapters.notify,
421
+ locale: c?.locale
418
422
  });
419
- } catch {
420
- d()?.(m.value ? "Image upload failed" : "图片上传失败", "error");
421
- }
423
+ });
422
424
  };
423
- return (t, n) => (p(), i("div", Ve, [
425
+ return (t, n) => (p(), i("div", He, [
424
426
  a("select", {
425
427
  class: "kun-editor__heading-select",
426
- "aria-label": b.value.textSize,
427
- onChange: S
428
- }, [a("option", Q, v(b.value.textSize), 1), (p(!0), i(e, null, g(x.value, (e) => (p(), i("option", {
428
+ "aria-label": _.value.textSize,
429
+ onChange: x
430
+ }, [a("option", We, v(_.value.textSize), 1), (p(!0), i(e, null, g(b.value, (e) => (p(), i("option", {
429
431
  key: e.level,
430
432
  value: e.level
431
- }, v(e.label), 9, Ue))), 128))], 40, He),
432
- (p(!0), i(e, null, g(C.value, (t, r) => (p(), i(e, { key: r }, [n[0] ||= a("span", {
433
+ }, v(e.label), 9, Ge))), 128))], 40, Ue),
434
+ (p(!0), i(e, null, g(S.value, (t, r) => (p(), i(e, { key: r }, [n[0] ||= a("span", {
433
435
  class: "kun-editor__toolbar-divider",
434
436
  "aria-hidden": "true"
435
437
  }, null, -1), (p(!0), i(e, null, g(t, (e, t) => (p(), i("button", {
@@ -442,7 +444,7 @@ var q = Symbol("kun-editor-context"), _e = [
442
444
  }, [a("span", {
443
445
  class: "kun-editor__icon",
444
446
  innerHTML: e.svg
445
- }, null, 8, Ge)], 8, We))), 128))], 64))), 128)),
447
+ }, null, 8, qe)], 8, Ke))), 128))], 64))), 128)),
446
448
  u.value ? (p(), i(e, { key: 0 }, [
447
449
  n[1] ||= a("span", {
448
450
  class: "kun-editor__toolbar-divider",
@@ -451,29 +453,29 @@ var q = Symbol("kun-editor-context"), _e = [
451
453
  a("button", {
452
454
  type: "button",
453
455
  class: "kun-editor__tool",
454
- title: b.value.image,
455
- "aria-label": b.value.image,
456
- onClick: T
456
+ title: _.value.image,
457
+ "aria-label": _.value.image,
458
+ onClick: w
457
459
  }, [a("span", {
458
460
  class: "kun-editor__icon",
459
461
  innerHTML: y(X).image
460
- }, null, 8, qe)], 8, Ke),
462
+ }, null, 8, Ye)], 8, Je),
461
463
  a("input", {
462
464
  ref_key: "fileInput",
463
- ref: w,
465
+ ref: C,
464
466
  type: "file",
465
467
  accept: ".jpg,.jpeg,.png,.webp,.gif",
466
468
  hidden: "",
467
- onChange: E
469
+ onChange: T
468
470
  }, null, 544)
469
471
  ], 64)) : r("", !0),
470
- f.value ? (p(), i(e, { key: 1 }, [n[2] ||= a("span", {
472
+ d.value ? (p(), i(e, { key: 1 }, [n[2] ||= a("span", {
471
473
  class: "kun-editor__toolbar-divider",
472
474
  "aria-hidden": "true"
473
- }, null, -1), o(Be)], 64)) : r("", !0)
475
+ }, null, -1), o(Ve)], 64)) : r("", !0)
474
476
  ]));
475
477
  }
476
- }), Ye = /* @__PURE__ */ s({
478
+ }), Xe = /* @__PURE__ */ s({
477
479
  __name: "ToolbarHost",
478
480
  setup(e) {
479
481
  let [, t] = O(), n = l(q, void 0), r = (e, n) => {
@@ -488,11 +490,21 @@ var q = Symbol("kun-editor-context"), _e = [
488
490
  n.dispatch(n.state.tr.insertText(e));
489
491
  }), i();
490
492
  },
493
+ uploadImage: (e) => {
494
+ let r = n?.adapters.uploadImage, i = t();
495
+ !r || !i || i.action((t) => {
496
+ V(t.get(P), e, {
497
+ uploadImage: r,
498
+ notify: n?.adapters.notify,
499
+ locale: n?.locale
500
+ });
501
+ });
502
+ },
491
503
  insertQuote: (e) => {
492
- r(V.key, e), i();
504
+ r(B.key, e), i();
493
505
  },
494
506
  insertMention: (e) => {
495
- r(B.key, e), i();
507
+ r(z.key, e), i();
496
508
  },
497
509
  focus: i,
498
510
  get adapters() {
@@ -507,7 +519,7 @@ var q = Symbol("kun-editor-context"), _e = [
507
519
  };
508
520
  return (e, t) => _(e.$slots, "default", u(c(a)));
509
521
  }
510
- }), Xe = /* @__PURE__ */ s({
522
+ }), Ze = /* @__PURE__ */ s({
511
523
  __name: "MarkdownSource",
512
524
  props: {
513
525
  modelValue: {},
@@ -515,13 +527,13 @@ var q = Symbol("kun-editor-context"), _e = [
515
527
  },
516
528
  emits: ["update:modelValue"],
517
529
  setup(e, { emit: t }) {
518
- let n = e, r = t, a = h(null), o = null, s = (e) => me.create({
530
+ let n = e, r = t, a = h(null), o = null, s = (e) => he.create({
519
531
  doc: e,
520
532
  extensions: [
521
- ie(),
533
+ ae(),
522
534
  K.lineWrapping,
523
- ge,
524
- he(),
535
+ _e,
536
+ ge(),
525
537
  K.editable.of(!n.readonly),
526
538
  K.updateListener.of((e) => {
527
539
  e.docChanged && r("update:modelValue", e.state.doc.toString());
@@ -543,13 +555,10 @@ var q = Symbol("kun-editor-context"), _e = [
543
555
  class: "kun-editor__source"
544
556
  }, null, 512));
545
557
  }
546
- }), Ze = {
547
- class: "kun-editor",
548
- "data-kun-editor": ""
549
- }, Qe = {
558
+ }), Qe = ["data-mode"], $e = {
550
559
  class: "kun-editor__toolbar",
551
560
  role: "tablist"
552
- }, $e = ["aria-selected", "data-active"], et = ["aria-selected", "data-active"], tt = { class: "kun-editor__wysiwyg" }, $ = /* @__PURE__ */ s({
561
+ }, et = ["aria-selected", "data-active"], tt = ["aria-selected", "data-active"], nt = ["aria-selected", "data-active"], rt = ["title", "aria-label"], it = ["data-swap"], at = { class: "kun-editor__wysiwyg kun-editor__pane" }, $ = /* @__PURE__ */ s({
553
562
  __name: "KunEditor",
554
563
  props: {
555
564
  modelValue: {},
@@ -578,72 +587,102 @@ var q = Symbol("kun-editor-context"), _e = [
578
587
  });
579
588
  let g = h("wysiwyg"), x = (e) => {
580
589
  g.value = e;
581
- }, w = t(() => d.locale.toLowerCase().startsWith("en")), T = t(() => w.value ? {
590
+ }, w = h(!1), T = () => {
591
+ w.value = !w.value;
592
+ }, D = t(() => d.locale.toLowerCase().startsWith("en")), O = t(() => D.value ? {
582
593
  wysiwyg: "Preview",
583
- source: "Markdown"
594
+ source: "Markdown",
595
+ split: "Split",
596
+ swap: "Swap sides"
584
597
  } : {
585
598
  wysiwyg: "预览",
586
- source: "Markdown"
587
- }), D = (e) => f("update:modelValue", e), O = h(null);
599
+ source: "Markdown",
600
+ split: "分栏",
601
+ swap: "左右互换"
602
+ }), A = t(() => d.readonly || g.value === "split"), j = (e) => f("update:modelValue", e), M = h(null);
588
603
  return s({
589
- insertQuote: (e) => O.value?.insertQuote(e),
590
- insertMention: (e) => O.value?.insertMention(e),
591
- focus: () => O.value?.focus()
592
- }), (t, s) => (p(), i("div", Ze, [
593
- _(t.$slots, "view-switch", {
594
- mode: g.value,
595
- setMode: x,
596
- labels: T.value
597
- }, () => [a("div", Qe, [a("button", {
604
+ insertQuote: (e) => M.value?.insertQuote(e),
605
+ insertMention: (e) => M.value?.insertMention(e),
606
+ focus: () => M.value?.focus()
607
+ }), (t, s) => (p(), i("div", {
608
+ class: "kun-editor",
609
+ "data-kun-editor": "",
610
+ "data-mode": g.value
611
+ }, [_(t.$slots, "view-switch", {
612
+ mode: g.value,
613
+ setMode: x,
614
+ labels: O.value,
615
+ swapped: w.value,
616
+ swap: T
617
+ }, () => [a("div", $e, [
618
+ a("button", {
598
619
  type: "button",
599
620
  class: "kun-editor__tab",
600
621
  "aria-selected": g.value === "wysiwyg",
601
622
  "data-active": g.value === "wysiwyg",
602
623
  onClick: s[0] ||= (e) => x("wysiwyg")
603
- }, v(T.value.wysiwyg), 9, $e), a("button", {
624
+ }, v(O.value.wysiwyg), 9, et),
625
+ a("button", {
604
626
  type: "button",
605
627
  class: "kun-editor__tab",
606
628
  "aria-selected": g.value === "source",
607
629
  "data-active": g.value === "source",
608
630
  onClick: s[1] ||= (e) => x("source")
609
- }, v(T.value.source), 9, et)])]),
610
- o(y(E), null, {
611
- default: S(() => [o(y(k), null, {
612
- default: S(() => [C(a("div", null, [o(Ye, null, {
613
- default: S((e) => [_(t.$slots, "toolbar", u(c(e)), () => [o(Je)])]),
614
- _: 3
615
- })], 512), [[b, g.value === "wysiwyg" && !e.readonly]]), C(a("div", tt, [o(Te, {
616
- ref_key: "inner",
617
- ref: O,
618
- "model-value": e.modelValue,
619
- adapters: e.adapters,
620
- features: e.features,
621
- locale: e.locale,
622
- readonly: e.readonly,
623
- placeholder: e.placeholder,
624
- "onUpdate:modelValue": D
625
- }, null, 8, [
626
- "model-value",
627
- "adapters",
628
- "features",
629
- "locale",
630
- "readonly",
631
- "placeholder"
632
- ])], 512), [[b, g.value === "wysiwyg"]])]),
631
+ }, v(O.value.source), 9, tt),
632
+ a("button", {
633
+ type: "button",
634
+ class: "kun-editor__tab",
635
+ "aria-selected": g.value === "split",
636
+ "data-active": g.value === "split",
637
+ onClick: s[2] ||= (e) => x("split")
638
+ }, v(O.value.split), 9, nt),
639
+ g.value === "split" ? (p(), i("button", {
640
+ key: 0,
641
+ type: "button",
642
+ class: "kun-editor__tab kun-editor__swap",
643
+ title: O.value.swap,
644
+ "aria-label": O.value.swap,
645
+ onClick: s[3] ||= (e) => T()
646
+ }, "", 8, rt)) : r("", !0)
647
+ ])]), o(y(E), null, {
648
+ default: S(() => [o(y(k), null, {
649
+ default: S(() => [C(a("div", null, [o(Xe, null, {
650
+ default: S((e) => [_(t.$slots, "toolbar", u(c(e)), () => [o(Q)])]),
633
651
  _: 3
634
- })]),
652
+ })], 512), [[b, g.value === "wysiwyg" && !e.readonly]]), a("div", {
653
+ class: "kun-editor__panes",
654
+ "data-swap": w.value
655
+ }, [g.value === "source" || g.value === "split" ? (p(), n(Ze, {
656
+ key: 0,
657
+ class: "kun-editor__pane",
658
+ "model-value": e.modelValue,
659
+ readonly: e.readonly,
660
+ "onUpdate:modelValue": j
661
+ }, null, 8, ["model-value", "readonly"])) : r("", !0), C(a("div", at, [o(Ee, {
662
+ ref_key: "inner",
663
+ ref: M,
664
+ "model-value": e.modelValue,
665
+ adapters: e.adapters,
666
+ features: e.features,
667
+ locale: e.locale,
668
+ readonly: A.value,
669
+ placeholder: e.placeholder,
670
+ "onUpdate:modelValue": j
671
+ }, null, 8, [
672
+ "model-value",
673
+ "adapters",
674
+ "features",
675
+ "locale",
676
+ "readonly",
677
+ "placeholder"
678
+ ])], 512), [[b, g.value === "wysiwyg" || g.value === "split"]])], 8, it)]),
635
679
  _: 3
636
- }),
637
- g.value === "source" ? (p(), n(Xe, {
638
- key: 0,
639
- "model-value": e.modelValue,
640
- readonly: e.readonly,
641
- "onUpdate:modelValue": D
642
- }, null, 8, ["model-value", "readonly"])) : r("", !0)
643
- ]));
680
+ })]),
681
+ _: 3
682
+ })], 8, Qe));
644
683
  }
645
- }), nt = { install(e) {
684
+ }), ot = { install(e) {
646
685
  e.component("KunEditor", $);
647
686
  } };
648
687
  //#endregion
649
- export { Z as EMOJI, $ as KunEditor, nt as KunEditorPlugin };
688
+ export { Z as EMOJI, $ as KunEditor, ot as KunEditorPlugin };
package/dist/types.d.ts CHANGED
@@ -5,6 +5,12 @@ export interface KunEditorToolbarApi {
5
5
  run: <T>(key: CmdKey<T>, payload?: T) => void;
6
6
  /** Insert plain text at the cursor (e.g. an emoji). */
7
7
  insertText: (text: string) => void;
8
+ /**
9
+ * Upload an image File via the `uploadImage` adapter, showing an in-document
10
+ * "uploading…" placeholder at the caret until it resolves (then the image), or
11
+ * removing it + notifying on failure. No-op without an `uploadImage` adapter.
12
+ */
13
+ uploadImage: (file: File) => void;
8
14
  /** Insert a reference atom at the cursor (requires the quote feature). */
9
15
  insertQuote: (payload: {
10
16
  refId: string;
@@ -25,15 +31,21 @@ export interface KunEditorToolbarApi {
25
31
  readonly locale: KunEditorLocale;
26
32
  }
27
33
  export interface KunEditorViewSwitchApi {
28
- /** The active view. */
29
- mode: 'wysiwyg' | 'source';
34
+ /** The active view: WYSIWYG, markdown source, or the desktop split. */
35
+ mode: 'wysiwyg' | 'source' | 'split';
30
36
  /** Switch the active view. */
31
- setMode: (mode: 'wysiwyg' | 'source') => void;
32
- /** Localized labels for the two views (respects the `locale` prop). */
37
+ setMode: (mode: 'wysiwyg' | 'source' | 'split') => void;
38
+ /** Localized labels (respects the `locale` prop). */
33
39
  labels: {
34
40
  wysiwyg: string;
35
41
  source: string;
42
+ split: string;
43
+ swap: string;
36
44
  };
45
+ /** Whether the split panes are swapped (source on the right). */
46
+ swapped: boolean;
47
+ /** Toggle the split panes' left/right order. */
48
+ swap: () => void;
37
49
  }
38
50
  export interface KunEditorExpose {
39
51
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAM5B,MAAM,WAAW,mBAAmB;IAClC,8EAA8E;IAC9E,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,IAAI,CAAA;IAC7C,uDAAuD;IACvD,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC,0EAA0E;IAC1E,WAAW,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAChE,6CAA6C;IAC7C,aAAa,EAAE,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAClE,gCAAgC;IAChC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IACpC,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IACpC,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;CACjC;AAMD,MAAM,WAAW,sBAAsB;IACrC,uBAAuB;IACvB,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAA;IAC1B,8BAA8B;IAC9B,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,KAAK,IAAI,CAAA;IAC7C,uEAAuE;IACvE,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5C;AASD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAC5D;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAC9D,gCAAgC;IAChC,KAAK,IAAI,IAAI,CAAA;CACd"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAM5B,MAAM,WAAW,mBAAmB;IAClC,8EAA8E;IAC9E,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,KAAK,IAAI,CAAA;IAC7C,uDAAuD;IACvD,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC;;;;OAIG;IACH,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAA;IACjC,0EAA0E;IAC1E,WAAW,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAChE,6CAA6C;IAC7C,aAAa,EAAE,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAClE,gCAAgC;IAChC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IACpC,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IACpC,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;CACjC;AAMD,MAAM,WAAW,sBAAsB;IACrC,uEAAuE;IACvE,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;IACpC,8BAA8B;IAC9B,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,KAAK,IAAI,CAAA;IACvD,qDAAqD;IACrD,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IACxE,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAA;IAChB,gDAAgD;IAChD,IAAI,EAAE,MAAM,IAAI,CAAA;CACjB;AASD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,WAAW,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAC5D;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAC9D,gCAAgC;IAChC,KAAK,IAAI,IAAI,CAAA;CACd"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungal/editor-vue",
3
- "version": "0.17.0",
3
+ "version": "0.19.0",
4
4
  "description": "KunEditor Vue 3 layer — the headless <KunEditor> component (dual WYSIWYG / markdown-source), toolbar and plugin views. Ships zero CSS and no UI-kit dependency; consumes @kungal/editor-core, and pairs with @kungal/editor-nuxt for optional KunUI chrome.",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@prosemirror-adapter/vue": "^0.4.6",
43
- "@kungal/editor-core": "0.17.0"
43
+ "@kungal/editor-core": "0.19.0"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@codemirror/lang-markdown": "^6.0.0",
@@ -80,7 +80,7 @@
80
80
  "vite": "^8.0.16",
81
81
  "vue": "^3.5.35",
82
82
  "vue-tsc": "^3.3.3",
83
- "@kungal/editor-core": "0.17.0"
83
+ "@kungal/editor-core": "0.19.0"
84
84
  },
85
85
  "scripts": {
86
86
  "build": "vite build && vue-tsc -p tsconfig.build.json",