calculateNodeHeight.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.calculateNodeStyling = calculateNodeStyling;
  6. exports.default = calculateNodeHeight;
  7. // Thanks to https://github.com/andreypopp/react-textarea-autosize/
  8. /**
  9. * calculateNodeHeight(uiTextNode, useCache = false)
  10. */
  11. var HIDDEN_TEXTAREA_STYLE = "\n min-height:0 !important;\n max-height:none !important;\n height:0 !important;\n visibility:hidden !important;\n overflow:hidden !important;\n position:absolute !important;\n z-index:-1000 !important;\n top:0 !important;\n right:0 !important\n";
  12. var SIZING_STYLE = ['letter-spacing', 'line-height', 'padding-top', 'padding-bottom', 'font-family', 'font-weight', 'font-size', 'font-variant', 'text-rendering', 'text-transform', 'width', 'text-indent', 'padding-left', 'padding-right', 'border-width', 'box-sizing', 'word-break'];
  13. var computedStyleCache = {};
  14. var hiddenTextarea;
  15. function calculateNodeStyling(node) {
  16. var useCache = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  17. var nodeRef = node.getAttribute('id') || node.getAttribute('data-reactid') || node.getAttribute('name');
  18. if (useCache && computedStyleCache[nodeRef]) {
  19. return computedStyleCache[nodeRef];
  20. }
  21. var style = window.getComputedStyle(node);
  22. var boxSizing = style.getPropertyValue('box-sizing') || style.getPropertyValue('-moz-box-sizing') || style.getPropertyValue('-webkit-box-sizing');
  23. var paddingSize = parseFloat(style.getPropertyValue('padding-bottom')) + parseFloat(style.getPropertyValue('padding-top'));
  24. var borderSize = parseFloat(style.getPropertyValue('border-bottom-width')) + parseFloat(style.getPropertyValue('border-top-width'));
  25. var sizingStyle = SIZING_STYLE.map(function (name) {
  26. return "".concat(name, ":").concat(style.getPropertyValue(name));
  27. }).join(';');
  28. var nodeInfo = {
  29. sizingStyle: sizingStyle,
  30. paddingSize: paddingSize,
  31. borderSize: borderSize,
  32. boxSizing: boxSizing
  33. };
  34. if (useCache && nodeRef) {
  35. computedStyleCache[nodeRef] = nodeInfo;
  36. }
  37. return nodeInfo;
  38. }
  39. function calculateNodeHeight(uiTextNode) {
  40. var useCache = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  41. var minRows = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
  42. var maxRows = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
  43. if (!hiddenTextarea) {
  44. hiddenTextarea = document.createElement('textarea');
  45. hiddenTextarea.setAttribute('tab-index', '-1');
  46. hiddenTextarea.setAttribute('aria-hidden', 'true');
  47. document.body.appendChild(hiddenTextarea);
  48. }
  49. // Fix wrap="off" issue
  50. // https://github.com/ant-design/ant-design/issues/6577
  51. if (uiTextNode.getAttribute('wrap')) {
  52. hiddenTextarea.setAttribute('wrap', uiTextNode.getAttribute('wrap'));
  53. } else {
  54. hiddenTextarea.removeAttribute('wrap');
  55. }
  56. // Copy all CSS properties that have an impact on the height of the content in
  57. // the textbox
  58. var _calculateNodeStyling = calculateNodeStyling(uiTextNode, useCache),
  59. paddingSize = _calculateNodeStyling.paddingSize,
  60. borderSize = _calculateNodeStyling.borderSize,
  61. boxSizing = _calculateNodeStyling.boxSizing,
  62. sizingStyle = _calculateNodeStyling.sizingStyle;
  63. // Need to have the overflow attribute to hide the scrollbar otherwise
  64. // text-lines will not calculated properly as the shadow will technically be
  65. // narrower for content
  66. hiddenTextarea.setAttribute('style', "".concat(sizingStyle, ";").concat(HIDDEN_TEXTAREA_STYLE));
  67. hiddenTextarea.value = uiTextNode.value || uiTextNode.placeholder || '';
  68. var minHeight = Number.MIN_SAFE_INTEGER;
  69. var maxHeight = Number.MAX_SAFE_INTEGER;
  70. var height = hiddenTextarea.scrollHeight;
  71. var overflowY;
  72. if (boxSizing === 'border-box') {
  73. // border-box: add border, since height = content + padding + border
  74. height += borderSize;
  75. } else if (boxSizing === 'content-box') {
  76. // remove padding, since height = content
  77. height -= paddingSize;
  78. }
  79. if (minRows !== null || maxRows !== null) {
  80. // measure height of a textarea with a single row
  81. hiddenTextarea.value = ' ';
  82. var singleRowHeight = hiddenTextarea.scrollHeight - paddingSize;
  83. if (minRows !== null) {
  84. minHeight = singleRowHeight * minRows;
  85. if (boxSizing === 'border-box') {
  86. minHeight = minHeight + paddingSize + borderSize;
  87. }
  88. height = Math.max(minHeight, height);
  89. }
  90. if (maxRows !== null) {
  91. maxHeight = singleRowHeight * maxRows;
  92. if (boxSizing === 'border-box') {
  93. maxHeight = maxHeight + paddingSize + borderSize;
  94. }
  95. overflowY = height > maxHeight ? '' : 'hidden';
  96. height = Math.min(maxHeight, height);
  97. }
  98. }
  99. return {
  100. height: "".concat(height, "px"),
  101. minHeight: "".concat(minHeight, "px"),
  102. maxHeight: "".concat(maxHeight, "px"),
  103. overflowY: overflowY,
  104. resize: 'none'
  105. };
  106. }