BlockNote icon indicating copy to clipboard operation
BlockNote copied to clipboard

Having trouble with autofocus feature - TypeError: Cannot read properties of undefined (reading 'focus')

Open softmarshmallow opened this issue 1 year ago • 4 comments

The editor is typed NonNullable by useCreateBlockNote, but It cannot be accessed (or at least not mounted) on initial hook call.

Screenshot 2024-06-30 at 8 19 46 PM
  const editor = useCreateBlockNote({
    schema: schema,
    initialContent: safevalue(defaultValue),
  });

  useEffect(() => {
    if (!editor) return;
    if (!editor.focus) return;
    editor.focus();
  }, [editor]);

Am I missing something here?

Below will work when called via click event

     <div
          className="prose dark:prose-invert mx-auto w-full"
          onClick={() => editor.focus()}
        >
          <ThemedRichTextEditorContent
            onKeyDown={(e) => {
              // this is required for preventing exit on enter pressed
              e.stopPropagation();
            }}
            editor={editor}
          />
        </div>

softmarshmallow avatar Jun 30 '24 11:06 softmarshmallow

This seems unexpected. Are you using the latest version of BlockNote? Could you perhaps share a Stackblitz reproducing this issue?

YousefED avatar Jul 01 '24 08:07 YousefED

I got it to work with the following

  useEffect(() => {
    if (!editor) return;
    if (!editor.prosemirrorView) return;

    editor.focus();
  }, [editor]);

I suspect the element is not yet fully mounted in OPs example

ellie avatar Jul 25 '24 14:07 ellie

I've seen this issue crop up a few times recently, it might be worth exposing a hook with this code as it seems like a common use case. Either that, or initialize the editor view synchronously in useCreateBlockNote.

matthewlipski avatar Aug 27 '24 13:08 matthewlipski

It would be great if there was an autofocus prop which, when true, would also initialize the editor if it is not already initialized and then focus it. The current DX is a bit challenging.

adamtowerz avatar Aug 27 '24 20:08 adamtowerz

It would be great if supported officialy, but for now - one possible workaround is by busy waiting:

import type { BlockNoteEditor } from '@blocknote/core';

function useFocusOnEditor(editor: BlockNoteEditor) {
  useEffect(() => {
    const intervalID = setInterval(() => {
      if (editor) {
        editor.focus(); // This will focus on 1st line, beginning of the editor
        clearInterval(intervalID);
      }
    }, 500); // Adjust the interval as needed

    return () => {
      clearInterval(intervalID);
    };
  }, [editor]);
}

For customization such as where to put the cursor's position, it could be done by accessing tiptap's editor instead (although I believe we're not supposed to access it, so it can break in future updates):

// https://tiptap.dev/docs/editor/api/commands/selection/focus
editor._tiptapEditor.commands.focus('end'); // focus at the end

sindras avatar Nov 30 '24 20:11 sindras