JSFiddle - React, Tailwind, and code Playground

HTML

<textarea onkeydown="textarealimit(this, 4, 43, 'textarea_rowsleft', 'textarea_charsleft');" onkeyup="textarealimit(this, 4, 43, 'textarea_rowsleft', 'textarea_charsleft');" onpaste="textarealimit(this, 4, 43, 'textarea_rowsleft', 'textarea_charsleft');" rows="4" style="overflow: hidden; resize: none;">
</textarea>
<div>
    Rows left: <span id="textarea_rowsleft">4</span>
    Characters left: <span id="textarea_charsleft">43</span>
</div>

JavaScript

function textarealimit(textarea, rows, chars, rowsleft_id, charsleft_id) {
    var newValue;
    var valueSegments = textarea.value.split('\n');
    if(rows != undefined && valueSegments.length > rows) { // too many rows
        newValue = valueSegments.slice(0, rows).join("\n");
    }
    if(chars != undefined && textarea.value.length > chars) { // too many chars
        if(newValue != undefined) 
            newValue = newValue.substring(0, chars);
        else
            newValue = textarea.value.substring(0, chars);
    }
    if(newValue != undefined) textarea.value = newValue;
    
    if(rowsleft_id != undefined) {
        if(textarea.value == "") document.getElementById(rowsleft_id).innerHTML = rows;
        else if(rows - valueSegments.length >= 0) document.getElementById(rowsleft_id).innerHTML = rows - valueSegments.length;
    }
    if(charsleft_id != undefined) {
        if(chars != undefined) document.getElementById(charsleft_id).innerHTML = chars - textarea.value.length;
    }
}