How to create a custom input extension using Tiptap React

715 views Asked by At

I want to create an input extension in tiptap but am unable to get the editor to focus on the input.

Here is a gif of me trying to focus the input element and failing to do so as it reverts the focus back to a previous text block within the editor.

enter image description here

Here is my Tiptap custom extension setup:

InputBlockView:

import { Node } from "@tiptap/core";
import { ReactNodeViewRenderer } from "@tiptap/react";
import ReactInputBlockView from "./ReactInputBlockView";

export default Node.create({
  name: "input_block",
  content: "text*",
  marks: "",
  group: "block",
  defining: true,
  isolating: true,

  parseHTML() {
    return [
      {
        tag: "div",
        preserveWhitespace: "full"
      }
    ];
  },

  renderHTML({ HTMLAttributes }) {
    return ["div"];
  },

  addNodeView() {
    return ReactNodeViewRenderer(ReactInputBlockView);
  }
});

ReactInputBlockView:

const ReactInputBlockView: React.FC<NodeViewProps> = (props) => {
  return (
    <NodeViewWrapper
      contentEditable={false}
      as="div"
      className="group relative mx-auto flex w-full h-full gap-2 flex-col pb-1 bg-white rounded border"
    >
      <Input placeholder='Type here'/>
    </NodeViewWrapper>
  );
};

export default ReactInputBlockView;

I want the editor to focus on the input when I click it and focus on the other blocks when I click them. I've tried using event handlers with refs like this:

useEffect(() => {
  const handleInputFocus = () => {
    if (inputRef.current) {
      inputRef.current.focus();
    } else {
      editor.chain().focus();
    }
  };

  editor.on("selectionUpdate", handleInputFocus);

  return () => {
    editor.off("selectionUpdate", handleInputFocus);
  };
}, [editor]);

I have the onClick enabled for the editor fyi

      onClick={() => {
        // editor?.chain().focus().run();
      }}

I've also tried using on("focus"), but the focus still does not work correctly. Any guidance on how to achieve the desired focus behavior would be appreciated.

2

There are 2 answers

1
Tom De Kooning On

I suggest using the CodeBlock extension from TipTap (https://tiptap.dev/api/nodes/code-block).

const editor = useEditor({
    extensions: [..., CodeBlock],
    content:content
});
2
Hadi El Yakhni On

Have you tried an editable node view?