UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Microsoft 365.

140 lines 7.3 kB
define(["require", "exports", "tslib", "react", "./BaseDecorator", "../../Utilities"], function (require, exports, tslib_1, React, BaseDecorator_1, Utilities_1) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var RESIZE_DELAY = 500; var MAX_RESIZE_ATTEMPTS = 3; /** * A decorator to update decorated component on viewport or window resize events. * * @param ComposedComponent - decorated React component reference. */ function withViewport(ComposedComponent) { return /** @class */ (function (_super) { tslib_1.__extends(WithViewportComponent, _super); function WithViewportComponent(props) { var _this = _super.call(this, props) || this; _this._root = React.createRef(); _this._registerResizeObserver = function () { var win = Utilities_1.getWindow(_this._root.current); _this._viewportResizeObserver = new win.ResizeObserver(_this._onAsyncResize); _this._viewportResizeObserver.observe(_this._root.current); }; _this._unregisterResizeObserver = function () { if (_this._viewportResizeObserver) { _this._viewportResizeObserver.disconnect(); delete _this._viewportResizeObserver; } }; /* Note: using lambda here because decorators don't seem to work in decorators. */ _this._updateViewport = function (withForceUpdate) { var viewport = _this.state.viewport; var viewportElement = _this._root.current; var scrollElement = Utilities_1.findScrollableParent(viewportElement); var scrollRect = Utilities_1.getRect(scrollElement); var clientRect = Utilities_1.getRect(viewportElement); var updateComponent = function () { if (withForceUpdate && _this._composedComponentInstance) { _this._composedComponentInstance.forceUpdate(); } }; var isSizeChanged = (clientRect && clientRect.width) !== viewport.width || (scrollRect && scrollRect.height) !== viewport.height; if (isSizeChanged && _this._resizeAttempts < MAX_RESIZE_ATTEMPTS && clientRect && scrollRect) { _this._resizeAttempts++; _this.setState({ viewport: { width: clientRect.width, height: scrollRect.height, }, }, function () { _this._updateViewport(withForceUpdate); }); } else { _this._resizeAttempts = 0; updateComponent(); } }; _this._async = new Utilities_1.Async(_this); _this._events = new Utilities_1.EventGroup(_this); _this._resizeAttempts = 0; _this.state = { viewport: { width: 0, height: 0, }, }; return _this; } WithViewportComponent.prototype.componentDidMount = function () { var _this = this; var _a = this.props, delayFirstMeasure = _a.delayFirstMeasure, disableResizeObserver = _a.disableResizeObserver, skipViewportMeasures = _a.skipViewportMeasures; var win = Utilities_1.getWindow(this._root.current); this._onAsyncResize = this._async.debounce(this._onAsyncResize, RESIZE_DELAY, { leading: false, }); if (!skipViewportMeasures) { if (!disableResizeObserver && this._isResizeObserverAvailable()) { this._registerResizeObserver(); } else { this._events.on(win, 'resize', this._onAsyncResize); } if (delayFirstMeasure) { this._async.setTimeout(function () { _this._updateViewport(); }, RESIZE_DELAY); } else { this._updateViewport(); } } }; WithViewportComponent.prototype.componentDidUpdate = function (previousProps) { var previousSkipViewportMeasures = previousProps.skipViewportMeasures; var _a = this.props, disableResizeObserver = _a.disableResizeObserver, skipViewportMeasures = _a.skipViewportMeasures; var win = Utilities_1.getWindow(this._root.current); if (skipViewportMeasures !== previousSkipViewportMeasures) { if (!skipViewportMeasures) { if (!disableResizeObserver && this._isResizeObserverAvailable()) { if (!this._viewportResizeObserver) { this._registerResizeObserver(); } } else { this._events.on(win, 'resize', this._onAsyncResize); } this._updateViewport(); } else { this._unregisterResizeObserver(); this._events.off(win, 'resize', this._onAsyncResize); } } }; WithViewportComponent.prototype.componentWillUnmount = function () { this._events.dispose(); this._async.dispose(); this._unregisterResizeObserver(); }; WithViewportComponent.prototype.render = function () { var viewport = this.state.viewport; var newViewport = viewport.width > 0 && viewport.height > 0 ? viewport : undefined; return (React.createElement("div", { className: "ms-Viewport", ref: this._root, style: { minWidth: 1, minHeight: 1 } }, React.createElement(ComposedComponent, tslib_1.__assign({ ref: this._updateComposedComponentRef, viewport: newViewport }, this.props)))); }; WithViewportComponent.prototype.forceUpdate = function () { this._updateViewport(true); }; WithViewportComponent.prototype._onAsyncResize = function () { this._updateViewport(); }; WithViewportComponent.prototype._isResizeObserverAvailable = function () { var win = Utilities_1.getWindow(this._root.current); return win && win.ResizeObserver; }; return WithViewportComponent; }(BaseDecorator_1.BaseDecorator)); } exports.withViewport = withViewport; }); //# sourceMappingURL=withViewport.js.map