아래에서 영상으로 보여주겠지만 드래그를 한 상태에서 아무것도 없는 영역을 클릭했을때 사용자는 드래그한 영역이 풀리는 것을 기대한다.

하지만 드래그한 영역이 풀리지 않고 계속 드래그 한 곳을 포커스 해주는 상태를 발견하였다.

우선 코드는 바깥 영역을 클릭해도 input 영역에 포커스가 일어나게 해야했기 때문에 아래와 같이 코드를 작성하였었다.

export default function Tiptap({ text, setText }) {
  const editor = useEditor({
    extensions: [
      StarterKit.configure({
        codeBlock: false,
      }),
      Placeholder.configure({
        emptyEditorClass: "is-editor-empty",
        placeholder: "회의록을 입력해주세요...",
      }),
      TextAlign.configure({
        types: ["heading", "paragraph"],
      }),
      Highlight,
      Typography,
      Indent,
      CustomCodeBlockLowlight,
    ],
    content: text,
    onUpdate({ editor }) {
      setText(editor.getHTML());
    },
  });
//이쪽 부분을 확인
  return (
    <>
      <div
        className="h-full cursor-text overflow-hidden rounded-[20px] border border-solid border-grayscale-500 p-3"
        onClick={() => {
		        editor?.commands.focus();
          }
        }}
      >
        <MenuBar editor={editor} />
        <EditorContent editor={editor}} />
      </div>
    </>
  );
}

2.gif

위와 같이 코드를 짜니 바깥 영역을 클릭하니 input이 활성화는 되지만 계속 그 상태를 유지하고 있어 드래그한 요소가 취소되지 않았다.

그래서 이 문제를 해결하기 위해 처음에는 아래와 같이 구현해 보았는데 또 아래와 같이 구현하면 둘다 비동기적으로 작동하기 때문에 blur처리가 되기 전에 focus가 되고 blur처리가 되서 포커스가 사라지는 것을 확인하였다. 그래서 setTimeout으로 감싸거나 그런방식으로 focus가 되게 할 수는 있는데 또 여기서 문제가 blur처리를 한다고 드래그 했던 요소가 취소되는게 아니라 그냥 포커스만 떠나는 거라는 것을 알게되었다.. 그래서 또 다른 방법을 찾아보았..

editor?.commands.blur();
editor?.commands.focus();

먼가 추가적으로 editor의 기능들이 더 있을 것 같아 찾아보다가 https://tiptap.dev/docs/editor/api/commands 위의 문서를 찾을 수 있었다.

우선 blur로는 해결할 수 없기 때문에 제거하고 아래의 방식으로 구현할 수 있었다. 우선 editor를 까보니 엄청나게 많은 변수들과 함수들을 담고 있었고 그 중 드래그한 요소의 시작점과 끝 커서의 위치를 닮고 있는 editor.state.selection의 (from, to)를 활용해 드래그가 끝난 커서의 위치로 돌릴 수 있도록 구현하였다.

그리고 input 쪽에서도 계속 상위의 이벤트가 발생하기 때문에 e.stopPropagation을 통해 발생되지 않도록 막아주었다. 이렇게 해결~~!! 생각보다 많은 것들이 있고 이런것들을 찾으며 해결하다보니 재밌네 :)

return (
    <>
      <div
        className="h-full cursor-text overflow-hidden rounded-[20px] border border-solid border-grayscale-500 p-3"
        onClick={(e) => {
          if (editor) {
            const endPoint = editor.state.selection.to;
            editor.chain().focus().setTextSelection(endPoint).run();
          }
        }}
      >
        <MenuBar editor={editor} />
        <EditorContent editor={editor} onClick={(e) => e.stopPropagation()} />
      </div>
    </>
  );

3.gif