docs: update content

This commit is contained in:
Hans Pagel
2021-04-03 16:49:53 +02:00
parent e5866a08cf
commit 3c963c302b
4 changed files with 112 additions and 4 deletions

View File

@@ -3,13 +3,23 @@
## toc ## toc
## Introduction ## Introduction
TODO Node views enable you to fully customize your nodes. We are collecting a few different examples here. Feel free to copy them and start building on them.
Keep in mind that those are just examples to get you started, not officially supported extensions. We dont have tests for them, and dont plan to maintain them with the same attention as we do with official extensions.
## Drag handles ## Drag handles
Drag handles arent that easy to add. We are still on the lookout whats the best way to add them. Official support will come at some point, but theres no timeline yet.
<demo name="Guide/NodeViews/DragHandle" /> <demo name="Guide/NodeViews/DragHandle" />
## Table of contents ## Table of contents
This one loops through the editor content, gives all headings an ID and renders a Table of Contents with Vue.
<demo name="Guide/NodeViews/TableOfContents" /> <demo name="Guide/NodeViews/TableOfContents" />
## Drawing in the editor ## Drawing in the editor
The drawing example shows a SVG that enables you to draw inside the editor.
<demo name="Examples/Drawing" /> <demo name="Examples/Drawing" />
Its not working very well with the Collaboration extension. Its sending all data on every change, which can get pretty huge with Y.js. If you plan to use those two in combination, you need to improve it or your WebSocket backend will melt.

View File

@@ -3,8 +3,106 @@
## toc ## toc
## Introduction ## Introduction
TODO Using plain JavaScript can feel complex if you are used to work in React. Good news: You can use regular React 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 React component
Here is what you need to do to render React components inside your editor:
1. [Create a node extension](/guide/build-extensions)
2. Create a React component
3. Pass that component to the provided `ReactNodeViewRenderer`
4. Register it with `addNodeView()`
5. [Configure tiptap to use your new node extension](/guide/configuration)
This is how your node extension could look like:
```js
import { Node } from '@tiptap/core'
import { ReactNodeViewRenderer } from '@tiptap/react'
import Component from './Component.jsx'
export default Node.create({
// configuration …
addNodeView() {
return ReactNodeViewRenderer(Component)
},
})
```
There is a little bit of magic required to make this work. But dont worry, we provide a wrapper component you can use to get started easily. Dont forget to add it to your custom React component, like shown below:
```html
<NodeViewWrapper className="react-component">
React Component
</NodeViewWrapper>
```
Got it? Lets see it in action. Feel free to copy the below example to get started.
<demo name="Guide/NodeViews/ReactComponent" /> <demo name="Guide/NodeViews/ReactComponent" />
That component doesnt interact with the editor, though. Time to wire it up.
## Access node attributes
The `ReactNodeViewRenderer` which you use in your node extension, passes a few very helpful props to your custom React component. One of them is the `node` prop. 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
props.node.attrs.count
```
## Update node attributes
You can even update node attributes from your node, with the help of the `updateAttributes` prop passed to your component. Pass an object with updated attributes to the `updateAttributes` prop:
```js
export default props => {
const increase = () => {
props.updateAttributes({
count: props.node.attrs.count + 1,
})
}
// …
}
```
And yes, all of that is reactive, too. A pretty seemless communication, isnt it?
## Adding a content editable
There is another component called `NodeViewContent` which helps you adding editable content to your node view. Here is an example:
```js
import React from 'react'
import { NodeViewWrapper, NodeViewContent } from '@tiptap/react'
export default () => {
return (
<NodeViewWrapper className="react-component-with-content">
<span className="label" contenteditable="false">React Component</span>
<NodeViewContent className="content" />
</NodeViewWrapper>
)
}
```
You dont need to add those `className` attributes, feel free to remove them or pass other class names. Try it out in the following example:
<demo name="Guide/NodeViews/ReactComponentContent" /> <demo name="Guide/NodeViews/ReactComponentContent" />
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).
The `NodeViewWrapper` and `NodeViewContent` components render a `<div>` HTML tag (`<span>` for inline nodes), but you can change that. For example `<NodeViewContent as="p">` should render a paragraph. One limitation though: That tag must not change during runtime.
## All available props
Here is the full list of what props you can expect:
| Prop | Description |
| ------------------ | -------------------------------------------------------- |
| `editor` | The editor instance |
| `node` | The current node |
| `decorations` | An array of decorations |
| `selected` | `true` when the cursor is inside the node view |
| `extension` | Access to the node extension, for example to get options |
| `getPos` | Get the document position of the current node |
| `updateAttributes` | Update attributes of the current node |

View File

@@ -47,7 +47,7 @@ Got it? Lets see it in action. Feel free to copy the below example to get sta
That component doesnt interact with the editor, though. Time to wire it up. That component doesnt interact with the editor, though. Time to wire it up.
## Access node attributes ## 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: The `VueNodeViewRenderer` which you use in your node extension, passes a few very helpful props to your custom Vue component. One of them is the `node` prop. Add this snippet to your Vue component to directly access the node:
```js ```js
props: { props: {

View File

@@ -107,7 +107,7 @@
type: new type: new
- title: With React - title: With React
link: /guide/node-views/react link: /guide/node-views/react
type: draft type: new
- title: With Vue - title: With Vue
link: /guide/node-views/vue link: /guide/node-views/vue
- title: A few examples - title: A few examples