tiptap/docs/api/editor.md

399 lines
11 KiB
Markdown
Raw Normal View History

---
tableOfContents: true
---
2020-04-19 02:39:48 +08:00
# Editor
2020-09-16 03:07:16 +08:00
## Introduction
2021-10-20 04:30:45 +08:00
This class is a central building block of Tiptap. It does most of the heavy lifting of creating a working [ProseMirror](https://ProseMirror.net/) editor such as creating the [`EditorView`](https://ProseMirror.net/docs/ref/#view.EditorView), setting the initial [`EditorState`](https://ProseMirror.net/docs/ref/#state.Editor_State) and so on.
2021-04-03 21:21:30 +08:00
## Methods
The editor instance will provide a bunch of public methods. Methods are regular functions and can return anything. Theyll help you to work with the editor.
Dont confuse methods with [commands](/api/commands). Commands are used to change the state of editor (content, selection, and so on) and only return `true` or `false`.
### can()
Check if a command or a command chain can be executed without actually executing it. Can be very helpful to enable/disable or show/hide buttons.
```js
// Returns `true` if the undo command can be executed
editor.can().undo()
```
### chain()
Create a command chain to call multiple commands at once.
```js
// Execute two commands at once
editor.chain().toggleBold().focus().run()
```
### destroy()
Stops the editor instance and unbinds all events.
```js
// Hasta la vista, baby!
editor.destroy()
```
### getHTML()
Returns the current editor document as HTML
```js
editor.getHTML()
```
### getJSON()
Returns the current editor document as JSON.
```js
editor.getJSON()
```
2021-10-02 04:10:59 +08:00
### getText()
Returns the current editor document as plain text.
| Parameter | Type | Description |
| ---------- | ------------------------------ | ------------------------ |
| options | { blockSeparator?: string, textSerializers?: Record<string, TextSerializer>} | Options for the serialization. |
```js
// Give me plain text!
editor.getText()
// Add two line breaks between nodes
editor.getText({ blockSeparator: "\n\n" })
```
2021-10-02 04:10:59 +08:00
### getAttributes()
Get attributes of the currently selected node or mark.
| Parameter | Type | Description |
| ---------- | ------------------------------ | ------------------------ |
| typeOrName | string \| NodeType \| MarkType | Name of the node or mark |
```js
editor.getAttributes('link').href
```
2021-10-02 04:10:59 +08:00
### isActive()
Returns if the currently selected node or mark is active.
| Parameter | Type | Description |
| ---------------------- | ------------------- | ------------------------------ |
| name | string \| null | Name of the node or mark |
| attributes | Record<string, any> | Attributes of the node or mark |
```js
// Check if its a heading
editor.isActive('heading')
// Check if its a heading with a specific attribute value
editor.isActive('heading', { level: 2 })
// Check if it has a specific attribute value, doesnt care what node/mark it is
editor.isActive({ textAlign: 'justify' })
```
2021-10-02 04:10:59 +08:00
### registerPlugin()
Register a ProseMirror plugin.
| Parameter | Type | Description |
| -------------- | -------------------------------------------------- | --------------------------------------------------------- |
| plugin | Plugin | A ProseMirror plugin |
| handlePlugins? | (newPlugin: Plugin, plugins: Plugin[]) => Plugin[] | Control how to merge the plugin into the existing plugins |
2021-10-02 04:10:59 +08:00
### setOptions()
Update editor options.
| Parameter | Type | Description |
| --------- | ---------------------- | ----------------- |
| options | Partial<EditorOptions> | A list of options |
```js
// Add a class to an existing editor instance
editor.setOptions({
editorProps: {
attributes: {
class: 'my-custom-class',
},
},
})
```
### setEditable()
Update editable state of the editor.
| Parameter | Type | Description |
| --------- | ------- | ------------------------------------------------------------- |
| editable | boolean | `true` when the user should be able to write into the editor. |
| emitUpdate | boolean | Defaults to `true`. Determines whether `onUpdate` is triggered. |
```js
// Make the editor read-only
editor.setEditable(false)
```
2021-10-02 04:10:59 +08:00
### unregisterPlugin()
Unregister a ProseMirror plugin.
| Parameter | Type | Description |
| --------------- | ------------------- | ---------------- |
| nameOrPluginKey | string \| PluginKey | The plugins name |
## Getters
### isEditable
Returns whether the editor is editable or read-only.
```js
editor.isEditable
```
### isEmpty
Check if there is content.
```js
editor.isEmpty
```
2021-04-03 21:21:30 +08:00
## Settings
2020-11-18 00:10:48 +08:00
2021-10-02 04:10:59 +08:00
### element
2022-01-03 02:03:54 +08:00
The `element` specifies the HTML element the editor will be binded to. The following code will integrate Tiptap with an element with the `.element` class:
2020-11-18 00:10:48 +08:00
```js
import { Editor } from '@tiptap/core'
2021-05-07 00:41:22 +08:00
import StarterKit from '@tiptap/starter-kit'
2020-11-18 00:10:48 +08:00
new Editor({
element: document.querySelector('.element'),
2021-05-07 00:41:22 +08:00
extensions: [
StarterKit,
],
2020-11-18 00:10:48 +08:00
})
```
2021-01-28 19:21:12 +08:00
You can even initiate your editor before mounting it to an element. This is useful when your DOM is not yet available. Just leave out the `element`, well create one for you. Append it to your container at a later date like that:
```js
yourContainerElement.append(editor.options.element)
```
2021-10-02 04:10:59 +08:00
### extensions
2020-11-18 00:10:48 +08:00
Its required to pass a list of extensions to the `extensions` property, even if you only want to allow paragraphs.
```js
import { Editor } from '@tiptap/core'
2021-05-07 00:41:22 +08:00
import StarterKit from '@tiptap/starter-kit'
2020-11-18 00:10:48 +08:00
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import Highlight from '@tiptap/extension-highlight'
new Editor({
// Use the default extensions
2021-05-07 00:41:22 +08:00
extensions: [
StarterKit,
],
2020-11-18 00:10:48 +08:00
// … or use specific extensions
extensions: [
Document,
Paragraph,
Text,
],
// … or both
extensions: [
2021-05-07 00:41:22 +08:00
StarterKit,
2020-11-18 00:10:48 +08:00
Highlight,
2020-11-30 21:24:48 +08:00
],
2020-11-18 00:10:48 +08:00
})
```
2021-10-02 04:10:59 +08:00
### content
2020-11-18 00:10:48 +08:00
With the `content` property you can provide the initial content for the editor. This can be HTML or JSON.
```js
import { Editor } from '@tiptap/core'
2021-05-07 00:41:22 +08:00
import StarterKit from '@tiptap/starter-kit'
2020-11-18 00:10:48 +08:00
new Editor({
content: `<p>Example Text</p>`,
2021-05-07 00:41:22 +08:00
extensions: [
StarterKit,
],
2020-11-18 00:10:48 +08:00
})
```
2021-10-02 04:10:59 +08:00
### editable
2020-11-18 00:10:48 +08:00
The `editable` property determines if users can write into the editor.
```js
import { Editor } from '@tiptap/core'
2021-05-07 00:41:22 +08:00
import StarterKit from '@tiptap/starter-kit'
2020-11-18 00:10:48 +08:00
new Editor({
content: `<p>Example Text</p>`,
2021-05-07 00:41:22 +08:00
extensions: [
StarterKit,
],
2020-11-18 00:10:48 +08:00
editable: false,
})
```
2021-10-02 04:10:59 +08:00
### autofocus
2020-11-18 00:10:48 +08:00
With `autofocus` you can force the cursor to jump in the editor on initialization.
2021-10-02 04:25:12 +08:00
| Value | Description |
| --------- | ------------------------------------------------------ |
| `'start'` | Sets the focus to the beginning of the document. |
| `'end'` | Sets the focus to the end of the document. |
| `'all'` | Selects the whole document. |
2021-10-02 04:25:12 +08:00
| `Number` | Sets the focus to a specific position in the document. |
| `true` | Enables autofocus. |
| `false` | Disables autofocus. |
| `null` | Disables autofocus. |
2020-11-18 00:10:48 +08:00
```js
import { Editor } from '@tiptap/core'
2021-05-07 00:41:22 +08:00
import StarterKit from '@tiptap/starter-kit'
2020-11-18 00:10:48 +08:00
new Editor({
2021-05-07 00:41:22 +08:00
extensions: [
StarterKit,
],
2020-11-18 00:10:48 +08:00
autofocus: false,
})
```
2021-10-02 04:10:59 +08:00
### enableInputRules
2021-11-18 19:50:07 +08:00
By default, Tiptap enables all [input rules](/guide/custom-extensions/#input-rules). With `enableInputRules` you can control that.
```js
import { Editor } from '@tiptap/core'
2021-05-07 00:41:22 +08:00
import StarterKit from '@tiptap/starter-kit'
new Editor({
content: `<p>Example Text</p>`,
2021-05-07 00:41:22 +08:00
extensions: [
StarterKit,
],
enableInputRules: false,
})
```
2021-11-18 19:50:07 +08:00
Alternatively you can allow only specific input rules.
```js
import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
import Link from '@tiptap/extension-link'
new Editor({
content: `<p>Example Text</p>`,
extensions: [
StarterKit,
Link,
],
// pass an array of extensions or extension names
// to allow only specific input rules
enableInputRules: [Link, 'horizontalRule'],
})
```
2021-10-02 04:10:59 +08:00
### enablePasteRules
2021-11-18 19:50:07 +08:00
By default, Tiptap enables all [paste rules](/guide/custom-extensions/#paste-rules). With `enablePasteRules` you can control that.
```js
import { Editor } from '@tiptap/core'
2021-05-07 00:41:22 +08:00
import StarterKit from '@tiptap/starter-kit'
new Editor({
content: `<p>Example Text</p>`,
2021-05-07 00:41:22 +08:00
extensions: [
StarterKit,
],
enablePasteRules: false,
})
```
2020-11-18 00:10:48 +08:00
2021-11-18 19:50:07 +08:00
Alternatively you can allow only specific paste rules.
```js
import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
import Link from '@tiptap/extension-link'
new Editor({
content: `<p>Example Text</p>`,
extensions: [
StarterKit,
Link,
],
// pass an array of extensions or extension names
// to allow only specific paste rules
enablePasteRules: [Link, 'horizontalRule'],
})
```
2021-10-02 04:10:59 +08:00
### injectCSS
2021-10-20 04:30:45 +08:00
By default, Tiptap injects [a little bit of CSS](https://github.com/ueberdosis/tiptap/tree/main/packages/core/src/style.ts). With `injectCSS` you can disable that.
2020-11-18 00:10:48 +08:00
```js
import { Editor } from '@tiptap/core'
2021-05-07 00:41:22 +08:00
import StarterKit from '@tiptap/starter-kit'
2020-11-18 00:10:48 +08:00
new Editor({
2021-05-07 00:41:22 +08:00
extensions: [
StarterKit,
],
2020-11-18 00:10:48 +08:00
injectCSS: false,
})
```
### injectNonce
When you use a [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) with `nonce`, you can specify a `nonce` to be added to dynamically created elements. Here is an example:
```js
import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
new Editor({
extensions: [
StarterKit,
],
injectCSS: true,
injectNonce: "your-nonce-here"
})
```
2021-10-02 04:10:59 +08:00
### editorProps
2021-09-21 23:43:58 +08:00
For advanced use cases, you can pass `editorProps` which will be handled by [ProseMirror](https://prosemirror.net/docs/ref/#view.EditorProps). You can use it to override various editor events or change editor DOM element attributes, for example to add some Tailwind classes. Here is an example:
2020-11-18 00:10:48 +08:00
2021-04-03 21:21:30 +08:00
```js
new Editor({
// Learn more: https://prosemirror.net/docs/ref/#view.EditorProps
editorProps: {
attributes: {
class: 'prose prose-sm sm:prose lg:prose-lg xl:prose-2xl mx-auto focus:outline-none',
2021-04-21 17:46:45 +08:00
},
transformPastedText(text) {
2021-09-21 23:43:58 +08:00
return text.toUpperCase()
}
}
2021-09-21 23:43:58 +08:00
})
2021-04-03 21:21:30 +08:00
```
2020-11-18 00:10:48 +08:00
2021-04-16 03:48:19 +08:00
You can use that to hook into event handlers and pass - for example - a custom paste handler, too.
2021-10-02 04:10:59 +08:00
### parseOptions
2021-04-03 21:21:30 +08:00
Passed content is parsed by ProseMirror. To hook into the parsing, you can pass `parseOptions` which are then handled by [ProseMirror](https://prosemirror.net/docs/ref/#model.ParseOptions).
2020-11-18 00:10:48 +08:00
2021-04-03 21:21:30 +08:00
```js
new Editor({
// Learn more: https://prosemirror.net/docs/ref/#model.ParseOptions
parseOptions: {
preserveWhitespace: 'full',
},
})
```