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
