Skip to content

Instantly share code, notes, and snippets.

@Schniz
Last active April 8, 2022 17:46
Show Gist options
  • Star 26 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save Schniz/e398a630c81cfd8a3d1e to your computer and use it in GitHub Desktop.
Save Schniz/e398a630c81cfd8a3d1e to your computer and use it in GitHub Desktop.
Plain-Text ContentEditable div for React.js
.comPlainTextContentEditable {
-webkit-user-modify: read-write-plaintext-only;
}
.comPlainTextContentEditable--has-placeholder::before {
content: attr(placeholder);
opacity: 0.5;
color: inherit;
cursor: text;
}
/** @jsx React.DOM */
/* global document, window */
"use strict";
require('./plaintext-contenteditable.css');
var React = require('react');
/*************************************************
* PlainTextContentEditable
* -----------------------------------------------
* Acts like a textarea but can be used with a
* column-width/count CSS styling
* -----------------------------------------------
* Props:
* - onChange : function(event)
* to get ev.target.value
* - placeholder: placeholder text
* - className : className to pass the div
*************************************************/
var PlainTextContentEditable = React.createClass({
getDefaultProps() {
return {
onChange: function() {},
placeholder: "",
className: ""
};
},
getInitialState() {
return {
text: ""
};
},
getText(el) {
return el.innerText || this.getTextForFirefox(el);
},
getTextForFirefox(el) {
// Taken from http://stackoverflow.com/a/3908094
var text = "";
if (typeof window.getSelection != "undefined") {
var sel = window.getSelection();
var tempRange = sel.getRangeAt(0);
sel.removeAllRanges();
var range = document.createRange();
range.selectNodeContents(el);
sel.addRange(range);
text = sel.toString();
sel.removeAllRanges();
sel.addRange(tempRange);
}
return text;
},
onTextChange(ev) {
var text = this.getText(ev.target);
this.setState({ text: text });
this.props.onChange({
target: {
value: text
}
});
},
onPaste(ev) {
ev.preventDefault();
var text = ev.clipboardData.getData("text");
document.execCommand('insertText', false, text);
},
getClassName() {
var placeholder = this.state.text === "" ? "comPlainTextContentEditable--has-placeholder" : "";
return `comPlainTextContentEditable ${placeholder} ${this.props.className}`;
},
render() {
return (
<div
ref="content"
contentEditable="true"
className={ this.getClassName() }
onPaste={ this.onPaste }
onInput={ this.onTextChange }
placeholder={ this.props.placeholder }
/>
);
}
});
module.exports = PlainTextContentEditable;
@richardaum
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment