wix-style-react
Version:
271 lines (232 loc) • 11.5 kB
JavaScript
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;