diff --git a/packages/core/src/editor.module.css b/packages/core/src/editor.module.css
index f73cd09944..923ba5fad2 100644
--- a/packages/core/src/editor.module.css
+++ b/packages/core/src/editor.module.css
@@ -38,7 +38,6 @@ Tippy popups that are appended to document.body directly
.defaultStyles h3,
.defaultStyles li {
all: unset !important;
- flex-grow: 1 !important;
margin: 0;
padding: 0;
font-size: inherit;
diff --git a/packages/core/src/extensions/Blocks/api/block.ts b/packages/core/src/extensions/Blocks/api/block.ts
index 6fdc3ee2e5..77604299a9 100644
--- a/packages/core/src/extensions/Blocks/api/block.ts
+++ b/packages/core/src/extensions/Blocks/api/block.ts
@@ -186,6 +186,14 @@ export function createBlockSpec<
// Render elements
const rendered = blockConfig.render(block as any, editor);
+ // Add inlineContent class to inline content
+ if ("contentDOM" in rendered) {
+ rendered.contentDOM.className = `${
+ rendered.contentDOM.className
+ ? rendered.contentDOM.className + " "
+ : ""
+ }${styles.inlineContent}`;
+ }
// Add elements to blockContent
blockContent.appendChild(rendered.dom);
diff --git a/packages/core/src/extensions/Blocks/nodes/Block.module.css b/packages/core/src/extensions/Blocks/nodes/Block.module.css
index acb851a4ac..a85152345a 100644
--- a/packages/core/src/extensions/Blocks/nodes/Block.module.css
+++ b/packages/core/src/extensions/Blocks/nodes/Block.module.css
@@ -7,14 +7,26 @@ BASIC STYLES
transition: margin 0.2s;
}
+/*Ensures blocks & block content spans editor width*/
+.block {
+ display: flex;
+ flex-direction: column;
+}
+
+/*Ensures block content inside React node views spans editor width*/
+.reactNodeViewRenderer {
+ display: flex;
+ flex-grow: 1;
+}
+
.blockContent {
padding: 3px 0;
+ flex-grow: 1;
transition: font-size 0.2s;
/*
because the content elements are display: block
we use flex to position them next to list markers
*/
- display: flex;
}
.blockContent::before {
@@ -225,8 +237,8 @@ NESTED BLOCKS
/* PLACEHOLDERS*/
-.blockContent.isEmpty > :first-child:before,
-.blockContent.isFilter > :first-child:before {
+.isEmpty .inlineContent:before,
+.isFilter .inlineContent:before {
/*float: left; */
content: "";
pointer-events: none;
@@ -236,33 +248,33 @@ NESTED BLOCKS
font-style: italic;
}
-[data-theme="light"] .blockContent.isEmpty > :first-child:before,
-.blockContent.isFilter > :first-child:before {
+[data-theme="light"] .isEmpty .inlineContent:before,
+.isFilter .inlineContent:before {
color: #cccccc;
}
-[data-theme="dark"] .blockContent.isEmpty > :first-child:before,
-.blockContent.isFilter > :first-child:before {
+[data-theme="dark"] .isEmpty .inlineContent:before,
+.isFilter .inlineContent:before {
color: #999999;
}
/* TODO: would be nicer if defined from code */
-.blockContent.isEmpty.hasAnchor > :first-child:before {
+.isEmpty.hasAnchor .inlineContent:before {
content: "Enter text or type '/' for commands";
}
-.blockContent.isFilter.hasAnchor > :first-child:before {
+.blockContent.isFilter.hasAnchor .inlineContent:before {
content: "Type to filter";
}
-.blockContent[data-content-type="heading"].isEmpty > :first-child::before {
+.blockContent[data-content-type="heading"].isEmpty .inlineContent:before {
content: "Heading";
}
-.blockContent[data-content-type="bulletListItem"].isEmpty > :first-child:before,
+.blockContent[data-content-type="bulletListItem"].isEmpty .inlineContent:before,
.blockContent[data-content-type="numberedListItem"].isEmpty
- > :first-child:before {
+.inlineContent:before {
content: "List";
}
diff --git a/packages/core/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts b/packages/core/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts
index b9810feb8f..3dcb402257 100644
--- a/packages/core/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts
+++ b/packages/core/src/extensions/Blocks/nodes/BlockContent/HeadingBlockContent/HeadingBlockContent.ts
@@ -70,7 +70,7 @@ export const HeadingBlockContent = createTipTapBlock<"heading">({
class: styles.blockContent,
"data-content-type": this.name,
}),
- ["h" + node.attrs.level, 0],
+ ["h" + node.attrs.level, { class: styles.inlineContent }, 0],
];
},
});
diff --git a/packages/core/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts b/packages/core/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts
index eab5e37632..58ef2002ff 100644
--- a/packages/core/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts
+++ b/packages/core/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/BulletListItemBlockContent/BulletListItemBlockContent.ts
@@ -88,7 +88,7 @@ export const BulletListItemBlockContent = createTipTapBlock<"bulletListItem">({
class: styles.blockContent,
"data-content-type": this.name,
}),
- ["p", 0],
+ ["p", { class: styles.inlineContent }, 0],
];
},
});
diff --git a/packages/core/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts b/packages/core/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts
index 11e229f6a1..f8055bf31f 100644
--- a/packages/core/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts
+++ b/packages/core/src/extensions/Blocks/nodes/BlockContent/ListItemBlockContent/NumberedListItemBlockContent/NumberedListItemBlockContent.ts
@@ -114,7 +114,7 @@ export const NumberedListItemBlockContent =
}),
// we use a
tag, because for
tags we'd need to add a parent for around siblings to be semantically correct,
// which would be quite cumbersome
- ["p", 0],
+ ["p", { class: styles.inlineContent }, 0],
];
},
});
diff --git a/packages/core/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts b/packages/core/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts
index 3affad6ca8..9d44f9bb7a 100644
--- a/packages/core/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts
+++ b/packages/core/src/extensions/Blocks/nodes/BlockContent/ParagraphBlockContent/ParagraphBlockContent.ts
@@ -23,7 +23,7 @@ export const ParagraphBlockContent = createTipTapBlock<"paragraph">({
class: styles.blockContent,
"data-content-type": this.name,
}),
- ["p", 0],
+ ["p", { class: styles.inlineContent }, 0],
];
},
});
diff --git a/packages/core/src/extensions/Placeholder/PlaceholderExtension.ts b/packages/core/src/extensions/Placeholder/PlaceholderExtension.ts
index ba6de34a1d..9def2e85d9 100644
--- a/packages/core/src/extensions/Placeholder/PlaceholderExtension.ts
+++ b/packages/core/src/extensions/Placeholder/PlaceholderExtension.ts
@@ -72,6 +72,7 @@ export const Placeholder = Extension.create({
if ((hasAnchor || !this.options.showOnlyCurrent) && isEmpty) {
const classes = [this.options.emptyNodeClass];
+ // TODO: Doesn't work?
if (this.editor.isEmpty) {
classes.push(this.options.emptyEditorClass);
}
diff --git a/packages/react/src/FormattingToolbar/components/DefaultButtons/TextAlignButton.tsx b/packages/react/src/FormattingToolbar/components/DefaultButtons/TextAlignButton.tsx
index ae5be57332..dde4fe6342 100644
--- a/packages/react/src/FormattingToolbar/components/DefaultButtons/TextAlignButton.tsx
+++ b/packages/react/src/FormattingToolbar/components/DefaultButtons/TextAlignButton.tsx
@@ -1,9 +1,10 @@
import {
BlockNoteEditor,
- DefaultBlockSchema,
+ BlockSchema,
DefaultProps,
+ PartialBlock,
} from "@blocknote/core";
-import { useCallback } from "react";
+import { useCallback, useMemo } from "react";
import { IconType } from "react-icons";
import {
RiAlignCenter,
@@ -22,10 +23,30 @@ const icons: Record = {
justify: RiAlignJustify,
};
-export const TextAlignButton = (props: {
- editor: BlockNoteEditor;
+export const TextAlignButton = (props: {
+ editor: BlockNoteEditor;
textAlignment: TextAlignment;
}) => {
+ const show = useMemo(() => {
+ const selection = props.editor.getSelection();
+
+ if (selection) {
+ for (const block of selection.blocks) {
+ if (!("textAlignment" in block.props)) {
+ return false;
+ }
+ }
+ } else {
+ const block = props.editor.getTextCursorPosition().block;
+
+ if (!("textAlignment" in block.props)) {
+ return false;
+ }
+ }
+
+ return true;
+ }, [props.editor]);
+
const setTextAlignment = useCallback(
(textAlignment: TextAlignment) => {
props.editor.focus();
@@ -36,17 +57,23 @@ export const TextAlignButton = (props: {
for (const block of selection.blocks) {
props.editor.updateBlock(block, {
props: { textAlignment: textAlignment },
- });
+ } as PartialBlock);
}
} else {
- props.editor.updateBlock(props.editor.getTextCursorPosition().block, {
+ const block = props.editor.getTextCursorPosition().block;
+
+ props.editor.updateBlock(block, {
props: { textAlignment: textAlignment },
- });
+ } as PartialBlock);
}
},
[props.editor]
);
+ if (!show) {
+ return null;
+ }
+
return (
setTextAlignment(props.textAlignment)}
diff --git a/packages/react/src/ReactBlockSpec.tsx b/packages/react/src/ReactBlockSpec.tsx
index ab5249854e..2dacf41b40 100644
--- a/packages/react/src/ReactBlockSpec.tsx
+++ b/packages/react/src/ReactBlockSpec.tsx
@@ -11,12 +11,11 @@ import {
} from "@blocknote/core";
import {
NodeViewContent,
- NodeViewContentProps,
NodeViewProps,
NodeViewWrapper,
ReactNodeViewRenderer,
} from "@tiptap/react";
-import { FC } from "react";
+import { FC, HTMLAttributes } from "react";
import { blockStyles } from "@blocknote/core";
// extend BlockConfig but use a react render function
@@ -39,8 +38,13 @@ export type ReactBlockConfig<
}>;
};
-export const ContentDOM = (props: NodeViewContentProps) => (
-
+export const InlineContent = (props: HTMLAttributes) => (
+
);
// A function to create custom block for API consumers
@@ -115,7 +119,9 @@ export function createReactBlockSpec<
);
};
- return ReactNodeViewRenderer(BlockContent);
+ return ReactNodeViewRenderer(BlockContent, {
+ className: blockStyles.reactNodeViewRenderer,
+ });
},
});
diff --git a/packages/react/src/SharedComponents/Toolbar/components/ToolbarDropdown.tsx b/packages/react/src/SharedComponents/Toolbar/components/ToolbarDropdown.tsx
index 40e4009509..9e8e5ff474 100644
--- a/packages/react/src/SharedComponents/Toolbar/components/ToolbarDropdown.tsx
+++ b/packages/react/src/SharedComponents/Toolbar/components/ToolbarDropdown.tsx
@@ -18,6 +18,10 @@ export type ToolbarDropdownProps = {
export function ToolbarDropdown(props: ToolbarDropdownProps) {
const activeItem = props.items.filter((p) => p.isSelected)[0];
+ if (!activeItem) {
+ return null;
+ }
+
return (