Skip to content

feature: Column based layouts #1154

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 99 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
51f4216
extract updateBlockCommand
YousefED Oct 8, 2024
18ff213
Extracted remaining commands
matthewlipski Oct 8, 2024
de6f1ec
extract keyboard shortcuts
YousefED Oct 8, 2024
c3cea79
move directory
YousefED Oct 8, 2024
717301e
remove createblockcommand
YousefED Oct 8, 2024
9c32c92
Added merge/split tests
matthewlipski Oct 8, 2024
3fe50d5
Updated snapshots
matthewlipski Oct 9, 2024
6a0fda3
Added update block tests and unified test setup
matthewlipski Oct 9, 2024
df6dccc
Added test cases for reverting props
matthewlipski Oct 9, 2024
d4f206d
Added additional test cases for changing content type
matthewlipski Oct 9, 2024
5ac23d9
remove "nested" insert option
YousefED Oct 9, 2024
fc0010b
Split remaining commands & cleaned up
matthewlipski Oct 9, 2024
e392637
Added `getNearestBlockContainerPos`
matthewlipski Oct 10, 2024
5dd4afd
Refactored `getBlockInfoFromPos`
matthewlipski Oct 10, 2024
58016a9
Rewrote `splitBlockCommand`
matthewlipski Oct 12, 2024
6bcd81d
Added text cursor position tests
matthewlipski Oct 12, 2024
ab18dd4
Fixed lint issue
matthewlipski Oct 12, 2024
968b6fc
fix lint
YousefED Oct 13, 2024
89a86fb
Fixed `splitBlock` selection
matthewlipski Oct 14, 2024
adb0907
Merge remote-tracking branch 'origin/refactor/clean-blockcontainer' i…
matthewlipski Oct 14, 2024
ba11dd2
Small fix
matthewlipski Oct 14, 2024
dd572c3
Added unit tests to check selection setting
matthewlipski Oct 14, 2024
74a0cda
simplify splitblocks
YousefED Oct 14, 2024
690ec6a
Merge branch 'refactor/clean-blockcontainer' of github.com:TypeCellOS…
YousefED Oct 14, 2024
f57b0eb
Fixed selection in `splitBlock` tests
matthewlipski Oct 14, 2024
1236476
wip: deprecate getBlockInfoFromPos
YousefED Oct 14, 2024
7b17ded
finish cleanup
YousefED Oct 14, 2024
bf4635e
Fixed `mergeBlocks` edge cases
matthewlipski Oct 14, 2024
3f73033
fix build
YousefED Oct 15, 2024
0a50308
Merge branch 'refactor/clean-blockcontainer' of github.com:TypeCellOS…
YousefED Oct 15, 2024
9ae58f6
clean nodeconversions
YousefED Oct 15, 2024
0b53241
update prosemirror-model
YousefED Oct 15, 2024
df73af7
basics wip
YousefED Oct 15, 2024
80c8b46
Implemented PR feedback
matthewlipski Oct 15, 2024
15c821f
basics working
YousefED Oct 15, 2024
353e36d
fix tabs
YousefED Oct 15, 2024
1414e14
Finished review and remaining changes
matthewlipski Oct 15, 2024
9fe93fd
separate package
YousefED Oct 15, 2024
f627732
Fixed bug in `insertOrUpdateBlock`
matthewlipski Oct 15, 2024
3d09350
Removed log
matthewlipski Oct 15, 2024
429f571
update architecture
YousefED Oct 15, 2024
704d6b9
fix build
YousefED Oct 15, 2024
1e1f7c3
wip, play with transition style of sidemenu
YousefED Oct 16, 2024
1ffbb71
show sidemenu for blocks inside columns
YousefED Oct 16, 2024
90085b5
fix sidemenu
YousefED Oct 16, 2024
a6747fe
small fixes
YousefED Oct 16, 2024
3d0e80e
Tiny changes
matthewlipski Oct 16, 2024
cb1e705
Merge pull request #1151 from TypeCellOS/refactor/clean-blockcontaine…
matthewlipski Oct 16, 2024
ab902c9
Fixed merge/delete behaviour on Backspace
matthewlipski Oct 17, 2024
959a8b8
Merge remote-tracking branch 'origin/refactor/clean-blockcontainer-cl…
YousefED Oct 29, 2024
eda61f3
Merge remote-tracking branch 'origin/refactor/clean-blockcontainer' i…
YousefED Oct 29, 2024
e5e05eb
cherry pick squash commit
YousefED Oct 17, 2024
47724e8
update prosemirror-model
YousefED Oct 15, 2024
4886506
basics wip
YousefED Oct 15, 2024
e8c28b5
basics working
YousefED Oct 15, 2024
04722b1
fix tabs
YousefED Oct 15, 2024
4123c14
separate package
YousefED Oct 15, 2024
2f0f3a9
update architecture
YousefED Oct 15, 2024
0968611
fix build
YousefED Oct 15, 2024
2d093ba
wip, play with transition style of sidemenu
YousefED Oct 16, 2024
4bc9344
show sidemenu for blocks inside columns
YousefED Oct 16, 2024
21680c4
fix sidemenu
YousefED Oct 16, 2024
3d536b3
small fixes
YousefED Oct 16, 2024
3b62830
cherry pick squash commit
YousefED Oct 17, 2024
b495dc3
Merge branch 'feature/multi-column' of github.com:TypeCellOS/BlockNot…
YousefED Oct 29, 2024
c2c63e8
fix
YousefED Oct 29, 2024
12c6b87
remove blockAtDocStart and clean mergeBlocks a bit further
YousefED Oct 30, 2024
166d2a8
Merge branch 'main' into feature/multi-column
YousefED Oct 30, 2024
84026c8
implement multi-column backspace
YousefED Oct 31, 2024
314c315
feat: Multi-column resizing (#1186)
matthewlipski Nov 1, 2024
4727c20
Implemented PR feedback
matthewlipski Nov 1, 2024
f3d6433
Implemented PR feedback
matthewlipski Nov 1, 2024
09a6758
Fixed column list styles and `nestBlock`
matthewlipski Nov 1, 2024
6dad736
Added column slash menu items
matthewlipski Nov 1, 2024
99cf5eb
Added unit tests for multi column
matthewlipski Nov 4, 2024
670a35b
Added unit tests for node & html conversions
matthewlipski Nov 4, 2024
efe7cc1
Updated snapshots
matthewlipski Nov 4, 2024
a89c1c8
fix internal serializer for bnBlock types
YousefED Nov 5, 2024
1c807f0
remove md from license
YousefED Nov 5, 2024
407d235
fix trailing node
YousefED Nov 5, 2024
903a0ba
fix bug
YousefED Nov 5, 2024
d6d63a8
switch to createChecked and fix multicolumn tests
YousefED Nov 5, 2024
d71b926
fix external html for multi-column
YousefED Nov 5, 2024
6a2dc94
fix text/html on clipboard
YousefED Nov 5, 2024
6741958
improve copy / paste
YousefED Nov 5, 2024
097fbe2
remove unused snapshots and skip one test
YousefED Nov 5, 2024
de481d0
fix text cursor
YousefED Nov 5, 2024
59dbe07
Fixed internationalization
matthewlipski Nov 5, 2024
565d190
remove scrollbar
YousefED Nov 5, 2024
d7c4238
Merge remote-tracking branch 'origin/feature/multi-column' into featu…
matthewlipski Nov 5, 2024
9e804e2
fix dictionary as any
YousefED Nov 5, 2024
a625cbb
combineByGroup
YousefED Nov 5, 2024
3d71d1e
clean examples
YousefED Nov 5, 2024
0e2ab1c
Fixed slash menu item cursor positioning
matthewlipski Nov 5, 2024
8e24bb2
move package
YousefED Nov 5, 2024
e7016ca
Merge branch 'feature/multi-column' of github.com:TypeCellOS/BlockNot…
YousefED Nov 5, 2024
18311f3
Fixed type
matthewlipski Nov 5, 2024
e944e5a
Updated docs
matthewlipski Nov 5, 2024
9fb3d71
remove as any
YousefED Nov 5, 2024
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
11 changes: 10 additions & 1 deletion docs/components/pages/landing/hero/DemoEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { uploadToTmpFilesDotOrg_DEV_ONLY } from "@blocknote/core";
import {
BlockNoteSchema,
uploadToTmpFilesDotOrg_DEV_ONLY,
} from "@blocknote/core";
import "@blocknote/core/fonts/inter.css";
import { useCreateBlockNote } from "@blocknote/react";
import { BlockNoteView } from "@blocknote/mantine";
import {
multiColumnDropCursor,
withMultiColumn,
} from "@blocknote/xl-multi-column";
import "@blocknote/mantine/style.css";
import { useCallback, useMemo, useState } from "react";
import YPartyKitProvider from "y-partykit/provider";
Expand Down Expand Up @@ -67,6 +74,8 @@ export default function DemoEditor(props: { theme?: "light" | "dark" }) {

const editor = useCreateBlockNote(
{
schema: withMultiColumn(BlockNoteSchema.create()),
dropCursor: multiColumnDropCursor,
collaboration: {
provider,
fragment: doc.getXmlFragment("blocknote"),
Expand Down
1 change: 1 addition & 0 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@blocknote/mantine": "^0.18.1",
"@blocknote/react": "^0.18.1",
"@blocknote/shadcn": "^0.18.1",
"@blocknote/xl-multi-column": "^0.18.1",
"@headlessui/react": "^1.7.18",
"@heroicons/react": "^2.1.4",
"@mantine/core": "^7.10.1",
Expand Down
28 changes: 28 additions & 0 deletions docs/pages/docs/editor-basics/document-structure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,34 @@ type Block = {

`children:` Any blocks nested inside the block. The nested blocks are also represented using `Block` objects.

### Column Blocks

The `@blocknote/xl-multi-column` package allows you to organize blocks side-by-side in columns. It introduces 2 additional block types, the column and column list:

```typescript
type ColumnBlock = {
id: string;
type: "column";
props: { width: number };
content: undefined;
children: Block[];
};

type ColumnListBlock = {
id: string;
type: "columnList";
props: {};
content: undefined;
children: ColumnBlock[];
};
```

While both of these act as regular blocks, there are a few additional restrictions to have in mind when working with them:

- Children of columns must be regular blocks
- Children of column lists must be columns
- There must be at least 2 columns in a column list

## Inline Content

The `content` field of a block contains the rich-text content of a block. This is defined as an array of `InlineContent` objects. Inline content can either be styled text or a link (or a custom inline content type if you customize the editor schema).
Expand Down
6 changes: 0 additions & 6 deletions examples/01-basic/03-all-blocks/.bnexample.json

This file was deleted.

9 changes: 9 additions & 0 deletions examples/01-basic/03-multi-column/.bnexample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"playground": true,
"docs": true,
"author": "yousefed",
"tags": ["Basic", "Blocks"],
"dependencies": {
"@blocknote/xl-multi-column": "latest"
}
}
118 changes: 118 additions & 0 deletions examples/01-basic/03-multi-column/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import {
BlockNoteSchema,
combineByGroup,
filterSuggestionItems,
locales,
} from "@blocknote/core";
import "@blocknote/core/fonts/inter.css";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import {
SuggestionMenuController,
getDefaultReactSlashMenuItems,
useCreateBlockNote,
} from "@blocknote/react";
import {
getMultiColumnSlashMenuItems,
multiColumnDropCursor,
locales as multiColumnLocales,
withMultiColumn,
} from "@blocknote/xl-multi-column";
import { useMemo } from "react";
export default function App() {
// Creates a new editor instance.
const editor = useCreateBlockNote({
// Adds column and column list blocks to the schema.
schema: withMultiColumn(BlockNoteSchema.create()),
// The default drop cursor only shows up above and below blocks - we replace
// it with the multi-column one that also shows up on the sides of blocks.
dropCursor: multiColumnDropCursor,
// Merges the default dictionary with the multi-column dictionary.
dictionary: {
...locales.en,
multi_column: multiColumnLocales.en,
},
initialContent: [
{
type: "paragraph",
content: "Welcome to this demo!",
},
{
type: "columnList",
children: [
{
type: "column",
props: {
width: 0.8,
},
children: [
{
type: "paragraph",
content: "This paragraph is in a column!",
},
],
},
{
type: "column",
props: {
width: 1.4,
},
children: [
{
type: "heading",
content: "So is this heading!",
},
],
},
{
type: "column",
props: {
width: 0.8,
},
children: [
{
type: "paragraph",
content: "You can have multiple blocks in a column too",
},
{
type: "bulletListItem",
content: "Block 1",
},
{
type: "bulletListItem",
content: "Block 2",
},
{
type: "bulletListItem",
content: "Block 3",
},
],
},
],
},
{
type: "paragraph",
},
],
});

// Merges the default slash menu items with the multi-column ones.
const slashMenuItems = useMemo(() => {
return combineByGroup(
getDefaultReactSlashMenuItems(editor),
getMultiColumnSlashMenuItems(editor)
);
}, [editor]);

// Renders the editor instance using a React component.
return (
<BlockNoteView editor={editor} slashMenu={false}>
{/* Replaces the default slash menu with one that has both the default
items and the multi-column ones. */}
<SuggestionMenuController
triggerCharacter={"/"}
getItems={async (query) => filterSuggestionItems(slashMenuItems, query)}
/>
</BlockNoteView>
);
}
8 changes: 8 additions & 0 deletions examples/01-basic/03-multi-column/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Multi-Column Blocks

This example showcases multi-column blocks, allowing you to stack blocks next to each other. These come as part of the `@blocknote/xl-multi-column` package.

**Relevant Docs:**

- [Editor Setup](/docs/editor-basics/setup)
- [Document Structure](/docs/editor-basics/document-structure)
14 changes: 14 additions & 0 deletions examples/01-basic/03-multi-column/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<html lang="en">
<head>
<script>
<!-- AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY -->
</script>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Multi-Column Blocks</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
</html>
38 changes: 38 additions & 0 deletions examples/01-basic/03-multi-column/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@blocknote/example-multi-column",
"description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
"private": true,
"version": "0.12.4",
"scripts": {
"start": "vite",
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"lint": "eslint . --max-warnings 0"
},
"dependencies": {
"@blocknote/core": "latest",
"@blocknote/react": "latest",
"@blocknote/ariakit": "latest",
"@blocknote/mantine": "latest",
"@blocknote/shadcn": "latest",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"@blocknote/xl-multi-column": "latest"
},
"devDependencies": {
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.9",
"@vitejs/plugin-react": "^4.3.1",
"eslint": "^8.10.0",
"vite": "^5.3.4"
},
"eslintConfig": {
"extends": [
"../../../.eslintrc.js"
]
},
"eslintIgnore": [
"dist"
]
}
9 changes: 9 additions & 0 deletions examples/01-basic/04-all-blocks/.bnexample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"playground": true,
"docs": true,
"author": "yousefed",
"tags": ["Basic", "Blocks", "Inline Content"],
"dependencies": {
"@blocknote/xl-multi-column": "latest"
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,33 @@
import {
BlockNoteSchema,
combineByGroup,
filterSuggestionItems,
locales,
} from "@blocknote/core";
import "@blocknote/core/fonts/inter.css";
import { useCreateBlockNote } from "@blocknote/react";
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";

import {
SuggestionMenuController,
getDefaultReactSlashMenuItems,
useCreateBlockNote,
} from "@blocknote/react";
import {
getMultiColumnSlashMenuItems,
multiColumnDropCursor,
locales as multiColumnLocales,
withMultiColumn,
} from "@blocknote/xl-multi-column";
import { useMemo } from "react";
export default function App() {
// Creates a new editor instance.
const editor = useCreateBlockNote({
schema: withMultiColumn(BlockNoteSchema.create()),
dropCursor: multiColumnDropCursor,
dictionary: {
...locales.en,
multi_column: multiColumnLocales.en,
},
initialContent: [
{
type: "paragraph",
Expand All @@ -28,6 +50,35 @@ export default function App() {
type: "paragraph",
content: "Paragraph",
},
{
type: "columnList",
children: [
{
type: "column",
props: {
width: 0.8,
},
children: [
{
type: "paragraph",
content: "Hello to the left!",
},
],
},
{
type: "column",
props: {
width: 1.2,
},
children: [
{
type: "paragraph",
content: "Hello to the right!",
},
],
},
],
},
{
type: "heading",
content: "Heading",
Expand Down Expand Up @@ -137,6 +188,20 @@ export default function App() {
],
});

const slashMenuItems = useMemo(() => {
return combineByGroup(
getDefaultReactSlashMenuItems(editor),
getMultiColumnSlashMenuItems(editor)
);
}, [editor]);

// Renders the editor instance using a React component.
return <BlockNoteView editor={editor} />;
return (
<BlockNoteView editor={editor} slashMenu={false}>
<SuggestionMenuController
triggerCharacter={"/"}
getItems={async (query) => filterSuggestionItems(slashMenuItems, query)}
/>
</BlockNoteView>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ This example showcases each block and inline content type in BlockNote's default

**Relevant Docs:**

- [Editor Setup](/docs/editor-basics/setup)
- [Document Structure](/docs/editor-basics/document-structure)
- [Default Schema](/docs/editor-basics/default-schema)
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"@blocknote/mantine": "latest",
"@blocknote/shadcn": "latest",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react-dom": "^18.3.1",
"@blocknote/xl-multi-column": "latest"
},
"devDependencies": {
"@types/react": "^18.0.25",
Expand Down
Loading
Loading