Skip to content

feat: tables #413

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 32 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f5e523a
fix table types
YousefED Nov 15, 2023
94a23de
add tablecontent
YousefED Nov 16, 2023
0567bc0
clean BNUpdateBlock
YousefED Nov 16, 2023
9b35854
add partial inline content
YousefED Nov 16, 2023
2a0d1a6
add contentNodeToTableContent
YousefED Nov 16, 2023
d5e6f2a
first draft of tablehandles
YousefED Nov 16, 2023
e86313a
implement table functions
YousefED Nov 16, 2023
37b308b
fix styles
YousefED Nov 17, 2023
f73c502
fix imports
YousefED Nov 17, 2023
2f458e3
create separate TableExtension
YousefED Nov 17, 2023
cfb326f
improve types
YousefED Nov 17, 2023
226320a
test some types
YousefED Nov 17, 2023
708d4e9
Fixed setting selection for table blocks
matthewlipski Nov 17, 2023
18d1970
Merge remote-tracking branch 'origin/feature/tables' into feature/tables
matthewlipski Nov 17, 2023
c18e6f3
Fixed backspace deleting table if at start of cell
matthewlipski Nov 17, 2023
0c9f620
small code fixes
YousefED Nov 20, 2023
0cadfd0
Implemented PR feedback
matthewlipski Nov 20, 2023
36ad319
Merge remote-tracking branch 'origin/feature/tables' into feature/tables
matthewlipski Nov 20, 2023
d9ac4d1
Improved table row/column drag & drop UX
matthewlipski Nov 22, 2023
a2685e9
Fixed table menus moving around, drag indicator flakiness, menu z-ind…
matthewlipski Nov 23, 2023
da01f40
Implemented PR feedback
matthewlipski Nov 23, 2023
77766cd
Implemented PR feedback
matthewlipski Nov 23, 2023
5c1123e
Fixed drag handles sometimes not showing
matthewlipski Nov 24, 2023
f5dfe73
Fixed scrolling behaviour
matthewlipski Nov 24, 2023
1a1385c
Small fixes
matthewlipski Nov 24, 2023
2ac6722
Fixed table handles UI
matthewlipski Nov 24, 2023
79e1d1c
Fixed remaining UX/UI issues
matthewlipski Nov 27, 2023
47fd63e
Removed redundant state from table handles plugin
matthewlipski Nov 27, 2023
bd8b3be
Implemented table drag & drop logic
matthewlipski Nov 27, 2023
d6902f3
Added table enter handling
matthewlipski Nov 27, 2023
f5b4a0d
Small fix
matthewlipski Nov 27, 2023
6ef5ea1
feat: custom styles and custom inline content (#418)
YousefED Nov 29, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
// import logo from './logo.svg'
import "@blocknote/core/style.css";
import { BlockNoteView, useBlockNote } from "@blocknote/react";
import "./App.css";

import { uploadToTmpFilesDotOrg_DEV_ONLY } from "@blocknote/core";

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

function App() {
export function App() {
const editor = useBlockNote({
onEditorContentChange: (editor) => {
console.log(editor.topLevelBlocks);
},
domAttributes: {
editor: {
class: "editor",
Expand All @@ -23,7 +19,7 @@ function App() {
// Give tests a way to get prosemirror instance
(window as WindowWithProseMirror).ProseMirror = editor?._tiptapEditor;

return <BlockNoteView editor={editor} />;
return <BlockNoteView className="root" editor={editor} />;
}

export default App;
48 changes: 48 additions & 0 deletions examples/editor/examples/Collaboration.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import "@blocknote/core/style.css";
import { BlockNoteView, useBlockNote } from "@blocknote/react";

import { uploadToTmpFilesDotOrg_DEV_ONLY } from "@blocknote/core";

import YPartyKitProvider from "y-partykit/provider";
import * as Y from "yjs";

const doc = new Y.Doc();

const provider = new YPartyKitProvider(
"blocknote-dev.yousefed.partykit.dev",
// use a unique name as a "room" for your application:
"your-project-name",
doc
);

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

export function App() {
const editor = useBlockNote({
domAttributes: {
editor: {
class: "editor",
"data-test": "editor",
},
},
collaboration: {
// The Yjs Provider responsible for transporting updates:
provider,
// Where to store BlockNote data in the Y.Doc:
fragment: doc.getXmlFragment("document-storesss"),
// Information (name and color) for this user:
user: {
name: "My Username",
color: "#ff0000",
},
},
uploadFile: uploadToTmpFilesDotOrg_DEV_ONLY,
});

// Give tests a way to get prosemirror instance
(window as WindowWithProseMirror).ProseMirror = editor?._tiptapEditor;

return <BlockNoteView className="root" editor={editor} />;
}

export default App;
90 changes: 90 additions & 0 deletions examples/editor/examples/ReactInlineContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { defaultInlineContentSpecs } from "@blocknote/core";
import "@blocknote/core/style.css";
import {
BlockNoteView,
createReactInlineContentSpec,
useBlockNote,
} from "@blocknote/react";

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

const mention = createReactInlineContentSpec(
{
type: "mention",
propSchema: {
user: {
default: "",
},
},
content: "none",
},
{
render: (props) => {
return <span>@{props.inlineContent.props.user}</span>;
},
}
);

const tag = createReactInlineContentSpec(
{
type: "tag",
propSchema: {},
content: "styled",
},
{
render: (props) => {
return (
<span>
#<span ref={props.contentRef}></span>
</span>
);
},
}
);

export function ReactInlineContent() {
const editor = useBlockNote({
inlineContentSpecs: {
mention,
tag,
...defaultInlineContentSpecs,
},
domAttributes: {
editor: {
class: "editor",
"data-test": "editor",
},
},
initialContent: [
{
type: "paragraph",
content: [
"I enjoy working with ",
{
type: "mention",
props: {
user: "Matthew",
},
content: undefined,
} as any,
],
},
{
type: "paragraph",
content: [
"I love ",
{
type: "tag",
// props: {},
content: "BlockNote",
} as any,
],
},
],
});

// Give tests a way to get prosemirror instance
(window as WindowWithProseMirror).ProseMirror = editor?._tiptapEditor;

return <BlockNoteView className="root" editor={editor} />;
}
138 changes: 138 additions & 0 deletions examples/editor/examples/ReactStyles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import "@blocknote/core/style.css";
import {
BlockNoteView,
FormattingToolbarPositioner,
Toolbar,
ToolbarButton,
createReactStyleSpec,
useActiveStyles,
useBlockNote,
} from "@blocknote/react";

import {
BlockNoteEditor,
DefaultBlockSchema,
DefaultInlineContentSchema,
StyleSchemaFromSpecs,
defaultStyleSpecs,
} from "@blocknote/core";

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

const small = createReactStyleSpec(
{
type: "small",
propSchema: "boolean",
},
{
render: (props) => {
return <small ref={props.contentRef}></small>;
},
}
);

const fontSize = createReactStyleSpec(
{
type: "fontSize",
propSchema: "string",
},
{
render: (props) => {
return (
<span ref={props.contentRef} style={{ fontSize: props.value }}></span>
);
},
}
);

const customReactStyles = {
...defaultStyleSpecs,
small,
fontSize,
};

type MyEditorType = BlockNoteEditor<
DefaultBlockSchema,
DefaultInlineContentSchema,
StyleSchemaFromSpecs<typeof customReactStyles>
>;

const CustomFormattingToolbar = (props: { editor: MyEditorType }) => {
const activeStyles = useActiveStyles(props.editor);

return (
<Toolbar>
<ToolbarButton
mainTooltip={"small"}
onClick={() => {
props.editor.toggleStyles({
small: true,
});
}}
isSelected={activeStyles.small}>
Small
</ToolbarButton>
<ToolbarButton
mainTooltip={"font size"}
onClick={() => {
props.editor.toggleStyles({
fontSize: "30px",
});
}}
isSelected={!!activeStyles.fontSize}>
Font size
</ToolbarButton>
</Toolbar>
);
};

export function ReactStyles() {
const editor = useBlockNote(
{
styleSpecs: customReactStyles,
onEditorContentChange: (editor) => {
console.log(editor.topLevelBlocks);
},
domAttributes: {
editor: {
class: "editor",
"data-test": "editor",
},
},
initialContent: [
{
type: "paragraph",
content: [
{
type: "text",
text: "large text",
styles: {
fontSize: "30px",
},
},
{
type: "text",
text: "small text",
styles: {
small: true,
},
},
],
},
],
},
[]
);

// Give tests a way to get prosemirror instance
(window as WindowWithProseMirror).ProseMirror = editor?._tiptapEditor;

return (
<BlockNoteView className="root" editor={editor}>
<FormattingToolbarPositioner
editor={editor}
formattingToolbar={CustomFormattingToolbar}
/>
</BlockNoteView>
);
}
6 changes: 5 additions & 1 deletion examples/editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@
"dependencies": {
"@blocknote/core": "^0.9.6",
"@blocknote/react": "^0.9.6",
"@mantine/core": "^5.6.1",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-dom": "^18.2.0",
"react-router-dom": "^6.20.0",
"y-partykit": "^0.0.0-4c022c1",
"yjs": "^13.6.10"
},
"devDependencies": {
"@types/react": "^18.0.25",
Expand Down
9 changes: 9 additions & 0 deletions examples/editor/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,12 @@
margin: 0 calc((100% - 731px) / 2);
height: 100%;
}

body {
margin: 0;
}

.root {
height: 100%;
width: 100%;
}
Loading