Making a selected text bold or un-bold in React rich text editor

33 Views Asked by At

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>.

0

There are 0 best solutions below