UNPKG

zoapp-ui

Version:

Javascript ES7 React UI Material Components extensions

288 lines (245 loc) 8.28 kB
"use strict"; 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;