Skip to content

Commit

Permalink
fix: Key inputs in blocks without content (#730)
Browse files Browse the repository at this point in the history
* Added temp fix for Enter inputs on blocks without content

* Updated fix to handle more edge cases
  • Loading branch information
matthewlipski committed May 10, 2024
1 parent 5e1861b commit c720a63
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 13 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/editor/BlockNoteExtensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export const getBlockNoteExtensions = <
UniqueID.configure({
types: ["blockContainer"],
}),
HardBreak,
HardBreak.extend({ priority: 10 }),
// Comments,

// basics:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,58 @@
import { Plugin, PluginKey } from "prosemirror-state";
import { Plugin, PluginKey, TextSelection } from "prosemirror-state";

const PLUGIN_KEY = new PluginKey("non-editable-block");
// Prevent typing for blocks without inline content, as this would otherwise
// convert them into paragraph blocks.
// By default, typing with a node selection active will cause ProseMirror to
// replace the node with one that contains editable content. This plugin blocks
// this behaviour without also blocking things like keyboard shortcuts:
//
// - Lets through key presses that do not include alphanumeric characters. This
// includes things like backspace/delete/home/end/etc.
// - Lets through any key presses that include ctrl/meta keys. These will be
// shortcuts of some kind like ctrl+C/mod+C.
// - Special case for Enter key which creates a new paragraph block below and
// sets the selection to it. This is just to bring the UX closer to Notion
//
// While a more elegant solution would probably process transactions instead of
// keystrokes, this brings us most of the way to Notion's UX without much added
// complexity.
export const NonEditableBlockPlugin = () => {
return new Plugin({
key: PLUGIN_KEY,
props: {
handleKeyDown: (view, event) => {
// Checks for node selection
if ("node" in view.state.selection) {
// Checks if key input will insert a character - we want to block this
// as it will convert the block into a paragraph.
if (
event.key.length === 1 &&
!event.ctrlKey &&
!event.altKey &&
!event.metaKey &&
!event.shiftKey
) {
// Checks if key press uses ctrl/meta modifier
if (event.ctrlKey || event.metaKey) {
return false;
}
// Checks if key press is alphanumeric
if (event.key.length === 1) {
event.preventDefault();

return true;
}
// Checks if key press is Enter
if (event.key === "Enter") {
const tr = view.state.tr;
view.dispatch(
tr
.insert(
view.state.tr.selection.$to.after(),
view.state.schema.nodes["paragraph"].create()
)
.setSelection(
new TextSelection(
tr.doc.resolve(view.state.tr.selection.$to.after() + 1)
)
)
);

return true;
}
}

return false;
},
},
});
Expand Down

0 comments on commit c720a63

Please sign in to comment.