add support for raw Y.js fragments to the collaboration extension

This commit is contained in:
Hans Pagel
2021-01-11 18:37:30 +01:00
parent 7809aa13f5
commit ecd0a6669a
4 changed files with 48 additions and 27 deletions

View File

@@ -70,7 +70,7 @@ export default {
Text, Text,
Collaboration.configure({ Collaboration.configure({
document: ydoc, document: ydoc,
fragment: 'title', field: 'title',
}), }),
], ],
}) })
@@ -84,7 +84,7 @@ export default {
CustomTaskItem, CustomTaskItem,
Collaboration.configure({ Collaboration.configure({
document: ydoc, document: ydoc,
fragment: 'tasks', field: 'tasks',
}), }),
], ],
}) })
@@ -96,7 +96,7 @@ export default {
Text, Text,
Collaboration.configure({ Collaboration.configure({
document: ydoc, document: ydoc,
fragment: 'description', field: 'description',
}), }),
], ],
}) })
@@ -112,17 +112,23 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
ul[data-type="taskList"] { .ProseMirror {
list-style: none; > * + * {
padding: 0; margin-top: 0.75em;
}
li { ul[data-type="taskList"] {
display: flex; list-style: none;
align-items: center; padding: 0;
> input { li {
flex: 0 0 auto; display: flex;
margin-right: 0.5rem; align-items: center;
> input {
flex: 0 0 auto;
margin-right: 0.5rem;
}
} }
} }
} }
@@ -137,7 +143,7 @@ ul[data-type="taskList"] {
.form__item { .form__item {
margin: 0 0 1rem; margin: 0 0 1rem;
padding: 1rem; padding: 0.75rem 1rem;
border-radius: 5px; border-radius: 5px;
border: 1px solid #e9ecef; border: 1px solid #e9ecef;

View File

@@ -20,10 +20,11 @@ yarn add @tiptap/extension-collaboration yjs y-websocket
``` ```
## Settings ## Settings
| Option | Type | Default | Description | | Option | Type | Default | Description |
| -------- | -------- | --------- | ----------------------------------------------------------------------------------------- | | -------- | -------- | ----------- | --------------------------------------------------------------------------------------- |
| document | `Object` | `null` | An initialized Y.js document. | | document | `Object` | `null` | An initialized Y.js document. |
| fragment | `String` | `default` | Name of the Y.js fragment, can be changed to sync multiple fields with one Y.js document. | | field | `String` | `'default'` | Name of a Y.js fragment, can be changed to sync multiple fields with one Y.js document. |
| fragment | `Object` | `null` | A raw Y.js fragment, can be used instead of `document` and `field`. |
## Commands ## Commands
| Command | Parameters | Description | | Command | Parameters | Description |

View File

@@ -236,13 +236,22 @@ And if youd like to sync multiple fields with one Y.js document, just pass di
// a tiptap instance for the field // a tiptap instance for the field
Collaboration.configure({ Collaboration.configure({
document: ydoc, document: ydoc,
fragment: 'title', field: 'title',
}) })
// and another instance for the summary, both in the same Y.js document // and another instance for the summary, both in the same Y.js document
Collaboration.configure({ Collaboration.configure({
document: ydoc, document: ydoc,
fragment: 'summary', field: 'summary',
})
```
If your setup is somehow more complex, for example with nested fragments, you can pass a raw Y.js fragment too. `document` and `field` will be ignored then.
```js
// a raw Y.js fragment
Collaboration.configure({
fragment: ydoc.getXmlFragment('custom'),
}) })
``` ```

View File

@@ -12,9 +12,13 @@ export interface CollaborationOptions {
*/ */
document: any, document: any,
/** /**
* A string to determine the fragment that should be used. * Name of a Y.js fragment, can be changed to sync multiple fields with one Y.js document.
*/ */
fragment: string, field: string,
/**
* A raw Y.js fragment, can be used instead of `document` and `field`.
*/
fragment: any,
} }
export const Collaboration = Extension.create({ export const Collaboration = Extension.create({
@@ -22,7 +26,8 @@ export const Collaboration = Extension.create({
defaultOptions: <CollaborationOptions>{ defaultOptions: <CollaborationOptions>{
document: null, document: null,
fragment: 'default', field: 'default',
fragment: null,
}, },
addCommands() { addCommands() {
@@ -55,12 +60,12 @@ export const Collaboration = Extension.create({
}, },
addProseMirrorPlugins() { addProseMirrorPlugins() {
const fragment = this.options.fragment
? this.options.fragment
: this.options.document.getXmlFragment(this.options.field)
return [ return [
ySyncPlugin( ySyncPlugin(fragment),
this.options.document.getXmlFragment(
this.options.fragment,
),
),
yUndoPlugin(), yUndoPlugin(),
] ]
}, },