@kungal/editor-vue 0.3.0 → 0.4.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 +22 -0
- package/README.md +7 -2
- package/dist/components/KunEditor.vue.d.ts.map +1 -1
- package/dist/components/MentionDropdown.vue.d.ts +4 -0
- package/dist/components/MentionDropdown.vue.d.ts.map +1 -0
- package/dist/components/MilkdownEditor.vue.d.ts.map +1 -1
- package/dist/context.d.ts +10 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/index.js +195 -58
- package/dist/style.css +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @kungal/editor-vue
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 56f4a77: P3 — wire the `@mention` autocomplete dropdown.
|
|
8
|
+
|
|
9
|
+
Typing `@` in `<KunEditor>` now opens a debounced, keyboard-navigable dropdown
|
|
10
|
+
(ported from the forum's `MentionDropdown.vue`) that resolves users through the
|
|
11
|
+
injected `searchMentionUsers` adapter and inserts a mention chip serializing to
|
|
12
|
+
`[@name](kungal-user:id)`. Without the adapter the mention schema still
|
|
13
|
+
round-trips — there's just no autocomplete.
|
|
14
|
+
|
|
15
|
+
The adapter reaches the dropdown via a `provide()` on `<KunEditor>`: because
|
|
16
|
+
@prosemirror-adapter/vue renders plugin views as portals that are _siblings_ of
|
|
17
|
+
the editor (children of `<ProsemirrorAdapterProvider>`), only an ancestor of the
|
|
18
|
+
provider can inject into them. Verified end-to-end in a real browser via the new
|
|
19
|
+
`apps/playground` dev app.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- @kungal/editor-core@0.4.0
|
|
24
|
+
|
|
3
25
|
## 0.3.0
|
|
4
26
|
|
|
5
27
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -54,9 +54,14 @@ editor**: a WYSIWYG view built from `@kungal/editor-core/preset`
|
|
|
54
54
|
…), plus a markdown-source view, over one `v-model`. The prop/emit surface
|
|
55
55
|
(`v-model`, `adapters`, `features`, `locale`, `readonly`) is stable.
|
|
56
56
|
|
|
57
|
+
The **`@mention` autocomplete dropdown** is wired: type `@`, and — when the host
|
|
58
|
+
supplies `searchMentionUsers` — a debounced, keyboard-navigable dropdown offers
|
|
59
|
+
users and inserts a mention chip (`[@name](kungal-user:id)`). Without the adapter
|
|
60
|
+
the mention schema still round-trips; there's just no autocomplete.
|
|
61
|
+
|
|
57
62
|
Still to come in P3 (they build on `@kungal/ui-vue`, hence staged): the rich
|
|
58
|
-
formatting toolbar, the
|
|
59
|
-
|
|
63
|
+
formatting toolbar, the sticker/emoji picker, and the CodeMirror markdown-source
|
|
64
|
+
view (currently a `<textarea>`). See
|
|
60
65
|
[`../../docs/architecture.md`](../../docs/architecture.md) § migration.
|
|
61
66
|
|
|
62
67
|
## Build
|
|
@@ -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":"AA0MA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAI5B,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;AAqLJ,QAAA,MAAM,YAAY;;;;;cA5LH,iBAAiB;cAEjB,iBAAiB;YAEnB,eAAe;cAEb,OAAO;6EA0LpB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2
|
+
declare const _default: typeof __VLS_export;
|
|
3
|
+
export default _default;
|
|
4
|
+
//# sourceMappingURL=MentionDropdown.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MentionDropdown.vue.d.ts","sourceRoot":"","sources":["../../src/components/MentionDropdown.vue"],"names":[],"mappings":"AA8pBA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MilkdownEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/MilkdownEditor.vue"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MilkdownEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/MilkdownEditor.vue"],"names":[],"mappings":"AAkIA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAI5B,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;CAClB,CAAC;AA2GF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { InjectionKey } from 'vue';
|
|
2
|
+
import type { KunEditorAdapters, KunEditorLocale } from '@kungal/editor-core';
|
|
3
|
+
export interface KunEditorContext {
|
|
4
|
+
/** The host policy bundle (searchMentionUsers, stickerSource, notify, …). */
|
|
5
|
+
readonly adapters: KunEditorAdapters;
|
|
6
|
+
/** UI language, for view chrome (dropdown hints, etc.). */
|
|
7
|
+
readonly locale: KunEditorLocale;
|
|
8
|
+
}
|
|
9
|
+
export declare const KUN_EDITOR_CONTEXT: InjectionKey<KunEditorContext>;
|
|
10
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,KAAK,CAAA;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAE7E,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IACpC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;CACjC;AAED,eAAO,MAAM,kBAAkB,EAAE,YAAY,CAAC,gBAAgB,CAChC,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,138 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Milkdown as
|
|
3
|
-
import { ProsemirrorAdapterProvider as
|
|
4
|
-
import { Editor as
|
|
5
|
-
import { listenerCtx as
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { Fragment as e, computed as t, createBlock as n, createElementBlock as r, createElementVNode as i, createVNode as a, defineComponent as o, inject as s, onBeforeUnmount as c, onMounted as l, openBlock as u, provide as d, ref as f, renderList as p, toDisplayString as m, unref as h, vShow as g, watch as _, withCtx as v, withDirectives as y, withModifiers as b } from "vue";
|
|
2
|
+
import { Milkdown as x, MilkdownProvider as S, useEditor as C } from "@milkdown/vue";
|
|
3
|
+
import { ProsemirrorAdapterProvider as w, usePluginViewContext as T, usePluginViewFactory as E } from "@prosemirror-adapter/vue";
|
|
4
|
+
import { Editor as D, defaultValueCtx as O, editorViewOptionsCtx as k, rootCtx as A } from "@milkdown/kit/core";
|
|
5
|
+
import { listenerCtx as j } from "@milkdown/kit/plugin/listener";
|
|
6
|
+
import { SlashProvider as M, slashFactory as N } from "@milkdown/kit/plugin/slash";
|
|
7
|
+
import { replaceAll as P } from "@milkdown/kit/utils";
|
|
8
|
+
import { createKunEditorPlugins as F, mentionId as I } from "@kungal/editor-core/preset";
|
|
9
|
+
import { TextSelection as L } from "@milkdown/kit/prose/state";
|
|
10
|
+
//#region src/context.ts
|
|
11
|
+
var R = Symbol("kun-editor-context"), z = [
|
|
12
|
+
"data-active",
|
|
13
|
+
"onMousedown",
|
|
14
|
+
"onMouseenter"
|
|
15
|
+
], B = ["src", "alt"], V = {
|
|
16
|
+
key: 1,
|
|
17
|
+
class: "kun-mention-dropdown__avatar kun-mention-dropdown__avatar--fallback"
|
|
18
|
+
}, H = { class: "kun-mention-dropdown__name" }, U = {
|
|
19
|
+
key: 1,
|
|
20
|
+
class: "kun-mention-dropdown__hint"
|
|
21
|
+
}, W = {
|
|
22
|
+
key: 2,
|
|
23
|
+
class: "kun-mention-dropdown__hint"
|
|
24
|
+
}, G = {
|
|
25
|
+
key: 3,
|
|
26
|
+
class: "kun-mention-dropdown__hint"
|
|
27
|
+
}, K = /* @__PURE__ */ o({
|
|
28
|
+
__name: "MentionDropdown",
|
|
29
|
+
setup(n) {
|
|
30
|
+
let a = /(?:^|\s)@([^\s@]{0,30})$/, o = s(R), d = o?.adapters.searchMentionUsers, h = t(() => (o?.locale ?? "zh-cn").toLowerCase().startsWith("en")), g = t(() => h.value ? {
|
|
31
|
+
searching: "Searching…",
|
|
32
|
+
empty: "No matching users",
|
|
33
|
+
prompt: "Type a username to search"
|
|
34
|
+
} : {
|
|
35
|
+
searching: "搜索中…",
|
|
36
|
+
empty: "无匹配用户",
|
|
37
|
+
prompt: "输入用户名以搜索"
|
|
38
|
+
}), { view: v, prevState: y } = T(), x = f(null), S, C = f(!1), w = f(""), E = f([]), D = f(0), O = f(!1), k = null, A = 0, j = null, N = () => {
|
|
39
|
+
j &&= (clearTimeout(j), null), w.value = "", E.value = [], D.value = 0, O.value = !1, k = null;
|
|
40
|
+
}, P = (e) => {
|
|
41
|
+
if (j &&= (clearTimeout(j), null), !e || !d) {
|
|
42
|
+
E.value = [], O.value = !1;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
O.value = !0, j = setTimeout(async () => {
|
|
46
|
+
let t = ++A, n = [];
|
|
47
|
+
try {
|
|
48
|
+
n = await d(e);
|
|
49
|
+
} catch {
|
|
50
|
+
n = [];
|
|
51
|
+
}
|
|
52
|
+
t === A && (E.value = n ?? [], D.value = 0, O.value = !1);
|
|
53
|
+
}, 180);
|
|
54
|
+
}, F = (e) => {
|
|
55
|
+
let { selection: t } = e.state;
|
|
56
|
+
if (!t.empty) return null;
|
|
57
|
+
let { $from: n } = t, r = n.parent.textBetween(Math.max(0, n.parentOffset - 100), n.parentOffset, void 0, "").match(a);
|
|
58
|
+
return r ? r[1] ?? "" : null;
|
|
59
|
+
}, K = (e) => {
|
|
60
|
+
let t = F(e);
|
|
61
|
+
if (t === null) return !1;
|
|
62
|
+
let n = e.state.selection.$from.pos;
|
|
63
|
+
return k = {
|
|
64
|
+
from: n - (t.length + 1),
|
|
65
|
+
to: n
|
|
66
|
+
}, t !== w.value && (w.value = t, P(t)), !0;
|
|
67
|
+
}, q = (e) => {
|
|
68
|
+
let t = v.value;
|
|
69
|
+
if (!t || !k) return;
|
|
70
|
+
let n = t.state.schema.nodes[I];
|
|
71
|
+
if (!n) return;
|
|
72
|
+
let r = n.create({
|
|
73
|
+
userId: e.id,
|
|
74
|
+
name: e.name
|
|
75
|
+
}), { from: i, to: a } = k, o = t.state.tr.replaceWith(i, a, r), s = i + r.nodeSize;
|
|
76
|
+
o.insertText(" ", s), o.setSelection(L.create(o.doc, s + 1)), t.dispatch(o.scrollIntoView()), t.focus(), S.hide();
|
|
77
|
+
}, J = (e) => {
|
|
78
|
+
if (!C.value || !E.value.length) {
|
|
79
|
+
C.value && e.key === "Escape" && (e.preventDefault(), S.hide());
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
let t = E.value.length - 1;
|
|
83
|
+
switch (e.key) {
|
|
84
|
+
case "ArrowDown":
|
|
85
|
+
e.preventDefault(), e.stopPropagation(), D.value = D.value >= t ? 0 : D.value + 1;
|
|
86
|
+
break;
|
|
87
|
+
case "ArrowUp":
|
|
88
|
+
e.preventDefault(), e.stopPropagation(), D.value = D.value <= 0 ? t : D.value - 1;
|
|
89
|
+
break;
|
|
90
|
+
case "Enter":
|
|
91
|
+
case "Tab": {
|
|
92
|
+
let t = E.value[D.value];
|
|
93
|
+
t && (e.preventDefault(), e.stopPropagation(), q(t));
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
case "Escape":
|
|
97
|
+
e.preventDefault(), e.stopPropagation(), S.hide();
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
return l(() => {
|
|
102
|
+
S = new M({
|
|
103
|
+
content: x.value,
|
|
104
|
+
trigger: "@",
|
|
105
|
+
shouldShow: K,
|
|
106
|
+
debounce: 0
|
|
107
|
+
}), S.onShow = () => {
|
|
108
|
+
C.value = !0;
|
|
109
|
+
}, S.onHide = () => {
|
|
110
|
+
C.value = !1, N();
|
|
111
|
+
}, S.update(v.value, y.value), window.addEventListener("keydown", J, !0);
|
|
112
|
+
}), _([v, y], () => {
|
|
113
|
+
S?.update(v.value, y.value);
|
|
114
|
+
}), c(() => {
|
|
115
|
+
j && clearTimeout(j), window.removeEventListener("keydown", J, !0), S?.destroy();
|
|
116
|
+
}), (t, n) => (u(), r("div", {
|
|
117
|
+
ref_key: "divRef",
|
|
118
|
+
ref: x,
|
|
119
|
+
class: "kun-mention-dropdown",
|
|
120
|
+
"data-show": "false"
|
|
121
|
+
}, [E.value.length ? (u(!0), r(e, { key: 0 }, p(E.value, (e, t) => (u(), r("button", {
|
|
122
|
+
key: e.id,
|
|
123
|
+
type: "button",
|
|
124
|
+
class: "kun-mention-dropdown__item",
|
|
125
|
+
"data-active": t === D.value,
|
|
126
|
+
onMousedown: b((t) => q(e), ["prevent"]),
|
|
127
|
+
onMouseenter: (e) => D.value = t
|
|
128
|
+
}, [e.avatar ? (u(), r("img", {
|
|
129
|
+
key: 0,
|
|
130
|
+
src: e.avatar,
|
|
131
|
+
alt: e.name,
|
|
132
|
+
class: "kun-mention-dropdown__avatar"
|
|
133
|
+
}, null, 8, B)) : (u(), r("span", V, m(e.name.charAt(0)), 1)), i("span", H, m(e.name), 1)], 40, z))), 128)) : O.value ? (u(), r("div", U, m(g.value.searching), 1)) : w.value ? (u(), r("div", W, m(g.value.empty), 1)) : (u(), r("div", G, m(g.value.prompt), 1))], 512));
|
|
134
|
+
}
|
|
135
|
+
}), q = /* @__PURE__ */ o({
|
|
11
136
|
__name: "MilkdownEditor",
|
|
12
137
|
props: {
|
|
13
138
|
modelValue: {},
|
|
@@ -17,30 +142,33 @@ var T = /* @__PURE__ */ a({
|
|
|
17
142
|
readonly: { type: Boolean }
|
|
18
143
|
},
|
|
19
144
|
emits: ["update:modelValue"],
|
|
20
|
-
setup(e, { emit:
|
|
21
|
-
let r = e, i =
|
|
22
|
-
|
|
23
|
-
t
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
})
|
|
145
|
+
setup(e, { emit: t }) {
|
|
146
|
+
let r = e, i = t, a = r.modelValue, o = E(), s = N("kunMention"), c = r.features.mention !== !1 && !!r.adapters.searchMentionUsers && !!o, l = C((e) => {
|
|
147
|
+
let t = D.make().config((t) => {
|
|
148
|
+
t.set(A, e), t.set(O, r.modelValue), t.get(j).markdownUpdated((e, t, n) => {
|
|
149
|
+
t !== n && (a = t, i("update:modelValue", t));
|
|
150
|
+
}), t.update(k, (e) => ({
|
|
151
|
+
...e,
|
|
152
|
+
editable: () => !r.readonly
|
|
153
|
+
})), c && t.set(s.key, { view: o({ component: K }) });
|
|
154
|
+
}).use(F(r.adapters, r.features, { locale: r.locale }));
|
|
155
|
+
return c && t.use(s), t;
|
|
156
|
+
});
|
|
157
|
+
return _(() => r.modelValue, (e) => {
|
|
158
|
+
e !== a && (a = e, l.get()?.action(P(e)));
|
|
159
|
+
}), (e, t) => (u(), n(h(x)));
|
|
32
160
|
}
|
|
33
|
-
}),
|
|
161
|
+
}), J = {
|
|
34
162
|
class: "kun-editor",
|
|
35
163
|
"data-kun-editor": ""
|
|
36
|
-
},
|
|
164
|
+
}, Y = {
|
|
37
165
|
class: "kun-editor__toolbar",
|
|
38
166
|
role: "tablist"
|
|
39
|
-
},
|
|
167
|
+
}, X = ["aria-selected", "data-active"], Z = ["aria-selected", "data-active"], Q = { class: "kun-editor__wysiwyg" }, ee = [
|
|
40
168
|
"value",
|
|
41
169
|
"readonly",
|
|
42
170
|
"lang"
|
|
43
|
-
],
|
|
171
|
+
], $ = /* @__PURE__ */ o({
|
|
44
172
|
__name: "KunEditor",
|
|
45
173
|
props: {
|
|
46
174
|
modelValue: {},
|
|
@@ -53,60 +181,69 @@ var T = /* @__PURE__ */ a({
|
|
|
53
181
|
}
|
|
54
182
|
},
|
|
55
183
|
emits: ["update:modelValue"],
|
|
56
|
-
setup(
|
|
57
|
-
let
|
|
184
|
+
setup(e, { emit: n }) {
|
|
185
|
+
let o = e, s = n;
|
|
186
|
+
d(R, {
|
|
187
|
+
get adapters() {
|
|
188
|
+
return o.adapters;
|
|
189
|
+
},
|
|
190
|
+
get locale() {
|
|
191
|
+
return o.locale;
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
let c = f("wysiwyg"), l = t(() => o.locale.toLowerCase().startsWith("en")), p = t(() => l.value ? {
|
|
58
195
|
wysiwyg: "Preview",
|
|
59
196
|
source: "Markdown"
|
|
60
197
|
} : {
|
|
61
198
|
wysiwyg: "预览",
|
|
62
199
|
source: "Markdown"
|
|
63
|
-
}),
|
|
64
|
-
return (
|
|
65
|
-
|
|
200
|
+
}), _ = (e) => s("update:modelValue", e), b = (e) => s("update:modelValue", e.target.value);
|
|
201
|
+
return (t, n) => (u(), r("div", J, [
|
|
202
|
+
i("div", Y, [i("button", {
|
|
66
203
|
type: "button",
|
|
67
204
|
class: "kun-editor__tab",
|
|
68
|
-
"aria-selected":
|
|
69
|
-
"data-active":
|
|
70
|
-
onClick:
|
|
71
|
-
},
|
|
205
|
+
"aria-selected": c.value === "wysiwyg",
|
|
206
|
+
"data-active": c.value === "wysiwyg",
|
|
207
|
+
onClick: n[0] ||= (e) => c.value = "wysiwyg"
|
|
208
|
+
}, m(p.value.wysiwyg), 9, X), i("button", {
|
|
72
209
|
type: "button",
|
|
73
210
|
class: "kun-editor__tab",
|
|
74
|
-
"aria-selected":
|
|
75
|
-
"data-active":
|
|
76
|
-
onClick:
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
default:
|
|
80
|
-
default:
|
|
81
|
-
"model-value":
|
|
82
|
-
adapters:
|
|
83
|
-
features:
|
|
84
|
-
locale:
|
|
85
|
-
readonly:
|
|
86
|
-
"onUpdate:modelValue":
|
|
211
|
+
"aria-selected": c.value === "source",
|
|
212
|
+
"data-active": c.value === "source",
|
|
213
|
+
onClick: n[1] ||= (e) => c.value = "source"
|
|
214
|
+
}, m(p.value.source), 9, Z)]),
|
|
215
|
+
a(h(S), null, {
|
|
216
|
+
default: v(() => [a(h(w), null, {
|
|
217
|
+
default: v(() => [y(i("div", Q, [a(q, {
|
|
218
|
+
"model-value": e.modelValue,
|
|
219
|
+
adapters: e.adapters,
|
|
220
|
+
features: e.features,
|
|
221
|
+
locale: e.locale,
|
|
222
|
+
readonly: e.readonly,
|
|
223
|
+
"onUpdate:modelValue": _
|
|
87
224
|
}, null, 8, [
|
|
88
225
|
"model-value",
|
|
89
226
|
"adapters",
|
|
90
227
|
"features",
|
|
91
228
|
"locale",
|
|
92
229
|
"readonly"
|
|
93
|
-
])], 512), [[
|
|
230
|
+
])], 512), [[g, c.value === "wysiwyg"]])]),
|
|
94
231
|
_: 1
|
|
95
232
|
})]),
|
|
96
233
|
_: 1
|
|
97
234
|
}),
|
|
98
|
-
|
|
235
|
+
y(i("textarea", {
|
|
99
236
|
class: "kun-editor__source",
|
|
100
|
-
value:
|
|
101
|
-
readonly:
|
|
102
|
-
lang:
|
|
237
|
+
value: e.modelValue,
|
|
238
|
+
readonly: e.readonly,
|
|
239
|
+
lang: e.locale,
|
|
103
240
|
spellcheck: "false",
|
|
104
|
-
onInput:
|
|
105
|
-
}, null, 40,
|
|
241
|
+
onInput: b
|
|
242
|
+
}, null, 40, ee), [[g, c.value === "source"]])
|
|
106
243
|
]));
|
|
107
244
|
}
|
|
108
|
-
}),
|
|
109
|
-
e.component("KunEditor",
|
|
245
|
+
}), te = { install(e) {
|
|
246
|
+
e.component("KunEditor", $);
|
|
110
247
|
} };
|
|
111
248
|
//#endregion
|
|
112
|
-
export {
|
|
249
|
+
export { $ as KunEditor, te as KunEditorPlugin };
|
package/dist/style.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
.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);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}
|
|
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{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);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
2
|
/*$vite$:1*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungal/editor-vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.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": [
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@prosemirror-adapter/vue": "^0.4.6",
|
|
47
|
-
"@kungal/editor-core": "0.
|
|
47
|
+
"@kungal/editor-core": "0.4.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@kungal/ui-vue": "^2.7.0",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"vite": "^8.0.16",
|
|
64
64
|
"vue": "^3.5.35",
|
|
65
65
|
"vue-tsc": "^3.3.3",
|
|
66
|
-
"@kungal/editor-core": "0.
|
|
66
|
+
"@kungal/editor-core": "0.4.0"
|
|
67
67
|
},
|
|
68
68
|
"scripts": {
|
|
69
69
|
"build": "vite build && vue-tsc -p tsconfig.build.json",
|