@aappddeevv/dynamics-client-ui
Version:
## What is it? A library to help you create great dynamics applications.
146 lines • 6.09 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
/* tslint:disable:no-unused-variable */
const React = require("react");
const ReactDOM = require("react-dom");
/* tslint:enable:no-unused-variable */
const PropTypes = require("prop-types");
const Utilities_1 = require("office-ui-fabric-react/lib/Utilities");
const Sticky_types_1 = require("office-ui-fabric-react/lib/components/Sticky/Sticky.types");
class Sticky extends Utilities_1.BaseComponent {
constructor(props) {
super(props);
this.state = {
isStickyTop: false,
isStickyBottom: false
};
}
componentDidMount() {
if (!this.context.scrollablePane) {
throw new TypeError('Expected Sticky to be mounted within ScrollablePane');
}
const { scrollablePane } = this.context;
scrollablePane.subscribe(this._onScrollEvent);
this.content = document.createElement('div');
this.content.style.background = this.props.stickyBackgroundColor || this._getBackground();
ReactDOM.render(React.createElement("div", null, this.props.children), this.content);
this.root.appendChild(this.content);
this.context.scrollablePane.notifySubscribers(true);
}
componentWillUnmount() {
const { isStickyTop, isStickyBottom } = this.state;
const { scrollablePane } = this.context;
if (isStickyTop) {
this._resetSticky(() => {
scrollablePane.removeStickyHeader(this);
});
}
if (isStickyBottom) {
this._resetSticky(() => {
scrollablePane.removeStickyFooter(this);
});
}
scrollablePane.unsubscribe(this._onScrollEvent);
}
componentDidUpdate(prevProps, prevState) {
const { isStickyTop, isStickyBottom } = this.state;
const { scrollablePane } = this.context;
if (this.props.children !== prevProps.children) {
ReactDOM.render(React.createElement("div", null, this.props.children), this.content);
}
if (isStickyTop && !prevState.isStickyTop) {
this._setSticky(() => {
scrollablePane.addStickyHeader(this);
});
}
else if (!isStickyTop && prevState.isStickyTop) {
this._resetSticky(() => {
scrollablePane.removeStickyHeader(this);
});
}
if (isStickyBottom && !prevState.isStickyBottom) {
this._setSticky(() => {
scrollablePane.addStickyFooter(this);
});
}
else if (!isStickyBottom && prevState.isStickyBottom) {
this._resetSticky(() => {
scrollablePane.removeStickyFooter(this);
});
}
}
shouldComponentUpdate(nextProps, nextState) {
const { isStickyTop, isStickyBottom, placeholderHeight } = this.state;
return isStickyTop !== nextState.isStickyTop ||
isStickyBottom !== nextState.isStickyBottom ||
placeholderHeight !== nextState.placeholderHeight ||
this.props.children !== nextProps.children;
}
setPlaceholderHeight(height) {
this.setState({
placeholderHeight: height
});
}
render() {
const { isStickyTop, isStickyBottom, placeholderHeight } = this.state;
const isSticky = isStickyTop || isStickyBottom;
return (React.createElement("div", { ref: this._resolveRef('root') },
React.createElement("div", { style: { height: (isSticky ? placeholderHeight : 0) } })));
}
_onScrollEvent(headerBound, footerBound) {
const { top, bottom } = this.root.getBoundingClientRect();
const { isStickyTop, isStickyBottom } = this.state;
const { stickyPosition } = this.props;
const canStickyHeader = stickyPosition === Sticky_types_1.StickyPositionType.Both || stickyPosition === Sticky_types_1.StickyPositionType.Header;
const canStickyFooter = stickyPosition === Sticky_types_1.StickyPositionType.Both || stickyPosition === Sticky_types_1.StickyPositionType.Footer;
this.setState({
isStickyTop: canStickyHeader && ((!isStickyTop && top <= headerBound.bottom) || (isStickyTop && bottom < headerBound.bottom)),
isStickyBottom: canStickyFooter && ((!isStickyBottom && bottom >= footerBound.top) || (isStickyBottom && top > footerBound.top))
});
}
_setSticky(callback) {
if (this.content.parentElement) {
this.content.parentElement.removeChild(this.content);
}
callback();
}
_resetSticky(callback) {
this.root.appendChild(this.content);
setTimeout(() => {
if (this.props.stickyClassName) {
this.content.children[0].classList.remove(this.props.stickyClassName);
}
}, 1);
callback();
}
// Gets background of nearest parent element that has a declared background-color attribute
_getBackground() {
let curr = this.root;
while (window.getComputedStyle(curr).getPropertyValue('background-color') === 'rgba(0, 0, 0, 0)' ||
window.getComputedStyle(curr).getPropertyValue('background-color') === 'transparent') {
if (curr.tagName === 'HTML') {
// Fallback color if no element has a declared background-color attribute
return null;
}
if (curr.parentElement) {
curr = curr.parentElement;
}
}
return window.getComputedStyle(curr).getPropertyValue('background-color');
}
}
Sticky.defaultProps = {
stickyPosition: Sticky_types_1.StickyPositionType.Both
};
Sticky.contextTypes = {
scrollablePane: PropTypes.object
};
tslib_1.__decorate([
Utilities_1.autobind
], Sticky.prototype, "componentDidMount", null);
tslib_1.__decorate([
Utilities_1.autobind
], Sticky.prototype, "_onScrollEvent", null);
exports.Sticky = Sticky;
//# sourceMappingURL=StickyX.js.map