office-ui-fabric-react
Version:
Reusable React components for building experiences for Office 365.
192 lines • 8.56 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, classNamesFunction, customizable, divProperties, getNativeProps } from '../../Utilities';
var getClassNames = classNamesFunction();
var ScrollablePaneBase = /** @class */ (function (_super) {
tslib_1.__extends(ScrollablePaneBase, _super);
function ScrollablePaneBase(props) {
var _this = _super.call(this, props) || this;
_this._subscribers = new Set();
_this._stickyAbove = new Set();
_this._stickyBelow = new Set();
return _this;
}
ScrollablePaneBase.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
}
};
};
ScrollablePaneBase.prototype.componentDidMount = function () {
this._events.on(this.root, 'scroll', this.notifySubscribers);
this._events.on(window, 'resize', this._onWindowResize);
};
ScrollablePaneBase.prototype.componentWillUnmount = function () {
this._events.off(this.root);
this._events.off(window);
};
ScrollablePaneBase.prototype.render = function () {
var _a = this.props, className = _a.className, theme = _a.theme, getStyles = _a.getStyles;
var classNames = getClassNames(getStyles, {
theme: theme,
className: className
});
return (React.createElement("div", tslib_1.__assign({}, getNativeProps(this.props, divProperties), { ref: this._resolveRef('root'), className: classNames.root }),
React.createElement("div", { ref: this._resolveRef('stickyAbove'), className: classNames.stickyAbove }),
React.createElement("div", { ref: this._resolveRef('stickyBelow'), className: classNames.stickyBelow }),
React.createElement("div", { "data-is-scrollable": true }, this.props.children)));
};
ScrollablePaneBase.prototype.forceLayoutUpdate = function () {
this._onWindowResize();
};
ScrollablePaneBase.prototype.subscribe = function (handler) {
this._subscribers.add(handler);
};
ScrollablePaneBase.prototype.unsubscribe = function (handler) {
this._subscribers.delete(handler);
};
ScrollablePaneBase.prototype.addStickyHeader = function (sticky) {
var _this = this;
this._addSticky(sticky, this._stickyAbove, this.stickyAbove, function () {
_this.stickyAbove.appendChild(sticky.content);
});
};
ScrollablePaneBase.prototype.addStickyFooter = function (sticky) {
var _this = this;
this._addSticky(sticky, this._stickyBelow, this.stickyBelow, function () {
_this.stickyBelow.insertBefore(sticky.content, _this.stickyBelow.firstChild);
});
};
ScrollablePaneBase.prototype.removeStickyHeader = function (sticky) {
this._removeSticky(sticky, this._stickyAbove, this.stickyAbove);
};
ScrollablePaneBase.prototype.removeStickyFooter = function (sticky) {
this._removeSticky(sticky, this._stickyBelow, this.stickyBelow);
};
ScrollablePaneBase.prototype.notifySubscribers = function (sort) {
var _this = this;
this._subscribers.forEach(function (handle) {
handle(_this.stickyAbove.getBoundingClientRect(), _this.stickyBelow.getBoundingClientRect());
});
if (this._stickyAbove.size > 1) {
this._sortStickies(this._stickyAbove, this.stickyAbove);
}
if (this._stickyBelow.size > 1) {
this._sortStickies(this._stickyBelow, this.stickyBelow);
}
};
ScrollablePaneBase.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) {
this._async.setTimeout(function () {
if (sticky.props.stickyClassName) {
sticky.content.children[0].classList.add(sticky.props.stickyClassName);
}
}, 1);
}
this._setPlaceholderHeights(stickyList);
}
};
ScrollablePaneBase.prototype._removeSticky = function (sticky, stickyList, container) {
if (stickyList.has(sticky)) {
sticky.content.removeEventListener('transitionend', this._setPlaceholderHeights.bind(null, stickyList, container));
stickyList.delete(sticky);
}
};
ScrollablePaneBase.prototype._onWindowResize = function () {
var _this = this;
this._async.setTimeout(function () {
_this.notifySubscribers();
_this._setPlaceholderHeights(_this._stickyAbove);
_this._setPlaceholderHeights(_this._stickyBelow);
}, 5);
};
ScrollablePaneBase.prototype._setPlaceholderHeights = function (stickies) {
stickies.forEach(function (sticky, idx) {
sticky.setPlaceholderHeight(sticky.content.clientHeight);
});
};
ScrollablePaneBase.prototype._sortStickies = function (stickyList, container) {
var _this = this;
var stickyArr = Array.from(stickyList);
stickyArr = stickyArr.sort(function (a, b) {
var aOffset = _this._calculateOffsetParent(a.root);
var bOffset = _this._calculateOffsetParent(b.root);
return aOffset - bOffset;
});
// Get number of elements that is already in order.
var elementsInOrder = 0;
while (elementsInOrder < container.children.length && elementsInOrder < stickyArr.length) {
if (container.children[elementsInOrder] === stickyArr[elementsInOrder].content) {
++elementsInOrder;
}
else {
break;
}
}
// Remove elements that is not in order if exist.
for (var i = container.children.length - 1; i >= elementsInOrder; --i) {
container.removeChild(container.children[i]);
}
// Append further elements if needed.
for (var i = elementsInOrder; i < stickyArr.length; ++i) {
container.appendChild(stickyArr[i].content);
}
};
ScrollablePaneBase.prototype._calculateOffsetParent = function (ele) {
var offset = 0;
while (ele.offsetParent !== this.root.offsetParent) {
offset += ele.offsetTop;
if (ele.parentElement) {
ele = ele.parentElement;
}
}
return offset;
};
ScrollablePaneBase.childContextTypes = {
scrollablePane: PropTypes.object
};
tslib_1.__decorate([
autobind
], ScrollablePaneBase.prototype, "subscribe", null);
tslib_1.__decorate([
autobind
], ScrollablePaneBase.prototype, "unsubscribe", null);
tslib_1.__decorate([
autobind
], ScrollablePaneBase.prototype, "addStickyHeader", null);
tslib_1.__decorate([
autobind
], ScrollablePaneBase.prototype, "addStickyFooter", null);
tslib_1.__decorate([
autobind
], ScrollablePaneBase.prototype, "removeStickyHeader", null);
tslib_1.__decorate([
autobind
], ScrollablePaneBase.prototype, "removeStickyFooter", null);
tslib_1.__decorate([
autobind
], ScrollablePaneBase.prototype, "notifySubscribers", null);
tslib_1.__decorate([
autobind
], ScrollablePaneBase.prototype, "_setPlaceholderHeights", null);
ScrollablePaneBase = tslib_1.__decorate([
customizable('ScrollablePane', ['theme'])
], ScrollablePaneBase);
return ScrollablePaneBase;
}(BaseComponent));
export { ScrollablePaneBase };
//# sourceMappingURL=ScrollablePane.base.js.map