Merge branch 'main' of https://github.com/ueberdosis/tiptap-next into feature/remove-inferred-commands
# Conflicts: # docs/src/demos/Experiments/Annotation/extension/annotation.ts # docs/src/demos/Experiments/Color/extension/Color.ts # docs/src/demos/Experiments/Details/details.ts
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
import * as Y from 'yjs'
|
||||
import { Extension, Command } from '@tiptap/core'
|
||||
import { AnnotationPlugin, AnnotationPluginKey } from './AnnotationPlugin'
|
||||
|
||||
export interface AddAnnotationAction {
|
||||
type: 'addAnnotation',
|
||||
data: any,
|
||||
from: number,
|
||||
to: number,
|
||||
}
|
||||
|
||||
export interface UpdateAnnotationAction {
|
||||
type: 'updateAnnotation',
|
||||
id: string,
|
||||
data: any,
|
||||
}
|
||||
|
||||
export interface DeleteAnnotationAction {
|
||||
type: 'deleteAnnotation',
|
||||
id: string,
|
||||
}
|
||||
|
||||
export interface AnnotationOptions {
|
||||
HTMLAttributes: {
|
||||
[key: string]: any
|
||||
},
|
||||
/**
|
||||
* An event listener which receives annotations for the current selection.
|
||||
*/
|
||||
onUpdate: (items: [any?]) => {},
|
||||
/**
|
||||
* An initialized Y.js document.
|
||||
*/
|
||||
document: Y.Doc | null,
|
||||
/**
|
||||
* Name of a Y.js map, can be changed to sync multiple fields with one Y.js document.
|
||||
*/
|
||||
field: string,
|
||||
/**
|
||||
* A raw Y.js map, can be used instead of `document` and `field`.
|
||||
*/
|
||||
map: Y.Map<any> | null,
|
||||
instance: string,
|
||||
}
|
||||
|
||||
function getMapFromOptions(options: AnnotationOptions): Y.Map<any> {
|
||||
return options.map
|
||||
? options.map
|
||||
: options.document?.getMap(options.field) as Y.Map<any>
|
||||
}
|
||||
|
||||
declare module '@tiptap/core' {
|
||||
interface AllCommands {
|
||||
annotation: {
|
||||
addAnnotation: (data: any) => Command,
|
||||
updateAnnotation: (id: string, data: any) => Command,
|
||||
deleteAnnotation: (id: string) => Command,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const CollaborationAnnotation = Extension.create({
|
||||
name: 'annotation',
|
||||
|
||||
defaultOptions: <AnnotationOptions>{
|
||||
HTMLAttributes: {
|
||||
class: 'annotation',
|
||||
},
|
||||
onUpdate: decorations => decorations,
|
||||
document: null,
|
||||
field: 'annotations',
|
||||
map: null,
|
||||
instance: '',
|
||||
},
|
||||
|
||||
onCreate() {
|
||||
const map = getMapFromOptions(this.options)
|
||||
|
||||
map.observe(() => {
|
||||
console.log(`[${this.options.instance}] map updated → createDecorations`)
|
||||
|
||||
const transaction = this.editor.state.tr.setMeta(AnnotationPluginKey, {
|
||||
type: 'createDecorations',
|
||||
})
|
||||
|
||||
this.editor.view.dispatch(transaction)
|
||||
})
|
||||
},
|
||||
|
||||
addCommands() {
|
||||
return {
|
||||
addAnnotation: (data: any) => ({ dispatch, state }) => {
|
||||
const { selection } = state
|
||||
|
||||
if (selection.empty) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (dispatch && data) {
|
||||
state.tr.setMeta(AnnotationPluginKey, <AddAnnotationAction>{
|
||||
type: 'addAnnotation',
|
||||
from: selection.from,
|
||||
to: selection.to,
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
updateAnnotation: (id: string, data: any) => ({ dispatch, state }) => {
|
||||
if (dispatch) {
|
||||
state.tr.setMeta(AnnotationPluginKey, <UpdateAnnotationAction>{
|
||||
type: 'updateAnnotation',
|
||||
id,
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
deleteAnnotation: id => ({ dispatch, state }) => {
|
||||
if (dispatch) {
|
||||
state.tr.setMeta(AnnotationPluginKey, <DeleteAnnotationAction>{
|
||||
type: 'deleteAnnotation',
|
||||
id,
|
||||
})
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
addProseMirrorPlugins() {
|
||||
return [
|
||||
AnnotationPlugin({
|
||||
HTMLAttributes: this.options.HTMLAttributes,
|
||||
onUpdate: this.options.onUpdate,
|
||||
map: getMapFromOptions(this.options),
|
||||
instance: this.options.instance,
|
||||
}),
|
||||
]
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user