Skip to content

feat: Threads sidebar #1454

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 174 commits into from
Mar 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
174 commits
Select commit Hold shift + click to select a range
4d6e252
wip: better liveblocks support
YousefED Nov 14, 2024
dcd7c72
Merge remote-tracking branch 'origin/main' into feature/liveblocks-v2
YousefED Nov 18, 2024
c659253
misc fixes
YousefED Nov 18, 2024
a03d33f
misc
YousefED Nov 19, 2024
85521df
revert minimal
YousefED Nov 19, 2024
e43741a
simplify setup
YousefED Nov 20, 2024
e0c7f0f
update config
YousefED Nov 20, 2024
d747238
fix
YousefED Nov 20, 2024
6ce69ea
fix
YousefED Nov 20, 2024
a3028c1
markview
YousefED Dec 14, 2024
15c7520
cleanup
YousefED Dec 14, 2024
b8a8d49
Merge remote-tracking branch 'origin/main' into feature/liveblocks-v2
YousefED Jan 8, 2025
1b44296
wip
YousefED Jan 10, 2025
23275a0
wip
YousefED Jan 13, 2025
721a4e9
wip
YousefED Jan 14, 2025
e824c42
wip
YousefED Jan 15, 2025
f2d4bb8
misc
YousefED Jan 16, 2025
434eafa
add threadstore tests
YousefED Jan 16, 2025
9d35f72
document recommended auth rules
YousefED Jan 16, 2025
58ed7c0
resolve
YousefED Jan 16, 2025
b761e1e
basic userstore impl
YousefED Jan 16, 2025
5f52147
user auth
YousefED Jan 16, 2025
060708d
Big comments UX WIP
matthewlipski Jan 24, 2025
5c6f45b
Merge branch 'main' into feature/comments
matthewlipski Jan 28, 2025
16c6a7a
Merge branch 'main' into feature/comments
matthewlipski Jan 28, 2025
a5e07c0
Updated reactions UX
matthewlipski Jan 28, 2025
b42047f
change reaction implementation
YousefED Feb 10, 2025
43a1eb0
reactions improvements
YousefED Feb 10, 2025
306c335
small cleanup
YousefED Feb 10, 2025
99d9d21
cleanups + mark some todos
YousefED Feb 10, 2025
4501af4
comments
YousefED Feb 11, 2025
eadb49d
fix locales
YousefED Feb 11, 2025
b81bab0
Merge remote-tracking branch 'upstream/main' into feature/comments
YousefED Feb 11, 2025
9f40651
fix build
YousefED Feb 11, 2025
7ae2b7f
cleanup + sample
YousefED Feb 11, 2025
748a183
fix build
YousefED Feb 11, 2025
e93b53b
fix lint
YousefED Feb 11, 2025
be9dd46
disable liveblocks for now
YousefED Feb 11, 2025
3e93d1e
lint
YousefED Feb 11, 2025
40269a5
fix linkify warning + make toggle editable comment
YousefED Feb 11, 2025
62a8944
fix content reset bug
YousefED Feb 11, 2025
22fdde6
Implemented PR feedback
matthewlipski Feb 11, 2025
c293fdf
Merge remote-tracking branch 'origin/feature/comments' into feature/c…
matthewlipski Feb 11, 2025
c0d1bd5
fix placeholder
YousefED Feb 12, 2025
311881c
Merge branch 'feature/comments' of github.com:TypeCellOS/BlockNote in…
YousefED Feb 12, 2025
a71fc69
clean comment editor
YousefED Feb 12, 2025
4d498de
fix build
YousefED Feb 12, 2025
c5a6a0c
fix placeholders
YousefED Feb 12, 2025
3f7828d
- Adjusted comment spacing
matthewlipski Feb 13, 2025
d2c9f34
Implemented PR feedback
matthewlipski Feb 14, 2025
6df6886
fix build
YousefED Feb 14, 2025
5b7e3d4
implement TipTapThreadStore
YousefED Feb 14, 2025
3ef17e5
address feedback
YousefED Feb 14, 2025
db7d339
add comment
YousefED Feb 17, 2025
6067a2b
Merge remote-tracking branch 'origin/main' into feature/liveblocks-v2
YousefED Feb 17, 2025
298ba46
Merge branch 'feature/liveblocks-v2' into feature/comments
YousefED Feb 17, 2025
c007f84
wip
YousefED Feb 17, 2025
99c599c
Merge branch 'main' into feature/comments
YousefED Feb 18, 2025
c0c848a
add autofocus
YousefED Feb 18, 2025
9576cfe
Simplified tooltip + popover interaction
matthewlipski Feb 18, 2025
9fa9d07
wip
YousefED Feb 19, 2025
44b2dca
feat: ShadCN comments (#1445)
matthewlipski Feb 20, 2025
6c6b017
change reaction auth
YousefED Feb 20, 2025
97f1f0a
Merge branch 'feature/comments' of github.com:TypeCellOS/BlockNote in…
YousefED Feb 20, 2025
5decc46
make emoji optional
YousefED Feb 20, 2025
4cb7af0
fix bug
YousefED Feb 20, 2025
27a2523
Extracted reaction badge WIP
matthewlipski Feb 20, 2025
b27db16
Merge remote-tracking branch 'origin/feature/comments' into feature/c…
matthewlipski Feb 20, 2025
65dfc20
fix useUsers
YousefED Feb 20, 2025
2fe1052
Fixed formatting toolbar not showing up when editor is non-editable
matthewlipski Feb 20, 2025
e3291d0
Merge remote-tracking branch 'origin/feature/comments' into feature/c…
matthewlipski Feb 20, 2025
165a014
Fixed reaction badge tooltip line breaks and made leaving comment not…
matthewlipski Feb 20, 2025
d11053c
Merge remote-tracking branch 'origin/feature/comments' into feature/c…
YousefED Feb 20, 2025
807d8d1
Improved badge UX and made reactions hide when editing
matthewlipski Feb 20, 2025
3fada1a
wip
YousefED Feb 21, 2025
4d3d2ff
refactor: add renderEditor boolean to BlockNoteView
YousefED Feb 21, 2025
42cdbd1
Merge branch 'refactor/blocknoteview' into feature/comments-streamview
YousefED Feb 21, 2025
e3e5867
Fixed new comments sometimes not being selectable
matthewlipski Feb 21, 2025
bcd375d
fix unnecessary rerender
YousefED Feb 21, 2025
6bdbf15
remove unused files
YousefED Feb 21, 2025
ec26b30
Improved UX/UI
matthewlipski Feb 21, 2025
a2b9e30
Merge remote-tracking branch 'origin/feature/comments-streamview' int…
matthewlipski Feb 21, 2025
d0b3f39
rest thread store
YousefED Feb 22, 2025
cfd94eb
fix copy/paste
YousefED Feb 22, 2025
ac6a17c
add shift
YousefED Feb 22, 2025
f200646
add docs
YousefED Feb 22, 2025
7c0746e
Merge remote-tracking branch 'origin/main' into feature/comments
YousefED Feb 22, 2025
4d293ef
update docs
YousefED Feb 22, 2025
85f0f9f
Merge branch 'feature/comments' into feature/comments-streamview
YousefED Feb 22, 2025
f35a66a
revert liveblocks, will be separate PR
YousefED Feb 23, 2025
8d9d542
clean lockfile
YousefED Feb 23, 2025
0f1e019
fix some todos
YousefED Feb 23, 2025
490291f
adress number of comments
YousefED Feb 23, 2025
11d9ee6
address more comments
YousefED Feb 23, 2025
7d4b64e
address some comments
YousefED Feb 23, 2025
8ec3e50
clean commentsplugin
YousefED Feb 23, 2025
fa1e5a7
ForceSelectionVisible
YousefED Feb 23, 2025
f2f29e7
fix floatingcomposercontroller
YousefED Feb 23, 2025
e97985e
fix unit test
YousefED Feb 23, 2025
c7b1f85
Merge branch 'feature/comments' into feature/comments-streamview
YousefED Feb 23, 2025
a4a90b8
close threads on esc
YousefED Feb 23, 2025
df1d6a0
Merge remote-tracking branch 'origin/main' into feature/comments
YousefED Feb 23, 2025
7b128dc
remove debugger
YousefED Feb 23, 2025
9ae74bd
small fix
YousefED Feb 24, 2025
953aefa
Fixed badge styles on docs
matthewlipski Feb 25, 2025
46101a0
Fixed badge click handler
matthewlipski Feb 25, 2025
ab00b5d
Added remaining UX fixes from Mantine to Ariakit/ShadCN
matthewlipski Feb 25, 2025
38a670d
Externalized strings
matthewlipski Feb 26, 2025
8d8ebec
Small styling fix
matthewlipski Feb 26, 2025
6744b26
Merge branch 'main' into feature/comments
matthewlipski Feb 26, 2025
a7a5656
Small styling fix
matthewlipski Feb 26, 2025
ebfb4da
Fix lint
matthewlipski Feb 26, 2025
9944ca7
Fixed side menu regression issue
matthewlipski Feb 26, 2025
30003d7
Implemented PR feedback
matthewlipski Feb 27, 2025
f1557b1
Implemented PR feedback
matthewlipski Feb 27, 2025
a647ec3
Updated emoji picker screenshots
matthewlipski Feb 28, 2025
065c74d
Revert "Updated emoji picker screenshots"
matthewlipski Feb 28, 2025
f26edd3
Merge branch 'main' into feature/comments
matthewlipski Feb 28, 2025
ae534b4
Updated `package-lock.json`
matthewlipski Feb 28, 2025
9a12826
Merge branch 'main' into feature/comments
matthewlipski Feb 28, 2025
828d13e
Fixed `no` locale
matthewlipski Feb 28, 2025
46836e5
Updated `package-lock.json`
matthewlipski Feb 28, 2025
641a6b8
Added temp test pass
matthewlipski Feb 28, 2025
f13a43c
Merged main
matthewlipski Mar 3, 2025
c4a4819
Fixed merge issues
matthewlipski Mar 3, 2025
95da229
Merge branch 'feature/comments' into feature/comments-streamview
matthewlipski Mar 3, 2025
4313177
Fixed issues and build
matthewlipski Mar 3, 2025
290834e
Separated open and resolved comments
matthewlipski Mar 3, 2025
6f5575d
Merge branch 'main' into feature/comments-streamview
matthewlipski Mar 5, 2025
2b0dd0b
Small fixes
matthewlipski Mar 5, 2025
615b5cd
BlockNoteView changes and major UX improvements
matthewlipski Mar 5, 2025
8b3b0fc
Small user select change
matthewlipski Mar 5, 2025
f83207c
- Renamed `ThreadStreamView` to `ThreadsSidebar`
matthewlipski Mar 6, 2025
b5fb0e7
Small cleanup
matthewlipski Mar 6, 2025
1978fa9
Fix build and cleanup
matthewlipski Mar 6, 2025
0ead24d
Merge branch 'main' into feature/comments-streamview
matthewlipski Mar 6, 2025
1c987e2
`BlockNoteView` fix
matthewlipski Mar 6, 2025
b12de1a
WIP feedback TODOs
matthewlipski Mar 11, 2025
150251a
WIP feedback
matthewlipski Mar 11, 2025
8ea7ae2
Small fix
matthewlipski Mar 11, 2025
1c39781
Small fix
matthewlipski Mar 11, 2025
d706b60
WIP feedback
matthewlipski Mar 11, 2025
89eda3b
WIP feedback
matthewlipski Mar 11, 2025
1851f1c
WIP feedback
matthewlipski Mar 12, 2025
250f823
WIP feedback
matthewlipski Mar 12, 2025
502627b
Shrunk emoji picker
matthewlipski Mar 12, 2025
495b793
Fixed build
matthewlipski Mar 13, 2025
4890967
Fixed lint
matthewlipski Mar 13, 2025
f9e8bc2
Small styling fix
matthewlipski Mar 13, 2025
65a4c72
Fixed docs build
matthewlipski Mar 13, 2025
41b6177
Merge branch 'main' into feature/comments-streamview
matthewlipski Mar 13, 2025
d072e66
Updated `Thread` and `Comment` props + small changes
matthewlipski Mar 13, 2025
80bb337
Implemented PR feedback
matthewlipski Mar 13, 2025
e49a066
Merge branch 'main' into feature/comments-streamview
matthewlipski Mar 13, 2025
27a33da
Updated demo styles
matthewlipski Mar 13, 2025
a8d46ac
Added file name extensions to examples
matthewlipski Mar 13, 2025
49aa06b
Added docs & minor changes
matthewlipski Mar 17, 2025
8db2f1a
Fixed i18n
matthewlipski Mar 17, 2025
ef94c80
Styling changes
matthewlipski Mar 17, 2025
c532ac2
Fixed lint/build
matthewlipski Mar 17, 2025
5209c2d
improve commentplugin state
YousefED Mar 17, 2025
dc8c7f7
Merge branch 'feature/comments-streamview' of github.com:TypeCellOS/B…
YousefED Mar 17, 2025
184977a
clean threadssidebar and fix performance
YousefED Mar 17, 2025
d25fe2c
Implemented PR feedback
matthewlipski Mar 17, 2025
d4f7a09
Moved styles
matthewlipski Mar 18, 2025
ed07f0e
Reverted doc ID
matthewlipski Mar 18, 2025
9fe3cf5
Resolved remaining feedback
matthewlipski Mar 18, 2025
5c369c4
Small fix
matthewlipski Mar 18, 2025
a49d236
Fixed TODOs
matthewlipski Mar 18, 2025
eba834d
Small fix
matthewlipski Mar 18, 2025
35edf21
Implemented remaining TODO
matthewlipski Mar 18, 2025
f9d85a5
Implemented PR feedback
matthewlipski Mar 18, 2025
123e8e2
Small examples update
matthewlipski Mar 19, 2025
79e2f77
Small styling fix
matthewlipski Mar 19, 2025
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
34 changes: 29 additions & 5 deletions docs/pages/docs/collaboration/comments.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Learn how to enable comments in your BlockNote editor
imageTitle: Comments
---

import { Example } from "@/components/example";
import {Example} from "@/components/example";

# Comments

Expand Down Expand Up @@ -33,7 +33,7 @@ const editor = useCreateBlockNote({

**Demo**

<Example name="collaboration/comments" />
<Example name="collaboration/comments"/>

## ThreadStores

Expand Down Expand Up @@ -63,7 +63,10 @@ The `RESTYjsThreadStore` combines Yjs storage with a REST API backend, providing
In this implementation, data is written to the Yjs document via a REST API which can handle access control. Data is still retrieved from the Yjs document directly (after it's been updated by the REST API), this way all comment information automatically syncs between clients using the existing collaboration provider.

```tsx
import { RESTYjsThreadStore, DefaultThreadStoreAuth } from "@blocknote/core/comments";
import {
RESTYjsThreadStore,
DefaultThreadStoreAuth,
} from "@blocknote/core/comments";

const threadStore = new RESTYjsThreadStore(
"https://api.example.com/comments", // Base URL for the REST API
Expand All @@ -84,7 +87,10 @@ _Note: Because writes are executed via a REST API, the `RESTYjsThreadStore` is n
The `TiptapThreadStore` integrates with Tiptap's collaboration provider for comment management. This implementation is designed specifically for use with Tiptap's collaborative editing features.

```tsx
import { TiptapThreadStore, DefaultThreadStoreAuth } from "@blocknote/core/comments";
import {
TiptapThreadStore,
DefaultThreadStoreAuth,
} from "@blocknote/core/comments";
import { TiptapCollabProvider } from "@hocuspocus/provider";

// Create a TiptapCollabProvider (you probably have this already)
Expand Down Expand Up @@ -130,9 +136,27 @@ async function myResolveUsers(userIds: string[]): Promise<User[]> {
// fetch user information from your database / backend
// and return an array of User objects

return await callYourBackend(userIds); //
return await callYourBackend(userIds);

// Return a list of users
return users;
}
```

## Sidebar View

BlockNote also offers a different way of viewing and interacting with comments, via a sidebar instead of floating in the editor, using the `ThreadsSidebar` component:

<Example name="collaboration/comments-with-sidebar"/>

The only requirement for `ThreadsSidebar` is that it should be placed somewhere within your `BlockNoteView`, other than that you can position and style it however you want.

`ThreadsSidebar` also takes 2 props:

**`filter`**: Filter the comments in the sidebar. Can pass `"open"`, `"resolved"`, or `"all"`, to only show open, resolved, or all comments. Defaults to `"all"`.

**`sort`**: Sort the comments in the sidebar. Can pass `"position"`, `"recent-activity"`, or `"oldest"`. Sorting by `"recent-activity"` uses the most recently added comment to sort threads, while `"oldest"` uses the thread creation date. Sorting by `"position"` puts comments in the same order as their reference text in the editor. Defaults to `"position"`.

**`maxCommentsBeforeCollapse`**: The maximum number of comments that can be in a thread before the replies get collapsed. Defaults to 5.

See [here](https://playground.blocknotejs.org/collaboration/comments-with-sidebar?hideMenu=true) for a standalone example of the `ThreadsSidebar` component.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
useCreateBlockNote,
} from "@blocknote/react";

import { BlueButton } from "./BlueButton";
import { BlueButton } from "./BlueButton.js";

export default function App() {
// Creates a new editor instance.
Expand Down
2 changes: 1 addition & 1 deletion examples/03-ui-components/04-side-menu-buttons/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
useCreateBlockNote,
} from "@blocknote/react";

import { RemoveBlockButton } from "./RemoveBlockButton";
import { RemoveBlockButton } from "./RemoveBlockButton.js";

export default function App() {
// Creates a new editor instance.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
useCreateBlockNote,
} from "@blocknote/react";

import { ResetBlockTypeItem } from "./ResetBlockTypeItem";
import { ResetBlockTypeItem } from "./ResetBlockTypeItem.js";

export default function App() {
// Creates a new editor instance.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
useCreateBlockNote,
} from "@blocknote/react";

import { Mention } from "./Mention";
import { Mention } from "./Mention.js";

// Our schema with inline content specs, which contain the configs and
// implementations for inline content that we want our editor to use.
Expand Down
4 changes: 2 additions & 2 deletions examples/03-ui-components/11-uppy-file-panel/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
useCreateBlockNote,
} from "@blocknote/react";

import { FileReplaceButton } from "./FileReplaceButton";
import { uploadFile, UppyFilePanel } from "./UppyFilePanel";
import { FileReplaceButton } from "./FileReplaceButton.js";
import { uploadFile, UppyFilePanel } from "./UppyFilePanel.js";

export default function App() {
// Creates a new editor instance.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
import { useEffect, useState } from "react";

import { RiImageEditFill } from "react-icons/ri";
import { UppyFilePanel } from "./UppyFilePanel";

import { UppyFilePanel } from "./UppyFilePanel.js";

// Copied with minor changes from:
// https://github.com/TypeCellOS/BlockNote/blob/main/packages/react/src/components/FormattingToolbar/DefaultButtons/FileReplaceButton.tsx
Expand Down
8 changes: 4 additions & 4 deletions examples/03-ui-components/13-custom-ui/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import "@blocknote/react/style.css";
import { createTheme, ThemeProvider, useMediaQuery } from "@mui/material";
import { useMemo } from "react";

import { schema } from "./schema";
import { CustomMUIFormattingToolbar } from "./MUIFormattingToolbar";
import { CustomMUISideMenu } from "./MUISideMenu";
import { MUISuggestionMenu } from "./MUISuggestionMenu";
import { schema } from "./schema.js";
import { CustomMUIFormattingToolbar } from "./MUIFormattingToolbar.js";
import { CustomMUISideMenu } from "./MUISideMenu.js";
import { MUISuggestionMenu } from "./MUISuggestionMenu.js";

import "./style.css";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import {
ReactNode,
} from "react";

import { TextBlockSchema } from "./schema";
import { TextBlockSchema } from "./schema.js";

// This replaces the generic Mantine `ToolbarSelect` component with a simplified
// MUI version:
Expand Down
2 changes: 1 addition & 1 deletion examples/03-ui-components/13-custom-ui/MUISideMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from "@mui/material";
import { MouseEvent, ReactNode, useCallback, useMemo, useState } from "react";

import { TextBlockSchema } from "./schema";
import { TextBlockSchema } from "./schema.js";

// This replaces the default `RemoveBlockItem` component with a simplified
// MUI version:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from "@mui/material";
import { useEffect, useMemo, useRef } from "react";

import { TextBlockSchema } from "./schema";
import { TextBlockSchema } from "./schema.js";

// If you want to change the items in a Suggestion Menu, like the Slash Menu,
// you don't need to modify any of the components in this file. Instead, you
Expand Down
2 changes: 1 addition & 1 deletion examples/03-ui-components/link-toolbar-buttons/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
useCreateBlockNote,
} from "@blocknote/react";

import { AlertButton } from "./AlertButton";
import { AlertButton } from "./AlertButton.js";

export default function App() {
// Creates a new editor instance.
Expand Down
2 changes: 1 addition & 1 deletion examples/06-custom-schema/01-alert-block/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
} from "@blocknote/react";

import { RiAlertFill } from "react-icons/ri";
import { Alert } from "./Alert";
import { Alert } from "./Alert.js";

// Our schema with block specs, which contain the configs and implementations for blocks
// that we want our editor to use.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
useCreateBlockNote,
} from "@blocknote/react";

import { Mention } from "./Mention";
import { Mention } from "./Mention.js";

// Our schema with inline content specs, which contain the configs and
// implementations for inline content that we want our editor to use.
Expand Down
2 changes: 1 addition & 1 deletion examples/06-custom-schema/03-font-style/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {

import { RiText } from "react-icons/ri";

import { Font } from "./Font";
import { Font } from "./Font.js";

// Our schema with style specs, which contain the configs and implementations for styles
// that we want our editor to use.
Expand Down
2 changes: 1 addition & 1 deletion examples/06-custom-schema/04-pdf-file-block/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {

import { RiFilePdfFill } from "react-icons/ri";

import { PDF } from "./PDF";
import { PDF } from "./PDF.js";

// Our schema with block specs, which contain the configs and implementations for blocks
// that we want our editor to use.
Expand Down
78 changes: 39 additions & 39 deletions examples/07-collaboration/04-comments/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import {
import { BlockNoteView } from "@blocknote/mantine";
import "@blocknote/mantine/style.css";
import { useCreateBlockNote } from "@blocknote/react";
import { MantineProvider, Select } from "@mantine/core";
import { YDocProvider, useYDoc, useYjsProvider } from "@y-sweet/react";
import { useMemo, useState } from "react";

import { SettingsSelect } from "./SettingsSelect.js";
import { HARDCODED_USERS, MyUserType, getRandomColor } from "./userdata.js";

import "./style.css";

// The resolveUsers function fetches information about your users
// (e.g. their name, avatar, etc.). Usually, you'd fetch this from your
// own database or user management system.
Expand All @@ -27,21 +30,20 @@ async function resolveUsers(userIds: string[]) {
// (but of course, you also use other collaboration providers
// see the docs for more information)
export default function App() {
const docId = "my-blocknote-document-with-comments";
const docId = "my-blocknote-document-with-comments-1";

return (
<MantineProvider>
<YDocProvider
docId={docId}
authEndpoint="https://demos.y-sweet.dev/api/auth">
<Document />
</YDocProvider>
</MantineProvider>
<YDocProvider
docId={docId}
authEndpoint="https://demos.y-sweet.dev/api/auth">
<Document />
</YDocProvider>
);
}

function Document() {
const [user, setUser] = useState<MyUserType>(HARDCODED_USERS[0]);
const [activeUser, setActiveUser] = useState<MyUserType>(HARDCODED_USERS[0]);

const provider = useYjsProvider();

// take the Y.Doc collaborative document from Y-Sweet
Expand All @@ -57,16 +59,16 @@ function Document() {
// document: doc,
// });
// return new TiptapThreadStore(
// user.id,
// activeUser.id,
// provider,
// new DefaultThreadStoreAuth(user.id, user.role)
// new DefaultThreadStoreAuth(activeUser.id, activeUser.role)
// );
return new YjsThreadStore(
user.id,
activeUser.id,
doc.getMap("threads"),
new DefaultThreadStoreAuth(user.id, user.role)
new DefaultThreadStoreAuth(activeUser.id, activeUser.role)
);
}, [doc, user]);
}, [doc, activeUser]);

// setup the editor with comments and collaboration
const editor = useCreateBlockNote(
Expand All @@ -78,34 +80,32 @@ function Document() {
collaboration: {
provider,
fragment: doc.getXmlFragment("blocknote"),
user: { color: getRandomColor(), name: user.username },
user: { color: getRandomColor(), name: activeUser.username },
},
},
[user, threadStore]
[activeUser, threadStore]
);

return (
<div>
{/* This is a simple user selector to switch between users, for demo purposes */}
<Select
style={{ maxWidth: "300px" }}
required
label="Active user:"
placeholder="Pick value"
data={HARDCODED_USERS.map((user) => ({
value: user.id,
label: user.username + " (" + user.role + ")",
}))}
onChange={(value) => {
if (!value) {
return;
}
setUser(HARDCODED_USERS.find((user) => user.id === value)!);
}}
value={user.id}
/>
{/* render the actual editor */}
<BlockNoteView editor={editor} editable={user.role === "editor"} />
</div>
<BlockNoteView
className={"comments-main-container"}
editor={editor}
editable={activeUser.role === "editor"}>
{/* We place user settings select within `BlockNoteView` as it uses
BlockNote UI components and needs the context for them. */}
<div className={"settings"}>
<SettingsSelect
label={"User"}
items={HARDCODED_USERS.map((user) => ({
text: `${user.username} (${
user.role === "editor" ? "Editor" : "Commenter"
})`,
icon: null,
onClick: () => setActiveUser(user),
isSelected: user.id === activeUser.id,
}))}
/>
</div>
</BlockNoteView>
);
}
6 changes: 3 additions & 3 deletions examples/07-collaboration/04-comments/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# Comments & Threads

In this example, you can add comments to the document while collaborating with others. You can also pick user accounts with different permissions, as well as react to, reply to, and resolve existing comments.
In this example, you can add comments to the document while collaborating with others. You can also pick user accounts with different permissions, as well as react to, reply to, and resolve existing comments. The comments are displayed floating next to the text they refer to, and appear when selecting said text.

**Try it out:** Click the "Add comment" button in the [Formatting Toolbar](/docs/ui-components/formatting-toolbar) to add a comment!

**Relevant Docs:**

- [Editor Setup](/docs/editor-basics/setup)
- [Comments](/docs/collaboration/comments)
- [Real-time collaboration](/docs/collaboration/real-time-collaboration)
- [Y-Sweet on Jamsocket](https://docs.jamsocket.com/y-sweet/tutorials/blocknote)
- [Comments](/docs/collaboration/comments)
- [Editor Setup](/docs/editor-basics/setup)

24 changes: 24 additions & 0 deletions examples/07-collaboration/04-comments/SettingsSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ComponentProps, useComponentsContext } from "@blocknote/react";

// This component is used to display a selection dropdown with a label. By using
// the useComponentsContext hook, we can create it out of existing components
// within the same UI library that `BlockNoteView` uses (Mantine, Ariakit, or
// ShadCN), to match the design of the editor.
export const SettingsSelect = (props: {
label: string;
items: ComponentProps["FormattingToolbar"]["Select"]["items"];
}) => {
const Components = useComponentsContext()!;

return (
<div className={"settings-select"}>
<Components.Generic.Toolbar.Root className={"bn-toolbar"}>
<h2>{props.label + ":"}</h2>
<Components.Generic.Toolbar.Select
className={"bn-select"}
items={props.items}
/>
</Components.Generic.Toolbar.Root>
</div>
);
};
Loading
Loading