mirror of
https://github.com/ueberdosis/tiptap.git
synced 2024-11-23 19:19:03 +08:00
feature(core): add onPaste and onDrop events to editor (#4843)
This commit is contained in:
parent
da8fcf373e
commit
9e18d243e0
5
.changeset/lovely-bears-wonder.md
Normal file
5
.changeset/lovely-bears-wonder.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@tiptap/core": minor
|
||||
---
|
||||
|
||||
Added `onPaste` and `onDrop` options to the editor allowing for easier event binding for both cases
|
5
.changeset/nine-pianos-move.md
Normal file
5
.changeset/nine-pianos-move.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@tiptap/vue-3": patch
|
||||
---
|
||||
|
||||
Fixed an issue where plugin registration on editor initialization would break Vue3 editors.
|
@ -24,6 +24,8 @@ import { isActive } from './helpers/isActive.js'
|
||||
import { isNodeEmpty } from './helpers/isNodeEmpty.js'
|
||||
import { resolveFocusPosition } from './helpers/resolveFocusPosition.js'
|
||||
import { NodePos } from './NodePos.js'
|
||||
import { DropPlugin } from './plugins/DropPlugin.js'
|
||||
import { PastePlugin } from './plugins/PastePlugin.js'
|
||||
import { style } from './style.js'
|
||||
import {
|
||||
CanCommands,
|
||||
@ -88,6 +90,8 @@ export class Editor extends EventEmitter<EditorEvents> {
|
||||
onBlur: () => null,
|
||||
onDestroy: () => null,
|
||||
onContentError: ({ error }) => { throw error },
|
||||
onPaste: () => null,
|
||||
onDrop: () => null,
|
||||
}
|
||||
|
||||
constructor(options: Partial<EditorOptions> = {}) {
|
||||
@ -109,6 +113,14 @@ export class Editor extends EventEmitter<EditorEvents> {
|
||||
this.on('blur', this.options.onBlur)
|
||||
this.on('destroy', this.options.onDestroy)
|
||||
|
||||
if (this.options.onPaste) {
|
||||
this.registerPlugin(PastePlugin(this.options.onPaste))
|
||||
}
|
||||
|
||||
if (this.options.onDrop) {
|
||||
this.registerPlugin(DropPlugin(this.options.onDrop))
|
||||
}
|
||||
|
||||
window.setTimeout(() => {
|
||||
if (this.isDestroyed) {
|
||||
return
|
||||
|
@ -11,6 +11,8 @@ export * from './NodePos.js'
|
||||
export * from './NodeView.js'
|
||||
export * from './PasteRule.js'
|
||||
export * from './pasteRules/index.js'
|
||||
export * from './plugins/DropPlugin.js'
|
||||
export * from './plugins/PastePlugin.js'
|
||||
export * from './Tracker.js'
|
||||
export * from './types.js'
|
||||
export * from './utilities/index.js'
|
||||
|
14
packages/core/src/plugins/DropPlugin.ts
Normal file
14
packages/core/src/plugins/DropPlugin.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Plugin, PluginKey } from '@tiptap/pm/state'
|
||||
import { Slice } from 'packages/pm/model'
|
||||
|
||||
export const DropPlugin = (onDrop: (e: DragEvent, slice: Slice, moved: boolean) => void) => {
|
||||
return new Plugin({
|
||||
key: new PluginKey('tiptapDrop'),
|
||||
|
||||
props: {
|
||||
handleDrop: (_, e, slice, moved) => {
|
||||
onDrop(e, slice, moved)
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
14
packages/core/src/plugins/PastePlugin.ts
Normal file
14
packages/core/src/plugins/PastePlugin.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { Slice } from '@tiptap/pm/model'
|
||||
import { Plugin, PluginKey } from '@tiptap/pm/state'
|
||||
|
||||
export const PastePlugin = (onPaste: (e: ClipboardEvent, slice: Slice) => void) => {
|
||||
return new Plugin({
|
||||
key: new PluginKey('tiptapPaste'),
|
||||
|
||||
props: {
|
||||
handlePaste: (_view, e, slice) => {
|
||||
onPaste(e, slice)
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
@ -3,6 +3,7 @@ import {
|
||||
Node as ProseMirrorNode,
|
||||
NodeType,
|
||||
ParseOptions,
|
||||
Slice,
|
||||
} from '@tiptap/pm/model'
|
||||
import { EditorState, Transaction } from '@tiptap/pm/state'
|
||||
import {
|
||||
@ -121,6 +122,8 @@ export interface EditorOptions {
|
||||
onFocus: (props: EditorEvents['focus']) => void;
|
||||
onBlur: (props: EditorEvents['blur']) => void;
|
||||
onDestroy: (props: EditorEvents['destroy']) => void;
|
||||
onPaste: (e: ClipboardEvent, slice: Slice) => void
|
||||
onDrop: (e: DragEvent, slice: Slice, moved: boolean) => void
|
||||
}
|
||||
|
||||
export type HTMLContent = string;
|
||||
|
@ -149,6 +149,8 @@ class EditorInstanceManager {
|
||||
onTransaction: (...args) => this.options.current.onTransaction?.(...args),
|
||||
onUpdate: (...args) => this.options.current.onUpdate?.(...args),
|
||||
onContentError: (...args) => this.options.current.onContentError?.(...args),
|
||||
onDrop: (...args) => this.options.current.onDrop?.(...args),
|
||||
onPaste: (...args) => this.options.current.onPaste?.(...args),
|
||||
}
|
||||
const editor = new Editor(optionsToApply)
|
||||
|
||||
|
@ -75,7 +75,9 @@ export class Editor extends CoreEditor {
|
||||
handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[],
|
||||
): void {
|
||||
super.registerPlugin(plugin, handlePlugins)
|
||||
this.reactiveState.value = this.view.state
|
||||
if (this.reactiveState) {
|
||||
this.reactiveState.value = this.view.state
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,6 +85,8 @@ export class Editor extends CoreEditor {
|
||||
*/
|
||||
public unregisterPlugin(nameOrPluginKey: string | PluginKey): void {
|
||||
super.unregisterPlugin(nameOrPluginKey)
|
||||
this.reactiveState.value = this.view.state
|
||||
if (this.reactiveState) {
|
||||
this.reactiveState.value = this.view.state
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user