Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cursor jumping to the end #285

Open
jackwshepherd opened this issue Jul 7, 2024 · 2 comments
Open

Cursor jumping to the end #285

jackwshepherd opened this issue Jul 7, 2024 · 2 comments

Comments

@jackwshepherd
Copy link

jackwshepherd commented Jul 7, 2024

I am 100% sure there is a fix for this as there have been previous posts on this: #160

However, I don't understand how to implement the resolution. Every time the div class is updated, the cursor jumps to the end...anyone can help?


const processHTML = (paras) => {
    const htmlParas = !paras.includes("<div>") ? `<div>${paras}</div>` : paras;

    const result = htmlParas.replace(/<div>(.*?)<\/div>/g, (match, content) => {
      if (content.startsWith("### "))
        return `<div class="header-3">${content}</div>`;
      if (content.startsWith("## "))
        return `<div class="header-2">${content}</div>`;
      if (content.startsWith("# "))
        return `<div class="header-1">${content}</div>`;

      return match;
    });

    setParagraphs(result);
  };

 <ContentEditable
              innerRef={bottomDivRef}
              className="textarea-input"
              onChange={(event) => {
                processHTML(sanitizeHtml(event.target.value));
              }}
              html={paragraphs}
              onPaste={(paste) => console.log(paste)}
              onMouseOver={trackCursor}
              onKeyDown={trackCursor}
              contentEditable={true}
              onClick={trackCursor}
            />
@jackwshepherd
Copy link
Author

I tried this solution, which does not work either. Any advice appreciated

import React, { forwardRef, useState, useEffect, useRef } from "react";
import ContentEditable from "react-contenteditable";

const Editor = forwardRef(({ body = "\n", onChange, trackCursor }, ref) => {
  const contentEditableRef = useRef(null);
  const [html, setHtml] = useState("");

  useEffect(() => {
    const nodes = body
      .split("\n")
      .map((text) => `<div>${text}</div>`)
      .join("")
      .match(/<div.*?>(.*?)<\/div>/g)
      .map((div) => div.replace(/<\/?div.*?>/g, ""));

    const bodyClasses = nodes
      .map((value) => {
        const className = value.startsWith("# ")
          ? "header-1"
          : value.startsWith("## ")
          ? "header-2"
          : value.startsWith("### ")
          ? "header-3"
          : "";
        return `<div class="${className}">${value}</div>`;
      })
      .join("");

    setHtml(bodyClasses);
  }, [body]);

  const handleChange = (evt) => {
    const newHtml = evt.target.value;

    // Preserve cursor position
    const selection = window.getSelection();
    const range = selection.getRangeAt(0);
    const startOffset = range.startOffset;
    const endOffset = range.endOffset;
    const startContainer = range.startContainer;
    const endContainer = range.endContainer;

    setHtml(newHtml);

    // Restore cursor position after DOM update
    setTimeout(() => {
      if (contentEditableRef.current) {
        const newRange = document.createRange();
        const sel = window.getSelection();
        newRange.setStart(startContainer, startOffset);
        newRange.setEnd(endContainer, endOffset);
        sel.removeAllRanges();
        sel.addRange(newRange);
      }
    }, 0);

    onChange && onChange(newHtml);
  };

  return (
    <div className="textarea-container">
      <ContentEditable
        innerRef={contentEditableRef}
        className="textarea-input"
        html={html}
        onChange={handleChange}
        onMouseOver={trackCursor}
        onKeyDown={trackCursor}
        onClick={trackCursor}
      />
    </div>
  );
});

export default Editor;

@saeedhemmati
Copy link

I have this issue too

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants