Files
tiptap/packages/extension-placeholder/src/placeholder.ts
Dominik 1ebc8f8e14 chore: migrate to new versions of prosemirror packages (#2854)
* refactor: upgrade prosemirror packages to new typescript versions

* refactor: migrate to new typings from prosemirror

* style: fix linting issues

* style: fix linting issues

* style: fix linting issues

* fix(ci): fix build process by reimplement filterTransaction

* fix(extension-test): fix broken build because of wrong output file names

* fix: fix prosemirror-tables not being bundled correctly for ES6

* fix: move to prosemirror-tables-contently until es6 build is working

* fix: fix tests for youtube

* fix: fix youtube test

* fix(demos): fix demos build
2022-06-20 11:45:37 +02:00

83 lines
2.4 KiB
TypeScript

import { Editor, Extension } from '@tiptap/core'
import { Node as ProsemirrorNode } from 'prosemirror-model'
import { Plugin } from 'prosemirror-state'
import { Decoration, DecorationSet } from 'prosemirror-view'
export interface PlaceholderOptions {
emptyEditorClass: string,
emptyNodeClass: string,
placeholder: ((PlaceholderProps: {
editor: Editor,
node: ProsemirrorNode,
pos: number,
hasAnchor: boolean,
}) => string) | string,
showOnlyWhenEditable: boolean,
showOnlyCurrent: boolean,
includeChildren: boolean,
}
export const Placeholder = Extension.create<PlaceholderOptions>({
name: 'placeholder',
addOptions() {
return {
emptyEditorClass: 'is-editor-empty',
emptyNodeClass: 'is-empty',
placeholder: 'Write something …',
showOnlyWhenEditable: true,
showOnlyCurrent: true,
includeChildren: false,
}
},
addProseMirrorPlugins() {
return [
new Plugin({
props: {
decorations: ({ doc, selection }) => {
const active = this.editor.isEditable || !this.options.showOnlyWhenEditable
const { anchor } = selection
const decorations: Decoration[] = []
if (!active) {
return null
}
doc.descendants((node, pos) => {
const hasAnchor = anchor >= pos && anchor <= (pos + node.nodeSize)
const isEmpty = !node.isLeaf && !node.childCount
if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {
const classes = [this.options.emptyNodeClass]
if (this.editor.isEmpty) {
classes.push(this.options.emptyEditorClass)
}
const decoration = Decoration.node(pos, pos + node.nodeSize, {
class: classes.join(' '),
'data-placeholder': typeof this.options.placeholder === 'function'
? this.options.placeholder({
editor: this.editor,
node,
pos,
hasAnchor,
})
: this.options.placeholder,
})
decorations.push(decoration)
}
return this.options.includeChildren
})
return DecorationSet.create(doc, decorations)
},
},
}),
]
},
})