@blocknote/core 0.4.6-alpha.1 → 0.4.6-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -34
- package/dist/blocknote.js +31 -29
- package/dist/blocknote.js.map +1 -1
- package/dist/blocknote.umd.cjs +2 -2
- package/dist/blocknote.umd.cjs.map +1 -1
- package/package.json +3 -3
- package/src/BlockNoteEditor.ts +2 -2
- package/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts +3 -3
- package/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts +2 -2
- package/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts +2 -2
- package/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts +1 -1
- package/src/extensions/DraggableBlocks/DraggableBlocksPlugin.ts +6 -0
- package/types/src/BlockNoteEditor.d.ts +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://www.blocknotejs.org">
|
|
3
|
+
<img alt="TypeCell" src="https://github.com/TypeCellOS/BlockNote/raw/main/packages/website/docs/public/img/logos/banner.svg?raw=true" width="300" />
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
Welcome to BlockNote! The open source Block-Based
|
|
9
|
+
rich text editor. Easily add a modern text editing experience to your app.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
3
13
|
<a href="https://discord.gg/Qc2QTTH5dF"><img alt="Discord" src="https://img.shields.io/badge/Chat on discord%20-%237289DA.svg?&style=for-the-badge&logo=discord&logoColor=white"/></a> <a href="https://matrix.to/#/#typecell-space:matrix.org"><img alt="Matrix" src="https://img.shields.io/badge/Chat on matrix%20-%23000.svg?&style=for-the-badge&logo=matrix&logoColor=white"/></a>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<a href="https://www.blocknotejs.org">
|
|
18
|
+
Homepage
|
|
19
|
+
</a> - <a href="https://www.blocknotejs.org/docs/introduction">
|
|
20
|
+
Introduction
|
|
21
|
+
</a> - <a href="https://www.blocknotejs.org/docs/quickstart">
|
|
22
|
+
Documentation
|
|
23
|
+
</a>
|
|
24
|
+
</p>
|
|
8
25
|
|
|
9
26
|
# Live demo
|
|
10
27
|
|
|
@@ -14,13 +31,15 @@ Play with the editor @ [https://blocknote-main.vercel.app/](https://blocknote-ma
|
|
|
14
31
|
|
|
15
32
|
# Example code (React)
|
|
16
33
|
|
|
34
|
+
[](https://badge.fury.io/js/%40blocknote%2Freact)
|
|
35
|
+
|
|
17
36
|
```typescript
|
|
18
37
|
import { BlockNoteView, useBlockNote } from "@blocknote/react";
|
|
19
38
|
import "@blocknote/core/style.css";
|
|
20
39
|
|
|
21
40
|
function App() {
|
|
22
41
|
const editor = useBlockNote({
|
|
23
|
-
|
|
42
|
+
onEditorContentChange: (editor) => {
|
|
24
43
|
// Log the document to console on every update
|
|
25
44
|
console.log(editor.getJSON());
|
|
26
45
|
},
|
|
@@ -32,7 +51,7 @@ function App() {
|
|
|
32
51
|
|
|
33
52
|
`@blocknote/react` comes with a fully styled UI that makes it an instant, polished editor ready to use in your app.
|
|
34
53
|
|
|
35
|
-
If you prefer to create your own UI components (menus), or don't want to use React, you can use `@blocknote/core` (_advanced_, see
|
|
54
|
+
If you prefer to create your own UI components (menus), or don't want to use React, you can use `@blocknote/core` (_advanced_, [see docs](https://www.blocknotejs.org/docs/vanilla-js)).
|
|
36
55
|
|
|
37
56
|
# Features
|
|
38
57
|
|
|
@@ -40,33 +59,39 @@ BlockNote comes with a number of features and components to make it easy to embe
|
|
|
40
59
|
|
|
41
60
|
### Animations:
|
|
42
61
|
|
|
43
|
-
<img src="https://github.com/
|
|
62
|
+
<img src="https://github.com/TypeCellOS/BlockNote/blob/readme/.resources/animations.gif?raw=true" width="400" />
|
|
44
63
|
|
|
45
64
|
### Helpful placeholders:
|
|
46
65
|
|
|
47
|
-
<img src="https://github.com/
|
|
66
|
+
<img src="https://github.com/TypeCellOS/BlockNote/blob/readme/.resources/placeholders.gif?raw=true" width="400" />
|
|
48
67
|
|
|
49
68
|
### Drag and drop blocks:
|
|
50
69
|
|
|
51
|
-
<img src="https://github.com/
|
|
70
|
+
<img src="https://github.com/TypeCellOS/BlockNote/blob/readme/.resources/dragdrop.gif?raw=true" width="400" />
|
|
52
71
|
|
|
53
72
|
### Nesting / indentation with tab and shift+tab:
|
|
54
73
|
|
|
55
|
-
<img src="https://github.com/
|
|
74
|
+
<img src="https://github.com/TypeCellOS/BlockNote/blob/readme/.resources/nesting.gif?raw=true" width="400" />
|
|
56
75
|
|
|
57
76
|
### Slash (/) menu:
|
|
58
77
|
|
|
59
|
-
<img src="https://github.com/
|
|
78
|
+
<img src="https://github.com/TypeCellOS/BlockNote/blob/readme/.resources/slashmenu.gif?raw=true" width="400" />
|
|
60
79
|
|
|
61
80
|
### Format menu:
|
|
62
81
|
|
|
63
|
-
<img src="https://github.com/
|
|
82
|
+
<img src="https://github.com/TypeCellOS/BlockNote/blob/readme/.resources/selectmenu.gif?raw=true" width="400" />
|
|
64
83
|
|
|
65
84
|
### Real-time collaboration:
|
|
66
85
|
|
|
67
|
-
<img src="https://github.com/
|
|
86
|
+
<img src="https://github.com/TypeCellOS/BlockNote/blob/readme/.resources/collaboration.gif?raw=true" width="400" />
|
|
87
|
+
|
|
88
|
+
# Feedback 🙋♂️🙋♀️
|
|
89
|
+
|
|
90
|
+
We'd love to hear your thoughts and see your experiments, so [come and say hi on Discord](https://discord.gg/Qc2QTTH5dF) or [Matrix](https://matrix.to/#/#typecell-space:matrix.org).
|
|
91
|
+
|
|
92
|
+
# Contributing 🙌
|
|
68
93
|
|
|
69
|
-
|
|
94
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for more info and guidance on how to run the project (TLDR: just use `npm start`).
|
|
70
95
|
|
|
71
96
|
Directory structure:
|
|
72
97
|
|
|
@@ -79,24 +104,7 @@ blocknote
|
|
|
79
104
|
└── tests - Playwright end to end tests
|
|
80
105
|
```
|
|
81
106
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
## Running
|
|
85
|
-
|
|
86
|
-
To run the project, open the command line in the project's root directory and enter the following commands:
|
|
87
|
-
|
|
88
|
-
# Install all required npm modules for lerna, and bootstrap lerna packages
|
|
89
|
-
npm install
|
|
90
|
-
npm run bootstrap
|
|
91
|
-
|
|
92
|
-
# Start the example project
|
|
93
|
-
npm start
|
|
94
|
-
|
|
95
|
-
## Adding packages
|
|
96
|
-
|
|
97
|
-
- Add the dependency to the relevant `package.json` file (packages/xxx/package.json)
|
|
98
|
-
- run `npm run install-new-packages`
|
|
99
|
-
- Double check `package-lock.json` to make sure only the relevant packages have been affected
|
|
107
|
+
The codebase is automatically tested using Vitest and Playwright.
|
|
100
108
|
|
|
101
109
|
# Credits ❤️
|
|
102
110
|
|
|
@@ -105,3 +113,7 @@ BlockNote builds directly on two awesome projects; [Prosemirror](https://prosemi
|
|
|
105
113
|
BlockNote is built as part of [TypeCell](https://www.typecell.org). TypeCell is proudly sponsored by the renowned [NLNet foundation](https://nlnet.nl/foundation/) who are on a mission to support an open internet, and protect the privacy and security of internet users. Check them out!
|
|
106
114
|
|
|
107
115
|
<a href="https://nlnet.nl"><img src="https://nlnet.nl/image/logos/NGIAssure_tag.svg" alt="NLNet" width="100"></a>
|
|
116
|
+
|
|
117
|
+
Hosting and deployments powered by Vercel:
|
|
118
|
+
|
|
119
|
+
<a href="https://vercel.com/?utm_source=TypeCell&utm_campaign=oss"><img src="https://images.ctfassets.net/e5382hct74si/78Olo8EZRdUlcDUFQvnzG7/fa4cdb6dc04c40fceac194134788a0e2/1618983297-powered-by-vercel.svg" alt="NLNet" width="150"></a>
|
package/dist/blocknote.js
CHANGED
|
@@ -4,9 +4,9 @@ var h = (o, e, t) => (Be(o, typeof e != "symbol" ? e + "" : e, t), t);
|
|
|
4
4
|
import { Extension as C, findChildren as q, combineTransactionSteps as Te, getChangedRanges as we, findChildrenInRange as Me, Mark as ne, Node as E, mergeAttributes as x, InputRule as j, findParentNode as xe, isTextSelection as Ee, isNodeSelection as Ie, posToDOMRect as re, getMarkRange as X, extensions as N, Editor as Se } from "@tiptap/core";
|
|
5
5
|
import { Slice as A, Fragment as P, DOMSerializer as Ae, DOMParser as Pe } from "prosemirror-model";
|
|
6
6
|
import { Plugin as B, PluginKey as v, TextSelection as Q, Selection as U, NodeSelection as Ne } from "prosemirror-state";
|
|
7
|
-
import { v4 as
|
|
7
|
+
import { v4 as Le } from "uuid";
|
|
8
8
|
import ie from "rehype-parse";
|
|
9
|
-
import
|
|
9
|
+
import He from "rehype-remark";
|
|
10
10
|
import se from "rehype-stringify";
|
|
11
11
|
import ae from "remark-gfm";
|
|
12
12
|
import Oe from "remark-parse";
|
|
@@ -88,7 +88,7 @@ const W = C.create({
|
|
|
88
88
|
return {
|
|
89
89
|
attributeName: "id",
|
|
90
90
|
types: [],
|
|
91
|
-
generateID: () => window.__TEST_OPTIONS ? (window.__TEST_OPTIONS.mockID === void 0 ? window.__TEST_OPTIONS.mockID = 0 : window.__TEST_OPTIONS.mockID++, parseInt(window.__TEST_OPTIONS.mockID)) :
|
|
91
|
+
generateID: () => window.__TEST_OPTIONS ? (window.__TEST_OPTIONS.mockID === void 0 ? window.__TEST_OPTIONS.mockID = 0 : window.__TEST_OPTIONS.mockID++, parseInt(window.__TEST_OPTIONS.mockID)) : Le(),
|
|
92
92
|
filterTransaction: null
|
|
93
93
|
};
|
|
94
94
|
},
|
|
@@ -144,18 +144,18 @@ const W = C.create({
|
|
|
144
144
|
m,
|
|
145
145
|
(T) => a.includes(T.type.name)
|
|
146
146
|
), g = y.map(({ node: T }) => T.attrs[l]).filter((T) => T !== null), R = Je(g);
|
|
147
|
-
y.forEach(({ node: T, pos:
|
|
147
|
+
y.forEach(({ node: T, pos: H }) => {
|
|
148
148
|
var z;
|
|
149
|
-
const J = (z = s.doc.nodeAt(
|
|
149
|
+
const J = (z = s.doc.nodeAt(H)) === null || z === void 0 ? void 0 : z.attrs[l];
|
|
150
150
|
if (J === null) {
|
|
151
|
-
s.setNodeMarkup(
|
|
151
|
+
s.setNodeMarkup(H, void 0, {
|
|
152
152
|
...T.attrs,
|
|
153
153
|
[l]: c()
|
|
154
154
|
});
|
|
155
155
|
return;
|
|
156
156
|
}
|
|
157
|
-
const { deleted: ve } = f.invert().mapResult(
|
|
158
|
-
ve && R.includes(J) && s.setNodeMarkup(
|
|
157
|
+
const { deleted: ve } = f.invert().mapResult(H);
|
|
158
|
+
ve && R.includes(J) && s.setNodeMarkup(H, void 0, {
|
|
159
159
|
...T.attrs,
|
|
160
160
|
[l]: c()
|
|
161
161
|
});
|
|
@@ -511,7 +511,7 @@ async function ke(o, e) {
|
|
|
511
511
|
return i;
|
|
512
512
|
}
|
|
513
513
|
async function it(o, e) {
|
|
514
|
-
return (await Y().use(ie, { fragment: !0 }).use(nt).use(
|
|
514
|
+
return (await Y().use(ie, { fragment: !0 }).use(nt).use(He).use(ae).use(De).process(await me(o, e))).value;
|
|
515
515
|
}
|
|
516
516
|
async function st(o, e) {
|
|
517
517
|
const t = await Y().use(Oe).use(ae).use(_e).use(se).process(o);
|
|
@@ -989,7 +989,7 @@ const at = C.create({
|
|
|
989
989
|
{
|
|
990
990
|
tag: "p",
|
|
991
991
|
priority: 200,
|
|
992
|
-
node: "
|
|
992
|
+
node: "paragraph"
|
|
993
993
|
}
|
|
994
994
|
];
|
|
995
995
|
},
|
|
@@ -1039,17 +1039,17 @@ const at = C.create({
|
|
|
1039
1039
|
{
|
|
1040
1040
|
tag: "h1",
|
|
1041
1041
|
attrs: { level: "1" },
|
|
1042
|
-
node: "
|
|
1042
|
+
node: "heading"
|
|
1043
1043
|
},
|
|
1044
1044
|
{
|
|
1045
1045
|
tag: "h2",
|
|
1046
1046
|
attrs: { level: "2" },
|
|
1047
|
-
node: "
|
|
1047
|
+
node: "heading"
|
|
1048
1048
|
},
|
|
1049
1049
|
{
|
|
1050
1050
|
tag: "h3",
|
|
1051
1051
|
attrs: { level: "3" },
|
|
1052
|
-
node: "
|
|
1052
|
+
node: "heading"
|
|
1053
1053
|
}
|
|
1054
1054
|
];
|
|
1055
1055
|
},
|
|
@@ -1116,7 +1116,7 @@ const at = C.create({
|
|
|
1116
1116
|
const e = o.parentElement;
|
|
1117
1117
|
return e === null ? !1 : e.tagName === "UL" ? {} : !1;
|
|
1118
1118
|
},
|
|
1119
|
-
node: "
|
|
1119
|
+
node: "bulletListItem"
|
|
1120
1120
|
},
|
|
1121
1121
|
// Case for BlockNote list structure.
|
|
1122
1122
|
{
|
|
@@ -1128,7 +1128,7 @@ const at = C.create({
|
|
|
1128
1128
|
return e === null ? !1 : e.getAttribute("data-content-type") === "bulletListItem" ? {} : !1;
|
|
1129
1129
|
},
|
|
1130
1130
|
priority: 300,
|
|
1131
|
-
node: "
|
|
1131
|
+
node: "bulletListItem"
|
|
1132
1132
|
}
|
|
1133
1133
|
];
|
|
1134
1134
|
},
|
|
@@ -1221,7 +1221,7 @@ const at = C.create({
|
|
|
1221
1221
|
const e = o.parentElement;
|
|
1222
1222
|
return e === null ? !1 : e.tagName === "OL" ? {} : !1;
|
|
1223
1223
|
},
|
|
1224
|
-
node: "
|
|
1224
|
+
node: "numberedListItem"
|
|
1225
1225
|
},
|
|
1226
1226
|
// Case for BlockNote list structure.
|
|
1227
1227
|
// (e.g.: when pasting from blocknote)
|
|
@@ -1234,7 +1234,7 @@ const at = C.create({
|
|
|
1234
1234
|
return e === null ? !1 : e.getAttribute("data-content-type") === "numberedListItem" ? {} : !1;
|
|
1235
1235
|
},
|
|
1236
1236
|
priority: 300,
|
|
1237
|
-
node: "
|
|
1237
|
+
node: "numberedListItem"
|
|
1238
1238
|
}
|
|
1239
1239
|
];
|
|
1240
1240
|
},
|
|
@@ -1329,7 +1329,7 @@ class Nt {
|
|
|
1329
1329
|
};
|
|
1330
1330
|
}
|
|
1331
1331
|
}
|
|
1332
|
-
function
|
|
1332
|
+
function Lt({
|
|
1333
1333
|
pluginKey: o,
|
|
1334
1334
|
editor: e,
|
|
1335
1335
|
defaultTriggerCharacter: t,
|
|
@@ -1472,7 +1472,7 @@ function Ht({
|
|
|
1472
1472
|
}
|
|
1473
1473
|
});
|
|
1474
1474
|
}
|
|
1475
|
-
const K = new v("suggestions-slash-commands"),
|
|
1475
|
+
const K = new v("suggestions-slash-commands"), Ht = C.create({
|
|
1476
1476
|
name: "slash-command",
|
|
1477
1477
|
addOptions() {
|
|
1478
1478
|
return {
|
|
@@ -1486,7 +1486,7 @@ const K = new v("suggestions-slash-commands"), Lt = C.create({
|
|
|
1486
1486
|
throw new Error("required args not defined for SlashMenuExtension");
|
|
1487
1487
|
const o = this.options.commands;
|
|
1488
1488
|
return [
|
|
1489
|
-
|
|
1489
|
+
Lt({
|
|
1490
1490
|
pluginKey: K,
|
|
1491
1491
|
editor: this.options.editor,
|
|
1492
1492
|
defaultTriggerCharacter: "/",
|
|
@@ -1499,7 +1499,7 @@ const K = new v("suggestions-slash-commands"), Lt = C.create({
|
|
|
1499
1499
|
];
|
|
1500
1500
|
}
|
|
1501
1501
|
});
|
|
1502
|
-
class
|
|
1502
|
+
class L extends U {
|
|
1503
1503
|
constructor(t, n) {
|
|
1504
1504
|
super(t, n);
|
|
1505
1505
|
h(this, "nodes");
|
|
@@ -1510,13 +1510,13 @@ class H extends U {
|
|
|
1510
1510
|
});
|
|
1511
1511
|
}
|
|
1512
1512
|
static create(t, n, r = n) {
|
|
1513
|
-
return new
|
|
1513
|
+
return new L(t.resolve(n), t.resolve(r));
|
|
1514
1514
|
}
|
|
1515
1515
|
content() {
|
|
1516
1516
|
return new A(P.from(this.nodes), 0, 0);
|
|
1517
1517
|
}
|
|
1518
1518
|
eq(t) {
|
|
1519
|
-
if (!(t instanceof
|
|
1519
|
+
if (!(t instanceof L) || this.nodes.length !== t.nodes.length || this.from !== t.from || this.to !== t.to)
|
|
1520
1520
|
return !1;
|
|
1521
1521
|
for (let n = 0; n < this.nodes.length; n++)
|
|
1522
1522
|
if (!this.nodes[n].eq(t.nodes[n]))
|
|
@@ -1525,7 +1525,7 @@ class H extends U {
|
|
|
1525
1525
|
}
|
|
1526
1526
|
map(t, n) {
|
|
1527
1527
|
let r = n.mapResult(this.from), i = n.mapResult(this.to);
|
|
1528
|
-
return i.deleted ? U.near(t.resolve(r.pos)) : r.deleted ? U.near(t.resolve(i.pos)) : new
|
|
1528
|
+
return i.deleted ? U.near(t.resolve(r.pos)) : r.deleted ? U.near(t.resolve(i.pos)) : new L(
|
|
1529
1529
|
t.resolve(r.pos),
|
|
1530
1530
|
t.resolve(i.pos)
|
|
1531
1531
|
);
|
|
@@ -1538,6 +1538,8 @@ const Ot = Ve.__serializeForClipboard;
|
|
|
1538
1538
|
let w;
|
|
1539
1539
|
function ye(o, e) {
|
|
1540
1540
|
var r;
|
|
1541
|
+
if (!e.dom.isConnected)
|
|
1542
|
+
return;
|
|
1541
1543
|
let t = e.posAtCoords(o);
|
|
1542
1544
|
if (!t)
|
|
1543
1545
|
return;
|
|
@@ -1598,7 +1600,7 @@ function Ft(o, e) {
|
|
|
1598
1600
|
if (r != null) {
|
|
1599
1601
|
const i = e.state.selection, d = e.state.doc, { from: s, to: a } = Dt(i, d), l = s <= r && r < a, c = !i.$anchor.node().eq(i.$head.node());
|
|
1600
1602
|
l && c ? (e.dispatch(
|
|
1601
|
-
e.state.tr.setSelection(
|
|
1603
|
+
e.state.tr.setSelection(L.create(d, s, a))
|
|
1602
1604
|
), oe(e, s, a)) : (e.dispatch(
|
|
1603
1605
|
e.state.tr.setSelection(Ne.create(e.state.doc, r))
|
|
1604
1606
|
), oe(e, r));
|
|
@@ -2495,7 +2497,7 @@ const Qt = [
|
|
|
2495
2497
|
hyperlinkToolbarFactory: o.uiFactories.hyperlinkToolbarFactory
|
|
2496
2498
|
})
|
|
2497
2499
|
) : e.push(de), o.uiFactories.slashMenuFactory && e.push(
|
|
2498
|
-
|
|
2500
|
+
Ht.configure({
|
|
2499
2501
|
editor: o.editor,
|
|
2500
2502
|
commands: o.slashCommands,
|
|
2501
2503
|
slashMenuFactory: o.uiFactories.slashMenuFactory
|
|
@@ -2506,7 +2508,7 @@ const Qt = [
|
|
|
2506
2508
|
enablePasteRules: !0,
|
|
2507
2509
|
enableCoreExtensions: !1
|
|
2508
2510
|
};
|
|
2509
|
-
class
|
|
2511
|
+
class Lo {
|
|
2510
2512
|
constructor(e = {}) {
|
|
2511
2513
|
h(this, "_tiptapEditor");
|
|
2512
2514
|
h(this, "blockCache", /* @__PURE__ */ new WeakMap());
|
|
@@ -2522,7 +2524,7 @@ class Ho {
|
|
|
2522
2524
|
...e._tiptapOptions,
|
|
2523
2525
|
onCreate: () => {
|
|
2524
2526
|
var a;
|
|
2525
|
-
(a = e.
|
|
2527
|
+
(a = e.onEditorReady) == null || a.call(e, this);
|
|
2526
2528
|
},
|
|
2527
2529
|
onUpdate: () => {
|
|
2528
2530
|
var a;
|
|
@@ -2695,7 +2697,7 @@ class Ho {
|
|
|
2695
2697
|
}
|
|
2696
2698
|
export {
|
|
2697
2699
|
I as BaseSlashMenuItem,
|
|
2698
|
-
|
|
2700
|
+
Lo as BlockNoteEditor,
|
|
2699
2701
|
ee as blockProps,
|
|
2700
2702
|
Qt as defaultSlashMenuItems,
|
|
2701
2703
|
no as getBlockNoteExtensions,
|