Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion packages/core/src/BlockNoteEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,14 @@ export type BlockNoteEditorOptions = {
* A callback function that runs whenever the text cursor position changes.
*/
onTextCursorPositionChange: (editor: BlockNoteEditor) => void;
/**
* Locks the editor from being editable by the user if set to `false`.
*/
editable: boolean;
/**
* The content that should be in the editor when it's created, represented as an array of partial block objects.
*/
initialContent: PartialBlock[];

/**
* Use default BlockNote font and reset the styles of <p> <li> <h1> elements etc., that are used in BlockNote.
*
Expand Down Expand Up @@ -134,6 +140,7 @@ export class BlockNoteEditor {
onSelectionUpdate: () => {
options.onTextCursorPositionChange?.(this);
},
editable: options.editable === undefined ? true : options.editable,
extensions:
options.enableBlockNoteExtensions === false
? options._tiptapOptions?.extensions
Expand Down Expand Up @@ -312,6 +319,22 @@ export class BlockNoteEditor {
}
}

/**
* Checks if the editor is currently editable, or if it's locked.
* @returns True if the editor is editable, false otherwise.
*/
public get isEditable(): boolean {
return this._tiptapEditor.isEditable;
}

/**
* Makes the editor editable or locks it, depending on the argument passed.
* @param editable True to make the editor editable, or false to lock it.
*/
public set isEditable(editable: boolean) {
this._tiptapEditor.setEditable(editable);
}

/**
* Inserts new blocks into the editor. If a block's `id` is undefined, BlockNote generates one automatically. Throws an
* error if the reference block could not be found.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ export class BlockMenuView {
const block = getDraggableBlockFromCoords(coords, this.editor.view);

// Closes the menu if the mouse cursor is beyond the editor vertically.
if (!block) {
if (!block || !this.editor.isEditable) {
if (this.menuOpen) {
this.menuOpen = false;
this.blockMenu.hide();
Expand All @@ -411,11 +411,13 @@ export class BlockMenuView {
}

// Shows or updates elements.
if (!this.menuOpen) {
this.menuOpen = true;
this.blockMenu.render(this.getDynamicParams(), true);
} else {
this.blockMenu.render(this.getDynamicParams(), false);
if (this.editor.isEditable) {
if (!this.menuOpen) {
this.menuOpen = true;
this.blockMenu.render(this.getDynamicParams(), true);
} else {
this.blockMenu.render(this.getDynamicParams(), false);
}
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export class FormattingToolbarView {

public toolbarIsOpen = false;

public prevWasEditable: boolean | null = null;

public shouldShow: Exclude<FormattingToolbarPluginProps["shouldShow"], null> =
({ view, state, from, to }) => {
const { doc, selection } = state;
Expand Down Expand Up @@ -134,10 +136,16 @@ export class FormattingToolbarView {
const isSame =
oldState && oldState.doc.eq(doc) && oldState.selection.eq(selection);

if (composing || isSame) {
if (
(this.prevWasEditable === null ||
this.prevWasEditable === this.editor.isEditable) &&
(composing || isSame)
) {
return;
}

this.prevWasEditable = this.editor.isEditable;

// support for CellSelections
const { ranges } = selection;
const from = Math.min(...ranges.map((range) => range.$from.pos));
Expand All @@ -154,6 +162,7 @@ export class FormattingToolbarView {

// Checks if menu should be shown.
if (
this.editor.isEditable &&
!this.toolbarIsOpen &&
!this.preventShow &&
(shouldShow || this.preventHide)
Expand Down Expand Up @@ -184,7 +193,7 @@ export class FormattingToolbarView {
if (
this.toolbarIsOpen &&
!this.preventHide &&
(!shouldShow || this.preventShow)
(!shouldShow || this.preventShow || !this.editor.isEditable)
) {
this.formattingToolbar.hide();
this.toolbarIsOpen = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class HyperlinkToolbarView {
this.hyperlinkMarkRange = this.keyboardHoveredHyperlinkMarkRange;
}

if (this.hyperlinkMark) {
if (this.hyperlinkMark && this.editor.isEditable) {
this.getDynamicParams();

// Shows menu.
Expand All @@ -171,7 +171,7 @@ class HyperlinkToolbarView {
}

// Hides menu.
if (!this.hyperlinkMark && prevHyperlinkMark) {
if (prevHyperlinkMark && (!this.hyperlinkMark || !this.editor.isEditable)) {
this.hyperlinkToolbar.element?.removeEventListener(
"mouseleave",
this.startMenuUpdateTimer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ class SuggestionPluginView<T extends SuggestionItem> {

this.pluginState = stopped ? prev : next;

if (stopped) {
if (stopped || !this.editor.isEditable) {
this.suggestionsMenu.hide();

// Listener stops focus moving to the menu on click.
Expand All @@ -160,7 +160,7 @@ class SuggestionPluginView<T extends SuggestionItem> {
this.suggestionsMenu.render(this.getDynamicParams(), false);
}

if (started) {
if (started && this.editor.isEditable) {
this.suggestionsMenu.render(this.getDynamicParams(), true);

// Listener stops focus moving to the menu on click.
Expand Down
8 changes: 2 additions & 6 deletions packages/website/docs/docs/converting-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,7 @@ export default function App() {
// Creates a new editor instance.
const editor: BlockNoteEditor | null = useBlockNote({
// Makes the editor non-editable.
_tiptapOptions: {
editable: false,
},
editable: false
})

useEffect(() => {
Expand Down Expand Up @@ -245,9 +243,7 @@ export default function App() {
// Creates a new editor instance.
const editor: BlockNoteEditor | null = useBlockNote({
// Makes the editor non-editable.
_tiptapOptions: {
editable: false,
},
editable: false
})

useEffect(() => {
Expand Down
3 changes: 3 additions & 0 deletions packages/website/docs/docs/editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ There are a number of options that you can pass to `useBlockNote()`, which you c

```typescript
export type BlockNoteEditorOptions = Partial<{
editable: boolean;
initialContent: PartialBlock[];
editorDOMAttributes: Record<string, string>;
onEditorReady: (editor: BlockNoteEditor) => void;
Expand All @@ -19,6 +20,8 @@ export type BlockNoteEditorOptions = Partial<{
}>;
```

`editable:` Locks the editor from being editable by the user if set to `false`. [Editor Functions](/docs/blocks#editor-functions) will still work.

`initialContent:` The content that should be in the editor when it's created, represented as an array of [partial block objects](/docs/manipulating-blocks#partial-blocks).

`editorDOMAttributes:` An object containing attributes that should be added to the editor's HTML element. For example, you can pass `{ class: "my-editor-class" }` to set a custom class name.
Expand Down