JSFiddle - React, Tailwind, and code Playground

by ampersand

HTML

<html>
<body>
    <div>
        <textarea>my text area</textarea>
    </div>
    <div id="pos">Pos: <span></span></div>
</body>
</html>

CSS

textarea {
    width: 300px;
    height: 100px;
    font-size: 25px;
    font-family: Helvetica, Arial, Verdana;
}

body {
  padding: 50px 100px
}

JavaScript

// http://stackoverflow.com/questions/263743/how-to-get-caret-position-in-textarea
function getCaret(el) { 
  if (el.selectionStart) { 
    return el.selectionStart; 
  } else if (document.selection) { 
    el.focus(); 

    var r = document.selection.createRange(); 
    if (r == null) { 
      return 0; 
    } 

    var re = el.createTextRange(), 
        rc = re.duplicate(); 
    re.moveToBookmark(r.getBookmark()); 
    rc.setEndPoint('EndToStart', re); 

    return rc.text.length; 
  }  
  return 0; 
}


$(function(){
    var span = $('#pos span');
    var textarea = $('textarea');
    
    var clone = $('<div></div>').appendTo($('body'));
    clone.width(textarea.width());
    clone.height(textarea.height());
    clone.css('max-height', textarea.height() + "px");
    clone.css('overflow', 'auto');
    var style = document.defaultView.getComputedStyle(textarea[0],null);

    clone.css("font",style.font);    
    
    var fakeCursor, hidePrompt; 
    
    textarea.on('keydown keyup click', function(e) {
        console.log(e);
        var pos = getCaret(textarea[0]);
        span.text(pos);
        
        var v = textarea.val().substring(0, pos);
        
        var buf = "";
        for(var i=0; i < v.length; i++) {
            var c = v[i];
            
            if(c=="\r") { continue; }
            if(c=="\n") { buf = buf + '<br>'; continue;}
            
            c = c.replace("<", "&lt;");
            c = c.replace(">", "&gt;");
            c = c.replace(" ", "&nbsp;");
        
            clone.html(buf + c); 
            if (clone[0].scrollWidth>clone[0].clientWidth) {
              var splitPos = buf.lastIndexOf("&nbsp;");
              if (splitPos > -1) {
                buf = buf.substring(0,splitPos) + "<br>" + buf.substring(splitPos) + c;
              } else {
                buf = buf + "<br>" + c;
              }
              
            } else {
              buf = buf + c;
            }
        }
        
        var cursor =...