add placeholder experiment

This commit is contained in:
Hans Pagel 2021-02-03 11:06:42 +01:00
parent 5fa89f3ea3
commit 8ff0997f3e
4 changed files with 129 additions and 1 deletions

View File

@ -0,0 +1,67 @@
import { Extension } 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 default Extension.create({
name: 'placeholder',
defaultOptions: <PlaceholderOptions>{
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[] = []
const isEditorEmpty = doc.textContent.length === 0
if (!active) {
return
}
doc.descendants((node, pos) => {
const hasAnchor = anchor >= pos && anchor <= (pos + node.nodeSize)
const isNodeEmpty = node.content.size === 0
if ((hasAnchor || !this.options.showOnlyCurrent) && isNodeEmpty) {
const classes = [this.options.emptyNodeClass]
if (isEditorEmpty) {
classes.push(this.options.emptyEditorClass)
}
const decoration = Decoration.node(pos, pos + node.nodeSize, {
class: classes.join(' '),
'data-empty-text': typeof this.options.placeholder === 'function'
? this.options.placeholder(node)
: this.options.placeholder,
})
decorations.push(decoration)
}
return false
})
return DecorationSet.create(doc, decorations)
},
},
}),
]
},
})

View File

@ -0,0 +1,56 @@
<template>
<editor-content :editor="editor" />
</template>
<script>
import { Editor, EditorContent } from '@tiptap/vue-starter-kit'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import Placeholder from './extension/placeholder'
export default {
components: {
EditorContent,
},
data() {
return {
editor: null,
}
},
mounted() {
this.editor = new Editor({
extensions: [
Document,
Paragraph,
Text,
Placeholder,
],
})
},
beforeDestroy() {
this.editor.destroy()
},
}
</script>
<style lang="scss">
/* Basic editor styles */
.ProseMirror {
> * + * {
margin-top: 0.75em;
}
}
/* Placeholder */
.ProseMirror p.is-editor-empty:first-child::before {
content: attr(data-empty-text);
float: left;
color: #ced4da;
pointer-events: none;
height: 0;
}
</style>

View File

@ -9,4 +9,4 @@ Congratulations! Youve found our secret playground with a list of experiments
* [Commands](/experiments/commands)
## Waiting for approval
* [Placeholder](/experiments/placeholder)

View File

@ -0,0 +1,5 @@
# Placeholder
⚠️ Experiment
<demo name="Experiments/Placeholder" highlight="" />