add a trailing node example
This commit is contained in:
65
docs/src/demos/Experiments/TrailingNode/index.vue
Normal file
65
docs/src/demos/Experiments/TrailingNode/index.vue
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="editor">
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-2'
|
||||||
|
import { defaultExtensions } from '@tiptap/starter-kit'
|
||||||
|
import { TrailingNode } from './trailing-node'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
extensions: [
|
||||||
|
...defaultExtensions(),
|
||||||
|
TrailingNode,
|
||||||
|
],
|
||||||
|
content: `
|
||||||
|
<p>Example text</p>
|
||||||
|
<pre><code>console.log('foo')</code></pre>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
::v-deep {
|
||||||
|
.ProseMirror {
|
||||||
|
> * + * {
|
||||||
|
margin-top: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
background: #0D0D0D;
|
||||||
|
color: #FFF;
|
||||||
|
font-family: 'JetBrainsMono', monospace;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
|
||||||
|
code {
|
||||||
|
color: inherit;
|
||||||
|
padding: 0;
|
||||||
|
background: none;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
68
docs/src/demos/Experiments/TrailingNode/trailing-node.ts
Normal file
68
docs/src/demos/Experiments/TrailingNode/trailing-node.ts
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import { Extension } from '@tiptap/core'
|
||||||
|
import { PluginKey, Plugin } from 'prosemirror-state'
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
function nodeEqualsType({ types, node }) {
|
||||||
|
return (Array.isArray(types) && types.includes(node.type)) || node.type === types
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension based on:
|
||||||
|
* - https://github.com/ueberdosis/tiptap/blob/v1/packages/tiptap-extensions/src/extensions/TrailingNode.js
|
||||||
|
* - https://github.com/remirror/remirror/blob/e0f1bec4a1e8073ce8f5500d62193e52321155b9/packages/prosemirror-trailing-node/src/trailing-node-plugin.ts
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface TrailingNodeOptions {
|
||||||
|
node: string,
|
||||||
|
notAfter: string[],
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TrailingNode = Extension.create<TrailingNodeOptions>({
|
||||||
|
name: 'trailingNode',
|
||||||
|
|
||||||
|
defaultOptions: {
|
||||||
|
node: 'paragraph',
|
||||||
|
notAfter: [
|
||||||
|
'paragraph',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
addProseMirrorPlugins() {
|
||||||
|
const plugin = new PluginKey(this.name)
|
||||||
|
const disabledNodes = Object.entries(this.editor.schema.nodes)
|
||||||
|
.map(([, value]) => value)
|
||||||
|
.filter(node => this.options.notAfter.includes(node.name))
|
||||||
|
|
||||||
|
return [
|
||||||
|
new Plugin({
|
||||||
|
key: plugin,
|
||||||
|
appendTransaction: (_, __, state) => {
|
||||||
|
const { doc, tr, schema } = state
|
||||||
|
const shouldInsertNodeAtEnd = plugin.getState(state)
|
||||||
|
const endPosition = doc.content.size
|
||||||
|
const type = schema.nodes[this.options.node]
|
||||||
|
|
||||||
|
if (!shouldInsertNodeAtEnd) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return tr.insert(endPosition, type.create())
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
init: (_, state) => {
|
||||||
|
const lastNode = state.tr.doc.lastChild
|
||||||
|
return !nodeEqualsType({ node: lastNode, types: disabledNodes })
|
||||||
|
},
|
||||||
|
apply: (tr, value) => {
|
||||||
|
if (!tr.docChanged) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastNode = tr.doc.lastChild
|
||||||
|
return !nodeEqualsType({ node: lastNode, types: disabledNodes })
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -10,3 +10,4 @@ Congratulations! You’ve found our playground with a list of experiments. Be aw
|
|||||||
* [@tiptap/extension-toggle-list?](/experiments/details)
|
* [@tiptap/extension-toggle-list?](/experiments/details)
|
||||||
* [@tiptap/extension-collaboration-annotation](/experiments/collaboration-annotation)
|
* [@tiptap/extension-collaboration-annotation](/experiments/collaboration-annotation)
|
||||||
* [@tiptap/extension-word-break](/experiments/word-break)
|
* [@tiptap/extension-word-break](/experiments/word-break)
|
||||||
|
* [@tiptap/extension-trailing-node](/experiments/trailing-node)
|
||||||
|
|||||||
5
docs/src/docPages/experiments/trailing-node.md
Normal file
5
docs/src/docPages/experiments/trailing-node.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Trailing node
|
||||||
|
|
||||||
|
⚠️ Experiment
|
||||||
|
|
||||||
|
<demo name="Experiments/TrailingNode" />
|
||||||
Reference in New Issue
Block a user