JSFiddle - React, Tailwind, and code Playground

HTML

<h1>Editable area:</h1>
<div id='x' contenteditable><span>asdasd</span></div>

<table>
    <tr>
        <td>Is caret</td>
        <td id='caret'></td>
    </tr>
    <tr>
        <td>Is at start</td>
        <td id='start'></td>
    </tr>
    <tr>
        <td>Is at end</td>
        <td id='end'></td>
    </tr>
    <tr>
        <td>First line</td>
        <td id='first'></td>
    </tr>
    <tr>
        <td>Last line</td>
        <td id='last'></td>
    </tr>
</table>

CSS

div#x {
    width: 80%;
    background-color: #DDD;
    border: 1px solid gray;
    border-radius: 15px;
    padding: 6px 0.5em;
    margin-left: auto;
    margin-right: auto;
}

table {
    border: 1px solid gray;
    width: 200px;
    margin-left: auto;
    margin-right: auto;
}

td {
 padding: 6px;   
    border-bottom: 1px dashed gray;
}

CoffeeScript

#     CODE
LINE_HEIGHT = 20

is_caret_at_start_of_node = (node, range) ->
  # See: http://stackoverflow.com/questions/7451468
  pre_range = document.createRange()
  pre_range.selectNodeContents(node)
  pre_range.setEnd(range.startContainer, range.startOffset)
  return pre_range.toString().trim().length == 0

is_caret_at_end_of_node = (node, range) ->
  post_range = document.createRange()
  post_range.selectNodeContents(node)
  post_range.setStart(range.endContainer, range.endOffset)
  return post_range.toString().trim().length == 0

$.fn.editableIsCaret = ->
  return window.getSelection().type == 'Caret'
  # alt test:
  # return sel.rangeCount == 1 and sel.getRangeAt(0).collapsed

$.fn.editableRange = ->
  # Return the range for the selection
  sel = window.getSelection()
  return unless sel.rangeCount > 0
  return sel.getRangeAt(0)

$.fn.editableCaretRange = ->
  return unless @editableIsCaret()
  return @editableRange()

$.fn.editableSetRange = (range) ->
  sel = window.getSelection()
  sel.removeAllRanges() if sel.rangeCount > 0
  sel.addRange(range)

$.fn.editableFocus = (at_start=true) ->
  return unless @attr('contenteditable')
  sel = window.getSelection()
  sel.removeAllRanges() if sel.rangeCount > 0
  range = document.createRange()
  range.selectNodeContents(@[0])
  range.collapse(at_start)
  sel.addRange(range)

$.fn.editableCaretAtStart = ->
  range = @editableRange()
  return false unless range
  return is_caret_at_start_of_node(@[0], range)

$.fn.editableCaretAtEnd = ->
  range = @editableRange()
  return false unless range
  return is_caret_at_end_of_node(@[0], range)

$.fn.editableCaretOnFirstLine = ->
  range = @editableRange()
  return false unless range
  # At the start of a node, the getClientRects() is [], so we have to
  # use the getBoundingClientRect (which seems to work).
  if is_caret_at_start_of_node(@[0], range)
    return true
  else if is_caret_at_end_of_node(@[0], range)
    ctop = @[0].getBoundingClientRect().bottom - LINE_HEIGHT
 ...