zoapp-ui
Version:
Javascript ES7 React UI Material Components extensions
288 lines (245 loc) • 8.28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _toConsumableArray2 = require("babel-runtime/helpers/toConsumableArray");
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require("babel-runtime/helpers/createClass");
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require("babel-runtime/helpers/possibleConstructorReturn");
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require("babel-runtime/helpers/inherits");
var _inherits3 = _interopRequireDefault(_inherits2);
var _react = require("react");
var _react2 = _interopRequireDefault(_react);
var _propTypes = require("prop-types");
var _propTypes2 = _interopRequireDefault(_propTypes);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Inspired from https://github.com/bmcmahen/react-wysiwyg/blob/master/index.js
/**
* Copyright (c) 2015-present, CWB SAS
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var ContentEditable = function (_Component) {
(0, _inherits3.default)(ContentEditable, _Component);
function ContentEditable(props) {
(0, _classCallCheck3.default)(this, ContentEditable);
var _this = (0, _possibleConstructorReturn3.default)(this, (ContentEditable.__proto__ || Object.getPrototypeOf(ContentEditable)).call(this, props));
_initialiseProps.call(_this);
var caretPosition = _this.props.caretPosition || -1;
// const selectedItem = this.props.selectedItem || -1;
_this.state = { caretPosition: caretPosition };
return _this;
}
(0, _createClass3.default)(ContentEditable, [{
key: "componentDidMount",
value: function componentDidMount() {
var _this2 = this;
// this.updateFocus();
window.setTimeout(function () {
_this2.updateFocus();
}, 100);
}
}, {
key: "shouldComponentUpdate",
value: function shouldComponentUpdate(nextProps) {
var element = this.node; // ReactDOM.findDOMNode(this);
var template = document.createElement("template");
var content = nextProps.content;
template.innerHTML = content;
content = template.innerHTML;
var current = element.innerHTML;
if (content !== current) {
return true;
}
return false;
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate() {
var _this3 = this;
// this.updateFocus();
window.setTimeout(function () {
_this3.updateFocus();
}, 100);
}
}, {
key: "getCaretPosition",
value: function getCaretPosition() {
var range = window.getSelection().getRangeAt(0);
this.range = range;
// const clone = range.cloneRange();
// clone.selectNodeContents(element);
// clone.setEnd(range.endContainer, range.endOffset);
// console.log("clone ", clone.startOffset, clone.endOffset, clone, range);
return range.startOffset;
}
}, {
key: "updateFocus",
value: function updateFocus() {
var source = this.node; // ReactDOM.findDOMNode(this);
var focusIndex = this.props.selectedItem;
var caretPosition = this.state.caretPosition;
var children = [].concat((0, _toConsumableArray3.default)(source.children));
var element = null;
if (focusIndex === -1) {
focusIndex = children.length - 1;
}
for (var index = 0; index < children.length; index += 1) {
if (focusIndex === index) {
element = children[index];
break;
}
}
if (element) {
element.focus();
var len = element.innerText.length - 1;
if (len < 0) {
len = 0;
}
if (caretPosition < 0 || caretPosition >= len) {
caretPosition = len;
}
var range = document.createRange();
var sel = window.getSelection();
range.selectNodeContents(element);
var carret = 1;
range.setStart(element, carret);
range.setEnd(element, carret);
// range.collapse(false);
sel.removeAllRanges();
sel.addRange(range);
// console.log("setFocus");
}
}
}, {
key: "updateCaretPosition",
value: function updateCaretPosition(element) {
var caretPosition = this.getCaretPosition(element);
if (this.state.caretPosition !== caretPosition) {
this.setState(function () {
return { caretPosition: caretPosition };
});
}
return caretPosition;
}
}, {
key: "navigate",
value: function navigate(e /* , name */) {
var element = e.target;
if (element.tabIndex !== 0) {
/* const caretPosition = */this.updateCaretPosition(element);
// console.log("navigate", name, caretPosition);
}
}
}, {
key: "render",
value: function render() {
var _this4 = this;
// const editing = true;
var _props = this.props,
className = _props.className,
content = _props.content;
var tagName = "div";
// setup our classes
var classes = "ContentEditable ";
// TODO set Material Design color
var placeholderStyle = { color: "#bbbbbb" };
if (className) {
classes += className;
}
// return our newly created element
return _react2.default.createElement(tagName, {
tabIndex: 0,
key: "0",
className: classes,
contentEditable: false,
"aria-label": this.props.placeholder,
style: this.props.placeholder ? placeholderStyle : this.props.style || {},
dangerouslySetInnerHTML: {
__html: content
},
spellCheck: false,
onFocus: this.onFocus,
onMouseUp: this.onMouseUp,
onTouchEnd: this.onMouseUp,
onKeyUp: this.onKeyPress,
onInput: this.onInput,
ref: function ref(node) {
_this4.node = node;
}
});
}
}]);
return ContentEditable;
}(_react.Component);
var _initialiseProps = function _initialiseProps() {
var _this5 = this;
this.onFocus = function (e) {
// WIP
var element = e.target;
if (element.tabIndex !== 0) {
// console.log("onFocus In ", element);
var caretPosition = _this5.updateCaretPosition(element);
_this5.props.onFocusIn(element, caretPosition);
// e.preventDefault();
}
// console.log("onFocus ", e.target);
};
this.onMouseUp = function (e) {
var element = e.target;
if (element.tabIndex !== 0) {
/* const caretPosition = */_this5.updateCaretPosition(element);
// console.log("onMouseUp ", caretPosition);
}
};
this.onKeyPress = function (e) {
switch (e.which) {
case 38:
_this5.navigate(e, "ArrowUp");
break;
case 40:
_this5.navigate(e, "ArrowDown");
break;
case 37:
_this5.navigate(e, "ArrowLeft");
break;
case 39:
_this5.navigate(e, "ArrowRight");
break;
default:
break;
}
};
this.onInput = function (event) {
var element = _this5.node; // ReactDOM.findDOMNode(this);
var text = element.textContent.trim();
var e = event.target;
var caretPosition = _this5.updateCaretPosition(e);
_this5.props.onChange(text, element, { element: e, caretPosition: caretPosition });
};
};
ContentEditable.defaultProps = {
className: null,
selectedItem: -1,
content: "",
caretPosition: 0,
placeholder: null,
onFocusIn: null,
style: null
};
ContentEditable.propTypes = {
className: _propTypes2.default.string,
selectedItem: _propTypes2.default.number,
content: _propTypes2.default.string,
caretPosition: _propTypes2.default.number,
placeholder: _propTypes2.default.string,
onChange: _propTypes2.default.func.isRequired,
onFocusIn: _propTypes2.default.func,
style: _propTypes2.default.objectOf(_propTypes2.default.string)
};
exports.default = ContentEditable;