react-quill
react-quill copied to clipboard
so many features don't show styles in html
heading styles
blockquote
code
align
indent
list
@simon-zhangmuye Did you find a solution to this problem?
EDIT: I found out that you need to add the css class "ql-editor" on the root component of the html block, where you quill html code
@maxstue Thanks. I will take a look at it.
@maxstue
@simon-zhangmuye I'm sorry to hear that it didn't help. In my project it helped fixing it for deeper lists. I hope you find a solution :)
@maxstue Thanks.
@simon-zhangmuye last idea: upgrade to version 2.0, which came out a couple of days a ago
@maxstue @zenoamaro Thank you maxtue. I face a problem which cannot be solved by quill. When I upload an image to backend and get a URL, I insert it to the HTML string.
quill.insertEmbed(range.index, "image", url, Quill.sources.USER);
quill.formatText(range.index + 1, 1, {
height: "auto",
width: "auto",
});
Here is what it looks like.
But when I try to resize the image, I can only resize it a little bit since when the size of image changes, it will rerender the editor. The size of the image can be changed but only a little bit.
Do you know how to fix this issue? This issue has been bothering me for a long time.
@simon-zhangmuye We had the exact same problem, after we upgraded to React 18. The fix was to upgrade to react-quill v2 (non beta). Luckily the fix for us was that easy, because the editor was acting really weird with non React 18 support.
@maxstue I upgrade to react-quill v2 and use React 18.
After uploading the image, the editor disappears.
Here is my quill editor code.
import React, { useState, useRef } from "react";
import ReactQuill, { Quill } from "react-quill";
import * as Emoji from "quill-emoji";
import "react-quill/dist/quill.snow.css";
import "quill-emoji/dist/quill-emoji.css";
import ResizeModule from "@ssumo/quill-resize-module";
import { getDownloadURL, ref, uploadBytes } from "firebase/storage";
import { message } from "antd";
import { uuidv4 } from "@firebase/util";
import { myStorage } from "../firebaseConfig";
import Compressor from "compressorjs";
Quill.register("modules/resize", ResizeModule);
Quill.register("modules/emoji", Emoji);
function QuillEditor() {
const [value, setValue] = useState("");
let quillRef = useRef();
function fileCompress(file) {
return new Promise((resolve, reject) => {
new Compressor(file, {
quality: 0.5,
maxWidth: 1000,
maxHeight: 1000,
success(file) {
return resolve({ success: true, file: file });
},
error(err) {
return resolve({ success: false, file: file });
},
});
});
}
function imageUploadHandler() {
const input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/png, image/gif, image/jpeg");
input.onchange = async (e) => {
const file = e.target.files[0];
const maxSize = 1024 * 1024 * 5;
const minSize = 1024 * 2;
if (file.size > maxSize || file.size < minSize) {
message.error("Uploaded image size is from 2KB to 5MB!");
return;
}
const fileReader = new FileReader();
fileReader.onloadend = () => {
if (fileReader.result) {
const view = new DataView(fileReader.result);
const first4Byte = view.getUint32(0, false);
const hexValue = Number(first4Byte).toString(16);
if (!["ffd8ffe0", "89504e47", "47494638"].includes(hexValue)) {
message.error("Image type are not PNG, GIF, JEPG!");
}
}
};
fileReader.readAsArrayBuffer(file);
const compressState = await fileCompress(file);
console.log(compressState);
if (compressState.success) {
const uuid = uuidv4();
const imageRef = ref(myStorage, uuid + "/" + file.name);
uploadBytes(imageRef, compressState.file, { contentType: file.type })
.then((res) => {
getDownloadURL(res.ref).then((url) => {
const quill = quillRef.getEditor();
const range = quill.getSelection(true);
quill.insertEmbed(range.index, "image", url, Quill.sources.USER);
quill.formatText(range.index, range.index + 1, {
height: "auto",
width: "auto",
});
});
})
.catch((error) => {
message.error(error);
});
}
};
input.click();
}
const toolbarOptions = {
container: [
[
{ header: [1, 2, 3, 4, 5, 6, false] },
"bold",
"italic",
"underline",
"strike",
{ color: [] },
{ background: [] },
"emoji",
"blockquote",
"code-block",
], // toggled buttons
[{ align: [] }, { indent: "-1" }, { indent: "+1" }], // superscript/subscript
[{ list: "ordered" }, { list: "bullet" }], // outdent/indent
["image", "video"],
["clean"], // remove formatting button
],
handlers: {
image: imageUploadHandler,
},
};
const modules = {
toolbar: toolbarOptions,
"emoji-toolbar": true,
"emoji-textarea": false,
"emoji-shortname": true,
resize: {
locale: {
altTip: "hold alt to resize",
floatLeft: "left",
floatRight: "right",
center: "center",
restore: "restore",
},
},
};
return (
<div className="flex justify-center divide-x-[90px] divide-white">
<ReactQuill
theme="snow"
ref={(el) => {
quillRef = el;
}}
className="w-[500px] h-[300px]"
value={value}
onChange={setValue}
modules={modules}
/>
<div className="ql-snow">
<div
className="ql-editor mt-16 w-[500px] h-[300px]"
dangerouslySetInnerHTML={{ __html: value }}
/>
</div>
<div className="w-[500px] h-[300px] overflow-y-auto">{value}</div>
</div>
);
}
export default QuillEditor;
@simon-zhangmuye Your modules and in you case your toolbaroptions should be wrapped inside of a "usememo" with "[]" or "[quillRef]" as dependency
if your editor just disappears, it sounds like it is crashing. Are there any errors in the browser logs?
@maxstue It gives me this warning. @zenoamaro
Not just image, the editor crashes when I input any content.
I remove custom image handlers, then it works.
Do you know why this happens?
@maxstue I am trying useMemo now and see if it works.
@maxstue It works. Thank you so much maxstue. You are my hero.
@simon-zhangmuye Glad i could help :) I struggled a lot with this myself so, maybe the docs should include more information like this.
@maxstue Hey maxstue, you have this issue. Upload an image and then delete it, and the quillRef becomes null and crashes
@simon-zhangmuye I never had that issue. But I read a couple of days ago that you only should use ".getEditor()" if you want to read data and use ".editor" if you want to read and/or manipulate data. If that doesn't help try to log the state of quill before/during and after the call to firebase and to see what happens.
@maxstue It works. Thank you so much.
@maxstue Hey maxstue. Sorry to bother you again. I use useState to control the value of Quill and when I try to resize the image or align it to a different position. The value of Quill doesn't change until I input a letter. Do you know how to fix this issue? Thanks a lot.
https://www.vidline.com/share/V0X85HL5N6/9090c5e86ef8332ec8ae9a08f5113032
I type enter then the value updates. Then image moves to the center.
I find out a way to solve this issue. Try another plugin quill-image-resize-module-react and it works.
@simon-zhangmuye Sorry for the late response. It sounds like the change is not properly triggering a usestate update 🤔 But glad you found a solution.
Quill is not the best editor for react compatibility, maybe take alook at metas new react editor lexical. It is still in alpha but it looks promising. Or tiptap looks great as well
Mine worked after wrapping it with an element that have ql-snow class
<main className="ql-snow"> <div className="ql-editor">{parse(htmlcontent)}</div> </main>
For me, the bellow code is working fully perfectly including all styles.
<div className="ql-snow w-full mt-16 "> <strong>Editor Response:</strong> <div className="ql-editor" dangerouslySetInnerHTML={{__html: value}} /> </div>