add placeholder extension
This commit is contained in:
14
packages/extension-placeholder/README.md
Normal file
14
packages/extension-placeholder/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# @tiptap/extension-placeholder
|
||||
[](https://www.npmjs.com/package/@tiptap/extension-placeholder)
|
||||
[](https://npmcharts.com/compare/tiptap?minimal=true)
|
||||
[](https://www.npmjs.com/package/@tiptap/extension-placeholder)
|
||||
[](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).
|
||||
31
packages/extension-placeholder/package.json
Normal file
31
packages/extension-placeholder/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
5
packages/extension-placeholder/src/index.ts
Normal file
5
packages/extension-placeholder/src/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { Placeholder } from './placeholder'
|
||||
|
||||
export * from './placeholder'
|
||||
|
||||
export default Placeholder
|
||||
67
packages/extension-placeholder/src/placeholder.ts
Normal file
67
packages/extension-placeholder/src/placeholder.ts
Normal 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)
|
||||
},
|
||||
},
|
||||
}),
|
||||
]
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user