UNPKG

react-blessed

Version:
246 lines (185 loc) 8.29 kB
/** * React Blessed Component * ======================== * * React component abstraction for the blessed library. */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var _blessed = require('blessed'); var _blessed2 = _interopRequireDefault(_blessed); var _reactLibReactMultiChild = require('react/lib/ReactMultiChild'); var _reactLibReactMultiChild2 = _interopRequireDefault(_reactLibReactMultiChild); var _ReactBlessedIDOperations = require('./ReactBlessedIDOperations'); var _ReactBlessedIDOperations2 = _interopRequireDefault(_ReactBlessedIDOperations); var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant); var _update = require('./update'); var _update2 = _interopRequireDefault(_update); var _solveClass = require('./solveClass'); var _solveClass2 = _interopRequireDefault(_solveClass); var _lodash = require('lodash'); /** * Variable types that must be solved as content rather than real children. */ var CONTENT_TYPES = { string: true, number: true }; /** * Renders the given react element with blessed. * * @constructor ReactBlessedComponent * @extends ReactMultiChild */ var ReactBlessedComponent = (function () { function ReactBlessedComponent(tag) { _classCallCheck(this, ReactBlessedComponent); this._tag = tag.toLowerCase(); this._renderedChildren = null; this._previousStyle = null; this._previousStyleCopy = null; this._rootNodeID = null; this._wrapperState = null; this._topLevelWrapper = null; this._nodeWithLegacyProperties = null; } /** * Extending the component with the MultiChild mixin. */ _createClass(ReactBlessedComponent, [{ key: 'construct', value: function construct(element) { var _this = this; // Setting some properties this._currentElement = element; this._eventListener = function (type) { for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } var handler = _this._currentElement.props['on' + (0, _lodash.startCase)(type)]; if (typeof handler === 'function') handler.apply(null, args); }; } /** * Mounting the root component. * * @internal * @param {string} rootID - The root blessed ID for this node. * @param {ReactBlessedReconcileTransaction} transaction * @param {object} context */ }, { key: 'mountComponent', value: function mountComponent(rootID, transaction, context) { this._rootNodeID = rootID; // Mounting blessed node var node = this.mountNode(_ReactBlessedIDOperations2['default'].getParent(rootID), this._currentElement); _ReactBlessedIDOperations2['default'].add(rootID, node); // Mounting children var childrenToUse = this._currentElement.props.children; childrenToUse = childrenToUse === null ? [] : [].concat(childrenToUse); if (childrenToUse.length) { // Discriminating content components from real children var _groupBy = (0, _lodash.groupBy)(childrenToUse, function (c) { return CONTENT_TYPES[typeof c] ? 'content' : 'realChildren'; }); var _groupBy$content = _groupBy.content; var content = _groupBy$content === undefined ? null : _groupBy$content; var _groupBy$realChildren = _groupBy.realChildren; var realChildren = _groupBy$realChildren === undefined ? [] : _groupBy$realChildren; // Setting textual content if (content) node.setContent('' + content.join('')); // Mounting real children this.mountChildren(realChildren, transaction, context); } // Rendering the screen _ReactBlessedIDOperations2['default'].screen.debouncedRender(); } /** * Mounting the blessed node itself. * * @param {BlessedNode|BlessedScreen} parent - The parent node. * @param {ReactElement} element - The element to mount. * @return {BlessedNode} - The mounted node. */ }, { key: 'mountNode', value: function mountNode(parent, element) { var props = element.props; var type = element.type; var children = props.children; var options = _objectWithoutProperties(props, ['children']); var blessedElement = _blessed2['default'][type]; (0, _invariant2['default'])(!!blessedElement, 'Invalid blessed element "' + type + '".'); var node = _blessed2['default'][type]((0, _solveClass2['default'])(options)); node.on('event', this._eventListener); parent.append(node); return node; } /** * Receive a component update. * * @param {ReactElement} nextElement * @param {ReactReconcileTransaction} transaction * @param {object} context * @internal * @overridable */ }, { key: 'receiveComponent', value: function receiveComponent(nextElement, transaction, context) { var _nextElement$props = nextElement.props; var children = _nextElement$props.children; var options = _objectWithoutProperties(_nextElement$props, ['children']); var node = _ReactBlessedIDOperations2['default'].get(this._rootNodeID); (0, _update2['default'])(node, (0, _solveClass2['default'])(options)); // Updating children var childrenToUse = children === null ? [] : [].concat(children); if (childrenToUse.length) { // Discriminating content components from real children var _groupBy2 = (0, _lodash.groupBy)(childrenToUse, function (c) { return CONTENT_TYPES[typeof c] ? 'content' : 'realChildren'; }); var _groupBy2$content = _groupBy2.content; var content = _groupBy2$content === undefined ? null : _groupBy2$content; var _groupBy2$realChildren = _groupBy2.realChildren; var realChildren = _groupBy2$realChildren === undefined ? [] : _groupBy2$realChildren; // Setting textual content if (content) node.setContent('' + content.join('')); this.updateChildren(realChildren, transaction, context); } _ReactBlessedIDOperations2['default'].screen.debouncedRender(); } /** * Dropping the component. */ }, { key: 'unmountComponent', value: function unmountComponent() { this.unmountChildren(); var node = _ReactBlessedIDOperations2['default'].get(this._rootNodeID); node.off('event', this._eventListener); node.destroy(); _ReactBlessedIDOperations2['default'].drop(this._rootNodeID); this._rootNodeID = null; } /** * Getting a public instance of the component for refs. * * @return {BlessedNode} - The instance's node. */ }, { key: 'getPublicInstance', value: function getPublicInstance() { return _ReactBlessedIDOperations2['default'].get(this._rootNodeID); } }]); return ReactBlessedComponent; })(); exports['default'] = ReactBlessedComponent; (0, _lodash.extend)(ReactBlessedComponent.prototype, _reactLibReactMultiChild2['default'].Mixin); module.exports = exports['default'];