function calculateTextareaHeight(textareaElement, textareaValue = '-', minRows = null, maxRows = null, minHeight = null, maxHeight = null) {
  // Regarding textareaValue: IE will return a height of 0 in case the textare is empty.
  // To prevent reducing the size to 0 we simply use a dummy text.
  if (!canUseDOM) { return 0; }

  if (!hiddenTextarea) {
    hiddenTextarea = document.createElement('textarea');
    document.body.appendChild(hiddenTextarea);
    hiddenTextarea.setAttribute('class', 'belle-input-helper');
  }

  const { style, verticalPaddingSize, verticalBorderSize, boxSizing } = calculateStyling(textareaElement);

  hiddenTextarea.setAttribute('style', `${style};${hiddenTextareaStyle}`);
  hiddenTextarea.value = textareaValue;

  let calculatedMinHeight;
  let calculatedMaxHeight;
  let height = hiddenTextarea.scrollHeight;

  // for a textarea with border-box, the border width has to be added while
  // for content-box it's necessary to subtract the padding
  if (boxSizing === 'border-box') {
    // border-box: content + padding + border
    height = height + verticalBorderSize;
  } else if (boxSizing === 'content-box') {
    // content-box: content
    height = height - verticalPaddingSize;
  }

  if (minRows !== null && minHeight === null ||
      maxRows !== null && maxHeight === null) {
    // measure height of a textarea with a single row
    hiddenTextarea.value = '-';
    const singleRowHeight = hiddenTextarea.scrollHeight - verticalPaddingSize;

    if (minRows !== null && minHeight === null) {
      calculatedMinHeight = singleRowHeight * minRows;
      if (boxSizing === 'border-box') {
        calculatedMinHeight = calculatedMinHeight + verticalPaddingSize + verticalBorderSize;
      }
    }

    if (maxRows !== null && maxHeight === null) {
      calculatedMaxHeight = singleRowHeight * maxRows;
      if (boxSizing === 'border-box') {
        calculatedMaxHeight = calculatedMaxHeight + verticalPaddingSize + verticalBorderSize;
      }
    }
  }

  const finalMinHeight = minHeight || calculatedMinHeight;
  if (finalMinHeight) {
    height = Math.max(finalMinHeight, height);
  }

  const finalMaxHeight = maxHeight || calculatedMaxHeight;
  if (finalMaxHeight) {
    height = Math.min(finalMaxHeight, height);
  }

  return height;
}
Returns an object containing height of the textare as if all the content
would be visible. The minHeight & maxHeight are in the object as well and are
based on minRows & maxRows.

In order to improve the performance a hidden textarea is added to the DOM
and used for further caluculations. In addition the styling of each textarea
is cached to improve performance.