@douyinfe/semi-ui
Version:
A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.
285 lines (284 loc) • 10.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _throttle2 = _interopRequireDefault(require("lodash/throttle"));
var _isObject2 = _interopRequireDefault(require("lodash/isObject"));
var _isUndefined2 = _interopRequireDefault(require("lodash/isUndefined"));
var _isFunction2 = _interopRequireDefault(require("lodash/isFunction"));
var _omit2 = _interopRequireDefault(require("lodash/omit"));
var _noop2 = _interopRequireDefault(require("lodash/noop"));
var _react = _interopRequireDefault(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _textareaFoundation = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/input/textareaFoundation"));
var _constants = require("@douyinfe/semi-foundation/lib/cjs/input/constants");
var _baseComponent = _interopRequireDefault(require("../_base/baseComponent"));
require("@douyinfe/semi-foundation/lib/cjs/input/textarea.css");
var _semiIcons = require("@douyinfe/semi-icons");
var _resizeObserver = _interopRequireDefault(require("../resizeObserver"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
var __rest = void 0 && (void 0).__rest || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
};
const prefixCls = _constants.cssClasses.PREFIX;
class TextArea extends _baseComponent.default {
constructor(props) {
super(props);
this.handleClear = e => {
this.foundation.handleClear(e);
};
this.setRef = node => {
this.libRef.current = node;
const {
forwardRef
} = this.props;
if (typeof forwardRef === 'function') {
forwardRef(node);
} else if (forwardRef && typeof forwardRef === 'object') {
forwardRef.current = node;
}
};
const initValue = 'value' in props ? props.value : props.defaultValue;
this.state = {
value: initValue,
isFocus: false,
isHover: false,
height: 0,
minLength: props.minLength,
cachedValue: props.value
};
this.focusing = false;
this.foundation = new _textareaFoundation.default(this.adapter);
this.libRef = /*#__PURE__*/_react.default.createRef();
this.throttledResizeTextarea = (0, _throttle2.default)(this.foundation.resizeTextarea, 10);
}
get adapter() {
return Object.assign(Object.assign({}, super.adapter), {
setValue: value => this.setState({
value
}, () => {
if (this.props.autosize) {
this.foundation.resizeTextarea();
}
}),
getRef: () => this.libRef.current,
toggleFocusing: focusing => this.setState({
isFocus: focusing
}),
toggleHovering: hovering => this.setState({
isHover: hovering
}),
notifyChange: (val, e) => {
this.props.onChange(val, e);
},
notifyClear: e => this.props.onClear(e),
notifyBlur: (val, e) => this.props.onBlur(e),
notifyFocus: (val, e) => this.props.onFocus(e),
notifyKeyDown: e => {
this.props.onKeyDown(e);
},
notifyHeightUpdate: height => {
this.setState({
height
});
this.props.onResize({
height
});
},
notifyPressEnter: e => {
this.props.onEnterPress && this.props.onEnterPress(e);
},
setMinLength: minLength => this.setState({
minLength
})
});
}
static getDerivedStateFromProps(props, state) {
const willUpdateStates = {};
if (props.value !== state.cachedValue) {
willUpdateStates.value = props.value;
willUpdateStates.cachedValue = props.value;
}
return willUpdateStates;
}
componentWillUnmount() {
var _a, _b;
if (this.throttledResizeTextarea) {
(_b = (_a = this.throttledResizeTextarea) === null || _a === void 0 ? void 0 : _a.cancel) === null || _b === void 0 ? void 0 : _b.call(_a);
this.throttledResizeTextarea = null;
}
}
componentDidUpdate(prevProps, prevState) {
if ((this.props.value !== prevProps.value || this.props.placeholder !== prevProps.placeholder) && this.props.autosize) {
this.foundation.resizeTextarea();
}
}
renderClearBtn() {
const {
showClear
} = this.props;
const displayClearBtn = this.foundation.isAllowClear();
const clearCls = (0, _classnames.default)(`${prefixCls}-clearbtn`, {
[`${prefixCls}-clearbtn-hidden`]: !displayClearBtn
});
if (showClear) {
return (
/*#__PURE__*/
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
_react.default.createElement("div", {
className: clearCls,
onClick: this.handleClear
}, /*#__PURE__*/_react.default.createElement(_semiIcons.IconClear, null))
);
}
return null;
}
renderCounter() {
let counter, current, total, countCls;
const {
showCounter,
maxCount,
getValueLength
} = this.props;
if (showCounter || maxCount) {
const {
value
} = this.state;
// eslint-disable-next-line no-nested-ternary
current = value ? (0, _isFunction2.default)(getValueLength) ? getValueLength(value) : value.length : 0;
total = maxCount || null;
countCls = (0, _classnames.default)(`${prefixCls}-textarea-counter`, {
[`${prefixCls}-textarea-counter-exceed`]: current > total
});
counter = /*#__PURE__*/_react.default.createElement("div", {
className: countCls
}, current, total ? '/' : null, total);
} else {
counter = null;
}
return counter;
}
render() {
const _a = this.props,
{
autosize,
placeholder,
onEnterPress,
onResize,
// resize,
disabled,
readonly,
className,
showCounter,
validateStatus,
maxCount,
defaultValue,
style,
forwardRef,
getValueLength,
maxLength,
minLength,
showClear,
borderless,
autoFocus
} = _a,
rest = __rest(_a, ["autosize", "placeholder", "onEnterPress", "onResize", "disabled", "readonly", "className", "showCounter", "validateStatus", "maxCount", "defaultValue", "style", "forwardRef", "getValueLength", "maxLength", "minLength", "showClear", "borderless", "autoFocus"]);
const {
isFocus,
value,
minLength: stateMinLength
} = this.state;
const wrapperCls = (0, _classnames.default)(className, `${prefixCls}-textarea-wrapper`, {
[`${prefixCls}-textarea-borderless`]: borderless,
[`${prefixCls}-textarea-wrapper-disabled`]: disabled,
[`${prefixCls}-textarea-wrapper-readonly`]: readonly,
[`${prefixCls}-textarea-wrapper-${validateStatus}`]: Boolean(validateStatus),
[`${prefixCls}-textarea-wrapper-focus`]: isFocus
// [`${prefixCls}-textarea-wrapper-resize`]: !autosize && resize,
});
// const ref = this.props.forwardRef || this.textAreaRef;
const itemCls = (0, _classnames.default)(`${prefixCls}-textarea`, {
[`${prefixCls}-textarea-disabled`]: disabled,
[`${prefixCls}-textarea-readonly`]: readonly,
[`${prefixCls}-textarea-autosize`]: (0, _isObject2.default)(autosize) ? (0, _isUndefined2.default)(autosize === null || autosize === void 0 ? void 0 : autosize.maxRows) : autosize,
[`${prefixCls}-textarea-showClear`]: showClear
});
const itemProps = Object.assign(Object.assign({}, (0, _omit2.default)(rest, 'insetLabel', 'insetLabelId', 'getValueLength', 'onClear', 'showClear', 'disabledEnterStartNewLine')), {
autoFocus: autoFocus || this.props['autofocus'],
className: itemCls,
disabled,
readOnly: readonly,
placeholder: !placeholder ? null : placeholder,
onChange: e => this.foundation.handleChange(e.target.value, e),
onFocus: e => this.foundation.handleFocus(e),
onBlur: e => this.foundation.handleBlur(e.nativeEvent),
onKeyDown: e => this.foundation.handleKeyDown(e),
value: value === null || value === undefined ? '' : value
});
if (!(0, _isFunction2.default)(getValueLength)) {
itemProps.maxLength = maxLength;
}
if (stateMinLength) {
itemProps.minLength = stateMinLength;
}
return /*#__PURE__*/_react.default.createElement("div", {
className: wrapperCls,
style: style,
onMouseEnter: e => this.foundation.handleMouseEnter(e),
onMouseLeave: e => this.foundation.handleMouseLeave(e)
}, autosize ? ( /*#__PURE__*/_react.default.createElement(_resizeObserver.default, {
onResize: this.throttledResizeTextarea
}, /*#__PURE__*/_react.default.createElement("textarea", Object.assign({}, itemProps, {
ref: this.setRef
})))) : ( /*#__PURE__*/_react.default.createElement("textarea", Object.assign({}, itemProps, {
ref: this.setRef
}))), this.renderClearBtn(), this.renderCounter());
}
}
TextArea.propTypes = {
autosize: _propTypes.default.oneOfType([_propTypes.default.bool, _propTypes.default.object]),
borderless: _propTypes.default.bool,
placeholder: _propTypes.default.string,
value: _propTypes.default.string,
rows: _propTypes.default.number,
cols: _propTypes.default.number,
maxCount: _propTypes.default.number,
onEnterPress: _propTypes.default.func,
validateStatus: _propTypes.default.string,
className: _propTypes.default.string,
style: _propTypes.default.object,
showClear: _propTypes.default.bool,
onClear: _propTypes.default.func,
onResize: _propTypes.default.func,
getValueLength: _propTypes.default.func,
disabledEnterStartNewLine: _propTypes.default.bool
// TODO
// resize: PropTypes.bool,
};
TextArea.defaultProps = {
autosize: false,
borderless: false,
rows: 4,
cols: 20,
showCounter: false,
showClear: false,
onEnterPress: _noop2.default,
onChange: _noop2.default,
onBlur: _noop2.default,
onFocus: _noop2.default,
onKeyDown: _noop2.default,
onResize: _noop2.default,
onClear: _noop2.default
// resize: false,
};
const ForwardTextarea = /*#__PURE__*/_react.default.forwardRef((props, ref) => ( /*#__PURE__*/_react.default.createElement(TextArea, Object.assign({}, props, {
forwardRef: ref
}))));
var _default = exports.default = ForwardTextarea;