@kungal/editor-vue 0.6.0 → 0.8.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 +45 -0
- package/README.md +24 -16
- package/dist/components/EditorToolbar.vue.d.ts.map +1 -1
- package/dist/components/KunEditor.vue.d.ts.map +1 -1
- package/dist/components/MarkdownSource.vue.d.ts +12 -0
- package/dist/components/MarkdownSource.vue.d.ts.map +1 -0
- package/dist/components/MentionDropdown.vue.d.ts.map +1 -1
- package/dist/components/StickerPicker.vue.d.ts.map +1 -1
- package/dist/index.js +114 -80
- package/package.json +27 -10
- package/dist/style.css +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# @kungal/editor-vue
|
|
2
2
|
|
|
3
|
+
## 0.8.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- c0908c5: Make `<KunEditor>` headless — ship zero CSS.
|
|
8
|
+
|
|
9
|
+
**BREAKING** (pre-1.0): the `@kungal/editor-vue/style.css` export is removed. The
|
|
10
|
+
component now renders only stable class hooks (`.kun-editor__*`,
|
|
11
|
+
`.kun-mention-dropdown*`) and `data-*` state; all styling is the host's.
|
|
12
|
+
|
|
13
|
+
Migration: copy the reference stylesheet
|
|
14
|
+
`apps/docs/app/assets/css/kun-editor.css` (themed with KunUI tokens) into your
|
|
15
|
+
app and import it, or write your own targeting the same hooks. Also import each
|
|
16
|
+
enabled peer's CSS (e.g. `katex/dist/katex.min.css`). The reference stylesheet
|
|
17
|
+
carries the two structural rules the editor needs (ProseMirror `white-space`,
|
|
18
|
+
popover positioning / show-hide).
|
|
19
|
+
|
|
20
|
+
Also drops the unused `@kungal/ui-vue` peer dependency — the editor no longer
|
|
21
|
+
references any UI kit, so it installs in any Vue 3 app.
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- @kungal/editor-core@0.8.0
|
|
26
|
+
|
|
27
|
+
## 0.7.0
|
|
28
|
+
|
|
29
|
+
### Minor Changes
|
|
30
|
+
|
|
31
|
+
- 4968c96: P3 (complete) — replace the source-mode `<textarea>` with a CodeMirror editor.
|
|
32
|
+
|
|
33
|
+
The "Markdown" tab is now a real CodeMirror editor with markdown syntax
|
|
34
|
+
highlighting, reusing the code block's `kunCM` theme (from
|
|
35
|
+
`@kungal/editor-core`) so the source view and code blocks match. Edits sync back
|
|
36
|
+
through `v-model` to the WYSIWYG view; the view is mounted on demand (CodeMirror
|
|
37
|
+
measures poorly while hidden).
|
|
38
|
+
|
|
39
|
+
Adds `@codemirror/lang-markdown` alongside the CodeMirror packages the editor
|
|
40
|
+
already needs (declared as optional peers; externalized from the build so the
|
|
41
|
+
host dedupes them). This finishes the P3 dual-view editor: WYSIWYG + toolbar +
|
|
42
|
+
@mention dropdown + sticker/emoji picker + CodeMirror source.
|
|
43
|
+
|
|
44
|
+
### Patch Changes
|
|
45
|
+
|
|
46
|
+
- @kungal/editor-core@0.7.0
|
|
47
|
+
|
|
3
48
|
## 0.6.0
|
|
4
49
|
|
|
5
50
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -2,18 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
The **Vue 3 render layer** of KunEditor: the `<KunEditor>` component (dual
|
|
4
4
|
WYSIWYG preview + markdown-source), its toolbar and the Vue plugin views
|
|
5
|
-
(mention dropdown,
|
|
6
|
-
[`@kungal/editor-core`](../editor-core) for the plugin brain
|
|
7
|
-
[`@kungal/ui-vue`](https://github.com/kungal/kun-ui) for the chrome.
|
|
5
|
+
(mention dropdown, sticker/emoji picker). Consumes
|
|
6
|
+
[`@kungal/editor-core`](../editor-core) for the plugin brain.
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
**Headless — ships zero CSS.** The component only renders stable class hooks
|
|
9
|
+
(`.kun-editor__*`, `.kun-mention-dropdown*`) + `data-*` state; you own the look.
|
|
10
|
+
Copy the reference stylesheet [`apps/docs/app/assets/css/kun-editor.css`](../../apps/docs/app/assets/css/kun-editor.css)
|
|
11
|
+
(themed with KunUI tokens), or write your own. It works in any Vue 3 app;
|
|
12
|
+
`@kungal/editor-nuxt` adds Nuxt auto-import sugar.
|
|
10
13
|
|
|
11
14
|
## Usage
|
|
12
15
|
|
|
13
16
|
```vue
|
|
14
17
|
<script setup lang="ts">
|
|
15
18
|
import { KunEditor, type KunEditorAdapters } from '@kungal/editor-vue'
|
|
16
|
-
|
|
19
|
+
// Headless: bring your own styles. See apps/docs for the KunUI-themed reference.
|
|
20
|
+
import '~/assets/kun-editor.css'
|
|
17
21
|
|
|
18
22
|
const markdown = ref('')
|
|
19
23
|
|
|
@@ -38,21 +42,21 @@ no other config.
|
|
|
38
42
|
Install the Milkdown stack **once in the host** (single ProseMirror instance):
|
|
39
43
|
|
|
40
44
|
```bash
|
|
41
|
-
pnpm add @kungal/editor-vue @kungal/editor-core \
|
|
42
|
-
@kungal/ui-vue vue \
|
|
45
|
+
pnpm add @kungal/editor-vue @kungal/editor-core vue \
|
|
43
46
|
@milkdown/kit @milkdown/prose @milkdown/vue
|
|
44
47
|
```
|
|
45
48
|
|
|
46
|
-
Enable optional plugins by also installing their peers: `katex` (LaTeX
|
|
47
|
-
`
|
|
49
|
+
Enable optional plugins by also installing their peers: `katex` (LaTeX, also
|
|
50
|
+
import `katex/dist/katex.min.css`), the `@codemirror/*` packages + `codemirror`
|
|
51
|
+
(code blocks and the markdown-source view).
|
|
48
52
|
|
|
49
53
|
## Status
|
|
50
54
|
|
|
51
|
-
**P3
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
**P3 complete.** `<KunEditor>` is a **real Milkdown dual-view editor**: a WYSIWYG
|
|
56
|
+
view built from `@kungal/editor-core/preset` (`createKunEditorPlugins` — spoiler /
|
|
57
|
+
katex / code-block / mention / upload / …) and a CodeMirror markdown-source view,
|
|
58
|
+
over one `v-model`. The prop/emit surface (`v-model`, `adapters`, `features`,
|
|
59
|
+
`locale`, `readonly`) is stable.
|
|
56
60
|
|
|
57
61
|
A **formatting toolbar** is wired: bold / italic / strikethrough / inline code,
|
|
58
62
|
H1–H3, bullet & ordered lists, blockquote, code block, divider, spoiler, LaTeX —
|
|
@@ -70,8 +74,12 @@ The **sticker / emoji picker** is a toolbar popover: a built-in emoji tab
|
|
|
70
74
|
host supplies `stickerSource`, inserting each sticker as an image node. Turn the
|
|
71
75
|
whole picker off with `features.sticker: false`.
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
The **markdown-source view** (the "Markdown" tab) is a CodeMirror editor with
|
|
78
|
+
markdown highlighting, sharing the code block's `kunCM` theme. Edits sync back
|
|
79
|
+
through `v-model` to the WYSIWYG view.
|
|
80
|
+
|
|
81
|
+
Next: **P4** — adopt in the forum, replacing its in-repo `components/kun/milkdown`
|
|
82
|
+
with real adapters. See
|
|
75
83
|
[`../../docs/architecture.md`](../../docs/architecture.md) § migration.
|
|
76
84
|
|
|
77
85
|
## Build
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorToolbar.vue.d.ts","sourceRoot":"","sources":["../../src/components/EditorToolbar.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"EditorToolbar.vue.d.ts","sourceRoot":"","sources":["../../src/components/EditorToolbar.vue"],"names":[],"mappings":"AAgZA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KunEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/KunEditor.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"KunEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/KunEditor.vue"],"names":[],"mappings":"AA6JA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAM5B,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;CACnB,CAAC;AAuMJ,QAAA,MAAM,YAAY;;;;;cA9MH,iBAAiB;cAEjB,iBAAiB;YAEnB,eAAe;cAEb,OAAO;6EA4MpB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
modelValue: string;
|
|
3
|
+
readonly: boolean;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
6
|
+
"update:modelValue": (markdown: string) => any;
|
|
7
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
8
|
+
"onUpdate:modelValue"?: ((markdown: string) => any) | undefined;
|
|
9
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
10
|
+
declare const _default: typeof __VLS_export;
|
|
11
|
+
export default _default;
|
|
12
|
+
//# sourceMappingURL=MarkdownSource.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownSource.vue.d.ts","sourceRoot":"","sources":["../../src/components/MarkdownSource.vue"],"names":[],"mappings":"AA2FA,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;CAClB,CAAC;AA2EF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MentionDropdown.vue.d.ts","sourceRoot":"","sources":["../../src/components/MentionDropdown.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MentionDropdown.vue.d.ts","sourceRoot":"","sources":["../../src/components/MentionDropdown.vue"],"names":[],"mappings":"AAulBA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StickerPicker.vue.d.ts","sourceRoot":"","sources":["../../src/components/StickerPicker.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StickerPicker.vue.d.ts","sourceRoot":"","sources":["../../src/components/StickerPicker.vue"],"names":[],"mappings":"AA8aA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
package/dist/index.js
CHANGED
|
@@ -5,28 +5,32 @@ import { Editor as k, defaultValueCtx as A, editorViewCtx as j, editorViewOption
|
|
|
5
5
|
import { listenerCtx as P } from "@milkdown/kit/plugin/listener";
|
|
6
6
|
import { SlashProvider as ee, slashFactory as F } from "@milkdown/kit/plugin/slash";
|
|
7
7
|
import { callCommand as I, replaceAll as L } from "@milkdown/kit/utils";
|
|
8
|
-
import { createKunEditorPlugins as
|
|
9
|
-
import { TextSelection as
|
|
10
|
-
import { createCodeBlockCommand as
|
|
11
|
-
import { toggleStrikethroughCommand as
|
|
8
|
+
import { createKunEditorPlugins as R, insertKunSpoilerCommand as te, kunCM as ne, mentionId as re, toggleLatexCommand as ie } from "@kungal/editor-core/preset";
|
|
9
|
+
import { TextSelection as ae } from "@milkdown/kit/prose/state";
|
|
10
|
+
import { createCodeBlockCommand as oe, insertHrCommand as se, insertImageCommand as z, toggleEmphasisCommand as B, toggleInlineCodeCommand as V, toggleStrongCommand as H, wrapInBlockquoteCommand as U, wrapInBulletListCommand as W, wrapInHeadingCommand as G, wrapInOrderedListCommand as K } from "@milkdown/kit/preset/commonmark";
|
|
11
|
+
import { toggleStrikethroughCommand as ce } from "@milkdown/kit/preset/gfm";
|
|
12
|
+
import { EditorState as le } from "@codemirror/state";
|
|
13
|
+
import { EditorView as q } from "@codemirror/view";
|
|
14
|
+
import { markdown as ue } from "@codemirror/lang-markdown";
|
|
15
|
+
import { basicSetup as de } from "codemirror";
|
|
12
16
|
//#region src/context.ts
|
|
13
|
-
var J = Symbol("kun-editor-context"),
|
|
17
|
+
var J = Symbol("kun-editor-context"), fe = [
|
|
14
18
|
"data-active",
|
|
15
19
|
"onMousedown",
|
|
16
20
|
"onMouseenter"
|
|
17
|
-
],
|
|
21
|
+
], pe = ["src", "alt"], me = {
|
|
18
22
|
key: 1,
|
|
19
23
|
class: "kun-mention-dropdown__avatar kun-mention-dropdown__avatar--fallback"
|
|
20
|
-
},
|
|
24
|
+
}, he = { class: "kun-mention-dropdown__name" }, ge = {
|
|
21
25
|
key: 1,
|
|
22
26
|
class: "kun-mention-dropdown__hint"
|
|
23
|
-
},
|
|
27
|
+
}, _e = {
|
|
24
28
|
key: 2,
|
|
25
29
|
class: "kun-mention-dropdown__hint"
|
|
26
|
-
},
|
|
30
|
+
}, ve = {
|
|
27
31
|
key: 3,
|
|
28
32
|
class: "kun-mention-dropdown__hint"
|
|
29
|
-
},
|
|
33
|
+
}, ye = /* @__PURE__ */ s({
|
|
30
34
|
__name: "MentionDropdown",
|
|
31
35
|
setup(n) {
|
|
32
36
|
let r = /(?:^|\s)@([^\s@]{0,30})$/, o = c(J), s = o?.adapters.searchMentionUsers, f = t(() => (o?.locale ?? "zh-cn").toLowerCase().startsWith("en")), g = t(() => f.value ? {
|
|
@@ -69,13 +73,13 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
69
73
|
}, I = (e) => {
|
|
70
74
|
let t = _.value;
|
|
71
75
|
if (!t || !k) return;
|
|
72
|
-
let n = t.state.schema.nodes[
|
|
76
|
+
let n = t.state.schema.nodes[re];
|
|
73
77
|
if (!n) return;
|
|
74
78
|
let r = n.create({
|
|
75
79
|
userId: e.id,
|
|
76
80
|
name: e.name
|
|
77
81
|
}), { from: i, to: a } = k, o = t.state.tr.replaceWith(i, a, r), s = i + r.nodeSize;
|
|
78
|
-
o.insertText(" ", s), o.setSelection(
|
|
82
|
+
o.insertText(" ", s), o.setSelection(ae.create(o.doc, s + 1)), t.dispatch(o.scrollIntoView()), t.focus(), S.hide();
|
|
79
83
|
}, L = (e) => {
|
|
80
84
|
if (!C.value || !T.value.length) {
|
|
81
85
|
C.value && e.key === "Escape" && (e.preventDefault(), S.hide());
|
|
@@ -132,9 +136,9 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
132
136
|
src: e.avatar,
|
|
133
137
|
alt: e.name,
|
|
134
138
|
class: "kun-mention-dropdown__avatar"
|
|
135
|
-
}, null, 8,
|
|
139
|
+
}, null, 8, pe)) : (d(), i("span", me, h(e.name.charAt(0)), 1)), a("span", he, h(e.name), 1)], 40, fe))), 128)) : O.value ? (d(), i("div", ge, h(g.value.searching), 1)) : w.value ? (d(), i("div", _e, h(g.value.empty), 1)) : (d(), i("div", ve, h(g.value.prompt), 1))], 512));
|
|
136
140
|
}
|
|
137
|
-
}),
|
|
141
|
+
}), be = /* @__PURE__ */ s({
|
|
138
142
|
__name: "MilkdownEditor",
|
|
139
143
|
props: {
|
|
140
144
|
modelValue: {},
|
|
@@ -152,8 +156,8 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
152
156
|
}), t.update(M, (e) => ({
|
|
153
157
|
...e,
|
|
154
158
|
editable: () => !r.readonly
|
|
155
|
-
})), c && t.set(s.key, { view: o({ component:
|
|
156
|
-
}).use(
|
|
159
|
+
})), c && t.set(s.key, { view: o({ component: ye }) });
|
|
160
|
+
}).use(R(r.adapters, r.features, { locale: r.locale }));
|
|
157
161
|
return c && t.use(s), t;
|
|
158
162
|
});
|
|
159
163
|
return v(() => r.modelValue, (e) => {
|
|
@@ -177,21 +181,21 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
177
181
|
spoiler: Y("<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\"/>"),
|
|
178
182
|
latex: X("Σ", 15),
|
|
179
183
|
smile: Y("<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\"/>")
|
|
180
|
-
},
|
|
184
|
+
}, xe = /* @__PURE__ */ "😀.😃.😄.😁.😆.😅.🤣.😂.🙂.🙃.😉.😊.😇.🥰.😍.🤩.😘.😗.😚.😋.😛.😜.🤪.😝.🤗.🤭.🤔.🤐.😐.😑.😶.😏.😒.🙄.😬.😌.😔.😪.🤤.😴.😷.🤒.🤕.🥵.🥶.🥴.😵.🤯.🤠.🥳.😎.🤓.🧐.😕.😟.🙁.😮.😯.😲.😳.🥺.😦.😧.😨.😰.😥.😢.😭.😱.😖.😣.😞.😓.😩.😫.🥱.😤.😡.😠.🤬.😈.👿.💀.💩.🤡.👻.👽.🤖.😺.😸.👍.👎.👌.🤌.🤏.✌️.🤞.🤟.🤘.👋.🤚.🖐️.✋.👏.🙌.🤝.🙏.💪.👀.👁️.❤️.🧡.💛.💚.💙.💜.🖤.🤍.💔.💕.💞.💓.💗.💖.💘.💝.💯.✨.⭐.🌟.🔥.💥.💫.⚡.☀️.🌈.🎉.🎊.🎁.🏆.🐶.🐱.🐭.🦊.🐻.🐼.🐨.🦄.🐢.🐳.🍎.🍑.🍓.🍉.🍰.🍺.🍵.☕.🍜.🍙.✅.❌.❓.❗.💤.👑.🎮.🎵.📌.🔖".split("."), Se = [
|
|
181
185
|
"title",
|
|
182
186
|
"aria-label",
|
|
183
187
|
"aria-expanded"
|
|
184
|
-
],
|
|
188
|
+
], Ce = ["innerHTML"], we = { class: "kun-editor__picker-panel" }, Te = {
|
|
185
189
|
key: 0,
|
|
186
190
|
class: "kun-editor__picker-tabs",
|
|
187
191
|
role: "tablist"
|
|
188
|
-
},
|
|
192
|
+
}, Ee = ["data-active"], De = ["data-active"], Oe = { class: "kun-editor__emoji-grid" }, ke = ["onClick"], Ae = {
|
|
189
193
|
key: 1,
|
|
190
194
|
class: "kun-editor__sticker-body"
|
|
191
|
-
},
|
|
195
|
+
}, je = { class: "kun-editor__pack-name" }, Me = { class: "kun-editor__sticker-grid" }, Ne = ["title", "onClick"], Pe = ["src", "alt"], Fe = {
|
|
192
196
|
key: 1,
|
|
193
197
|
class: "kun-editor__picker-hint"
|
|
194
|
-
},
|
|
198
|
+
}, Ie = /* @__PURE__ */ s({
|
|
195
199
|
__name: "StickerPicker",
|
|
196
200
|
setup(n) {
|
|
197
201
|
let [, o] = T(), s = c(J), f = s?.adapters.stickerSource, v = !!f, y = t(() => (s?.locale ?? "zh-cn").toLowerCase().startsWith("en")), x = t(() => y.value ? {
|
|
@@ -247,28 +251,28 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
247
251
|
}, [a("span", {
|
|
248
252
|
class: "kun-editor__icon",
|
|
249
253
|
innerHTML: g(Z).smile
|
|
250
|
-
}, null, 8,
|
|
251
|
-
v ? (d(), i("div",
|
|
254
|
+
}, null, 8, Ce)], 8, Se), b(a("div", we, [
|
|
255
|
+
v ? (d(), i("div", Te, [a("button", {
|
|
252
256
|
type: "button",
|
|
253
257
|
class: "kun-editor__picker-tab",
|
|
254
258
|
"data-active": w.value === "emoji",
|
|
255
259
|
onClick: n[0] ||= (e) => w.value = "emoji"
|
|
256
|
-
}, h(x.value.emoji), 9,
|
|
260
|
+
}, h(x.value.emoji), 9, Ee), a("button", {
|
|
257
261
|
type: "button",
|
|
258
262
|
class: "kun-editor__picker-tab",
|
|
259
263
|
"data-active": w.value === "sticker",
|
|
260
264
|
onClick: n[1] ||= (e) => w.value = "sticker"
|
|
261
|
-
}, h(x.value.sticker), 9,
|
|
262
|
-
b(a("div",
|
|
265
|
+
}, h(x.value.sticker), 9, De)])) : r("", !0),
|
|
266
|
+
b(a("div", Oe, [(d(!0), i(e, null, m(g(xe), (e, t) => (d(), i("button", {
|
|
263
267
|
key: t,
|
|
264
268
|
type: "button",
|
|
265
269
|
class: "kun-editor__emoji",
|
|
266
270
|
onClick: (t) => N(e)
|
|
267
|
-
}, h(e), 9,
|
|
268
|
-
v ? b((d(), i("div",
|
|
271
|
+
}, h(e), 9, ke))), 128))], 512), [[_, !v || w.value === "emoji"]]),
|
|
272
|
+
v ? b((d(), i("div", Ae, [E.value.length ? (d(!0), i(e, { key: 0 }, m(E.value, (t) => (d(), i("div", {
|
|
269
273
|
key: t.name,
|
|
270
274
|
class: "kun-editor__pack"
|
|
271
|
-
}, [a("div",
|
|
275
|
+
}, [a("div", je, h(t.name), 1), a("div", Me, [(d(!0), i(e, null, m(t.stickers, (e, t) => (d(), i("button", {
|
|
272
276
|
key: t,
|
|
273
277
|
type: "button",
|
|
274
278
|
class: "kun-editor__sticker",
|
|
@@ -278,21 +282,21 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
278
282
|
src: e.src,
|
|
279
283
|
alt: e.name,
|
|
280
284
|
loading: "lazy"
|
|
281
|
-
}, null, 8,
|
|
285
|
+
}, null, 8, Pe)], 8, Ne))), 128))])]))), 128)) : (d(), i("div", Fe, h(O.value ? x.value.failed : x.value.empty), 1))], 512)), [[_, w.value === "sticker"]]) : r("", !0)
|
|
282
286
|
], 512), [[_, S.value]])], 512));
|
|
283
287
|
}
|
|
284
|
-
}),
|
|
288
|
+
}), Le = {
|
|
285
289
|
class: "kun-editor__format-toolbar",
|
|
286
290
|
role: "toolbar"
|
|
287
|
-
},
|
|
291
|
+
}, Re = {
|
|
288
292
|
key: 0,
|
|
289
293
|
class: "kun-editor__toolbar-divider",
|
|
290
294
|
"aria-hidden": "true"
|
|
291
|
-
},
|
|
295
|
+
}, ze = [
|
|
292
296
|
"title",
|
|
293
297
|
"aria-label",
|
|
294
298
|
"onClick"
|
|
295
|
-
],
|
|
299
|
+
], Be = ["innerHTML"], Ve = ["title", "aria-label"], He = ["innerHTML"], Q = /* @__PURE__ */ s({
|
|
296
300
|
__name: "EditorToolbar",
|
|
297
301
|
setup(n) {
|
|
298
302
|
let [, s] = T(), l = c(J), u = t(() => l?.adapters.uploadImage), f = () => l?.adapters.notify, h = t(() => l?.features.sticker !== !1), _ = t(() => (l?.locale ?? "zh-cn").toLowerCase().startsWith("en")), v = (e, t) => {
|
|
@@ -331,7 +335,7 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
331
335
|
{
|
|
332
336
|
svg: Z.strike,
|
|
333
337
|
title: y.value.strike,
|
|
334
|
-
run: () => v(
|
|
338
|
+
run: () => v(ce.key)
|
|
335
339
|
},
|
|
336
340
|
{
|
|
337
341
|
svg: Z.code,
|
|
@@ -375,22 +379,22 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
375
379
|
{
|
|
376
380
|
svg: Z.codeBlock,
|
|
377
381
|
title: y.value.codeBlock,
|
|
378
|
-
run: () => v(
|
|
382
|
+
run: () => v(oe.key, "")
|
|
379
383
|
},
|
|
380
384
|
{
|
|
381
385
|
svg: Z.hr,
|
|
382
386
|
title: y.value.hr,
|
|
383
|
-
run: () => v(
|
|
387
|
+
run: () => v(se.key)
|
|
384
388
|
}
|
|
385
389
|
],
|
|
386
390
|
[{
|
|
387
391
|
svg: Z.spoiler,
|
|
388
392
|
title: y.value.spoiler,
|
|
389
|
-
run: () => v(
|
|
393
|
+
run: () => v(te.key)
|
|
390
394
|
}, {
|
|
391
395
|
svg: Z.latex,
|
|
392
396
|
title: y.value.latex,
|
|
393
|
-
run: () => v(
|
|
397
|
+
run: () => v(ie.key)
|
|
394
398
|
}]
|
|
395
399
|
]), x = p(null), S = () => x.value?.click(), C = async (e) => {
|
|
396
400
|
let t = e.target, n = t.files?.[0];
|
|
@@ -407,8 +411,8 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
407
411
|
f()?.(_.value ? "Image upload failed" : "图片上传失败", "error");
|
|
408
412
|
}
|
|
409
413
|
};
|
|
410
|
-
return (t, n) => (d(), i("div",
|
|
411
|
-
(d(!0), i(e, null, m(b.value, (t, n) => (d(), i(e, { key: n }, [n > 0 ? (d(), i("span",
|
|
414
|
+
return (t, n) => (d(), i("div", Le, [
|
|
415
|
+
(d(!0), i(e, null, m(b.value, (t, n) => (d(), i(e, { key: n }, [n > 0 ? (d(), i("span", Re)) : r("", !0), (d(!0), i(e, null, m(t, (e, t) => (d(), i("button", {
|
|
412
416
|
key: t,
|
|
413
417
|
type: "button",
|
|
414
418
|
class: "kun-editor__tool",
|
|
@@ -418,7 +422,7 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
418
422
|
}, [a("span", {
|
|
419
423
|
class: "kun-editor__icon",
|
|
420
424
|
innerHTML: e.svg
|
|
421
|
-
}, null, 8,
|
|
425
|
+
}, null, 8, Be)], 8, ze))), 128))], 64))), 128)),
|
|
422
426
|
u.value ? (d(), i(e, { key: 0 }, [
|
|
423
427
|
n[0] ||= a("span", {
|
|
424
428
|
class: "kun-editor__toolbar-divider",
|
|
@@ -433,7 +437,7 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
433
437
|
}, [a("span", {
|
|
434
438
|
class: "kun-editor__icon",
|
|
435
439
|
innerHTML: g(Z).image
|
|
436
|
-
}, null, 8,
|
|
440
|
+
}, null, 8, He)], 8, Ve),
|
|
437
441
|
a("input", {
|
|
438
442
|
ref_key: "fileInput",
|
|
439
443
|
ref: x,
|
|
@@ -446,20 +450,52 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
446
450
|
h.value ? (d(), i(e, { key: 1 }, [n[1] ||= a("span", {
|
|
447
451
|
class: "kun-editor__toolbar-divider",
|
|
448
452
|
"aria-hidden": "true"
|
|
449
|
-
}, null, -1), o(
|
|
453
|
+
}, null, -1), o(Ie)], 64)) : r("", !0)
|
|
450
454
|
]));
|
|
451
455
|
}
|
|
452
|
-
}),
|
|
456
|
+
}), Ue = /* @__PURE__ */ s({
|
|
457
|
+
__name: "MarkdownSource",
|
|
458
|
+
props: {
|
|
459
|
+
modelValue: {},
|
|
460
|
+
readonly: { type: Boolean }
|
|
461
|
+
},
|
|
462
|
+
emits: ["update:modelValue"],
|
|
463
|
+
setup(e, { emit: t }) {
|
|
464
|
+
let n = e, r = t, a = p(null), o = null, s = (e) => le.create({
|
|
465
|
+
doc: e,
|
|
466
|
+
extensions: [
|
|
467
|
+
ne(),
|
|
468
|
+
q.lineWrapping,
|
|
469
|
+
de,
|
|
470
|
+
ue(),
|
|
471
|
+
q.editable.of(!n.readonly),
|
|
472
|
+
q.updateListener.of((e) => {
|
|
473
|
+
e.docChanged && r("update:modelValue", e.state.doc.toString());
|
|
474
|
+
})
|
|
475
|
+
]
|
|
476
|
+
});
|
|
477
|
+
return u(() => {
|
|
478
|
+
a.value && (o = new q({
|
|
479
|
+
state: s(n.modelValue),
|
|
480
|
+
parent: a.value
|
|
481
|
+
}));
|
|
482
|
+
}), l(() => {
|
|
483
|
+
o?.destroy(), o = null;
|
|
484
|
+
}), v(() => n.modelValue, (e) => {
|
|
485
|
+
o && o.state.doc.toString() !== e && o.setState(s(e));
|
|
486
|
+
}), (e, t) => (d(), i("div", {
|
|
487
|
+
ref_key: "host",
|
|
488
|
+
ref: a,
|
|
489
|
+
class: "kun-editor__source"
|
|
490
|
+
}, null, 512));
|
|
491
|
+
}
|
|
492
|
+
}), We = {
|
|
453
493
|
class: "kun-editor",
|
|
454
494
|
"data-kun-editor": ""
|
|
455
|
-
},
|
|
495
|
+
}, Ge = {
|
|
456
496
|
class: "kun-editor__toolbar",
|
|
457
497
|
role: "tablist"
|
|
458
|
-
},
|
|
459
|
-
"value",
|
|
460
|
-
"readonly",
|
|
461
|
-
"lang"
|
|
462
|
-
], $ = /* @__PURE__ */ s({
|
|
498
|
+
}, Ke = ["aria-selected", "data-active"], qe = ["aria-selected", "data-active"], Je = { class: "kun-editor__wysiwyg" }, $ = /* @__PURE__ */ s({
|
|
463
499
|
__name: "KunEditor",
|
|
464
500
|
props: {
|
|
465
501
|
modelValue: {},
|
|
@@ -472,72 +508,70 @@ var J = Symbol("kun-editor-context"), se = [
|
|
|
472
508
|
}
|
|
473
509
|
},
|
|
474
510
|
emits: ["update:modelValue"],
|
|
475
|
-
setup(e, { emit:
|
|
476
|
-
let
|
|
511
|
+
setup(e, { emit: s }) {
|
|
512
|
+
let c = e, l = s;
|
|
477
513
|
f(J, {
|
|
478
514
|
get adapters() {
|
|
479
|
-
return
|
|
515
|
+
return c.adapters;
|
|
480
516
|
},
|
|
481
517
|
get features() {
|
|
482
|
-
return
|
|
518
|
+
return c.features;
|
|
483
519
|
},
|
|
484
520
|
get locale() {
|
|
485
|
-
return
|
|
521
|
+
return c.locale;
|
|
486
522
|
}
|
|
487
523
|
});
|
|
488
|
-
let
|
|
524
|
+
let u = p("wysiwyg"), m = t(() => c.locale.toLowerCase().startsWith("en")), v = t(() => m.value ? {
|
|
489
525
|
wysiwyg: "Preview",
|
|
490
526
|
source: "Markdown"
|
|
491
527
|
} : {
|
|
492
528
|
wysiwyg: "预览",
|
|
493
529
|
source: "Markdown"
|
|
494
|
-
}),
|
|
495
|
-
return (t,
|
|
496
|
-
a("div",
|
|
530
|
+
}), x = (e) => l("update:modelValue", e);
|
|
531
|
+
return (t, s) => (d(), i("div", We, [
|
|
532
|
+
a("div", Ge, [a("button", {
|
|
497
533
|
type: "button",
|
|
498
534
|
class: "kun-editor__tab",
|
|
499
|
-
"aria-selected":
|
|
500
|
-
"data-active":
|
|
501
|
-
onClick:
|
|
502
|
-
}, h(
|
|
535
|
+
"aria-selected": u.value === "wysiwyg",
|
|
536
|
+
"data-active": u.value === "wysiwyg",
|
|
537
|
+
onClick: s[0] ||= (e) => u.value = "wysiwyg"
|
|
538
|
+
}, h(v.value.wysiwyg), 9, Ke), a("button", {
|
|
503
539
|
type: "button",
|
|
504
540
|
class: "kun-editor__tab",
|
|
505
|
-
"aria-selected":
|
|
506
|
-
"data-active":
|
|
507
|
-
onClick:
|
|
508
|
-
}, h(
|
|
541
|
+
"aria-selected": u.value === "source",
|
|
542
|
+
"data-active": u.value === "source",
|
|
543
|
+
onClick: s[1] ||= (e) => u.value = "source"
|
|
544
|
+
}, h(v.value.source), 9, qe)]),
|
|
509
545
|
o(g(C), null, {
|
|
510
546
|
default: y(() => [o(g(E), null, {
|
|
511
|
-
default: y(() => [b(o(
|
|
547
|
+
default: y(() => [b(o(Q, null, null, 512), [[_, u.value === "wysiwyg" && !e.readonly]]), b(a("div", Je, [o(be, {
|
|
512
548
|
"model-value": e.modelValue,
|
|
513
549
|
adapters: e.adapters,
|
|
514
550
|
features: e.features,
|
|
515
551
|
locale: e.locale,
|
|
516
552
|
readonly: e.readonly,
|
|
517
|
-
"onUpdate:modelValue":
|
|
553
|
+
"onUpdate:modelValue": x
|
|
518
554
|
}, null, 8, [
|
|
519
555
|
"model-value",
|
|
520
556
|
"adapters",
|
|
521
557
|
"features",
|
|
522
558
|
"locale",
|
|
523
559
|
"readonly"
|
|
524
|
-
])], 512), [[_,
|
|
560
|
+
])], 512), [[_, u.value === "wysiwyg"]])]),
|
|
525
561
|
_: 1
|
|
526
562
|
})]),
|
|
527
563
|
_: 1
|
|
528
564
|
}),
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
value: e.modelValue,
|
|
565
|
+
u.value === "source" ? (d(), n(Ue, {
|
|
566
|
+
key: 0,
|
|
567
|
+
"model-value": e.modelValue,
|
|
532
568
|
readonly: e.readonly,
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
onInput: v
|
|
536
|
-
}, null, 40, Ue), [[_, c.value === "source"]])
|
|
569
|
+
"onUpdate:modelValue": x
|
|
570
|
+
}, null, 8, ["model-value", "readonly"])) : r("", !0)
|
|
537
571
|
]));
|
|
538
572
|
}
|
|
539
|
-
}),
|
|
573
|
+
}), Ye = { install(e) {
|
|
540
574
|
e.component("KunEditor", $);
|
|
541
575
|
} };
|
|
542
576
|
//#endregion
|
|
543
|
-
export { $ as KunEditor,
|
|
577
|
+
export { $ as KunEditor, Ye as KunEditorPlugin };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungal/editor-vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "KunEditor Vue 3 layer — the <KunEditor> component (dual WYSIWYG / markdown-source), toolbar and plugin views. Consumes @kungal/editor-core; pairs with @kungal/ui-vue.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -24,10 +24,7 @@
|
|
|
24
24
|
"publishConfig": {
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
|
-
"sideEffects":
|
|
28
|
-
"*.css",
|
|
29
|
-
"*.vue"
|
|
30
|
-
],
|
|
27
|
+
"sideEffects": false,
|
|
31
28
|
"files": [
|
|
32
29
|
"CHANGELOG.md",
|
|
33
30
|
"dist"
|
|
@@ -39,31 +36,51 @@
|
|
|
39
36
|
".": {
|
|
40
37
|
"types": "./dist/index.d.ts",
|
|
41
38
|
"import": "./dist/index.js"
|
|
42
|
-
}
|
|
43
|
-
"./style.css": "./dist/style.css"
|
|
39
|
+
}
|
|
44
40
|
},
|
|
45
41
|
"dependencies": {
|
|
46
42
|
"@prosemirror-adapter/vue": "^0.4.6",
|
|
47
|
-
"@kungal/editor-core": "0.
|
|
43
|
+
"@kungal/editor-core": "0.8.0"
|
|
48
44
|
},
|
|
49
45
|
"peerDependencies": {
|
|
50
|
-
"@
|
|
46
|
+
"@codemirror/lang-markdown": "^6.0.0",
|
|
47
|
+
"@codemirror/state": "^6.0.0",
|
|
48
|
+
"@codemirror/view": "^6.0.0",
|
|
51
49
|
"@milkdown/kit": "^7.21.2",
|
|
52
50
|
"@milkdown/prose": "^7.21.2",
|
|
53
51
|
"@milkdown/vue": "^7.21.2",
|
|
52
|
+
"codemirror": "^6.0.0",
|
|
54
53
|
"vue": "^3.5.0"
|
|
55
54
|
},
|
|
55
|
+
"peerDependenciesMeta": {
|
|
56
|
+
"@codemirror/lang-markdown": {
|
|
57
|
+
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"@codemirror/state": {
|
|
60
|
+
"optional": true
|
|
61
|
+
},
|
|
62
|
+
"@codemirror/view": {
|
|
63
|
+
"optional": true
|
|
64
|
+
},
|
|
65
|
+
"codemirror": {
|
|
66
|
+
"optional": true
|
|
67
|
+
}
|
|
68
|
+
},
|
|
56
69
|
"devDependencies": {
|
|
70
|
+
"@codemirror/lang-markdown": "^6.5.0",
|
|
71
|
+
"@codemirror/state": "^6.5.2",
|
|
72
|
+
"@codemirror/view": "^6.39.4",
|
|
57
73
|
"@milkdown/kit": "^7.21.2",
|
|
58
74
|
"@milkdown/prose": "^7.21.2",
|
|
59
75
|
"@milkdown/vue": "7.21.2",
|
|
60
76
|
"@types/node": "^22.10.0",
|
|
61
77
|
"@vitejs/plugin-vue": "^6.0.7",
|
|
78
|
+
"codemirror": "^6.0.2",
|
|
62
79
|
"typescript": "^5.7.0",
|
|
63
80
|
"vite": "^8.0.16",
|
|
64
81
|
"vue": "^3.5.35",
|
|
65
82
|
"vue-tsc": "^3.3.3",
|
|
66
|
-
"@kungal/editor-core": "0.
|
|
83
|
+
"@kungal/editor-core": "0.8.0"
|
|
67
84
|
},
|
|
68
85
|
"scripts": {
|
|
69
86
|
"build": "vite build && vue-tsc -p tsconfig.build.json",
|
package/dist/style.css
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
.kun-mention-dropdown{z-index:30;background:var(--color-background,#fff);border:1px solid var(--color-default-200,#e4e4e7);border-radius:.5rem;min-width:12rem;max-width:20rem;max-height:16rem;padding:.25rem;display:none;position:absolute;overflow-y:auto;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.kun-mention-dropdown[data-show=true]{display:block}.kun-mention-dropdown__item{width:100%;font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;border-radius:.375rem;align-items:center;gap:.5rem;padding:.375rem .5rem;display:flex}.kun-mention-dropdown__item:hover,.kun-mention-dropdown__item[data-active=true]{background:var(--color-default-100,#f4f4f5)}.kun-mention-dropdown__avatar{object-fit:cover;border-radius:9999px;flex-shrink:0;width:1.5rem;height:1.5rem}.kun-mention-dropdown__avatar--fallback{background:var(--color-default-200,#e4e4e7);color:var(--color-default-600,#52525b);justify-content:center;align-items:center;font-size:.75rem;display:flex}.kun-mention-dropdown__name{text-overflow:ellipsis;white-space:nowrap;font-size:.875rem;overflow:hidden}.kun-mention-dropdown__hint{color:var(--color-default-400,#a1a1aa);padding:.375rem .5rem;font-size:.875rem}.kun-editor__picker{display:inline-flex;position:relative}.kun-editor__picker-panel{z-index:30;background:var(--color-background,#fff);border:1px solid var(--color-default-200,#e4e4e7);border-radius:.5rem;width:18rem;padding:.5rem;position:absolute;top:calc(100% + .25rem);left:0;box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.kun-editor__picker-tabs{gap:.25rem;margin-bottom:.5rem;display:flex}.kun-editor__picker-tab{font:inherit;cursor:pointer;background:0 0;border:none;border-bottom:2px solid #0000;flex:1;padding:.25rem .5rem}.kun-editor__picker-tab[data-active=true]{border-bottom-color:var(--color-primary,#006fee);color:var(--color-primary,#006fee)}.kun-editor__emoji-grid{grid-template-columns:repeat(8,1fr);gap:.125rem;max-height:16rem;display:grid;overflow-y:auto}.kun-editor__emoji{aspect-ratio:1;cursor:pointer;background:0 0;border:none;border-radius:.375rem;font-size:1.25rem;line-height:1}.kun-editor__emoji:hover{background:var(--color-default-100,#f4f4f5)}.kun-editor__sticker-body{max-height:16rem;overflow-y:auto}.kun-editor__pack-name{color:var(--color-default-500,#71717a);padding:.25rem .125rem;font-size:.75rem}.kun-editor__sticker-grid{grid-template-columns:repeat(5,1fr);gap:.25rem;display:grid}.kun-editor__sticker{aspect-ratio:1;cursor:pointer;background:0 0;border:none;border-radius:.375rem;padding:.125rem}.kun-editor__sticker:hover{background:var(--color-default-100,#f4f4f5)}.kun-editor__sticker img{object-fit:contain;width:100%;height:100%}.kun-editor__picker-hint{color:var(--color-default-400,#a1a1aa);text-align:center;padding:1rem;font-size:.875rem}.kun-editor__format-toolbar{flex-wrap:wrap;align-items:center;gap:.125rem;display:flex}.kun-editor__toolbar-divider{background:var(--color-default-200,#e4e4e7);align-self:stretch;width:1px;margin:.25rem}.kun-editor__tool{width:1.75rem;height:1.75rem;color:var(--color-foreground,#27272a);cursor:pointer;background:0 0;border:none;border-radius:.375rem;justify-content:center;align-items:center;padding:0;display:inline-flex}.kun-editor__tool:hover{background:var(--color-default-100,#f4f4f5)}.kun-editor__icon{display:inline-flex}.kun-editor{flex-direction:column;gap:.5rem;display:flex}.kun-editor__toolbar{gap:.25rem;display:flex}.kun-editor__tab{border:1px solid var(--color-default-200,#e4e4e7);font:inherit;cursor:pointer;background:0 0;border-radius:.5rem;padding:.25rem .75rem}.kun-editor__tab[data-active=true]{background:var(--color-primary,#006fee);border-color:var(--color-primary,#006fee);color:#fff}.kun-editor__wysiwyg .milkdown{outline:none}.kun-editor__wysiwyg .ProseMirror{border:1px solid var(--color-default-200,#e4e4e7);white-space:pre-wrap;word-wrap:break-word;border-radius:.5rem;outline:none;min-height:8rem;padding:.75rem}.kun-editor__source{border:1px solid var(--color-default-200,#e4e4e7);resize:vertical;border-radius:.5rem;width:100%;min-height:8rem;padding:.75rem;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.875rem}
|
|
2
|
-
/*$vite$:1*/
|