UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

161 lines (160 loc) 6.53 kB
import { __assign, __extends } from "tslib"; import "../../CommonImports"; import "../../Core/core.css"; import * as React from "react"; import { createMergedRef } from '../../Util'; // We need to monitor fine grained changes, especially when the list // has horizontal scroll. You dont get 100% visible ever. var defaultThreshold = []; for (var index = 0; index <= 100; index++) { defaultThreshold.push(index / 100); } var IntersectionContextImpl = /** @class */ (function () { function IntersectionContextImpl() { var _this = this; this.callbacks = []; this.pending = []; this.rootMargin = 0; this.root = document.body; this.onIntersect = function (entries) { if (_this.observer) { for (var _i = 0, _a = _this.callbacks; _i < _a.length; _i++) { var callback = _a[_i]; callback(entries, _this.observer); } } }; } IntersectionContextImpl.prototype.connect = function (root, rootMargin, threshold) { if (rootMargin === void 0) { rootMargin = 0; } if (threshold === void 0) { threshold = defaultThreshold; } this.observer = new IntersectionObserver(this.onIntersect, { root: root, rootMargin: rootMargin + "px", threshold: threshold }); this.rootMargin = rootMargin; this.root = root; for (var _i = 0, _a = this.pending; _i < _a.length; _i++) { var element = _a[_i]; this.observer.observe(element); } }; IntersectionContextImpl.prototype.disconnect = function () { if (this.observer) { this.observer.disconnect(); } }; IntersectionContextImpl.prototype.observe = function (element) { if (this.observer) { this.observer.observe(element); } else { this.pending.push(element); } }; IntersectionContextImpl.prototype.register = function (callback) { this.callbacks.push(callback); }; IntersectionContextImpl.prototype.unobserve = function (element) { var elementIndex = this.pending.indexOf(element); if (elementIndex >= 0) { this.pending.splice(elementIndex, 1); } if (this.observer) { this.observer.unobserve(element); } }; IntersectionContextImpl.prototype.unregister = function (callback) { var callbackIndex = this.callbacks.indexOf(callback); if (callbackIndex >= 0) { this.callbacks.splice(callbackIndex, 1); } }; return IntersectionContextImpl; }()); export var IntersectionContext = React.createContext(new IntersectionContextImpl()); /** * The Intersection is used to observe the changes of visibility in the children * of the rootElement. It also will notify the caller when the rootElement is * scrolled. It will pass an empty array of entries in the scorlling case. */ var Intersection = /** @class */ (function (_super) { __extends(Intersection, _super); function Intersection() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.mergedRef = createMergedRef(); _this.rootElement = React.createRef(); _this.state = new IntersectionContextImpl(); _this.onScroll = function (event) { _this.state.onIntersect([]); }; return _this; } // Render the provider around a SINGLE child. This is the element that is scrollable. Intersection.prototype.render = function () { var _this = this; var child = React.Children.only(this.props.children); var onScroll; if (child.props.onScroll) { onScroll = function (event) { if (child.props.onScroll) { child.props.onScroll(event); } _this.onScroll(event); }; } else { onScroll = this.onScroll; } return (React.createElement(IntersectionContext.Provider, { value: this.state }, React.cloneElement(child, __assign(__assign({}, child.props), { ref: this.mergedRef(this.rootElement, child.ref), onScroll: onScroll }), child.props.children))); }; Intersection.prototype.componentDidMount = function () { var _a = this.props, observationElement = _a.observationElement, rootElement = _a.rootElement; var connectElement = null; if (rootElement) { if (typeof rootElement === "string") { connectElement = document.querySelector(rootElement); } else if (typeof rootElement === "function") { connectElement = rootElement(); } else { connectElement = rootElement; } if (connectElement) { connectElement.addEventListener("scroll", this.onScroll); this.externalElement = connectElement; } } else if (this.rootElement) { connectElement = this.rootElement.current; } if (connectElement) { this.state.connect(connectElement, this.props.rootMargin, this.props.threshold); // Allow the creator of the intersection to observe intersection events. if (this.props.onIntersect) { this.state.register(this.props.onIntersect); } if (observationElement) { var observeElement = void 0; if (typeof observationElement === "string") { observeElement = document.querySelector(observationElement); } else if (typeof observationElement === "function") { observeElement = observationElement(); } else { observeElement = observationElement; } if (observeElement) { this.state.observe(observeElement); } } } }; Intersection.prototype.componentWillUnmount = function () { if (this.externalElement) { this.externalElement.removeEventListener("scroll", this.onScroll); } this.state.disconnect(); }; return Intersection; }(React.Component)); export { Intersection };