@prosekit/vue 0.1.2 → 0.1.4

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,23 +1,43 @@
1
+ import type { Attrs } from '@prosekit/pm/model';
1
2
  import { AutocompleteEmptyProps as AutocompleteEmptyProps_2 } from '@prosekit/lit/autocomplete-empty';
2
3
  import { AutocompleteItemProps as AutocompleteItemProps_2 } from '@prosekit/lit/autocomplete-item';
3
4
  import { AutocompleteListProps as AutocompleteListProps_2 } from '@prosekit/lit/autocomplete-list';
4
5
  import { AutocompletePopoverProps as AutocompletePopoverProps_2 } from '@prosekit/lit/autocomplete-popover';
6
+ import { BaseNodeViewOptions } from '@prosekit/core';
5
7
  import { ComboBoxInputProps as ComboBoxInputProps_2 } from '@prosekit/lit/combo-box-input';
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 { ComponentOptionsMixin } from 'vue';
13
+ import { CoreNodeView } from '@prosemirror-adapter/core';
14
+ import type { CoreNodeViewSpec } from '@prosemirror-adapter/core';
15
+ import type { CoreNodeViewUserOptions } from '@prosemirror-adapter/core';
16
+ import type { Decoration } from '@prosekit/pm/view';
17
+ import type { DecorationSource } from '@prosekit/pm/view';
18
+ import { DefineComponent } from 'vue';
9
19
  import { Editor } from '@prosekit/core';
20
+ import type { EditorView } from '@prosekit/pm/view';
10
21
  import { Extension } from '@prosekit/core';
22
+ import { ExtensionTyping } from '@prosekit/core';
23
+ import { ExtractPropTypes } from 'vue';
24
+ import type { InjectionKey } from 'vue';
11
25
  import { InlinePopoverProps as InlinePopoverProps_2 } from '@prosekit/lit/inline-popover';
12
26
  import { Keymap } from '@prosekit/core';
27
+ import type { Node as Node_2 } from '@prosekit/pm/model';
28
+ import type { NodeViewConstructor } from '@prosekit/pm/view';
13
29
  import { Options } from 'tsup';
14
30
  import { PopoverOptions } from '@prosekit/lit/autocomplete-popover';
15
31
  import { PopoverOptions as PopoverOptions_alias_1 } from '@prosekit/lit/inline-popover';
16
32
  import { PopoverProps as PopoverProps_2 } from '@prosekit/lit/popover';
17
33
  import { Priority } from '@prosekit/core';
34
+ import { PublicProps } from 'vue';
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 type { VNodeRef } from 'vue';
21
41
 
22
42
  declare const AutocompleteEmpty: (props: AutocompleteEmptyProps_2 & {
23
43
  class?: string | undefined;
@@ -83,9 +103,29 @@ export declare type ComboBoxListProps = PropsWithClass<ComboBoxListProps_2>;
83
103
 
84
104
  export declare type ComboBoxProps = PropsWithClass<ComboBoxProps_2>;
85
105
 
106
+ export declare type CreateVueNodeView = ReturnType<typeof useVueNodeViewCreator>;
107
+
86
108
  export declare const default_alias: Options | Options[] | ((overrideOptions: Options) => Options | Options[] | Promise<Options | Options[]>);
87
109
 
88
- export declare const default_alias_1: UserProjectConfigExport;
110
+ export declare const default_alias_1: {
111
+ test: {
112
+ environment: "jsdom";
113
+ };
114
+ };
115
+
116
+ /**
117
+ * Defines a node view using a Vue component.
118
+ *
119
+ * @public
120
+ */
121
+ declare function defineVueNodeView(options: VueNodeViewOptions): Extension;
122
+ export { defineVueNodeView }
123
+ export { defineVueNodeView as defineVueNodeView_alias_1 }
124
+
125
+ /**
126
+ * @internal
127
+ */
128
+ export declare function defineVueNodeViewFactory(nodeViewFactory: NodeViewFactory): Extension<ExtensionTyping<string, string, CommandArgs>>;
89
129
 
90
130
  export declare function injectEditor(): Editor;
91
131
 
@@ -99,6 +139,10 @@ declare type InlinePopoverProps = PropsWithClass<InlinePopoverProps_2>;
99
139
  export { InlinePopoverProps }
100
140
  export { InlinePopoverProps as InlinePopoverProps_alias_1 }
101
141
 
142
+ export declare type NodeViewFactory = (options: VueNodeViewUserOptions) => NodeViewConstructor;
143
+
144
+ export declare const nodeViewFactoryKey: InjectionKey<NodeViewFactory>;
145
+
102
146
  export declare const Popover: (props: PopoverProps_2 & {
103
147
  class?: string | undefined;
104
148
  } & {}) => any;
@@ -112,11 +156,9 @@ export declare type PopoverProps = PropsWithClass<PopoverProps_2>;
112
156
  /**
113
157
  * @internal
114
158
  */
115
- declare type PropsWithClass<P = unknown> = P & {
159
+ export declare type PropsWithClass<P = unknown> = P & {
116
160
  class?: string | undefined;
117
161
  };
118
- export { PropsWithClass }
119
- export { PropsWithClass as PropsWithClass_alias_1 }
120
162
 
121
163
  declare const ProseKit: (props: ProseKitProps & {}) => any;
122
164
  export { ProseKit }
@@ -157,6 +199,81 @@ declare function useKeymap(keymap: Ref<Keymap>, options?: {
157
199
  export { useKeymap }
158
200
  export { useKeymap as useKeymap_alias_1 }
159
201
 
202
+ export declare function useNodeViewFactory(): NodeViewFactory;
203
+
160
204
  export declare function usePriorityExtension<T extends Extension = Extension>(extension: Ref<T | null>, priority?: Priority | null): void;
161
205
 
206
+ export declare function useVueNodeViewCreator(renderVueRenderer: VueRendererResult['renderVueRenderer'], removeVueRenderer: VueRendererResult['removeVueRenderer']): NodeViewFactory;
207
+
208
+ export declare function useVueRenderer(): VueRendererResult;
209
+
210
+ export declare class VueNodeView extends CoreNodeView<VueNodeViewComponent> implements VueRenderer<VueNodeViewProps> {
211
+ key: string;
212
+ context: VueNodeViewProps;
213
+ updateContext: () => void;
214
+ render: () => VueRendererComponent;
215
+ }
216
+
217
+ declare type VueNodeViewComponent = DefineComponent<VueNodeViewProps, any, any>;
218
+ export { VueNodeViewComponent }
219
+ export { VueNodeViewComponent as VueNodeViewComponent_alias_1 }
220
+
221
+ /**
222
+ * Options for {@link defineVueNodeView}.
223
+ *
224
+ * @public
225
+ */
226
+ declare interface VueNodeViewOptions extends BaseNodeViewOptions {
227
+ /**
228
+ * The name of the node type.
229
+ */
230
+ name: string;
231
+ /**
232
+ * The Vue component to render the node.
233
+ */
234
+ component: VueNodeViewComponent;
235
+ }
236
+ export { VueNodeViewOptions }
237
+ export { VueNodeViewOptions as VueNodeViewOptions_alias_1 }
238
+
239
+ declare interface VueNodeViewProps {
240
+ contentRef: VNodeRef;
241
+ view: EditorView;
242
+ getPos: () => number | undefined;
243
+ setAttrs: (attrs: Attrs) => void;
244
+ node: ShallowRef<Node_2>;
245
+ selected: ShallowRef<boolean>;
246
+ decorations: ShallowRef<readonly Decoration[]>;
247
+ innerDecorations: ShallowRef<DecorationSource>;
248
+ }
249
+ export { VueNodeViewProps }
250
+ export { VueNodeViewProps as VueNodeViewProps_alias_1 }
251
+
252
+ export declare type VueNodeViewSpec = CoreNodeViewSpec<VueNodeViewComponent>;
253
+
254
+ export declare type VueNodeViewUserOptions = CoreNodeViewUserOptions<VueNodeViewComponent>;
255
+
256
+ export declare interface VueRenderer<Context> {
257
+ key: string;
258
+ context: Context;
259
+ render: () => VueRendererComponent;
260
+ updateContext: () => void;
261
+ }
262
+
263
+ export declare type VueRendererComponent = DefineComponent<any, any, any>;
264
+
265
+ export declare interface VueRendererResult {
266
+ readonly portals: Ref<Record<string, VueRendererComponent>>;
267
+ readonly renderVueRenderer: (renderer: VueRenderer<unknown>) => void;
268
+ readonly removeVueRenderer: (renderer: VueRenderer<unknown>) => void;
269
+ }
270
+
271
+ export declare const VueViewsConsumer: DefineComponent< {}, () => null, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<ExtractPropTypes< {}>>, {}, {}>;
272
+
273
+ declare const VueViewsProvider: DefineComponent< {}, () => VNode<RendererNode, RendererElement, {
274
+ [key: string]: any;
275
+ }>, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {}, string, PublicProps, Readonly<ExtractPropTypes< {}>>, {}, {}>;
276
+ export { VueViewsProvider }
277
+ export { VueViewsProvider as VueViewsProvider_alias_1 }
278
+
162
279
  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,221 @@ 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 {
190
+ defineNodeViewFactory
191
+ } from "@prosekit/core";
192
+ function defineVueNodeView(options) {
193
+ const { name, ...userOptions } = options;
194
+ return defineNodeViewFactory({
195
+ group: "vue",
196
+ name,
197
+ args: userOptions
198
+ });
199
+ }
200
+ function defineVueNodeViewFactory(nodeViewFactory) {
201
+ return defineNodeViewFactory({
202
+ group: "vue",
203
+ factory: nodeViewFactory
204
+ });
205
+ }
206
+
207
+ // src/hooks/use-extension.ts
208
+ import "@prosekit/core";
209
+ import { unref, watchPostEffect } from "vue";
31
210
 
32
211
  // src/hooks/use-editor.ts
33
212
  import { defineUpdateHandler } from "@prosekit/core";
34
213
  import {
35
214
  onMounted,
36
- onUnmounted,
37
- shallowRef,
215
+ onUnmounted as onUnmounted2,
216
+ shallowRef as shallowRef2,
38
217
  triggerRef
39
218
  } from "vue";
40
219
  function useEditor(options) {
41
220
  var _a;
42
221
  const update = (_a = options == null ? void 0 : options.update) != null ? _a : false;
43
222
  const editor = injectEditor();
44
- const editorRef = shallowRef(editor);
223
+ const editorRef = shallowRef2(editor);
45
224
  if (update) {
46
225
  onMounted(() => {
47
226
  const forceUpdate = () => triggerRef(editorRef);
48
227
  const dispose = editor.use(defineUpdateHandler(forceUpdate));
49
- onUnmounted(dispose);
228
+ onUnmounted2(dispose);
50
229
  });
51
230
  }
52
231
  return editorRef;
53
232
  }
54
233
 
55
234
  // src/hooks/use-extension.ts
56
- import "@prosekit/core";
57
- import { unref, watchPostEffect } from "vue";
58
235
  function useExtension(extension) {
59
236
  const editor = useEditor();
60
237
  watchPostEffect((onCleanup) => {
@@ -65,15 +242,45 @@ function useExtension(extension) {
65
242
  });
66
243
  }
67
244
 
245
+ // src/views/vue-views-comsumer.ts
246
+ var VueViewsConsumer = defineComponent3({
247
+ name: "VueViewsConsumer",
248
+ setup: () => {
249
+ const nodeViewFactory = useNodeViewFactory();
250
+ const extension = computed(() => {
251
+ return defineVueNodeViewFactory(nodeViewFactory);
252
+ });
253
+ useExtension(extension);
254
+ return () => null;
255
+ }
256
+ });
257
+
258
+ // src/components/prosekit.ts
259
+ var ProseKit = defineComponent4(
260
+ (props, { slots }) => {
261
+ provideEditor(props.editor);
262
+ return () => {
263
+ return h3(VueViewsProvider, null, () => {
264
+ var _a;
265
+ return [
266
+ h3(VueViewsConsumer),
267
+ (_a = slots.default) == null ? void 0 : _a.call(slots)
268
+ ];
269
+ });
270
+ };
271
+ },
272
+ { props: ["editor"] }
273
+ );
274
+
68
275
  // src/hooks/use-keymap.ts
69
276
  import { defineKeymap } from "@prosekit/core";
70
- import { computed as computed2, unref as unref3 } from "vue";
277
+ import { computed as computed3, unref as unref3 } from "vue";
71
278
 
72
279
  // src/hooks/use-priority-extension.ts
73
280
  import { withPriority } from "@prosekit/core";
74
- import { computed, unref as unref2 } from "vue";
281
+ import { computed as computed2, unref as unref2 } from "vue";
75
282
  function usePriorityExtension(extension, priority) {
76
- const extensionWithPriority = computed(() => {
283
+ const extensionWithPriority = computed2(() => {
77
284
  const ext = unref2(extension);
78
285
  return ext && priority ? withPriority(ext, priority) : ext;
79
286
  });
@@ -82,11 +289,12 @@ function usePriorityExtension(extension, priority) {
82
289
 
83
290
  // src/hooks/use-keymap.ts
84
291
  function useKeymap(keymap, options) {
85
- const extension = computed2(() => defineKeymap(unref3(keymap)));
292
+ const extension = computed3(() => defineKeymap(unref3(keymap)));
86
293
  usePriorityExtension(extension, options == null ? void 0 : options.priority);
87
294
  }
88
295
  export {
89
296
  ProseKit,
297
+ defineVueNodeView,
90
298
  useEditor,
91
299
  useExtension,
92
300
  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.4",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",
@@ -85,8 +85,10 @@
85
85
  "dist"
86
86
  ],
87
87
  "dependencies": {
88
- "@prosekit/core": "^0.1.0",
89
- "@prosekit/lit": "^0.1.0"
88
+ "@prosekit/core": "^0.2.0",
89
+ "@prosekit/lit": "^0.1.5",
90
+ "@prosekit/pm": "^0.1.1",
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.1.0",
106
+ "vue": "^3.4.0-rc.2"
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'