JSFiddle - React, Tailwind, and code Playground

by dirtyd77

HTML

<svg height="200" width="200">
    <rect x="10" y="10" width="100" height="100"></rect>
    <text class="text"></text>
   <foreignobject class="awesome" x="10" y="10" width="100" height="100">
        <textArea></textArea>
    </foreignobject>
</svg>

CSS

rect{
    fill: red;  
}

foreignObject{
    position: relative;
}
textarea{
    margin: 5px;
    width: 80%;
    height: 80%;
    resize: none;
    border: 2px solid blue;
    outline: none;
}
textarea:disabled{
    pointer-events: none;
  -webkit-user-select: none;  /* Chrome all / Safari all */
  -moz-user-select: none;     /* Firefox all */
  -ms-user-select: none;      /* IE 10+ */
  -o-user-select: none;
  user-select: none;   
  border: 1px solid gray;
}

JavaScript

var textArea = d3.select('textarea'),
    foreignObject = d3.select('.awesome'),
    daText = d3.select('.text'),
    disable = false;
d3.select('foreignObject').on('dblclick', function (){
    
});

textArea.on('change', function (){
    var textAreaNode = textArea.node(),
        width = textAreaNode.clientWidth,
        textValue = textAreaNode.value;
    daText.html(textValue);
    wrap(daText, width);
    textArea.attr('display', 'none');
});

function wrap(text, width) {
  text.each(function() {
    var text = d3.select(this),
        words = text.text().split(/\s+/).reverse(),
        word,
        line = [],
        lineNumber = 0,
        lineHeight = 1.1, // ems
        y = text.attr("y"),
        dy = parseFloat(text.attr("dy")),
        tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
    while (word = words.pop()) {
      line.push(word);
      tspan.text(line.join(" "));
      if (tspan.node().getComputedTextLength() > width) {
        line.pop();
        tspan.text(line.join(" "));
        line = [word];
        tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
      }
    }
  });
}

textArea.on('dblclick', function (){
   disable = !disable;
    console.log('double', disable);
    textArea.attr('disabled', (disable ? 'disable' : null));
});