JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://rangy.googlecode.com/svn/trunk/dev/rangy-core.js"></script>
<script src="http://rangy.googlecode.com/svn/trunk/dev/rangy-textrange.js"></script>
<p>
    source:
    <span contenteditable=true id="source" class="editable">testing...</span>
<p>
    <span contenteditable=true id="foo" class="editable target"></span>
</p>

CSS

.red {color: red;}
.blue{color: blue;}
.editable {
    border: 1px solid black;
    border-radius: 5px;
    padding: 5px;
}

.letter {
    
    border: 1px solid #eee;
    border-radius:2px;
    padding: 1px;
}

JavaScript

function isAlpha(code) { return code>=65 && code<=90; }
function newLetterHTML(c) {
    console.log("making letter for char " + c);
    return "<span class='letter'>"+c+"</span>";
}
function newLetter(c) { return $(newLetterHTML(c)); }
function parentLetter(node) {
    var letter = node;
    while (letter.nodeType != 6
           && letter.tagName !== "SPAN"
           && letter.parentNode)
        letter = letter.parentNode;
    if (letter.className.split(' ').indexOf('letter')<0)
        return null;
    return letter;
}
function updateFields() {
    var source = $('#source').text();
    var lettersHTML = source.split('')
        .map(newLetterHTML)
        .join('');
    $('.editable').empty().append(lettersHTML);
    $('span:even',$('#foo')).addClass('red');
    $('span:odd',$('#foo')).addClass('blue');
}

$('#source').keydown(function($e){
    if ($e.which==13) {
        updateFields();
        $e.preventDefault();
    }
});

var oldRange = null;
function oldRangeIsCollapsed() {
    if (!oldRange) return true;
    var r = oldRange[0].characterRange;
    return (r.end - r.start == 0);
}
function saveRange(selection) {
    if (!selection)
        oldRange = null;
    else
        oldRange = selection.saveCharacterRanges($('#foo')[0]);
}
function loadRange(selection) {
    if (!oldRange) return;
    selection.restoreCharacterRanges($('#foo')[0],oldRange);
}

function downHandler(placeholder) { return function($e){
    var sel = rangy.getSelection();
    
    if (!isAlpha($e.which))
        saveRange(sel);
    else {
        if (!!oldRange)
            breakOutLastChar(sel);
        else
            saveRange(sel);
    }
};}

function upHandler($e) {
    if (!isAlpha($e.which))
        saveRange(null);
    else if (!!oldRange)
        breakOutLastChar(rangy.getSelection());
}
function insertContentAtNode(c,node,before) {
    var $newSpan = newLetter(c);
    $parent = $(parentLetter(node));
    if (!$parent.length) {
        $('#foo').empty().append($newSpan);
  ...