Skip to content

Commit 93e1d4f

Browse files
matthewlipskiYousefEDCTNicholas
authored
refactor: Mentions & custom suggestion menus (#534)
* fix: Docs home page demo styling fix (#507) * Fixed styling for code styles (#517) * Made suggestions plugin control multiple menus * Added hook to create suggestion menu * Fixed add block button behaviour on blocks with different content (#526) * Small CSS fix (#527) * fix: List item shortcuts (#528) * Fixed list item shortcuts * Updated test screenshots * Added code toggle formatting toolbar example (#531) * fix: Errors when hovering image block while editor is uneditable (#533) * Fixed errors when hovering image block while editor is uneditable * Small fix * fix: Formatting toolbar not hiding while dragging blocks (#529) * Fixed formatting toolbar not hiding while dragging blocks * Small fix * Updated Mantine (#535) * Updated `package-lock.json` (#536) * v0.11.1 * v0.6.2 * v0.8.1 * v0.8.2 * v0.8.3 * v0.8.4 * v0.8.5 * v0.9.0 * v0.9.1 * Revert "v0.9.1" This reverts commit 6e9d61f. * v0.9.1 * Revert "v0.9.1" This reverts commit ac7abee. * v0.9.2 * v0.9.3 * v0.9.4 * v0.9.5 * v0.9.6 * v0.10.0 * v0.10.1 * v0.11.0 * v0.11.1 * fix collaboration and editable: false bug (#538) * pair refactoring * wip * fix type annotations on some of the docs (#539) * Cleanup and continue refactor * docs: Dark mode styling fix (#548) * Fixed styles that were overwritten by Mantine globals * Removed old code * Implemented PR feedback * Add Liveblocks info and BlockNote download command (#540) * Update real-time-collaboration.md * feat: Example image * feat: Replace image with video * Fixed video --------- Co-authored-by: Matthew Lipski <[email protected]> * Implemented PR feedback * fix: Mantine styles (#553) * Updated Mantine and package-lock * Added Mantine global styles reset * Made Mantine global styles not get imported * Fixed CSS import order * Updated test & snapshots * Implemented PR feedback * Implemented PR feedback * Fixed paragraph shortcut (#556) * v0.11.2 * Fixed build issues * Fixed add block button behaviour * Small fix * Small fix * Fixed tests --------- Co-authored-by: Yousef <[email protected]> Co-authored-by: Chris Nicholas <[email protected]>
1 parent 03126c5 commit 93e1d4f

File tree

72 files changed

+3396
-2658
lines changed

Some content is hidden

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

72 files changed

+3396
-2658
lines changed

examples/editor/examples/basic/App.tsx

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,11 @@ import {
99
uploadToTmpFilesDotOrg_DEV_ONLY,
1010
} from "@blocknote/core";
1111
import {
12+
BlockNoteDefaultUI,
1213
BlockNoteView,
1314
createReactInlineContentSpec,
14-
DefaultSlashMenu,
15-
FormattingToolbarPositioner,
16-
HyperlinkToolbarPositioner,
17-
ImageToolbarPositioner,
18-
SideMenuPositioner,
19-
SlashMenuPositioner,
20-
SuggestionMenuPositioner,
21-
TableHandlesPositioner,
15+
DefaultPositionedSuggestionMenu,
16+
SuggestionMenuItemProps,
2217
useBlockNote,
2318
} from "@blocknote/react";
2419
import "@blocknote/react/style.css";
@@ -53,17 +48,23 @@ const customInlineContentSchema = {
5348
mention: MentionInlineContent.config,
5449
} satisfies InlineContentSchema;
5550

56-
async function getMentionMenuItems(query: string) {
51+
async function getMentionMenuItems(
52+
editor: BlockNoteEditor<
53+
DefaultBlockSchema,
54+
typeof customInlineContentSchema,
55+
DefaultStyleSchema
56+
>,
57+
query: string,
58+
closeMenu: () => void,
59+
clearQuery: () => void
60+
): Promise<SuggestionMenuItemProps[]> {
5761
const users = ["Steve", "Bob", "Joe", "Mike"];
58-
const items = users.map((user) => ({
62+
const items: SuggestionMenuItemProps[] = users.map((user) => ({
5963
name: user,
60-
execute: (
61-
editor: BlockNoteEditor<
62-
DefaultBlockSchema,
63-
typeof customInlineContentSchema,
64-
DefaultStyleSchema
65-
>
66-
) => {
64+
execute: () => {
65+
closeMenu();
66+
clearQuery();
67+
6768
editor._tiptapEditor.commands.insertContent({
6869
type: "mention",
6970
attrs: {
@@ -94,32 +95,21 @@ export function App() {
9495
},
9596
},
9697
uploadFile: uploadToTmpFilesDotOrg_DEV_ONLY,
97-
extraSuggestionMenus: [
98-
{
99-
name: "mentions",
100-
triggerCharacter: "@",
101-
getItems: getMentionMenuItems,
102-
},
103-
],
10498
});
10599

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

103+
// TODO: Figure out cleaner API for adding/changing/removing menus & toolbars
109104
return (
110105
<BlockNoteView className="root" editor={editor}>
111-
<FormattingToolbarPositioner editor={editor} />
112-
<HyperlinkToolbarPositioner editor={editor} />
113-
<SlashMenuPositioner editor={editor} />
114-
<SideMenuPositioner editor={editor} />
115-
<ImageToolbarPositioner editor={editor} />
116-
{editor.blockSchema.table && (
117-
<TableHandlesPositioner editor={editor as any} />
118-
)}
119-
<SuggestionMenuPositioner
120-
editor={editor as any}
121-
suggestionsMenuName={"mentions"}
122-
suggestionsMenuComponent={DefaultSlashMenu}
106+
<BlockNoteDefaultUI editor={editor} />
107+
<DefaultPositionedSuggestionMenu
108+
editor={editor}
109+
triggerCharacter={"@"}
110+
getItems={(query, closeMenu, clearQuery) =>
111+
getMentionMenuItems(editor, query, closeMenu, clearQuery)
112+
}
123113
/>
124114
</BlockNoteView>
125115
);

examples/editor/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@blocknote/example-editor",
33
"private": true,
4-
"version": "0.11.0",
4+
"version": "0.11.2",
55
"scripts": {
66
"dev": "vite",
77
"build": "tsc && vite build",
@@ -10,9 +10,9 @@
1010
"clean": "rimraf dist"
1111
},
1212
"dependencies": {
13-
"@blocknote/core": "^0.11.0",
14-
"@blocknote/react": "^0.11.0",
15-
"@mantine/core": "^7.3.1",
13+
"@blocknote/core": "^0.11.2",
14+
"@blocknote/react": "^0.11.2",
15+
"@mantine/core": "^7.4.2",
1616
"react": "^18.2.0",
1717
"react-dom": "^18.2.0",
1818
"react-router-dom": "^6.20.0",

examples/editor/src/main.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import {
88
createBrowserRouter,
99
} from "react-router-dom";
1010

11+
import "./style.css";
1112
import { App } from "../examples/basic/App";
1213
import { ReactCustomBlocks } from "../examples/react-custom-blocks/App";
1314
import { ReactInlineContent } from "../examples/react-custom-inline-content/App";
1415
import { ReactStyles } from "../examples/react-custom-styles/App";
1516
import { CustomBlocks } from "../examples/vanilla-custom-blocks/App";
1617
import { InlineContent } from "../examples/vanilla-custom-inline-content/App";
17-
import "./style.css";
1818

1919
window.React = React;
2020

examples/editor/src/style.css

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
body {
2-
height: auto;
3-
}
1+
@import url("@mantine/core/styles.css");
42

53
.editor {
64
margin: 8px calc((100% - 731px) / 2) 0;

examples/vanilla/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"name": "@blocknote/example-vanilla",
33
"private": true,
4-
"version": "0.11.0",
4+
"version": "0.11.2",
55
"scripts": {
66
"dev": "vite",
77
"build": "tsc && vite build",
88
"preview": "vite preview",
99
"lint": "eslint src --max-warnings 0"
1010
},
1111
"dependencies": {
12-
"@blocknote/core": "^0.11.0"
12+
"@blocknote/core": "^0.11.2"
1313
},
1414
"devDependencies": {
1515
"eslint": "^8.10.0",

examples/vanilla/src/ui/addSlashMenu.ts

Lines changed: 76 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,18 @@
1-
import {
2-
BlockNoteEditor,
3-
DefaultBlockSchema,
4-
DefaultInlineContentSchema,
5-
DefaultStyleSchema,
6-
SuggestionItem,
7-
} from "@blocknote/core";
1+
import { BlockNoteEditor } from "@blocknote/core";
82
import { createButton } from "./util";
93

104
export const addSlashMenu = async (editor: BlockNoteEditor) => {
115
let element: HTMLElement;
126

137
async function updateItems(
148
query: string,
15-
getItems: (
16-
query: string
17-
) => Promise<
18-
SuggestionItem<
19-
DefaultBlockSchema,
20-
DefaultInlineContentSchema,
21-
DefaultStyleSchema
22-
>[]
23-
>,
24-
onClick: (
25-
item: SuggestionItem<
26-
DefaultBlockSchema,
27-
DefaultInlineContentSchema,
28-
DefaultStyleSchema
29-
>
30-
) => void
9+
getItems: (query: string) => Promise<any[]>
3110
) {
3211
element.innerHTML = "";
3312
const items = await getItems(query);
34-
const domItems = items.map((val, i) => {
35-
const element = createButton(val.name, () => {
36-
onClick(val);
13+
const domItems = items.map((val) => {
14+
const element = createButton(val.text, () => {
15+
val.executeItem();
3716
});
3817
element.style.display = "block";
3918
return element;
@@ -42,7 +21,7 @@ export const addSlashMenu = async (editor: BlockNoteEditor) => {
4221
return domItems;
4322
}
4423

45-
editor.suggestionMenus.slashMenu.onUpdate(async (slashMenuState) => {
24+
editor.suggestionMenus.onUpdate("slashMenu", async (slashMenuState) => {
4625
if (!element) {
4726
element = document.createElement("div");
4827
element.style.background = "gray";
@@ -55,11 +34,76 @@ export const addSlashMenu = async (editor: BlockNoteEditor) => {
5534
}
5635

5736
if (slashMenuState.show) {
58-
await updateItems(
59-
slashMenuState.query,
60-
editor.suggestionMenus.slashMenu.getItems,
61-
editor.suggestionMenus.slashMenu.executeItem
62-
);
37+
// TODO: Default vanilla getItems data type?
38+
const getItems = async (query: string) => {
39+
const items = [
40+
{
41+
text: "Heading",
42+
aliases: ["h", "heading1", "h1"],
43+
executeItem: () => {
44+
editor.suggestionMenus.closeMenu();
45+
editor.suggestionMenus.clearQuery();
46+
47+
editor.insertBlocks(
48+
[
49+
{
50+
type: "heading",
51+
},
52+
],
53+
editor.getTextCursorPosition().block,
54+
"after"
55+
);
56+
},
57+
},
58+
{
59+
text: "List",
60+
aliases: ["ul", "li", "list", "bulletlist", "bullet list"],
61+
executeItem: () => {
62+
editor.suggestionMenus.closeMenu();
63+
editor.suggestionMenus.clearQuery();
64+
65+
editor.insertBlocks(
66+
[
67+
{
68+
type: "bulletListItem",
69+
},
70+
],
71+
editor.getTextCursorPosition().block,
72+
"after"
73+
);
74+
},
75+
},
76+
{
77+
text: "Paragraph",
78+
aliases: ["p", "paragraph"],
79+
executeItem: () => {
80+
editor.suggestionMenus.closeMenu();
81+
editor.suggestionMenus.clearQuery();
82+
83+
editor.insertBlocks(
84+
[
85+
{
86+
type: "paragraph",
87+
},
88+
],
89+
editor.getTextCursorPosition().block,
90+
"after"
91+
);
92+
},
93+
},
94+
];
95+
96+
return items.filter(
97+
({ text, aliases }) =>
98+
text.toLowerCase().startsWith(query.toLowerCase()) ||
99+
(aliases &&
100+
aliases.filter((alias) =>
101+
alias.toLowerCase().startsWith(query.toLowerCase())
102+
).length !== 0)
103+
);
104+
};
105+
106+
await updateItems(slashMenuState.query, getItems);
63107

64108
element.style.display = "block";
65109

lerna.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
33
"useNx": false,
44
"useWorkspaces": true,
5-
"version": "0.11.0"
5+
"version": "0.11.2"
66
}

0 commit comments

Comments
 (0)