Skip to content

Commit 0b6bfea

Browse files
feat: tables (#413)
* fix table types * add tablecontent * clean BNUpdateBlock * add partial inline content * add contentNodeToTableContent * first draft of tablehandles * implement table functions * fix styles * fix imports * create separate TableExtension * improve types * test some types * Fixed setting selection for table blocks * Fixed backspace deleting table if at start of cell * small code fixes * Implemented PR feedback * Improved table row/column drag & drop UX * Fixed table menus moving around, drag indicator flakiness, menu z-index issues, and drag preview * Implemented PR feedback * Implemented PR feedback * Fixed drag handles sometimes not showing * Fixed scrolling behaviour * Small fixes * Fixed table handles UI * Fixed remaining UX/UI issues * Removed redundant state from table handles plugin * Implemented table drag & drop logic * Added table enter handling * Small fix * feat: custom styles and custom inline content (#418) * wip custom styles * fix * fix tests * simplify PartialInlineContent * custom inline content * clean nodeconversions test * streamline tests * update tests * move schema files * add custom style test * inline content + tests * misc * clean imports * fix react tests * add react nodeconversions tests * move tests and add test for ReactStyles * fix react tests * basis of new examples * add react examples * fix bug * misc fixes * wip * clean * small cleanup * add comments * move funcs * fix tests * address PR feedback * fix inline content types * feat: HTML paste handling (#422) * refactor parse * fix parse-divsc * add test case * add extra test (that should be fixed) * readd markdown functions * fix tests * remove unused file * remove comments * add comment * nested list handling * add todos * added comment * use refs for blocks (#424) * use refs for blocks * update react htmlConversion test * Custom inline content and styles commands/copy & paste fixes (#425) * Fixed commands and internal copy/paste for inline content * Fixed internal copy/paste for styles * Small cleanup * fix some tests --------- Co-authored-by: yousefed <yousefdardiry@gmail.com> --------- Co-authored-by: Matthew Lipski <50169049+matthewlipski@users.noreply.github.com> * use processSync --------- Co-authored-by: Matthew Lipski <50169049+matthewlipski@users.noreply.github.com> * fix build --------- Co-authored-by: Matthew Lipski <50169049+matthewlipski@users.noreply.github.com> --------- Co-authored-by: Matthew Lipski <matthewlipski@gmail.com> Co-authored-by: Matthew Lipski <50169049+matthewlipski@users.noreply.github.com>
1 parent 84fb89a commit 0b6bfea

File tree

247 files changed

+11082
-3720
lines changed

Some content is hidden

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

247 files changed

+11082
-3720
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
// import logo from './logo.svg'
21
import "@blocknote/core/style.css";
32
import { BlockNoteView, useBlockNote } from "@blocknote/react";
4-
import "./App.css";
3+
54
import { uploadToTmpFilesDotOrg_DEV_ONLY } from "@blocknote/core";
65

76
type WindowWithProseMirror = Window & typeof globalThis & { ProseMirror: any };
87

9-
function App() {
8+
export function App() {
109
const editor = useBlockNote({
11-
onEditorContentChange: (editor) => {
12-
console.log(editor.topLevelBlocks);
13-
},
1410
domAttributes: {
1511
editor: {
1612
class: "editor",
@@ -23,7 +19,7 @@ function App() {
2319
// Give tests a way to get prosemirror instance
2420
(window as WindowWithProseMirror).ProseMirror = editor?._tiptapEditor;
2521

26-
return <BlockNoteView editor={editor} />;
22+
return <BlockNoteView className="root" editor={editor} />;
2723
}
2824

2925
export default App;
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import "@blocknote/core/style.css";
2+
import { BlockNoteView, useBlockNote } from "@blocknote/react";
3+
4+
import { uploadToTmpFilesDotOrg_DEV_ONLY } from "@blocknote/core";
5+
6+
import YPartyKitProvider from "y-partykit/provider";
7+
import * as Y from "yjs";
8+
9+
const doc = new Y.Doc();
10+
11+
const provider = new YPartyKitProvider(
12+
"blocknote-dev.yousefed.partykit.dev",
13+
// use a unique name as a "room" for your application:
14+
"your-project-name",
15+
doc
16+
);
17+
18+
type WindowWithProseMirror = Window & typeof globalThis & { ProseMirror: any };
19+
20+
export function App() {
21+
const editor = useBlockNote({
22+
domAttributes: {
23+
editor: {
24+
class: "editor",
25+
"data-test": "editor",
26+
},
27+
},
28+
collaboration: {
29+
// The Yjs Provider responsible for transporting updates:
30+
provider,
31+
// Where to store BlockNote data in the Y.Doc:
32+
fragment: doc.getXmlFragment("document-storesss"),
33+
// Information (name and color) for this user:
34+
user: {
35+
name: "My Username",
36+
color: "#ff0000",
37+
},
38+
},
39+
uploadFile: uploadToTmpFilesDotOrg_DEV_ONLY,
40+
});
41+
42+
// Give tests a way to get prosemirror instance
43+
(window as WindowWithProseMirror).ProseMirror = editor?._tiptapEditor;
44+
45+
return <BlockNoteView className="root" editor={editor} />;
46+
}
47+
48+
export default App;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { defaultInlineContentSpecs } from "@blocknote/core";
2+
import "@blocknote/core/style.css";
3+
import {
4+
BlockNoteView,
5+
createReactInlineContentSpec,
6+
useBlockNote,
7+
} from "@blocknote/react";
8+
9+
type WindowWithProseMirror = Window & typeof globalThis & { ProseMirror: any };
10+
11+
const mention = createReactInlineContentSpec(
12+
{
13+
type: "mention",
14+
propSchema: {
15+
user: {
16+
default: "",
17+
},
18+
},
19+
content: "none",
20+
},
21+
{
22+
render: (props) => {
23+
return <span>@{props.inlineContent.props.user}</span>;
24+
},
25+
}
26+
);
27+
28+
const tag = createReactInlineContentSpec(
29+
{
30+
type: "tag",
31+
propSchema: {},
32+
content: "styled",
33+
},
34+
{
35+
render: (props) => {
36+
return (
37+
<span>
38+
#<span ref={props.contentRef}></span>
39+
</span>
40+
);
41+
},
42+
}
43+
);
44+
45+
export function ReactInlineContent() {
46+
const editor = useBlockNote({
47+
inlineContentSpecs: {
48+
mention,
49+
tag,
50+
...defaultInlineContentSpecs,
51+
},
52+
domAttributes: {
53+
editor: {
54+
class: "editor",
55+
"data-test": "editor",
56+
},
57+
},
58+
initialContent: [
59+
{
60+
type: "paragraph",
61+
content: [
62+
"I enjoy working with ",
63+
{
64+
type: "mention",
65+
props: {
66+
user: "Matthew",
67+
},
68+
content: undefined,
69+
} as any,
70+
],
71+
},
72+
{
73+
type: "paragraph",
74+
content: [
75+
"I love ",
76+
{
77+
type: "tag",
78+
// props: {},
79+
content: "BlockNote",
80+
} as any,
81+
],
82+
},
83+
],
84+
});
85+
86+
// Give tests a way to get prosemirror instance
87+
(window as WindowWithProseMirror).ProseMirror = editor?._tiptapEditor;
88+
89+
return <BlockNoteView className="root" editor={editor} />;
90+
}
+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import "@blocknote/core/style.css";
2+
import {
3+
BlockNoteView,
4+
FormattingToolbarPositioner,
5+
Toolbar,
6+
ToolbarButton,
7+
createReactStyleSpec,
8+
useActiveStyles,
9+
useBlockNote,
10+
} from "@blocknote/react";
11+
12+
import {
13+
BlockNoteEditor,
14+
DefaultBlockSchema,
15+
DefaultInlineContentSchema,
16+
StyleSchemaFromSpecs,
17+
defaultStyleSpecs,
18+
} from "@blocknote/core";
19+
20+
type WindowWithProseMirror = Window & typeof globalThis & { ProseMirror: any };
21+
22+
const small = createReactStyleSpec(
23+
{
24+
type: "small",
25+
propSchema: "boolean",
26+
},
27+
{
28+
render: (props) => {
29+
return <small ref={props.contentRef}></small>;
30+
},
31+
}
32+
);
33+
34+
const fontSize = createReactStyleSpec(
35+
{
36+
type: "fontSize",
37+
propSchema: "string",
38+
},
39+
{
40+
render: (props) => {
41+
return (
42+
<span ref={props.contentRef} style={{ fontSize: props.value }}></span>
43+
);
44+
},
45+
}
46+
);
47+
48+
const customReactStyles = {
49+
...defaultStyleSpecs,
50+
small,
51+
fontSize,
52+
};
53+
54+
type MyEditorType = BlockNoteEditor<
55+
DefaultBlockSchema,
56+
DefaultInlineContentSchema,
57+
StyleSchemaFromSpecs<typeof customReactStyles>
58+
>;
59+
60+
const CustomFormattingToolbar = (props: { editor: MyEditorType }) => {
61+
const activeStyles = useActiveStyles(props.editor);
62+
63+
return (
64+
<Toolbar>
65+
<ToolbarButton
66+
mainTooltip={"small"}
67+
onClick={() => {
68+
props.editor.toggleStyles({
69+
small: true,
70+
});
71+
}}
72+
isSelected={activeStyles.small}>
73+
Small
74+
</ToolbarButton>
75+
<ToolbarButton
76+
mainTooltip={"font size"}
77+
onClick={() => {
78+
props.editor.toggleStyles({
79+
fontSize: "30px",
80+
});
81+
}}
82+
isSelected={!!activeStyles.fontSize}>
83+
Font size
84+
</ToolbarButton>
85+
</Toolbar>
86+
);
87+
};
88+
89+
export function ReactStyles() {
90+
const editor = useBlockNote(
91+
{
92+
styleSpecs: customReactStyles,
93+
onEditorContentChange: (editor) => {
94+
console.log(editor.topLevelBlocks);
95+
},
96+
domAttributes: {
97+
editor: {
98+
class: "editor",
99+
"data-test": "editor",
100+
},
101+
},
102+
initialContent: [
103+
{
104+
type: "paragraph",
105+
content: [
106+
{
107+
type: "text",
108+
text: "large text",
109+
styles: {
110+
fontSize: "30px",
111+
},
112+
},
113+
{
114+
type: "text",
115+
text: "small text",
116+
styles: {
117+
small: true,
118+
},
119+
},
120+
],
121+
},
122+
],
123+
},
124+
[]
125+
);
126+
127+
// Give tests a way to get prosemirror instance
128+
(window as WindowWithProseMirror).ProseMirror = editor?._tiptapEditor;
129+
130+
return (
131+
<BlockNoteView className="root" editor={editor}>
132+
<FormattingToolbarPositioner
133+
editor={editor}
134+
formattingToolbar={CustomFormattingToolbar}
135+
/>
136+
</BlockNoteView>
137+
);
138+
}

examples/editor/package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@
1111
"dependencies": {
1212
"@blocknote/core": "^0.9.6",
1313
"@blocknote/react": "^0.9.6",
14+
"@mantine/core": "^5.6.1",
1415
"react": "^18.2.0",
15-
"react-dom": "^18.2.0"
16+
"react-dom": "^18.2.0",
17+
"react-router-dom": "^6.20.0",
18+
"y-partykit": "^0.0.0-4c022c1",
19+
"yjs": "^13.6.10"
1620
},
1721
"devDependencies": {
1822
"@types/react": "^18.0.25",

examples/editor/src/App.css

+9
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,12 @@
22
margin: 0 calc((100% - 731px) / 2);
33
height: 100%;
44
}
5+
6+
body {
7+
margin: 0;
8+
}
9+
10+
.root {
11+
height: 100%;
12+
width: 100%;
13+
}

0 commit comments

Comments
 (0)