add placeholder extension

This commit is contained in:
Philipp Kühn
2021-03-24 22:50:30 +01:00
parent 58939fe02b
commit 49611e16e5
8 changed files with 86 additions and 8 deletions

View File

@@ -0,0 +1,14 @@
# @tiptap/extension-placeholder
[![Version](https://img.shields.io/npm/v/@tiptap/extension-placeholder.svg?label=version)](https://www.npmjs.com/package/@tiptap/extension-placeholder)
[![Downloads](https://img.shields.io/npm/dm/@tiptap/extension-placeholder.svg)](https://npmcharts.com/compare/tiptap?minimal=true)
[![License](https://img.shields.io/npm/l/@tiptap/extension-placeholder.svg)](https://www.npmjs.com/package/@tiptap/extension-placeholder)
[![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub)](https://github.com/sponsors/ueberdosis)
## Introduction
tiptap is a headless wrapper around [ProseMirror](https://ProseMirror.net) a toolkit for building rich text WYSIWYG editors, which is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*.
## Offical Documentation
Documentation can be found on the [tiptap website](https://tiptap.dev).
## License
tiptap is open-sourced software licensed under the [MIT license](https://github.com/ueberdosis/tiptap-next/blob/main/LICENSE.md).

View File

@@ -0,0 +1,31 @@
{
"name": "@tiptap/extension-placeholder",
"description": "placeholder extension for tiptap",
"version": "2.0.0-beta.0",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
"tiptap extension"
],
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"main": "dist/tiptap-extension-placeholder.cjs.js",
"umd": "dist/tiptap-extension-placeholder.umd.js",
"module": "dist/tiptap-extension-placeholder.esm.js",
"unpkg": "dist/tiptap-extension-placeholder.bundle.umd.min.js",
"types": "dist/packages/extension-placeholder/src/index.d.ts",
"files": [
"src",
"dist"
],
"peerDependencies": {
"@tiptap/core": "^2.0.0-beta.1"
},
"dependencies": {
"prosemirror-state": "^1.3.4",
"prosemirror-view": "^1.18.1"
}
}

View File

@@ -0,0 +1,5 @@
import { Placeholder } from './placeholder'
export * from './placeholder'
export default Placeholder

View File

@@ -0,0 +1,67 @@
import { Extension, isNodeEmpty } from '@tiptap/core'
import { Decoration, DecorationSet } from 'prosemirror-view'
import { Plugin } from 'prosemirror-state'
export interface PlaceholderOptions {
emptyEditorClass: string,
emptyNodeClass: string,
placeholder: string | Function,
showOnlyWhenEditable: boolean,
showOnlyCurrent: boolean,
}
export const Placeholder = Extension.create<PlaceholderOptions>({
name: 'placeholder',
defaultOptions: {
emptyEditorClass: 'is-editor-empty',
emptyNodeClass: 'is-empty',
placeholder: 'Write something …',
showOnlyWhenEditable: true,
showOnlyCurrent: true,
},
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
}
doc.descendants((node, pos) => {
const hasAnchor = anchor >= pos && anchor <= (pos + node.nodeSize)
const isEmpty = !node.isLeaf && isNodeEmpty(node)
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(node)
: this.options.placeholder,
})
decorations.push(decoration)
}
return false
})
return DecorationSet.create(doc, decorations)
},
},
}),
]
},
})