JSFiddle - React, Tailwind, and code Playground

HTML

<button id="bold">B</button>
<button id="italic">I</button>
<div contentEditable="true">Lorem</div>

JavaScript

document.getElementById('bold').addEventListener('click', () => edit('STRONG'));
document.getElementById('italic').addEventListener('click', () => edit('EM'));

function edit(format) {
  let parentElementOfSelectedText = document.getSelection().getRangeAt(0).commonAncestorContainer;

  // If element is already formatted, undo the format
  if (parentElementOfSelectedText.tagName === format || parentElementOfSelectedText.parentElement.tagName === format) {
    if (parentElementOfSelectedText.tagName !== format) parentElementOfSelectedText = parentElementOfSelectedText.parentElement;

    let grandParentOfSelectedText = parentElementOfSelectedText.parentElement;
    if (parentElementOfSelectedText.textContent) {
      const selectedText = document.createTextNode(document.getSelection().toString());

      //work with range of old element because 
      //text nodes are pass by value
      //and we cant create a range after its a text node
      const range = document.createRange();
      range.selectNode(parentElementOfSelectedText);

      //this replaces some of your code but uses a range
      range.deleteContents();
      range.insertNode(selectedText);

      grandParentOfSelectedText.normalize();

      //select the range again :)
      const selection = window.getSelection();
      selection.removeAllRanges();
      selection.addRange(range);
    }
  } else {
    let selectedText = document.getSelection().getRangeAt(0);
    const node = document.createElement(format);
    const fragment = selectedText.extractContents();

    if (fragment) {
      node.appendChild(fragment);
    }
    selectedText.insertNode(node);


    //make only the inside of the node a range
    //so [...].commonAncestorContainer is "STRONG" or "EM"
    //and gets recognized
    const range = document.createRange();
    range.selectNodeContents(node);
    const selection = window.getSelection();
    window.getSelection().removeAllRanges()
    selection.addRange(range);
  }
}