Skip to content

Commit

Permalink
feat: Add collaborative initial content example
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Anselmo authored and Martin Anselmo committed Aug 7, 2024
1 parent 823f151 commit e026105
Show file tree
Hide file tree
Showing 17 changed files with 18,774 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"playground": true,
"docs": true,
"author": "mfanselmo",
"tags": ["Advanced", "Blocks", "yjs", "Collaboration"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules
client/node_modules
server/node_modules
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Initial content with server-util and yjs

This example shows how to instantiate a collaborative editor with existing content, using the `@blocknote/server-util` API

## Relevant documentation
- https://docs.yjs.dev/api/document-updates
- https://www.blocknotejs.org/docs/editor-api/server-processing
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { BlockNoteSchema } from '@blocknote/core';
import '@blocknote/core/fonts/inter.css';
import { useCreateBlockNote } from '@blocknote/react';
import { BlockNoteView } from '@blocknote/ariakit';
import '@blocknote/ariakit/style.css';
import * as Y from 'yjs';
import { useEffect, useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { toUint8Array } from 'js-base64';

const schema = BlockNoteSchema.create();

export default function App() {
// Just fetches the initial contents
const { data: initialContentsUpdateVector, refetch } = useQuery({
queryKey: [1],
queryFn: async () =>
fetch('http://localhost:3000/')
.then((res) => res.text())
.then((res) => toUint8Array(res)), // API returns initial doc as a yjs update encoded as base64
});

const ydoc = useMemo(() => {
const doc = new Y.Doc();
if (initialContentsUpdateVector) {
// https://docs.yjs.dev/api/document-updates
Y.applyUpdateV2(doc, initialContentsUpdateVector);
}

return doc;
}, [initialContentsUpdateVector]);

// Cleanup of the ydoc it is re-initialized
useEffect(() => {
return () => {
if (ydoc) {
ydoc.destroy();
}
};
}, [ydoc]);

// Creates a new editor instance.
const editor = useCreateBlockNote(
{
collaboration: {
fragment: ydoc.getXmlFragment('document-store'),
provider: null,
user: {
name: 'me',
color: 'white',
},
},
schema,
},
[ydoc] // Since we are changing the doc we need to re-initialize the editor
);

return (
<>
<button onClick={() => refetch()}>refetch initial contents</button>
<BlockNoteView editor={editor}></BlockNoteView>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Alert Block

In this example, we create a custom `Alert` block which is used to emphasize text. In addition, we create a Slash Menu item which inserts an `Alert` block.

**Try it out:** Press the "/" key to open the Slash Menu and insert an `Alert` block!

**Relevant Docs:**

- [Custom Blocks](/docs/custom-schemas/custom-blocks)
- [Changing Slash Menu Items](/docs/ui-components/suggestion-menus#changing-slash-menu-items)
- [Editor Setup](/docs/editor-basics/setup)
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>Alert Block</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const root = createRoot(document.getElementById('root')!);
const queryClient = new QueryClient();

root.render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
);
Loading

0 comments on commit e026105

Please sign in to comment.