simple-text-editor-react
Version:
A simple text editor with image upload functionality
254 lines (226 loc) • 7.73 kB
JavaScript
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import parse from 'html-react-parser';
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
var SimpleEditor = /*#__PURE__*/function (_Component) {
_inheritsLoose(SimpleEditor, _Component);
function SimpleEditor(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.getText = function () {
var element = document.querySelector('div[contenteditable]');
var firstTag = element.firstChild.nodeName;
var keyTag = new RegExp(firstTag === '#text' ? '<br' : '</' + firstTag, 'i');
var tmp = document.createElement('p');
tmp.innerHTML = element.innerHTML.replace(/<[^>]+>/g, function (m, i) {
return keyTag.test(m) ? '{ß®}' : '';
}).replace(/{ß®}$/, '');
return tmp.innerText.replace(/{ß®}/g, '\n');
};
_this.updateWordCharCount = function (element) {
var text = element.innerText.replace(/\n|\r/g, ' ');
var cc = text.replace(/[^a-z0-9]/gi, '').length;
var wc = text.split(' ').filter(function (text) {
return text !== '';
}).length;
_this.setState({
wordcount: wc,
charcount: cc
});
};
_this.storeKeyEvent = function (e) {
_this.setState(function (prevState) {
return {
keyEvents: [].concat(prevState.keyEvents, [e.code])
};
});
};
_this.clickFile = function () {
document.getElementById('simple-editor-image-upload').click();
};
_this.handleFileUpload = function (e) {
var onImageUpload = _this.props.onImageUpload;
var element = document.querySelector('#simple-editor');
if (e.target.files[0].type === 'image/jpeg' || e.target.files[0].type === 'image/png') {
var filename = e.target.files[0].name.split(' ');
var currentTimstamp = Date.now().toString();
var imageName = currentTimstamp.concat('-', filename[filename.length - 1]);
var imgelement = document.createElement('img');
imgelement.id = "" + imageName;
imgelement.classList.add('s-e-image');
imgelement.style.cssText = 'max-width: 60%; height: auto;';
imgelement.src = URL.createObjectURL(e.target.files[0]);
document.getElementById('simple-editor').appendChild(imgelement);
onImageUpload(e.target.files[0], function (status, url) {
if (status) {
document.getElementById("" + imageName).src = url;
} else {
document.getElementById("" + imageName).remove();
}
_this.props.onChange({
html: element.innerHTML,
keyEvents: _this.state.keyEvents
});
document.getElementById('simple-editor-image-upload').value = '';
});
} else {
document.getElementById('simple-editor-image-upload').value = '';
alert('Only Png or Jpeg Image format is allowed');
}
};
_this.state = {
text: _this.props.value,
id: _this.props.id,
wordcount: 0,
charcount: 0,
isChanged: false,
keyEvents: []
};
return _this;
}
var _proto = SimpleEditor.prototype;
_proto.componentDidMount = function componentDidMount() {
var _this2 = this;
var element = document.querySelector('#simple-editor');
element.addEventListener('paste', function (event) {
event.preventDefault();
});
element.addEventListener('copy', function (event) {
event.preventDefault();
});
element.addEventListener('cut', function (event) {
event.preventDefault();
});
element.addEventListener('keydown', this.storeKeyEvent);
var observer = new MutationObserver(function (mutations) {
return mutations.forEach(function (mutation) {
_this2.setState({
isChanged: true
});
_this2.updateWordCharCount(element);
_this2.props.onChange({
html: element.innerHTML,
keyEvents: _this2.state.keyEvents
});
});
});
observer.observe(element, {
childList: true,
characterData: true,
subtree: true
});
};
SimpleEditor.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
if (prevState.id !== nextProps.id) {
return {
id: nextProps.id,
isChanged: false,
keyEvents: []
};
}
return null;
};
_proto.componentDidUpdate = function componentDidUpdate(prevProps) {
if (this.props.id !== prevProps.id) {
this.SimpleEditorNode.innerHTML = this.props.value;
} else if (this.props.id == prevProps.id && !this.state.isChanged) {
this.SimpleEditorNode.innerHTML = this.props.value;
} else if (this.props.value !== prevProps.value) {
if (this.props.value === '') {
this.SimpleEditorNode.innerHTML = this.props.value;
}
}
};
_proto.render = function render() {
var _this3 = this;
var _this$props = this.props,
containerStyle = _this$props.containerStyle,
editorStyle = _this$props.editorStyle,
showWordCharCount = _this$props.showWordCharCount;
var _this$state = this.state,
wordcount = _this$state.wordcount,
text = _this$state.text,
charcount = _this$state.charcount;
return /*#__PURE__*/React.createElement("div", {
style: containerStyle,
id: "simple-editor-container"
}, /*#__PURE__*/React.createElement("div", {
style: {
height: '35px',
backgroundColor: '#f3f2f2'
}
}, /*#__PURE__*/React.createElement("input", {
type: "file",
accept: "image/png,image/jpeg",
id: "simple-editor-image-upload",
style: {
display: 'none'
},
onChange: this.handleFileUpload
}), /*#__PURE__*/React.createElement("img", {
src: "https://ik.imagekit.io/bikram/add_photo_alternate-24px_KDmBRwDhm.svg",
style: {
height: '25px',
width: '25px',
padding: '6px',
cursor: 'pointer'
},
alt: "add",
onClick: this.clickFile
})), /*#__PURE__*/React.createElement("div", {
id: "simple-editor",
style: editorStyle,
contentEditable: "true",
suppressContentEditableWarning: "true",
ref: function ref(node) {
return _this3.SimpleEditorNode = node;
}
}, parse(text)), showWordCharCount && /*#__PURE__*/React.createElement("div", {
style: {
position: 'absolute',
bottom: '4px',
right: '10px',
fontSize: '12px',
color: 'rgb(74 74 74)'
}
}, /*#__PURE__*/React.createElement("span", null, wordcount + " " + (wordcount < 2 ? 'word' : 'words') + ", " + charcount + " " + (charcount < 2 ? 'character' : 'characters'))));
};
return SimpleEditor;
}(Component);
SimpleEditor.defaultProps = {
containerStyle: {
position: 'relative',
width: '600px',
height: '600px',
border: '1px solid #cec7c7',
paddingBottom: '20px'
},
editorStyle: {
width: 'calc(100% - 9px)',
height: 'calc(100% - 62px)',
padding: '4px',
outline: 'none',
overflow: 'auto',
'&:focus': {
outline: '0px'
}
},
onChange: function onChange() {},
value: '',
id: '1',
showWordCharCount: true
};
SimpleEditor.propTypes = {
containerStyle: PropTypes.object,
onImageUpload: PropTypes.func.isRequired,
onChange: PropTypes.func,
value: PropTypes.string,
id: PropTypes.string,
showWordCharCount: PropTypes.bool
};
export default SimpleEditor;
//# sourceMappingURL=index.modern.js.map