UNPKG

@aappddeevv/dynamics-client-ui

Version:

## What is it? A library to help you create great dynamics applications.

146 lines 6.09 kB
"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