I'm working on creating a rich text editor in react without using any library using contentEditable attribute. I'm able to bold a text using the code given below. But the problem arises when I try to un-bold it.
When I bold the selected text it gets bold, but when without unselecting it I try to un-bold it, it instead runs the same code as making the text bold.
here's the code I'm using -
<div
className={`${styles.richTextEditor}`}
ref={richTextEditorRef}
onInput={handleContentChange}
contentEditable
dir="ltr"
dangerouslySetInnerHTML={{ __html: defaultValue.current }}
></div>
export function toggleBold() {
let selection = window.getSelection();
if (selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
const parentElement = range.commonAncestorContainer;
const nearestHtmlTag = findNearestHTML(parentElement);
if (nearestHtmlTag.tagName.toLowerCase() !== "span") {
const boldSpan = document.createElement("span");
boldSpan.style.fontWeight = "bold";
// boldSpan.setAttribute("class", "boldSpan");
range.surroundContents(boldSpan);
}
if (
nearestHtmlTag.tagName.toLowerCase() === "span" &&
nearestHtmlTag.contains(range.commonAncestorContainer)
) {
const isBold =
nearestHtmlTag.style.fontWeight === "bold" ||
window.getComputedStyle(nearestHtmlTag).fontWeight === "bold";
if (isBold) {
nearestHtmlTag.style.fontWeight = "normal";
} else {
nearestHtmlTag.style.fontWeight = "bold";
}
}
}
}
function findNearestHTML(node) {
while (node && node.nodeType !== 1) {
node = node.parentNode;
}
return node;
}
I think the problem lies in selecting the parentElement and neartestHtmlTag because if I unselect the text and then select it, the code works perfectly fine. Also using console.log without unselecting the text the parent element is not <span> but <div>.