zenoamaro / react-quill

A Quill component for React.
https://zenoamaro.github.io/react-quill
MIT License
6.79k stars 925 forks source link

Unable to position cursor between two pictures or between picture and text #975

Open huya666 opened 6 months ago

huya666 commented 6 months ago

Example

Ticket due diligence

ReactQuill version

Video

huya666 commented 6 months ago

I saw that it was the default industry, so I solved it like this. code

1、Register and add img method Register `

const ImageBlot = Quill.import("formats/image");

export default class ImageBlotNode extends ImageBlot {
  static create(value) {
    const node = super.create();
    node.setAttribute("alt", value?.alt);
    node.setAttribute("id", value?.id);
    node.setAttribute("src", value?.url);
    return node;
  }

  static value(node) {
    return {
      id: node?.getAttribute("id"),
      alt: node?.getAttribute("alt"),
      url: node?.getAttribute("src"),
    };
  }
}
ImageBlot.blotName = "image";
ImageBlot.tagName = "img";

`

2、Use in react editor.js

`

Quill.register(ImageBlotNode);

const IMG = "IMG";

const Editor = () => {
  const [html, setHtml] = useState("");
  const ref = useRef(null);
  const selectionRef = useRef(null);
  const parentRef = useRef(null);

  const onClickImg = useCallback((event) => {
    console.log(event);
    const { target } = event;
    const uuid = target?.getAttribute?.("id");

    if (!uuid || target?.nodeName !== IMG) {
      return;
    }

    const { editor } = ref?.current || {};
    const contents = editor?.getContents?.();

    const index = calcImagePos(contents?.ops, uuid);
    const { left = 0 } = editor?.getBounds?.(index) || {};
    const parentOffsetLeft = parentRef.current?.offsetLeft || 0;
    const eventPageX = event.pageX;

    if (left + parentOffsetLeft - eventPageX > (target?.width || 0) / 2) {
      editor?.setSelection?.(Math.max(0, index - 1));
    } else {
      editor?.setSelection?.(index || 0);
    }
  }, []);

  const insertImage = useCallback(() => {
    if (ref.current) {
      const editor = ref.current?.editor;
      editor?.insertEmbed(selectionRef.current, "image", {
        id: uuidv4(),
        alt: "image",
        url: "https://avatars.githubusercontent.com/u/34231749?v=4",
        style: { display: "inline-block" },
      });
      editor?.setSelection(selectionRef.current + 1);
      selectionRef.current += 1;
    }
  }, []);

  return (
    <>
      <div ref={parentRef} onClick={onClickImg}>
        <ReactQuill
          ref={ref}
          value={html}
          modules={{ toolbar: false }}
          style={{ height: 200 }}
          theme="snow"
        />
      </div>
      <button onClick={insertImage}>inset img</button>
    </>
  );
};

export default Editor;

`