UNPKG

wix-style-react

Version:
271 lines (232 loc) • 11.5 kB
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 ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } 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 { EditorState, Editor, CompositeDecorator } from 'draft-js'; import { convertFromHTML } from 'draft-convert'; import { FontUpgradeContext } from '../FontUpgrade/context'; import { st, classes, vars } from './RichTextInputArea.st.css'; import RichTextToolbar from './Toolbar/RichTextToolbar'; import EditorUtilities from './EditorUtilities'; import { RichTextInputAreaContext } from './RichTextInputAreaContext'; import { defaultTexts } from './RichTextInputAreaTexts'; import StatusIndicator from '../StatusIndicator'; import deprecationLog from '../utils/deprecationLog'; var decorator = new CompositeDecorator([{ strategy: EditorUtilities.findLinkEntities, component: function component(_ref) { var contentState = _ref.contentState, entityKey = _ref.entityKey, children = _ref.children; var _contentState$getEnti = contentState.getEntity(entityKey).getData(), url = _contentState$getEnti.url; return /*#__PURE__*/React.createElement("a", { "data-hook": "richtextarea-link", href: url, className: classes.link, target: "_blank" // Avoids a potentially serious vulnerability for '_blank' links , rel: "noopener noreferrer" }, children); } }]); var RichTextInputArea = /*#__PURE__*/function (_React$PureComponent) { _inherits(RichTextInputArea, _React$PureComponent); var _super = _createSuper(RichTextInputArea); function RichTextInputArea(props) { var _this; _classCallCheck(this, RichTextInputArea); _this = _super.call(this, props); _defineProperty(_assertThisInitialized(_this), "_setEditorState", function (newEditorState) { var onStateChanged = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; _this.setState({ editorState: newEditorState }, function () { var _this$props = _this.props, _this$props$onChange = _this$props.onChange, onChange = _this$props$onChange === void 0 ? function () {} : _this$props$onChange, prependHTTP = _this$props.prependHTTP; var htmlText = EditorUtilities.convertToHtml(newEditorState, prependHTTP); var plainText = newEditorState.getCurrentContent().getPlainText(); onChange(htmlText, { plainText: plainText }); onStateChanged(); }); }); _defineProperty(_assertThisInitialized(_this), "_updateContentByValue", function (value) { var content = convertFromHTML({ htmlToEntity: function htmlToEntity(nodeName, node, createEntity) { if (nodeName === 'a') { return createEntity('LINK', 'MUTABLE', { url: node.href }); } } })(value); var updatedEditorState = EditorState.push(_this.state.editorState, content); _this.setState({ editorState: updatedEditorState }); }); _defineProperty(_assertThisInitialized(_this), "setValue", function (value) { _this._updateContentByValue(value); }); var consumerTexts = props.texts, _prependHTTP = props.prependHTTP; if (_prependHTTP) { deprecationLog('<RichTextInputArea /> - prependHTTP prop is deprecated and will be removed in next major release, please use tooltipContent instead'); } _this.state = { editorState: EditorState.createEmpty(decorator), texts: { toolbarButtons: _objectSpread(_objectSpread({}, defaultTexts.toolbarButtons), consumerTexts.toolbarButtons), insertionForm: _objectSpread(_objectSpread({}, defaultTexts.insertionForm), consumerTexts.insertionForm) } }; return _this; } _createClass(RichTextInputArea, [{ key: "componentDidMount", value: function componentDidMount() { var initialValue = this.props.initialValue; // TODO: currently it treats the value as an initial value this._updateContentByValue(initialValue); this.editorRef = /*#__PURE__*/React.createRef(); } }, { key: "render", value: function render() { var _this2 = this; var _this$props2 = this.props, dataHook = _this$props2.dataHook, className = _this$props2.className, placeholder = _this$props2.placeholder, disabled = _this$props2.disabled, minHeight = _this$props2.minHeight, maxHeight = _this$props2.maxHeight, status = _this$props2.status, statusMessage = _this$props2.statusMessage, spellCheck = _this$props2.spellCheck; var isEditorEmpty = EditorUtilities.isEditorEmpty(this.state.editorState); return /*#__PURE__*/React.createElement(FontUpgradeContext.Consumer, null, function (_ref2) { var _ref3; var isMadefor = _ref2.active; return /*#__PURE__*/React.createElement("div", { "data-hook": dataHook, className: st(classes.root, { isMadefor: isMadefor, hidePlaceholder: !isEditorEmpty, disabled: disabled, hasError: !disabled && status === 'error', hasWarning: !disabled && status === 'warning' }, className) // Using CSS variable instead of applying minHeight & maxHeight on each child, down to the editor's content , style: (_ref3 = {}, _defineProperty(_ref3, vars.minHeight, minHeight), _defineProperty(_ref3, vars.maxHeight, maxHeight), _ref3) }, /*#__PURE__*/React.createElement(RichTextInputAreaContext.Provider, { value: { texts: _this2.state.texts } }, /*#__PURE__*/React.createElement(RichTextToolbar, { dataHook: "richtextarea-toolbar", className: classes.toolbar, isDisabled: disabled, editorState: _this2.state.editorState, onBold: _this2._setEditorState, onItalic: _this2._setEditorState, onUnderline: _this2._setEditorState, onLink: function onLink(newEditorState) { _this2._setEditorState(newEditorState, function () { return _this2.editorRef.current.focus(); }); }, onBulletedList: _this2._setEditorState, onNumberedList: _this2._setEditorState })), /*#__PURE__*/React.createElement("div", { className: classes.editorWrapper }, /*#__PURE__*/React.createElement(Editor, { ref: _this2.editorRef, editorState: _this2.state.editorState, onChange: _this2._setEditorState, placeholder: placeholder, readOnly: disabled, spellCheck: spellCheck }), !disabled && status && /*#__PURE__*/React.createElement("span", { className: classes.statusIndicator }, /*#__PURE__*/React.createElement(StatusIndicator, { dataHook: "richtextarea-status-indicator", status: status, message: statusMessage })))); }); } }]); return RichTextInputArea; }(React.PureComponent); RichTextInputArea.displayName = 'RichTextInputArea'; RichTextInputArea.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, /** Sets the initial value to be displayed in the editor. */ initialValue: PropTypes.string, /** Sets a placeholder message to display. */ placeholder: PropTypes.string, /** Specifies whether an editor and its toolbar should be disabled. */ disabled: PropTypes.bool, /** Specifies 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.string, /** Defines a standard callback function for changes: `onChange(htmlText, { plainText })` */ onChange: PropTypes.func, /** Defines a minimum height for the editor (it grows by default) */ minHeight: PropTypes.string, /** Defines a maximum height for the editor (it grows by default) */ maxHeight: PropTypes.string, /** * Enables browsers spell checking. * Do not affect IE. * In Safari, autocorrects by default. */ spellCheck: PropTypes.bool, /** Defines text styles to be shown. */ texts: PropTypes.shape({ toolbarButtons: PropTypes.shape({ boldButtonLabel: PropTypes.string, italicButtonLabel: PropTypes.string, underlineButtonLabel: PropTypes.string, linkButtonLabel: PropTypes.string, bulletedListButtonLabel: PropTypes.string, numberedListButtonLabel: PropTypes.string }), insertionForm: PropTypes.shape({ confirmButtonLabel: PropTypes.string, cancelButtonLabel: PropTypes.string, link: PropTypes.shape({ textInputPlaceholder: PropTypes.string, urlInputPlaceholder: PropTypes.string }) }) }), /** Prepend http protocol to link if it does not have it. * (ex. typed link is wix.com becomes http://wix.com) * @deprecated */ prependHTTP: PropTypes.bool }; RichTextInputArea.defaultProps = { initialValue: '<p/>', texts: {}, disabled: false }; export default RichTextInputArea;