docs: update content

This commit is contained in:
Hans Pagel 2021-04-03 16:13:47 +02:00
parent 4792fc3200
commit e5866a08cf
10 changed files with 314 additions and 80 deletions

View File

@ -12,11 +12,7 @@ import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import Bold from '@tiptap/extension-bold'
export default {
data() {
return {
output: '',
json: {
const json = {
type: 'doc',
content: [
{
@ -38,12 +34,12 @@ export default {
],
},
],
},
}
},
mounted() {
this.output = generateHTML(this.json, [
export default {
computed: {
output() {
return generateHTML(json, [
Document,
Paragraph,
Text,
@ -51,5 +47,6 @@ export default {
// other extensions
])
},
},
}
</script>

View File

@ -0,0 +1,77 @@
import { Node, mergeAttributes } from '@tiptap/core'
export default Node.create({
name: 'nodeView',
group: 'block',
atom: true,
addAttributes() {
return {
count: {
default: 0,
},
}
},
parseHTML() {
return [
{
tag: 'node-view',
},
]
},
renderHTML({ HTMLAttributes }) {
return ['node-view', mergeAttributes(HTMLAttributes)]
},
addNodeView() {
return ({ editor, node, getPos }) => {
const { view } = editor
// Markup
/*
<div class="node-view">
<span class="label">Node view</span>
<div class="content">
<button>
This button has been clicked ${node.attrs.count} times.
</button>
</div>
</div>
*/
const dom = document.createElement('div')
dom.classList.add('node-view')
const label = document.createElement('span')
label.classList.add('label')
label.innerHTML = 'Node view'
const content = document.createElement('div')
content.classList.add('content')
const button = document.createElement('button')
button.innerHTML = `This button has been clicked ${node.attrs.count} times.`
button.addEventListener('click', () => {
if (typeof getPos === 'function') {
view.dispatch(view.state.tr.setNodeMarkup(getPos(), undefined, {
count: node.attrs.count + 1,
}))
editor.commands.focus()
}
})
content.append(button)
dom.append(label, content)
return {
dom,
}
}
},
})

View File

@ -5,7 +5,7 @@
<script>
import { Editor, EditorContent } from '@tiptap/vue-2'
import { defaultExtensions } from '@tiptap/starter-kit'
import VueComponent from './index.js'
import NodeView from './Extension.js'
export default {
components: {
@ -22,13 +22,13 @@ export default {
this.editor = new Editor({
extensions: [
...defaultExtensions(),
VueComponent,
NodeView,
],
content: `
<p>
This is still the text editor youre used to, but enriched with node views.
</p>
<node-view count="0"></node-view>
<node-view></node-view>
<p>
Did you see that? Thats a JavaScript node view. We are really living in the future.
</p>
@ -52,7 +52,8 @@ export default {
::v-deep {
.node-view {
border: 1px solid #adb5bd;
background: #FAF594;
border: 3px solid #0D0D0D;
border-radius: 0.5rem;
margin: 1rem 0;
position: relative;
@ -60,7 +61,7 @@ export default {
.label {
margin-left: 1rem;
background-color: #adb5bd;
background-color: #0D0D0D;
font-size: 0.6rem;
letter-spacing: 1px;
font-weight: bold;
@ -73,7 +74,8 @@ export default {
}
.content {
margin: 2.5rem 1rem 1rem;
margin-top: 1.5rem;
padding: 1rem;
}
}
</style>

View File

@ -5,15 +5,7 @@ export default Node.create({
group: 'block',
atom: true,
addAttributes() {
return {
count: {
default: 0,
},
}
},
content: 'inline*',
parseHTML() {
return [
@ -29,32 +21,32 @@ export default Node.create({
addNodeView() {
return () => {
// Markup
/*
<div class="node-view">
<span class="label">Node view</span>
<div class="content"></div>
</div>
*/
const dom = document.createElement('div')
dom.classList.add('node-view')
const label = document.createElement('span')
label.classList.add('label')
label.innerHTML = 'Node View'
label.innerHTML = 'Node view'
label.contentEditable = false
const content = document.createElement('div')
content.classList.add('content')
content.innerHTML = 'Im rendered with JavaScript.'
dom.append(label, content)
return {
dom,
contentDOM: content,
}
}
},
})
// <node-view-wrapper class="vue-component">
// <span class="label">Vue Component</span>
// <div class="content">
// <button @click="increase">
// This button has been clicked {{ node.attrs.count }} times.
// </button>
// </div>
// </node-view-wrapper>

View File

@ -0,0 +1,85 @@
<template>
<editor-content :editor="editor" />
</template>
<script>
import { Editor, EditorContent } from '@tiptap/vue-2'
import { defaultExtensions } from '@tiptap/starter-kit'
import NodeView from './Extension.js'
export default {
components: {
EditorContent,
},
data() {
return {
editor: null,
}
},
mounted() {
this.editor = new Editor({
extensions: [
...defaultExtensions(),
NodeView,
],
content: `
<p>
This is still the text editor youre used to, but enriched with node views.
</p>
<node-view>
<p>This is editable.</p>
</node-view>
<p>
Did you see that? Thats a JavaScript node view. We are really living in the future.
</p>
`,
})
},
beforeDestroy() {
this.editor.destroy()
},
}
</script>
<style lang="scss" scoped>
/* Basic editor styles */
.ProseMirror {
> * + * {
margin-top: 0.75em;
}
}
::v-deep {
.node-view {
background: #FAF594;
border: 3px solid #0D0D0D;
border-radius: 0.5rem;
margin: 1rem 0;
position: relative;
}
.label {
margin-left: 1rem;
background-color: #0D0D0D;
font-size: 0.6rem;
letter-spacing: 1px;
font-weight: bold;
text-transform: uppercase;
color: #fff;
position: absolute;
top: 0;
padding: 0.25rem 0.75rem;
border-radius: 0 0 0.5rem 0.5rem;
}
.content {
margin: 2.5rem 1rem 1rem;
padding: 0.5rem;
border: 2px dashed #0D0D0D20;
border-radius: 0.5rem;
}
}
</style>

View File

@ -8,4 +8,4 @@ The utility helps rendering JSON content as HTML without an editor instance, for
[packages/html/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/html/)
## Usage
<demo name="Guide/Content/GenerateHTML" highlight="6,43-48"/>
<demo name="Guide/Content/GenerateHTML" highlight="6-7,42-48"/>

View File

@ -117,7 +117,7 @@ If you need to render the content on the server side, for example to generate th
Thats what the `generateHTML()` is for. Its a helper function which renders HTML without an actual editor instance.
<demo name="Guide/Content/GenerateHTML" highlight="6-7,46-52"/>
<demo name="Guide/Content/GenerateHTML" highlight="6-7,42-48"/>
## Migration
If youre migrating existing content to tiptap we would recommend to get your existing output to HTML. Thats probably the best format to get your initial content into tiptap, because ProseMirror ensures there is nothing wrong with it. Even if there are some tags or attributes that arent allowed (based on your configuration), tiptap just throws them away quietly.

View File

@ -3,15 +3,25 @@
## toc
## Introduction
TODO
Using frameworks like Vue or React can feel too complex, if youre used to work without those two. Good news: You can use plain JavaScript in your node views. There is just a little bit you need to know, but lets go through this one by one.
## Render a node view with JavaScript
Here is what you need to do to render a node view inside your editor:
1. [Create a node extension](/guide/build-extensions)
2. Register a new node view with `addNodeView()`
3. Write your render function
4. [Configure tiptap to use your new node extension](/guide/configuration)
This is how your node extension could look like:
## Code snippet
```js
import { Node } from '@tiptap/core'
import { VueNodeViewRenderer } from '@tiptap/vue-2'
import Component from './Component.vue'
export default Node.create({
// configuration …
addNodeView() {
return ({ editor, node, getPos, HTMLAttributes, decorations, extension }) => {
const dom = document.createElement('div')
@ -26,17 +36,88 @@ export default Node.create({
})
```
## Render markup
Got it? Lets see it in action. Feel free to copy the below example to get started.
<demo name="Guide/NodeViews/JavaScript" />
That node view even interacts with the editor. Time to see how that is wired up.
## Access node attributes
TODO
The editor passes a few helpful things to your render function. One of them is the the `node` prop. This one enables you to access node attributes in your node view. Lets say you have [added an attribute](/guide/extend-extensions#attributes) named `count` to your node extension. You could access the attribute like this:
```js
addNodeView() {
return ({ node }) => {
console.log(node.attrs.count)
// …
}
}
```
## Update node attributes
TODO
You can even update node attributes from your node view, with the help of the `getPos` prop passed to your render function. Dispatch a new transaction with an object of the updated attributes:
```js
addNodeView() {
return ({ editor, node, getPos }) => {
const { view } = editor
// Create a button …
const button = document.createElement('button')
button.innerHTML = `This button has been clicked ${node.attrs.count} times.`
// … and when its clicked …
button.addEventListener('click', () => {
if (typeof getPos === 'function') {
// … dispatch a transaction, for the current position in the document …
view.dispatch(view.state.tr.setNodeMarkup(getPos(), undefined, {
count: node.attrs.count + 1,
}))
// … and set the focus back to the editor.
editor.commands.focus()
}
})
// …
}
}
```
Does seem a little bit too complex? Consider using [React](/guide/node-views/react) or [Vue](/guide/node-views/vue), if you have one of those in your project anyway. It gets a little bit easier with those two.
## Adding a content editable
TODO
To add editable content to your node view, you need to pass a `contentDOM`, a container element for the content. Here is a simplified version of a node view with non-editable and editable text content:
```js
// Create a container for the node view
const dom = document.createElement('div')
// Give other elements containing text `contentEditable = false`
const label = document.createElement('span')
label.innerHTML = 'Node view'
label.contentEditable = false
// Create a container for the content
const content = document.createElement('div')
// Append all elements to the node view container
dom.append(label, content)
return {
// Pass the node view container …
dom,
// … and the content container:
contentDOM: content,
}
```
Got it? Youre free to do anything you like, as long as you return a container for the node view and another one for the content. Here is the above example in action:
<demo name="Guide/NodeViews/JavaScriptContent" />
Keep in mind that this content is rendered by tiptap. That means you need to tell what kind of content is allowed, for example with `content: 'inline*'` in your node extension (thats what we use in the above example).
## All available props
TODO

View File

@ -3,10 +3,10 @@
## toc
## Introduction
Using Vanilla JavaScript can feel complex if you are used to work in Vue. Good news: You can use regular Vue components in your node views, too. There is just a little bit you need to know, but lets go through this one by one.
Using plain JavaScript can feel complex if you are used to work in Vue. Good news: You can use regular Vue components in your node views, too. There is just a little bit you need to know, but lets go through this one by one.
## Render a Vue component
Here is what you need to do to render Vue components inside your text editor:
Here is what you need to do to render Vue components inside your editor:
1. [Create a node extension](/guide/build-extensions)
2. Create a Vue component
@ -44,7 +44,7 @@ Got it? Lets see it in action. Feel free to copy the below example to get sta
<demo name="Guide/NodeViews/VueComponent" />
That component doesnt interactive with the editor, though. Time to connect it to the editor output.
That component doesnt interact with the editor, though. Time to wire it up.
## Access node attributes
The `VueNodeViewRenderer` which you use in your node extension, passes a few very helpful props to your custom view component. One of them is the `node` prop. Add this snippet to your Vue component to directly access the node:
@ -58,7 +58,7 @@ props: {
},
```
That makes it super easy to access node attributes in your Vue component. Lets say you have [added an attribute](/guide/extend-extensions#attributes) named `count` to your node extension (like we did in the above example) you could access it like this:
That enables you to access node attributes in your Vue component. Lets say you have [added an attribute](/guide/extend-extensions#attributes) named `count` to your node extension (like we did in the above example) you could access it like this:
```js
this.node.attrs.count

View File

@ -104,7 +104,7 @@
items:
- title: With JavaScript
link: /guide/node-views/js
type: draft
type: new
- title: With React
link: /guide/node-views/react
type: draft