ResizableTextArea.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. var _typeof3 = require("@babel/runtime/helpers/typeof");
  4. Object.defineProperty(exports, "__esModule", {
  5. value: true
  6. });
  7. exports.default = void 0;
  8. var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  9. var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
  10. var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
  11. var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
  12. var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
  13. var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
  14. var _classnames = _interopRequireDefault(require("classnames"));
  15. var _rcResizeObserver = _interopRequireDefault(require("rc-resize-observer"));
  16. var _useLayoutEffect = _interopRequireDefault(require("rc-util/lib/hooks/useLayoutEffect"));
  17. var _useMergedState3 = _interopRequireDefault(require("rc-util/lib/hooks/useMergedState"));
  18. var _raf = _interopRequireDefault(require("rc-util/lib/raf"));
  19. var React = _interopRequireWildcard(require("react"));
  20. var _calculateNodeHeight = _interopRequireDefault(require("./calculateNodeHeight"));
  21. var _excluded = ["prefixCls", "defaultValue", "value", "autoSize", "onResize", "className", "style", "disabled", "onChange", "onInternalAutoSize"];
  22. function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
  23. function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
  24. var RESIZE_START = 0;
  25. var RESIZE_MEASURING = 1;
  26. var RESIZE_STABLE = 2;
  27. var ResizableTextArea = /*#__PURE__*/React.forwardRef(function (props, ref) {
  28. var _ref = props,
  29. prefixCls = _ref.prefixCls,
  30. defaultValue = _ref.defaultValue,
  31. value = _ref.value,
  32. autoSize = _ref.autoSize,
  33. onResize = _ref.onResize,
  34. className = _ref.className,
  35. style = _ref.style,
  36. disabled = _ref.disabled,
  37. onChange = _ref.onChange,
  38. onInternalAutoSize = _ref.onInternalAutoSize,
  39. restProps = (0, _objectWithoutProperties2.default)(_ref, _excluded);
  40. // =============================== Value ================================
  41. var _useMergedState = (0, _useMergedState3.default)(defaultValue, {
  42. value: value,
  43. postState: function postState(val) {
  44. return val !== null && val !== void 0 ? val : '';
  45. }
  46. }),
  47. _useMergedState2 = (0, _slicedToArray2.default)(_useMergedState, 2),
  48. mergedValue = _useMergedState2[0],
  49. setMergedValue = _useMergedState2[1];
  50. var onInternalChange = function onInternalChange(event) {
  51. setMergedValue(event.target.value);
  52. onChange === null || onChange === void 0 || onChange(event);
  53. };
  54. // ================================ Ref =================================
  55. var textareaRef = React.useRef();
  56. React.useImperativeHandle(ref, function () {
  57. return {
  58. textArea: textareaRef.current
  59. };
  60. });
  61. // ============================== AutoSize ==============================
  62. var _React$useMemo = React.useMemo(function () {
  63. if (autoSize && (0, _typeof2.default)(autoSize) === 'object') {
  64. return [autoSize.minRows, autoSize.maxRows];
  65. }
  66. return [];
  67. }, [autoSize]),
  68. _React$useMemo2 = (0, _slicedToArray2.default)(_React$useMemo, 2),
  69. minRows = _React$useMemo2[0],
  70. maxRows = _React$useMemo2[1];
  71. var needAutoSize = !!autoSize;
  72. // =============================== Resize ===============================
  73. var _React$useState = React.useState(RESIZE_STABLE),
  74. _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
  75. resizeState = _React$useState2[0],
  76. setResizeState = _React$useState2[1];
  77. var _React$useState3 = React.useState(),
  78. _React$useState4 = (0, _slicedToArray2.default)(_React$useState3, 2),
  79. autoSizeStyle = _React$useState4[0],
  80. setAutoSizeStyle = _React$useState4[1];
  81. var startResize = function startResize() {
  82. setResizeState(RESIZE_START);
  83. if (process.env.NODE_ENV === 'test') {
  84. onInternalAutoSize === null || onInternalAutoSize === void 0 || onInternalAutoSize();
  85. }
  86. };
  87. // Change to trigger resize measure
  88. (0, _useLayoutEffect.default)(function () {
  89. if (needAutoSize) {
  90. startResize();
  91. }
  92. }, [value, minRows, maxRows, needAutoSize]);
  93. (0, _useLayoutEffect.default)(function () {
  94. if (resizeState === RESIZE_START) {
  95. setResizeState(RESIZE_MEASURING);
  96. } else if (resizeState === RESIZE_MEASURING) {
  97. var textareaStyles = (0, _calculateNodeHeight.default)(textareaRef.current, false, minRows, maxRows);
  98. // Safari has bug that text will keep break line on text cut when it's prev is break line.
  99. // ZombieJ: This not often happen. So we just skip it.
  100. // const { selectionStart, selectionEnd, scrollTop } = textareaRef.current;
  101. // const { value: tmpValue } = textareaRef.current;
  102. // textareaRef.current.value = '';
  103. // textareaRef.current.value = tmpValue;
  104. // if (document.activeElement === textareaRef.current) {
  105. // textareaRef.current.scrollTop = scrollTop;
  106. // textareaRef.current.setSelectionRange(selectionStart, selectionEnd);
  107. // }
  108. setResizeState(RESIZE_STABLE);
  109. setAutoSizeStyle(textareaStyles);
  110. } else {
  111. // https://github.com/react-component/textarea/pull/23
  112. // Firefox has blink issue before but fixed in latest version.
  113. }
  114. }, [resizeState]);
  115. // We lock resize trigger by raf to avoid Safari warning
  116. var resizeRafRef = React.useRef();
  117. var cleanRaf = function cleanRaf() {
  118. _raf.default.cancel(resizeRafRef.current);
  119. };
  120. var onInternalResize = function onInternalResize(size) {
  121. if (resizeState === RESIZE_STABLE) {
  122. onResize === null || onResize === void 0 || onResize(size);
  123. if (autoSize) {
  124. cleanRaf();
  125. resizeRafRef.current = (0, _raf.default)(function () {
  126. startResize();
  127. });
  128. }
  129. }
  130. };
  131. React.useEffect(function () {
  132. return cleanRaf;
  133. }, []);
  134. // =============================== Render ===============================
  135. var mergedAutoSizeStyle = needAutoSize ? autoSizeStyle : null;
  136. var mergedStyle = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, style), mergedAutoSizeStyle);
  137. if (resizeState === RESIZE_START || resizeState === RESIZE_MEASURING) {
  138. mergedStyle.overflowY = 'hidden';
  139. mergedStyle.overflowX = 'hidden';
  140. }
  141. return /*#__PURE__*/React.createElement(_rcResizeObserver.default, {
  142. onResize: onInternalResize,
  143. disabled: !(autoSize || onResize)
  144. }, /*#__PURE__*/React.createElement("textarea", (0, _extends2.default)({}, restProps, {
  145. ref: textareaRef,
  146. style: mergedStyle,
  147. className: (0, _classnames.default)(prefixCls, className, (0, _defineProperty2.default)({}, "".concat(prefixCls, "-disabled"), disabled)),
  148. disabled: disabled,
  149. value: mergedValue,
  150. onChange: onInternalChange
  151. })));
  152. });
  153. var _default = exports.default = ResizableTextArea;