UNPKG

wix-style-react

Version:
345 lines (344 loc) 12 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _draftJs = require("draft-js"); var _EditorUtilities = _interopRequireDefault(require("./EditorUtilities")); var _constants = require("./constants"); var _VariableInputSt = require("./VariableInput.st.css"); var _StatusIndicator = _interopRequireDefault(require("../StatusIndicator")); var _StatusContext = require("../FormField/StatusContext"); var _context = require("../WixStyleReactProvider/context"); var _jsxFileName = "/home/builduser/work/a9c1ac8876d5057c/packages/wix-style-react/dist/cjs/VariableInput/VariableInput.js"; /** Input with variables as tags */ class VariableInput extends _react.default.PureComponent { constructor(props) { var _this; super(props); _this = this; this._handlePastedText = (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.default.insertText(editorState, text)); return true; } return false; }; this._isEmpty = () => this.state.editorState.getCurrentContent().getPlainText().length === 0; this._inputToTagSize = inputSize => { return _constants.inputToTagsSize[inputSize] || VariableInput.defaultProps.size; }; this._toString = () => { var { variableTemplate: { prefix, suffix } } = this.props; var { editorState } = this.state; return _EditorUtilities.default.convertToString({ editorState, prefix, suffix }); }; this._onBlur = () => { var { onBlur = () => {} } = this.props; onBlur(this._toString()); }; this._onFocus = () => { var { onFocus = () => {} } = this.props; onFocus(this._toString()); }; this._onSubmit = () => { var { onSubmit = () => {} } = this.props; onSubmit(this._toString()); }; this._onChange = () => { var { onChange = () => {} } = this.props; onChange(this._toString()); }; this._onEditorChange = editorState => { this._setEditorState(editorState); }; this._setEditorState = function (editorState) { var onStateChanged = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : () => {}; var { editorState: editorStateBefore } = _this.state; var { variableTemplate: { prefix, suffix } } = _this.props; var updateEditorState = _EditorUtilities.default.moveToEdge(editorState); var triggerCallback = () => {}; if (_EditorUtilities.default.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.default.hasUnparsedEntity(updateEditorState, prefix, suffix)) { updateEditorState = _this._stringToContentState(_EditorUtilities.default.convertToString({ editorState: updateEditorState, prefix, suffix })); } } else if (_EditorUtilities.default.isContentChanged(editorStateBefore, updateEditorState)) { triggerCallback = _this._onChange; } _this.setState({ editorState: updateEditorState }, () => { triggerCallback(); onStateChanged(); }); }; this._stringToContentState = str => { var { variableParser = () => {}, variableTagPropsParser, variableTemplate: { prefix, suffix } } = this.props; var { editorState } = this.state; var content = _EditorUtilities.default.stringToContentState({ str, variableParser, variableTagPropsParser, prefix, suffix }); return _EditorUtilities.default.pushAndKeepSelection({ editorState, content }); }; this._setStringValue = function (str) { var afterUpdated = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : () => {}; var updatedEditorState = _draftJs.EditorState.moveSelectionToEnd(_this._stringToContentState(str)); _this._setEditorState(updatedEditorState, () => { afterUpdated(updatedEditorState); }); }; /** Set value to display in the input */ this.setValue = value => { this._setStringValue(value, () => { this._onSubmit(); }); }; /** Insert variable at the input cursor position */ this.insertVariable = value => { var { variableParser, variableTagPropsParser, variableTemplate: { prefix, suffix } } = this.props; var { editorState } = this.state; var text = variableParser(value); var tagProps = variableTagPropsParser(value); var newState = text ? _EditorUtilities.default.insertEntity(editorState, { text, value, tagProps }) : _EditorUtilities.default.insertText(editorState, "".concat(prefix).concat(value).concat(suffix, " ")); this._setEditorState(newState, () => { this._onSubmit(); }); }; var { size, disabled } = props; var decorator = _EditorUtilities.default.decoratorFactory({ tag: { size: this._inputToTagSize(size), disabled } }); this.state = { editorState: _draftJs.EditorState.createEmpty(decorator) }; } componentDidMount() { var { initialValue } = this.props; this._setStringValue(initialValue); this.editorRef = /*#__PURE__*/_react.default.createRef(); } render() { var { dataHook, multiline, rows, size, disabled, readOnly, placeholder, status, statusMessage, className } = this.props; var singleLineProps = { handlePastedText: this._handlePastedText, handleReturn: () => 'handled' }; var finalStatus = (0, _StatusContext.getStatusFromContext)(this.context, status); return /*#__PURE__*/_react.default.createElement(_context.WixStyleReactContext.Consumer, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 55, columnNumber: 7 } }, _ref => { var { newColorsBranding } = _ref; return /*#__PURE__*/_react.default.createElement("div", { "data-hook": dataHook, className: (0, _VariableInputSt.st)(_VariableInputSt.classes.root, { disabled, readOnly, size, status: finalStatus, singleLine: !multiline, newColorsBranding }, className), style: { [_VariableInputSt.vars.rows]: rows }, __self: this, __source: { fileName: _jsxFileName, lineNumber: 57, columnNumber: 11 } }, /*#__PURE__*/_react.default.createElement(_draftJs.Editor, (0, _extends2.default)({ ref: this.editorRef, editorState: this.state.editorState, onChange: this._onEditorChange, onFocus: this._onFocus, placeholder: placeholder, readOnly: disabled || readOnly }, readOnly && { tabIndex: 0 }, !multiline && singleLineProps, { __self: this, __source: { fileName: _jsxFileName, lineNumber: 73, columnNumber: 13 } })), (status || finalStatus === 'loading') && /*#__PURE__*/_react.default.createElement("span", { className: _VariableInputSt.classes.indicatorWrapper, __self: this, __source: { fileName: _jsxFileName, lineNumber: 86, columnNumber: 15 } }, /*#__PURE__*/_react.default.createElement(_StatusIndicator.default, { dataHook: _constants.dataHooks.indicator, status: finalStatus, message: statusMessage, __self: this, __source: { fileName: _jsxFileName, lineNumber: 87, columnNumber: 17 } }))); }); } } VariableInput.contextType = _StatusContext.StatusContext; VariableInput.displayName = 'VariableInput'; VariableInput.propTypes = { /** Specifies a CSS class name to be appended to the component’s root element */ className: _propTypes.default.string, /** Applies a data-hook HTML attribute that can be used in the tests */ dataHook: _propTypes.default.string, /** Specifies whether input should be disabled or not */ disabled: _propTypes.default.bool, /** Specifies whether input is read only */ readOnly: _propTypes.default.bool, /** Defines an initial value to display */ initialValue: _propTypes.default.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.default.bool, /** Defines a callback function that is called each time value is changed: * `onChange(value: String): void` */ onChange: _propTypes.default.func, /** Defines a callback function that is called on value submit, in other words after `insertVariable()` and `setValue()` * `onSubmit(value: String): void` */ onSubmit: _propTypes.default.func, /** Defines a callback function that is called on focus out: * `onBlur(value: String): void` */ onBlur: _propTypes.default.func, /** Defines a callback function that is called on focus in: * `onFocus(value: String): void` */ onFocus: _propTypes.default.func, /** Specify the status of a field */ status: _propTypes.default.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.default.node, /** Sets a placeholder message to display */ placeholder: _propTypes.default.string, /** Set the height of a component to fit the given number of rows */ rows: _propTypes.default.number, /** Controls the size of the input and variable tags */ size: _propTypes.default.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.default.func, /** A function callback that is being called on each keyboard enter and expects a return of object with properties meant for Tag component. * It is designed to dynamically determine the styling or properties applied to variable tags within the input field.` */ variableTagPropsParser: _propTypes.default.func, /** Defines a template for variable recognition. Typed text strings with matching prefix and suffix symbols will be converted to <Tag/> components. */ variableTemplate: _propTypes.default.shape({ prefix: _propTypes.default.string, suffix: _propTypes.default.string }) }; VariableInput.defaultProps = { initialValue: '', multiline: true, rows: 1, size: _constants.sizeTypes.medium, variableParser: () => {}, variableTagPropsParser: () => ({}), variableTemplate: { prefix: '{{', suffix: '}}' } }; var _default = exports.default = VariableInput; //# sourceMappingURL=VariableInput.js.map