office-ui-fabric-react
Version:
Reusable React components for building experiences for Office 365.
124 lines (122 loc) • 6.03 kB
JavaScript
define(["require", "exports", "tslib", "react", "../../Utilities", "./ResizeGroup.scss"], function (require, exports, tslib_1, React, Utilities_1, styles) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var RESIZE_DELAY = 16;
var ResizeGroup = (function (_super) {
tslib_1.__extends(ResizeGroup, _super);
function ResizeGroup(props) {
var _this = _super.call(this, props) || this;
_this._lastKnownRootWidth = undefined;
_this._lastKnownMeasuredWidth = undefined;
_this.state = {
shouldMeasure: true,
renderedData: null,
measuredData: tslib_1.__assign({}, _this.props.data),
};
return _this;
}
ResizeGroup.prototype.componentWillReceiveProps = function (nextProps) {
if (this.props.data !== nextProps.data) {
this.setState({
shouldMeasure: true,
renderedData: null,
measuredData: tslib_1.__assign({}, nextProps.data)
});
}
};
ResizeGroup.prototype.componentDidMount = function () {
this._measureItems();
this._events.on(window, 'resize', this._async.debounce(this._onResize, RESIZE_DELAY, { leading: true }));
};
ResizeGroup.prototype.componentWillUnmount = function () {
this._lastKnownRootWidth = undefined;
this._lastKnownMeasuredWidth = undefined;
};
ResizeGroup.prototype.render = function () {
var _a = this.props, onRenderData = _a.onRenderData, data = _a.data;
var _b = this.state, shouldMeasure = _b.shouldMeasure, renderedData = _b.renderedData, measuredData = _b.measuredData;
if (Object.keys(data).length === 0) {
return null;
}
return (React.createElement("div", { className: Utilities_1.css('ms-ResizeGroup'), ref: this._resolveRef('_root') },
shouldMeasure && (React.createElement("div", { className: Utilities_1.css(styles.measured), ref: this._resolveRef('_measured') }, onRenderData(measuredData))),
renderedData && onRenderData(renderedData)));
};
ResizeGroup.prototype.componentDidUpdate = function (prevProps) {
this._measureItems();
if (this.state.renderedData) {
if (this.props.dataDidRender) {
this.props.dataDidRender(this.state.renderedData);
}
}
};
ResizeGroup.prototype._onResize = function () {
var shouldMeasure = true;
var nextMeasuredData = this.state.measuredData;
if (this._root && this._lastKnownRootWidth && this._lastKnownMeasuredWidth) {
// If we have some cached measurements, let's see if we can skip rendering
var containerWidth = this._root.getBoundingClientRect().width;
if (containerWidth <= this._lastKnownRootWidth) {
// If the container shrank as a result of this resize, we can do an optimized rerender.
if (this._lastKnownMeasuredWidth <= containerWidth) {
// If the contents still fit within the container, don't trigger a remeasure.
this._lastKnownRootWidth = containerWidth;
shouldMeasure = false;
}
else {
// If the container shrank and the contents don't fit, we can trigger a measurement
// pass starting from the current value of rendered data.
nextMeasuredData = this.state.renderedData;
}
}
}
if (shouldMeasure) {
this.setState({
shouldMeasure: true,
measuredData: nextMeasuredData
});
}
};
ResizeGroup.prototype._setStateToDoneMeasuring = function () {
var _this = this;
this.setState(function (prevState, props) {
return {
renderedData: prevState.measuredData,
measuredData: tslib_1.__assign({}, _this.props.data),
shouldMeasure: false
};
});
};
ResizeGroup.prototype._measureItems = function () {
var _a = this.props, data = _a.data, onReduceData = _a.onReduceData;
var shouldMeasure = this.state.shouldMeasure;
if (shouldMeasure && Object.keys(data).length !== 0 && this._root && this._measured) {
var containerWidth = this._lastKnownRootWidth = this._root.getBoundingClientRect().width;
var measuredWidth = this._lastKnownMeasuredWidth = this._measured.getBoundingClientRect().width;
if ((measuredWidth > containerWidth)) {
var nextMeasuredData = onReduceData(this.state.measuredData);
// We don't want to get stuck in an infinite render loop when there are no more
// scaling steps, so implementations of onReduceData should return undefined when
// there are no more scaling states to apply.
if (nextMeasuredData !== undefined) {
this.setState({
measuredData: nextMeasuredData,
});
}
else {
this._setStateToDoneMeasuring();
}
}
else {
this._setStateToDoneMeasuring();
}
}
};
return ResizeGroup;
}(Utilities_1.BaseComponent));
ResizeGroup.defaultProps = {
data: {}
};
exports.ResizeGroup = ResizeGroup;
});
//# sourceMappingURL=ResizeGroup.js.map