update docs
This commit is contained in:
@@ -23,20 +23,20 @@ You don’t have to use it, but we prepared a `@tiptap/vue-starter-kit` which in
|
|||||||
You’re free to create your own extensions for tiptap. Here is the boilerplate code that’s need to create and register your own extension:
|
You’re free to create your own extensions for tiptap. Here is the boilerplate code that’s need to create and register your own extension:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { createExtension } from '@tiptap/core'
|
import { Extension } from '@tiptap/core'
|
||||||
|
|
||||||
const CustomExtension = createExtension({
|
const CustomExtension = Extension.create({
|
||||||
// Your code here
|
// Your code here
|
||||||
})
|
})
|
||||||
|
|
||||||
const editor = new Editor({
|
const editor = new Editor({
|
||||||
extensions: [
|
extensions: [
|
||||||
// Register your custom extension with the editor.
|
// Register your custom extension with the editor.
|
||||||
CustomExtension(),
|
CustomExtension,
|
||||||
// … and don’t forget all other extensions.
|
// … and don’t forget all other extensions.
|
||||||
Document(),
|
Document,
|
||||||
Paragraph(),
|
Paragraph,
|
||||||
Text(),
|
Text,
|
||||||
// …
|
// …
|
||||||
],
|
],
|
||||||
```
|
```
|
||||||
@@ -49,7 +49,7 @@ ProseMirror has a fantastic eco system with many amazing plugins. If you want to
|
|||||||
```js
|
```js
|
||||||
import { history } from 'prosemirror-history'
|
import { history } from 'prosemirror-history'
|
||||||
|
|
||||||
const History = createExtension({
|
const History = Extension.create({
|
||||||
addProseMirrorPlugins() {
|
addProseMirrorPlugins() {
|
||||||
return [
|
return [
|
||||||
history(),
|
history(),
|
||||||
|
|||||||
@@ -38,15 +38,15 @@ In tiptap every node, mark and extension is living in its own file. This allows
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
// the tiptap schema API
|
// the tiptap schema API
|
||||||
import { createNode } from '@tiptap/core'
|
import { NodeExtension } from '@tiptap/core'
|
||||||
|
|
||||||
const Document = createNode({
|
const Document = NodeExtension.create({
|
||||||
name: 'document',
|
name: 'document',
|
||||||
topNode: true,
|
topNode: true,
|
||||||
content: 'block+',
|
content: 'block+',
|
||||||
})
|
})
|
||||||
|
|
||||||
const Paragraph = createNode({
|
const Paragraph = NodeExtension.create({
|
||||||
name: 'paragraph',
|
name: 'paragraph',
|
||||||
group: 'block',
|
group: 'block',
|
||||||
content: 'inline*',
|
content: 'inline*',
|
||||||
@@ -55,12 +55,12 @@ const Paragraph = createNode({
|
|||||||
{ tag: 'p' },
|
{ tag: 'p' },
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
renderHTML({ attributes }) {
|
renderHTML({ HTMLAttributes }) {
|
||||||
return ['p', attributes, 0]
|
return ['p', HTMLAttributes, 0]
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const Text = createNode({
|
const Text = NodeExtension.create({
|
||||||
name: 'text',
|
name: 'text',
|
||||||
group: 'inline',
|
group: 'inline',
|
||||||
})
|
})
|
||||||
@@ -79,7 +79,7 @@ Marks can be applied to specific parts of a node. That’s the case for **bold**
|
|||||||
The content attribute defines exactly what kind of content the node can have. ProseMirror is really strict with that. That means, content which doesn’t fit the schema is thrown away. It expects a name or group as a string. Here are a few examples:
|
The content attribute defines exactly what kind of content the node can have. ProseMirror is really strict with that. That means, content which doesn’t fit the schema is thrown away. It expects a name or group as a string. Here are a few examples:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createNode({
|
NodeExtension.create({
|
||||||
// must have one ore more blocks
|
// must have one ore more blocks
|
||||||
content: 'block+',
|
content: 'block+',
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ createNode({
|
|||||||
You can define which marks are allowed inside of a node with the `marks` setting of the schema. Add a one or more names or groups of marks, allow all or disallow all marks like this:
|
You can define which marks are allowed inside of a node with the `marks` setting of the schema. Add a one or more names or groups of marks, allow all or disallow all marks like this:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createNode({
|
NodeExtension.create({
|
||||||
// allows only the 'bold' mark
|
// allows only the 'bold' mark
|
||||||
marks: 'bold',
|
marks: 'bold',
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ createNode({
|
|||||||
Add this node to a group of extensions, which can be referred to in the [content](#content) attribute of the schema.
|
Add this node to a group of extensions, which can be referred to in the [content](#content) attribute of the schema.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createNode({
|
NodeExtension.create({
|
||||||
// add to 'block' group
|
// add to 'block' group
|
||||||
group: 'block',
|
group: 'block',
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ createNode({
|
|||||||
Nodes can be rendered inline, too. When setting `inline: true` nodes are rendered in line with the text. That’s the case for mentions. The result is more like a mark, but with the functionality of a node. One difference is the resulting JSON document. Multiple marks are applied at once, inline nodes would result in a nested structure.
|
Nodes can be rendered inline, too. When setting `inline: true` nodes are rendered in line with the text. That’s the case for mentions. The result is more like a mark, but with the functionality of a node. One difference is the resulting JSON document. Multiple marks are applied at once, inline nodes would result in a nested structure.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createNode({
|
NodeExtension.create({
|
||||||
// renders nodes in line with the text, for example
|
// renders nodes in line with the text, for example
|
||||||
inline: true,
|
inline: true,
|
||||||
})
|
})
|
||||||
@@ -144,7 +144,7 @@ createNode({
|
|||||||
Nodes with `atom: true` aren’t directly editable and should be treated as a single unit. It’s not so likely to use that in a editor context, but this is how it would look like:
|
Nodes with `atom: true` aren’t directly editable and should be treated as a single unit. It’s not so likely to use that in a editor context, but this is how it would look like:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createNode({
|
NodeExtension.create({
|
||||||
atom: true,
|
atom: true,
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -153,7 +153,7 @@ createNode({
|
|||||||
Besides the already visible text selection, there is an invisible node selection. If you want to make your nodes selectable, you can configure it like this:
|
Besides the already visible text selection, there is an invisible node selection. If you want to make your nodes selectable, you can configure it like this:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createNode({
|
NodeExtension.create({
|
||||||
selectable: true,
|
selectable: true,
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -162,7 +162,7 @@ createNode({
|
|||||||
All nodes can be configured to be draggable (by default they aren’t) with this setting:
|
All nodes can be configured to be draggable (by default they aren’t) with this setting:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createNode({
|
NodeExtension.create({
|
||||||
draggable: true,
|
draggable: true,
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -171,7 +171,7 @@ createNode({
|
|||||||
Users expect code to behave very differently. For all kind of nodes containing code, you can set `code: true` to take this into account.
|
Users expect code to behave very differently. For all kind of nodes containing code, you can set `code: true` to take this into account.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createNode({
|
NodeExtension.create({
|
||||||
code: true,
|
code: true,
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -182,7 +182,7 @@ Nodes get dropped when their entire content is replaced (for example, when pasti
|
|||||||
Typically, that applies to [`Blockquote`](/api/node/blockquote), [`CodeBlock`](/api/node/code-block), [`Heading`](/api/node/heading), and [`ListItem`](/api/node/list-item).
|
Typically, that applies to [`Blockquote`](/api/node/blockquote), [`CodeBlock`](/api/node/code-block), [`Heading`](/api/node/heading), and [`ListItem`](/api/node/list-item).
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createNode({
|
NodeExtension.create({
|
||||||
defining: true,
|
defining: true,
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -191,7 +191,7 @@ createNode({
|
|||||||
For nodes that should fence the cursor for regular editing operations like backspacing, for example a TableCell, set `isolating: true`.
|
For nodes that should fence the cursor for regular editing operations like backspacing, for example a TableCell, set `isolating: true`.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createNode({
|
NodeExtension.create({
|
||||||
isolating: true,
|
isolating: true,
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -201,7 +201,7 @@ createNode({
|
|||||||
If you don’t want the mark to be active when the cursor is at its end, set inclusive to `false`. For example, that’s how it’s configured for [`Link`](/api/marks/link) marks:
|
If you don’t want the mark to be active when the cursor is at its end, set inclusive to `false`. For example, that’s how it’s configured for [`Link`](/api/marks/link) marks:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createMark({
|
MarkExtension.create({
|
||||||
inclusive: false,
|
inclusive: false,
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -210,7 +210,7 @@ createMark({
|
|||||||
By default all nodes can be applied at the same time. With the excludes attribute you can define which marks must not coexist with the mark. For example, the inline code mark excludes any other mark (bold, italic, and all others).
|
By default all nodes can be applied at the same time. With the excludes attribute you can define which marks must not coexist with the mark. For example, the inline code mark excludes any other mark (bold, italic, and all others).
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createMark({
|
MarkExtension.create({
|
||||||
// must not coexist with the bold mark
|
// must not coexist with the bold mark
|
||||||
excludes: 'bold'
|
excludes: 'bold'
|
||||||
// exclude any other mark
|
// exclude any other mark
|
||||||
@@ -222,7 +222,7 @@ createMark({
|
|||||||
Add this mark to a group of extensions, which can be referred to in the content attribute of the schema.
|
Add this mark to a group of extensions, which can be referred to in the content attribute of the schema.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createMark({
|
MarkExtension.create({
|
||||||
// add this mark to the 'basic' group
|
// add this mark to the 'basic' group
|
||||||
group: 'basic',
|
group: 'basic',
|
||||||
// add this mark to the 'basic' and the 'foobar' group
|
// add this mark to the 'basic' and the 'foobar' group
|
||||||
@@ -234,7 +234,7 @@ createMark({
|
|||||||
Users expect code to behave very differently. For all kind of marks containing code, you can set `code: true` to take this into account.
|
Users expect code to behave very differently. For all kind of marks containing code, you can set `code: true` to take this into account.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createMark({
|
MarkExtension.create({
|
||||||
code: true,
|
code: true,
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -243,7 +243,7 @@ createMark({
|
|||||||
By default marks can span multiple nodes when rendered as HTML. Set `spanning: false` to indicate that a mark must not span multiple nodes.
|
By default marks can span multiple nodes when rendered as HTML. Set `spanning: false` to indicate that a mark must not span multiple nodes.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
createMark({
|
MarkExtension.create({
|
||||||
spanning: false,
|
spanning: false,
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -262,9 +262,9 @@ import Text from '@tiptap/extension-text'
|
|||||||
|
|
||||||
const editor = new Editor({
|
const editor = new Editor({
|
||||||
extensions: [
|
extensions: [
|
||||||
Document(),
|
Document,
|
||||||
Paragraph(),
|
Paragraph,
|
||||||
Text(),
|
Text,
|
||||||
// add more extensions here
|
// add more extensions here
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
@@ -282,9 +282,9 @@ import Paragraph from '@tiptap/extension-paragraph'
|
|||||||
import Text from '@tiptap/extension-text'
|
import Text from '@tiptap/extension-text'
|
||||||
|
|
||||||
const schema = getSchema([
|
const schema = getSchema([
|
||||||
Document(),
|
Document,
|
||||||
Paragraph(),
|
Paragraph,
|
||||||
Text(),
|
Text,
|
||||||
// add more extensions here
|
// add more extensions here
|
||||||
])
|
])
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -171,9 +171,9 @@ Attributes can be applied to multiple extensions at once. That’s useful for te
|
|||||||
Take a closer look at [the full source code](https://github.com/ueberdosis/tiptap-next/tree/main/packages/extension-text-align) of the [`TextAlign`](/api/extensions/text-align) extension to see a more complex example. But here is how it works in a nutshell:
|
Take a closer look at [the full source code](https://github.com/ueberdosis/tiptap-next/tree/main/packages/extension-text-align) of the [`TextAlign`](/api/extensions/text-align) extension to see a more complex example. But here is how it works in a nutshell:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { createExtension } from '@tiptap/core'
|
import { Extension } from '@tiptap/core'
|
||||||
|
|
||||||
const TextAlign = createExtension({
|
const TextAlign = Extension.create({
|
||||||
addGlobalAttributes() {
|
addGlobalAttributes() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@@ -204,8 +204,8 @@ const TextAlign = createExtension({
|
|||||||
With the `renderHTML` function you can control how an extension is rendered to HTML. We pass an attributes object to it, with all local attributes, global attributes, and configured CSS classes. Here is an example from the `Bold` extension:
|
With the `renderHTML` function you can control how an extension is rendered to HTML. We pass an attributes object to it, with all local attributes, global attributes, and configured CSS classes. Here is an example from the `Bold` extension:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
renderHTML({ attributes }) {
|
renderHTML({ HTMLAttributes }) {
|
||||||
return ['strong', attributes, 0]
|
return ['strong', HTMLAttributes, 0]
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -214,16 +214,16 @@ The first value in the array should be the name of HTML tag. If the second eleme
|
|||||||
The number zero (representing a hole) is used to indicate where the content should be inserted. Let’s look at the rendering of the `CodeBlock` extension with two nested tags:
|
The number zero (representing a hole) is used to indicate where the content should be inserted. Let’s look at the rendering of the `CodeBlock` extension with two nested tags:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
renderHTML({ attributes }) {
|
renderHTML({ HTMLAttributes }) {
|
||||||
return ['pre', ['code', attributes, 0]]
|
return ['pre', ['code', HTMLAttributes, 0]]
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to add some specific attributes there, import the `mergeAttributes` helper from `@tiptap/core`:
|
If you want to add some specific attributes there, import the `mergeAttributes` helper from `@tiptap/core`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
renderHTML({ attributes }) {
|
renderHTML({ HTMLAttributes }) {
|
||||||
return ['a', mergeAttributes(attributes, { rel: this.options.rel }), 0]
|
return ['a', mergeAttributes(HTMLAttributes, { rel: this.options.rel }), 0]
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -386,33 +386,33 @@ const CustomLink = Link.extend({
|
|||||||
There is a whole lot to learn about node views, so head over to the [dedicated section in our guide about node views](/guide/advanced-node-views) for more information. If you’re looking for a real-world example, look at the source code of the [`TaskItem`](/api/nodes/task-item) node. This is using a node view to render the checkboxes.
|
There is a whole lot to learn about node views, so head over to the [dedicated section in our guide about node views](/guide/advanced-node-views) for more information. If you’re looking for a real-world example, look at the source code of the [`TaskItem`](/api/nodes/task-item) node. This is using a node view to render the checkboxes.
|
||||||
|
|
||||||
## Start from scratch
|
## Start from scratch
|
||||||
You can also build your own extensions from scratch with the `createNode()`, `createMark()`, and `createExtension()` functions. Pass an option with your code and configuration.
|
You can also build your own extensions from scratch with the `NodeExtension`, `MarkExtension`, and `Extension` classes. Pass an option with your code and configuration.
|
||||||
|
|
||||||
And if everything is working fine, don’t forget to [share it with the community](https://github.com/ueberdosis/tiptap-next/issues/new/choose).
|
And if everything is working fine, don’t forget to [share it with the community](https://github.com/ueberdosis/tiptap-next/issues/new/choose).
|
||||||
|
|
||||||
### Create a node
|
### Create a node
|
||||||
```js
|
```js
|
||||||
import { createNode } from '@tiptap/core'
|
import { NodeExtension } from '@tiptap/core'
|
||||||
|
|
||||||
const CustomNode = createNode({
|
const CustomNode = NodeExtension.create({
|
||||||
// Your code goes here.
|
// Your code goes here.
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
### Create a mark
|
### Create a mark
|
||||||
```js
|
```js
|
||||||
import { createMark } from '@tiptap/core'
|
import { MarkExtension } from '@tiptap/core'
|
||||||
|
|
||||||
const CustomMark = createMark({
|
const CustomMark = MarkExtension.create({
|
||||||
// Your code goes here.
|
// Your code goes here.
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
### Create an extension
|
### Create an extension
|
||||||
```js
|
```js
|
||||||
import { createExtension } from '@tiptap/core'
|
import { Extension } from '@tiptap/core'
|
||||||
|
|
||||||
const CustomExtension = createExtension({
|
const CustomExtension = Extension.create({
|
||||||
// Your code goes here.
|
// Your code goes here.
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -28,23 +28,23 @@ p {
|
|||||||
## Option 2: Add custom classes
|
## Option 2: Add custom classes
|
||||||
Most extensions have a `class` option, which you can use to add a custom CSS class to the HTML tag.
|
Most extensions have a `class` option, which you can use to add a custom CSS class to the HTML tag.
|
||||||
|
|
||||||
Most extensions allow you to add attributes to the rendered HTML through the `attributes` configuration. You can use that to add a custom class (or any other attribute):
|
Most extensions allow you to add attributes to the rendered HTML through the `HTMLAttributes` configuration. You can use that to add a custom class (or any other attribute):
|
||||||
|
|
||||||
```js
|
```js
|
||||||
new Editor({
|
new Editor({
|
||||||
extensions: [
|
extensions: [
|
||||||
Document(),
|
Document,
|
||||||
Paragraph({
|
Paragraph.set({
|
||||||
attributes: {
|
HTMLAttributes: {
|
||||||
class: 'my-custom-paragraph',
|
class: 'my-custom-paragraph',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
Heading({
|
Heading.set({
|
||||||
attributes: {
|
HTMLAttributes: {
|
||||||
class: 'my-custom-heading',
|
class: 'my-custom-heading',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
Text(),
|
Text,
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
@@ -65,10 +65,10 @@ You can even customize the markup for every extension. This will make a custom b
|
|||||||
import Bold from '@tiptap/extension-bold'
|
import Bold from '@tiptap/extension-bold'
|
||||||
|
|
||||||
const CustomBold = Bold.extend({
|
const CustomBold = Bold.extend({
|
||||||
renderHTML({ attributes }) {
|
renderHTML({ HTMLAttributes }) {
|
||||||
// Original:
|
// Original:
|
||||||
// return ['strong', attributes, 0]
|
// return ['strong', HTMLAttributes, 0]
|
||||||
return ['b', attributes, 0]
|
return ['b', HTMLAttributes, 0]
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ If you’re using TypeScript in your project and want to extend tiptap, there ar
|
|||||||
To extend or create default options for an extension, you’ll need to define a custom type, here is an example:
|
To extend or create default options for an extension, you’ll need to define a custom type, here is an example:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { createExtension } from '@tiptap/core'
|
import { Extension } from '@tiptap/core'
|
||||||
|
|
||||||
export interface CustomExtensionOptions {
|
export interface CustomExtensionOptions {
|
||||||
awesomeness: number,
|
awesomeness: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
const CustomExtension = createExtension({
|
const CustomExtension = Extension.create({
|
||||||
defaultOptions: <CustomExtensionOptions>{
|
defaultOptions: <CustomExtensionOptions>{
|
||||||
awesomeness: 100,
|
awesomeness: 100,
|
||||||
},
|
},
|
||||||
@@ -32,9 +32,9 @@ const CustomExtension = createExtension({
|
|||||||
The core package also exports a `Command` type, which needs to be added to all commands that you specify in your code. Here is an example:
|
The core package also exports a `Command` type, which needs to be added to all commands that you specify in your code. Here is an example:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { Command, createExtension } from '@tiptap/core'
|
import { Command, Extension } from '@tiptap/core'
|
||||||
|
|
||||||
const CustomExtension = createExtension({
|
const CustomExtension = Extension.create({
|
||||||
addCommands() {
|
addCommands() {
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ import Text from '@tiptap/extension-text'
|
|||||||
|
|
||||||
new Editor({
|
new Editor({
|
||||||
extensions: [
|
extensions: [
|
||||||
Document(),
|
Document,
|
||||||
Paragraph(),
|
Paragraph,
|
||||||
Text(),
|
Text,
|
||||||
// all your other extensions
|
// all your other extensions
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
@@ -44,9 +44,9 @@ new Editor({
|
|||||||
In case you’ve built some custom extensions for your project, you’re required to rewrite them to fit the new API. No worries, you can keep a lot of your work though. The `schema`, `commands`, `keys`, `inputRules` and `pasteRules` all work like they did before. It’s just different how you register them.
|
In case you’ve built some custom extensions for your project, you’re required to rewrite them to fit the new API. No worries, you can keep a lot of your work though. The `schema`, `commands`, `keys`, `inputRules` and `pasteRules` all work like they did before. It’s just different how you register them.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { createNode } from '@tiptap/core'
|
import { NodeExtension } from '@tiptap/core'
|
||||||
|
|
||||||
const CustomExtension = createNode({
|
const CustomExtension = NodeExtension.create({
|
||||||
name: 'custom_extension'
|
name: 'custom_extension'
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
…
|
…
|
||||||
@@ -57,7 +57,7 @@ const CustomExtension = createNode({
|
|||||||
parseHTML() {
|
parseHTML() {
|
||||||
…
|
…
|
||||||
},
|
},
|
||||||
renderHTML({ node, attributes }) {
|
renderHTML({ node, HTMLAttributes }) {
|
||||||
…
|
…
|
||||||
},
|
},
|
||||||
addCommands() {
|
addCommands() {
|
||||||
|
|||||||
Reference in New Issue
Block a user