docs: update content

This commit is contained in:
Hans Pagel 2021-03-17 22:35:41 +01:00
parent 5323eb7e82
commit 8db7963c5e
12 changed files with 402 additions and 227 deletions

View File

@ -10,6 +10,7 @@ A headless and extendable rich text editor, based on [ProseMirror](https://githu
## Feedback
We are looking for your feedback to improve tiptap 2 before the first public release! Share everything that helps to make it better for everyone!
* Join the Discord server! [Link](https://discord.gg/WtJ49jGshW)
* Create issues on GitHub! [Link](https://github.com/ueberdosis/tiptap-next/issues)
* Send an email! [humans@tiptap.dev](mailto:humans@tiptap.dev)
* Follow us on Twitter! [@tiptap_editor](https://twitter.com/tiptap_editor) [@hanspagel](https://twitter.com/hanspagel) [@_philippkuehn](https://twitter.com/_philippkuehn)

View File

@ -0,0 +1,59 @@
<template>
<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>
</template>
<script>
import { NodeViewWrapper, nodeViewProps } from '@tiptap/vue-2'
export default {
components: {
NodeViewWrapper,
},
props: nodeViewProps,
methods: {
increase() {
this.updateAttributes({
count: this.node.attrs.count + 1,
})
},
},
}
</script>
<style lang="scss">
.vue-component {
border: 1px solid #adb5bd;
border-radius: 0.5rem;
margin: 1rem 0;
position: relative;
}
.label {
margin-left: 1rem;
background-color: #adb5bd;
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-top: 1.5rem;
padding: 1rem;
}
</style>

View File

@ -0,0 +1,35 @@
import { Node, mergeAttributes } from '@tiptap/core'
import { VueNodeViewRenderer } from '@tiptap/vue-2'
import Component from './Component.vue'
export default Node.create({
name: 'vueComponent',
group: 'block',
atom: true,
addAttributes() {
return {
count: {
default: 0,
},
}
},
parseHTML() {
return [
{
tag: 'vue-component',
},
]
},
renderHTML({ HTMLAttributes }) {
return ['vue-component', mergeAttributes(HTMLAttributes)]
},
addNodeView() {
return VueNodeViewRenderer(Component)
},
})

View File

@ -0,0 +1,7 @@
context('/demos/Examples/InteractiveNodeViews', () => {
before(() => {
cy.visit('/demos/Examples/InteractiveNodeViews')
})
// TODO: Write tests
})

View File

@ -0,0 +1,63 @@
<template>
<editor-content :editor="editor" />
</template>
<script>
import { Editor, EditorContent } from '@tiptap/vue-2'
import { defaultExtensions } from '@tiptap/starter-kit'
import VueComponent from './index.js'
export default {
components: {
EditorContent,
},
data() {
return {
editor: null,
}
},
mounted() {
this.editor = new Editor({
extensions: [
...defaultExtensions(),
VueComponent,
],
content: `
<p>
This is still the text editor youre used to, but enriched with node views.
</p>
<vue-component count="0"></vue-component>
<p>
Did you see that? Thats a Vue component. We are really living in the future.
</p>
`,
})
},
beforeDestroy() {
this.editor.destroy()
},
}
</script>
<style lang="scss">
/* Basic editor styles */
.ProseMirror {
> * + * {
margin-top: 0.75em;
}
}
.output {
background-color: #0D0D0D;
color: #fff;
padding: 1rem;
font-family: monospace;
font-size: 1.1rem;
border-radius: 0.5rem;
margin: 1rem 0;
position: relative;
}
</style>

View File

@ -0,0 +1,3 @@
# Interactive node views
<demo name="Examples/InteractiveNodeViews" />

View File

@ -75,201 +75,6 @@ You can even mix non-editable and editable text. Thats great because you can
**BUT**, that also means the cursor cant just move from outside of the node view to the inside. Users have to manually place their cursor to edit the content inside the node view. Just so you know.
## Node views with JavaScript
TODO
```js
import { Node } from '@tiptap/core'
import { VueNodeViewRenderer } from '@tiptap/vue-2'
import Component from './Component.vue'
export default Node.create({
addNodeView() {
return ({ editor, node, getPos, HTMLAttributes, decorations, extension }) => {
const dom = document.createElement('div')
dom.innerHTML = 'Hello, Im a node view!'
return {
dom,
}
})
},
})
```
## Node views with Vue
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.
### Render a Vue component
Here is what you need to do to render Vue components inside your text editor:
1. [Create a node extension](/guide/build-extensions)
2. Create a Vue component
3. Pass that component to the provided `VueNodeViewRenderer`
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 { VueNodeViewRenderer } from '@tiptap/vue-2'
import Component from './Component.vue'
export default Node.create({
// configuration …
addNodeView() {
return VueNodeViewRenderer(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 Vue component, like shown below:
```html
<template>
<node-view-wrapper>
Vue Component
</node-view-wrapper>
</template>
```
Got it? Lets see it in action. Feel free to copy the below example to get started.
<demo name="Guide/NodeViews/VueComponent" />
That component doesnt interactive with the editor, though. Time to connect it to the editor output.
### 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:
```js
props: {
node: {
type: Object,
required: true,
},
},
```
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:
```js
this.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. Just add this snippet to your component:
```js
props: {
updateAttributes: {
type: Function,
required: true,
},
},
```
Pass an object with updated attributes to the function:
```js
this.updateAttributes({
count: this.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:
```html
<template>
<node-view-wrapper class="dom">
<node-view-content class="content-dom" />
</node-view-wrapper>
</template>
<script>
import { NodeViewWrapper, NodeViewContent } from '@tiptap/vue-2'
export default {
components: {
NodeViewWrapper,
NodeViewContent,
},
}
```
You dont need to add those `class` attributes, feel free to remove them or pass other class names. Try it out in the following example:
<demo name="Guide/NodeViews/VueComponentContent" />
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 `<node-view-content as="p">` should render a paragraph. One limitation though: That tag must not change during runtime.
### All available props
For advanced use cases, we pass a few more props to the component. Here is the full list of what you can expect:
```html
<template>
<node-view-wrapper />
</template>
<script>
import { NodeViewWrapper } from '@tiptap/vue-2'
export default {
components: {
NodeViewWrapper,
},
props: {
// the editor instance
editor: {
type: Object,
},
// the current node
node: {
type: Object,
},
// an array of decorations
decorations: {
type: Array,
},
// true when the cursor is inside the node view
selected: {
type: Boolean,
},
// access to the node extension, for example to get options
extension: {
type: Object,
},
// get the document position of the current node
getPos: {
type: Function,
},
// update attributes of the current node
updateAttributes: {
type: Function,
},
},
}
</script>
```
## Node views with React
TODO
## Rendered content
```js
@ -284,9 +89,6 @@ renderHTML({ HTMLAttributes }) {
},
```
## Examples
Weve put together [a list of interactive examples](/guide/node-views/examples). :-)
## Reference
### dom: ?dom.Node

View File

@ -0,0 +1,26 @@
# Node views with JavaScript
## toc
## Introduction
TODO
```js
import { Node } from '@tiptap/core'
import { VueNodeViewRenderer } from '@tiptap/vue-2'
import Component from './Component.vue'
export default Node.create({
addNodeView() {
return ({ editor, node, getPos, HTMLAttributes, decorations, extension }) => {
const dom = document.createElement('div')
dom.innerHTML = 'Hello, Im a node view!'
return {
dom,
}
})
},
})
```

View File

@ -0,0 +1,6 @@
# Node views with React
## toc
## Introduction
TODO

View File

@ -0,0 +1,172 @@
# Node views with Vue
## 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.
## Render a Vue component
Here is what you need to do to render Vue components inside your text editor:
1. [Create a node extension](/guide/build-extensions)
2. Create a Vue component
3. Pass that component to the provided `VueNodeViewRenderer`
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 { VueNodeViewRenderer } from '@tiptap/vue-2'
import Component from './Component.vue'
export default Node.create({
// configuration …
addNodeView() {
return VueNodeViewRenderer(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 Vue component, like shown below:
```html
<template>
<node-view-wrapper>
Vue Component
</node-view-wrapper>
</template>
```
Got it? Lets see it in action. Feel free to copy the below example to get started.
<demo name="Guide/NodeViews/VueComponent" />
That component doesnt interactive with the editor, though. Time to connect it to the editor output.
## 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:
```js
props: {
node: {
type: Object,
required: true,
},
},
```
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:
```js
this.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. Just add this snippet to your component:
```js
props: {
updateAttributes: {
type: Function,
required: true,
},
},
```
Pass an object with updated attributes to the function:
```js
this.updateAttributes({
count: this.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:
```html
<template>
<node-view-wrapper class="dom">
<node-view-content class="content-dom" />
</node-view-wrapper>
</template>
<script>
import { NodeViewWrapper, NodeViewContent } from '@tiptap/vue-2'
export default {
components: {
NodeViewWrapper,
NodeViewContent,
},
}
```
You dont need to add those `class` attributes, feel free to remove them or pass other class names. Try it out in the following example:
<demo name="Guide/NodeViews/VueComponentContent" />
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 `<node-view-content as="p">` should render a paragraph. One limitation though: That tag must not change during runtime.
## All available props
For advanced use cases, we pass a few more props to the component. Here is the full list of what you can expect:
```html
<template>
<node-view-wrapper />
</template>
<script>
import { NodeViewWrapper } from '@tiptap/vue-2'
export default {
components: {
NodeViewWrapper,
},
props: {
// the editor instance
editor: {
type: Object,
},
// the current node
node: {
type: Object,
},
// an array of decorations
decorations: {
type: Array,
},
// true when the cursor is inside the node view
selected: {
type: Boolean,
},
// access to the node extension, for example to get options
extension: {
type: Object,
},
// get the document position of the current node
getPos: {
type: Function,
},
// update attributes of the current node
updateAttributes: {
type: Function,
},
},
}
</script>
```

View File

@ -20,12 +20,7 @@ We use Netlify to host the documentation. It features continuous deployment from
### Tracking (Plausible)
We use [Plausible](https://plausible.io) to gain insight about our visitors in general. It doesnt track individual users per se and does not store any personal identifiable information. Go to [their documentation](https://plausible.io/data-policy) to find out what Simple Analytics collects (and more importantly what they dont).
Or have a look at the [public analytics dashboard](https://plausible.io/tiptap.dev) they provide. Its not a stripped down version, its the exact same dashboard we use to check the traffic.
### Tracking (Simple Analytics, deprecated, will be removed soon)
We use [Simple Analytics](https://simpleanalytics.com/) to gain insight about our visitors in general. It doesnt track individual users per se and does not store any personal identifiable information. Go to their documentation to find out what Simple Analytics collects (and more importantly what they dont).
Or have a look at the [public analytics dashboard](https://simpleanalytics.com/tiptap.dev) they provide. Its not a stripped down version, its the exact same dashboard we use to check the traffic.
Or have a look at the [public analytics dashboard](https://plausible.io/next.tiptap.dev) they provide. Its not a stripped down version, its the exact same dashboard we use to check the traffic.
### Search (Algolia)
We use [Algolia DocSearch](https://docsearch.algolia.com/) to offer search functionality for the documentation. They crawl the same pages as you see once every day. If you click on the search field on top of this page, their search interface pops up.

View File

@ -6,22 +6,19 @@
- title: CDN
link: /installation/cdn
skip: true
- title: CodeSandbox
link: /installation/codesandbox
skip: true
- title: Vue 2
link: /installation/vue2
- title: React
link: /installation/react
type: draft
skip: true
- title: Vue 3
link: /installation/vue3
skip: true
- title: Vue 2
link: /installation/vue2
skip: true
- title: Nuxt.js
link: /installation/nuxt
skip: true
- title: React
link: /installation/react
type: draft
skip: true
- title: Svelte
link: /installation/svelte
type: draft
@ -34,6 +31,9 @@
link: /installation/livewire
type: draft
skip: true
- title: CodeSandbox
link: /installation/codesandbox
skip: true
- title: Upgrade guide
link: /overview/upgrade-guide
- title: Become a sponsor
@ -50,12 +50,12 @@
link: /examples/default
- title: Collaborative editing
link: /examples/collaborative-editing
type: pro
# type: pro
- title: Markdown shortcuts
link: /examples/markdown-shortcuts
- title: Tables
link: /examples/tables
type: pro
# type: pro
- title: Images
link: /examples/images
- title: Formatting
@ -72,6 +72,8 @@
link: /examples/minimal
- title: Savvy editor
link: /examples/savvy
- title: Interactive node views
link: /examples/interactive
- title: Guide
items:
@ -87,18 +89,25 @@
link: /guide/content
- title: Collaborative editing
link: /guide/collaborative-editing
type: pro
# type: pro
- title: Extend the functionality
link: /guide/extend-extensions
- title: Build extensions
link: /guide/build-extensions
- title: Interactive node views
link: /guide/node-views
type: draft
items:
- title: With JavaScript
link: /guide/node-views/js
type: draft
- title: With React
link: /guide/node-views/react
type: draft
- title: With Vue
link: /guide/node-views/vue
- title: Examples
link: /guide/node-views/examples
draft: true
type: draft
- title: Working with TypeScript
link: /guide/typescript
@ -139,23 +148,22 @@
link: /api/nodes/list-item
- title: Mention
link: /api/nodes/mention
type: new
- title: OrderedList
link: /api/nodes/ordered-list
- title: Paragraph
link: /api/nodes/paragraph
- title: Table
link: /api/nodes/table
type: pro
# type: pro
- title: TableRow
link: /api/nodes/table-row
type: pro
# type: pro
- title: TableCell
link: /api/nodes/table-cell
type: pro
# type: pro
- title: TableHeader
link: /api/nodes/table-header
type: pro
# type: pro
- title: TaskList
link: /api/nodes/task-list
- title: TaskItem
@ -189,13 +197,12 @@
# type: draft
- title: CharacterCount
link: /api/extensions/character-count
type: new
- title: Collaboration
link: /api/extensions/collaboration
type: pro
# type: pro
- title: CollaborationCursor
link: /api/extensions/collaboration-cursor
type: pro
# type: pro
- title: Dropcursor
link: /api/extensions/dropcursor
- title: Focus
@ -218,7 +225,6 @@
link: /api/utilities/html
- title: Suggestion
link: /api/utilities/suggestion
type: new
- title: Events
link: /api/events
- title: Schema