@prosekit/vue 0.1.2 → 0.1.3

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.
@@ -1,3 +1,5 @@
1
+ import { AllowedComponentProps } from 'vue';
2
+ import type { Attrs } from '@prosekit/pm/model';
1
3
  import { AutocompleteEmptyProps as AutocompleteEmptyProps_2 } from '@prosekit/lit/autocomplete-empty';
2
4
  import { AutocompleteItemProps as AutocompleteItemProps_2 } from '@prosekit/lit/autocomplete-item';
3
5
  import { AutocompleteListProps as AutocompleteListProps_2 } from '@prosekit/lit/autocomplete-list';
@@ -6,18 +8,37 @@ import { ComboBoxInputProps as ComboBoxInputProps_2 } from '@prosekit/lit/combo-
6
8
  import { ComboBoxItemProps as ComboBoxItemProps_2 } from '@prosekit/lit/combo-box-item';
7
9
  import { ComboBoxListProps as ComboBoxListProps_2 } from '@prosekit/lit/combo-box-list';
8
10
  import { ComboBoxProps as ComboBoxProps_2 } from '@prosekit/lit/combo-box';
11
+ import { CommandArgs } from '@prosekit/core';
12
+ import { ComponentCustomProps } from 'vue';
13
+ import { ComponentOptionsMixin } from 'vue';
14
+ import { CoreNodeView } from '@prosemirror-adapter/core';
15
+ import type { CoreNodeViewSpec } from '@prosemirror-adapter/core';
16
+ import type { CoreNodeViewUserOptions } from '@prosemirror-adapter/core';
17
+ import type { Decoration } from '@prosekit/pm/view';
18
+ import type { DecorationSource } from '@prosekit/pm/view';
19
+ import { DefineComponent } from 'vue';
9
20
  import { Editor } from '@prosekit/core';
21
+ import type { EditorView } from '@prosekit/pm/view';
10
22
  import { Extension } from '@prosekit/core';
23
+ import { ExtensionTyping } from '@prosekit/core';
24
+ import { ExtractPropTypes } from 'vue';
25
+ import type { InjectionKey } from 'vue';
11
26
  import { InlinePopoverProps as InlinePopoverProps_2 } from '@prosekit/lit/inline-popover';
12
27
  import { Keymap } from '@prosekit/core';
28
+ import type { Node as Node_2 } from '@prosekit/pm/model';
29
+ import type { NodeViewConstructor } from '@prosekit/pm/view';
13
30
  import { Options } from 'tsup';
14
31
  import { PopoverOptions } from '@prosekit/lit/autocomplete-popover';
15
32
  import { PopoverOptions as PopoverOptions_alias_1 } from '@prosekit/lit/inline-popover';
16
33
  import { PopoverProps as PopoverProps_2 } from '@prosekit/lit/popover';
17
34
  import { Priority } from '@prosekit/core';
18
35
  import { Ref } from 'vue';
36
+ import { RendererElement } from 'vue';
37
+ import { RendererNode } from 'vue';
19
38
  import { ShallowRef } from 'vue';
20
- import { UserProjectConfigExport } from 'vitest/dist/config.js';
39
+ import { VNode } from 'vue';
40
+ import { VNodeProps } from 'vue';
41
+ import type { VNodeRef } from 'vue';
21
42
 
22
43
  declare const AutocompleteEmpty: (props: AutocompleteEmptyProps_2 & {
23
44
  class?: string | undefined;
@@ -83,9 +104,29 @@ export declare type ComboBoxListProps = PropsWithClass<ComboBoxListProps_2>;
83
104
 
84
105
  export declare type ComboBoxProps = PropsWithClass<ComboBoxProps_2>;
85
106
 
107
+ export declare type CreateVueNodeView = ReturnType<typeof useVueNodeViewCreator>;
108
+
86
109
  export declare const default_alias: Options | Options[] | ((overrideOptions: Options) => Options | Options[] | Promise<Options | Options[]>);
87
110
 
88
- export declare const default_alias_1: UserProjectConfigExport;
111
+ export declare const default_alias_1: {
112
+ test: {
113
+ environment: "jsdom";
114
+ };
115
+ };
116
+
117
+ /**
118
+ * Defines a node view using a Vue component.
119
+ *
120
+ * @public
121
+ */
122
+ declare function defineVueNodeView(options: VueNodeViewOptions): Extension;
123
+ export { defineVueNodeView }
124
+ export { defineVueNodeView as defineVueNodeView_alias_1 }
125
+
126
+ /**
127
+ * @internal
128
+ */
129
+ export declare function defineVueNodeViewFactory(nodeViewFactory: NodeViewFactory): Extension<ExtensionTyping<string, string, CommandArgs>>;
89
130
 
90
131
  export declare function injectEditor(): Editor;
91
132
 
@@ -99,6 +140,10 @@ declare type InlinePopoverProps = PropsWithClass<InlinePopoverProps_2>;
99
140
  export { InlinePopoverProps }
100
141
  export { InlinePopoverProps as InlinePopoverProps_alias_1 }
101
142
 
143
+ export declare type NodeViewFactory = (options: VueNodeViewUserOptions) => NodeViewConstructor;
144
+
145
+ export declare const nodeViewFactoryKey: InjectionKey<NodeViewFactory>;
146
+
102
147
  export declare const Popover: (props: PopoverProps_2 & {
103
148
  class?: string | undefined;
104
149
  } & {}) => any;
@@ -112,11 +157,9 @@ export declare type PopoverProps = PropsWithClass<PopoverProps_2>;
112
157
  /**
113
158
  * @internal
114
159
  */
115
- declare type PropsWithClass<P = unknown> = P & {
160
+ export declare type PropsWithClass<P = unknown> = P & {
116
161
  class?: string | undefined;
117
162
  };
118
- export { PropsWithClass }
119
- export { PropsWithClass as PropsWithClass_alias_1 }
120
163
 
121
164
  declare const ProseKit: (props: ProseKitProps & {}) => any;
122
165
  export { ProseKit }
@@ -157,6 +200,77 @@ declare function useKeymap(keymap: Ref<Keymap>, options?: {
157
200
  export { useKeymap }
158
201
  export { useKeymap as useKeymap_alias_1 }
159
202
 
203
+ export declare function useNodeViewFactory(): NodeViewFactory;
204
+
160
205
  export declare function usePriorityExtension<T extends Extension = Extension>(extension: Ref<T | null>, priority?: Priority | null): void;
161
206
 
207
+ export declare function useVueNodeViewCreator(renderVueRenderer: VueRendererResult['renderVueRenderer'], removeVueRenderer: VueRendererResult['removeVueRenderer']): NodeViewFactory;
208
+
209
+ export declare function useVueRenderer(): VueRendererResult;
210
+
211
+ export declare class VueNodeView extends CoreNodeView<VueNodeViewComponent> implements VueRenderer<VueNodeViewProps> {
212
+ key: string;
213
+ context: VueNodeViewProps;
214
+ updateContext: () => void;
215
+ render: () => VueRendererComponent;
216
+ }
217
+
218
+ declare type VueNodeViewComponent = DefineComponent<VueNodeViewProps, any, any>;
219
+ export { VueNodeViewComponent }
220
+ export { VueNodeViewComponent as VueNodeViewComponent_alias_1 }
221
+
222
+ /**
223
+ * Options for {@link defineVueNodeView}.
224
+ *
225
+ * @public
226
+ */
227
+ declare interface VueNodeViewOptions extends VueNodeViewUserOptions {
228
+ /**
229
+ * The name of the node.
230
+ */
231
+ name: string;
232
+ }
233
+ export { VueNodeViewOptions }
234
+ export { VueNodeViewOptions as VueNodeViewOptions_alias_1 }
235
+
236
+ declare interface VueNodeViewProps {
237
+ contentRef: VNodeRef;
238
+ view: EditorView;
239
+ getPos: () => number | undefined;
240
+ setAttrs: (attrs: Attrs) => void;
241
+ node: ShallowRef<Node_2>;
242
+ selected: ShallowRef<boolean>;
243
+ decorations: ShallowRef<readonly Decoration[]>;
244
+ innerDecorations: ShallowRef<DecorationSource>;
245
+ }
246
+ export { VueNodeViewProps }
247
+ export { VueNodeViewProps as VueNodeViewProps_alias_1 }
248
+
249
+ export declare type VueNodeViewSpec = CoreNodeViewSpec<VueNodeViewComponent>;
250
+
251
+ export declare type VueNodeViewUserOptions = CoreNodeViewUserOptions<VueNodeViewComponent>;
252
+
253
+ export declare interface VueRenderer<Context> {
254
+ key: string;
255
+ context: Context;
256
+ render: () => VueRendererComponent;
257
+ updateContext: () => void;
258
+ }
259
+
260
+ export declare type VueRendererComponent = DefineComponent<any, any, any>;
261
+
262
+ export declare interface VueRendererResult {
263
+ readonly portals: Ref<Record<string, VueRendererComponent>>;
264
+ readonly renderVueRenderer: (renderer: VueRenderer<unknown>) => void;
265
+ readonly removeVueRenderer: (renderer: VueRenderer<unknown>) => void;
266
+ }
267
+
268
+ export declare const VueViewsConsumer: DefineComponent< {}, () => null, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes< {}>>, {}, {}>;
269
+
270
+ declare const VueViewsProvider: DefineComponent< {}, () => VNode<RendererNode, RendererElement, {
271
+ [key: string]: any;
272
+ }>, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, VNodeProps & AllowedComponentProps & ComponentCustomProps, Readonly<ExtractPropTypes< {}>>, {}, {}>;
273
+ export { VueViewsProvider }
274
+ export { VueViewsProvider as VueViewsProvider_alias_1 }
275
+
162
276
  export { }
@@ -1,6 +1,9 @@
1
1
  export { ProseKit } from './_tsup-dts-rollup';
2
2
  export { ProseKitProps } from './_tsup-dts-rollup';
3
+ export { defineVueNodeView } from './_tsup-dts-rollup';
4
+ export { VueNodeViewOptions } from './_tsup-dts-rollup';
3
5
  export { useEditor } from './_tsup-dts-rollup';
4
6
  export { useExtension } from './_tsup-dts-rollup';
5
7
  export { useKeymap } from './_tsup-dts-rollup';
6
- export { PropsWithClass } from './_tsup-dts-rollup';
8
+ export { VueNodeViewComponent } from './_tsup-dts-rollup';
9
+ export { VueNodeViewProps } from './_tsup-dts-rollup';
@@ -1,6 +1,6 @@
1
1
  // src/components/prosekit.ts
2
2
  import "@prosekit/core";
3
- import { defineComponent } from "vue";
3
+ import { defineComponent as defineComponent4, h as h3 } from "vue";
4
4
 
5
5
  // src/injection/editor-injection.ts
6
6
  import { ProseKitError } from "@prosekit/core";
@@ -17,44 +17,219 @@ function injectEditor() {
17
17
  return editor;
18
18
  }
19
19
 
20
- // src/components/prosekit.ts
21
- var ProseKit = defineComponent(
22
- (props, { slots }) => {
23
- provideEditor(props.editor);
20
+ // src/views/vue-views-provider.ts
21
+ import { Fragment, defineComponent as defineComponent2, h as h2, provide as provide2 } from "vue";
22
+
23
+ // src/views/node-view/node-view-context.ts
24
+ import { ProseKitError as ProseKitError2 } from "@prosekit/core";
25
+ import { inject as inject2 } from "vue";
26
+ var nodeViewFactoryKey = Symbol(
27
+ "[ProseKit]useNodeViewFactory"
28
+ );
29
+ function useNodeViewFactory() {
30
+ const nodeViewFactory = inject2(nodeViewFactoryKey);
31
+ if (!nodeViewFactory) {
32
+ throw new ProseKitError2("Cannot find node view factory context.");
33
+ }
34
+ return nodeViewFactory;
35
+ }
36
+
37
+ // src/views/node-view/vue-node-view.ts
38
+ import { _getId } from "@prosekit/core";
39
+ import { CoreNodeView } from "@prosemirror-adapter/core";
40
+ import { Teleport, defineComponent, h, markRaw, shallowRef } from "vue";
41
+ var VueNodeView = class extends CoreNodeView {
42
+ constructor() {
43
+ super(...arguments);
44
+ this.key = _getId();
45
+ this.context = {
46
+ contentRef: (element) => {
47
+ if (element && element instanceof HTMLElement && this.contentDOM && element.firstChild !== this.contentDOM)
48
+ element.appendChild(this.contentDOM);
49
+ },
50
+ view: this.view,
51
+ getPos: this.getPos,
52
+ setAttrs: this.setAttrs,
53
+ node: shallowRef(this.node),
54
+ selected: shallowRef(this.selected),
55
+ decorations: shallowRef(this.decorations),
56
+ innerDecorations: shallowRef(this.innerDecorations)
57
+ };
58
+ this.updateContext = () => {
59
+ Object.entries({
60
+ node: this.node,
61
+ selected: this.selected,
62
+ decorations: this.decorations,
63
+ innerDecorations: this.innerDecorations
64
+ }).forEach(([key, value]) => {
65
+ const prev = this.context[key];
66
+ if (prev.value !== value)
67
+ prev.value = value;
68
+ });
69
+ };
70
+ this.render = () => {
71
+ const UserComponent = this.component;
72
+ return markRaw(
73
+ defineComponent({
74
+ name: "ProsemirrorNodeView",
75
+ setup: () => {
76
+ return () => h(
77
+ Teleport,
78
+ {
79
+ key: this.key,
80
+ to: this.dom
81
+ },
82
+ h(UserComponent, this.context)
83
+ );
84
+ }
85
+ })
86
+ );
87
+ };
88
+ }
89
+ };
90
+
91
+ // src/views/node-view/use-vue-node-view-creator.ts
92
+ function useVueNodeViewCreator(renderVueRenderer, removeVueRenderer) {
93
+ const createVueNodeView = (options) => (node, view, getPos, decorations, innerDecorations) => {
94
+ const nodeView = new VueNodeView({
95
+ node,
96
+ view,
97
+ getPos,
98
+ decorations,
99
+ innerDecorations,
100
+ options: {
101
+ ...options,
102
+ onUpdate() {
103
+ var _a;
104
+ (_a = options.onUpdate) == null ? void 0 : _a.call(options);
105
+ nodeView.updateContext();
106
+ },
107
+ selectNode() {
108
+ var _a;
109
+ (_a = options.selectNode) == null ? void 0 : _a.call(options);
110
+ nodeView.updateContext();
111
+ },
112
+ deselectNode() {
113
+ var _a;
114
+ (_a = options.deselectNode) == null ? void 0 : _a.call(options);
115
+ nodeView.updateContext();
116
+ },
117
+ destroy() {
118
+ var _a;
119
+ (_a = options.destroy) == null ? void 0 : _a.call(options);
120
+ removeVueRenderer(nodeView);
121
+ }
122
+ }
123
+ });
124
+ renderVueRenderer(nodeView);
125
+ return nodeView;
126
+ };
127
+ return createVueNodeView;
128
+ }
129
+
130
+ // src/views/vue-renderer.ts
131
+ import {
132
+ getCurrentInstance,
133
+ markRaw as markRaw2,
134
+ onBeforeMount,
135
+ onUnmounted,
136
+ ref
137
+ } from "vue";
138
+ function useVueRenderer() {
139
+ const portals = ref({});
140
+ const instance = getCurrentInstance();
141
+ const update = markRaw2({});
142
+ onBeforeMount(() => {
143
+ update.updater = () => {
144
+ instance == null ? void 0 : instance.update();
145
+ };
146
+ });
147
+ onUnmounted(() => {
148
+ update.updater = void 0;
149
+ });
150
+ const renderVueRenderer = (renderer) => {
151
+ var _a;
152
+ portals.value[renderer.key] = renderer.render();
153
+ (_a = update.updater) == null ? void 0 : _a.call(update);
154
+ };
155
+ const removeVueRenderer = (renderer) => {
156
+ delete portals.value[renderer.key];
157
+ };
158
+ return {
159
+ portals,
160
+ renderVueRenderer,
161
+ removeVueRenderer
162
+ };
163
+ }
164
+
165
+ // src/views/vue-views-provider.ts
166
+ var VueViewsProvider = defineComponent2({
167
+ name: "VueViewsProvider",
168
+ setup: (_, { slots }) => {
169
+ const { portals, renderVueRenderer, removeVueRenderer } = useVueRenderer();
170
+ const createVueNodeView = useVueNodeViewCreator(
171
+ renderVueRenderer,
172
+ removeVueRenderer
173
+ );
174
+ provide2(nodeViewFactoryKey, createVueNodeView);
24
175
  return () => {
25
176
  var _a;
26
- return (_a = slots.default) == null ? void 0 : _a.call(slots);
177
+ return h2(Fragment, null, [
178
+ (_a = slots.default) == null ? void 0 : _a.call(slots),
179
+ Object.values(portals.value).map((x) => h2(x))
180
+ ]);
27
181
  };
28
- },
29
- { props: ["editor"] }
30
- );
182
+ }
183
+ });
184
+
185
+ // src/views/vue-views-comsumer.ts
186
+ import { computed, defineComponent as defineComponent3 } from "vue";
187
+
188
+ // src/extensions/vue-node-view.ts
189
+ import { defineNodeViewFactory } from "@prosekit/core";
190
+ function defineVueNodeView(options) {
191
+ const { name, ...userOptions } = options;
192
+ return defineNodeViewFactory({
193
+ group: "vue",
194
+ name,
195
+ args: userOptions
196
+ });
197
+ }
198
+ function defineVueNodeViewFactory(nodeViewFactory) {
199
+ return defineNodeViewFactory({
200
+ group: "vue",
201
+ factory: nodeViewFactory
202
+ });
203
+ }
204
+
205
+ // src/hooks/use-extension.ts
206
+ import "@prosekit/core";
207
+ import { unref, watchPostEffect } from "vue";
31
208
 
32
209
  // src/hooks/use-editor.ts
33
210
  import { defineUpdateHandler } from "@prosekit/core";
34
211
  import {
35
212
  onMounted,
36
- onUnmounted,
37
- shallowRef,
213
+ onUnmounted as onUnmounted2,
214
+ shallowRef as shallowRef2,
38
215
  triggerRef
39
216
  } from "vue";
40
217
  function useEditor(options) {
41
218
  var _a;
42
219
  const update = (_a = options == null ? void 0 : options.update) != null ? _a : false;
43
220
  const editor = injectEditor();
44
- const editorRef = shallowRef(editor);
221
+ const editorRef = shallowRef2(editor);
45
222
  if (update) {
46
223
  onMounted(() => {
47
224
  const forceUpdate = () => triggerRef(editorRef);
48
225
  const dispose = editor.use(defineUpdateHandler(forceUpdate));
49
- onUnmounted(dispose);
226
+ onUnmounted2(dispose);
50
227
  });
51
228
  }
52
229
  return editorRef;
53
230
  }
54
231
 
55
232
  // src/hooks/use-extension.ts
56
- import "@prosekit/core";
57
- import { unref, watchPostEffect } from "vue";
58
233
  function useExtension(extension) {
59
234
  const editor = useEditor();
60
235
  watchPostEffect((onCleanup) => {
@@ -65,15 +240,45 @@ function useExtension(extension) {
65
240
  });
66
241
  }
67
242
 
243
+ // src/views/vue-views-comsumer.ts
244
+ var VueViewsConsumer = defineComponent3({
245
+ name: "VueViewsConsumer",
246
+ setup: () => {
247
+ const nodeViewFactory = useNodeViewFactory();
248
+ const extension = computed(() => {
249
+ return defineVueNodeViewFactory(nodeViewFactory);
250
+ });
251
+ useExtension(extension);
252
+ return () => null;
253
+ }
254
+ });
255
+
256
+ // src/components/prosekit.ts
257
+ var ProseKit = defineComponent4(
258
+ (props, { slots }) => {
259
+ provideEditor(props.editor);
260
+ return () => {
261
+ return h3(VueViewsProvider, null, () => {
262
+ var _a;
263
+ return [
264
+ h3(VueViewsConsumer),
265
+ (_a = slots.default) == null ? void 0 : _a.call(slots)
266
+ ];
267
+ });
268
+ };
269
+ },
270
+ { props: ["editor"] }
271
+ );
272
+
68
273
  // src/hooks/use-keymap.ts
69
274
  import { defineKeymap } from "@prosekit/core";
70
- import { computed as computed2, unref as unref3 } from "vue";
275
+ import { computed as computed3, unref as unref3 } from "vue";
71
276
 
72
277
  // src/hooks/use-priority-extension.ts
73
278
  import { withPriority } from "@prosekit/core";
74
- import { computed, unref as unref2 } from "vue";
279
+ import { computed as computed2, unref as unref2 } from "vue";
75
280
  function usePriorityExtension(extension, priority) {
76
- const extensionWithPriority = computed(() => {
281
+ const extensionWithPriority = computed2(() => {
77
282
  const ext = unref2(extension);
78
283
  return ext && priority ? withPriority(ext, priority) : ext;
79
284
  });
@@ -82,11 +287,12 @@ function usePriorityExtension(extension, priority) {
82
287
 
83
288
  // src/hooks/use-keymap.ts
84
289
  function useKeymap(keymap, options) {
85
- const extension = computed2(() => defineKeymap(unref3(keymap)));
290
+ const extension = computed3(() => defineKeymap(unref3(keymap)));
86
291
  usePriorityExtension(extension, options == null ? void 0 : options.priority);
87
292
  }
88
293
  export {
89
294
  ProseKit,
295
+ defineVueNodeView,
90
296
  useEditor,
91
297
  useExtension,
92
298
  useKeymap
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/vue",
3
3
  "type": "module",
4
- "version": "0.1.2",
4
+ "version": "0.1.3",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",
@@ -86,7 +86,9 @@
86
86
  ],
87
87
  "dependencies": {
88
88
  "@prosekit/core": "^0.1.0",
89
- "@prosekit/lit": "^0.1.0"
89
+ "@prosekit/lit": "^0.1.0",
90
+ "@prosekit/pm": "^0.1.0",
91
+ "@prosemirror-adapter/core": "^0.2.6"
90
92
  },
91
93
  "peerDependencies": {
92
94
  "vue": ">= 3.0.0"
@@ -99,9 +101,9 @@
99
101
  "devDependencies": {
100
102
  "@prosekit/dev": "*",
101
103
  "tsup": "^8.0.1",
102
- "typescript": "^5.3.2",
103
- "vitest": "^0.34.6",
104
- "vue": "^3.3.9"
104
+ "typescript": "^5.3.3",
105
+ "vitest": "^1.0.4",
106
+ "vue": "^3.3.11"
105
107
  },
106
108
  "scripts": {
107
109
  "build:tsup": "tsup",
package/src/index.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  export { ProseKit, type ProseKitProps } from './components/prosekit'
2
+ export {
3
+ defineVueNodeView,
4
+ type VueNodeViewOptions,
5
+ } from './extensions/vue-node-view'
2
6
  export { useEditor } from './hooks/use-editor'
3
7
  export { useExtension } from './hooks/use-extension'
4
8
  export { useKeymap } from './hooks/use-keymap'
5
- export type { PropsWithClass } from './types'
9
+ export type { VueNodeViewComponent } from './views/node-view/vue-node-view-options'
10
+ export type { VueNodeViewProps } from './views/node-view/vue-node-view-props'