diff --git a/docs/pages/docs/advanced/vanilla-js.mdx b/docs/pages/docs/advanced/vanilla-js.mdx
index 0921d07b11..6c0981696b 100644
--- a/docs/pages/docs/advanced/vanilla-js.mdx
+++ b/docs/pages/docs/advanced/vanilla-js.mdx
@@ -49,7 +49,7 @@ While it's up to you to decide how you want the elements to be rendered, BlockNo
```typescript
type UIElement =
| "formattingToolbar"
- | "hyperlinkToolbar"
+ | "linkToolbar"
| "imageToolbar"
| "sideMenu"
| "suggestionMenu"
diff --git a/docs/pages/docs/editor-basics/setup.mdx b/docs/pages/docs/editor-basics/setup.mdx
index 220a1ab91a..eddf89a58b 100644
--- a/docs/pages/docs/editor-basics/setup.mdx
+++ b/docs/pages/docs/editor-basics/setup.mdx
@@ -87,7 +87,7 @@ export type BlockNoteViewProps = {
dark: Theme;
};
formattingToolbar?: boolean;
- hyperlinkToolbar?: boolean;
+ linkToolbar?: boolean;
sideMenu?: boolean;
slashMenu?: boolean;
imageToolbar?: boolean;
@@ -108,7 +108,7 @@ export type BlockNoteViewProps = {
`formattingToolbar`: Whether the [Formatting Toolbar](/docs/ui-components/formatting-toolbar) should be enabled.
-`hyperlinkToolbar`: Whether the Hyperlink Toolbar should be enabled.
+`linkToolbar`: Whether the Link Toolbar should be enabled.
`sideMenu`: Whether the [Block Side Menu](/docs/ui-components/side-menu) should be enabled.
diff --git a/docs/pages/docs/styling-theming/overriding-css.mdx b/docs/pages/docs/styling-theming/overriding-css.mdx
index 2f926f1ca2..dffa489a17 100644
--- a/docs/pages/docs/styling-theming/overriding-css.mdx
+++ b/docs/pages/docs/styling-theming/overriding-css.mdx
@@ -31,7 +31,7 @@ Within the editor's DOM structure, you'll find many elements have classes with t
`.bn-inline-content`: Element for only the block's editable, rich text content.
-`.bn-toolbar`: Element for the formatting & hyperlink toolbars.
+`.bn-toolbar`: Element for the formatting & link toolbars.
`.bn-side-menu`: Element for the side menu.
diff --git a/docs/pages/docs/ui-components.mdx b/docs/pages/docs/ui-components.mdx
index ece58c1632..b6073d6b38 100644
--- a/docs/pages/docs/ui-components.mdx
+++ b/docs/pages/docs/ui-components.mdx
@@ -12,5 +12,5 @@ BlockNote includes a number of UI Components (like menus and toolbars) that can
- [Block Side Menu](/docs/ui-components/side-menu)
- [Formatting Toolbar](/docs/ui-components/formatting-toolbar)
- [Suggestion Menus](/docs/ui-components/suggestion-menus)
- {/* - Hyperlink Toolbar */}
+ {/* - Link Toolbar */}
{/* - [Image Toolbar](/docs/ui-components/image-toolbar) */}
diff --git a/docs/pages/docs/ui-components/_meta.json b/docs/pages/docs/ui-components/_meta.json
index 850fab1a9d..5784d1ed55 100644
--- a/docs/pages/docs/ui-components/_meta.json
+++ b/docs/pages/docs/ui-components/_meta.json
@@ -1,8 +1,8 @@
{
"side-menu": "Block Side Menu",
"formatting-toolbar": "Formatting Toolbar",
- "hyperlink-toolbar": {
- "title": "Hyperlink Toolbar",
+ "link-toolbar": {
+ "title": "Link Toolbar",
"display": "hidden"
},
"image-toolbar": {
diff --git a/docs/pages/docs/ui-components/formatting-toolbar.mdx b/docs/pages/docs/ui-components/formatting-toolbar.mdx
index e9e2559ee4..2f2ee74ad3 100644
--- a/docs/pages/docs/ui-components/formatting-toolbar.mdx
+++ b/docs/pages/docs/ui-components/formatting-toolbar.mdx
@@ -32,16 +32,16 @@ Setting `formattingToolbar={false}` on `BlockNoteView` tells BlockNote not to sh
Tip: The children you pass to the `FormattingToolbar` component
- should be default dropdowns/buttons (e.g. `BlockTypeDropdown` & `BasicTextStyleButton`) or custom dropdowns/buttons
- (`ToolbarDropdown` & `ToolbarButton`). To see all the components you can use, head to the
+ should be default selects/buttons (e.g. `BlockTypeSelect` & `BasicTextStyleButton`) or custom selects/buttons
+ (`ToolbarSelect` & `ToolbarButton`). To see all the components you can use, head to the
[Formatting Toolbar's source code](https://github.com/TypeCellOS/BlockNote/blob/main/packages/react/src/components/FormattingToolbar/mantine/FormattingToolbar.tsx).
-## Changing Block Type Dropdown Items
+## Changing Block Type Select (Dropdown) Items
-The first element in the default Formatting Toolbar is the Block Type Dropdown, and you can change the items in it. The demo makes the Block Type Dropdown work for image blocks by adding an item to it.
+The first element in the default Formatting Toolbar is the Block Type Select, and you can change the items in it. The demo makes the Block Type Select work for image blocks by adding an item to it.
-Here, we use the `FormattingToolbar` component but keep the default buttons (we don't pass any children). Instead, we pass our customized Block Type Dropdown items using the `blockTypeDropdownItems` prop.
+Here, we use the `FormattingToolbar` component but keep the default buttons (we don't pass any children). Instead, we pass our customized Block Type Select items using the `blockTypeSelectItems` prop.
diff --git a/docs/pages/docs/ui-components/hyperlink-toolbar.mdx b/docs/pages/docs/ui-components/hyperlink-toolbar.mdx
index e7f5418139..2f1ea13f49 100644
--- a/docs/pages/docs/ui-components/hyperlink-toolbar.mdx
+++ b/docs/pages/docs/ui-components/hyperlink-toolbar.mdx
@@ -1,37 +1,37 @@
---
-title: Hyperlink Toolbar
-description: The Hyperlink Toolbar appears whenever you hover a link in the editor.
-imageTitle: Hyperlink Toolbar
-path: /docs/hyperlink-toolbar
+title: Link Toolbar
+description: The Link Toolbar appears whenever you hover a link in the editor.
+imageTitle: Link Toolbar
+path: /docs/link-toolbar
---
import { Example } from "@/components/example";
-# Hyperlink Toolbar
+# Link Toolbar
-The Hyperlink Toolbar appears whenever you hover a link in the editor.
+The Link Toolbar appears whenever you hover a link in the editor.
TODO Image
-[//]: # ''
+[//]: # ''
-## Changing the Hyperlink Toolbar
+## Changing the Link Toolbar
-You can change or replace the Hyperlink Toolbar with your own React component. In the demo below, a button is added to the default Hyperlink Toolbar, which opens a browser alert.
+You can change or replace the Link Toolbar with your own React component. In the demo below, a button is added to the default Link Toolbar, which opens a browser alert.
-[//]: # ()
+[//]: # ()
-We use the `HyperlinkToolbar` component to create a custom Hyperlink Toolbar. By specifying its children, we can replace the default buttons in the toolbar with our own.
+We use the `LinkToolbar` component to create a custom Link Toolbar. By specifying its children, we can replace the default buttons in the toolbar with our own.
-This custom Hyperlink Toolbar is passed to a `HyperlinkToolbarController`, which controls its position and visibility (above or below the hovered link).
+This custom Link Toolbar is passed to a `LinkToolbarController`, which controls its position and visibility (above or below the hovered link).
-Setting `hyperlinkToolbar={false}` on `BlockNoteView` tells BlockNote not to show the default Hyperlink Toolbar.
+Setting `linkToolbar={false}` on `BlockNoteView` tells BlockNote not to show the default Link Toolbar.
- Tip: The children you pass to the `HyperlinkToolbar`
- component should be default buttons (e.g. TODO) or custom dropdowns/buttons
- (`ToolbarDropdown` & `ToolbarButton`). To see all the components you can
- use, head to the [Hyperlink Toolbar's source code](link).
+ Tip: The children you pass to the `LinkToolbar`
+ component should be default buttons (e.g. TODO) or custom selects/buttons
+ (`ToolbarSelect` & `ToolbarButton`). To see all the components you can
+ use, head to the [Link Toolbar's source code](link).
diff --git a/examples/02-ui-components/01-ui-elements-remove/App.tsx b/examples/02-ui-components/01-ui-elements-remove/App.tsx
index 1c5dbfd0f8..0f67fdc449 100644
--- a/examples/02-ui-components/01-ui-elements-remove/App.tsx
+++ b/examples/02-ui-components/01-ui-elements-remove/App.tsx
@@ -32,7 +32,7 @@ export default function App() {
editor={editor}
// Removes all menus and toolbars.
formattingToolbar={false}
- hyperlinkToolbar={false}
+ linkToolbar={false}
imageToolbar={false}
sideMenu={false}
slashMenu={false}
diff --git a/examples/02-ui-components/02-formatting-toolbar-buttons/App.tsx b/examples/02-ui-components/02-formatting-toolbar-buttons/App.tsx
index e34a0d9cdf..8f44929e33 100644
--- a/examples/02-ui-components/02-formatting-toolbar-buttons/App.tsx
+++ b/examples/02-ui-components/02-formatting-toolbar-buttons/App.tsx
@@ -2,7 +2,7 @@ import "@blocknote/core/fonts/inter.css";
import {
BasicTextStyleButton,
BlockNoteView,
- BlockTypeDropdown,
+ BlockTypeSelect,
ColorStyleButton,
CreateLinkButton,
FormattingToolbar,
@@ -72,7 +72,7 @@ export default function App() {
(
-
+
{/* Extra button to toggle blue text & background */}
diff --git a/examples/02-ui-components/03-formatting-toolbar-block-type-items/App.tsx b/examples/02-ui-components/03-formatting-toolbar-block-type-items/App.tsx
index 315e4afc5b..0ede58d56e 100644
--- a/examples/02-ui-components/03-formatting-toolbar-block-type-items/App.tsx
+++ b/examples/02-ui-components/03-formatting-toolbar-block-type-items/App.tsx
@@ -2,11 +2,11 @@ import { BlockNoteSchema, defaultBlockSpecs } from "@blocknote/core";
import "@blocknote/core/fonts/inter.css";
import {
BlockNoteView,
- BlockTypeDropdownItem,
FormattingToolbar,
FormattingToolbarController,
- blockTypeDropdownItems,
useCreateBlockNote,
+ blockTypeSelectItems,
+ BlockTypeSelectItem,
} from "@blocknote/react";
import "@blocknote/react/style.css";
import { RiAlertFill } from "react-icons/ri";
@@ -36,12 +36,12 @@ export default function App() {
{
type: "paragraph",
content:
- "Try selecting some text - you'll see the new 'Alert' item in the Block Type Dropdown",
+ "Try selecting some text - you'll see the new 'Alert' item in the Block Type Select",
},
{
type: "alert",
content:
- "Or select text in this alert - the Block Type Dropdown also appears",
+ "Or select text in this alert - the Block Type Select also appears",
},
{
type: "paragraph",
@@ -49,20 +49,20 @@ export default function App() {
],
});
- // Renders the editor instance with the updated Block Type Dropdown.
+ // Renders the editor instance with the updated Block Type Select.
return (
(
block.type === "alert",
- } satisfies BlockTypeDropdownItem,
+ } satisfies BlockTypeSelectItem,
]}
/>
)}
diff --git a/examples/02-ui-components/03-formatting-toolbar-block-type-items/README.md b/examples/02-ui-components/03-formatting-toolbar-block-type-items/README.md
index 28a7a27833..005e3bc916 100644
--- a/examples/02-ui-components/03-formatting-toolbar-block-type-items/README.md
+++ b/examples/02-ui-components/03-formatting-toolbar-block-type-items/README.md
@@ -1,11 +1,11 @@
-# Adding Block Type Dropdown Items
+# Adding Block Type Select Items
-In this example, we add an item to the Block Type Dropdown, so that it works for a custom alert block we create.
+In this example, we add an item to the Block Type Select, so that it works for a custom alert block we create.
-**Try it out:** Select some text to open the Formatting Toolbar, and click "Alert" in the Block Type Dropdown to change the selected block!
+**Try it out:** Select some text to open the Formatting Toolbar, and click "Alert" in the Block Type Select to change the selected block!
**Relevant Docs:**
-- [Changing Block Type Dropdown Items](/docs/ui-components/formatting-toolbar#changing-block-type-dropdown-items)
+- [Changing Block Type Select Items](/docs/ui-components/formatting-toolbar#changing-block-type-select-items)
- [Custom Block Types](/docs/custom-schemas/custom-blocks)
- [Editor Setup](/docs/editor-basics/setup)
\ No newline at end of file
diff --git a/examples/02-ui-components/03-formatting-toolbar-block-type-items/index.html b/examples/02-ui-components/03-formatting-toolbar-block-type-items/index.html
index 258dfd61f4..1e84936eca 100644
--- a/examples/02-ui-components/03-formatting-toolbar-block-type-items/index.html
+++ b/examples/02-ui-components/03-formatting-toolbar-block-type-items/index.html
@@ -5,7 +5,7 @@
- Adding Block Type Dropdown Items
+ Adding Block Type Select Items
diff --git a/examples/02-ui-components/hyperlink-toolbar-buttons/README.md b/examples/02-ui-components/hyperlink-toolbar-buttons/README.md
deleted file mode 100644
index af0cbc607a..0000000000
--- a/examples/02-ui-components/hyperlink-toolbar-buttons/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# Adding Hyperlink Toolbar Buttons
-
-In this example, we add a button to the Hyperlink Toolbar which opens a browser alert.
-
-**Try it out:** Hover the link open the Hyperlink Toolbar, and click the new "Open Alert" button!
-
-**Relevant Docs:**
-
-- [Changing the Hyperlink Toolbar](/docs/ui-components/hyperlink-toolbar#changing-the-hyperlink-toolbar)
-- [Editor Setup](/docs/editor-basics/setup)
\ No newline at end of file
diff --git a/examples/02-ui-components/hyperlink-toolbar-buttons/.bnexample.json b/examples/02-ui-components/link-toolbar-buttons/.bnexample.json
similarity index 100%
rename from examples/02-ui-components/hyperlink-toolbar-buttons/.bnexample.json
rename to examples/02-ui-components/link-toolbar-buttons/.bnexample.json
diff --git a/examples/02-ui-components/hyperlink-toolbar-buttons/AlertButton.tsx b/examples/02-ui-components/link-toolbar-buttons/AlertButton.tsx
similarity index 50%
rename from examples/02-ui-components/hyperlink-toolbar-buttons/AlertButton.tsx
rename to examples/02-ui-components/link-toolbar-buttons/AlertButton.tsx
index bdf9640b4b..123d856b0e 100644
--- a/examples/02-ui-components/hyperlink-toolbar-buttons/AlertButton.tsx
+++ b/examples/02-ui-components/link-toolbar-buttons/AlertButton.tsx
@@ -1,7 +1,7 @@
-import { HyperlinkToolbarProps, ToolbarButton } from "@blocknote/react";
+import { LinkToolbarProps, ToolbarButton } from "@blocknote/react";
-// Custom Hyperlink Toolbar button to open a browser alert.
-export function AlertButton(props: HyperlinkToolbarProps) {
+// Custom Link Toolbar button to open a browser alert.
+export function AlertButton(props: LinkToolbarProps) {
return (
- (
-
+
+ (
+
-
+
)}
/>
diff --git a/examples/02-ui-components/link-toolbar-buttons/README.md b/examples/02-ui-components/link-toolbar-buttons/README.md
new file mode 100644
index 0000000000..2257f47059
--- /dev/null
+++ b/examples/02-ui-components/link-toolbar-buttons/README.md
@@ -0,0 +1,10 @@
+# Adding Link Toolbar Buttons
+
+In this example, we add a button to the Link Toolbar which opens a browser alert.
+
+**Try it out:** Hover the link open the Link Toolbar, and click the new "Open Alert" button!
+
+**Relevant Docs:**
+
+- [Changing the Link Toolbar](/docs/ui-components/link-toolbar#changing-the-link-toolbar)
+- [Editor Setup](/docs/editor-basics/setup)
\ No newline at end of file
diff --git a/examples/02-ui-components/hyperlink-toolbar-buttons/index.html b/examples/02-ui-components/link-toolbar-buttons/index.html
similarity index 86%
rename from examples/02-ui-components/hyperlink-toolbar-buttons/index.html
rename to examples/02-ui-components/link-toolbar-buttons/index.html
index b30eb96292..c7356c7253 100644
--- a/examples/02-ui-components/hyperlink-toolbar-buttons/index.html
+++ b/examples/02-ui-components/link-toolbar-buttons/index.html
@@ -5,7 +5,7 @@
- Adding Hyperlink Toolbar Buttons
+ Adding Link Toolbar Buttons
diff --git a/examples/02-ui-components/hyperlink-toolbar-buttons/main.tsx b/examples/02-ui-components/link-toolbar-buttons/main.tsx
similarity index 100%
rename from examples/02-ui-components/hyperlink-toolbar-buttons/main.tsx
rename to examples/02-ui-components/link-toolbar-buttons/main.tsx
diff --git a/examples/02-ui-components/hyperlink-toolbar-buttons/package.json b/examples/02-ui-components/link-toolbar-buttons/package.json
similarity index 92%
rename from examples/02-ui-components/hyperlink-toolbar-buttons/package.json
rename to examples/02-ui-components/link-toolbar-buttons/package.json
index 840d70465b..470ec0c68f 100644
--- a/examples/02-ui-components/hyperlink-toolbar-buttons/package.json
+++ b/examples/02-ui-components/link-toolbar-buttons/package.json
@@ -1,5 +1,5 @@
{
- "name": "@blocknote/example-hyperlink-toolbar-buttons",
+ "name": "@blocknote/example-link-toolbar-buttons",
"description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY",
"private": true,
"version": "0.12.0",
diff --git a/examples/02-ui-components/hyperlink-toolbar-buttons/tsconfig.json b/examples/02-ui-components/link-toolbar-buttons/tsconfig.json
similarity index 100%
rename from examples/02-ui-components/hyperlink-toolbar-buttons/tsconfig.json
rename to examples/02-ui-components/link-toolbar-buttons/tsconfig.json
diff --git a/examples/02-ui-components/hyperlink-toolbar-buttons/vite.config.ts b/examples/02-ui-components/link-toolbar-buttons/vite.config.ts
similarity index 100%
rename from examples/02-ui-components/hyperlink-toolbar-buttons/vite.config.ts
rename to examples/02-ui-components/link-toolbar-buttons/vite.config.ts
diff --git a/examples/05-custom-schema/03-font-style/App.tsx b/examples/05-custom-schema/03-font-style/App.tsx
index 1b8c79a96f..edb7f96322 100644
--- a/examples/05-custom-schema/03-font-style/App.tsx
+++ b/examples/05-custom-schema/03-font-style/App.tsx
@@ -3,7 +3,7 @@ import "@blocknote/core/fonts/inter.css";
import {
BasicTextStyleButton,
BlockNoteView,
- BlockTypeDropdown,
+ BlockTypeSelect,
ColorStyleButton,
CreateLinkButton,
FormattingToolbar,
@@ -99,7 +99,7 @@ export default function App() {
(
-
+
diff --git a/packages/core/src/blocks/ImageBlockContent/ImageBlockContent.ts b/packages/core/src/blocks/ImageBlockContent/ImageBlockContent.ts
index 8bfc3d4678..21f8eeeb00 100644
--- a/packages/core/src/blocks/ImageBlockContent/ImageBlockContent.ts
+++ b/packages/core/src/blocks/ImageBlockContent/ImageBlockContent.ts
@@ -234,7 +234,7 @@ export const renderImage = (
// Opens the image toolbar.
const addImageButtonClickHandler = () => {
editor._tiptapEditor.view.dispatch(
- editor._tiptapEditor.state.tr.setMeta(editor.imageToolbar!.plugin, {
+ editor._tiptapEditor.state.tr.setMeta(editor.imagePanel!.plugin, {
block: block,
})
);
diff --git a/packages/core/src/editor/BlockNoteEditor.ts b/packages/core/src/editor/BlockNoteEditor.ts
index 659e9ff823..001782123b 100644
--- a/packages/core/src/editor/BlockNoteEditor.ts
+++ b/packages/core/src/editor/BlockNoteEditor.ts
@@ -27,10 +27,10 @@ import {
PartialBlock,
} from "../blocks/defaultBlocks";
import { FormattingToolbarProsemirrorPlugin } from "../extensions/FormattingToolbar/FormattingToolbarPlugin";
-import { HyperlinkToolbarProsemirrorPlugin } from "../extensions/HyperlinkToolbar/HyperlinkToolbarPlugin";
-import { ImageToolbarProsemirrorPlugin } from "../extensions/ImageToolbar/ImageToolbarPlugin";
+import { LinkToolbarProsemirrorPlugin } from "../extensions/LinkToolbar/LinkToolbarPlugin";
import { SideMenuProsemirrorPlugin } from "../extensions/SideMenu/SideMenuPlugin";
import { SuggestionMenuProseMirrorPlugin } from "../extensions/SuggestionMenu/SuggestionPlugin";
+import { ImagePanelProsemirrorPlugin } from "../extensions/ImagePanel/ImageToolbarPlugin";
import { TableHandlesProsemirrorPlugin } from "../extensions/TableHandles/TableHandlesPlugin";
import { UniqueID } from "../extensions/UniqueID/UniqueID";
import {
@@ -54,14 +54,15 @@ import { TextCursorPosition } from "./cursorPositionTypes";
import { Selection } from "./selectionTypes";
import { transformPasted } from "./transformPasted";
-// CSS
import { checkDefaultBlockTypeInSchema } from "../blocks/defaultBlockTypeGuards";
-import "./Block.css";
import { BlockNoteSchema } from "./BlockNoteSchema";
import {
BlockNoteTipTapEditor,
BlockNoteTipTapEditorOptions,
} from "./BlockNoteTipTapEditor";
+
+// CSS
+import "./Block.css";
import "./editor.css";
export type BlockNoteEditorOptions<
@@ -156,7 +157,7 @@ export class BlockNoteEditor<
public readonly styleImplementations: StyleSpecs;
public readonly formattingToolbar: FormattingToolbarProsemirrorPlugin;
- public readonly hyperlinkToolbar: HyperlinkToolbarProsemirrorPlugin<
+ public readonly linkToolbar: LinkToolbarProsemirrorPlugin<
BSchema,
ISchema,
SSchema
@@ -171,10 +172,7 @@ export class BlockNoteEditor<
ISchema,
SSchema
>;
- public readonly imageToolbar?: ImageToolbarProsemirrorPlugin<
- ISchema,
- SSchema
- >;
+ public readonly imagePanel?: ImagePanelProsemirrorPlugin;
public readonly tableHandles?: TableHandlesProsemirrorPlugin<
ISchema,
SSchema
@@ -232,12 +230,12 @@ export class BlockNoteEditor<
this.styleImplementations = newOptions.schema.styleSpecs;
this.formattingToolbar = new FormattingToolbarProsemirrorPlugin(this);
- this.hyperlinkToolbar = new HyperlinkToolbarProsemirrorPlugin(this);
+ this.linkToolbar = new LinkToolbarProsemirrorPlugin(this);
this.sideMenu = new SideMenuProsemirrorPlugin(this);
this.suggestionMenus = new SuggestionMenuProseMirrorPlugin(this);
if (checkDefaultBlockTypeInSchema("image", this)) {
// Type guards only work on `const`s? Not working for `this`
- this.imageToolbar = new ImageToolbarProsemirrorPlugin(this as any);
+ this.imagePanel = new ImagePanelProsemirrorPlugin(this as any);
}
if (checkDefaultBlockTypeInSchema("table", this)) {
this.tableHandles = new TableHandlesProsemirrorPlugin(this as any);
@@ -260,10 +258,10 @@ export class BlockNoteEditor<
addProseMirrorPlugins: () => {
return [
this.formattingToolbar.plugin,
- this.hyperlinkToolbar.plugin,
+ this.linkToolbar.plugin,
this.sideMenu.plugin,
this.suggestionMenus.plugin,
- ...(this.imageToolbar ? [this.imageToolbar.plugin] : []),
+ ...(this.imagePanel ? [this.imagePanel.plugin] : []),
...(this.tableHandles ? [this.tableHandles.plugin] : []),
];
},
diff --git a/packages/core/src/extensions/ImageToolbar/ImageToolbarPlugin.ts b/packages/core/src/extensions/ImagePanel/ImageToolbarPlugin.ts
similarity index 87%
rename from packages/core/src/extensions/ImageToolbar/ImageToolbarPlugin.ts
rename to packages/core/src/extensions/ImagePanel/ImageToolbarPlugin.ts
index 26a28c13c2..516f7f2852 100644
--- a/packages/core/src/extensions/ImageToolbar/ImageToolbarPlugin.ts
+++ b/packages/core/src/extensions/ImagePanel/ImageToolbarPlugin.ts
@@ -11,7 +11,7 @@ import { UiElementPosition } from "../../extensions-shared/UiElementPosition";
import { EventEmitter } from "../../util/EventEmitter";
import { DefaultBlockSchema } from "../../blocks/defaultBlocks";
-export type ImageToolbarState<
+export type ImagePanelState<
I extends InlineContentSchema,
S extends StyleSchema
> = UiElementPosition & {
@@ -19,11 +19,11 @@ export type ImageToolbarState<
block: BlockFromConfig;
};
-export class ImageToolbarView<
+export class ImagePanelView<
I extends InlineContentSchema,
S extends StyleSchema
> {
- public state?: ImageToolbarState;
+ public state?: ImagePanelState;
public emitUpdate: () => void;
public prevWasEditable: boolean | null = null;
@@ -31,11 +31,11 @@ export class ImageToolbarView<
constructor(
private readonly pluginKey: PluginKey,
private readonly pmView: EditorView,
- emitUpdate: (state: ImageToolbarState) => void
+ emitUpdate: (state: ImagePanelState) => void
) {
this.emitUpdate = () => {
if (!this.state) {
- throw new Error("Attempting to update uninitialized image toolbar");
+ throw new Error("Attempting to update uninitialized image panel");
}
emitUpdate(this.state);
@@ -69,7 +69,7 @@ export class ImageToolbarView<
const editorWrapper = this.pmView.dom.parentElement!;
// Checks if the focus is moving to an element outside the editor. If it is,
- // the toolbar is hidden.
+ // the panel is hidden.
if (
// An element is clicked.
event &&
@@ -142,13 +142,13 @@ export class ImageToolbarView<
}
}
-const imageToolbarPluginKey = new PluginKey("ImageToolbarPlugin");
+const imagePanelPluginKey = new PluginKey("ImagePanelPlugin");
-export class ImageToolbarProsemirrorPlugin<
+export class ImagePanelProsemirrorPlugin<
I extends InlineContentSchema,
S extends StyleSchema
> extends EventEmitter {
- private view: ImageToolbarView | undefined;
+ private view: ImagePanelView | undefined;
public readonly plugin: Plugin;
constructor(
@@ -158,11 +158,11 @@ export class ImageToolbarProsemirrorPlugin<
this.plugin = new Plugin<{
block: BlockFromConfig | undefined;
}>({
- key: imageToolbarPluginKey,
+ key: imagePanelPluginKey,
view: (editorView) => {
- this.view = new ImageToolbarView(
+ this.view = new ImagePanelView(
// editor,
- imageToolbarPluginKey,
+ imagePanelPluginKey,
editorView,
(state) => {
this.emit("update", state);
@@ -179,7 +179,7 @@ export class ImageToolbarProsemirrorPlugin<
apply: (transaction) => {
const block:
| BlockFromConfig
- | undefined = transaction.getMeta(imageToolbarPluginKey)?.block;
+ | undefined = transaction.getMeta(imagePanelPluginKey)?.block;
return {
block,
@@ -189,7 +189,7 @@ export class ImageToolbarProsemirrorPlugin<
});
}
- public onUpdate(callback: (state: ImageToolbarState) => void) {
+ public onUpdate(callback: (state: ImagePanelState) => void) {
return this.on("update", callback);
}
}
diff --git a/packages/core/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts b/packages/core/src/extensions/LinkToolbar/LinkToolbarPlugin.ts
similarity index 55%
rename from packages/core/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts
rename to packages/core/src/extensions/LinkToolbar/LinkToolbarPlugin.ts
index c0d524c0b4..7fd9cde3a4 100644
--- a/packages/core/src/extensions/HyperlinkToolbar/HyperlinkToolbarPlugin.ts
+++ b/packages/core/src/extensions/LinkToolbar/LinkToolbarPlugin.ts
@@ -8,38 +8,38 @@ import { BlockSchema, InlineContentSchema, StyleSchema } from "../../schema";
import { UiElementPosition } from "../../extensions-shared/UiElementPosition";
import { EventEmitter } from "../../util/EventEmitter";
-export type HyperlinkToolbarState = UiElementPosition & {
- // The hovered hyperlink's URL, and the text it's displayed with in the
+export type LinkToolbarState = UiElementPosition & {
+ // The hovered link's URL, and the text it's displayed with in the
// editor.
url: string;
text: string;
};
-class HyperlinkToolbarView {
- public state?: HyperlinkToolbarState;
+class LinkToolbarView {
+ public state?: LinkToolbarState;
public emitUpdate: () => void;
menuUpdateTimer: ReturnType | undefined;
startMenuUpdateTimer: () => void;
stopMenuUpdateTimer: () => void;
- mouseHoveredHyperlinkMark: Mark | undefined;
- mouseHoveredHyperlinkMarkRange: Range | undefined;
+ mouseHoveredLinkMark: Mark | undefined;
+ mouseHoveredLinkMarkRange: Range | undefined;
- keyboardHoveredHyperlinkMark: Mark | undefined;
- keyboardHoveredHyperlinkMarkRange: Range | undefined;
+ keyboardHoveredLinkMark: Mark | undefined;
+ keyboardHoveredLinkMarkRange: Range | undefined;
- hyperlinkMark: Mark | undefined;
- hyperlinkMarkRange: Range | undefined;
+ linkMark: Mark | undefined;
+ linkMarkRange: Range | undefined;
constructor(
private readonly editor: BlockNoteEditor,
private readonly pmView: EditorView,
- emitUpdate: (state: HyperlinkToolbarState) => void
+ emitUpdate: (state: LinkToolbarState) => void
) {
this.emitUpdate = () => {
if (!this.state) {
- throw new Error("Attempting to update uninitialized hyperlink toolbar");
+ throw new Error("Attempting to update uninitialized link toolbar");
}
emitUpdate(this.state);
@@ -66,9 +66,9 @@ class HyperlinkToolbarView {
}
mouseOverHandler = (event: MouseEvent) => {
- // Resets the hyperlink mark currently hovered by the mouse cursor.
- this.mouseHoveredHyperlinkMark = undefined;
- this.mouseHoveredHyperlinkMarkRange = undefined;
+ // Resets the link mark currently hovered by the mouse cursor.
+ this.mouseHoveredLinkMark = undefined;
+ this.mouseHoveredLinkMarkRange = undefined;
this.stopMenuUpdateTimer();
@@ -76,27 +76,23 @@ class HyperlinkToolbarView {
event.target instanceof HTMLAnchorElement &&
event.target.nodeName === "A"
) {
- // Finds link mark at the hovered element's position to update mouseHoveredHyperlinkMark and
- // mouseHoveredHyperlinkMarkRange.
- const hoveredHyperlinkElement = event.target;
- const posInHoveredHyperlinkMark =
- this.pmView.posAtDOM(hoveredHyperlinkElement, 0) + 1;
- const resolvedPosInHoveredHyperlinkMark = this.pmView.state.doc.resolve(
- posInHoveredHyperlinkMark
- );
- const marksAtPos = resolvedPosInHoveredHyperlinkMark.marks();
+ // Finds link mark at the hovered element's position to update mouseHoveredLinkMark and
+ // mouseHoveredLinkMarkRange.
+ const hoveredLinkElement = event.target;
+ const posInHoveredLinkMark =
+ this.pmView.posAtDOM(hoveredLinkElement, 0) + 1;
+ const resolvedPosInHoveredLinkMark =
+ this.pmView.state.doc.resolve(posInHoveredLinkMark);
+ const marksAtPos = resolvedPosInHoveredLinkMark.marks();
for (const mark of marksAtPos) {
if (
mark.type.name === this.pmView.state.schema.mark("link").type.name
) {
- this.mouseHoveredHyperlinkMark = mark;
- this.mouseHoveredHyperlinkMarkRange =
- getMarkRange(
- resolvedPosInHoveredHyperlinkMark,
- mark.type,
- mark.attrs
- ) || undefined;
+ this.mouseHoveredLinkMark = mark;
+ this.mouseHoveredLinkMarkRange =
+ getMarkRange(resolvedPosInHoveredLinkMark, mark.type, mark.attrs) ||
+ undefined;
break;
}
@@ -113,7 +109,7 @@ class HyperlinkToolbarView {
if (
// Toolbar is open.
- this.hyperlinkMark &&
+ this.linkMark &&
// An element is clicked.
event &&
event.target &&
@@ -131,27 +127,27 @@ class HyperlinkToolbarView {
};
scrollHandler = () => {
- if (this.hyperlinkMark !== undefined) {
+ if (this.linkMark !== undefined) {
if (this.state?.show) {
this.state.referencePos = posToDOMRect(
this.pmView,
- this.hyperlinkMarkRange!.from,
- this.hyperlinkMarkRange!.to
+ this.linkMarkRange!.from,
+ this.linkMarkRange!.to
);
this.emitUpdate();
}
}
};
- editHyperlink(url: string, text: string) {
+ editLink(url: string, text: string) {
const tr = this.pmView.state.tr.insertText(
text,
- this.hyperlinkMarkRange!.from,
- this.hyperlinkMarkRange!.to
+ this.linkMarkRange!.from,
+ this.linkMarkRange!.to
);
tr.addMark(
- this.hyperlinkMarkRange!.from,
- this.hyperlinkMarkRange!.from + text.length,
+ this.linkMarkRange!.from,
+ this.linkMarkRange!.from + text.length,
this.pmView.state.schema.mark("link", { href: url })
);
this.pmView.dispatch(tr);
@@ -163,13 +159,13 @@ class HyperlinkToolbarView {
}
}
- deleteHyperlink() {
+ deleteLink() {
this.pmView.dispatch(
this.pmView.state.tr
.removeMark(
- this.hyperlinkMarkRange!.from,
- this.hyperlinkMarkRange!.to,
- this.hyperlinkMark!.type
+ this.linkMarkRange!.from,
+ this.linkMarkRange!.to,
+ this.linkMark!.type
)
.setMeta("preventAutolink", true)
);
@@ -186,19 +182,19 @@ class HyperlinkToolbarView {
return;
}
- // Saves the currently hovered hyperlink mark before it's updated.
- const prevHyperlinkMark = this.hyperlinkMark;
+ // Saves the currently hovered link mark before it's updated.
+ const prevLinkMark = this.linkMark;
- // Resets the currently hovered hyperlink mark.
- this.hyperlinkMark = undefined;
- this.hyperlinkMarkRange = undefined;
+ // Resets the currently hovered link mark.
+ this.linkMark = undefined;
+ this.linkMarkRange = undefined;
- // Resets the hyperlink mark currently hovered by the keyboard cursor.
- this.keyboardHoveredHyperlinkMark = undefined;
- this.keyboardHoveredHyperlinkMarkRange = undefined;
+ // Resets the link mark currently hovered by the keyboard cursor.
+ this.keyboardHoveredLinkMark = undefined;
+ this.keyboardHoveredLinkMarkRange = undefined;
- // Finds link mark at the editor selection's position to update keyboardHoveredHyperlinkMark and
- // keyboardHoveredHyperlinkMarkRange.
+ // Finds link mark at the editor selection's position to update keyboardHoveredLinkMark and
+ // keyboardHoveredLinkMarkRange.
if (this.pmView.state.selection.empty) {
const marksAtPos = this.pmView.state.selection.$from.marks();
@@ -206,8 +202,8 @@ class HyperlinkToolbarView {
if (
mark.type.name === this.pmView.state.schema.mark("link").type.name
) {
- this.keyboardHoveredHyperlinkMark = mark;
- this.keyboardHoveredHyperlinkMarkRange =
+ this.keyboardHoveredLinkMark = mark;
+ this.keyboardHoveredLinkMarkRange =
getMarkRange(
this.pmView.state.selection.$from,
mark.type,
@@ -219,29 +215,29 @@ class HyperlinkToolbarView {
}
}
- if (this.mouseHoveredHyperlinkMark) {
- this.hyperlinkMark = this.mouseHoveredHyperlinkMark;
- this.hyperlinkMarkRange = this.mouseHoveredHyperlinkMarkRange;
+ if (this.mouseHoveredLinkMark) {
+ this.linkMark = this.mouseHoveredLinkMark;
+ this.linkMarkRange = this.mouseHoveredLinkMarkRange;
}
- // Keyboard cursor position takes precedence over mouse hovered hyperlink.
- if (this.keyboardHoveredHyperlinkMark) {
- this.hyperlinkMark = this.keyboardHoveredHyperlinkMark;
- this.hyperlinkMarkRange = this.keyboardHoveredHyperlinkMarkRange;
+ // Keyboard cursor position takes precedence over mouse hovered link.
+ if (this.keyboardHoveredLinkMark) {
+ this.linkMark = this.keyboardHoveredLinkMark;
+ this.linkMarkRange = this.keyboardHoveredLinkMarkRange;
}
- if (this.hyperlinkMark && this.editor.isEditable) {
+ if (this.linkMark && this.editor.isEditable) {
this.state = {
show: true,
referencePos: posToDOMRect(
this.pmView,
- this.hyperlinkMarkRange!.from,
- this.hyperlinkMarkRange!.to
+ this.linkMarkRange!.from,
+ this.linkMarkRange!.to
),
- url: this.hyperlinkMark!.attrs.href,
+ url: this.linkMark!.attrs.href,
text: this.pmView.state.doc.textBetween(
- this.hyperlinkMarkRange!.from,
- this.hyperlinkMarkRange!.to
+ this.linkMarkRange!.from,
+ this.linkMarkRange!.to
),
};
this.emitUpdate();
@@ -252,8 +248,8 @@ class HyperlinkToolbarView {
// Hides menu.
if (
this.state?.show &&
- prevHyperlinkMark &&
- (!this.hyperlinkMark || !this.editor.isEditable)
+ prevLinkMark &&
+ (!this.linkMark || !this.editor.isEditable)
) {
this.state.show = false;
this.emitUpdate();
@@ -269,24 +265,22 @@ class HyperlinkToolbarView {
}
}
-export const hyperlinkToolbarPluginKey = new PluginKey(
- "HyperlinkToolbarPlugin"
-);
+export const linkToolbarPluginKey = new PluginKey("LinkToolbarPlugin");
-export class HyperlinkToolbarProsemirrorPlugin<
+export class LinkToolbarProsemirrorPlugin<
BSchema extends BlockSchema,
I extends InlineContentSchema,
S extends StyleSchema
> extends EventEmitter {
- private view: HyperlinkToolbarView | undefined;
+ private view: LinkToolbarView | undefined;
public readonly plugin: Plugin;
constructor(editor: BlockNoteEditor) {
super();
this.plugin = new Plugin({
- key: hyperlinkToolbarPluginKey,
+ key: linkToolbarPluginKey,
view: (editorView) => {
- this.view = new HyperlinkToolbarView(editor, editorView, (state) => {
+ this.view = new LinkToolbarView(editor, editorView, (state) => {
this.emit("update", state);
});
return this.view;
@@ -294,39 +288,41 @@ export class HyperlinkToolbarProsemirrorPlugin<
});
}
- public onUpdate(callback: (state: HyperlinkToolbarState) => void) {
+ public onUpdate(callback: (state: LinkToolbarState) => void) {
return this.on("update", callback);
}
/**
- * Edit the currently hovered hyperlink.
+ * Edit the currently hovered link.
*/
- public editHyperlink = (url: string, text: string) => {
- this.view!.editHyperlink(url, text);
+ public editLink = (url: string, text: string) => {
+ this.view!.editLink(url, text);
};
/**
- * Delete the currently hovered hyperlink.
+ * Delete the currently hovered link.
*/
- public deleteHyperlink = () => {
- this.view!.deleteHyperlink();
+ public deleteLink = () => {
+ this.view!.deleteLink();
};
/**
- * When hovering on/off hyperlinks using the mouse cursor, the hyperlink
- * toolbar will open & close with a delay.
+ * When hovering on/off links using the mouse cursor, the link toolbar will
+ * open & close with a delay.
*
- * This function starts the delay timer, and should be used for when the mouse cursor enters the hyperlink toolbar.
+ * This function starts the delay timer, and should be used for when the mouse
+ * cursor enters the link toolbar.
*/
public startHideTimer = () => {
this.view!.startMenuUpdateTimer();
};
/**
- * When hovering on/off hyperlinks using the mouse cursor, the hyperlink
- * toolbar will open & close with a delay.
+ * When hovering on/off links using the mouse cursor, the link toolbar will
+ * open & close with a delay.
*
- * This function stops the delay timer, and should be used for when the mouse cursor exits the hyperlink toolbar.
+ * This function stops the delay timer, and should be used for when the mouse
+ * cursor exits the link toolbar.
*/
public stopHideTimer = () => {
this.view!.stopMenuUpdateTimer();
diff --git a/packages/core/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts b/packages/core/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts
index d110436173..a56363634e 100644
--- a/packages/core/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts
+++ b/packages/core/src/extensions/SuggestionMenu/getDefaultSlashMenuItems.ts
@@ -205,7 +205,7 @@ export function getDefaultSlashMenuItems<
// Immediately open the image toolbar
editor.prosemirrorView.dispatch(
- editor._tiptapEditor.state.tr.setMeta(editor.imageToolbar!.plugin, {
+ editor._tiptapEditor.state.tr.setMeta(editor.imagePanel!.plugin, {
block: insertedBlock,
})
);
diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts
index 0a809fae0d..5a202f72bd 100644
--- a/packages/core/src/index.ts
+++ b/packages/core/src/index.ts
@@ -11,8 +11,8 @@ export * from "./editor/BlockNoteSchema";
export * from "./editor/selectionTypes";
export * from "./extensions-shared/UiElementPosition";
export * from "./extensions/FormattingToolbar/FormattingToolbarPlugin";
-export * from "./extensions/HyperlinkToolbar/HyperlinkToolbarPlugin";
-export * from "./extensions/ImageToolbar/ImageToolbarPlugin";
+export * from "./extensions/ImagePanel/ImageToolbarPlugin";
+export * from "./extensions/LinkToolbar/LinkToolbarPlugin";
export * from "./extensions/SideMenu/SideMenuPlugin";
export * from "./extensions/SuggestionMenu/DefaultSuggestionItem";
export * from "./extensions/SuggestionMenu/SuggestionPlugin";
diff --git a/packages/react/src/components/FormattingToolbar/FormattingToolbarProps.ts b/packages/react/src/components/FormattingToolbar/FormattingToolbarProps.ts
index 158ac4ec32..afa71ed7c7 100644
--- a/packages/react/src/components/FormattingToolbar/FormattingToolbarProps.ts
+++ b/packages/react/src/components/FormattingToolbar/FormattingToolbarProps.ts
@@ -1,5 +1,5 @@
-import { BlockTypeDropdownItem } from "./mantine/DefaultDropdowns/BlockTypeDropdown";
+import { BlockTypeSelectItem } from "./mantine/DefaultSelects/BlockTypeSelect";
export type FormattingToolbarProps = {
- blockTypeDropdownItems?: BlockTypeDropdownItem[];
+ blockTypeSelectItems?: BlockTypeSelectItem[];
};
diff --git a/packages/react/src/components/FormattingToolbar/mantine/DefaultButtons/CreateLinkButton.tsx b/packages/react/src/components/FormattingToolbar/mantine/DefaultButtons/CreateLinkButton.tsx
index 9de18b94db..d80f8b4e9d 100644
--- a/packages/react/src/components/FormattingToolbar/mantine/DefaultButtons/CreateLinkButton.tsx
+++ b/packages/react/src/components/FormattingToolbar/mantine/DefaultButtons/CreateLinkButton.tsx
@@ -2,6 +2,7 @@ import { useCallback, useMemo, useState } from "react";
import { RiLink } from "react-icons/ri";
import {
+ BlockNoteEditor,
BlockSchema,
formatKeyboardShortcut,
InlineContentSchema,
@@ -11,11 +12,29 @@ import {
import { useBlockNoteEditor } from "../../../../hooks/useBlockNoteEditor";
import { useEditorContentOrSelectionChange } from "../../../../hooks/useEditorContentOrSelectionChange";
import { useSelectedBlocks } from "../../../../hooks/useSelectedBlocks";
-import { EditHyperlinkMenu } from "../../../HyperlinkToolbar/mantine/EditHyperlinkMenu/EditHyperlinkMenu";
import { ToolbarButton } from "../../../mantine-shared/Toolbar/ToolbarButton";
-import { ToolbarInputDropdownButton } from "../../../mantine-shared/Toolbar/ToolbarInputDropdownButton";
+import { ToolbarInputsMenu } from "../../../mantine-shared/Toolbar/ToolbarInputsMenu";
+import { EditLinkMenuItems } from "../../../LinkToolbar/mantine/EditLinkMenuItems";
+
+function checkLinkInSchema(
+ editor: BlockNoteEditor
+): editor is BlockNoteEditor<
+ BlockSchema,
+ {
+ link: {
+ type: "link";
+ propSchema: any;
+ content: "styled";
+ };
+ },
+ StyleSchema
+> {
+ return (
+ "link" in editor.schema.inlineContentSchema &&
+ editor.schema.inlineContentSchema["link"] === "link"
+ );
+}
-// TODO: Make sure Link is in inline content schema
export const CreateLinkButton = () => {
const editor = useBlockNoteEditor<
BlockSchema,
@@ -23,6 +42,8 @@ export const CreateLinkButton = () => {
StyleSchema
>();
+ const linkInSchema = checkLinkInSchema(editor);
+
const selectedBlocks = useSelectedBlocks(editor);
const [url, setUrl] = useState(editor.getSelectedLinkUrl() || "");
@@ -42,6 +63,10 @@ export const CreateLinkButton = () => {
);
const show = useMemo(() => {
+ if (!linkInSchema) {
+ return false;
+ }
+
for (const block of selectedBlocks) {
if (block.content === undefined) {
return false;
@@ -49,22 +74,24 @@ export const CreateLinkButton = () => {
}
return true;
- }, [selectedBlocks]);
+ }, [linkInSchema, selectedBlocks]);
if (!show) {
return null;
}
return (
-
}
- dropdown={}
+ dropdownItems={
+
+ }
/>
);
};
diff --git a/packages/react/src/components/FormattingToolbar/mantine/DefaultButtons/ImageCaptionButton.tsx b/packages/react/src/components/FormattingToolbar/mantine/DefaultButtons/ImageCaptionButton.tsx
index 91811faff1..9fb6c7896b 100644
--- a/packages/react/src/components/FormattingToolbar/mantine/DefaultButtons/ImageCaptionButton.tsx
+++ b/packages/react/src/components/FormattingToolbar/mantine/DefaultButtons/ImageCaptionButton.tsx
@@ -17,9 +17,8 @@ import { RiText } from "react-icons/ri";
import { useBlockNoteEditor } from "../../../../hooks/useBlockNoteEditor";
import { useSelectedBlocks } from "../../../../hooks/useSelectedBlocks";
import { ToolbarButton } from "../../../mantine-shared/Toolbar/ToolbarButton";
-import { ToolbarInputDropdown } from "../../../mantine-shared/Toolbar/ToolbarInputDropdown";
-import { ToolbarInputDropdownButton } from "../../../mantine-shared/Toolbar/ToolbarInputDropdownButton";
-import { ToolbarInputDropdownItem } from "../../../mantine-shared/Toolbar/ToolbarInputDropdownItem";
+import { ToolbarInputsMenu } from "../../../mantine-shared/Toolbar/ToolbarInputsMenu";
+import { ToolbarInputsMenuItem } from "../../../mantine-shared/Toolbar/ToolbarInputsMenuItem";
export const ImageCaptionButton = () => {
const editor = useBlockNoteEditor<
@@ -77,30 +76,25 @@ export const ImageCaptionButton = () => {
}
return (
-
}
- dropdown={
-
-
-
+ dropdownItems={
+
}
/>
);
diff --git a/packages/react/src/components/FormattingToolbar/mantine/DefaultButtons/ReplaceImageButton.tsx b/packages/react/src/components/FormattingToolbar/mantine/DefaultButtons/ReplaceImageButton.tsx
index d878532d87..b5dba08d3c 100644
--- a/packages/react/src/components/FormattingToolbar/mantine/DefaultButtons/ReplaceImageButton.tsx
+++ b/packages/react/src/components/FormattingToolbar/mantine/DefaultButtons/ReplaceImageButton.tsx
@@ -10,7 +10,7 @@ import { RiImageEditFill } from "react-icons/ri";
import { useBlockNoteEditor } from "../../../../hooks/useBlockNoteEditor";
import { useSelectedBlocks } from "../../../../hooks/useSelectedBlocks";
-import { ImageToolbar } from "../../../ImageToolbar/mantine/ImageToolbar";
+import { ImagePanel } from "../../../ImagePanel/mantine/ImagePanel";
import { ToolbarButton } from "../../../mantine-shared/Toolbar/ToolbarButton";
export const ReplaceImageButton = () => {
@@ -49,7 +49,7 @@ export const ReplaceImageButton = () => {
/>
-
+
);
diff --git a/packages/react/src/components/FormattingToolbar/mantine/DefaultDropdowns/BlockTypeDropdown.tsx b/packages/react/src/components/FormattingToolbar/mantine/DefaultSelects/BlockTypeSelect.tsx
similarity index 66%
rename from packages/react/src/components/FormattingToolbar/mantine/DefaultDropdowns/BlockTypeDropdown.tsx
rename to packages/react/src/components/FormattingToolbar/mantine/DefaultSelects/BlockTypeSelect.tsx
index 1218753798..566469ab3c 100644
--- a/packages/react/src/components/FormattingToolbar/mantine/DefaultDropdowns/BlockTypeDropdown.tsx
+++ b/packages/react/src/components/FormattingToolbar/mantine/DefaultSelects/BlockTypeSelect.tsx
@@ -1,6 +1,8 @@
import {
Block,
BlockSchema,
+ checkDefaultBlockTypeInSchema,
+ DefaultBlockSchema,
InlineContentSchema,
StyleSchema,
} from "@blocknote/core";
@@ -18,10 +20,10 @@ import {
import { useBlockNoteEditor } from "../../../../hooks/useBlockNoteEditor";
import { useEditorContentOrSelectionChange } from "../../../../hooks/useEditorContentOrSelectionChange";
import { useSelectedBlocks } from "../../../../hooks/useSelectedBlocks";
-import { ToolbarDropdown } from "../../../mantine-shared/Toolbar/ToolbarDropdown";
-import { ToolbarDropdownItemProps } from "../../../mantine-shared/Toolbar/ToolbarDropdownItem";
+import { ToolbarSelect } from "../../../mantine-shared/Toolbar/ToolbarSelect";
+import { ToolbarSelectItemProps } from "../../../mantine-shared/Toolbar/ToolbarSelectItem";
-export type BlockTypeDropdownItem = {
+export type BlockTypeSelectItem = {
name: string;
type: string;
props?: Record;
@@ -31,8 +33,7 @@ export type BlockTypeDropdownItem = {
) => boolean;
};
-// TODO: Filtering from schema should be done here, not in component?
-export const blockTypeDropdownItems: BlockTypeDropdownItem[] = [
+export const blockTypeSelectItems: BlockTypeSelectItem[] = [
{
name: "Paragraph",
type: "paragraph",
@@ -83,9 +84,7 @@ export const blockTypeDropdownItems: BlockTypeDropdownItem[] = [
},
];
-export const BlockTypeDropdown = (props: {
- items?: BlockTypeDropdownItem[];
-}) => {
+export const BlockTypeSelect = (props: { items?: BlockTypeSelectItem[] }) => {
const editor = useBlockNoteEditor<
BlockSchema,
InlineContentSchema,
@@ -96,33 +95,13 @@ export const BlockTypeDropdown = (props: {
const [block, setBlock] = useState(editor.getTextCursorPosition().block);
- const filteredItems: BlockTypeDropdownItem[] = useMemo(() => {
- return (props.items || blockTypeDropdownItems).filter((item) => {
- // Checks if block type exists in the schema
- if (!(item.type in editor.schema.blockSchema)) {
- return false;
- }
-
- // Checks if props for the block type are valid
- for (const [prop, value] of Object.entries(item.props || {})) {
- const propSchema = editor.schema.blockSchema[item.type].propSchema;
-
- // Checks if the prop exists for the block type
- if (!(prop in propSchema)) {
- return false;
- }
-
- // Checks if the prop's value is valid
- if (
- propSchema[prop].values !== undefined &&
- !propSchema[prop].values!.includes(value)
- ) {
- return false;
- }
- }
-
- return true;
- });
+ const filteredItems: BlockTypeSelectItem[] = useMemo(() => {
+ return (props.items || blockTypeSelectItems).filter((item) =>
+ checkDefaultBlockTypeInSchema(
+ item.type as keyof DefaultBlockSchema,
+ editor
+ )
+ );
}, [editor, props.items]);
const shouldShow: boolean = useMemo(
@@ -130,8 +109,8 @@ export const BlockTypeDropdown = (props: {
[block.type, filteredItems]
);
- const fullItems: ToolbarDropdownItemProps[] = useMemo(() => {
- const onClick = (item: BlockTypeDropdownItem) => {
+ const fullItems: ToolbarSelectItemProps[] = useMemo(() => {
+ const onClick = (item: BlockTypeSelectItem) => {
editor.focus();
for (const block of selectedBlocks) {
@@ -158,5 +137,5 @@ export const BlockTypeDropdown = (props: {
return null;
}
- return ;
+ return ;
};
diff --git a/packages/react/src/components/FormattingToolbar/mantine/FormattingToolbar.tsx b/packages/react/src/components/FormattingToolbar/mantine/FormattingToolbar.tsx
index ef5b6fea49..04b83212d2 100644
--- a/packages/react/src/components/FormattingToolbar/mantine/FormattingToolbar.tsx
+++ b/packages/react/src/components/FormattingToolbar/mantine/FormattingToolbar.tsx
@@ -1,3 +1,5 @@
+import { ReactNode } from "react";
+
import { Toolbar } from "../../mantine-shared/Toolbar/Toolbar";
import { FormattingToolbarProps } from "../FormattingToolbarProps";
import { BasicTextStyleButton } from "./DefaultButtons/BasicTextStyleButton";
@@ -11,17 +13,14 @@ import {
import { ReplaceImageButton } from "./DefaultButtons/ReplaceImageButton";
import { TextAlignButton } from "./DefaultButtons/TextAlignButton";
import {
- BlockTypeDropdown,
- BlockTypeDropdownItem,
-} from "./DefaultDropdowns/BlockTypeDropdown";
+ BlockTypeSelect,
+ BlockTypeSelectItem,
+} from "./DefaultSelects/BlockTypeSelect";
export const getFormattingToolbarItems = (
- blockTypeDropdownItems?: BlockTypeDropdownItem[]
+ blockTypeSelectItems?: BlockTypeSelectItem[]
): JSX.Element[] => [
- ,
+ ,
,
,
,
@@ -40,27 +39,26 @@ export const getFormattingToolbarItems = (
,
];
-// TODO: props.blockTypeDropdownItems should only be available if no children
+// TODO: props.blockTypeSelectItems should only be available if no children
// are passed
/**
* By default, the FormattingToolbar component will render with default
- * dropdowns/buttons. However, you can override the dropdowns/buttons to render
+ * selects/buttons. However, you can override the selects/buttons to render
* by passing children. The children you pass should be:
*
- * - Default dropdowns: Components found within the `/DefaultDropdowns` directory.
+ * - Default selects: Components found within the `/DefaultSelects` directory.
* - Default buttons: Components found within the `/DefaultButtons` directory.
- * - Custom dropdowns: The `ToolbarDropdown` component in the
+ * - Custom selects: The `ToolbarSelect` component in the
* `components/mantine-shared/Toolbar` directory.
* - Custom buttons: The `ToolbarButton` component in the
* `components/mantine-shared/Toolbar` directory.
*/
export const FormattingToolbar = (
- props: FormattingToolbarProps & { children?: React.ReactNode }
+ props: FormattingToolbarProps & { children?: ReactNode }
) => {
return (
- {props.children ||
- getFormattingToolbarItems(props.blockTypeDropdownItems)}
+ {props.children || getFormattingToolbarItems(props.blockTypeSelectItems)}
);
};
diff --git a/packages/react/src/components/HyperlinkToolbar/HyperlinkToolbarProps.ts b/packages/react/src/components/HyperlinkToolbar/HyperlinkToolbarProps.ts
deleted file mode 100644
index 864b5dbd48..0000000000
--- a/packages/react/src/components/HyperlinkToolbar/HyperlinkToolbarProps.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import {
- BlockNoteEditor,
- BlockSchema,
- HyperlinkToolbarState,
- InlineContentSchema,
- StyleSchema,
- UiElementPosition,
-} from "@blocknote/core";
-
-export type HyperlinkToolbarProps = Omit<
- HyperlinkToolbarState,
- keyof UiElementPosition
-> &
- Pick<
- BlockNoteEditor<
- BlockSchema,
- InlineContentSchema,
- StyleSchema
- >["hyperlinkToolbar"],
- "deleteHyperlink" | "editHyperlink" | "startHideTimer" | "stopHideTimer"
- >;
\ No newline at end of file
diff --git a/packages/react/src/components/HyperlinkToolbar/mantine/EditHyperlinkMenu/EditHyperlinkMenu.tsx b/packages/react/src/components/HyperlinkToolbar/mantine/EditHyperlinkMenu/EditHyperlinkMenu.tsx
deleted file mode 100644
index d5a71daff6..0000000000
--- a/packages/react/src/components/HyperlinkToolbar/mantine/EditHyperlinkMenu/EditHyperlinkMenu.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import {
- ChangeEvent,
- forwardRef,
- HTMLAttributes,
- KeyboardEvent,
- useCallback,
- useEffect,
- useState,
-} from "react";
-import { RiLink, RiText } from "react-icons/ri";
-
-import { ToolbarInputDropdown } from "../../../mantine-shared/Toolbar/ToolbarInputDropdown";
-import { ToolbarInputDropdownItem } from "../../../mantine-shared/Toolbar/ToolbarInputDropdownItem";
-
-export type EditHyperlinkMenuProps = {
- url: string;
- text: string;
- update: (url: string, text: string) => void;
-};
-
-/**
- * Menu which opens when editing an existing hyperlink or creating a new one.
- * Provides input fields for setting the hyperlink URL and title.
- */
-export const EditHyperlinkMenu = forwardRef<
- HTMLDivElement,
- EditHyperlinkMenuProps & HTMLAttributes
->(({ url, text, update, ...props }, ref) => {
- const [currentUrl, setCurrentUrl] = useState(url);
- const [currentText, setCurrentText] = useState(text);
-
- useEffect(() => {
- setCurrentUrl(url);
- setCurrentText(text);
- }, [text, url]);
-
- const handleEnter = useCallback(
- (event: KeyboardEvent) => {
- if (event.key === "Enter") {
- event.preventDefault();
- update(currentUrl, currentText);
- }
- },
- [update, currentUrl, currentText]
- );
-
- const handleUrlChange = useCallback(
- (event: ChangeEvent) =>
- setCurrentUrl(event.currentTarget.value),
- []
- );
-
- const handleTextChange = useCallback(
- (event: ChangeEvent) =>
- setCurrentText(event.currentTarget.value),
- []
- );
-
- const handleSubmit = useCallback(
- () => update(currentUrl, currentText),
- [update, currentUrl, currentText]
- );
-
- return (
-
-
-
-
- );
-});
diff --git a/packages/react/src/components/HyperlinkToolbar/mantine/HyperlinkToolbar.tsx b/packages/react/src/components/HyperlinkToolbar/mantine/HyperlinkToolbar.tsx
deleted file mode 100644
index ba931b5d31..0000000000
--- a/packages/react/src/components/HyperlinkToolbar/mantine/HyperlinkToolbar.tsx
+++ /dev/null
@@ -1,83 +0,0 @@
-import { useRef, useState } from "react";
-import { RiExternalLinkFill, RiLinkUnlink } from "react-icons/ri";
-
-import { HyperlinkToolbarProps } from "../HyperlinkToolbarProps";
-import { EditHyperlinkMenu } from "./EditHyperlinkMenu/EditHyperlinkMenu";
-import { Toolbar } from "../../mantine-shared/Toolbar/Toolbar";
-import { ToolbarButton } from "../../mantine-shared/Toolbar/ToolbarButton";
-
-/**
- * By default, the HyperlinkToolbar component will render with default buttons.
- * However, you can override the dropdowns/buttons to render by passing
- * children. The children you pass should be:
- *
- * TODO: Refactor and export default buttons
- * - Custom dropdowns: The `ToolbarDropdown` component in the
- * `components/mantine-shared/Toolbar` directory.
- * - Custom buttons: The `ToolbarButton` component in the
- * `components/mantine-shared/Toolbar` directory.
- */
-export const HyperlinkToolbar = (
- props: HyperlinkToolbarProps & { children?: React.ReactNode }
-) => {
- const [isEditing, setIsEditing] = useState(false);
- const editMenuRef = useRef(null);
-
- if (props.children) {
- return {props.children};
- }
-
- const {
- text,
- url,
- deleteHyperlink,
- editHyperlink,
- startHideTimer,
- stopHideTimer,
- } = props;
-
- if (isEditing) {
- return (
-
- setTimeout(() => {
- if (editMenuRef.current?.contains(event.relatedTarget)) {
- return;
- }
- setIsEditing(false);
- }, 500)
- }
- ref={editMenuRef}
- />
- );
- }
-
- return (
-
- setIsEditing(true)}>
- Edit Link
-
- {
- window.open(url, "_blank");
- }}
- icon={RiExternalLinkFill}
- />
-
-
- );
-};
diff --git a/packages/react/src/components/ImageToolbar/ImageToolbarController.tsx b/packages/react/src/components/ImagePanel/ImagePanelController.tsx
similarity index 78%
rename from packages/react/src/components/ImageToolbar/ImageToolbarController.tsx
rename to packages/react/src/components/ImagePanel/ImagePanelController.tsx
index 67da6a8071..adadd8a364 100644
--- a/packages/react/src/components/ImageToolbar/ImageToolbarController.tsx
+++ b/packages/react/src/components/ImagePanel/ImagePanelController.tsx
@@ -11,14 +11,14 @@ import { FC } from "react";
import { useBlockNoteEditor } from "../../hooks/useBlockNoteEditor";
import { useUIElementPositioning } from "../../hooks/useUIElementPositioning";
import { useUIPluginState } from "../../hooks/useUIPluginState";
-import { ImageToolbarProps } from "./ImageToolbarProps";
-import { ImageToolbar } from "./mantine/ImageToolbar";
+import { ImagePanelProps } from "./ImagePanelProps";
+import { ImagePanel } from "./mantine/ImagePanel";
-export const ImageToolbarController = <
+export const ImagePanelController = <
I extends InlineContentSchema = DefaultInlineContentSchema,
S extends StyleSchema = DefaultStyleSchema
>(props: {
- imageToolbar?: FC>;
+ imageToolbar?: FC>;
}) => {
const editor = useBlockNoteEditor<
{ image: DefaultBlockSchema["image"] },
@@ -26,14 +26,14 @@ export const ImageToolbarController = <
S
>();
- if (!editor.imageToolbar) {
+ if (!editor.imagePanel) {
throw new Error(
"ImageToolbarController can only be used when BlockNote editor schema contains image block"
);
}
const state = useUIPluginState(
- editor.imageToolbar.onUpdate.bind(editor.imageToolbar)
+ editor.imagePanel.onUpdate.bind(editor.imagePanel)
);
const { isMounted, ref, style } = useUIElementPositioning(
state?.show || false,
@@ -51,7 +51,7 @@ export const ImageToolbarController = <
const { show, referencePos, ...data } = state;
- const Component = props.imageToolbar || ImageToolbar;
+ const Component = props.imageToolbar || ImagePanel;
return (