UNPKG

wix-style-react

Version:
339 lines (285 loc) 13.4 kB
import _extends from "@babel/runtime/helpers/extends"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } import React from 'react'; import PropTypes from 'prop-types'; import { Editor, EditorState } from 'draft-js'; import EditorUtilities from './EditorUtilities'; import { sizeTypes, inputToTagsSize, dataHooks } from './constants'; import { st, classes, vars } from './VariableInput.st.css'; import StatusIndicator from '../StatusIndicator'; import { FontUpgradeContext } from '../FontUpgrade/context'; /** Input with variables as tags */ var VariableInput = /*#__PURE__*/function (_React$PureComponent) { _inherits(VariableInput, _React$PureComponent); var _super = _createSuper(VariableInput); function VariableInput(props) { var _this; _classCallCheck(this, VariableInput); _this = _super.call(this, props); _defineProperty(_assertThisInitialized(_this), "_handlePastedText", function (text, html, editorState) { /** We need to prevent new line when `multilne` is false, * here we are removing any new lines while pasting text */ if (/\r|\n/.exec(text)) { text = text.replace(/(\r\n|\n|\r)/gm, ''); _this._onEditorChange(EditorUtilities.insertText(editorState, text)); return true; } return false; }); _defineProperty(_assertThisInitialized(_this), "_isEmpty", function () { return _this.state.editorState.getCurrentContent().getPlainText().length === 0; }); _defineProperty(_assertThisInitialized(_this), "_inputToTagSize", function (inputSize) { return inputToTagsSize[inputSize] || VariableInput.defaultProps.size; }); _defineProperty(_assertThisInitialized(_this), "_toString", function () { var _this$props$variableT = _this.props.variableTemplate, prefix = _this$props$variableT.prefix, suffix = _this$props$variableT.suffix; var editorState = _this.state.editorState; return EditorUtilities.convertToString({ editorState: editorState, prefix: prefix, suffix: suffix }); }); _defineProperty(_assertThisInitialized(_this), "_onBlur", function () { var _this$props$onBlur = _this.props.onBlur, onBlur = _this$props$onBlur === void 0 ? function () {} : _this$props$onBlur; onBlur(_this._toString()); }); _defineProperty(_assertThisInitialized(_this), "_onFocus", function () { var _this$props$onFocus = _this.props.onFocus, onFocus = _this$props$onFocus === void 0 ? function () {} : _this$props$onFocus; onFocus(_this._toString()); }); _defineProperty(_assertThisInitialized(_this), "_onSubmit", function () { var _this$props$onSubmit = _this.props.onSubmit, onSubmit = _this$props$onSubmit === void 0 ? function () {} : _this$props$onSubmit; onSubmit(_this._toString()); }); _defineProperty(_assertThisInitialized(_this), "_onChange", function () { var _this$props$onChange = _this.props.onChange, onChange = _this$props$onChange === void 0 ? function () {} : _this$props$onChange; onChange(_this._toString()); }); _defineProperty(_assertThisInitialized(_this), "_onEditorChange", function (editorState) { _this._setEditorState(editorState); }); _defineProperty(_assertThisInitialized(_this), "_setEditorState", function (editorState) { var onStateChanged = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; var editorStateBefore = _this.state.editorState; var _this$props$variableT2 = _this.props.variableTemplate, prefix = _this$props$variableT2.prefix, suffix = _this$props$variableT2.suffix; var updateEditorState = EditorUtilities.moveToEdge(editorState); var triggerCallback = function triggerCallback() {}; if (EditorUtilities.isBlured(editorStateBefore, updateEditorState)) { // onChange is called after the editor blur handler // and we can't reflect the changes there, we moved the logic here. triggerCallback = _this._onBlur; if (EditorUtilities.hasUnparsedEntity(updateEditorState, prefix, suffix)) { updateEditorState = _this._stringToContentState(EditorUtilities.convertToString({ editorState: updateEditorState, prefix: prefix, suffix: suffix })); } } else if (EditorUtilities.isContentChanged(editorStateBefore, updateEditorState)) { triggerCallback = _this._onChange; } _this.setState({ editorState: updateEditorState }, function () { triggerCallback(); onStateChanged(); }); }); _defineProperty(_assertThisInitialized(_this), "_stringToContentState", function (str) { var _this$props = _this.props, _this$props$variableP = _this$props.variableParser, variableParser = _this$props$variableP === void 0 ? function () {} : _this$props$variableP, _this$props$variableT3 = _this$props.variableTemplate, prefix = _this$props$variableT3.prefix, suffix = _this$props$variableT3.suffix; var editorState = _this.state.editorState; var content = EditorUtilities.stringToContentState({ str: str, variableParser: variableParser, prefix: prefix, suffix: suffix }); return EditorUtilities.pushAndKeepSelection({ editorState: editorState, content: content }); }); _defineProperty(_assertThisInitialized(_this), "_setStringValue", function (str) { var afterUpdated = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; var updatedEditorState = EditorState.moveSelectionToEnd(_this._stringToContentState(str)); _this._setEditorState(updatedEditorState, function () { afterUpdated(updatedEditorState); }); }); _defineProperty(_assertThisInitialized(_this), "setValue", function (value) { _this._setStringValue(value, function () { _this._onSubmit(); }); }); _defineProperty(_assertThisInitialized(_this), "insertVariable", function (value) { var _this$props2 = _this.props, variableParser = _this$props2.variableParser, _this$props2$variable = _this$props2.variableTemplate, prefix = _this$props2$variable.prefix, suffix = _this$props2$variable.suffix; var editorState = _this.state.editorState; var text = variableParser(value); var newState = text ? EditorUtilities.insertEntity(editorState, { text: text, value: value }) : EditorUtilities.insertText(editorState, "".concat(prefix).concat(value).concat(suffix, " ")); _this._setEditorState(newState, function () { _this._onSubmit(); }); }); var size = props.size, disabled = props.disabled; var decorator = EditorUtilities.decoratorFactory({ tag: { size: _this._inputToTagSize(size), disabled: disabled } }); _this.state = { editorState: EditorState.createEmpty(decorator) }; return _this; } _createClass(VariableInput, [{ key: "componentDidMount", value: function componentDidMount() { var initialValue = this.props.initialValue; this._setStringValue(initialValue); this.editorRef = /*#__PURE__*/React.createRef(); } }, { key: "render", value: function render() { var _this2 = this; var _this$props3 = this.props, dataHook = _this$props3.dataHook, multiline = _this$props3.multiline, rows = _this$props3.rows, size = _this$props3.size, disabled = _this$props3.disabled, readOnly = _this$props3.readOnly, placeholder = _this$props3.placeholder, status = _this$props3.status, statusMessage = _this$props3.statusMessage, className = _this$props3.className; var singleLineProps = { handlePastedText: this._handlePastedText, handleReturn: function handleReturn() { return 'handled'; } }; return /*#__PURE__*/React.createElement(FontUpgradeContext.Consumer, null, function (_ref) { var isMadefor = _ref.active; return /*#__PURE__*/React.createElement("div", { "data-hook": dataHook, className: st(classes.root, { isMadefor: isMadefor, disabled: disabled, readOnly: readOnly, size: size, status: status, singleLine: !multiline }, className), style: _defineProperty({}, vars.rows, rows) }, /*#__PURE__*/React.createElement(Editor, _extends({ ref: _this2.editorRef, editorState: _this2.state.editorState, onChange: _this2._onEditorChange, onFocus: _this2._onFocus, placeholder: placeholder, readOnly: disabled || readOnly }, readOnly && { tabIndex: 0 }, !multiline && singleLineProps)), status && /*#__PURE__*/React.createElement("span", { className: classes.indicatorWrapper }, /*#__PURE__*/React.createElement(StatusIndicator, { dataHook: dataHooks.indicator, status: status, message: statusMessage }))); }); } }]); return VariableInput; }(React.PureComponent); VariableInput.displayName = 'VariableInput'; VariableInput.propTypes = { /** Specifies a CSS class name to be appended to the component’s root element */ className: PropTypes.string, /** Applies a data-hook HTML attribute that can be used in the tests */ dataHook: PropTypes.string, /** Specifies whether input should be disabled or not */ disabled: PropTypes.bool, /** Specifies whether input is read only */ readOnly: PropTypes.bool, /** Defines an initial value to display */ initialValue: PropTypes.string, /** Specifies whether component allow multiple lines or not. If false, text won’t wrap and horizontal scroll will appear inside of a component. */ multiline: PropTypes.bool, /** Defines a callback function that is called each time value is changed: * `onChange(value: String): void` */ onChange: PropTypes.func, /** Defines a callback function that is called on value submit, in other words after `insertVariable()` and `setValue()` * `onSubmit(value: String): void` */ onSubmit: PropTypes.func, /** Defines a callback function that is called on focus out: * `onBlur(value: String): void` */ onBlur: PropTypes.func, /** Defines a callback function that is called on focus in: * `onFocus(value: String): void` */ onFocus: PropTypes.func, /** Specify the status of a field */ status: PropTypes.oneOf(['error', 'warning', 'loading']), /** Defines the message to display on status icon hover. If not given or empty there will be no tooltip. */ statusMessage: PropTypes.node, /** Sets a placeholder message to display */ placeholder: PropTypes.string, /** Set the height of a component to fit the given number of rows */ rows: PropTypes.number, /** Controls the size of the input and variable tags */ size: PropTypes.oneOf(['small', 'medium', 'large']), /** Defines the variable keys that component will parse and convert to <Tag/> components on blur and while using `insertVariable`. * For each key `variableParser` will be called and should return a proper text for that key or false in case the key is invalid. * `variableParser(key: String): String|boolean` */ variableParser: PropTypes.func, /** Defines a template for variable recognition. Typed text strings with matching prefix and suffix symbols will be converted to <Tag/> components. */ variableTemplate: PropTypes.shape({ prefix: PropTypes.string, suffix: PropTypes.string }) }; VariableInput.defaultProps = { initialValue: '', multiline: true, rows: 1, size: sizeTypes.medium, variableParser: function variableParser() {}, variableTemplate: { prefix: '{{', suffix: '}}' } }; export default VariableInput;