office-ui-fabric-react
Version:
Reusable React components for building experiences for Office 365.
203 lines • 8.99 kB
JavaScript
import * as tslib_1 from "tslib";
/* tslint:disable:no-unused-variable */
import * as React from 'react';
/* tslint:enable:no-unused-variable */
import * as PropTypes from 'prop-types';
import { autobind, BaseComponent, css } from '../../Utilities';
import * as stylesImport from './ScrollablePane.scss';
var styles = stylesImport;
var ScrollablePane = /** @class */ (function (_super) {
tslib_1.__extends(ScrollablePane, _super);
function ScrollablePane(props) {
var _this = _super.call(this, props) || this;
_this._subscribers = new Set();
_this._stickyAbove = new Set();
_this._stickyBelow = new Set();
return _this;
}
ScrollablePane.prototype.getChildContext = function () {
return {
scrollablePane: {
subscribe: this.subscribe,
unsubscribe: this.unsubscribe,
addStickyHeader: this.addStickyHeader,
removeStickyHeader: this.removeStickyHeader,
addStickyFooter: this.addStickyFooter,
removeStickyFooter: this.removeStickyFooter,
notifySubscribers: this.notifySubscribers
}
};
};
ScrollablePane.prototype.componentDidMount = function () {
var _this = this;
var _a = this.refs, root = _a.root, stickyContainer = _a.stickyContainer;
this._events.on(root, 'scroll', this.notifySubscribers);
this._events.on(window, 'resize', this._onWindowResize);
setTimeout(function () {
_this._resizeContainer();
if (stickyContainer.parentElement && root.parentElement) {
stickyContainer.parentElement.removeChild(stickyContainer);
root.parentElement.insertBefore(stickyContainer, root.nextSibling);
_this.notifySubscribers();
}
}, 500);
};
ScrollablePane.prototype.componentWillUnmount = function () {
var stickyContainer = this.refs.stickyContainer;
this._events.off(this.refs.root);
this._events.off(window);
if (stickyContainer.parentElement) {
stickyContainer.parentElement.removeChild(stickyContainer);
}
};
ScrollablePane.prototype.render = function () {
var className = this.props.className;
return (React.createElement("div", { ref: 'root', className: css('ms-ScrollablePane', styles.root, className), "data-is-scrollable": true },
React.createElement("div", { ref: 'stickyContainer', className: styles.stickyContainer },
React.createElement("div", { ref: 'stickyAbove', className: styles.stickyAbove }),
React.createElement("div", { ref: 'stickyBelow', className: styles.stickyBelow })),
this.props.children));
};
ScrollablePane.prototype.forceLayoutUpdate = function () {
this._onWindowResize();
};
ScrollablePane.prototype.subscribe = function (handler) {
this._subscribers.add(handler);
};
ScrollablePane.prototype.unsubscribe = function (handler) {
this._subscribers.delete(handler);
};
ScrollablePane.prototype.addStickyHeader = function (sticky) {
var stickyAbove = this.refs.stickyAbove;
this._addSticky(sticky, this._stickyAbove, stickyAbove, function () {
stickyAbove.appendChild(sticky.content);
});
};
ScrollablePane.prototype.addStickyFooter = function (sticky) {
var stickyBelow = this.refs.stickyBelow;
this._addSticky(sticky, this._stickyBelow, stickyBelow, function () {
stickyBelow.insertBefore(sticky.content, stickyBelow.firstChild);
});
};
ScrollablePane.prototype.removeStickyHeader = function (sticky) {
this._removeSticky(sticky, this._stickyAbove, this.refs.stickyAbove);
};
ScrollablePane.prototype.removeStickyFooter = function (sticky) {
this._removeSticky(sticky, this._stickyBelow, this.refs.stickyBelow);
};
ScrollablePane.prototype.notifySubscribers = function (sort) {
var _a = this.refs, stickyAbove = _a.stickyAbove, stickyBelow = _a.stickyBelow;
this._subscribers.forEach(function (handle) {
handle(stickyAbove.getBoundingClientRect(), stickyBelow.getBoundingClientRect());
});
if (this._stickyAbove.size > 1) {
this._sortStickies(this._stickyAbove, stickyAbove);
}
if (this._stickyBelow.size > 1) {
this._sortStickies(this._stickyBelow, stickyBelow);
}
};
ScrollablePane.prototype._addSticky = function (sticky, stickyList, container, addStickyToContainer) {
if (!stickyList.has(sticky)) {
stickyList.add(sticky);
addStickyToContainer();
sticky.content.addEventListener('transitionend', this._setPlaceholderHeights.bind(null, stickyList), false);
if (sticky.props.stickyClassName) {
setTimeout(function () {
if (sticky.props.stickyClassName) {
sticky.content.children[0].classList.add(sticky.props.stickyClassName);
}
}, 1);
}
this.notifySubscribers();
this._setPlaceholderHeights(stickyList);
}
};
ScrollablePane.prototype._removeSticky = function (sticky, stickyList, container) {
if (stickyList.has(sticky)) {
sticky.content.removeEventListener('transitionend', this._setPlaceholderHeights.bind(null, stickyList, container));
stickyList.delete(sticky);
}
};
ScrollablePane.prototype._onWindowResize = function () {
var _this = this;
setTimeout(function () {
_this._resizeContainer();
_this.notifySubscribers();
_this._setPlaceholderHeights(_this._stickyAbove);
_this._setPlaceholderHeights(_this._stickyBelow);
}, 5);
};
ScrollablePane.prototype._resizeContainer = function () {
var _a = this.refs, stickyContainer = _a.stickyContainer, root = _a.root;
var _b = getComputedStyle(root), borderTopWidth = _b.borderTopWidth, borderLeftWidth = _b.borderLeftWidth;
stickyContainer.style.height = root.clientHeight + 'px';
stickyContainer.style.width = root.clientWidth + 'px';
if (borderTopWidth) {
stickyContainer.style.top = root.offsetTop + parseInt(borderTopWidth, 10) + 'px';
}
if (borderLeftWidth) {
stickyContainer.style.left = root.offsetLeft + parseInt(borderLeftWidth, 10) + 'px';
}
};
ScrollablePane.prototype._setPlaceholderHeights = function (stickies) {
stickies.forEach(function (sticky, idx) {
sticky.setPlaceholderHeight(sticky.content.clientHeight);
});
};
ScrollablePane.prototype._sortStickies = function (stickyList, container) {
var _this = this;
var stickyArr = Array.from(stickyList);
stickyArr = stickyArr.sort(function (a, b) {
var aOffset = _this._calculateOffsetParent(a.refs.root);
var bOffset = _this._calculateOffsetParent(b.refs.root);
return aOffset - bOffset;
});
while (container.lastChild) {
container.removeChild(container.lastChild);
}
stickyArr.forEach(function (sticky) {
container.appendChild(sticky.content);
});
};
ScrollablePane.prototype._calculateOffsetParent = function (ele) {
var offset = 0;
while (ele.offsetParent !== this.refs.root.offsetParent) {
offset += ele.offsetTop;
if (ele.parentElement) {
ele = ele.parentElement;
}
}
return offset;
};
ScrollablePane.childContextTypes = {
scrollablePane: PropTypes.object
};
tslib_1.__decorate([
autobind
], ScrollablePane.prototype, "subscribe", null);
tslib_1.__decorate([
autobind
], ScrollablePane.prototype, "unsubscribe", null);
tslib_1.__decorate([
autobind
], ScrollablePane.prototype, "addStickyHeader", null);
tslib_1.__decorate([
autobind
], ScrollablePane.prototype, "addStickyFooter", null);
tslib_1.__decorate([
autobind
], ScrollablePane.prototype, "removeStickyHeader", null);
tslib_1.__decorate([
autobind
], ScrollablePane.prototype, "removeStickyFooter", null);
tslib_1.__decorate([
autobind
], ScrollablePane.prototype, "notifySubscribers", null);
tslib_1.__decorate([
autobind
], ScrollablePane.prototype, "_setPlaceholderHeights", null);
return ScrollablePane;
}(BaseComponent));
export { ScrollablePane };
//# sourceMappingURL=ScrollablePane.js.map