Skip to content

Commit f731cd9

Browse files
chore(release): publish version 3.0.0-next.5(#6012)
1 parent e80ba58 commit f731cd9

File tree

116 files changed

+1789
-274
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+1789
-274
lines changed

.changeset/pre.json

+15-2
Original file line numberDiff line numberDiff line change
@@ -58,25 +58,38 @@
5858
"@tiptap/vue-2": "2.5.6",
5959
"@tiptap/vue-3": "2.5.6",
6060
"@tiptap/extensions": "3.0.0-next.3",
61-
"@tiptap/static-renderer": "3.0.0-next.1"
61+
"@tiptap/static-renderer": "3.0.0-next.1",
62+
"@tiptap/extension-list": "3.0.0-next.4"
6263
},
6364
"changesets": [
6465
"big-wolves-design",
6566
"blue-shrimps-rush",
6667
"chilled-trees-agree",
6768
"chilly-lemons-remember",
6869
"cool-bananas-breathe",
70+
"curly-adults-move",
6971
"dirty-bats-look",
7072
"dirty-colts-shave",
73+
"eighty-gifts-matter",
7174
"fair-jars-shout",
75+
"gold-ads-own",
7276
"green-wolves-arrive",
77+
"healthy-pigs-work",
78+
"large-kangaroos-battle",
7379
"lazy-needles-train",
80+
"moody-geckos-sort",
7481
"nervous-hairs-walk",
7582
"orange-spoons-rescue",
7683
"perfect-rice-vanish",
7784
"quick-days-matter",
85+
"red-ants-wonder",
7886
"red-rivers-exist",
87+
"seven-llamas-love",
88+
"sixty-news-ring",
7989
"tame-worms-applaud",
80-
"weak-books-eat"
90+
"tidy-fireants-hang",
91+
"twenty-moose-invent",
92+
"weak-books-eat",
93+
"witty-eels-cheer"
8194
]
8295
}

packages/core/CHANGELOG.md

+264
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,269 @@
11
# Change Log
22

3+
## 3.0.0-next.5
4+
5+
### Major Changes
6+
7+
- 32958d6: `Node`, `Mark` and `Extension` config options now are strongly typed and do not allow arbitrary keys on the options object.
8+
9+
To add keys, like when using `extendNodeSchema` or `extendMarkSchema`, you can do this:
10+
11+
```ts
12+
declare module '@tiptap/core' {
13+
interface NodeConfig {
14+
/**
15+
* This key will be added to all NodeConfig objects in your project
16+
*/
17+
newKey?: string
18+
}
19+
interface MarkConfig {
20+
/**
21+
* This key will be added to all MarkConfig objects in your project
22+
*/
23+
newKey?: string
24+
}
25+
interface ExtensionConfig {
26+
/**
27+
* This key will be added to all ExtensionConfig objects in your project
28+
*/
29+
newKey?: string
30+
}
31+
}
32+
```
33+
34+
- 062afaf: `clearContent` command defaults to emitting updates now
35+
- 062afaf: Change signature of `setContent` command to `(content, options)` and default to emitting updates
36+
- 32958d6: `editor.storage` is now strongly typed `Storage` instances, using a similar pattern as commands, where you can define the type of the storage value using namespaces like:
37+
38+
```ts
39+
declare module '@tiptap/core' {
40+
interface Storage {
41+
extensionName: StorageValue
42+
}
43+
}
44+
```
45+
46+
- 32958d6: `editor.storage` is instantiated per editor rather than per extension.
47+
48+
Previously, the storage value was a singleton per extension instance, this caused strange bugs when using multiple editor instances on a single page.
49+
50+
Now, storage instances are _per editor instance_, so changing the value on one `editor.storage` instance will not affect another editor's value.
51+
52+
### Minor Changes
53+
54+
- 0e3207f: Add support for [markviews](https://prosemirror.net/docs/ref/#view.MarkView), which allow you to render custom views for marks within the editor. This is useful for rendering custom UI for marks, like a color picker for a text color mark or a link editor for a link mark.
55+
56+
Here is a plain JS markview example:
57+
58+
```ts
59+
Mark.create({
60+
// Other options...
61+
addMarkView() {
62+
return ({ mark, HTMLAttributes }) => {
63+
const dom = document.createElement('b')
64+
const contentDOM = document.createElement('span')
65+
66+
dom.appendChild(contentDOM)
67+
68+
return {
69+
dom,
70+
contentDOM,
71+
}
72+
}
73+
},
74+
})
75+
```
76+
77+
## React binding
78+
79+
To use a React component for a markview, you can use the `@tiptap/react` package:
80+
81+
```ts
82+
import { Mark } from '@tiptap/core'
83+
import { ReactMarkViewRenderer } from '@tiptap/react'
84+
85+
import Component from './Component.jsx'
86+
87+
export default Mark.create({
88+
name: 'reactComponent',
89+
90+
parseHTML() {
91+
return [
92+
{
93+
tag: 'react-component',
94+
},
95+
]
96+
},
97+
98+
renderHTML({ HTMLAttributes }) {
99+
return ['react-component', HTMLAttributes]
100+
},
101+
102+
addMarkView() {
103+
return ReactMarkViewRenderer(Component)
104+
},
105+
})
106+
```
107+
108+
And here is an example of a React component:
109+
110+
```tsx
111+
import { MarkViewContent, MarkViewRendererProps } from '@tiptap/react'
112+
import React from 'react'
113+
114+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
115+
export default (props: MarkViewRendererProps) => {
116+
const [count, setCount] = React.useState(0)
117+
118+
return (
119+
<span className="content" data-test-id="mark-view">
120+
<MarkViewContent />
121+
<label contentEditable={false}>
122+
React component:
123+
<button
124+
onClick={() => {
125+
setCount(count + 1)
126+
}}
127+
>
128+
This button has been clicked {count} times.
129+
</button>
130+
</label>
131+
</span>
132+
)
133+
}
134+
```
135+
136+
## Vue 3 binding
137+
138+
To use a Vue 3 component for a markview, you can use the `@tiptap/vue-3` package:
139+
140+
```ts
141+
import { Mark } from '@tiptap/core'
142+
import { VueMarkViewRenderer } from '@tiptap/vue-3'
143+
144+
import Component from './Component.vue'
145+
146+
export default Mark.create({
147+
name: 'vueComponent',
148+
149+
parseHTML() {
150+
return [
151+
{
152+
tag: 'vue-component',
153+
},
154+
]
155+
},
156+
157+
renderHTML({ HTMLAttributes }) {
158+
return ['vue-component', HTMLAttributes]
159+
},
160+
161+
addMarkView() {
162+
return VueMarkViewRenderer(Component)
163+
},
164+
})
165+
```
166+
167+
And here is an example of a Vue 3 component:
168+
169+
```vue
170+
<template>
171+
<span className="content" data-test-id="mark-view">
172+
<mark-view-content />
173+
<label contenteditable="false"
174+
>Vue Component::
175+
<button @click="increase" class="primary">This button has been clicked {{ count }} times.</button>
176+
</label>
177+
</span>
178+
</template>
179+
180+
<script>
181+
import { MarkViewContent, markViewProps } from '@tiptap/vue-3'
182+
export default {
183+
components: {
184+
MarkViewContent,
185+
},
186+
data() {
187+
return {
188+
count: 0,
189+
}
190+
},
191+
props: markViewProps,
192+
methods: {
193+
increase() {
194+
this.count += 1
195+
},
196+
},
197+
}
198+
</script>
199+
```
200+
201+
- 28c5418: Adds a new `delete` event which can detect content which has been deleted by the editor as a core extension
202+
- 704f462: This introduces a new behavior for the editor, the ability to be safely run on the server-side (without rendering).
203+
204+
`prosemirror-view` encapsulates all view (& DOM) related code, and cannot safely be SSR'd, but, the majority of the editor instance itself is in plain JS that does not require DOM APIs (unless your content is specified in HTML).
205+
206+
But, we have so many convenient methods available for manipulating content. So, it is a shame that they could not be used on the server side too. With this change, the editor can be rendered on the server-side and will use a stub for select prosemirror-view methods. If accessing unsupported methods or values on the `editor.view`, you will encounter runtime errors, so it is important for you to test to see if the methods you call actually work.
207+
208+
This is a step towards being able to server-side render content, but, it is not completely supported yet. This does not mean that you can render an editor instance on the server and expect it to just output any HTML.
209+
210+
## Usage
211+
212+
If you pass `element: null` to your editor options:
213+
214+
- the `editor.view` will not be initialized
215+
- the editor will not emit it's `'create'` event
216+
- the focus will not be initialized to it's first position
217+
218+
You can however, later use the new `mount` function on the instance, which will mount the editor view to a DOM element. This obviously will not be allowed on the server which has no document object.
219+
220+
Therefore, this will work on the server:
221+
222+
```ts
223+
import { Editor } from '@tiptap/core'
224+
import StarterKit from '@tiptap/starter-kit'
225+
226+
const editor = new Editor({
227+
element: null,
228+
content: { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Hello, World!' }] }] },
229+
extensions: [StarterKit],
230+
})
231+
232+
editor
233+
.chain()
234+
.selectAll()
235+
.setContent({ type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'XYZ' }] }] })
236+
.run()
237+
238+
console.log(editor.state.doc.toJSON())
239+
// { type: 'doc', content: [ { type: 'paragraph', content: [ { type: 'text', text: 'XYZ' } ] } ] }
240+
```
241+
242+
Any of these things will not work on the server, and result in a runtime error:
243+
244+
```ts
245+
import { Editor } from '@tiptap/core'
246+
import StarterKit from '@tiptap/starter-kit'
247+
248+
const editor = new Editor({
249+
// document will not be defined in a server environment
250+
element: document.createElement('div'),
251+
content: { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Hello, World!' }] }] },
252+
extensions: [StarterKit],
253+
})
254+
255+
editor
256+
.chain()
257+
// focus is a command which depends on the editor-view, so it will not work in a server environment
258+
.focus()
259+
.run()
260+
261+
console.log(editor.getHTML())
262+
// getHTML relies on the editor-view, so it will not work in a server environment
263+
```
264+
265+
- 32958d6: Extensions, Nodes and Marks no longer respect the deprecated `defaultOptions` config value
266+
3267
## 3.0.0-next.4
4268

5269
### Minor Changes

packages/core/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@tiptap/core",
33
"description": "headless rich text editor",
4-
"version": "3.0.0-next.4",
4+
"version": "3.0.0-next.5",
55
"homepage": "https://tiptap.dev",
66
"keywords": [
77
"tiptap",
@@ -51,7 +51,7 @@
5151
"jsx-runtime"
5252
],
5353
"devDependencies": {
54-
"@tiptap/pm": "^3.0.0-next.4"
54+
"@tiptap/pm": "^3.0.0-next.5"
5555
},
5656
"peerDependencies": {
5757
"@tiptap/pm": "^3.0.0-next.1"

packages/extension-blockquote/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Change Log
22

3+
## 3.0.0-next.5
4+
35
## 3.0.0-next.4
46

57
## 3.0.0-next.3

packages/extension-blockquote/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@tiptap/extension-blockquote",
33
"description": "blockquote extension for tiptap",
4-
"version": "3.0.0-next.4",
4+
"version": "3.0.0-next.5",
55
"homepage": "https://tiptap.dev",
66
"keywords": [
77
"tiptap",
@@ -31,7 +31,7 @@
3131
"dist"
3232
],
3333
"devDependencies": {
34-
"@tiptap/core": "^3.0.0-next.4"
34+
"@tiptap/core": "^3.0.0-next.5"
3535
},
3636
"peerDependencies": {
3737
"@tiptap/core": "^3.0.0-next.1"

packages/extension-bold/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Change Log
22

3+
## 3.0.0-next.5
4+
35
## 3.0.0-next.4
46

57
## 3.0.0-next.3

packages/extension-bold/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@tiptap/extension-bold",
33
"description": "bold extension for tiptap",
4-
"version": "3.0.0-next.4",
4+
"version": "3.0.0-next.5",
55
"homepage": "https://tiptap.dev",
66
"keywords": [
77
"tiptap",
@@ -31,7 +31,7 @@
3131
"dist"
3232
],
3333
"devDependencies": {
34-
"@tiptap/core": "^3.0.0-next.4"
34+
"@tiptap/core": "^3.0.0-next.5"
3535
},
3636
"peerDependencies": {
3737
"@tiptap/core": "^3.0.0-next.1"

packages/extension-bubble-menu/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Change Log
22

3+
## 3.0.0-next.5
4+
35
## 3.0.0-next.4
46

57
## 3.0.0-next.3

0 commit comments

Comments
 (0)