From 0eab377f832d8d47f63bc8c38f7757126df5a515 Mon Sep 17 00:00:00 2001 From: yousefed Date: Wed, 11 Jan 2023 12:15:59 +0100 Subject: [PATCH 1/4] refactor entrypoints --- examples/editor/src/App.tsx | 42 ++---- packages/core/package.json | 1 - packages/core/src/BlockNoteEditor.ts | 138 +++++++++++------- packages/core/src/EditorContent.tsx | 2 - .../src/extensions/SlashMenu/SlashMenuItem.ts | 2 - .../extensions/SlashMenu/defaultCommands.tsx | 14 -- packages/core/src/index.ts | 4 +- .../plugins/suggestion/SuggestionItem.ts | 7 - packages/core/src/useEditor.ts | 85 ----------- packages/core/vite.config.bundled.ts | 4 +- packages/react/src/BlockNoteView.tsx | 6 + packages/react/src/Editor/useEditor.ts | 51 ------- .../components/SuggestionList.tsx | 8 +- .../components/SuggestionListItem.tsx | 36 ++++- packages/react/src/hooks/useBlockNote.ts | 68 +++++++++ .../src}/hooks/useEditorForceUpdate.tsx | 0 packages/react/src/index.ts | 4 +- 17 files changed, 213 insertions(+), 259 deletions(-) delete mode 100644 packages/core/src/EditorContent.tsx delete mode 100644 packages/core/src/useEditor.ts create mode 100644 packages/react/src/BlockNoteView.tsx delete mode 100644 packages/react/src/Editor/useEditor.ts create mode 100644 packages/react/src/hooks/useBlockNote.ts rename packages/{core/src/shared => react/src}/hooks/useEditorForceUpdate.tsx (100%) diff --git a/examples/editor/src/App.tsx b/examples/editor/src/App.tsx index 65fae001d7..1c6c5c7f4e 100644 --- a/examples/editor/src/App.tsx +++ b/examples/editor/src/App.tsx @@ -1,45 +1,27 @@ // import logo from './logo.svg' -import { EditorContent, useEditor } from "@blocknote/core"; import "@blocknote/core/style.css"; +import { BlockNoteView, useBlockNote } from "@blocknote/react"; import { Editor } from "@tiptap/core"; import styles from "./App.module.css"; -import { - ReactAddBlockButtonFactory, - ReactBubbleMenuFactory, - ReactDragHandleFactory, - ReactDragHandleMenuFactory, - ReactHyperlinkMenuFactory, - ReactSuggestionsMenuFactory, -} from "@blocknote/react"; type WindowWithProseMirror = Window & typeof globalThis & { ProseMirror: Editor }; function App() { - const editor = useEditor( - { - addBlockButtonFactory: ReactAddBlockButtonFactory, - bubbleMenuFactory: ReactBubbleMenuFactory, - dragHandleFactory: ReactDragHandleFactory, - dragHandleMenuFactory: ReactDragHandleMenuFactory, - hyperlinkMenuFactory: ReactHyperlinkMenuFactory, - suggestionsMenuFactory: ReactSuggestionsMenuFactory, + const editor = useBlockNote({ + onUpdate: ({ editor }) => { + console.log(editor.getJSON()); + (window as WindowWithProseMirror).ProseMirror = editor; // Give tests a way to get editor instance }, - { - onUpdate: ({ editor }) => { - console.log(editor.getJSON()); - (window as WindowWithProseMirror).ProseMirror = editor; // Give tests a way to get editor instance + editorProps: { + attributes: { + class: styles.editor, + "data-test": "editor", }, - editorProps: { - attributes: { - class: styles.editor, - "data-test": "editor", - }, - }, - } - ); + }, + }); - return ; + return ; } export default App; diff --git a/packages/core/package.json b/packages/core/package.json index 260e1175d2..df48c0880b 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -69,7 +69,6 @@ "prosemirror-model": "1.18.1", "prosemirror-state": "1.4.1", "prosemirror-view": "1.26.2", - "react-icons": "^4.3.1", "uuid": "^8.3.2" }, "devDependencies": { diff --git a/packages/core/src/BlockNoteEditor.ts b/packages/core/src/BlockNoteEditor.ts index 73d4bc034c..229baa5b79 100644 --- a/packages/core/src/BlockNoteEditor.ts +++ b/packages/core/src/BlockNoteEditor.ts @@ -3,20 +3,27 @@ import { Editor, EditorOptions } from "@tiptap/core"; import { getBlockNoteExtensions } from "./BlockNoteExtensions"; import styles from "./editor.module.css"; import { BubbleMenuFactory } from "./extensions/BubbleMenu/BubbleMenuFactoryTypes"; -import { HyperlinkHoverMenuFactory } from "./extensions/Hyperlinks/HyperlinkMenuFactoryTypes"; -import { SuggestionsMenuFactory } from "./shared/plugins/suggestion/SuggestionsMenuFactoryTypes"; +import { + AddBlockButtonFactory, + DragHandleFactory, + DragHandleMenuFactory, +} from "./extensions/DraggableBlocks/DragMenuFactoryTypes"; +import { HyperlinkMenuFactory } from "./extensions/Hyperlinks/HyperlinkMenuFactoryTypes"; import rootStyles from "./root.module.css"; import { SuggestionItem } from "./shared/plugins/suggestion/SuggestionItem"; +import { SuggestionsMenuFactory } from "./shared/plugins/suggestion/SuggestionsMenuFactoryTypes"; -type BlockNoteEditorOptions = EditorOptions & { +export type BlockNoteEditorOptions = EditorOptions & { enableBlockNoteExtensions: boolean; disableHistoryExtension: boolean; -}; - -export type MenuFactories = { - bubbleMenuFactory: BubbleMenuFactory; - hyperlinkMenuFactory: HyperlinkHoverMenuFactory; - suggestionsMenuFactory: SuggestionsMenuFactory; + uiFactories: { + bubbleMenuFactory: BubbleMenuFactory; + hyperlinkMenuFactory: HyperlinkMenuFactory; + suggestionsMenuFactory: SuggestionsMenuFactory; + addBlockButtonFactory: AddBlockButtonFactory; + dragHandleFactory: DragHandleFactory; + dragHandleMenuFactory: DragHandleMenuFactory; + }; }; const blockNoteExtensions = getBlockNoteExtensions(); @@ -27,55 +34,78 @@ const blockNoteOptions = { enableCoreExtensions: false, }; -export const mountBlockNoteEditor = ( - menuFactories: MenuFactories, - options: Partial = {} -) => { - let extensions = options.disableHistoryExtension - ? blockNoteExtensions.filter((e) => e.name !== "history") - : blockNoteExtensions; +export class BlockNoteEditor { + public readonly tiptapEditor: Editor & { contentComponent: any }; - // TODO: review - extensions = extensions.map((extension) => { - if (extension.name === "BubbleMenuExtension") { - return extension.configure({ - bubbleMenuFactory: menuFactories.bubbleMenuFactory, - }); - } + constructor(options: Partial = {}) { + let extensions = options.disableHistoryExtension + ? blockNoteExtensions.filter((e) => e.name !== "history") + : blockNoteExtensions; - if (extension.name === "link") { - return extension.configure({ - hyperlinkMenuFactory: menuFactories.hyperlinkMenuFactory, - }); - } + // TODO: review + extensions = extensions.map((extension) => { + if ( + extension.name === "BubbleMenuExtension" && + options.uiFactories?.bubbleMenuFactory + ) { + return extension.configure({ + bubbleMenuFactory: options.uiFactories.bubbleMenuFactory, + }); + } - if (extension.name === "slash-command") { - return extension.configure({ - suggestionsMenuFactory: menuFactories.suggestionsMenuFactory, - }); - } + if ( + extension.name === "link" && + options.uiFactories?.hyperlinkMenuFactory + ) { + return extension.configure({ + hyperlinkMenuFactory: options.uiFactories.hyperlinkMenuFactory, + }); + } - return extension; - }); + if ( + extension.name === "slash-command" && + options.uiFactories?.suggestionsMenuFactory + ) { + return extension.configure({ + suggestionsMenuFactory: options.uiFactories.suggestionsMenuFactory, + }); + } - const tiptapOptions = { - ...blockNoteOptions, - ...options, - extensions: - options.enableBlockNoteExtensions === false - ? options.extensions - : [...(options.extensions || []), ...extensions], - editorProps: { - attributes: { - ...(options.editorProps?.attributes || {}), - class: [ - styles.bnEditor, - rootStyles.bnRoot, - (options.editorProps?.attributes as any)?.class || "", - ].join(" "), + if ( + extension.name === "DraggableBlocksExtension" && + options.uiFactories + ) { + return extension.configure({ + addBlockButtonFactory: options.uiFactories.addBlockButtonFactory, + dragHandleFactory: options.uiFactories.dragHandleFactory, + dragHandleMenuFactory: options.uiFactories.dragHandleMenuFactory, + }); + } + + return extension; + }); + + const tiptapOptions = { + ...blockNoteOptions, + ...options, + extensions: + options.enableBlockNoteExtensions === false + ? options.extensions + : [...(options.extensions || []), ...extensions], + editorProps: { + attributes: { + ...(options.editorProps?.attributes || {}), + class: [ + styles.bnEditor, + rootStyles.bnRoot, + (options.editorProps?.attributes as any)?.class || "", + ].join(" "), + }, }, - }, - }; + }; - return new Editor(tiptapOptions); -}; + this.tiptapEditor = new Editor(tiptapOptions) as Editor & { + contentComponent: any; + }; + } +} diff --git a/packages/core/src/EditorContent.tsx b/packages/core/src/EditorContent.tsx deleted file mode 100644 index 7bcccbc6cd..0000000000 --- a/packages/core/src/EditorContent.tsx +++ /dev/null @@ -1,2 +0,0 @@ -// BlockNote uses a similar pattern as Tiptap, so for now we can just export that -export { EditorContent } from "@tiptap/react"; diff --git a/packages/core/src/extensions/SlashMenu/SlashMenuItem.ts b/packages/core/src/extensions/SlashMenu/SlashMenuItem.ts index 76e76da6ce..576038b894 100644 --- a/packages/core/src/extensions/SlashMenu/SlashMenuItem.ts +++ b/packages/core/src/extensions/SlashMenu/SlashMenuItem.ts @@ -1,5 +1,4 @@ import { Editor, Range } from "@tiptap/core"; -import { IconType } from "react-icons"; import { SuggestionItem } from "../../shared/plugins/suggestion/SuggestionItem"; export type SlashMenuCallback = (editor: Editor, range: Range) => boolean; @@ -40,7 +39,6 @@ export class SlashMenuItem implements SuggestionItem { public readonly group: SlashMenuGroups, public readonly execute: SlashMenuCallback, public readonly aliases: string[] = [], - public readonly icon?: IconType, public readonly hint?: string, public readonly shortcut?: string ) { diff --git a/packages/core/src/extensions/SlashMenu/defaultCommands.tsx b/packages/core/src/extensions/SlashMenu/defaultCommands.tsx index f5024a56cb..42ac95d2bd 100644 --- a/packages/core/src/extensions/SlashMenu/defaultCommands.tsx +++ b/packages/core/src/extensions/SlashMenu/defaultCommands.tsx @@ -1,11 +1,3 @@ -import { - RiH1, - RiH2, - RiH3, - RiListOrdered, - RiListUnordered, - RiText, -} from "react-icons/ri"; import { formatKeyboardShortcut } from "../../utils"; import { SlashMenuGroups, SlashMenuItem } from "./SlashMenuItem"; @@ -28,7 +20,6 @@ const defaultCommands: { [key: string]: SlashMenuItem } = { .run(); }, ["h", "heading1", "h1"], - RiH1, "Used for a top-level heading", formatKeyboardShortcut("Mod-Alt-1") ), @@ -48,7 +39,6 @@ const defaultCommands: { [key: string]: SlashMenuItem } = { .run(); }, ["h2", "heading2", "subheading"], - RiH2, "Used for key sections", formatKeyboardShortcut("Mod-Alt-2") ), @@ -68,7 +58,6 @@ const defaultCommands: { [key: string]: SlashMenuItem } = { .run(); }, ["h3", "heading3", "subheading"], - RiH3, "Used for subsections and group headings", formatKeyboardShortcut("Mod-Alt-3") ), @@ -88,7 +77,6 @@ const defaultCommands: { [key: string]: SlashMenuItem } = { .run(); }, ["li", "list", "numberedlist", "numbered list"], - RiListOrdered, "Used to display a numbered list", formatKeyboardShortcut("Mod-Shift-7") ), @@ -108,7 +96,6 @@ const defaultCommands: { [key: string]: SlashMenuItem } = { .run(); }, ["ul", "list", "bulletlist", "bullet list"], - RiListUnordered, "Used to display an unordered list", formatKeyboardShortcut("Mod-Shift-8") ), @@ -126,7 +113,6 @@ const defaultCommands: { [key: string]: SlashMenuItem } = { .run(); }, ["p"], - RiText, "Used for the body of your document", formatKeyboardShortcut("Mod-Alt-0") ), diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index f8c5c1ad27..48cca1a6a1 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -2,10 +2,8 @@ import "./globals.css"; export * from "./BlockNoteEditor"; export * from "./BlockNoteExtensions"; -export * from "./EditorContent"; export * from "./extensions/BubbleMenu/BubbleMenuFactoryTypes"; export * from "./extensions/DraggableBlocks/DragMenuFactoryTypes"; export * from "./extensions/Hyperlinks/HyperlinkMenuFactoryTypes"; -export * from "./shared/plugins/suggestion/SuggestionsMenuFactoryTypes"; export type { SuggestionItem } from "./shared/plugins/suggestion/SuggestionItem"; -export * from "./useEditor"; +export * from "./shared/plugins/suggestion/SuggestionsMenuFactoryTypes"; diff --git a/packages/core/src/shared/plugins/suggestion/SuggestionItem.ts b/packages/core/src/shared/plugins/suggestion/SuggestionItem.ts index 688aaea88e..837089e32b 100644 --- a/packages/core/src/shared/plugins/suggestion/SuggestionItem.ts +++ b/packages/core/src/shared/plugins/suggestion/SuggestionItem.ts @@ -1,5 +1,3 @@ -import { IconType } from "react-icons"; - /** * A generic interface used in all suggestion menus (slash menu, mentions, etc) */ @@ -14,11 +12,6 @@ export interface SuggestionItem { */ groupName: string; - /** - * The react icon - */ - icon?: IconType; - hint?: string; shortcut?: string; diff --git a/packages/core/src/useEditor.ts b/packages/core/src/useEditor.ts deleted file mode 100644 index cddb6e5219..0000000000 --- a/packages/core/src/useEditor.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { EditorOptions, useEditor as useEditorTiptap } from "@tiptap/react"; - -import { DependencyList } from "react"; -import { getBlockNoteExtensions } from "./BlockNoteExtensions"; -import styles from "./editor.module.css"; -import rootStyles from "./root.module.css"; -import { ElementFactories } from "./BlockNoteEditor"; - -type BlockNoteEditorOptions = EditorOptions & { - enableBlockNoteExtensions: boolean; - disableHistoryExtension: boolean; -}; - -const blockNoteExtensions = getBlockNoteExtensions(); - -const blockNoteOptions = { - enableInputRules: true, - enablePasteRules: true, - enableCoreExtensions: false, -}; - -/** - * Main hook for importing a BlockNote editor into a react project - */ -export const useEditor = ( - elementFactories: ElementFactories, - options: Partial = {}, - deps: DependencyList = [] -) => { - let extensions = options.disableHistoryExtension - ? blockNoteExtensions.filter((e) => e.name !== "history") - : blockNoteExtensions; - - // TODO: review - extensions = extensions.map((extension) => { - if (extension.name === "BubbleMenuExtension") { - return extension.configure({ - bubbleMenuFactory: elementFactories.bubbleMenuFactory, - }); - } - - if (extension.name === "link") { - return extension.configure({ - hyperlinkMenuFactory: elementFactories.hyperlinkMenuFactory, - }); - } - - if (extension.name === "slash-command") { - return extension.configure({ - suggestionsMenuFactory: elementFactories.suggestionsMenuFactory, - }); - } - - if (extension.name === "DraggableBlocksExtension") { - return extension.configure({ - addBlockButtonFactory: elementFactories.addBlockButtonFactory, - dragHandleFactory: elementFactories.dragHandleFactory, - dragHandleMenuFactory: elementFactories.dragHandleMenuFactory, - }); - } - - return extension; - }); - - const tiptapOptions = { - ...blockNoteOptions, - ...options, - extensions: - options.enableBlockNoteExtensions === false - ? options.extensions - : [...(options.extensions || []), ...extensions], - editorProps: { - attributes: { - ...(options.editorProps?.attributes || {}), - class: [ - styles.bnEditor, - rootStyles.bnRoot, - (options.editorProps?.attributes as any)?.class || "", - ].join(" "), - }, - }, - }; - - return useEditorTiptap(tiptapOptions, deps); -}; diff --git a/packages/core/vite.config.bundled.ts b/packages/core/vite.config.bundled.ts index 9a6ebab09c..7ca00d3dd8 100644 --- a/packages/core/vite.config.bundled.ts +++ b/packages/core/vite.config.bundled.ts @@ -21,8 +21,8 @@ export default defineConfig({ // Provide global variables to use in the UMD build // for externalized deps globals: { - react: "React", - "react-dom": "ReactDOM", + // react: "React", + // "react-dom": "ReactDOM", }, }, }, diff --git a/packages/react/src/BlockNoteView.tsx b/packages/react/src/BlockNoteView.tsx new file mode 100644 index 0000000000..0c7a5e176b --- /dev/null +++ b/packages/react/src/BlockNoteView.tsx @@ -0,0 +1,6 @@ +import { BlockNoteEditor } from "@blocknote/core"; +import { EditorContent } from "@tiptap/react"; + +export function BlockNoteView(props: { editor: BlockNoteEditor | null }) { + return ; +} diff --git a/packages/react/src/Editor/useEditor.ts b/packages/react/src/Editor/useEditor.ts deleted file mode 100644 index 9dc75db22b..0000000000 --- a/packages/react/src/Editor/useEditor.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { EditorOptions, useEditor as useEditorTiptap } from "@tiptap/react"; - -import { getBlockNoteExtensions } from "@blocknote/core"; -import { DependencyList } from "react"; -// import styles from "../../../core/src/editor.module.css"; -// import rootStyles from "../../../core/src/root.module.css"; - -type BlockNoteEditorOptions = EditorOptions & { - enableBlockNoteExtensions: boolean; - disableHistoryExtension: boolean; -}; - -const blockNoteExtensions = getBlockNoteExtensions(); - -const blockNoteOptions = { - enableInputRules: true, - enablePasteRules: true, - enableCoreExtensions: false, -}; - -/** - * Main hook for importing a BlockNote editor into a react project - */ -export const useEditor = ( - options: Partial = {}, - deps: DependencyList = [] -) => { - const extensions = options.disableHistoryExtension - ? blockNoteExtensions.filter((e) => e.name !== "history") - : blockNoteExtensions; - - const tiptapOptions = { - ...blockNoteOptions, - ...options, - extensions: - options.enableBlockNoteExtensions === false - ? options.extensions - : [...(options.extensions || []), ...extensions], - editorProps: { - attributes: { - ...(options.editorProps?.attributes || {}), - class: [ - // styles.bnEditor, - // rootStyles.bnRoot, - (options.editorProps?.attributes as any)?.class || "", - ].join(" "), - }, - }, - }; - return useEditorTiptap(tiptapOptions, deps); -}; diff --git a/packages/react/src/SuggestionsMenu/components/SuggestionList.tsx b/packages/react/src/SuggestionsMenu/components/SuggestionList.tsx index 0e701b5db5..e4fd8e04dd 100644 --- a/packages/react/src/SuggestionsMenu/components/SuggestionList.tsx +++ b/packages/react/src/SuggestionsMenu/components/SuggestionList.tsx @@ -15,8 +15,8 @@ export function SuggestionList( name: "SuggestionList", }); - const headingGroup = []; - const basicBlockGroup = []; + const headingGroup: T[] = []; + const basicBlockGroup: T[] = []; for (const item of props.items) { if (item.name === "Heading") { @@ -44,7 +44,7 @@ export function SuggestionList( } } - const renderedItems = []; + const renderedItems: any[] = []; let index = 0; if (headingGroup.length > 0) { @@ -58,7 +58,6 @@ export function SuggestionList( key={item.name} name={item.name} hint={item.hint} - icon={item.icon} isSelected={props.selectedItemIndex === index} set={() => props.itemCallback(item)} /> @@ -78,7 +77,6 @@ export function SuggestionList( key={item.name} name={item.name} hint={item.hint} - icon={item.icon} isSelected={props.selectedItemIndex === index} set={() => props.itemCallback(item)} /> diff --git a/packages/react/src/SuggestionsMenu/components/SuggestionListItem.tsx b/packages/react/src/SuggestionsMenu/components/SuggestionListItem.tsx index 31a5cbf61c..7a7520d492 100644 --- a/packages/react/src/SuggestionsMenu/components/SuggestionListItem.tsx +++ b/packages/react/src/SuggestionsMenu/components/SuggestionListItem.tsx @@ -3,12 +3,20 @@ import { Badge, createStyles, Menu, Stack, Text } from "@mantine/core"; import { useEffect, useRef } from "react"; import { IconType } from "react-icons"; +import { + RiH1, + RiH2, + RiH3, + RiListOrdered, + RiListUnordered, + RiText, +} from "react-icons/ri"; + const MIN_LEFT_MARGIN = 5; export type SuggestionGroupItemProps = { name: string; hint: string | undefined; - icon: IconType | undefined; shortcut?: string; isSelected: boolean; set: () => void; @@ -54,7 +62,31 @@ export function SuggestionListItem(props: SuggestionGroupItemProps) { } }); - const Icon = props.icon; + // TODO: rearchitect, this is hacky + let Icon: IconType | undefined; + switch (props.name) { + case "Heading": + Icon = RiH1; + break; + case "Heading 2": + Icon = RiH2; + break; + + case "Heading 3": + Icon = RiH3; + break; + case "Numbered List": + Icon = RiListOrdered; + break; + case "Bullet List": + Icon = RiListUnordered; + break; + case "Paragraph": + Icon = RiText; + break; + default: + break; + } return ( setValue((value) => value + 1); +} + +/** + * Main hook for importing a BlockNote editor into a react project + */ +export const useBlockNote = ( + options: Partial = {}, + deps: DependencyList = [] +) => { + const [editor, setEditor] = useState(); + const forceUpdate = useForceUpdate(); + // useEditorForceUpdate(editor.tiptapEditor); + + useEffect(() => { + let isMounted = true; + let newOptions = { ...options }; + if (!newOptions.uiFactories) { + newOptions = { + ...newOptions, + uiFactories: { + bubbleMenuFactory: ReactBubbleMenuFactory, + hyperlinkMenuFactory: ReactHyperlinkMenuFactory, + suggestionsMenuFactory: ReactSuggestionsMenuFactory, + addBlockButtonFactory: ReactAddBlockButtonFactory, + dragHandleFactory: ReactDragHandleFactory, + dragHandleMenuFactory: ReactDragHandleMenuFactory, + }, + }; + } + console.log("create new blocknote instance"); + const instance = new BlockNoteEditor(newOptions); + + setEditor(instance); + + instance.tiptapEditor.on("transaction", () => { + requestAnimationFrame(() => { + requestAnimationFrame(() => { + if (isMounted) { + forceUpdate(); + } + }); + }); + }); + + return () => { + instance.tiptapEditor.destroy(); + isMounted = false; + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, deps); + + return editor; +}; diff --git a/packages/core/src/shared/hooks/useEditorForceUpdate.tsx b/packages/react/src/hooks/useEditorForceUpdate.tsx similarity index 100% rename from packages/core/src/shared/hooks/useEditorForceUpdate.tsx rename to packages/react/src/hooks/useEditorForceUpdate.tsx diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index dc4253e378..444df8d17c 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -1,8 +1,10 @@ // TODO: review directories export * from "./AddBlockButton/AddBlockButtonFactory"; +export * from "./BlockNoteView"; export * from "./BubbleMenu/BubbleMenuFactory"; export * from "./DragHandle/DragHandleFactory"; export * from "./DragHandleMenu/DragHandleMenuFactory"; -export * from "./Editor/EditorContent"; +export * from "./hooks/useBlockNote"; +export * from "./hooks/useEditorForceUpdate"; export * from "./HyperlinkMenu/HyperlinkMenuFactory"; export * from "./SuggestionsMenu/SuggestionsMenuFactory"; From 81aa62c9764e68aa99891b07e716e6dda6957b55 Mon Sep 17 00:00:00 2001 From: yousefed Date: Wed, 11 Jan 2023 12:21:07 +0100 Subject: [PATCH 2/4] fix packages --- package-lock.json | 22 +++++++++------------- packages/react/package.json | 3 ++- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index d4880954af..2af04677d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11669,9 +11669,9 @@ } }, "node_modules/react-icons": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.6.0.tgz", - "integrity": "sha512-rR/L9m9340yO8yv1QT1QurxWQvWpbNHqVX0fzMln2HEb9TEIrQRGsqiNFQfiv9/JEUbyHmHPlNTB2LWm2Ttz0g==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.7.1.tgz", + "integrity": "sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==", "peerDependencies": { "react": "*" } @@ -13712,13 +13712,10 @@ "prosemirror-model": "1.18.1", "prosemirror-state": "1.4.1", "prosemirror-view": "1.26.2", - "react-icons": "^4.3.1", "uuid": "^8.3.2" }, "devDependencies": { "@types/lodash": "^4.14.179", - "@types/react": "^18.0.25", - "@types/react-dom": "^18.0.9", "@types/uuid": "^8.3.4", "eslint": "^8.10.0", "eslint-config-react-app": "^7.0.0", @@ -13735,7 +13732,8 @@ "@blocknote/core": "^0.1.2", "@mantine/core": "^5.6.1", "@tippyjs/react": "^4.2.6", - "@tiptap/react": "^2.0.0-beta.207" + "@tiptap/react": "^2.0.0-beta.207", + "react-icons": "^4.3.1" }, "devDependencies": { "@types/react": "^18.0.25", @@ -15172,8 +15170,6 @@ "@tiptap/extension-text": "^2.0.0-beta.17", "@tiptap/extension-underline": "^2.0.0-beta.25", "@types/lodash": "^4.14.179", - "@types/react": "^18.0.25", - "@types/react-dom": "^18.0.9", "@types/uuid": "^8.3.4", "eslint": "^8.10.0", "eslint-config-react-app": "^7.0.0", @@ -15182,7 +15178,6 @@ "prosemirror-model": "1.18.1", "prosemirror-state": "1.4.1", "prosemirror-view": "1.26.2", - "react-icons": "^4.3.1", "typescript": "^4.5.4", "uuid": "^8.3.2", "vite": "^3.0.5", @@ -15219,6 +15214,7 @@ "eslint": "^8.10.0", "eslint-config-react-app": "^7.0.0", "prettier": "^2.7.1", + "react-icons": "^4.3.1", "typescript": "^4.5.4", "vite": "^3.0.5", "vite-plugin-eslint": "^1.7.0" @@ -22391,9 +22387,9 @@ } }, "react-icons": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.6.0.tgz", - "integrity": "sha512-rR/L9m9340yO8yv1QT1QurxWQvWpbNHqVX0fzMln2HEb9TEIrQRGsqiNFQfiv9/JEUbyHmHPlNTB2LWm2Ttz0g==", + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.7.1.tgz", + "integrity": "sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==", "requires": {} }, "react-refresh": { diff --git a/packages/react/package.json b/packages/react/package.json index a7606610df..8f22317a2b 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -29,7 +29,8 @@ "@mantine/core": "^5.6.1", "@blocknote/core": "^0.1.2", "@tippyjs/react": "^4.2.6", - "@tiptap/react": "^2.0.0-beta.207" + "@tiptap/react": "^2.0.0-beta.207", + "react-icons": "^4.3.1" }, "devDependencies": { "@types/react": "^18.0.25", From ed74b5a48d779d7b705731febf9a0b90cfc3f635 Mon Sep 17 00:00:00 2001 From: yousefed Date: Wed, 11 Jan 2023 12:34:44 +0100 Subject: [PATCH 3/4] fix build --- packages/react/src/hooks/useBlockNote.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/hooks/useBlockNote.ts b/packages/react/src/hooks/useBlockNote.ts index 8775497b57..181b748fcf 100644 --- a/packages/react/src/hooks/useBlockNote.ts +++ b/packages/react/src/hooks/useBlockNote.ts @@ -22,7 +22,7 @@ export const useBlockNote = ( options: Partial = {}, deps: DependencyList = [] ) => { - const [editor, setEditor] = useState(); + const [editor, setEditor] = useState(null); const forceUpdate = useForceUpdate(); // useEditorForceUpdate(editor.tiptapEditor); From dd0973d02fe3072010c79e45fe788f4ff11da6f3 Mon Sep 17 00:00:00 2001 From: yousefed Date: Wed, 11 Jan 2023 13:45:31 +0100 Subject: [PATCH 4/4] move some more files / remove root.module.css --- packages/core/src/BlockNoteEditor.ts | 3 +- packages/core/src/assets/fonts-inter.css | 92 ++++++++++++++++++ packages/core/src/editor.module.css | 20 ++++ .../BubbleMenu/BubbleMenuFactoryTypes.ts | 2 +- .../DraggableBlocks/DragMenuFactoryTypes.ts | 2 +- .../Hyperlinks/HyperlinkMenuFactoryTypes.ts | 2 +- .../extensions/SlashMenu/defaultCommands.tsx | 2 +- packages/core/src/fonts-inter.css | 94 ------------------- packages/core/src/globals.css | 28 ------ packages/core/src/index.ts | 2 - packages/core/src/root.module.css | 19 ---- .../core/src/{ => shared}/EditorElement.ts | 0 .../suggestion/SuggestionsMenuFactoryTypes.ts | 2 +- packages/core/src/{ => shared}/utils.ts | 0 14 files changed, 118 insertions(+), 150 deletions(-) create mode 100644 packages/core/src/assets/fonts-inter.css delete mode 100644 packages/core/src/fonts-inter.css delete mode 100644 packages/core/src/globals.css delete mode 100644 packages/core/src/root.module.css rename packages/core/src/{ => shared}/EditorElement.ts (100%) rename packages/core/src/{ => shared}/utils.ts (100%) diff --git a/packages/core/src/BlockNoteEditor.ts b/packages/core/src/BlockNoteEditor.ts index 229baa5b79..a427625f94 100644 --- a/packages/core/src/BlockNoteEditor.ts +++ b/packages/core/src/BlockNoteEditor.ts @@ -9,7 +9,6 @@ import { DragHandleMenuFactory, } from "./extensions/DraggableBlocks/DragMenuFactoryTypes"; import { HyperlinkMenuFactory } from "./extensions/Hyperlinks/HyperlinkMenuFactoryTypes"; -import rootStyles from "./root.module.css"; import { SuggestionItem } from "./shared/plugins/suggestion/SuggestionItem"; import { SuggestionsMenuFactory } from "./shared/plugins/suggestion/SuggestionsMenuFactoryTypes"; @@ -97,7 +96,7 @@ export class BlockNoteEditor { ...(options.editorProps?.attributes || {}), class: [ styles.bnEditor, - rootStyles.bnRoot, + styles.bnRoot, (options.editorProps?.attributes as any)?.class || "", ].join(" "), }, diff --git a/packages/core/src/assets/fonts-inter.css b/packages/core/src/assets/fonts-inter.css new file mode 100644 index 0000000000..a074dfe49d --- /dev/null +++ b/packages/core/src/assets/fonts-inter.css @@ -0,0 +1,92 @@ +/* Generated using https://google-webfonts-helper.herokuapp.com/fonts/inter?subsets=latin */ + +/* inter-100 - latin */ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 100; + src: local(""), + url("./inter-v12-latin/inter-v12-latin-100.woff2") format("woff2"), + /* Chrome 26+, Opera 23+, Firefox 39+ */ + url("./inter-v12-latin/inter-v12-latin-100.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} +/* inter-200 - latin */ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 200; + src: local(""), + url("./inter-v12-latin/inter-v12-latin-200.woff2") format("woff2"), + /* Chrome 26+, Opera 23+, Firefox 39+ */ + url("./inter-v12-latin/inter-v12-latin-200.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} +/* inter-300 - latin */ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 300; + src: local(""), + url("./inter-v12-latin/inter-v12-latin-300.woff2") format("woff2"), + /* Chrome 26+, Opera 23+, Firefox 39+ */ + url("./inter-v12-latin/inter-v12-latin-300.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} +/* inter-regular - latin */ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + src: local(""), + url("./inter-v12-latin/inter-v12-latin-regular.woff2") format("woff2"), + /* Chrome 26+, Opera 23+, Firefox 39+ */ + url("./inter-v12-latin/inter-v12-latin-regular.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} +/* inter-500 - latin */ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 500; + src: local(""), + url("./inter-v12-latin/inter-v12-latin-500.woff2") format("woff2"), + /* Chrome 26+, Opera 23+, Firefox 39+ */ + url("./inter-v12-latin/inter-v12-latin-500.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} +/* inter-600 - latin */ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 600; + src: local(""), + url("./inter-v12-latin/inter-v12-latin-600.woff2") format("woff2"), + /* Chrome 26+, Opera 23+, Firefox 39+ */ + url("./inter-v12-latin/inter-v12-latin-600.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} +/* inter-700 - latin */ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 700; + src: local(""), + url("./inter-v12-latin/inter-v12-latin-700.woff2") format("woff2"), + /* Chrome 26+, Opera 23+, Firefox 39+ */ + url("./inter-v12-latin/inter-v12-latin-700.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} +/* inter-800 - latin */ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 800; + src: local(""), + url("./inter-v12-latin/inter-v12-latin-800.woff2") format("woff2"), + /* Chrome 26+, Opera 23+, Firefox 39+ */ + url("./inter-v12-latin/inter-v12-latin-800.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} +/* inter-900 - latin */ +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 900; + src: local(""), + url("./inter-v12-latin/inter-v12-latin-900.woff2") format("woff2"), + /* Chrome 26+, Opera 23+, Firefox 39+ */ + url("./inter-v12-latin/inter-v12-latin-900.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ +} diff --git a/packages/core/src/editor.module.css b/packages/core/src/editor.module.css index 78fa284a5a..47296e8811 100644 --- a/packages/core/src/editor.module.css +++ b/packages/core/src/editor.module.css @@ -1,3 +1,23 @@ .bnEditor { outline: none; } + +/* +bnRoot should be applied to all top-level elements + +This includes the Prosemirror editor, but also
element such as +Tippy popups that are appended to document.body directly +*/ +.bnRoot { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.bnRoot *, +.bnRoot *::before, +.bnRoot *::after { + -webkit-box-sizing: inherit; + -moz-box-sizing: inherit; + box-sizing: inherit; +} diff --git a/packages/core/src/extensions/BubbleMenu/BubbleMenuFactoryTypes.ts b/packages/core/src/extensions/BubbleMenu/BubbleMenuFactoryTypes.ts index 36fdbe7728..3fb9bbec8b 100644 --- a/packages/core/src/extensions/BubbleMenu/BubbleMenuFactoryTypes.ts +++ b/packages/core/src/extensions/BubbleMenu/BubbleMenuFactoryTypes.ts @@ -1,4 +1,4 @@ -import { EditorElement, ElementFactory } from "../../EditorElement"; +import { EditorElement, ElementFactory } from "../../shared/EditorElement"; export type BubbleMenuParams = { boldIsActive: boolean; diff --git a/packages/core/src/extensions/DraggableBlocks/DragMenuFactoryTypes.ts b/packages/core/src/extensions/DraggableBlocks/DragMenuFactoryTypes.ts index 715950f48c..96668e35eb 100644 --- a/packages/core/src/extensions/DraggableBlocks/DragMenuFactoryTypes.ts +++ b/packages/core/src/extensions/DraggableBlocks/DragMenuFactoryTypes.ts @@ -1,4 +1,4 @@ -import { EditorElement, ElementFactory } from "../../EditorElement"; +import { EditorElement, ElementFactory } from "../../shared/EditorElement"; export type AddBlockButtonParams = { addBlock: () => void; diff --git a/packages/core/src/extensions/Hyperlinks/HyperlinkMenuFactoryTypes.ts b/packages/core/src/extensions/Hyperlinks/HyperlinkMenuFactoryTypes.ts index efa75ed20c..3d45862a67 100644 --- a/packages/core/src/extensions/Hyperlinks/HyperlinkMenuFactoryTypes.ts +++ b/packages/core/src/extensions/Hyperlinks/HyperlinkMenuFactoryTypes.ts @@ -1,4 +1,4 @@ -import { EditorElement, ElementFactory } from "../../EditorElement"; +import { EditorElement, ElementFactory } from "../../shared/EditorElement"; export type HyperlinkMenuParams = { url: string; diff --git a/packages/core/src/extensions/SlashMenu/defaultCommands.tsx b/packages/core/src/extensions/SlashMenu/defaultCommands.tsx index 42ac95d2bd..cbd4c609e4 100644 --- a/packages/core/src/extensions/SlashMenu/defaultCommands.tsx +++ b/packages/core/src/extensions/SlashMenu/defaultCommands.tsx @@ -1,4 +1,4 @@ -import { formatKeyboardShortcut } from "../../utils"; +import { formatKeyboardShortcut } from "../../shared/utils"; import { SlashMenuGroups, SlashMenuItem } from "./SlashMenuItem"; /** diff --git a/packages/core/src/fonts-inter.css b/packages/core/src/fonts-inter.css deleted file mode 100644 index 8a2be5de51..0000000000 --- a/packages/core/src/fonts-inter.css +++ /dev/null @@ -1,94 +0,0 @@ -/* Generated using https://google-webfonts-helper.herokuapp.com/fonts/inter?subsets=latin */ - -/* inter-100 - latin */ -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 100; - src: local(""), - url("./assets/inter-v12-latin/inter-v12-latin-100.woff2") format("woff2"), - /* Chrome 26+, Opera 23+, Firefox 39+ */ - url("./assets/inter-v12-latin/inter-v12-latin-100.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ -} -/* inter-200 - latin */ -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 200; - src: local(""), - url("./assets/inter-v12-latin/inter-v12-latin-200.woff2") format("woff2"), - /* Chrome 26+, Opera 23+, Firefox 39+ */ - url("./assets/inter-v12-latin/inter-v12-latin-200.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ -} -/* inter-300 - latin */ -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 300; - src: local(""), - url("./assets/inter-v12-latin/inter-v12-latin-300.woff2") format("woff2"), - /* Chrome 26+, Opera 23+, Firefox 39+ */ - url("./assets/inter-v12-latin/inter-v12-latin-300.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ -} -/* inter-regular - latin */ -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 400; - src: local(""), - url("./assets/inter-v12-latin/inter-v12-latin-regular.woff2") - format("woff2"), - /* Chrome 26+, Opera 23+, Firefox 39+ */ - url("./assets/inter-v12-latin/inter-v12-latin-regular.woff") - format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ -} -/* inter-500 - latin */ -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 500; - src: local(""), - url("./assets/inter-v12-latin/inter-v12-latin-500.woff2") format("woff2"), - /* Chrome 26+, Opera 23+, Firefox 39+ */ - url("./assets/inter-v12-latin/inter-v12-latin-500.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ -} -/* inter-600 - latin */ -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 600; - src: local(""), - url("./assets/inter-v12-latin/inter-v12-latin-600.woff2") format("woff2"), - /* Chrome 26+, Opera 23+, Firefox 39+ */ - url("./assets/inter-v12-latin/inter-v12-latin-600.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ -} -/* inter-700 - latin */ -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 700; - src: local(""), - url("./assets/inter-v12-latin/inter-v12-latin-700.woff2") format("woff2"), - /* Chrome 26+, Opera 23+, Firefox 39+ */ - url("./assets/inter-v12-latin/inter-v12-latin-700.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ -} -/* inter-800 - latin */ -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 800; - src: local(""), - url("./assets/inter-v12-latin/inter-v12-latin-800.woff2") format("woff2"), - /* Chrome 26+, Opera 23+, Firefox 39+ */ - url("./assets/inter-v12-latin/inter-v12-latin-800.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ -} -/* inter-900 - latin */ -@font-face { - font-family: "Inter"; - font-style: normal; - font-weight: 900; - src: local(""), - url("./assets/inter-v12-latin/inter-v12-latin-900.woff2") format("woff2"), - /* Chrome 26+, Opera 23+, Firefox 39+ */ - url("./assets/inter-v12-latin/inter-v12-latin-900.woff") format("woff"); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ -} diff --git a/packages/core/src/globals.css b/packages/core/src/globals.css deleted file mode 100644 index 636c561a70..0000000000 --- a/packages/core/src/globals.css +++ /dev/null @@ -1,28 +0,0 @@ -@import url("fonts-inter.css"); - -/* TODO: should not be on root as this changes entire consuming application */ - -:root { - /* Define a set of colors to be used throughout the app for consistency - see https://atlassian.design/foundations/color for more info */ - --N800: #172b4d; /* Dark neutral used for tooltips and text on light background */ - --N40: #dfe1e6; /* Light neutral used for subtle borders and text on dark background */ - - font-family: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, - "Open Sans", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", - "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - color: rgb(60, 65, 73); -} - -button { - font-family: "Inter", "SF Pro Display", -apple-system, BlinkMacSystemFont, - "Open Sans", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", - "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - color: rgb(60, 65, 73); -} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 48cca1a6a1..1d9d832763 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,5 +1,3 @@ -import "./globals.css"; - export * from "./BlockNoteEditor"; export * from "./BlockNoteExtensions"; export * from "./extensions/BubbleMenu/BubbleMenuFactoryTypes"; diff --git a/packages/core/src/root.module.css b/packages/core/src/root.module.css deleted file mode 100644 index e2f9877bad..0000000000 --- a/packages/core/src/root.module.css +++ /dev/null @@ -1,19 +0,0 @@ -/* -bnRoot should be applied to all top-level elements - -This includes the Prosemirror editor, but also
element such as -Tippy popups that are appended to document.body directly -*/ -.bnRoot { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} - -.bnRoot *, -.bnRoot *::before, -.bnRoot *::after { - -webkit-box-sizing: inherit; - -moz-box-sizing: inherit; - box-sizing: inherit; -} diff --git a/packages/core/src/EditorElement.ts b/packages/core/src/shared/EditorElement.ts similarity index 100% rename from packages/core/src/EditorElement.ts rename to packages/core/src/shared/EditorElement.ts diff --git a/packages/core/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.ts b/packages/core/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.ts index 2a7e736f64..dd8b1399ef 100644 --- a/packages/core/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.ts +++ b/packages/core/src/shared/plugins/suggestion/SuggestionsMenuFactoryTypes.ts @@ -1,5 +1,5 @@ +import { EditorElement, ElementFactory } from "../../EditorElement"; import { SuggestionItem } from "./SuggestionItem"; -import { EditorElement, ElementFactory } from "../../../EditorElement"; export type SuggestionsMenuParams = { items: T[]; diff --git a/packages/core/src/utils.ts b/packages/core/src/shared/utils.ts similarity index 100% rename from packages/core/src/utils.ts rename to packages/core/src/shared/utils.ts