Skip to content

Commit

Permalink
Merge pull request #139 from krehak/main
Browse files Browse the repository at this point in the history
  • Loading branch information
steven-tey committed Sep 26, 2023
2 parents 1433458 + e6c413a commit baac052
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 28 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ next-env.d.ts
# vscode
.vscode

# intellij
.idea

dist/**
/dist
packages/*/dist
Expand Down
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,18 @@ export default function App() {

The `Editor` is a React component that takes in the following props:

| Prop | Type | Description | Default |
| ------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `completionApi` | `string` | The API route to use for the OpenAI completion API. | `/api/generate` |
| `className` | `string` | Editor container classname. | `"relative min-h-[500px] w-full max-w-screen-lg border-stone-200 bg-white sm:mb-[calc(20vh)] sm:rounded-lg sm:border sm:shadow-lg"` |
| `defaultValue` | `JSONContent` or `string` | The default value to use for the editor. | [`defaultEditorContent`](https://github.com/steven-tey/novel/blob/main/packages/core/src/ui/editor/default-content.tsx) |
| `extensions` | `Extension[]` | A list of extensions to use for the editor, in addition to the [default Novel extensions](https://github.com/steven-tey/novel/blob/main/packages/core/src/ui/editor/extensions/index.tsx). | `[]` |
| `editorProps` | `EditorProps` | Props to pass to the underlying Tiptap editor, in addition to the [default Novel editor props](https://github.com/steven-tey/novel/blob/main/packages/core/src/ui/editor/props.ts). | `{}` |
| `onUpdate` | `(editor?: Editor) => void` | A callback function that is called whenever the editor is updated. | `() => {}` |
| `onDebouncedUpdate` | `(editor?: Editor) => void` | A callback function that is called whenever the editor is updated, but only after the defined debounce duration. | `() => {}` |
| `debounceDuration` | `number` | The duration (in milliseconds) to debounce the `onDebouncedUpdate` callback. | `750` |
| `storageKey` | `string` | The key to use for storing the editor's value in local storage. | `novel__content` |
| Prop | Type | Description | Default |
| --------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `completionApi` | `string` | The API route to use for the OpenAI completion API. | `/api/generate` |
| `className` | `string` | Editor container classname. | `"relative min-h-[500px] w-full max-w-screen-lg border-stone-200 bg-white sm:mb-[calc(20vh)] sm:rounded-lg sm:border sm:shadow-lg"` |
| `defaultValue` | `JSONContent` or `string` | The default value to use for the editor. | [`defaultEditorContent`](https://github.com/steven-tey/novel/blob/main/packages/core/src/ui/editor/default-content.tsx) |
| `extensions` | `Extension[]` | A list of extensions to use for the editor, in addition to the [default Novel extensions](https://github.com/steven-tey/novel/blob/main/packages/core/src/ui/editor/extensions/index.tsx). | `[]` |
| `editorProps` | `EditorProps` | Props to pass to the underlying Tiptap editor, in addition to the [default Novel editor props](https://github.com/steven-tey/novel/blob/main/packages/core/src/ui/editor/props.ts). | `{}` |
| `onUpdate` | `(editor?: Editor) => void` | A callback function that is called whenever the editor is updated. | `() => {}` |
| `onDebouncedUpdate` | `(editor?: Editor) => void` | A callback function that is called whenever the editor is updated, but only after the defined debounce duration. | `() => {}` |
| `debounceDuration` | `number` | The duration (in milliseconds) to debounce the `onDebouncedUpdate` callback. | `750` |
| `storageKey` | `string` | The key to use for storing the editor's value in local storage. | `novel__content` |
| `disableLocalStorage` | `boolean` | Enabling this option will prevent read/write content from/to local storage. | `false` |

> **Note**: Make sure to define an API endpoint that matches the `completionApi` prop (default is `/api/generate`). This is needed for the AI autocompletions to work. Here's an example: https://github.com/steven-tey/novel/blob/main/apps/web/app/api/generate/route.ts
Expand Down
23 changes: 12 additions & 11 deletions packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,18 @@ export default function App() {

The `Editor` is a React component that takes in the following props:

| Prop | Type | Description | Default |
| ------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `completionApi` | `string` | The API route to use for the OpenAI completion API. | `/api/generate` |
| `className` | `string` | Editor container classname. | `"relative min-h-[500px] w-full max-w-screen-lg border-stone-200 bg-white sm:mb-[calc(20vh)] sm:rounded-lg sm:border sm:shadow-lg"` |
| `defaultValue` | `JSONContent` or `string` | The default value to use for the editor. | [`defaultEditorContent`](https://github.com/steven-tey/novel/blob/main/packages/core/src/ui/editor/default-content.tsx) |
| `extensions` | `Extension[]` | A list of extensions to use for the editor, in addition to the [default Novel extensions](https://github.com/steven-tey/novel/blob/main/packages/core/src/ui/editor/extensions/index.tsx). | `[]` |
| `editorProps` | `EditorProps` | Props to pass to the underlying Tiptap editor, in addition to the [default Novel editor props](https://github.com/steven-tey/novel/blob/main/packages/core/src/ui/editor/props.ts). | `{}` |
| `onUpdate` | `(editor?: Editor) => void` | A callback function that is called whenever the editor is updated. | `() => {}` |
| `onDebouncedUpdate` | `(editor?: Editor) => void` | A callback function that is called whenever the editor is updated, but only after the defined debounce duration. | `() => {}` |
| `debounceDuration` | `number` | The duration (in milliseconds) to debounce the `onDebouncedUpdate` callback. | `750` |
| `storageKey` | `string` | The key to use for storing the editor's value in local storage. | `novel__content` |
| Prop | Type | Description | Default |
| --------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `completionApi` | `string` | The API route to use for the OpenAI completion API. | `/api/generate` |
| `className` | `string` | Editor container classname. | `"relative min-h-[500px] w-full max-w-screen-lg border-stone-200 bg-white sm:mb-[calc(20vh)] sm:rounded-lg sm:border sm:shadow-lg"` |
| `defaultValue` | `JSONContent` or `string` | The default value to use for the editor. | [`defaultEditorContent`](https://github.com/steven-tey/novel/blob/main/packages/core/src/ui/editor/default-content.tsx) |
| `extensions` | `Extension[]` | A list of extensions to use for the editor, in addition to the [default Novel extensions](https://github.com/steven-tey/novel/blob/main/packages/core/src/ui/editor/extensions/index.tsx). | `[]` |
| `editorProps` | `EditorProps` | Props to pass to the underlying Tiptap editor, in addition to the [default Novel editor props](https://github.com/steven-tey/novel/blob/main/packages/core/src/ui/editor/props.ts). | `{}` |
| `onUpdate` | `(editor?: Editor) => void` | A callback function that is called whenever the editor is updated. | `() => {}` |
| `onDebouncedUpdate` | `(editor?: Editor) => void` | A callback function that is called whenever the editor is updated, but only after the defined debounce duration. | `() => {}` |
| `debounceDuration` | `number` | The duration (in milliseconds) to debounce the `onDebouncedUpdate` callback. | `750` |
| `storageKey` | `string` | The key to use for storing the editor's value in local storage. | `novel__content` |
| `disableLocalStorage` | `boolean` | Enabling this option will prevent read/write content from/to local storage. | `false` |

> **Note**: Make sure to define an API endpoint that matches the `completionApi` prop (default is `/api/generate`). This is needed for the AI autocompletions to work. Here's an example: https://github.com/steven-tey/novel/blob/main/apps/web/app/api/generate/route.ts
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "novel",
"version": "0.1.20",
"version": "0.1.21",
"description": "Notion-style WYSIWYG editor with AI-powered autocompletions",
"license": "Apache-2.0",
"main": "./dist/index.js",
Expand Down
24 changes: 19 additions & 5 deletions packages/core/src/ui/editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export default function Editor({
onDebouncedUpdate = () => {},
debounceDuration = 750,
storageKey = "novel__content",
disableLocalStorage = false,
}: {
/**
* The API route to use for the OpenAI completion API.
Expand Down Expand Up @@ -79,15 +80,23 @@ export default function Editor({
* Defaults to "novel__content".
*/
storageKey?: string;
/**
* Disable local storage read/save.
* Defaults to false.
*/
disableLocalStorage?: boolean;
}) {
const [content, setContent] = useLocalStorage(storageKey, defaultValue);

const [hydrated, setHydrated] = useState(false);

const debouncedUpdates = useDebouncedCallback(async ({ editor }) => {
const json = editor.getJSON();
setContent(json);
onDebouncedUpdate(editor);

if (!disableLocalStorage) {
setContent(json);
}
}, debounceDuration);

const editor = useEditor({
Expand Down Expand Up @@ -183,13 +192,18 @@ export default function Editor({
};
}, [stop, isLoading, editor, complete, completion.length]);

// Hydrate the editor with the content from localStorage.
// Default: Hydrate the editor with the content from localStorage.
// If disableLocalStorage is true, hydrate the editor with the defaultValue.
useEffect(() => {
if (editor && content && !hydrated) {
editor.commands.setContent(content);
if (!editor || hydrated) return;

const value = disableLocalStorage ? defaultValue : content;

if (value) {
editor.commands.setContent(value);
setHydrated(true);
}
}, [editor, content, hydrated]);
}, [editor, defaultValue, content, hydrated, disableLocalStorage]);

return (
<div
Expand Down

1 comment on commit baac052

@vercel
Copy link

@vercel vercel bot commented on baac052 Sep 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.