@milkdown/vue 5.4.1 → 5.5.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/lib/index.es.js +6 -6
- package/lib/index.es.js.map +1 -1
- package/package.json +4 -4
- package/src/Editor.tsx +3 -3
- package/src/VueNode.tsx +3 -3
package/lib/index.es.js
CHANGED
|
@@ -23,11 +23,11 @@ const VueNodeContainer = defineComponent({
|
|
|
23
23
|
var _a, _b;
|
|
24
24
|
return createVNode("div", {
|
|
25
25
|
"data-view-container": true
|
|
26
|
-
}, [(_b = (_a = context.slots)
|
|
26
|
+
}, [(_b = (_a = context.slots)["default"]) == null ? void 0 : _b.call(_a)]);
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
});
|
|
30
|
-
VueNodeContainer
|
|
30
|
+
VueNodeContainer["props"] = ["ctx", "editor", "node", "view", "getPos", "decorations"];
|
|
31
31
|
const Content = defineComponent({
|
|
32
32
|
name: "milkdown-content",
|
|
33
33
|
setup: ({
|
|
@@ -40,7 +40,7 @@ const Content = defineComponent({
|
|
|
40
40
|
}, null);
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
|
-
Content
|
|
43
|
+
Content["props"] = ["isMark"];
|
|
44
44
|
const nanoid = customAlphabet("abcedfghicklmn", 10);
|
|
45
45
|
const createVueView = (addPortal, removePortalByKey) => (component) => (ctx) => (node, view, getPos, decorations) => new VueNodeView(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations);
|
|
46
46
|
class VueNodeView {
|
|
@@ -183,11 +183,11 @@ const EditorComponent = defineComponent({
|
|
|
183
183
|
var _a;
|
|
184
184
|
return createVNode("div", {
|
|
185
185
|
"ref": refs.divRef
|
|
186
|
-
}, [(_a = slots
|
|
186
|
+
}, [(_a = slots["default"]) == null ? void 0 : _a.call(slots)]);
|
|
187
187
|
};
|
|
188
188
|
}
|
|
189
189
|
});
|
|
190
|
-
EditorComponent
|
|
190
|
+
EditorComponent["props"] = ["editor", "editorRef"];
|
|
191
191
|
const rootInstance = {
|
|
192
192
|
instance: null
|
|
193
193
|
};
|
|
@@ -227,7 +227,7 @@ const VueEditor = defineComponent({
|
|
|
227
227
|
};
|
|
228
228
|
}
|
|
229
229
|
});
|
|
230
|
-
VueEditor
|
|
230
|
+
VueEditor["props"] = ["editor", "editorRef"];
|
|
231
231
|
const useEditor = (getEditor) => {
|
|
232
232
|
return (...args) => getEditor(...args);
|
|
233
233
|
};
|
package/lib/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../src/VueNode.tsx","../src/VueNodeView.tsx","../src/Editor.tsx"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport { Decoration, EditorView, Mark, Node } from '@milkdown/prose';\nimport { defineComponent, h, InjectionKey, provide } from 'vue';\n\nexport type NodeContext = {\n ctx: Ctx;\n node: Node | Mark;\n view: EditorView;\n getPos: boolean | (() => number);\n decorations: Decoration[];\n};\n\nexport const nodeMetadata: InjectionKey<NodeContext> = Symbol();\n\nexport const VueNodeContainer = defineComponent<NodeContext>({\n name: 'milkdown-node-container',\n setup: ({ node, view, getPos, decorations, ctx }, context) => {\n provide(nodeMetadata, {\n ctx,\n node,\n view,\n getPos,\n decorations,\n });\n return () => <div data-view-container>{context.slots.default?.()}</div>;\n },\n});\nVueNodeContainer.props = ['ctx', 'editor', 'node', 'view', 'getPos', 'decorations'];\n\nexport const Content = defineComponent<{ isInline?: boolean }>({\n name: 'milkdown-content',\n setup: ({ isInline }) => {\n return () => (isInline ? <span data-view-content /> : <div data-view-content />);\n },\n});\nContent.props = ['isMark'];\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport type { Decoration, EditorView, NodeView, ViewFactory } from '@milkdown/prose';\nimport { Mark, Node } from '@milkdown/prose';\nimport { customAlphabet } from 'nanoid';\nimport { DefineComponent, defineComponent, h, markRaw, Teleport } from 'vue';\n\nimport { getRootInstance } from '.';\nimport { Content, VueNodeContainer } from './VueNode';\n\nconst nanoid = customAlphabet('abcedfghicklmn', 10);\n\nexport const createVueView =\n (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) =>\n (component: DefineComponent): ((ctx: Ctx) => ViewFactory) =>\n (ctx) =>\n (node, view, getPos, decorations) =>\n new VueNodeView(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations);\n\nexport class VueNodeView implements NodeView {\n teleportDOM: HTMLElement;\n key: string;\n\n get isInlineOrMark() {\n return this.node instanceof Mark || this.node.isInline;\n }\n\n constructor(\n private ctx: Ctx,\n private component: DefineComponent,\n private addPortal: (portal: DefineComponent, key: string) => void,\n private removePortalByKey: (key: string) => void,\n private node: Node | Mark,\n private view: EditorView,\n private getPos: boolean | (() => number),\n private decorations: Decoration[],\n ) {\n this.key = nanoid();\n this.teleportDOM = document.createElement(this.isInlineOrMark ? 'span' : 'div');\n this.renderPortal();\n }\n\n get dom() {\n return this.teleportDOM.firstElementChild || this.teleportDOM;\n }\n\n get contentDOM() {\n if (this.node instanceof Node && this.node.isLeaf) {\n return null;\n }\n\n return this.teleportDOM.querySelector('[data-view-content]') || this.dom;\n }\n\n renderPortal() {\n if (!this.teleportDOM) return;\n\n const CustomComponent = this.component;\n const Portal = defineComponent({\n name: 'milkdown-portal',\n setup: () => {\n return () => (\n <Teleport key={this.key} to={this.teleportDOM}>\n <VueNodeContainer\n ctx={this.ctx}\n node={this.node}\n view={this.view}\n getPos={this.getPos}\n decorations={this.decorations}\n >\n <CustomComponent>\n <Content isInline={this.isInlineOrMark} />\n </CustomComponent>\n </VueNodeContainer>\n </Teleport>\n );\n },\n });\n this.addPortal(markRaw(Portal) as DefineComponent, this.key);\n const instance = getRootInstance();\n if (instance) {\n instance.update();\n }\n }\n\n destroy() {\n this.removePortalByKey(this.key);\n }\n\n ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {\n if (!this.dom || !this.contentDOM) {\n return true;\n }\n\n if (this.node instanceof Node) {\n if (this.node.isLeaf || this.node.isAtom) {\n return true;\n }\n }\n\n if (mutation.type === 'selection') {\n return false;\n }\n\n if (this.contentDOM === this.dom) {\n return false;\n }\n\n if (this.contentDOM.contains(mutation.target)) {\n return false;\n }\n\n return true;\n }\n\n update(node: Node | Mark, decorations: Decoration[]) {\n if (this.node.type !== node.type) {\n return false;\n }\n\n if (node === this.node && this.decorations === decorations) {\n return true;\n }\n\n this.node = node;\n this.decorations = decorations;\n return true;\n }\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx, Editor, editorViewCtx, rootCtx } from '@milkdown/core';\nimport { ViewFactory } from '@milkdown/prose';\nimport {\n ComponentInternalInstance,\n DefineComponent,\n defineComponent,\n getCurrentInstance,\n h,\n inject,\n InjectionKey,\n markRaw,\n onBeforeMount,\n onMounted,\n onUnmounted,\n provide,\n Ref,\n ref,\n shallowReactive,\n} from 'vue';\n\nimport { AnyVueComponent } from './utils';\nimport { createVueView } from './VueNodeView';\n\nconst rendererKey: InjectionKey<(component: DefineComponent) => (ctx: Ctx) => ViewFactory> = Symbol();\n\ntype GetEditor = (\n container: HTMLDivElement,\n renderVue: (Component: AnyVueComponent) => (ctx: Ctx) => ViewFactory,\n) => Editor;\n\nconst useGetEditor = (getEditor: GetEditor) => {\n const divRef = ref<HTMLDivElement | null>(null);\n const renderVue = inject<(Component: DefineComponent) => (ctx: Ctx) => ViewFactory>(rendererKey, () => {\n throw new Error();\n });\n const editorRef = markRaw<{ editor?: Editor }>({});\n onMounted(() => {\n if (!divRef.value) return;\n\n getEditor(divRef.value, renderVue)\n .create()\n .then((editor) => {\n editorRef.editor = editor;\n return;\n })\n .catch((e) => console.error(e));\n });\n onUnmounted(() => {\n const view = editorRef.editor?.action((ctx) => ctx.get(editorViewCtx));\n const root = editorRef.editor?.action((ctx) => ctx.get(rootCtx)) as HTMLElement;\n\n root?.firstChild?.remove();\n view?.destroy();\n });\n\n return { divRef, editorRef };\n};\n\nexport const EditorComponent = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({\n name: 'milkdown-dom-root',\n setup: (props, { slots }) => {\n const refs = useGetEditor(props.editor);\n if (props.editorRef) {\n props.editorRef.value = {\n get: () => refs.editorRef.editor,\n dom: () => refs.divRef.value,\n };\n }\n\n return () => <div ref={refs.divRef}>{slots.default?.()}</div>;\n },\n});\nEditorComponent.props = ['editor', 'editorRef'];\n\nexport type EditorRef = { get: () => Editor | undefined; dom: () => HTMLDivElement | null };\n\nconst rootInstance: {\n instance: null | ComponentInternalInstance;\n} = {\n instance: null,\n};\nexport const getRootInstance = () => {\n return rootInstance.instance;\n};\n\ntype PortalPair = [key: string, component: DefineComponent];\nexport const VueEditor = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({\n name: 'milkdown-vue-root',\n setup: (props) => {\n const portals = shallowReactive<PortalPair[]>([]);\n\n const instance = getCurrentInstance();\n\n onBeforeMount(() => {\n rootInstance.instance = (instance as ComponentInternalInstance & { ctx: { _: ComponentInternalInstance } })\n .ctx._ as ComponentInternalInstance;\n });\n\n onUnmounted(() => {\n rootInstance.instance = null;\n });\n\n const addPortal = markRaw((component: DefineComponent, key: string) => {\n portals.push([key, component]);\n });\n const removePortalByKey = markRaw((key: string) => {\n const index = portals.findIndex((p) => p[0] === key);\n portals.splice(index, 1);\n });\n const renderVue = createVueView(addPortal, removePortalByKey);\n provide(rendererKey, renderVue);\n\n return () => {\n const portalElements = portals.map(([id, P]) => <P key={id} />);\n return (\n <EditorComponent editorRef={props.editorRef} editor={props.editor}>\n {portalElements}\n </EditorComponent>\n );\n };\n },\n});\nVueEditor.props = ['editor', 'editorRef'];\n\nexport const useEditor = (getEditor: GetEditor) => {\n return (...args: Parameters<GetEditor>) => getEditor(...args);\n};\n"],"names":["nodeMetadata","Symbol","VueNodeContainer","defineComponent","name","setup","node","view","getPos","decorations","ctx","context","provide","slots","default","props","Content","isInline","nanoid","customAlphabet","createVueView","addPortal","removePortalByKey","component","VueNodeView","isInlineOrMark","Mark","constructor","key","teleportDOM","document","createElement","renderPortal","dom","firstElementChild","contentDOM","Node","isLeaf","querySelector","CustomComponent","Portal","markRaw","instance","getRootInstance","update","destroy","ignoreMutation","mutation","isAtom","type","contains","target","rendererKey","useGetEditor","getEditor","divRef","ref","renderVue","inject","Error","editorRef","onMounted","value","create","then","editor","catch","e","console","error","onUnmounted","action","get","editorViewCtx","root","rootCtx","firstChild","remove","EditorComponent","refs","rootInstance","VueEditor","portals","shallowReactive","getCurrentInstance","onBeforeMount","_","push","index","findIndex","p","splice","portalElements","map","id","P","useEditor","args"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../src/VueNode.tsx","../src/VueNodeView.tsx","../src/Editor.tsx"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport { Decoration, EditorView, Mark, Node } from '@milkdown/prose';\nimport { defineComponent, h, InjectionKey, provide } from 'vue';\n\nexport type NodeContext = {\n ctx: Ctx;\n node: Node | Mark;\n view: EditorView;\n getPos: boolean | (() => number);\n decorations: Decoration[];\n};\n\nexport const nodeMetadata: InjectionKey<NodeContext> = Symbol();\n\nexport const VueNodeContainer = defineComponent<NodeContext>({\n name: 'milkdown-node-container',\n setup: ({ node, view, getPos, decorations, ctx }, context) => {\n provide(nodeMetadata, {\n ctx,\n node,\n view,\n getPos,\n decorations,\n });\n return () => <div data-view-container>{context.slots['default']?.()}</div>;\n },\n});\nVueNodeContainer['props'] = ['ctx', 'editor', 'node', 'view', 'getPos', 'decorations'];\n\nexport const Content = defineComponent<{ isInline?: boolean }>({\n name: 'milkdown-content',\n setup: ({ isInline }) => {\n return () => (isInline ? <span data-view-content /> : <div data-view-content />);\n },\n});\nContent['props'] = ['isMark'];\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx } from '@milkdown/core';\nimport type { Decoration, EditorView, NodeView, ViewFactory } from '@milkdown/prose';\nimport { Mark, Node } from '@milkdown/prose';\nimport { customAlphabet } from 'nanoid';\nimport { DefineComponent, defineComponent, h, markRaw, Teleport } from 'vue';\n\nimport { getRootInstance } from '.';\nimport { Content, VueNodeContainer } from './VueNode';\n\nconst nanoid = customAlphabet('abcedfghicklmn', 10);\n\nexport const createVueView =\n (addPortal: (portal: DefineComponent, key: string) => void, removePortalByKey: (key: string) => void) =>\n (component: DefineComponent): ((ctx: Ctx) => ViewFactory) =>\n (ctx) =>\n (node, view, getPos, decorations) =>\n new VueNodeView(ctx, component, addPortal, removePortalByKey, node, view, getPos, decorations);\n\nexport class VueNodeView implements NodeView {\n teleportDOM: HTMLElement;\n key: string;\n\n get isInlineOrMark() {\n return this.node instanceof Mark || this.node.isInline;\n }\n\n constructor(\n private ctx: Ctx,\n private component: DefineComponent,\n private addPortal: (portal: DefineComponent, key: string) => void,\n private removePortalByKey: (key: string) => void,\n private node: Node | Mark,\n private view: EditorView,\n private getPos: boolean | (() => number),\n private decorations: Decoration[],\n ) {\n this.key = nanoid();\n this.teleportDOM = document.createElement(this.isInlineOrMark ? 'span' : 'div');\n this.renderPortal();\n }\n\n get dom() {\n return this.teleportDOM.firstElementChild || this.teleportDOM;\n }\n\n get contentDOM() {\n if (this.node instanceof Node && this.node.isLeaf) {\n return null;\n }\n\n return this.teleportDOM.querySelector('[data-view-content]') || this.dom;\n }\n\n renderPortal() {\n if (!this.teleportDOM) return;\n\n const CustomComponent = this.component;\n const Portal = defineComponent({\n name: 'milkdown-portal',\n setup: () => {\n return () => (\n <Teleport key={this.key} to={this.teleportDOM}>\n <VueNodeContainer\n ctx={this.ctx}\n node={this.node}\n view={this.view}\n getPos={this.getPos}\n decorations={this.decorations}\n >\n <CustomComponent>\n <Content isInline={this.isInlineOrMark} />\n </CustomComponent>\n </VueNodeContainer>\n </Teleport>\n );\n },\n });\n this.addPortal(markRaw(Portal) as DefineComponent, this.key);\n const instance = getRootInstance();\n if (instance) {\n instance.update();\n }\n }\n\n destroy() {\n this.removePortalByKey(this.key);\n }\n\n ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {\n if (!this.dom || !this.contentDOM) {\n return true;\n }\n\n if (this.node instanceof Node) {\n if (this.node.isLeaf || this.node.isAtom) {\n return true;\n }\n }\n\n if (mutation.type === 'selection') {\n return false;\n }\n\n if (this.contentDOM === this.dom) {\n return false;\n }\n\n if (this.contentDOM.contains(mutation.target)) {\n return false;\n }\n\n return true;\n }\n\n update(node: Node | Mark, decorations: Decoration[]) {\n if (this.node.type !== node.type) {\n return false;\n }\n\n if (node === this.node && this.decorations === decorations) {\n return true;\n }\n\n this.node = node;\n this.decorations = decorations;\n return true;\n }\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { Ctx, Editor, editorViewCtx, rootCtx } from '@milkdown/core';\nimport { ViewFactory } from '@milkdown/prose';\nimport {\n ComponentInternalInstance,\n DefineComponent,\n defineComponent,\n getCurrentInstance,\n h,\n inject,\n InjectionKey,\n markRaw,\n onBeforeMount,\n onMounted,\n onUnmounted,\n provide,\n Ref,\n ref,\n shallowReactive,\n} from 'vue';\n\nimport { AnyVueComponent } from './utils';\nimport { createVueView } from './VueNodeView';\n\nconst rendererKey: InjectionKey<(component: DefineComponent) => (ctx: Ctx) => ViewFactory> = Symbol();\n\ntype GetEditor = (\n container: HTMLDivElement,\n renderVue: (Component: AnyVueComponent) => (ctx: Ctx) => ViewFactory,\n) => Editor;\n\nconst useGetEditor = (getEditor: GetEditor) => {\n const divRef = ref<HTMLDivElement | null>(null);\n const renderVue = inject<(Component: DefineComponent) => (ctx: Ctx) => ViewFactory>(rendererKey, () => {\n throw new Error();\n });\n const editorRef = markRaw<{ editor?: Editor }>({});\n onMounted(() => {\n if (!divRef.value) return;\n\n getEditor(divRef.value, renderVue)\n .create()\n .then((editor) => {\n editorRef.editor = editor;\n return;\n })\n .catch((e) => console.error(e));\n });\n onUnmounted(() => {\n const view = editorRef.editor?.action((ctx) => ctx.get(editorViewCtx));\n const root = editorRef.editor?.action((ctx) => ctx.get(rootCtx)) as HTMLElement;\n\n root?.firstChild?.remove();\n view?.destroy();\n });\n\n return { divRef, editorRef };\n};\n\nexport const EditorComponent = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({\n name: 'milkdown-dom-root',\n setup: (props, { slots }) => {\n const refs = useGetEditor(props.editor);\n if (props.editorRef) {\n props.editorRef.value = {\n get: () => refs.editorRef.editor,\n dom: () => refs.divRef.value,\n };\n }\n\n return () => <div ref={refs.divRef}>{slots['default']?.()}</div>;\n },\n});\nEditorComponent['props'] = ['editor', 'editorRef'];\n\nexport type EditorRef = { get: () => Editor | undefined; dom: () => HTMLDivElement | null };\n\nconst rootInstance: {\n instance: null | ComponentInternalInstance;\n} = {\n instance: null,\n};\nexport const getRootInstance = () => {\n return rootInstance.instance;\n};\n\ntype PortalPair = [key: string, component: DefineComponent];\nexport const VueEditor = defineComponent<{ editor: GetEditor; editorRef?: Ref<EditorRef> }>({\n name: 'milkdown-vue-root',\n setup: (props) => {\n const portals = shallowReactive<PortalPair[]>([]);\n\n const instance = getCurrentInstance();\n\n onBeforeMount(() => {\n rootInstance.instance = (instance as ComponentInternalInstance & { ctx: { _: ComponentInternalInstance } })\n .ctx._ as ComponentInternalInstance;\n });\n\n onUnmounted(() => {\n rootInstance.instance = null;\n });\n\n const addPortal = markRaw((component: DefineComponent, key: string) => {\n portals.push([key, component]);\n });\n const removePortalByKey = markRaw((key: string) => {\n const index = portals.findIndex((p) => p[0] === key);\n portals.splice(index, 1);\n });\n const renderVue = createVueView(addPortal, removePortalByKey);\n provide(rendererKey, renderVue);\n\n return () => {\n const portalElements = portals.map(([id, P]) => <P key={id} />);\n return (\n <EditorComponent editorRef={props.editorRef} editor={props.editor}>\n {portalElements}\n </EditorComponent>\n );\n };\n },\n});\nVueEditor['props'] = ['editor', 'editorRef'];\n\nexport const useEditor = (getEditor: GetEditor) => {\n return (...args: Parameters<GetEditor>) => getEditor(...args);\n};\n"],"names":["nodeMetadata","Symbol","VueNodeContainer","defineComponent","name","setup","node","view","getPos","decorations","ctx","context","provide","slots","Content","isInline","nanoid","customAlphabet","createVueView","addPortal","removePortalByKey","component","VueNodeView","isInlineOrMark","Mark","constructor","key","teleportDOM","document","createElement","renderPortal","dom","firstElementChild","contentDOM","Node","isLeaf","querySelector","CustomComponent","Portal","markRaw","instance","getRootInstance","update","destroy","ignoreMutation","mutation","isAtom","type","contains","target","rendererKey","useGetEditor","getEditor","divRef","ref","renderVue","inject","Error","editorRef","onMounted","value","create","then","editor","catch","e","console","error","onUnmounted","action","get","editorViewCtx","root","rootCtx","firstChild","remove","EditorComponent","props","refs","rootInstance","VueEditor","portals","shallowReactive","getCurrentInstance","onBeforeMount","_","push","index","findIndex","p","splice","portalElements","map","id","P","useEditor","args"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milkdown/vue",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./lib/index.es.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"vue"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@milkdown/utils": "5.
|
|
19
|
+
"@milkdown/utils": "5.5.0",
|
|
20
20
|
"nanoid": "^3.1.25",
|
|
21
21
|
"tslib": "^2.3.1"
|
|
22
22
|
},
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"vue": "^3.0.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@milkdown/core": "5.
|
|
30
|
-
"@milkdown/prose": "5.
|
|
29
|
+
"@milkdown/core": "5.5.0",
|
|
30
|
+
"@milkdown/prose": "5.5.0",
|
|
31
31
|
"vue": "^3.0.0"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
package/src/Editor.tsx
CHANGED
|
@@ -68,10 +68,10 @@ export const EditorComponent = defineComponent<{ editor: GetEditor; editorRef?:
|
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
return () => <div ref={refs.divRef}>{slots
|
|
71
|
+
return () => <div ref={refs.divRef}>{slots['default']?.()}</div>;
|
|
72
72
|
},
|
|
73
73
|
});
|
|
74
|
-
EditorComponent
|
|
74
|
+
EditorComponent['props'] = ['editor', 'editorRef'];
|
|
75
75
|
|
|
76
76
|
export type EditorRef = { get: () => Editor | undefined; dom: () => HTMLDivElement | null };
|
|
77
77
|
|
|
@@ -121,7 +121,7 @@ export const VueEditor = defineComponent<{ editor: GetEditor; editorRef?: Ref<Ed
|
|
|
121
121
|
};
|
|
122
122
|
},
|
|
123
123
|
});
|
|
124
|
-
VueEditor
|
|
124
|
+
VueEditor['props'] = ['editor', 'editorRef'];
|
|
125
125
|
|
|
126
126
|
export const useEditor = (getEditor: GetEditor) => {
|
|
127
127
|
return (...args: Parameters<GetEditor>) => getEditor(...args);
|
package/src/VueNode.tsx
CHANGED
|
@@ -23,10 +23,10 @@ export const VueNodeContainer = defineComponent<NodeContext>({
|
|
|
23
23
|
getPos,
|
|
24
24
|
decorations,
|
|
25
25
|
});
|
|
26
|
-
return () => <div data-view-container>{context.slots
|
|
26
|
+
return () => <div data-view-container>{context.slots['default']?.()}</div>;
|
|
27
27
|
},
|
|
28
28
|
});
|
|
29
|
-
VueNodeContainer
|
|
29
|
+
VueNodeContainer['props'] = ['ctx', 'editor', 'node', 'view', 'getPos', 'decorations'];
|
|
30
30
|
|
|
31
31
|
export const Content = defineComponent<{ isInline?: boolean }>({
|
|
32
32
|
name: 'milkdown-content',
|
|
@@ -34,4 +34,4 @@ export const Content = defineComponent<{ isInline?: boolean }>({
|
|
|
34
34
|
return () => (isInline ? <span data-view-content /> : <div data-view-content />);
|
|
35
35
|
},
|
|
36
36
|
});
|
|
37
|
-
Content
|
|
37
|
+
Content['props'] = ['isMark'];
|