@ap666/office-word 0.1.3 → 0.1.6
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/README.md +117 -1
- package/dist/components/LocalFileBlockView.vue.d.ts +3 -0
- package/dist/components/OutlinePanel.vue.d.ts +1 -0
- package/dist/components/RichTextEditor.vue.d.ts +10 -1
- package/dist/composables/useRichTextEditor.d.ts +8 -0
- package/dist/extensions/local-file-block.d.ts +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4429 -4178
- package/dist/index.umd.cjs +396 -218
- package/dist/style.css +1 -1
- package/dist/types.d.ts +40 -0
- package/docs/usage.md +49 -0
- package/package.json +8 -2
- package/yjs/README.md +63 -0
- package/yjs/index.js +224 -0
- package/yjs/package.json +14 -0
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ npm install @ap666/office-word
|
|
|
11
11
|
If your package manager does not auto-install peer dependencies, install the required runtime peers as well:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npm install vue @tiptap/core @tiptap/vue-3 @tiptap/pm @tiptap/starter-kit @tiptap/extension-placeholder @tiptap/extension-code-block @tiptap/extension-code-block-lowlight @tiptap/extension-font-family @tiptap/extension-subscript @tiptap/extension-superscript @tiptap/extension-table @tiptap/extension-table-cell @tiptap/extension-table-header @tiptap/extension-table-row @tiptap/extension-task-item @tiptap/extension-task-list @tiptap/extension-text-style @tiptap/extension-underline lowlight
|
|
14
|
+
npm install vue @tiptap/core @tiptap/vue-3 @tiptap/pm @tiptap/starter-kit @tiptap/extension-placeholder @tiptap/extension-code-block @tiptap/extension-code-block-lowlight @tiptap/extension-collaboration @tiptap/extension-collaboration-caret @tiptap/extension-font-family @tiptap/extension-subscript @tiptap/extension-superscript @tiptap/extension-table @tiptap/extension-table-cell @tiptap/extension-table-header @tiptap/extension-table-row @tiptap/extension-task-item @tiptap/extension-task-list @tiptap/extension-text-style @tiptap/extension-underline @tiptap/y-tiptap lowlight y-prosemirror yjs
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Basic Use
|
|
@@ -36,7 +36,99 @@ The package imports its own styles from the entry, so no extra CSS import is req
|
|
|
36
36
|
|
|
37
37
|
- `modelValue?: JSONContent | null`
|
|
38
38
|
- `editable?: boolean`
|
|
39
|
+
- `mode?: 'edit' | 'preview'`
|
|
40
|
+
- `outlinePlacement?: 'left' | 'right'`
|
|
41
|
+
- `enabledExportItems?: ('pdf' | 'html' | 'image' | 'print')[] | null`
|
|
42
|
+
- `enabledInsertMenuItems?: ('image' | 'video' | 'table' | 'local-file' | 'columns' | 'highlight-block' | 'date' | 'code-block' | 'formula' | 'blockquote' | 'emoji' | 'link' | 'divider' | 'countdown' | 'markdown-import')[] | null`
|
|
43
|
+
- `enabledToolbarActions?: ('blockquote')[] | null`
|
|
39
44
|
- `placeholder?: string`
|
|
45
|
+
- `collaboration?: RichTextEditorCollaborationOptions | null`
|
|
46
|
+
|
|
47
|
+
When these whitelist props are omitted, all built-in options stay enabled. Once you pass a list, only the listed items remain visible and usable.
|
|
48
|
+
|
|
49
|
+
```vue
|
|
50
|
+
<RichTextEditor
|
|
51
|
+
v-model="content"
|
|
52
|
+
:enabled-export-items="['html', 'image']"
|
|
53
|
+
:enabled-insert-menu-items="['image', 'local-file', 'blockquote']"
|
|
54
|
+
:enabled-toolbar-actions="['blockquote']"
|
|
55
|
+
/>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Preview Mode
|
|
59
|
+
|
|
60
|
+
Use `mode="preview"` to switch the component into a read-only preview shell. In preview mode, the toolbar is hidden, editing is disabled, and the outline can be placed on either side.
|
|
61
|
+
|
|
62
|
+
```vue
|
|
63
|
+
<template>
|
|
64
|
+
<RichTextEditor
|
|
65
|
+
v-model="content"
|
|
66
|
+
mode="preview"
|
|
67
|
+
outline-placement="right"
|
|
68
|
+
/>
|
|
69
|
+
</template>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
On narrow screens, preview mode automatically scales the page canvas down so the document stays readable on phones.
|
|
73
|
+
|
|
74
|
+
## Collaboration
|
|
75
|
+
|
|
76
|
+
The same component supports both normal single-user editing and optional Yjs collaboration.
|
|
77
|
+
|
|
78
|
+
```vue
|
|
79
|
+
<script setup lang="ts">
|
|
80
|
+
import { ref } from 'vue'
|
|
81
|
+
import * as Y from 'yjs'
|
|
82
|
+
import { WebsocketProvider } from 'y-websocket'
|
|
83
|
+
import type { JSONContent } from '@tiptap/core'
|
|
84
|
+
import { RichTextEditor } from '@ap666/office-word'
|
|
85
|
+
|
|
86
|
+
const ydoc = new Y.Doc()
|
|
87
|
+
const provider = new WebsocketProvider('ws://localhost:1234', 'office-word-demo', ydoc)
|
|
88
|
+
const content = ref<JSONContent | null>(null)
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<template>
|
|
92
|
+
<RichTextEditor
|
|
93
|
+
v-model="content"
|
|
94
|
+
:collaboration="{
|
|
95
|
+
document: ydoc,
|
|
96
|
+
field: 'content',
|
|
97
|
+
provider,
|
|
98
|
+
user: {
|
|
99
|
+
name: '张三',
|
|
100
|
+
color: '#3b82f6',
|
|
101
|
+
},
|
|
102
|
+
}"
|
|
103
|
+
/>
|
|
104
|
+
</template>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
In collaboration mode, the shared Yjs fragment becomes the source of truth. The component still emits JSON updates, but external `modelValue` changes are not pushed back into the editor. If you want remote cursors, also install `y-websocket` in the host project and pass `provider + user`.
|
|
108
|
+
|
|
109
|
+
Do not use `modelValue` as the initial seed source for a collaborative room. Seed the Yjs document before mounting the editor if the room needs default content.
|
|
110
|
+
|
|
111
|
+
### Included Yjs Server Example
|
|
112
|
+
|
|
113
|
+
The published package also includes a minimal collaboration server under `yjs/`.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
cd node_modules/@ap666/office-word/yjs
|
|
117
|
+
npm install
|
|
118
|
+
npm run start
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Default address is `ws://0.0.0.0:1234`.
|
|
122
|
+
|
|
123
|
+
Use the same websocket address and room name on every client:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import * as Y from 'yjs'
|
|
127
|
+
import { WebsocketProvider } from 'y-websocket'
|
|
128
|
+
|
|
129
|
+
const ydoc = new Y.Doc()
|
|
130
|
+
const provider = new WebsocketProvider('ws://127.0.0.1:1234', 'office-word-demo', ydoc)
|
|
131
|
+
```
|
|
40
132
|
|
|
41
133
|
## Instance API
|
|
42
134
|
|
|
@@ -64,9 +156,29 @@ Available methods:
|
|
|
64
156
|
- `insertImage(payload | payload[]): boolean`
|
|
65
157
|
- `insertVideo(payload): boolean`
|
|
66
158
|
- `insertFile(payload): boolean`
|
|
159
|
+
- `insertLocalFile(payload): boolean`
|
|
160
|
+
- `openLocalFilePicker(): void`
|
|
67
161
|
- `focus(): void`
|
|
68
162
|
- `getJSON(): JSONContent | null`
|
|
69
163
|
|
|
164
|
+
## Local File Block
|
|
165
|
+
|
|
166
|
+
The insert menu now supports `Local File`, and the component instance also exposes local-file insertion APIs.
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
editorRef.value?.insertLocalFile({
|
|
170
|
+
url: 'https://cdn.example.com/files/demo.txt',
|
|
171
|
+
name: 'demo.txt',
|
|
172
|
+
size: 2048,
|
|
173
|
+
mimeType: 'text/plain',
|
|
174
|
+
})
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Listen for local file events from the component:
|
|
178
|
+
|
|
179
|
+
- `@local-file-upload`: emitted after a local file is selected from the editor picker and inserted
|
|
180
|
+
- `@local-file-download`: emitted when the file card download button is clicked
|
|
181
|
+
|
|
70
182
|
## Export Example
|
|
71
183
|
|
|
72
184
|
```ts
|
|
@@ -167,6 +279,9 @@ async function uploadFile(file: File) {
|
|
|
167
279
|
|
|
168
280
|
```ts
|
|
169
281
|
import type {
|
|
282
|
+
RichTextEditorCollaborationProvider,
|
|
283
|
+
RichTextEditorCollaborationUser,
|
|
284
|
+
RichTextEditorCollaborationOptions,
|
|
170
285
|
RichTextEditorFilePayload,
|
|
171
286
|
RichTextEditorImageExportOptions,
|
|
172
287
|
RichTextEditorImagePayload,
|
|
@@ -178,3 +293,4 @@ import type {
|
|
|
178
293
|
## Package Docs
|
|
179
294
|
|
|
180
295
|
- usage guide: `docs/usage.md`
|
|
296
|
+
- bundled Yjs server example: `yjs/README.md`
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { NodeViewProps } from '@tiptap/vue-3';
|
|
2
|
+
declare const _default: import('vue').DefineComponent<NodeViewProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<NodeViewProps> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
3
|
+
export default _default;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { JSONContent } from '@tiptap/core';
|
|
2
|
-
import { RichTextEditorFilePayload, RichTextEditorImageExportOptions, RichTextEditorImagePayload, RichTextEditorProps, RichTextEditorVideoPayload } from '../types';
|
|
2
|
+
import { RichTextEditorFilePayload, RichTextEditorImageExportOptions, RichTextEditorImagePayload, RichTextEditorLocalFilePayload, RichTextEditorProps, RichTextEditorVideoPayload } from '../types';
|
|
3
3
|
declare const _default: import('vue').DefineComponent<RichTextEditorProps, {
|
|
4
4
|
exportPdf: () => Promise<Blob | null>;
|
|
5
5
|
exportImage: (options?: RichTextEditorImageExportOptions) => Promise<Blob | null>;
|
|
@@ -7,18 +7,26 @@ declare const _default: import('vue').DefineComponent<RichTextEditorProps, {
|
|
|
7
7
|
insertImage: (payload: RichTextEditorImagePayload | RichTextEditorImagePayload[]) => boolean;
|
|
8
8
|
insertVideo: (payload: RichTextEditorVideoPayload) => boolean;
|
|
9
9
|
insertFile: (payload: RichTextEditorFilePayload) => boolean;
|
|
10
|
+
insertLocalFile: (payload: RichTextEditorLocalFilePayload) => boolean;
|
|
11
|
+
openLocalFilePicker: () => void;
|
|
10
12
|
focus: () => void;
|
|
11
13
|
getJSON: () => JSONContent | null;
|
|
12
14
|
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
13
15
|
change: (value: JSONContent) => any;
|
|
14
16
|
"update:modelValue": (value: JSONContent) => any;
|
|
17
|
+
"local-file-upload": (value: RichTextEditorLocalFilePayload) => any;
|
|
18
|
+
"local-file-download": (value: RichTextEditorLocalFilePayload) => any;
|
|
15
19
|
}, string, import('vue').PublicProps, Readonly<RichTextEditorProps> & Readonly<{
|
|
16
20
|
onChange?: ((value: JSONContent) => any) | undefined;
|
|
17
21
|
"onUpdate:modelValue"?: ((value: JSONContent) => any) | undefined;
|
|
22
|
+
"onLocal-file-upload"?: ((value: RichTextEditorLocalFilePayload) => any) | undefined;
|
|
23
|
+
"onLocal-file-download"?: ((value: RichTextEditorLocalFilePayload) => any) | undefined;
|
|
18
24
|
}>, {
|
|
19
25
|
placeholder: string;
|
|
26
|
+
mode: "edit" | "preview";
|
|
20
27
|
editable: boolean;
|
|
21
28
|
modelValue: JSONContent | null;
|
|
29
|
+
outlinePlacement: "left" | "right";
|
|
22
30
|
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
23
31
|
rootRef: HTMLDivElement;
|
|
24
32
|
insertMenuRef: HTMLDivElement;
|
|
@@ -47,5 +55,6 @@ declare const _default: import('vue').DefineComponent<RichTextEditorProps, {
|
|
|
47
55
|
countdownBubbleMenuRef: HTMLDivElement;
|
|
48
56
|
countdownBubbleEditButtonRef: HTMLButtonElement;
|
|
49
57
|
markdownImportInputRef: HTMLInputElement;
|
|
58
|
+
localFileInputRef: HTMLInputElement;
|
|
50
59
|
}, HTMLDivElement>;
|
|
51
60
|
export default _default;
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import { JSONContent } from '@tiptap/core';
|
|
2
|
+
import { RichTextEditorCollaborationOptions } from '../types';
|
|
2
3
|
type UseRichTextEditorOptions = {
|
|
3
4
|
content: JSONContent;
|
|
4
5
|
editable: boolean;
|
|
5
6
|
placeholder: string;
|
|
7
|
+
collaboration?: RichTextEditorCollaborationOptions | null;
|
|
8
|
+
onLocalFileDownload?: (payload: {
|
|
9
|
+
url: string;
|
|
10
|
+
name: string;
|
|
11
|
+
size?: number;
|
|
12
|
+
mimeType?: string;
|
|
13
|
+
}) => void;
|
|
6
14
|
onUpdate: (value: JSONContent) => void;
|
|
7
15
|
};
|
|
8
16
|
export declare function useRichTextEditor(options: UseRichTextEditorOptions): import('vue').ShallowRef<import('@tiptap/vue-3').Editor | undefined, import('@tiptap/vue-3').Editor | undefined>;
|
package/dist/index.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ import { default as RichTextEditor } from './components/RichTextEditor.vue';
|
|
|
4
4
|
import { default as ScrollArea } from './components/ScrollArea.vue';
|
|
5
5
|
export { OfficeColorIcon, OfficeIcon, RichTextEditor, ScrollArea };
|
|
6
6
|
export { colorIconNames, monoIconNames } from './icons';
|
|
7
|
-
export type { OfficeColorIconProps, OfficeIconProps, RichTextEditorFilePayload, RichTextEditorImageExportOptions, RichTextEditorImagePayload, RichTextEditorInstance, RichTextEditorProps, RichTextEditorVideoPayload, } from './types';
|
|
7
|
+
export type { OfficeColorIconProps, OfficeIconProps, RichTextEditorCollaborationAwareness, RichTextEditorCollaborationDocument, RichTextEditorCollaborationOptions, RichTextEditorCollaborationProvider, RichTextEditorCollaborationUser, RichTextEditorFilePayload, RichTextEditorExportItemKey, RichTextEditorImageExportOptions, RichTextEditorImagePayload, RichTextEditorInstance, RichTextEditorInsertMenuItemKey, RichTextEditorLocalFilePayload, RichTextEditorProps, RichTextEditorToolbarActionKey, RichTextEditorVideoPayload, } from './types';
|
|
8
8
|
export default RichTextEditor;
|