@kungal/editor-vue 0.2.0 → 0.3.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,30 @@
1
1
  # @kungal/editor-vue
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 62b2dad: P3 (in progress) — `<KunEditor>` is now a real Milkdown dual-view editor.
8
+
9
+ Replaces the P0 textarea scaffold with a WYSIWYG view built from
10
+ `@kungal/editor-core/preset` (`createKunEditorPlugins` — spoiler / katex /
11
+ code-block / mention / upload / stop-link), plus a markdown-source view, bound to
12
+ one `v-model`. Wires the Milkdown + ProseMirror adapter providers and handles
13
+ external-value sync without cursor-resetting feedback loops.
14
+
15
+ The public prop/emit surface is unchanged (`v-model`, `adapters`, `features`,
16
+ `locale`, `readonly`), so P0 integrations keep working. View state is
17
+ per-instance (fixes the forum's module-level `activeTab` singleton that would
18
+ cross-wire two editors on a page).
19
+
20
+ Still to come in P3 (they build on `@kungal/ui-vue`): the rich formatting
21
+ toolbar, the `@mention` autocomplete dropdown, the sticker/emoji picker, and the
22
+ CodeMirror markdown-source view (currently a `<textarea>`).
23
+
24
+ ### Patch Changes
25
+
26
+ - @kungal/editor-core@0.3.0
27
+
3
28
  ## 0.2.0
4
29
 
5
30
  ### Patch Changes
package/README.md CHANGED
@@ -48,12 +48,16 @@ Enable optional plugins by also installing their peers: `katex` (LaTeX),
48
48
 
49
49
  ## Status
50
50
 
51
- Scaffold. The `<KunEditor>` prop/emit surface (`v-model`, `adapters`,
52
- `features`, `locale`, `readonly`) is stable; the Milkdown wiring is ported from
53
- the forum's `DualEditorProvider` + `Editor.vue` see
54
- [`../../docs/architecture.md`](../../docs/architecture.md) § migration. Until
55
- then the component renders a textarea fallback that keeps `v-model` live so you
56
- can integrate against the real contract today.
51
+ **P3 in progress.** `<KunEditor>` now renders a **real Milkdown dual-view
52
+ editor**: a WYSIWYG view built from `@kungal/editor-core/preset`
53
+ (`createKunEditorPlugins` spoiler / katex / code-block / mention / upload /
54
+ ), plus a markdown-source view, over one `v-model`. The prop/emit surface
55
+ (`v-model`, `adapters`, `features`, `locale`, `readonly`) is stable.
56
+
57
+ Still to come in P3 (they build on `@kungal/ui-vue`, hence staged): the rich
58
+ formatting toolbar, the `@mention` autocomplete dropdown, the sticker/emoji
59
+ picker, and the CodeMirror markdown-source view (currently a `<textarea>`). See
60
+ [`../../docs/architecture.md`](../../docs/architecture.md) § migration.
57
61
 
58
62
  ## Build
59
63
 
@@ -1,6 +1,6 @@
1
1
  import type { KunEditorAdapters, KunEditorFeatures, KunEditorLocale } from '@kungal/editor-core';
2
2
  type __VLS_Props = {
3
- /** Bound markdown (v-model:markdown). */
3
+ /** Bound markdown (v-model). */
4
4
  modelValue: string;
5
5
  /** Policy: where uploads go, how mentions resolve, how toasts show. */
6
6
  adapters?: KunEditorAdapters;
@@ -8,7 +8,7 @@ type __VLS_Props = {
8
8
  features?: KunEditorFeatures;
9
9
  /** UI language for toolbar labels / placeholders. */
10
10
  locale?: KunEditorLocale;
11
- /** Read-only render (no toolbar, no editing). */
11
+ /** Read-only render (no editing). */
12
12
  readonly?: boolean;
13
13
  };
14
14
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
@@ -1 +1 @@
1
- {"version":3,"file":"KunEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/KunEditor.vue"],"names":[],"mappings":"AA2EA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAE5B,KAAK,WAAW,GAAG;IACf,yCAAyC;IACzC,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,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAC;AAsEJ,QAAA,MAAM,YAAY;;;;;cA7EH,iBAAiB;cAEjB,iBAAiB;YAEnB,eAAe;cAEb,OAAO;6EA2EpB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"KunEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/KunEditor.vue"],"names":[],"mappings":"AA2LA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAG5B,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;AAuKJ,QAAA,MAAM,YAAY;;;;;cA9KH,iBAAiB;cAEjB,iBAAiB;YAEnB,eAAe;cAEb,OAAO;6EA4KpB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -0,0 +1,16 @@
1
+ import type { KunEditorAdapters, KunEditorFeatures, KunEditorLocale } from '@kungal/editor-core';
2
+ type __VLS_Props = {
3
+ modelValue: string;
4
+ adapters: KunEditorAdapters;
5
+ features: KunEditorFeatures;
6
+ locale: KunEditorLocale;
7
+ readonly: boolean;
8
+ };
9
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
10
+ "update:modelValue": (markdown: string) => any;
11
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
12
+ "onUpdate:modelValue"?: ((markdown: string) => any) | undefined;
13
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const _default: typeof __VLS_export;
15
+ export default _default;
16
+ //# sourceMappingURL=MilkdownEditor.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MilkdownEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/MilkdownEditor.vue"],"names":[],"mappings":"AAsGA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAG5B,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;AAoFF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
package/dist/index.js CHANGED
@@ -1,13 +1,46 @@
1
- import { createElementBlock as e, createElementVNode as t, defineComponent as n, openBlock as r } from "vue";
2
- //#region src/components/KunEditor.vue?vue&type=script&setup=true&lang.ts
3
- var i = {
1
+ import { computed as e, createBlock as t, createElementBlock as n, createElementVNode as r, createVNode as i, defineComponent as a, openBlock as o, ref as s, toDisplayString as c, unref as l, vShow as u, watch as d, withCtx as f, withDirectives as p } from "vue";
2
+ import { Milkdown as m, MilkdownProvider as h, useEditor as g } from "@milkdown/vue";
3
+ import { ProsemirrorAdapterProvider as _ } from "@prosemirror-adapter/vue";
4
+ import { Editor as v, defaultValueCtx as y, editorViewOptionsCtx as b, rootCtx as x } from "@milkdown/kit/core";
5
+ import { listenerCtx as S } from "@milkdown/kit/plugin/listener";
6
+ import { replaceAll as C } from "@milkdown/kit/utils";
7
+ import { createKunEditorPlugins as w } from "@kungal/editor-core/preset";
8
+ //#endregion
9
+ //#region src/components/MilkdownEditor.vue
10
+ var T = /* @__PURE__ */ a({
11
+ __name: "MilkdownEditor",
12
+ props: {
13
+ modelValue: {},
14
+ adapters: {},
15
+ features: {},
16
+ locale: {},
17
+ readonly: { type: Boolean }
18
+ },
19
+ emits: ["update:modelValue"],
20
+ setup(e, { emit: n }) {
21
+ let r = e, i = n, a = r.modelValue, s = g((e) => v.make().config((t) => {
22
+ t.set(x, e), t.set(y, r.modelValue), t.get(S).markdownUpdated((e, t, n) => {
23
+ t !== n && (a = t, i("update:modelValue", t));
24
+ }), t.update(b, (e) => ({
25
+ ...e,
26
+ editable: () => !r.readonly
27
+ }));
28
+ }).use(w(r.adapters, r.features, { locale: r.locale })));
29
+ return d(() => r.modelValue, (e) => {
30
+ e !== a && (a = e, s.get()?.action(C(e)));
31
+ }), (e, n) => (o(), t(l(m)));
32
+ }
33
+ }), E = {
4
34
  class: "kun-editor",
5
35
  "data-kun-editor": ""
6
- }, a = [
36
+ }, D = {
37
+ class: "kun-editor__toolbar",
38
+ role: "tablist"
39
+ }, O = ["aria-selected", "data-active"], k = ["aria-selected", "data-active"], A = { class: "kun-editor__wysiwyg" }, j = [
7
40
  "value",
8
41
  "readonly",
9
42
  "lang"
10
- ], o = /* @__PURE__ */ n({
43
+ ], M = /* @__PURE__ */ a({
11
44
  __name: "KunEditor",
12
45
  props: {
13
46
  modelValue: {},
@@ -20,20 +53,60 @@ var i = {
20
53
  }
21
54
  },
22
55
  emits: ["update:modelValue"],
23
- setup(n, { emit: o }) {
24
- let s = n, c = o, l = (e) => {
25
- c("update:modelValue", e.target.value);
26
- };
27
- return s.adapters, s.features, s.locale, (o, s) => (r(), e("div", i, [t("textarea", {
28
- class: "kun-editor__fallback",
29
- value: n.modelValue,
30
- readonly: n.readonly,
31
- lang: n.locale,
32
- onInput: l
33
- }, null, 40, a)]));
56
+ setup(t, { emit: a }) {
57
+ let d = t, m = a, g = s("wysiwyg"), v = e(() => d.locale.toLowerCase().startsWith("en")), y = e(() => v.value ? {
58
+ wysiwyg: "Preview",
59
+ source: "Markdown"
60
+ } : {
61
+ wysiwyg: "预览",
62
+ source: "Markdown"
63
+ }), b = (e) => m("update:modelValue", e), x = (e) => m("update:modelValue", e.target.value);
64
+ return (e, a) => (o(), n("div", E, [
65
+ r("div", D, [r("button", {
66
+ type: "button",
67
+ class: "kun-editor__tab",
68
+ "aria-selected": g.value === "wysiwyg",
69
+ "data-active": g.value === "wysiwyg",
70
+ onClick: a[0] ||= (e) => g.value = "wysiwyg"
71
+ }, c(y.value.wysiwyg), 9, O), r("button", {
72
+ type: "button",
73
+ class: "kun-editor__tab",
74
+ "aria-selected": g.value === "source",
75
+ "data-active": g.value === "source",
76
+ onClick: a[1] ||= (e) => g.value = "source"
77
+ }, c(y.value.source), 9, k)]),
78
+ i(l(h), null, {
79
+ default: f(() => [i(l(_), null, {
80
+ default: f(() => [p(r("div", A, [i(T, {
81
+ "model-value": t.modelValue,
82
+ adapters: t.adapters,
83
+ features: t.features,
84
+ locale: t.locale,
85
+ readonly: t.readonly,
86
+ "onUpdate:modelValue": b
87
+ }, null, 8, [
88
+ "model-value",
89
+ "adapters",
90
+ "features",
91
+ "locale",
92
+ "readonly"
93
+ ])], 512), [[u, g.value === "wysiwyg"]])]),
94
+ _: 1
95
+ })]),
96
+ _: 1
97
+ }),
98
+ p(r("textarea", {
99
+ class: "kun-editor__source",
100
+ value: t.modelValue,
101
+ readonly: t.readonly,
102
+ lang: t.locale,
103
+ spellcheck: "false",
104
+ onInput: x
105
+ }, null, 40, j), [[u, g.value === "source"]])
106
+ ]));
34
107
  }
35
- }), s = { install(e) {
36
- e.component("KunEditor", o);
108
+ }), N = { install(e) {
109
+ e.component("KunEditor", M);
37
110
  } };
38
111
  //#endregion
39
- export { o as KunEditor, s as KunEditorPlugin };
112
+ export { M as KunEditor, N as KunEditorPlugin };
package/dist/style.css ADDED
@@ -0,0 +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}
2
+ /*$vite$:1*/
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungal/editor-vue",
3
- "version": "0.2.0",
3
+ "version": "0.3.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.2.0"
47
+ "@kungal/editor-core": "0.3.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.2.0"
66
+ "@kungal/editor-core": "0.3.0"
67
67
  },
68
68
  "scripts": {
69
69
  "build": "vite build && vue-tsc -p tsconfig.build.json",