armo-breadboard
Version:
Edit a live React component's source in real time.
289 lines (235 loc) • 10.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.InjectDimensions = undefined;
var _class, _temp;
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; }; }();
exports.injectDimensions = injectDimensions;
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _exenv = require('exenv');
var _exenv2 = _interopRequireDefault(_exenv);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _hoistNonReactStatics = require('hoist-non-react-statics');
var _hoistNonReactStatics2 = _interopRequireDefault(_hoistNonReactStatics);
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 _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var breadboardResizeObserver = void 0;
if (_exenv2.default.canUseDOM) {
var ResizeObserver = require('resize-observer-polyfill').default;
var BreadboardResizeObserver = function () {
function BreadboardResizeObserver() {
var _this = this;
_classCallCheck(this, BreadboardResizeObserver);
this.callbacks = new Map();
this.observer = new ResizeObserver(function (entries) {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = entries[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var entry = _step.value;
var callback = _this.callbacks.get(entry.target);
if (callback) {
callback({
height: entry.contentRect.height,
width: entry.contentRect.width
});
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
});
}
_createClass(BreadboardResizeObserver, [{
key: 'observe',
value: function observe(target, callback) {
this.observer.observe(target);
this.callbacks.set(target, callback);
}
}, {
key: 'unobserve',
value: function unobserve(target, callback) {
this.observer.unobserve(target);
this.callbacks.delete(target, callback);
}
}]);
return BreadboardResizeObserver;
}();
breadboardResizeObserver = new BreadboardResizeObserver();
}
/**
* Inject the child element's width and height, as computed by a
* ResizeObserver.
*/
var InjectDimensions = exports.InjectDimensions = (_temp = _class = function (_Component) {
_inherits(InjectDimensions, _Component);
function InjectDimensions(props) {
_classCallCheck(this, InjectDimensions);
// The dimensions are not defined until we can measure them, or unless
// a fixed value is provided.
var _this2 = _possibleConstructorReturn(this, (InjectDimensions.__proto__ || Object.getPrototypeOf(InjectDimensions)).call(this, props));
_this2.receiveRef = function (x) {
_this2.domNode = x && _reactDom2.default.findDOMNode(x);
};
_this2.handleResize = function (measured) {
_this2.setState({
height: measured.height,
width: measured.width
});
};
_this2.state = {
observed: false,
height: undefined,
width: undefined
};
return _this2;
}
_createClass(InjectDimensions, [{
key: 'componentDidMount',
value: function componentDidMount() {
var shouldObserve = this.props.width === undefined || this.props.height === undefined;
if (shouldObserve) {
this.observe();
}
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
var shouldObserve = nextProps.width === undefined || nextProps.height === undefined;
if (shouldObserve && !this.state.observed) {
this.observe();
} else if (!shouldObserve && this.state.observed) {
this.unobserve();
this.setState({
observed: false
});
}
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate(prevProps, prevState) {
var shouldObserve = this.props.width === undefined || this.props.height === undefined;
if (this.domNode !== this.state.observed) {
this.unobserve();
if (this.domNode && shouldObserve) {
this.observe();
}
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.unobserve();
}
}, {
key: 'shouldComponentUpdate',
value: function shouldComponentUpdate(nextProps, nextState) {
var measuredHeightChanged = nextState.height !== this.state.height;
var measuredWidthChanged = nextState.width !== this.state.width;
// don't cause an update when it originated from a resize observation,
// but that observation is overriden by a forced width/height
var insignificantMeasurementOccured = nextState.observed && this.state.observed && (measuredHeightChanged || measuredWidthChanged) && !(measuredHeightChanged && nextProps.height === undefined || measuredWidthChanged && nextProps.width === undefined);
return !insignificantMeasurementOccured;
}
}, {
key: 'render',
value: function render() {
var props = this.props;
var state = this.state;
return _react2.default.cloneElement(_react2.default.Children.only(props.children), {
width: state.width === undefined ? props.defaultWidth : state.width,
height: state.height === undefined ? props.defaultHeight : state.height,
ref: this.receiveRef
});
}
}, {
key: 'observe',
value: function observe() {
breadboardResizeObserver.observe(this.domNode, this.handleResize);
var measured = this.domNode.getBoundingClientRect();
this.setState({
observed: this.domNode,
height: measured.height,
width: measured.width
});
}
}, {
key: 'unobserve',
value: function unobserve() {
if (this.state.observed) {
breadboardResizeObserver.unobserve(this.state.observed, this.handleResize);
}
}
}]);
return InjectDimensions;
}(_react.Component), _class.propTypes = {
/**
* The value to use for `height` before we are able to make a measurement.
*/
defaultHeight: _propTypes2.default.number,
/**
* The value to use for `width` before we are able to make a measurement.
*/
defaultWidth: _propTypes2.default.number,
/**
* If a number or `null`, the height will be passed directly to the child
* element instead of being observed.
*/
height: _propTypes2.default.number,
/**
* If a number or `null`, the width will be passed directly to the child
* element instead of being observed.
*/
width: _propTypes2.default.number,
/**
* This component expects a single child that is a React Element.
*/
children: _propTypes2.default.element.isRequired
}, _temp);
function injectDimensions(WrappedComponent) {
function InjectDimensionsWrapper(_ref) {
var defaultHeight = _ref.defaultHeight,
defaultWidth = _ref.defaultWidth,
height = _ref.height,
width = _ref.width,
other = _objectWithoutProperties(_ref, ['defaultHeight', 'defaultWidth', 'height', 'width']);
return _react2.default.createElement(InjectDimensions, { defaultHeight: defaultHeight, defaultWidth: defaultWidth, height: height, width: width }, _react2.default.createElement(WrappedComponent, other));
}
(0, _hoistNonReactStatics2.default)(InjectDimensionsWrapper, WrappedComponent);
return InjectDimensionsWrapper;
}
injectDimensions.withConfiguration = function (forceProps) {
return function injectDimensions(WrappedComponent) {
function InjectDimensionsWrapper(props) {
var _Object$assign = Object.assign({}, props, forceProps),
defaultHeight = _Object$assign.defaultHeight,
defaultWidth = _Object$assign.defaultWidth,
height = _Object$assign.height,
width = _Object$assign.width,
other = _objectWithoutProperties(_Object$assign, ['defaultHeight', 'defaultWidth', 'height', 'width']);
return _react2.default.createElement(InjectDimensions, { defaultHeight: defaultHeight, defaultWidth: defaultWidth, height: height, width: width }, _react2.default.createElement(WrappedComponent, other));
}
(0, _hoistNonReactStatics2.default)(InjectDimensionsWrapper, WrappedComponent);
return InjectDimensionsWrapper;
};
};