@kungal/editor-vue 0.25.2 → 0.27.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,68 @@
1
1
  # @kungal/editor-vue
2
2
 
3
+ ## 0.27.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ac86c0a: Add a heading-outline API for building a table of contents (TOC).
8
+
9
+ A host (e.g. a desktop editor with a left-side outline) can now render its own TOC
10
+ and navigate the editor, without reaching into editor internals:
11
+
12
+ - **`@update:headings`** on `<KunEditor>` — emits the ordered outline
13
+ (`KunHeading[]` = `{ level, text }`) whenever the content changes.
14
+ - **`ref.scrollToHeading(index)`** — scrolls to that heading in the _current_ view
15
+ and places the caret there: the WYSIWYG heading in wysiwyg mode, the CodeMirror
16
+ heading line in source/split mode (so a click navigates the editable pane).
17
+ - **editor-core** exports the pure `parseHeadings(markdown)` (and `KunHeading`) it's
18
+ built on — usable server-side too. Parses ATX headings, skipping code fences.
19
+
20
+ The TOC's styling, colour, indentation and layout (e.g. reserving space on the
21
+ left of the split editor) are entirely the host's — the editor only exposes the
22
+ data + navigation, matching the headless design.
23
+
24
+ Verified in a new docs example (`/examples/toc`): the outline tracks the content;
25
+ clicking an item scrolls + carets to that heading in wysiwyg (scrollTop 0→386,
26
+ caret in the target) and in source (CodeMirror scrolled, cursor on `## …`); new
27
+ `parseHeadings` unit tests pass; 0 console errors.
28
+
29
+ ### Patch Changes
30
+
31
+ - Updated dependencies [ac86c0a]
32
+ - @kungal/editor-core@0.27.0
33
+
34
+ ## 0.26.0
35
+
36
+ ### Minor Changes
37
+
38
+ - 945708d: Add an insert-link feature (click to add a URL).
39
+
40
+ The `link` mark already existed (so `[text](url)` round-trips and pasted URLs
41
+ autolink), but there was no click-to-insert UI. Now there is:
42
+
43
+ - **editor-core**: `insertLinkCommand` (`{ href, text? }`) — applies the link mark
44
+ to the selection, or inserts linked text on an empty selection; clears the
45
+ stored mark afterwards. Re-exported from `@kungal/editor-core/preset`.
46
+ - **editor-vue**: `KunEditorToolbarApi.insertLink(payload)`; a `link` button in the
47
+ default toolbar and the selection bubble (both default-on); `'link'` added to
48
+ `KunToolbarItem` and `KunSelectionItem`. Headless UI prompts for the URL.
49
+ - **editor-nuxt**: `<KunEditorToolbar>` gains a `link` button — a KunPopover with a
50
+ KunInput for the URL.
51
+
52
+ A link is a **mark** (`[text](url)`), deliberately distinct from the custom-NODE
53
+ embeds (mention / quote). A future "article card" or custom component would be a
54
+ node like those (schema + toUrl/fromUrl), not this — a separate mechanism.
55
+
56
+ Verified in the docs production build: the KunUI toolbar popover wraps a selection
57
+ (`[…](https://example.com)`); the selection bubble does too
58
+ (`[linktext](https://kun.com)`); 4 new core tests (wrap / insert / autolink
59
+ fallback / blank-href no-op) pass; 0 console errors.
60
+
61
+ ### Patch Changes
62
+
63
+ - Updated dependencies [945708d]
64
+ - @kungal/editor-core@0.26.0
65
+
3
66
  ## 0.25.2
4
67
 
5
68
  ### Patch Changes
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"EditorToolbar.vue.d.ts","sourceRoot":"","sources":["../../src/components/EditorToolbar.vue"],"names":[],"mappings":"AAieA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -1,4 +1,4 @@
1
- import type { KunEditorAdapters, KunEditorFeatures, KunEditorLocale } from '@kungal/editor-core';
1
+ import type { KunEditorAdapters, KunEditorFeatures, KunEditorLocale, KunHeading } from '@kungal/editor-core';
2
2
  import type { KunEditorExpose, KunSelectionItem } from '../types';
3
3
  type ViewMode = 'wysiwyg' | 'source' | 'split';
4
4
  type __VLS_Props = {
@@ -56,6 +56,10 @@ declare var __VLS_1: {
56
56
  run: <T>(key: import("@milkdown/kit/core").CmdKey<T>, payload?: T) => void;
57
57
  insertText: (text: string) => void;
58
58
  uploadImage: (file: File) => void;
59
+ insertLink: (payload: {
60
+ href: string;
61
+ text?: string;
62
+ }) => void;
59
63
  insertQuote: (payload: {
60
64
  refId: string;
61
65
  label: string;
@@ -76,8 +80,10 @@ type __VLS_Slots = {} & {
76
80
  };
77
81
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, KunEditorExpose, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
78
82
  "update:modelValue": (markdown: string) => any;
83
+ "update:headings": (headings: KunHeading[]) => any;
79
84
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
80
85
  "onUpdate:modelValue"?: ((markdown: string) => any) | undefined;
86
+ "onUpdate:headings"?: ((headings: KunHeading[]) => any) | undefined;
81
87
  }>, {
82
88
  adapters: KunEditorAdapters;
83
89
  features: KunEditorFeatures;
@@ -1 +1 @@
1
- {"version":3,"file":"KunEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/KunEditor.vue"],"names":[],"mappings":"AAuWA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAM5B,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AASjE,KAAK,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE9C,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,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,eAAe,CAAC,EAAE,KAAK,GAAG,OAAO,CAAA;IACjC;;;;OAIG;IACH,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;IAClB;oEACgE;IAChE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,gBAAgB,EAAE,CAAA;CAChD,CAAC;AAgaJ,QAAA,IAAI,OAAO;;iBAvWS,QAAQ;;;;;;;;;;;;;CAuWP,EAAE,QAAQ;iEA3d/B,CA1UkC;;;;;;;;;;;;;;;CAqyB8B,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;AAQhD,QAAA,MAAM,UAAU;;;;;cA1cD,iBAAiB;cAEjB,iBAAiB;YAEnB,eAAe;cAEb,OAAO;iBAEJ,MAAM;qBAMF,KAAK,GAAG,OAAO;sBAgBd,OAAO,GAAG,gBAAgB,EAAE;WAVvC,QAAQ,EAAE;gBAGL,OAAO;6EAwbtB,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":"AAgYA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,UAAU,EACX,MAAM,qBAAqB,CAAA;AAO5B,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAUjE,KAAK,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE9C,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,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,eAAe,CAAC,EAAE,KAAK,GAAG,OAAO,CAAA;IACjC;;;;OAIG;IACH,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAA;IAClB;oEACgE;IAChE,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,gBAAgB,EAAE,CAAA;CAChD,CAAC;AAwbJ,QAAA,IAAI,OAAO;;iBApXS,QAAQ;;;;;;;;;;;;;CAoXP,EAAE,QAAQ;iEAtf/B,CAjWE;;;;;YAiWF,CA7UiC;;;;;;;;;;;;;;CAm0BoD,CAAE;AACvF,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;AAShD,QAAA,MAAM,UAAU;;;;;;;cAneD,iBAAiB;cAEjB,iBAAiB;YAEnB,eAAe;cAEb,OAAO;iBAEJ,MAAM;qBAMF,KAAK,GAAG,OAAO;sBAgBd,OAAO,GAAG,gBAAgB,EAAE;WAVvC,QAAQ,EAAE;gBAGL,OAAO;6EAidtB,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"}
@@ -2,7 +2,9 @@ type __VLS_Props = {
2
2
  modelValue: string;
3
3
  readonly: boolean;
4
4
  };
5
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
6
+ scrollToHeading: (index: number) => void;
7
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
8
  "update:modelValue": (markdown: string) => any;
7
9
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
8
10
  "onUpdate:modelValue"?: ((markdown: string) => any) | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownSource.vue.d.ts","sourceRoot":"","sources":["../../src/components/MarkdownSource.vue"],"names":[],"mappings":"AA2GA,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;CAClB,CAAC;AA2FF,QAAA,MAAM,YAAY;;;;kFAGhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"MarkdownSource.vue.d.ts","sourceRoot":"","sources":["../../src/components/MarkdownSource.vue"],"names":[],"mappings":"AAkJA,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;CAClB,CAAC;AAmIF,QAAA,MAAM,YAAY;6BA/Ec,MAAM;;;;;kFAmFpC,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MilkdownEditor.vue.d.ts","sourceRoot":"","sources":["../../src/components/MilkdownEditor.vue"],"names":[],"mappings":"AAsOA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAI5B,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;IACnB,eAAe,EAAE,KAAK,GAAG,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;IACzB;;;;OAIG;IACH,MAAM,EAAE,OAAO,CAAA;CAChB,CAAC;AA+KF,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":"AA0QA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAI5B,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;IACnB,eAAe,EAAE,KAAK,GAAG,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;IACzB;;;;OAIG;IACH,MAAM,EAAE,OAAO,CAAA;CAChB,CAAC;AAiNF,QAAA,MAAM,YAAY;;;;kFAIhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectionTooltip.vue.d.ts","sourceRoot":"","sources":["../../src/components/SelectionTooltip.vue"],"names":[],"mappings":"AA2RA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"SelectionTooltip.vue.d.ts","sourceRoot":"","sources":["../../src/components/SelectionTooltip.vue"],"names":[],"mappings":"AAiTA,QAAA,MAAM,YAAY,+QAChB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -3,6 +3,10 @@ declare var __VLS_1: {
3
3
  run: <T>(key: CmdKey<T>, payload?: T) => void;
4
4
  insertText: (text: string) => void;
5
5
  uploadImage: (file: File) => void;
6
+ insertLink: (payload: {
7
+ href: string;
8
+ text?: string;
9
+ }) => void;
6
10
  insertQuote: (payload: {
7
11
  refId: string;
8
12
  label: string;
@@ -1 +1 @@
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,CArDQ;;;;;;;;;;;;;;;CA6Ic,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":"AA+FA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AA6FhD,QAAA,IAAI,OAAO;oCA9FX,CA1DqB;;;;;YA0DrB,CAvC2C;;;;;;;;;;;;;;CAqIrB,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.d.ts CHANGED
@@ -7,6 +7,8 @@ export type { KunToolbarItem } from './types';
7
7
  export type { KunSelectionItem } from './types';
8
8
  export type { KunEditorViewSwitchApi } from './types';
9
9
  export { EMOJI } from './emoji';
10
+ export type { KunHeading } from '@kungal/editor-core';
11
+ export { parseHeadings } from '@kungal/editor-core';
10
12
  export type { KunEditorAdapters, KunEditorFeatures, KunEditorLocale, UploadImage, SearchMentionUsers, StickerSource, Notify, NotifyLevel, MentionUser, StickerItem, StickerPack } from '@kungal/editor-core';
11
13
  /** Vue plugin: `app.use(KunEditorPlugin)` to register <KunEditor> globally. */
12
14
  export declare const KunEditorPlugin: Plugin;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAO,MAAM,EAAE,MAAM,KAAK,CAAA;AACtC,OAAO,SAAS,MAAM,4BAA4B,CAAA;AAElD,OAAO,EAAE,SAAS,EAAE,CAAA;AAGpB,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAG9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAGlD,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAG7C,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAG/C,YAAY,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAGrD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAG/B,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,MAAM,EACN,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACZ,MAAM,qBAAqB,CAAA;AAE5B,+EAA+E;AAC/E,eAAO,MAAM,eAAe,EAAE,MAI7B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAO,MAAM,EAAE,MAAM,KAAK,CAAA;AACtC,OAAO,SAAS,MAAM,4BAA4B,CAAA;AAElD,OAAO,EAAE,SAAS,EAAE,CAAA;AAGpB,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAG9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAGlD,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAG7C,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAG/C,YAAY,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAA;AAGrD,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAG/B,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAGnD,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,MAAM,EACN,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACZ,MAAM,qBAAqB,CAAA;AAE5B,+EAA+E;AAC/E,eAAO,MAAM,eAAe,EAAE,MAI7B,CAAA"}
package/dist/index.js CHANGED
@@ -1,37 +1,38 @@
1
1
  import { Fragment as e, computed as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, createVNode as o, defineComponent as s, guardReactiveProps as c, inject as l, nextTick as u, normalizeProps as d, onBeforeUnmount as f, onMounted as p, openBlock as m, provide as h, ref as g, renderList as _, renderSlot as v, toDisplayString as y, unref as b, vShow as x, watch as S, withCtx as C, withDirectives as w, withModifiers as T } from "vue";
2
2
  import { Milkdown as E, MilkdownProvider as D, useEditor as O, useInstance as k } from "@milkdown/vue";
3
3
  import { ProsemirrorAdapterProvider as A, usePluginViewContext as j, usePluginViewFactory as M } from "@prosemirror-adapter/vue";
4
- import { Editor as N, defaultValueCtx as P, editorViewCtx as F, editorViewOptionsCtx as I, rootCtx as L } from "@milkdown/kit/core";
5
- import { listenerCtx as R } from "@milkdown/kit/plugin/listener";
6
- import { SlashProvider as z, slashFactory as B } from "@milkdown/kit/plugin/slash";
7
- import { TooltipProvider as V, tooltipFactory as H } from "@milkdown/kit/plugin/tooltip";
8
- import { callCommand as U, replaceAll as W } from "@milkdown/kit/utils";
9
- import { createKunEditorPlugins as G, insertKunSpoilerCommand as K, insertMentionCommand as q, insertQuoteCommand as J, kunCM as ee, mentionId as te, setHeadingCommand as ne, startImageUpload as re } from "@kungal/editor-core/preset";
10
- import { TextSelection as ie } from "@milkdown/kit/prose/state";
11
- import { createCodeBlockCommand as ae, insertHrCommand as oe, insertImageCommand as se, toggleEmphasisCommand as ce, toggleInlineCodeCommand as le, toggleStrongCommand as ue, wrapInBlockquoteCommand as de, wrapInBulletListCommand as fe, wrapInOrderedListCommand as pe } from "@milkdown/kit/preset/commonmark";
12
- import { toggleStrikethroughCommand as me } from "@milkdown/kit/preset/gfm";
13
- import { Annotation as he, EditorState as ge } from "@codemirror/state";
4
+ import { parseHeadings as N, parseHeadings as ee } from "@kungal/editor-core";
5
+ import { Editor as P, defaultValueCtx as F, editorViewCtx as I, editorViewOptionsCtx as L, rootCtx as R } from "@milkdown/kit/core";
6
+ import { listenerCtx as z } from "@milkdown/kit/plugin/listener";
7
+ import { SlashProvider as B, slashFactory as V } from "@milkdown/kit/plugin/slash";
8
+ import { TooltipProvider as H, tooltipFactory as U } from "@milkdown/kit/plugin/tooltip";
9
+ import { callCommand as W, replaceAll as te } from "@milkdown/kit/utils";
10
+ import { TextSelection as G } from "@milkdown/kit/prose/state";
11
+ import { createKunEditorPlugins as K, insertKunSpoilerCommand as q, insertLinkCommand as J, insertMentionCommand as ne, insertQuoteCommand as re, kunCM as ie, mentionId as ae, setHeadingCommand as oe, startImageUpload as se } from "@kungal/editor-core/preset";
12
+ import { createCodeBlockCommand as ce, insertHrCommand as le, insertImageCommand as ue, toggleEmphasisCommand as de, toggleInlineCodeCommand as fe, toggleStrongCommand as pe, wrapInBlockquoteCommand as me, wrapInBulletListCommand as he, wrapInOrderedListCommand as ge } from "@milkdown/kit/preset/commonmark";
13
+ import { toggleStrikethroughCommand as _e } from "@milkdown/kit/preset/gfm";
14
+ import { Annotation as ve, EditorState as ye } from "@codemirror/state";
14
15
  import { EditorView as Y } from "@codemirror/view";
15
- import { markdown as _e } from "@codemirror/lang-markdown";
16
- import { basicSetup as ve } from "codemirror";
16
+ import { markdown as be } from "@codemirror/lang-markdown";
17
+ import { basicSetup as xe } from "codemirror";
17
18
  //#region src/context.ts
18
- var X = Symbol("kun-editor-context"), ye = [
19
+ var X = Symbol("kun-editor-context"), Se = [
19
20
  "data-active",
20
21
  "onMousedown",
21
22
  "onMouseenter"
22
- ], be = ["src", "alt"], xe = {
23
+ ], Ce = ["src", "alt"], we = {
23
24
  key: 1,
24
25
  class: "kun-mention-dropdown__avatar kun-mention-dropdown__avatar--fallback"
25
- }, Se = { class: "kun-mention-dropdown__name" }, Ce = {
26
+ }, Te = { class: "kun-mention-dropdown__name" }, Ee = {
26
27
  key: 1,
27
28
  class: "kun-mention-dropdown__hint"
28
- }, we = {
29
+ }, De = {
29
30
  key: 2,
30
31
  class: "kun-mention-dropdown__hint"
31
- }, Te = {
32
+ }, Oe = {
32
33
  key: 3,
33
34
  class: "kun-mention-dropdown__hint"
34
- }, Ee = /* @__PURE__ */ s({
35
+ }, ke = /* @__PURE__ */ s({
35
36
  __name: "MentionDropdown",
36
37
  setup(n) {
37
38
  let r = /(?:^|\s)@([^\s@]{0,30})$/, o = l(X), s = o?.adapters.searchMentionUsers, c = t(() => (o?.locale ?? "zh-cn").toLowerCase().startsWith("en")), u = t(() => c.value ? {
@@ -58,30 +59,30 @@ var X = Symbol("kun-editor-context"), ye = [
58
59
  }
59
60
  t === k && (w.value = n ?? [], E.value = 0, D.value = !1);
60
61
  }, 180);
61
- }, P = (e) => {
62
+ }, ee = (e) => {
62
63
  let { selection: t } = e.state;
63
64
  if (!t.empty) return null;
64
65
  let { $from: n } = t, i = n.parent.textBetween(Math.max(0, n.parentOffset - 100), n.parentOffset, void 0, "").match(r);
65
66
  return i ? i[1] ?? "" : null;
66
- }, F = (e) => {
67
- let t = P(e);
67
+ }, P = (e) => {
68
+ let t = ee(e);
68
69
  if (t === null) return !1;
69
70
  let n = e.state.selection.$from.pos;
70
71
  return O = {
71
72
  from: n - (t.length + 1),
72
73
  to: n
73
74
  }, t !== C.value && (C.value = t, N(t)), !0;
74
- }, I = (e) => {
75
+ }, F = (e) => {
75
76
  let t = d.value;
76
77
  if (!t || !O) return;
77
- let n = t.state.schema.nodes[te];
78
+ let n = t.state.schema.nodes[ae];
78
79
  if (!n) return;
79
80
  let r = n.create({
80
81
  userId: e.id,
81
82
  name: e.name
82
83
  }), { from: i, to: a } = O, o = t.state.tr.replaceWith(i, a, r), s = i + r.nodeSize;
83
- o.insertText(" ", s), o.setSelection(ie.create(o.doc, s + 1)), t.dispatch(o.scrollIntoView()), t.focus(), b.hide();
84
- }, L = (e) => {
84
+ o.insertText(" ", s), o.setSelection(G.create(o.doc, s + 1)), t.dispatch(o.scrollIntoView()), t.focus(), b.hide();
85
+ }, I = (e) => {
85
86
  if (!x.value || !w.value.length) {
86
87
  x.value && e.key === "Escape" && (e.preventDefault(), b.hide());
87
88
  return;
@@ -97,7 +98,7 @@ var X = Symbol("kun-editor-context"), ye = [
97
98
  case "Enter":
98
99
  case "Tab": {
99
100
  let t = w.value[E.value];
100
- t && (e.preventDefault(), e.stopPropagation(), I(t));
101
+ t && (e.preventDefault(), e.stopPropagation(), F(t));
101
102
  break;
102
103
  }
103
104
  case "Escape":
@@ -106,20 +107,20 @@ var X = Symbol("kun-editor-context"), ye = [
106
107
  }
107
108
  };
108
109
  return p(() => {
109
- b = new z({
110
+ b = new B({
110
111
  content: v.value,
111
112
  trigger: "@",
112
- shouldShow: F,
113
+ shouldShow: P,
113
114
  debounce: 0
114
115
  }), b.onShow = () => {
115
116
  x.value = !0;
116
117
  }, b.onHide = () => {
117
118
  x.value = !1, M();
118
- }, b.update(d.value, h.value), window.addEventListener("keydown", L, !0);
119
+ }, b.update(d.value, h.value), window.addEventListener("keydown", I, !0);
119
120
  }), S([d, h], () => {
120
121
  b?.update(d.value, h.value);
121
122
  }), f(() => {
122
- A && clearTimeout(A), window.removeEventListener("keydown", L, !0), b?.destroy();
123
+ A && clearTimeout(A), window.removeEventListener("keydown", I, !0), b?.destroy();
123
124
  }), (t, n) => (m(), i("div", {
124
125
  ref_key: "divRef",
125
126
  ref: v,
@@ -130,14 +131,14 @@ var X = Symbol("kun-editor-context"), ye = [
130
131
  type: "button",
131
132
  class: "kun-mention-dropdown__item",
132
133
  "data-active": t === E.value,
133
- onMousedown: T((t) => I(e), ["prevent"]),
134
+ onMousedown: T((t) => F(e), ["prevent"]),
134
135
  onMouseenter: (e) => E.value = t
135
136
  }, [e.avatar ? (m(), i("img", {
136
137
  key: 0,
137
138
  src: e.avatar,
138
139
  alt: e.name,
139
140
  class: "kun-mention-dropdown__avatar"
140
- }, null, 8, be)) : (m(), i("span", xe, y(e.name.charAt(0)), 1)), a("span", Se, y(e.name), 1)], 40, ye))), 128)) : D.value ? (m(), i("div", Ce, y(u.value.searching), 1)) : C.value ? (m(), i("div", we, y(u.value.empty), 1)) : (m(), i("div", Te, y(u.value.prompt), 1))], 512));
141
+ }, null, 8, Ce)) : (m(), i("span", we, y(e.name.charAt(0)), 1)), a("span", Te, y(e.name), 1)], 40, Se))), 128)) : D.value ? (m(), i("div", Ee, y(u.value.searching), 1)) : C.value ? (m(), i("div", De, y(u.value.empty), 1)) : (m(), i("div", Oe, y(u.value.prompt), 1))], 512));
141
142
  }
142
143
  }), Z = (e) => `<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${e}</svg>`, Q = (e, t = 13) => `<svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><text x="12" y="12" dominant-baseline="central" text-anchor="middle" font-size="${t}" font-weight="700" font-family="ui-sans-serif, system-ui, sans-serif" fill="currentColor">${e}</text></svg>`, $ = {
143
144
  bold: Z("<path d=\"M6 4h8a4 4 0 0 1 0 8H6z\"/><path d=\"M6 12h9a4 4 0 0 1 0 8H6z\"/>"),
@@ -154,51 +155,61 @@ var X = Symbol("kun-editor-context"), ye = [
154
155
  hr: Z("<line x1=\"4\" y1=\"12\" x2=\"20\" y2=\"12\"/>"),
155
156
  image: Z("<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/><circle cx=\"9\" cy=\"9\" r=\"1.8\" fill=\"currentColor\" stroke=\"none\"/><path d=\"m21 15-4.5-4.5a2 2 0 0 0-2.8 0L5 19\"/>"),
156
157
  spoiler: Z("<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\"/>"),
158
+ link: Z("<path d=\"M10 13a5 5 0 0 0 7.07 0l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"/><path d=\"M14 11a5 5 0 0 0-7.07 0l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"/>"),
157
159
  latex: Q("Σ", 15),
158
160
  smile: Z("<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\"/>")
159
- }, De = {
161
+ }, Ae = {
160
162
  key: 0,
161
163
  class: "kun-editor__toolbar-divider",
162
164
  "aria-hidden": "true"
163
- }, Oe = [
165
+ }, je = [
164
166
  "title",
165
167
  "aria-label",
166
168
  "onMousedown"
167
- ], ke = ["innerHTML"], Ae = /* @__PURE__ */ s({
169
+ ], Me = ["innerHTML"], Ne = /* @__PURE__ */ s({
168
170
  __name: "SelectionTooltip",
169
171
  setup(n) {
170
172
  let { view: r, prevState: o } = j(), [, s] = k(), c = l(X), u = t(() => (c?.locale ?? "zh-cn").toLowerCase().startsWith("en")), d = g(null), h, v = (e, t) => {
171
- s()?.action(U(e, t));
172
- }, y = t(() => {
173
+ s()?.action(W(e, t));
174
+ }, y = () => {
175
+ let e = window.prompt(u.value ? "Link URL" : "链接 URL")?.trim();
176
+ e && v(J.key, { href: e });
177
+ }, b = t(() => {
173
178
  let e = u.value;
174
179
  return {
175
180
  bold: {
176
181
  svg: $.bold,
177
182
  title: e ? "Bold" : "加粗",
178
- run: () => v(ue.key)
183
+ run: () => v(pe.key)
179
184
  },
180
185
  italic: {
181
186
  svg: $.italic,
182
187
  title: e ? "Italic" : "斜体",
183
- run: () => v(ce.key)
188
+ run: () => v(de.key)
184
189
  },
185
190
  strike: {
186
191
  svg: $.strike,
187
192
  title: e ? "Strikethrough" : "删除线",
188
- run: () => v(me.key)
193
+ run: () => v(_e.key)
189
194
  },
190
195
  code: {
191
196
  svg: $.code,
192
197
  title: e ? "Inline code" : "行内代码",
193
- run: () => v(le.key)
198
+ run: () => v(fe.key)
199
+ },
200
+ link: {
201
+ svg: $.link,
202
+ title: e ? "Link" : "链接",
203
+ run: y
194
204
  }
195
205
  };
196
- }), b = t(() => {
197
- let e = y.value, t = (c?.selectionToolbarItems ?? [
206
+ }), x = t(() => {
207
+ let e = b.value, t = (c?.selectionToolbarItems ?? [
198
208
  "bold",
199
209
  "italic",
200
210
  "strike",
201
- "code"
211
+ "code",
212
+ "link"
202
213
  ]).map((t) => t === "|" ? { divider: !0 } : e[t] ? {
203
214
  divider: !1,
204
215
  ...e[t]
@@ -208,7 +219,7 @@ var X = Symbol("kun-editor-context"), ye = [
208
219
  return n;
209
220
  });
210
221
  return p(() => {
211
- h = new V({
222
+ h = new H({
212
223
  content: d.value,
213
224
  offset: 8
214
225
  }), h.update(r.value, o.value);
@@ -221,7 +232,7 @@ var X = Symbol("kun-editor-context"), ye = [
221
232
  ref: d,
222
233
  class: "kun-editor__bubble",
223
234
  "data-show": "false"
224
- }, [(m(!0), i(e, null, _(b.value, (t, n) => (m(), i(e, { key: n }, [t.divider ? (m(), i("span", De)) : (m(), i("button", {
235
+ }, [(m(!0), i(e, null, _(x.value, (t, n) => (m(), i(e, { key: n }, [t.divider ? (m(), i("span", Ae)) : (m(), i("button", {
225
236
  key: 1,
226
237
  type: "button",
227
238
  class: "kun-editor__bubble-btn",
@@ -231,9 +242,9 @@ var X = Symbol("kun-editor-context"), ye = [
231
242
  }, [a("span", {
232
243
  class: "kun-editor__icon",
233
244
  innerHTML: t.svg
234
- }, null, 8, ke)], 40, Oe))], 64))), 128))], 512));
245
+ }, null, 8, Me)], 40, je))], 64))), 128))], 512));
235
246
  }
236
- }), je = /* @__PURE__ */ s({
247
+ }), Pe = /* @__PURE__ */ s({
237
248
  __name: "MilkdownEditor",
238
249
  props: {
239
250
  modelValue: {},
@@ -248,15 +259,15 @@ var X = Symbol("kun-editor-context"), ye = [
248
259
  },
249
260
  emits: ["update:modelValue"],
250
261
  setup(e, { expose: t, emit: r }) {
251
- let i = e, a = r, o = i.modelValue, s = !1, c = M(), l = B("kunMention"), u = i.features.mention !== !1 && !!i.adapters.searchMentionUsers && !!c, d = H("kunSelectionTooltip"), f = i.selectionToolbar && !!c, p = O((e) => {
252
- let t = N.make().config((t) => {
253
- t.set(L, e), t.set(P, i.modelValue), t.get(R).markdownUpdated((e, t, n) => {
262
+ let i = e, a = r, o = i.modelValue, s = !1, c = M(), l = V("kunMention"), u = i.features.mention !== !1 && !!i.adapters.searchMentionUsers && !!c, d = U("kunSelectionTooltip"), f = i.selectionToolbar && !!c, p = O((e) => {
263
+ let t = P.make().config((t) => {
264
+ t.set(R, e), t.set(F, i.modelValue), t.get(z).markdownUpdated((e, t, n) => {
254
265
  !i.active || s || t === n || (o = t, a("update:modelValue", t));
255
- }), t.update(I, (e) => ({
266
+ }), t.update(L, (e) => ({
256
267
  ...e,
257
268
  editable: () => !i.readonly
258
- })), u && t.set(l.key, { view: c({ component: Ee }) }), f && t.set(d.key, { view: c({ component: Ae }) });
259
- }).use(G(i.adapters, i.features, {
269
+ })), u && t.set(l.key, { view: c({ component: ke }) }), f && t.set(d.key, { view: c({ component: Ne }) });
270
+ }).use(K(i.adapters, i.features, {
260
271
  locale: i.locale,
261
272
  placeholder: i.placeholder,
262
273
  placeholderMode: i.placeholderMode
@@ -267,41 +278,55 @@ var X = Symbol("kun-editor-context"), ye = [
267
278
  if (e === o) return;
268
279
  o = e;
269
280
  let t = p.get();
270
- t && (s = !0, t.action(W(e)), s = !1);
281
+ t && (s = !0, t.action(te(e)), s = !1);
271
282
  }), S(() => i.readonly, () => {
272
283
  p.get()?.action((e) => {
273
- let t = e.get(F);
284
+ let t = e.get(I);
274
285
  t.dispatch(t.state.tr);
275
286
  });
276
287
  });
277
288
  let h = () => {
278
- p.get()?.action((e) => e.get(F).focus());
289
+ p.get()?.action((e) => e.get(I).focus());
279
290
  };
280
291
  return t({
281
292
  insertQuote: (e) => {
282
- p.get()?.action(U(J.key, e)), h();
293
+ p.get()?.action(W(re.key, e)), h();
283
294
  },
284
295
  insertMention: (e) => {
285
- p.get()?.action(U(q.key, e)), h();
296
+ p.get()?.action(W(ne.key, e)), h();
286
297
  },
287
- focus: h
298
+ focus: h,
299
+ scrollToHeading: (e) => {
300
+ p.get()?.action((t) => {
301
+ let n = t.get(I), r = 0, i = -1;
302
+ if (n.state.doc.forEach((t, n) => {
303
+ t.type.name === "heading" && (r === e && (i = n), r += 1);
304
+ }), !(i < 0) && (n.nodeDOM(i)?.scrollIntoView({
305
+ behavior: "smooth",
306
+ block: "start"
307
+ }), n.editable)) {
308
+ let e = G.near(n.state.doc.resolve(i + 1));
309
+ n.dispatch(n.state.tr.setSelection(e)), n.focus();
310
+ }
311
+ });
312
+ }
288
313
  }), (e, t) => (m(), n(b(E)));
289
314
  }
290
- }), Me = /* @__PURE__ */ "😀.😃.😄.😁.😆.😅.🤣.😂.🙂.🙃.😉.😊.😇.🥰.😍.🤩.😘.😗.😚.😋.😛.😜.🤪.😝.🤗.🤭.🤔.🤐.😐.😑.😶.😏.😒.🙄.😬.😌.😔.😪.🤤.😴.😷.🤒.🤕.🥵.🥶.🥴.😵.🤯.🤠.🥳.😎.🤓.🧐.😕.😟.🙁.😮.😯.😲.😳.🥺.😦.😧.😨.😰.😥.😢.😭.😱.😖.😣.😞.😓.😩.😫.🥱.😤.😡.😠.🤬.😈.👿.💀.💩.🤡.👻.👽.🤖.😺.😸.👍.👎.👌.🤌.🤏.✌️.🤞.🤟.🤘.👋.🤚.🖐️.✋.👏.🙌.🤝.🙏.💪.👀.👁️.❤️.🧡.💛.💚.💙.💜.🖤.🤍.💔.💕.💞.💓.💗.💖.💘.💝.💯.✨.⭐.🌟.🔥.💥.💫.⚡.☀️.🌈.🎉.🎊.🎁.🏆.🐶.🐱.🐭.🦊.🐻.🐼.🐨.🦄.🐢.🐳.🍎.🍑.🍓.🍉.🍰.🍺.🍵.☕.🍜.🍙.✅.❌.❓.❗.💤.👑.🎮.🎵.📌.🔖".split("."), Ne = [
315
+ }), Fe = /* @__PURE__ */ "😀.😃.😄.😁.😆.😅.🤣.😂.🙂.🙃.😉.😊.😇.🥰.😍.🤩.😘.😗.😚.😋.😛.😜.🤪.😝.🤗.🤭.🤔.🤐.😐.😑.😶.😏.😒.🙄.😬.😌.😔.😪.🤤.😴.😷.🤒.🤕.🥵.🥶.🥴.😵.🤯.🤠.🥳.😎.🤓.🧐.😕.😟.🙁.😮.😯.😲.😳.🥺.😦.😧.😨.😰.😥.😢.😭.😱.😖.😣.😞.😓.😩.😫.🥱.😤.😡.😠.🤬.😈.👿.💀.💩.🤡.👻.👽.🤖.😺.😸.👍.👎.👌.🤌.🤏.✌️.🤞.🤟.🤘.👋.🤚.🖐️.✋.👏.🙌.🤝.🙏.💪.👀.👁️.❤️.🧡.💛.💚.💙.💜.🖤.🤍.💔.💕.💞.💓.💗.💖.💘.💝.💯.✨.⭐.🌟.🔥.💥.💫.⚡.☀️.🌈.🎉.🎊.🎁.🏆.🐶.🐱.🐭.🦊.🐻.🐼.🐨.🦄.🐢.🐳.🍎.🍑.🍓.🍉.🍰.🍺.🍵.☕.🍜.🍙.✅.❌.❓.❗.💤.👑.🎮.🎵.📌.🔖".split("."), Ie = [
291
316
  "title",
292
317
  "aria-label",
293
318
  "aria-expanded"
294
- ], Pe = ["innerHTML"], Fe = { class: "kun-editor__picker-panel" }, Ie = {
319
+ ], Le = ["innerHTML"], Re = { class: "kun-editor__picker-panel" }, ze = {
295
320
  key: 0,
296
321
  class: "kun-editor__picker-tabs",
297
322
  role: "tablist"
298
- }, Le = ["data-active"], Re = ["data-active"], ze = { class: "kun-editor__emoji-grid" }, Be = ["onClick"], Ve = {
323
+ }, Be = ["data-active"], Ve = ["data-active"], He = { class: "kun-editor__emoji-grid" }, Ue = ["onClick"], We = {
299
324
  key: 1,
300
325
  class: "kun-editor__sticker-body"
301
- }, He = { class: "kun-editor__pack-name" }, Ue = { class: "kun-editor__sticker-grid" }, We = ["title", "onClick"], Ge = ["src", "alt"], Ke = {
326
+ }, Ge = { class: "kun-editor__pack-name" }, Ke = { class: "kun-editor__sticker-grid" }, qe = ["title", "onClick"], Je = ["src", "alt"], Ye = {
302
327
  key: 1,
303
328
  class: "kun-editor__picker-hint"
304
- }, qe = /* @__PURE__ */ s({
329
+ }, Xe = /* @__PURE__ */ s({
305
330
  __name: "StickerPicker",
306
331
  setup(n) {
307
332
  let [, o] = k(), s = l(X), c = s?.adapters.stickerSource, u = !!c, d = t(() => (s?.locale ?? "zh-cn").toLowerCase().startsWith("en")), h = t(() => d.value ? {
@@ -333,11 +358,11 @@ var X = Symbol("kun-editor-context"), ye = [
333
358
  p(() => document.addEventListener("click", j)), f(() => document.removeEventListener("click", j));
334
359
  let M = (e) => {
335
360
  o()?.action((t) => {
336
- let n = t.get(F), { state: r } = n;
361
+ let n = t.get(I), { state: r } = n;
337
362
  n.dispatch(r.tr.insertText(e, r.selection.from));
338
363
  });
339
364
  }, N = (e, t) => {
340
- o()?.action(U(se.key, {
365
+ o()?.action(W(ue.key, {
341
366
  src: e,
342
367
  title: t,
343
368
  alt: t
@@ -357,28 +382,28 @@ var X = Symbol("kun-editor-context"), ye = [
357
382
  }, [a("span", {
358
383
  class: "kun-editor__icon",
359
384
  innerHTML: b($).smile
360
- }, null, 8, Pe)], 8, Ne), w(a("div", Fe, [
361
- u ? (m(), i("div", Ie, [a("button", {
385
+ }, null, 8, Le)], 8, Ie), w(a("div", Re, [
386
+ u ? (m(), i("div", ze, [a("button", {
362
387
  type: "button",
363
388
  class: "kun-editor__picker-tab",
364
389
  "data-active": C.value === "emoji",
365
390
  onClick: n[0] ||= (e) => C.value = "emoji"
366
- }, y(h.value.emoji), 9, Le), a("button", {
391
+ }, y(h.value.emoji), 9, Be), a("button", {
367
392
  type: "button",
368
393
  class: "kun-editor__picker-tab",
369
394
  "data-active": C.value === "sticker",
370
395
  onClick: n[1] ||= (e) => C.value = "sticker"
371
- }, y(h.value.sticker), 9, Re)])) : r("", !0),
372
- w(a("div", ze, [(m(!0), i(e, null, _(b(Me), (e, t) => (m(), i("button", {
396
+ }, y(h.value.sticker), 9, Ve)])) : r("", !0),
397
+ w(a("div", He, [(m(!0), i(e, null, _(b(Fe), (e, t) => (m(), i("button", {
373
398
  key: t,
374
399
  type: "button",
375
400
  class: "kun-editor__emoji",
376
401
  onClick: (t) => M(e)
377
- }, y(e), 9, Be))), 128))], 512), [[x, !u || C.value === "emoji"]]),
378
- u ? w((m(), i("div", Ve, [T.value.length ? (m(!0), i(e, { key: 0 }, _(T.value, (t) => (m(), i("div", {
402
+ }, y(e), 9, Ue))), 128))], 512), [[x, !u || C.value === "emoji"]]),
403
+ u ? w((m(), i("div", We, [T.value.length ? (m(!0), i(e, { key: 0 }, _(T.value, (t) => (m(), i("div", {
379
404
  key: t.name,
380
405
  class: "kun-editor__pack"
381
- }, [a("div", He, y(t.name), 1), a("div", Ue, [(m(!0), i(e, null, _(t.stickers, (e, t) => (m(), i("button", {
406
+ }, [a("div", Ge, y(t.name), 1), a("div", Ke, [(m(!0), i(e, null, _(t.stickers, (e, t) => (m(), i("button", {
382
407
  key: t,
383
408
  type: "button",
384
409
  class: "kun-editor__sticker",
@@ -388,26 +413,29 @@ var X = Symbol("kun-editor-context"), ye = [
388
413
  src: e.src,
389
414
  alt: e.name,
390
415
  loading: "lazy"
391
- }, null, 8, Ge)], 8, We))), 128))])]))), 128)) : (m(), i("div", Ke, y(D.value ? h.value.failed : h.value.empty), 1))], 512)), [[x, C.value === "sticker"]]) : r("", !0)
416
+ }, null, 8, Je)], 8, qe))), 128))])]))), 128)) : (m(), i("div", Ye, y(D.value ? h.value.failed : h.value.empty), 1))], 512)), [[x, C.value === "sticker"]]) : r("", !0)
392
417
  ], 512), [[x, v.value]])], 512));
393
418
  }
394
- }), Je = {
419
+ }), Ze = {
395
420
  class: "kun-editor__format-toolbar",
396
421
  role: "toolbar"
397
- }, Ye = ["aria-label"], Xe = {
422
+ }, Qe = ["aria-label"], $e = {
398
423
  value: "",
399
424
  disabled: "",
400
425
  selected: ""
401
- }, Ze = ["value"], Qe = [
426
+ }, et = ["value"], tt = [
402
427
  "title",
403
428
  "aria-label",
404
429
  "onClick"
405
- ], $e = ["innerHTML"], et = ["title", "aria-label"], tt = ["innerHTML"], nt = /* @__PURE__ */ s({
430
+ ], nt = ["innerHTML"], rt = ["title", "aria-label"], it = ["innerHTML"], at = /* @__PURE__ */ s({
406
431
  __name: "EditorToolbar",
407
432
  setup(n) {
408
433
  let [, s] = k(), c = l(X), u = t(() => c?.adapters.uploadImage), d = t(() => c?.features.sticker !== !1), f = t(() => (c?.locale ?? "zh-cn").toLowerCase().startsWith("en")), p = (e, t) => {
409
- s()?.action(U(e, t));
410
- }, h = t(() => {
434
+ s()?.action(W(e, t));
435
+ }, h = () => {
436
+ let e = window.prompt(f.value ? "Link URL" : "链接 URL")?.trim();
437
+ e && p(J.key, { href: e });
438
+ }, v = t(() => {
411
439
  let e = f.value;
412
440
  return {
413
441
  textSize: e ? "Text size" : "文本大小",
@@ -415,6 +443,7 @@ var X = Symbol("kun-editor-context"), ye = [
415
443
  italic: e ? "Italic" : "斜体",
416
444
  strike: e ? "Strikethrough" : "删除线",
417
445
  code: e ? "Inline code" : "行内代码",
446
+ link: e ? "Link" : "链接",
418
447
  bulletList: e ? "Bullet list" : "无序列表",
419
448
  orderedList: e ? "Ordered list" : "有序列表",
420
449
  quote: e ? "Blockquote" : "引用块",
@@ -423,7 +452,7 @@ var X = Symbol("kun-editor-context"), ye = [
423
452
  spoiler: e ? "Spoiler" : "隐藏文本",
424
453
  image: e ? "Upload image" : "上传图片"
425
454
  };
426
- }), v = t(() => {
455
+ }), x = t(() => {
427
456
  let e = f.value;
428
457
  return [
429
458
  "正文",
@@ -437,86 +466,91 @@ var X = Symbol("kun-editor-context"), ye = [
437
466
  level: n,
438
467
  label: e ? n === 0 ? "Paragraph" : `Heading ${n}` : t
439
468
  }));
440
- }), x = (e) => {
469
+ }), S = (e) => {
441
470
  let t = e.target;
442
- p(ne.key, Number(t.value)), t.selectedIndex = 0;
443
- }, S = t(() => [
471
+ p(oe.key, Number(t.value)), t.selectedIndex = 0;
472
+ }, C = t(() => [
444
473
  [
445
474
  {
446
475
  svg: $.bold,
447
- title: h.value.bold,
448
- run: () => p(ue.key)
476
+ title: v.value.bold,
477
+ run: () => p(pe.key)
449
478
  },
450
479
  {
451
480
  svg: $.italic,
452
- title: h.value.italic,
453
- run: () => p(ce.key)
481
+ title: v.value.italic,
482
+ run: () => p(de.key)
454
483
  },
455
484
  {
456
485
  svg: $.strike,
457
- title: h.value.strike,
458
- run: () => p(me.key)
486
+ title: v.value.strike,
487
+ run: () => p(_e.key)
459
488
  },
460
489
  {
461
490
  svg: $.code,
462
- title: h.value.code,
463
- run: () => p(le.key)
491
+ title: v.value.code,
492
+ run: () => p(fe.key)
493
+ },
494
+ {
495
+ svg: $.link,
496
+ title: v.value.link,
497
+ run: h
464
498
  }
465
499
  ],
466
500
  [
467
501
  {
468
502
  svg: $.bulletList,
469
- title: h.value.bulletList,
470
- run: () => p(fe.key)
503
+ title: v.value.bulletList,
504
+ run: () => p(he.key)
471
505
  },
472
506
  {
473
507
  svg: $.orderedList,
474
- title: h.value.orderedList,
475
- run: () => p(pe.key)
508
+ title: v.value.orderedList,
509
+ run: () => p(ge.key)
476
510
  },
477
511
  {
478
512
  svg: $.quote,
479
- title: h.value.quote,
480
- run: () => p(de.key)
513
+ title: v.value.quote,
514
+ run: () => p(me.key)
481
515
  },
482
516
  {
483
517
  svg: $.codeBlock,
484
- title: h.value.codeBlock,
485
- run: () => p(ae.key, "")
518
+ title: v.value.codeBlock,
519
+ run: () => p(ce.key, "")
486
520
  },
487
521
  {
488
522
  svg: $.hr,
489
- title: h.value.hr,
490
- run: () => p(oe.key)
523
+ title: v.value.hr,
524
+ run: () => p(le.key)
491
525
  }
492
526
  ],
493
527
  [{
494
528
  svg: $.spoiler,
495
- title: h.value.spoiler,
496
- run: () => p(K.key)
529
+ title: v.value.spoiler,
530
+ run: () => p(q.key)
497
531
  }]
498
- ]), C = g(null), w = () => C.value?.click(), T = (e) => {
532
+ ]), w = g(null), T = () => w.value?.click(), E = (e) => {
499
533
  let t = e.target, n = t.files?.[0];
500
534
  t.value = "";
501
535
  let r = u.value;
502
536
  !n || !r || s()?.action((e) => {
503
- re(e.get(F), n, {
537
+ se(e.get(I), n, {
504
538
  uploadImage: r,
505
539
  notify: c?.adapters.notify,
506
540
  locale: c?.locale
507
541
  });
508
542
  });
509
543
  };
510
- return (t, n) => (m(), i("div", Je, [
544
+ return (t, n) => (m(), i("div", Ze, [
511
545
  a("select", {
512
546
  class: "kun-editor__heading-select",
513
- "aria-label": h.value.textSize,
514
- onChange: x
515
- }, [a("option", Xe, y(h.value.textSize), 1), (m(!0), i(e, null, _(v.value, (e) => (m(), i("option", {
547
+ "aria-label": v.value.textSize,
548
+ onChange: S
549
+ }, [a("option", $e, y(v.value.textSize), 1), (m(!0), i(e, null, _(x.value, (e) => (m(), i("option", {
516
550
  key: e.level,
517
551
  value: e.level
518
- }, y(e.label), 9, Ze))), 128))], 40, Ye),
519
- (m(!0), i(e, null, _(S.value, (t, r) => (m(), i(e, { key: r }, [n[0] ||= a("span", {
552
+ }, y(e.label), 9, et))), 128))], 40, Qe),
553
+ (m(!0), i(e, null, _(C.value, (t, r) => (m(), i(e, { key: r }, [n[0] ||= a("span", {
520
554
  class: "kun-editor__toolbar-divider",
521
555
  "aria-hidden": "true"
522
556
  }, null, -1), (m(!0), i(e, null, _(t, (e, t) => (m(), i("button", {
@@ -529,7 +563,7 @@ var X = Symbol("kun-editor-context"), ye = [
529
563
  }, [a("span", {
530
564
  class: "kun-editor__icon",
531
565
  innerHTML: e.svg
532
- }, null, 8, $e)], 8, Qe))), 128))], 64))), 128)),
566
+ }, null, 8, nt)], 8, tt))), 128))], 64))), 128)),
533
567
  u.value ? (m(), i(e, { key: 0 }, [
534
568
  n[1] ||= a("span", {
535
569
  class: "kun-editor__toolbar-divider",
@@ -538,58 +572,61 @@ var X = Symbol("kun-editor-context"), ye = [
538
572
  a("button", {
539
573
  type: "button",
540
574
  class: "kun-editor__tool",
541
- title: h.value.image,
542
- "aria-label": h.value.image,
543
- onClick: w
575
+ title: v.value.image,
576
+ "aria-label": v.value.image,
577
+ onClick: T
544
578
  }, [a("span", {
545
579
  class: "kun-editor__icon",
546
580
  innerHTML: b($).image
547
- }, null, 8, tt)], 8, et),
581
+ }, null, 8, it)], 8, rt),
548
582
  a("input", {
549
583
  ref_key: "fileInput",
550
- ref: C,
584
+ ref: w,
551
585
  type: "file",
552
586
  accept: ".jpg,.jpeg,.png,.webp,.gif",
553
587
  hidden: "",
554
- onChange: T
588
+ onChange: E
555
589
  }, null, 544)
556
590
  ], 64)) : r("", !0),
557
591
  d.value ? (m(), i(e, { key: 1 }, [n[2] ||= a("span", {
558
592
  class: "kun-editor__toolbar-divider",
559
593
  "aria-hidden": "true"
560
- }, null, -1), o(qe)], 64)) : r("", !0)
594
+ }, null, -1), o(Xe)], 64)) : r("", !0)
561
595
  ]));
562
596
  }
563
- }), rt = /* @__PURE__ */ s({
597
+ }), ot = /* @__PURE__ */ s({
564
598
  __name: "ToolbarHost",
565
599
  setup(e) {
566
600
  let [, t] = k(), n = l(X, void 0), r = (e, n) => {
567
- t()?.action(U(e, n));
601
+ t()?.action(W(e, n));
568
602
  }, i = () => {
569
- t()?.action((e) => e.get(F).focus());
603
+ t()?.action((e) => e.get(I).focus());
570
604
  }, a = {
571
605
  run: r,
572
606
  insertText: (e) => {
573
607
  t()?.action((t) => {
574
- let n = t.get(F);
608
+ let n = t.get(I);
575
609
  n.dispatch(n.state.tr.insertText(e));
576
610
  }), i();
577
611
  },
578
612
  uploadImage: (e) => {
579
613
  let r = n?.adapters.uploadImage, i = t();
580
614
  !r || !i || i.action((t) => {
581
- re(t.get(F), e, {
615
+ se(t.get(I), e, {
582
616
  uploadImage: r,
583
617
  notify: n?.adapters.notify,
584
618
  locale: n?.locale
585
619
  });
586
620
  });
587
621
  },
588
- insertQuote: (e) => {
622
+ insertLink: (e) => {
589
623
  r(J.key, e), i();
590
624
  },
625
+ insertQuote: (e) => {
626
+ r(re.key, e), i();
627
+ },
591
628
  insertMention: (e) => {
592
- r(q.key, e), i();
629
+ r(ne.key, e), i();
593
630
  },
594
631
  focus: i,
595
632
  get adapters() {
@@ -604,68 +641,91 @@ var X = Symbol("kun-editor-context"), ye = [
604
641
  };
605
642
  return (e, t) => v(e.$slots, "default", d(c(a)));
606
643
  }
607
- }), it = /* @__PURE__ */ s({
644
+ }), st = /* @__PURE__ */ s({
608
645
  __name: "MarkdownSource",
609
646
  props: {
610
647
  modelValue: {},
611
648
  readonly: { type: Boolean }
612
649
  },
613
650
  emits: ["update:modelValue"],
614
- setup(e, { emit: t }) {
615
- let n = e, r = t, a = g(null), o = null, s = he.define(), c = (e) => ge.create({
651
+ setup(e, { expose: t, emit: n }) {
652
+ let r = e, a = n, o = g(null), s = null, c = ve.define(), l = (e) => ye.create({
616
653
  doc: e,
617
654
  extensions: [
618
- ee(),
655
+ ie(),
619
656
  Y.lineWrapping,
620
- ve,
621
- _e(),
622
- Y.editable.of(!n.readonly),
657
+ xe,
658
+ be(),
659
+ Y.editable.of(!r.readonly),
623
660
  Y.updateListener.of((e) => {
624
- e.docChanged && !e.transactions.some((e) => e.annotation(s)) && r("update:modelValue", e.state.doc.toString());
661
+ e.docChanged && !e.transactions.some((e) => e.annotation(c)) && a("update:modelValue", e.state.doc.toString());
625
662
  })
626
663
  ]
627
664
  });
628
- return p(() => {
629
- a.value && (o = new Y({
630
- state: c(n.modelValue),
631
- parent: a.value
665
+ p(() => {
666
+ o.value && (s = new Y({
667
+ state: l(r.modelValue),
668
+ parent: o.value
632
669
  }));
633
670
  }), f(() => {
634
- o?.destroy(), o = null;
635
- }), S(() => n.modelValue, (e) => {
636
- if (!o || o.state.doc.toString() === e) return;
637
- let { anchor: t, head: n } = o.state.selection.main, r = e.length;
638
- o.dispatch({
671
+ s?.destroy(), s = null;
672
+ });
673
+ let u = /^\s{0,3}(?:```|~~~)/, d = /^ {0,3}#{1,6}\s+/;
674
+ return t({ scrollToHeading: (e) => {
675
+ if (!s) return;
676
+ let { doc: t } = s.state, n = 0, r = !1, i = -1;
677
+ for (let a = 1; a <= t.lines; a += 1) {
678
+ let o = t.line(a);
679
+ if (u.test(o.text)) {
680
+ r = !r;
681
+ continue;
682
+ }
683
+ if (!r && d.test(o.text)) {
684
+ if (n === e) {
685
+ i = o.from;
686
+ break;
687
+ }
688
+ n += 1;
689
+ }
690
+ }
691
+ i < 0 || (s.dispatch({
692
+ selection: { anchor: i },
693
+ scrollIntoView: !0
694
+ }), s.focus());
695
+ } }), S(() => r.modelValue, (e) => {
696
+ if (!s || s.state.doc.toString() === e) return;
697
+ let { anchor: t, head: n } = s.state.selection.main, r = e.length;
698
+ s.dispatch({
639
699
  changes: {
640
700
  from: 0,
641
- to: o.state.doc.length,
701
+ to: s.state.doc.length,
642
702
  insert: e
643
703
  },
644
704
  selection: {
645
705
  anchor: Math.min(t, r),
646
706
  head: Math.min(n, r)
647
707
  },
648
- annotations: s.of(!0)
708
+ annotations: c.of(!0)
649
709
  });
650
710
  }), (e, t) => (m(), i("div", {
651
711
  ref_key: "host",
652
- ref: a,
712
+ ref: o,
653
713
  class: "kun-editor__source"
654
714
  }, null, 512));
655
715
  }
656
- }), at = ["data-mode"], ot = {
716
+ }), ct = ["data-mode"], lt = {
657
717
  key: 0,
658
718
  class: "kun-editor__toolbar",
659
719
  role: "tablist"
660
- }, st = [
720
+ }, ut = [
661
721
  "aria-selected",
662
722
  "data-active",
663
723
  "onClick"
664
- ], ct = ["title", "aria-label"], lt = [
724
+ ], dt = ["title", "aria-label"], ft = [
665
725
  "data-active",
666
726
  "title",
667
727
  "aria-pressed"
668
- ], ut = ["data-swap"], dt = { class: "kun-editor__wysiwyg kun-editor__pane" }, ft = /* @__PURE__ */ s({
728
+ ], pt = ["data-swap"], mt = { class: "kun-editor__wysiwyg kun-editor__pane" }, ht = /* @__PURE__ */ s({
669
729
  __name: "KunEditor",
670
730
  props: {
671
731
  modelValue: {},
@@ -692,15 +752,16 @@ var X = Symbol("kun-editor-context"), ye = [
692
752
  default: !0
693
753
  }
694
754
  },
695
- emits: ["update:modelValue"],
755
+ emits: ["update:modelValue", "update:headings"],
696
756
  setup(s, { expose: l, emit: p }) {
697
757
  let T = [
698
758
  "bold",
699
759
  "italic",
700
760
  "strike",
701
- "code"
761
+ "code",
762
+ "link"
702
763
  ], E = s, O = p;
703
- h(X, {
764
+ S(() => E.modelValue, (e) => O("update:headings", ee(e)), { immediate: !0 }), h(X, {
704
765
  get adapters() {
705
766
  return E.adapters;
706
767
  },
@@ -763,11 +824,14 @@ var X = Symbol("kun-editor-context"), ye = [
763
824
  S([j, F], ([e, t]) => {
764
825
  U(), e === "split" && t && u(W);
765
826
  }), f(U);
766
- let G = t(() => E.readonly || j.value === "split"), K = (e) => O("update:modelValue", e), q = g(null);
827
+ let te = t(() => E.readonly || j.value === "split"), G = (e) => O("update:modelValue", e), K = g(null), q = g(null);
767
828
  return l({
768
- insertQuote: (e) => q.value?.insertQuote(e),
769
- insertMention: (e) => q.value?.insertMention(e),
770
- focus: () => q.value?.focus()
829
+ insertQuote: (e) => K.value?.insertQuote(e),
830
+ insertMention: (e) => K.value?.insertMention(e),
831
+ focus: () => K.value?.focus(),
832
+ scrollToHeading: (e) => {
833
+ j.value === "source" || j.value === "split" ? q.value?.scrollToHeading(e) : K.value?.scrollToHeading(e);
834
+ }
771
835
  }), (t, l) => (m(), i("div", {
772
836
  ref_key: "rootEl",
773
837
  ref: z,
@@ -783,53 +847,55 @@ var X = Symbol("kun-editor-context"), ye = [
783
847
  swap: P,
784
848
  scrollSync: F.value,
785
849
  toggleScrollSync: I
786
- }, () => [s.views.length > 1 ? (m(), i("div", ot, [(m(!0), i(e, null, _(s.views, (e) => (m(), i("button", {
850
+ }, () => [s.views.length > 1 ? (m(), i("div", lt, [(m(!0), i(e, null, _(s.views, (e) => (m(), i("button", {
787
851
  key: e,
788
852
  type: "button",
789
853
  class: "kun-editor__tab",
790
854
  "aria-selected": j.value === e,
791
855
  "data-active": j.value === e,
792
856
  onClick: (t) => M(e)
793
- }, y(R.value[e]), 9, st))), 128)), j.value === "split" ? (m(), i(e, { key: 0 }, [a("button", {
857
+ }, y(R.value[e]), 9, ut))), 128)), j.value === "split" ? (m(), i(e, { key: 0 }, [a("button", {
794
858
  type: "button",
795
859
  class: "kun-editor__tab kun-editor__swap",
796
860
  title: R.value.swap,
797
861
  "aria-label": R.value.swap,
798
862
  onClick: l[0] ||= (e) => P()
799
- }, " ⇄ ", 8, ct), a("button", {
863
+ }, " ⇄ ", 8, dt), a("button", {
800
864
  type: "button",
801
865
  class: "kun-editor__tab",
802
866
  "data-active": F.value,
803
867
  title: R.value.scrollSync,
804
868
  "aria-pressed": F.value,
805
869
  onClick: l[1] ||= (e) => I()
806
- }, y(R.value.scrollSync), 9, lt)], 64)) : r("", !0)])) : r("", !0)]), o(b(D), null, {
870
+ }, y(R.value.scrollSync), 9, ft)], 64)) : r("", !0)])) : r("", !0)]), o(b(D), null, {
807
871
  default: C(() => [o(b(A), null, {
808
- default: C(() => [w(a("div", null, [o(rt, null, {
809
- default: C((e) => [v(t.$slots, "toolbar", d(c(e)), () => [o(nt)])]),
872
+ default: C(() => [w(a("div", null, [o(ot, null, {
873
+ default: C((e) => [v(t.$slots, "toolbar", d(c(e)), () => [o(at)])]),
810
874
  _: 3
811
875
  })], 512), [[x, j.value === "wysiwyg" && !s.readonly]]), a("div", {
812
876
  class: "kun-editor__panes",
813
877
  "data-swap": N.value
814
- }, [j.value === "source" || j.value === "split" ? (m(), n(it, {
878
+ }, [j.value === "source" || j.value === "split" ? (m(), n(st, {
815
879
  key: 0,
880
+ ref_key: "source",
881
+ ref: q,
816
882
  class: "kun-editor__pane",
817
883
  "model-value": s.modelValue,
818
884
  readonly: s.readonly,
819
- "onUpdate:modelValue": K
820
- }, null, 8, ["model-value", "readonly"])) : r("", !0), w(a("div", dt, [o(je, {
885
+ "onUpdate:modelValue": G
886
+ }, null, 8, ["model-value", "readonly"])) : r("", !0), w(a("div", mt, [o(Pe, {
821
887
  ref_key: "inner",
822
- ref: q,
888
+ ref: K,
823
889
  "model-value": s.modelValue,
824
890
  adapters: s.adapters,
825
891
  features: s.features,
826
892
  locale: s.locale,
827
- readonly: G.value,
893
+ readonly: te.value,
828
894
  placeholder: s.placeholder,
829
895
  "placeholder-mode": s.placeholderMode,
830
896
  active: j.value === "wysiwyg" && !s.readonly,
831
897
  "selection-toolbar": k.value,
832
- "onUpdate:modelValue": K
898
+ "onUpdate:modelValue": G
833
899
  }, null, 8, [
834
900
  "model-value",
835
901
  "adapters",
@@ -840,14 +906,14 @@ var X = Symbol("kun-editor-context"), ye = [
840
906
  "placeholder-mode",
841
907
  "active",
842
908
  "selection-toolbar"
843
- ])], 512), [[x, j.value === "wysiwyg" || j.value === "split"]])], 8, ut)]),
909
+ ])], 512), [[x, j.value === "wysiwyg" || j.value === "split"]])], 8, pt)]),
844
910
  _: 3
845
911
  })]),
846
912
  _: 3
847
- })], 8, at));
913
+ })], 8, ct));
848
914
  }
849
- }), pt = { install(e) {
850
- e.component("KunEditor", ft);
915
+ }), gt = { install(e) {
916
+ e.component("KunEditor", ht);
851
917
  } };
852
918
  //#endregion
853
- export { Me as EMOJI, ft as KunEditor, pt as KunEditorPlugin };
919
+ export { Fe as EMOJI, ht as KunEditor, gt as KunEditorPlugin, N as parseHeadings };
@@ -13,6 +13,7 @@ export declare const TOOLBAR_ICONS: {
13
13
  readonly hr: string;
14
14
  readonly image: string;
15
15
  readonly spoiler: string;
16
+ readonly link: string;
16
17
  readonly latex: string;
17
18
  readonly smile: string;
18
19
  };
@@ -1 +1 @@
1
- {"version":3,"file":"toolbar-icons.d.ts","sourceRoot":"","sources":["../src/toolbar-icons.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;CAiBhB,CAAA"}
1
+ {"version":3,"file":"toolbar-icons.d.ts","sourceRoot":"","sources":["../src/toolbar-icons.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;CAkBhB,CAAA"}
package/dist/types.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { CmdKey } from '@milkdown/kit/core';
2
2
  import type { KunEditorAdapters, KunEditorFeatures, KunEditorLocale } from '@kungal/editor-core';
3
- export type KunToolbarItem = 'heading' | 'bold' | 'italic' | 'strike' | 'code' | 'bulletList' | 'orderedList' | 'quote' | 'codeBlock' | 'hr' | 'spoiler' | 'image' | 'picker' | '|';
4
- export type KunSelectionItem = 'bold' | 'italic' | 'strike' | 'code' | '|';
3
+ export type KunToolbarItem = 'heading' | 'bold' | 'italic' | 'strike' | 'code' | 'bulletList' | 'orderedList' | 'quote' | 'codeBlock' | 'hr' | 'spoiler' | 'link' | 'image' | 'picker' | '|';
4
+ export type KunSelectionItem = 'bold' | 'italic' | 'strike' | 'code' | 'link' | '|';
5
5
  export interface KunEditorToolbarApi {
6
6
  /** Run a Milkdown command (import its key from the preset/commonmark/gfm). */
7
7
  run: <T>(key: CmdKey<T>, payload?: T) => void;
@@ -13,6 +13,14 @@ export interface KunEditorToolbarApi {
13
13
  * removing it + notifying on failure. No-op without an `uploadImage` adapter.
14
14
  */
15
15
  uploadImage: (file: File) => void;
16
+ /**
17
+ * Apply a link to the selection, or (empty selection) insert linked text.
18
+ * `text` defaults to the href. Standard markdown `[text](href)`.
19
+ */
20
+ insertLink: (payload: {
21
+ href: string;
22
+ text?: string;
23
+ }) => void;
16
24
  /** Insert a reference atom at the cursor (requires the quote feature). */
17
25
  insertQuote: (payload: {
18
26
  refId: string;
@@ -75,5 +83,11 @@ export interface KunEditorExpose {
75
83
  }): void;
76
84
  /** Focus the WYSIWYG editor. */
77
85
  focus(): void;
86
+ /**
87
+ * Scroll to the index-th heading (matching the `update:headings` outline order)
88
+ * in the active view, placing the caret there when editable. Powers a
89
+ * host-rendered table of contents.
90
+ */
91
+ scrollToHeading(index: number): void;
78
92
  }
79
93
  //# sourceMappingURL=types.d.ts.map
@@ -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;AAK5B,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,YAAY,GACZ,aAAa,GACb,OAAO,GACP,WAAW,GACX,IAAI,GACJ,SAAS,GACT,OAAO,GACP,QAAQ,GACR,GAAG,CAAA;AAIP,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,GAAG,CAAA;AAM1E,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,8EAA8E;IAC9E,KAAK,EAAE,CAAC,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAA;IACzC,qDAAqD;IACrD,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,EAAE,MAAM,CAAA;KACnB,CAAA;IACD,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAA;IAChB,gDAAgD;IAChD,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,4CAA4C;IAC5C,UAAU,EAAE,OAAO,CAAA;IACnB,qCAAqC;IACrC,gBAAgB,EAAE,MAAM,IAAI,CAAA;CAC7B;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;AAK5B,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,YAAY,GACZ,aAAa,GACb,OAAO,GACP,WAAW,GACX,IAAI,GACJ,SAAS,GACT,MAAM,GACN,OAAO,GACP,QAAQ,GACR,GAAG,CAAA;AAIP,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,GACN,GAAG,CAAA;AAMP,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;;;OAGG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAC9D,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,8EAA8E;IAC9E,KAAK,EAAE,CAAC,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC,EAAE,CAAA;IACzC,qDAAqD;IACrD,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,EAAE,MAAM,CAAA;KACnB,CAAA;IACD,iEAAiE;IACjE,OAAO,EAAE,OAAO,CAAA;IAChB,gDAAgD;IAChD,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,4CAA4C;IAC5C,UAAU,EAAE,OAAO,CAAA;IACnB,qCAAqC;IACrC,gBAAgB,EAAE,MAAM,IAAI,CAAA;CAC7B;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;IACb;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungal/editor-vue",
3
- "version": "0.25.2",
3
+ "version": "0.27.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.25.2"
43
+ "@kungal/editor-core": "0.27.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.25.2"
83
+ "@kungal/editor-core": "0.27.0"
84
84
  },
85
85
  "scripts": {
86
86
  "build": "vite build && vue-tsc -p tsconfig.build.json",