uawdijnntqw1x1x1
IP : 216.73.216.110
Hostname : 6.87.74.97.host.secureserver.net
Kernel : Linux 6.87.74.97.host.secureserver.net 4.18.0-553.83.1.el8_10.x86_64 #1 SMP Mon Nov 10 04:22:44 EST 2025 x86_64
Disable Function : None :)
OS : Linux
PATH:
/
home
/
emeraadmin
/
.razor
/
..
/
.
/
www
/
node_modules
/
parse-filepath
/
..
/
..
/
4d695
/
react-virtualized.tar
/
/
package.json000064400000011002151676725760007052 0ustar00{ "_from": "react-virtualized@^9.21.2", "_id": "react-virtualized@9.22.5", "_inBundle": false, "_integrity": "sha512-YqQMRzlVANBv1L/7r63OHa2b0ZsAaDp1UhVNEdUaXI8A5u6hTpA5NYtUueLH2rFuY/27mTGIBl7ZhqFKzw18YQ==", "_location": "/react-virtualized", "_phantomChildren": {}, "_requested": { "type": "range", "registry": true, "raw": "react-virtualized@^9.21.2", "name": "react-virtualized", "escapedName": "react-virtualized", "rawSpec": "^9.21.2", "saveSpec": null, "fetchSpec": "^9.21.2" }, "_requiredBy": [ "/react-sortable-tree-patch-react-17" ], "_resolved": "https://registry.npmjs.org/react-virtualized/-/react-virtualized-9.22.5.tgz", "_shasum": "bfb96fed519de378b50d8c0064b92994b3b91620", "_spec": "react-virtualized@^9.21.2", "_where": "C:\\xampp\\htdocs\\emeraltd\\node_modules\\react-sortable-tree-patch-react-17", "author": { "name": "Brian Vaughn", "email": "brian.david.vaughn@gmail.com" }, "browserify": { "transform": [ "loose-envify" ] }, "bugs": { "url": "https://github.com/bvaughn/react-virtualized/issues" }, "bundleDependencies": false, "dependencies": { "@babel/runtime": "^7.7.2", "clsx": "^1.0.4", "dom-helpers": "^5.1.3", "loose-envify": "^1.4.0", "prop-types": "^15.7.2", "react-lifecycles-compat": "^3.0.4" }, "deprecated": false, "description": "React components for efficiently rendering large, scrollable lists and tabular data", "devDependencies": { "@babel/cli": "^7.7.0", "@babel/core": "^7.7.2", "@babel/plugin-external-helpers": "^7.2.0", "@babel/plugin-proposal-class-properties": "^7.7.0", "@babel/plugin-transform-modules-commonjs": "^7.7.0", "@babel/plugin-transform-runtime": "^7.6.2", "@babel/polyfill": "^7.7.0", "@babel/preset-env": "^7.7.1", "@babel/preset-flow": "^7.0.0", "@babel/preset-react": "^7.7.0", "@babel/preset-stage-2": "^7.0.0", "autoprefixer": "^9.7.1", "babel-eslint": "^10.0.3", "babel-jest": "^24.9.0", "babel-loader": "8.0.6", "babel-plugin-flow-react-proptypes": "^26.0.0", "babel-plugin-transform-react-remove-prop-types": "^0.4.24", "codecov": "^3.6.1", "codemirror": "^5.49.2", "cross-env": "^6.0.3", "css-loader": "^3.2.0", "eslint": "^6.6.0", "eslint-config-fbjs": "^3.1.1", "eslint-config-prettier": "^6.5.0", "eslint-config-react": "^1.1.7", "eslint-plugin-babel": "^5.3.0", "eslint-plugin-flowtype": "^4.3.0", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-prettier": "^3.1.1", "eslint-plugin-react": "^7.16.0", "eslint-plugin-relay": "^1.3.12", "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^4.2.0", "flow-bin": "^0.111.3", "flow-copy-source": "^2.0.8", "gh-pages": "^2.1.1", "html-webpack-plugin": "^3.2.0", "husky": "^3.0.9", "immutable": "^4.0.0-rc.12", "jest": "^24.9.0", "jest-environment-puppeteer": "^4.3.0", "lint-staged": "^9.4.2", "postcss": "^7.0.21", "postcss-cli": "^6.1.3", "postcss-loader": "^3.0.0", "prettier": "1.19.1", "pretty-quick": "^2.0.1", "puppeteer": "^2.0.0", "react": "^16.11.0", "react-codemirror": "^1.0.0", "react-dom": "^16.11.0", "react-router": "^5.1.2", "react-router-dom": "^5.1.2", "react-test-renderer": "^16.11.0", "rimraf": "^3.0.0", "rollup": "^1.26.5", "rollup-plugin-babel": "^4.3.3", "rollup-plugin-commonjs": "^10.1.0", "rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-replace": "^2.2.0", "rollup-plugin-uglify": "^6.0.3", "style-loader": "^1.0.0", "watch": "^1.0.2", "webpack": "^4.41.2", "webpack-cli": "^3.3.10", "webpack-dev-server": "^3.9.0" }, "files": [ "dist", "styles.css" ], "homepage": "https://github.com/bvaughn/react-virtualized", "jsnext:main": "dist/es/index.js", "keywords": [ "react", "reactjs", "react-component", "virtual", "list", "scrolling", "infinite", "virtualized", "table", "fixed", "header", "flex", "flexbox", "grid", "spreadsheet" ], "license": "MIT", "main": "dist/commonjs/index.js", "module": "dist/es/index.js", "name": "react-virtualized", "peerDependencies": { "react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0", "react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0" }, "repository": { "type": "git", "url": "git+https://github.com/bvaughn/react-virtualized.git" }, "user": "bvaughn", "version": "9.22.5" } LICENSE000064400000002070151676725760005576 0ustar00The MIT License (MIT) Copyright (c) 2015 Brian Vaughn Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. dist/umd/react-virtualized.js000064400001111507151676725760012324 0ustar00!function(global, factory) { "object" == typeof exports && "undefined" != typeof module ? factory(exports, require("react"), require("react-dom")) : "function" == typeof define && define.amd ? define([ "exports", "react", "react-dom" ], factory) : factory((global = global || self).ReactVirtualized = {}, global.React, global.ReactDOM); }(this, function(exports, React, ReactDOM) { "use strict"; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function"); } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || !1, descriptor.configurable = !0, "value" in descriptor && (descriptor.writable = !0), Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { return protoProps && _defineProperties(Constructor.prototype, protoProps), staticProps && _defineProperties(Constructor, staticProps), Constructor; } function _defineProperty(obj, key, value) { return key in obj ? Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }) : obj[key] = value, obj; } function _extends() { return (_extends = Object.assign || function(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) Object.prototype.hasOwnProperty.call(source, key) && (target[key] = source[key]); } return target; }).apply(this, arguments); } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function(sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(source, !0).forEach(function(key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(source).forEach(function(key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _inherits(subClass, superClass) { if ("function" != typeof superClass && null !== superClass) throw new TypeError("Super expression must either be null or a function"); subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: !0, configurable: !0 } }), superClass && _setPrototypeOf(subClass, superClass); } function _getPrototypeOf(o) { return (_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function(o) { return o.__proto__ || Object.getPrototypeOf(o); })(o); } function _setPrototypeOf(o, p) { return (_setPrototypeOf = Object.setPrototypeOf || function(o, p) { return o.__proto__ = p, o; })(o, p); } function _objectWithoutProperties(source, excluded) { if (null == source) return {}; var key, i, target = function(source, excluded) { if (null == source) return {}; var key, i, target = {}, sourceKeys = Object.keys(source); for (i = 0; i < sourceKeys.length; i++) key = sourceKeys[i], 0 <= excluded.indexOf(key) || (target[key] = source[key]); return target; }(source, excluded); if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) key = sourceSymbolKeys[i], 0 <= excluded.indexOf(key) || Object.prototype.propertyIsEnumerable.call(source, key) && (target[key] = source[key]); } return target; } function _assertThisInitialized(self) { if (void 0 === self) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return self; } function _possibleConstructorReturn(self, call) { return !call || "object" != typeof call && "function" != typeof call ? _assertThisInitialized(self) : call; } function _slicedToArray(arr, i) { return function(arr) { if (Array.isArray(arr)) return arr; }(arr) || function(arr, i) { if (!(Symbol.iterator in Object(arr) || "[object Arguments]" === Object.prototype.toString.call(arr))) return; var _arr = [], _n = !0, _d = !1, _e = void 0; try { for (var _s, _i = arr[Symbol.iterator](); !(_n = (_s = _i.next()).done) && (_arr.push(_s.value), !i || _arr.length !== i); _n = !0) ; } catch (err) { _d = !0, _e = err; } finally { try { _n || null == _i.return || _i.return(); } finally { if (_d) throw _e; } } return _arr; }(arr, i) || function() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ (); } function _toConsumableArray(arr) { return function(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } }(arr) || function(iter) { if (Symbol.iterator in Object(iter) || "[object Arguments]" === Object.prototype.toString.call(iter)) return Array.from(iter); }(arr) || function() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }(); } function componentWillMount() { // Call this.constructor.gDSFP to support sub-classes. var state = this.constructor.getDerivedStateFromProps(this.props, this.state); null != state && this.setState(state); } function componentWillReceiveProps(nextProps) { // Binding "this" is important for shallow renderer support. this.setState( // Call this.constructor.gDSFP to support sub-classes. // Use the setState() updater to ensure state isn't stale in certain edge cases. function(prevState) { var state = this.constructor.getDerivedStateFromProps(nextProps, prevState); return null != state ? state : null; }.bind(this)); } function componentWillUpdate(nextProps, nextState) { try { var prevProps = this.props, prevState = this.state; this.props = nextProps, this.state = nextState, this.__reactInternalSnapshotFlag = !0, this.__reactInternalSnapshot = this.getSnapshotBeforeUpdate(prevProps, prevState); } finally { this.props = prevProps, this.state = prevState; } } // React may warn about cWM/cWRP/cWU methods being deprecated. // Add a flag to suppress these warnings for this special case. function polyfill(Component) { var prototype = Component.prototype; if (!prototype || !prototype.isReactComponent) throw new Error("Can only polyfill class components"); if ("function" != typeof Component.getDerivedStateFromProps && "function" != typeof prototype.getSnapshotBeforeUpdate) return Component; // If new component APIs are defined, "unsafe" lifecycles won't be called. // Error if any of these lifecycles are present, // Because they would work differently between older and newer (16.3+) versions of React. var foundWillMountName = null, foundWillReceivePropsName = null, foundWillUpdateName = null; if ("function" == typeof prototype.componentWillMount ? foundWillMountName = "componentWillMount" : "function" == typeof prototype.UNSAFE_componentWillMount && (foundWillMountName = "UNSAFE_componentWillMount"), "function" == typeof prototype.componentWillReceiveProps ? foundWillReceivePropsName = "componentWillReceiveProps" : "function" == typeof prototype.UNSAFE_componentWillReceiveProps && (foundWillReceivePropsName = "UNSAFE_componentWillReceiveProps"), "function" == typeof prototype.componentWillUpdate ? foundWillUpdateName = "componentWillUpdate" : "function" == typeof prototype.UNSAFE_componentWillUpdate && (foundWillUpdateName = "UNSAFE_componentWillUpdate"), null !== foundWillMountName || null !== foundWillReceivePropsName || null !== foundWillUpdateName) { var componentName = Component.displayName || Component.name, newApiName = "function" == typeof Component.getDerivedStateFromProps ? "getDerivedStateFromProps()" : "getSnapshotBeforeUpdate()"; throw Error("Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n" + componentName + " uses " + newApiName + " but also contains the following legacy lifecycles:" + (null !== foundWillMountName ? "\n " + foundWillMountName : "") + (null !== foundWillReceivePropsName ? "\n " + foundWillReceivePropsName : "") + (null !== foundWillUpdateName ? "\n " + foundWillUpdateName : "") + "\n\nThe above lifecycles should be removed. Learn more about this warning here:\nhttps://fb.me/react-async-component-lifecycle-hooks"); } // React <= 16.2 does not support static getDerivedStateFromProps. // As a workaround, use cWM and cWRP to invoke the new static lifecycle. // Newer versions of React will ignore these lifecycles if gDSFP exists. // React <= 16.2 does not support getSnapshotBeforeUpdate. // As a workaround, use cWU to invoke the new lifecycle. // Newer versions of React will ignore that lifecycle if gSBU exists. if ("function" == typeof Component.getDerivedStateFromProps && (prototype.componentWillMount = componentWillMount, prototype.componentWillReceiveProps = componentWillReceiveProps), "function" == typeof prototype.getSnapshotBeforeUpdate) { if ("function" != typeof prototype.componentDidUpdate) throw new Error("Cannot polyfill getSnapshotBeforeUpdate() for components that do not define componentDidUpdate() on the prototype"); prototype.componentWillUpdate = componentWillUpdate; var componentDidUpdate = prototype.componentDidUpdate; prototype.componentDidUpdate = function(prevProps, prevState, maybeSnapshot) { // 16.3+ will not execute our will-update method; // It will pass a snapshot value to did-update though. // Older versions will require our polyfilled will-update value. // We need to handle both cases, but can't just check for the presence of "maybeSnapshot", // Because for <= 15.x versions this might be a "prevContext" object. // We also can't just check "__reactInternalSnapshot", // Because get-snapshot might return a falsy value. // So check for the explicit __reactInternalSnapshotFlag flag to determine behavior. var snapshot = this.__reactInternalSnapshotFlag ? this.__reactInternalSnapshot : maybeSnapshot; componentDidUpdate.call(this, prevProps, prevState, snapshot); }; } return Component; } componentWillUpdate.__suppressDeprecationWarning = componentWillReceiveProps.__suppressDeprecationWarning = componentWillMount.__suppressDeprecationWarning = !0; var ArrowKeyStepper = function() { function ArrowKeyStepper() { var _getPrototypeOf2, _this; _classCallCheck(this, ArrowKeyStepper); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key]; return _defineProperty(_assertThisInitialized(_this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(ArrowKeyStepper)).call.apply(_getPrototypeOf2, [ this ].concat(args)))), "state", { scrollToColumn: 0, scrollToRow: 0, instanceProps: { prevScrollToColumn: 0, prevScrollToRow: 0 } }), _defineProperty(_assertThisInitialized(_this), "_columnStartIndex", 0), _defineProperty(_assertThisInitialized(_this), "_columnStopIndex", 0), _defineProperty(_assertThisInitialized(_this), "_rowStartIndex", 0), _defineProperty(_assertThisInitialized(_this), "_rowStopIndex", 0), _defineProperty(_assertThisInitialized(_this), "_onKeyDown", function(event) { var _this$props = _this.props, columnCount = _this$props.columnCount, disabled = _this$props.disabled, mode = _this$props.mode, rowCount = _this$props.rowCount; if (!disabled) { var _this$_getScrollState = _this._getScrollState(), scrollToColumnPrevious = _this$_getScrollState.scrollToColumn, scrollToRowPrevious = _this$_getScrollState.scrollToRow, _this$_getScrollState2 = _this._getScrollState(), scrollToColumn = _this$_getScrollState2.scrollToColumn, scrollToRow = _this$_getScrollState2.scrollToRow; switch (event.key) { case "ArrowDown": scrollToRow = "cells" === mode ? Math.min(scrollToRow + 1, rowCount - 1) : Math.min(_this._rowStopIndex + 1, rowCount - 1); break; case "ArrowLeft": scrollToColumn = "cells" === mode ? Math.max(scrollToColumn - 1, 0) : Math.max(_this._columnStartIndex - 1, 0); break; case "ArrowRight": scrollToColumn = "cells" === mode ? Math.min(scrollToColumn + 1, columnCount - 1) : Math.min(_this._columnStopIndex + 1, columnCount - 1); break; case "ArrowUp": scrollToRow = "cells" === mode ? Math.max(scrollToRow - 1, 0) : Math.max(_this._rowStartIndex - 1, 0); } scrollToColumn === scrollToColumnPrevious && scrollToRow === scrollToRowPrevious || (event.preventDefault(), _this._updateScrollState({ scrollToColumn: scrollToColumn, scrollToRow: scrollToRow })); } }), _defineProperty(_assertThisInitialized(_this), "_onSectionRendered", function(_ref) { var columnStartIndex = _ref.columnStartIndex, columnStopIndex = _ref.columnStopIndex, rowStartIndex = _ref.rowStartIndex, rowStopIndex = _ref.rowStopIndex; _this._columnStartIndex = columnStartIndex, _this._columnStopIndex = columnStopIndex, _this._rowStartIndex = rowStartIndex, _this._rowStopIndex = rowStopIndex; }), _this; } return _inherits(ArrowKeyStepper, React.PureComponent), _createClass(ArrowKeyStepper, [ { key: "setScrollIndexes", value: function(_ref2) { var scrollToColumn = _ref2.scrollToColumn, scrollToRow = _ref2.scrollToRow; this.setState({ scrollToRow: scrollToRow, scrollToColumn: scrollToColumn }); } }, { key: "render", value: function() { var _this$props2 = this.props, className = _this$props2.className, children = _this$props2.children, _this$_getScrollState3 = this._getScrollState(), scrollToColumn = _this$_getScrollState3.scrollToColumn, scrollToRow = _this$_getScrollState3.scrollToRow; return React.createElement("div", { className: className, onKeyDown: this._onKeyDown }, children({ onSectionRendered: this._onSectionRendered, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow })); } }, { key: "_getScrollState", value: function() { return this.props.isControlled ? this.props : this.state; } }, { key: "_updateScrollState", value: function(_ref3) { var scrollToColumn = _ref3.scrollToColumn, scrollToRow = _ref3.scrollToRow, _this$props3 = this.props, isControlled = _this$props3.isControlled, onScrollToChange = _this$props3.onScrollToChange; "function" == typeof onScrollToChange && onScrollToChange({ scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }), isControlled || this.setState({ scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }); } } ], [ { key: "getDerivedStateFromProps", value: function(nextProps, prevState) { return nextProps.isControlled ? {} : nextProps.scrollToColumn !== prevState.instanceProps.prevScrollToColumn || nextProps.scrollToRow !== prevState.instanceProps.prevScrollToRow ? _objectSpread2({}, prevState, { scrollToColumn: nextProps.scrollToColumn, scrollToRow: nextProps.scrollToRow, instanceProps: { prevScrollToColumn: nextProps.scrollToColumn, prevScrollToRow: nextProps.scrollToRow } }) : {}; } } ]), ArrowKeyStepper; }(); function createDetectElementResize(nonce, hostWindow) { var _window, cancel, raf, attachEvent = void 0 !== (_window = void 0 !== hostWindow ? hostWindow : "undefined" != typeof window ? window : "undefined" != typeof self ? self : global).document && _window.document.attachEvent; if (!attachEvent) { var requestFrame = (raf = _window.requestAnimationFrame || _window.mozRequestAnimationFrame || _window.webkitRequestAnimationFrame || function(fn) { return _window.setTimeout(fn, 20); }, function(fn) { return raf(fn); }), cancelFrame = (cancel = _window.cancelAnimationFrame || _window.mozCancelAnimationFrame || _window.webkitCancelAnimationFrame || _window.clearTimeout, function(id) { return cancel(id); }), resetTriggers = function(element) { var triggers = element.__resizeTriggers__, expand = triggers.firstElementChild, contract = triggers.lastElementChild, expandChild = expand.firstElementChild; contract.scrollLeft = contract.scrollWidth, contract.scrollTop = contract.scrollHeight, expandChild.style.width = expand.offsetWidth + 1 + "px", expandChild.style.height = expand.offsetHeight + 1 + "px", expand.scrollLeft = expand.scrollWidth, expand.scrollTop = expand.scrollHeight; }, scrollListener = function(e) { if (!(e.target.className && "function" == typeof e.target.className.indexOf && e.target.className.indexOf("contract-trigger") < 0 && e.target.className.indexOf("expand-trigger") < 0)) { var element = this; resetTriggers(this), this.__resizeRAF__ && cancelFrame(this.__resizeRAF__), this.__resizeRAF__ = requestFrame(function() { !function(element) { return element.offsetWidth != element.__resizeLast__.width || element.offsetHeight != element.__resizeLast__.height; }(element) || (element.__resizeLast__.width = element.offsetWidth, element.__resizeLast__.height = element.offsetHeight, element.__resizeListeners__.forEach(function(fn) { fn.call(element, e); })); }); } }, animation = !1, keyframeprefix = "", animationstartevent = "animationstart", domPrefixes = "Webkit Moz O ms".split(" "), startEvents = "webkitAnimationStart animationstart oAnimationStart MSAnimationStart".split(" "), elm = _window.document.createElement("fakeelement"); if (void 0 !== elm.style.animationName && (animation = !0), !1 === animation) for (var i = 0; i < domPrefixes.length; i++) if (void 0 !== elm.style[domPrefixes[i] + "AnimationName"]) { keyframeprefix = "-" + domPrefixes[i].toLowerCase() + "-", animationstartevent = startEvents[i], animation = !0; break; } var animationName = "resizeanim", animationKeyframes = "@" + keyframeprefix + "keyframes " + animationName + " { from { opacity: 0; } to { opacity: 0; } } ", animationStyle = keyframeprefix + "animation: 1ms " + animationName + "; "; } return { addResizeListener: function(element, fn) { if (attachEvent) element.attachEvent("onresize", fn); else { if (!element.__resizeTriggers__) { var doc = element.ownerDocument, elementStyle = _window.getComputedStyle(element); elementStyle && "static" == elementStyle.position && (element.style.position = "relative"), function(doc) { if (!doc.getElementById("detectElementResize")) { var css = (animationKeyframes || "") + ".resize-triggers { " + (animationStyle || "") + 'visibility: hidden; opacity: 0; } .resize-triggers, .resize-triggers > div, .contract-trigger:before { content: " "; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; z-index: -1; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }', head = doc.head || doc.getElementsByTagName("head")[0], style = doc.createElement("style"); style.id = "detectElementResize", style.type = "text/css", null != nonce && style.setAttribute("nonce", nonce), style.styleSheet ? style.styleSheet.cssText = css : style.appendChild(doc.createTextNode(css)), head.appendChild(style); } }(doc), element.__resizeLast__ = {}, element.__resizeListeners__ = [], (element.__resizeTriggers__ = doc.createElement("div")).className = "resize-triggers"; var resizeTriggersHtml = '<div class="expand-trigger"><div></div></div><div class="contract-trigger"></div>'; if (window.trustedTypes) { var staticPolicy = trustedTypes.createPolicy("react-virtualized-auto-sizer", { createHTML: function() { return resizeTriggersHtml; } }); element.__resizeTriggers__.innerHTML = staticPolicy.createHTML(""); } else element.__resizeTriggers__.innerHTML = resizeTriggersHtml; element.appendChild(element.__resizeTriggers__), resetTriggers(element), element.addEventListener("scroll", scrollListener, !0), animationstartevent && (element.__resizeTriggers__.__animationListener__ = function(e) { e.animationName == animationName && resetTriggers(element); }, element.__resizeTriggers__.addEventListener(animationstartevent, element.__resizeTriggers__.__animationListener__)); } element.__resizeListeners__.push(fn); } }, removeResizeListener: function(element, fn) { if (attachEvent) element.detachEvent("onresize", fn); else if (element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1), !element.__resizeListeners__.length) { element.removeEventListener("scroll", scrollListener, !0), element.__resizeTriggers__.__animationListener__ && (element.__resizeTriggers__.removeEventListener(animationstartevent, element.__resizeTriggers__.__animationListener__), element.__resizeTriggers__.__animationListener__ = null); try { element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__); } catch (e) {} } } }; } _defineProperty(ArrowKeyStepper, "defaultProps", { disabled: !1, isControlled: !1, mode: "edges", scrollToColumn: 0, scrollToRow: 0 }), polyfill(ArrowKeyStepper); var AutoSizer = function() { function AutoSizer() { var _getPrototypeOf2, _this; _classCallCheck(this, AutoSizer); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key]; return _defineProperty(_assertThisInitialized(_this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(AutoSizer)).call.apply(_getPrototypeOf2, [ this ].concat(args)))), "state", { height: _this.props.defaultHeight || 0, width: _this.props.defaultWidth || 0 }), _defineProperty(_assertThisInitialized(_this), "_parentNode", void 0), _defineProperty(_assertThisInitialized(_this), "_autoSizer", void 0), _defineProperty(_assertThisInitialized(_this), "_window", void 0), _defineProperty(_assertThisInitialized(_this), "_detectElementResize", void 0), _defineProperty(_assertThisInitialized(_this), "_onResize", function() { var _this$props = _this.props, disableHeight = _this$props.disableHeight, disableWidth = _this$props.disableWidth, onResize = _this$props.onResize; if (_this._parentNode) { var height = _this._parentNode.offsetHeight || 0, width = _this._parentNode.offsetWidth || 0, style = (_this._window || window).getComputedStyle(_this._parentNode) || {}, paddingLeft = parseInt(style.paddingLeft, 10) || 0, paddingRight = parseInt(style.paddingRight, 10) || 0, paddingTop = parseInt(style.paddingTop, 10) || 0, paddingBottom = parseInt(style.paddingBottom, 10) || 0, newHeight = height - paddingTop - paddingBottom, newWidth = width - paddingLeft - paddingRight; (!disableHeight && _this.state.height !== newHeight || !disableWidth && _this.state.width !== newWidth) && (_this.setState({ height: height - paddingTop - paddingBottom, width: width - paddingLeft - paddingRight }), onResize({ height: height, width: width })); } }), _defineProperty(_assertThisInitialized(_this), "_setRef", function(autoSizer) { _this._autoSizer = autoSizer; }), _this; } return _inherits(AutoSizer, React.Component), _createClass(AutoSizer, [ { key: "componentDidMount", value: function() { var nonce = this.props.nonce; this._autoSizer && this._autoSizer.parentNode && this._autoSizer.parentNode.ownerDocument && this._autoSizer.parentNode.ownerDocument.defaultView && this._autoSizer.parentNode instanceof this._autoSizer.parentNode.ownerDocument.defaultView.HTMLElement && (this._parentNode = this._autoSizer.parentNode, this._window = this._autoSizer.parentNode.ownerDocument.defaultView, this._detectElementResize = createDetectElementResize(nonce, this._window), this._detectElementResize.addResizeListener(this._parentNode, this._onResize), this._onResize()); } }, { key: "componentWillUnmount", value: function() { this._detectElementResize && this._parentNode && this._detectElementResize.removeResizeListener(this._parentNode, this._onResize); } }, { key: "render", value: function() { var _this$props2 = this.props, children = _this$props2.children, className = _this$props2.className, disableHeight = _this$props2.disableHeight, disableWidth = _this$props2.disableWidth, style = _this$props2.style, _this$state = this.state, height = _this$state.height, width = _this$state.width, outerStyle = { overflow: "visible" }, childParams = {}; return disableHeight || (outerStyle.height = 0, childParams.height = height), disableWidth || (outerStyle.width = 0, childParams.width = width), React.createElement("div", { className: className, ref: this._setRef, style: _objectSpread2({}, outerStyle, {}, style) }, children(childParams)); } } ]), AutoSizer; }(); _defineProperty(AutoSizer, "defaultProps", { onResize: function() {}, disableHeight: !1, disableWidth: !1, style: {} }); var CellMeasurer = function() { function CellMeasurer() { var _getPrototypeOf2, _this; _classCallCheck(this, CellMeasurer); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key]; return _defineProperty(_assertThisInitialized(_this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(CellMeasurer)).call.apply(_getPrototypeOf2, [ this ].concat(args)))), "_child", void 0), _defineProperty(_assertThisInitialized(_this), "_measure", function() { var _this$props = _this.props, cache = _this$props.cache, _this$props$columnInd = _this$props.columnIndex, columnIndex = void 0 === _this$props$columnInd ? 0 : _this$props$columnInd, parent = _this$props.parent, _this$props$rowIndex = _this$props.rowIndex, rowIndex = void 0 === _this$props$rowIndex ? _this.props.index || 0 : _this$props$rowIndex, _this$_getCellMeasure = _this._getCellMeasurements(), height = _this$_getCellMeasure.height, width = _this$_getCellMeasure.width; height === cache.getHeight(rowIndex, columnIndex) && width === cache.getWidth(rowIndex, columnIndex) || (cache.set(rowIndex, columnIndex, width, height), parent && "function" == typeof parent.recomputeGridSize && parent.recomputeGridSize({ columnIndex: columnIndex, rowIndex: rowIndex })); }), _defineProperty(_assertThisInitialized(_this), "_registerChild", function(element) { !element || element instanceof Element || console.warn("CellMeasurer registerChild expects to be passed Element or null"), (_this._child = element) && _this._maybeMeasureCell(); }), _this; } return _inherits(CellMeasurer, React.PureComponent), _createClass(CellMeasurer, [ { key: "componentDidMount", value: function() { this._maybeMeasureCell(); } }, { key: "componentDidUpdate", value: function() { this._maybeMeasureCell(); } }, { key: "render", value: function() { var children = this.props.children; return "function" == typeof children ? children({ measure: this._measure, registerChild: this._registerChild }) : children; } }, { key: "_getCellMeasurements", value: function() { var cache = this.props.cache, node = this._child || ReactDOM.findDOMNode(this); if (node && node.ownerDocument && node.ownerDocument.defaultView && node instanceof node.ownerDocument.defaultView.HTMLElement) { var styleWidth = node.style.width, styleHeight = node.style.height; cache.hasFixedWidth() || (node.style.width = "auto"), cache.hasFixedHeight() || (node.style.height = "auto"); var height = Math.ceil(node.offsetHeight), width = Math.ceil(node.offsetWidth); return styleWidth && (node.style.width = styleWidth), styleHeight && (node.style.height = styleHeight), { height: height, width: width }; } return { height: 0, width: 0 }; } }, { key: "_maybeMeasureCell", value: function() { var _this$props2 = this.props, cache = _this$props2.cache, _this$props2$columnIn = _this$props2.columnIndex, columnIndex = void 0 === _this$props2$columnIn ? 0 : _this$props2$columnIn, parent = _this$props2.parent, _this$props2$rowIndex = _this$props2.rowIndex, rowIndex = void 0 === _this$props2$rowIndex ? this.props.index || 0 : _this$props2$rowIndex; if (!cache.has(rowIndex, columnIndex)) { var _this$_getCellMeasure2 = this._getCellMeasurements(), height = _this$_getCellMeasure2.height, width = _this$_getCellMeasure2.width; cache.set(rowIndex, columnIndex, width, height), parent && "function" == typeof parent.invalidateCellSizeAfterRender && parent.invalidateCellSizeAfterRender({ columnIndex: columnIndex, rowIndex: rowIndex }); } } } ]), CellMeasurer; }(); _defineProperty(CellMeasurer, "__internalCellMeasurerFlag", !1), CellMeasurer.__internalCellMeasurerFlag = !0; var CellMeasurerCache = function() { function CellMeasurerCache() { var _this = this, params = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; _classCallCheck(this, CellMeasurerCache), _defineProperty(this, "_cellHeightCache", {}), _defineProperty(this, "_cellWidthCache", {}), _defineProperty(this, "_columnWidthCache", {}), _defineProperty(this, "_rowHeightCache", {}), _defineProperty(this, "_defaultHeight", void 0), _defineProperty(this, "_defaultWidth", void 0), _defineProperty(this, "_minHeight", void 0), _defineProperty(this, "_minWidth", void 0), _defineProperty(this, "_keyMapper", void 0), _defineProperty(this, "_hasFixedHeight", void 0), _defineProperty(this, "_hasFixedWidth", void 0), _defineProperty(this, "_columnCount", 0), _defineProperty(this, "_rowCount", 0), _defineProperty(this, "columnWidth", function(_ref) { var index = _ref.index, key = _this._keyMapper(0, index); return void 0 !== _this._columnWidthCache[key] ? _this._columnWidthCache[key] : _this._defaultWidth; }), _defineProperty(this, "rowHeight", function(_ref2) { var index = _ref2.index, key = _this._keyMapper(index, 0); return void 0 !== _this._rowHeightCache[key] ? _this._rowHeightCache[key] : _this._defaultHeight; }); var defaultHeight = params.defaultHeight, defaultWidth = params.defaultWidth, fixedHeight = params.fixedHeight, fixedWidth = params.fixedWidth, keyMapper = params.keyMapper, minHeight = params.minHeight, minWidth = params.minWidth; this._hasFixedHeight = !0 === fixedHeight, this._hasFixedWidth = !0 === fixedWidth, this._minHeight = minHeight || 0, this._minWidth = minWidth || 0, this._keyMapper = keyMapper || defaultKeyMapper, this._defaultHeight = Math.max(this._minHeight, "number" == typeof defaultHeight ? defaultHeight : 30), this._defaultWidth = Math.max(this._minWidth, "number" == typeof defaultWidth ? defaultWidth : 100), !1 === this._hasFixedHeight && !1 === this._hasFixedWidth && console.warn("CellMeasurerCache should only measure a cell's width or height. You have configured CellMeasurerCache to measure both. This will result in poor performance."), !1 === this._hasFixedHeight && 0 === this._defaultHeight && console.warn("Fixed height CellMeasurerCache should specify a :defaultHeight greater than 0. Failing to do so will lead to unnecessary layout and poor performance."), !1 === this._hasFixedWidth && 0 === this._defaultWidth && console.warn("Fixed width CellMeasurerCache should specify a :defaultWidth greater than 0. Failing to do so will lead to unnecessary layout and poor performance."); } return _createClass(CellMeasurerCache, [ { key: "clear", value: function(rowIndex, argument_1) { var columnIndex = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : 0, key = this._keyMapper(rowIndex, columnIndex); delete this._cellHeightCache[key], delete this._cellWidthCache[key], this._updateCachedColumnAndRowSizes(rowIndex, columnIndex); } }, { key: "clearAll", value: function() { this._cellHeightCache = {}, this._cellWidthCache = {}, this._columnWidthCache = {}, this._rowHeightCache = {}, this._rowCount = 0, this._columnCount = 0; } }, { key: "hasFixedHeight", value: function() { return this._hasFixedHeight; } }, { key: "hasFixedWidth", value: function() { return this._hasFixedWidth; } }, { key: "getHeight", value: function(rowIndex, argument_1) { var columnIndex = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : 0; if (this._hasFixedHeight) return this._defaultHeight; var _key = this._keyMapper(rowIndex, columnIndex); return void 0 !== this._cellHeightCache[_key] ? Math.max(this._minHeight, this._cellHeightCache[_key]) : this._defaultHeight; } }, { key: "getWidth", value: function(rowIndex, argument_1) { var columnIndex = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : 0; if (this._hasFixedWidth) return this._defaultWidth; var _key2 = this._keyMapper(rowIndex, columnIndex); return void 0 !== this._cellWidthCache[_key2] ? Math.max(this._minWidth, this._cellWidthCache[_key2]) : this._defaultWidth; } }, { key: "has", value: function(rowIndex, argument_1) { var columnIndex = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : 0, key = this._keyMapper(rowIndex, columnIndex); return void 0 !== this._cellHeightCache[key]; } }, { key: "set", value: function(rowIndex, columnIndex, width, height) { var key = this._keyMapper(rowIndex, columnIndex); columnIndex >= this._columnCount && (this._columnCount = columnIndex + 1), rowIndex >= this._rowCount && (this._rowCount = rowIndex + 1), this._cellHeightCache[key] = height, this._cellWidthCache[key] = width, this._updateCachedColumnAndRowSizes(rowIndex, columnIndex); } }, { key: "_updateCachedColumnAndRowSizes", value: function(rowIndex, columnIndex) { if (!this._hasFixedWidth) { for (var columnWidth = 0, i = 0; i < this._rowCount; i++) columnWidth = Math.max(columnWidth, this.getWidth(i, columnIndex)); var columnKey = this._keyMapper(0, columnIndex); this._columnWidthCache[columnKey] = columnWidth; } if (!this._hasFixedHeight) { for (var rowHeight = 0, _i = 0; _i < this._columnCount; _i++) rowHeight = Math.max(rowHeight, this.getHeight(rowIndex, _i)); var rowKey = this._keyMapper(rowIndex, 0); this._rowHeightCache[rowKey] = rowHeight; } } }, { key: "defaultHeight", get: function() { return this._defaultHeight; } }, { key: "defaultWidth", get: function() { return this._defaultWidth; } } ]), CellMeasurerCache; }(); function defaultKeyMapper(rowIndex, columnIndex) { return "".concat(rowIndex, "-").concat(columnIndex); } function unwrapExports(x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x.default : x; } function createCommonjsModule(fn, module) { return fn(module = { exports: {} }, module.exports), module.exports; } var reactIs_production_min = createCommonjsModule(function(module, exports) { Object.defineProperty(exports, "__esModule", { value: !0 }); var b = "function" == typeof Symbol && Symbol.for, c = b ? Symbol.for("react.element") : 60103, d = b ? Symbol.for("react.portal") : 60106, e = b ? Symbol.for("react.fragment") : 60107, f = b ? Symbol.for("react.strict_mode") : 60108, g = b ? Symbol.for("react.profiler") : 60114, h = b ? Symbol.for("react.provider") : 60109, k = b ? Symbol.for("react.context") : 60110, l = b ? Symbol.for("react.async_mode") : 60111, m = b ? Symbol.for("react.concurrent_mode") : 60111, n = b ? Symbol.for("react.forward_ref") : 60112, p = b ? Symbol.for("react.suspense") : 60113, q = b ? Symbol.for("react.suspense_list") : 60120, r = b ? Symbol.for("react.memo") : 60115, t = b ? Symbol.for("react.lazy") : 60116, v = b ? Symbol.for("react.fundamental") : 60117, w = b ? Symbol.for("react.responder") : 60118, x = b ? Symbol.for("react.scope") : 60119; function y(a) { if ("object" == typeof a && null !== a) { var u = a.$$typeof; switch (u) { case c: switch (a = a.type) { case l: case m: case e: case g: case f: case p: return a; default: switch (a = a && a.$$typeof) { case k: case n: case h: return a; default: return u; } } case t: case r: case d: return u; } } } function z(a) { return y(a) === m; } exports.typeOf = y, exports.AsyncMode = l, exports.ConcurrentMode = m, exports.ContextConsumer = k, exports.ContextProvider = h, exports.Element = c, exports.ForwardRef = n, exports.Fragment = e, exports.Lazy = t, exports.Memo = r, exports.Portal = d, exports.Profiler = g, exports.StrictMode = f, exports.Suspense = p, exports.isValidElementType = function(a) { return "string" == typeof a || "function" == typeof a || a === e || a === m || a === g || a === f || a === p || a === q || "object" == typeof a && null !== a && (a.$$typeof === t || a.$$typeof === r || a.$$typeof === h || a.$$typeof === k || a.$$typeof === n || a.$$typeof === v || a.$$typeof === w || a.$$typeof === x); }, exports.isAsyncMode = function(a) { return z(a) || y(a) === l; }, exports.isConcurrentMode = z, exports.isContextConsumer = function(a) { return y(a) === k; }, exports.isContextProvider = function(a) { return y(a) === h; }, exports.isElement = function(a) { return "object" == typeof a && null !== a && a.$$typeof === c; }, exports.isForwardRef = function(a) { return y(a) === n; }, exports.isFragment = function(a) { return y(a) === e; }, exports.isLazy = function(a) { return y(a) === t; }, exports.isMemo = function(a) { return y(a) === r; }, exports.isPortal = function(a) { return y(a) === d; }, exports.isProfiler = function(a) { return y(a) === g; }, exports.isStrictMode = function(a) { return y(a) === f; }, exports.isSuspense = function(a) { return y(a) === p; }; }); unwrapExports(reactIs_production_min); reactIs_production_min.typeOf, reactIs_production_min.AsyncMode, reactIs_production_min.ConcurrentMode, reactIs_production_min.ContextConsumer, reactIs_production_min.ContextProvider, reactIs_production_min.Element, reactIs_production_min.ForwardRef, reactIs_production_min.Fragment, reactIs_production_min.Lazy, reactIs_production_min.Memo, reactIs_production_min.Portal, reactIs_production_min.Profiler, reactIs_production_min.StrictMode, reactIs_production_min.Suspense, reactIs_production_min.isValidElementType, reactIs_production_min.isAsyncMode, reactIs_production_min.isConcurrentMode, reactIs_production_min.isContextConsumer, reactIs_production_min.isContextProvider, reactIs_production_min.isElement, reactIs_production_min.isForwardRef, reactIs_production_min.isFragment, reactIs_production_min.isLazy, reactIs_production_min.isMemo, reactIs_production_min.isPortal, reactIs_production_min.isProfiler, reactIs_production_min.isStrictMode, reactIs_production_min.isSuspense; var reactIs_development = createCommonjsModule(function(module, exports) { !function() { Object.defineProperty(exports, "__esModule", { value: !0 }); // The Symbol used to tag the ReactElement-like types. If there is no native Symbol // nor polyfill, then a plain number is used for performance. var hasSymbol = "function" == typeof Symbol && Symbol.for, REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for("react.element") : 60103, REACT_PORTAL_TYPE = hasSymbol ? Symbol.for("react.portal") : 60106, REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for("react.fragment") : 60107, REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for("react.strict_mode") : 60108, REACT_PROFILER_TYPE = hasSymbol ? Symbol.for("react.profiler") : 60114, REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for("react.provider") : 60109, REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for("react.context") : 60110, REACT_ASYNC_MODE_TYPE = hasSymbol ? Symbol.for("react.async_mode") : 60111, REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for("react.concurrent_mode") : 60111, REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for("react.forward_ref") : 60112, REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for("react.suspense") : 60113, REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for("react.suspense_list") : 60120, REACT_MEMO_TYPE = hasSymbol ? Symbol.for("react.memo") : 60115, REACT_LAZY_TYPE = hasSymbol ? Symbol.for("react.lazy") : 60116, REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for("react.fundamental") : 60117, REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for("react.responder") : 60118, REACT_SCOPE_TYPE = hasSymbol ? Symbol.for("react.scope") : 60119; /** * Forked from fbjs/warning: * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js * * Only change is we use console.warn instead of console.error, * and do nothing when 'console' is not supported. * This really simplifies the code. * --- * Similar to invariant but only logs a warning if the condition is not met. * This can be used to log issues in development environments in critical * paths. Removing the logging code for production environments will keep the * same logic and follow the same code paths. */ var lowPriorityWarningWithoutStack$1 = function(condition, format) { if (void 0 === format) throw new Error("`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning message argument"); if (!condition) { for (var _len2 = arguments.length, args = new Array(2 < _len2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) args[_key2 - 2] = arguments[_key2]; (function(format) { for (var _len = arguments.length, args = new Array(1 < _len ? _len - 1 : 0), _key = 1; _key < _len; _key++) args[_key - 1] = arguments[_key]; var argIndex = 0, message = "Warning: " + format.replace(/%s/g, function() { return args[argIndex++]; }); "undefined" != typeof console && console.warn(message); try { // --- Welcome to debugging React --- // This error was thrown as a convenience so that you can use this stack // to find the callsite that caused this warning to fire. throw new Error(message); } catch (x) {} }).apply(void 0, [ format ].concat(args)); } }; function typeOf(object) { if ("object" == typeof object && null !== object) { var $$typeof = object.$$typeof; switch ($$typeof) { case REACT_ELEMENT_TYPE: var type = object.type; switch (type) { case REACT_ASYNC_MODE_TYPE: case REACT_CONCURRENT_MODE_TYPE: case REACT_FRAGMENT_TYPE: case REACT_PROFILER_TYPE: case REACT_STRICT_MODE_TYPE: case REACT_SUSPENSE_TYPE: return type; default: var $$typeofType = type && type.$$typeof; switch ($$typeofType) { case REACT_CONTEXT_TYPE: case REACT_FORWARD_REF_TYPE: case REACT_PROVIDER_TYPE: return $$typeofType; default: return $$typeof; } } case REACT_LAZY_TYPE: case REACT_MEMO_TYPE: case REACT_PORTAL_TYPE: return $$typeof; } } } // AsyncMode is deprecated along with isAsyncMode var AsyncMode = REACT_ASYNC_MODE_TYPE, ConcurrentMode = REACT_CONCURRENT_MODE_TYPE, ContextConsumer = REACT_CONTEXT_TYPE, ContextProvider = REACT_PROVIDER_TYPE, Element = REACT_ELEMENT_TYPE, ForwardRef = REACT_FORWARD_REF_TYPE, Fragment = REACT_FRAGMENT_TYPE, Lazy = REACT_LAZY_TYPE, Memo = REACT_MEMO_TYPE, Portal = REACT_PORTAL_TYPE, Profiler = REACT_PROFILER_TYPE, StrictMode = REACT_STRICT_MODE_TYPE, Suspense = REACT_SUSPENSE_TYPE, hasWarnedAboutDeprecatedIsAsyncMode = !1; function isConcurrentMode(object) { return typeOf(object) === REACT_CONCURRENT_MODE_TYPE; } exports.typeOf = typeOf, exports.AsyncMode = AsyncMode, exports.ConcurrentMode = ConcurrentMode, exports.ContextConsumer = ContextConsumer, exports.ContextProvider = ContextProvider, exports.Element = Element, exports.ForwardRef = ForwardRef, exports.Fragment = Fragment, exports.Lazy = Lazy, exports.Memo = Memo, exports.Portal = Portal, exports.Profiler = Profiler, exports.StrictMode = StrictMode, exports.Suspense = Suspense, exports.isValidElementType = function(type) { return "string" == typeof type || "function" == typeof type || // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill. type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || "object" == typeof type && null !== type && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE); }, exports.isAsyncMode = // AsyncMode should be deprecated function(object) { return hasWarnedAboutDeprecatedIsAsyncMode || lowPriorityWarningWithoutStack$1(!(hasWarnedAboutDeprecatedIsAsyncMode = !0), "The ReactIs.isAsyncMode() alias has been deprecated, and will be removed in React 17+. Update your code to use ReactIs.isConcurrentMode() instead. It has the exact same API."), isConcurrentMode(object) || typeOf(object) === REACT_ASYNC_MODE_TYPE; }, exports.isConcurrentMode = isConcurrentMode, exports.isContextConsumer = function(object) { return typeOf(object) === REACT_CONTEXT_TYPE; }, exports.isContextProvider = function(object) { return typeOf(object) === REACT_PROVIDER_TYPE; }, exports.isElement = function(object) { return "object" == typeof object && null !== object && object.$$typeof === REACT_ELEMENT_TYPE; }, exports.isForwardRef = function(object) { return typeOf(object) === REACT_FORWARD_REF_TYPE; }, exports.isFragment = function(object) { return typeOf(object) === REACT_FRAGMENT_TYPE; }, exports.isLazy = function(object) { return typeOf(object) === REACT_LAZY_TYPE; }, exports.isMemo = function(object) { return typeOf(object) === REACT_MEMO_TYPE; }, exports.isPortal = function(object) { return typeOf(object) === REACT_PORTAL_TYPE; }, exports.isProfiler = function(object) { return typeOf(object) === REACT_PROFILER_TYPE; }, exports.isStrictMode = function(object) { return typeOf(object) === REACT_STRICT_MODE_TYPE; }, exports.isSuspense = function(object) { return typeOf(object) === REACT_SUSPENSE_TYPE; }; }(); }); unwrapExports(reactIs_development); reactIs_development.typeOf, reactIs_development.AsyncMode, reactIs_development.ConcurrentMode, reactIs_development.ContextConsumer, reactIs_development.ContextProvider, reactIs_development.Element, reactIs_development.ForwardRef, reactIs_development.Fragment, reactIs_development.Lazy, reactIs_development.Memo, reactIs_development.Portal, reactIs_development.Profiler, reactIs_development.StrictMode, reactIs_development.Suspense, reactIs_development.isValidElementType, reactIs_development.isAsyncMode, reactIs_development.isConcurrentMode, reactIs_development.isContextConsumer, reactIs_development.isContextProvider, reactIs_development.isElement, reactIs_development.isForwardRef, reactIs_development.isFragment, reactIs_development.isLazy, reactIs_development.isMemo, reactIs_development.isPortal, reactIs_development.isProfiler, reactIs_development.isStrictMode, reactIs_development.isSuspense; var reactIs = createCommonjsModule(function(module) { module.exports = reactIs_development; }), getOwnPropertySymbols = Object.getOwnPropertySymbols, hasOwnProperty = Object.prototype.hasOwnProperty, propIsEnumerable = Object.prototype.propertyIsEnumerable; var printWarning, objectAssign = function() { try { if (!Object.assign) return !1; // Detect buggy property enumeration order in older V8 versions. // https://bugs.chromium.org/p/v8/issues/detail?id=4118 var test1 = new String("abc"); // eslint-disable-line no-new-wrappers if (test1[5] = "de", "5" === Object.getOwnPropertyNames(test1)[0]) return !1; // https://bugs.chromium.org/p/v8/issues/detail?id=3056 for (var test2 = {}, i = 0; i < 10; i++) test2["_" + String.fromCharCode(i)] = i; if ("0123456789" !== Object.getOwnPropertyNames(test2).map(function(n) { return test2[n]; }).join("")) return !1; // https://bugs.chromium.org/p/v8/issues/detail?id=3056 var test3 = {}; return "abcdefghijklmnopqrst".split("").forEach(function(letter) { test3[letter] = letter; }), "abcdefghijklmnopqrst" === Object.keys(Object.assign({}, test3)).join(""); } catch (err) { // We don't expect any of the above to throw, but better to be safe. return !1; } }() ? Object.assign : function(target, source) { for (var from, symbols, to = function(val) { if (null == val) throw new TypeError("Object.assign cannot be called with null or undefined"); return Object(val); }(target), s = 1; s < arguments.length; s++) { for (var key in from = Object(arguments[s])) hasOwnProperty.call(from, key) && (to[key] = from[key]); if (getOwnPropertySymbols) { symbols = getOwnPropertySymbols(from); for (var i = 0; i < symbols.length; i++) propIsEnumerable.call(from, symbols[i]) && (to[symbols[i]] = from[symbols[i]]); } } return to; }, ReactPropTypesSecret_1 = "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED", loggedTypeFailures = {}, has = Function.call.bind(Object.prototype.hasOwnProperty); /** * Copyright (c) 2013-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ /** * Assert that the values match with the type specs. * Error messages are memorized and will only be shown once. * * @param {object} typeSpecs Map of name to a ReactPropType * @param {object} values Runtime values that need to be type-checked * @param {string} location e.g. "prop", "context", "child context" * @param {string} componentName Name of the component for error messages. * @param {?Function} getStack Returns the component stack. * @private */ function checkPropTypes(typeSpecs, values, location, componentName, getStack) { for (var typeSpecName in typeSpecs) if (has(typeSpecs, typeSpecName)) { var error; // Prop type validation may throw. In case they do, we don't want to // fail the render phase where it didn't fail before. So we log it. // After these have been cleaned up, we'll let them throw. try { // This is intentionally an invariant that gets caught. It's the same // behavior as without this statement except with a better message. if ("function" != typeof typeSpecs[typeSpecName]) { var err = Error((componentName || "React class") + ": " + location + " type `" + typeSpecName + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof typeSpecs[typeSpecName] + "`."); throw err.name = "Invariant Violation", err; } error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"); } catch (ex) { error = ex; } if (!error || error instanceof Error || printWarning((componentName || "React class") + ": type specification of " + location + " `" + typeSpecName + "` is invalid; the type checker function must return `null` or an `Error` but returned a " + typeof error + ". You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument)."), error instanceof Error && !(error.message in loggedTypeFailures)) { // Only monitor this failure once because there tends to be a lot of the // same error. loggedTypeFailures[error.message] = !0; var stack = getStack ? getStack() : ""; printWarning("Failed " + location + " type: " + error.message + (null != stack ? stack : "")); } } } /** * Resets warning cache when testing. * * @private */ printWarning = function(text) { var message = "Warning: " + text; "undefined" != typeof console && console.error(message); try { // --- Welcome to debugging React --- // This error was thrown as a convenience so that you can use this stack // to find the callsite that caused this warning to fire. throw new Error(message); } catch (x) {} }, checkPropTypes.resetWarningCache = function() { loggedTypeFailures = {}; }; var printWarning$1, checkPropTypes_1 = checkPropTypes, has$1 = Function.call.bind(Object.prototype.hasOwnProperty); function emptyFunctionThatReturnsNull() { return null; } printWarning$1 = function(text) { var message = "Warning: " + text; "undefined" != typeof console && console.error(message); try { // --- Welcome to debugging React --- // This error was thrown as a convenience so that you can use this stack // to find the callsite that caused this warning to fire. throw new Error(message); } catch (x) {} }; function factoryWithTypeCheckers(isValidElement, throwOnDirectAccess) { /* global Symbol */ var ITERATOR_SYMBOL = "function" == typeof Symbol && Symbol.iterator, FAUX_ITERATOR_SYMBOL = "@@iterator", ANONYMOUS = "<<anonymous>>", ReactPropTypes = { array: createPrimitiveTypeChecker("array"), bool: createPrimitiveTypeChecker("boolean"), func: createPrimitiveTypeChecker("function"), number: createPrimitiveTypeChecker("number"), object: createPrimitiveTypeChecker("object"), string: createPrimitiveTypeChecker("string"), symbol: createPrimitiveTypeChecker("symbol"), any: createChainableTypeChecker(emptyFunctionThatReturnsNull), arrayOf: function(typeChecker) { return createChainableTypeChecker(function(props, propName, componentName, location, propFullName) { if ("function" != typeof typeChecker) return new PropTypeError("Property `" + propFullName + "` of component `" + componentName + "` has invalid PropType notation inside arrayOf."); var propValue = props[propName]; if (!Array.isArray(propValue)) return new PropTypeError("Invalid " + location + " `" + propFullName + "` of type `" + getPropType(propValue) + "` supplied to `" + componentName + "`, expected an array."); for (var i = 0; i < propValue.length; i++) { var error = typeChecker(propValue, i, componentName, location, propFullName + "[" + i + "]", ReactPropTypesSecret_1); if (error instanceof Error) return error; } return null; }); }, element: createChainableTypeChecker(function(props, propName, componentName, location, propFullName) { var propValue = props[propName]; return isValidElement(propValue) ? null : new PropTypeError("Invalid " + location + " `" + propFullName + "` of type `" + getPropType(propValue) + "` supplied to `" + componentName + "`, expected a single ReactElement."); }), elementType: createChainableTypeChecker(function(props, propName, componentName, location, propFullName) { var propValue = props[propName]; return reactIs.isValidElementType(propValue) ? null : new PropTypeError("Invalid " + location + " `" + propFullName + "` of type `" + getPropType(propValue) + "` supplied to `" + componentName + "`, expected a single ReactElement type."); }), instanceOf: function(expectedClass) { return createChainableTypeChecker(function(props, propName, componentName, location, propFullName) { if (props[propName] instanceof expectedClass) return null; var expectedClassName = expectedClass.name || ANONYMOUS; return new PropTypeError("Invalid " + location + " `" + propFullName + "` of type `" + // Returns class name of the object, if any. function(propValue) { return propValue.constructor && propValue.constructor.name ? propValue.constructor.name : ANONYMOUS; }(props[propName]) + "` supplied to `" + componentName + "`, expected instance of `" + expectedClassName + "`."); }); }, node: createChainableTypeChecker(function(props, propName, componentName, location, propFullName) { return isNode(props[propName]) ? null : new PropTypeError("Invalid " + location + " `" + propFullName + "` supplied to `" + componentName + "`, expected a ReactNode."); }), objectOf: function(typeChecker) { return createChainableTypeChecker(function(props, propName, componentName, location, propFullName) { if ("function" != typeof typeChecker) return new PropTypeError("Property `" + propFullName + "` of component `" + componentName + "` has invalid PropType notation inside objectOf."); var propValue = props[propName], propType = getPropType(propValue); if ("object" !== propType) return new PropTypeError("Invalid " + location + " `" + propFullName + "` of type `" + propType + "` supplied to `" + componentName + "`, expected an object."); for (var key in propValue) if (has$1(propValue, key)) { var error = typeChecker(propValue, key, componentName, location, propFullName + "." + key, ReactPropTypesSecret_1); if (error instanceof Error) return error; } return null; }); }, oneOf: function(expectedValues) { if (!Array.isArray(expectedValues)) return printWarning$1(1 < arguments.length ? "Invalid arguments supplied to oneOf, expected an array, got " + arguments.length + " arguments. A common mistake is to write oneOf(x, y, z) instead of oneOf([x, y, z])." : "Invalid argument supplied to oneOf, expected an array."), emptyFunctionThatReturnsNull; return createChainableTypeChecker(function(props, propName, componentName, location, propFullName) { for (var propValue = props[propName], i = 0; i < expectedValues.length; i++) if (is(propValue, expectedValues[i])) return null; var valuesString = JSON.stringify(expectedValues, function(key, value) { return "symbol" === getPreciseType(value) ? String(value) : value; }); return new PropTypeError("Invalid " + location + " `" + propFullName + "` of value `" + String(propValue) + "` supplied to `" + componentName + "`, expected one of " + valuesString + "."); }); }, oneOfType: function(arrayOfTypeCheckers) { if (!Array.isArray(arrayOfTypeCheckers)) return printWarning$1("Invalid argument supplied to oneOfType, expected an instance of array."), emptyFunctionThatReturnsNull; for (var i = 0; i < arrayOfTypeCheckers.length; i++) { var checker = arrayOfTypeCheckers[i]; if ("function" != typeof checker) return printWarning$1("Invalid argument supplied to oneOfType. Expected an array of check functions, but received " + getPostfixForTypeWarning(checker) + " at index " + i + "."), emptyFunctionThatReturnsNull; } return createChainableTypeChecker(function(props, propName, componentName, location, propFullName) { for (var i = 0; i < arrayOfTypeCheckers.length; i++) { if (null == (0, arrayOfTypeCheckers[i])(props, propName, componentName, location, propFullName, ReactPropTypesSecret_1)) return null; } return new PropTypeError("Invalid " + location + " `" + propFullName + "` supplied to `" + componentName + "`."); }); }, shape: function(shapeTypes) { return createChainableTypeChecker(function(props, propName, componentName, location, propFullName) { var propValue = props[propName], propType = getPropType(propValue); if ("object" !== propType) return new PropTypeError("Invalid " + location + " `" + propFullName + "` of type `" + propType + "` supplied to `" + componentName + "`, expected `object`."); for (var key in shapeTypes) { var checker = shapeTypes[key]; if (checker) { var error = checker(propValue, key, componentName, location, propFullName + "." + key, ReactPropTypesSecret_1); if (error) return error; } } return null; }); }, exact: function(shapeTypes) { return createChainableTypeChecker(function(props, propName, componentName, location, propFullName) { var propValue = props[propName], propType = getPropType(propValue); if ("object" !== propType) return new PropTypeError("Invalid " + location + " `" + propFullName + "` of type `" + propType + "` supplied to `" + componentName + "`, expected `object`."); // We need to check all keys in case some are required but missing from // props. var allKeys = objectAssign({}, props[propName], shapeTypes); for (var key in allKeys) { var checker = shapeTypes[key]; if (!checker) return new PropTypeError("Invalid " + location + " `" + propFullName + "` key `" + key + "` supplied to `" + componentName + "`.\nBad object: " + JSON.stringify(props[propName], null, " ") + "\nValid keys: " + JSON.stringify(Object.keys(shapeTypes), null, " ")); var error = checker(propValue, key, componentName, location, propFullName + "." + key, ReactPropTypesSecret_1); if (error) return error; } return null; }); } }; /** * inlined Object.is polyfill to avoid requiring consumers ship their own * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is */ /*eslint-disable no-self-compare*/ function is(x, y) { // SameValue algorithm return x === y ? 0 !== x || 1 / x == 1 / y : x != x && y != y; } /*eslint-enable no-self-compare*/ /** * We use an Error-like object for backward compatibility as people may call * PropTypes directly and inspect their output. However, we don't use real * Errors anymore. We don't inspect their stack anyway, and creating them * is prohibitively expensive if they are created too often, such as what * happens in oneOfType() for any type before the one that matched. */ function PropTypeError(message) { this.message = message, this.stack = ""; } // Make `instanceof Error` still work for returned errors. function createChainableTypeChecker(validate) { var manualPropTypeCallCache = {}, manualPropTypeWarningCount = 0; function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { if (componentName = componentName || ANONYMOUS, propFullName = propFullName || propName, secret !== ReactPropTypesSecret_1) { if (throwOnDirectAccess) { // New behavior only for users of `prop-types` package var err = new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use `PropTypes.checkPropTypes()` to call them. Read more at http://fb.me/use-check-prop-types"); throw err.name = "Invariant Violation", err; } if ("undefined" != typeof console) { // Old behavior for people using React.PropTypes var cacheKey = componentName + ":" + propName; !manualPropTypeCallCache[cacheKey] && // Avoid spamming the console because they are often not actionable except for lib authors manualPropTypeWarningCount < 3 && (printWarning$1("You are manually calling a React.PropTypes validation function for the `" + propFullName + "` prop on `" + componentName + "`. This is deprecated and will throw in the standalone `prop-types` package. You may be seeing this warning due to a third-party PropTypes library. See https://fb.me/react-warning-dont-call-proptypes for details."), manualPropTypeCallCache[cacheKey] = !0, manualPropTypeWarningCount++); } } return null == props[propName] ? isRequired ? null === props[propName] ? new PropTypeError("The " + location + " `" + propFullName + "` is marked as required in `" + componentName + "`, but its value is `null`.") : new PropTypeError("The " + location + " `" + propFullName + "` is marked as required in `" + componentName + "`, but its value is `undefined`.") : null : validate(props, propName, componentName, location, propFullName); } var chainedCheckType = checkType.bind(null, !1); return chainedCheckType.isRequired = checkType.bind(null, !0), chainedCheckType; } function createPrimitiveTypeChecker(expectedType) { return createChainableTypeChecker(function(props, propName, componentName, location, propFullName, secret) { var propValue = props[propName]; return getPropType(propValue) === expectedType ? null : new PropTypeError("Invalid " + location + " `" + propFullName + "` of type `" + getPreciseType(propValue) + "` supplied to `" + componentName + "`, expected `" + expectedType + "`."); }); } function isNode(propValue) { switch (typeof propValue) { case "number": case "string": case "undefined": return !0; case "boolean": return !propValue; case "object": if (Array.isArray(propValue)) return propValue.every(isNode); if (null === propValue || isValidElement(propValue)) return !0; var iteratorFn = // Before Symbol spec. /** * Returns the iterator method function contained on the iterable object. * * Be sure to invoke the function with the iterable as context: * * var iteratorFn = getIteratorFn(myIterable); * if (iteratorFn) { * var iterator = iteratorFn.call(myIterable); * ... * } * * @param {?object} maybeIterable * @return {?function} */ function(maybeIterable) { var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); if ("function" == typeof iteratorFn) return iteratorFn; } /** * Collection of methods that allow declaration and validation of props that are * supplied to React components. Example usage: * * var Props = require('ReactPropTypes'); * var MyArticle = React.createClass({ * propTypes: { * // An optional string prop named "description". * description: Props.string, * * // A required enum prop named "category". * category: Props.oneOf(['News','Photos']).isRequired, * * // A prop named "dialog" that requires an instance of Dialog. * dialog: Props.instanceOf(Dialog).isRequired * }, * render: function() { ... } * }); * * A more formal specification of how these methods are used: * * type := array|bool|func|object|number|string|oneOf([...])|instanceOf(...) * decl := ReactPropTypes.{type}(.isRequired)? * * Each and every declaration produces a function with the same signature. This * allows the creation of custom validation functions. For example: * * var MyLink = React.createClass({ * propTypes: { * // An optional string or URI prop named "href". * href: function(props, propName, componentName) { * var propValue = props[propName]; * if (propValue != null && typeof propValue !== 'string' && * !(propValue instanceof URI)) { * return new Error( * 'Expected a string or an URI for ' + propName + ' in ' + * componentName * ); * } * } * }, * render: function() {...} * }); * * @internal */ (propValue); if (!iteratorFn) return !1; var step, iterator = iteratorFn.call(propValue); if (iteratorFn !== propValue.entries) { for (;!(step = iterator.next()).done; ) if (!isNode(step.value)) return !1; } else // Iterator will provide entry [k,v] tuples rather than values. for (;!(step = iterator.next()).done; ) { var entry = step.value; if (entry && !isNode(entry[1])) return !1; } return !0; default: return !1; } } // Equivalent of `typeof` but with special handling for array and regexp. function getPropType(propValue) { var propType = typeof propValue; return Array.isArray(propValue) ? "array" : propValue instanceof RegExp ? "object" : function(propType, propValue) { // Native Symbol. return "symbol" === propType || // falsy value can't be a Symbol !!propValue && ( // 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' "Symbol" === propValue["@@toStringTag"] || "function" == typeof Symbol && propValue instanceof Symbol); }(propType, propValue) ? "symbol" : propType; } // This handles more types than `getPropType`. Only used for error messages. // See `createPrimitiveTypeChecker`. function getPreciseType(propValue) { if (null == propValue) return "" + propValue; var propType = getPropType(propValue); if ("object" === propType) { if (propValue instanceof Date) return "date"; if (propValue instanceof RegExp) return "regexp"; } return propType; } // Returns a string that is postfixed to a warning about an invalid type. // For example, "undefined" or "of type array" function getPostfixForTypeWarning(value) { var type = getPreciseType(value); switch (type) { case "array": case "object": return "an " + type; case "boolean": case "date": case "regexp": return "a " + type; default: return type; } } return PropTypeError.prototype = Error.prototype, ReactPropTypes.checkPropTypes = checkPropTypes_1, ReactPropTypes.resetWarningCache = checkPropTypes_1.resetWarningCache, ReactPropTypes.PropTypes = ReactPropTypes; } var propTypes = createCommonjsModule(function(module) { var ReactIs = reactIs; // By explicitly using `prop-types` you are opting into new development behavior. // http://fb.me/prop-types-in-prod module.exports = factoryWithTypeCheckers(ReactIs.isElement, !0); }); function toVal(mix) { var k, y, str = ""; if (mix) if ("object" == typeof mix) if (mix.push) for (k = 0; k < mix.length; k++) mix[k] && (y = toVal(mix[k])) && (str && (str += " "), str += y); else for (k in mix) mix[k] && (y = toVal(k)) && (str && (str += " "), str += y); else "boolean" == typeof mix || mix.call || (str && (str += " "), str += mix); return str; } function clsx() { for (var x, i = 0, str = ""; i < arguments.length; ) (x = toVal(arguments[i++])) && (str && (str += " "), str += x); return str; } function createCallbackMemoizer(argument_0) { var requireAllKeys = !(0 < arguments.length && void 0 !== argument_0) || argument_0, cachedIndices = {}; return function(_ref) { var callback = _ref.callback, indices = _ref.indices, keys = Object.keys(indices), allInitialized = !requireAllKeys || keys.every(function(key) { var value = indices[key]; return Array.isArray(value) ? 0 < value.length : 0 <= value; }), indexChanged = keys.length !== Object.keys(cachedIndices).length || keys.some(function(key) { var cachedValue = cachedIndices[key], value = indices[key]; return Array.isArray(value) ? cachedValue.join(",") !== value.join(",") : cachedValue !== value; }); cachedIndices = indices, allInitialized && indexChanged && callback(indices); }; } var size, canUseDOM = !("undefined" == typeof window || !window.document || !window.document.createElement); function scrollbarSize(recalc) { if ((!size && 0 !== size || recalc) && canUseDOM) { var scrollDiv = document.createElement("div"); scrollDiv.style.position = "absolute", scrollDiv.style.top = "-9999px", scrollDiv.style.width = "50px", scrollDiv.style.height = "50px", scrollDiv.style.overflow = "scroll", document.body.appendChild(scrollDiv), size = scrollDiv.offsetWidth - scrollDiv.clientWidth, document.body.removeChild(scrollDiv); } return size; } var SCROLL_POSITION_CHANGE_REASONS_OBSERVED = "observed", SCROLL_POSITION_CHANGE_REASONS_REQUESTED = "requested", CollectionView = function() { function CollectionView() { var _getPrototypeOf2, _this; _classCallCheck(this, CollectionView); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key]; return _defineProperty(_assertThisInitialized(_this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(CollectionView)).call.apply(_getPrototypeOf2, [ this ].concat(args)))), "state", { isScrolling: !1, scrollLeft: 0, scrollTop: 0 }), _defineProperty(_assertThisInitialized(_this), "_calculateSizeAndPositionDataOnNextUpdate", !1), _defineProperty(_assertThisInitialized(_this), "_onSectionRenderedMemoizer", createCallbackMemoizer()), _defineProperty(_assertThisInitialized(_this), "_onScrollMemoizer", createCallbackMemoizer(!1)), _defineProperty(_assertThisInitialized(_this), "_invokeOnSectionRenderedHelper", function() { var _this$props = _this.props, cellLayoutManager = _this$props.cellLayoutManager, onSectionRendered = _this$props.onSectionRendered; _this._onSectionRenderedMemoizer({ callback: onSectionRendered, indices: { indices: cellLayoutManager.getLastRenderedIndices() } }); }), _defineProperty(_assertThisInitialized(_this), "_setScrollingContainerRef", function(ref) { _this._scrollingContainer = ref; }), _defineProperty(_assertThisInitialized(_this), "_updateScrollPositionForScrollToCell", function() { var _this$props2 = _this.props, cellLayoutManager = _this$props2.cellLayoutManager, height = _this$props2.height, scrollToAlignment = _this$props2.scrollToAlignment, scrollToCell = _this$props2.scrollToCell, width = _this$props2.width, _this$state = _this.state, scrollLeft = _this$state.scrollLeft, scrollTop = _this$state.scrollTop; if (0 <= scrollToCell) { var scrollPosition = cellLayoutManager.getScrollPositionForCell({ align: scrollToAlignment, cellIndex: scrollToCell, height: height, scrollLeft: scrollLeft, scrollTop: scrollTop, width: width }); scrollPosition.scrollLeft === scrollLeft && scrollPosition.scrollTop === scrollTop || _this._setScrollPosition(scrollPosition); } }), _defineProperty(_assertThisInitialized(_this), "_onScroll", function(event) { if (event.target === _this._scrollingContainer) { _this._enablePointerEventsAfterDelay(); var _this$props3 = _this.props, cellLayoutManager = _this$props3.cellLayoutManager, height = _this$props3.height, isScrollingChange = _this$props3.isScrollingChange, width = _this$props3.width, scrollbarSize = _this._scrollbarSize, _cellLayoutManager$ge = cellLayoutManager.getTotalSize(), totalHeight = _cellLayoutManager$ge.height, totalWidth = _cellLayoutManager$ge.width, scrollLeft = Math.max(0, Math.min(totalWidth - width + scrollbarSize, event.target.scrollLeft)), scrollTop = Math.max(0, Math.min(totalHeight - height + scrollbarSize, event.target.scrollTop)); if (_this.state.scrollLeft !== scrollLeft || _this.state.scrollTop !== scrollTop) { var scrollPositionChangeReason = event.cancelable ? SCROLL_POSITION_CHANGE_REASONS_OBSERVED : SCROLL_POSITION_CHANGE_REASONS_REQUESTED; _this.state.isScrolling || isScrollingChange(!0), _this.setState({ isScrolling: !0, scrollLeft: scrollLeft, scrollPositionChangeReason: scrollPositionChangeReason, scrollTop: scrollTop }); } _this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft, scrollTop: scrollTop, totalWidth: totalWidth, totalHeight: totalHeight }); } }), _this._scrollbarSize = scrollbarSize(), void 0 === _this._scrollbarSize ? (_this._scrollbarSizeMeasured = !1, _this._scrollbarSize = 0) : _this._scrollbarSizeMeasured = !0, _this; } return _inherits(CollectionView, React.PureComponent), _createClass(CollectionView, [ { key: "recomputeCellSizesAndPositions", value: function() { this._calculateSizeAndPositionDataOnNextUpdate = !0, this.forceUpdate(); } }, { key: "componentDidMount", value: function() { var _this$props4 = this.props, cellLayoutManager = _this$props4.cellLayoutManager, scrollLeft = _this$props4.scrollLeft, scrollToCell = _this$props4.scrollToCell, scrollTop = _this$props4.scrollTop; this._scrollbarSizeMeasured || (this._scrollbarSize = scrollbarSize(), this._scrollbarSizeMeasured = !0, this.setState({})), 0 <= scrollToCell ? this._updateScrollPositionForScrollToCell() : (0 <= scrollLeft || 0 <= scrollTop) && this._setScrollPosition({ scrollLeft: scrollLeft, scrollTop: scrollTop }), this._invokeOnSectionRenderedHelper(); var _cellLayoutManager$ge2 = cellLayoutManager.getTotalSize(), totalHeight = _cellLayoutManager$ge2.height, totalWidth = _cellLayoutManager$ge2.width; this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft || 0, scrollTop: scrollTop || 0, totalHeight: totalHeight, totalWidth: totalWidth }); } }, { key: "componentDidUpdate", value: function(prevProps, prevState) { var _this$props5 = this.props, height = _this$props5.height, scrollToAlignment = _this$props5.scrollToAlignment, scrollToCell = _this$props5.scrollToCell, width = _this$props5.width, _this$state2 = this.state, scrollLeft = _this$state2.scrollLeft, scrollPositionChangeReason = _this$state2.scrollPositionChangeReason, scrollTop = _this$state2.scrollTop; scrollPositionChangeReason === SCROLL_POSITION_CHANGE_REASONS_REQUESTED && (0 <= scrollLeft && scrollLeft !== prevState.scrollLeft && scrollLeft !== this._scrollingContainer.scrollLeft && (this._scrollingContainer.scrollLeft = scrollLeft), 0 <= scrollTop && scrollTop !== prevState.scrollTop && scrollTop !== this._scrollingContainer.scrollTop && (this._scrollingContainer.scrollTop = scrollTop)), height === prevProps.height && scrollToAlignment === prevProps.scrollToAlignment && scrollToCell === prevProps.scrollToCell && width === prevProps.width || this._updateScrollPositionForScrollToCell(), this._invokeOnSectionRenderedHelper(); } }, { key: "componentWillUnmount", value: function() { this._disablePointerEventsTimeoutId && clearTimeout(this._disablePointerEventsTimeoutId); } }, { key: "render", value: function() { var _this$props6 = this.props, autoHeight = _this$props6.autoHeight, cellCount = _this$props6.cellCount, cellLayoutManager = _this$props6.cellLayoutManager, className = _this$props6.className, height = _this$props6.height, horizontalOverscanSize = _this$props6.horizontalOverscanSize, id = _this$props6.id, noContentRenderer = _this$props6.noContentRenderer, style = _this$props6.style, verticalOverscanSize = _this$props6.verticalOverscanSize, width = _this$props6.width, _this$state3 = this.state, isScrolling = _this$state3.isScrolling, scrollLeft = _this$state3.scrollLeft, scrollTop = _this$state3.scrollTop; this._lastRenderedCellCount === cellCount && this._lastRenderedCellLayoutManager === cellLayoutManager && !this._calculateSizeAndPositionDataOnNextUpdate || (this._lastRenderedCellCount = cellCount, this._lastRenderedCellLayoutManager = cellLayoutManager, this._calculateSizeAndPositionDataOnNextUpdate = !1, cellLayoutManager.calculateSizeAndPositionData()); var _cellLayoutManager$ge3 = cellLayoutManager.getTotalSize(), totalHeight = _cellLayoutManager$ge3.height, totalWidth = _cellLayoutManager$ge3.width, left = Math.max(0, scrollLeft - horizontalOverscanSize), top = Math.max(0, scrollTop - verticalOverscanSize), right = Math.min(totalWidth, scrollLeft + width + horizontalOverscanSize), bottom = Math.min(totalHeight, scrollTop + height + verticalOverscanSize), childrenToDisplay = 0 < height && 0 < width ? cellLayoutManager.cellRenderers({ height: bottom - top, isScrolling: isScrolling, width: right - left, x: left, y: top }) : [], collectionStyle = { boxSizing: "border-box", direction: "ltr", height: autoHeight ? "auto" : height, position: "relative", WebkitOverflowScrolling: "touch", width: width, willChange: "transform" }, verticalScrollBarSize = height < totalHeight ? this._scrollbarSize : 0, horizontalScrollBarSize = width < totalWidth ? this._scrollbarSize : 0; return collectionStyle.overflowX = totalWidth + verticalScrollBarSize <= width ? "hidden" : "auto", collectionStyle.overflowY = totalHeight + horizontalScrollBarSize <= height ? "hidden" : "auto", React.createElement("div", { ref: this._setScrollingContainerRef, "aria-label": this.props["aria-label"], className: clsx("ReactVirtualized__Collection", className), id: id, onScroll: this._onScroll, role: "grid", style: _objectSpread2({}, collectionStyle, {}, style), tabIndex: 0 }, 0 < cellCount && React.createElement("div", { className: "ReactVirtualized__Collection__innerScrollContainer", style: { height: totalHeight, maxHeight: totalHeight, maxWidth: totalWidth, overflow: "hidden", pointerEvents: isScrolling ? "none" : "", width: totalWidth } }, childrenToDisplay), 0 === cellCount && noContentRenderer()); } }, { key: "_enablePointerEventsAfterDelay", value: function() { var _this2 = this; this._disablePointerEventsTimeoutId && clearTimeout(this._disablePointerEventsTimeoutId), this._disablePointerEventsTimeoutId = setTimeout(function() { (0, _this2.props.isScrollingChange)(!1), _this2._disablePointerEventsTimeoutId = null, _this2.setState({ isScrolling: !1 }); }, 150); } }, { key: "_invokeOnScrollMemoizer", value: function(_ref) { var _this3 = this, scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, totalHeight = _ref.totalHeight, totalWidth = _ref.totalWidth; this._onScrollMemoizer({ callback: function(_ref2) { var scrollLeft = _ref2.scrollLeft, scrollTop = _ref2.scrollTop, _this3$props = _this3.props, height = _this3$props.height; (0, _this3$props.onScroll)({ clientHeight: height, clientWidth: _this3$props.width, scrollHeight: totalHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: totalWidth }); }, indices: { scrollLeft: scrollLeft, scrollTop: scrollTop } }); } }, { key: "_setScrollPosition", value: function(_ref3) { var scrollLeft = _ref3.scrollLeft, scrollTop = _ref3.scrollTop, newState = { scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS_REQUESTED }; 0 <= scrollLeft && (newState.scrollLeft = scrollLeft), 0 <= scrollTop && (newState.scrollTop = scrollTop), (0 <= scrollLeft && scrollLeft !== this.state.scrollLeft || 0 <= scrollTop && scrollTop !== this.state.scrollTop) && this.setState(newState); } } ], [ { key: "getDerivedStateFromProps", value: function(nextProps, prevState) { return 0 !== nextProps.cellCount || 0 === prevState.scrollLeft && 0 === prevState.scrollTop ? nextProps.scrollLeft !== prevState.scrollLeft || nextProps.scrollTop !== prevState.scrollTop ? { scrollLeft: null != nextProps.scrollLeft ? nextProps.scrollLeft : prevState.scrollLeft, scrollTop: null != nextProps.scrollTop ? nextProps.scrollTop : prevState.scrollTop, scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS_REQUESTED } : null : { scrollLeft: 0, scrollTop: 0, scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS_REQUESTED }; } } ]), CollectionView; }(); _defineProperty(CollectionView, "propTypes", { "aria-label": propTypes.string, autoHeight: propTypes.bool, cellCount: propTypes.number.isRequired, cellLayoutManager: propTypes.object.isRequired, className: propTypes.string, height: propTypes.number.isRequired, id: propTypes.string, horizontalOverscanSize: propTypes.number.isRequired, isScrollingChange: propTypes.func, noContentRenderer: propTypes.func.isRequired, onScroll: propTypes.func.isRequired, onSectionRendered: propTypes.func.isRequired, scrollLeft: propTypes.number, scrollToAlignment: propTypes.oneOf([ "auto", "end", "start", "center" ]).isRequired, scrollToCell: propTypes.number.isRequired, scrollTop: propTypes.number, style: propTypes.object, verticalOverscanSize: propTypes.number.isRequired, width: propTypes.number.isRequired }), _defineProperty(CollectionView, "defaultProps", { "aria-label": "grid", horizontalOverscanSize: 0, noContentRenderer: function() { return null; }, onScroll: function() { return null; }, onSectionRendered: function() { return null; }, scrollToAlignment: "auto", scrollToCell: -1, style: {}, verticalOverscanSize: 0 }), polyfill(CollectionView); var Section = function() { function Section(_ref) { var height = _ref.height, width = _ref.width, x = _ref.x, y = _ref.y; _classCallCheck(this, Section), this.height = height, this.width = width, this.x = x, this.y = y, this._indexMap = {}, this._indices = []; } return _createClass(Section, [ { key: "addCellIndex", value: function(_ref2) { var index = _ref2.index; this._indexMap[index] || (this._indexMap[index] = !0, this._indices.push(index)); } }, { key: "getCellIndices", value: function() { return this._indices; } }, { key: "toString", value: function() { return "".concat(this.x, ",").concat(this.y, " ").concat(this.width, "x").concat(this.height); } } ]), Section; }(), SectionManager = function() { function SectionManager() { var sectionSize = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : 100; _classCallCheck(this, SectionManager), this._sectionSize = sectionSize, this._cellMetadata = [], this._sections = {}; } return _createClass(SectionManager, [ { key: "getCellIndices", value: function(_ref) { var height = _ref.height, width = _ref.width, x = _ref.x, y = _ref.y, indices = {}; return this.getSections({ height: height, width: width, x: x, y: y }).forEach(function(section) { return section.getCellIndices().forEach(function(index) { indices[index] = index; }); }), Object.keys(indices).map(function(index) { return indices[index]; }); } }, { key: "getCellMetadata", value: function(_ref2) { var index = _ref2.index; return this._cellMetadata[index]; } }, { key: "getSections", value: function(_ref3) { for (var height = _ref3.height, width = _ref3.width, x = _ref3.x, y = _ref3.y, sectionXStart = Math.floor(x / this._sectionSize), sectionXStop = Math.floor((x + width - 1) / this._sectionSize), sectionYStart = Math.floor(y / this._sectionSize), sectionYStop = Math.floor((y + height - 1) / this._sectionSize), sections = [], sectionX = sectionXStart; sectionX <= sectionXStop; sectionX++) for (var sectionY = sectionYStart; sectionY <= sectionYStop; sectionY++) { var key = "".concat(sectionX, ".").concat(sectionY); this._sections[key] || (this._sections[key] = new Section({ height: this._sectionSize, width: this._sectionSize, x: sectionX * this._sectionSize, y: sectionY * this._sectionSize })), sections.push(this._sections[key]); } return sections; } }, { key: "getTotalSectionCount", value: function() { return Object.keys(this._sections).length; } }, { key: "toString", value: function() { var _this = this; return Object.keys(this._sections).map(function(index) { return _this._sections[index].toString(); }); } }, { key: "registerCell", value: function(_ref4) { var cellMetadatum = _ref4.cellMetadatum, index = _ref4.index; this._cellMetadata[index] = cellMetadatum, this.getSections(cellMetadatum).forEach(function(section) { return section.addCellIndex({ index: index }); }); } } ]), SectionManager; }(); function getUpdatedOffsetForIndex(_ref) { var _ref$align = _ref.align, align = void 0 === _ref$align ? "auto" : _ref$align, cellOffset = _ref.cellOffset, cellSize = _ref.cellSize, containerSize = _ref.containerSize, currentOffset = _ref.currentOffset, maxOffset = cellOffset, minOffset = maxOffset - containerSize + cellSize; switch (align) { case "start": return maxOffset; case "end": return minOffset; case "center": return maxOffset - (containerSize - cellSize) / 2; default: return Math.max(minOffset, Math.min(maxOffset, currentOffset)); } } var Collection = function() { function Collection(props, context) { var _this; return _classCallCheck(this, Collection), (_this = _possibleConstructorReturn(this, _getPrototypeOf(Collection).call(this, props, context)))._cellMetadata = [], _this._lastRenderedCellIndices = [], _this._cellCache = [], _this._isScrollingChange = _this._isScrollingChange.bind(_assertThisInitialized(_this)), _this._setCollectionViewRef = _this._setCollectionViewRef.bind(_assertThisInitialized(_this)), _this; } return _inherits(Collection, React.PureComponent), _createClass(Collection, [ { key: "forceUpdate", value: function() { void 0 !== this._collectionView && this._collectionView.forceUpdate(); } }, { key: "recomputeCellSizesAndPositions", value: function() { this._cellCache = [], this._collectionView.recomputeCellSizesAndPositions(); } }, { key: "render", value: function() { var props = _extends({}, this.props); return React.createElement(CollectionView, _extends({ cellLayoutManager: this, isScrollingChange: this._isScrollingChange, ref: this._setCollectionViewRef }, props)); } }, { key: "calculateSizeAndPositionData", value: function() { var _this$props = this.props, data = function(_ref) { for (var cellCount = _ref.cellCount, cellSizeAndPositionGetter = _ref.cellSizeAndPositionGetter, sectionSize = _ref.sectionSize, cellMetadata = [], sectionManager = new SectionManager(sectionSize), height = 0, width = 0, index = 0; index < cellCount; index++) { var cellMetadatum = cellSizeAndPositionGetter({ index: index }); if (null == cellMetadatum.height || isNaN(cellMetadatum.height) || null == cellMetadatum.width || isNaN(cellMetadatum.width) || null == cellMetadatum.x || isNaN(cellMetadatum.x) || null == cellMetadatum.y || isNaN(cellMetadatum.y)) throw Error("Invalid metadata returned for cell ".concat(index, ":\n x:").concat(cellMetadatum.x, ", y:").concat(cellMetadatum.y, ", width:").concat(cellMetadatum.width, ", height:").concat(cellMetadatum.height)); height = Math.max(height, cellMetadatum.y + cellMetadatum.height), width = Math.max(width, cellMetadatum.x + cellMetadatum.width), cellMetadata[index] = cellMetadatum, sectionManager.registerCell({ cellMetadatum: cellMetadatum, index: index }); } return { cellMetadata: cellMetadata, height: height, sectionManager: sectionManager, width: width }; }({ cellCount: _this$props.cellCount, cellSizeAndPositionGetter: _this$props.cellSizeAndPositionGetter, sectionSize: _this$props.sectionSize }); this._cellMetadata = data.cellMetadata, this._sectionManager = data.sectionManager, this._height = data.height, this._width = data.width; } }, { key: "getLastRenderedIndices", value: function() { return this._lastRenderedCellIndices; } }, { key: "getScrollPositionForCell", value: function(_ref) { var align = _ref.align, cellIndex = _ref.cellIndex, height = _ref.height, scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, width = _ref.width, cellCount = this.props.cellCount; if (0 <= cellIndex && cellIndex < cellCount) { var cellMetadata = this._cellMetadata[cellIndex]; scrollLeft = getUpdatedOffsetForIndex({ align: align, cellOffset: cellMetadata.x, cellSize: cellMetadata.width, containerSize: width, currentOffset: scrollLeft, targetIndex: cellIndex }), scrollTop = getUpdatedOffsetForIndex({ align: align, cellOffset: cellMetadata.y, cellSize: cellMetadata.height, containerSize: height, currentOffset: scrollTop, targetIndex: cellIndex }); } return { scrollLeft: scrollLeft, scrollTop: scrollTop }; } }, { key: "getTotalSize", value: function() { return { height: this._height, width: this._width }; } }, { key: "cellRenderers", value: function(_ref2) { var _this2 = this, height = _ref2.height, isScrolling = _ref2.isScrolling, width = _ref2.width, x = _ref2.x, y = _ref2.y, _this$props2 = this.props, cellGroupRenderer = _this$props2.cellGroupRenderer, cellRenderer = _this$props2.cellRenderer; return this._lastRenderedCellIndices = this._sectionManager.getCellIndices({ height: height, width: width, x: x, y: y }), cellGroupRenderer({ cellCache: this._cellCache, cellRenderer: cellRenderer, cellSizeAndPositionGetter: function(_ref3) { var index = _ref3.index; return _this2._sectionManager.getCellMetadata({ index: index }); }, indices: this._lastRenderedCellIndices, isScrolling: isScrolling }); } }, { key: "_isScrollingChange", value: function(isScrolling) { isScrolling || (this._cellCache = []); } }, { key: "_setCollectionViewRef", value: function(ref) { this._collectionView = ref; } } ]), Collection; }(); _defineProperty(Collection, "propTypes", { "aria-label": propTypes.string, cellCount: propTypes.number.isRequired, cellGroupRenderer: propTypes.func.isRequired, cellRenderer: propTypes.func.isRequired, cellSizeAndPositionGetter: propTypes.func.isRequired, sectionSize: propTypes.number }), _defineProperty(Collection, "defaultProps", { "aria-label": "grid", cellGroupRenderer: function(_ref4) { var cellCache = _ref4.cellCache, cellRenderer = _ref4.cellRenderer, cellSizeAndPositionGetter = _ref4.cellSizeAndPositionGetter, indices = _ref4.indices, isScrolling = _ref4.isScrolling; return indices.map(function(index) { var cellMetadata = cellSizeAndPositionGetter({ index: index }), cellRendererProps = { index: index, isScrolling: isScrolling, key: index, style: { height: cellMetadata.height, left: cellMetadata.x, position: "absolute", top: cellMetadata.y, width: cellMetadata.width } }; return isScrolling ? (index in cellCache || (cellCache[index] = cellRenderer(cellRendererProps)), cellCache[index]) : cellRenderer(cellRendererProps); }).filter(function(renderedCell) { return !!renderedCell; }); } }); var ColumnSizer = function() { function ColumnSizer(props, context) { var _this; return _classCallCheck(this, ColumnSizer), (_this = _possibleConstructorReturn(this, _getPrototypeOf(ColumnSizer).call(this, props, context)))._registerChild = _this._registerChild.bind(_assertThisInitialized(_this)), _this; } return _inherits(ColumnSizer, React.PureComponent), _createClass(ColumnSizer, [ { key: "componentDidUpdate", value: function(prevProps) { var _this$props = this.props, columnMaxWidth = _this$props.columnMaxWidth, columnMinWidth = _this$props.columnMinWidth, columnCount = _this$props.columnCount, width = _this$props.width; columnMaxWidth === prevProps.columnMaxWidth && columnMinWidth === prevProps.columnMinWidth && columnCount === prevProps.columnCount && width === prevProps.width || this._registeredChild && this._registeredChild.recomputeGridSize(); } }, { key: "render", value: function() { var _this$props2 = this.props, children = _this$props2.children, columnMaxWidth = _this$props2.columnMaxWidth, columnMinWidth = _this$props2.columnMinWidth, columnCount = _this$props2.columnCount, width = _this$props2.width, safeColumnMinWidth = columnMinWidth || 1, safeColumnMaxWidth = columnMaxWidth ? Math.min(columnMaxWidth, width) : width, columnWidth = width / columnCount; return columnWidth = Math.max(safeColumnMinWidth, columnWidth), columnWidth = Math.min(safeColumnMaxWidth, columnWidth), columnWidth = Math.floor(columnWidth), children({ adjustedWidth: Math.min(width, columnWidth * columnCount), columnWidth: columnWidth, getColumnWidth: function() { return columnWidth; }, registerChild: this._registerChild }); } }, { key: "_registerChild", value: function(child) { if (child && "function" != typeof child.recomputeGridSize) throw Error("Unexpected child type registered; only Grid/MultiGrid children are supported."); this._registeredChild = child, this._registeredChild && this._registeredChild.recomputeGridSize(); } } ]), ColumnSizer; }(); function calculateSizeAndPositionDataAndUpdateScrollOffset(_ref) { var cellCount = _ref.cellCount, cellSize = _ref.cellSize, computeMetadataCallback = _ref.computeMetadataCallback, computeMetadataCallbackProps = _ref.computeMetadataCallbackProps, nextCellsCount = _ref.nextCellsCount, nextCellSize = _ref.nextCellSize, nextScrollToIndex = _ref.nextScrollToIndex, scrollToIndex = _ref.scrollToIndex, updateScrollOffsetForScrollToIndex = _ref.updateScrollOffsetForScrollToIndex; cellCount === nextCellsCount && ("number" != typeof cellSize && "number" != typeof nextCellSize || cellSize === nextCellSize) || (computeMetadataCallback(computeMetadataCallbackProps), 0 <= scrollToIndex && scrollToIndex === nextScrollToIndex && updateScrollOffsetForScrollToIndex()); } _defineProperty(ColumnSizer, "propTypes", { children: propTypes.func.isRequired, columnMaxWidth: propTypes.number, columnMinWidth: propTypes.number, columnCount: propTypes.number.isRequired, width: propTypes.number.isRequired }); var win, CellSizeAndPositionManager = function() { function CellSizeAndPositionManager(_ref) { var cellCount = _ref.cellCount, cellSizeGetter = _ref.cellSizeGetter, estimatedCellSize = _ref.estimatedCellSize; _classCallCheck(this, CellSizeAndPositionManager), _defineProperty(this, "_cellSizeAndPositionData", {}), _defineProperty(this, "_lastMeasuredIndex", -1), _defineProperty(this, "_lastBatchedIndex", -1), _defineProperty(this, "_cellCount", void 0), _defineProperty(this, "_cellSizeGetter", void 0), _defineProperty(this, "_estimatedCellSize", void 0), this._cellSizeGetter = cellSizeGetter, this._cellCount = cellCount, this._estimatedCellSize = estimatedCellSize; } return _createClass(CellSizeAndPositionManager, [ { key: "areOffsetsAdjusted", value: function() { return !1; } }, { key: "configure", value: function(_ref2) { var cellCount = _ref2.cellCount, estimatedCellSize = _ref2.estimatedCellSize, cellSizeGetter = _ref2.cellSizeGetter; this._cellCount = cellCount, this._estimatedCellSize = estimatedCellSize, this._cellSizeGetter = cellSizeGetter; } }, { key: "getCellCount", value: function() { return this._cellCount; } }, { key: "getEstimatedCellSize", value: function() { return this._estimatedCellSize; } }, { key: "getLastMeasuredIndex", value: function() { return this._lastMeasuredIndex; } }, { key: "getOffsetAdjustment", value: function() { return 0; } }, { key: "getSizeAndPositionOfCell", value: function(index) { if (index < 0 || index >= this._cellCount) throw Error("Requested index ".concat(index, " is outside of range 0..").concat(this._cellCount)); if (index > this._lastMeasuredIndex) for (var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(), offset = lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size, i = this._lastMeasuredIndex + 1; i <= index; i++) { var size = this._cellSizeGetter({ index: i }); if (void 0 === size || isNaN(size)) throw Error("Invalid size returned for cell ".concat(i, " of value ").concat(size)); null === size ? (this._cellSizeAndPositionData[i] = { offset: offset, size: 0 }, this._lastBatchedIndex = index) : (this._cellSizeAndPositionData[i] = { offset: offset, size: size }, offset += size, this._lastMeasuredIndex = index); } return this._cellSizeAndPositionData[index]; } }, { key: "getSizeAndPositionOfLastMeasuredCell", value: function() { return 0 <= this._lastMeasuredIndex ? this._cellSizeAndPositionData[this._lastMeasuredIndex] : { offset: 0, size: 0 }; } }, { key: "getTotalSize", value: function() { var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); return lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size + (this._cellCount - this._lastMeasuredIndex - 1) * this._estimatedCellSize; } }, { key: "getUpdatedOffsetForIndex", value: function(_ref3) { var _ref3$align = _ref3.align, align = void 0 === _ref3$align ? "auto" : _ref3$align, containerSize = _ref3.containerSize, currentOffset = _ref3.currentOffset, targetIndex = _ref3.targetIndex; if (containerSize <= 0) return 0; var idealOffset, datum = this.getSizeAndPositionOfCell(targetIndex), maxOffset = datum.offset, minOffset = maxOffset - containerSize + datum.size; switch (align) { case "start": idealOffset = maxOffset; break; case "end": idealOffset = minOffset; break; case "center": idealOffset = maxOffset - (containerSize - datum.size) / 2; break; default: idealOffset = Math.max(minOffset, Math.min(maxOffset, currentOffset)); } var totalSize = this.getTotalSize(); return Math.max(0, Math.min(totalSize - containerSize, idealOffset)); } }, { key: "getVisibleCellRange", value: function(params) { var containerSize = params.containerSize, offset = params.offset; if (0 === this.getTotalSize()) return {}; var maxOffset = offset + containerSize, start = this._findNearestCell(offset), datum = this.getSizeAndPositionOfCell(start); offset = datum.offset + datum.size; for (var stop = start; offset < maxOffset && stop < this._cellCount - 1; ) stop++, offset += this.getSizeAndPositionOfCell(stop).size; return { start: start, stop: stop }; } }, { key: "resetCell", value: function(index) { this._lastMeasuredIndex = Math.min(this._lastMeasuredIndex, index - 1); } }, { key: "_binarySearch", value: function(high, low, offset) { for (;low <= high; ) { var middle = low + Math.floor((high - low) / 2), currentOffset = this.getSizeAndPositionOfCell(middle).offset; if (currentOffset === offset) return middle; currentOffset < offset ? low = middle + 1 : offset < currentOffset && (high = middle - 1); } return 0 < low ? low - 1 : 0; } }, { key: "_exponentialSearch", value: function(index, offset) { for (var interval = 1; index < this._cellCount && this.getSizeAndPositionOfCell(index).offset < offset; ) index += interval, interval *= 2; return this._binarySearch(Math.min(index, this._cellCount - 1), Math.floor(index / 2), offset); } }, { key: "_findNearestCell", value: function(offset) { if (isNaN(offset)) throw Error("Invalid offset ".concat(offset, " specified")); offset = Math.max(0, offset); var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(), lastMeasuredIndex = Math.max(0, this._lastMeasuredIndex); return lastMeasuredCellSizeAndPosition.offset >= offset ? this._binarySearch(lastMeasuredIndex, 0, offset) : this._exponentialSearch(lastMeasuredIndex, offset); } } ]), CellSizeAndPositionManager; }(), getMaxElementSize = function() { return "undefined" != typeof window && window.chrome ? 16777100 : 15e5; }, ScalingCellSizeAndPositionManager = function() { function ScalingCellSizeAndPositionManager(_ref) { var _ref$maxScrollSize = _ref.maxScrollSize, maxScrollSize = void 0 === _ref$maxScrollSize ? getMaxElementSize() : _ref$maxScrollSize, params = _objectWithoutProperties(_ref, [ "maxScrollSize" ]); _classCallCheck(this, ScalingCellSizeAndPositionManager), _defineProperty(this, "_cellSizeAndPositionManager", void 0), _defineProperty(this, "_maxScrollSize", void 0), this._cellSizeAndPositionManager = new CellSizeAndPositionManager(params), this._maxScrollSize = maxScrollSize; } return _createClass(ScalingCellSizeAndPositionManager, [ { key: "areOffsetsAdjusted", value: function() { return this._cellSizeAndPositionManager.getTotalSize() > this._maxScrollSize; } }, { key: "configure", value: function(params) { this._cellSizeAndPositionManager.configure(params); } }, { key: "getCellCount", value: function() { return this._cellSizeAndPositionManager.getCellCount(); } }, { key: "getEstimatedCellSize", value: function() { return this._cellSizeAndPositionManager.getEstimatedCellSize(); } }, { key: "getLastMeasuredIndex", value: function() { return this._cellSizeAndPositionManager.getLastMeasuredIndex(); } }, { key: "getOffsetAdjustment", value: function(_ref2) { var containerSize = _ref2.containerSize, offset = _ref2.offset, totalSize = this._cellSizeAndPositionManager.getTotalSize(), safeTotalSize = this.getTotalSize(), offsetPercentage = this._getOffsetPercentage({ containerSize: containerSize, offset: offset, totalSize: safeTotalSize }); return Math.round(offsetPercentage * (safeTotalSize - totalSize)); } }, { key: "getSizeAndPositionOfCell", value: function(index) { return this._cellSizeAndPositionManager.getSizeAndPositionOfCell(index); } }, { key: "getSizeAndPositionOfLastMeasuredCell", value: function() { return this._cellSizeAndPositionManager.getSizeAndPositionOfLastMeasuredCell(); } }, { key: "getTotalSize", value: function() { return Math.min(this._maxScrollSize, this._cellSizeAndPositionManager.getTotalSize()); } }, { key: "getUpdatedOffsetForIndex", value: function(_ref3) { var _ref3$align = _ref3.align, align = void 0 === _ref3$align ? "auto" : _ref3$align, containerSize = _ref3.containerSize, currentOffset = _ref3.currentOffset, targetIndex = _ref3.targetIndex; currentOffset = this._safeOffsetToOffset({ containerSize: containerSize, offset: currentOffset }); var offset = this._cellSizeAndPositionManager.getUpdatedOffsetForIndex({ align: align, containerSize: containerSize, currentOffset: currentOffset, targetIndex: targetIndex }); return this._offsetToSafeOffset({ containerSize: containerSize, offset: offset }); } }, { key: "getVisibleCellRange", value: function(_ref4) { var containerSize = _ref4.containerSize, offset = _ref4.offset; return offset = this._safeOffsetToOffset({ containerSize: containerSize, offset: offset }), this._cellSizeAndPositionManager.getVisibleCellRange({ containerSize: containerSize, offset: offset }); } }, { key: "resetCell", value: function(index) { this._cellSizeAndPositionManager.resetCell(index); } }, { key: "_getOffsetPercentage", value: function(_ref5) { var containerSize = _ref5.containerSize, offset = _ref5.offset, totalSize = _ref5.totalSize; return totalSize <= containerSize ? 0 : offset / (totalSize - containerSize); } }, { key: "_offsetToSafeOffset", value: function(_ref6) { var containerSize = _ref6.containerSize, offset = _ref6.offset, totalSize = this._cellSizeAndPositionManager.getTotalSize(), safeTotalSize = this.getTotalSize(); if (totalSize === safeTotalSize) return offset; var offsetPercentage = this._getOffsetPercentage({ containerSize: containerSize, offset: offset, totalSize: totalSize }); return Math.round(offsetPercentage * (safeTotalSize - containerSize)); } }, { key: "_safeOffsetToOffset", value: function(_ref7) { var containerSize = _ref7.containerSize, offset = _ref7.offset, totalSize = this._cellSizeAndPositionManager.getTotalSize(), safeTotalSize = this.getTotalSize(); if (totalSize === safeTotalSize) return offset; var offsetPercentage = this._getOffsetPercentage({ containerSize: containerSize, offset: offset, totalSize: safeTotalSize }); return Math.round(offsetPercentage * (totalSize - containerSize)); } } ]), ScalingCellSizeAndPositionManager; }(); function defaultOverscanIndicesGetter(_ref) { var cellCount = _ref.cellCount, overscanCellsCount = _ref.overscanCellsCount, scrollDirection = _ref.scrollDirection, startIndex = _ref.startIndex, stopIndex = _ref.stopIndex; return 1 === scrollDirection ? { overscanStartIndex: Math.max(0, startIndex), overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount) } : { overscanStartIndex: Math.max(0, startIndex - overscanCellsCount), overscanStopIndex: Math.min(cellCount - 1, stopIndex) }; } function updateScrollIndexHelper(_ref) { var cellSize = _ref.cellSize, cellSizeAndPositionManager = _ref.cellSizeAndPositionManager, previousCellsCount = _ref.previousCellsCount, previousCellSize = _ref.previousCellSize, previousScrollToAlignment = _ref.previousScrollToAlignment, previousScrollToIndex = _ref.previousScrollToIndex, previousSize = _ref.previousSize, scrollOffset = _ref.scrollOffset, scrollToAlignment = _ref.scrollToAlignment, scrollToIndex = _ref.scrollToIndex, size = _ref.size, sizeJustIncreasedFromZero = _ref.sizeJustIncreasedFromZero, updateScrollIndexCallback = _ref.updateScrollIndexCallback, cellCount = cellSizeAndPositionManager.getCellCount(), hasScrollToIndex = 0 <= scrollToIndex && scrollToIndex < cellCount; hasScrollToIndex && (size !== previousSize || sizeJustIncreasedFromZero || !previousCellSize || "number" == typeof cellSize && cellSize !== previousCellSize || scrollToAlignment !== previousScrollToAlignment || scrollToIndex !== previousScrollToIndex) ? updateScrollIndexCallback(scrollToIndex) : !hasScrollToIndex && 0 < cellCount && (size < previousSize || cellCount < previousCellsCount) && scrollOffset > cellSizeAndPositionManager.getTotalSize() - size && updateScrollIndexCallback(cellCount - 1); } function defaultCellRangeRenderer(_ref) { for (var cellCache = _ref.cellCache, cellRenderer = _ref.cellRenderer, columnSizeAndPositionManager = _ref.columnSizeAndPositionManager, columnStartIndex = _ref.columnStartIndex, columnStopIndex = _ref.columnStopIndex, deferredMeasurementCache = _ref.deferredMeasurementCache, horizontalOffsetAdjustment = _ref.horizontalOffsetAdjustment, isScrolling = _ref.isScrolling, isScrollingOptOut = _ref.isScrollingOptOut, parent = _ref.parent, rowSizeAndPositionManager = _ref.rowSizeAndPositionManager, rowStartIndex = _ref.rowStartIndex, rowStopIndex = _ref.rowStopIndex, styleCache = _ref.styleCache, verticalOffsetAdjustment = _ref.verticalOffsetAdjustment, visibleColumnIndices = _ref.visibleColumnIndices, visibleRowIndices = _ref.visibleRowIndices, renderedCells = [], areOffsetsAdjusted = columnSizeAndPositionManager.areOffsetsAdjusted() || rowSizeAndPositionManager.areOffsetsAdjusted(), canCacheStyle = !isScrolling && !areOffsetsAdjusted, rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) for (var rowDatum = rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex), columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) { var columnDatum = columnSizeAndPositionManager.getSizeAndPositionOfCell(columnIndex), isVisible = columnIndex >= visibleColumnIndices.start && columnIndex <= visibleColumnIndices.stop && rowIndex >= visibleRowIndices.start && rowIndex <= visibleRowIndices.stop, key = "".concat(rowIndex, "-").concat(columnIndex), style = void 0; canCacheStyle && styleCache[key] ? style = styleCache[key] : deferredMeasurementCache && !deferredMeasurementCache.has(rowIndex, columnIndex) ? style = { height: "auto", left: 0, position: "absolute", top: 0, width: "auto" } : (style = { height: rowDatum.size, left: columnDatum.offset + horizontalOffsetAdjustment, position: "absolute", top: rowDatum.offset + verticalOffsetAdjustment, width: columnDatum.size }, styleCache[key] = style); var cellRendererParams = { columnIndex: columnIndex, isScrolling: isScrolling, isVisible: isVisible, key: key, parent: parent, rowIndex: rowIndex, style: style }, renderedCell = void 0; null != (renderedCell = !isScrollingOptOut && !isScrolling || horizontalOffsetAdjustment || verticalOffsetAdjustment ? cellRenderer(cellRendererParams) : (cellCache[key] || (cellCache[key] = cellRenderer(cellRendererParams)), cellCache[key])) && !1 !== renderedCell && (warnAboutMissingStyle(parent, renderedCell), renderedCells.push(renderedCell)); } return renderedCells; } function warnAboutMissingStyle(parent, renderedCell) { renderedCell && (renderedCell.type && renderedCell.type.__internalCellMeasurerFlag && (renderedCell = renderedCell.props.children), renderedCell && renderedCell.props && void 0 === renderedCell.props.style && !0 !== parent.__warnedAboutMissingStyle && (parent.__warnedAboutMissingStyle = !0, console.warn("Rendered cell should include style property for positioning."))); } var request = (win = "undefined" != typeof window ? window : "undefined" != typeof self ? self : {}).requestAnimationFrame || win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame || win.oRequestAnimationFrame || win.msRequestAnimationFrame || function(callback) { return win.setTimeout(callback, 1e3 / 60); }, cancel = win.cancelAnimationFrame || win.webkitCancelAnimationFrame || win.mozCancelAnimationFrame || win.oCancelAnimationFrame || win.msCancelAnimationFrame || function(id) { win.clearTimeout(id); }, raf = request, caf = cancel, cancelAnimationTimeout = function(frame) { return caf(frame.id); }, requestAnimationTimeout = function(callback, delay) { var start; Promise.resolve().then(function() { start = Date.now(); }); var frame = { id: raf(function timeout() { Date.now() - start >= delay ? callback.call() : frame.id = raf(timeout); }) }; return frame; }, SCROLL_POSITION_CHANGE_REASONS$1_OBSERVED = "observed", SCROLL_POSITION_CHANGE_REASONS$1_REQUESTED = "requested", Grid = function() { function Grid(props) { var _this; _classCallCheck(this, Grid), _defineProperty(_assertThisInitialized(_this = _possibleConstructorReturn(this, _getPrototypeOf(Grid).call(this, props))), "_onGridRenderedMemoizer", createCallbackMemoizer()), _defineProperty(_assertThisInitialized(_this), "_onScrollMemoizer", createCallbackMemoizer(!1)), _defineProperty(_assertThisInitialized(_this), "_deferredInvalidateColumnIndex", null), _defineProperty(_assertThisInitialized(_this), "_deferredInvalidateRowIndex", null), _defineProperty(_assertThisInitialized(_this), "_recomputeScrollLeftFlag", !1), _defineProperty(_assertThisInitialized(_this), "_recomputeScrollTopFlag", !1), _defineProperty(_assertThisInitialized(_this), "_horizontalScrollBarSize", 0), _defineProperty(_assertThisInitialized(_this), "_verticalScrollBarSize", 0), _defineProperty(_assertThisInitialized(_this), "_scrollbarPresenceChanged", !1), _defineProperty(_assertThisInitialized(_this), "_scrollingContainer", void 0), _defineProperty(_assertThisInitialized(_this), "_childrenToDisplay", void 0), _defineProperty(_assertThisInitialized(_this), "_columnStartIndex", void 0), _defineProperty(_assertThisInitialized(_this), "_columnStopIndex", void 0), _defineProperty(_assertThisInitialized(_this), "_rowStartIndex", void 0), _defineProperty(_assertThisInitialized(_this), "_rowStopIndex", void 0), _defineProperty(_assertThisInitialized(_this), "_renderedColumnStartIndex", 0), _defineProperty(_assertThisInitialized(_this), "_renderedColumnStopIndex", 0), _defineProperty(_assertThisInitialized(_this), "_renderedRowStartIndex", 0), _defineProperty(_assertThisInitialized(_this), "_renderedRowStopIndex", 0), _defineProperty(_assertThisInitialized(_this), "_initialScrollTop", void 0), _defineProperty(_assertThisInitialized(_this), "_initialScrollLeft", void 0), _defineProperty(_assertThisInitialized(_this), "_disablePointerEventsTimeoutId", void 0), _defineProperty(_assertThisInitialized(_this), "_styleCache", {}), _defineProperty(_assertThisInitialized(_this), "_cellCache", {}), _defineProperty(_assertThisInitialized(_this), "_debounceScrollEndedCallback", function() { _this._disablePointerEventsTimeoutId = null, _this.setState({ isScrolling: !1, needToResetStyleCache: !1 }); }), _defineProperty(_assertThisInitialized(_this), "_invokeOnGridRenderedHelper", function() { var onSectionRendered = _this.props.onSectionRendered; _this._onGridRenderedMemoizer({ callback: onSectionRendered, indices: { columnOverscanStartIndex: _this._columnStartIndex, columnOverscanStopIndex: _this._columnStopIndex, columnStartIndex: _this._renderedColumnStartIndex, columnStopIndex: _this._renderedColumnStopIndex, rowOverscanStartIndex: _this._rowStartIndex, rowOverscanStopIndex: _this._rowStopIndex, rowStartIndex: _this._renderedRowStartIndex, rowStopIndex: _this._renderedRowStopIndex } }); }), _defineProperty(_assertThisInitialized(_this), "_setScrollingContainerRef", function(ref) { _this._scrollingContainer = ref; }), _defineProperty(_assertThisInitialized(_this), "_onScroll", function(event) { event.target === _this._scrollingContainer && _this.handleScrollEvent(event.target); }); var columnSizeAndPositionManager = new ScalingCellSizeAndPositionManager({ cellCount: props.columnCount, cellSizeGetter: function(params) { return Grid._wrapSizeGetter(props.columnWidth)(params); }, estimatedCellSize: Grid._getEstimatedColumnSize(props) }), rowSizeAndPositionManager = new ScalingCellSizeAndPositionManager({ cellCount: props.rowCount, cellSizeGetter: function(params) { return Grid._wrapSizeGetter(props.rowHeight)(params); }, estimatedCellSize: Grid._getEstimatedRowSize(props) }); return _this.state = { instanceProps: { columnSizeAndPositionManager: columnSizeAndPositionManager, rowSizeAndPositionManager: rowSizeAndPositionManager, prevColumnWidth: props.columnWidth, prevRowHeight: props.rowHeight, prevColumnCount: props.columnCount, prevRowCount: props.rowCount, prevIsScrolling: !0 === props.isScrolling, prevScrollToColumn: props.scrollToColumn, prevScrollToRow: props.scrollToRow, scrollbarSize: 0, scrollbarSizeMeasured: !1 }, isScrolling: !1, scrollDirectionHorizontal: 1, scrollDirectionVertical: 1, scrollLeft: 0, scrollTop: 0, scrollPositionChangeReason: null, needToResetStyleCache: !1 }, 0 < props.scrollToRow && (_this._initialScrollTop = _this._getCalculatedScrollTop(props, _this.state)), 0 < props.scrollToColumn && (_this._initialScrollLeft = _this._getCalculatedScrollLeft(props, _this.state)), _this; } return _inherits(Grid, React.PureComponent), _createClass(Grid, [ { key: "getOffsetForCell", value: function(argument_0) { var _ref = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : {}, _ref$alignment = _ref.alignment, alignment = void 0 === _ref$alignment ? this.props.scrollToAlignment : _ref$alignment, _ref$columnIndex = _ref.columnIndex, columnIndex = void 0 === _ref$columnIndex ? this.props.scrollToColumn : _ref$columnIndex, _ref$rowIndex = _ref.rowIndex, rowIndex = void 0 === _ref$rowIndex ? this.props.scrollToRow : _ref$rowIndex, offsetProps = _objectSpread2({}, this.props, { scrollToAlignment: alignment, scrollToColumn: columnIndex, scrollToRow: rowIndex }); return { scrollLeft: this._getCalculatedScrollLeft(offsetProps), scrollTop: this._getCalculatedScrollTop(offsetProps) }; } }, { key: "getTotalRowsHeight", value: function() { return this.state.instanceProps.rowSizeAndPositionManager.getTotalSize(); } }, { key: "getTotalColumnsWidth", value: function() { return this.state.instanceProps.columnSizeAndPositionManager.getTotalSize(); } }, { key: "handleScrollEvent", value: function(_ref2) { var _ref2$scrollLeft = _ref2.scrollLeft, scrollLeftParam = void 0 === _ref2$scrollLeft ? 0 : _ref2$scrollLeft, _ref2$scrollTop = _ref2.scrollTop, scrollTopParam = void 0 === _ref2$scrollTop ? 0 : _ref2$scrollTop; if (!(scrollTopParam < 0)) { this._debounceScrollEnded(); var _this$props = this.props, autoHeight = _this$props.autoHeight, autoWidth = _this$props.autoWidth, height = _this$props.height, width = _this$props.width, instanceProps = this.state.instanceProps, scrollbarSize = instanceProps.scrollbarSize, totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(), totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(), scrollLeft = Math.min(Math.max(0, totalColumnsWidth - width + scrollbarSize), scrollLeftParam), scrollTop = Math.min(Math.max(0, totalRowsHeight - height + scrollbarSize), scrollTopParam); if (this.state.scrollLeft !== scrollLeft || this.state.scrollTop !== scrollTop) { var newState = { isScrolling: !0, scrollDirectionHorizontal: scrollLeft !== this.state.scrollLeft ? scrollLeft > this.state.scrollLeft ? 1 : -1 : this.state.scrollDirectionHorizontal, scrollDirectionVertical: scrollTop !== this.state.scrollTop ? scrollTop > this.state.scrollTop ? 1 : -1 : this.state.scrollDirectionVertical, scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS$1_OBSERVED }; autoHeight || (newState.scrollTop = scrollTop), autoWidth || (newState.scrollLeft = scrollLeft), newState.needToResetStyleCache = !1, this.setState(newState); } this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft, scrollTop: scrollTop, totalColumnsWidth: totalColumnsWidth, totalRowsHeight: totalRowsHeight }); } } }, { key: "invalidateCellSizeAfterRender", value: function(_ref3) { var columnIndex = _ref3.columnIndex, rowIndex = _ref3.rowIndex; this._deferredInvalidateColumnIndex = "number" == typeof this._deferredInvalidateColumnIndex ? Math.min(this._deferredInvalidateColumnIndex, columnIndex) : columnIndex, this._deferredInvalidateRowIndex = "number" == typeof this._deferredInvalidateRowIndex ? Math.min(this._deferredInvalidateRowIndex, rowIndex) : rowIndex; } }, { key: "measureAllCells", value: function() { var _this$props2 = this.props, columnCount = _this$props2.columnCount, rowCount = _this$props2.rowCount, instanceProps = this.state.instanceProps; instanceProps.columnSizeAndPositionManager.getSizeAndPositionOfCell(columnCount - 1), instanceProps.rowSizeAndPositionManager.getSizeAndPositionOfCell(rowCount - 1); } }, { key: "recomputeGridSize", value: function(argument_0) { var _ref4 = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : {}, _ref4$columnIndex = _ref4.columnIndex, columnIndex = void 0 === _ref4$columnIndex ? 0 : _ref4$columnIndex, _ref4$rowIndex = _ref4.rowIndex, rowIndex = void 0 === _ref4$rowIndex ? 0 : _ref4$rowIndex, _this$props3 = this.props, scrollToColumn = _this$props3.scrollToColumn, scrollToRow = _this$props3.scrollToRow, instanceProps = this.state.instanceProps; instanceProps.columnSizeAndPositionManager.resetCell(columnIndex), instanceProps.rowSizeAndPositionManager.resetCell(rowIndex), this._recomputeScrollLeftFlag = 0 <= scrollToColumn && (1 === this.state.scrollDirectionHorizontal ? columnIndex <= scrollToColumn : scrollToColumn <= columnIndex), this._recomputeScrollTopFlag = 0 <= scrollToRow && (1 === this.state.scrollDirectionVertical ? rowIndex <= scrollToRow : scrollToRow <= rowIndex), this._styleCache = {}, this._cellCache = {}, this.forceUpdate(); } }, { key: "scrollToCell", value: function(_ref5) { var columnIndex = _ref5.columnIndex, rowIndex = _ref5.rowIndex, columnCount = this.props.columnCount, props = this.props; 1 < columnCount && void 0 !== columnIndex && this._updateScrollLeftForScrollToColumn(_objectSpread2({}, props, { scrollToColumn: columnIndex })), void 0 !== rowIndex && this._updateScrollTopForScrollToRow(_objectSpread2({}, props, { scrollToRow: rowIndex })); } }, { key: "componentDidMount", value: function() { var _this$props4 = this.props, getScrollbarSize = _this$props4.getScrollbarSize, height = _this$props4.height, scrollLeft = _this$props4.scrollLeft, scrollToColumn = _this$props4.scrollToColumn, scrollTop = _this$props4.scrollTop, scrollToRow = _this$props4.scrollToRow, width = _this$props4.width, instanceProps = this.state.instanceProps; if (this._initialScrollTop = 0, this._initialScrollLeft = 0, this._handleInvalidatedGridSize(), instanceProps.scrollbarSizeMeasured || this.setState(function(prevState) { var stateUpdate = _objectSpread2({}, prevState, { needToResetStyleCache: !1 }); return stateUpdate.instanceProps.scrollbarSize = getScrollbarSize(), stateUpdate.instanceProps.scrollbarSizeMeasured = !0, stateUpdate; }), "number" == typeof scrollLeft && 0 <= scrollLeft || "number" == typeof scrollTop && 0 <= scrollTop) { var stateUpdate = Grid._getScrollToPositionStateUpdate({ prevState: this.state, scrollLeft: scrollLeft, scrollTop: scrollTop }); stateUpdate && (stateUpdate.needToResetStyleCache = !1, this.setState(stateUpdate)); } this._scrollingContainer && (this._scrollingContainer.scrollLeft !== this.state.scrollLeft && (this._scrollingContainer.scrollLeft = this.state.scrollLeft), this._scrollingContainer.scrollTop !== this.state.scrollTop && (this._scrollingContainer.scrollTop = this.state.scrollTop)); var sizeIsBiggerThanZero = 0 < height && 0 < width; 0 <= scrollToColumn && sizeIsBiggerThanZero && this._updateScrollLeftForScrollToColumn(), 0 <= scrollToRow && sizeIsBiggerThanZero && this._updateScrollTopForScrollToRow(), this._invokeOnGridRenderedHelper(), this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft || 0, scrollTop: scrollTop || 0, totalColumnsWidth: instanceProps.columnSizeAndPositionManager.getTotalSize(), totalRowsHeight: instanceProps.rowSizeAndPositionManager.getTotalSize() }), this._maybeCallOnScrollbarPresenceChange(); } }, { key: "componentDidUpdate", value: function(prevProps, prevState) { var _this2 = this, _this$props5 = this.props, autoHeight = _this$props5.autoHeight, autoWidth = _this$props5.autoWidth, columnCount = _this$props5.columnCount, height = _this$props5.height, rowCount = _this$props5.rowCount, scrollToAlignment = _this$props5.scrollToAlignment, scrollToColumn = _this$props5.scrollToColumn, scrollToRow = _this$props5.scrollToRow, width = _this$props5.width, _this$state = this.state, scrollLeft = _this$state.scrollLeft, scrollPositionChangeReason = _this$state.scrollPositionChangeReason, scrollTop = _this$state.scrollTop, instanceProps = _this$state.instanceProps; this._handleInvalidatedGridSize(); var columnOrRowCountJustIncreasedFromZero = 0 < columnCount && 0 === prevProps.columnCount || 0 < rowCount && 0 === prevProps.rowCount; scrollPositionChangeReason === SCROLL_POSITION_CHANGE_REASONS$1_REQUESTED && (!autoWidth && 0 <= scrollLeft && (scrollLeft !== this._scrollingContainer.scrollLeft || columnOrRowCountJustIncreasedFromZero) && (this._scrollingContainer.scrollLeft = scrollLeft), !autoHeight && 0 <= scrollTop && (scrollTop !== this._scrollingContainer.scrollTop || columnOrRowCountJustIncreasedFromZero) && (this._scrollingContainer.scrollTop = scrollTop)); var sizeJustIncreasedFromZero = (0 === prevProps.width || 0 === prevProps.height) && 0 < height && 0 < width; if (this._recomputeScrollLeftFlag ? (this._recomputeScrollLeftFlag = !1, this._updateScrollLeftForScrollToColumn(this.props)) : updateScrollIndexHelper({ cellSizeAndPositionManager: instanceProps.columnSizeAndPositionManager, previousCellsCount: prevProps.columnCount, previousCellSize: prevProps.columnWidth, previousScrollToAlignment: prevProps.scrollToAlignment, previousScrollToIndex: prevProps.scrollToColumn, previousSize: prevProps.width, scrollOffset: scrollLeft, scrollToAlignment: scrollToAlignment, scrollToIndex: scrollToColumn, size: width, sizeJustIncreasedFromZero: sizeJustIncreasedFromZero, updateScrollIndexCallback: function() { return _this2._updateScrollLeftForScrollToColumn(_this2.props); } }), this._recomputeScrollTopFlag ? (this._recomputeScrollTopFlag = !1, this._updateScrollTopForScrollToRow(this.props)) : updateScrollIndexHelper({ cellSizeAndPositionManager: instanceProps.rowSizeAndPositionManager, previousCellsCount: prevProps.rowCount, previousCellSize: prevProps.rowHeight, previousScrollToAlignment: prevProps.scrollToAlignment, previousScrollToIndex: prevProps.scrollToRow, previousSize: prevProps.height, scrollOffset: scrollTop, scrollToAlignment: scrollToAlignment, scrollToIndex: scrollToRow, size: height, sizeJustIncreasedFromZero: sizeJustIncreasedFromZero, updateScrollIndexCallback: function() { return _this2._updateScrollTopForScrollToRow(_this2.props); } }), this._invokeOnGridRenderedHelper(), scrollLeft !== prevState.scrollLeft || scrollTop !== prevState.scrollTop) { var totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(), totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(); this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft, scrollTop: scrollTop, totalColumnsWidth: totalColumnsWidth, totalRowsHeight: totalRowsHeight }); } this._maybeCallOnScrollbarPresenceChange(); } }, { key: "componentWillUnmount", value: function() { this._disablePointerEventsTimeoutId && cancelAnimationTimeout(this._disablePointerEventsTimeoutId); } }, { key: "render", value: function() { var _this$props6 = this.props, autoContainerWidth = _this$props6.autoContainerWidth, autoHeight = _this$props6.autoHeight, autoWidth = _this$props6.autoWidth, className = _this$props6.className, containerProps = _this$props6.containerProps, containerRole = _this$props6.containerRole, containerStyle = _this$props6.containerStyle, height = _this$props6.height, id = _this$props6.id, noContentRenderer = _this$props6.noContentRenderer, role = _this$props6.role, style = _this$props6.style, tabIndex = _this$props6.tabIndex, width = _this$props6.width, _this$state2 = this.state, instanceProps = _this$state2.instanceProps, needToResetStyleCache = _this$state2.needToResetStyleCache, isScrolling = this._isScrolling(), gridStyle = { boxSizing: "border-box", direction: "ltr", height: autoHeight ? "auto" : height, position: "relative", width: autoWidth ? "auto" : width, WebkitOverflowScrolling: "touch", willChange: "transform" }; needToResetStyleCache && (this._styleCache = {}), this.state.isScrolling || this._resetStyleCache(), this._calculateChildrenToRender(this.props, this.state); var totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(), totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(), verticalScrollBarSize = height < totalRowsHeight ? instanceProps.scrollbarSize : 0, horizontalScrollBarSize = width < totalColumnsWidth ? instanceProps.scrollbarSize : 0; horizontalScrollBarSize === this._horizontalScrollBarSize && verticalScrollBarSize === this._verticalScrollBarSize || (this._horizontalScrollBarSize = horizontalScrollBarSize, this._verticalScrollBarSize = verticalScrollBarSize, this._scrollbarPresenceChanged = !0), gridStyle.overflowX = totalColumnsWidth + verticalScrollBarSize <= width ? "hidden" : "auto", gridStyle.overflowY = totalRowsHeight + horizontalScrollBarSize <= height ? "hidden" : "auto"; var childrenToDisplay = this._childrenToDisplay, showNoContentRenderer = 0 === childrenToDisplay.length && 0 < height && 0 < width; return React.createElement("div", _extends({ ref: this._setScrollingContainerRef }, containerProps, { "aria-label": this.props["aria-label"], "aria-readonly": this.props["aria-readonly"], className: clsx("ReactVirtualized__Grid", className), id: id, onScroll: this._onScroll, role: role, style: _objectSpread2({}, gridStyle, {}, style), tabIndex: tabIndex }), 0 < childrenToDisplay.length && React.createElement("div", { className: "ReactVirtualized__Grid__innerScrollContainer", role: containerRole, style: _objectSpread2({ width: autoContainerWidth ? "auto" : totalColumnsWidth, height: totalRowsHeight, maxWidth: totalColumnsWidth, maxHeight: totalRowsHeight, overflow: "hidden", pointerEvents: isScrolling ? "none" : "", position: "relative" }, containerStyle) }, childrenToDisplay), showNoContentRenderer && noContentRenderer()); } }, { key: "_calculateChildrenToRender", value: function(argument_0, argument_1) { var props = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : this.props, state = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : this.state, cellRenderer = props.cellRenderer, cellRangeRenderer = props.cellRangeRenderer, columnCount = props.columnCount, deferredMeasurementCache = props.deferredMeasurementCache, height = props.height, overscanColumnCount = props.overscanColumnCount, overscanIndicesGetter = props.overscanIndicesGetter, overscanRowCount = props.overscanRowCount, rowCount = props.rowCount, width = props.width, isScrollingOptOut = props.isScrollingOptOut, scrollDirectionHorizontal = state.scrollDirectionHorizontal, scrollDirectionVertical = state.scrollDirectionVertical, instanceProps = state.instanceProps, scrollTop = 0 < this._initialScrollTop ? this._initialScrollTop : state.scrollTop, scrollLeft = 0 < this._initialScrollLeft ? this._initialScrollLeft : state.scrollLeft, isScrolling = this._isScrolling(props, state); if (this._childrenToDisplay = [], 0 < height && 0 < width) { var visibleColumnIndices = instanceProps.columnSizeAndPositionManager.getVisibleCellRange({ containerSize: width, offset: scrollLeft }), visibleRowIndices = instanceProps.rowSizeAndPositionManager.getVisibleCellRange({ containerSize: height, offset: scrollTop }), horizontalOffsetAdjustment = instanceProps.columnSizeAndPositionManager.getOffsetAdjustment({ containerSize: width, offset: scrollLeft }), verticalOffsetAdjustment = instanceProps.rowSizeAndPositionManager.getOffsetAdjustment({ containerSize: height, offset: scrollTop }); this._renderedColumnStartIndex = visibleColumnIndices.start, this._renderedColumnStopIndex = visibleColumnIndices.stop, this._renderedRowStartIndex = visibleRowIndices.start, this._renderedRowStopIndex = visibleRowIndices.stop; var overscanColumnIndices = overscanIndicesGetter({ direction: "horizontal", cellCount: columnCount, overscanCellsCount: overscanColumnCount, scrollDirection: scrollDirectionHorizontal, startIndex: "number" == typeof visibleColumnIndices.start ? visibleColumnIndices.start : 0, stopIndex: "number" == typeof visibleColumnIndices.stop ? visibleColumnIndices.stop : -1 }), overscanRowIndices = overscanIndicesGetter({ direction: "vertical", cellCount: rowCount, overscanCellsCount: overscanRowCount, scrollDirection: scrollDirectionVertical, startIndex: "number" == typeof visibleRowIndices.start ? visibleRowIndices.start : 0, stopIndex: "number" == typeof visibleRowIndices.stop ? visibleRowIndices.stop : -1 }), columnStartIndex = overscanColumnIndices.overscanStartIndex, columnStopIndex = overscanColumnIndices.overscanStopIndex, rowStartIndex = overscanRowIndices.overscanStartIndex, rowStopIndex = overscanRowIndices.overscanStopIndex; if (deferredMeasurementCache) { if (!deferredMeasurementCache.hasFixedHeight()) for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) if (!deferredMeasurementCache.has(rowIndex, 0)) { columnStartIndex = 0, columnStopIndex = columnCount - 1; break; } if (!deferredMeasurementCache.hasFixedWidth()) for (var columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) if (!deferredMeasurementCache.has(0, columnIndex)) { rowStartIndex = 0, rowStopIndex = rowCount - 1; break; } } this._childrenToDisplay = cellRangeRenderer({ cellCache: this._cellCache, cellRenderer: cellRenderer, columnSizeAndPositionManager: instanceProps.columnSizeAndPositionManager, columnStartIndex: columnStartIndex, columnStopIndex: columnStopIndex, deferredMeasurementCache: deferredMeasurementCache, horizontalOffsetAdjustment: horizontalOffsetAdjustment, isScrolling: isScrolling, isScrollingOptOut: isScrollingOptOut, parent: this, rowSizeAndPositionManager: instanceProps.rowSizeAndPositionManager, rowStartIndex: rowStartIndex, rowStopIndex: rowStopIndex, scrollLeft: scrollLeft, scrollTop: scrollTop, styleCache: this._styleCache, verticalOffsetAdjustment: verticalOffsetAdjustment, visibleColumnIndices: visibleColumnIndices, visibleRowIndices: visibleRowIndices }), this._columnStartIndex = columnStartIndex, this._columnStopIndex = columnStopIndex, this._rowStartIndex = rowStartIndex, this._rowStopIndex = rowStopIndex; } } }, { key: "_debounceScrollEnded", value: function() { var scrollingResetTimeInterval = this.props.scrollingResetTimeInterval; this._disablePointerEventsTimeoutId && cancelAnimationTimeout(this._disablePointerEventsTimeoutId), this._disablePointerEventsTimeoutId = requestAnimationTimeout(this._debounceScrollEndedCallback, scrollingResetTimeInterval); } }, { key: "_handleInvalidatedGridSize", value: function() { if ("number" == typeof this._deferredInvalidateColumnIndex && "number" == typeof this._deferredInvalidateRowIndex) { var columnIndex = this._deferredInvalidateColumnIndex, rowIndex = this._deferredInvalidateRowIndex; this._deferredInvalidateColumnIndex = null, this._deferredInvalidateRowIndex = null, this.recomputeGridSize({ columnIndex: columnIndex, rowIndex: rowIndex }); } } }, { key: "_invokeOnScrollMemoizer", value: function(_ref6) { var _this3 = this, scrollLeft = _ref6.scrollLeft, scrollTop = _ref6.scrollTop, totalColumnsWidth = _ref6.totalColumnsWidth, totalRowsHeight = _ref6.totalRowsHeight; this._onScrollMemoizer({ callback: function(_ref7) { var scrollLeft = _ref7.scrollLeft, scrollTop = _ref7.scrollTop, _this3$props = _this3.props, height = _this3$props.height; (0, _this3$props.onScroll)({ clientHeight: height, clientWidth: _this3$props.width, scrollHeight: totalRowsHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: totalColumnsWidth }); }, indices: { scrollLeft: scrollLeft, scrollTop: scrollTop } }); } }, { key: "_isScrolling", value: function(argument_0, argument_1) { var props = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : this.props, state = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : this.state; return Object.hasOwnProperty.call(props, "isScrolling") ? Boolean(props.isScrolling) : Boolean(state.isScrolling); } }, { key: "_maybeCallOnScrollbarPresenceChange", value: function() { if (this._scrollbarPresenceChanged) { var onScrollbarPresenceChange = this.props.onScrollbarPresenceChange; this._scrollbarPresenceChanged = !1, onScrollbarPresenceChange({ horizontal: 0 < this._horizontalScrollBarSize, size: this.state.instanceProps.scrollbarSize, vertical: 0 < this._verticalScrollBarSize }); } } }, { key: "scrollToPosition", value: function(_ref8) { var scrollLeft = _ref8.scrollLeft, scrollTop = _ref8.scrollTop, stateUpdate = Grid._getScrollToPositionStateUpdate({ prevState: this.state, scrollLeft: scrollLeft, scrollTop: scrollTop }); stateUpdate && (stateUpdate.needToResetStyleCache = !1, this.setState(stateUpdate)); } }, { key: "_getCalculatedScrollLeft", value: function(argument_0, argument_1) { var props = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : this.props, state = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : this.state; return Grid._getCalculatedScrollLeft(props, state); } }, { key: "_updateScrollLeftForScrollToColumn", value: function(argument_0, argument_1) { var props = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : this.props, state = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : this.state, stateUpdate = Grid._getScrollLeftForScrollToColumnStateUpdate(props, state); stateUpdate && (stateUpdate.needToResetStyleCache = !1, this.setState(stateUpdate)); } }, { key: "_getCalculatedScrollTop", value: function(argument_0, argument_1) { var props = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : this.props, state = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : this.state; return Grid._getCalculatedScrollTop(props, state); } }, { key: "_resetStyleCache", value: function() { var styleCache = this._styleCache, cellCache = this._cellCache, isScrollingOptOut = this.props.isScrollingOptOut; this._cellCache = {}, this._styleCache = {}; for (var rowIndex = this._rowStartIndex; rowIndex <= this._rowStopIndex; rowIndex++) for (var columnIndex = this._columnStartIndex; columnIndex <= this._columnStopIndex; columnIndex++) { var key = "".concat(rowIndex, "-").concat(columnIndex); this._styleCache[key] = styleCache[key], isScrollingOptOut && (this._cellCache[key] = cellCache[key]); } } }, { key: "_updateScrollTopForScrollToRow", value: function(argument_0, argument_1) { var props = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : this.props, state = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : this.state, stateUpdate = Grid._getScrollTopForScrollToRowStateUpdate(props, state); stateUpdate && (stateUpdate.needToResetStyleCache = !1, this.setState(stateUpdate)); } } ], [ { key: "getDerivedStateFromProps", value: function(nextProps, prevState) { var newState = {}; 0 === nextProps.columnCount && 0 !== prevState.scrollLeft || 0 === nextProps.rowCount && 0 !== prevState.scrollTop ? (newState.scrollLeft = 0, newState.scrollTop = 0) : (nextProps.scrollLeft !== prevState.scrollLeft && nextProps.scrollToColumn < 0 || nextProps.scrollTop !== prevState.scrollTop && nextProps.scrollToRow < 0) && Object.assign(newState, Grid._getScrollToPositionStateUpdate({ prevState: prevState, scrollLeft: nextProps.scrollLeft, scrollTop: nextProps.scrollTop })); var maybeStateA, maybeStateB, instanceProps = prevState.instanceProps; return newState.needToResetStyleCache = !1, nextProps.columnWidth === instanceProps.prevColumnWidth && nextProps.rowHeight === instanceProps.prevRowHeight || (newState.needToResetStyleCache = !0), instanceProps.columnSizeAndPositionManager.configure({ cellCount: nextProps.columnCount, estimatedCellSize: Grid._getEstimatedColumnSize(nextProps), cellSizeGetter: Grid._wrapSizeGetter(nextProps.columnWidth) }), instanceProps.rowSizeAndPositionManager.configure({ cellCount: nextProps.rowCount, estimatedCellSize: Grid._getEstimatedRowSize(nextProps), cellSizeGetter: Grid._wrapSizeGetter(nextProps.rowHeight) }), 0 !== instanceProps.prevColumnCount && 0 !== instanceProps.prevRowCount || (instanceProps.prevColumnCount = 0, instanceProps.prevRowCount = 0), nextProps.autoHeight && !1 === nextProps.isScrolling && !0 === instanceProps.prevIsScrolling && Object.assign(newState, { isScrolling: !1 }), calculateSizeAndPositionDataAndUpdateScrollOffset({ cellCount: instanceProps.prevColumnCount, cellSize: "number" == typeof instanceProps.prevColumnWidth ? instanceProps.prevColumnWidth : null, computeMetadataCallback: function() { return instanceProps.columnSizeAndPositionManager.resetCell(0); }, computeMetadataCallbackProps: nextProps, nextCellsCount: nextProps.columnCount, nextCellSize: "number" == typeof nextProps.columnWidth ? nextProps.columnWidth : null, nextScrollToIndex: nextProps.scrollToColumn, scrollToIndex: instanceProps.prevScrollToColumn, updateScrollOffsetForScrollToIndex: function() { maybeStateA = Grid._getScrollLeftForScrollToColumnStateUpdate(nextProps, prevState); } }), calculateSizeAndPositionDataAndUpdateScrollOffset({ cellCount: instanceProps.prevRowCount, cellSize: "number" == typeof instanceProps.prevRowHeight ? instanceProps.prevRowHeight : null, computeMetadataCallback: function() { return instanceProps.rowSizeAndPositionManager.resetCell(0); }, computeMetadataCallbackProps: nextProps, nextCellsCount: nextProps.rowCount, nextCellSize: "number" == typeof nextProps.rowHeight ? nextProps.rowHeight : null, nextScrollToIndex: nextProps.scrollToRow, scrollToIndex: instanceProps.prevScrollToRow, updateScrollOffsetForScrollToIndex: function() { maybeStateB = Grid._getScrollTopForScrollToRowStateUpdate(nextProps, prevState); } }), instanceProps.prevColumnCount = nextProps.columnCount, instanceProps.prevColumnWidth = nextProps.columnWidth, instanceProps.prevIsScrolling = !0 === nextProps.isScrolling, instanceProps.prevRowCount = nextProps.rowCount, instanceProps.prevRowHeight = nextProps.rowHeight, instanceProps.prevScrollToColumn = nextProps.scrollToColumn, instanceProps.prevScrollToRow = nextProps.scrollToRow, instanceProps.scrollbarSize = nextProps.getScrollbarSize(), void 0 === instanceProps.scrollbarSize ? (instanceProps.scrollbarSizeMeasured = !1, instanceProps.scrollbarSize = 0) : instanceProps.scrollbarSizeMeasured = !0, newState.instanceProps = instanceProps, _objectSpread2({}, newState, {}, maybeStateA, {}, maybeStateB); } }, { key: "_getEstimatedColumnSize", value: function(props) { return "number" == typeof props.columnWidth ? props.columnWidth : props.estimatedColumnSize; } }, { key: "_getEstimatedRowSize", value: function(props) { return "number" == typeof props.rowHeight ? props.rowHeight : props.estimatedRowSize; } }, { key: "_getScrollToPositionStateUpdate", value: function(_ref9) { var prevState = _ref9.prevState, scrollLeft = _ref9.scrollLeft, scrollTop = _ref9.scrollTop, newState = { scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS$1_REQUESTED }; return "number" == typeof scrollLeft && 0 <= scrollLeft && (newState.scrollDirectionHorizontal = scrollLeft > prevState.scrollLeft ? 1 : -1, newState.scrollLeft = scrollLeft), "number" == typeof scrollTop && 0 <= scrollTop && (newState.scrollDirectionVertical = scrollTop > prevState.scrollTop ? 1 : -1, newState.scrollTop = scrollTop), "number" == typeof scrollLeft && 0 <= scrollLeft && scrollLeft !== prevState.scrollLeft || "number" == typeof scrollTop && 0 <= scrollTop && scrollTop !== prevState.scrollTop ? newState : {}; } }, { key: "_wrapSizeGetter", value: function(value) { return "function" == typeof value ? value : function() { return value; }; } }, { key: "_getCalculatedScrollLeft", value: function(nextProps, prevState) { var columnCount = nextProps.columnCount, height = nextProps.height, scrollToAlignment = nextProps.scrollToAlignment, scrollToColumn = nextProps.scrollToColumn, width = nextProps.width, scrollLeft = prevState.scrollLeft, instanceProps = prevState.instanceProps; if (0 < columnCount) { var finalColumn = columnCount - 1, targetIndex = scrollToColumn < 0 ? finalColumn : Math.min(finalColumn, scrollToColumn), totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(), scrollBarSize = instanceProps.scrollbarSizeMeasured && height < totalRowsHeight ? instanceProps.scrollbarSize : 0; return instanceProps.columnSizeAndPositionManager.getUpdatedOffsetForIndex({ align: scrollToAlignment, containerSize: width - scrollBarSize, currentOffset: scrollLeft, targetIndex: targetIndex }); } return 0; } }, { key: "_getScrollLeftForScrollToColumnStateUpdate", value: function(nextProps, prevState) { var scrollLeft = prevState.scrollLeft, calculatedScrollLeft = Grid._getCalculatedScrollLeft(nextProps, prevState); return "number" == typeof calculatedScrollLeft && 0 <= calculatedScrollLeft && scrollLeft !== calculatedScrollLeft ? Grid._getScrollToPositionStateUpdate({ prevState: prevState, scrollLeft: calculatedScrollLeft, scrollTop: -1 }) : {}; } }, { key: "_getCalculatedScrollTop", value: function(nextProps, prevState) { var height = nextProps.height, rowCount = nextProps.rowCount, scrollToAlignment = nextProps.scrollToAlignment, scrollToRow = nextProps.scrollToRow, width = nextProps.width, scrollTop = prevState.scrollTop, instanceProps = prevState.instanceProps; if (0 < rowCount) { var finalRow = rowCount - 1, targetIndex = scrollToRow < 0 ? finalRow : Math.min(finalRow, scrollToRow), totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(), scrollBarSize = instanceProps.scrollbarSizeMeasured && width < totalColumnsWidth ? instanceProps.scrollbarSize : 0; return instanceProps.rowSizeAndPositionManager.getUpdatedOffsetForIndex({ align: scrollToAlignment, containerSize: height - scrollBarSize, currentOffset: scrollTop, targetIndex: targetIndex }); } return 0; } }, { key: "_getScrollTopForScrollToRowStateUpdate", value: function(nextProps, prevState) { var scrollTop = prevState.scrollTop, calculatedScrollTop = Grid._getCalculatedScrollTop(nextProps, prevState); return "number" == typeof calculatedScrollTop && 0 <= calculatedScrollTop && scrollTop !== calculatedScrollTop ? Grid._getScrollToPositionStateUpdate({ prevState: prevState, scrollLeft: -1, scrollTop: calculatedScrollTop }) : {}; } } ]), Grid; }(); _defineProperty(Grid, "defaultProps", { "aria-label": "grid", "aria-readonly": !0, autoContainerWidth: !1, autoHeight: !1, autoWidth: !1, cellRangeRenderer: defaultCellRangeRenderer, containerRole: "rowgroup", containerStyle: {}, estimatedColumnSize: 100, estimatedRowSize: 30, getScrollbarSize: scrollbarSize, noContentRenderer: function() { return null; }, onScroll: function() {}, onScrollbarPresenceChange: function() {}, onSectionRendered: function() {}, overscanColumnCount: 0, overscanIndicesGetter: defaultOverscanIndicesGetter, overscanRowCount: 10, role: "grid", scrollingResetTimeInterval: 150, scrollToAlignment: "auto", scrollToColumn: -1, scrollToRow: -1, style: {}, tabIndex: 0, isScrollingOptOut: !1 }), polyfill(Grid); function defaultOverscanIndicesGetter$1(_ref) { var cellCount = _ref.cellCount, overscanCellsCount = _ref.overscanCellsCount, scrollDirection = _ref.scrollDirection, startIndex = _ref.startIndex, stopIndex = _ref.stopIndex; return overscanCellsCount = Math.max(1, overscanCellsCount), 1 === scrollDirection ? { overscanStartIndex: Math.max(0, startIndex - 1), overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount) } : { overscanStartIndex: Math.max(0, startIndex - overscanCellsCount), overscanStopIndex: Math.min(cellCount - 1, stopIndex + 1) }; } var InfiniteLoader = function() { function InfiniteLoader(props, context) { var _this; return _classCallCheck(this, InfiniteLoader), (_this = _possibleConstructorReturn(this, _getPrototypeOf(InfiniteLoader).call(this, props, context)))._loadMoreRowsMemoizer = createCallbackMemoizer(), _this._onRowsRendered = _this._onRowsRendered.bind(_assertThisInitialized(_this)), _this._registerChild = _this._registerChild.bind(_assertThisInitialized(_this)), _this; } return _inherits(InfiniteLoader, React.PureComponent), _createClass(InfiniteLoader, [ { key: "resetLoadMoreRowsCache", value: function(autoReload) { this._loadMoreRowsMemoizer = createCallbackMemoizer(), autoReload && this._doStuff(this._lastRenderedStartIndex, this._lastRenderedStopIndex); } }, { key: "render", value: function() { return (0, this.props.children)({ onRowsRendered: this._onRowsRendered, registerChild: this._registerChild }); } }, { key: "_loadUnloadedRanges", value: function(unloadedRanges) { var _this2 = this, loadMoreRows = this.props.loadMoreRows; unloadedRanges.forEach(function(unloadedRange) { var promise = loadMoreRows(unloadedRange); promise && promise.then(function() { (function(_ref4) { var lastRenderedStartIndex = _ref4.lastRenderedStartIndex, lastRenderedStopIndex = _ref4.lastRenderedStopIndex, startIndex = _ref4.startIndex, stopIndex = _ref4.stopIndex; return !(lastRenderedStopIndex < startIndex || stopIndex < lastRenderedStartIndex); })({ lastRenderedStartIndex: _this2._lastRenderedStartIndex, lastRenderedStopIndex: _this2._lastRenderedStopIndex, startIndex: unloadedRange.startIndex, stopIndex: unloadedRange.stopIndex }) && _this2._registeredChild && function(component) { var currentIndex = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : 0, recomputeSize = "function" == typeof component.recomputeGridSize ? component.recomputeGridSize : component.recomputeRowHeights; recomputeSize ? recomputeSize.call(component, currentIndex) : component.forceUpdate(); }(_this2._registeredChild, _this2._lastRenderedStartIndex); }); }); } }, { key: "_onRowsRendered", value: function(_ref) { var startIndex = _ref.startIndex, stopIndex = _ref.stopIndex; this._lastRenderedStartIndex = startIndex, this._lastRenderedStopIndex = stopIndex, this._doStuff(startIndex, stopIndex); } }, { key: "_doStuff", value: function(startIndex, stopIndex) { var _ref2, _this3 = this, _this$props = this.props, isRowLoaded = _this$props.isRowLoaded, minimumBatchSize = _this$props.minimumBatchSize, rowCount = _this$props.rowCount, threshold = _this$props.threshold, unloadedRanges = function(_ref5) { for (var isRowLoaded = _ref5.isRowLoaded, minimumBatchSize = _ref5.minimumBatchSize, rowCount = _ref5.rowCount, startIndex = _ref5.startIndex, stopIndex = _ref5.stopIndex, unloadedRanges = [], rangeStartIndex = null, rangeStopIndex = null, index = startIndex; index <= stopIndex; index++) { isRowLoaded({ index: index }) ? null !== rangeStopIndex && (unloadedRanges.push({ startIndex: rangeStartIndex, stopIndex: rangeStopIndex }), rangeStartIndex = rangeStopIndex = null) : (rangeStopIndex = index, null === rangeStartIndex && (rangeStartIndex = index)); } if (null !== rangeStopIndex) { for (var potentialStopIndex = Math.min(Math.max(rangeStopIndex, rangeStartIndex + minimumBatchSize - 1), rowCount - 1), _index = rangeStopIndex + 1; _index <= potentialStopIndex && !isRowLoaded({ index: _index }); _index++) rangeStopIndex = _index; unloadedRanges.push({ startIndex: rangeStartIndex, stopIndex: rangeStopIndex }); } if (unloadedRanges.length) for (var firstUnloadedRange = unloadedRanges[0]; firstUnloadedRange.stopIndex - firstUnloadedRange.startIndex + 1 < minimumBatchSize && 0 < firstUnloadedRange.startIndex; ) { var _index2 = firstUnloadedRange.startIndex - 1; if (isRowLoaded({ index: _index2 })) break; firstUnloadedRange.startIndex = _index2; } return unloadedRanges; }({ isRowLoaded: isRowLoaded, minimumBatchSize: minimumBatchSize, rowCount: rowCount, startIndex: Math.max(0, startIndex - threshold), stopIndex: Math.min(rowCount - 1, stopIndex + threshold) }), squashedUnloadedRanges = (_ref2 = []).concat.apply(_ref2, _toConsumableArray(unloadedRanges.map(function(_ref3) { return [ _ref3.startIndex, _ref3.stopIndex ]; }))); this._loadMoreRowsMemoizer({ callback: function() { _this3._loadUnloadedRanges(unloadedRanges); }, indices: { squashedUnloadedRanges: squashedUnloadedRanges } }); } }, { key: "_registerChild", value: function(registeredChild) { this._registeredChild = registeredChild; } } ]), InfiniteLoader; }(); _defineProperty(InfiniteLoader, "propTypes", { children: propTypes.func.isRequired, isRowLoaded: propTypes.func.isRequired, loadMoreRows: propTypes.func.isRequired, minimumBatchSize: propTypes.number.isRequired, rowCount: propTypes.number.isRequired, threshold: propTypes.number.isRequired }), _defineProperty(InfiniteLoader, "defaultProps", { minimumBatchSize: 10, rowCount: 0, threshold: 15 }); var List = function() { function List() { var _getPrototypeOf2, _this; _classCallCheck(this, List); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key]; return _defineProperty(_assertThisInitialized(_this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(List)).call.apply(_getPrototypeOf2, [ this ].concat(args)))), "Grid", void 0), _defineProperty(_assertThisInitialized(_this), "_cellRenderer", function(_ref) { var parent = _ref.parent, rowIndex = _ref.rowIndex, style = _ref.style, isScrolling = _ref.isScrolling, isVisible = _ref.isVisible, key = _ref.key, rowRenderer = _this.props.rowRenderer, widthDescriptor = Object.getOwnPropertyDescriptor(style, "width"); return widthDescriptor && widthDescriptor.writable && (style.width = "100%"), rowRenderer({ index: rowIndex, style: style, isScrolling: isScrolling, isVisible: isVisible, key: key, parent: parent }); }), _defineProperty(_assertThisInitialized(_this), "_setRef", function(ref) { _this.Grid = ref; }), _defineProperty(_assertThisInitialized(_this), "_onScroll", function(_ref2) { var clientHeight = _ref2.clientHeight, scrollHeight = _ref2.scrollHeight, scrollTop = _ref2.scrollTop; (0, _this.props.onScroll)({ clientHeight: clientHeight, scrollHeight: scrollHeight, scrollTop: scrollTop }); }), _defineProperty(_assertThisInitialized(_this), "_onSectionRendered", function(_ref3) { var rowOverscanStartIndex = _ref3.rowOverscanStartIndex, rowOverscanStopIndex = _ref3.rowOverscanStopIndex, rowStartIndex = _ref3.rowStartIndex, rowStopIndex = _ref3.rowStopIndex; (0, _this.props.onRowsRendered)({ overscanStartIndex: rowOverscanStartIndex, overscanStopIndex: rowOverscanStopIndex, startIndex: rowStartIndex, stopIndex: rowStopIndex }); }), _this; } return _inherits(List, React.PureComponent), _createClass(List, [ { key: "forceUpdateGrid", value: function() { this.Grid && this.Grid.forceUpdate(); } }, { key: "getOffsetForRow", value: function(_ref4) { var alignment = _ref4.alignment, index = _ref4.index; return this.Grid ? this.Grid.getOffsetForCell({ alignment: alignment, rowIndex: index, columnIndex: 0 }).scrollTop : 0; } }, { key: "invalidateCellSizeAfterRender", value: function(_ref5) { var columnIndex = _ref5.columnIndex, rowIndex = _ref5.rowIndex; this.Grid && this.Grid.invalidateCellSizeAfterRender({ rowIndex: rowIndex, columnIndex: columnIndex }); } }, { key: "measureAllRows", value: function() { this.Grid && this.Grid.measureAllCells(); } }, { key: "recomputeGridSize", value: function(argument_0) { var _ref6 = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : {}, _ref6$columnIndex = _ref6.columnIndex, columnIndex = void 0 === _ref6$columnIndex ? 0 : _ref6$columnIndex, _ref6$rowIndex = _ref6.rowIndex, rowIndex = void 0 === _ref6$rowIndex ? 0 : _ref6$rowIndex; this.Grid && this.Grid.recomputeGridSize({ rowIndex: rowIndex, columnIndex: columnIndex }); } }, { key: "recomputeRowHeights", value: function(argument_0) { var index = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : 0; this.Grid && this.Grid.recomputeGridSize({ rowIndex: index, columnIndex: 0 }); } }, { key: "scrollToPosition", value: function(argument_0) { var scrollTop = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : 0; this.Grid && this.Grid.scrollToPosition({ scrollTop: scrollTop }); } }, { key: "scrollToRow", value: function(argument_0) { var index = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : 0; this.Grid && this.Grid.scrollToCell({ columnIndex: 0, rowIndex: index }); } }, { key: "render", value: function() { var _this$props = this.props, className = _this$props.className, noRowsRenderer = _this$props.noRowsRenderer, scrollToIndex = _this$props.scrollToIndex, width = _this$props.width, classNames = clsx("ReactVirtualized__List", className); return React.createElement(Grid, _extends({}, this.props, { autoContainerWidth: !0, cellRenderer: this._cellRenderer, className: classNames, columnWidth: width, columnCount: 1, noContentRenderer: noRowsRenderer, onScroll: this._onScroll, onSectionRendered: this._onSectionRendered, ref: this._setRef, scrollToRow: scrollToIndex })); } } ]), List; }(); _defineProperty(List, "defaultProps", { autoHeight: !1, estimatedRowSize: 30, onScroll: function() {}, noRowsRenderer: function() { return null; }, onRowsRendered: function() {}, overscanIndicesGetter: defaultOverscanIndicesGetter$1, overscanRowCount: 10, scrollToAlignment: "auto", scrollToIndex: -1, style: {} }); var bounds = { ge: function(a, y, c, l, h) { return "function" == typeof c ? function(a, l, h, y, c) { for (var i = h + 1; l <= h; ) { var m = l + h >>> 1; 0 <= c(a[m], y) ? h = (i = m) - 1 : l = 1 + m; } return i; }(a, void 0 === l ? 0 : 0 | l, void 0 === h ? a.length - 1 : 0 | h, y, c) : function(a, l, h, y) { for (var i = h + 1; l <= h; ) { var m = l + h >>> 1; y <= a[m] ? h = (i = m) - 1 : l = 1 + m; } return i; }(a, void 0 === c ? 0 : 0 | c, void 0 === l ? a.length - 1 : 0 | l, y); }, gt: function(a, y, c, l, h) { return "function" == typeof c ? function(a, l, h, y, c) { for (var i = h + 1; l <= h; ) { var m = l + h >>> 1; 0 < c(a[m], y) ? h = (i = m) - 1 : l = 1 + m; } return i; }(a, void 0 === l ? 0 : 0 | l, void 0 === h ? a.length - 1 : 0 | h, y, c) : function(a, l, h, y) { for (var i = h + 1; l <= h; ) { var m = l + h >>> 1; y < a[m] ? h = (i = m) - 1 : l = 1 + m; } return i; }(a, void 0 === c ? 0 : 0 | c, void 0 === l ? a.length - 1 : 0 | l, y); }, lt: function(a, y, c, l, h) { return "function" == typeof c ? function(a, l, h, y, c) { for (var i = l - 1; l <= h; ) { var m = l + h >>> 1; c(a[m], y) < 0 ? l = 1 + (i = m) : h = m - 1; } return i; }(a, void 0 === l ? 0 : 0 | l, void 0 === h ? a.length - 1 : 0 | h, y, c) : function(a, l, h, y) { for (var i = l - 1; l <= h; ) { var m = l + h >>> 1; a[m] < y ? l = 1 + (i = m) : h = m - 1; } return i; }(a, void 0 === c ? 0 : 0 | c, void 0 === l ? a.length - 1 : 0 | l, y); }, le: function(a, y, c, l, h) { return "function" == typeof c ? function(a, l, h, y, c) { for (var i = l - 1; l <= h; ) { var m = l + h >>> 1; c(a[m], y) <= 0 ? l = 1 + (i = m) : h = m - 1; } return i; }(a, void 0 === l ? 0 : 0 | l, void 0 === h ? a.length - 1 : 0 | h, y, c) : function(a, l, h, y) { for (var i = l - 1; l <= h; ) { var m = l + h >>> 1; a[m] <= y ? l = 1 + (i = m) : h = m - 1; } return i; }(a, void 0 === c ? 0 : 0 | c, void 0 === l ? a.length - 1 : 0 | l, y); }, eq: function(a, y, c, l, h) { return "function" == typeof c ? function(a, l, h, y, c) { for (;l <= h; ) { var m = l + h >>> 1, p = c(a[m], y); if (0 === p) return m; p <= 0 ? l = 1 + m : h = m - 1; } return -1; }(a, void 0 === l ? 0 : 0 | l, void 0 === h ? a.length - 1 : 0 | h, y, c) : function(a, l, h, y) { for (;l <= h; ) { var m = l + h >>> 1, x = a[m]; if (x === y) return m; x <= y ? l = 1 + m : h = m - 1; } return -1; }(a, void 0 === c ? 0 : 0 | c, void 0 === l ? a.length - 1 : 0 | l, y); } }; function IntervalTreeNode(mid, left, right, leftPoints, rightPoints) { this.mid = mid, this.left = left, this.right = right, this.leftPoints = leftPoints, this.rightPoints = rightPoints, this.count = (left ? left.count : 0) + (right ? right.count : 0) + leftPoints.length; } var proto = IntervalTreeNode.prototype; function copy(a, b) { a.mid = b.mid, a.left = b.left, a.right = b.right, a.leftPoints = b.leftPoints, a.rightPoints = b.rightPoints, a.count = b.count; } function rebuild(node, intervals) { var ntree = createIntervalTree(intervals); node.mid = ntree.mid, node.left = ntree.left, node.right = ntree.right, node.leftPoints = ntree.leftPoints, node.rightPoints = ntree.rightPoints, node.count = ntree.count; } function rebuildWithInterval(node, interval) { var intervals = node.intervals([]); intervals.push(interval), rebuild(node, intervals); } function rebuildWithoutInterval(node, interval) { var intervals = node.intervals([]), idx = intervals.indexOf(interval); return idx < 0 ? 0 : (intervals.splice(idx, 1), rebuild(node, intervals), 1); } function reportLeftRange(arr, hi, cb) { for (var i = 0; i < arr.length && arr[i][0] <= hi; ++i) { var r = cb(arr[i]); if (r) return r; } } function reportRightRange(arr, lo, cb) { for (var i = arr.length - 1; 0 <= i && arr[i][1] >= lo; --i) { var r = cb(arr[i]); if (r) return r; } } function reportRange(arr, cb) { for (var i = 0; i < arr.length; ++i) { var r = cb(arr[i]); if (r) return r; } } function compareNumbers(a, b) { return a - b; } function compareBegin(a, b) { var d = a[0] - b[0]; return d || a[1] - b[1]; } function compareEnd(a, b) { var d = a[1] - b[1]; return d || a[0] - b[0]; } function createIntervalTree(intervals) { if (0 === intervals.length) return null; for (var pts = [], i = 0; i < intervals.length; ++i) pts.push(intervals[i][0], intervals[i][1]); pts.sort(compareNumbers); var mid = pts[pts.length >> 1], leftIntervals = [], rightIntervals = [], centerIntervals = []; for (i = 0; i < intervals.length; ++i) { var s = intervals[i]; s[1] < mid ? leftIntervals.push(s) : mid < s[0] ? rightIntervals.push(s) : centerIntervals.push(s); } var leftPoints = centerIntervals, rightPoints = centerIntervals.slice(); return leftPoints.sort(compareBegin), rightPoints.sort(compareEnd), new IntervalTreeNode(mid, createIntervalTree(leftIntervals), createIntervalTree(rightIntervals), leftPoints, rightPoints); } function IntervalTree(root) { this.root = root; } proto.intervals = function(result) { return result.push.apply(result, this.leftPoints), this.left && this.left.intervals(result), this.right && this.right.intervals(result), result; }, proto.insert = function(interval) { var weight = this.count - this.leftPoints.length; if (this.count += 1, interval[1] < this.mid) this.left ? 4 * (this.left.count + 1) > 3 * (1 + weight) ? rebuildWithInterval(this, interval) : this.left.insert(interval) : this.left = createIntervalTree([ interval ]); else if (interval[0] > this.mid) this.right ? 4 * (this.right.count + 1) > 3 * (1 + weight) ? rebuildWithInterval(this, interval) : this.right.insert(interval) : this.right = createIntervalTree([ interval ]); else { var l = bounds.ge(this.leftPoints, interval, compareBegin), r = bounds.ge(this.rightPoints, interval, compareEnd); this.leftPoints.splice(l, 0, interval), this.rightPoints.splice(r, 0, interval); } }, proto.remove = function(interval) { var weight = this.count - this.leftPoints; if (interval[1] < this.mid) { return this.left ? 3 * (weight - 1) < 4 * (this.right ? this.right.count : 0) ? rebuildWithoutInterval(this, interval) : 2 === (r = this.left.remove(interval)) ? (this.left = null, this.count -= 1, 1) : (1 === r && (this.count -= 1), r) : 0; } else { if (interval[0] > this.mid) return this.right ? 3 * (weight - 1) < 4 * (this.left ? this.left.count : 0) ? rebuildWithoutInterval(this, interval) : 2 === (r = this.right.remove(interval)) ? (this.right = null, this.count -= 1, 1) : (1 === r && (this.count -= 1), r) : 0; if (1 === this.count) return this.leftPoints[0] === interval ? 2 : 0; if (1 === this.leftPoints.length && this.leftPoints[0] === interval) { if (this.left && this.right) { for (var p = this, n = this.left; n.right; ) n = (p = n).right; if (p === this) n.right = this.right; else { var l = this.left; r = this.right; p.count -= n.count, p.right = n.left, n.left = l, n.right = r; } copy(this, n), this.count = (this.left ? this.left.count : 0) + (this.right ? this.right.count : 0) + this.leftPoints.length; } else this.left ? copy(this, this.left) : copy(this, this.right); return 1; } for (l = bounds.ge(this.leftPoints, interval, compareBegin); l < this.leftPoints.length && this.leftPoints[l][0] === interval[0]; ++l) if (this.leftPoints[l] === interval) { this.count -= 1, this.leftPoints.splice(l, 1); for (r = bounds.ge(this.rightPoints, interval, compareEnd); r < this.rightPoints.length && this.rightPoints[r][1] === interval[1]; ++r) if (this.rightPoints[r] === interval) return this.rightPoints.splice(r, 1), 1; } return 0; var r; } }, proto.queryPoint = function(x, cb) { if (x < this.mid) { if (this.left) if (r = this.left.queryPoint(x, cb)) return r; return reportLeftRange(this.leftPoints, x, cb); } if (x > this.mid) { var r; if (this.right) if (r = this.right.queryPoint(x, cb)) return r; return reportRightRange(this.rightPoints, x, cb); } return reportRange(this.leftPoints, cb); }, proto.queryInterval = function(lo, hi, cb) { var r; if (lo < this.mid && this.left && (r = this.left.queryInterval(lo, hi, cb))) return r; if (hi > this.mid && this.right && (r = this.right.queryInterval(lo, hi, cb))) return r; return hi < this.mid ? reportLeftRange(this.leftPoints, hi, cb) : lo > this.mid ? reportRightRange(this.rightPoints, lo, cb) : reportRange(this.leftPoints, cb); }; var tproto = IntervalTree.prototype; tproto.insert = function(interval) { this.root ? this.root.insert(interval) : this.root = new IntervalTreeNode(interval[0], null, null, [ interval ], [ interval ]); }, tproto.remove = function(interval) { if (this.root) { var r = this.root.remove(interval); return 2 === r && (this.root = null), 0 !== r; } return !1; }, tproto.queryPoint = function(p, cb) { if (this.root) return this.root.queryPoint(p, cb); }, tproto.queryInterval = function(lo, hi, cb) { if (lo <= hi && this.root) return this.root.queryInterval(lo, hi, cb); }, Object.defineProperty(tproto, "count", { get: function() { return this.root ? this.root.count : 0; } }), Object.defineProperty(tproto, "intervals", { get: function() { return this.root ? this.root.intervals([]) : []; } }); var PositionCache = function() { function PositionCache() { _classCallCheck(this, PositionCache), _defineProperty(this, "_columnSizeMap", {}), _defineProperty(this, "_intervalTree", function(intervals) { return intervals && 0 !== intervals.length ? new IntervalTree(createIntervalTree(intervals)) : new IntervalTree(null); }()), _defineProperty(this, "_leftMap", {}); } return _createClass(PositionCache, [ { key: "estimateTotalHeight", value: function(cellCount, columnCount, defaultCellHeight) { var unmeasuredCellCount = cellCount - this.count; return this.tallestColumnSize + Math.ceil(unmeasuredCellCount / columnCount) * defaultCellHeight; } }, { key: "range", value: function(scrollTop, clientHeight, renderCallback) { var _this = this; this._intervalTree.queryInterval(scrollTop, scrollTop + clientHeight, function(_ref) { var _ref2 = _slicedToArray(_ref, 3), top = _ref2[0], index = (_ref2[1], _ref2[2]); return renderCallback(index, _this._leftMap[index], top); }); } }, { key: "setPosition", value: function(index, left, top, height) { this._intervalTree.insert([ top, top + height, index ]), this._leftMap[index] = left; var columnSizeMap = this._columnSizeMap, columnHeight = columnSizeMap[left]; columnSizeMap[left] = void 0 === columnHeight ? top + height : Math.max(columnHeight, top + height); } }, { key: "count", get: function() { return this._intervalTree.count; } }, { key: "shortestColumnSize", get: function() { var columnSizeMap = this._columnSizeMap, size = 0; for (var i in columnSizeMap) { var height = columnSizeMap[i]; size = 0 === size ? height : Math.min(size, height); } return size; } }, { key: "tallestColumnSize", get: function() { var columnSizeMap = this._columnSizeMap, size = 0; for (var i in columnSizeMap) { var height = columnSizeMap[i]; size = Math.max(size, height); } return size; } } ]), PositionCache; }(), Masonry = function() { function Masonry() { var _getPrototypeOf2, _this; _classCallCheck(this, Masonry); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key]; return _defineProperty(_assertThisInitialized(_this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Masonry)).call.apply(_getPrototypeOf2, [ this ].concat(args)))), "state", { isScrolling: !1, scrollTop: 0 }), _defineProperty(_assertThisInitialized(_this), "_debounceResetIsScrollingId", void 0), _defineProperty(_assertThisInitialized(_this), "_invalidateOnUpdateStartIndex", null), _defineProperty(_assertThisInitialized(_this), "_invalidateOnUpdateStopIndex", null), _defineProperty(_assertThisInitialized(_this), "_positionCache", new PositionCache()), _defineProperty(_assertThisInitialized(_this), "_startIndex", null), _defineProperty(_assertThisInitialized(_this), "_startIndexMemoized", null), _defineProperty(_assertThisInitialized(_this), "_stopIndex", null), _defineProperty(_assertThisInitialized(_this), "_stopIndexMemoized", null), _defineProperty(_assertThisInitialized(_this), "_debounceResetIsScrollingCallback", function() { _this.setState({ isScrolling: !1 }); }), _defineProperty(_assertThisInitialized(_this), "_setScrollingContainerRef", function(ref) { _this._scrollingContainer = ref; }), _defineProperty(_assertThisInitialized(_this), "_onScroll", function(event) { var height = _this.props.height, eventScrollTop = event.currentTarget.scrollTop, scrollTop = Math.min(Math.max(0, _this._getEstimatedTotalHeight() - height), eventScrollTop); eventScrollTop === scrollTop && (_this._debounceResetIsScrolling(), _this.state.scrollTop !== scrollTop && _this.setState({ isScrolling: !0, scrollTop: scrollTop })); }), _this; } return _inherits(Masonry, React.PureComponent), _createClass(Masonry, [ { key: "clearCellPositions", value: function() { this._positionCache = new PositionCache(), this.forceUpdate(); } }, { key: "invalidateCellSizeAfterRender", value: function(_ref) { var index = _ref.rowIndex; null === this._invalidateOnUpdateStartIndex ? (this._invalidateOnUpdateStartIndex = index, this._invalidateOnUpdateStopIndex = index) : (this._invalidateOnUpdateStartIndex = Math.min(this._invalidateOnUpdateStartIndex, index), this._invalidateOnUpdateStopIndex = Math.max(this._invalidateOnUpdateStopIndex, index)); } }, { key: "recomputeCellPositions", value: function() { var stopIndex = this._positionCache.count - 1; this._positionCache = new PositionCache(), this._populatePositionCache(0, stopIndex), this.forceUpdate(); } }, { key: "componentDidMount", value: function() { this._checkInvalidateOnUpdate(), this._invokeOnScrollCallback(), this._invokeOnCellsRenderedCallback(); } }, { key: "componentDidUpdate", value: function(prevProps) { this._checkInvalidateOnUpdate(), this._invokeOnScrollCallback(), this._invokeOnCellsRenderedCallback(), this.props.scrollTop !== prevProps.scrollTop && this._debounceResetIsScrolling(); } }, { key: "componentWillUnmount", value: function() { this._debounceResetIsScrollingId && cancelAnimationTimeout(this._debounceResetIsScrollingId); } }, { key: "render", value: function() { var stopIndex, _this2 = this, _this$props = this.props, autoHeight = _this$props.autoHeight, cellCount = _this$props.cellCount, cellMeasurerCache = _this$props.cellMeasurerCache, cellRenderer = _this$props.cellRenderer, className = _this$props.className, height = _this$props.height, id = _this$props.id, keyMapper = _this$props.keyMapper, overscanByPixels = _this$props.overscanByPixels, role = _this$props.role, style = _this$props.style, tabIndex = _this$props.tabIndex, width = _this$props.width, rowDirection = _this$props.rowDirection, _this$state = this.state, isScrolling = _this$state.isScrolling, scrollTop = _this$state.scrollTop, children = [], estimateTotalHeight = this._getEstimatedTotalHeight(), shortestColumnSize = this._positionCache.shortestColumnSize, measuredCellCount = this._positionCache.count, startIndex = 0; if (this._positionCache.range(Math.max(0, scrollTop - overscanByPixels), height + 2 * overscanByPixels, function(index, left, top) { var _style; stopIndex = void 0 === stopIndex ? startIndex = index : (startIndex = Math.min(startIndex, index), Math.max(stopIndex, index)), children.push(cellRenderer({ index: index, isScrolling: isScrolling, key: keyMapper(index), parent: _this2, style: (_style = { height: cellMeasurerCache.getHeight(index) }, _defineProperty(_style, "ltr" === rowDirection ? "left" : "right", left), _defineProperty(_style, "position", "absolute"), _defineProperty(_style, "top", top), _defineProperty(_style, "width", cellMeasurerCache.getWidth(index)), _style) })); }), shortestColumnSize < scrollTop + height + overscanByPixels && measuredCellCount < cellCount) for (var batchSize = Math.min(cellCount - measuredCellCount, Math.ceil((scrollTop + height + overscanByPixels - shortestColumnSize) / cellMeasurerCache.defaultHeight * width / cellMeasurerCache.defaultWidth)), _index = measuredCellCount; _index < measuredCellCount + batchSize; _index++) stopIndex = _index, children.push(cellRenderer({ index: _index, isScrolling: isScrolling, key: keyMapper(_index), parent: this, style: { width: cellMeasurerCache.getWidth(_index) } })); return this._startIndex = startIndex, this._stopIndex = stopIndex, React.createElement("div", { ref: this._setScrollingContainerRef, "aria-label": this.props["aria-label"], className: clsx("ReactVirtualized__Masonry", className), id: id, onScroll: this._onScroll, role: role, style: _objectSpread2({ boxSizing: "border-box", direction: "ltr", height: autoHeight ? "auto" : height, overflowX: "hidden", overflowY: estimateTotalHeight < height ? "hidden" : "auto", position: "relative", width: width, WebkitOverflowScrolling: "touch", willChange: "transform" }, style), tabIndex: tabIndex }, React.createElement("div", { className: "ReactVirtualized__Masonry__innerScrollContainer", style: { width: "100%", height: estimateTotalHeight, maxWidth: "100%", maxHeight: estimateTotalHeight, overflow: "hidden", pointerEvents: isScrolling ? "none" : "", position: "relative" } }, children)); } }, { key: "_checkInvalidateOnUpdate", value: function() { if ("number" == typeof this._invalidateOnUpdateStartIndex) { var startIndex = this._invalidateOnUpdateStartIndex, stopIndex = this._invalidateOnUpdateStopIndex; this._invalidateOnUpdateStartIndex = null, this._invalidateOnUpdateStopIndex = null, this._populatePositionCache(startIndex, stopIndex), this.forceUpdate(); } } }, { key: "_debounceResetIsScrolling", value: function() { var scrollingResetTimeInterval = this.props.scrollingResetTimeInterval; this._debounceResetIsScrollingId && cancelAnimationTimeout(this._debounceResetIsScrollingId), this._debounceResetIsScrollingId = requestAnimationTimeout(this._debounceResetIsScrollingCallback, scrollingResetTimeInterval); } }, { key: "_getEstimatedTotalHeight", value: function() { var _this$props2 = this.props, cellCount = _this$props2.cellCount, cellMeasurerCache = _this$props2.cellMeasurerCache, width = _this$props2.width, estimatedColumnCount = Math.max(1, Math.floor(width / cellMeasurerCache.defaultWidth)); return this._positionCache.estimateTotalHeight(cellCount, estimatedColumnCount, cellMeasurerCache.defaultHeight); } }, { key: "_invokeOnScrollCallback", value: function() { var _this$props3 = this.props, height = _this$props3.height, onScroll = _this$props3.onScroll, scrollTop = this.state.scrollTop; this._onScrollMemoized !== scrollTop && (onScroll({ clientHeight: height, scrollHeight: this._getEstimatedTotalHeight(), scrollTop: scrollTop }), this._onScrollMemoized = scrollTop); } }, { key: "_invokeOnCellsRenderedCallback", value: function() { this._startIndexMemoized === this._startIndex && this._stopIndexMemoized === this._stopIndex || ((0, this.props.onCellsRendered)({ startIndex: this._startIndex, stopIndex: this._stopIndex }), this._startIndexMemoized = this._startIndex, this._stopIndexMemoized = this._stopIndex); } }, { key: "_populatePositionCache", value: function(startIndex, stopIndex) { for (var _this$props4 = this.props, cellMeasurerCache = _this$props4.cellMeasurerCache, cellPositioner = _this$props4.cellPositioner, _index2 = startIndex; _index2 <= stopIndex; _index2++) { var _cellPositioner = cellPositioner(_index2), left = _cellPositioner.left, top = _cellPositioner.top; this._positionCache.setPosition(_index2, left, top, cellMeasurerCache.getHeight(_index2)); } } } ], [ { key: "getDerivedStateFromProps", value: function(nextProps, prevState) { return void 0 !== nextProps.scrollTop && prevState.scrollTop !== nextProps.scrollTop ? { isScrolling: !0, scrollTop: nextProps.scrollTop } : null; } } ]), Masonry; }(); function noop() {} _defineProperty(Masonry, "defaultProps", { autoHeight: !1, keyMapper: function(value) { return value; }, onCellsRendered: noop, onScroll: noop, overscanByPixels: 20, role: "grid", scrollingResetTimeInterval: 150, style: {}, tabIndex: 0, rowDirection: "ltr" }), polyfill(Masonry); var CellMeasurerCacheDecorator = function() { function CellMeasurerCacheDecorator() { var _this = this, params = 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : {}; _classCallCheck(this, CellMeasurerCacheDecorator), _defineProperty(this, "_cellMeasurerCache", void 0), _defineProperty(this, "_columnIndexOffset", void 0), _defineProperty(this, "_rowIndexOffset", void 0), _defineProperty(this, "columnWidth", function(_ref) { var index = _ref.index; _this._cellMeasurerCache.columnWidth({ index: index + _this._columnIndexOffset }); }), _defineProperty(this, "rowHeight", function(_ref2) { var index = _ref2.index; _this._cellMeasurerCache.rowHeight({ index: index + _this._rowIndexOffset }); }); var cellMeasurerCache = params.cellMeasurerCache, _params$columnIndexOf = params.columnIndexOffset, columnIndexOffset = void 0 === _params$columnIndexOf ? 0 : _params$columnIndexOf, _params$rowIndexOffse = params.rowIndexOffset, rowIndexOffset = void 0 === _params$rowIndexOffse ? 0 : _params$rowIndexOffse; this._cellMeasurerCache = cellMeasurerCache, this._columnIndexOffset = columnIndexOffset, this._rowIndexOffset = rowIndexOffset; } return _createClass(CellMeasurerCacheDecorator, [ { key: "clear", value: function(rowIndex, columnIndex) { this._cellMeasurerCache.clear(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset); } }, { key: "clearAll", value: function() { this._cellMeasurerCache.clearAll(); } }, { key: "hasFixedHeight", value: function() { return this._cellMeasurerCache.hasFixedHeight(); } }, { key: "hasFixedWidth", value: function() { return this._cellMeasurerCache.hasFixedWidth(); } }, { key: "getHeight", value: function(rowIndex, argument_1) { var columnIndex = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : 0; return this._cellMeasurerCache.getHeight(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset); } }, { key: "getWidth", value: function(rowIndex, argument_1) { var columnIndex = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : 0; return this._cellMeasurerCache.getWidth(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset); } }, { key: "has", value: function(rowIndex, argument_1) { var columnIndex = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : 0; return this._cellMeasurerCache.has(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset); } }, { key: "set", value: function(rowIndex, columnIndex, width, height) { this._cellMeasurerCache.set(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset, width, height); } }, { key: "defaultHeight", get: function() { return this._cellMeasurerCache.defaultHeight; } }, { key: "defaultWidth", get: function() { return this._cellMeasurerCache.defaultWidth; } } ]), CellMeasurerCacheDecorator; }(), MultiGrid = function() { function MultiGrid(props, context) { var _this; _classCallCheck(this, MultiGrid), _defineProperty(_assertThisInitialized(_this = _possibleConstructorReturn(this, _getPrototypeOf(MultiGrid).call(this, props, context))), "state", { scrollLeft: 0, scrollTop: 0, scrollbarSize: 0, showHorizontalScrollbar: !1, showVerticalScrollbar: !1 }), _defineProperty(_assertThisInitialized(_this), "_deferredInvalidateColumnIndex", null), _defineProperty(_assertThisInitialized(_this), "_deferredInvalidateRowIndex", null), _defineProperty(_assertThisInitialized(_this), "_bottomLeftGridRef", function(ref) { _this._bottomLeftGrid = ref; }), _defineProperty(_assertThisInitialized(_this), "_bottomRightGridRef", function(ref) { _this._bottomRightGrid = ref; }), _defineProperty(_assertThisInitialized(_this), "_cellRendererBottomLeftGrid", function(_ref) { var rowIndex = _ref.rowIndex, rest = _objectWithoutProperties(_ref, [ "rowIndex" ]), _this$props = _this.props, cellRenderer = _this$props.cellRenderer, fixedRowCount = _this$props.fixedRowCount; return rowIndex === _this$props.rowCount - fixedRowCount ? React.createElement("div", { key: rest.key, style: _objectSpread2({}, rest.style, { height: 20 }) }) : cellRenderer(_objectSpread2({}, rest, { parent: _assertThisInitialized(_this), rowIndex: rowIndex + fixedRowCount })); }), _defineProperty(_assertThisInitialized(_this), "_cellRendererBottomRightGrid", function(_ref2) { var columnIndex = _ref2.columnIndex, rowIndex = _ref2.rowIndex, rest = _objectWithoutProperties(_ref2, [ "columnIndex", "rowIndex" ]), _this$props2 = _this.props, cellRenderer = _this$props2.cellRenderer, fixedColumnCount = _this$props2.fixedColumnCount, fixedRowCount = _this$props2.fixedRowCount; return cellRenderer(_objectSpread2({}, rest, { columnIndex: columnIndex + fixedColumnCount, parent: _assertThisInitialized(_this), rowIndex: rowIndex + fixedRowCount })); }), _defineProperty(_assertThisInitialized(_this), "_cellRendererTopRightGrid", function(_ref3) { var columnIndex = _ref3.columnIndex, rest = _objectWithoutProperties(_ref3, [ "columnIndex" ]), _this$props3 = _this.props, cellRenderer = _this$props3.cellRenderer, columnCount = _this$props3.columnCount, fixedColumnCount = _this$props3.fixedColumnCount; return columnIndex === columnCount - fixedColumnCount ? React.createElement("div", { key: rest.key, style: _objectSpread2({}, rest.style, { width: 20 }) }) : cellRenderer(_objectSpread2({}, rest, { columnIndex: columnIndex + fixedColumnCount, parent: _assertThisInitialized(_this) })); }), _defineProperty(_assertThisInitialized(_this), "_columnWidthRightGrid", function(_ref4) { var index = _ref4.index, _this$props4 = _this.props, columnCount = _this$props4.columnCount, fixedColumnCount = _this$props4.fixedColumnCount, columnWidth = _this$props4.columnWidth, _this$state = _this.state, scrollbarSize = _this$state.scrollbarSize; return _this$state.showHorizontalScrollbar && index === columnCount - fixedColumnCount ? scrollbarSize : "function" == typeof columnWidth ? columnWidth({ index: index + fixedColumnCount }) : columnWidth; }), _defineProperty(_assertThisInitialized(_this), "_onScroll", function(scrollInfo) { var scrollLeft = scrollInfo.scrollLeft, scrollTop = scrollInfo.scrollTop; _this.setState({ scrollLeft: scrollLeft, scrollTop: scrollTop }); var onScroll = _this.props.onScroll; onScroll && onScroll(scrollInfo); }), _defineProperty(_assertThisInitialized(_this), "_onScrollbarPresenceChange", function(_ref5) { var horizontal = _ref5.horizontal, size = _ref5.size, vertical = _ref5.vertical, _this$state2 = _this.state, showHorizontalScrollbar = _this$state2.showHorizontalScrollbar, showVerticalScrollbar = _this$state2.showVerticalScrollbar; if (horizontal !== showHorizontalScrollbar || vertical !== showVerticalScrollbar) { _this.setState({ scrollbarSize: size, showHorizontalScrollbar: horizontal, showVerticalScrollbar: vertical }); var onScrollbarPresenceChange = _this.props.onScrollbarPresenceChange; "function" == typeof onScrollbarPresenceChange && onScrollbarPresenceChange({ horizontal: horizontal, size: size, vertical: vertical }); } }), _defineProperty(_assertThisInitialized(_this), "_onScrollLeft", function(scrollInfo) { var scrollLeft = scrollInfo.scrollLeft; _this._onScroll({ scrollLeft: scrollLeft, scrollTop: _this.state.scrollTop }); }), _defineProperty(_assertThisInitialized(_this), "_onScrollTop", function(scrollInfo) { var scrollTop = scrollInfo.scrollTop; _this._onScroll({ scrollTop: scrollTop, scrollLeft: _this.state.scrollLeft }); }), _defineProperty(_assertThisInitialized(_this), "_rowHeightBottomGrid", function(_ref6) { var index = _ref6.index, _this$props5 = _this.props, fixedRowCount = _this$props5.fixedRowCount, rowCount = _this$props5.rowCount, rowHeight = _this$props5.rowHeight, _this$state3 = _this.state, scrollbarSize = _this$state3.scrollbarSize; return _this$state3.showVerticalScrollbar && index === rowCount - fixedRowCount ? scrollbarSize : "function" == typeof rowHeight ? rowHeight({ index: index + fixedRowCount }) : rowHeight; }), _defineProperty(_assertThisInitialized(_this), "_topLeftGridRef", function(ref) { _this._topLeftGrid = ref; }), _defineProperty(_assertThisInitialized(_this), "_topRightGridRef", function(ref) { _this._topRightGrid = ref; }); var deferredMeasurementCache = props.deferredMeasurementCache, _fixedColumnCount = props.fixedColumnCount, _fixedRowCount = props.fixedRowCount; return _this._maybeCalculateCachedStyles(!0), deferredMeasurementCache && (_this._deferredMeasurementCacheBottomLeftGrid = 0 < _fixedRowCount ? new CellMeasurerCacheDecorator({ cellMeasurerCache: deferredMeasurementCache, columnIndexOffset: 0, rowIndexOffset: _fixedRowCount }) : deferredMeasurementCache, _this._deferredMeasurementCacheBottomRightGrid = 0 < _fixedColumnCount || 0 < _fixedRowCount ? new CellMeasurerCacheDecorator({ cellMeasurerCache: deferredMeasurementCache, columnIndexOffset: _fixedColumnCount, rowIndexOffset: _fixedRowCount }) : deferredMeasurementCache, _this._deferredMeasurementCacheTopRightGrid = 0 < _fixedColumnCount ? new CellMeasurerCacheDecorator({ cellMeasurerCache: deferredMeasurementCache, columnIndexOffset: _fixedColumnCount, rowIndexOffset: 0 }) : deferredMeasurementCache), _this; } return _inherits(MultiGrid, React.PureComponent), _createClass(MultiGrid, [ { key: "forceUpdateGrids", value: function() { this._bottomLeftGrid && this._bottomLeftGrid.forceUpdate(), this._bottomRightGrid && this._bottomRightGrid.forceUpdate(), this._topLeftGrid && this._topLeftGrid.forceUpdate(), this._topRightGrid && this._topRightGrid.forceUpdate(); } }, { key: "invalidateCellSizeAfterRender", value: function(argument_0) { var _ref7 = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : {}, _ref7$columnIndex = _ref7.columnIndex, columnIndex = void 0 === _ref7$columnIndex ? 0 : _ref7$columnIndex, _ref7$rowIndex = _ref7.rowIndex, rowIndex = void 0 === _ref7$rowIndex ? 0 : _ref7$rowIndex; this._deferredInvalidateColumnIndex = "number" == typeof this._deferredInvalidateColumnIndex ? Math.min(this._deferredInvalidateColumnIndex, columnIndex) : columnIndex, this._deferredInvalidateRowIndex = "number" == typeof this._deferredInvalidateRowIndex ? Math.min(this._deferredInvalidateRowIndex, rowIndex) : rowIndex; } }, { key: "measureAllCells", value: function() { this._bottomLeftGrid && this._bottomLeftGrid.measureAllCells(), this._bottomRightGrid && this._bottomRightGrid.measureAllCells(), this._topLeftGrid && this._topLeftGrid.measureAllCells(), this._topRightGrid && this._topRightGrid.measureAllCells(); } }, { key: "recomputeGridSize", value: function(argument_0) { var _ref8 = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : {}, _ref8$columnIndex = _ref8.columnIndex, columnIndex = void 0 === _ref8$columnIndex ? 0 : _ref8$columnIndex, _ref8$rowIndex = _ref8.rowIndex, rowIndex = void 0 === _ref8$rowIndex ? 0 : _ref8$rowIndex, _this$props6 = this.props, fixedColumnCount = _this$props6.fixedColumnCount, fixedRowCount = _this$props6.fixedRowCount, adjustedColumnIndex = Math.max(0, columnIndex - fixedColumnCount), adjustedRowIndex = Math.max(0, rowIndex - fixedRowCount); this._bottomLeftGrid && this._bottomLeftGrid.recomputeGridSize({ columnIndex: columnIndex, rowIndex: adjustedRowIndex }), this._bottomRightGrid && this._bottomRightGrid.recomputeGridSize({ columnIndex: adjustedColumnIndex, rowIndex: adjustedRowIndex }), this._topLeftGrid && this._topLeftGrid.recomputeGridSize({ columnIndex: columnIndex, rowIndex: rowIndex }), this._topRightGrid && this._topRightGrid.recomputeGridSize({ columnIndex: adjustedColumnIndex, rowIndex: rowIndex }), this._leftGridWidth = null, this._topGridHeight = null, this._maybeCalculateCachedStyles(!0); } }, { key: "componentDidMount", value: function() { var _this$props7 = this.props, scrollLeft = _this$props7.scrollLeft, scrollTop = _this$props7.scrollTop; if (0 < scrollLeft || 0 < scrollTop) { var newState = {}; 0 < scrollLeft && (newState.scrollLeft = scrollLeft), 0 < scrollTop && (newState.scrollTop = scrollTop), this.setState(newState); } this._handleInvalidatedGridSize(); } }, { key: "componentDidUpdate", value: function() { this._handleInvalidatedGridSize(); } }, { key: "render", value: function() { var _this$props8 = this.props, onScroll = _this$props8.onScroll, onSectionRendered = _this$props8.onSectionRendered, scrollToColumn = (_this$props8.onScrollbarPresenceChange, _this$props8.scrollLeft, _this$props8.scrollToColumn), scrollToRow = (_this$props8.scrollTop, _this$props8.scrollToRow), rest = _objectWithoutProperties(_this$props8, [ "onScroll", "onSectionRendered", "onScrollbarPresenceChange", "scrollLeft", "scrollToColumn", "scrollTop", "scrollToRow" ]); if (this._prepareForRender(), 0 === this.props.width || 0 === this.props.height) return null; var _this$state4 = this.state, scrollLeft = _this$state4.scrollLeft, scrollTop = _this$state4.scrollTop; return React.createElement("div", { style: this._containerOuterStyle }, React.createElement("div", { style: this._containerTopStyle }, this._renderTopLeftGrid(rest), this._renderTopRightGrid(_objectSpread2({}, rest, { onScroll: onScroll, scrollLeft: scrollLeft }))), React.createElement("div", { style: this._containerBottomStyle }, this._renderBottomLeftGrid(_objectSpread2({}, rest, { onScroll: onScroll, scrollTop: scrollTop })), this._renderBottomRightGrid(_objectSpread2({}, rest, { onScroll: onScroll, onSectionRendered: onSectionRendered, scrollLeft: scrollLeft, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow, scrollTop: scrollTop })))); } }, { key: "_getBottomGridHeight", value: function(props) { return props.height - this._getTopGridHeight(props); } }, { key: "_getLeftGridWidth", value: function(props) { var fixedColumnCount = props.fixedColumnCount, columnWidth = props.columnWidth; if (null == this._leftGridWidth) if ("function" == typeof columnWidth) { for (var leftGridWidth = 0, index = 0; index < fixedColumnCount; index++) leftGridWidth += columnWidth({ index: index }); this._leftGridWidth = leftGridWidth; } else this._leftGridWidth = columnWidth * fixedColumnCount; return this._leftGridWidth; } }, { key: "_getRightGridWidth", value: function(props) { return props.width - this._getLeftGridWidth(props); } }, { key: "_getTopGridHeight", value: function(props) { var fixedRowCount = props.fixedRowCount, rowHeight = props.rowHeight; if (null == this._topGridHeight) if ("function" == typeof rowHeight) { for (var topGridHeight = 0, index = 0; index < fixedRowCount; index++) topGridHeight += rowHeight({ index: index }); this._topGridHeight = topGridHeight; } else this._topGridHeight = rowHeight * fixedRowCount; return this._topGridHeight; } }, { key: "_handleInvalidatedGridSize", value: function() { if ("number" == typeof this._deferredInvalidateColumnIndex) { var columnIndex = this._deferredInvalidateColumnIndex, rowIndex = this._deferredInvalidateRowIndex; this._deferredInvalidateColumnIndex = null, this._deferredInvalidateRowIndex = null, this.recomputeGridSize({ columnIndex: columnIndex, rowIndex: rowIndex }), this.forceUpdate(); } } }, { key: "_maybeCalculateCachedStyles", value: function(resetAll) { var _this$props9 = this.props, columnWidth = _this$props9.columnWidth, enableFixedColumnScroll = _this$props9.enableFixedColumnScroll, enableFixedRowScroll = _this$props9.enableFixedRowScroll, height = _this$props9.height, fixedColumnCount = _this$props9.fixedColumnCount, fixedRowCount = _this$props9.fixedRowCount, rowHeight = _this$props9.rowHeight, style = _this$props9.style, styleBottomLeftGrid = _this$props9.styleBottomLeftGrid, styleBottomRightGrid = _this$props9.styleBottomRightGrid, styleTopLeftGrid = _this$props9.styleTopLeftGrid, styleTopRightGrid = _this$props9.styleTopRightGrid, width = _this$props9.width, sizeChange = resetAll || height !== this._lastRenderedHeight || width !== this._lastRenderedWidth, leftSizeChange = resetAll || columnWidth !== this._lastRenderedColumnWidth || fixedColumnCount !== this._lastRenderedFixedColumnCount, topSizeChange = resetAll || fixedRowCount !== this._lastRenderedFixedRowCount || rowHeight !== this._lastRenderedRowHeight; (resetAll || sizeChange || style !== this._lastRenderedStyle) && (this._containerOuterStyle = _objectSpread2({ height: height, overflow: "visible", width: width }, style)), (resetAll || sizeChange || topSizeChange) && (this._containerTopStyle = { height: this._getTopGridHeight(this.props), position: "relative", width: width }, this._containerBottomStyle = { height: height - this._getTopGridHeight(this.props), overflow: "visible", position: "relative", width: width }), !resetAll && styleBottomLeftGrid === this._lastRenderedStyleBottomLeftGrid || (this._bottomLeftGridStyle = _objectSpread2({ left: 0, overflowX: "hidden", overflowY: enableFixedColumnScroll ? "auto" : "hidden", position: "absolute" }, styleBottomLeftGrid)), (resetAll || leftSizeChange || styleBottomRightGrid !== this._lastRenderedStyleBottomRightGrid) && (this._bottomRightGridStyle = _objectSpread2({ left: this._getLeftGridWidth(this.props), position: "absolute" }, styleBottomRightGrid)), !resetAll && styleTopLeftGrid === this._lastRenderedStyleTopLeftGrid || (this._topLeftGridStyle = _objectSpread2({ left: 0, overflowX: "hidden", overflowY: "hidden", position: "absolute", top: 0 }, styleTopLeftGrid)), (resetAll || leftSizeChange || styleTopRightGrid !== this._lastRenderedStyleTopRightGrid) && (this._topRightGridStyle = _objectSpread2({ left: this._getLeftGridWidth(this.props), overflowX: enableFixedRowScroll ? "auto" : "hidden", overflowY: "hidden", position: "absolute", top: 0 }, styleTopRightGrid)), this._lastRenderedColumnWidth = columnWidth, this._lastRenderedFixedColumnCount = fixedColumnCount, this._lastRenderedFixedRowCount = fixedRowCount, this._lastRenderedHeight = height, this._lastRenderedRowHeight = rowHeight, this._lastRenderedStyle = style, this._lastRenderedStyleBottomLeftGrid = styleBottomLeftGrid, this._lastRenderedStyleBottomRightGrid = styleBottomRightGrid, this._lastRenderedStyleTopLeftGrid = styleTopLeftGrid, this._lastRenderedStyleTopRightGrid = styleTopRightGrid, this._lastRenderedWidth = width; } }, { key: "_prepareForRender", value: function() { this._lastRenderedColumnWidth === this.props.columnWidth && this._lastRenderedFixedColumnCount === this.props.fixedColumnCount || (this._leftGridWidth = null), this._lastRenderedFixedRowCount === this.props.fixedRowCount && this._lastRenderedRowHeight === this.props.rowHeight || (this._topGridHeight = null), this._maybeCalculateCachedStyles(), this._lastRenderedColumnWidth = this.props.columnWidth, this._lastRenderedFixedColumnCount = this.props.fixedColumnCount, this._lastRenderedFixedRowCount = this.props.fixedRowCount, this._lastRenderedRowHeight = this.props.rowHeight; } }, { key: "_renderBottomLeftGrid", value: function(props) { var enableFixedColumnScroll = props.enableFixedColumnScroll, fixedColumnCount = props.fixedColumnCount, fixedRowCount = props.fixedRowCount, rowCount = props.rowCount, hideBottomLeftGridScrollbar = props.hideBottomLeftGridScrollbar, showVerticalScrollbar = this.state.showVerticalScrollbar; if (!fixedColumnCount) return null; var additionalRowCount = showVerticalScrollbar ? 1 : 0, height = this._getBottomGridHeight(props), width = this._getLeftGridWidth(props), scrollbarSize = this.state.showVerticalScrollbar ? this.state.scrollbarSize : 0, gridWidth = hideBottomLeftGridScrollbar ? width + scrollbarSize : width, bottomLeftGrid = React.createElement(Grid, _extends({}, props, { cellRenderer: this._cellRendererBottomLeftGrid, className: this.props.classNameBottomLeftGrid, columnCount: fixedColumnCount, deferredMeasurementCache: this._deferredMeasurementCacheBottomLeftGrid, height: height, onScroll: enableFixedColumnScroll ? this._onScrollTop : void 0, ref: this._bottomLeftGridRef, rowCount: Math.max(0, rowCount - fixedRowCount) + additionalRowCount, rowHeight: this._rowHeightBottomGrid, style: this._bottomLeftGridStyle, tabIndex: null, width: gridWidth })); return hideBottomLeftGridScrollbar ? React.createElement("div", { className: "BottomLeftGrid_ScrollWrapper", style: _objectSpread2({}, this._bottomLeftGridStyle, { height: height, width: width, overflowY: "hidden" }) }, bottomLeftGrid) : bottomLeftGrid; } }, { key: "_renderBottomRightGrid", value: function(props) { var columnCount = props.columnCount, fixedColumnCount = props.fixedColumnCount, fixedRowCount = props.fixedRowCount, rowCount = props.rowCount, scrollToColumn = props.scrollToColumn, scrollToRow = props.scrollToRow; return React.createElement(Grid, _extends({}, props, { cellRenderer: this._cellRendererBottomRightGrid, className: this.props.classNameBottomRightGrid, columnCount: Math.max(0, columnCount - fixedColumnCount), columnWidth: this._columnWidthRightGrid, deferredMeasurementCache: this._deferredMeasurementCacheBottomRightGrid, height: this._getBottomGridHeight(props), onScroll: this._onScroll, onScrollbarPresenceChange: this._onScrollbarPresenceChange, ref: this._bottomRightGridRef, rowCount: Math.max(0, rowCount - fixedRowCount), rowHeight: this._rowHeightBottomGrid, scrollToColumn: scrollToColumn - fixedColumnCount, scrollToRow: scrollToRow - fixedRowCount, style: this._bottomRightGridStyle, width: this._getRightGridWidth(props) })); } }, { key: "_renderTopLeftGrid", value: function(props) { var fixedColumnCount = props.fixedColumnCount, fixedRowCount = props.fixedRowCount; return fixedColumnCount && fixedRowCount ? React.createElement(Grid, _extends({}, props, { className: this.props.classNameTopLeftGrid, columnCount: fixedColumnCount, height: this._getTopGridHeight(props), ref: this._topLeftGridRef, rowCount: fixedRowCount, style: this._topLeftGridStyle, tabIndex: null, width: this._getLeftGridWidth(props) })) : null; } }, { key: "_renderTopRightGrid", value: function(props) { var columnCount = props.columnCount, enableFixedRowScroll = props.enableFixedRowScroll, fixedColumnCount = props.fixedColumnCount, fixedRowCount = props.fixedRowCount, scrollLeft = props.scrollLeft, hideTopRightGridScrollbar = props.hideTopRightGridScrollbar, _this$state5 = this.state, showHorizontalScrollbar = _this$state5.showHorizontalScrollbar, scrollbarSize = _this$state5.scrollbarSize; if (!fixedRowCount) return null; var additionalColumnCount = showHorizontalScrollbar ? 1 : 0, height = this._getTopGridHeight(props), width = this._getRightGridWidth(props), additionalHeight = showHorizontalScrollbar ? scrollbarSize : 0, gridHeight = height, style = this._topRightGridStyle; hideTopRightGridScrollbar && (gridHeight = height + additionalHeight, style = _objectSpread2({}, this._topRightGridStyle, { left: 0 })); var topRightGrid = React.createElement(Grid, _extends({}, props, { cellRenderer: this._cellRendererTopRightGrid, className: this.props.classNameTopRightGrid, columnCount: Math.max(0, columnCount - fixedColumnCount) + additionalColumnCount, columnWidth: this._columnWidthRightGrid, deferredMeasurementCache: this._deferredMeasurementCacheTopRightGrid, height: gridHeight, onScroll: enableFixedRowScroll ? this._onScrollLeft : void 0, ref: this._topRightGridRef, rowCount: fixedRowCount, scrollLeft: scrollLeft, style: style, tabIndex: null, width: width })); return hideTopRightGridScrollbar ? React.createElement("div", { className: "TopRightGrid_ScrollWrapper", style: _objectSpread2({}, this._topRightGridStyle, { height: height, width: width, overflowX: "hidden" }) }, topRightGrid) : topRightGrid; } } ], [ { key: "getDerivedStateFromProps", value: function(nextProps, prevState) { return nextProps.scrollLeft !== prevState.scrollLeft || nextProps.scrollTop !== prevState.scrollTop ? { scrollLeft: null != nextProps.scrollLeft && 0 <= nextProps.scrollLeft ? nextProps.scrollLeft : prevState.scrollLeft, scrollTop: null != nextProps.scrollTop && 0 <= nextProps.scrollTop ? nextProps.scrollTop : prevState.scrollTop } : null; } } ]), MultiGrid; }(); _defineProperty(MultiGrid, "propTypes", { classNameBottomLeftGrid: propTypes.string.isRequired, classNameBottomRightGrid: propTypes.string.isRequired, classNameTopLeftGrid: propTypes.string.isRequired, classNameTopRightGrid: propTypes.string.isRequired, enableFixedColumnScroll: propTypes.bool.isRequired, enableFixedRowScroll: propTypes.bool.isRequired, fixedColumnCount: propTypes.number.isRequired, fixedRowCount: propTypes.number.isRequired, onScrollbarPresenceChange: propTypes.func, style: propTypes.object.isRequired, styleBottomLeftGrid: propTypes.object.isRequired, styleBottomRightGrid: propTypes.object.isRequired, styleTopLeftGrid: propTypes.object.isRequired, styleTopRightGrid: propTypes.object.isRequired, hideTopRightGridScrollbar: propTypes.bool, hideBottomLeftGridScrollbar: propTypes.bool }), _defineProperty(MultiGrid, "defaultProps", { classNameBottomLeftGrid: "", classNameBottomRightGrid: "", classNameTopLeftGrid: "", classNameTopRightGrid: "", enableFixedColumnScroll: !1, enableFixedRowScroll: !1, fixedColumnCount: 0, fixedRowCount: 0, scrollToColumn: -1, scrollToRow: -1, style: {}, styleBottomLeftGrid: {}, styleBottomRightGrid: {}, styleTopLeftGrid: {}, styleTopRightGrid: {}, hideTopRightGridScrollbar: !1, hideBottomLeftGridScrollbar: !1 }), polyfill(MultiGrid); var ScrollSync = function() { function ScrollSync(props, context) { var _this; return _classCallCheck(this, ScrollSync), (_this = _possibleConstructorReturn(this, _getPrototypeOf(ScrollSync).call(this, props, context))).state = { clientHeight: 0, clientWidth: 0, scrollHeight: 0, scrollLeft: 0, scrollTop: 0, scrollWidth: 0 }, _this._onScroll = _this._onScroll.bind(_assertThisInitialized(_this)), _this; } return _inherits(ScrollSync, React.PureComponent), _createClass(ScrollSync, [ { key: "render", value: function() { var children = this.props.children, _this$state = this.state, clientHeight = _this$state.clientHeight, clientWidth = _this$state.clientWidth, scrollHeight = _this$state.scrollHeight, scrollLeft = _this$state.scrollLeft, scrollTop = _this$state.scrollTop, scrollWidth = _this$state.scrollWidth; return children({ clientHeight: clientHeight, clientWidth: clientWidth, onScroll: this._onScroll, scrollHeight: scrollHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: scrollWidth }); } }, { key: "_onScroll", value: function(_ref) { var clientHeight = _ref.clientHeight, clientWidth = _ref.clientWidth, scrollHeight = _ref.scrollHeight, scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, scrollWidth = _ref.scrollWidth; this.setState({ clientHeight: clientHeight, clientWidth: clientWidth, scrollHeight: scrollHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: scrollWidth }); } } ]), ScrollSync; }(); function defaultCellDataGetter(_ref) { var dataKey = _ref.dataKey, rowData = _ref.rowData; return "function" == typeof rowData.get ? rowData.get(dataKey) : rowData[dataKey]; } function defaultCellRenderer(_ref) { var cellData = _ref.cellData; return null == cellData ? "" : String(cellData); } function defaultHeaderRowRenderer(_ref) { var className = _ref.className, columns = _ref.columns, style = _ref.style; return React.createElement("div", { className: className, role: "row", style: style }, columns); } _defineProperty(ScrollSync, "propTypes", { children: propTypes.func.isRequired }); var SortDirection = { ASC: "ASC", DESC: "DESC" }; function SortIndicator(_ref) { var sortDirection = _ref.sortDirection, classNames = clsx("ReactVirtualized__Table__sortableHeaderIcon", { "ReactVirtualized__Table__sortableHeaderIcon--ASC": sortDirection === SortDirection.ASC, "ReactVirtualized__Table__sortableHeaderIcon--DESC": sortDirection === SortDirection.DESC }); return React.createElement("svg", { className: classNames, width: 18, height: 18, viewBox: "0 0 24 24" }, sortDirection === SortDirection.ASC ? React.createElement("path", { d: "M7 14l5-5 5 5z" }) : React.createElement("path", { d: "M7 10l5 5 5-5z" }), React.createElement("path", { d: "M0 0h24v24H0z", fill: "none" })); } function defaultHeaderRenderer(_ref) { var dataKey = _ref.dataKey, label = _ref.label, sortBy = _ref.sortBy, sortDirection = _ref.sortDirection, showSortIndicator = sortBy === dataKey, children = [ React.createElement("span", { className: "ReactVirtualized__Table__headerTruncatedText", key: "label", title: "string" == typeof label ? label : null }, label) ]; return showSortIndicator && children.push(React.createElement(SortIndicator, { key: "SortIndicator", sortDirection: sortDirection })), children; } function defaultRowRenderer(_ref) { var className = _ref.className, columns = _ref.columns, index = _ref.index, key = _ref.key, onRowClick = _ref.onRowClick, onRowDoubleClick = _ref.onRowDoubleClick, onRowMouseOut = _ref.onRowMouseOut, onRowMouseOver = _ref.onRowMouseOver, onRowRightClick = _ref.onRowRightClick, rowData = _ref.rowData, style = _ref.style, a11yProps = { "aria-rowindex": index + 1 }; return (onRowClick || onRowDoubleClick || onRowMouseOut || onRowMouseOver || onRowRightClick) && (a11yProps["aria-label"] = "row", a11yProps.tabIndex = 0, onRowClick && (a11yProps.onClick = function(event) { return onRowClick({ event: event, index: index, rowData: rowData }); }), onRowDoubleClick && (a11yProps.onDoubleClick = function(event) { return onRowDoubleClick({ event: event, index: index, rowData: rowData }); }), onRowMouseOut && (a11yProps.onMouseOut = function(event) { return onRowMouseOut({ event: event, index: index, rowData: rowData }); }), onRowMouseOver && (a11yProps.onMouseOver = function(event) { return onRowMouseOver({ event: event, index: index, rowData: rowData }); }), onRowRightClick && (a11yProps.onContextMenu = function(event) { return onRowRightClick({ event: event, index: index, rowData: rowData }); })), React.createElement("div", _extends({}, a11yProps, { className: className, key: key, role: "row", style: style }), columns); } SortIndicator.propTypes = { sortDirection: propTypes.oneOf([ SortDirection.ASC, SortDirection.DESC ]) }; var Column = function() { function Column() { return _classCallCheck(this, Column), _possibleConstructorReturn(this, _getPrototypeOf(Column).apply(this, arguments)); } return _inherits(Column, React.Component), Column; }(); _defineProperty(Column, "propTypes", { "aria-label": propTypes.string, cellDataGetter: propTypes.func, cellRenderer: propTypes.func, className: propTypes.string, columnData: propTypes.object, dataKey: propTypes.any.isRequired, defaultSortDirection: propTypes.oneOf([ SortDirection.ASC, SortDirection.DESC ]), disableSort: propTypes.bool, flexGrow: propTypes.number, flexShrink: propTypes.number, headerClassName: propTypes.string, headerRenderer: propTypes.func.isRequired, headerStyle: propTypes.object, id: propTypes.string, label: propTypes.node, maxWidth: propTypes.number, minWidth: propTypes.number, style: propTypes.object, width: propTypes.number.isRequired }), _defineProperty(Column, "defaultProps", { cellDataGetter: defaultCellDataGetter, cellRenderer: defaultCellRenderer, defaultSortDirection: SortDirection.ASC, flexGrow: 0, flexShrink: 1, headerRenderer: defaultHeaderRenderer, style: {} }); var Table = function() { function Table(props) { var _this; return _classCallCheck(this, Table), (_this = _possibleConstructorReturn(this, _getPrototypeOf(Table).call(this, props))).state = { scrollbarWidth: 0 }, _this._createColumn = _this._createColumn.bind(_assertThisInitialized(_this)), _this._createRow = _this._createRow.bind(_assertThisInitialized(_this)), _this._onScroll = _this._onScroll.bind(_assertThisInitialized(_this)), _this._onSectionRendered = _this._onSectionRendered.bind(_assertThisInitialized(_this)), _this._setRef = _this._setRef.bind(_assertThisInitialized(_this)), _this; } return _inherits(Table, React.PureComponent), _createClass(Table, [ { key: "forceUpdateGrid", value: function() { this.Grid && this.Grid.forceUpdate(); } }, { key: "getOffsetForRow", value: function(_ref) { var alignment = _ref.alignment, index = _ref.index; return this.Grid ? this.Grid.getOffsetForCell({ alignment: alignment, rowIndex: index }).scrollTop : 0; } }, { key: "invalidateCellSizeAfterRender", value: function(_ref2) { var columnIndex = _ref2.columnIndex, rowIndex = _ref2.rowIndex; this.Grid && this.Grid.invalidateCellSizeAfterRender({ rowIndex: rowIndex, columnIndex: columnIndex }); } }, { key: "measureAllRows", value: function() { this.Grid && this.Grid.measureAllCells(); } }, { key: "recomputeGridSize", value: function(argument_0) { var _ref3 = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : {}, _ref3$columnIndex = _ref3.columnIndex, columnIndex = void 0 === _ref3$columnIndex ? 0 : _ref3$columnIndex, _ref3$rowIndex = _ref3.rowIndex, rowIndex = void 0 === _ref3$rowIndex ? 0 : _ref3$rowIndex; this.Grid && this.Grid.recomputeGridSize({ rowIndex: rowIndex, columnIndex: columnIndex }); } }, { key: "recomputeRowHeights", value: function(argument_0) { var index = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : 0; this.Grid && this.Grid.recomputeGridSize({ rowIndex: index }); } }, { key: "scrollToPosition", value: function(argument_0) { var scrollTop = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : 0; this.Grid && this.Grid.scrollToPosition({ scrollTop: scrollTop }); } }, { key: "scrollToRow", value: function(argument_0) { var index = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : 0; this.Grid && this.Grid.scrollToCell({ columnIndex: 0, rowIndex: index }); } }, { key: "getScrollbarWidth", value: function() { if (this.Grid) { var _Grid = ReactDOM.findDOMNode(this.Grid), clientWidth = _Grid.clientWidth || 0; return (_Grid.offsetWidth || 0) - clientWidth; } return 0; } }, { key: "componentDidMount", value: function() { this._setScrollbarWidth(); } }, { key: "componentDidUpdate", value: function() { this._setScrollbarWidth(); } }, { key: "render", value: function() { var _this2 = this, _this$props = this.props, children = _this$props.children, className = _this$props.className, disableHeader = _this$props.disableHeader, gridClassName = _this$props.gridClassName, gridStyle = _this$props.gridStyle, headerHeight = _this$props.headerHeight, headerRowRenderer = _this$props.headerRowRenderer, height = _this$props.height, id = _this$props.id, noRowsRenderer = _this$props.noRowsRenderer, rowClassName = _this$props.rowClassName, rowStyle = _this$props.rowStyle, scrollToIndex = _this$props.scrollToIndex, style = _this$props.style, width = _this$props.width, scrollbarWidth = this.state.scrollbarWidth, availableRowsHeight = disableHeader ? height : height - headerHeight, rowClass = "function" == typeof rowClassName ? rowClassName({ index: -1 }) : rowClassName, rowStyleObject = "function" == typeof rowStyle ? rowStyle({ index: -1 }) : rowStyle; return this._cachedColumnStyles = [], React.Children.toArray(children).forEach(function(column, index) { var flexStyles = _this2._getFlexStyleForColumn(column, column.props.style); _this2._cachedColumnStyles[index] = _objectSpread2({ overflow: "hidden" }, flexStyles); }), React.createElement("div", { "aria-label": this.props["aria-label"], "aria-labelledby": this.props["aria-labelledby"], "aria-colcount": React.Children.toArray(children).length, "aria-rowcount": this.props.rowCount, className: clsx("ReactVirtualized__Table", className), id: id, role: "grid", style: style }, !disableHeader && headerRowRenderer({ className: clsx("ReactVirtualized__Table__headerRow", rowClass), columns: this._getHeaderColumns(), style: _objectSpread2({ height: headerHeight, overflow: "hidden", paddingRight: scrollbarWidth, width: width }, rowStyleObject) }), React.createElement(Grid, _extends({}, this.props, { "aria-readonly": null, autoContainerWidth: !0, className: clsx("ReactVirtualized__Table__Grid", gridClassName), cellRenderer: this._createRow, columnWidth: width, columnCount: 1, height: availableRowsHeight, id: void 0, noContentRenderer: noRowsRenderer, onScroll: this._onScroll, onSectionRendered: this._onSectionRendered, ref: this._setRef, role: "rowgroup", scrollbarWidth: scrollbarWidth, scrollToRow: scrollToIndex, style: _objectSpread2({}, gridStyle, { overflowX: "hidden" }) }))); } }, { key: "_createColumn", value: function(_ref4) { var column = _ref4.column, columnIndex = _ref4.columnIndex, isScrolling = _ref4.isScrolling, parent = _ref4.parent, rowData = _ref4.rowData, rowIndex = _ref4.rowIndex, onColumnClick = this.props.onColumnClick, _column$props = column.props, cellDataGetter = _column$props.cellDataGetter, cellRenderer = _column$props.cellRenderer, className = _column$props.className, columnData = _column$props.columnData, dataKey = _column$props.dataKey, id = _column$props.id, renderedCell = cellRenderer({ cellData: cellDataGetter({ columnData: columnData, dataKey: dataKey, rowData: rowData }), columnData: columnData, columnIndex: columnIndex, dataKey: dataKey, isScrolling: isScrolling, parent: parent, rowData: rowData, rowIndex: rowIndex }), style = this._cachedColumnStyles[columnIndex], title = "string" == typeof renderedCell ? renderedCell : null; return React.createElement("div", { "aria-colindex": columnIndex + 1, "aria-describedby": id, className: clsx("ReactVirtualized__Table__rowColumn", className), key: "Row" + rowIndex + "-Col" + columnIndex, onClick: function(event) { onColumnClick && onColumnClick({ columnData: columnData, dataKey: dataKey, event: event }); }, role: "gridcell", style: style, title: title }, renderedCell); } }, { key: "_createHeader", value: function(_ref5) { var headerOnClick, headerOnKeyDown, headerTabIndex, headerAriaSort, headerAriaLabel, column = _ref5.column, index = _ref5.index, _this$props2 = this.props, headerClassName = _this$props2.headerClassName, headerStyle = _this$props2.headerStyle, onHeaderClick = _this$props2.onHeaderClick, sort = _this$props2.sort, sortBy = _this$props2.sortBy, sortDirection = _this$props2.sortDirection, _column$props2 = column.props, columnData = _column$props2.columnData, dataKey = _column$props2.dataKey, defaultSortDirection = _column$props2.defaultSortDirection, disableSort = _column$props2.disableSort, headerRenderer = _column$props2.headerRenderer, id = _column$props2.id, label = _column$props2.label, sortEnabled = !disableSort && sort, classNames = clsx("ReactVirtualized__Table__headerColumn", headerClassName, column.props.headerClassName, { ReactVirtualized__Table__sortableHeaderColumn: sortEnabled }), style = this._getFlexStyleForColumn(column, _objectSpread2({}, headerStyle, {}, column.props.headerStyle)), renderedHeader = headerRenderer({ columnData: columnData, dataKey: dataKey, disableSort: disableSort, label: label, sortBy: sortBy, sortDirection: sortDirection }); if (sortEnabled || onHeaderClick) { var newSortDirection = sortBy !== dataKey ? defaultSortDirection : sortDirection === SortDirection.DESC ? SortDirection.ASC : SortDirection.DESC, onClick = function(event) { sortEnabled && sort({ defaultSortDirection: defaultSortDirection, event: event, sortBy: dataKey, sortDirection: newSortDirection }), onHeaderClick && onHeaderClick({ columnData: columnData, dataKey: dataKey, event: event }); }; headerAriaLabel = column.props["aria-label"] || label || dataKey, headerAriaSort = "none", headerTabIndex = 0, headerOnClick = onClick, headerOnKeyDown = function(event) { "Enter" !== event.key && " " !== event.key || onClick(event); }; } return sortBy === dataKey && (headerAriaSort = sortDirection === SortDirection.ASC ? "ascending" : "descending"), React.createElement("div", { "aria-label": headerAriaLabel, "aria-sort": headerAriaSort, className: classNames, id: id, key: "Header-Col" + index, onClick: headerOnClick, onKeyDown: headerOnKeyDown, role: "columnheader", style: style, tabIndex: headerTabIndex }, renderedHeader); } }, { key: "_createRow", value: function(_ref6) { var _this3 = this, index = _ref6.rowIndex, isScrolling = _ref6.isScrolling, key = _ref6.key, parent = _ref6.parent, style = _ref6.style, _this$props3 = this.props, children = _this$props3.children, onRowClick = _this$props3.onRowClick, onRowDoubleClick = _this$props3.onRowDoubleClick, onRowRightClick = _this$props3.onRowRightClick, onRowMouseOver = _this$props3.onRowMouseOver, onRowMouseOut = _this$props3.onRowMouseOut, rowClassName = _this$props3.rowClassName, rowGetter = _this$props3.rowGetter, rowRenderer = _this$props3.rowRenderer, rowStyle = _this$props3.rowStyle, scrollbarWidth = this.state.scrollbarWidth, rowClass = "function" == typeof rowClassName ? rowClassName({ index: index }) : rowClassName, rowStyleObject = "function" == typeof rowStyle ? rowStyle({ index: index }) : rowStyle, rowData = rowGetter({ index: index }), columns = React.Children.toArray(children).map(function(column, columnIndex) { return _this3._createColumn({ column: column, columnIndex: columnIndex, isScrolling: isScrolling, parent: parent, rowData: rowData, rowIndex: index, scrollbarWidth: scrollbarWidth }); }), className = clsx("ReactVirtualized__Table__row", rowClass), flattenedStyle = _objectSpread2({}, style, { height: this._getRowHeight(index), overflow: "hidden", paddingRight: scrollbarWidth }, rowStyleObject); return rowRenderer({ className: className, columns: columns, index: index, isScrolling: isScrolling, key: key, onRowClick: onRowClick, onRowDoubleClick: onRowDoubleClick, onRowRightClick: onRowRightClick, onRowMouseOver: onRowMouseOver, onRowMouseOut: onRowMouseOut, rowData: rowData, style: flattenedStyle }); } }, { key: "_getFlexStyleForColumn", value: function(column, argument_1) { var customStyle = 1 < arguments.length && void 0 !== argument_1 ? argument_1 : {}, flexValue = "".concat(column.props.flexGrow, " ").concat(column.props.flexShrink, " ").concat(column.props.width, "px"), style = _objectSpread2({}, customStyle, { flex: flexValue, msFlex: flexValue, WebkitFlex: flexValue }); return column.props.maxWidth && (style.maxWidth = column.props.maxWidth), column.props.minWidth && (style.minWidth = column.props.minWidth), style; } }, { key: "_getHeaderColumns", value: function() { var _this4 = this, _this$props4 = this.props, children = _this$props4.children; return (_this$props4.disableHeader ? [] : React.Children.toArray(children)).map(function(column, index) { return _this4._createHeader({ column: column, index: index }); }); } }, { key: "_getRowHeight", value: function(rowIndex) { var rowHeight = this.props.rowHeight; return "function" == typeof rowHeight ? rowHeight({ index: rowIndex }) : rowHeight; } }, { key: "_onScroll", value: function(_ref7) { var clientHeight = _ref7.clientHeight, scrollHeight = _ref7.scrollHeight, scrollTop = _ref7.scrollTop; (0, this.props.onScroll)({ clientHeight: clientHeight, scrollHeight: scrollHeight, scrollTop: scrollTop }); } }, { key: "_onSectionRendered", value: function(_ref8) { var rowOverscanStartIndex = _ref8.rowOverscanStartIndex, rowOverscanStopIndex = _ref8.rowOverscanStopIndex, rowStartIndex = _ref8.rowStartIndex, rowStopIndex = _ref8.rowStopIndex; (0, this.props.onRowsRendered)({ overscanStartIndex: rowOverscanStartIndex, overscanStopIndex: rowOverscanStopIndex, startIndex: rowStartIndex, stopIndex: rowStopIndex }); } }, { key: "_setRef", value: function(ref) { this.Grid = ref; } }, { key: "_setScrollbarWidth", value: function() { var scrollbarWidth = this.getScrollbarWidth(); this.setState({ scrollbarWidth: scrollbarWidth }); } } ]), Table; }(); _defineProperty(Table, "propTypes", { "aria-label": propTypes.string, "aria-labelledby": propTypes.string, autoHeight: propTypes.bool, children: function(props) { for (var children = React.Children.toArray(props.children), i = 0; i < children.length; i++) { var childType = children[i].type; if (childType !== Column && !(childType.prototype instanceof Column)) return new Error("Table only accepts children of type Column"); } }, className: propTypes.string, disableHeader: propTypes.bool, estimatedRowSize: propTypes.number.isRequired, gridClassName: propTypes.string, gridStyle: propTypes.object, headerClassName: propTypes.string, headerHeight: propTypes.number.isRequired, headerRowRenderer: propTypes.func, headerStyle: propTypes.object, height: propTypes.number.isRequired, id: propTypes.string, noRowsRenderer: propTypes.func, onColumnClick: propTypes.func, onHeaderClick: propTypes.func, onRowClick: propTypes.func, onRowDoubleClick: propTypes.func, onRowMouseOut: propTypes.func, onRowMouseOver: propTypes.func, onRowRightClick: propTypes.func, onRowsRendered: propTypes.func, onScroll: propTypes.func.isRequired, overscanIndicesGetter: propTypes.func.isRequired, overscanRowCount: propTypes.number.isRequired, rowClassName: propTypes.oneOfType([ propTypes.string, propTypes.func ]), rowGetter: propTypes.func.isRequired, rowHeight: propTypes.oneOfType([ propTypes.number, propTypes.func ]).isRequired, rowCount: propTypes.number.isRequired, rowRenderer: propTypes.func, rowStyle: propTypes.oneOfType([ propTypes.object, propTypes.func ]).isRequired, scrollToAlignment: propTypes.oneOf([ "auto", "end", "start", "center" ]).isRequired, scrollToIndex: propTypes.number.isRequired, scrollTop: propTypes.number, sort: propTypes.func, sortBy: propTypes.string, sortDirection: propTypes.oneOf([ SortDirection.ASC, SortDirection.DESC ]), style: propTypes.object, tabIndex: propTypes.number, width: propTypes.number.isRequired }), _defineProperty(Table, "defaultProps", { disableHeader: !1, estimatedRowSize: 30, headerHeight: 0, headerStyle: {}, noRowsRenderer: function() { return null; }, onRowsRendered: function() { return null; }, onScroll: function() { return null; }, overscanIndicesGetter: defaultOverscanIndicesGetter$1, overscanRowCount: 10, rowRenderer: defaultRowRenderer, headerRowRenderer: defaultHeaderRowRenderer, rowStyle: {}, scrollToAlignment: "auto", scrollToIndex: -1, style: {} }); var mountedInstances = [], originalBodyPointerEvents = null, disablePointerEventsTimeoutId = null; function enablePointerEventsIfDisabled() { disablePointerEventsTimeoutId && (disablePointerEventsTimeoutId = null, document.body && null != originalBodyPointerEvents && (document.body.style.pointerEvents = originalBodyPointerEvents), originalBodyPointerEvents = null); } function enablePointerEventsAfterDelayCallback() { enablePointerEventsIfDisabled(), mountedInstances.forEach(function(instance) { return instance.__resetIsScrolling(); }); } function onScrollWindow(event) { event.currentTarget === window && null == originalBodyPointerEvents && document.body && (originalBodyPointerEvents = document.body.style.pointerEvents, document.body.style.pointerEvents = "none"), function() { disablePointerEventsTimeoutId && cancelAnimationTimeout(disablePointerEventsTimeoutId); var maximumTimeout = 0; mountedInstances.forEach(function(instance) { maximumTimeout = Math.max(maximumTimeout, instance.props.scrollingResetTimeInterval); }), disablePointerEventsTimeoutId = requestAnimationTimeout(enablePointerEventsAfterDelayCallback, maximumTimeout); }(), mountedInstances.forEach(function(instance) { instance.props.scrollElement === event.currentTarget && instance.__handleWindowScrollEvent(); }); } function registerScrollListener(component, element) { mountedInstances.some(function(instance) { return instance.props.scrollElement === element; }) || element.addEventListener("scroll", onScrollWindow), mountedInstances.push(component); } function unregisterScrollListener(component, element) { (mountedInstances = mountedInstances.filter(function(instance) { return instance !== component; })).length || (element.removeEventListener("scroll", onScrollWindow), disablePointerEventsTimeoutId && (cancelAnimationTimeout(disablePointerEventsTimeoutId), enablePointerEventsIfDisabled())); } var isWindow = function(element) { return element === window; }, getBoundingBox = function(element) { return element.getBoundingClientRect(); }; function getDimensions(scrollElement, props) { if (scrollElement) { if (isWindow(scrollElement)) { var _window = window, innerHeight = _window.innerHeight, innerWidth = _window.innerWidth; return { height: "number" == typeof innerHeight ? innerHeight : 0, width: "number" == typeof innerWidth ? innerWidth : 0 }; } return getBoundingBox(scrollElement); } return { height: props.serverHeight, width: props.serverWidth }; } function getScrollOffset(element) { return isWindow(element) && document.documentElement ? { top: "scrollY" in window ? window.scrollY : document.documentElement.scrollTop, left: "scrollX" in window ? window.scrollX : document.documentElement.scrollLeft } : { top: element.scrollTop, left: element.scrollLeft }; } var getWindow = function() { return "undefined" != typeof window ? window : void 0; }, WindowScroller = function() { function WindowScroller() { var _getPrototypeOf2, _this; _classCallCheck(this, WindowScroller); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) args[_key] = arguments[_key]; return _defineProperty(_assertThisInitialized(_this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(WindowScroller)).call.apply(_getPrototypeOf2, [ this ].concat(args)))), "_window", getWindow()), _defineProperty(_assertThisInitialized(_this), "_isMounted", !1), _defineProperty(_assertThisInitialized(_this), "_positionFromTop", 0), _defineProperty(_assertThisInitialized(_this), "_positionFromLeft", 0), _defineProperty(_assertThisInitialized(_this), "_detectElementResize", void 0), _defineProperty(_assertThisInitialized(_this), "_child", void 0), _defineProperty(_assertThisInitialized(_this), "state", _objectSpread2({}, getDimensions(_this.props.scrollElement, _this.props), { isScrolling: !1, scrollLeft: 0, scrollTop: 0 })), _defineProperty(_assertThisInitialized(_this), "_registerChild", function(element) { !element || element instanceof Element || console.warn("WindowScroller registerChild expects to be passed Element or null"), _this._child = element, _this.updatePosition(); }), _defineProperty(_assertThisInitialized(_this), "_onChildScroll", function(_ref) { var scrollTop = _ref.scrollTop; if (_this.state.scrollTop !== scrollTop) { var scrollElement = _this.props.scrollElement; scrollElement && ("function" == typeof scrollElement.scrollTo ? scrollElement.scrollTo(0, scrollTop + _this._positionFromTop) : scrollElement.scrollTop = scrollTop + _this._positionFromTop); } }), _defineProperty(_assertThisInitialized(_this), "_registerResizeListener", function(element) { element === window ? window.addEventListener("resize", _this._onResize, !1) : _this._detectElementResize.addResizeListener(element, _this._onResize); }), _defineProperty(_assertThisInitialized(_this), "_unregisterResizeListener", function(element) { element === window ? window.removeEventListener("resize", _this._onResize, !1) : element && _this._detectElementResize.removeResizeListener(element, _this._onResize); }), _defineProperty(_assertThisInitialized(_this), "_onResize", function() { _this.updatePosition(); }), _defineProperty(_assertThisInitialized(_this), "__handleWindowScrollEvent", function() { if (_this._isMounted) { var onScroll = _this.props.onScroll, scrollElement = _this.props.scrollElement; if (scrollElement) { var scrollOffset = getScrollOffset(scrollElement), scrollLeft = Math.max(0, scrollOffset.left - _this._positionFromLeft), scrollTop = Math.max(0, scrollOffset.top - _this._positionFromTop); _this.setState({ isScrolling: !0, scrollLeft: scrollLeft, scrollTop: scrollTop }), onScroll({ scrollLeft: scrollLeft, scrollTop: scrollTop }); } } }), _defineProperty(_assertThisInitialized(_this), "__resetIsScrolling", function() { _this.setState({ isScrolling: !1 }); }), _this; } return _inherits(WindowScroller, React.PureComponent), _createClass(WindowScroller, [ { key: "updatePosition", value: function(argument_0) { var scrollElement = 0 < arguments.length && void 0 !== argument_0 ? argument_0 : this.props.scrollElement, onResize = this.props.onResize, _this$state = this.state, height = _this$state.height, width = _this$state.width, thisNode = this._child || ReactDOM.findDOMNode(this); if (thisNode instanceof Element && scrollElement) { var offset = function(element, container) { if (isWindow(container) && document.documentElement) { var containerElement = document.documentElement, elementRect = getBoundingBox(element), containerRect = getBoundingBox(containerElement); return { top: elementRect.top - containerRect.top, left: elementRect.left - containerRect.left }; } var scrollOffset = getScrollOffset(container), _elementRect = getBoundingBox(element), _containerRect = getBoundingBox(container); return { top: _elementRect.top + scrollOffset.top - _containerRect.top, left: _elementRect.left + scrollOffset.left - _containerRect.left }; }(thisNode, scrollElement); this._positionFromTop = offset.top, this._positionFromLeft = offset.left; } var dimensions = getDimensions(scrollElement, this.props); height === dimensions.height && width === dimensions.width || (this.setState({ height: dimensions.height, width: dimensions.width }), onResize({ height: dimensions.height, width: dimensions.width })); } }, { key: "componentDidMount", value: function() { var scrollElement = this.props.scrollElement; this._detectElementResize = createDetectElementResize(), this.updatePosition(scrollElement), scrollElement && (registerScrollListener(this, scrollElement), this._registerResizeListener(scrollElement)), this._isMounted = !0; } }, { key: "componentDidUpdate", value: function(prevProps) { var scrollElement = this.props.scrollElement, prevScrollElement = prevProps.scrollElement; prevScrollElement !== scrollElement && null != prevScrollElement && null != scrollElement && (this.updatePosition(scrollElement), unregisterScrollListener(this, prevScrollElement), registerScrollListener(this, scrollElement), this._unregisterResizeListener(prevScrollElement), this._registerResizeListener(scrollElement)); } }, { key: "componentWillUnmount", value: function() { var scrollElement = this.props.scrollElement; scrollElement && (unregisterScrollListener(this, scrollElement), this._unregisterResizeListener(scrollElement)), this._isMounted = !1; } }, { key: "render", value: function() { var children = this.props.children, _this$state2 = this.state, isScrolling = _this$state2.isScrolling, scrollTop = _this$state2.scrollTop, scrollLeft = _this$state2.scrollLeft, height = _this$state2.height, width = _this$state2.width; return children({ onChildScroll: this._onChildScroll, registerChild: this._registerChild, height: height, isScrolling: isScrolling, scrollLeft: scrollLeft, scrollTop: scrollTop, width: width }); } } ]), WindowScroller; }(); _defineProperty(WindowScroller, "defaultProps", { onResize: function() {}, onScroll: function() {}, scrollingResetTimeInterval: 150, scrollElement: getWindow(), serverHeight: 0, serverWidth: 0 }), exports.ArrowKeyStepper = ArrowKeyStepper, exports.AutoSizer = AutoSizer, exports.CellMeasurer = CellMeasurer, exports.CellMeasurerCache = CellMeasurerCache, exports.Collection = Collection, exports.Column = Column, exports.ColumnSizer = ColumnSizer, exports.Grid = Grid, exports.InfiniteLoader = InfiniteLoader, exports.List = List, exports.Masonry = Masonry, exports.MultiGrid = MultiGrid, exports.ScrollSync = ScrollSync, exports.SortDirection = SortDirection, exports.SortIndicator = SortIndicator, exports.Table = Table, exports.WindowScroller = WindowScroller, exports.accessibilityOverscanIndicesGetter = defaultOverscanIndicesGetter$1, exports.createMasonryCellPositioner = function(_ref) { var columnHeights, cellMeasurerCache = _ref.cellMeasurerCache, columnCount = _ref.columnCount, columnWidth = _ref.columnWidth, _ref$spacer = _ref.spacer, spacer = void 0 === _ref$spacer ? 0 : _ref$spacer; function cellPositioner(index) { for (var columnIndex = 0, i = 1; i < columnHeights.length; i++) columnHeights[i] < columnHeights[columnIndex] && (columnIndex = i); var left = columnIndex * (columnWidth + spacer), top = columnHeights[columnIndex] || 0; return columnHeights[columnIndex] = top + cellMeasurerCache.getHeight(index) + spacer, { left: left, top: top }; } function initOrResetDerivedValues() { columnHeights = []; for (var i = 0; i < columnCount; i++) columnHeights[i] = 0; } return initOrResetDerivedValues(), cellPositioner.reset = function(params) { columnCount = params.columnCount, columnWidth = params.columnWidth, spacer = params.spacer, initOrResetDerivedValues(); }, cellPositioner; }, exports.createTableMultiSort = function(sortCallback) { var _ref = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {}, defaultSortBy = _ref.defaultSortBy, _ref$defaultSortDirec = _ref.defaultSortDirection, defaultSortDirection = void 0 === _ref$defaultSortDirec ? {} : _ref$defaultSortDirec; if (!sortCallback) throw Error('Required parameter "sortCallback" not specified'); var sortBy = defaultSortBy || [], sortDirection = {}; return sortBy.forEach(function(dataKey) { sortDirection[dataKey] = void 0 !== defaultSortDirection[dataKey] ? defaultSortDirection[dataKey] : "ASC"; }), { sort: function(_ref2) { var defaultSortDirection = _ref2.defaultSortDirection, event = _ref2.event, dataKey = _ref2.sortBy; if (event.shiftKey) void 0 !== sortDirection[dataKey] ? sortDirection[dataKey] = "ASC" === sortDirection[dataKey] ? "DESC" : "ASC" : (sortDirection[dataKey] = defaultSortDirection, sortBy.push(dataKey)); else if (event.ctrlKey || event.metaKey) { var index = sortBy.indexOf(dataKey); 0 <= index && (sortBy.splice(index, 1), delete sortDirection[dataKey]); } else { sortBy.length = 0, sortBy.push(dataKey), Object.keys(sortDirection).forEach(function(key) { key !== dataKey && delete sortDirection[key]; }), void 0 !== sortDirection[dataKey] ? sortDirection[dataKey] = "ASC" === sortDirection[dataKey] ? "DESC" : "ASC" : sortDirection[dataKey] = defaultSortDirection; } sortCallback({ sortBy: sortBy, sortDirection: sortDirection }); }, sortBy: sortBy, sortDirection: sortDirection }; }, exports.defaultCellRangeRenderer = defaultCellRangeRenderer, exports.defaultOverscanIndicesGetter = defaultOverscanIndicesGetter, exports.defaultTableCellDataGetter = defaultCellDataGetter, exports.defaultTableCellRenderer = defaultCellRenderer, exports.defaultTableHeaderRenderer = defaultHeaderRenderer, exports.defaultTableHeaderRowRenderer = defaultHeaderRowRenderer, exports.defaultTableRowRenderer = defaultRowRenderer, Object.defineProperty(exports, "__esModule", { value: !0 }); }); dist/commonjs/ScrollSync/ScrollSync.js000064400000006646151676725760014122 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); /** * HOC that simplifies the process of synchronizing scrolling between two or more virtualized components. */ var ScrollSync = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(ScrollSync, _React$PureComponent); function ScrollSync(props, context) { var _this; (0, _classCallCheck2["default"])(this, ScrollSync); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(ScrollSync).call(this, props, context)); _this.state = { clientHeight: 0, clientWidth: 0, scrollHeight: 0, scrollLeft: 0, scrollTop: 0, scrollWidth: 0 }; _this._onScroll = _this._onScroll.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(ScrollSync, [{ key: "render", value: function render() { var children = this.props.children; var _this$state = this.state, clientHeight = _this$state.clientHeight, clientWidth = _this$state.clientWidth, scrollHeight = _this$state.scrollHeight, scrollLeft = _this$state.scrollLeft, scrollTop = _this$state.scrollTop, scrollWidth = _this$state.scrollWidth; return children({ clientHeight: clientHeight, clientWidth: clientWidth, onScroll: this._onScroll, scrollHeight: scrollHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: scrollWidth }); } }, { key: "_onScroll", value: function _onScroll(_ref) { var clientHeight = _ref.clientHeight, clientWidth = _ref.clientWidth, scrollHeight = _ref.scrollHeight, scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, scrollWidth = _ref.scrollWidth; this.setState({ clientHeight: clientHeight, clientWidth: clientWidth, scrollHeight: scrollHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: scrollWidth }); } }]); return ScrollSync; }(React.PureComponent); exports["default"] = ScrollSync; ScrollSync.propTypes = process.env.NODE_ENV !== "production" ? { /** * Function responsible for rendering 2 or more virtualized components. * This function should implement the following signature: * ({ onScroll, scrollLeft, scrollTop }) => PropTypes.element */ children: _propTypes["default"].func.isRequired } : {};dist/commonjs/ScrollSync/index.js000064400000000724151676725760013125 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "ScrollSync", { enumerable: true, get: function get() { return _ScrollSync["default"]; } }); exports["default"] = void 0; var _ScrollSync = _interopRequireDefault(require("./ScrollSync")); var _default = _ScrollSync["default"]; exports["default"] = _default;dist/commonjs/ScrollSync/ScrollSync.example.js000064400000026020151676725760015540 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var React = _interopRequireWildcard(require("react")); var _ContentBox = require("../demo/ContentBox"); var _AutoSizer = _interopRequireDefault(require("../AutoSizer")); var _Grid = _interopRequireDefault(require("../Grid")); var _ScrollSync = _interopRequireDefault(require("./ScrollSync")); var _clsx = _interopRequireDefault(require("clsx")); var _ScrollSyncExample = _interopRequireDefault(require("./ScrollSync.example.css")); var _scrollbarSize = _interopRequireDefault(require("dom-helpers/scrollbarSize")); var LEFT_COLOR_FROM = hexToRgb('#471061'); var LEFT_COLOR_TO = hexToRgb('#BC3959'); var TOP_COLOR_FROM = hexToRgb('#000000'); var TOP_COLOR_TO = hexToRgb('#333333'); var GridExample = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(GridExample, _React$PureComponent); function GridExample(props, context) { var _this; (0, _classCallCheck2["default"])(this, GridExample); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(GridExample).call(this, props, context)); _this.state = { columnWidth: 75, columnCount: 50, height: 300, overscanColumnCount: 0, overscanRowCount: 5, rowHeight: 40, rowCount: 100 }; _this._renderBodyCell = _this._renderBodyCell.bind((0, _assertThisInitialized2["default"])(_this)); _this._renderHeaderCell = _this._renderHeaderCell.bind((0, _assertThisInitialized2["default"])(_this)); _this._renderLeftSideCell = _this._renderLeftSideCell.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(GridExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, columnCount = _this$state.columnCount, columnWidth = _this$state.columnWidth, height = _this$state.height, overscanColumnCount = _this$state.overscanColumnCount, overscanRowCount = _this$state.overscanRowCount, rowHeight = _this$state.rowHeight, rowCount = _this$state.rowCount; return React.createElement(_ContentBox.ContentBox, null, React.createElement(_ContentBox.ContentBoxHeader, { text: "ScrollSync", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/ScrollSync/ScrollSync.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/ScrollSync.md" }), React.createElement(_ContentBox.ContentBoxParagraph, null, "High order component that simplifies the process of synchronizing scrolling between two or more virtualized components."), React.createElement(_ContentBox.ContentBoxParagraph, null, "This example shows two ", React.createElement("code", null, "Grid"), "s and one ", React.createElement("code", null, "List"), ' ', "configured to mimic a spreadsheet with a fixed header and first column. It also shows how a scroll callback can be used to control UI properties such as background color."), React.createElement(_ScrollSync["default"], null, function (_ref) { var clientHeight = _ref.clientHeight, clientWidth = _ref.clientWidth, onScroll = _ref.onScroll, scrollHeight = _ref.scrollHeight, scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, scrollWidth = _ref.scrollWidth; var x = scrollLeft / (scrollWidth - clientWidth); var y = scrollTop / (scrollHeight - clientHeight); var leftBackgroundColor = mixColors(LEFT_COLOR_FROM, LEFT_COLOR_TO, y); var leftColor = '#ffffff'; var topBackgroundColor = mixColors(TOP_COLOR_FROM, TOP_COLOR_TO, x); var topColor = '#ffffff'; var middleBackgroundColor = mixColors(leftBackgroundColor, topBackgroundColor, 0.5); var middleColor = '#ffffff'; return React.createElement("div", { className: _ScrollSyncExample["default"].GridRow }, React.createElement("div", { className: _ScrollSyncExample["default"].LeftSideGridContainer, style: { position: 'absolute', left: 0, top: 0, color: leftColor, backgroundColor: "rgb(".concat(topBackgroundColor.r, ",").concat(topBackgroundColor.g, ",").concat(topBackgroundColor.b, ")") } }, React.createElement(_Grid["default"], { cellRenderer: _this2._renderLeftHeaderCell, className: _ScrollSyncExample["default"].HeaderGrid, width: columnWidth, height: rowHeight, rowHeight: rowHeight, columnWidth: columnWidth, rowCount: 1, columnCount: 1 })), React.createElement("div", { className: _ScrollSyncExample["default"].LeftSideGridContainer, style: { position: 'absolute', left: 0, top: rowHeight, color: leftColor, backgroundColor: "rgb(".concat(leftBackgroundColor.r, ",").concat(leftBackgroundColor.g, ",").concat(leftBackgroundColor.b, ")") } }, React.createElement(_Grid["default"], { overscanColumnCount: overscanColumnCount, overscanRowCount: overscanRowCount, cellRenderer: _this2._renderLeftSideCell, columnWidth: columnWidth, columnCount: 1, className: _ScrollSyncExample["default"].LeftSideGrid, height: height - (0, _scrollbarSize["default"])(), rowHeight: rowHeight, rowCount: rowCount, scrollTop: scrollTop, width: columnWidth })), React.createElement("div", { className: _ScrollSyncExample["default"].GridColumn }, React.createElement(_AutoSizer["default"], { disableHeight: true }, function (_ref2) { var width = _ref2.width; return React.createElement("div", null, React.createElement("div", { style: { backgroundColor: "rgb(".concat(topBackgroundColor.r, ",").concat(topBackgroundColor.g, ",").concat(topBackgroundColor.b, ")"), color: topColor, height: rowHeight, width: width - (0, _scrollbarSize["default"])() } }, React.createElement(_Grid["default"], { className: _ScrollSyncExample["default"].HeaderGrid, columnWidth: columnWidth, columnCount: columnCount, height: rowHeight, overscanColumnCount: overscanColumnCount, cellRenderer: _this2._renderHeaderCell, rowHeight: rowHeight, rowCount: 1, scrollLeft: scrollLeft, width: width - (0, _scrollbarSize["default"])() })), React.createElement("div", { style: { backgroundColor: "rgb(".concat(middleBackgroundColor.r, ",").concat(middleBackgroundColor.g, ",").concat(middleBackgroundColor.b, ")"), color: middleColor, height: height, width: width } }, React.createElement(_Grid["default"], { className: _ScrollSyncExample["default"].BodyGrid, columnWidth: columnWidth, columnCount: columnCount, height: height, onScroll: onScroll, overscanColumnCount: overscanColumnCount, overscanRowCount: overscanRowCount, cellRenderer: _this2._renderBodyCell, rowHeight: rowHeight, rowCount: rowCount, width: width }))); }))); })); } }, { key: "_renderBodyCell", value: function _renderBodyCell(_ref3) { var columnIndex = _ref3.columnIndex, key = _ref3.key, rowIndex = _ref3.rowIndex, style = _ref3.style; if (columnIndex < 1) { return; } return this._renderLeftSideCell({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } }, { key: "_renderHeaderCell", value: function _renderHeaderCell(_ref4) { var columnIndex = _ref4.columnIndex, key = _ref4.key, rowIndex = _ref4.rowIndex, style = _ref4.style; if (columnIndex < 1) { return; } return this._renderLeftHeaderCell({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } }, { key: "_renderLeftHeaderCell", value: function _renderLeftHeaderCell(_ref5) { var columnIndex = _ref5.columnIndex, key = _ref5.key, style = _ref5.style; return React.createElement("div", { className: _ScrollSyncExample["default"].headerCell, key: key, style: style }, "C".concat(columnIndex)); } }, { key: "_renderLeftSideCell", value: function _renderLeftSideCell(_ref6) { var columnIndex = _ref6.columnIndex, key = _ref6.key, rowIndex = _ref6.rowIndex, style = _ref6.style; var rowClass = rowIndex % 2 === 0 ? columnIndex % 2 === 0 ? _ScrollSyncExample["default"].evenRow : _ScrollSyncExample["default"].oddRow : columnIndex % 2 !== 0 ? _ScrollSyncExample["default"].evenRow : _ScrollSyncExample["default"].oddRow; var classNames = (0, _clsx["default"])(rowClass, _ScrollSyncExample["default"].cell); return React.createElement("div", { className: classNames, key: key, style: style }, "R".concat(rowIndex, ", C").concat(columnIndex)); } }]); return GridExample; }(React.PureComponent); exports["default"] = GridExample; function hexToRgb(hex) { var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; } /** * Ported from sass implementation in C * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 */ function mixColors(color1, color2, amount) { var weight1 = amount; var weight2 = 1 - amount; var r = Math.round(weight1 * color1.r + weight2 * color2.r); var g = Math.round(weight1 * color1.g + weight2 * color2.g); var b = Math.round(weight1 * color1.b + weight2 * color2.b); return { r: r, g: g, b: b }; }dist/commonjs/ScrollSync/ScrollSync.jest.js000064400000006314151676725760015056 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _TestUtils = require("../TestUtils"); var _ScrollSync = _interopRequireDefault(require("./ScrollSync")); function ChildComponent(_ref) { var clientHeight = _ref.clientHeight, clientWidth = _ref.clientWidth, scrollHeight = _ref.scrollHeight, scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, scrollWidth = _ref.scrollWidth; return React.createElement("div", null, "clientHeight:".concat(clientHeight), "clientWidth:".concat(clientWidth), "scrollHeight:".concat(scrollHeight), "scrollLeft:".concat(scrollLeft), "scrollTop:".concat(scrollTop), "scrollWidth:".concat(scrollWidth)); } describe('ScrollSync', function () { it('should pass through an initial value of 0 for :scrollLeft and :scrollTop', function () { var component = (0, _TestUtils.render)(React.createElement(_ScrollSync["default"], null, function (_ref2) { var clientHeight = _ref2.clientHeight, clientWidth = _ref2.clientWidth, scrollHeight = _ref2.scrollHeight, scrollLeft = _ref2.scrollLeft, scrollTop = _ref2.scrollTop, scrollWidth = _ref2.scrollWidth; return React.createElement(ChildComponent, { clientHeight: clientHeight, clientWidth: clientWidth, scrollHeight: scrollHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: scrollWidth }); })); expect((0, _reactDom.findDOMNode)(component).textContent).toContain('clientHeight:0'); expect((0, _reactDom.findDOMNode)(component).textContent).toContain('clientWidth:0'); expect((0, _reactDom.findDOMNode)(component).textContent).toContain('scrollHeight:0'); expect((0, _reactDom.findDOMNode)(component).textContent).toContain('scrollLeft:0'); expect((0, _reactDom.findDOMNode)(component).textContent).toContain('scrollTop:0'); expect((0, _reactDom.findDOMNode)(component).textContent).toContain('scrollWidth:0'); }); it('should update :scrollLeft and :scrollTop when :onScroll is called', function () { var onScroll; var component = (0, _TestUtils.render)(React.createElement(_ScrollSync["default"], null, function (params) { onScroll = params.onScroll; return React.createElement(ChildComponent, params); })); onScroll({ clientHeight: 400, clientWidth: 200, scrollHeight: 1000, scrollLeft: 50, scrollTop: 100, scrollWidth: 500 }); expect((0, _reactDom.findDOMNode)(component).textContent).toContain('clientHeight:400'); expect((0, _reactDom.findDOMNode)(component).textContent).toContain('clientWidth:200'); expect((0, _reactDom.findDOMNode)(component).textContent).toContain('scrollHeight:1000'); expect((0, _reactDom.findDOMNode)(component).textContent).toContain('scrollLeft:50'); expect((0, _reactDom.findDOMNode)(component).textContent).toContain('scrollTop:100'); expect((0, _reactDom.findDOMNode)(component).textContent).toContain('scrollWidth:500'); }); });dist/commonjs/Masonry/Masonry.js000064400000051122151676725760013001 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports.bpfrpt_proptype_Positioner = exports.bpfrpt_proptype_CellMeasurerCache = exports["default"] = exports.DEFAULT_SCROLLING_RESET_TIME_INTERVAL = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _clsx = _interopRequireDefault(require("clsx")); var React = _interopRequireWildcard(require("react")); var _reactLifecyclesCompat = require("react-lifecycles-compat"); var _PositionCache = _interopRequireDefault(require("./PositionCache")); var _requestAnimationTimeout = require("../utils/requestAnimationTimeout"); var _propTypes = _interopRequireDefault(require("prop-types")); var _class, _temp; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var emptyObject = {}; /** * Specifies the number of miliseconds during which to disable pointer events while a scroll is in progress. * This improves performance and makes scrolling smoother. */ var DEFAULT_SCROLLING_RESET_TIME_INTERVAL = 150; /** * This component efficiently displays arbitrarily positioned cells using windowing techniques. * Cell position is determined by an injected `cellPositioner` property. * Windowing is vertical; this component does not support horizontal scrolling. * * Rendering occurs in two phases: * 1) First pass uses estimated cell sizes (provided by the cache) to determine how many cells to measure in a batch. * Batch size is chosen using a fast, naive layout algorithm that stacks images in order until the viewport has been filled. * After measurement is complete (componentDidMount or componentDidUpdate) this component evaluates positioned cells * in order to determine if another measurement pass is required (eg if actual cell sizes were less than estimated sizes). * All measurements are permanently cached (keyed by `keyMapper`) for performance purposes. * 2) Second pass uses the external `cellPositioner` to layout cells. * At this time the positioner has access to cached size measurements for all cells. * The positions it returns are cached by Masonry for fast access later. * Phase one is repeated if the user scrolls beyond the current layout's bounds. * If the layout is invalidated due to eg a resize, cached positions can be cleared using `recomputeCellPositions()`. * * Animation constraints: * Simple animations are supported (eg translate/slide into place on initial reveal). * More complex animations are not (eg flying from one position to another on resize). * * Layout constraints: * This component supports multi-column layout. * The height of each item may vary. * The width of each item must not exceed the width of the column it is "in". * The left position of all items within a column must align. * (Items may not span multiple columns.) */ exports.DEFAULT_SCROLLING_RESET_TIME_INTERVAL = DEFAULT_SCROLLING_RESET_TIME_INTERVAL; var Masonry = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(Masonry, _React$PureComponent); function Masonry() { var _getPrototypeOf2; var _this; (0, _classCallCheck2["default"])(this, Masonry); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(Masonry)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", { isScrolling: false, scrollTop: 0 }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_debounceResetIsScrollingId", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_invalidateOnUpdateStartIndex", null); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_invalidateOnUpdateStopIndex", null); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_positionCache", new _PositionCache["default"]()); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_startIndex", null); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_startIndexMemoized", null); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_stopIndex", null); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_stopIndexMemoized", null); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_debounceResetIsScrollingCallback", function () { _this.setState({ isScrolling: false }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_setScrollingContainerRef", function (ref) { _this._scrollingContainer = ref; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onScroll", function (event) { var height = _this.props.height; var eventScrollTop = event.currentTarget.scrollTop; // When this component is shrunk drastically, React dispatches a series of back-to-back scroll events, // Gradually converging on a scrollTop that is within the bounds of the new, smaller height. // This causes a series of rapid renders that is slow for long lists. // We can avoid that by doing some simple bounds checking to ensure that scroll offsets never exceed their bounds. var scrollTop = Math.min(Math.max(0, _this._getEstimatedTotalHeight() - height), eventScrollTop); // On iOS, we can arrive at negative offsets by swiping past the start or end. // Avoid re-rendering in this case as it can cause problems; see #532 for more. if (eventScrollTop !== scrollTop) { return; } // Prevent pointer events from interrupting a smooth scroll _this._debounceResetIsScrolling(); // Certain devices (like Apple touchpad) rapid-fire duplicate events. // Don't force a re-render if this is the case. // The mouse may move faster then the animation frame does. // Use requestAnimationFrame to avoid over-updating. if (_this.state.scrollTop !== scrollTop) { _this.setState({ isScrolling: true, scrollTop: scrollTop }); } }); return _this; } (0, _createClass2["default"])(Masonry, [{ key: "clearCellPositions", value: function clearCellPositions() { this._positionCache = new _PositionCache["default"](); this.forceUpdate(); } // HACK This method signature was intended for Grid }, { key: "invalidateCellSizeAfterRender", value: function invalidateCellSizeAfterRender(_ref) { var index = _ref.rowIndex; if (this._invalidateOnUpdateStartIndex === null) { this._invalidateOnUpdateStartIndex = index; this._invalidateOnUpdateStopIndex = index; } else { this._invalidateOnUpdateStartIndex = Math.min(this._invalidateOnUpdateStartIndex, index); this._invalidateOnUpdateStopIndex = Math.max(this._invalidateOnUpdateStopIndex, index); } } }, { key: "recomputeCellPositions", value: function recomputeCellPositions() { var stopIndex = this._positionCache.count - 1; this._positionCache = new _PositionCache["default"](); this._populatePositionCache(0, stopIndex); this.forceUpdate(); } }, { key: "componentDidMount", value: function componentDidMount() { this._checkInvalidateOnUpdate(); this._invokeOnScrollCallback(); this._invokeOnCellsRenderedCallback(); } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { this._checkInvalidateOnUpdate(); this._invokeOnScrollCallback(); this._invokeOnCellsRenderedCallback(); if (this.props.scrollTop !== prevProps.scrollTop) { this._debounceResetIsScrolling(); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this._debounceResetIsScrollingId) { (0, _requestAnimationTimeout.cancelAnimationTimeout)(this._debounceResetIsScrollingId); } } }, { key: "render", value: function render() { var _this2 = this; var _this$props = this.props, autoHeight = _this$props.autoHeight, cellCount = _this$props.cellCount, cellMeasurerCache = _this$props.cellMeasurerCache, cellRenderer = _this$props.cellRenderer, className = _this$props.className, height = _this$props.height, id = _this$props.id, keyMapper = _this$props.keyMapper, overscanByPixels = _this$props.overscanByPixels, role = _this$props.role, style = _this$props.style, tabIndex = _this$props.tabIndex, width = _this$props.width, rowDirection = _this$props.rowDirection; var _this$state = this.state, isScrolling = _this$state.isScrolling, scrollTop = _this$state.scrollTop; var children = []; var estimateTotalHeight = this._getEstimatedTotalHeight(); var shortestColumnSize = this._positionCache.shortestColumnSize; var measuredCellCount = this._positionCache.count; var startIndex = 0; var stopIndex; this._positionCache.range(Math.max(0, scrollTop - overscanByPixels), height + overscanByPixels * 2, function (index, left, top) { var _style; if (typeof stopIndex === 'undefined') { startIndex = index; stopIndex = index; } else { startIndex = Math.min(startIndex, index); stopIndex = Math.max(stopIndex, index); } children.push(cellRenderer({ index: index, isScrolling: isScrolling, key: keyMapper(index), parent: _this2, style: (_style = { height: cellMeasurerCache.getHeight(index) }, (0, _defineProperty2["default"])(_style, rowDirection === 'ltr' ? 'left' : 'right', left), (0, _defineProperty2["default"])(_style, "position", 'absolute'), (0, _defineProperty2["default"])(_style, "top", top), (0, _defineProperty2["default"])(_style, "width", cellMeasurerCache.getWidth(index)), _style) })); }); // We need to measure additional cells for this layout if (shortestColumnSize < scrollTop + height + overscanByPixels && measuredCellCount < cellCount) { var batchSize = Math.min(cellCount - measuredCellCount, Math.ceil((scrollTop + height + overscanByPixels - shortestColumnSize) / cellMeasurerCache.defaultHeight * width / cellMeasurerCache.defaultWidth)); for (var _index = measuredCellCount; _index < measuredCellCount + batchSize; _index++) { stopIndex = _index; children.push(cellRenderer({ index: _index, isScrolling: isScrolling, key: keyMapper(_index), parent: this, style: { width: cellMeasurerCache.getWidth(_index) } })); } } this._startIndex = startIndex; this._stopIndex = stopIndex; return React.createElement("div", { ref: this._setScrollingContainerRef, "aria-label": this.props['aria-label'], className: (0, _clsx["default"])('ReactVirtualized__Masonry', className), id: id, onScroll: this._onScroll, role: role, style: _objectSpread({ boxSizing: 'border-box', direction: 'ltr', height: autoHeight ? 'auto' : height, overflowX: 'hidden', overflowY: estimateTotalHeight < height ? 'hidden' : 'auto', position: 'relative', width: width, WebkitOverflowScrolling: 'touch', willChange: 'transform' }, style), tabIndex: tabIndex }, React.createElement("div", { className: "ReactVirtualized__Masonry__innerScrollContainer", style: { width: '100%', height: estimateTotalHeight, maxWidth: '100%', maxHeight: estimateTotalHeight, overflow: 'hidden', pointerEvents: isScrolling ? 'none' : '', position: 'relative' } }, children)); } }, { key: "_checkInvalidateOnUpdate", value: function _checkInvalidateOnUpdate() { if (typeof this._invalidateOnUpdateStartIndex === 'number') { var startIndex = this._invalidateOnUpdateStartIndex; var stopIndex = this._invalidateOnUpdateStopIndex; this._invalidateOnUpdateStartIndex = null; this._invalidateOnUpdateStopIndex = null; // Query external layout logic for position of newly-measured cells this._populatePositionCache(startIndex, stopIndex); this.forceUpdate(); } } }, { key: "_debounceResetIsScrolling", value: function _debounceResetIsScrolling() { var scrollingResetTimeInterval = this.props.scrollingResetTimeInterval; if (this._debounceResetIsScrollingId) { (0, _requestAnimationTimeout.cancelAnimationTimeout)(this._debounceResetIsScrollingId); } this._debounceResetIsScrollingId = (0, _requestAnimationTimeout.requestAnimationTimeout)(this._debounceResetIsScrollingCallback, scrollingResetTimeInterval); } }, { key: "_getEstimatedTotalHeight", value: function _getEstimatedTotalHeight() { var _this$props2 = this.props, cellCount = _this$props2.cellCount, cellMeasurerCache = _this$props2.cellMeasurerCache, width = _this$props2.width; var estimatedColumnCount = Math.max(1, Math.floor(width / cellMeasurerCache.defaultWidth)); return this._positionCache.estimateTotalHeight(cellCount, estimatedColumnCount, cellMeasurerCache.defaultHeight); } }, { key: "_invokeOnScrollCallback", value: function _invokeOnScrollCallback() { var _this$props3 = this.props, height = _this$props3.height, onScroll = _this$props3.onScroll; var scrollTop = this.state.scrollTop; if (this._onScrollMemoized !== scrollTop) { onScroll({ clientHeight: height, scrollHeight: this._getEstimatedTotalHeight(), scrollTop: scrollTop }); this._onScrollMemoized = scrollTop; } } }, { key: "_invokeOnCellsRenderedCallback", value: function _invokeOnCellsRenderedCallback() { if (this._startIndexMemoized !== this._startIndex || this._stopIndexMemoized !== this._stopIndex) { var onCellsRendered = this.props.onCellsRendered; onCellsRendered({ startIndex: this._startIndex, stopIndex: this._stopIndex }); this._startIndexMemoized = this._startIndex; this._stopIndexMemoized = this._stopIndex; } } }, { key: "_populatePositionCache", value: function _populatePositionCache(startIndex, stopIndex) { var _this$props4 = this.props, cellMeasurerCache = _this$props4.cellMeasurerCache, cellPositioner = _this$props4.cellPositioner; for (var _index2 = startIndex; _index2 <= stopIndex; _index2++) { var _cellPositioner = cellPositioner(_index2), left = _cellPositioner.left, top = _cellPositioner.top; this._positionCache.setPosition(_index2, left, top, cellMeasurerCache.getHeight(_index2)); } } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps, prevState) { if (nextProps.scrollTop !== undefined && prevState.scrollTop !== nextProps.scrollTop) { return { isScrolling: true, scrollTop: nextProps.scrollTop }; } return null; } }]); return Masonry; }(React.PureComponent), (0, _defineProperty2["default"])(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { "autoHeight": _propTypes["default"].bool.isRequired, "cellCount": _propTypes["default"].number.isRequired, "cellMeasurerCache": function cellMeasurerCache() { return (typeof CellMeasurerCache === "function" ? _propTypes["default"].instanceOf(CellMeasurerCache).isRequired : _propTypes["default"].any.isRequired).apply(this, arguments); }, "cellPositioner": function cellPositioner() { return (typeof Positioner === "function" ? _propTypes["default"].instanceOf(Positioner).isRequired : _propTypes["default"].any.isRequired).apply(this, arguments); }, "cellRenderer": function cellRenderer() { return (typeof CellRenderer === "function" ? _propTypes["default"].instanceOf(CellRenderer).isRequired : _propTypes["default"].any.isRequired).apply(this, arguments); }, "className": _propTypes["default"].string, "height": _propTypes["default"].number.isRequired, "id": _propTypes["default"].string, "keyMapper": function keyMapper() { return (typeof KeyMapper === "function" ? _propTypes["default"].instanceOf(KeyMapper).isRequired : _propTypes["default"].any.isRequired).apply(this, arguments); }, "onCellsRendered": function onCellsRendered() { return (typeof OnCellsRenderedCallback === "function" ? _propTypes["default"].instanceOf(OnCellsRenderedCallback) : _propTypes["default"].any).apply(this, arguments); }, "onScroll": function onScroll() { return (typeof OnScrollCallback === "function" ? _propTypes["default"].instanceOf(OnScrollCallback) : _propTypes["default"].any).apply(this, arguments); }, "overscanByPixels": _propTypes["default"].number.isRequired, "role": _propTypes["default"].string.isRequired, "scrollingResetTimeInterval": _propTypes["default"].number.isRequired, "style": function style(props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } }, "tabIndex": _propTypes["default"].number.isRequired, "width": _propTypes["default"].number.isRequired, "rowDirection": _propTypes["default"].string.isRequired, "scrollTop": _propTypes["default"].number }), _temp); (0, _defineProperty2["default"])(Masonry, "defaultProps", { autoHeight: false, keyMapper: identity, onCellsRendered: noop, onScroll: noop, overscanByPixels: 20, role: 'grid', scrollingResetTimeInterval: DEFAULT_SCROLLING_RESET_TIME_INTERVAL, style: emptyObject, tabIndex: 0, rowDirection: 'ltr' }); function identity(value) { return value; } function noop() {} var bpfrpt_proptype_CellMeasurerCache = process.env.NODE_ENV === 'production' ? null : { "defaultHeight": _propTypes["default"].number.isRequired, "defaultWidth": _propTypes["default"].number.isRequired, "getHeight": _propTypes["default"].func.isRequired, "getWidth": _propTypes["default"].func.isRequired }; exports.bpfrpt_proptype_CellMeasurerCache = bpfrpt_proptype_CellMeasurerCache; (0, _reactLifecyclesCompat.polyfill)(Masonry); var _default = Masonry; exports["default"] = _default; var bpfrpt_proptype_Positioner = process.env.NODE_ENV === 'production' ? null : _propTypes["default"].func; exports.bpfrpt_proptype_Positioner = bpfrpt_proptype_Positioner;dist/commonjs/Masonry/createCellPositioner.js000064400000002654151676725760015476 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = createCellPositioner; var _Masonry = require("./Masonry"); function createCellPositioner(_ref) { var cellMeasurerCache = _ref.cellMeasurerCache, columnCount = _ref.columnCount, columnWidth = _ref.columnWidth, _ref$spacer = _ref.spacer, spacer = _ref$spacer === void 0 ? 0 : _ref$spacer; var columnHeights; initOrResetDerivedValues(); function cellPositioner(index) { // Find the shortest column and use it. var columnIndex = 0; for (var i = 1; i < columnHeights.length; i++) { if (columnHeights[i] < columnHeights[columnIndex]) { columnIndex = i; } } var left = columnIndex * (columnWidth + spacer); var top = columnHeights[columnIndex] || 0; columnHeights[columnIndex] = top + cellMeasurerCache.getHeight(index) + spacer; return { left: left, top: top }; } function initOrResetDerivedValues() { // Track the height of each column. // Layout algorithm below always inserts into the shortest column. columnHeights = []; for (var i = 0; i < columnCount; i++) { columnHeights[i] = 0; } } function reset(params) { columnCount = params.columnCount; columnWidth = params.columnWidth; spacer = params.spacer; initOrResetDerivedValues(); } cellPositioner.reset = reset; return cellPositioner; }dist/commonjs/Masonry/PositionCache.js000064400000006266151676725760014112 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _intervalTree = _interopRequireDefault(require("../vendor/intervalTree")); // Position cache requirements: // O(log(n)) lookup of cells to render for a given viewport size // O(1) lookup of shortest measured column (so we know when to enter phase 1) var PositionCache = /*#__PURE__*/ function () { function PositionCache() { (0, _classCallCheck2["default"])(this, PositionCache); (0, _defineProperty2["default"])(this, "_columnSizeMap", {}); (0, _defineProperty2["default"])(this, "_intervalTree", (0, _intervalTree["default"])()); (0, _defineProperty2["default"])(this, "_leftMap", {}); } (0, _createClass2["default"])(PositionCache, [{ key: "estimateTotalHeight", value: function estimateTotalHeight(cellCount, columnCount, defaultCellHeight) { var unmeasuredCellCount = cellCount - this.count; return this.tallestColumnSize + Math.ceil(unmeasuredCellCount / columnCount) * defaultCellHeight; } // Render all cells visible within the viewport range defined. }, { key: "range", value: function range(scrollTop, clientHeight, renderCallback) { var _this = this; this._intervalTree.queryInterval(scrollTop, scrollTop + clientHeight, function (_ref) { var _ref2 = (0, _slicedToArray2["default"])(_ref, 3), top = _ref2[0], _ = _ref2[1], index = _ref2[2]; return renderCallback(index, _this._leftMap[index], top); }); } }, { key: "setPosition", value: function setPosition(index, left, top, height) { this._intervalTree.insert([top, top + height, index]); this._leftMap[index] = left; var columnSizeMap = this._columnSizeMap; var columnHeight = columnSizeMap[left]; if (columnHeight === undefined) { columnSizeMap[left] = top + height; } else { columnSizeMap[left] = Math.max(columnHeight, top + height); } } }, { key: "count", get: function get() { return this._intervalTree.count; } }, { key: "shortestColumnSize", get: function get() { var columnSizeMap = this._columnSizeMap; var size = 0; for (var i in columnSizeMap) { var height = columnSizeMap[i]; size = size === 0 ? height : Math.min(size, height); } return size; } }, { key: "tallestColumnSize", get: function get() { var columnSizeMap = this._columnSizeMap; var size = 0; for (var i in columnSizeMap) { var height = columnSizeMap[i]; size = Math.max(size, height); } return size; } }]); return PositionCache; }(); exports["default"] = PositionCache;dist/commonjs/Masonry/index.js000064400000001267151676725760012465 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "createCellPositioner", { enumerable: true, get: function get() { return _createCellPositioner["default"]; } }); Object.defineProperty(exports, "Masonry", { enumerable: true, get: function get() { return _Masonry["default"]; } }); exports["default"] = void 0; var _createCellPositioner = _interopRequireDefault(require("./createCellPositioner")); var _Masonry = _interopRequireDefault(require("./Masonry")); var _default = _Masonry["default"]; exports["default"] = _default;dist/commonjs/Masonry/Masonry.jest.js000064400000044250151676725760013751 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _testUtils = require("react-dom/test-utils"); var _TestUtils = require("../TestUtils"); var _createCellPositioner = _interopRequireDefault(require("./createCellPositioner")); var _Masonry = _interopRequireDefault(require("./Masonry")); var _CellMeasurer = require("../CellMeasurer"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var ALTERNATING_CELL_HEIGHTS = [100, 50, 100, 150]; var CELL_SIZE_MULTIPLIER = 50; var COLUMN_COUNT = 3; function assertVisibleCells(rendered, text) { expect(Array.from(rendered.querySelectorAll('.cell')).map(function (node) { return node.textContent; }).sort().join(',')).toEqual(text); } function createCellMeasurerCache() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return new _CellMeasurer.CellMeasurerCache(_objectSpread({ defaultHeight: CELL_SIZE_MULTIPLIER, defaultWidth: CELL_SIZE_MULTIPLIER, fixedWidth: true, keyMapper: function keyMapper(index) { return index; } }, props)); } function createCellPositioner(cache) { return (0, _createCellPositioner["default"])({ cellMeasurerCache: cache, columnCount: COLUMN_COUNT, columnWidth: CELL_SIZE_MULTIPLIER }); } function createCellRenderer(cache, renderCallback) { renderCallback = typeof renderCallback === 'function' ? renderCallback : function (index) { return index; }; return function cellRenderer(_ref) { var index = _ref.index, isScrolling = _ref.isScrolling, key = _ref.key, parent = _ref.parent, style = _ref.style; var height = ALTERNATING_CELL_HEIGHTS[index % ALTERNATING_CELL_HEIGHTS.length]; var width = CELL_SIZE_MULTIPLIER; return React.createElement(_CellMeasurer.CellMeasurer, { cache: cache, index: index, key: key, parent: parent }, React.createElement("div", { className: "cell", ref: function ref(_ref2) { if (_ref2) { // Accounts for the fact that JSDom doesn't support measurements. Object.defineProperty(_ref2, 'offsetHeight', { configurable: true, value: height }); Object.defineProperty(_ref2, 'offsetWidth', { configurable: true, value: width }); } }, style: _objectSpread({}, style, { minHeight: height, minWidth: width }) }, renderCallback(index, { index: index, isScrolling: isScrolling, key: key, parent: parent, style: style }))); }; } function getMarkup() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var cellMeasurerCache = props.cellMeasurerCache || createCellMeasurerCache(); return React.createElement(_Masonry["default"], (0, _extends2["default"])({ cellCount: 1000, cellMeasurerCache: cellMeasurerCache, cellPositioner: createCellPositioner(cellMeasurerCache), cellRenderer: createCellRenderer(cellMeasurerCache), columnCount: COLUMN_COUNT, height: CELL_SIZE_MULTIPLIER * 2, overscanByPixels: CELL_SIZE_MULTIPLIER, width: CELL_SIZE_MULTIPLIER * COLUMN_COUNT }, props)); } function simulateScroll(masonry) { var scrollTop = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var target = { scrollTop: scrollTop }; masonry._scrollingContainer = target; // HACK to work around _onScroll target check var masonryNode = (0, _reactDom.findDOMNode)(masonry); masonryNode.scrollTop = scrollTop; _testUtils.Simulate.scroll(masonryNode); } describe('Masonry', function () { beforeEach(_TestUtils.render.unmount); describe('layout and measuring', function () { it('should measure only enough cells required for initial render', function () { // avg cell size: CELL_SIZE_MULTIPLIER // width: CELL_SIZE_MULTIPLIER * 3 // height: CELL_SIZE_MULTIPLIER * 2 // overcsan by: CELL_SIZE_MULTIPLIER // Expected to measure 9 cells var cellMeasurerCache = createCellMeasurerCache(); (0, _TestUtils.render)(getMarkup({ cellMeasurerCache: cellMeasurerCache })); for (var i = 0; i <= 8; i++) { expect(cellMeasurerCache.has(i)).toBe(true); } expect(cellMeasurerCache.has(9)).toBe(false); }); it('should not measure cells while scrolling until they are needed', function () { // Expected to measure 9 cells var cellMeasurerCache = createCellMeasurerCache(); var renderCallback = jest.fn().mockImplementation(function (index) { return index; }); var cellRenderer = createCellRenderer(cellMeasurerCache, renderCallback); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellRenderer: cellRenderer }))); renderCallback.mockClear(); // Scroll a little bit, but not so much to require re-measuring simulateScroll(rendered, 51); // Verify that render was only called enough times to fill view port (no extra for measuring) expect(renderCallback).toHaveBeenCalledTimes(9); }); it('should measure additional cells on scroll when it runs out of measured cells', function () { var cellMeasurerCache = createCellMeasurerCache(); var renderCallback = jest.fn().mockImplementation(function (index) { return index; }); var cellRenderer = createCellRenderer(cellMeasurerCache, renderCallback); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer, cellMeasurerCache: cellMeasurerCache }))); expect(cellMeasurerCache.has(9)).toBe(false); renderCallback.mockClear(); simulateScroll(rendered, 101); expect(cellMeasurerCache.has(9)).toBe(true); expect(cellMeasurerCache.has(10)).toBe(false); }); // Masonry used to do a render pass for only unmeasured cells, // But this resulting in removing (and later re-adding) measured cells from the DOM, // Which was bad for performance. See GitHub issue #875 it('should not remove previously-measured cells when measuring new ones', function () { var log = []; var cellMeasurerCache = createCellMeasurerCache(); var renderCallback = function renderCallback(index) { log.push(index); }; var cellRenderer = createCellRenderer(cellMeasurerCache, renderCallback); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellRenderer: cellRenderer }))); // Expected to have rendered twice: // 1st time to measure 9 cells (b'c of esimated size) // 2nd time to render and position 9 cells (b'c of actual size) expect(log).toHaveLength(18); log.splice(0); simulateScroll(rendered, 101); // Expected to have rendered twice: // 1st time to measure additional cells (based on estimated size) // 2nd time to render and position with new cells // The 1st render should also have included the pre-measured cells, // To prevent them from being removed, recreated, and re-added to the DOM. expect(log).toHaveLength(18); }); it('should only render enough cells to fill the viewport', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ overscanByPixels: 0 }))); assertVisibleCells(rendered, '0,1,2,3,4,5'); simulateScroll(rendered, 51); assertVisibleCells(rendered, '0,2,3,4,5,6'); simulateScroll(rendered, 101); assertVisibleCells(rendered, '3,4,5,6,7,8'); simulateScroll(rendered, 1001); assertVisibleCells(rendered, '30,31,32,33,34,35'); }); it('should only render enough cells to fill the viewport plus overscanByPixels', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ overscanByPixels: 100 }))); assertVisibleCells(rendered, '0,1,10,11,2,3,4,5,6,7,8,9'); simulateScroll(rendered, 51); assertVisibleCells(rendered, '0,1,10,11,2,3,4,5,6,7,8,9'); simulateScroll(rendered, 101); assertVisibleCells(rendered, '0,1,10,11,2,3,4,5,6,7,8,9'); simulateScroll(rendered, 1001); assertVisibleCells(rendered, '26,27,28,29,30,31,32,33,34,35,36,37'); }); it('should still render correctly when autoHeight is true (eg WindowScroller)', function () { // Share instances between renders to avoid resetting state in ways we don't intend var cellMeasurerCache = createCellMeasurerCache(); var cellPositioner = createCellPositioner(cellMeasurerCache); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ autoHeight: true, cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner }))); assertVisibleCells(rendered, '0,1,2,3,4,5,6,7,8'); rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ autoHeight: true, cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner, scrollTop: 51 }))); assertVisibleCells(rendered, '0,1,2,3,4,5,6,7,8'); rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ autoHeight: true, cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner, scrollTop: 101 }))); assertVisibleCells(rendered, '0,2,3,4,5,6,7,8,9'); rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ autoHeight: true, cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner, scrollTop: 1001 }))); assertVisibleCells(rendered, '27,29,30,31,32,33,34,35,36'); }); it('should set right instead of left in a cell styles for rtl row direction', function () { // Share instances between renders to avoid resetting state in ways we don't intend var cellMeasurerCache = createCellMeasurerCache(); var cellPositioner = createCellPositioner(cellMeasurerCache); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner, rowDirection: 'rtl' }))); Array.from(rendered.querySelectorAll('.cell')).map(function (node) { expect(node.style.right).toMatch(/px/); }); }); it('should consider scroll only of the container element and not of any ancestor element', function () { var cellMeasurerCache = createCellMeasurerCache(); var renderScrollableCell = function renderScrollableCell(index) { return React.createElement("div", { style: { height: '50px', overflow: 'visible' }, id: "scrollable-cell-".concat(index) }, React.createElement("div", { style: { height: '500px' } }, index)); }; var cellRenderer = createCellRenderer(cellMeasurerCache, renderScrollableCell); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ overscanByPixels: 0, cellMeasurerCache: cellMeasurerCache, cellRenderer: cellRenderer }))); assertVisibleCells(rendered, '0,1,2,3,4,5'); var cellEl = rendered.querySelector('#scrollable-cell-1'); _testUtils.Simulate.scroll(cellEl, { target: { scrollTop: 100 } }); assertVisibleCells(rendered, '0,1,2,3,4,5'); }); }); describe('recomputeCellPositions', function () { it('should refresh all cell positions', function () { // Share instances between renders to avoid resetting state in ways we don't intend var cellMeasurerCache = createCellMeasurerCache(); var cellPositioner = jest.fn().mockImplementation(createCellPositioner(cellMeasurerCache)); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner }))); assertVisibleCells(rendered, '0,1,2,3,4,5,6,7,8'); cellPositioner.mockImplementation(function (index) { return { left: 0, top: index * CELL_SIZE_MULTIPLIER }; }); var component = (0, _TestUtils.render)(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner })); rendered = (0, _reactDom.findDOMNode)(component); assertVisibleCells(rendered, '0,1,2,3,4,5,6,7,8'); component.recomputeCellPositions(); assertVisibleCells(rendered, '0,1,2,3,4'); }); it('should not reset measurement cache', function () { var cellMeasurerCache = createCellMeasurerCache(); var component = (0, _TestUtils.render)(getMarkup({ cellMeasurerCache: cellMeasurerCache })); var rendered = (0, _reactDom.findDOMNode)(component); simulateScroll(rendered, 101); expect(cellMeasurerCache.has(9)).toBe(true); simulateScroll(rendered, 0); component.recomputeCellPositions(); for (var i = 0; i <= 9; i++) { expect(cellMeasurerCache.has(i)).toBe(true); } }); }); describe('isScrolling', function () { it('should be true for cellRenderer while scrolling is in progress', function () { var cellMeasurerCache = createCellMeasurerCache(); var renderCallback = jest.fn().mockImplementation(function (index) { return index; }); var cellRenderer = createCellRenderer(cellMeasurerCache, renderCallback); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellRenderer: cellRenderer }))); renderCallback.mockClear(); simulateScroll(rendered, 51); expect(renderCallback.mock.calls[0][1].isScrolling).toEqual(true); }); it('should be reset after a small debounce when scrolling stops', function () { var cellMeasurerCache = createCellMeasurerCache(); var renderCallback = jest.fn().mockImplementation(function (index) { return index; }); var cellRenderer = createCellRenderer(cellMeasurerCache, renderCallback); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellRenderer: cellRenderer }))); simulateScroll(rendered, 51); renderCallback.mockClear(); setTimeout(function () { expect(renderCallback.mock.calls[0][1].isScrolling).toEqual(false); }, 0); }); }); describe('callbacks', function () { it('should call onCellsRendered when rendered cells change', function () { var onCellsRendered = jest.fn(); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onCellsRendered: onCellsRendered }))); expect(onCellsRendered.mock.calls).toEqual([[{ startIndex: 0, stopIndex: 8 }]]); simulateScroll(rendered, 51); expect(onCellsRendered.mock.calls).toEqual([[{ startIndex: 0, stopIndex: 8 }]]); simulateScroll(rendered, 101); expect(onCellsRendered.mock.calls).toEqual([[{ startIndex: 0, stopIndex: 8 }], [{ startIndex: 0, stopIndex: 9 }]]); }); it('should call onScroll when scroll position changes', function () { var onScroll = jest.fn(); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onScroll: onScroll }))); expect(onScroll.mock.calls).toEqual([[{ clientHeight: 100, scrollHeight: 16900, scrollTop: 0 }]]); simulateScroll(rendered, 51); expect(onScroll.mock.calls).toEqual([[{ clientHeight: 100, scrollHeight: 16900, scrollTop: 0 }], [{ clientHeight: 100, scrollHeight: 16900, scrollTop: 51 }]]); simulateScroll(rendered, 0); expect(onScroll.mock.calls).toEqual([[{ clientHeight: 100, scrollHeight: 16900, scrollTop: 0 }], [{ clientHeight: 100, scrollHeight: 16900, scrollTop: 51 }], [{ clientHeight: 100, scrollHeight: 16900, scrollTop: 0 }]]); }); }); describe('keyMapper', function () { it('should pass the correct key to rendered cells', function () { var keyMapper = jest.fn().mockImplementation(function (index) { return "key:".concat(index); }); var cellRenderer = jest.fn().mockImplementation(function (_ref3) { var index = _ref3.index, key = _ref3.key, style = _ref3.style; return React.createElement("div", { key: key, style: style }, index); }); (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer, keyMapper: keyMapper }))); expect(keyMapper).toHaveBeenCalled(); expect(cellRenderer).toHaveBeenCalled(); expect(cellRenderer.mock.calls[0][0].key).toEqual('key:0'); }); }); });dist/commonjs/Masonry/Masonry.example.js000064400000030451151676725760014435 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _immutable = _interopRequireDefault(require("immutable")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _ContentBox = require("../demo/ContentBox"); var _LabeledInput = require("../demo/LabeledInput"); var _CellMeasurer = require("../CellMeasurer"); var _AutoSizer = _interopRequireDefault(require("../AutoSizer")); var _WindowScroller = _interopRequireDefault(require("../WindowScroller")); var _createCellPositioner = _interopRequireDefault(require("./createCellPositioner")); var _Masonry = _interopRequireDefault(require("./Masonry")); var _MasonryExample = _interopRequireDefault(require("./Masonry.example.css")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var GridExample = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(GridExample, _React$PureComponent); function GridExample(props, context) { var _this; (0, _classCallCheck2["default"])(this, GridExample); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(GridExample).call(this, props, context)); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_resetList", function () { var ROW_HEIGHTS = [25, 50, 75, 100]; var list = _this.context.list; list.forEach(function (datum) { datum.size = ROW_HEIGHTS[Math.floor(Math.random() * ROW_HEIGHTS.length)]; }); _this._cache.clearAll(); _this._resetCellPositioner(); _this._masonry.clearCellPositions(); }); _this._columnCount = 0; _this._cache = new _CellMeasurer.CellMeasurerCache({ defaultHeight: 250, defaultWidth: 200, fixedWidth: true }); _this.state = { columnWidth: 200, height: 300, gutterSize: 10, overscanByPixels: 0, windowScrollerEnabled: false }; _this._cellRenderer = _this._cellRenderer.bind((0, _assertThisInitialized2["default"])(_this)); _this._onResize = _this._onResize.bind((0, _assertThisInitialized2["default"])(_this)); _this._renderAutoSizer = _this._renderAutoSizer.bind((0, _assertThisInitialized2["default"])(_this)); _this._renderMasonry = _this._renderMasonry.bind((0, _assertThisInitialized2["default"])(_this)); _this._setMasonryRef = _this._setMasonryRef.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(GridExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, columnWidth = _this$state.columnWidth, height = _this$state.height, gutterSize = _this$state.gutterSize, overscanByPixels = _this$state.overscanByPixels, windowScrollerEnabled = _this$state.windowScrollerEnabled; var child; if (windowScrollerEnabled) { child = React.createElement(_WindowScroller["default"], { overscanByPixels: overscanByPixels }, this._renderAutoSizer); } else { child = this._renderAutoSizer({ height: height }); } return React.createElement(_ContentBox.ContentBox, null, React.createElement(_ContentBox.ContentBoxHeader, { text: "Masonry", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/Masonry/Masonry.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/Masonry.md" }), React.createElement(_ContentBox.ContentBoxParagraph, null, "Optimized for masonry layouts. Cells are j.i.t. measured and layed out as a user scrolls. Sizes are cached so that resize/reflow is fast and does not require re-measuring."), React.createElement(_ContentBox.ContentBoxParagraph, null, React.createElement("label", { className: _MasonryExample["default"].checkboxLabel }, React.createElement("input", { "aria-label": "Use WindowScroller?", checked: windowScrollerEnabled, className: _MasonryExample["default"].checkbox, type: "checkbox", onChange: function onChange(event) { // HACK Because this demo switches between using WindowScroller and not, // It's easier to clear the cache when toggling modes to avoid a partially stale state. _this2._cache.clearAll(); _this2.setState({ windowScrollerEnabled: event.target.checked }); } }), "Use ", React.createElement("code", null, "WindowScroller"), "?"), React.createElement("label", { className: _MasonryExample["default"].checkboxLabel }, React.createElement("button", { onClick: this._resetList }, "Reset List Data"))), React.createElement(_LabeledInput.InputRow, null, React.createElement(_LabeledInput.LabeledInput, { label: "Height", name: "height", onChange: function onChange(event) { _this2.setState({ height: parseInt(event.target.value, 10) || 300 }); }, value: height }), React.createElement(_LabeledInput.LabeledInput, { label: "Column Width", name: "columnWidth", onChange: function onChange(event) { _this2._cache.clearAll(); _this2.setState({ columnWidth: parseInt(event.target.value, 10) || 200 }, function () { _this2._calculateColumnCount(); _this2._resetCellPositioner(); _this2._masonry.clearCellPositions(); }); }, value: columnWidth }), React.createElement(_LabeledInput.LabeledInput, { label: "Gutter Size", name: "gutterSize", onChange: function onChange(event) { _this2.setState({ gutterSize: parseInt(event.target.value, 10) || 10 }, function () { _this2._calculateColumnCount(); _this2._resetCellPositioner(); _this2._masonry.recomputeCellPositions(); }); }, value: gutterSize }), React.createElement(_LabeledInput.LabeledInput, { label: "Overscan (px)", name: "overscanByPixels", onChange: function onChange(event) { _this2.setState({ overscanByPixels: parseInt(event.target.value, 10) || 0 }); }, value: overscanByPixels })), child); } }, { key: "_calculateColumnCount", value: function _calculateColumnCount() { var _this$state2 = this.state, columnWidth = _this$state2.columnWidth, gutterSize = _this$state2.gutterSize; this._columnCount = Math.floor(this._width / (columnWidth + gutterSize)); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref) { var index = _ref.index, key = _ref.key, parent = _ref.parent, style = _ref.style; var list = this.context.list; var columnWidth = this.state.columnWidth; var datum = list.get(index % list.size); return React.createElement(_CellMeasurer.CellMeasurer, { cache: this._cache, index: index, key: key, parent: parent }, React.createElement("div", { className: _MasonryExample["default"].Cell, style: _objectSpread({}, style, { width: columnWidth }) }, React.createElement("div", { style: { backgroundColor: datum.color, borderRadius: '0.5rem', height: datum.size * 3, marginBottom: '0.5rem', width: '100%', fontSize: 20, color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center' } }, index), datum.random)); } }, { key: "_initCellPositioner", value: function _initCellPositioner() { if (typeof this._cellPositioner === 'undefined') { var _this$state3 = this.state, columnWidth = _this$state3.columnWidth, gutterSize = _this$state3.gutterSize; this._cellPositioner = (0, _createCellPositioner["default"])({ cellMeasurerCache: this._cache, columnCount: this._columnCount, columnWidth: columnWidth, spacer: gutterSize }); } } }, { key: "_onResize", value: function _onResize(_ref2) { var width = _ref2.width; this._width = width; this._calculateColumnCount(); this._resetCellPositioner(); this._masonry.recomputeCellPositions(); } }, { key: "_renderAutoSizer", value: function _renderAutoSizer(_ref3) { var height = _ref3.height, scrollTop = _ref3.scrollTop; this._height = height; this._scrollTop = scrollTop; var overscanByPixels = this.state.overscanByPixels; return React.createElement(_AutoSizer["default"], { disableHeight: true, height: height, onResize: this._onResize, overscanByPixels: overscanByPixels, scrollTop: this._scrollTop }, this._renderMasonry); } }, { key: "_renderMasonry", value: function _renderMasonry(_ref4) { var width = _ref4.width; this._width = width; this._calculateColumnCount(); this._initCellPositioner(); var _this$state4 = this.state, height = _this$state4.height, overscanByPixels = _this$state4.overscanByPixels, windowScrollerEnabled = _this$state4.windowScrollerEnabled; return React.createElement(_Masonry["default"], { autoHeight: windowScrollerEnabled, cellCount: 1000, cellMeasurerCache: this._cache, cellPositioner: this._cellPositioner, cellRenderer: this._cellRenderer, height: windowScrollerEnabled ? this._height : height, overscanByPixels: overscanByPixels, ref: this._setMasonryRef, scrollTop: this._scrollTop, width: width }); } // This is a bit of a hack to simulate newly loaded cells }, { key: "_resetCellPositioner", value: function _resetCellPositioner() { var _this$state5 = this.state, columnWidth = _this$state5.columnWidth, gutterSize = _this$state5.gutterSize; this._cellPositioner.reset({ columnCount: this._columnCount, columnWidth: columnWidth, spacer: gutterSize }); } }, { key: "_setMasonryRef", value: function _setMasonryRef(ref) { this._masonry = ref; } }]); return GridExample; }(React.PureComponent); exports["default"] = GridExample; (0, _defineProperty2["default"])(GridExample, "contextTypes", { list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired });dist/commonjs/utils/TestHelper.js000064400000001375151676725760013145 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.getCellMetadata = getCellMetadata; var _initCellMetadata = _interopRequireDefault(require("./initCellMetadata")); // Default cell sizes and offsets for use in below tests function getCellMetadata() { var cellSizes = [10, // 0: 0..0 (min) 20, // 1: 0..10 15, // 2: 0..30 10, // 3: 5..45 15, // 4: 20..55 30, // 5: 50..70 20, // 6: 70..100 10, // 7: 80..110 30 // 8: 110..110 (max) ]; return (0, _initCellMetadata["default"])({ cellCount: cellSizes.length, size: function size(_ref) { var index = _ref.index; return cellSizes[index]; } }); }dist/commonjs/utils/createCallbackMemoizer.jest.js000064400000014150151676725760016415 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _createCallbackMemoizer = _interopRequireDefault(require("./createCallbackMemoizer")); describe('createCallbackMemoizer', function () { function OnRowsRendered() { var _numCalls = 0; var _overscanStartIndex; var _overscanStopIndex; var _startIndex; var _stopIndex; return { numCalls: function numCalls() { return _numCalls; }, overscanStartIndex: function overscanStartIndex() { return _overscanStartIndex; }, overscanStopIndex: function overscanStopIndex() { return _overscanStopIndex; }, startIndex: function startIndex() { return _startIndex; }, stopIndex: function stopIndex() { return _stopIndex; }, update: function update(params) { _overscanStartIndex = params.overscanStartIndex; _overscanStopIndex = params.overscanStopIndex; _startIndex = params.startIndex; _stopIndex = params.stopIndex; _numCalls++; } }; } it('should not call onRowsRendered if startIndex or stopIndex are invalid', function () { var util = new OnRowsRendered(); var helper = (0, _createCallbackMemoizer["default"])(); helper({ callback: util.update, indices: { startIndex: 0, stopIndex: undefined } }); expect(util.numCalls()).toEqual(0); helper({ callback: util.update, indices: { startIndex: undefined, stopIndex: 0 } }); expect(util.numCalls()).toEqual(0); }); it('should call onRowsRendered if startIndex and stopIndex are valid', function () { var util = new OnRowsRendered(); var helper = (0, _createCallbackMemoizer["default"])(); helper({ callback: util.update, indices: { startIndex: 0, stopIndex: 1 } }); expect(util.numCalls()).toEqual(1); expect(util.startIndex()).toEqual(0); expect(util.stopIndex()).toEqual(1); }); it('should call onRowsRendered if startIndex and stopIndex are invalid but :requireAllKeys is false', function () { var util = new OnRowsRendered(); var helper = (0, _createCallbackMemoizer["default"])(false); helper({ callback: util.update, indices: { startIndex: undefined, stopIndex: 1 } }); expect(util.numCalls()).toEqual(1); expect(util.startIndex()).toEqual(undefined); expect(util.stopIndex()).toEqual(1); }); it('should not call onRowsRendered if startIndex or stopIndex have not changed', function () { var util = new OnRowsRendered(); var helper = (0, _createCallbackMemoizer["default"])(); helper({ callback: util.update, indices: { startIndex: 0, stopIndex: 1 } }); expect(util.numCalls()).toEqual(1); expect(util.startIndex()).toEqual(0); expect(util.stopIndex()).toEqual(1); helper({ callback: util.update, indices: { startIndex: 0, stopIndex: 1 } }); expect(util.numCalls()).toEqual(1); }); it('should not call onRowsRendered if startIndex or stopIndex have changed', function () { var util = new OnRowsRendered(); var helper = (0, _createCallbackMemoizer["default"])(); helper({ callback: util.update, indices: { startIndex: 0, stopIndex: 1 } }); expect(util.numCalls()).toEqual(1); expect(util.startIndex()).toEqual(0); expect(util.stopIndex()).toEqual(1); helper({ callback: util.update, indices: { startIndex: 1, stopIndex: 1 } }); expect(util.numCalls()).toEqual(2); expect(util.startIndex()).toEqual(1); expect(util.stopIndex()).toEqual(1); helper({ callback: util.update, indices: { startIndex: 1, stopIndex: 2 } }); expect(util.numCalls()).toEqual(3); expect(util.startIndex()).toEqual(1); expect(util.stopIndex()).toEqual(2); }); it('should call onRowsRendered if :overscanCellsCount changes', function () { var util = new OnRowsRendered(); var helper = (0, _createCallbackMemoizer["default"])(); helper({ callback: util.update, indices: { overscanStartIndex: 0, overscanStopIndex: 2, startIndex: 0, stopIndex: 1 } }); expect(util.numCalls()).toEqual(1); expect(util.startIndex()).toEqual(0); expect(util.stopIndex()).toEqual(1); expect(util.overscanStartIndex()).toEqual(0); expect(util.overscanStopIndex()).toEqual(2); helper({ callback: util.update, indices: { overscanStartIndex: 0, overscanStopIndex: 3, startIndex: 0, stopIndex: 1 } }); expect(util.numCalls()).toEqual(2); expect(util.startIndex()).toEqual(0); expect(util.stopIndex()).toEqual(1); expect(util.overscanStartIndex()).toEqual(0); expect(util.overscanStopIndex()).toEqual(3); }); it('should support an array of indices', function () { var numCalls = 0; var indices; var callback = function callback(params) { indices = params; numCalls++; }; var helper = (0, _createCallbackMemoizer["default"])(); helper({ callback: callback, indices: [0, 1, 2] }); expect(numCalls).toEqual(1); expect(indices).toEqual([0, 1, 2]); helper({ callback: callback, indices: [0, 1] }); expect(numCalls).toEqual(2); expect(indices).toEqual([0, 1]); }); it('should support an attribute containing an array of indices', function () { var numCalls = 0; var indices; var callback = function callback(params) { indices = params.indices; numCalls++; }; var helper = (0, _createCallbackMemoizer["default"])(); helper({ callback: callback, indices: { indices: [0, 1, 2] } }); expect(numCalls).toEqual(1); expect(indices).toEqual([0, 1, 2]); helper({ callback: callback, indices: { indices: [0, 1] } }); expect(numCalls).toEqual(2); expect(indices).toEqual([0, 1]); }); });dist/commonjs/utils/requestAnimationTimeout.js000064400000003172151676725760015762 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.bpfrpt_proptype_AnimationTimeoutId = exports.requestAnimationTimeout = exports.cancelAnimationTimeout = void 0; var _animationFrame = require("./animationFrame"); var _propTypes = _interopRequireDefault(require("prop-types")); var bpfrpt_proptype_AnimationTimeoutId = process.env.NODE_ENV === 'production' ? null : { "id": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_AnimationTimeoutId = bpfrpt_proptype_AnimationTimeoutId; var cancelAnimationTimeout = function cancelAnimationTimeout(frame) { return (0, _animationFrame.caf)(frame.id); }; /** * Recursively calls requestAnimationFrame until a specified delay has been met or exceeded. * When the delay time has been reached the function you're timing out will be called. * * Credit: Joe Lambert (https://gist.github.com/joelambert/1002116#file-requesttimeout-js) */ exports.cancelAnimationTimeout = cancelAnimationTimeout; var requestAnimationTimeout = function requestAnimationTimeout(callback, delay) { var start; // wait for end of processing current event handler, because event handler may be long Promise.resolve().then(function () { start = Date.now(); }); var timeout = function timeout() { if (Date.now() - start >= delay) { callback.call(); } else { frame.id = (0, _animationFrame.raf)(timeout); } }; var frame = { id: (0, _animationFrame.raf)(timeout) }; return frame; }; exports.requestAnimationTimeout = requestAnimationTimeout;dist/commonjs/utils/createCallbackMemoizer.js000064400000002123151676725760015446 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = createCallbackMemoizer; /** * Helper utility that updates the specified callback whenever any of the specified indices have changed. */ function createCallbackMemoizer() { var requireAllKeys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; var cachedIndices = {}; return function (_ref) { var callback = _ref.callback, indices = _ref.indices; var keys = Object.keys(indices); var allInitialized = !requireAllKeys || keys.every(function (key) { var value = indices[key]; return Array.isArray(value) ? value.length > 0 : value >= 0; }); var indexChanged = keys.length !== Object.keys(cachedIndices).length || keys.some(function (key) { var cachedValue = cachedIndices[key]; var value = indices[key]; return Array.isArray(value) ? cachedValue.join(',') !== value.join(',') : cachedValue !== value; }); cachedIndices = indices; if (allInitialized && indexChanged) { callback(indices); } }; }dist/commonjs/utils/initCellMetadata.js000064400000002064151676725760014266 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = initCellMetadata; /** * Initializes metadata for an axis and its cells. * This data is used to determine which cells are visible given a container size and scroll position. * * @param cellCount Total number of cells. * @param size Either a fixed size or a function that returns the size for a given given an index. * @return Object mapping cell index to cell metadata (size, offset) */ function initCellMetadata(_ref) { var cellCount = _ref.cellCount, size = _ref.size; var sizeGetter = typeof size === 'function' ? size : function () { return size; }; var cellMetadata = []; var offset = 0; for (var i = 0; i < cellCount; i++) { var _size = sizeGetter({ index: i }); if (_size == null || isNaN(_size)) { throw Error("Invalid size returned for cell ".concat(i, " of value ").concat(_size)); } cellMetadata[i] = { size: _size, offset: offset }; offset += _size; } return cellMetadata; }dist/commonjs/utils/animationFrame.js000064400000001662151676725760014017 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.caf = exports.raf = void 0; // Properly handle server-side rendering. var win; if (typeof window !== 'undefined') { win = window; } else if (typeof self !== 'undefined') { win = self; } else { win = {}; } // requestAnimationFrame() shim by Paul Irish // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ var request = win.requestAnimationFrame || win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame || win.oRequestAnimationFrame || win.msRequestAnimationFrame || function (callback) { return win.setTimeout(callback, 1000 / 60); }; var cancel = win.cancelAnimationFrame || win.webkitCancelAnimationFrame || win.mozCancelAnimationFrame || win.oCancelAnimationFrame || win.msCancelAnimationFrame || function (id) { win.clearTimeout(id); }; var raf = request; exports.raf = raf; var caf = cancel; exports.caf = caf;dist/commonjs/utils/getUpdatedOffsetForIndex.jest.js000064400000004303151676725760016720 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _getUpdatedOffsetForIndex = _interopRequireDefault(require("./getUpdatedOffsetForIndex")); var _TestHelper = require("./TestHelper"); describe('getUpdatedOffsetForIndex', function () { function testHelper(targetIndex, currentOffset) { var cellMetadata = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : (0, _TestHelper.getCellMetadata)(); return (0, _getUpdatedOffsetForIndex["default"])({ cellOffset: cellMetadata[targetIndex].offset, cellSize: cellMetadata[targetIndex].size, containerSize: 50, currentOffset: currentOffset }); } it('should scroll to the beginning', function () { expect(testHelper(0, 100)).toEqual(0); }); it('should scroll forward to the middle', function () { expect(testHelper(4, 0)).toEqual(20); }); it('should scroll backward to the middle', function () { expect(testHelper(2, 100)).toEqual(30); }); it('should not scroll if an item is already visible', function () { expect(testHelper(2, 20)).toEqual(20); }); it('should scroll to the end', function () { expect(testHelper(8, 0)).toEqual(110); }); it('should honor specified :align values', function () { expect((0, _getUpdatedOffsetForIndex["default"])({ align: 'auto', cellOffset: 50, cellSize: 10, containerSize: 50, currentOffset: 0 })).toEqual(10); expect((0, _getUpdatedOffsetForIndex["default"])({ align: 'start', cellOffset: 50, cellSize: 10, containerSize: 50, currentOffset: 0 })).toEqual(50); expect((0, _getUpdatedOffsetForIndex["default"])({ align: 'auto', cellOffset: 50, cellSize: 10, containerSize: 50, currentOffset: 100 })).toEqual(50); expect((0, _getUpdatedOffsetForIndex["default"])({ align: 'end', cellOffset: 50, cellSize: 10, containerSize: 50, currentOffset: 100 })).toEqual(10); expect((0, _getUpdatedOffsetForIndex["default"])({ align: 'center', cellOffset: 50, cellSize: 10, containerSize: 50, currentOffset: 100 })).toEqual(30); }); });dist/commonjs/utils/getUpdatedOffsetForIndex.js000064400000002670151676725760015761 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = getUpdatedOffsetForIndex; /** * Determines a new offset that ensures a certain cell is visible, given the current offset. * If the cell is already visible then the current offset will be returned. * If the current offset is too great or small, it will be adjusted just enough to ensure the specified index is visible. * * @param align Desired alignment within container; one of "auto" (default), "start", or "end" * @param cellOffset Offset (x or y) position for cell * @param cellSize Size (width or height) of cell * @param containerSize Total size (width or height) of the container * @param currentOffset Container's current (x or y) offset * @return Offset to use to ensure the specified cell is visible */ function getUpdatedOffsetForIndex(_ref) { var _ref$align = _ref.align, align = _ref$align === void 0 ? 'auto' : _ref$align, cellOffset = _ref.cellOffset, cellSize = _ref.cellSize, containerSize = _ref.containerSize, currentOffset = _ref.currentOffset; var maxOffset = cellOffset; var minOffset = maxOffset - containerSize + cellSize; switch (align) { case 'start': return maxOffset; case 'end': return minOffset; case 'center': return maxOffset - (containerSize - cellSize) / 2; default: return Math.max(minOffset, Math.min(maxOffset, currentOffset)); } }dist/commonjs/index.js000064400000010576151676725760011040 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "ArrowKeyStepper", { enumerable: true, get: function get() { return _ArrowKeyStepper.ArrowKeyStepper; } }); Object.defineProperty(exports, "AutoSizer", { enumerable: true, get: function get() { return _AutoSizer.AutoSizer; } }); Object.defineProperty(exports, "CellMeasurer", { enumerable: true, get: function get() { return _CellMeasurer.CellMeasurer; } }); Object.defineProperty(exports, "CellMeasurerCache", { enumerable: true, get: function get() { return _CellMeasurer.CellMeasurerCache; } }); Object.defineProperty(exports, "Collection", { enumerable: true, get: function get() { return _Collection.Collection; } }); Object.defineProperty(exports, "ColumnSizer", { enumerable: true, get: function get() { return _ColumnSizer.ColumnSizer; } }); Object.defineProperty(exports, "accessibilityOverscanIndicesGetter", { enumerable: true, get: function get() { return _Grid.accessibilityOverscanIndicesGetter; } }); Object.defineProperty(exports, "defaultCellRangeRenderer", { enumerable: true, get: function get() { return _Grid.defaultCellRangeRenderer; } }); Object.defineProperty(exports, "defaultOverscanIndicesGetter", { enumerable: true, get: function get() { return _Grid.defaultOverscanIndicesGetter; } }); Object.defineProperty(exports, "Grid", { enumerable: true, get: function get() { return _Grid.Grid; } }); Object.defineProperty(exports, "InfiniteLoader", { enumerable: true, get: function get() { return _InfiniteLoader.InfiniteLoader; } }); Object.defineProperty(exports, "List", { enumerable: true, get: function get() { return _List.List; } }); Object.defineProperty(exports, "createMasonryCellPositioner", { enumerable: true, get: function get() { return _Masonry.createCellPositioner; } }); Object.defineProperty(exports, "Masonry", { enumerable: true, get: function get() { return _Masonry.Masonry; } }); Object.defineProperty(exports, "MultiGrid", { enumerable: true, get: function get() { return _MultiGrid.MultiGrid; } }); Object.defineProperty(exports, "ScrollSync", { enumerable: true, get: function get() { return _ScrollSync.ScrollSync; } }); Object.defineProperty(exports, "createTableMultiSort", { enumerable: true, get: function get() { return _Table.createMultiSort; } }); Object.defineProperty(exports, "defaultTableCellDataGetter", { enumerable: true, get: function get() { return _Table.defaultCellDataGetter; } }); Object.defineProperty(exports, "defaultTableCellRenderer", { enumerable: true, get: function get() { return _Table.defaultCellRenderer; } }); Object.defineProperty(exports, "defaultTableHeaderRenderer", { enumerable: true, get: function get() { return _Table.defaultHeaderRenderer; } }); Object.defineProperty(exports, "defaultTableHeaderRowRenderer", { enumerable: true, get: function get() { return _Table.defaultHeaderRowRenderer; } }); Object.defineProperty(exports, "defaultTableRowRenderer", { enumerable: true, get: function get() { return _Table.defaultRowRenderer; } }); Object.defineProperty(exports, "Table", { enumerable: true, get: function get() { return _Table.Table; } }); Object.defineProperty(exports, "Column", { enumerable: true, get: function get() { return _Table.Column; } }); Object.defineProperty(exports, "SortDirection", { enumerable: true, get: function get() { return _Table.SortDirection; } }); Object.defineProperty(exports, "SortIndicator", { enumerable: true, get: function get() { return _Table.SortIndicator; } }); Object.defineProperty(exports, "WindowScroller", { enumerable: true, get: function get() { return _WindowScroller.WindowScroller; } }); var _ArrowKeyStepper = require("./ArrowKeyStepper"); var _AutoSizer = require("./AutoSizer"); var _CellMeasurer = require("./CellMeasurer"); var _Collection = require("./Collection"); var _ColumnSizer = require("./ColumnSizer"); var _Grid = require("./Grid"); var _InfiniteLoader = require("./InfiniteLoader"); var _List = require("./List"); var _Masonry = require("./Masonry"); var _MultiGrid = require("./MultiGrid"); var _ScrollSync = require("./ScrollSync"); var _Table = require("./Table"); var _WindowScroller = require("./WindowScroller");dist/commonjs/Table/createMultiSort.jest.js000064400000015532151676725760015047 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _createMultiSort = _interopRequireDefault(require("./createMultiSort")); describe('createMultiSort', function () { function simulate(sort, dataKey) { var eventModifier = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; var defaultSortDirection = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'ASC'; sort({ defaultSortDirection: defaultSortDirection, event: { ctrlKey: eventModifier === 'control', metaKey: eventModifier === 'meta', shiftKey: eventModifier === 'shift' }, sortBy: dataKey }); } it('errors if the user did not specify a sort callback', function () { expect(_createMultiSort["default"]).toThrow(); }); it('sets the correct default values', function () { var multiSort = (0, _createMultiSort["default"])(jest.fn(), { defaultSortBy: ['a', 'b'], defaultSortDirection: { a: 'ASC', b: 'DESC' } }); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('DESC'); }); it('sets the correct default sparse values', function () { var multiSort = (0, _createMultiSort["default"])(jest.fn(), { defaultSortBy: ['a', 'b'] }); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('ASC'); }); describe('on click', function () { it('sets the correct default value for a field', function () { var multiSort = (0, _createMultiSort["default"])(jest.fn()); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toBe('ASC'); simulate(multiSort.sort, 'b', '', 'DESC'); expect(multiSort.sortBy).toEqual(['b']); expect(multiSort.sortDirection.b).toBe('DESC'); }); it('toggles a field value', function () { var multiSort = (0, _createMultiSort["default"])(jest.fn()); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toBe('ASC'); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toBe('DESC'); simulate(multiSort.sort, 'b', '', 'DESC'); expect(multiSort.sortBy).toEqual(['b']); expect(multiSort.sortDirection.b).toBe('DESC'); simulate(multiSort.sort, 'b', '', 'DESC'); expect(multiSort.sortBy).toEqual(['b']); expect(multiSort.sortDirection.b).toBe('ASC'); }); it('resets sort-by fields', function () { var multiSort = (0, _createMultiSort["default"])(jest.fn(), { defaultSortBy: ['a', 'b'] }); expect(multiSort.sortBy).toEqual(['a', 'b']); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); }); it('resets sort-direction fields', function () { var multiSort = (0, _createMultiSort["default"])(jest.fn(), { defaultSortBy: ['a', 'b'], defaultSortDirection: { a: 'DESC', b: 'ASC' } }); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toEqual('DESC'); expect(multiSort.sortDirection.b).toEqual('ASC'); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toEqual('ASC'); expect(multiSort.sortDirection.b).toEqual(undefined); simulate(multiSort.sort, 'b'); expect(multiSort.sortBy).toEqual(['b']); expect(multiSort.sortDirection.a).toEqual(undefined); expect(multiSort.sortDirection.b).toEqual('ASC'); }); }); describe('on shift click', function () { it('appends a field to the sort by list', function () { var multiSort = (0, _createMultiSort["default"])(jest.fn()); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toBe('ASC'); simulate(multiSort.sort, 'b', 'shift'); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('ASC'); }); it('toggles an appended field value', function () { var multiSort = (0, _createMultiSort["default"])(jest.fn()); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toBe('ASC'); simulate(multiSort.sort, 'b', 'shift'); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('ASC'); simulate(multiSort.sort, 'a', 'shift'); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('DESC'); expect(multiSort.sortDirection.b).toBe('ASC'); simulate(multiSort.sort, 'a', 'shift'); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('ASC'); }); it('able to shift+click more than once', function () { var multiSort = (0, _createMultiSort["default"])(jest.fn()); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toBe('ASC'); simulate(multiSort.sort, 'b', 'shift'); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('ASC'); simulate(multiSort.sort, 'b'); expect(multiSort.sortBy).toEqual(['b']); expect(multiSort.sortDirection.b).toBe('DESC'); simulate(multiSort.sort, 'a', 'shift'); expect(multiSort.sortBy).toEqual(['b', 'a']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('DESC'); }); }); ['control', 'meta'].forEach(function (modifier) { describe("".concat(modifier, " click"), function () { it('removes a field from the sort by list', function () { var multiSort = (0, _createMultiSort["default"])(jest.fn(), { defaultSortBy: ['a', 'b'] }); expect(multiSort.sortBy).toEqual(['a', 'b']); simulate(multiSort.sort, 'a', modifier); expect(multiSort.sortBy).toEqual(['b']); simulate(multiSort.sort, 'b', modifier); expect(multiSort.sortBy).toEqual([]); }); it('ignores fields not in the list on control click', function () { var multiSort = (0, _createMultiSort["default"])(jest.fn(), { defaultSortBy: ['a', 'b'] }); expect(multiSort.sortBy).toEqual(['a', 'b']); simulate(multiSort.sort, 'c', modifier); expect(multiSort.sortBy).toEqual(['a', 'b']); }); }); }); });dist/commonjs/Table/createMultiSort.js000064400000004506151676725760014102 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = createMultiSort; function createMultiSort(sortCallback) { var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, defaultSortBy = _ref.defaultSortBy, _ref$defaultSortDirec = _ref.defaultSortDirection, defaultSortDirection = _ref$defaultSortDirec === void 0 ? {} : _ref$defaultSortDirec; if (!sortCallback) { throw Error("Required parameter \"sortCallback\" not specified"); } var sortBy = defaultSortBy || []; var sortDirection = {}; sortBy.forEach(function (dataKey) { sortDirection[dataKey] = defaultSortDirection[dataKey] !== undefined ? defaultSortDirection[dataKey] : 'ASC'; }); function sort(_ref2) { var defaultSortDirection = _ref2.defaultSortDirection, event = _ref2.event, dataKey = _ref2.sortBy; if (event.shiftKey) { // Shift + click appends a column to existing criteria if (sortDirection[dataKey] !== undefined) { sortDirection[dataKey] = sortDirection[dataKey] === 'ASC' ? 'DESC' : 'ASC'; } else { sortDirection[dataKey] = defaultSortDirection; sortBy.push(dataKey); } } else if (event.ctrlKey || event.metaKey) { // Control + click removes column from sort (if pressent) var index = sortBy.indexOf(dataKey); if (index >= 0) { sortBy.splice(index, 1); delete sortDirection[dataKey]; } } else { // Clear sortBy array of all non-selected keys sortBy.length = 0; sortBy.push(dataKey); // Clear sortDirection object of all non-selected keys var sortDirectionKeys = Object.keys(sortDirection); sortDirectionKeys.forEach(function (key) { if (key !== dataKey) delete sortDirection[key]; }); // If key is already selected, reverse sort direction. // Else, set sort direction to default direction. if (sortDirection[dataKey] !== undefined) { sortDirection[dataKey] = sortDirection[dataKey] === 'ASC' ? 'DESC' : 'ASC'; } else { sortDirection[dataKey] = defaultSortDirection; } } // Notify application code sortCallback({ sortBy: sortBy, sortDirection: sortDirection }); } return { sort: sort, sortBy: sortBy, sortDirection: sortDirection }; }dist/commonjs/Table/Column.js000064400000010712151676725760012205 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _defaultHeaderRenderer = _interopRequireDefault(require("./defaultHeaderRenderer")); var _defaultCellRenderer = _interopRequireDefault(require("./defaultCellRenderer")); var _defaultCellDataGetter = _interopRequireDefault(require("./defaultCellDataGetter")); var _SortDirection = _interopRequireDefault(require("./SortDirection")); /** * Describes the header and cell contents of a table column. */ var Column = /*#__PURE__*/ function (_React$Component) { (0, _inherits2["default"])(Column, _React$Component); function Column() { (0, _classCallCheck2["default"])(this, Column); return (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(Column).apply(this, arguments)); } return Column; }(React.Component); exports["default"] = Column; (0, _defineProperty2["default"])(Column, "defaultProps", { cellDataGetter: _defaultCellDataGetter["default"], cellRenderer: _defaultCellRenderer["default"], defaultSortDirection: _SortDirection["default"].ASC, flexGrow: 0, flexShrink: 1, headerRenderer: _defaultHeaderRenderer["default"], style: {} }); Column.propTypes = process.env.NODE_ENV !== "production" ? { /** Optional aria-label value to set on the column header */ 'aria-label': _propTypes["default"].string, /** * Callback responsible for returning a cell's data, given its :dataKey * ({ columnData: any, dataKey: string, rowData: any }): any */ cellDataGetter: _propTypes["default"].func, /** * Callback responsible for rendering a cell's contents. * ({ cellData: any, columnData: any, dataKey: string, rowData: any, rowIndex: number }): node */ cellRenderer: _propTypes["default"].func, /** Optional CSS class to apply to cell */ className: _propTypes["default"].string, /** Optional additional data passed to this column's :cellDataGetter */ columnData: _propTypes["default"].object, /** Uniquely identifies the row-data attribute corresponding to this cell */ dataKey: _propTypes["default"].any.isRequired, /** Optional direction to be used when clicked the first time */ defaultSortDirection: _propTypes["default"].oneOf([_SortDirection["default"].ASC, _SortDirection["default"].DESC]), /** If sort is enabled for the table at large, disable it for this column */ disableSort: _propTypes["default"].bool, /** Flex grow style; defaults to 0 */ flexGrow: _propTypes["default"].number, /** Flex shrink style; defaults to 1 */ flexShrink: _propTypes["default"].number, /** Optional CSS class to apply to this column's header */ headerClassName: _propTypes["default"].string, /** * Optional callback responsible for rendering a column header contents. * ({ columnData: object, dataKey: string, disableSort: boolean, label: node, sortBy: string, sortDirection: string }): PropTypes.node */ headerRenderer: _propTypes["default"].func.isRequired, /** Optional inline style to apply to this column's header */ headerStyle: _propTypes["default"].object, /** Optional id to set on the column header */ id: _propTypes["default"].string, /** Header label for this column */ label: _propTypes["default"].node, /** Maximum width of column; this property will only be used if :flexGrow is > 0. */ maxWidth: _propTypes["default"].number, /** Minimum width of column. */ minWidth: _propTypes["default"].number, /** Optional inline style to apply to cell */ style: _propTypes["default"].object, /** Flex basis (width) for this column; This value can grow or shrink based on :flexGrow and :flexShrink properties. */ width: _propTypes["default"].number.isRequired } : {};dist/commonjs/Table/Table.jest.js000064400000154556151676725760012762 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _TestUtils = require("../TestUtils"); var _testUtils = require("react-dom/test-utils"); var _immutable = _interopRequireDefault(require("immutable")); var _Column2 = _interopRequireDefault(require("./Column")); var _Table = _interopRequireDefault(require("./Table")); var _SortDirection = _interopRequireDefault(require("./SortDirection")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } describe('Table', function () { var array = []; for (var i = 0; i < 100; i++) { array.push({ id: i, name: "Name ".concat(i), email: "user-".concat(i, "@treasure-data.com") }); } var list = _immutable["default"].fromJS(array); // Works with an Immutable List of Maps function immutableRowGetter(_ref) { var index = _ref.index; return list.get(index); } // Works with an Array of Objects function vanillaRowGetter(_ref2) { var index = _ref2.index; return array[index]; } // Override default behavior of overscanning by at least 1 (for accessibility) // Because it makes for simple tests below function overscanIndicesGetter(_ref3) { var startIndex = _ref3.startIndex, stopIndex = _ref3.stopIndex; return { overscanStartIndex: startIndex, overscanStopIndex: stopIndex }; } function getMarkup() { var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, cellDataGetter = _ref4.cellDataGetter, cellRenderer = _ref4.cellRenderer, _ref4$columnData = _ref4.columnData, columnData = _ref4$columnData === void 0 ? { data: 123 } : _ref4$columnData, columnID = _ref4.columnID, columnStyle = _ref4.columnStyle, columnHeaderStyle = _ref4.columnHeaderStyle, _ref4$disableSort = _ref4.disableSort, disableSort = _ref4$disableSort === void 0 ? false : _ref4$disableSort, headerRenderer = _ref4.headerRenderer, maxWidth = _ref4.maxWidth, minWidth = _ref4.minWidth, defaultSortDirection = _ref4.defaultSortDirection, label = _ref4.label, flexTableProps = (0, _objectWithoutProperties2["default"])(_ref4, ["cellDataGetter", "cellRenderer", "columnData", "columnID", "columnStyle", "columnHeaderStyle", "disableSort", "headerRenderer", "maxWidth", "minWidth", "defaultSortDirection", "label"]); return React.createElement(_Table["default"], (0, _extends2["default"])({ headerHeight: 20, height: 100, overscanRowCount: 0, overscanIndicesGetter: overscanIndicesGetter, rowCount: list.size, rowGetter: immutableRowGetter, rowHeight: 10, width: 100 }, flexTableProps), React.createElement(_Column2["default"], { label: label || 'Name', dataKey: "name", columnData: columnData, width: 50, cellRenderer: cellRenderer, cellDataGetter: cellDataGetter, headerRenderer: headerRenderer, disableSort: disableSort, defaultSortDirection: defaultSortDirection, style: columnStyle, headerStyle: columnHeaderStyle, id: columnID }), React.createElement(_Column2["default"], { label: "Email", dataKey: "email", maxWidth: maxWidth, minWidth: minWidth, width: 50 }), false, true, null, undefined); } beforeEach(function () { return jest.resetModules(); }); describe('children', function () { it('should accept Column children', function () { var children = [React.createElement(_Column2["default"], { dataKey: "foo", width: 100 })]; var result = _Table["default"].propTypes.children({ children: children }, 'children', 'Table'); expect(result instanceof Error).toEqual(false); }); it('should accept subclasses of Column as children', function () { var AnotherColumn = /*#__PURE__*/ function (_Column) { (0, _inherits2["default"])(AnotherColumn, _Column); function AnotherColumn() { (0, _classCallCheck2["default"])(this, AnotherColumn); return (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(AnotherColumn).apply(this, arguments)); } return AnotherColumn; }(_Column2["default"]); var children = [React.createElement(AnotherColumn, { dataKey: "foo", width: 100 })]; var result = _Table["default"].propTypes.children({ children: children }, 'children', 'Table'); expect(result instanceof Error).toEqual(false); }); it('should not accept non-Column children', function () { var children = [React.createElement("div", null)]; var result = _Table["default"].propTypes.children({ children: children }, 'children', 'Table'); expect(result instanceof Error).toEqual(true); }); it('should accept falsy children to allow easier dynamic showing/hiding of columns', function () { var children = [false, React.createElement(_Column2["default"], { dataKey: "foo", width: 100 }), null]; var result = _Table["default"].propTypes.children({ children: children }, 'children', 'Table'); expect(result instanceof Error).toEqual(false); }); }); describe('height', function () { it('should subtract header row height from the inner Grid height if headers are enabled', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ headerHeight: 10, overscanRowCount: 0, rowHeight: 20, height: 50 }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); expect(rows.length).toEqual(2); }); it('should not subtract header row height from the inner Grid height if headers are disabled', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ disableHeader: true, headerHeight: 10, overscanRowCount: 0, rowHeight: 20, height: 50 }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); expect(rows.length).toEqual(3); }); }); describe('initial rendering', function () { // Ensure that both Immutable Lists of Maps and Arrays of Objects are supported var useImmutable = [true, false]; useImmutable.forEach(function (useImmutable) { it('should render the correct number of rows', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ rowGetter: useImmutable ? immutableRowGetter : vanillaRowGetter }))); // 100px height should fit 1 header (20px) and 8 rows (10px each) - expect(rendered.querySelectorAll('.ReactVirtualized__Table__headerRow').length).toEqual(1); expect(rendered.querySelectorAll('.ReactVirtualized__Table__row').length).toEqual(8); }); it('should render the expected headers', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ rowGetter: useImmutable ? immutableRowGetter : vanillaRowGetter }))); var columns = rendered.querySelectorAll('.ReactVirtualized__Table__headerColumn'); expect(columns.length).toEqual(2); expect(columns[0].textContent).toEqual('Name'); expect(columns[1].textContent).toEqual('Email'); }); it('should render the expected rows and columns', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ rowGetter: useImmutable ? immutableRowGetter : vanillaRowGetter, headerHeight: 10, rowHeight: 20, height: 50 }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); expect(rows.length).toEqual(2); Array.from(rows).forEach(function (row, index) { var rowData = list.get(index); var columns = row.querySelectorAll('.ReactVirtualized__Table__rowColumn'); expect(columns.length).toEqual(2); expect(columns[0].textContent).toEqual(rowData.get('name')); expect(columns[1].textContent).toEqual(rowData.get('email')); }); }); }); it('should support a :rowHeight function', function () { var rowHeight = function rowHeight(_ref5) { var index = _ref5.index; return 10 + index * 10; }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ rowHeight: rowHeight, rowCount: 3 }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); Array.from(rows).forEach(function (row, index) { expect(Number.parseInt(row.style.height, 10)).toEqual(rowHeight({ index: index })); }); }); it('should support :minWidth and :maxWidth values for a column', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ maxWidth: 75, minWidth: 25, rowCount: 1 }))); var columns = rendered.querySelectorAll('.ReactVirtualized__Table__rowColumn'); var emailColumn = columns[1]; expect(Number.parseInt(emailColumn.style.maxWidth, 10)).toEqual(75); expect(Number.parseInt(emailColumn.style.minWidth, 10)).toEqual(25); }); }); describe('measureAllRows', function () { it('should measure any unmeasured rows', function () { var rendered = (0, _TestUtils.render)(getMarkup({ estimatedRowSize: 15, height: 0, rowCount: 10, rowHeight: function rowHeight() { return 20; }, width: 0 })); expect(rendered.Grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(150); rendered.measureAllRows(); expect(rendered.Grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(200); }); }); describe('recomputeRowHeights', function () { it('should recompute row heights and other values when called', function () { var indices = []; var rowHeight = function rowHeight(_ref6) { var index = _ref6.index; indices.push(index); return 10; }; var component = (0, _TestUtils.render)(getMarkup({ rowHeight: rowHeight, rowCount: 50 })); indices.splice(0); component.recomputeRowHeights(); // Only the rows required to fill the current viewport will be rendered expect(indices[0]).toEqual(0); expect(indices[indices.length - 1]).toEqual(7); indices.splice(0); component.recomputeRowHeights(4); expect(indices[0]).toEqual(4); expect(indices[indices.length - 1]).toEqual(7); }); }); describe('forceUpdateGrid', function () { it('should refresh inner Grid content when called', function () { var marker = 'a'; function cellRenderer(_ref7) { var rowIndex = _ref7.rowIndex; return "".concat(rowIndex).concat(marker); } var component = (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer })); var node = (0, _reactDom.findDOMNode)(component); expect(node.textContent).toContain('1a'); marker = 'b'; component.forceUpdateGrid(); expect(node.textContent).toContain('1b'); }); }); describe('custom getter functions', function () { it('should use a custom cellDataGetter if specified', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellDataGetter: function cellDataGetter(_ref8) { var dataKey = _ref8.dataKey, rowData = _ref8.rowData; return "Custom ".concat(dataKey, " for row ").concat(rowData.get('id')); } }))); var nameColumns = rendered.querySelectorAll('.ReactVirtualized__Table__rowColumn:first-of-type'); Array.from(nameColumns).forEach(function (nameColumn, index) { expect(nameColumn.textContent).toEqual("Custom name for row ".concat(index)); }); }); it('should use a custom cellRenderer if specified', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellRenderer: function cellRenderer(_ref9) { var cellData = _ref9.cellData; return "Custom ".concat(cellData); } }))); var nameColumns = rendered.querySelectorAll('.ReactVirtualized__Table__rowColumn:first-of-type'); Array.from(nameColumns).forEach(function (nameColumn, index) { var rowData = list.get(index); expect(nameColumn.textContent).toEqual("Custom ".concat(rowData.get('name'))); }); }); it('should set the rendered cell content as the cell :title if it is a string', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellRenderer: function cellRenderer() { return 'Custom'; } }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__rowColumn:first-of-type'); expect(nameColumn.getAttribute('title')).toContain('Custom'); }); it('should not set a cell :title if the rendered cell content is not a string', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellRenderer: function cellRenderer() { return React.createElement("div", null, "Custom"); } }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__rowColumn:first-of-type'); expect(nameColumn.getAttribute('title')).toEqual(null); }); it('should set the rendered header label as header :title if it is a string', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ label: 'Custom' }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerTruncatedText:first-of-type'); expect(nameColumn.getAttribute('title')).toContain('Custom'); }); it('should not set a header :title if the rendered header label is not a string', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ label: React.createElement("div", null, "Custom") }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerTruncatedText:first-of-type'); expect(nameColumn.getAttribute('title')).toEqual(null); }); }); describe('sorting', function () { it('should not render sort indicators if no sort function is provided', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); var nameColumn = rendered.querySelectorAll('.ReactVirtualized__Table__headerColumn:first-of-type'); expect(nameColumn.className || '').not.toContain('ReactVirtualized__Table__sortableHeaderColumn'); }); it('should not render sort indicators for non-sortable columns', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ disableSort: true, sort: function sort() {} }))); var nameColumn = rendered.querySelectorAll('.ReactVirtualized__Table__headerColumn:first-of-type'); expect(nameColumn.className || '').not.toContain('ReactVirtualized__Table__sortableHeaderColumn'); expect(rendered.querySelectorAll('.ReactVirtualized__Table__sortableHeaderColumn').length).toEqual(1); // Email only }); it('should render sortable column headers as sortable', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ sort: function sort() {} }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); expect(nameColumn.className).toContain('ReactVirtualized__Table__sortableHeaderColumn'); expect(rendered.querySelectorAll('.ReactVirtualized__Table__sortableHeaderColumn').length).toEqual(2); // Email and Name }); it('should render the correct sort indicator by the current sort-by column', function () { var sortDirections = [_SortDirection["default"].ASC, _SortDirection["default"].DESC]; sortDirections.forEach(function (sortDirection) { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ sort: function sort() {}, sortBy: 'name', sortDirection: sortDirection }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); expect(nameColumn.querySelector('.ReactVirtualized__Table__sortableHeaderIcon')).not.toEqual(null); expect(nameColumn.querySelector(".ReactVirtualized__Table__sortableHeaderIcon--".concat(sortDirection))).not.toEqual(null); }); }); it('should call sort with the correct arguments when the current sort-by column header is clicked', function () { var sortDirections = [_SortDirection["default"].ASC, _SortDirection["default"].DESC]; sortDirections.forEach(function (sortDirection) { var sortCalls = []; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ sort: function sort(_ref10) { var sortBy = _ref10.sortBy, sortDirection = _ref10.sortDirection; return sortCalls.push({ sortBy: sortBy, sortDirection: sortDirection }); }, sortBy: 'name', sortDirection: sortDirection }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); _testUtils.Simulate.click(nameColumn); expect(sortCalls.length).toEqual(1); var _sortCalls$ = sortCalls[0], sortBy = _sortCalls$.sortBy, newSortDirection = _sortCalls$.sortDirection; var expectedSortDirection = sortDirection === _SortDirection["default"].ASC ? _SortDirection["default"].DESC : _SortDirection["default"].ASC; expect(sortBy).toEqual('name'); expect(newSortDirection).toEqual(expectedSortDirection); }); }); it('should call sort with the correct arguments when a new sort-by column header is clicked', function () { var sortCalls = []; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ sort: function sort(_ref11) { var sortBy = _ref11.sortBy, sortDirection = _ref11.sortDirection; return sortCalls.push({ sortBy: sortBy, sortDirection: sortDirection }); }, sortBy: 'email', sortDirection: _SortDirection["default"].ASC }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); _testUtils.Simulate.click(nameColumn); expect(sortCalls.length).toEqual(1); var _sortCalls$2 = sortCalls[0], sortBy = _sortCalls$2.sortBy, sortDirection = _sortCalls$2.sortDirection; expect(sortBy).toEqual('name'); expect(sortDirection).toEqual(_SortDirection["default"].ASC); }); it('should call sort when a column header is activated via ENTER or SPACE key', function () { var sortCalls = []; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ sort: function sort(_ref12) { var sortBy = _ref12.sortBy, sortDirection = _ref12.sortDirection; return sortCalls.push({ sortBy: sortBy, sortDirection: sortDirection }); }, sortBy: 'name' }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); expect(sortCalls.length).toEqual(0); _testUtils.Simulate.keyDown(nameColumn, { key: ' ' }); expect(sortCalls.length).toEqual(1); _testUtils.Simulate.keyDown(nameColumn, { key: 'Enter' }); expect(sortCalls.length).toEqual(2); _testUtils.Simulate.keyDown(nameColumn, { key: 'F' }); expect(sortCalls.length).toEqual(2); }); it('should honor the default sort order on first click of the column', function () { var sortDirections = [_SortDirection["default"].ASC, _SortDirection["default"].DESC]; sortDirections.forEach(function (sortDirection) { var sortCalls = []; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ sort: function sort(_ref13) { var sortBy = _ref13.sortBy, sortDirection = _ref13.sortDirection; return sortCalls.push({ sortBy: sortBy, sortDirection: sortDirection }); }, defaultSortDirection: sortDirection }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); _testUtils.Simulate.click(nameColumn); expect(sortCalls.length).toEqual(1); var _sortCalls$3 = sortCalls[0], sortBy = _sortCalls$3.sortBy, newSortDirection = _sortCalls$3.sortDirection; expect(sortBy).toEqual('name'); expect(newSortDirection).toEqual(sortDirection); }); }); }); describe('headerRowRenderer', function () { it('should render a custom header row if one is provided', function () { var headerRowRenderer = jest.fn().mockReturnValue(React.createElement("div", null, "foo bar")); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ headerHeight: 33, headerRowRenderer: headerRowRenderer, rowClassName: 'someRowClass' }))); expect(rendered.textContent).toContain('foo bar'); expect(headerRowRenderer).toHaveBeenCalled(); var params = headerRowRenderer.mock.calls[0][0]; expect(params.className).toContain('someRowClass'); expect(params.columns).toHaveLength(2); expect(params.style.height).toBe(33); }); }); describe('headerRenderer', function () { it('should render a custom header if one is provided', function () { var columnData = { foo: 'foo', bar: 'bar' }; var headerRendererCalls = []; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnData: columnData, headerRenderer: function headerRenderer(params) { headerRendererCalls.push(params); return 'custom header'; }, sortBy: 'name', sortDirection: _SortDirection["default"].ASC }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); expect(nameColumn.textContent).toContain('custom header'); expect(headerRendererCalls.length).toBeTruthy(); var headerRendererCall = headerRendererCalls[0]; expect(headerRendererCall.columnData).toEqual(columnData); expect(headerRendererCall.dataKey).toEqual('name'); expect(headerRendererCall.disableSort).toEqual(false); expect(headerRendererCall.label).toEqual('Name'); expect(headerRendererCall.sortBy).toEqual('name'); expect(headerRendererCall.sortDirection).toEqual(_SortDirection["default"].ASC); }); it('should honor sort for custom headers', function () { var sortCalls = []; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ headerRenderer: function headerRenderer() { return 'custom header'; }, sort: function sort(_ref14) { var sortBy = _ref14.sortBy, sortDirection = _ref14.sortDirection; return sortCalls.push([sortBy, sortDirection]); }, sortBy: 'name', sortDirection: _SortDirection["default"].ASC }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); _testUtils.Simulate.click(nameColumn); expect(sortCalls.length).toEqual(1); var sortCall = sortCalls[0]; expect(sortCall[0]).toEqual('name'); expect(sortCall[1]).toEqual(_SortDirection["default"].DESC); }); it('should honor :onHeaderClick for custom header', function () { var columnData = { foo: 'foo', bar: 'bar' }; var onHeaderClick = jest.fn(); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnData: columnData, headerRenderer: function headerRenderer() { return 'custom header'; }, onHeaderClick: onHeaderClick }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); _testUtils.Simulate.click(nameColumn); expect(onHeaderClick).toHaveBeenCalledTimes(1); var params = onHeaderClick.mock.calls[0][0]; expect(params.dataKey).toEqual('name'); expect(params.columnData).toEqual(columnData); expect(params.event.type).toEqual('click'); }); }); describe('noRowsRenderer', function () { it('should call :noRowsRenderer if :rowCount is 0', function () { var rendered = (0, _TestUtils.render)(getMarkup({ noRowsRenderer: function noRowsRenderer() { return React.createElement("div", null, "No rows!"); }, rowCount: 0 })); var bodyDOMNode = (0, _reactDom.findDOMNode)(rendered.Grid); expect(bodyDOMNode.textContent).toEqual('No rows!'); }); it('should render an empty body if :rowCount is 0 and there is no :noRowsRenderer', function () { var rendered = (0, _TestUtils.render)(getMarkup({ rowCount: 0 })); var bodyDOMNode = (0, _reactDom.findDOMNode)(rendered.Grid); expect(bodyDOMNode.textContent).toEqual(''); }); }); describe('onColumnClick', function () { it('should call :onColumnClick with the correct arguments when a column is clicked', function () { var onColumnClick = jest.fn(); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onColumnClick: onColumnClick }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__rowColumn:first-of-type'); _testUtils.Simulate.click(nameColumn); expect(onColumnClick).toHaveBeenCalledTimes(1); var params = onColumnClick.mock.calls[0][0]; expect(params.dataKey).toEqual('name'); expect(params.columnData.data).toEqual(123); expect(params.event.type).toEqual('click'); }); }); describe('onHeaderClick', function () { it('should call :onHeaderClick with the correct arguments when a column header is clicked and sorting is disabled', function () { var onHeaderClick = jest.fn(); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ disableSort: true, onHeaderClick: onHeaderClick }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); _testUtils.Simulate.click(nameColumn); expect(onHeaderClick).toHaveBeenCalledTimes(1); var params = onHeaderClick.mock.calls[0][0]; expect(params.dataKey).toEqual('name'); expect(params.columnData.data).toEqual(123); expect(params.event.type).toEqual('click'); }); it('should call :onHeaderClick with the correct arguments when a column header is clicked and sorting is enabled', function () { var onHeaderClick = jest.fn(); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ disableSort: false, onHeaderClick: onHeaderClick }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); _testUtils.Simulate.click(nameColumn); expect(onHeaderClick).toHaveBeenCalledTimes(1); var params = onHeaderClick.mock.calls[0][0]; expect(params.dataKey).toEqual('name'); expect(params.columnData.data).toEqual(123); expect(params.event.type).toEqual('click'); }); }); describe('onRowClick', function () { it('should call :onRowClick with the correct :rowIndex when a row is clicked', function () { var onRowClick = jest.fn(); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onRowClick: onRowClick }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); _testUtils.Simulate.click(rows[0]); _testUtils.Simulate.click(rows[3]); expect(onRowClick).toHaveBeenCalledTimes(2); expect(onRowClick.mock.calls.map(function (call) { return call[0].index; })).toEqual([0, 3]); }); }); describe('onRowDoubleClick', function () { it('should call :onRowDoubleClick with the correct :rowIndex when a row is clicked', function () { var onRowDoubleClick = jest.fn(); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onRowDoubleClick: onRowDoubleClick }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); _testUtils.Simulate.doubleClick(rows[0]); _testUtils.Simulate.doubleClick(rows[3]); expect(onRowDoubleClick).toHaveBeenCalledTimes(2); expect(onRowDoubleClick.mock.calls.map(function (call) { return call[0].index; })).toEqual([0, 3]); }); }); describe('onRowRightClick', function () { it('should call :onRowRightClick with the correct :rowIndex when a row is right-clicked', function () { var onRowRightClick = jest.fn(); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onRowRightClick: onRowRightClick }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); _testUtils.Simulate.contextMenu(rows[0]); _testUtils.Simulate.contextMenu(rows[3]); expect(onRowRightClick).toHaveBeenCalledTimes(2); expect(onRowRightClick.mock.calls.map(function (call) { return call[0].index; })).toEqual([0, 3]); }); }); describe('onRowMouseOver/Out', function () { it('should call :onRowMouseOver and :onRowMouseOut with the correct :rowIndex when the mouse is moved over rows', function () { var onRowMouseOver = jest.fn(); var onRowMouseOut = jest.fn(); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onRowMouseOver: onRowMouseOver, onRowMouseOut: onRowMouseOut }))); var simulateMouseOver = function simulateMouseOver(from, to) { _testUtils.Simulate.mouseOut(from, { relatedTarget: to }); _testUtils.Simulate.mouseOver(to, { relatedTarget: from }); }; var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); simulateMouseOver(rows[0], rows[1]); simulateMouseOver(rows[1], rows[2]); simulateMouseOver(rows[2], rows[3]); expect(onRowMouseOver).toHaveBeenCalled(); expect(onRowMouseOut).toHaveBeenCalled(); expect(onRowMouseOver.mock.calls.map(function (call) { return call[0].index; })).toEqual([1, 2, 3]); expect(onRowMouseOut.mock.calls.map(function (call) { return call[0].index; })).toEqual([0, 1, 2]); }); }); describe('rowClassName', function () { it('should render a static classname given :rowClassName as a string', function () { var staticClassName = 'staticClass'; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ rowClassName: staticClassName }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); Array.from(rows).forEach(function (row) { expect(row.className).toContain(staticClassName); }); }); it('should render dynamic classname given :rowClassName as a function', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ rowClassName: function rowClassName(_ref15) { var index = _ref15.index; return index % 2 === 0 ? 'even' : 'odd'; } }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); Array.from(rows).forEach(function (row, index) { if (index % 2 === 0) { expect(row.className).toContain('even'); expect(row.className).not.toContain('odd'); } else { expect(row.className).toContain('odd'); expect(row.className).not.toContain('even'); } }); }); }); describe('onRowsRendered', function () { it('should call :onRowsRendered at least one row is rendered', function () { var startIndex, stopIndex; (0, _TestUtils.render)(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params; return _params = params, startIndex = _params.startIndex, stopIndex = _params.stopIndex, _params; } })); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(7); }); it('should not call :onRowsRendered unless the start or stop indices have changed', function () { var numCalls = 0; var startIndex; var stopIndex; var onRowsRendered = function onRowsRendered(params) { startIndex = params.startIndex; stopIndex = params.stopIndex; numCalls++; }; (0, _TestUtils.render)(getMarkup({ onRowsRendered: onRowsRendered })); expect(numCalls).toEqual(1); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(7); (0, _TestUtils.render)(getMarkup({ onRowsRendered: onRowsRendered })); expect(numCalls).toEqual(1); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(7); }); it('should call :onRowsRendered if the start or stop indices have changed', function () { var numCalls = 0; var startIndex; var stopIndex; var onRowsRendered = function onRowsRendered(params) { startIndex = params.startIndex; stopIndex = params.stopIndex; numCalls++; }; (0, _TestUtils.render)(getMarkup({ onRowsRendered: onRowsRendered })); expect(numCalls).toEqual(1); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(7); (0, _TestUtils.render)(getMarkup({ height: 50, onRowsRendered: onRowsRendered })); expect(numCalls).toEqual(2); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(2); }); it('should not call :onRowsRendered if no rows are rendered', function () { var startIndex, stopIndex; (0, _TestUtils.render)(getMarkup({ height: 0, onRowsRendered: function onRowsRendered(params) { var _params2; return _params2 = params, startIndex = _params2.startIndex, stopIndex = _params2.stopIndex, _params2; } })); expect(startIndex).toEqual(undefined); expect(stopIndex).toEqual(undefined); }); }); describe(':scrollTop property', function () { it('should render correctly when an initial :scrollTop property is specified', function () { var startIndex, stopIndex; (0, _TestUtils.render)(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params3; return _params3 = params, startIndex = _params3.startIndex, stopIndex = _params3.stopIndex, _params3; }, scrollTop: 80 })); expect(startIndex).toEqual(8); expect(stopIndex).toEqual(15); }); it('should render correctly when :scrollTop property is updated', function () { var startIndex, stopIndex; (0, _TestUtils.render)(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params4; return _params4 = params, startIndex = _params4.startIndex, stopIndex = _params4.stopIndex, _params4; } })); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(7); (0, _TestUtils.render)(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params5; return _params5 = params, startIndex = _params5.startIndex, stopIndex = _params5.stopIndex, _params5; }, scrollTop: 80 })); expect(startIndex).toEqual(8); expect(stopIndex).toEqual(15); }); }); describe('styles, classNames, and ids', function () { it('should use the expected global CSS classNames', function () { var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ sort: function sort() {}, sortBy: 'name', sortDirection: _SortDirection["default"].ASC }))); expect(node.className).toEqual('ReactVirtualized__Table'); expect(node.querySelector('.ReactVirtualized__Table__headerRow')).toBeTruthy(); expect(node.querySelector('.ReactVirtualized__Table__rowColumn')).toBeTruthy(); expect(node.querySelector('.ReactVirtualized__Table__headerColumn')).toBeTruthy(); expect(node.querySelector('.ReactVirtualized__Table__row')).toBeTruthy(); expect(node.querySelector('.ReactVirtualized__Table__sortableHeaderColumn')).toBeTruthy(); expect(node.querySelector('.ReactVirtualized__Table__sortableHeaderIcon')).toBeTruthy(); }); it('should use a custom :className if specified', function () { var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ className: 'foo', headerClassName: 'bar', rowClassName: 'baz' }))); expect(node.className).toContain('foo'); expect(node.querySelectorAll('.bar').length).toEqual(2); expect(node.querySelectorAll('.baz').length).toEqual(9); }); it('should use a custom :id if specified', function () { var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ id: 'bar' }))); expect(node.getAttribute('id')).toEqual('bar'); }); it('should not set :id on the inner Grid', function () { var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ id: 'bar' }))); var grid = node.querySelector('.ReactVirtualized__Grid'); expect(grid.getAttribute('id')).not.toEqual('bar'); }); it('should use custom :styles if specified', function () { var columnStyle = { backgroundColor: 'red', overflow: 'visible' }; var headerStyle = { backgroundColor: 'blue' }; var columnHeaderStyle = { color: 'yellow' }; var rowStyle = { backgroundColor: 'green' }; var style = { backgroundColor: 'orange' }; var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnStyle: columnStyle, headerStyle: headerStyle, columnHeaderStyle: columnHeaderStyle, rowStyle: rowStyle, style: style }))); expect(node.querySelector('.ReactVirtualized__Table__rowColumn').style.backgroundColor).toEqual('red'); expect(node.querySelector('.ReactVirtualized__Table__rowColumn').style.overflow).toEqual('visible'); expect(node.querySelector('.ReactVirtualized__Table__headerColumn').style.backgroundColor).toEqual('blue'); expect(node.querySelector('.ReactVirtualized__Table__headerColumn').style.color).toEqual('yellow'); expect(node.querySelector('.ReactVirtualized__Table__row').style.backgroundColor).toEqual('green'); expect(node.style.backgroundColor).toEqual('orange'); }); it('should render dynamic style given :rowStyle as a function', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ rowStyle: function rowStyle(_ref16) { var index = _ref16.index; return index % 2 === 0 ? { backgroundColor: 'red' } : { backgroundColor: 'green' }; } }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); Array.from(rows).forEach(function (row, index) { if (index % 2 === 0) { expect(row.style.backgroundColor).toEqual('red'); } else { expect(row.style.backgroundColor).toEqual('green'); } }); }); it('should pass :gridClassName and :gridStyle to the inner Grid', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ gridClassName: 'foo', gridStyle: { backgroundColor: 'red' } }))); var grid = rendered.querySelector('.ReactVirtualized__Grid'); expect(grid.className).toContain('foo'); expect(grid.style.backgroundColor).toEqual('red'); }); }); describe('overscanRowCount', function () { it('should not overscan by default', function () { var mock = jest.fn(); mock.mockImplementation(overscanIndicesGetter); (0, _TestUtils.render)(getMarkup({ overscanIndicesGetter: mock })); expect(mock.mock.calls[0][0].overscanCellsCount).toEqual(0); expect(mock.mock.calls[1][0].overscanCellsCount).toEqual(0); }); it('should overscan the specified amount', function () { var mock = jest.fn(); mock.mockImplementation(overscanIndicesGetter); (0, _TestUtils.render)(getMarkup({ overscanIndicesGetter: mock, overscanRowCount: 10 })); expect(mock.mock.calls[0][0].overscanCellsCount).toEqual(0); expect(mock.mock.calls[1][0].overscanCellsCount).toEqual(10); }); }); describe('onScroll', function () { it('should trigger callback when component initially mounts', function () { var onScrollCalls = []; (0, _TestUtils.render)(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); expect(onScrollCalls).toEqual([{ clientHeight: 80, scrollHeight: 1000, scrollTop: 0 }]); }); it('should trigger callback when component scrolls', function () { var onScrollCalls = []; var rendered = (0, _TestUtils.render)(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); var target = { scrollLeft: 0, scrollTop: 100 }; rendered.Grid._scrollingContainer = target; // HACK to work around _onScroll target check _testUtils.Simulate.scroll((0, _reactDom.findDOMNode)(rendered.Grid), { target: target }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: 80, scrollHeight: 1000, scrollTop: 100 }); }); }); describe('a11y properties', function () { it('should set aria role on the table', function () { var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(node.getAttribute('role')).toEqual('grid'); }); it('should set aria col/row count on the table', function () { var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(node.getAttribute('aria-colcount')).toEqual('2'); expect(node.getAttribute('aria-rowcount')).toEqual("".concat(list.size)); }); it('should pass down aria labels on the table', function () { var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ 'aria-label': 'my-table-label', 'aria-labelledby': 'my-table-label-id' }))); expect(node.getAttribute('aria-label')).toEqual('my-table-label'); expect(node.getAttribute('aria-labelledby')).toEqual('my-table-label-id'); }); it('should set aria role on the header row', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); var row = rendered.querySelector('.ReactVirtualized__Table__headerRow'); expect(row.getAttribute('role')).toEqual('row'); }); it('should set appropriate aria role on the grid', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); var grid = rendered.querySelector('.ReactVirtualized__Table__Grid'); expect(grid.getAttribute('role')).toEqual('rowgroup'); }); it('should set aria role on a row', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); var row = rendered.querySelector('.ReactVirtualized__Table__row'); expect(row.getAttribute('role')).toEqual('row'); }); it('should set aria rowindex on a row', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); expect(rows[0].getAttribute('aria-rowindex')).toEqual('1'); expect(rows[1].getAttribute('aria-rowindex')).toEqual('2'); }); it('should set aria role on a cell', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); var cell = rendered.querySelector('.ReactVirtualized__Table__rowColumn'); expect(cell.getAttribute('role')).toEqual('gridcell'); }); it('should set aria colindex on a cell', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); var cells = rendered.querySelectorAll('.ReactVirtualized__Table__rowColumn'); expect(cells[0].getAttribute('aria-colindex')).toEqual('1'); expect(cells[1].getAttribute('aria-colindex')).toEqual('2'); }); it('should set aria-describedby on a cell when the column has an id', function () { var columnID = 'column-header-test'; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnID: columnID }))); var cell = rendered.querySelector('.ReactVirtualized__Table__rowColumn'); expect(cell.getAttribute('aria-describedby')).toEqual(columnID); }); it('should attach a11y properties to a row if :onRowClick is specified', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onRowClick: function onRowClick() {} }))); var row = rendered.querySelector('.ReactVirtualized__Table__row'); expect(row.getAttribute('aria-label')).toEqual('row'); expect(row.tabIndex).toEqual(0); }); it('should not attach a11y properties to a row if no :onRowClick is specified', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onRowClick: null }))); var row = rendered.querySelector('.ReactVirtualized__Table__row'); expect(row.getAttribute('aria-label')).toEqual(null); expect(row.tabIndex).toEqual(-1); }); it('should set aria role on a header column', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); var header = rendered.querySelector('.ReactVirtualized__Table__headerColumn'); expect(header.getAttribute('role')).toEqual('columnheader'); }); it('should set aria-sort ascending on a header column if the column is sorted ascending', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ sortBy: 'name', sortDirection: _SortDirection["default"].ASC }))); var header = rendered.querySelector('.ReactVirtualized__Table__headerColumn'); expect(header.getAttribute('aria-sort')).toEqual('ascending'); }); it('should set aria-sort descending on a header column if the column is sorted descending', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ sortBy: 'name', sortDirection: _SortDirection["default"].DESC }))); var header = rendered.querySelector('.ReactVirtualized__Table__headerColumn'); expect(header.getAttribute('aria-sort')).toEqual('descending'); }); it('should set aria-sort to "none" if the column is sortable but not the current sort', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ disableSort: true, sort: jest.fn() }))); var headers = rendered.querySelectorAll('.ReactVirtualized__Table__headerColumn'); // the first column is not sortable expect(headers[0].getAttribute('aria-sort')).toBe(null); // the second column is sortable expect(headers[1].getAttribute('aria-sort')).toEqual('none'); }); it('should set id on a header column when the column has an id', function () { var columnID = 'column-header-test'; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnID: columnID }))); var header = rendered.querySelector('.ReactVirtualized__Table__headerColumn'); expect(header.getAttribute('id')).toEqual(columnID); }); it('should attach a11y properties to a header column if sort is enabled', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ disableSort: false, sort: function sort() {} }))); var row = rendered.querySelector('.ReactVirtualized__Table__headerColumn'); expect(row.getAttribute('aria-label')).toEqual('Name'); expect(row.tabIndex).toEqual(0); }); it('should not attach a11y properties to a header column if sort is not enabled', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ disableSort: true }))); var row = rendered.querySelector('.ReactVirtualized__Table__headerColumn'); expect(row.getAttribute('aria-label')).toEqual(null); expect(row.tabIndex).toEqual(-1); }); }); describe('tabIndex', function () { it('should be focusable by default', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.querySelector('.ReactVirtualized__Grid').tabIndex).toEqual(0); }); it('should allow tabIndex to be overridden', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ tabIndex: -1 }))); expect(rendered.querySelector('.ReactVirtualized__Grid').tabIndex).toEqual(-1); }); }); describe('pure', function () { it('should not re-render unless props have changed', function () { var headerRendererCalled = false; var cellRendererCalled = false; function headerRenderer() { headerRendererCalled = true; return 'foo'; } function cellRenderer() { cellRendererCalled = true; return 'foo'; } var markup = getMarkup({ headerRenderer: headerRenderer, cellRenderer: cellRenderer }); (0, _TestUtils.render)(markup); expect(headerRendererCalled).toEqual(true); expect(cellRendererCalled).toEqual(true); headerRendererCalled = false; cellRendererCalled = false; (0, _TestUtils.render)(markup); expect(headerRendererCalled).toEqual(false); expect(cellRendererCalled).toEqual(false); }); it('should re-render both the Table and the inner Grid whenever an external property changes', function () { var headerRendererCalled = false; var cellRendererCalled = false; function headerRenderer() { headerRendererCalled = true; return 'foo'; } function cellRenderer() { cellRendererCalled = true; return 'foo'; } var initialProperties = { autoHeight: false, cellRenderer: cellRenderer, estimatedRowSize: 15, headerRenderer: headerRenderer, overscanRowCount: 1, rowHeight: 15, rowCount: 20, scrollToAlignment: 'auto', scrollTop: 0, sortBy: 'name', sortDirection: _SortDirection["default"].ASC, tabIndex: null }; var changedProperties = { autoHeight: true, estimatedRowSize: 10, overscanRowCount: 0, rowHeight: 10, rowCount: 10, scrollToAlignment: 'center', scrollTop: 1, sortBy: 'email', sortDirection: _SortDirection["default"].DESC, tabIndex: 1 }; Object.entries(changedProperties).forEach(function (_ref17) { var _ref18 = (0, _slicedToArray2["default"])(_ref17, 2), key = _ref18[0], value = _ref18[1]; _TestUtils.render.unmount(); // Reset (0, _TestUtils.render)(getMarkup(initialProperties)); headerRendererCalled = true; cellRendererCalled = false; (0, _TestUtils.render)(getMarkup(_objectSpread({}, initialProperties, (0, _defineProperty2["default"])({}, key, value)))); expect(headerRendererCalled).toEqual(true); expect(cellRendererCalled).toEqual(true); }); }); }); it('should set the width of the single-column inner Grid to auto', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('auto'); }); it('should relay the Grid :parent param to the Column :cellRenderer', function () { var cellRenderer = jest.fn().mockReturnValue(null); (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer }))); expect(cellRenderer.mock.calls[0][0].parent).not.toBeUndefined(); }); });dist/commonjs/Table/types.js000064400000011024151676725760012111 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.bpfrpt_proptype_RowRendererParams = exports.bpfrpt_proptype_HeaderRendererParams = exports.bpfrpt_proptype_HeaderRowRendererParams = exports.bpfrpt_proptype_CellRendererParams = exports.bpfrpt_proptype_CellDataGetterParams = void 0; var _propTypes = _interopRequireDefault(require("prop-types")); var bpfrpt_proptype_CellDataGetterParams = process.env.NODE_ENV === 'production' ? null : { "columnData": _propTypes["default"].any, "dataKey": _propTypes["default"].string.isRequired, "rowData": function rowData(props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } } }; exports.bpfrpt_proptype_CellDataGetterParams = bpfrpt_proptype_CellDataGetterParams; var bpfrpt_proptype_CellRendererParams = process.env.NODE_ENV === 'production' ? null : { "cellData": _propTypes["default"].any, "columnData": _propTypes["default"].any, "dataKey": _propTypes["default"].string.isRequired, "rowData": function rowData(props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } }, "rowIndex": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_CellRendererParams = bpfrpt_proptype_CellRendererParams; var bpfrpt_proptype_HeaderRowRendererParams = process.env.NODE_ENV === 'production' ? null : { "className": _propTypes["default"].string.isRequired, "columns": _propTypes["default"].arrayOf(function (props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } }).isRequired, "style": function style(props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } } }; exports.bpfrpt_proptype_HeaderRowRendererParams = bpfrpt_proptype_HeaderRowRendererParams; var bpfrpt_proptype_HeaderRendererParams = process.env.NODE_ENV === 'production' ? null : { "columnData": _propTypes["default"].any, "dataKey": _propTypes["default"].string.isRequired, "disableSort": _propTypes["default"].bool, "label": _propTypes["default"].any, "sortBy": _propTypes["default"].string, "sortDirection": _propTypes["default"].string }; exports.bpfrpt_proptype_HeaderRendererParams = bpfrpt_proptype_HeaderRendererParams; var bpfrpt_proptype_RowRendererParams = process.env.NODE_ENV === 'production' ? null : { "className": _propTypes["default"].string.isRequired, "columns": _propTypes["default"].arrayOf(function (props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } }).isRequired, "index": _propTypes["default"].number.isRequired, "isScrolling": _propTypes["default"].bool.isRequired, "onRowClick": _propTypes["default"].func, "onRowDoubleClick": _propTypes["default"].func, "onRowMouseOver": _propTypes["default"].func, "onRowMouseOut": _propTypes["default"].func, "rowData": function rowData(props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } }, "style": function style(props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } }, "key": _propTypes["default"].string.isRequired }; exports.bpfrpt_proptype_RowRendererParams = bpfrpt_proptype_RowRendererParams;dist/commonjs/Table/Table.js000064400000070236151676725760012006 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _clsx = _interopRequireDefault(require("clsx")); var _Column = _interopRequireDefault(require("./Column")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _Grid2 = _interopRequireWildcard(require("../Grid")); var _defaultRowRenderer = _interopRequireDefault(require("./defaultRowRenderer")); var _defaultHeaderRowRenderer = _interopRequireDefault(require("./defaultHeaderRowRenderer")); var _SortDirection = _interopRequireDefault(require("./SortDirection")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * Table component with fixed headers and virtualized rows for improved performance with large data sets. * This component expects explicit width, height, and padding parameters. */ var Table = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(Table, _React$PureComponent); function Table(props) { var _this; (0, _classCallCheck2["default"])(this, Table); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(Table).call(this, props)); _this.state = { scrollbarWidth: 0 }; _this._createColumn = _this._createColumn.bind((0, _assertThisInitialized2["default"])(_this)); _this._createRow = _this._createRow.bind((0, _assertThisInitialized2["default"])(_this)); _this._onScroll = _this._onScroll.bind((0, _assertThisInitialized2["default"])(_this)); _this._onSectionRendered = _this._onSectionRendered.bind((0, _assertThisInitialized2["default"])(_this)); _this._setRef = _this._setRef.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(Table, [{ key: "forceUpdateGrid", value: function forceUpdateGrid() { if (this.Grid) { this.Grid.forceUpdate(); } } /** See Grid#getOffsetForCell */ }, { key: "getOffsetForRow", value: function getOffsetForRow(_ref) { var alignment = _ref.alignment, index = _ref.index; if (this.Grid) { var _this$Grid$getOffsetF = this.Grid.getOffsetForCell({ alignment: alignment, rowIndex: index }), scrollTop = _this$Grid$getOffsetF.scrollTop; return scrollTop; } return 0; } /** CellMeasurer compatibility */ }, { key: "invalidateCellSizeAfterRender", value: function invalidateCellSizeAfterRender(_ref2) { var columnIndex = _ref2.columnIndex, rowIndex = _ref2.rowIndex; if (this.Grid) { this.Grid.invalidateCellSizeAfterRender({ rowIndex: rowIndex, columnIndex: columnIndex }); } } /** See Grid#measureAllCells */ }, { key: "measureAllRows", value: function measureAllRows() { if (this.Grid) { this.Grid.measureAllCells(); } } /** CellMeasurer compatibility */ }, { key: "recomputeGridSize", value: function recomputeGridSize() { var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref3$columnIndex = _ref3.columnIndex, columnIndex = _ref3$columnIndex === void 0 ? 0 : _ref3$columnIndex, _ref3$rowIndex = _ref3.rowIndex, rowIndex = _ref3$rowIndex === void 0 ? 0 : _ref3$rowIndex; if (this.Grid) { this.Grid.recomputeGridSize({ rowIndex: rowIndex, columnIndex: columnIndex }); } } /** See Grid#recomputeGridSize */ }, { key: "recomputeRowHeights", value: function recomputeRowHeights() { var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (this.Grid) { this.Grid.recomputeGridSize({ rowIndex: index }); } } /** See Grid#scrollToPosition */ }, { key: "scrollToPosition", value: function scrollToPosition() { var scrollTop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (this.Grid) { this.Grid.scrollToPosition({ scrollTop: scrollTop }); } } /** See Grid#scrollToCell */ }, { key: "scrollToRow", value: function scrollToRow() { var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (this.Grid) { this.Grid.scrollToCell({ columnIndex: 0, rowIndex: index }); } } }, { key: "getScrollbarWidth", value: function getScrollbarWidth() { if (this.Grid) { var _Grid = (0, _reactDom.findDOMNode)(this.Grid); var clientWidth = _Grid.clientWidth || 0; var offsetWidth = _Grid.offsetWidth || 0; return offsetWidth - clientWidth; } return 0; } }, { key: "componentDidMount", value: function componentDidMount() { this._setScrollbarWidth(); } }, { key: "componentDidUpdate", value: function componentDidUpdate() { this._setScrollbarWidth(); } }, { key: "render", value: function render() { var _this2 = this; var _this$props = this.props, children = _this$props.children, className = _this$props.className, disableHeader = _this$props.disableHeader, gridClassName = _this$props.gridClassName, gridStyle = _this$props.gridStyle, headerHeight = _this$props.headerHeight, headerRowRenderer = _this$props.headerRowRenderer, height = _this$props.height, id = _this$props.id, noRowsRenderer = _this$props.noRowsRenderer, rowClassName = _this$props.rowClassName, rowStyle = _this$props.rowStyle, scrollToIndex = _this$props.scrollToIndex, style = _this$props.style, width = _this$props.width; var scrollbarWidth = this.state.scrollbarWidth; var availableRowsHeight = disableHeader ? height : height - headerHeight; var rowClass = typeof rowClassName === 'function' ? rowClassName({ index: -1 }) : rowClassName; var rowStyleObject = typeof rowStyle === 'function' ? rowStyle({ index: -1 }) : rowStyle; // Precompute and cache column styles before rendering rows and columns to speed things up this._cachedColumnStyles = []; React.Children.toArray(children).forEach(function (column, index) { var flexStyles = _this2._getFlexStyleForColumn(column, column.props.style); _this2._cachedColumnStyles[index] = _objectSpread({ overflow: 'hidden' }, flexStyles); }); // Note that we specify :rowCount, :scrollbarWidth, :sortBy, and :sortDirection as properties on Grid even though these have nothing to do with Grid. // This is done because Grid is a pure component and won't update unless its properties or state has changed. // Any property that should trigger a re-render of Grid then is specified here to avoid a stale display. return React.createElement("div", { "aria-label": this.props['aria-label'], "aria-labelledby": this.props['aria-labelledby'], "aria-colcount": React.Children.toArray(children).length, "aria-rowcount": this.props.rowCount, className: (0, _clsx["default"])('ReactVirtualized__Table', className), id: id, role: "grid", style: style }, !disableHeader && headerRowRenderer({ className: (0, _clsx["default"])('ReactVirtualized__Table__headerRow', rowClass), columns: this._getHeaderColumns(), style: _objectSpread({ height: headerHeight, overflow: 'hidden', paddingRight: scrollbarWidth, width: width }, rowStyleObject) }), React.createElement(_Grid2["default"], (0, _extends2["default"])({}, this.props, { "aria-readonly": null, autoContainerWidth: true, className: (0, _clsx["default"])('ReactVirtualized__Table__Grid', gridClassName), cellRenderer: this._createRow, columnWidth: width, columnCount: 1, height: availableRowsHeight, id: undefined, noContentRenderer: noRowsRenderer, onScroll: this._onScroll, onSectionRendered: this._onSectionRendered, ref: this._setRef, role: "rowgroup", scrollbarWidth: scrollbarWidth, scrollToRow: scrollToIndex, style: _objectSpread({}, gridStyle, { overflowX: 'hidden' }) }))); } }, { key: "_createColumn", value: function _createColumn(_ref4) { var column = _ref4.column, columnIndex = _ref4.columnIndex, isScrolling = _ref4.isScrolling, parent = _ref4.parent, rowData = _ref4.rowData, rowIndex = _ref4.rowIndex; var onColumnClick = this.props.onColumnClick; var _column$props = column.props, cellDataGetter = _column$props.cellDataGetter, cellRenderer = _column$props.cellRenderer, className = _column$props.className, columnData = _column$props.columnData, dataKey = _column$props.dataKey, id = _column$props.id; var cellData = cellDataGetter({ columnData: columnData, dataKey: dataKey, rowData: rowData }); var renderedCell = cellRenderer({ cellData: cellData, columnData: columnData, columnIndex: columnIndex, dataKey: dataKey, isScrolling: isScrolling, parent: parent, rowData: rowData, rowIndex: rowIndex }); var onClick = function onClick(event) { onColumnClick && onColumnClick({ columnData: columnData, dataKey: dataKey, event: event }); }; var style = this._cachedColumnStyles[columnIndex]; var title = typeof renderedCell === 'string' ? renderedCell : null; // Avoid using object-spread syntax with multiple objects here, // Since it results in an extra method call to 'babel-runtime/helpers/extends' // See PR https://github.com/bvaughn/react-virtualized/pull/942 return React.createElement("div", { "aria-colindex": columnIndex + 1, "aria-describedby": id, className: (0, _clsx["default"])('ReactVirtualized__Table__rowColumn', className), key: 'Row' + rowIndex + '-' + 'Col' + columnIndex, onClick: onClick, role: "gridcell", style: style, title: title }, renderedCell); } }, { key: "_createHeader", value: function _createHeader(_ref5) { var column = _ref5.column, index = _ref5.index; var _this$props2 = this.props, headerClassName = _this$props2.headerClassName, headerStyle = _this$props2.headerStyle, onHeaderClick = _this$props2.onHeaderClick, sort = _this$props2.sort, sortBy = _this$props2.sortBy, sortDirection = _this$props2.sortDirection; var _column$props2 = column.props, columnData = _column$props2.columnData, dataKey = _column$props2.dataKey, defaultSortDirection = _column$props2.defaultSortDirection, disableSort = _column$props2.disableSort, headerRenderer = _column$props2.headerRenderer, id = _column$props2.id, label = _column$props2.label; var sortEnabled = !disableSort && sort; var classNames = (0, _clsx["default"])('ReactVirtualized__Table__headerColumn', headerClassName, column.props.headerClassName, { ReactVirtualized__Table__sortableHeaderColumn: sortEnabled }); var style = this._getFlexStyleForColumn(column, _objectSpread({}, headerStyle, {}, column.props.headerStyle)); var renderedHeader = headerRenderer({ columnData: columnData, dataKey: dataKey, disableSort: disableSort, label: label, sortBy: sortBy, sortDirection: sortDirection }); var headerOnClick, headerOnKeyDown, headerTabIndex, headerAriaSort, headerAriaLabel; if (sortEnabled || onHeaderClick) { // If this is a sortable header, clicking it should update the table data's sorting. var isFirstTimeSort = sortBy !== dataKey; // If this is the firstTime sort of this column, use the column default sort order. // Otherwise, invert the direction of the sort. var newSortDirection = isFirstTimeSort ? defaultSortDirection : sortDirection === _SortDirection["default"].DESC ? _SortDirection["default"].ASC : _SortDirection["default"].DESC; var onClick = function onClick(event) { sortEnabled && sort({ defaultSortDirection: defaultSortDirection, event: event, sortBy: dataKey, sortDirection: newSortDirection }); onHeaderClick && onHeaderClick({ columnData: columnData, dataKey: dataKey, event: event }); }; var onKeyDown = function onKeyDown(event) { if (event.key === 'Enter' || event.key === ' ') { onClick(event); } }; headerAriaLabel = column.props['aria-label'] || label || dataKey; headerAriaSort = 'none'; headerTabIndex = 0; headerOnClick = onClick; headerOnKeyDown = onKeyDown; } if (sortBy === dataKey) { headerAriaSort = sortDirection === _SortDirection["default"].ASC ? 'ascending' : 'descending'; } // Avoid using object-spread syntax with multiple objects here, // Since it results in an extra method call to 'babel-runtime/helpers/extends' // See PR https://github.com/bvaughn/react-virtualized/pull/942 return React.createElement("div", { "aria-label": headerAriaLabel, "aria-sort": headerAriaSort, className: classNames, id: id, key: 'Header-Col' + index, onClick: headerOnClick, onKeyDown: headerOnKeyDown, role: "columnheader", style: style, tabIndex: headerTabIndex }, renderedHeader); } }, { key: "_createRow", value: function _createRow(_ref6) { var _this3 = this; var index = _ref6.rowIndex, isScrolling = _ref6.isScrolling, key = _ref6.key, parent = _ref6.parent, style = _ref6.style; var _this$props3 = this.props, children = _this$props3.children, onRowClick = _this$props3.onRowClick, onRowDoubleClick = _this$props3.onRowDoubleClick, onRowRightClick = _this$props3.onRowRightClick, onRowMouseOver = _this$props3.onRowMouseOver, onRowMouseOut = _this$props3.onRowMouseOut, rowClassName = _this$props3.rowClassName, rowGetter = _this$props3.rowGetter, rowRenderer = _this$props3.rowRenderer, rowStyle = _this$props3.rowStyle; var scrollbarWidth = this.state.scrollbarWidth; var rowClass = typeof rowClassName === 'function' ? rowClassName({ index: index }) : rowClassName; var rowStyleObject = typeof rowStyle === 'function' ? rowStyle({ index: index }) : rowStyle; var rowData = rowGetter({ index: index }); var columns = React.Children.toArray(children).map(function (column, columnIndex) { return _this3._createColumn({ column: column, columnIndex: columnIndex, isScrolling: isScrolling, parent: parent, rowData: rowData, rowIndex: index, scrollbarWidth: scrollbarWidth }); }); var className = (0, _clsx["default"])('ReactVirtualized__Table__row', rowClass); var flattenedStyle = _objectSpread({}, style, { height: this._getRowHeight(index), overflow: 'hidden', paddingRight: scrollbarWidth }, rowStyleObject); return rowRenderer({ className: className, columns: columns, index: index, isScrolling: isScrolling, key: key, onRowClick: onRowClick, onRowDoubleClick: onRowDoubleClick, onRowRightClick: onRowRightClick, onRowMouseOver: onRowMouseOver, onRowMouseOut: onRowMouseOut, rowData: rowData, style: flattenedStyle }); } /** * Determines the flex-shrink, flex-grow, and width values for a cell (header or column). */ }, { key: "_getFlexStyleForColumn", value: function _getFlexStyleForColumn(column) { var customStyle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var flexValue = "".concat(column.props.flexGrow, " ").concat(column.props.flexShrink, " ").concat(column.props.width, "px"); var style = _objectSpread({}, customStyle, { flex: flexValue, msFlex: flexValue, WebkitFlex: flexValue }); if (column.props.maxWidth) { style.maxWidth = column.props.maxWidth; } if (column.props.minWidth) { style.minWidth = column.props.minWidth; } return style; } }, { key: "_getHeaderColumns", value: function _getHeaderColumns() { var _this4 = this; var _this$props4 = this.props, children = _this$props4.children, disableHeader = _this$props4.disableHeader; var items = disableHeader ? [] : React.Children.toArray(children); return items.map(function (column, index) { return _this4._createHeader({ column: column, index: index }); }); } }, { key: "_getRowHeight", value: function _getRowHeight(rowIndex) { var rowHeight = this.props.rowHeight; return typeof rowHeight === 'function' ? rowHeight({ index: rowIndex }) : rowHeight; } }, { key: "_onScroll", value: function _onScroll(_ref7) { var clientHeight = _ref7.clientHeight, scrollHeight = _ref7.scrollHeight, scrollTop = _ref7.scrollTop; var onScroll = this.props.onScroll; onScroll({ clientHeight: clientHeight, scrollHeight: scrollHeight, scrollTop: scrollTop }); } }, { key: "_onSectionRendered", value: function _onSectionRendered(_ref8) { var rowOverscanStartIndex = _ref8.rowOverscanStartIndex, rowOverscanStopIndex = _ref8.rowOverscanStopIndex, rowStartIndex = _ref8.rowStartIndex, rowStopIndex = _ref8.rowStopIndex; var onRowsRendered = this.props.onRowsRendered; onRowsRendered({ overscanStartIndex: rowOverscanStartIndex, overscanStopIndex: rowOverscanStopIndex, startIndex: rowStartIndex, stopIndex: rowStopIndex }); } }, { key: "_setRef", value: function _setRef(ref) { this.Grid = ref; } }, { key: "_setScrollbarWidth", value: function _setScrollbarWidth() { var scrollbarWidth = this.getScrollbarWidth(); this.setState({ scrollbarWidth: scrollbarWidth }); } }]); return Table; }(React.PureComponent); exports["default"] = Table; (0, _defineProperty2["default"])(Table, "defaultProps", { disableHeader: false, estimatedRowSize: 30, headerHeight: 0, headerStyle: {}, noRowsRenderer: function noRowsRenderer() { return null; }, onRowsRendered: function onRowsRendered() { return null; }, onScroll: function onScroll() { return null; }, overscanIndicesGetter: _Grid2.accessibilityOverscanIndicesGetter, overscanRowCount: 10, rowRenderer: _defaultRowRenderer["default"], headerRowRenderer: _defaultHeaderRowRenderer["default"], rowStyle: {}, scrollToAlignment: 'auto', scrollToIndex: -1, style: {} }); Table.propTypes = process.env.NODE_ENV !== "production" ? { /** This is just set on the grid top element. */ 'aria-label': _propTypes["default"].string, /** This is just set on the grid top element. */ 'aria-labelledby': _propTypes["default"].string, /** * Removes fixed height from the scrollingContainer so that the total height * of rows can stretch the window. Intended for use with WindowScroller */ autoHeight: _propTypes["default"].bool, /** One or more Columns describing the data displayed in this row */ children: function children(props) { var children = React.Children.toArray(props.children); for (var i = 0; i < children.length; i++) { var childType = children[i].type; if (childType !== _Column["default"] && !(childType.prototype instanceof _Column["default"])) { return new Error('Table only accepts children of type Column'); } } }, /** Optional CSS class name */ className: _propTypes["default"].string, /** Disable rendering the header at all */ disableHeader: _propTypes["default"].bool, /** * Used to estimate the total height of a Table before all of its rows have actually been measured. * The estimated total height is adjusted as rows are rendered. */ estimatedRowSize: _propTypes["default"].number.isRequired, /** Optional custom CSS class name to attach to inner Grid element. */ gridClassName: _propTypes["default"].string, /** Optional inline style to attach to inner Grid element. */ gridStyle: _propTypes["default"].object, /** Optional CSS class to apply to all column headers */ headerClassName: _propTypes["default"].string, /** Fixed height of header row */ headerHeight: _propTypes["default"].number.isRequired, /** * Responsible for rendering a table row given an array of columns: * Should implement the following interface: ({ * className: string, * columns: any[], * style: any * }): PropTypes.node */ headerRowRenderer: _propTypes["default"].func, /** Optional custom inline style to attach to table header columns. */ headerStyle: _propTypes["default"].object, /** Fixed/available height for out DOM element */ height: _propTypes["default"].number.isRequired, /** Optional id */ id: _propTypes["default"].string, /** Optional renderer to be used in place of table body rows when rowCount is 0 */ noRowsRenderer: _propTypes["default"].func, /** * Optional callback when a column is clicked. * ({ columnData: any, dataKey: string }): void */ onColumnClick: _propTypes["default"].func, /** * Optional callback when a column's header is clicked. * ({ columnData: any, dataKey: string }): void */ onHeaderClick: _propTypes["default"].func, /** * Callback invoked when a user clicks on a table row. * ({ index: number }): void */ onRowClick: _propTypes["default"].func, /** * Callback invoked when a user double-clicks on a table row. * ({ index: number }): void */ onRowDoubleClick: _propTypes["default"].func, /** * Callback invoked when the mouse leaves a table row. * ({ index: number }): void */ onRowMouseOut: _propTypes["default"].func, /** * Callback invoked when a user moves the mouse over a table row. * ({ index: number }): void */ onRowMouseOver: _propTypes["default"].func, /** * Callback invoked when a user right-clicks on a table row. * ({ index: number }): void */ onRowRightClick: _propTypes["default"].func, /** * Callback invoked with information about the slice of rows that were just rendered. * ({ startIndex, stopIndex }): void */ onRowsRendered: _propTypes["default"].func, /** * Callback invoked whenever the scroll offset changes within the inner scrollable region. * This callback can be used to sync scrolling between lists, tables, or grids. * ({ clientHeight, scrollHeight, scrollTop }): void */ onScroll: _propTypes["default"].func.isRequired, /** See Grid#overscanIndicesGetter */ overscanIndicesGetter: _propTypes["default"].func.isRequired, /** * Number of rows to render above/below the visible bounds of the list. * These rows can help for smoother scrolling on touch devices. */ overscanRowCount: _propTypes["default"].number.isRequired, /** * Optional CSS class to apply to all table rows (including the header row). * This property can be a CSS class name (string) or a function that returns a class name. * If a function is provided its signature should be: ({ index: number }): string */ rowClassName: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].func]), /** * Callback responsible for returning a data row given an index. * ({ index: number }): any */ rowGetter: _propTypes["default"].func.isRequired, /** * Either a fixed row height (number) or a function that returns the height of a row given its index. * ({ index: number }): number */ rowHeight: _propTypes["default"].oneOfType([_propTypes["default"].number, _propTypes["default"].func]).isRequired, /** Number of rows in table. */ rowCount: _propTypes["default"].number.isRequired, /** * Responsible for rendering a table row given an array of columns: * Should implement the following interface: ({ * className: string, * columns: Array, * index: number, * isScrolling: boolean, * onRowClick: ?Function, * onRowDoubleClick: ?Function, * onRowMouseOver: ?Function, * onRowMouseOut: ?Function, * rowData: any, * style: any * }): PropTypes.node */ rowRenderer: _propTypes["default"].func, /** Optional custom inline style to attach to table rows. */ rowStyle: _propTypes["default"].oneOfType([_propTypes["default"].object, _propTypes["default"].func]).isRequired, /** See Grid#scrollToAlignment */ scrollToAlignment: _propTypes["default"].oneOf(['auto', 'end', 'start', 'center']).isRequired, /** Row index to ensure visible (by forcefully scrolling if necessary) */ scrollToIndex: _propTypes["default"].number.isRequired, /** Vertical offset. */ scrollTop: _propTypes["default"].number, /** * Sort function to be called if a sortable header is clicked. * Should implement the following interface: ({ * defaultSortDirection: 'ASC' | 'DESC', * event: MouseEvent, * sortBy: string, * sortDirection: SortDirection * }): void */ sort: _propTypes["default"].func, /** Table data is currently sorted by this :dataKey (if it is sorted at all) */ sortBy: _propTypes["default"].string, /** Table data is currently sorted in this direction (if it is sorted at all) */ sortDirection: _propTypes["default"].oneOf([_SortDirection["default"].ASC, _SortDirection["default"].DESC]), /** Optional inline style */ style: _propTypes["default"].object, /** Tab index for focus */ tabIndex: _propTypes["default"].number, /** Width of list */ width: _propTypes["default"].number.isRequired } : {};dist/commonjs/Table/defaultCellRenderer.js000064400000000744151676725760014667 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = defaultCellRenderer; var _types = require("./types"); /** * Default cell renderer that displays an attribute as a simple string * You should override the column's cellRenderer if your data is some other type of object. */ function defaultCellRenderer(_ref) { var cellData = _ref.cellData; if (cellData == null) { return ''; } else { return String(cellData); } }dist/commonjs/Table/defaultRowRenderer.js000064400000005113151676725760014552 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = defaultRowRenderer; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _types = require("./types"); var _propTypes = _interopRequireDefault(require("prop-types")); /** * Default row renderer for Table. */ function defaultRowRenderer(_ref) { var className = _ref.className, columns = _ref.columns, index = _ref.index, key = _ref.key, onRowClick = _ref.onRowClick, onRowDoubleClick = _ref.onRowDoubleClick, onRowMouseOut = _ref.onRowMouseOut, onRowMouseOver = _ref.onRowMouseOver, onRowRightClick = _ref.onRowRightClick, rowData = _ref.rowData, style = _ref.style; var a11yProps = { 'aria-rowindex': index + 1 }; if (onRowClick || onRowDoubleClick || onRowMouseOut || onRowMouseOver || onRowRightClick) { a11yProps['aria-label'] = 'row'; a11yProps.tabIndex = 0; if (onRowClick) { a11yProps.onClick = function (event) { return onRowClick({ event: event, index: index, rowData: rowData }); }; } if (onRowDoubleClick) { a11yProps.onDoubleClick = function (event) { return onRowDoubleClick({ event: event, index: index, rowData: rowData }); }; } if (onRowMouseOut) { a11yProps.onMouseOut = function (event) { return onRowMouseOut({ event: event, index: index, rowData: rowData }); }; } if (onRowMouseOver) { a11yProps.onMouseOver = function (event) { return onRowMouseOver({ event: event, index: index, rowData: rowData }); }; } if (onRowRightClick) { a11yProps.onContextMenu = function (event) { return onRowRightClick({ event: event, index: index, rowData: rowData }); }; } } return React.createElement("div", (0, _extends2["default"])({}, a11yProps, { className: className, key: key, role: "row", style: style }), columns); } defaultRowRenderer.propTypes = process.env.NODE_ENV === 'production' ? null : _types.bpfrpt_proptype_RowRendererParams === _propTypes["default"].any ? {} : _types.bpfrpt_proptype_RowRendererParams;dist/commonjs/Table/index.js000064400000004710151676725760012060 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "createMultiSort", { enumerable: true, get: function get() { return _createMultiSort["default"]; } }); Object.defineProperty(exports, "defaultCellDataGetter", { enumerable: true, get: function get() { return _defaultCellDataGetter["default"]; } }); Object.defineProperty(exports, "defaultCellRenderer", { enumerable: true, get: function get() { return _defaultCellRenderer["default"]; } }); Object.defineProperty(exports, "defaultHeaderRowRenderer", { enumerable: true, get: function get() { return _defaultHeaderRowRenderer["default"]; } }); Object.defineProperty(exports, "defaultHeaderRenderer", { enumerable: true, get: function get() { return _defaultHeaderRenderer["default"]; } }); Object.defineProperty(exports, "defaultRowRenderer", { enumerable: true, get: function get() { return _defaultRowRenderer["default"]; } }); Object.defineProperty(exports, "Column", { enumerable: true, get: function get() { return _Column["default"]; } }); Object.defineProperty(exports, "SortDirection", { enumerable: true, get: function get() { return _SortDirection["default"]; } }); Object.defineProperty(exports, "SortIndicator", { enumerable: true, get: function get() { return _SortIndicator["default"]; } }); Object.defineProperty(exports, "Table", { enumerable: true, get: function get() { return _Table["default"]; } }); exports["default"] = void 0; var _createMultiSort = _interopRequireDefault(require("./createMultiSort")); var _defaultCellDataGetter = _interopRequireDefault(require("./defaultCellDataGetter")); var _defaultCellRenderer = _interopRequireDefault(require("./defaultCellRenderer")); var _defaultHeaderRowRenderer = _interopRequireDefault(require("./defaultHeaderRowRenderer.js")); var _defaultHeaderRenderer = _interopRequireDefault(require("./defaultHeaderRenderer")); var _defaultRowRenderer = _interopRequireDefault(require("./defaultRowRenderer")); var _Column = _interopRequireDefault(require("./Column")); var _SortDirection = _interopRequireDefault(require("./SortDirection")); var _SortIndicator = _interopRequireDefault(require("./SortIndicator")); var _Table = _interopRequireDefault(require("./Table")); var _default = _Table["default"]; exports["default"] = _default;dist/commonjs/Table/SortIndicator.js000064400000003057151676725770013541 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = SortIndicator; var _clsx = _interopRequireDefault(require("clsx")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _SortDirection = _interopRequireDefault(require("./SortDirection")); /** * Displayed beside a header to indicate that a Table is currently sorted by this column. */ function SortIndicator(_ref) { var sortDirection = _ref.sortDirection; var classNames = (0, _clsx["default"])('ReactVirtualized__Table__sortableHeaderIcon', { 'ReactVirtualized__Table__sortableHeaderIcon--ASC': sortDirection === _SortDirection["default"].ASC, 'ReactVirtualized__Table__sortableHeaderIcon--DESC': sortDirection === _SortDirection["default"].DESC }); return React.createElement("svg", { className: classNames, width: 18, height: 18, viewBox: "0 0 24 24" }, sortDirection === _SortDirection["default"].ASC ? React.createElement("path", { d: "M7 14l5-5 5 5z" }) : React.createElement("path", { d: "M7 10l5 5 5-5z" }), React.createElement("path", { d: "M0 0h24v24H0z", fill: "none" })); } SortIndicator.propTypes = process.env.NODE_ENV !== "production" ? { sortDirection: _propTypes["default"].oneOf([_SortDirection["default"].ASC, _SortDirection["default"].DESC]) } : {};dist/commonjs/Table/Table.example.js000064400000031644151676725770013441 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _immutable = _interopRequireDefault(require("immutable")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _ContentBox = require("../demo/ContentBox"); var _LabeledInput = require("../demo/LabeledInput"); var _AutoSizer = _interopRequireDefault(require("../AutoSizer")); var _Column = _interopRequireDefault(require("./Column")); var _Table = _interopRequireDefault(require("./Table")); var _SortDirection = _interopRequireDefault(require("./SortDirection")); var _SortIndicator = _interopRequireDefault(require("./SortIndicator")); var _TableExample = _interopRequireDefault(require("./Table.example.css")); var TableExample = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(TableExample, _React$PureComponent); function TableExample(props, context) { var _this; (0, _classCallCheck2["default"])(this, TableExample); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(TableExample).call(this, props, context)); var sortBy = 'index'; var sortDirection = _SortDirection["default"].ASC; var sortedList = _this._sortList({ sortBy: sortBy, sortDirection: sortDirection }); _this.state = { disableHeader: false, headerHeight: 30, height: 270, hideIndexRow: false, overscanRowCount: 10, rowHeight: 40, rowCount: 1000, scrollToIndex: undefined, sortBy: sortBy, sortDirection: sortDirection, sortedList: sortedList, useDynamicRowHeight: false }; _this._getRowHeight = _this._getRowHeight.bind((0, _assertThisInitialized2["default"])(_this)); _this._headerRenderer = _this._headerRenderer.bind((0, _assertThisInitialized2["default"])(_this)); _this._noRowsRenderer = _this._noRowsRenderer.bind((0, _assertThisInitialized2["default"])(_this)); _this._onRowCountChange = _this._onRowCountChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._onScrollToRowChange = _this._onScrollToRowChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._rowClassName = _this._rowClassName.bind((0, _assertThisInitialized2["default"])(_this)); _this._sort = _this._sort.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(TableExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, disableHeader = _this$state.disableHeader, headerHeight = _this$state.headerHeight, height = _this$state.height, hideIndexRow = _this$state.hideIndexRow, overscanRowCount = _this$state.overscanRowCount, rowHeight = _this$state.rowHeight, rowCount = _this$state.rowCount, scrollToIndex = _this$state.scrollToIndex, sortBy = _this$state.sortBy, sortDirection = _this$state.sortDirection, sortedList = _this$state.sortedList, useDynamicRowHeight = _this$state.useDynamicRowHeight; var rowGetter = function rowGetter(_ref) { var index = _ref.index; return _this2._getDatum(sortedList, index); }; return React.createElement(_ContentBox.ContentBox, null, React.createElement(_ContentBox.ContentBoxHeader, { text: "Table", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/Table/Table.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/Table.md" }), React.createElement(_ContentBox.ContentBoxParagraph, null, "The table layout below is created with flexboxes. This allows it to have a fixed header and scrollable body content. It also makes use of", ' ', React.createElement("code", null, "Grid"), " for windowing table content so that large lists are rendered efficiently. Adjust its configurable properties below to see how it reacts."), React.createElement(_ContentBox.ContentBoxParagraph, null, React.createElement("label", { className: _TableExample["default"].checkboxLabel }, React.createElement("input", { "aria-label": "Use dynamic row heights?", checked: useDynamicRowHeight, className: _TableExample["default"].checkbox, type: "checkbox", onChange: function onChange(event) { return _this2._updateUseDynamicRowHeight(event.target.checked); } }), "Use dynamic row heights?"), React.createElement("label", { className: _TableExample["default"].checkboxLabel }, React.createElement("input", { "aria-label": "Hide index?", checked: hideIndexRow, className: _TableExample["default"].checkbox, type: "checkbox", onChange: function onChange(event) { return _this2.setState({ hideIndexRow: event.target.checked }); } }), "Hide index?"), React.createElement("label", { className: _TableExample["default"].checkboxLabel }, React.createElement("input", { "aria-label": "Hide header?", checked: disableHeader, className: _TableExample["default"].checkbox, type: "checkbox", onChange: function onChange(event) { return _this2.setState({ disableHeader: event.target.checked }); } }), "Hide header?")), React.createElement(_LabeledInput.InputRow, null, React.createElement(_LabeledInput.LabeledInput, { label: "Num rows", name: "rowCount", onChange: this._onRowCountChange, value: rowCount }), React.createElement(_LabeledInput.LabeledInput, { label: "Scroll to", name: "onScrollToRow", placeholder: "Index...", onChange: this._onScrollToRowChange, value: scrollToIndex || '' }), React.createElement(_LabeledInput.LabeledInput, { label: "List height", name: "height", onChange: function onChange(event) { return _this2.setState({ height: parseInt(event.target.value, 10) || 1 }); }, value: height }), React.createElement(_LabeledInput.LabeledInput, { disabled: useDynamicRowHeight, label: "Row height", name: "rowHeight", onChange: function onChange(event) { return _this2.setState({ rowHeight: parseInt(event.target.value, 10) || 1 }); }, value: rowHeight }), React.createElement(_LabeledInput.LabeledInput, { label: "Header height", name: "headerHeight", onChange: function onChange(event) { return _this2.setState({ headerHeight: parseInt(event.target.value, 10) || 1 }); }, value: headerHeight }), React.createElement(_LabeledInput.LabeledInput, { label: "Overscan", name: "overscanRowCount", onChange: function onChange(event) { return _this2.setState({ overscanRowCount: parseInt(event.target.value, 10) || 0 }); }, value: overscanRowCount })), React.createElement("div", null, React.createElement(_AutoSizer["default"], { disableHeight: true }, function (_ref2) { var width = _ref2.width; return React.createElement(_Table["default"], { ref: "Table", disableHeader: disableHeader, headerClassName: _TableExample["default"].headerColumn, headerHeight: headerHeight, height: height, noRowsRenderer: _this2._noRowsRenderer, overscanRowCount: overscanRowCount, rowClassName: _this2._rowClassName, rowHeight: useDynamicRowHeight ? _this2._getRowHeight : rowHeight, rowGetter: rowGetter, rowCount: rowCount, scrollToIndex: scrollToIndex, sort: _this2._sort, sortBy: sortBy, sortDirection: sortDirection, width: width }, !hideIndexRow && React.createElement(_Column["default"], { label: "Index", cellDataGetter: function cellDataGetter(_ref3) { var rowData = _ref3.rowData; return rowData.index; }, dataKey: "index", disableSort: !_this2._isSortEnabled(), width: 60 }), React.createElement(_Column["default"], { dataKey: "name", disableSort: !_this2._isSortEnabled(), headerRenderer: _this2._headerRenderer, width: 90 }), React.createElement(_Column["default"], { width: 210, disableSort: true, label: "The description label is really long so that it will be truncated", dataKey: "random", className: _TableExample["default"].exampleColumn, cellRenderer: function cellRenderer(_ref4) { var cellData = _ref4.cellData; return cellData; }, flexGrow: 1 })); }))); } }, { key: "_getDatum", value: function _getDatum(list, index) { return list.get(index % list.size); } }, { key: "_getRowHeight", value: function _getRowHeight(_ref5) { var index = _ref5.index; var list = this.context.list; return this._getDatum(list, index).size; } }, { key: "_headerRenderer", value: function _headerRenderer(_ref6) { var dataKey = _ref6.dataKey, sortBy = _ref6.sortBy, sortDirection = _ref6.sortDirection; return React.createElement("div", null, "Full Name", sortBy === dataKey && React.createElement(_SortIndicator["default"], { sortDirection: sortDirection })); } }, { key: "_isSortEnabled", value: function _isSortEnabled() { var list = this.context.list; var rowCount = this.state.rowCount; return rowCount <= list.size; } }, { key: "_noRowsRenderer", value: function _noRowsRenderer() { return React.createElement("div", { className: _TableExample["default"].noRows }, "No rows"); } }, { key: "_onRowCountChange", value: function _onRowCountChange(event) { var rowCount = parseInt(event.target.value, 10) || 0; this.setState({ rowCount: rowCount }); } }, { key: "_onScrollToRowChange", value: function _onScrollToRowChange(event) { var rowCount = this.state.rowCount; var scrollToIndex = Math.min(rowCount - 1, parseInt(event.target.value, 10)); if (isNaN(scrollToIndex)) { scrollToIndex = undefined; } this.setState({ scrollToIndex: scrollToIndex }); } }, { key: "_rowClassName", value: function _rowClassName(_ref7) { var index = _ref7.index; if (index < 0) { return _TableExample["default"].headerRow; } else { return index % 2 === 0 ? _TableExample["default"].evenRow : _TableExample["default"].oddRow; } } }, { key: "_sort", value: function _sort(_ref8) { var sortBy = _ref8.sortBy, sortDirection = _ref8.sortDirection; var sortedList = this._sortList({ sortBy: sortBy, sortDirection: sortDirection }); this.setState({ sortBy: sortBy, sortDirection: sortDirection, sortedList: sortedList }); } }, { key: "_sortList", value: function _sortList(_ref9) { var sortBy = _ref9.sortBy, sortDirection = _ref9.sortDirection; var list = this.context.list; return list.sortBy(function (item) { return item[sortBy]; }).update(function (list) { return sortDirection === _SortDirection["default"].DESC ? list.reverse() : list; }); } }, { key: "_updateUseDynamicRowHeight", value: function _updateUseDynamicRowHeight(value) { this.setState({ useDynamicRowHeight: value }); } }]); return TableExample; }(React.PureComponent); exports["default"] = TableExample; (0, _defineProperty2["default"])(TableExample, "contextTypes", { list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired });dist/commonjs/Table/SortDirection.js000064400000000741151676725770013542 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var SortDirection = { /** * Sort items in ascending order. * This means arranging from the lowest value to the highest (e.g. a-z, 0-9). */ ASC: 'ASC', /** * Sort items in descending order. * This means arranging from the highest value to the lowest (e.g. z-a, 9-0). */ DESC: 'DESC' }; var _default = SortDirection; exports["default"] = _default;dist/commonjs/Table/defaultHeaderRenderer.js000064400000002542151676725770015177 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = defaultHeaderRenderer; var React = _interopRequireWildcard(require("react")); var _SortIndicator = _interopRequireDefault(require("./SortIndicator")); var _types = require("./types"); var _propTypes = _interopRequireDefault(require("prop-types")); /** * Default table header renderer. */ function defaultHeaderRenderer(_ref) { var dataKey = _ref.dataKey, label = _ref.label, sortBy = _ref.sortBy, sortDirection = _ref.sortDirection; var showSortIndicator = sortBy === dataKey; var children = [React.createElement("span", { className: "ReactVirtualized__Table__headerTruncatedText", key: "label", title: typeof label === 'string' ? label : null }, label)]; if (showSortIndicator) { children.push(React.createElement(_SortIndicator["default"], { key: "SortIndicator", sortDirection: sortDirection })); } return children; } defaultHeaderRenderer.propTypes = process.env.NODE_ENV === 'production' ? null : _types.bpfrpt_proptype_HeaderRendererParams === _propTypes["default"].any ? {} : _types.bpfrpt_proptype_HeaderRendererParams;dist/commonjs/Table/Column.jest.js000064400000006034151676725770013154 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var React = _interopRequireWildcard(require("react")); var _immutable = _interopRequireDefault(require("immutable")); var _defaultCellDataGetter = _interopRequireDefault(require("./defaultCellDataGetter")); var _defaultCellRenderer = _interopRequireDefault(require("./defaultCellRenderer")); var _defaultHeaderRenderer = _interopRequireDefault(require("./defaultHeaderRenderer")); describe('Column', function () { var rowData = _immutable["default"].Map({ foo: 'Foo', bar: 1 }); describe('defaultCellDataGetter', function () { it('should return a value for specified attributes', function () { expect((0, _defaultCellDataGetter["default"])({ dataKey: 'foo', rowData: rowData })).toEqual('Foo'); expect((0, _defaultCellDataGetter["default"])({ dataKey: 'bar', rowData: rowData })).toEqual(1); }); it('should return undefined for missing attributes', function () { expect((0, _defaultCellDataGetter["default"])({ dataKey: 'baz', rowData: rowData })).toEqual(undefined); }); }); describe('defaultCellRenderer', function () { it('should render a value for specified attributes', function () { expect((0, _defaultCellRenderer["default"])({ cellData: 'Foo', dataKey: 'foo', rowData: rowData, rowIndex: 0 })).toEqual('Foo'); expect((0, _defaultCellRenderer["default"])({ cellData: 1, dataKey: 'bar', rowData: rowData, rowIndex: 0 })).toEqual('1'); }); it('should render empty string for null or missing attributes', function () { expect((0, _defaultCellRenderer["default"])({ cellData: null, dataKey: 'baz', rowData: rowData, rowIndex: 0 })).toEqual(''); expect((0, _defaultCellRenderer["default"])({ cellData: undefined, dataKey: 'baz', rowData: rowData, rowIndex: 0 })).toEqual(''); }); }); describe('defaultHeaderRenderer', function () { it('should render a value for specified attributes', function () { expect((0, _defaultHeaderRenderer["default"])({ dataKey: 'foo', label: 'squirrel' })[0].props.children).toEqual('squirrel'); var label = React.createElement("div", { className: "rabbit" }, "Rabbit"); expect((0, _defaultHeaderRenderer["default"])({ dataKey: 'bar', label: label })[0].props.children).toEqual(label); }); it('should render empty string for null or missing attributes', function () { expect((0, _defaultHeaderRenderer["default"])({ dataKey: 'foo', label: null })[0].props.children).toBeNull(); expect((0, _defaultHeaderRenderer["default"])({ dataKey: 'bar', label: undefined })[0].props.children).toBeUndefined(); }); }); });dist/commonjs/Table/defaultCellDataGetter.js000064400000001174151676725770015144 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = defaultCellDataGetter; var _types = require("./types"); /** * Default accessor for returning a cell value for a given attribute. * This function expects to operate on either a vanilla Object or an Immutable Map. * You should override the column's cellDataGetter if your data is some other type of object. */ function defaultCellDataGetter(_ref) { var dataKey = _ref.dataKey, rowData = _ref.rowData; if (typeof rowData.get === 'function') { return rowData.get(dataKey); } else { return rowData[dataKey]; } }dist/commonjs/Table/defaultHeaderRowRenderer.js000064400000001632151676725770015666 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = defaultHeaderRowRenderer; var React = _interopRequireWildcard(require("react")); var _types = require("./types"); var _propTypes = _interopRequireDefault(require("prop-types")); function defaultHeaderRowRenderer(_ref) { var className = _ref.className, columns = _ref.columns, style = _ref.style; return React.createElement("div", { className: className, role: "row", style: style }, columns); } defaultHeaderRowRenderer.propTypes = process.env.NODE_ENV === 'production' ? null : _types.bpfrpt_proptype_HeaderRowRendererParams === _propTypes["default"].any ? {} : _types.bpfrpt_proptype_HeaderRowRendererParams;dist/commonjs/CellMeasurer/CellMeasurer.DynamicWidthMultiGrid.example.js000064400000012241151676725770022525 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _immutable = _interopRequireDefault(require("immutable")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _CellMeasurer = _interopRequireDefault(require("./CellMeasurer")); var _CellMeasurerCache = _interopRequireDefault(require("./CellMeasurerCache")); var _MultiGrid = _interopRequireDefault(require("../MultiGrid")); var _CellMeasurerExample = _interopRequireDefault(require("./CellMeasurer.example.css")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var DynamicWidthMultiGrid = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(DynamicWidthMultiGrid, _React$PureComponent); function DynamicWidthMultiGrid(props, context) { var _this; (0, _classCallCheck2["default"])(this, DynamicWidthMultiGrid); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(DynamicWidthMultiGrid).call(this, props, context)); _this._cache = new _CellMeasurerCache["default"]({ defaultHeight: 30, defaultWidth: 150, fixedHeight: true }); _this._cellRenderer = _this._cellRenderer.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(DynamicWidthMultiGrid, [{ key: "render", value: function render() { var width = this.props.width; return React.createElement(_MultiGrid["default"], { className: _CellMeasurerExample["default"].BodyGrid, columnCount: 50, columnWidth: this._cache.columnWidth, deferredMeasurementCache: this._cache, fixedColumnCount: 1, fixedRowCount: 0, height: 400, overscanColumnCount: 0, overscanRowCount: 0, cellRenderer: this._cellRenderer, rowCount: 50, rowHeight: 30, width: width }); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref) { var columnIndex = _ref.columnIndex, key = _ref.key, parent = _ref.parent, rowIndex = _ref.rowIndex, style = _ref.style; var _this$props = this.props, getClassName = _this$props.getClassName, getContent = _this$props.getContent, list = _this$props.list; var datum = list.get((rowIndex + columnIndex) % list.size); var classNames = getClassName({ columnIndex: columnIndex, rowIndex: rowIndex }); var content = getContent({ index: rowIndex, datum: datum, "long": false }); if (columnIndex === 0) { content = content.substr(0, 50); } return React.createElement(_CellMeasurer["default"], { cache: this._cache, columnIndex: columnIndex, key: key, parent: parent, rowIndex: rowIndex }, React.createElement("div", { className: classNames, style: _objectSpread({}, style, { whiteSpace: 'nowrap' }) }, content)); } }]); return DynamicWidthMultiGrid; }(React.PureComponent); exports["default"] = DynamicWidthMultiGrid; DynamicWidthMultiGrid.propTypes = process.env.NODE_ENV !== "production" ? { getClassName: _propTypes["default"].func.isRequired, getContent: _propTypes["default"].func.isRequired, list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired, width: _propTypes["default"].number.isRequired } : {};dist/commonjs/CellMeasurer/types.js000064400000001402151676725770013445 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.bpfrpt_proptype_CellMeasureCache = void 0; var _propTypes = _interopRequireDefault(require("prop-types")); var bpfrpt_proptype_CellMeasureCache = process.env.NODE_ENV === 'production' ? null : { "hasFixedWidth": _propTypes["default"].func.isRequired, "hasFixedHeight": _propTypes["default"].func.isRequired, "has": _propTypes["default"].func.isRequired, "set": _propTypes["default"].func.isRequired, "getHeight": _propTypes["default"].func.isRequired, "getWidth": _propTypes["default"].func.isRequired }; exports.bpfrpt_proptype_CellMeasureCache = bpfrpt_proptype_CellMeasureCache;dist/commonjs/CellMeasurer/CellMeasurerCache.js000064400000020213151676725770015611 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.DEFAULT_WIDTH = exports.DEFAULT_HEIGHT = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _types = require("./types"); var DEFAULT_HEIGHT = 30; exports.DEFAULT_HEIGHT = DEFAULT_HEIGHT; var DEFAULT_WIDTH = 100; // Enables more intelligent mapping of a given column and row index to an item ID. // This prevents a cell cache from being invalidated when its parent collection is modified. exports.DEFAULT_WIDTH = DEFAULT_WIDTH; /** * Caches measurements for a given cell. */ var CellMeasurerCache = /*#__PURE__*/ function () { function CellMeasurerCache() { var _this = this; var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; (0, _classCallCheck2["default"])(this, CellMeasurerCache); (0, _defineProperty2["default"])(this, "_cellHeightCache", {}); (0, _defineProperty2["default"])(this, "_cellWidthCache", {}); (0, _defineProperty2["default"])(this, "_columnWidthCache", {}); (0, _defineProperty2["default"])(this, "_rowHeightCache", {}); (0, _defineProperty2["default"])(this, "_defaultHeight", void 0); (0, _defineProperty2["default"])(this, "_defaultWidth", void 0); (0, _defineProperty2["default"])(this, "_minHeight", void 0); (0, _defineProperty2["default"])(this, "_minWidth", void 0); (0, _defineProperty2["default"])(this, "_keyMapper", void 0); (0, _defineProperty2["default"])(this, "_hasFixedHeight", void 0); (0, _defineProperty2["default"])(this, "_hasFixedWidth", void 0); (0, _defineProperty2["default"])(this, "_columnCount", 0); (0, _defineProperty2["default"])(this, "_rowCount", 0); (0, _defineProperty2["default"])(this, "columnWidth", function (_ref) { var index = _ref.index; var key = _this._keyMapper(0, index); return _this._columnWidthCache[key] !== undefined ? _this._columnWidthCache[key] : _this._defaultWidth; }); (0, _defineProperty2["default"])(this, "rowHeight", function (_ref2) { var index = _ref2.index; var key = _this._keyMapper(index, 0); return _this._rowHeightCache[key] !== undefined ? _this._rowHeightCache[key] : _this._defaultHeight; }); var defaultHeight = params.defaultHeight, defaultWidth = params.defaultWidth, fixedHeight = params.fixedHeight, fixedWidth = params.fixedWidth, keyMapper = params.keyMapper, minHeight = params.minHeight, minWidth = params.minWidth; this._hasFixedHeight = fixedHeight === true; this._hasFixedWidth = fixedWidth === true; this._minHeight = minHeight || 0; this._minWidth = minWidth || 0; this._keyMapper = keyMapper || defaultKeyMapper; this._defaultHeight = Math.max(this._minHeight, typeof defaultHeight === 'number' ? defaultHeight : DEFAULT_HEIGHT); this._defaultWidth = Math.max(this._minWidth, typeof defaultWidth === 'number' ? defaultWidth : DEFAULT_WIDTH); if (process.env.NODE_ENV !== 'production') { if (this._hasFixedHeight === false && this._hasFixedWidth === false) { console.warn("CellMeasurerCache should only measure a cell's width or height. " + 'You have configured CellMeasurerCache to measure both. ' + 'This will result in poor performance.'); } if (this._hasFixedHeight === false && this._defaultHeight === 0) { console.warn('Fixed height CellMeasurerCache should specify a :defaultHeight greater than 0. ' + 'Failing to do so will lead to unnecessary layout and poor performance.'); } if (this._hasFixedWidth === false && this._defaultWidth === 0) { console.warn('Fixed width CellMeasurerCache should specify a :defaultWidth greater than 0. ' + 'Failing to do so will lead to unnecessary layout and poor performance.'); } } } (0, _createClass2["default"])(CellMeasurerCache, [{ key: "clear", value: function clear(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var key = this._keyMapper(rowIndex, columnIndex); delete this._cellHeightCache[key]; delete this._cellWidthCache[key]; this._updateCachedColumnAndRowSizes(rowIndex, columnIndex); } }, { key: "clearAll", value: function clearAll() { this._cellHeightCache = {}; this._cellWidthCache = {}; this._columnWidthCache = {}; this._rowHeightCache = {}; this._rowCount = 0; this._columnCount = 0; } }, { key: "hasFixedHeight", value: function hasFixedHeight() { return this._hasFixedHeight; } }, { key: "hasFixedWidth", value: function hasFixedWidth() { return this._hasFixedWidth; } }, { key: "getHeight", value: function getHeight(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; if (this._hasFixedHeight) { return this._defaultHeight; } else { var _key = this._keyMapper(rowIndex, columnIndex); return this._cellHeightCache[_key] !== undefined ? Math.max(this._minHeight, this._cellHeightCache[_key]) : this._defaultHeight; } } }, { key: "getWidth", value: function getWidth(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; if (this._hasFixedWidth) { return this._defaultWidth; } else { var _key2 = this._keyMapper(rowIndex, columnIndex); return this._cellWidthCache[_key2] !== undefined ? Math.max(this._minWidth, this._cellWidthCache[_key2]) : this._defaultWidth; } } }, { key: "has", value: function has(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var key = this._keyMapper(rowIndex, columnIndex); return this._cellHeightCache[key] !== undefined; } }, { key: "set", value: function set(rowIndex, columnIndex, width, height) { var key = this._keyMapper(rowIndex, columnIndex); if (columnIndex >= this._columnCount) { this._columnCount = columnIndex + 1; } if (rowIndex >= this._rowCount) { this._rowCount = rowIndex + 1; } // Size is cached per cell so we don't have to re-measure if cells are re-ordered. this._cellHeightCache[key] = height; this._cellWidthCache[key] = width; this._updateCachedColumnAndRowSizes(rowIndex, columnIndex); } }, { key: "_updateCachedColumnAndRowSizes", value: function _updateCachedColumnAndRowSizes(rowIndex, columnIndex) { // :columnWidth and :rowHeight are derived based on all cells in a column/row. // Pre-cache these derived values for faster lookup later. // Reads are expected to occur more frequently than writes in this case. // Only update non-fixed dimensions though to avoid doing unnecessary work. if (!this._hasFixedWidth) { var columnWidth = 0; for (var i = 0; i < this._rowCount; i++) { columnWidth = Math.max(columnWidth, this.getWidth(i, columnIndex)); } var columnKey = this._keyMapper(0, columnIndex); this._columnWidthCache[columnKey] = columnWidth; } if (!this._hasFixedHeight) { var rowHeight = 0; for (var _i = 0; _i < this._columnCount; _i++) { rowHeight = Math.max(rowHeight, this.getHeight(rowIndex, _i)); } var rowKey = this._keyMapper(rowIndex, 0); this._rowHeightCache[rowKey] = rowHeight; } } }, { key: "defaultHeight", get: function get() { return this._defaultHeight; } }, { key: "defaultWidth", get: function get() { return this._defaultWidth; } }]); return CellMeasurerCache; }(); exports["default"] = CellMeasurerCache; function defaultKeyMapper(rowIndex, columnIndex) { return "".concat(rowIndex, "-").concat(columnIndex); }dist/commonjs/CellMeasurer/CellMeasurer.DynamicHeightGrid.example.js000064400000011653151676725770021651 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _immutable = _interopRequireDefault(require("immutable")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _CellMeasurer = _interopRequireDefault(require("./CellMeasurer")); var _CellMeasurerCache = _interopRequireDefault(require("./CellMeasurerCache")); var _Grid = _interopRequireDefault(require("../Grid")); var _CellMeasurerExample = _interopRequireDefault(require("./CellMeasurer.example.css")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var DynamicHeightGrid = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(DynamicHeightGrid, _React$PureComponent); function DynamicHeightGrid(props, context) { var _this; (0, _classCallCheck2["default"])(this, DynamicHeightGrid); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(DynamicHeightGrid).call(this, props, context)); _this._cache = new _CellMeasurerCache["default"]({ defaultWidth: 150, fixedWidth: true }); _this._cellRenderer = _this._cellRenderer.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(DynamicHeightGrid, [{ key: "render", value: function render() { var width = this.props.width; return React.createElement(_Grid["default"], { className: _CellMeasurerExample["default"].BodyGrid, columnCount: 50, columnWidth: 150, deferredMeasurementCache: this._cache, height: 400, overscanColumnCount: 0, overscanRowCount: 2, cellRenderer: this._cellRenderer, rowCount: 1000, rowHeight: this._cache.rowHeight, width: width }); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref) { var columnIndex = _ref.columnIndex, key = _ref.key, parent = _ref.parent, rowIndex = _ref.rowIndex, style = _ref.style; var _this$props = this.props, getClassName = _this$props.getClassName, getContent = _this$props.getContent, list = _this$props.list; var datum = list.get((rowIndex + columnIndex) % list.size); var classNames = getClassName({ columnIndex: columnIndex, rowIndex: rowIndex }); var content = getContent({ index: rowIndex, datum: datum }); return React.createElement(_CellMeasurer["default"], { cache: this._cache, columnIndex: columnIndex, key: key, parent: parent, rowIndex: rowIndex }, React.createElement("div", { className: classNames, style: _objectSpread({}, style, { width: 150 }) }, content)); } }]); return DynamicHeightGrid; }(React.PureComponent); exports["default"] = DynamicHeightGrid; DynamicHeightGrid.propTypes = process.env.NODE_ENV !== "production" ? { getClassName: _propTypes["default"].func.isRequired, getContent: _propTypes["default"].func.isRequired, list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired, width: _propTypes["default"].number.isRequired } : {};dist/commonjs/CellMeasurer/index.js000064400000001304151676725770013411 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "CellMeasurer", { enumerable: true, get: function get() { return _CellMeasurer["default"]; } }); Object.defineProperty(exports, "CellMeasurerCache", { enumerable: true, get: function get() { return _CellMeasurerCache["default"]; } }); exports["default"] = void 0; var _CellMeasurer = _interopRequireDefault(require("./CellMeasurer")); var _CellMeasurerCache = _interopRequireDefault(require("./CellMeasurerCache")); var _default = _CellMeasurer["default"]; exports["default"] = _default;dist/commonjs/CellMeasurer/CellMeasurer.example.js000064400000015231151676725770016323 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _immutable = _interopRequireDefault(require("immutable")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _ContentBox = require("../demo/ContentBox"); var _AutoSizer = _interopRequireDefault(require("../AutoSizer")); var _clsx3 = _interopRequireDefault(require("clsx")); var _CellMeasurerExample = _interopRequireDefault(require("./CellMeasurer.example.css")); var _CellMeasurerDynamicWidthGridExample = _interopRequireDefault(require("./CellMeasurer.DynamicWidthGrid.example.js")); var _CellMeasurerDynamicHeightGridExample = _interopRequireDefault(require("./CellMeasurer.DynamicHeightGrid.example.js")); var _CellMeasurerDynamicWidthMultiGridExample = _interopRequireDefault(require("./CellMeasurer.DynamicWidthMultiGrid.example.js")); var _CellMeasurerDynamicHeightListExample = _interopRequireDefault(require("./CellMeasurer.DynamicHeightList.example.js")); var _CellMeasurerDynamicHeightTableColumnExample = _interopRequireDefault(require("./CellMeasurer.DynamicHeightTableColumn.example.js")); var demoComponents = [_CellMeasurerDynamicWidthGridExample["default"], _CellMeasurerDynamicHeightGridExample["default"], _CellMeasurerDynamicWidthMultiGridExample["default"], _CellMeasurerDynamicHeightListExample["default"], _CellMeasurerDynamicHeightTableColumnExample["default"]]; var CellMeasurerExample = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(CellMeasurerExample, _React$PureComponent); function CellMeasurerExample(props, context) { var _this; (0, _classCallCheck2["default"])(this, CellMeasurerExample); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(CellMeasurerExample).call(this, props, context)); _this.state = { currentTab: 0 }; _this._onClick = _this._onClick.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(CellMeasurerExample, [{ key: "render", value: function render() { var list = this.context.list; var currentTab = this.state.currentTab; var buttonProps = { currentTab: currentTab, onClick: this._onClick }; var DemoComponent = demoComponents[currentTab]; return React.createElement(_ContentBox.ContentBox, null, React.createElement(_ContentBox.ContentBoxHeader, { text: "CellMeasurer", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/CellMeasurer/CellMeasurer.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/CellMeasurer.md" }), React.createElement(_ContentBox.ContentBoxParagraph, null, "This component can be used to just-in-time measure dynamic content (eg. messages in a chat interface)."), React.createElement(_AutoSizer["default"], { disableHeight: true }, function (_ref) { var width = _ref.width; return React.createElement("div", { style: { width: width } }, React.createElement("div", null, React.createElement("strong", null, "Grid"), ":", React.createElement(Tab, (0, _extends2["default"])({ id: 0 }, buttonProps), "dynamic width text"), React.createElement(Tab, (0, _extends2["default"])({ id: 1 }, buttonProps), "dynamic height text"), React.createElement("strong", null, "MultiGrid"), ":", React.createElement(Tab, (0, _extends2["default"])({ id: 2 }, buttonProps), "dynamic width text"), React.createElement("strong", null, "List"), ":", React.createElement(Tab, (0, _extends2["default"])({ id: 3 }, buttonProps), "dynamic height image"), React.createElement("strong", null, "Table"), ":", React.createElement(Tab, (0, _extends2["default"])({ id: 4 }, buttonProps), "mixed fixed and dynamic height text")), React.createElement(DemoComponent, { getClassName: getClassName, getContent: getContent, list: list, width: width })); })); } }, { key: "_onClick", value: function _onClick(id) { this.setState({ currentTab: id }); } }]); return CellMeasurerExample; }(React.PureComponent); exports["default"] = CellMeasurerExample; (0, _defineProperty2["default"])(CellMeasurerExample, "contextTypes", { list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired }); function getClassName(_ref2) { var columnIndex = _ref2.columnIndex, rowIndex = _ref2.rowIndex; var rowClass = rowIndex % 2 === 0 ? _CellMeasurerExample["default"].evenRow : _CellMeasurerExample["default"].oddRow; return (0, _clsx3["default"])(rowClass, _CellMeasurerExample["default"].cell, (0, _defineProperty2["default"])({}, _CellMeasurerExample["default"].centeredCell, columnIndex > 2)); } function getContent(_ref3) { var index = _ref3.index, datum = _ref3.datum, _ref3$long = _ref3["long"], _long = _ref3$long === void 0 ? true : _ref3$long; switch (index % 3) { case 0: return datum.color; case 1: return datum.name; case 2: return _long ? datum.randomLong : datum.random; } } function Tab(_ref4) { var children = _ref4.children, currentTab = _ref4.currentTab, id = _ref4.id, _onClick2 = _ref4.onClick; var classNames = (0, _clsx3["default"])(_CellMeasurerExample["default"].Tab, (0, _defineProperty2["default"])({}, _CellMeasurerExample["default"].ActiveTab, currentTab === id)); return React.createElement("button", { className: classNames, onClick: function onClick() { return _onClick2(id); } }, children); }dist/commonjs/CellMeasurer/CellMeasurer.DynamicHeightTableColumn.example.js000064400000011541151676725770023165 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _immutable = _interopRequireDefault(require("immutable")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _CellMeasurer = _interopRequireDefault(require("./CellMeasurer")); var _CellMeasurerCache = _interopRequireDefault(require("./CellMeasurerCache")); var _Table = require("../Table"); var _CellMeasurerExample = _interopRequireDefault(require("./CellMeasurer.example.css")); var DynamicHeightTableColumn = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(DynamicHeightTableColumn, _React$PureComponent); function DynamicHeightTableColumn() { var _getPrototypeOf2; var _this; (0, _classCallCheck2["default"])(this, DynamicHeightTableColumn); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(DynamicHeightTableColumn)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_cache", new _CellMeasurerCache["default"]({ fixedWidth: true, minHeight: 25 })); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_lastRenderedWidth", _this.props.width); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_columnCellRenderer", function (_ref) { var dataKey = _ref.dataKey, parent = _ref.parent, rowIndex = _ref.rowIndex; var list = _this.props.list; var datum = list.get(rowIndex % list.size); var content = rowIndex % 5 === 0 ? '' : datum.randomLong; return React.createElement(_CellMeasurer["default"], { cache: _this._cache, columnIndex: 0, key: dataKey, parent: parent, rowIndex: rowIndex }, React.createElement("div", { className: _CellMeasurerExample["default"].tableColumn, style: { whiteSpace: 'normal' } }, content)); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rowGetter", function (_ref2) { var index = _ref2.index; var list = _this.props.list; return list.get(index % list.size); }); return _this; } (0, _createClass2["default"])(DynamicHeightTableColumn, [{ key: "render", value: function render() { var width = this.props.width; if (this._lastRenderedWidth !== this.props.width) { this._lastRenderedWidth = this.props.width; this._cache.clearAll(); } return React.createElement(_Table.Table, { deferredMeasurementCache: this._cache, headerHeight: 20, height: 400, overscanRowCount: 2, rowClassName: _CellMeasurerExample["default"].tableRow, rowHeight: this._cache.rowHeight, rowGetter: this._rowGetter, rowCount: 1000, width: width }, React.createElement(_Table.Column, { className: _CellMeasurerExample["default"].tableColumn, dataKey: "name", label: "Name", width: 125 }), React.createElement(_Table.Column, { className: _CellMeasurerExample["default"].tableColumn, dataKey: "color", label: "Color", width: 75 }), React.createElement(_Table.Column, { width: width - 200, dataKey: "random", label: "Dynamic text", cellRenderer: this._columnCellRenderer })); } }]); return DynamicHeightTableColumn; }(React.PureComponent); exports["default"] = DynamicHeightTableColumn; DynamicHeightTableColumn.propTypes = process.env.NODE_ENV !== "production" ? { list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired, width: _propTypes["default"].number.isRequired } : {};dist/commonjs/CellMeasurer/CellMeasurer.jest.js000064400000026017151676725770015641 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _TestUtils = require("../TestUtils"); var _CellMeasurer = _interopRequireDefault(require("./CellMeasurer")); var _CellMeasurerCache = _interopRequireWildcard(require("./CellMeasurerCache")); // Accounts for the fact that JSDom doesn't support measurements. function mockClientWidthAndHeight(_ref) { var height = _ref.height, width = _ref.width; var object = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : HTMLElement.prototype; var heightFn = jest.fn().mockReturnValue(height); var widthFn = jest.fn().mockReturnValue(width); Object.defineProperty(object, 'offsetHeight', { configurable: true, get: heightFn }); Object.defineProperty(object, 'offsetWidth', { configurable: true, get: widthFn }); return { heightFn: heightFn, widthFn: widthFn }; } function createParent() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, cache = _ref2.cache, _ref2$invalidateCellS = _ref2.invalidateCellSizeAfterRender, invalidateCellSizeAfterRender = _ref2$invalidateCellS === void 0 ? jest.fn() : _ref2$invalidateCellS; return { invalidateCellSizeAfterRender: invalidateCellSizeAfterRender, props: { deferredMeasurementCache: cache } }; } function renderHelper() { var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref3$cache = _ref3.cache, cache = _ref3$cache === void 0 ? new _CellMeasurerCache["default"]({ fixedWidth: true }) : _ref3$cache, _ref3$children = _ref3.children, children = _ref3$children === void 0 ? React.createElement("div", null) : _ref3$children, parent = _ref3.parent; (0, _TestUtils.render)(React.createElement(_CellMeasurer["default"], { cache: cache, columnIndex: 0, parent: parent, rowIndex: 0, style: {} }, children)); } describe('CellMeasurer', function () { it('componentDidMount() should measure content that is not already in the cache', function () { var cache = new _CellMeasurerCache["default"]({ fixedWidth: true }); var parent = createParent({ cache: cache }); var _mockClientWidthAndHe = mockClientWidthAndHeight({ height: 20, width: 100 }), heightFn = _mockClientWidthAndHe.heightFn, widthFn = _mockClientWidthAndHe.widthFn; expect(heightFn).toHaveBeenCalledTimes(0); expect(widthFn).toHaveBeenCalledTimes(0); expect(cache.has(0, 0)).toBe(false); renderHelper({ cache: cache, parent: parent }); expect(parent.invalidateCellSizeAfterRender).toHaveBeenCalled(); expect(heightFn).toHaveBeenCalledTimes(1); expect(widthFn).toHaveBeenCalledTimes(1); expect(cache.has(0, 0)).toBe(true); expect(cache.getWidth(0, 0)).toBe(100); expect(cache.getHeight(0, 0)).toBe(20); }); it('componentDidMount() should not measure content that is already in the cache', function () { var cache = new _CellMeasurerCache["default"]({ fixedWidth: true }); cache.set(0, 0, 100, 20); var parent = createParent({ cache: cache }); var _mockClientWidthAndHe2 = mockClientWidthAndHeight({ height: 20, width: 100 }), heightFn = _mockClientWidthAndHe2.heightFn, widthFn = _mockClientWidthAndHe2.widthFn; expect(cache.has(0, 0)).toBe(true); renderHelper({ cache: cache, parent: parent }); expect(parent.invalidateCellSizeAfterRender).not.toHaveBeenCalled(); expect(heightFn).toHaveBeenCalledTimes(0); expect(widthFn).toHaveBeenCalledTimes(0); }); it('componentDidUpdate() should measure content that is not already in the cache', function () { var cache = new _CellMeasurerCache["default"]({ fixedWidth: true }); var parent = createParent({ cache: cache }); renderHelper({ cache: cache, parent: parent }); cache.clear(0, 0); parent.invalidateCellSizeAfterRender.mockReset(); expect(cache.has(0, 0)).toBe(false); expect(cache.getWidth(0, 0)).toBe(_CellMeasurerCache.DEFAULT_WIDTH); expect(cache.getHeight(0, 0)).toBe(_CellMeasurerCache.DEFAULT_HEIGHT); var _mockClientWidthAndHe3 = mockClientWidthAndHeight({ height: 20, width: 100 }), heightFn = _mockClientWidthAndHe3.heightFn, widthFn = _mockClientWidthAndHe3.widthFn; renderHelper({ cache: cache, parent: parent }); expect(cache.has(0, 0)).toBe(true); expect(parent.invalidateCellSizeAfterRender).toHaveBeenCalled(); expect(heightFn).toHaveBeenCalledTimes(1); expect(widthFn).toHaveBeenCalledTimes(1); expect(cache.getWidth(0, 0)).toBe(100); expect(cache.getHeight(0, 0)).toBe(20); }); it('componentDidUpdate() should not measure content that is already in the cache', function () { var cache = new _CellMeasurerCache["default"]({ fixedWidth: true }); cache.set(0, 0, 100, 20); var parent = createParent({ cache: cache }); expect(cache.has(0, 0)).toBe(true); var _mockClientWidthAndHe4 = mockClientWidthAndHeight({ height: 20, width: 100 }), heightFn = _mockClientWidthAndHe4.heightFn, widthFn = _mockClientWidthAndHe4.widthFn; renderHelper({ cache: cache, parent: parent }); renderHelper({ cache: cache, parent: parent }); expect(parent.invalidateCellSizeAfterRender).not.toHaveBeenCalled(); expect(heightFn).toHaveBeenCalledTimes(0); expect(widthFn).toHaveBeenCalledTimes(0); }); it('registerChild() should measure content that is not already in the cache', function () { var cache = new _CellMeasurerCache["default"]({ fixedWidth: true }); var parent = createParent({ cache: cache }); var element = document.createElement('div'); var _mockClientWidthAndHe5 = mockClientWidthAndHeight({ height: 20, width: 100 }, element), heightFn = _mockClientWidthAndHe5.heightFn, widthFn = _mockClientWidthAndHe5.widthFn; expect(heightFn).toHaveBeenCalledTimes(0); expect(widthFn).toHaveBeenCalledTimes(0); expect(cache.has(0, 0)).toBe(false); renderHelper({ cache: cache, parent: parent, children: function children(_ref4) { var registerChild = _ref4.registerChild; registerChild(element); return null; } }); expect(parent.invalidateCellSizeAfterRender).toHaveBeenCalled(); expect(heightFn).toHaveBeenCalledTimes(1); expect(widthFn).toHaveBeenCalledTimes(1); expect(cache.has(0, 0)).toBe(true); expect(cache.getWidth(0, 0)).toBe(100); expect(cache.getHeight(0, 0)).toBe(20); }); it('registerChild() should not measure content that is already in the cache', function () { var cache = new _CellMeasurerCache["default"]({ fixedWidth: true }); cache.set(0, 0, 100, 20); var parent = createParent({ cache: cache }); var element = document.createElement('div'); var _mockClientWidthAndHe6 = mockClientWidthAndHeight({ height: 20, width: 100 }, element), heightFn = _mockClientWidthAndHe6.heightFn, widthFn = _mockClientWidthAndHe6.widthFn; expect(cache.has(0, 0)).toBe(true); renderHelper({ cache: cache, parent: parent, children: function children(_ref5) { var registerChild = _ref5.registerChild; registerChild(element); return null; } }); expect(parent.invalidateCellSizeAfterRender).not.toHaveBeenCalled(); expect(heightFn).toHaveBeenCalledTimes(0); expect(widthFn).toHaveBeenCalledTimes(0); }); it('should pass a :measure param to a function child', function () { var cache = new _CellMeasurerCache["default"]({ fixedWidth: true }); var children = jest.fn().mockReturnValue(React.createElement("div", null)); renderHelper({ cache: cache, children: children }); expect(children).toHaveBeenCalled(); var params = children.mock.calls[0][0]; expect(typeof params.measure === 'function').toBe(true); }); it('should still update cache without a parent Grid', function () { jest.spyOn(console, 'warn'); mockClientWidthAndHeight({ height: 20, width: 100 }); var cache = new _CellMeasurerCache["default"]({ fixedWidth: true }); renderHelper({ cache: cache }); // No parent Grid expect(cache.has(0, 0)).toBe(true); expect(console.warn).not.toHaveBeenCalled(); }); // See issue #593 it('should explicitly set width/height style to "auto" before re-measuring', function () { var cache = new _CellMeasurerCache["default"]({ fixedWidth: true }); var parent = createParent({ cache: cache }); var child = jest.fn().mockReturnValue(React.createElement("div", { style: { width: 100, height: 30 } })); var measurer; var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(React.createElement(_CellMeasurer["default"], { ref: function ref(_ref6) { measurer = _ref6; }, cache: cache, columnIndex: 0, parent: parent, rowIndex: 0, style: {} }, child))); var styleHeights = [30]; var styleWidths = [100]; Object.defineProperties(node.style, { height: { get: function get() { return styleHeights[styleHeights.length - 1]; }, set: function set(value) { return styleHeights.push(value); } }, width: { get: function get() { return styleWidths[styleWidths.length - 1]; }, set: function set(value) { return styleWidths.push(value); } } }); var _measurer$_getCellMea = measurer._getCellMeasurements(node), height = _measurer$_getCellMea.height, width = _measurer$_getCellMea.width; expect(height).toBeGreaterThan(0); expect(width).toBeGreaterThan(0); expect(styleHeights).toEqual([30, 'auto', 30]); expect(styleWidths).toEqual([100, 100]); }); // See issue #660 it('should reset width/height style values after measuring with style "auto"', function () { var cache = new _CellMeasurerCache["default"]({ fixedHeight: true }); var parent = createParent({ cache: cache }); var child = jest.fn().mockReturnValue(React.createElement("div", { style: { width: 100, height: 30 } })); var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(React.createElement(_CellMeasurer["default"], { cache: cache, columnIndex: 0, parent: parent, rowIndex: 0, style: {} }, child))); node.style.width = 200; node.style.height = 60; child.mock.calls[0][0].measure(); expect(node.style.height).toBe('30px'); expect(node.style.width).toBe('100px'); }); });dist/commonjs/CellMeasurer/CellMeasurer.js000064400000020050151676725770014664 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _types = require("./types"); var _propTypes = _interopRequireDefault(require("prop-types")); var _class, _temp; /** * Wraps a cell and measures its rendered content. * Measurements are stored in a per-cell cache. * Cached-content is not be re-measured. */ var CellMeasurer = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(CellMeasurer, _React$PureComponent); function CellMeasurer() { var _getPrototypeOf2; var _this; (0, _classCallCheck2["default"])(this, CellMeasurer); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(CellMeasurer)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_child", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_measure", function () { var _this$props = _this.props, cache = _this$props.cache, _this$props$columnInd = _this$props.columnIndex, columnIndex = _this$props$columnInd === void 0 ? 0 : _this$props$columnInd, parent = _this$props.parent, _this$props$rowIndex = _this$props.rowIndex, rowIndex = _this$props$rowIndex === void 0 ? _this.props.index || 0 : _this$props$rowIndex; var _this$_getCellMeasure = _this._getCellMeasurements(), height = _this$_getCellMeasure.height, width = _this$_getCellMeasure.width; if (height !== cache.getHeight(rowIndex, columnIndex) || width !== cache.getWidth(rowIndex, columnIndex)) { cache.set(rowIndex, columnIndex, width, height); if (parent && typeof parent.recomputeGridSize === 'function') { parent.recomputeGridSize({ columnIndex: columnIndex, rowIndex: rowIndex }); } } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_registerChild", function (element) { if (element && !(element instanceof Element)) { console.warn('CellMeasurer registerChild expects to be passed Element or null'); } _this._child = element; if (element) { _this._maybeMeasureCell(); } }); return _this; } (0, _createClass2["default"])(CellMeasurer, [{ key: "componentDidMount", value: function componentDidMount() { this._maybeMeasureCell(); } }, { key: "componentDidUpdate", value: function componentDidUpdate() { this._maybeMeasureCell(); } }, { key: "render", value: function render() { var children = this.props.children; return typeof children === 'function' ? children({ measure: this._measure, registerChild: this._registerChild }) : children; } }, { key: "_getCellMeasurements", value: function _getCellMeasurements() { var cache = this.props.cache; var node = this._child || (0, _reactDom.findDOMNode)(this); // TODO Check for a bad combination of fixedWidth and missing numeric width or vice versa with height if (node && node.ownerDocument && node.ownerDocument.defaultView && node instanceof node.ownerDocument.defaultView.HTMLElement) { var styleWidth = node.style.width; var styleHeight = node.style.height; // If we are re-measuring a cell that has already been measured, // It will have a hard-coded width/height from the previous measurement. // The fact that we are measuring indicates this measurement is probably stale, // So explicitly clear it out (eg set to "auto") so we can recalculate. // See issue #593 for more info. // Even if we are measuring initially- if we're inside of a MultiGrid component, // Explicitly clear width/height before measuring to avoid being tainted by another Grid. // eg top/left Grid renders before bottom/right Grid // Since the CellMeasurerCache is shared between them this taints derived cell size values. if (!cache.hasFixedWidth()) { node.style.width = 'auto'; } if (!cache.hasFixedHeight()) { node.style.height = 'auto'; } var height = Math.ceil(node.offsetHeight); var width = Math.ceil(node.offsetWidth); // Reset after measuring to avoid breaking styles; see #660 if (styleWidth) { node.style.width = styleWidth; } if (styleHeight) { node.style.height = styleHeight; } return { height: height, width: width }; } else { return { height: 0, width: 0 }; } } }, { key: "_maybeMeasureCell", value: function _maybeMeasureCell() { var _this$props2 = this.props, cache = _this$props2.cache, _this$props2$columnIn = _this$props2.columnIndex, columnIndex = _this$props2$columnIn === void 0 ? 0 : _this$props2$columnIn, parent = _this$props2.parent, _this$props2$rowIndex = _this$props2.rowIndex, rowIndex = _this$props2$rowIndex === void 0 ? this.props.index || 0 : _this$props2$rowIndex; if (!cache.has(rowIndex, columnIndex)) { var _this$_getCellMeasure2 = this._getCellMeasurements(), height = _this$_getCellMeasure2.height, width = _this$_getCellMeasure2.width; cache.set(rowIndex, columnIndex, width, height); // If size has changed, let Grid know to re-render. if (parent && typeof parent.invalidateCellSizeAfterRender === 'function') { parent.invalidateCellSizeAfterRender({ columnIndex: columnIndex, rowIndex: rowIndex }); } } } }]); return CellMeasurer; }(React.PureComponent), (0, _defineProperty2["default"])(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { "cache": function cache() { return (typeof _types.bpfrpt_proptype_CellMeasureCache === "function" ? _types.bpfrpt_proptype_CellMeasureCache.isRequired ? _types.bpfrpt_proptype_CellMeasureCache.isRequired : _types.bpfrpt_proptype_CellMeasureCache : _propTypes["default"].shape(_types.bpfrpt_proptype_CellMeasureCache).isRequired).apply(this, arguments); }, "children": _propTypes["default"].oneOfType([_propTypes["default"].func, _propTypes["default"].node]).isRequired, "columnIndex": _propTypes["default"].number, "index": _propTypes["default"].number, "parent": _propTypes["default"].shape({ invalidateCellSizeAfterRender: _propTypes["default"].func, recomputeGridSize: _propTypes["default"].func }).isRequired, "rowIndex": _propTypes["default"].number }), _temp); // Used for DEV mode warning check exports["default"] = CellMeasurer; (0, _defineProperty2["default"])(CellMeasurer, "__internalCellMeasurerFlag", false); if (process.env.NODE_ENV !== 'production') { CellMeasurer.__internalCellMeasurerFlag = true; }dist/commonjs/CellMeasurer/CellMeasurer.DynamicWidthGrid.example.js000064400000011736151676725770021522 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _immutable = _interopRequireDefault(require("immutable")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _CellMeasurer = _interopRequireDefault(require("./CellMeasurer")); var _CellMeasurerCache = _interopRequireDefault(require("./CellMeasurerCache")); var _Grid = _interopRequireDefault(require("../Grid")); var _CellMeasurerExample = _interopRequireDefault(require("./CellMeasurer.example.css")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var DynamicWidthGrid = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(DynamicWidthGrid, _React$PureComponent); function DynamicWidthGrid(props, context) { var _this; (0, _classCallCheck2["default"])(this, DynamicWidthGrid); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(DynamicWidthGrid).call(this, props, context)); _this._cache = new _CellMeasurerCache["default"]({ defaultWidth: 100, fixedHeight: true }); _this._cellRenderer = _this._cellRenderer.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(DynamicWidthGrid, [{ key: "render", value: function render() { var width = this.props.width; return React.createElement(_Grid["default"], { className: _CellMeasurerExample["default"].BodyGrid, columnCount: 1000, columnWidth: this._cache.columnWidth, deferredMeasurementCache: this._cache, height: 400, overscanColumnCount: 0, overscanRowCount: 2, cellRenderer: this._cellRenderer, rowCount: 50, rowHeight: 35, width: width }); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref) { var columnIndex = _ref.columnIndex, key = _ref.key, parent = _ref.parent, rowIndex = _ref.rowIndex, style = _ref.style; var _this$props = this.props, getClassName = _this$props.getClassName, getContent = _this$props.getContent, list = _this$props.list; var datum = list.get((rowIndex + columnIndex) % list.size); var classNames = getClassName({ columnIndex: columnIndex, rowIndex: rowIndex }); var content = getContent({ index: columnIndex, datum: datum, "long": false }); return React.createElement(_CellMeasurer["default"], { cache: this._cache, columnIndex: columnIndex, key: key, parent: parent, rowIndex: rowIndex }, React.createElement("div", { className: classNames, style: _objectSpread({}, style, { height: 35, whiteSpace: 'nowrap' }) }, content)); } }]); return DynamicWidthGrid; }(React.PureComponent); exports["default"] = DynamicWidthGrid; DynamicWidthGrid.propTypes = process.env.NODE_ENV !== "production" ? { getClassName: _propTypes["default"].func.isRequired, getContent: _propTypes["default"].func.isRequired, list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired, width: _propTypes["default"].number.isRequired } : {};dist/commonjs/CellMeasurer/CellMeasurer.DynamicHeightList.example.js000064400000010021151676725770021663 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _immutable = _interopRequireDefault(require("immutable")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _CellMeasurer = _interopRequireDefault(require("./CellMeasurer")); var _CellMeasurerCache = _interopRequireDefault(require("./CellMeasurerCache")); var _List = _interopRequireDefault(require("../List")); var _CellMeasurerExample = _interopRequireDefault(require("./CellMeasurer.example.css")); var DynamicHeightList = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(DynamicHeightList, _React$PureComponent); function DynamicHeightList(props, context) { var _this; (0, _classCallCheck2["default"])(this, DynamicHeightList); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(DynamicHeightList).call(this, props, context)); _this._cache = new _CellMeasurerCache["default"]({ fixedWidth: true, minHeight: 50 }); _this._rowRenderer = _this._rowRenderer.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(DynamicHeightList, [{ key: "render", value: function render() { var width = this.props.width; return React.createElement(_List["default"], { className: _CellMeasurerExample["default"].BodyGrid, deferredMeasurementCache: this._cache, height: 400, overscanRowCount: 0, rowCount: 1000, rowHeight: this._cache.rowHeight, rowRenderer: this._rowRenderer, width: width }); } }, { key: "_rowRenderer", value: function _rowRenderer(_ref) { var index = _ref.index, key = _ref.key, parent = _ref.parent, style = _ref.style; var _this$props = this.props, getClassName = _this$props.getClassName, list = _this$props.list; var datum = list.get(index % list.size); var classNames = getClassName({ columnIndex: 0, rowIndex: index }); var imageWidth = 300; var imageHeight = datum.size * (1 + index % 3); var source = "https://www.fillmurray.com/".concat(imageWidth, "/").concat(imageHeight); return React.createElement(_CellMeasurer["default"], { cache: this._cache, columnIndex: 0, key: key, rowIndex: index, parent: parent }, function (_ref2) { var measure = _ref2.measure, registerChild = _ref2.registerChild; return React.createElement("div", { ref: registerChild, className: classNames, style: style }, React.createElement("img", { onLoad: measure, src: source, style: { width: imageWidth } })); }); } }]); return DynamicHeightList; }(React.PureComponent); exports["default"] = DynamicHeightList; DynamicHeightList.propTypes = process.env.NODE_ENV !== "production" ? { getClassName: _propTypes["default"].func.isRequired, list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired, width: _propTypes["default"].number.isRequired } : {};dist/commonjs/CellMeasurer/CellMeasurerCache.jest.js000064400000022556151676725770016571 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _CellMeasurerCache = _interopRequireWildcard(require("./CellMeasurerCache")); describe('CellMeasurerCache', function () { it('should override defaultHeight/defaultWidth if minHeight/minWidth are greater', function () { var cache = new _CellMeasurerCache["default"]({ defaultHeight: 20, defaultWidth: 100, fixedHeight: true, fixedWidth: true, minHeight: 30, minWidth: 150 }); cache.set(0, 0, 50, 10); expect(cache.getHeight(0, 0)).toBe(30); expect(cache.getWidth(0, 0)).toBe(150); expect(cache.rowHeight({ index: 0 })).toBe(30); expect(cache.columnWidth({ index: 0 })).toBe(150); }); it('should correctly report cache status', function () { var cache = new _CellMeasurerCache["default"]({ fixedHeight: true, fixedWidth: true }); expect(cache.has(0, 0)).toBe(false); }); it('should cache cells', function () { var cache = new _CellMeasurerCache["default"]({ fixedHeight: true, fixedWidth: true }); cache.set(0, 0, 100, 20); expect(cache.has(0, 0)).toBe(true); }); it('should return the correct default sizes for uncached cells if specified', function () { spyOn(console, 'warn'); // Ignore warning about variable width and height var cache = new _CellMeasurerCache["default"]({ defaultHeight: 20, defaultWidth: 100, minHeight: 15, minWidth: 80 }); expect(cache.getWidth(0, 0)).toBe(100); expect(cache.getHeight(0, 0)).toBe(20); cache.set(0, 0, 70, 10); expect(cache.getWidth(0, 0)).toBe(80); expect(cache.getHeight(0, 0)).toBe(15); }); it('should clear a single cached cell', function () { var cache = new _CellMeasurerCache["default"]({ fixedHeight: true, fixedWidth: true }); cache.set(0, 0, 100, 20); cache.set(1, 0, 100, 20); expect(cache.has(0, 0)).toBe(true); expect(cache.has(1, 0)).toBe(true); cache.clear(0, 0); expect(cache.has(0, 0)).toBe(false); expect(cache.has(1, 0)).toBe(true); }); it('should clear a single cached row cell in column 0 when columnIndex param is absent', function () { var cache = new _CellMeasurerCache["default"]({ fixedHeight: true, fixedWidth: true }); cache.set(0, 0, 100, 20); cache.set(1, 0, 100, 20); expect(cache.has(0, 0)).toBe(true); expect(cache.has(1, 0)).toBe(true); cache.clear(0); expect(cache.has(0, 0)).toBe(false); expect(cache.has(1, 0)).toBe(true); }); it('should clear all cached cells', function () { var cache = new _CellMeasurerCache["default"]({ fixedHeight: true, fixedWidth: true }); cache.set(0, 0, 100, 20); cache.set(1, 0, 100, 20); expect(cache.has(0, 0)).toBe(true); expect(cache.has(1, 0)).toBe(true); cache.clearAll(); expect(cache.has(0, 0)).toBe(false); expect(cache.has(1, 0)).toBe(false); }); it('should clear row and column counts when clearing all cells', function () { var cache = new _CellMeasurerCache["default"]({ fixedHeight: true, fixedWidth: true }); cache.set(0, 0, 100, 20); cache.set(1, 0, 100, 20); expect(cache._rowCount).toBe(2); expect(cache._columnCount).toBe(1); cache.clearAll(); expect(cache._rowCount).toBe(0); expect(cache._columnCount).toBe(0); }); it('should support a custom :keyMapper', function () { var keyMapper = jest.fn(); keyMapper.mockReturnValue('a'); spyOn(console, 'warn'); // Ignore warning about variable width and height var cache = new _CellMeasurerCache["default"]({ defaultHeight: 30, defaultWidth: 50, keyMapper: keyMapper }); cache.set(0, 0, 100, 20); expect(cache.has(0, 0)).toBe(true); // Changing the returned key should cause cache misses keyMapper.mockReset(); keyMapper.mockReturnValue('b'); expect(cache.has(0, 0)).toBe(false); expect(cache.columnWidth(0)).toBe(50); expect(cache.rowHeight(0)).toBe(30); expect(keyMapper.mock.calls).toHaveLength(3); // Restoring it should fix keyMapper.mockReset(); keyMapper.mockReturnValue('a'); expect(cache.has(0, 0)).toBe(true); expect(cache.columnWidth(0)).toBe(100); expect(cache.rowHeight(0)).toBe(20); expect(keyMapper.mock.calls).toHaveLength(3); }); it('should provide a Grid-compatible :columnWidth method', function () { var cache = new _CellMeasurerCache["default"]({ fixedHeight: true }); expect(cache.columnWidth({ index: 0 })).toBe(_CellMeasurerCache.DEFAULT_WIDTH); cache.set(0, 0, 100, 50); expect(cache.columnWidth({ index: 0 })).toBe(100); expect(cache.columnWidth({ index: 1 })).toBe(_CellMeasurerCache.DEFAULT_WIDTH); cache.set(1, 0, 75, 50); expect(cache.columnWidth({ index: 0 })).toBe(100); cache.set(2, 0, 125, 50); expect(cache.columnWidth({ index: 0 })).toBe(125); }); it('should provide a Grid-compatible :rowHeight method', function () { var cache = new _CellMeasurerCache["default"]({ fixedWidth: true }); expect(cache.rowHeight({ index: 0 })).toBe(_CellMeasurerCache.DEFAULT_HEIGHT); cache.set(0, 0, 100, 50); expect(cache.rowHeight({ index: 0 })).toBe(50); expect(cache.rowHeight({ index: 1 })).toBe(_CellMeasurerCache.DEFAULT_HEIGHT); cache.set(0, 1, 100, 25); expect(cache.rowHeight({ index: 0 })).toBe(50); cache.set(0, 2, 100, 75); expect(cache.rowHeight({ index: 0 })).toBe(75); }); it('should return the :defaultWidth for :columnWidth if not measured', function () { var cache = new _CellMeasurerCache["default"]({ defaultWidth: 25, fixedHeight: true, fixedWidth: true }); expect(cache.columnWidth({ index: 0 })).toBe(25); }); it('should return the :defaultHeight for :rowHeight if not measured', function () { var cache = new _CellMeasurerCache["default"]({ defaultHeight: 25, fixedHeight: true, fixedWidth: true }); expect(cache.rowHeight({ index: 0 })).toBe(25); }); it('should recalculate cached :columnWidth when cells are cleared', function () { var cache = new _CellMeasurerCache["default"]({ fixedHeight: true }); expect(cache.columnWidth({ index: 0 })).toBe(_CellMeasurerCache.DEFAULT_WIDTH); cache.set(0, 0, 125, 50); expect(cache.columnWidth({ index: 0 })).toBe(125); cache.set(1, 0, 150, 50); expect(cache.columnWidth({ index: 0 })).toBe(150); cache.clear(1, 0); expect(cache.columnWidth({ index: 0 })).toBe(125); cache.clear(0, 0); expect(cache.columnWidth({ index: 0 })).toBe(_CellMeasurerCache.DEFAULT_WIDTH); cache.set(0, 0, 125, 50); expect(cache.columnWidth({ index: 0 })).toBe(125); cache.clearAll(); expect(cache.columnWidth({ index: 0 })).toBe(_CellMeasurerCache.DEFAULT_WIDTH); }); it('should recalculate cached :rowHeight when cells are cleared', function () { var cache = new _CellMeasurerCache["default"]({ fixedWidth: true }); expect(cache.rowHeight({ index: 0 })).toBe(_CellMeasurerCache.DEFAULT_HEIGHT); cache.set(0, 0, 125, 50); expect(cache.rowHeight({ index: 0 })).toBe(50); cache.set(0, 1, 150, 75); expect(cache.rowHeight({ index: 0 })).toBe(75); cache.clear(0, 1); expect(cache.rowHeight({ index: 0 })).toBe(50); cache.clear(0, 0); expect(cache.rowHeight({ index: 0 })).toBe(_CellMeasurerCache.DEFAULT_HEIGHT); cache.set(0, 0, 125, 50); expect(cache.rowHeight({ index: 0 })).toBe(50); cache.clearAll(); expect(cache.rowHeight({ index: 0 })).toBe(_CellMeasurerCache.DEFAULT_HEIGHT); }); describe('DEV mode', function () { it('should warn about dynamic width and height configurations', function () { spyOn(console, 'warn'); var cache = new _CellMeasurerCache["default"]({ fixedHeight: false, fixedWidth: false }); expect(cache.hasFixedHeight()).toBe(false); expect(cache.hasFixedWidth()).toBe(false); expect(console.warn).toHaveBeenCalledWith("CellMeasurerCache should only measure a cell's width or height. " + 'You have configured CellMeasurerCache to measure both. ' + 'This will result in poor performance.'); }); it('should warn about dynamic width with a defaultWidth of 0', function () { spyOn(console, 'warn'); var cache = new _CellMeasurerCache["default"]({ defaultWidth: 0, fixedHeight: true }); expect(cache.getWidth(0, 0)).toBe(0); expect(console.warn).toHaveBeenCalledWith('Fixed width CellMeasurerCache should specify a :defaultWidth greater than 0. ' + 'Failing to do so will lead to unnecessary layout and poor performance.'); }); it('should warn about dynamic height with a defaultHeight of 0', function () { spyOn(console, 'warn'); var cache = new _CellMeasurerCache["default"]({ defaultHeight: 0, fixedWidth: true }); expect(cache.getHeight(0, 0)).toBe(0); expect(console.warn).toHaveBeenCalledWith('Fixed height CellMeasurerCache should specify a :defaultHeight greater than 0. ' + 'Failing to do so will lead to unnecessary layout and poor performance.'); }); }); });dist/commonjs/InfiniteLoader/InfiniteLoader.jest.js000064400000046654151676725770016474 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf5 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _InfiniteLoader = _interopRequireWildcard(require("./InfiniteLoader")); var React = _interopRequireWildcard(require("react")); var _List = _interopRequireDefault(require("../List")); var _TestUtils = require("../TestUtils"); describe('InfiniteLoader', function () { var innerOnRowsRendered; var isRowLoadedCalls = []; var isRowLoadedMap = {}; var loadMoreRowsCalls = []; var rowRendererCalls = []; beforeEach(function () { isRowLoadedCalls = []; isRowLoadedMap = {}; loadMoreRowsCalls = []; rowRendererCalls = []; }); function defaultIsRowLoaded(_ref) { var index = _ref.index; isRowLoadedCalls.push(index); return !!isRowLoadedMap[index]; } function defaultLoadMoreRows(_ref2) { var startIndex = _ref2.startIndex, stopIndex = _ref2.stopIndex; loadMoreRowsCalls.push({ startIndex: startIndex, stopIndex: stopIndex }); } function rowRenderer(_ref3) { var index = _ref3.index, key = _ref3.key, style = _ref3.style; rowRendererCalls.push(index); return React.createElement("div", { key: key, style: style }); } function getMarkup() { var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref4$height = _ref4.height, height = _ref4$height === void 0 ? 100 : _ref4$height, _ref4$isRowLoaded = _ref4.isRowLoaded, isRowLoaded = _ref4$isRowLoaded === void 0 ? defaultIsRowLoaded : _ref4$isRowLoaded, _ref4$loadMoreRows = _ref4.loadMoreRows, loadMoreRows = _ref4$loadMoreRows === void 0 ? defaultLoadMoreRows : _ref4$loadMoreRows, _ref4$minimumBatchSiz = _ref4.minimumBatchSize, minimumBatchSize = _ref4$minimumBatchSiz === void 0 ? 1 : _ref4$minimumBatchSiz, _ref4$rowHeight = _ref4.rowHeight, rowHeight = _ref4$rowHeight === void 0 ? 20 : _ref4$rowHeight, _ref4$rowCount = _ref4.rowCount, rowCount = _ref4$rowCount === void 0 ? 100 : _ref4$rowCount, scrollToIndex = _ref4.scrollToIndex, _ref4$threshold = _ref4.threshold, threshold = _ref4$threshold === void 0 ? 10 : _ref4$threshold, _ref4$width = _ref4.width, width = _ref4$width === void 0 ? 200 : _ref4$width; return React.createElement(_InfiniteLoader["default"], { isRowLoaded: isRowLoaded, loadMoreRows: loadMoreRows, minimumBatchSize: minimumBatchSize, rowCount: rowCount, threshold: threshold }, function (_ref5) { var onRowsRendered = _ref5.onRowsRendered, registerChild = _ref5.registerChild; innerOnRowsRendered = onRowsRendered; return React.createElement(_List["default"], { ref: registerChild, height: height, onRowsRendered: onRowsRendered, rowHeight: rowHeight, rowRenderer: rowRenderer, rowCount: rowCount, scrollToIndex: scrollToIndex, width: width }); }); } it('should call :isRowLoaded for all rows within the threshold each time a range of rows are rendered', function () { (0, _TestUtils.render)(getMarkup()); expect(isRowLoadedCalls).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]); }); it('should call :isRowLoaded for all rows within the rowCount each time a range of rows are rendered', function () { (0, _TestUtils.render)(getMarkup({ rowCount: 10 })); expect(isRowLoadedCalls).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); }); it('should call :loadMoreRows for unloaded rows within the threshold', function () { (0, _TestUtils.render)(getMarkup()); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 14 }]); }); it('should call :loadMoreRows for unloaded rows within the rowCount', function () { (0, _TestUtils.render)(getMarkup({ rowCount: 10 })); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 9 }]); }); it('should :forceUpdate once rows have loaded if :loadMoreRows returns a Promise', function _callee(done) { var savedResolve, loadMoreRows; return _regenerator["default"].async(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: loadMoreRows = function _ref6() { return new Promise(function (resolve) { savedResolve = resolve; }); }; (0, _TestUtils.render)(getMarkup({ loadMoreRows: loadMoreRows })); rowRendererCalls.splice(0); _context.next = 5; return _regenerator["default"].awrap(savedResolve()); case 5: expect(rowRendererCalls.length > 0).toEqual(true); done(); case 7: case "end": return _context.stop(); } } }); }); it('should not :forceUpdate once rows have loaded rows are no longer visible', function _callee2(done) { var resolves, loadMoreRows; return _regenerator["default"].async(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: loadMoreRows = function _ref7() { return new Promise(function (resolve) { resolves.push(resolve); }); }; resolves = []; (0, _TestUtils.render)(getMarkup({ loadMoreRows: loadMoreRows })); // Simulate a new range of rows being loaded innerOnRowsRendered({ startIndex: 100, stopIndex: 101 }); rowRendererCalls.splice(0); _context2.next = 7; return _regenerator["default"].awrap(resolves[0]()); case 7: // Resolve the first request only, not the simulated row-change expect(rowRendererCalls.length).toEqual(0); done(); case 9: case "end": return _context2.stop(); } } }); }); describe('minimumBatchSize', function () { it('should respect the specified :minimumBatchSize when scrolling down', function () { (0, _TestUtils.render)(getMarkup({ minimumBatchSize: 10, threshold: 0 })); expect(loadMoreRowsCalls.length).toEqual(1); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 9 }]); }); it('should respect the specified :minimumBatchSize when scrolling up', function () { (0, _TestUtils.render)(getMarkup({ minimumBatchSize: 10, scrollToIndex: 20, threshold: 0 })); loadMoreRowsCalls.splice(0); (0, _TestUtils.render)(getMarkup({ isRowLoaded: function isRowLoaded(_ref8) { var index = _ref8.index; return index >= 20; }, minimumBatchSize: 10, scrollToIndex: 15, threshold: 0 })); expect(loadMoreRowsCalls.length).toEqual(1); expect(loadMoreRowsCalls).toEqual([{ startIndex: 10, stopIndex: 19 }]); }); it('should not interfere with :threshold', function () { (0, _TestUtils.render)(getMarkup({ minimumBatchSize: 10, threshold: 10 })); expect(loadMoreRowsCalls.length).toEqual(1); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 14 }]); }); it('should respect the specified :minimumBatchSize if a user scrolls past the previous range', function () { var isRowLoadedIndices = {}; function isRowLoaded(_ref9) { var index = _ref9.index; if (!isRowLoadedIndices[index]) { isRowLoadedIndices[index] = true; return false; } else { return true; } } (0, _TestUtils.render)(getMarkup({ isRowLoaded: isRowLoaded, minimumBatchSize: 10, threshold: 0 })); // Simulate a new range of rows being loaded innerOnRowsRendered({ startIndex: 5, stopIndex: 10 }); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 9 }, { startIndex: 10, stopIndex: 19 }]); }); it('should not exceed ending boundaries if :minimumBatchSize is larger than needed', function () { (0, _TestUtils.render)(getMarkup({ minimumBatchSize: 10, rowCount: 25, threshold: 0 })); // Simulate a new range of rows being loaded innerOnRowsRendered({ startIndex: 18, stopIndex: 22 }); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 9 }, { startIndex: 15, stopIndex: 24 }]); }); it('should not exceed beginning boundaries if :minimumBatchSize is larger than needed', function () { (0, _TestUtils.render)(getMarkup({ minimumBatchSize: 10, scrollToIndex: 15, threshold: 0 })); loadMoreRowsCalls.splice(0); (0, _TestUtils.render)(getMarkup({ isRowLoaded: function isRowLoaded(_ref10) { var index = _ref10.index; return index >= 6; }, minimumBatchSize: 10, scrollToIndex: 2, threshold: 0 })); expect(loadMoreRowsCalls.length).toEqual(1); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 5 }]); }); }); // Verifies improved memoization; see bvaughn/react-virtualized/issues/345 it('should memoize calls to :loadMoreRows (not calling unless unloaded ranges have changed)', function () { (0, _TestUtils.render)(getMarkup({ isRowLoaded: function isRowLoaded() { return false; }, minimumBatchSize: 20, threshold: 0 })); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 19 }]); innerOnRowsRendered({ startIndex: 0, stopIndex: 15 }); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 19 }]); loadMoreRowsCalls.splice(0); innerOnRowsRendered({ startIndex: 0, stopIndex: 20 }); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 20 }]); }); it('resetLoadMoreRowsCache should reset memoized state', function () { var component = (0, _TestUtils.render)(getMarkup({ isRowLoaded: function isRowLoaded() { return false; }, minimumBatchSize: 20, threshold: 0 })); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 19 }]); innerOnRowsRendered({ startIndex: 0, stopIndex: 15 }); loadMoreRowsCalls.splice(0); expect(loadMoreRowsCalls).toEqual([]); component.resetLoadMoreRowsCache(); innerOnRowsRendered({ startIndex: 0, stopIndex: 15 }); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 19 }]); }); it('resetLoadMoreRowsCache should call :loadMoreRows if :autoReload parameter is true', function () { var component = (0, _TestUtils.render)(getMarkup({ isRowLoaded: function isRowLoaded() { return false; }, minimumBatchSize: 1, threshold: 0 })); // Simulate a new range of rows being loaded loadMoreRowsCalls.splice(0); innerOnRowsRendered({ startIndex: 0, stopIndex: 10 }); component.resetLoadMoreRowsCache(true); expect(loadMoreRowsCalls[loadMoreRowsCalls.length - 1]).toEqual({ startIndex: 0, stopIndex: 10 }); // Simulate a new range of rows being loaded loadMoreRowsCalls.splice(0); innerOnRowsRendered({ startIndex: 20, stopIndex: 30 }); expect(loadMoreRowsCalls[loadMoreRowsCalls.length - 1]).toEqual({ startIndex: 20, stopIndex: 30 }); loadMoreRowsCalls.splice(0); component.resetLoadMoreRowsCache(true); expect(loadMoreRowsCalls[loadMoreRowsCalls.length - 1]).toEqual({ startIndex: 20, stopIndex: 30 }); }); }); describe('scanForUnloadedRanges', function () { function createIsRowLoaded(rows) { return function (_ref11) { var index = _ref11.index; return rows[index]; }; } it('should return an empty array for a range of rows that have all been loaded', function () { expect((0, _InfiniteLoader.scanForUnloadedRanges)({ isRowLoaded: createIsRowLoaded([true, true, true]), startIndex: 0, stopIndex: 2 })).toEqual([]); }); it('return a range of only 1 unloaded row', function () { expect((0, _InfiniteLoader.scanForUnloadedRanges)({ isRowLoaded: createIsRowLoaded([true, false, true]), startIndex: 0, stopIndex: 2 })).toEqual([{ startIndex: 1, stopIndex: 1 }]); }); it('return a range of multiple unloaded rows', function () { expect((0, _InfiniteLoader.scanForUnloadedRanges)({ isRowLoaded: createIsRowLoaded([false, false, true]), startIndex: 0, stopIndex: 2 })).toEqual([{ startIndex: 0, stopIndex: 1 }]); }); it('return multiple ranges of unloaded rows', function () { expect((0, _InfiniteLoader.scanForUnloadedRanges)({ isRowLoaded: createIsRowLoaded([true, false, false, true, false, true, false]), startIndex: 0, stopIndex: 6 })).toEqual([{ startIndex: 1, stopIndex: 2 }, { startIndex: 4, stopIndex: 4 }, { startIndex: 6, stopIndex: 6 }]); }); }); describe('isRangeVisible', function () { it('first row(s) are visible', function () { expect((0, _InfiniteLoader.isRangeVisible)({ lastRenderedStartIndex: 10, lastRenderedStopIndex: 20, startIndex: 20, stopIndex: 30 })).toEqual(true); }); it('last row(s) are visible', function () { expect((0, _InfiniteLoader.isRangeVisible)({ lastRenderedStartIndex: 10, lastRenderedStopIndex: 20, startIndex: 0, stopIndex: 10 })).toEqual(true); }); it('all row(s) are visible', function () { expect((0, _InfiniteLoader.isRangeVisible)({ lastRenderedStartIndex: 10, lastRenderedStopIndex: 20, startIndex: 12, stopIndex: 14 })).toEqual(true); }); it('no row(s) are visible', function () { expect((0, _InfiniteLoader.isRangeVisible)({ lastRenderedStartIndex: 10, lastRenderedStopIndex: 20, startIndex: 0, stopIndex: 9 })).toEqual(false); expect((0, _InfiniteLoader.isRangeVisible)({ lastRenderedStartIndex: 10, lastRenderedStopIndex: 20, startIndex: 21, stopIndex: 30 })).toEqual(false); }); }); describe('forceUpdateReactVirtualizedComponent', function () { it('should call :recomputeGridSize if defined', function () { var recomputeGridSize = jest.fn(); var TestComponent = /*#__PURE__*/ function (_React$Component) { (0, _inherits2["default"])(TestComponent, _React$Component); function TestComponent() { var _getPrototypeOf2; var _this; (0, _classCallCheck2["default"])(this, TestComponent); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf5["default"])(TestComponent)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "recomputeGridSize", recomputeGridSize); return _this; } (0, _createClass2["default"])(TestComponent, [{ key: "render", value: function render() { return React.createElement("div", null); } }]); return TestComponent; }(React.Component); (0, _InfiniteLoader.forceUpdateReactVirtualizedComponent)((0, _TestUtils.render)(React.createElement(TestComponent, null)), 10); expect(recomputeGridSize).toHaveBeenCalledTimes(1); expect(recomputeGridSize).toHaveBeenCalledWith(10); }); it('should called :recomputeRowHeights if defined', function () { var recomputeRowHeights = jest.fn(); var TestComponent = /*#__PURE__*/ function (_React$Component2) { (0, _inherits2["default"])(TestComponent, _React$Component2); function TestComponent() { var _getPrototypeOf3; var _this2; (0, _classCallCheck2["default"])(this, TestComponent); for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } _this2 = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf3 = (0, _getPrototypeOf5["default"])(TestComponent)).call.apply(_getPrototypeOf3, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this2), "recomputeRowHeights", recomputeRowHeights); return _this2; } (0, _createClass2["default"])(TestComponent, [{ key: "render", value: function render() { return React.createElement("div", null); } }]); return TestComponent; }(React.Component); (0, _InfiniteLoader.forceUpdateReactVirtualizedComponent)((0, _TestUtils.render)(React.createElement(TestComponent, null)), 10); expect(recomputeRowHeights).toHaveBeenCalledTimes(1); expect(recomputeRowHeights).toHaveBeenCalledWith(10); }); it('should call :forceUpdate otherwise', function () { var forceUpdate = jest.fn(); var TestComponent = /*#__PURE__*/ function (_React$Component3) { (0, _inherits2["default"])(TestComponent, _React$Component3); function TestComponent() { var _getPrototypeOf4; var _this3; (0, _classCallCheck2["default"])(this, TestComponent); for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { args[_key3] = arguments[_key3]; } _this3 = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf4 = (0, _getPrototypeOf5["default"])(TestComponent)).call.apply(_getPrototypeOf4, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this3), "forceUpdate", forceUpdate); return _this3; } (0, _createClass2["default"])(TestComponent, [{ key: "render", value: function render() { return React.createElement("div", null); } }]); return TestComponent; }(React.Component); (0, _InfiniteLoader.forceUpdateReactVirtualizedComponent)((0, _TestUtils.render)(React.createElement(TestComponent, null)), 10); expect(forceUpdate).toHaveBeenCalledTimes(1); }); });dist/commonjs/InfiniteLoader/index.js000064400000000750151676725770013726 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "InfiniteLoader", { enumerable: true, get: function get() { return _InfiniteLoader["default"]; } }); exports["default"] = void 0; var _InfiniteLoader = _interopRequireDefault(require("./InfiniteLoader")); var _default = _InfiniteLoader["default"]; exports["default"] = _default;dist/commonjs/InfiniteLoader/InfiniteLoader.example.js000064400000017176151676725770017157 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var React = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _ContentBox = require("../demo/ContentBox"); var _immutable = _interopRequireDefault(require("immutable")); var _AutoSizer = _interopRequireDefault(require("../AutoSizer")); var _InfiniteLoader = _interopRequireDefault(require("./InfiniteLoader")); var _List = _interopRequireDefault(require("../List")); var _InfiniteLoaderExample = _interopRequireDefault(require("./InfiniteLoader.example.css")); var STATUS_LOADING = 1; var STATUS_LOADED = 2; var InfiniteLoaderExample = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(InfiniteLoaderExample, _React$PureComponent); function InfiniteLoaderExample(props) { var _this; (0, _classCallCheck2["default"])(this, InfiniteLoaderExample); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(InfiniteLoaderExample).call(this, props)); _this.state = { loadedRowCount: 0, loadedRowsMap: {}, loadingRowCount: 0 }; _this._timeoutIdMap = {}; _this._clearData = _this._clearData.bind((0, _assertThisInitialized2["default"])(_this)); _this._isRowLoaded = _this._isRowLoaded.bind((0, _assertThisInitialized2["default"])(_this)); _this._loadMoreRows = _this._loadMoreRows.bind((0, _assertThisInitialized2["default"])(_this)); _this._rowRenderer = _this._rowRenderer.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(InfiniteLoaderExample, [{ key: "componentWillUnmount", value: function componentWillUnmount() { Object.keys(this._timeoutIdMap).forEach(function (timeoutId) { clearTimeout(timeoutId); }); } }, { key: "render", value: function render() { var _this2 = this; var list = this.context.list; var _this$state = this.state, loadedRowCount = _this$state.loadedRowCount, loadingRowCount = _this$state.loadingRowCount; return React.createElement(_ContentBox.ContentBox, null, React.createElement(_ContentBox.ContentBoxHeader, { text: "InfiniteLoader", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/InfiniteLoader/InfiniteLoader.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/InfiniteLoader.md" }), React.createElement(_ContentBox.ContentBoxParagraph, null, "This component manages just-in-time data fetching to ensure that the all visible rows have been loaded. It also uses a threshold to determine how early to pre-fetch rows (before a user scrolls to them)."), React.createElement(_ContentBox.ContentBoxParagraph, null, React.createElement("div", { className: _InfiniteLoaderExample["default"].cacheButtonAndCountRow }, React.createElement("button", { className: _InfiniteLoaderExample["default"].button, onClick: this._clearData }, "Flush Cached Data"), React.createElement("div", { className: _InfiniteLoaderExample["default"].cacheCountRow }, loadingRowCount, " loading, ", loadedRowCount, " loaded"))), React.createElement(_InfiniteLoader["default"], { isRowLoaded: this._isRowLoaded, loadMoreRows: this._loadMoreRows, rowCount: list.size }, function (_ref) { var onRowsRendered = _ref.onRowsRendered, registerChild = _ref.registerChild; return React.createElement(_AutoSizer["default"], { disableHeight: true }, function (_ref2) { var width = _ref2.width; return React.createElement(_List["default"], { ref: registerChild, className: _InfiniteLoaderExample["default"].List, height: 200, onRowsRendered: onRowsRendered, rowCount: list.size, rowHeight: 30, rowRenderer: _this2._rowRenderer, width: width }); }); })); } }, { key: "_clearData", value: function _clearData() { this.setState({ loadedRowCount: 0, loadedRowsMap: {}, loadingRowCount: 0 }); } }, { key: "_isRowLoaded", value: function _isRowLoaded(_ref3) { var index = _ref3.index; var loadedRowsMap = this.state.loadedRowsMap; return !!loadedRowsMap[index]; // STATUS_LOADING or STATUS_LOADED } }, { key: "_loadMoreRows", value: function _loadMoreRows(_ref4) { var _this3 = this; var startIndex = _ref4.startIndex, stopIndex = _ref4.stopIndex; var _this$state2 = this.state, loadedRowsMap = _this$state2.loadedRowsMap, loadingRowCount = _this$state2.loadingRowCount; var increment = stopIndex - startIndex + 1; for (var i = startIndex; i <= stopIndex; i++) { loadedRowsMap[i] = STATUS_LOADING; } this.setState({ loadingRowCount: loadingRowCount + increment }); var timeoutId = setTimeout(function () { var _this3$state = _this3.state, loadedRowCount = _this3$state.loadedRowCount, loadingRowCount = _this3$state.loadingRowCount; delete _this3._timeoutIdMap[timeoutId]; for (var i = startIndex; i <= stopIndex; i++) { loadedRowsMap[i] = STATUS_LOADED; } _this3.setState({ loadingRowCount: loadingRowCount - increment, loadedRowCount: loadedRowCount + increment }); promiseResolver(); }, 1000 + Math.round(Math.random() * 2000)); this._timeoutIdMap[timeoutId] = true; var promiseResolver; return new Promise(function (resolve) { promiseResolver = resolve; }); } }, { key: "_rowRenderer", value: function _rowRenderer(_ref5) { var index = _ref5.index, key = _ref5.key, style = _ref5.style; var list = this.context.list; var loadedRowsMap = this.state.loadedRowsMap; var row = list.get(index); var content; if (loadedRowsMap[index] === STATUS_LOADED) { content = row.name; } else { content = React.createElement("div", { className: _InfiniteLoaderExample["default"].placeholder, style: { width: row.size } }); } return React.createElement("div", { className: _InfiniteLoaderExample["default"].row, key: key, style: style }, content); } }]); return InfiniteLoaderExample; }(React.PureComponent); exports["default"] = InfiniteLoaderExample; (0, _defineProperty2["default"])(InfiniteLoaderExample, "contextTypes", { list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired });dist/commonjs/InfiniteLoader/InfiniteLoader.js000064400000025747151676725770015530 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.isRangeVisible = isRangeVisible; exports.scanForUnloadedRanges = scanForUnloadedRanges; exports.forceUpdateReactVirtualizedComponent = forceUpdateReactVirtualizedComponent; exports["default"] = void 0; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var React = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _createCallbackMemoizer = _interopRequireDefault(require("../utils/createCallbackMemoizer")); /** * Higher-order component that manages lazy-loading for "infinite" data. * This component decorates a virtual component and just-in-time prefetches rows as a user scrolls. * It is intended as a convenience component; fork it if you'd like finer-grained control over data-loading. */ var InfiniteLoader = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(InfiniteLoader, _React$PureComponent); function InfiniteLoader(props, context) { var _this; (0, _classCallCheck2["default"])(this, InfiniteLoader); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(InfiniteLoader).call(this, props, context)); _this._loadMoreRowsMemoizer = (0, _createCallbackMemoizer["default"])(); _this._onRowsRendered = _this._onRowsRendered.bind((0, _assertThisInitialized2["default"])(_this)); _this._registerChild = _this._registerChild.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(InfiniteLoader, [{ key: "resetLoadMoreRowsCache", value: function resetLoadMoreRowsCache(autoReload) { this._loadMoreRowsMemoizer = (0, _createCallbackMemoizer["default"])(); if (autoReload) { this._doStuff(this._lastRenderedStartIndex, this._lastRenderedStopIndex); } } }, { key: "render", value: function render() { var children = this.props.children; return children({ onRowsRendered: this._onRowsRendered, registerChild: this._registerChild }); } }, { key: "_loadUnloadedRanges", value: function _loadUnloadedRanges(unloadedRanges) { var _this2 = this; var loadMoreRows = this.props.loadMoreRows; unloadedRanges.forEach(function (unloadedRange) { var promise = loadMoreRows(unloadedRange); if (promise) { promise.then(function () { // Refresh the visible rows if any of them have just been loaded. // Otherwise they will remain in their unloaded visual state. if (isRangeVisible({ lastRenderedStartIndex: _this2._lastRenderedStartIndex, lastRenderedStopIndex: _this2._lastRenderedStopIndex, startIndex: unloadedRange.startIndex, stopIndex: unloadedRange.stopIndex })) { if (_this2._registeredChild) { forceUpdateReactVirtualizedComponent(_this2._registeredChild, _this2._lastRenderedStartIndex); } } }); } }); } }, { key: "_onRowsRendered", value: function _onRowsRendered(_ref) { var startIndex = _ref.startIndex, stopIndex = _ref.stopIndex; this._lastRenderedStartIndex = startIndex; this._lastRenderedStopIndex = stopIndex; this._doStuff(startIndex, stopIndex); } }, { key: "_doStuff", value: function _doStuff(startIndex, stopIndex) { var _ref2, _this3 = this; var _this$props = this.props, isRowLoaded = _this$props.isRowLoaded, minimumBatchSize = _this$props.minimumBatchSize, rowCount = _this$props.rowCount, threshold = _this$props.threshold; var unloadedRanges = scanForUnloadedRanges({ isRowLoaded: isRowLoaded, minimumBatchSize: minimumBatchSize, rowCount: rowCount, startIndex: Math.max(0, startIndex - threshold), stopIndex: Math.min(rowCount - 1, stopIndex + threshold) }); // For memoize comparison var squashedUnloadedRanges = (_ref2 = []).concat.apply(_ref2, (0, _toConsumableArray2["default"])(unloadedRanges.map(function (_ref3) { var startIndex = _ref3.startIndex, stopIndex = _ref3.stopIndex; return [startIndex, stopIndex]; }))); this._loadMoreRowsMemoizer({ callback: function callback() { _this3._loadUnloadedRanges(unloadedRanges); }, indices: { squashedUnloadedRanges: squashedUnloadedRanges } }); } }, { key: "_registerChild", value: function _registerChild(registeredChild) { this._registeredChild = registeredChild; } }]); return InfiniteLoader; }(React.PureComponent); /** * Determines if the specified start/stop range is visible based on the most recently rendered range. */ exports["default"] = InfiniteLoader; (0, _defineProperty2["default"])(InfiniteLoader, "defaultProps", { minimumBatchSize: 10, rowCount: 0, threshold: 15 }); InfiniteLoader.propTypes = process.env.NODE_ENV !== "production" ? { /** * Function responsible for rendering a virtualized component. * This function should implement the following signature: * ({ onRowsRendered, registerChild }) => PropTypes.element * * The specified :onRowsRendered function should be passed through to the child's :onRowsRendered property. * The :registerChild callback should be set as the virtualized component's :ref. */ children: _propTypes["default"].func.isRequired, /** * Function responsible for tracking the loaded state of each row. * It should implement the following signature: ({ index: number }): boolean */ isRowLoaded: _propTypes["default"].func.isRequired, /** * Callback to be invoked when more rows must be loaded. * It should implement the following signature: ({ startIndex, stopIndex }): Promise * The returned Promise should be resolved once row data has finished loading. * It will be used to determine when to refresh the list with the newly-loaded data. * This callback may be called multiple times in reaction to a single scroll event. */ loadMoreRows: _propTypes["default"].func.isRequired, /** * Minimum number of rows to be loaded at a time. * This property can be used to batch requests to reduce HTTP requests. */ minimumBatchSize: _propTypes["default"].number.isRequired, /** * Number of rows in list; can be arbitrary high number if actual number is unknown. */ rowCount: _propTypes["default"].number.isRequired, /** * Threshold at which to pre-fetch data. * A threshold X means that data will start loading when a user scrolls within X rows. * This value defaults to 15. */ threshold: _propTypes["default"].number.isRequired } : {}; function isRangeVisible(_ref4) { var lastRenderedStartIndex = _ref4.lastRenderedStartIndex, lastRenderedStopIndex = _ref4.lastRenderedStopIndex, startIndex = _ref4.startIndex, stopIndex = _ref4.stopIndex; return !(startIndex > lastRenderedStopIndex || stopIndex < lastRenderedStartIndex); } /** * Returns all of the ranges within a larger range that contain unloaded rows. */ function scanForUnloadedRanges(_ref5) { var isRowLoaded = _ref5.isRowLoaded, minimumBatchSize = _ref5.minimumBatchSize, rowCount = _ref5.rowCount, startIndex = _ref5.startIndex, stopIndex = _ref5.stopIndex; var unloadedRanges = []; var rangeStartIndex = null; var rangeStopIndex = null; for (var index = startIndex; index <= stopIndex; index++) { var loaded = isRowLoaded({ index: index }); if (!loaded) { rangeStopIndex = index; if (rangeStartIndex === null) { rangeStartIndex = index; } } else if (rangeStopIndex !== null) { unloadedRanges.push({ startIndex: rangeStartIndex, stopIndex: rangeStopIndex }); rangeStartIndex = rangeStopIndex = null; } } // If :rangeStopIndex is not null it means we haven't ran out of unloaded rows. // Scan forward to try filling our :minimumBatchSize. if (rangeStopIndex !== null) { var potentialStopIndex = Math.min(Math.max(rangeStopIndex, rangeStartIndex + minimumBatchSize - 1), rowCount - 1); for (var _index = rangeStopIndex + 1; _index <= potentialStopIndex; _index++) { if (!isRowLoaded({ index: _index })) { rangeStopIndex = _index; } else { break; } } unloadedRanges.push({ startIndex: rangeStartIndex, stopIndex: rangeStopIndex }); } // Check to see if our first range ended prematurely. // In this case we should scan backwards to try filling our :minimumBatchSize. if (unloadedRanges.length) { var firstUnloadedRange = unloadedRanges[0]; while (firstUnloadedRange.stopIndex - firstUnloadedRange.startIndex + 1 < minimumBatchSize && firstUnloadedRange.startIndex > 0) { var _index2 = firstUnloadedRange.startIndex - 1; if (!isRowLoaded({ index: _index2 })) { firstUnloadedRange.startIndex = _index2; } else { break; } } } return unloadedRanges; } /** * Since RV components use shallowCompare we need to force a render (even though props haven't changed). * However InfiniteLoader may wrap a Grid or it may wrap a Table or List. * In the first case the built-in React forceUpdate() method is sufficient to force a re-render, * But in the latter cases we need to use the RV-specific forceUpdateGrid() method. * Else the inner Grid will not be re-rendered and visuals may be stale. * * Additionally, while a Grid is scrolling the cells can be cached, * So it's important to invalidate that cache by recalculating sizes * before forcing a rerender. */ function forceUpdateReactVirtualizedComponent(component) { var currentIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var recomputeSize = typeof component.recomputeGridSize === 'function' ? component.recomputeGridSize : component.recomputeRowHeights; if (recomputeSize) { recomputeSize.call(component, currentIndex); } else { component.forceUpdate(); } }dist/commonjs/vendor/intervalTree.js000064400000022561151676725770013670 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = createWrapper; var _binarySearchBounds = _interopRequireDefault(require("./binarySearchBounds")); /** * Binary Search Bounds * https://github.com/mikolalysenko/interval-tree-1d * Mikola Lysenko * * Inlined because of Content Security Policy issue caused by the use of `new Function(...)` syntax in an upstream dependency. * Issue reported here: https://github.com/mikolalysenko/binary-search-bounds/issues/5 **/ var NOT_FOUND = 0; var SUCCESS = 1; var EMPTY = 2; function IntervalTreeNode(mid, left, right, leftPoints, rightPoints) { this.mid = mid; this.left = left; this.right = right; this.leftPoints = leftPoints; this.rightPoints = rightPoints; this.count = (left ? left.count : 0) + (right ? right.count : 0) + leftPoints.length; } var proto = IntervalTreeNode.prototype; function copy(a, b) { a.mid = b.mid; a.left = b.left; a.right = b.right; a.leftPoints = b.leftPoints; a.rightPoints = b.rightPoints; a.count = b.count; } function rebuild(node, intervals) { var ntree = createIntervalTree(intervals); node.mid = ntree.mid; node.left = ntree.left; node.right = ntree.right; node.leftPoints = ntree.leftPoints; node.rightPoints = ntree.rightPoints; node.count = ntree.count; } function rebuildWithInterval(node, interval) { var intervals = node.intervals([]); intervals.push(interval); rebuild(node, intervals); } function rebuildWithoutInterval(node, interval) { var intervals = node.intervals([]); var idx = intervals.indexOf(interval); if (idx < 0) { return NOT_FOUND; } intervals.splice(idx, 1); rebuild(node, intervals); return SUCCESS; } proto.intervals = function (result) { result.push.apply(result, this.leftPoints); if (this.left) { this.left.intervals(result); } if (this.right) { this.right.intervals(result); } return result; }; proto.insert = function (interval) { var weight = this.count - this.leftPoints.length; this.count += 1; if (interval[1] < this.mid) { if (this.left) { if (4 * (this.left.count + 1) > 3 * (weight + 1)) { rebuildWithInterval(this, interval); } else { this.left.insert(interval); } } else { this.left = createIntervalTree([interval]); } } else if (interval[0] > this.mid) { if (this.right) { if (4 * (this.right.count + 1) > 3 * (weight + 1)) { rebuildWithInterval(this, interval); } else { this.right.insert(interval); } } else { this.right = createIntervalTree([interval]); } } else { var l = _binarySearchBounds["default"].ge(this.leftPoints, interval, compareBegin); var r = _binarySearchBounds["default"].ge(this.rightPoints, interval, compareEnd); this.leftPoints.splice(l, 0, interval); this.rightPoints.splice(r, 0, interval); } }; proto.remove = function (interval) { var weight = this.count - this.leftPoints; if (interval[1] < this.mid) { if (!this.left) { return NOT_FOUND; } var rw = this.right ? this.right.count : 0; if (4 * rw > 3 * (weight - 1)) { return rebuildWithoutInterval(this, interval); } var r = this.left.remove(interval); if (r === EMPTY) { this.left = null; this.count -= 1; return SUCCESS; } else if (r === SUCCESS) { this.count -= 1; } return r; } else if (interval[0] > this.mid) { if (!this.right) { return NOT_FOUND; } var lw = this.left ? this.left.count : 0; if (4 * lw > 3 * (weight - 1)) { return rebuildWithoutInterval(this, interval); } var r = this.right.remove(interval); if (r === EMPTY) { this.right = null; this.count -= 1; return SUCCESS; } else if (r === SUCCESS) { this.count -= 1; } return r; } else { if (this.count === 1) { if (this.leftPoints[0] === interval) { return EMPTY; } else { return NOT_FOUND; } } if (this.leftPoints.length === 1 && this.leftPoints[0] === interval) { if (this.left && this.right) { var p = this; var n = this.left; while (n.right) { p = n; n = n.right; } if (p === this) { n.right = this.right; } else { var l = this.left; var r = this.right; p.count -= n.count; p.right = n.left; n.left = l; n.right = r; } copy(this, n); this.count = (this.left ? this.left.count : 0) + (this.right ? this.right.count : 0) + this.leftPoints.length; } else if (this.left) { copy(this, this.left); } else { copy(this, this.right); } return SUCCESS; } for (var l = _binarySearchBounds["default"].ge(this.leftPoints, interval, compareBegin); l < this.leftPoints.length; ++l) { if (this.leftPoints[l][0] !== interval[0]) { break; } if (this.leftPoints[l] === interval) { this.count -= 1; this.leftPoints.splice(l, 1); for (var r = _binarySearchBounds["default"].ge(this.rightPoints, interval, compareEnd); r < this.rightPoints.length; ++r) { if (this.rightPoints[r][1] !== interval[1]) { break; } else if (this.rightPoints[r] === interval) { this.rightPoints.splice(r, 1); return SUCCESS; } } } } return NOT_FOUND; } }; function reportLeftRange(arr, hi, cb) { for (var i = 0; i < arr.length && arr[i][0] <= hi; ++i) { var r = cb(arr[i]); if (r) { return r; } } } function reportRightRange(arr, lo, cb) { for (var i = arr.length - 1; i >= 0 && arr[i][1] >= lo; --i) { var r = cb(arr[i]); if (r) { return r; } } } function reportRange(arr, cb) { for (var i = 0; i < arr.length; ++i) { var r = cb(arr[i]); if (r) { return r; } } } proto.queryPoint = function (x, cb) { if (x < this.mid) { if (this.left) { var r = this.left.queryPoint(x, cb); if (r) { return r; } } return reportLeftRange(this.leftPoints, x, cb); } else if (x > this.mid) { if (this.right) { var r = this.right.queryPoint(x, cb); if (r) { return r; } } return reportRightRange(this.rightPoints, x, cb); } else { return reportRange(this.leftPoints, cb); } }; proto.queryInterval = function (lo, hi, cb) { if (lo < this.mid && this.left) { var r = this.left.queryInterval(lo, hi, cb); if (r) { return r; } } if (hi > this.mid && this.right) { var r = this.right.queryInterval(lo, hi, cb); if (r) { return r; } } if (hi < this.mid) { return reportLeftRange(this.leftPoints, hi, cb); } else if (lo > this.mid) { return reportRightRange(this.rightPoints, lo, cb); } else { return reportRange(this.leftPoints, cb); } }; function compareNumbers(a, b) { return a - b; } function compareBegin(a, b) { var d = a[0] - b[0]; if (d) { return d; } return a[1] - b[1]; } function compareEnd(a, b) { var d = a[1] - b[1]; if (d) { return d; } return a[0] - b[0]; } function createIntervalTree(intervals) { if (intervals.length === 0) { return null; } var pts = []; for (var i = 0; i < intervals.length; ++i) { pts.push(intervals[i][0], intervals[i][1]); } pts.sort(compareNumbers); var mid = pts[pts.length >> 1]; var leftIntervals = []; var rightIntervals = []; var centerIntervals = []; for (var i = 0; i < intervals.length; ++i) { var s = intervals[i]; if (s[1] < mid) { leftIntervals.push(s); } else if (mid < s[0]) { rightIntervals.push(s); } else { centerIntervals.push(s); } } //Split center intervals var leftPoints = centerIntervals; var rightPoints = centerIntervals.slice(); leftPoints.sort(compareBegin); rightPoints.sort(compareEnd); return new IntervalTreeNode(mid, createIntervalTree(leftIntervals), createIntervalTree(rightIntervals), leftPoints, rightPoints); } //User friendly wrapper that makes it possible to support empty trees function IntervalTree(root) { this.root = root; } var tproto = IntervalTree.prototype; tproto.insert = function (interval) { if (this.root) { this.root.insert(interval); } else { this.root = new IntervalTreeNode(interval[0], null, null, [interval], [interval]); } }; tproto.remove = function (interval) { if (this.root) { var r = this.root.remove(interval); if (r === EMPTY) { this.root = null; } return r !== NOT_FOUND; } return false; }; tproto.queryPoint = function (p, cb) { if (this.root) { return this.root.queryPoint(p, cb); } }; tproto.queryInterval = function (lo, hi, cb) { if (lo <= hi && this.root) { return this.root.queryInterval(lo, hi, cb); } }; Object.defineProperty(tproto, 'count', { get: function get() { if (this.root) { return this.root.count; } return 0; } }); Object.defineProperty(tproto, 'intervals', { get: function get() { if (this.root) { return this.root.intervals([]); } return []; } }); function createWrapper(intervals) { if (!intervals || intervals.length === 0) { return new IntervalTree(null); } return new IntervalTree(createIntervalTree(intervals)); }dist/commonjs/vendor/binarySearchBounds.js000064400000010103151676725770014776 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; /** * Binary Search Bounds * https://github.com/mikolalysenko/binary-search-bounds * Mikola Lysenko * * Inlined because of Content Security Policy issue caused by the use of `new Function(...)` syntax. * Issue reported here: https://github.com/mikolalysenko/binary-search-bounds/issues/5 **/ function _GEA(a, l, h, y) { var i = h + 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (x >= y) { i = m; h = m - 1; } else { l = m + 1; } } return i; } function _GEP(a, l, h, y, c) { var i = h + 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (c(x, y) >= 0) { i = m; h = m - 1; } else { l = m + 1; } } return i; } function dispatchBsearchGE(a, y, c, l, h) { if (typeof c === 'function') { return _GEP(a, l === void 0 ? 0 : l | 0, h === void 0 ? a.length - 1 : h | 0, y, c); } else { return _GEA(a, c === void 0 ? 0 : c | 0, l === void 0 ? a.length - 1 : l | 0, y); } } function _GTA(a, l, h, y) { var i = h + 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (x > y) { i = m; h = m - 1; } else { l = m + 1; } } return i; } function _GTP(a, l, h, y, c) { var i = h + 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (c(x, y) > 0) { i = m; h = m - 1; } else { l = m + 1; } } return i; } function dispatchBsearchGT(a, y, c, l, h) { if (typeof c === 'function') { return _GTP(a, l === void 0 ? 0 : l | 0, h === void 0 ? a.length - 1 : h | 0, y, c); } else { return _GTA(a, c === void 0 ? 0 : c | 0, l === void 0 ? a.length - 1 : l | 0, y); } } function _LTA(a, l, h, y) { var i = l - 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (x < y) { i = m; l = m + 1; } else { h = m - 1; } } return i; } function _LTP(a, l, h, y, c) { var i = l - 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (c(x, y) < 0) { i = m; l = m + 1; } else { h = m - 1; } } return i; } function dispatchBsearchLT(a, y, c, l, h) { if (typeof c === 'function') { return _LTP(a, l === void 0 ? 0 : l | 0, h === void 0 ? a.length - 1 : h | 0, y, c); } else { return _LTA(a, c === void 0 ? 0 : c | 0, l === void 0 ? a.length - 1 : l | 0, y); } } function _LEA(a, l, h, y) { var i = l - 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (x <= y) { i = m; l = m + 1; } else { h = m - 1; } } return i; } function _LEP(a, l, h, y, c) { var i = l - 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (c(x, y) <= 0) { i = m; l = m + 1; } else { h = m - 1; } } return i; } function dispatchBsearchLE(a, y, c, l, h) { if (typeof c === 'function') { return _LEP(a, l === void 0 ? 0 : l | 0, h === void 0 ? a.length - 1 : h | 0, y, c); } else { return _LEA(a, c === void 0 ? 0 : c | 0, l === void 0 ? a.length - 1 : l | 0, y); } } function _EQA(a, l, h, y) { l - 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (x === y) { return m; } else if (x <= y) { l = m + 1; } else { h = m - 1; } } return -1; } function _EQP(a, l, h, y, c) { l - 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; var p = c(x, y); if (p === 0) { return m; } else if (p <= 0) { l = m + 1; } else { h = m - 1; } } return -1; } function dispatchBsearchEQ(a, y, c, l, h) { if (typeof c === 'function') { return _EQP(a, l === void 0 ? 0 : l | 0, h === void 0 ? a.length - 1 : h | 0, y, c); } else { return _EQA(a, c === void 0 ? 0 : c | 0, l === void 0 ? a.length - 1 : l | 0, y); } } var _default = { ge: dispatchBsearchGE, gt: dispatchBsearchGT, lt: dispatchBsearchLT, le: dispatchBsearchLE, eq: dispatchBsearchEQ }; exports["default"] = _default;dist/commonjs/vendor/detectElementResize.js000064400000020363151676725770015166 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = createDetectElementResize; /** * Detect Element Resize. * https://github.com/sdecima/javascript-detect-element-resize * Sebastian Decima * * Forked from version 0.5.3; includes the following modifications: * 1) Guard against unsafe 'window' and 'document' references (to support SSR). * 2) Defer initialization code via a top-level function wrapper (to support SSR). * 3) Avoid unnecessary reflows by not measuring size for scroll events bubbling from children. * 4) Add nonce for style element. * 5) Added support for injecting custom window object **/ function createDetectElementResize(nonce, hostWindow) { // Check `document` and `window` in case of server-side rendering var _window; if (typeof hostWindow !== 'undefined') { _window = hostWindow; } else if (typeof window !== 'undefined') { _window = window; } else if (typeof self !== 'undefined') { _window = self; } else { _window = global; } var attachEvent = typeof _window.document !== 'undefined' && _window.document.attachEvent; if (!attachEvent) { var requestFrame = function () { var raf = _window.requestAnimationFrame || _window.mozRequestAnimationFrame || _window.webkitRequestAnimationFrame || function (fn) { return _window.setTimeout(fn, 20); }; return function (fn) { return raf(fn); }; }(); var cancelFrame = function () { var cancel = _window.cancelAnimationFrame || _window.mozCancelAnimationFrame || _window.webkitCancelAnimationFrame || _window.clearTimeout; return function (id) { return cancel(id); }; }(); var resetTriggers = function resetTriggers(element) { var triggers = element.__resizeTriggers__, expand = triggers.firstElementChild, contract = triggers.lastElementChild, expandChild = expand.firstElementChild; contract.scrollLeft = contract.scrollWidth; contract.scrollTop = contract.scrollHeight; expandChild.style.width = expand.offsetWidth + 1 + 'px'; expandChild.style.height = expand.offsetHeight + 1 + 'px'; expand.scrollLeft = expand.scrollWidth; expand.scrollTop = expand.scrollHeight; }; var checkTriggers = function checkTriggers(element) { return element.offsetWidth != element.__resizeLast__.width || element.offsetHeight != element.__resizeLast__.height; }; var scrollListener = function scrollListener(e) { // Don't measure (which forces) reflow for scrolls that happen inside of children! if (e.target.className && typeof e.target.className.indexOf === 'function' && e.target.className.indexOf('contract-trigger') < 0 && e.target.className.indexOf('expand-trigger') < 0) { return; } var element = this; resetTriggers(this); if (this.__resizeRAF__) { cancelFrame(this.__resizeRAF__); } this.__resizeRAF__ = requestFrame(function () { if (checkTriggers(element)) { element.__resizeLast__.width = element.offsetWidth; element.__resizeLast__.height = element.offsetHeight; element.__resizeListeners__.forEach(function (fn) { fn.call(element, e); }); } }); }; /* Detect CSS Animations support to detect element display/re-attach */ var animation = false, keyframeprefix = '', animationstartevent = 'animationstart', domPrefixes = 'Webkit Moz O ms'.split(' '), startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '), pfx = ''; { var elm = _window.document.createElement('fakeelement'); if (elm.style.animationName !== undefined) { animation = true; } if (animation === false) { for (var i = 0; i < domPrefixes.length; i++) { if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) { pfx = domPrefixes[i]; keyframeprefix = '-' + pfx.toLowerCase() + '-'; animationstartevent = startEvents[i]; animation = true; break; } } } } var animationName = 'resizeanim'; var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } '; var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; '; } var createStyles = function createStyles(doc) { if (!doc.getElementById('detectElementResize')) { //opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360 var css = (animationKeyframes ? animationKeyframes : '') + '.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' + '.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: " "; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; z-index: -1; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }', head = doc.head || doc.getElementsByTagName('head')[0], style = doc.createElement('style'); style.id = 'detectElementResize'; style.type = 'text/css'; if (nonce != null) { style.setAttribute('nonce', nonce); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(doc.createTextNode(css)); } head.appendChild(style); } }; var addResizeListener = function addResizeListener(element, fn) { if (attachEvent) { element.attachEvent('onresize', fn); } else { if (!element.__resizeTriggers__) { var doc = element.ownerDocument; var elementStyle = _window.getComputedStyle(element); if (elementStyle && elementStyle.position == 'static') { element.style.position = 'relative'; } createStyles(doc); element.__resizeLast__ = {}; element.__resizeListeners__ = []; (element.__resizeTriggers__ = doc.createElement('div')).className = 'resize-triggers'; var resizeTriggersHtml = '<div class="expand-trigger"><div></div></div>' + '<div class="contract-trigger"></div>'; if (window.trustedTypes) { var staticPolicy = trustedTypes.createPolicy('react-virtualized-auto-sizer', { createHTML: function createHTML() { return resizeTriggersHtml; } }); element.__resizeTriggers__.innerHTML = staticPolicy.createHTML(''); } else { element.__resizeTriggers__.innerHTML = resizeTriggersHtml; } element.appendChild(element.__resizeTriggers__); resetTriggers(element); element.addEventListener('scroll', scrollListener, true); /* Listen for a css animation to detect element display/re-attach */ if (animationstartevent) { element.__resizeTriggers__.__animationListener__ = function animationListener(e) { if (e.animationName == animationName) { resetTriggers(element); } }; element.__resizeTriggers__.addEventListener(animationstartevent, element.__resizeTriggers__.__animationListener__); } } element.__resizeListeners__.push(fn); } }; var removeResizeListener = function removeResizeListener(element, fn) { if (attachEvent) { element.detachEvent('onresize', fn); } else { element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1); if (!element.__resizeListeners__.length) { element.removeEventListener('scroll', scrollListener, true); if (element.__resizeTriggers__.__animationListener__) { element.__resizeTriggers__.removeEventListener(animationstartevent, element.__resizeTriggers__.__animationListener__); element.__resizeTriggers__.__animationListener__ = null; } try { element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__); } catch (e) {// Preact compat; see developit/preact-compat/issues/228 } } } }; return { addResizeListener: addResizeListener, removeResizeListener: removeResizeListener }; }dist/commonjs/Collection/Section.js000064400000003427151676725770013426 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _types = require("./types"); /** * A section of the Window. * Window Sections are used to group nearby cells. * This enables us to more quickly determine which cells to display in a given region of the Window. * Sections have a fixed size and contain 0 to many cells (tracked by their indices). */ var Section = /*#__PURE__*/ function () { function Section(_ref) { var height = _ref.height, width = _ref.width, x = _ref.x, y = _ref.y; (0, _classCallCheck2["default"])(this, Section); this.height = height; this.width = width; this.x = x; this.y = y; this._indexMap = {}; this._indices = []; } /** Add a cell to this section. */ (0, _createClass2["default"])(Section, [{ key: "addCellIndex", value: function addCellIndex(_ref2) { var index = _ref2.index; if (!this._indexMap[index]) { this._indexMap[index] = true; this._indices.push(index); } } /** Get all cell indices that have been added to this section. */ }, { key: "getCellIndices", value: function getCellIndices() { return this._indices; } /** Intended for debugger/test purposes only */ }, { key: "toString", value: function toString() { return "".concat(this.x, ",").concat(this.y, " ").concat(this.width, "x").concat(this.height); } }]); return Section; }(); exports["default"] = Section;dist/commonjs/Collection/types.js000064400000003351151676725770013162 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.bpfrpt_proptype_SizeInfo = exports.bpfrpt_proptype_SizeAndPositionInfo = exports.bpfrpt_proptype_ScrollPosition = exports.bpfrpt_proptype_PositionInfo = exports.bpfrpt_proptype_Index = void 0; var _propTypes = _interopRequireDefault(require("prop-types")); var bpfrpt_proptype_Index = process.env.NODE_ENV === 'production' ? null : { "index": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_Index = bpfrpt_proptype_Index; var bpfrpt_proptype_PositionInfo = process.env.NODE_ENV === 'production' ? null : { "x": _propTypes["default"].number.isRequired, "y": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_PositionInfo = bpfrpt_proptype_PositionInfo; var bpfrpt_proptype_ScrollPosition = process.env.NODE_ENV === 'production' ? null : { "scrollLeft": _propTypes["default"].number.isRequired, "scrollTop": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_ScrollPosition = bpfrpt_proptype_ScrollPosition; var bpfrpt_proptype_SizeAndPositionInfo = process.env.NODE_ENV === 'production' ? null : { "height": _propTypes["default"].number.isRequired, "width": _propTypes["default"].number.isRequired, "x": _propTypes["default"].number.isRequired, "y": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_SizeAndPositionInfo = bpfrpt_proptype_SizeAndPositionInfo; var bpfrpt_proptype_SizeInfo = process.env.NODE_ENV === 'production' ? null : { "height": _propTypes["default"].number.isRequired, "width": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_SizeInfo = bpfrpt_proptype_SizeInfo;dist/commonjs/Collection/SectionManager.js000064400000010437151676725770014720 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _Section = _interopRequireDefault(require("./Section")); var _types = require("./types"); /** * Window Sections are used to group nearby cells. * This enables us to more quickly determine which cells to display in a given region of the Window. * */ var SECTION_SIZE = 100; /** * Contains 0 to many Sections. * Grows (and adds Sections) dynamically as cells are registered. * Automatically adds cells to the appropriate Section(s). */ var SectionManager = /*#__PURE__*/ function () { function SectionManager() { var sectionSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : SECTION_SIZE; (0, _classCallCheck2["default"])(this, SectionManager); this._sectionSize = sectionSize; this._cellMetadata = []; this._sections = {}; } /** * Gets all cell indices contained in the specified region. * A region may encompass 1 or more Sections. */ (0, _createClass2["default"])(SectionManager, [{ key: "getCellIndices", value: function getCellIndices(_ref) { var height = _ref.height, width = _ref.width, x = _ref.x, y = _ref.y; var indices = {}; this.getSections({ height: height, width: width, x: x, y: y }).forEach(function (section) { return section.getCellIndices().forEach(function (index) { indices[index] = index; }); }); // Object keys are strings; this function returns numbers return Object.keys(indices).map(function (index) { return indices[index]; }); } /** Get size and position information for the cell specified. */ }, { key: "getCellMetadata", value: function getCellMetadata(_ref2) { var index = _ref2.index; return this._cellMetadata[index]; } /** Get all Sections overlapping the specified region. */ }, { key: "getSections", value: function getSections(_ref3) { var height = _ref3.height, width = _ref3.width, x = _ref3.x, y = _ref3.y; var sectionXStart = Math.floor(x / this._sectionSize); var sectionXStop = Math.floor((x + width - 1) / this._sectionSize); var sectionYStart = Math.floor(y / this._sectionSize); var sectionYStop = Math.floor((y + height - 1) / this._sectionSize); var sections = []; for (var sectionX = sectionXStart; sectionX <= sectionXStop; sectionX++) { for (var sectionY = sectionYStart; sectionY <= sectionYStop; sectionY++) { var key = "".concat(sectionX, ".").concat(sectionY); if (!this._sections[key]) { this._sections[key] = new _Section["default"]({ height: this._sectionSize, width: this._sectionSize, x: sectionX * this._sectionSize, y: sectionY * this._sectionSize }); } sections.push(this._sections[key]); } } return sections; } /** Total number of Sections based on the currently registered cells. */ }, { key: "getTotalSectionCount", value: function getTotalSectionCount() { return Object.keys(this._sections).length; } /** Intended for debugger/test purposes only */ }, { key: "toString", value: function toString() { var _this = this; return Object.keys(this._sections).map(function (index) { return _this._sections[index].toString(); }); } /** Adds a cell to the appropriate Sections and registers it metadata for later retrievable. */ }, { key: "registerCell", value: function registerCell(_ref4) { var cellMetadatum = _ref4.cellMetadatum, index = _ref4.index; this._cellMetadata[index] = cellMetadatum; this.getSections(cellMetadatum).forEach(function (section) { return section.addCellIndex({ index: index }); }); } }]); return SectionManager; }(); exports["default"] = SectionManager;dist/commonjs/Collection/Collection.example.js000064400000024102151676725770015540 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _immutable = _interopRequireDefault(require("immutable")); var _ContentBox = require("../demo/ContentBox"); var _LabeledInput = require("../demo/LabeledInput"); var _AutoSizer = _interopRequireDefault(require("../AutoSizer")); var _Collection = _interopRequireDefault(require("./Collection")); var _CollectionExample = _interopRequireDefault(require("./Collection.example.css")); // Defines a pattern of sizes and positions for a range of 10 rotating cells // These cells cover an area of 600 (wide) x 400 (tall) var GUTTER_SIZE = 3; var CELL_WIDTH = 75; var CollectionExample = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(CollectionExample, _React$PureComponent); function CollectionExample(props, context) { var _this; (0, _classCallCheck2["default"])(this, CollectionExample); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(CollectionExample).call(this, props, context)); _this.state = { cellCount: context.list.size, columnCount: _this._getColumnCount(context.list.size), height: 300, horizontalOverscanSize: 0, scrollToCell: undefined, showScrollingPlaceholder: false, verticalOverscanSize: 0 }; _this._columnYMap = []; _this._cellRenderer = _this._cellRenderer.bind((0, _assertThisInitialized2["default"])(_this)); _this._cellSizeAndPositionGetter = _this._cellSizeAndPositionGetter.bind((0, _assertThisInitialized2["default"])(_this)); _this._noContentRenderer = _this._noContentRenderer.bind((0, _assertThisInitialized2["default"])(_this)); _this._onCellCountChange = _this._onCellCountChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._onHeightChange = _this._onHeightChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._onHorizontalOverscanSizeChange = _this._onHorizontalOverscanSizeChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._onScrollToCellChange = _this._onScrollToCellChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._onVerticalOverscanSizeChange = _this._onVerticalOverscanSizeChange.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(CollectionExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, cellCount = _this$state.cellCount, height = _this$state.height, horizontalOverscanSize = _this$state.horizontalOverscanSize, scrollToCell = _this$state.scrollToCell, showScrollingPlaceholder = _this$state.showScrollingPlaceholder, verticalOverscanSize = _this$state.verticalOverscanSize; return React.createElement(_ContentBox.ContentBox, null, React.createElement(_ContentBox.ContentBoxHeader, { text: "Collection", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/Collection/Collection.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/Collection.md" }), React.createElement(_ContentBox.ContentBoxParagraph, null, "Renders scattered or non-linear data. Unlike ", React.createElement("code", null, "Grid"), ", which renders checkerboard data, ", React.createElement("code", null, "Collection"), " can render arbitrarily positioned- even overlapping- data."), React.createElement(_ContentBox.ContentBoxParagraph, null, React.createElement("label", { className: _CollectionExample["default"].checkboxLabel }, React.createElement("input", { "aria-label": "Show placeholder while scrolling?", checked: showScrollingPlaceholder, className: _CollectionExample["default"].checkbox, type: "checkbox", onChange: function onChange(event) { return _this2.setState({ showScrollingPlaceholder: event.target.checked }); } }), "Show placeholder while scrolling?")), React.createElement(_LabeledInput.InputRow, null, React.createElement(_LabeledInput.LabeledInput, { label: "Num cells", name: "cellCount", onChange: this._onCellCountChange, value: cellCount }), React.createElement(_LabeledInput.LabeledInput, { label: "Scroll to cell", name: "onScrollToCell", placeholder: "Index...", onChange: this._onScrollToCellChange, value: scrollToCell || '' }), React.createElement(_LabeledInput.LabeledInput, { label: "Height", name: "height", onChange: this._onHeightChange, value: height }), React.createElement(_LabeledInput.LabeledInput, { label: "Horizontal Overscan", name: "horizontalOverscanSize", onChange: this._onHorizontalOverscanSizeChange, value: horizontalOverscanSize }), React.createElement(_LabeledInput.LabeledInput, { label: "Vertical Overscan", name: "verticalOverscanSize", onChange: this._onVerticalOverscanSizeChange, value: verticalOverscanSize })), React.createElement(_AutoSizer["default"], { disableHeight: true }, function (_ref) { var width = _ref.width; return React.createElement(_Collection["default"], { cellCount: cellCount, cellRenderer: _this2._cellRenderer, cellSizeAndPositionGetter: _this2._cellSizeAndPositionGetter, className: _CollectionExample["default"].collection, height: height, horizontalOverscanSize: horizontalOverscanSize, noContentRenderer: _this2._noContentRenderer, scrollToCell: scrollToCell, verticalOverscanSize: verticalOverscanSize, width: width }); })); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref2) { var index = _ref2.index, isScrolling = _ref2.isScrolling, key = _ref2.key, style = _ref2.style; var list = this.context.list; var showScrollingPlaceholder = this.state.showScrollingPlaceholder; var datum = list.get(index % list.size); // Customize style style.backgroundColor = datum.color; return React.createElement("div", { className: _CollectionExample["default"].cell, key: key, style: style }, showScrollingPlaceholder && isScrolling ? '...' : index); } }, { key: "_cellSizeAndPositionGetter", value: function _cellSizeAndPositionGetter(_ref3) { var index = _ref3.index; var list = this.context.list; var columnCount = this.state.columnCount; var columnPosition = index % (columnCount || 1); var datum = list.get(index % list.size); // Poor man's Masonry layout; columns won't all line up equally with the bottom. var height = datum.size; var width = CELL_WIDTH; var x = columnPosition * (GUTTER_SIZE + width); var y = this._columnYMap[columnPosition] || 0; this._columnYMap[columnPosition] = y + height + GUTTER_SIZE; return { height: height, width: width, x: x, y: y }; } }, { key: "_getColumnCount", value: function _getColumnCount(cellCount) { return Math.round(Math.sqrt(cellCount)); } }, { key: "_onHorizontalOverscanSizeChange", value: function _onHorizontalOverscanSizeChange(event) { var horizontalOverscanSize = parseInt(event.target.value, 10) || 0; this.setState({ horizontalOverscanSize: horizontalOverscanSize }); } }, { key: "_noContentRenderer", value: function _noContentRenderer() { return React.createElement("div", { className: _CollectionExample["default"].noCells }, "No cells"); } }, { key: "_onCellCountChange", value: function _onCellCountChange(event) { var cellCount = parseInt(event.target.value, 10) || 0; this._columnYMap = []; this.setState({ cellCount: cellCount, columnCount: this._getColumnCount(cellCount) }); } }, { key: "_onHeightChange", value: function _onHeightChange(event) { var height = parseInt(event.target.value, 10) || 0; this.setState({ height: height }); } }, { key: "_onScrollToCellChange", value: function _onScrollToCellChange(event) { var cellCount = this.state.cellCount; var scrollToCell = Math.min(cellCount - 1, parseInt(event.target.value, 10)); if (isNaN(scrollToCell)) { scrollToCell = undefined; } this.setState({ scrollToCell: scrollToCell }); } }, { key: "_onVerticalOverscanSizeChange", value: function _onVerticalOverscanSizeChange(event) { var verticalOverscanSize = parseInt(event.target.value, 10) || 0; this.setState({ verticalOverscanSize: verticalOverscanSize }); } }]); return CollectionExample; }(React.PureComponent); exports["default"] = CollectionExample; (0, _defineProperty2["default"])(CollectionExample, "contextTypes", { list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired });dist/commonjs/Collection/Section.jest.js000064400000003301151676725770014361 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _Section = _interopRequireDefault(require("./Section")); describe('Section', function () { function helper() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$height = _ref.height, height = _ref$height === void 0 ? 100 : _ref$height, _ref$width = _ref.width, width = _ref$width === void 0 ? 200 : _ref$width, _ref$x = _ref.x, x = _ref$x === void 0 ? 0 : _ref$x, _ref$y = _ref.y, y = _ref$y === void 0 ? 0 : _ref$y; return new _Section["default"]({ height: height, width: width, x: x, y: y }); } it('should add a new cell index', function () { var section = helper(); expect(section.getCellIndices()).toEqual([]); section.addCellIndex({ index: 0 }); expect(section.getCellIndices()).toEqual([0]); section.addCellIndex({ index: 1 }); expect(section.getCellIndices()).toEqual([0, 1]); }); it('should not add a duplicate cell index', function () { var section = helper(); section.addCellIndex({ index: 0 }); section.addCellIndex({ index: 1 }); section.addCellIndex({ index: 0 }); section.addCellIndex({ index: 1 }); section.addCellIndex({ index: 2 }); expect(section.getCellIndices()).toEqual([0, 1, 2]); }); it('should define a working toString() method for debugging', function () { var section = helper({ height: 100, width: 200, x: 25, y: 50 }); expect(section.toString()).toEqual('25,50 200x100'); }); });dist/commonjs/Collection/utils/calculateSizeAndPositionData.js000064400000003121151676725770020703 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = calculateSizeAndPositionData; var _SectionManager = _interopRequireDefault(require("../SectionManager")); function calculateSizeAndPositionData(_ref) { var cellCount = _ref.cellCount, cellSizeAndPositionGetter = _ref.cellSizeAndPositionGetter, sectionSize = _ref.sectionSize; var cellMetadata = []; var sectionManager = new _SectionManager["default"](sectionSize); var height = 0; var width = 0; for (var index = 0; index < cellCount; index++) { var cellMetadatum = cellSizeAndPositionGetter({ index: index }); if (cellMetadatum.height == null || isNaN(cellMetadatum.height) || cellMetadatum.width == null || isNaN(cellMetadatum.width) || cellMetadatum.x == null || isNaN(cellMetadatum.x) || cellMetadatum.y == null || isNaN(cellMetadatum.y)) { throw Error("Invalid metadata returned for cell ".concat(index, ":\n x:").concat(cellMetadatum.x, ", y:").concat(cellMetadatum.y, ", width:").concat(cellMetadatum.width, ", height:").concat(cellMetadatum.height)); } height = Math.max(height, cellMetadatum.y + cellMetadatum.height); width = Math.max(width, cellMetadatum.x + cellMetadatum.width); cellMetadata[index] = cellMetadatum; sectionManager.registerCell({ cellMetadatum: cellMetadatum, index: index }); } return { cellMetadata: cellMetadata, height: height, sectionManager: sectionManager, width: width }; }dist/commonjs/Collection/utils/calculateSizeAndPositionData.jest.js000064400000002377151676725770021663 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _calculateSizeAndPositionData = _interopRequireDefault(require("./calculateSizeAndPositionData")); describe('calculateSizeAndPositionData', function () { it('should query for size and position of each cell', function () { var cellSizeAndPositionGetterCalls = []; function cellSizeAndPositionGetter(_ref) { var index = _ref.index; cellSizeAndPositionGetterCalls.push(index); return { x: index * 50, y: 0, width: 50, height: 50 }; } var _calculateSizeAndPosi = (0, _calculateSizeAndPositionData["default"])({ cellCount: 3, cellSizeAndPositionGetter: cellSizeAndPositionGetter }), sectionManager = _calculateSizeAndPosi.sectionManager; expect(cellSizeAndPositionGetterCalls).toEqual([0, 1, 2]); expect(sectionManager.getTotalSectionCount()).toEqual(2); }); it('should throw an error if invalid metadata is returned for a cell', function () { expect(function () { return (0, _calculateSizeAndPositionData["default"])({ cellCount: 3, cellSizeAndPositionGetter: function cellSizeAndPositionGetter() {} }); }).toThrow(); }); });dist/commonjs/Collection/index.js000064400000000724151676725770013126 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "Collection", { enumerable: true, get: function get() { return _Collection["default"]; } }); exports["default"] = void 0; var _Collection = _interopRequireDefault(require("./Collection")); var _default = _Collection["default"]; exports["default"] = _default;dist/commonjs/Collection/Collection.js000064400000022735151676725770014120 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _CollectionView = _interopRequireDefault(require("./CollectionView")); var _calculateSizeAndPositionData2 = _interopRequireDefault(require("./utils/calculateSizeAndPositionData")); var _getUpdatedOffsetForIndex = _interopRequireDefault(require("../utils/getUpdatedOffsetForIndex")); var _types = require("./types"); /** * Renders scattered or non-linear data. * Unlike Grid, which renders checkerboard data, Collection can render arbitrarily positioned- even overlapping- data. */ var Collection = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(Collection, _React$PureComponent); function Collection(props, context) { var _this; (0, _classCallCheck2["default"])(this, Collection); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(Collection).call(this, props, context)); _this._cellMetadata = []; _this._lastRenderedCellIndices = []; // Cell cache during scroll (for performance) _this._cellCache = []; _this._isScrollingChange = _this._isScrollingChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._setCollectionViewRef = _this._setCollectionViewRef.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(Collection, [{ key: "forceUpdate", value: function forceUpdate() { if (this._collectionView !== undefined) { this._collectionView.forceUpdate(); } } /** See Collection#recomputeCellSizesAndPositions */ }, { key: "recomputeCellSizesAndPositions", value: function recomputeCellSizesAndPositions() { this._cellCache = []; this._collectionView.recomputeCellSizesAndPositions(); } /** React lifecycle methods */ }, { key: "render", value: function render() { var props = (0, _extends2["default"])({}, this.props); return React.createElement(_CollectionView["default"], (0, _extends2["default"])({ cellLayoutManager: this, isScrollingChange: this._isScrollingChange, ref: this._setCollectionViewRef }, props)); } /** CellLayoutManager interface */ }, { key: "calculateSizeAndPositionData", value: function calculateSizeAndPositionData() { var _this$props = this.props, cellCount = _this$props.cellCount, cellSizeAndPositionGetter = _this$props.cellSizeAndPositionGetter, sectionSize = _this$props.sectionSize; var data = (0, _calculateSizeAndPositionData2["default"])({ cellCount: cellCount, cellSizeAndPositionGetter: cellSizeAndPositionGetter, sectionSize: sectionSize }); this._cellMetadata = data.cellMetadata; this._sectionManager = data.sectionManager; this._height = data.height; this._width = data.width; } /** * Returns the most recently rendered set of cell indices. */ }, { key: "getLastRenderedIndices", value: function getLastRenderedIndices() { return this._lastRenderedCellIndices; } /** * Calculates the minimum amount of change from the current scroll position to ensure the specified cell is (fully) visible. */ }, { key: "getScrollPositionForCell", value: function getScrollPositionForCell(_ref) { var align = _ref.align, cellIndex = _ref.cellIndex, height = _ref.height, scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, width = _ref.width; var cellCount = this.props.cellCount; if (cellIndex >= 0 && cellIndex < cellCount) { var cellMetadata = this._cellMetadata[cellIndex]; scrollLeft = (0, _getUpdatedOffsetForIndex["default"])({ align: align, cellOffset: cellMetadata.x, cellSize: cellMetadata.width, containerSize: width, currentOffset: scrollLeft, targetIndex: cellIndex }); scrollTop = (0, _getUpdatedOffsetForIndex["default"])({ align: align, cellOffset: cellMetadata.y, cellSize: cellMetadata.height, containerSize: height, currentOffset: scrollTop, targetIndex: cellIndex }); } return { scrollLeft: scrollLeft, scrollTop: scrollTop }; } }, { key: "getTotalSize", value: function getTotalSize() { return { height: this._height, width: this._width }; } }, { key: "cellRenderers", value: function cellRenderers(_ref2) { var _this2 = this; var height = _ref2.height, isScrolling = _ref2.isScrolling, width = _ref2.width, x = _ref2.x, y = _ref2.y; var _this$props2 = this.props, cellGroupRenderer = _this$props2.cellGroupRenderer, cellRenderer = _this$props2.cellRenderer; // Store for later calls to getLastRenderedIndices() this._lastRenderedCellIndices = this._sectionManager.getCellIndices({ height: height, width: width, x: x, y: y }); return cellGroupRenderer({ cellCache: this._cellCache, cellRenderer: cellRenderer, cellSizeAndPositionGetter: function cellSizeAndPositionGetter(_ref3) { var index = _ref3.index; return _this2._sectionManager.getCellMetadata({ index: index }); }, indices: this._lastRenderedCellIndices, isScrolling: isScrolling }); } }, { key: "_isScrollingChange", value: function _isScrollingChange(isScrolling) { if (!isScrolling) { this._cellCache = []; } } }, { key: "_setCollectionViewRef", value: function _setCollectionViewRef(ref) { this._collectionView = ref; } }]); return Collection; }(React.PureComponent); exports["default"] = Collection; (0, _defineProperty2["default"])(Collection, "defaultProps", { 'aria-label': 'grid', cellGroupRenderer: defaultCellGroupRenderer }); Collection.propTypes = process.env.NODE_ENV !== "production" ? { 'aria-label': _propTypes["default"].string, /** * Number of cells in Collection. */ cellCount: _propTypes["default"].number.isRequired, /** * Responsible for rendering a group of cells given their indices. * Should implement the following interface: ({ * cellSizeAndPositionGetter:Function, * indices: Array<number>, * cellRenderer: Function * }): Array<PropTypes.node> */ cellGroupRenderer: _propTypes["default"].func.isRequired, /** * Responsible for rendering a cell given an row and column index. * Should implement the following interface: ({ index: number, key: string, style: object }): PropTypes.element */ cellRenderer: _propTypes["default"].func.isRequired, /** * Callback responsible for returning size and offset/position information for a given cell (index). * ({ index: number }): { height: number, width: number, x: number, y: number } */ cellSizeAndPositionGetter: _propTypes["default"].func.isRequired, /** * Optionally override the size of the sections a Collection's cells are split into. */ sectionSize: _propTypes["default"].number } : {}; function defaultCellGroupRenderer(_ref4) { var cellCache = _ref4.cellCache, cellRenderer = _ref4.cellRenderer, cellSizeAndPositionGetter = _ref4.cellSizeAndPositionGetter, indices = _ref4.indices, isScrolling = _ref4.isScrolling; return indices.map(function (index) { var cellMetadata = cellSizeAndPositionGetter({ index: index }); var cellRendererProps = { index: index, isScrolling: isScrolling, key: index, style: { height: cellMetadata.height, left: cellMetadata.x, position: 'absolute', top: cellMetadata.y, width: cellMetadata.width } }; // Avoid re-creating cells while scrolling. // This can lead to the same cell being created many times and can cause performance issues for "heavy" cells. // If a scroll is in progress- cache and reuse cells. // This cache will be thrown away once scrolling complets. if (isScrolling) { if (!(index in cellCache)) { cellCache[index] = cellRenderer(cellRendererProps); } return cellCache[index]; } else { return cellRenderer(cellRendererProps); } }).filter(function (renderedCell) { return !!renderedCell; }); }dist/commonjs/Collection/TestData.js000064400000001754151676725770013534 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SECTION_SIZE = exports.CELLS = void 0; /* 0 1 2 3 4 5 ┏━━━┯━━━┯━━━┓ 0┃0 0┊1 3┊6 6┃ 1┃0 0┊2 3┊6 6┃ ┠┈┈┈┼┈┈┈┼┈┈┈┨ 2┃4 4┊4 3┊7 8┃ 3┃4 4┊4 5┊9 9┃ ┗━━━┷━━━┷━━━┛ Sections to Cells map: 0.0 [0] 1.0 [1, 2, 3] 2.0 [6] 0.1 [4] 1.1 [3, 4, 5] 2.1 [7, 8, 9] */ var CELLS = [{ x: 0, y: 0, width: 2, height: 2 }, { x: 2, y: 0, width: 1, height: 1 }, { x: 2, y: 1, width: 1, height: 1 }, { x: 3, y: 0, width: 1, height: 3 }, { x: 0, y: 2, width: 3, height: 2 }, { x: 3, y: 3, width: 1, height: 1 }, { x: 4, y: 0, width: 2, height: 2 }, { x: 4, y: 2, width: 1, height: 1 }, { x: 5, y: 2, width: 1, height: 1 }, { x: 4, y: 3, width: 2, height: 1 }]; exports.CELLS = CELLS; var SECTION_SIZE = 2; exports.SECTION_SIZE = SECTION_SIZE;dist/commonjs/Collection/SectionManager.jest.js000064400000005501151676725770015660 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _SectionManager = _interopRequireDefault(require("./SectionManager")); var _TestData = require("./TestData"); function initSectionManager() { var sectionManager = new _SectionManager["default"](_TestData.SECTION_SIZE); _TestData.CELLS.forEach(function (cellMetadatum, index) { sectionManager.registerCell({ cellMetadatum: cellMetadatum, index: index }); }); return sectionManager; } function verifySections(sectionManager, sizeAndPosition, expectedSizeAndPositionInfos) { var sections = sectionManager.getSections(sizeAndPosition); expect(sections.length).toEqual(expectedSizeAndPositionInfos.length); expectedSizeAndPositionInfos.forEach(function (sizeAndPosition) { var match = sections.find(function (section) { return section.x === sizeAndPosition.x && section.y === sizeAndPosition.y; }); expect(!!match).toEqual(true); }); } describe('SectionManager', function () { it('creates the appropriate number of Sections', function () { var sectionManager = initSectionManager(); expect(sectionManager.getTotalSectionCount()).toEqual(6); }); it('returns the proper Sections based on the specified area', function () { var sectionManager = initSectionManager(); verifySections(sectionManager, { x: 0, y: 0, width: 1, height: 1 }, [{ x: 0, y: 0 }]); verifySections(sectionManager, { x: 1, y: 1, width: 1, height: 1 }, [{ x: 0, y: 0 }]); verifySections(sectionManager, { x: 0, y: 0, width: 4, height: 4 }, [{ x: 0, y: 0 }, { x: 2, y: 0 }, { x: 0, y: 2 }, { x: 2, y: 2 }]); verifySections(sectionManager, { x: 4, y: 0, width: 2, height: 3 }, [{ x: 4, y: 0 }, { x: 4, y: 2 }]); }); it('assigns cells to the appropriate sections', function () { var sectionManager = initSectionManager(); expect(sectionManager.getCellIndices({ x: 0, y: 0, width: 2, height: 2 })).toEqual([0]); expect(sectionManager.getCellIndices({ x: 2, y: 0, width: 2, height: 2 })).toEqual([1, 2, 3]); expect(sectionManager.getCellIndices({ x: 4, y: 0, width: 2, height: 2 })).toEqual([6]); expect(sectionManager.getCellIndices({ x: 0, y: 2, width: 2, height: 2 })).toEqual([4]); expect(sectionManager.getCellIndices({ x: 2, y: 2, width: 2, height: 2 })).toEqual([3, 4, 5]); expect(sectionManager.getCellIndices({ x: 4, y: 2, width: 2, height: 2 })).toEqual([7, 8, 9]); }); });dist/commonjs/Collection/CollectionView.js000064400000061545151676725770014755 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _clsx = _interopRequireDefault(require("clsx")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _reactLifecyclesCompat = require("react-lifecycles-compat"); var _createCallbackMemoizer = _interopRequireDefault(require("../utils/createCallbackMemoizer")); var _scrollbarSize = _interopRequireDefault(require("dom-helpers/scrollbarSize")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } // @TODO Merge Collection and CollectionView /** * Specifies the number of milliseconds during which to disable pointer events while a scroll is in progress. * This improves performance and makes scrolling smoother. */ var IS_SCROLLING_TIMEOUT = 150; /** * Controls whether the Grid updates the DOM element's scrollLeft/scrollTop based on the current state or just observes it. * This prevents Grid from interrupting mouse-wheel animations (see issue #2). */ var SCROLL_POSITION_CHANGE_REASONS = { OBSERVED: 'observed', REQUESTED: 'requested' }; /** * Monitors changes in properties (eg. cellCount) and state (eg. scroll offsets) to determine when rendering needs to occur. * This component does not render any visible content itself; it defers to the specified :cellLayoutManager. */ var CollectionView = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(CollectionView, _React$PureComponent); // Invokes callbacks only when their values have changed. function CollectionView() { var _getPrototypeOf2; var _this; (0, _classCallCheck2["default"])(this, CollectionView); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(CollectionView)).call.apply(_getPrototypeOf2, [this].concat(args))); // If this component is being rendered server-side, getScrollbarSize() will return undefined. // We handle this case in componentDidMount() (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", { isScrolling: false, scrollLeft: 0, scrollTop: 0 }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_calculateSizeAndPositionDataOnNextUpdate", false); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onSectionRenderedMemoizer", (0, _createCallbackMemoizer["default"])()); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onScrollMemoizer", (0, _createCallbackMemoizer["default"])(false)); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_invokeOnSectionRenderedHelper", function () { var _this$props = _this.props, cellLayoutManager = _this$props.cellLayoutManager, onSectionRendered = _this$props.onSectionRendered; _this._onSectionRenderedMemoizer({ callback: onSectionRendered, indices: { indices: cellLayoutManager.getLastRenderedIndices() } }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_setScrollingContainerRef", function (ref) { _this._scrollingContainer = ref; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_updateScrollPositionForScrollToCell", function () { var _this$props2 = _this.props, cellLayoutManager = _this$props2.cellLayoutManager, height = _this$props2.height, scrollToAlignment = _this$props2.scrollToAlignment, scrollToCell = _this$props2.scrollToCell, width = _this$props2.width; var _this$state = _this.state, scrollLeft = _this$state.scrollLeft, scrollTop = _this$state.scrollTop; if (scrollToCell >= 0) { var scrollPosition = cellLayoutManager.getScrollPositionForCell({ align: scrollToAlignment, cellIndex: scrollToCell, height: height, scrollLeft: scrollLeft, scrollTop: scrollTop, width: width }); if (scrollPosition.scrollLeft !== scrollLeft || scrollPosition.scrollTop !== scrollTop) { _this._setScrollPosition(scrollPosition); } } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onScroll", function (event) { // In certain edge-cases React dispatches an onScroll event with an invalid target.scrollLeft / target.scrollTop. // This invalid event can be detected by comparing event.target to this component's scrollable DOM element. // See issue #404 for more information. if (event.target !== _this._scrollingContainer) { return; } // Prevent pointer events from interrupting a smooth scroll _this._enablePointerEventsAfterDelay(); // When this component is shrunk drastically, React dispatches a series of back-to-back scroll events, // Gradually converging on a scrollTop that is within the bounds of the new, smaller height. // This causes a series of rapid renders that is slow for long lists. // We can avoid that by doing some simple bounds checking to ensure that scrollTop never exceeds the total height. var _this$props3 = _this.props, cellLayoutManager = _this$props3.cellLayoutManager, height = _this$props3.height, isScrollingChange = _this$props3.isScrollingChange, width = _this$props3.width; var scrollbarSize = _this._scrollbarSize; var _cellLayoutManager$ge = cellLayoutManager.getTotalSize(), totalHeight = _cellLayoutManager$ge.height, totalWidth = _cellLayoutManager$ge.width; var scrollLeft = Math.max(0, Math.min(totalWidth - width + scrollbarSize, event.target.scrollLeft)); var scrollTop = Math.max(0, Math.min(totalHeight - height + scrollbarSize, event.target.scrollTop)); // Certain devices (like Apple touchpad) rapid-fire duplicate events. // Don't force a re-render if this is the case. // The mouse may move faster then the animation frame does. // Use requestAnimationFrame to avoid over-updating. if (_this.state.scrollLeft !== scrollLeft || _this.state.scrollTop !== scrollTop) { // Browsers with cancelable scroll events (eg. Firefox) interrupt scrolling animations if scrollTop/scrollLeft is set. // Other browsers (eg. Safari) don't scroll as well without the help under certain conditions (DOM or style changes during scrolling). // All things considered, this seems to be the best current work around that I'm aware of. // For more information see https://github.com/bvaughn/react-virtualized/pull/124 var scrollPositionChangeReason = event.cancelable ? SCROLL_POSITION_CHANGE_REASONS.OBSERVED : SCROLL_POSITION_CHANGE_REASONS.REQUESTED; // Synchronously set :isScrolling the first time (since _setNextState will reschedule its animation frame each time it's called) if (!_this.state.isScrolling) { isScrollingChange(true); } _this.setState({ isScrolling: true, scrollLeft: scrollLeft, scrollPositionChangeReason: scrollPositionChangeReason, scrollTop: scrollTop }); } _this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft, scrollTop: scrollTop, totalWidth: totalWidth, totalHeight: totalHeight }); }); _this._scrollbarSize = (0, _scrollbarSize["default"])(); if (_this._scrollbarSize === undefined) { _this._scrollbarSizeMeasured = false; _this._scrollbarSize = 0; } else { _this._scrollbarSizeMeasured = true; } return _this; } /** * Forced recompute of cell sizes and positions. * This function should be called if cell sizes have changed but nothing else has. * Since cell positions are calculated by callbacks, the collection view has no way of detecting when the underlying data has changed. */ (0, _createClass2["default"])(CollectionView, [{ key: "recomputeCellSizesAndPositions", value: function recomputeCellSizesAndPositions() { this._calculateSizeAndPositionDataOnNextUpdate = true; this.forceUpdate(); } /* ---------------------------- Component lifecycle methods ---------------------------- */ /** * @private * This method updates scrollLeft/scrollTop in state for the following conditions: * 1) Empty content (0 rows or columns) * 2) New scroll props overriding the current state * 3) Cells-count or cells-size has changed, making previous scroll offsets invalid */ }, { key: "componentDidMount", value: function componentDidMount() { var _this$props4 = this.props, cellLayoutManager = _this$props4.cellLayoutManager, scrollLeft = _this$props4.scrollLeft, scrollToCell = _this$props4.scrollToCell, scrollTop = _this$props4.scrollTop; // If this component was first rendered server-side, scrollbar size will be undefined. // In that event we need to remeasure. if (!this._scrollbarSizeMeasured) { this._scrollbarSize = (0, _scrollbarSize["default"])(); this._scrollbarSizeMeasured = true; this.setState({}); } if (scrollToCell >= 0) { this._updateScrollPositionForScrollToCell(); } else if (scrollLeft >= 0 || scrollTop >= 0) { this._setScrollPosition({ scrollLeft: scrollLeft, scrollTop: scrollTop }); } // Update onSectionRendered callback. this._invokeOnSectionRenderedHelper(); var _cellLayoutManager$ge2 = cellLayoutManager.getTotalSize(), totalHeight = _cellLayoutManager$ge2.height, totalWidth = _cellLayoutManager$ge2.width; // Initialize onScroll callback. this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft || 0, scrollTop: scrollTop || 0, totalHeight: totalHeight, totalWidth: totalWidth }); } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { var _this$props5 = this.props, height = _this$props5.height, scrollToAlignment = _this$props5.scrollToAlignment, scrollToCell = _this$props5.scrollToCell, width = _this$props5.width; var _this$state2 = this.state, scrollLeft = _this$state2.scrollLeft, scrollPositionChangeReason = _this$state2.scrollPositionChangeReason, scrollTop = _this$state2.scrollTop; // Make sure requested changes to :scrollLeft or :scrollTop get applied. // Assigning to scrollLeft/scrollTop tells the browser to interrupt any running scroll animations, // And to discard any pending async changes to the scroll position that may have happened in the meantime (e.g. on a separate scrolling thread). // So we only set these when we require an adjustment of the scroll position. // See issue #2 for more information. if (scrollPositionChangeReason === SCROLL_POSITION_CHANGE_REASONS.REQUESTED) { if (scrollLeft >= 0 && scrollLeft !== prevState.scrollLeft && scrollLeft !== this._scrollingContainer.scrollLeft) { this._scrollingContainer.scrollLeft = scrollLeft; } if (scrollTop >= 0 && scrollTop !== prevState.scrollTop && scrollTop !== this._scrollingContainer.scrollTop) { this._scrollingContainer.scrollTop = scrollTop; } } // Update scroll offsets if the current :scrollToCell values requires it if (height !== prevProps.height || scrollToAlignment !== prevProps.scrollToAlignment || scrollToCell !== prevProps.scrollToCell || width !== prevProps.width) { this._updateScrollPositionForScrollToCell(); } // Update onRowsRendered callback if start/stop indices have changed this._invokeOnSectionRenderedHelper(); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this._disablePointerEventsTimeoutId) { clearTimeout(this._disablePointerEventsTimeoutId); } } }, { key: "render", value: function render() { var _this$props6 = this.props, autoHeight = _this$props6.autoHeight, cellCount = _this$props6.cellCount, cellLayoutManager = _this$props6.cellLayoutManager, className = _this$props6.className, height = _this$props6.height, horizontalOverscanSize = _this$props6.horizontalOverscanSize, id = _this$props6.id, noContentRenderer = _this$props6.noContentRenderer, style = _this$props6.style, verticalOverscanSize = _this$props6.verticalOverscanSize, width = _this$props6.width; var _this$state3 = this.state, isScrolling = _this$state3.isScrolling, scrollLeft = _this$state3.scrollLeft, scrollTop = _this$state3.scrollTop; // Memoization reset if (this._lastRenderedCellCount !== cellCount || this._lastRenderedCellLayoutManager !== cellLayoutManager || this._calculateSizeAndPositionDataOnNextUpdate) { this._lastRenderedCellCount = cellCount; this._lastRenderedCellLayoutManager = cellLayoutManager; this._calculateSizeAndPositionDataOnNextUpdate = false; cellLayoutManager.calculateSizeAndPositionData(); } var _cellLayoutManager$ge3 = cellLayoutManager.getTotalSize(), totalHeight = _cellLayoutManager$ge3.height, totalWidth = _cellLayoutManager$ge3.width; // Safely expand the rendered area by the specified overscan amount var left = Math.max(0, scrollLeft - horizontalOverscanSize); var top = Math.max(0, scrollTop - verticalOverscanSize); var right = Math.min(totalWidth, scrollLeft + width + horizontalOverscanSize); var bottom = Math.min(totalHeight, scrollTop + height + verticalOverscanSize); var childrenToDisplay = height > 0 && width > 0 ? cellLayoutManager.cellRenderers({ height: bottom - top, isScrolling: isScrolling, width: right - left, x: left, y: top }) : []; var collectionStyle = { boxSizing: 'border-box', direction: 'ltr', height: autoHeight ? 'auto' : height, position: 'relative', WebkitOverflowScrolling: 'touch', width: width, willChange: 'transform' }; // Force browser to hide scrollbars when we know they aren't necessary. // Otherwise once scrollbars appear they may not disappear again. // For more info see issue #116 var verticalScrollBarSize = totalHeight > height ? this._scrollbarSize : 0; var horizontalScrollBarSize = totalWidth > width ? this._scrollbarSize : 0; // Also explicitly init styles to 'auto' if scrollbars are required. // This works around an obscure edge case where external CSS styles have not yet been loaded, // But an initial scroll index of offset is set as an external prop. // Without this style, Grid would render the correct range of cells but would NOT update its internal offset. // This was originally reported via clauderic/react-infinite-calendar/issues/23 collectionStyle.overflowX = totalWidth + verticalScrollBarSize <= width ? 'hidden' : 'auto'; collectionStyle.overflowY = totalHeight + horizontalScrollBarSize <= height ? 'hidden' : 'auto'; return React.createElement("div", { ref: this._setScrollingContainerRef, "aria-label": this.props['aria-label'], className: (0, _clsx["default"])('ReactVirtualized__Collection', className), id: id, onScroll: this._onScroll, role: "grid", style: _objectSpread({}, collectionStyle, {}, style), tabIndex: 0 }, cellCount > 0 && React.createElement("div", { className: "ReactVirtualized__Collection__innerScrollContainer", style: { height: totalHeight, maxHeight: totalHeight, maxWidth: totalWidth, overflow: 'hidden', pointerEvents: isScrolling ? 'none' : '', width: totalWidth } }, childrenToDisplay), cellCount === 0 && noContentRenderer()); } /* ---------------------------- Helper methods ---------------------------- */ /** * Sets an :isScrolling flag for a small window of time. * This flag is used to disable pointer events on the scrollable portion of the Collection. * This prevents jerky/stuttery mouse-wheel scrolling. */ }, { key: "_enablePointerEventsAfterDelay", value: function _enablePointerEventsAfterDelay() { var _this2 = this; if (this._disablePointerEventsTimeoutId) { clearTimeout(this._disablePointerEventsTimeoutId); } this._disablePointerEventsTimeoutId = setTimeout(function () { var isScrollingChange = _this2.props.isScrollingChange; isScrollingChange(false); _this2._disablePointerEventsTimeoutId = null; _this2.setState({ isScrolling: false }); }, IS_SCROLLING_TIMEOUT); } }, { key: "_invokeOnScrollMemoizer", value: function _invokeOnScrollMemoizer(_ref) { var _this3 = this; var scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, totalHeight = _ref.totalHeight, totalWidth = _ref.totalWidth; this._onScrollMemoizer({ callback: function callback(_ref2) { var scrollLeft = _ref2.scrollLeft, scrollTop = _ref2.scrollTop; var _this3$props = _this3.props, height = _this3$props.height, onScroll = _this3$props.onScroll, width = _this3$props.width; onScroll({ clientHeight: height, clientWidth: width, scrollHeight: totalHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: totalWidth }); }, indices: { scrollLeft: scrollLeft, scrollTop: scrollTop } }); } }, { key: "_setScrollPosition", value: function _setScrollPosition(_ref3) { var scrollLeft = _ref3.scrollLeft, scrollTop = _ref3.scrollTop; var newState = { scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS.REQUESTED }; if (scrollLeft >= 0) { newState.scrollLeft = scrollLeft; } if (scrollTop >= 0) { newState.scrollTop = scrollTop; } if (scrollLeft >= 0 && scrollLeft !== this.state.scrollLeft || scrollTop >= 0 && scrollTop !== this.state.scrollTop) { this.setState(newState); } } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps, prevState) { if (nextProps.cellCount === 0 && (prevState.scrollLeft !== 0 || prevState.scrollTop !== 0)) { return { scrollLeft: 0, scrollTop: 0, scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS.REQUESTED }; } else if (nextProps.scrollLeft !== prevState.scrollLeft || nextProps.scrollTop !== prevState.scrollTop) { return { scrollLeft: nextProps.scrollLeft != null ? nextProps.scrollLeft : prevState.scrollLeft, scrollTop: nextProps.scrollTop != null ? nextProps.scrollTop : prevState.scrollTop, scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS.REQUESTED }; } return null; } }]); return CollectionView; }(React.PureComponent); (0, _defineProperty2["default"])(CollectionView, "defaultProps", { 'aria-label': 'grid', horizontalOverscanSize: 0, noContentRenderer: function noContentRenderer() { return null; }, onScroll: function onScroll() { return null; }, onSectionRendered: function onSectionRendered() { return null; }, scrollToAlignment: 'auto', scrollToCell: -1, style: {}, verticalOverscanSize: 0 }); CollectionView.propTypes = process.env.NODE_ENV !== "production" ? { 'aria-label': _propTypes["default"].string, /** * Removes fixed height from the scrollingContainer so that the total height * of rows can stretch the window. Intended for use with WindowScroller */ autoHeight: _propTypes["default"].bool, /** * Number of cells in collection. */ cellCount: _propTypes["default"].number.isRequired, /** * Calculates cell sizes and positions and manages rendering the appropriate cells given a specified window. */ cellLayoutManager: _propTypes["default"].object.isRequired, /** * Optional custom CSS class name to attach to root Collection element. */ className: _propTypes["default"].string, /** * Height of Collection; this property determines the number of visible (vs virtualized) rows. */ height: _propTypes["default"].number.isRequired, /** * Optional custom id to attach to root Collection element. */ id: _propTypes["default"].string, /** * Enables the `Collection` to horiontally "overscan" its content similar to how `Grid` does. * This can reduce flicker around the edges when a user scrolls quickly. */ horizontalOverscanSize: _propTypes["default"].number.isRequired, isScrollingChange: _propTypes["default"].func, /** * Optional renderer to be used in place of rows when either :rowCount or :cellCount is 0. */ noContentRenderer: _propTypes["default"].func.isRequired, /** * Callback invoked whenever the scroll offset changes within the inner scrollable region. * This callback can be used to sync scrolling between lists, tables, or grids. * ({ clientHeight, clientWidth, scrollHeight, scrollLeft, scrollTop, scrollWidth }): void */ onScroll: _propTypes["default"].func.isRequired, /** * Callback invoked with information about the section of the Collection that was just rendered. * This callback is passed a named :indices parameter which is an Array of the most recently rendered section indices. */ onSectionRendered: _propTypes["default"].func.isRequired, /** * Horizontal offset. */ scrollLeft: _propTypes["default"].number, /** * Controls scroll-to-cell behavior of the Grid. * The default ("auto") scrolls the least amount possible to ensure that the specified cell is fully visible. * Use "start" to align cells to the top/left of the Grid and "end" to align bottom/right. */ scrollToAlignment: _propTypes["default"].oneOf(['auto', 'end', 'start', 'center']).isRequired, /** * Cell index to ensure visible (by forcefully scrolling if necessary). */ scrollToCell: _propTypes["default"].number.isRequired, /** * Vertical offset. */ scrollTop: _propTypes["default"].number, /** * Optional custom inline style to attach to root Collection element. */ style: _propTypes["default"].object, /** * Enables the `Collection` to vertically "overscan" its content similar to how `Grid` does. * This can reduce flicker around the edges when a user scrolls quickly. */ verticalOverscanSize: _propTypes["default"].number.isRequired, /** * Width of Collection; this property determines the number of visible (vs virtualized) columns. */ width: _propTypes["default"].number.isRequired } : {}; (0, _reactLifecyclesCompat.polyfill)(CollectionView); var _default = CollectionView; exports["default"] = _default;dist/commonjs/Collection/Collection.jest.js000064400000075472151676725770015072 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _scrollbarSize = _interopRequireDefault(require("dom-helpers/scrollbarSize")); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _testUtils = require("react-dom/test-utils"); var _TestUtils = require("../TestUtils"); var _Collection = _interopRequireDefault(require("./Collection")); var _TestData = require("./TestData"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } describe('Collection', function () { function defaultCellRenderer(_ref) { var index = _ref.index, key = _ref.key, style = _ref.style; return React.createElement("div", { className: "cell", key: key, style: style }, "cell:", index); } function getMarkup() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var _props$cellCount = props.cellCount, cellCount = _props$cellCount === void 0 ? _TestData.CELLS.length : _props$cellCount; function defaultCellSizeAndPositionGetter(_ref2) { var index = _ref2.index; index %= cellCount; return _TestData.CELLS[index]; } return React.createElement(_Collection["default"], (0, _extends2["default"])({ cellCount: cellCount, cellRenderer: defaultCellRenderer, cellSizeAndPositionGetter: defaultCellSizeAndPositionGetter, height: _TestData.SECTION_SIZE, sectionSize: _TestData.SECTION_SIZE, width: _TestData.SECTION_SIZE * 2 }, props)); } function simulateScroll(_ref3) { var collection = _ref3.collection, _ref3$scrollLeft = _ref3.scrollLeft, scrollLeft = _ref3$scrollLeft === void 0 ? 0 : _ref3$scrollLeft, _ref3$scrollTop = _ref3.scrollTop, scrollTop = _ref3$scrollTop === void 0 ? 0 : _ref3$scrollTop; var target = { scrollLeft: scrollLeft, scrollTop: scrollTop }; collection._collectionView._scrollingContainer = target; // HACK to work around _onScroll target check _testUtils.Simulate.scroll((0, _reactDom.findDOMNode)(collection), { target: target }); } function compareArrays(array1, array2) { expect(array1.length).toEqual(array2.length); array2.forEach(function (value) { expect(array1).toContain(value); }); } describe('number of rendered children', function () { it('should render enough children to fill the available area', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.querySelectorAll('.cell').length).toEqual(4); }); it('should not render more cells than available if the area is not filled', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellCount: 2 }))); expect(rendered.querySelectorAll('.cell').length).toEqual(2); }); // Small performance tweak added in 5.5.6 it('should not render/parent cells that are null or false', function () { function cellRenderer(_ref4) { var index = _ref4.index, key = _ref4.key, style = _ref4.style; if (index > 2) { return null; } else { return React.createElement("div", { className: "cell", key: key, style: style }, index); } } var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer }))); expect(rendered.querySelectorAll('.cell').length).toEqual(3); }); }); describe('shows and hides scrollbars based on rendered content', function () { var scrollbarSize; beforeAll(function () { scrollbarSize = (0, _scrollbarSize["default"])(); }); it('should set overflowX:hidden if columns fit within the available width and y-axis has no scrollbar', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 4, width: 6 }))); expect(rendered.style.overflowX).toEqual('hidden'); }); it('should set overflowX:hidden if columns and y-axis scrollbar fit within the available width', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 1, width: 6 + scrollbarSize }))); expect(rendered.style.overflowX).toEqual('hidden'); }); it('should leave overflowX:auto if columns require more than the available width', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ width: 1 }))); expect(rendered.style.overflowX).not.toEqual('hidden'); }); it('should leave overflowX:auto if columns and y-axis scrollbar require more than the available width', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 1, width: 6 + scrollbarSize - 1 }))); expect(rendered.style.overflowX).not.toEqual('hidden'); }); it('should set overflowY:hidden if rows fit within the available width and xaxis has no scrollbar', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 4, width: 6 }))); expect(rendered.style.overflowY).toEqual('hidden'); }); it('should set overflowY:hidden if rows and x-axis scrollbar fit within the available width', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 4 + scrollbarSize, width: 1 }))); expect(rendered.style.overflowY).toEqual('hidden'); }); it('should leave overflowY:auto if rows require more than the available height', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 1 }))); expect(rendered.style.overflowY).not.toEqual('hidden'); }); it('should leave overflowY:auto if rows and y-axis scrollbar require more than the available height', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 4 + scrollbarSize - 1, width: 1 }))); expect(rendered.style.overflowY).not.toEqual('hidden'); }); it('should accept styles that overwrite calculated ones', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 1, style: { overflowX: 'auto', overflowY: 'auto' }, width: 1 }))); expect(rendered.style.overflowX).toEqual('auto'); expect(rendered.style.overflowY).toEqual('auto'); }); }); describe('autoHeight', function () { it('should set the container height to auto to adjust to innerScrollContainer height', function () { var props = { autoHeight: true }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props))); expect(rendered.style.height).toEqual('auto'); }); it('should have container height still affecting number of rows rendered', function () { var indices; var props = { autoHeight: true, height: 500, onSectionRendered: function onSectionRendered(params) { indices = params.indices; } }; (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props))); compareArrays(indices, [0, 1, 2, 3, 4, 5]); }); it('should have innerScrollContainer height to be equal number of rows * rowHeight', function () { var props = { autoHeight: true }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props))); expect(rendered.querySelector('.ReactVirtualized__Collection__innerScrollContainer').style.height).toEqual('4px'); }); }); describe(':scrollToCell', function () { it('should scroll to the top/left', function () { var collection = (0, _TestUtils.render)(getMarkup({ scrollToCell: 0 })); expect(collection._collectionView.state.scrollLeft).toEqual(0); expect(collection._collectionView.state.scrollTop).toEqual(0); }); it('should scroll over to the middle', function () { var collection = (0, _TestUtils.render)(getMarkup({ scrollToCell: 7 })); expect(collection._collectionView.state.scrollLeft).toEqual(1); expect(collection._collectionView.state.scrollTop).toEqual(1); }); it('should scroll to the bottom/right', function () { var collection = (0, _TestUtils.render)(getMarkup({ scrollToCell: 9 })); expect(collection._collectionView.state.scrollLeft).toEqual(2); expect(collection._collectionView.state.scrollTop).toEqual(2); }); it('should honor the specified :scrollToAlignment', function () { var collection = (0, _TestUtils.render)(getMarkup({ scrollToAlignment: 'start', scrollToCell: 2, width: _TestData.SECTION_SIZE })); // Minimum amount of scrolling ("auto") would be 0,0 expect(collection._collectionView.state.scrollLeft).toEqual(2); expect(collection._collectionView.state.scrollTop).toEqual(1); collection = (0, _TestUtils.render)(getMarkup({ scrollToAlignment: 'end', scrollToCell: 2, width: _TestData.SECTION_SIZE })); // This cell would already by visible by "auto" rules expect(collection._collectionView.state.scrollLeft).toEqual(1); expect(collection._collectionView.state.scrollTop).toEqual(0); collection = (0, _TestUtils.render)(getMarkup({ scrollToAlignment: 'center', scrollToCell: 4, width: _TestData.SECTION_SIZE })); // This cell doesn't fit entirely in the viewport but we center it anyway. expect(collection._collectionView.state.scrollLeft).toEqual(0.5); expect(collection._collectionView.state.scrollTop).toEqual(2); }); it('should scroll to a cell just added', function () { var collection = (0, _TestUtils.render)(getMarkup({ cellCount: 4 })); expect(collection._collectionView.state.scrollLeft).toEqual(0); expect(collection._collectionView.state.scrollTop).toEqual(0); collection = (0, _TestUtils.render)(getMarkup({ cellCount: 8, scrollToCell: 7 })); expect(collection._collectionView.state.scrollLeft).toEqual(1); expect(collection._collectionView.state.scrollTop).toEqual(1); }); }); describe('property updates', function () { it('should update :scrollToCell position when :width changes', function () { var collection = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToCell: 3 }))); expect(collection.textContent).toContain('cell:3'); // Making the collection narrower leaves only room for 1 item collection = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToCell: 3, width: 1 }))); expect(collection.textContent).toContain('cell:3'); }); it('should update :scrollToCell position when :height changes', function () { var collection = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToCell: 4 }))); expect(collection.textContent).toContain('cell:4'); // Making the collection shorter leaves only room for 1 item collection = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToCell: 4, height: 1 }))); expect(collection.textContent).toContain('cell:4'); }); it('should update scroll position when :scrollToCell changes', function () { var collection = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(collection.textContent).not.toContain('cell:9'); collection = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToCell: 9 }))); expect(collection.textContent).toContain('cell:9'); }); }); describe('noContentRenderer', function () { it('should call :noContentRenderer if :cellCount is 0', function () { var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ noContentRenderer: function noContentRenderer() { return React.createElement("div", null, "No data"); }, cellCount: 0 }))); expect(list.textContent).toEqual('No data'); }); it('should render an empty body if :cellCount is 0 and there is no :noContentRenderer', function () { var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellCount: 0 }))); expect(list.textContent).toEqual(''); }); it('should not show the :noContentRenderer when there are children, even if no children are currently visible (sparse)', function () { var offscreenSizeAndPosition = { x: _TestData.SECTION_SIZE * 3, y: _TestData.SECTION_SIZE * 3, width: 1, height: 1 }; function cellSizeAndPositionGetter() { return offscreenSizeAndPosition; } var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellCount: 1, cellSizeAndPositionGetter: cellSizeAndPositionGetter, noContentRenderer: function noContentRenderer() { return React.createElement("div", null, "No data"); } }))); expect(list.textContent).not.toEqual('No data'); }); }); describe('onSectionRendered', function () { it('should call :onSectionRendered if at least one cell is rendered', function () { var indices; (0, _TestUtils.render)(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; } })); compareArrays(indices, [0, 1, 2, 3]); }); it('should not call :onSectionRendered unless the rendered indices have changed', function () { var numCalls = 0; var indices; var onSectionRendered = function onSectionRendered(params) { indices = params.indices; numCalls++; }; (0, _TestUtils.render)(getMarkup({ onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(1); compareArrays(indices, [0, 1, 2, 3]); (0, _TestUtils.render)(getMarkup({ onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(1); compareArrays(indices, [0, 1, 2, 3]); }); it('should call :onSectionRendered if the rendered indices have changed', function () { var numCalls = 0; var indices; var onSectionRendered = function onSectionRendered(params) { indices = params.indices; numCalls++; }; (0, _TestUtils.render)(getMarkup({ onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(1); compareArrays(indices, [0, 1, 2, 3]); (0, _TestUtils.render)(getMarkup({ height: _TestData.SECTION_SIZE * 2, onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(2); compareArrays(indices, [0, 1, 2, 3, 4, 5]); (0, _TestUtils.render)(getMarkup({ height: _TestData.SECTION_SIZE * 2, onSectionRendered: onSectionRendered, width: _TestData.SECTION_SIZE })); expect(numCalls).toEqual(3); expect(indices).toEqual([0, 4]); }); it('should not call :onSectionRendered if no cells are rendered', function () { var numCalls = 0; (0, _TestUtils.render)(getMarkup({ height: 0, onSectionRendered: function onSectionRendered() { return numCalls++; } })); expect(numCalls).toEqual(0); }); }); describe(':scrollLeft and :scrollTop properties', function () { it('should render correctly when an initial :scrollLeft and :scrollTop properties are specified', function () { var indices; var collection = (0, _TestUtils.render)(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; }, scrollLeft: 2, scrollTop: 2 })); compareArrays(indices, [3, 4, 5, 7, 8, 9]); expect(collection._collectionView.state.scrollPositionChangeReason).toEqual('requested'); }); it('should render correctly when :scrollLeft and :scrollTop properties are updated', function () { var indices; (0, _TestUtils.render)(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; } })); compareArrays(indices, [0, 1, 2, 3]); var collection = (0, _TestUtils.render)(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; }, scrollLeft: 2, scrollTop: 2 })); compareArrays(indices, [3, 4, 5, 7, 8, 9]); expect(collection._collectionView.state.scrollPositionChangeReason).toEqual('requested'); }); }); describe('styles, classNames, and ids', function () { it('should use the expected global CSS classNames', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.className).toEqual('ReactVirtualized__Collection'); }); it('should use a custom :className if specified', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ className: 'foo' }))); expect(rendered.className).toContain('foo'); }); it('should use a custom :id if specified', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ id: 'bar' }))); expect(rendered.getAttribute('id')).toEqual('bar'); }); it('should use a custom :style if specified', function () { var style = { backgroundColor: 'red' }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ style: style }))); expect(rendered.style.backgroundColor).toEqual('red'); }); }); describe('onScroll', function () { it('should trigger callback when component is mounted', function () { var onScrollCalls = []; (0, _TestUtils.render)(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); }, scrollLeft: 2, scrollTop: 1 })); expect(onScrollCalls).toEqual([{ clientHeight: _TestData.SECTION_SIZE, clientWidth: _TestData.SECTION_SIZE * 2, scrollHeight: 4, scrollLeft: 2, scrollTop: 1, scrollWidth: 6 }]); }); it('should trigger callback when component scrolls horizontally', function () { var onScrollCalls = []; var collection = (0, _TestUtils.render)(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); simulateScroll({ collection: collection, scrollLeft: 1, scrollTop: 0 }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: _TestData.SECTION_SIZE, clientWidth: _TestData.SECTION_SIZE * 2, scrollHeight: 4, scrollLeft: 1, scrollTop: 0, scrollWidth: 6 }); }); it('should trigger callback when component scrolls vertically', function () { var onScrollCalls = []; var collection = (0, _TestUtils.render)(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); simulateScroll({ collection: collection, scrollLeft: 0, scrollTop: 2 }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: _TestData.SECTION_SIZE, clientWidth: _TestData.SECTION_SIZE * 2, scrollHeight: 4, scrollLeft: 0, scrollTop: 2, scrollWidth: 6 }); }); it('should not allow negative scroll values', function () { var onScrollCalls = []; var collection = (0, _TestUtils.render)(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); simulateScroll({ collection: collection, scrollLeft: -1, scrollTop: -1 }); expect(onScrollCalls.length).toEqual(1); expect(onScrollCalls[0].scrollLeft).toEqual(0); expect(onScrollCalls[0].scrollTop).toEqual(0); }); }); describe('cellGroupRenderer', function () { it('should use a custom :cellGroupRenderer if specified', function () { var cellGroupRendererCalled = 0; var cellGroupRendererParams; var cellRenderer = function cellRenderer(_ref5) { var index = _ref5.index, key = _ref5.key, style = _ref5.style; return React.createElement("div", { key: key, style: style }, index); }; (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer, cellGroupRenderer: function cellGroupRenderer(params) { cellGroupRendererParams = params; cellGroupRendererCalled++; return [React.createElement("div", { key: "0" }, "Fake content")]; } }))); expect(cellGroupRendererCalled).toEqual(1); expect(cellGroupRendererParams.cellRenderer).toEqual(cellRenderer); expect((0, _typeof2["default"])(cellGroupRendererParams.cellSizeAndPositionGetter)).toEqual('function'); compareArrays(cellGroupRendererParams.indices, [0, 1, 2, 3]); }); }); it('should pass the cellRenderer an :isScrolling flag when scrolling is in progress', function _callee(done) { var cellRendererCalls, cellRenderer, collection; return _regenerator["default"].async(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: cellRenderer = function _ref7(_ref6) { var index = _ref6.index, isScrolling = _ref6.isScrolling, key = _ref6.key, style = _ref6.style; cellRendererCalls.push(isScrolling); return defaultCellRenderer({ index: index, key: key, style: style }); }; cellRendererCalls = []; collection = (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer })); expect(cellRendererCalls[0]).toEqual(false); cellRendererCalls.splice(0); simulateScroll({ collection: collection, scrollTop: 1 }); // Give React time to process the queued setState() _context.next = 8; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, 1); })); case 8: expect(cellRendererCalls[0]).toEqual(true); done(); case 10: case "end": return _context.stop(); } } }); }); describe('horizontalOverscanSize and verticalOverscanSize', function () { it('should include the horizontal and vertical overscan size when rendering cells', function () { var indices; (0, _TestUtils.render)(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; }, height: 1, horizontalOverscanSize: 2, sectionSize: 1, scrollLeft: 2, scrollTop: 2, width: 1, verticalOverscanSize: 1 })); compareArrays(indices, [0, 2, 3, 4, 5, 6, 7, 9]); }); it('should not exceed the top/left borders regardless of overscan size', function () { var indices; (0, _TestUtils.render)(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; }, height: 2, horizontalOverscanSize: 1, sectionSize: 1, scrollLeft: 0, scrollTop: 0, width: 1, verticalOverscanSize: 2 })); compareArrays(indices, [0, 4]); }); it('should not exceed the bottom/right borders regardless of overscan size', function () { var indices; (0, _TestUtils.render)(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; }, height: 2, horizontalOverscanSize: 1, sectionSize: 1, scrollLeft: 5, scrollTop: 2, width: 1, verticalOverscanSize: 2 })); compareArrays(indices, [6, 7, 8, 9]); }); }); describe('cell caching', function () { it('should not cache cells if the Grid is not scrolling', function () { var cellRendererCalls = []; function cellRenderer(_ref8) { var isScrolling = _ref8.isScrolling, index = _ref8.index, key = _ref8.key, style = _ref8.style; cellRendererCalls.push({ isScrolling: isScrolling, index: index }); return defaultCellRenderer({ index: index, key: key, style: style }); } var props = { cellRenderer: cellRenderer, scrollLeft: 0, scrollTop: 0 }; (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props))); expect(cellRendererCalls.length).toEqual(4); cellRendererCalls.forEach(function (call) { return expect(call.isScrolling).toEqual(false); }); cellRendererCalls.splice(0); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { foo: 'bar' // Force re-render }))); expect(cellRendererCalls.length).toEqual(4); cellRendererCalls.forEach(function (call) { return expect(call.isScrolling).toEqual(false); }); }); it.skip('should cache a cell once it has been rendered while scrolling', function () { var cellRendererCalls = []; function cellRenderer(_ref9) { var isScrolling = _ref9.isScrolling, index = _ref9.index, key = _ref9.key, style = _ref9.style; cellRendererCalls.push({ isScrolling: isScrolling, index: index }); return defaultCellRenderer({ index: index, key: key, style: style }); } var props = { cellRenderer: cellRenderer, scrollLeft: 0, scrollTop: 0 }; var collection = (0, _TestUtils.render)(getMarkup(props)); expect(cellRendererCalls.length).toEqual(4); cellRendererCalls.forEach(function (call) { return expect(call.isScrolling).toEqual(false); }); // FIXME: simulate scroll is not triggering cells to render in cache // Scroll a little bit; newly-rendered cells will be cached. simulateScroll({ collection: collection, scrollTop: 2 }); cellRendererCalls.splice(0); // At this point cells 4 and 5 have been rendered, // But cells 7, 8, and 9 have not. (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { scrollLeft: 1, scrollTop: 3 }))); expect(cellRendererCalls.length).toEqual(3); cellRendererCalls.forEach(function (call) { return expect(call.isScrolling).toEqual(true); }); }); it('should clear cache once :isScrolling is false', function _callee2(done) { var cellRendererCalls, cellRenderer, props, collection; return _regenerator["default"].async(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: cellRenderer = function _ref11(_ref10) { var isScrolling = _ref10.isScrolling, index = _ref10.index, key = _ref10.key, style = _ref10.style; cellRendererCalls.push({ isScrolling: isScrolling, index: index }); return defaultCellRenderer({ isScrolling: isScrolling, index: index, key: key, style: style }); }; cellRendererCalls = []; props = { cellRenderer: cellRenderer, scrollLeft: 0, scrollTop: 0 }; collection = (0, _TestUtils.render)(getMarkup(props)); simulateScroll({ collection: collection, scrollTop: 1 }); // Allow scrolling timeout to complete so that cell cache is reset _context2.next = 7; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, 500); })); case 7: cellRendererCalls.splice(0); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { scrollTop: 1 }))); expect(cellRendererCalls.length).not.toEqual(0); done(); case 11: case "end": return _context2.stop(); } } }); }); }); // See issue #568 for more it('forceUpdate will also forceUpdate the inner CollectionView', function () { var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (_ref12) { var key = _ref12.key; return React.createElement("div", { key: key }); }); var rendered = (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer })); expect(cellRenderer).toHaveBeenCalled(); cellRenderer.mockReset(); rendered.forceUpdate(); expect(cellRenderer).toHaveBeenCalled(); }); });dist/commonjs/MultiGrid/MultiGrid.js000064400000100542151676725770013523 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _reactLifecyclesCompat = require("react-lifecycles-compat"); var _CellMeasurerCacheDecorator = _interopRequireDefault(require("./CellMeasurerCacheDecorator")); var _Grid = _interopRequireDefault(require("../Grid")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var SCROLLBAR_SIZE_BUFFER = 20; /** * Renders 1, 2, or 4 Grids depending on configuration. * A main (body) Grid will always be rendered. * Optionally, 1-2 Grids for sticky header rows will also be rendered. * If no sticky columns, only 1 sticky header Grid will be rendered. * If sticky columns, 2 sticky header Grids will be rendered. */ var MultiGrid = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(MultiGrid, _React$PureComponent); function MultiGrid(props, context) { var _this; (0, _classCallCheck2["default"])(this, MultiGrid); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(MultiGrid).call(this, props, context)); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", { scrollLeft: 0, scrollTop: 0, scrollbarSize: 0, showHorizontalScrollbar: false, showVerticalScrollbar: false }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_deferredInvalidateColumnIndex", null); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_deferredInvalidateRowIndex", null); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_bottomLeftGridRef", function (ref) { _this._bottomLeftGrid = ref; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_bottomRightGridRef", function (ref) { _this._bottomRightGrid = ref; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_cellRendererBottomLeftGrid", function (_ref) { var rowIndex = _ref.rowIndex, rest = (0, _objectWithoutProperties2["default"])(_ref, ["rowIndex"]); var _this$props = _this.props, cellRenderer = _this$props.cellRenderer, fixedRowCount = _this$props.fixedRowCount, rowCount = _this$props.rowCount; if (rowIndex === rowCount - fixedRowCount) { return React.createElement("div", { key: rest.key, style: _objectSpread({}, rest.style, { height: SCROLLBAR_SIZE_BUFFER }) }); } else { return cellRenderer(_objectSpread({}, rest, { parent: (0, _assertThisInitialized2["default"])(_this), rowIndex: rowIndex + fixedRowCount })); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_cellRendererBottomRightGrid", function (_ref2) { var columnIndex = _ref2.columnIndex, rowIndex = _ref2.rowIndex, rest = (0, _objectWithoutProperties2["default"])(_ref2, ["columnIndex", "rowIndex"]); var _this$props2 = _this.props, cellRenderer = _this$props2.cellRenderer, fixedColumnCount = _this$props2.fixedColumnCount, fixedRowCount = _this$props2.fixedRowCount; return cellRenderer(_objectSpread({}, rest, { columnIndex: columnIndex + fixedColumnCount, parent: (0, _assertThisInitialized2["default"])(_this), rowIndex: rowIndex + fixedRowCount })); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_cellRendererTopRightGrid", function (_ref3) { var columnIndex = _ref3.columnIndex, rest = (0, _objectWithoutProperties2["default"])(_ref3, ["columnIndex"]); var _this$props3 = _this.props, cellRenderer = _this$props3.cellRenderer, columnCount = _this$props3.columnCount, fixedColumnCount = _this$props3.fixedColumnCount; if (columnIndex === columnCount - fixedColumnCount) { return React.createElement("div", { key: rest.key, style: _objectSpread({}, rest.style, { width: SCROLLBAR_SIZE_BUFFER }) }); } else { return cellRenderer(_objectSpread({}, rest, { columnIndex: columnIndex + fixedColumnCount, parent: (0, _assertThisInitialized2["default"])(_this) })); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_columnWidthRightGrid", function (_ref4) { var index = _ref4.index; var _this$props4 = _this.props, columnCount = _this$props4.columnCount, fixedColumnCount = _this$props4.fixedColumnCount, columnWidth = _this$props4.columnWidth; var _this$state = _this.state, scrollbarSize = _this$state.scrollbarSize, showHorizontalScrollbar = _this$state.showHorizontalScrollbar; // An extra cell is added to the count // This gives the smaller Grid extra room for offset, // In case the main (bottom right) Grid has a scrollbar // If no scrollbar, the extra space is overflow:hidden anyway if (showHorizontalScrollbar && index === columnCount - fixedColumnCount) { return scrollbarSize; } return typeof columnWidth === 'function' ? columnWidth({ index: index + fixedColumnCount }) : columnWidth; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onScroll", function (scrollInfo) { var scrollLeft = scrollInfo.scrollLeft, scrollTop = scrollInfo.scrollTop; _this.setState({ scrollLeft: scrollLeft, scrollTop: scrollTop }); var onScroll = _this.props.onScroll; if (onScroll) { onScroll(scrollInfo); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onScrollbarPresenceChange", function (_ref5) { var horizontal = _ref5.horizontal, size = _ref5.size, vertical = _ref5.vertical; var _this$state2 = _this.state, showHorizontalScrollbar = _this$state2.showHorizontalScrollbar, showVerticalScrollbar = _this$state2.showVerticalScrollbar; if (horizontal !== showHorizontalScrollbar || vertical !== showVerticalScrollbar) { _this.setState({ scrollbarSize: size, showHorizontalScrollbar: horizontal, showVerticalScrollbar: vertical }); var onScrollbarPresenceChange = _this.props.onScrollbarPresenceChange; if (typeof onScrollbarPresenceChange === 'function') { onScrollbarPresenceChange({ horizontal: horizontal, size: size, vertical: vertical }); } } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onScrollLeft", function (scrollInfo) { var scrollLeft = scrollInfo.scrollLeft; _this._onScroll({ scrollLeft: scrollLeft, scrollTop: _this.state.scrollTop }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onScrollTop", function (scrollInfo) { var scrollTop = scrollInfo.scrollTop; _this._onScroll({ scrollTop: scrollTop, scrollLeft: _this.state.scrollLeft }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rowHeightBottomGrid", function (_ref6) { var index = _ref6.index; var _this$props5 = _this.props, fixedRowCount = _this$props5.fixedRowCount, rowCount = _this$props5.rowCount, rowHeight = _this$props5.rowHeight; var _this$state3 = _this.state, scrollbarSize = _this$state3.scrollbarSize, showVerticalScrollbar = _this$state3.showVerticalScrollbar; // An extra cell is added to the count // This gives the smaller Grid extra room for offset, // In case the main (bottom right) Grid has a scrollbar // If no scrollbar, the extra space is overflow:hidden anyway if (showVerticalScrollbar && index === rowCount - fixedRowCount) { return scrollbarSize; } return typeof rowHeight === 'function' ? rowHeight({ index: index + fixedRowCount }) : rowHeight; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_topLeftGridRef", function (ref) { _this._topLeftGrid = ref; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_topRightGridRef", function (ref) { _this._topRightGrid = ref; }); var deferredMeasurementCache = props.deferredMeasurementCache, _fixedColumnCount = props.fixedColumnCount, _fixedRowCount = props.fixedRowCount; _this._maybeCalculateCachedStyles(true); if (deferredMeasurementCache) { _this._deferredMeasurementCacheBottomLeftGrid = _fixedRowCount > 0 ? new _CellMeasurerCacheDecorator["default"]({ cellMeasurerCache: deferredMeasurementCache, columnIndexOffset: 0, rowIndexOffset: _fixedRowCount }) : deferredMeasurementCache; _this._deferredMeasurementCacheBottomRightGrid = _fixedColumnCount > 0 || _fixedRowCount > 0 ? new _CellMeasurerCacheDecorator["default"]({ cellMeasurerCache: deferredMeasurementCache, columnIndexOffset: _fixedColumnCount, rowIndexOffset: _fixedRowCount }) : deferredMeasurementCache; _this._deferredMeasurementCacheTopRightGrid = _fixedColumnCount > 0 ? new _CellMeasurerCacheDecorator["default"]({ cellMeasurerCache: deferredMeasurementCache, columnIndexOffset: _fixedColumnCount, rowIndexOffset: 0 }) : deferredMeasurementCache; } return _this; } (0, _createClass2["default"])(MultiGrid, [{ key: "forceUpdateGrids", value: function forceUpdateGrids() { this._bottomLeftGrid && this._bottomLeftGrid.forceUpdate(); this._bottomRightGrid && this._bottomRightGrid.forceUpdate(); this._topLeftGrid && this._topLeftGrid.forceUpdate(); this._topRightGrid && this._topRightGrid.forceUpdate(); } /** See Grid#invalidateCellSizeAfterRender */ }, { key: "invalidateCellSizeAfterRender", value: function invalidateCellSizeAfterRender() { var _ref7 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref7$columnIndex = _ref7.columnIndex, columnIndex = _ref7$columnIndex === void 0 ? 0 : _ref7$columnIndex, _ref7$rowIndex = _ref7.rowIndex, rowIndex = _ref7$rowIndex === void 0 ? 0 : _ref7$rowIndex; this._deferredInvalidateColumnIndex = typeof this._deferredInvalidateColumnIndex === 'number' ? Math.min(this._deferredInvalidateColumnIndex, columnIndex) : columnIndex; this._deferredInvalidateRowIndex = typeof this._deferredInvalidateRowIndex === 'number' ? Math.min(this._deferredInvalidateRowIndex, rowIndex) : rowIndex; } /** See Grid#measureAllCells */ }, { key: "measureAllCells", value: function measureAllCells() { this._bottomLeftGrid && this._bottomLeftGrid.measureAllCells(); this._bottomRightGrid && this._bottomRightGrid.measureAllCells(); this._topLeftGrid && this._topLeftGrid.measureAllCells(); this._topRightGrid && this._topRightGrid.measureAllCells(); } /** See Grid#recomputeGridSize */ }, { key: "recomputeGridSize", value: function recomputeGridSize() { var _ref8 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref8$columnIndex = _ref8.columnIndex, columnIndex = _ref8$columnIndex === void 0 ? 0 : _ref8$columnIndex, _ref8$rowIndex = _ref8.rowIndex, rowIndex = _ref8$rowIndex === void 0 ? 0 : _ref8$rowIndex; var _this$props6 = this.props, fixedColumnCount = _this$props6.fixedColumnCount, fixedRowCount = _this$props6.fixedRowCount; var adjustedColumnIndex = Math.max(0, columnIndex - fixedColumnCount); var adjustedRowIndex = Math.max(0, rowIndex - fixedRowCount); this._bottomLeftGrid && this._bottomLeftGrid.recomputeGridSize({ columnIndex: columnIndex, rowIndex: adjustedRowIndex }); this._bottomRightGrid && this._bottomRightGrid.recomputeGridSize({ columnIndex: adjustedColumnIndex, rowIndex: adjustedRowIndex }); this._topLeftGrid && this._topLeftGrid.recomputeGridSize({ columnIndex: columnIndex, rowIndex: rowIndex }); this._topRightGrid && this._topRightGrid.recomputeGridSize({ columnIndex: adjustedColumnIndex, rowIndex: rowIndex }); this._leftGridWidth = null; this._topGridHeight = null; this._maybeCalculateCachedStyles(true); } }, { key: "componentDidMount", value: function componentDidMount() { var _this$props7 = this.props, scrollLeft = _this$props7.scrollLeft, scrollTop = _this$props7.scrollTop; if (scrollLeft > 0 || scrollTop > 0) { var newState = {}; if (scrollLeft > 0) { newState.scrollLeft = scrollLeft; } if (scrollTop > 0) { newState.scrollTop = scrollTop; } this.setState(newState); } this._handleInvalidatedGridSize(); } }, { key: "componentDidUpdate", value: function componentDidUpdate() { this._handleInvalidatedGridSize(); } }, { key: "render", value: function render() { var _this$props8 = this.props, onScroll = _this$props8.onScroll, onSectionRendered = _this$props8.onSectionRendered, onScrollbarPresenceChange = _this$props8.onScrollbarPresenceChange, scrollLeftProp = _this$props8.scrollLeft, scrollToColumn = _this$props8.scrollToColumn, scrollTopProp = _this$props8.scrollTop, scrollToRow = _this$props8.scrollToRow, rest = (0, _objectWithoutProperties2["default"])(_this$props8, ["onScroll", "onSectionRendered", "onScrollbarPresenceChange", "scrollLeft", "scrollToColumn", "scrollTop", "scrollToRow"]); this._prepareForRender(); // Don't render any of our Grids if there are no cells. // This mirrors what Grid does, // And prevents us from recording inaccurage measurements when used with CellMeasurer. if (this.props.width === 0 || this.props.height === 0) { return null; } // scrollTop and scrollLeft props are explicitly filtered out and ignored var _this$state4 = this.state, scrollLeft = _this$state4.scrollLeft, scrollTop = _this$state4.scrollTop; return React.createElement("div", { style: this._containerOuterStyle }, React.createElement("div", { style: this._containerTopStyle }, this._renderTopLeftGrid(rest), this._renderTopRightGrid(_objectSpread({}, rest, { onScroll: onScroll, scrollLeft: scrollLeft }))), React.createElement("div", { style: this._containerBottomStyle }, this._renderBottomLeftGrid(_objectSpread({}, rest, { onScroll: onScroll, scrollTop: scrollTop })), this._renderBottomRightGrid(_objectSpread({}, rest, { onScroll: onScroll, onSectionRendered: onSectionRendered, scrollLeft: scrollLeft, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow, scrollTop: scrollTop })))); } }, { key: "_getBottomGridHeight", value: function _getBottomGridHeight(props) { var height = props.height; var topGridHeight = this._getTopGridHeight(props); return height - topGridHeight; } }, { key: "_getLeftGridWidth", value: function _getLeftGridWidth(props) { var fixedColumnCount = props.fixedColumnCount, columnWidth = props.columnWidth; if (this._leftGridWidth == null) { if (typeof columnWidth === 'function') { var leftGridWidth = 0; for (var index = 0; index < fixedColumnCount; index++) { leftGridWidth += columnWidth({ index: index }); } this._leftGridWidth = leftGridWidth; } else { this._leftGridWidth = columnWidth * fixedColumnCount; } } return this._leftGridWidth; } }, { key: "_getRightGridWidth", value: function _getRightGridWidth(props) { var width = props.width; var leftGridWidth = this._getLeftGridWidth(props); return width - leftGridWidth; } }, { key: "_getTopGridHeight", value: function _getTopGridHeight(props) { var fixedRowCount = props.fixedRowCount, rowHeight = props.rowHeight; if (this._topGridHeight == null) { if (typeof rowHeight === 'function') { var topGridHeight = 0; for (var index = 0; index < fixedRowCount; index++) { topGridHeight += rowHeight({ index: index }); } this._topGridHeight = topGridHeight; } else { this._topGridHeight = rowHeight * fixedRowCount; } } return this._topGridHeight; } }, { key: "_handleInvalidatedGridSize", value: function _handleInvalidatedGridSize() { if (typeof this._deferredInvalidateColumnIndex === 'number') { var columnIndex = this._deferredInvalidateColumnIndex; var rowIndex = this._deferredInvalidateRowIndex; this._deferredInvalidateColumnIndex = null; this._deferredInvalidateRowIndex = null; this.recomputeGridSize({ columnIndex: columnIndex, rowIndex: rowIndex }); this.forceUpdate(); } } /** * Avoid recreating inline styles each render; this bypasses Grid's shallowCompare. * This method recalculates styles only when specific props change. */ }, { key: "_maybeCalculateCachedStyles", value: function _maybeCalculateCachedStyles(resetAll) { var _this$props9 = this.props, columnWidth = _this$props9.columnWidth, enableFixedColumnScroll = _this$props9.enableFixedColumnScroll, enableFixedRowScroll = _this$props9.enableFixedRowScroll, height = _this$props9.height, fixedColumnCount = _this$props9.fixedColumnCount, fixedRowCount = _this$props9.fixedRowCount, rowHeight = _this$props9.rowHeight, style = _this$props9.style, styleBottomLeftGrid = _this$props9.styleBottomLeftGrid, styleBottomRightGrid = _this$props9.styleBottomRightGrid, styleTopLeftGrid = _this$props9.styleTopLeftGrid, styleTopRightGrid = _this$props9.styleTopRightGrid, width = _this$props9.width; var sizeChange = resetAll || height !== this._lastRenderedHeight || width !== this._lastRenderedWidth; var leftSizeChange = resetAll || columnWidth !== this._lastRenderedColumnWidth || fixedColumnCount !== this._lastRenderedFixedColumnCount; var topSizeChange = resetAll || fixedRowCount !== this._lastRenderedFixedRowCount || rowHeight !== this._lastRenderedRowHeight; if (resetAll || sizeChange || style !== this._lastRenderedStyle) { this._containerOuterStyle = _objectSpread({ height: height, overflow: 'visible', // Let :focus outline show through width: width }, style); } if (resetAll || sizeChange || topSizeChange) { this._containerTopStyle = { height: this._getTopGridHeight(this.props), position: 'relative', width: width }; this._containerBottomStyle = { height: height - this._getTopGridHeight(this.props), overflow: 'visible', // Let :focus outline show through position: 'relative', width: width }; } if (resetAll || styleBottomLeftGrid !== this._lastRenderedStyleBottomLeftGrid) { this._bottomLeftGridStyle = _objectSpread({ left: 0, overflowX: 'hidden', overflowY: enableFixedColumnScroll ? 'auto' : 'hidden', position: 'absolute' }, styleBottomLeftGrid); } if (resetAll || leftSizeChange || styleBottomRightGrid !== this._lastRenderedStyleBottomRightGrid) { this._bottomRightGridStyle = _objectSpread({ left: this._getLeftGridWidth(this.props), position: 'absolute' }, styleBottomRightGrid); } if (resetAll || styleTopLeftGrid !== this._lastRenderedStyleTopLeftGrid) { this._topLeftGridStyle = _objectSpread({ left: 0, overflowX: 'hidden', overflowY: 'hidden', position: 'absolute', top: 0 }, styleTopLeftGrid); } if (resetAll || leftSizeChange || styleTopRightGrid !== this._lastRenderedStyleTopRightGrid) { this._topRightGridStyle = _objectSpread({ left: this._getLeftGridWidth(this.props), overflowX: enableFixedRowScroll ? 'auto' : 'hidden', overflowY: 'hidden', position: 'absolute', top: 0 }, styleTopRightGrid); } this._lastRenderedColumnWidth = columnWidth; this._lastRenderedFixedColumnCount = fixedColumnCount; this._lastRenderedFixedRowCount = fixedRowCount; this._lastRenderedHeight = height; this._lastRenderedRowHeight = rowHeight; this._lastRenderedStyle = style; this._lastRenderedStyleBottomLeftGrid = styleBottomLeftGrid; this._lastRenderedStyleBottomRightGrid = styleBottomRightGrid; this._lastRenderedStyleTopLeftGrid = styleTopLeftGrid; this._lastRenderedStyleTopRightGrid = styleTopRightGrid; this._lastRenderedWidth = width; } }, { key: "_prepareForRender", value: function _prepareForRender() { if (this._lastRenderedColumnWidth !== this.props.columnWidth || this._lastRenderedFixedColumnCount !== this.props.fixedColumnCount) { this._leftGridWidth = null; } if (this._lastRenderedFixedRowCount !== this.props.fixedRowCount || this._lastRenderedRowHeight !== this.props.rowHeight) { this._topGridHeight = null; } this._maybeCalculateCachedStyles(); this._lastRenderedColumnWidth = this.props.columnWidth; this._lastRenderedFixedColumnCount = this.props.fixedColumnCount; this._lastRenderedFixedRowCount = this.props.fixedRowCount; this._lastRenderedRowHeight = this.props.rowHeight; } }, { key: "_renderBottomLeftGrid", value: function _renderBottomLeftGrid(props) { var enableFixedColumnScroll = props.enableFixedColumnScroll, fixedColumnCount = props.fixedColumnCount, fixedRowCount = props.fixedRowCount, rowCount = props.rowCount, hideBottomLeftGridScrollbar = props.hideBottomLeftGridScrollbar; var showVerticalScrollbar = this.state.showVerticalScrollbar; if (!fixedColumnCount) { return null; } var additionalRowCount = showVerticalScrollbar ? 1 : 0, height = this._getBottomGridHeight(props), width = this._getLeftGridWidth(props), scrollbarSize = this.state.showVerticalScrollbar ? this.state.scrollbarSize : 0, gridWidth = hideBottomLeftGridScrollbar ? width + scrollbarSize : width; var bottomLeftGrid = React.createElement(_Grid["default"], (0, _extends2["default"])({}, props, { cellRenderer: this._cellRendererBottomLeftGrid, className: this.props.classNameBottomLeftGrid, columnCount: fixedColumnCount, deferredMeasurementCache: this._deferredMeasurementCacheBottomLeftGrid, height: height, onScroll: enableFixedColumnScroll ? this._onScrollTop : undefined, ref: this._bottomLeftGridRef, rowCount: Math.max(0, rowCount - fixedRowCount) + additionalRowCount, rowHeight: this._rowHeightBottomGrid, style: this._bottomLeftGridStyle, tabIndex: null, width: gridWidth })); if (hideBottomLeftGridScrollbar) { return React.createElement("div", { className: "BottomLeftGrid_ScrollWrapper", style: _objectSpread({}, this._bottomLeftGridStyle, { height: height, width: width, overflowY: 'hidden' }) }, bottomLeftGrid); } return bottomLeftGrid; } }, { key: "_renderBottomRightGrid", value: function _renderBottomRightGrid(props) { var columnCount = props.columnCount, fixedColumnCount = props.fixedColumnCount, fixedRowCount = props.fixedRowCount, rowCount = props.rowCount, scrollToColumn = props.scrollToColumn, scrollToRow = props.scrollToRow; return React.createElement(_Grid["default"], (0, _extends2["default"])({}, props, { cellRenderer: this._cellRendererBottomRightGrid, className: this.props.classNameBottomRightGrid, columnCount: Math.max(0, columnCount - fixedColumnCount), columnWidth: this._columnWidthRightGrid, deferredMeasurementCache: this._deferredMeasurementCacheBottomRightGrid, height: this._getBottomGridHeight(props), onScroll: this._onScroll, onScrollbarPresenceChange: this._onScrollbarPresenceChange, ref: this._bottomRightGridRef, rowCount: Math.max(0, rowCount - fixedRowCount), rowHeight: this._rowHeightBottomGrid, scrollToColumn: scrollToColumn - fixedColumnCount, scrollToRow: scrollToRow - fixedRowCount, style: this._bottomRightGridStyle, width: this._getRightGridWidth(props) })); } }, { key: "_renderTopLeftGrid", value: function _renderTopLeftGrid(props) { var fixedColumnCount = props.fixedColumnCount, fixedRowCount = props.fixedRowCount; if (!fixedColumnCount || !fixedRowCount) { return null; } return React.createElement(_Grid["default"], (0, _extends2["default"])({}, props, { className: this.props.classNameTopLeftGrid, columnCount: fixedColumnCount, height: this._getTopGridHeight(props), ref: this._topLeftGridRef, rowCount: fixedRowCount, style: this._topLeftGridStyle, tabIndex: null, width: this._getLeftGridWidth(props) })); } }, { key: "_renderTopRightGrid", value: function _renderTopRightGrid(props) { var columnCount = props.columnCount, enableFixedRowScroll = props.enableFixedRowScroll, fixedColumnCount = props.fixedColumnCount, fixedRowCount = props.fixedRowCount, scrollLeft = props.scrollLeft, hideTopRightGridScrollbar = props.hideTopRightGridScrollbar; var _this$state5 = this.state, showHorizontalScrollbar = _this$state5.showHorizontalScrollbar, scrollbarSize = _this$state5.scrollbarSize; if (!fixedRowCount) { return null; } var additionalColumnCount = showHorizontalScrollbar ? 1 : 0, height = this._getTopGridHeight(props), width = this._getRightGridWidth(props), additionalHeight = showHorizontalScrollbar ? scrollbarSize : 0; var gridHeight = height, style = this._topRightGridStyle; if (hideTopRightGridScrollbar) { gridHeight = height + additionalHeight; style = _objectSpread({}, this._topRightGridStyle, { left: 0 }); } var topRightGrid = React.createElement(_Grid["default"], (0, _extends2["default"])({}, props, { cellRenderer: this._cellRendererTopRightGrid, className: this.props.classNameTopRightGrid, columnCount: Math.max(0, columnCount - fixedColumnCount) + additionalColumnCount, columnWidth: this._columnWidthRightGrid, deferredMeasurementCache: this._deferredMeasurementCacheTopRightGrid, height: gridHeight, onScroll: enableFixedRowScroll ? this._onScrollLeft : undefined, ref: this._topRightGridRef, rowCount: fixedRowCount, scrollLeft: scrollLeft, style: style, tabIndex: null, width: width })); if (hideTopRightGridScrollbar) { return React.createElement("div", { className: "TopRightGrid_ScrollWrapper", style: _objectSpread({}, this._topRightGridStyle, { height: height, width: width, overflowX: 'hidden' }) }, topRightGrid); } return topRightGrid; } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps, prevState) { if (nextProps.scrollLeft !== prevState.scrollLeft || nextProps.scrollTop !== prevState.scrollTop) { return { scrollLeft: nextProps.scrollLeft != null && nextProps.scrollLeft >= 0 ? nextProps.scrollLeft : prevState.scrollLeft, scrollTop: nextProps.scrollTop != null && nextProps.scrollTop >= 0 ? nextProps.scrollTop : prevState.scrollTop }; } return null; } }]); return MultiGrid; }(React.PureComponent); (0, _defineProperty2["default"])(MultiGrid, "defaultProps", { classNameBottomLeftGrid: '', classNameBottomRightGrid: '', classNameTopLeftGrid: '', classNameTopRightGrid: '', enableFixedColumnScroll: false, enableFixedRowScroll: false, fixedColumnCount: 0, fixedRowCount: 0, scrollToColumn: -1, scrollToRow: -1, style: {}, styleBottomLeftGrid: {}, styleBottomRightGrid: {}, styleTopLeftGrid: {}, styleTopRightGrid: {}, hideTopRightGridScrollbar: false, hideBottomLeftGridScrollbar: false }); MultiGrid.propTypes = process.env.NODE_ENV !== "production" ? { classNameBottomLeftGrid: _propTypes["default"].string.isRequired, classNameBottomRightGrid: _propTypes["default"].string.isRequired, classNameTopLeftGrid: _propTypes["default"].string.isRequired, classNameTopRightGrid: _propTypes["default"].string.isRequired, enableFixedColumnScroll: _propTypes["default"].bool.isRequired, enableFixedRowScroll: _propTypes["default"].bool.isRequired, fixedColumnCount: _propTypes["default"].number.isRequired, fixedRowCount: _propTypes["default"].number.isRequired, onScrollbarPresenceChange: _propTypes["default"].func, style: _propTypes["default"].object.isRequired, styleBottomLeftGrid: _propTypes["default"].object.isRequired, styleBottomRightGrid: _propTypes["default"].object.isRequired, styleTopLeftGrid: _propTypes["default"].object.isRequired, styleTopRightGrid: _propTypes["default"].object.isRequired, hideTopRightGridScrollbar: _propTypes["default"].bool, hideBottomLeftGridScrollbar: _propTypes["default"].bool } : {}; (0, _reactLifecyclesCompat.polyfill)(MultiGrid); var _default = MultiGrid; exports["default"] = _default;dist/commonjs/MultiGrid/CellMeasurerCacheDecorator.js000064400000007677151676725770017014 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _CellMeasurer = require("../CellMeasurer"); /** * Caches measurements for a given cell. */ var CellMeasurerCacheDecorator = /*#__PURE__*/ function () { function CellMeasurerCacheDecorator() { var _this = this; var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; (0, _classCallCheck2["default"])(this, CellMeasurerCacheDecorator); (0, _defineProperty2["default"])(this, "_cellMeasurerCache", void 0); (0, _defineProperty2["default"])(this, "_columnIndexOffset", void 0); (0, _defineProperty2["default"])(this, "_rowIndexOffset", void 0); (0, _defineProperty2["default"])(this, "columnWidth", function (_ref) { var index = _ref.index; _this._cellMeasurerCache.columnWidth({ index: index + _this._columnIndexOffset }); }); (0, _defineProperty2["default"])(this, "rowHeight", function (_ref2) { var index = _ref2.index; _this._cellMeasurerCache.rowHeight({ index: index + _this._rowIndexOffset }); }); var cellMeasurerCache = params.cellMeasurerCache, _params$columnIndexOf = params.columnIndexOffset, columnIndexOffset = _params$columnIndexOf === void 0 ? 0 : _params$columnIndexOf, _params$rowIndexOffse = params.rowIndexOffset, rowIndexOffset = _params$rowIndexOffse === void 0 ? 0 : _params$rowIndexOffse; this._cellMeasurerCache = cellMeasurerCache; this._columnIndexOffset = columnIndexOffset; this._rowIndexOffset = rowIndexOffset; } (0, _createClass2["default"])(CellMeasurerCacheDecorator, [{ key: "clear", value: function clear(rowIndex, columnIndex) { this._cellMeasurerCache.clear(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset); } }, { key: "clearAll", value: function clearAll() { this._cellMeasurerCache.clearAll(); } }, { key: "hasFixedHeight", value: function hasFixedHeight() { return this._cellMeasurerCache.hasFixedHeight(); } }, { key: "hasFixedWidth", value: function hasFixedWidth() { return this._cellMeasurerCache.hasFixedWidth(); } }, { key: "getHeight", value: function getHeight(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return this._cellMeasurerCache.getHeight(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset); } }, { key: "getWidth", value: function getWidth(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return this._cellMeasurerCache.getWidth(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset); } }, { key: "has", value: function has(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return this._cellMeasurerCache.has(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset); } }, { key: "set", value: function set(rowIndex, columnIndex, width, height) { this._cellMeasurerCache.set(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset, width, height); } }, { key: "defaultHeight", get: function get() { return this._cellMeasurerCache.defaultHeight; } }, { key: "defaultWidth", get: function get() { return this._cellMeasurerCache.defaultWidth; } }]); return CellMeasurerCacheDecorator; }(); exports["default"] = CellMeasurerCacheDecorator;dist/commonjs/MultiGrid/index.js000064400000000717151676725770012735 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "MultiGrid", { enumerable: true, get: function get() { return _MultiGrid["default"]; } }); exports["default"] = void 0; var _MultiGrid = _interopRequireDefault(require("./MultiGrid")); var _default = _MultiGrid["default"]; exports["default"] = _default;dist/commonjs/MultiGrid/MultiGrid.jest.js000064400000062062151676725770014473 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _TestUtils = require("../TestUtils"); var _MultiGrid = _interopRequireDefault(require("./MultiGrid")); var _CellMeasurer = require("../CellMeasurer"); // These tests only focus on what MultiGrid does specifically. // The inner Grid component is tested in depth elsewhere. describe('MultiGrid', function () { function defaultCellRenderer(_ref) { var columnIndex = _ref.columnIndex, key = _ref.key, rowIndex = _ref.rowIndex, style = _ref.style; return React.createElement("div", { className: "gridItem", key: key, style: style }, "row:".concat(rowIndex, ", column:").concat(columnIndex)); } function getMarkup() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return React.createElement(_MultiGrid["default"], (0, _extends2["default"])({ cellRenderer: defaultCellRenderer, columnCount: 50, columnWidth: 50, fixedColumnCount: 2, fixedRowCount: 1, height: 300, overscanColumnCount: 0, overscanRowCount: 0, autoHeight: false, rowHeight: 20, rowCount: 100, width: 400 }, props)); } describe('fixed columns and rows', function () { it('should render 4 Grids when configured for fixed columns and rows', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ fixedColumnCount: 1, fixedRowCount: 1 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(4); var _grids = (0, _slicedToArray2["default"])(grids, 4), topLeft = _grids[0], topRight = _grids[1], bottomLeft = _grids[2], bottomRight = _grids[3]; expect(topLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(topLeft.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(topRight.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(topRight.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(bottomLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(bottomLeft.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto'); }); it('should render 2 Grids when configured for fixed columns only', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ fixedColumnCount: 1, fixedRowCount: 0 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(2); var _grids2 = (0, _slicedToArray2["default"])(grids, 2), bottomLeft = _grids2[0], bottomRight = _grids2[1]; expect(bottomLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(bottomLeft.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto'); }); it('should render 2 Grids when configured for fixed rows only', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ fixedColumnCount: 0, fixedRowCount: 1 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(2); var _grids3 = (0, _slicedToArray2["default"])(grids, 2), topRight = _grids3[0], bottomRight = _grids3[1]; expect(topRight.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(topRight.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto'); }); it('should render 1 Grid when configured for neither fixed columns and rows', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ fixedColumnCount: 0, fixedRowCount: 0 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(1); var _grids4 = (0, _slicedToArray2["default"])(grids, 1), bottomRight = _grids4[0]; expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto'); }); it('should adjust the number of Grids when fixed column or row counts change', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ fixedColumnCount: 2, fixedRowCount: 1 }))); expect(rendered.querySelectorAll('.ReactVirtualized__Grid').length).toEqual(4); rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ fixedColumnCount: 0, fixedRowCount: 0 }))); expect(rendered.querySelectorAll('.ReactVirtualized__Grid').length).toEqual(1); rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ fixedColumnCount: 0, fixedRowCount: 2 }))); expect(rendered.querySelectorAll('.ReactVirtualized__Grid').length).toEqual(2); }); it('should allow scrolling of fixed Grids when configured for fixed columns and rows with scroll interaction', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ enableFixedColumnScroll: true, enableFixedRowScroll: true, fixedColumnCount: 1, fixedRowCount: 1 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(4); var _grids5 = (0, _slicedToArray2["default"])(grids, 4), topLeft = _grids5[0], topRight = _grids5[1], bottomLeft = _grids5[2], bottomRight = _grids5[3]; expect(topLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(topLeft.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(topRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(topRight.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(bottomLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(bottomLeft.style.getPropertyValue('overflow-y')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto'); }); }); describe('hideTopRightGridScrollbar, hideBottomLeftGridScrollbar should hide the scrollbars', function () { function getScrollbarSize20() { return 20; } it('should add scroll wrappers to hide scroll bar when configured for fixed columns and rows with scroll interaction', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ enableFixedColumnScroll: true, enableFixedRowScroll: true, fixedColumnCount: 1, fixedRowCount: 1, hideTopRightGridScrollbar: true, hideBottomLeftGridScrollbar: true, getScrollbarSize: getScrollbarSize20 }))); var wrappers = rendered.querySelectorAll('.TopRightGrid_ScrollWrapper'); expect(wrappers.length).toEqual(1); var _wrappers = wrappers, _wrappers2 = (0, _slicedToArray2["default"])(_wrappers, 1), topRightWrapper = _wrappers2[0]; wrappers = rendered.querySelectorAll('.BottomLeftGrid_ScrollWrapper'); expect(wrappers.length).toEqual(1); var _wrappers3 = wrappers, _wrappers4 = (0, _slicedToArray2["default"])(_wrappers3, 1), bottomLeftWrapper = _wrappers4[0]; expect(topRightWrapper.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(topRightWrapper.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(bottomLeftWrapper.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(bottomLeftWrapper.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(topRightWrapper.style.getPropertyValue('height')).toEqual('20px'); expect(bottomLeftWrapper.style.getPropertyValue('height')).toEqual('280px'); expect(topRightWrapper.style.getPropertyValue('width')).toEqual('350px'); expect(bottomLeftWrapper.style.getPropertyValue('width')).toEqual('50px'); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(4); var _grids6 = (0, _slicedToArray2["default"])(grids, 4), topLeft = _grids6[0], topRight = _grids6[1], bottomLeft = _grids6[2], bottomRight = _grids6[3]; expect(topLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(topLeft.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(topRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(topRight.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(topRight.style.getPropertyValue('height')).toEqual('40px'); expect(bottomLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(bottomLeft.style.getPropertyValue('overflow-y')).toEqual('auto'); expect(bottomLeft.style.getPropertyValue('width')).toEqual('70px'); expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto'); }); }); describe('#recomputeGridSize', function () { it('should clear calculated cached styles in recomputeGridSize', function () { var fixedRowHeight = 75; var fixedColumnWidth = 100; function variableRowHeight(_ref2) { var index = _ref2.index; if (index === 0) { return fixedRowHeight; } return 20; } function variableColumnWidth(_ref3) { var index = _ref3.index; if (index === 0) { return fixedColumnWidth; } return 50; } var multiGrid; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ fixedColumnCount: 1, fixedRowCount: 1, rowHeight: variableRowHeight, columnWidth: variableColumnWidth, ref: function ref(_ref4) { multiGrid = _ref4; } }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(4); var _grids7 = (0, _slicedToArray2["default"])(grids, 4), topLeft = _grids7[0], topRight = _grids7[1], bottomLeft = _grids7[2], bottomRight = _grids7[3]; expect(topLeft.style.getPropertyValue('height')).toEqual('75px'); expect(topRight.style.getPropertyValue('height')).toEqual('75px'); expect(bottomLeft.style.getPropertyValue('height')).toEqual('225px'); expect(bottomRight.style.getPropertyValue('height')).toEqual('225px'); expect(topLeft.style.getPropertyValue('width')).toEqual('100px'); expect(topRight.style.getPropertyValue('width')).toEqual('300px'); expect(bottomLeft.style.getPropertyValue('width')).toEqual('100px'); expect(bottomRight.style.getPropertyValue('width')).toEqual('300px'); expect(multiGrid._topGridHeight).toEqual(75); expect(multiGrid._leftGridWidth).toEqual(100); fixedRowHeight = 125; fixedColumnWidth = 75; multiGrid.recomputeGridSize(); expect(multiGrid._topGridHeight).toEqual(125); expect(multiGrid._leftGridWidth).toEqual(75); multiGrid.forceUpdate(); var gridsAfter = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(gridsAfter.length).toEqual(4); var _gridsAfter = (0, _slicedToArray2["default"])(gridsAfter, 4), topLeftAfter = _gridsAfter[0], topRightAfter = _gridsAfter[1], bottomLeftAfter = _gridsAfter[2], bottomRightAfter = _gridsAfter[3]; expect(topLeftAfter.style.getPropertyValue('height')).toEqual('125px'); expect(topRightAfter.style.getPropertyValue('height')).toEqual('125px'); expect(bottomLeftAfter.style.getPropertyValue('height')).toEqual('175px'); expect(bottomRightAfter.style.getPropertyValue('height')).toEqual('175px'); expect(topLeftAfter.style.getPropertyValue('width')).toEqual('75px'); expect(topRightAfter.style.getPropertyValue('width')).toEqual('325px'); expect(bottomLeftAfter.style.getPropertyValue('width')).toEqual('75px'); expect(bottomRightAfter.style.getPropertyValue('width')).toEqual('325px'); }); }); describe('scrollToColumn and scrollToRow', function () { it('should adjust :scrollLeft for the main Grid when scrollToColumn is used', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnWidth: 50, fixedColumnCount: 2, scrollToAlignment: 'start', scrollToColumn: 19 }))); // Bottom-right Grid is the last Grid var grid = rendered.querySelectorAll('.ReactVirtualized__Grid')[3]; // 20th column, less 2 for the fixed-column Grid, 50px column width expect(grid.scrollLeft).toEqual(850); }); it('should adjust :scrollTop for the main Grid when scrollToRow is used', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ fixedRowCount: 1, rowHeight: 50, scrollToAlignment: 'start', scrollToRow: 19 }))); // Bottom-right Grid is the last Grid var grid = rendered.querySelectorAll('.ReactVirtualized__Grid')[3]; // 20th row, less 1 for the fixed-row Grid, 50px row width expect(grid.scrollTop).toEqual(900); }); }); describe('#forceUpdateGrids', function () { it('should call forceUpdate() on inner Grids', function () { var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (_ref5) { var key = _ref5.key; return React.createElement("div", { key: key, style: {} }); }); var rendered = (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer, columnCount: 2, fixedColumnCount: 1, fixedRowCount: 1, rowCount: 2 })); expect(cellRenderer.mock.calls).toHaveLength(4); cellRenderer.mockReset(); rendered.forceUpdateGrids(); expect(cellRenderer.mock.calls).toHaveLength(4); }); }); describe('#invalidateCellSizeAfterRender', function () { it('should call invalidateCellSizeAfterRender() on inner Grids', function () { var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (_ref6) { var key = _ref6.key; return React.createElement("div", { key: key, style: {} }); }); var rendered = (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer, columnCount: 2, fixedColumnCount: 1, fixedRowCount: 1, rowCount: 2 })); cellRenderer.mockReset(); rendered.invalidateCellSizeAfterRender({ columnIndex: 0, rowIndex: 0 }); rendered.forceUpdate(); expect(cellRenderer.mock.calls).toHaveLength(4); }); it('should specify itself as the :parent for CellMeasurer rendered cells', function () { // HACK For some reason, using Jest mock broke here var savedParent; function cellRenderer(_ref7) { var key = _ref7.key, parent = _ref7.parent; savedParent = parent; return React.createElement("div", { key: key, style: {} }); } var rendered = (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer, columnCount: 2, fixedColumnCount: 1, fixedRowCount: 1, rowCount: 2 })); expect(savedParent).toBe(rendered); }); }); describe('styles', function () { it('should support custom style for the outer MultiGrid wrapper element', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ style: { backgroundColor: 'black' } }))); expect(rendered.style.backgroundColor).toEqual('black'); }); it('should support custom styles for each Grid', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ fixedColumnCount: 2, fixedRowCount: 1, styleBottomLeftGrid: { backgroundColor: 'green' }, styleBottomRightGrid: { backgroundColor: 'red' }, styleTopLeftGrid: { backgroundColor: 'blue' }, styleTopRightGrid: { backgroundColor: 'purple' } }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); var topLeftGrid = grids[0]; var topRightGrid = grids[1]; var bottomLeftGrid = grids[2]; var bottomRightGrid = grids[3]; expect(topLeftGrid.style.backgroundColor).toEqual('blue'); expect(topRightGrid.style.backgroundColor).toEqual('purple'); expect(bottomLeftGrid.style.backgroundColor).toEqual('green'); expect(bottomRightGrid.style.backgroundColor).toEqual('red'); }); }); describe('scrollTop and scrollLeft', function () { it('should adjust :scrollLeft for top-right and main grids when scrollLeft is used', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnWidth: 50, fixedColumnCount: 2, scrollLeft: 850 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); var topRightGrid = grids[1]; var bottomRightGrid = grids[3]; expect(topRightGrid.scrollLeft).toEqual(850); expect(bottomRightGrid.scrollLeft).toEqual(850); }); it('should adjust :scrollTop for bottom-left and main grids when scrollTop is used', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnWidth: 50, fixedColumnCount: 2, scrollTop: 500 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); var bottomLeftGrid = grids[2]; var bottomRightGrid = grids[3]; expect(bottomLeftGrid.scrollTop).toEqual(500); expect(bottomRightGrid.scrollTop).toEqual(500); }); it('should adjust :scrollTop and :scrollLeft when scrollTop and scrollLeft change', function () { (0, _TestUtils.render)(getMarkup()); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollTop: 750, scrollLeft: 900 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); var topRightGrid = grids[1]; var bottomLeftGrid = grids[2]; var bottomRightGrid = grids[3]; expect(topRightGrid.scrollLeft).toEqual(900); expect(bottomRightGrid.scrollLeft).toEqual(900); expect(bottomLeftGrid.scrollTop).toEqual(750); expect(bottomRightGrid.scrollTop).toEqual(750); }); it('should not crash when decreasing :rowCount', function () { (0, _TestUtils.render)(getMarkup()); var updated = (0, _TestUtils.render)(getMarkup({ rowCount: 2 })); expect(updated.props.rowCount).toEqual(2); }); it('should not crash when decreasing :columnCount', function () { (0, _TestUtils.render)(getMarkup()); var updated = (0, _TestUtils.render)(getMarkup({ columnCount: 3 })); expect(updated.props.columnCount).toEqual(3); }); }); describe('deferredMeasurementCache', function () { function getDeferredMeasurementCache() { var deferredMeasurementCache = new _CellMeasurer.CellMeasurerCache({ fixedHeight: true, fixedWidth: true }); deferredMeasurementCache._columnIndices = {}; deferredMeasurementCache._rowIndices = {}; deferredMeasurementCache.has = function (rowIndex, columnIndex) { deferredMeasurementCache._columnIndices[columnIndex] = columnIndex; deferredMeasurementCache._rowIndices[rowIndex] = rowIndex; return true; }; return deferredMeasurementCache; } it('should wrap top-right and bottom-right deferredMeasurementCache if fixedColumnCount is > 0', function () { var deferredMeasurementCache = getDeferredMeasurementCache(); (0, _TestUtils.render)(getMarkup({ deferredMeasurementCache: deferredMeasurementCache, columnCount: 3, fixedColumnCount: 1, fixedRowCount: 0, rowCount: 1 })); expect(Object.keys(deferredMeasurementCache._columnIndices)).toEqual(['0', '1', '2']); }); it('should not wrap top-right and bottom-right deferredMeasurementCache if fixedColumnCount is 0', function () { var deferredMeasurementCache = getDeferredMeasurementCache(); (0, _TestUtils.render)(getMarkup({ deferredMeasurementCache: deferredMeasurementCache, columnCount: 2, fixedColumnCount: 0, fixedRowCount: 0, rowCount: 1 })); expect(Object.keys(deferredMeasurementCache._columnIndices)).toEqual(['0', '1']); }); it('should wrap bottom-left and bottom-right deferredMeasurementCache if fixedRowCount is > 0', function () { var deferredMeasurementCache = getDeferredMeasurementCache(); (0, _TestUtils.render)(getMarkup({ deferredMeasurementCache: deferredMeasurementCache, columnCount: 1, fixedColumnCount: 0, fixedRowCount: 1, rowCount: 3 })); expect(Object.keys(deferredMeasurementCache._rowIndices)).toEqual(['0', '1', '2']); }); it('should not wrap bottom-left and bottom-right deferredMeasurementCache if fixedRowCount is 0', function () { var deferredMeasurementCache = getDeferredMeasurementCache(); (0, _TestUtils.render)(getMarkup({ deferredMeasurementCache: deferredMeasurementCache, columnCount: 1, fixedColumnCount: 0, fixedRowCount: 0, rowCount: 2 })); expect(Object.keys(deferredMeasurementCache._rowIndices)).toEqual(['0', '1']); }); }); describe('onScrollbarPresenceChange', function () { function getScrollbarSize20() { return 20; } it('should not trigger on-mount if scrollbars are hidden', function () { var onScrollbarPresenceChange = jest.fn(); (0, _TestUtils.render)(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 1 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); }); it('should trigger on-mount if scrollbars are visible', function () { var onScrollbarPresenceChange = jest.fn(); (0, _TestUtils.render)(getMarkup({ columnCount: 100, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 100 })); expect(onScrollbarPresenceChange).toHaveBeenCalled(); var args = onScrollbarPresenceChange.mock.calls[0][0]; expect(args.horizontal).toBe(true); expect(args.size).toBe(getScrollbarSize20()); expect(args.vertical).toBe(true); }); it('should trigger on-update if scrollbar visibility has changed', function () { var onScrollbarPresenceChange = jest.fn(); (0, _TestUtils.render)(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 1 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); (0, _TestUtils.render)(getMarkup({ columnCount: 100, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 100 })); expect(onScrollbarPresenceChange).toHaveBeenCalled(); var args = onScrollbarPresenceChange.mock.calls[0][0]; expect(args.horizontal).toBe(true); expect(args.size).toBe(getScrollbarSize20()); expect(args.vertical).toBe(true); }); it('should not trigger on-update if scrollbar visibility does not change', function () { var onScrollbarPresenceChange = jest.fn(); (0, _TestUtils.render)(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 1 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); (0, _TestUtils.render)(getMarkup({ columnCount: 2, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 2 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); }); }); });dist/commonjs/MultiGrid/MultiGrid.example.js000064400000013525151676725770015161 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _immutable = _interopRequireDefault(require("immutable")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _ContentBox = require("../demo/ContentBox"); var _LabeledInput = require("../demo/LabeledInput"); var _AutoSizer = _interopRequireDefault(require("../AutoSizer")); var _MultiGrid = _interopRequireDefault(require("./MultiGrid")); var _MultiGridExample = _interopRequireDefault(require("./MultiGrid.example.css")); var STYLE = { border: '1px solid #ddd' }; var STYLE_BOTTOM_LEFT_GRID = { borderRight: '2px solid #aaa', backgroundColor: '#f7f7f7' }; var STYLE_TOP_LEFT_GRID = { borderBottom: '2px solid #aaa', borderRight: '2px solid #aaa', fontWeight: 'bold' }; var STYLE_TOP_RIGHT_GRID = { borderBottom: '2px solid #aaa', fontWeight: 'bold' }; var MultiGridExample = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(MultiGridExample, _React$PureComponent); function MultiGridExample(props, context) { var _this; (0, _classCallCheck2["default"])(this, MultiGridExample); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(MultiGridExample).call(this, props, context)); _this.state = { fixedColumnCount: 2, fixedRowCount: 1, scrollToColumn: 0, scrollToRow: 0 }; _this._cellRenderer = _this._cellRenderer.bind((0, _assertThisInitialized2["default"])(_this)); _this._onFixedColumnCountChange = _this._createEventHandler('fixedColumnCount'); _this._onFixedRowCountChange = _this._createEventHandler('fixedRowCount'); _this._onScrollToColumnChange = _this._createEventHandler('scrollToColumn'); _this._onScrollToRowChange = _this._createEventHandler('scrollToRow'); return _this; } (0, _createClass2["default"])(MultiGridExample, [{ key: "render", value: function render() { var _this2 = this; return React.createElement(_ContentBox.ContentBox, null, React.createElement(_ContentBox.ContentBoxHeader, { text: "MultiGrid", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/MultiGrid/MultiGrid.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/MultiGrid.md" }), React.createElement(_ContentBox.ContentBoxParagraph, null, "This component stitches together several grids to provide a fixed column/row interface."), React.createElement(_LabeledInput.InputRow, null, this._createLabeledInput('fixedColumnCount', this._onFixedColumnCountChange), this._createLabeledInput('fixedRowCount', this._onFixedRowCountChange), this._createLabeledInput('scrollToColumn', this._onScrollToColumnChange), this._createLabeledInput('scrollToRow', this._onScrollToRowChange)), React.createElement(_AutoSizer["default"], { disableHeight: true }, function (_ref) { var width = _ref.width; return React.createElement(_MultiGrid["default"], (0, _extends2["default"])({}, _this2.state, { cellRenderer: _this2._cellRenderer, columnWidth: 75, columnCount: 50, enableFixedColumnScroll: true, enableFixedRowScroll: true, height: 300, rowHeight: 40, rowCount: 100, style: STYLE, styleBottomLeftGrid: STYLE_BOTTOM_LEFT_GRID, styleTopLeftGrid: STYLE_TOP_LEFT_GRID, styleTopRightGrid: STYLE_TOP_RIGHT_GRID, width: width, hideTopRightGridScrollbar: true, hideBottomLeftGridScrollbar: true })); })); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref2) { var columnIndex = _ref2.columnIndex, key = _ref2.key, rowIndex = _ref2.rowIndex, style = _ref2.style; return React.createElement("div", { className: _MultiGridExample["default"].Cell, key: key, style: style }, columnIndex, ", ", rowIndex); } }, { key: "_createEventHandler", value: function _createEventHandler(property) { var _this3 = this; return function (event) { var value = parseInt(event.target.value, 10) || 0; _this3.setState((0, _defineProperty2["default"])({}, property, value)); }; } }, { key: "_createLabeledInput", value: function _createLabeledInput(property, eventHandler) { var value = this.state[property]; return React.createElement(_LabeledInput.LabeledInput, { label: property, name: property, onChange: eventHandler, value: value }); } }]); return MultiGridExample; }(React.PureComponent); exports["default"] = MultiGridExample; (0, _defineProperty2["default"])(MultiGridExample, "contextTypes", { list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired });dist/commonjs/List/List.js000064400000031015151676725770011547 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _Grid = _interopRequireWildcard(require("../Grid")); var React = _interopRequireWildcard(require("react")); var _clsx = _interopRequireDefault(require("clsx")); var _types = require("./types"); var _propTypes = _interopRequireDefault(require("prop-types")); var _class, _temp; var List = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(List, _React$PureComponent); function List() { var _getPrototypeOf2; var _this; (0, _classCallCheck2["default"])(this, List); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(List)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "Grid", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_cellRenderer", function (_ref) { var parent = _ref.parent, rowIndex = _ref.rowIndex, style = _ref.style, isScrolling = _ref.isScrolling, isVisible = _ref.isVisible, key = _ref.key; var rowRenderer = _this.props.rowRenderer; // TRICKY The style object is sometimes cached by Grid. // This prevents new style objects from bypassing shallowCompare(). // However as of React 16, style props are auto-frozen (at least in dev mode) // Check to make sure we can still modify the style before proceeding. // https://github.com/facebook/react/commit/977357765b44af8ff0cfea327866861073095c12#commitcomment-20648713 var widthDescriptor = Object.getOwnPropertyDescriptor(style, 'width'); if (widthDescriptor && widthDescriptor.writable) { // By default, List cells should be 100% width. // This prevents them from flowing under a scrollbar (if present). style.width = '100%'; } return rowRenderer({ index: rowIndex, style: style, isScrolling: isScrolling, isVisible: isVisible, key: key, parent: parent }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_setRef", function (ref) { _this.Grid = ref; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onScroll", function (_ref2) { var clientHeight = _ref2.clientHeight, scrollHeight = _ref2.scrollHeight, scrollTop = _ref2.scrollTop; var onScroll = _this.props.onScroll; onScroll({ clientHeight: clientHeight, scrollHeight: scrollHeight, scrollTop: scrollTop }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onSectionRendered", function (_ref3) { var rowOverscanStartIndex = _ref3.rowOverscanStartIndex, rowOverscanStopIndex = _ref3.rowOverscanStopIndex, rowStartIndex = _ref3.rowStartIndex, rowStopIndex = _ref3.rowStopIndex; var onRowsRendered = _this.props.onRowsRendered; onRowsRendered({ overscanStartIndex: rowOverscanStartIndex, overscanStopIndex: rowOverscanStopIndex, startIndex: rowStartIndex, stopIndex: rowStopIndex }); }); return _this; } (0, _createClass2["default"])(List, [{ key: "forceUpdateGrid", value: function forceUpdateGrid() { if (this.Grid) { this.Grid.forceUpdate(); } } /** See Grid#getOffsetForCell */ }, { key: "getOffsetForRow", value: function getOffsetForRow(_ref4) { var alignment = _ref4.alignment, index = _ref4.index; if (this.Grid) { var _this$Grid$getOffsetF = this.Grid.getOffsetForCell({ alignment: alignment, rowIndex: index, columnIndex: 0 }), scrollTop = _this$Grid$getOffsetF.scrollTop; return scrollTop; } return 0; } /** CellMeasurer compatibility */ }, { key: "invalidateCellSizeAfterRender", value: function invalidateCellSizeAfterRender(_ref5) { var columnIndex = _ref5.columnIndex, rowIndex = _ref5.rowIndex; if (this.Grid) { this.Grid.invalidateCellSizeAfterRender({ rowIndex: rowIndex, columnIndex: columnIndex }); } } /** See Grid#measureAllCells */ }, { key: "measureAllRows", value: function measureAllRows() { if (this.Grid) { this.Grid.measureAllCells(); } } /** CellMeasurer compatibility */ }, { key: "recomputeGridSize", value: function recomputeGridSize() { var _ref6 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref6$columnIndex = _ref6.columnIndex, columnIndex = _ref6$columnIndex === void 0 ? 0 : _ref6$columnIndex, _ref6$rowIndex = _ref6.rowIndex, rowIndex = _ref6$rowIndex === void 0 ? 0 : _ref6$rowIndex; if (this.Grid) { this.Grid.recomputeGridSize({ rowIndex: rowIndex, columnIndex: columnIndex }); } } /** See Grid#recomputeGridSize */ }, { key: "recomputeRowHeights", value: function recomputeRowHeights() { var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (this.Grid) { this.Grid.recomputeGridSize({ rowIndex: index, columnIndex: 0 }); } } /** See Grid#scrollToPosition */ }, { key: "scrollToPosition", value: function scrollToPosition() { var scrollTop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (this.Grid) { this.Grid.scrollToPosition({ scrollTop: scrollTop }); } } /** See Grid#scrollToCell */ }, { key: "scrollToRow", value: function scrollToRow() { var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (this.Grid) { this.Grid.scrollToCell({ columnIndex: 0, rowIndex: index }); } } }, { key: "render", value: function render() { var _this$props = this.props, className = _this$props.className, noRowsRenderer = _this$props.noRowsRenderer, scrollToIndex = _this$props.scrollToIndex, width = _this$props.width; var classNames = (0, _clsx["default"])('ReactVirtualized__List', className); return React.createElement(_Grid["default"], (0, _extends2["default"])({}, this.props, { autoContainerWidth: true, cellRenderer: this._cellRenderer, className: classNames, columnWidth: width, columnCount: 1, noContentRenderer: noRowsRenderer, onScroll: this._onScroll, onSectionRendered: this._onSectionRendered, ref: this._setRef, scrollToRow: scrollToIndex })); } }]); return List; }(React.PureComponent), (0, _defineProperty2["default"])(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { "aria-label": _propTypes["default"].string, /** * Removes fixed height from the scrollingContainer so that the total height * of rows can stretch the window. Intended for use with WindowScroller */ "autoHeight": _propTypes["default"].bool.isRequired, /** Optional CSS class name */ "className": _propTypes["default"].string, /** * Used to estimate the total height of a List before all of its rows have actually been measured. * The estimated total height is adjusted as rows are rendered. */ "estimatedRowSize": _propTypes["default"].number.isRequired, /** Height constraint for list (determines how many actual rows are rendered) */ "height": _propTypes["default"].number.isRequired, /** Optional renderer to be used in place of rows when rowCount is 0 */ "noRowsRenderer": function noRowsRenderer() { return (typeof _Grid.bpfrpt_proptype_NoContentRenderer === "function" ? _Grid.bpfrpt_proptype_NoContentRenderer.isRequired ? _Grid.bpfrpt_proptype_NoContentRenderer.isRequired : _Grid.bpfrpt_proptype_NoContentRenderer : _propTypes["default"].shape(_Grid.bpfrpt_proptype_NoContentRenderer).isRequired).apply(this, arguments); }, /** Callback invoked with information about the slice of rows that were just rendered. */ "onRowsRendered": _propTypes["default"].func.isRequired, /** * Callback invoked whenever the scroll offset changes within the inner scrollable region. * This callback can be used to sync scrolling between lists, tables, or grids. */ "onScroll": _propTypes["default"].func.isRequired, /** See Grid#overscanIndicesGetter */ "overscanIndicesGetter": function overscanIndicesGetter() { return (typeof _Grid.bpfrpt_proptype_OverscanIndicesGetter === "function" ? _Grid.bpfrpt_proptype_OverscanIndicesGetter.isRequired ? _Grid.bpfrpt_proptype_OverscanIndicesGetter.isRequired : _Grid.bpfrpt_proptype_OverscanIndicesGetter : _propTypes["default"].shape(_Grid.bpfrpt_proptype_OverscanIndicesGetter).isRequired).apply(this, arguments); }, /** * Number of rows to render above/below the visible bounds of the list. * These rows can help for smoother scrolling on touch devices. */ "overscanRowCount": _propTypes["default"].number.isRequired, /** Either a fixed row height (number) or a function that returns the height of a row given its index. */ "rowHeight": function rowHeight() { return (typeof _Grid.bpfrpt_proptype_CellSize === "function" ? _Grid.bpfrpt_proptype_CellSize.isRequired ? _Grid.bpfrpt_proptype_CellSize.isRequired : _Grid.bpfrpt_proptype_CellSize : _propTypes["default"].shape(_Grid.bpfrpt_proptype_CellSize).isRequired).apply(this, arguments); }, /** Responsible for rendering a row given an index; ({ index: number }): node */ "rowRenderer": function rowRenderer() { return (typeof _types.bpfrpt_proptype_RowRenderer === "function" ? _types.bpfrpt_proptype_RowRenderer.isRequired ? _types.bpfrpt_proptype_RowRenderer.isRequired : _types.bpfrpt_proptype_RowRenderer : _propTypes["default"].shape(_types.bpfrpt_proptype_RowRenderer).isRequired).apply(this, arguments); }, /** Number of rows in list. */ "rowCount": _propTypes["default"].number.isRequired, /** See Grid#scrollToAlignment */ "scrollToAlignment": function scrollToAlignment() { return (typeof _Grid.bpfrpt_proptype_Alignment === "function" ? _Grid.bpfrpt_proptype_Alignment.isRequired ? _Grid.bpfrpt_proptype_Alignment.isRequired : _Grid.bpfrpt_proptype_Alignment : _propTypes["default"].shape(_Grid.bpfrpt_proptype_Alignment).isRequired).apply(this, arguments); }, /** Row index to ensure visible (by forcefully scrolling if necessary) */ "scrollToIndex": _propTypes["default"].number.isRequired, /** Vertical offset. */ "scrollTop": _propTypes["default"].number, /** Optional inline style */ "style": _propTypes["default"].object.isRequired, /** Tab index for focus */ "tabIndex": _propTypes["default"].number, /** Width of list */ "width": _propTypes["default"].number.isRequired }), _temp); exports["default"] = List; (0, _defineProperty2["default"])(List, "defaultProps", { autoHeight: false, estimatedRowSize: 30, onScroll: function onScroll() {}, noRowsRenderer: function noRowsRenderer() { return null; }, onRowsRendered: function onRowsRendered() {}, overscanIndicesGetter: _Grid.accessibilityOverscanIndicesGetter, overscanRowCount: 10, scrollToAlignment: 'auto', scrollToIndex: -1, style: {} });dist/commonjs/List/types.js000064400000003566151676725770012012 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports.bpfrpt_proptype_Scroll = exports.bpfrpt_proptype_RenderedRows = exports.bpfrpt_proptype_RowRenderer = exports.bpfrpt_proptype_RowRendererParams = void 0; var React = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var bpfrpt_proptype_RowRendererParams = process.env.NODE_ENV === 'production' ? null : { "index": _propTypes["default"].number.isRequired, "isScrolling": _propTypes["default"].bool.isRequired, "isVisible": _propTypes["default"].bool.isRequired, "key": _propTypes["default"].string.isRequired, "parent": _propTypes["default"].object.isRequired, "style": _propTypes["default"].object.isRequired }; exports.bpfrpt_proptype_RowRendererParams = bpfrpt_proptype_RowRendererParams; var bpfrpt_proptype_RowRenderer = process.env.NODE_ENV === 'production' ? null : _propTypes["default"].func; exports.bpfrpt_proptype_RowRenderer = bpfrpt_proptype_RowRenderer; var bpfrpt_proptype_RenderedRows = process.env.NODE_ENV === 'production' ? null : { "overscanStartIndex": _propTypes["default"].number.isRequired, "overscanStopIndex": _propTypes["default"].number.isRequired, "startIndex": _propTypes["default"].number.isRequired, "stopIndex": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_RenderedRows = bpfrpt_proptype_RenderedRows; var bpfrpt_proptype_Scroll = process.env.NODE_ENV === 'production' ? null : { "clientHeight": _propTypes["default"].number.isRequired, "scrollHeight": _propTypes["default"].number.isRequired, "scrollTop": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_Scroll = bpfrpt_proptype_Scroll;dist/commonjs/List/index.js000064400000001246151676725770011746 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function get() { return _List["default"]; } }); Object.defineProperty(exports, "List", { enumerable: true, get: function get() { return _List["default"]; } }); Object.defineProperty(exports, "bpfrpt_proptype_RowRendererParams", { enumerable: true, get: function get() { return _types.bpfrpt_proptype_RowRendererParams; } }); var _List = _interopRequireDefault(require("./List")); var _types = require("./types");dist/commonjs/List/List.jest.js000064400000047225151676725770012525 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _TestUtils = require("../TestUtils"); var _testUtils = require("react-dom/test-utils"); var _immutable = _interopRequireDefault(require("immutable")); var _List = _interopRequireDefault(require("./List")); var _Grid = require("../Grid"); describe('List', function () { var array = []; for (var i = 0; i < 100; i++) { array.push("Name ".concat(i)); } var names = _immutable["default"].fromJS(array); // Override default behavior of overscanning by at least 1 (for accessibility) // Because it makes for simple tests below function overscanIndicesGetter(_ref) { var startIndex = _ref.startIndex, stopIndex = _ref.stopIndex; return { overscanStartIndex: startIndex, overscanStopIndex: stopIndex }; } function getMarkup() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; function rowRenderer(_ref2) { var index = _ref2.index, key = _ref2.key, style = _ref2.style; return React.createElement("div", { className: "listItem", key: key, style: style }, names.get(index)); } return React.createElement(_List["default"], (0, _extends2["default"])({ height: 100, overscanIndicesGetter: overscanIndicesGetter, overscanRowCount: 0, rowHeight: 10, rowCount: names.size, rowRenderer: rowRenderer, width: 100 }, props)); } describe('number of rendered children', function () { it('should render enough children to fill the view', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.querySelectorAll('.listItem').length).toEqual(10); }); it('should not render more children than available if the list is not filled', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ rowCount: 5 }))); expect(rendered.querySelectorAll('.listItem').length).toEqual(5); }); }); describe('scrollToPosition', function () { it('should scroll to the top', function () { var instance = (0, _TestUtils.render)(getMarkup({ rowHeight: 10 })); instance.scrollToPosition(100); var rendered = (0, _reactDom.findDOMNode)(instance); expect(rendered.textContent).toContain('Name 10'); expect(rendered.textContent).toContain('Name 19'); }); }); /** Tests scrolling via initial props */ describe('scrollToIndex', function () { it('should scroll to the top', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToIndex: 0 }))); expect(rendered.textContent).toContain('Name 0'); }); it('should scroll down to the middle', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToIndex: 49 }))); // 100 items * 10 item height = 1,000 total item height // 10 items can be visible at a time and :scrollTop is initially 0, // So the minimum amount of scrolling leaves the 50th item at the bottom (just scrolled into view). expect(rendered.textContent).toContain('Name 49'); }); it('should scroll to the bottom', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToIndex: 99 }))); // 100 height - 10 header = 90 available scroll space. // 100 items * 10 item height = 1,000 total item height // Target height for the last item then is 1000 - 90 expect(rendered.textContent).toContain('Name 99'); }); it('should scroll to the correct position for :scrollToAlignment "start"', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToAlignment: 'start', scrollToIndex: 49 }))); // 100 items * 10 item height = 1,000 total item height; 10 items can be visible at a time. expect(rendered.textContent).toContain('Name 49'); expect(rendered.textContent).toContain('Name 58'); }); it('should scroll to the correct position for :scrollToAlignment "end"', function () { (0, _TestUtils.render)(getMarkup({ scrollToIndex: 99 })); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToAlignment: 'end', scrollToIndex: 49 }))); // 100 items * 10 item height = 1,000 total item height; 10 items can be visible at a time. expect(rendered.textContent).toContain('Name 40'); expect(rendered.textContent).toContain('Name 49'); }); it('should scroll to the correct position for :scrollToAlignment "center"', function () { (0, _TestUtils.render)(getMarkup({ scrollToIndex: 99 })); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToAlignment: 'center', scrollToIndex: 49 }))); // 100 items * 10 item height = 1,000 total item height; 11 items can be visible at a time (the first and last item are only partially visible) expect(rendered.textContent).toContain('Name 44'); expect(rendered.textContent).toContain('Name 54'); }); }); describe('property updates', function () { it('should update :scrollToIndex position when :rowHeight changes', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToIndex: 50 }))); expect(rendered.textContent).toContain('Name 50'); // Making rows taller pushes name off/beyond the scrolled area rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToIndex: 50, rowHeight: 20 }))); expect(rendered.textContent).toContain('Name 50'); }); it('should update :scrollToIndex position when :height changes', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToIndex: 50 }))); expect(rendered.textContent).toContain('Name 50'); // Making the list shorter leaves only room for 1 item rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToIndex: 50, height: 20 }))); expect(rendered.textContent).toContain('Name 50'); }); it('should update :scrollToIndex position when :scrollToIndex changes', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.textContent).not.toContain('Name 50'); rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToIndex: 50 }))); expect(rendered.textContent).toContain('Name 50'); }); it('should update scroll position if size shrinks smaller than the current scroll', function () { (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToIndex: 500 }))); (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToIndex: 500, rowCount: 10 }))); expect(rendered.textContent).toContain('Name 9'); }); }); describe('noRowsRenderer', function () { it('should call :noRowsRenderer if :rowCount is 0', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ noRowsRenderer: function noRowsRenderer() { return React.createElement("div", null, "No rows!"); }, rowCount: 0 }))); expect(rendered.textContent).toEqual('No rows!'); }); it('should render an empty body if :rowCount is 0 and there is no :noRowsRenderer', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ rowCount: 0 }))); expect(rendered.textContent).toEqual(''); }); }); describe('onRowsRendered', function () { it('should call :onRowsRendered if at least one row is rendered', function () { var startIndex, stopIndex; (0, _TestUtils.render)(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params; return _params = params, startIndex = _params.startIndex, stopIndex = _params.stopIndex, _params; } })); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(9); }); it('should not call :onRowsRendered unless the start or stop indices have changed', function () { var numCalls = 0; var startIndex; var stopIndex; var onRowsRendered = function onRowsRendered(params) { startIndex = params.startIndex; stopIndex = params.stopIndex; numCalls++; }; (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onRowsRendered: onRowsRendered }))); expect(numCalls).toEqual(1); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(9); (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onRowsRendered: onRowsRendered }))); expect(numCalls).toEqual(1); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(9); }); it('should call :onRowsRendered if the start or stop indices have changed', function () { var numCalls = 0; var startIndex; var stopIndex; var onRowsRendered = function onRowsRendered(params) { startIndex = params.startIndex; stopIndex = params.stopIndex; numCalls++; }; (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onRowsRendered: onRowsRendered }))); expect(numCalls).toEqual(1); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(9); (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 50, onRowsRendered: onRowsRendered }))); expect(numCalls).toEqual(2); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(4); }); it('should not call :onRowsRendered if no rows are rendered', function () { var startIndex, stopIndex; (0, _TestUtils.render)(getMarkup({ height: 0, onRowsRendered: function onRowsRendered(params) { var _params2; return _params2 = params, startIndex = _params2.startIndex, stopIndex = _params2.stopIndex, _params2; } })); expect(startIndex).toEqual(undefined); expect(stopIndex).toEqual(undefined); }); }); describe(':scrollTop property', function () { it('should render correctly when an initial :scrollTop property is specified', function () { var startIndex, stopIndex; (0, _TestUtils.render)(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params3; return _params3 = params, startIndex = _params3.startIndex, stopIndex = _params3.stopIndex, _params3; }, scrollTop: 100 })); expect(startIndex).toEqual(10); expect(stopIndex).toEqual(19); }); it('should render correctly when :scrollTop property is updated', function () { var startIndex, stopIndex; (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params4; return _params4 = params, startIndex = _params4.startIndex, stopIndex = _params4.stopIndex, _params4; } }))); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(9); (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params5; return _params5 = params, startIndex = _params5.startIndex, stopIndex = _params5.stopIndex, _params5; }, scrollTop: 100 }))); expect(startIndex).toEqual(10); expect(stopIndex).toEqual(19); }); }); describe('styles, classNames, and ids', function () { it('should use the expected global CSS classNames', function () { var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(node.className).toContain('ReactVirtualized__List'); }); it('should use a custom :className if specified', function () { var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ className: 'foo' }))); expect(node.className).toContain('foo'); }); it('should use a custom :id if specified', function () { var node = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ id: 'bar' }))); expect(node.getAttribute('id')).toEqual('bar'); }); it('should use a custom :style if specified', function () { var style = { backgroundColor: 'red' }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ style: style }))); expect(rendered.style.backgroundColor).toEqual('red'); }); it('should set the width of a row to be 100% by default', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); var cell = rendered.querySelector('.listItem'); expect(cell.style.width).toEqual('100%'); }); }); describe('overscanRowCount', function () { it('should not overscan by default', function () { var mock = jest.fn(); mock.mockImplementation(overscanIndicesGetter); (0, _TestUtils.render)(getMarkup({ overscanIndicesGetter: mock })); expect(mock.mock.calls[0][0].overscanCellsCount).toEqual(0); expect(mock.mock.calls[1][0].overscanCellsCount).toEqual(0); }); it('should overscan the specified amount', function () { var mock = jest.fn(); mock.mockImplementation(overscanIndicesGetter); (0, _TestUtils.render)(getMarkup({ overscanIndicesGetter: mock, overscanRowCount: 10 })); expect(mock.mock.calls[0][0].overscanCellsCount).toEqual(0); expect(mock.mock.calls[1][0].overscanCellsCount).toEqual(10); }); }); describe('onScroll', function () { it('should trigger callback when component initially mounts', function () { var onScrollCalls = []; (0, _TestUtils.render)(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); expect(onScrollCalls).toEqual([{ clientHeight: 100, scrollHeight: 1000, scrollTop: 0 }]); }); it('should trigger callback when component scrolls', function () { var onScrollCalls = []; var rendered = (0, _TestUtils.render)(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); var target = { scrollLeft: 0, scrollTop: 100 }; rendered.Grid._scrollingContainer = target; // HACK to work around _onScroll target check _testUtils.Simulate.scroll((0, _reactDom.findDOMNode)(rendered), { target: target }); expect(onScrollCalls[onScrollCalls.length - 1]).toEqual({ clientHeight: 100, scrollHeight: 1000, scrollTop: 100 }); }); }); describe('measureAllRows', function () { it('should measure any unmeasured rows', function () { var rendered = (0, _TestUtils.render)(getMarkup({ estimatedRowSize: 15, height: 0, rowCount: 10, rowHeight: function rowHeight() { return 20; }, width: 0 })); expect(rendered.Grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(150); rendered.measureAllRows(); expect(rendered.Grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(200); }); }); describe('recomputeRowHeights', function () { it('should recompute row heights and other values when called', function () { var indices = []; var rowHeight = function rowHeight(_ref3) { var index = _ref3.index; indices.push(index); return 10; }; var component = (0, _TestUtils.render)(getMarkup({ rowHeight: rowHeight, rowCount: 50 })); indices.splice(0); component.recomputeRowHeights(); // Only the rows required to fill the current viewport will be rendered expect(indices[0]).toEqual(0); expect(indices[indices.length - 1]).toEqual(9); indices.splice(0); component.recomputeRowHeights(4); expect(indices[0]).toEqual(4); expect(indices[indices.length - 1]).toEqual(9); }); }); describe('forceUpdateGrid', function () { it('should refresh inner Grid content when called', function () { var marker = 'a'; function rowRenderer(_ref4) { var index = _ref4.index, key = _ref4.key, style = _ref4.style; return React.createElement("div", { key: key, style: style }, index, marker); } var component = (0, _TestUtils.render)(getMarkup({ rowRenderer: rowRenderer })); var node = (0, _reactDom.findDOMNode)(component); expect(node.textContent).toContain('1a'); marker = 'b'; component.forceUpdateGrid(); expect(node.textContent).toContain('1b'); }); }); describe('tabIndex', function () { it('should be focusable by default', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.tabIndex).toEqual(0); }); it('should allow tabIndex to be overridden', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ tabIndex: -1 }))); expect(rendered.tabIndex).toEqual(-1); }); }); it('should pass the cellRenderer an :isVisible flag', function () { var rowRendererCalls = []; function rowRenderer(props) { rowRendererCalls.push(props); return null; } (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 50, overscanIndicesGetter: _Grid.defaultOverscanIndicesGetter, overscanRowCount: 1, rowHeight: 50, rowRenderer: rowRenderer }))); expect(rowRendererCalls[0].isVisible).toEqual(true); expect(rowRendererCalls[1].isVisible).toEqual(false); }); it('should relay the Grid :parent param to the :rowRenderer', function () { var rowRenderer = jest.fn().mockReturnValue(null); (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ rowRenderer: rowRenderer }))); expect(rowRenderer.mock.calls[0][0].parent).not.toBeUndefined(); }); describe('pure', function () { it('should not re-render unless props have changed', function () { var rowRendererCalled = false; function rowRenderer(_ref5) { var index = _ref5.index, key = _ref5.key, style = _ref5.style; rowRendererCalled = true; return React.createElement("div", { key: key, style: style }, index); } var markup = getMarkup({ rowRenderer: rowRenderer }); (0, _TestUtils.render)(markup); expect(rowRendererCalled).toEqual(true); rowRendererCalled = false; (0, _TestUtils.render)(markup); expect(rowRendererCalled).toEqual(false); }); }); it('should set the width of the single-column inner Grid to auto', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('auto'); }); });dist/commonjs/List/List.example.js000064400000023715151676725770013211 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _clsx = _interopRequireDefault(require("clsx")); var _immutable = _interopRequireDefault(require("immutable")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _ListExample = _interopRequireDefault(require("./List.example.css")); var _AutoSizer = _interopRequireDefault(require("../AutoSizer")); var _List = _interopRequireDefault(require("./List")); var _ContentBox = require("../demo/ContentBox"); var _LabeledInput = require("../demo/LabeledInput"); var ListExample = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(ListExample, _React$PureComponent); function ListExample(props, context) { var _this; (0, _classCallCheck2["default"])(this, ListExample); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(ListExample).call(this, props, context)); _this.state = { listHeight: 300, listRowHeight: 50, overscanRowCount: 10, rowCount: context.list.size, scrollToIndex: undefined, showScrollingPlaceholder: false, useDynamicRowHeight: false }; _this._getRowHeight = _this._getRowHeight.bind((0, _assertThisInitialized2["default"])(_this)); _this._noRowsRenderer = _this._noRowsRenderer.bind((0, _assertThisInitialized2["default"])(_this)); _this._onRowCountChange = _this._onRowCountChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._onScrollToRowChange = _this._onScrollToRowChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._rowRenderer = _this._rowRenderer.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(ListExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, listHeight = _this$state.listHeight, listRowHeight = _this$state.listRowHeight, overscanRowCount = _this$state.overscanRowCount, rowCount = _this$state.rowCount, scrollToIndex = _this$state.scrollToIndex, showScrollingPlaceholder = _this$state.showScrollingPlaceholder, useDynamicRowHeight = _this$state.useDynamicRowHeight; return React.createElement(_ContentBox.ContentBox, null, React.createElement(_ContentBox.ContentBoxHeader, { text: "List", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/List/List.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/List.md" }), React.createElement(_ContentBox.ContentBoxParagraph, null, "The list below is windowed (or \"virtualized\") meaning that only the visible rows are rendered. Adjust its configurable properties below to see how it reacts."), React.createElement(_ContentBox.ContentBoxParagraph, null, React.createElement("label", { className: _ListExample["default"].checkboxLabel }, React.createElement("input", { "aria-label": "Use dynamic row heights?", checked: useDynamicRowHeight, className: _ListExample["default"].checkbox, type: "checkbox", onChange: function onChange(event) { return _this2.setState({ useDynamicRowHeight: event.target.checked }); } }), "Use dynamic row heights?"), React.createElement("label", { className: _ListExample["default"].checkboxLabel }, React.createElement("input", { "aria-label": "Show scrolling placeholder?", checked: showScrollingPlaceholder, className: _ListExample["default"].checkbox, type: "checkbox", onChange: function onChange(event) { return _this2.setState({ showScrollingPlaceholder: event.target.checked }); } }), "Show scrolling placeholder?")), React.createElement(_LabeledInput.InputRow, null, React.createElement(_LabeledInput.LabeledInput, { label: "Num rows", name: "rowCount", onChange: this._onRowCountChange, value: rowCount }), React.createElement(_LabeledInput.LabeledInput, { label: "Scroll to", name: "onScrollToRow", placeholder: "Index...", onChange: this._onScrollToRowChange, value: scrollToIndex || '' }), React.createElement(_LabeledInput.LabeledInput, { label: "List height", name: "listHeight", onChange: function onChange(event) { return _this2.setState({ listHeight: parseInt(event.target.value, 10) || 1 }); }, value: listHeight }), React.createElement(_LabeledInput.LabeledInput, { disabled: useDynamicRowHeight, label: "Row height", name: "listRowHeight", onChange: function onChange(event) { return _this2.setState({ listRowHeight: parseInt(event.target.value, 10) || 1 }); }, value: listRowHeight }), React.createElement(_LabeledInput.LabeledInput, { label: "Overscan", name: "overscanRowCount", onChange: function onChange(event) { return _this2.setState({ overscanRowCount: parseInt(event.target.value, 10) || 0 }); }, value: overscanRowCount })), React.createElement("div", null, React.createElement(_AutoSizer["default"], { disableHeight: true }, function (_ref) { var width = _ref.width; return React.createElement(_List["default"], { ref: "List", className: _ListExample["default"].List, height: listHeight, overscanRowCount: overscanRowCount, noRowsRenderer: _this2._noRowsRenderer, rowCount: rowCount, rowHeight: useDynamicRowHeight ? _this2._getRowHeight : listRowHeight, rowRenderer: _this2._rowRenderer, scrollToIndex: scrollToIndex, width: width }); }))); } }, { key: "_getDatum", value: function _getDatum(index) { var list = this.context.list; return list.get(index % list.size); } }, { key: "_getRowHeight", value: function _getRowHeight(_ref2) { var index = _ref2.index; return this._getDatum(index).size; } }, { key: "_noRowsRenderer", value: function _noRowsRenderer() { return React.createElement("div", { className: _ListExample["default"].noRows }, "No rows"); } }, { key: "_onRowCountChange", value: function _onRowCountChange(event) { var rowCount = parseInt(event.target.value, 10) || 0; this.setState({ rowCount: rowCount }); } }, { key: "_onScrollToRowChange", value: function _onScrollToRowChange(event) { var rowCount = this.state.rowCount; var scrollToIndex = Math.min(rowCount - 1, parseInt(event.target.value, 10)); if (isNaN(scrollToIndex)) { scrollToIndex = undefined; } this.setState({ scrollToIndex: scrollToIndex }); } }, { key: "_rowRenderer", value: function _rowRenderer(_ref3) { var index = _ref3.index, isScrolling = _ref3.isScrolling, key = _ref3.key, style = _ref3.style; var _this$state2 = this.state, showScrollingPlaceholder = _this$state2.showScrollingPlaceholder, useDynamicRowHeight = _this$state2.useDynamicRowHeight; if (showScrollingPlaceholder && isScrolling) { return React.createElement("div", { className: (0, _clsx["default"])(_ListExample["default"].row, _ListExample["default"].isScrollingPlaceholder), key: key, style: style }, "Scrolling..."); } var datum = this._getDatum(index); var additionalContent; if (useDynamicRowHeight) { switch (datum.size) { case 75: additionalContent = React.createElement("div", null, "It is medium-sized."); break; case 100: additionalContent = React.createElement("div", null, "It is large-sized.", React.createElement("br", null), "It has a 3rd row."); break; } } return React.createElement("div", { className: _ListExample["default"].row, key: key, style: style }, React.createElement("div", { className: _ListExample["default"].letter, style: { backgroundColor: datum.color } }, datum.name.charAt(0)), React.createElement("div", null, React.createElement("div", { className: _ListExample["default"].name }, datum.name), React.createElement("div", { className: _ListExample["default"].index }, "This is row ", index), additionalContent), useDynamicRowHeight && React.createElement("span", { className: _ListExample["default"].height }, datum.size, "px")); } }]); return ListExample; }(React.PureComponent); exports["default"] = ListExample; (0, _defineProperty2["default"])(ListExample, "contextTypes", { list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired });dist/commonjs/AutoSizer/AutoSizer.jest.js000064400000031545151676725770014547 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _TestUtils = require("../TestUtils"); var _AutoSizer = _interopRequireDefault(require("./AutoSizer")); function DefaultChildComponent(_ref) { var height = _ref.height, width = _ref.width, foo = _ref.foo, bar = _ref.bar; return React.createElement("div", null, "width:".concat(width, ", height:").concat(height, ", foo:").concat(foo, ", bar:").concat(bar)); } describe('AutoSizer', function () { function getMarkup() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref2$bar = _ref2.bar, bar = _ref2$bar === void 0 ? 123 : _ref2$bar, _ref2$ChildComponent = _ref2.ChildComponent, ChildComponent = _ref2$ChildComponent === void 0 ? DefaultChildComponent : _ref2$ChildComponent, _ref2$className = _ref2.className, className = _ref2$className === void 0 ? undefined : _ref2$className, _ref2$defaultHeight = _ref2.defaultHeight, defaultHeight = _ref2$defaultHeight === void 0 ? undefined : _ref2$defaultHeight, _ref2$defaultWidth = _ref2.defaultWidth, defaultWidth = _ref2$defaultWidth === void 0 ? undefined : _ref2$defaultWidth, _ref2$disableHeight = _ref2.disableHeight, disableHeight = _ref2$disableHeight === void 0 ? false : _ref2$disableHeight, _ref2$disableWidth = _ref2.disableWidth, disableWidth = _ref2$disableWidth === void 0 ? false : _ref2$disableWidth, _ref2$foo = _ref2.foo, foo = _ref2$foo === void 0 ? 456 : _ref2$foo, _ref2$height = _ref2.height, height = _ref2$height === void 0 ? 100 : _ref2$height, onResize = _ref2.onResize, _ref2$paddingBottom = _ref2.paddingBottom, paddingBottom = _ref2$paddingBottom === void 0 ? 0 : _ref2$paddingBottom, _ref2$paddingLeft = _ref2.paddingLeft, paddingLeft = _ref2$paddingLeft === void 0 ? 0 : _ref2$paddingLeft, _ref2$paddingRight = _ref2.paddingRight, paddingRight = _ref2$paddingRight === void 0 ? 0 : _ref2$paddingRight, _ref2$paddingTop = _ref2.paddingTop, paddingTop = _ref2$paddingTop === void 0 ? 0 : _ref2$paddingTop, _ref2$style = _ref2.style, style = _ref2$style === void 0 ? undefined : _ref2$style, _ref2$width = _ref2.width, width = _ref2$width === void 0 ? 200 : _ref2$width; var wrapperStyle = { boxSizing: 'border-box', height: height, paddingBottom: paddingBottom, paddingLeft: paddingLeft, paddingRight: paddingRight, paddingTop: paddingTop, width: width }; mockOffsetSize(width, height); return React.createElement("div", { style: wrapperStyle }, React.createElement(_AutoSizer["default"], { className: className, defaultHeight: defaultHeight, defaultWidth: defaultWidth, disableHeight: disableHeight, disableWidth: disableWidth, onResize: onResize, style: style }, function (_ref3) { var height = _ref3.height, width = _ref3.width; return React.createElement(ChildComponent, { width: disableWidth ? undefined : width, height: disableHeight ? undefined : height, bar: bar, foo: foo }); })); } // AutoSizer uses offsetWidth and offsetHeight. // Jest runs in JSDom which doesn't support measurements APIs. function mockOffsetSize(width, height) { Object.defineProperty(HTMLElement.prototype, 'offsetHeight', { configurable: true, value: height }); Object.defineProperty(HTMLElement.prototype, 'offsetWidth', { configurable: true, value: width }); } it('should relay properties to ChildComponent or React child', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.textContent).toContain('foo:456'); expect(rendered.textContent).toContain('bar:123'); }); it('should set the correct initial width and height of ChildComponent or React child', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.textContent).toContain('height:100'); expect(rendered.textContent).toContain('width:200'); }); it('should account for padding when calculating the available width and height', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ paddingBottom: 10, paddingLeft: 4, paddingRight: 4, paddingTop: 15 }))); expect(rendered.textContent).toContain('height:75'); expect(rendered.textContent).toContain('width:192'); }); it('should not update :width if :disableWidth is true', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ disableWidth: true }))); expect(rendered.textContent).toContain('height:100'); expect(rendered.textContent).toContain('width:undefined'); }); it('should not update :height if :disableHeight is true', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ disableHeight: true }))); expect(rendered.textContent).toContain('height:undefined'); expect(rendered.textContent).toContain('width:200'); }); function simulateResize(_ref4) { var element, height, width, trigger; return _regenerator["default"].async(function simulateResize$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: element = _ref4.element, height = _ref4.height, width = _ref4.width; mockOffsetSize(width, height); // Trigger detectElementResize library by faking a scroll event // TestUtils Simulate doesn't work here in JSDom so we manually dispatch trigger = element.querySelector('.contract-trigger'); trigger.dispatchEvent(new Event('scroll')); // Allow requestAnimationFrame to be invoked before continuing _context.next = 6; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, 100); })); case 6: case "end": return _context.stop(); } } }); } it('should update :height after a resize event', function _callee(done) { var rendered; return _regenerator["default"].async(function _callee$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 100, width: 200 }))); expect(rendered.textContent).toContain('height:100'); expect(rendered.textContent).toContain('width:200'); _context2.next = 5; return _regenerator["default"].awrap(simulateResize({ element: rendered, height: 400, width: 300 })); case 5: expect(rendered.textContent).toContain('height:400'); expect(rendered.textContent).toContain('width:300'); done(); case 8: case "end": return _context2.stop(); } } }); }); describe('onResize and (re)render', function () { it('should trigger when size changes', function _callee2(done) { var onResize, ChildComponent, rendered; return _regenerator["default"].async(function _callee2$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: onResize = jest.fn(); ChildComponent = jest.fn().mockImplementation(DefaultChildComponent); rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ ChildComponent: ChildComponent, height: 100, onResize: onResize, width: 200 }))); ChildComponent.mockClear(); // TODO Improve initial check in version 10; see AutoSizer render() expect(onResize).toHaveBeenCalledTimes(1); _context3.next = 7; return _regenerator["default"].awrap(simulateResize({ element: rendered, height: 400, width: 300 })); case 7: expect(ChildComponent).toHaveBeenCalledTimes(1); expect(onResize).toHaveBeenCalledTimes(2); done(); case 10: case "end": return _context3.stop(); } } }); }); it('should only trigger when height changes for disableWidth == true', function _callee3(done) { var onResize, ChildComponent, rendered; return _regenerator["default"].async(function _callee3$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: onResize = jest.fn(); ChildComponent = jest.fn().mockImplementation(DefaultChildComponent); rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ ChildComponent: ChildComponent, disableWidth: true, height: 100, onResize: onResize, width: 200 }))); ChildComponent.mockClear(); // TODO Improve initial check in version 10; see AutoSizer render() expect(onResize).toHaveBeenCalledTimes(1); _context4.next = 7; return _regenerator["default"].awrap(simulateResize({ element: rendered, height: 100, width: 300 })); case 7: expect(ChildComponent).toHaveBeenCalledTimes(0); expect(onResize).toHaveBeenCalledTimes(1); _context4.next = 11; return _regenerator["default"].awrap(simulateResize({ element: rendered, height: 200, width: 300 })); case 11: expect(ChildComponent).toHaveBeenCalledTimes(1); expect(onResize).toHaveBeenCalledTimes(2); done(); case 14: case "end": return _context4.stop(); } } }); }); it('should only trigger when width changes for disableHeight == true', function _callee4(done) { var onResize, ChildComponent, rendered; return _regenerator["default"].async(function _callee4$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: onResize = jest.fn(); ChildComponent = jest.fn().mockImplementation(DefaultChildComponent); rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ ChildComponent: ChildComponent, disableHeight: true, height: 100, onResize: onResize, width: 200 }))); ChildComponent.mockClear(); // TODO Improve initial check in version 10; see AutoSizer render() expect(onResize).toHaveBeenCalledTimes(1); _context5.next = 7; return _regenerator["default"].awrap(simulateResize({ element: rendered, height: 200, width: 200 })); case 7: expect(ChildComponent).toHaveBeenCalledTimes(0); expect(onResize).toHaveBeenCalledTimes(1); _context5.next = 11; return _regenerator["default"].awrap(simulateResize({ element: rendered, height: 200, width: 300 })); case 11: expect(ChildComponent).toHaveBeenCalledTimes(1); expect(onResize).toHaveBeenCalledTimes(2); done(); case 14: case "end": return _context5.stop(); } } }); }); }); describe('className and style', function () { it('should use a custom :className if specified', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ className: 'foo' }))); expect(rendered.firstChild.className).toContain('foo'); }); it('should use a custom :style if specified', function () { var style = { backgroundColor: 'red' }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ style: style }))); expect(rendered.firstChild.style.backgroundColor).toEqual('red'); }); }); });dist/commonjs/AutoSizer/AutoSizer.js000064400000022232151676725770013574 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var React = _interopRequireWildcard(require("react")); var _detectElementResize = _interopRequireDefault(require("../vendor/detectElementResize")); var _propTypes = _interopRequireDefault(require("prop-types")); var _class, _temp; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var AutoSizer = (_temp = _class = /*#__PURE__*/ function (_React$Component) { (0, _inherits2["default"])(AutoSizer, _React$Component); function AutoSizer() { var _getPrototypeOf2; var _this; (0, _classCallCheck2["default"])(this, AutoSizer); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(AutoSizer)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", { height: _this.props.defaultHeight || 0, width: _this.props.defaultWidth || 0 }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_parentNode", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_autoSizer", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_window", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_detectElementResize", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onResize", function () { var _this$props = _this.props, disableHeight = _this$props.disableHeight, disableWidth = _this$props.disableWidth, onResize = _this$props.onResize; if (_this._parentNode) { // Guard against AutoSizer component being removed from the DOM immediately after being added. // This can result in invalid style values which can result in NaN values if we don't handle them. // See issue #150 for more context. var height = _this._parentNode.offsetHeight || 0; var width = _this._parentNode.offsetWidth || 0; var win = _this._window || window; var style = win.getComputedStyle(_this._parentNode) || {}; var paddingLeft = parseInt(style.paddingLeft, 10) || 0; var paddingRight = parseInt(style.paddingRight, 10) || 0; var paddingTop = parseInt(style.paddingTop, 10) || 0; var paddingBottom = parseInt(style.paddingBottom, 10) || 0; var newHeight = height - paddingTop - paddingBottom; var newWidth = width - paddingLeft - paddingRight; if (!disableHeight && _this.state.height !== newHeight || !disableWidth && _this.state.width !== newWidth) { _this.setState({ height: height - paddingTop - paddingBottom, width: width - paddingLeft - paddingRight }); onResize({ height: height, width: width }); } } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_setRef", function (autoSizer) { _this._autoSizer = autoSizer; }); return _this; } (0, _createClass2["default"])(AutoSizer, [{ key: "componentDidMount", value: function componentDidMount() { var nonce = this.props.nonce; if (this._autoSizer && this._autoSizer.parentNode && this._autoSizer.parentNode.ownerDocument && this._autoSizer.parentNode.ownerDocument.defaultView && this._autoSizer.parentNode instanceof this._autoSizer.parentNode.ownerDocument.defaultView.HTMLElement) { // Delay access of parentNode until mount. // This handles edge-cases where the component has already been unmounted before its ref has been set, // As well as libraries like react-lite which have a slightly different lifecycle. this._parentNode = this._autoSizer.parentNode; this._window = this._autoSizer.parentNode.ownerDocument.defaultView; // Defer requiring resize handler in order to support server-side rendering. // See issue #41 this._detectElementResize = (0, _detectElementResize["default"])(nonce, this._window); this._detectElementResize.addResizeListener(this._parentNode, this._onResize); this._onResize(); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this._detectElementResize && this._parentNode) { this._detectElementResize.removeResizeListener(this._parentNode, this._onResize); } } }, { key: "render", value: function render() { var _this$props2 = this.props, children = _this$props2.children, className = _this$props2.className, disableHeight = _this$props2.disableHeight, disableWidth = _this$props2.disableWidth, style = _this$props2.style; var _this$state = this.state, height = _this$state.height, width = _this$state.width; // Outer div should not force width/height since that may prevent containers from shrinking. // Inner component should overflow and use calculated width/height. // See issue #68 for more information. var outerStyle = { overflow: 'visible' }; var childParams = {}; if (!disableHeight) { outerStyle.height = 0; childParams.height = height; } if (!disableWidth) { outerStyle.width = 0; childParams.width = width; } /** * TODO: Avoid rendering children before the initial measurements have been collected. * At best this would just be wasting cycles. * Add this check into version 10 though as it could break too many ref callbacks in version 9. * Note that if default width/height props were provided this would still work with SSR. if ( height !== 0 && width !== 0 ) { child = children({ height, width }) } */ return React.createElement("div", { className: className, ref: this._setRef, style: _objectSpread({}, outerStyle, {}, style) }, children(childParams)); } }]); return AutoSizer; }(React.Component), (0, _defineProperty2["default"])(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { /** Function responsible for rendering children.*/ "children": _propTypes["default"].func.isRequired, /** Optional custom CSS class name to attach to root AutoSizer element. */ "className": _propTypes["default"].string, /** Default height to use for initial render; useful for SSR */ "defaultHeight": _propTypes["default"].number, /** Default width to use for initial render; useful for SSR */ "defaultWidth": _propTypes["default"].number, /** Disable dynamic :height property */ "disableHeight": _propTypes["default"].bool.isRequired, /** Disable dynamic :width property */ "disableWidth": _propTypes["default"].bool.isRequired, /** Nonce of the inlined stylesheet for Content Security Policy */ "nonce": _propTypes["default"].string, /** Callback to be invoked on-resize */ "onResize": _propTypes["default"].func.isRequired, /** Optional inline style */ "style": _propTypes["default"].object }), _temp); exports["default"] = AutoSizer; (0, _defineProperty2["default"])(AutoSizer, "defaultProps", { onResize: function onResize() {}, disableHeight: false, disableWidth: false, style: {} });dist/commonjs/AutoSizer/index.js000064400000000756151676725770012765 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function get() { return _AutoSizer["default"]; } }); Object.defineProperty(exports, "AutoSizer", { enumerable: true, get: function get() { return _AutoSizer["default"]; } }); var _AutoSizer = _interopRequireDefault(require("./AutoSizer"));dist/commonjs/AutoSizer/AutoSizer.example.js000064400000012622151676725770015230 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _immutable = require("immutable"); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _ContentBox = require("../demo/ContentBox"); var _AutoSizer = _interopRequireDefault(require("./AutoSizer")); var _List = _interopRequireWildcard(require("../List")); var _AutoSizerExample = _interopRequireDefault(require("./AutoSizer.example.css")); var _class, _temp; var AutoSizerExample = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(AutoSizerExample, _React$PureComponent); function AutoSizerExample() { var _getPrototypeOf2; var _this; (0, _classCallCheck2["default"])(this, AutoSizerExample); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(AutoSizerExample)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", { hideDescription: false }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rowRenderer", function (_ref) { var index = _ref.index, key = _ref.key, style = _ref.style; var list = _this.context.list; var row = list.get(index); return React.createElement("div", { key: key, className: _AutoSizerExample["default"].row, style: style }, row.name); }); return _this; } (0, _createClass2["default"])(AutoSizerExample, [{ key: "render", value: function render() { var _this2 = this; var list = this.context.list; var hideDescription = this.state.hideDescription; return React.createElement(_ContentBox.ContentBox, (0, _extends2["default"])({}, this.props, { style: { height: 400 } }), React.createElement(_ContentBox.ContentBoxHeader, { text: "AutoSizer", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/AutoSizer/AutoSizer.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/AutoSizer.md" }), React.createElement(_ContentBox.ContentBoxParagraph, null, React.createElement("label", { className: _AutoSizerExample["default"].checkboxLabel }, React.createElement("input", { "aria-label": "Hide description (to show resize)?", className: _AutoSizerExample["default"].checkbox, type: "checkbox", checked: hideDescription, onChange: function onChange(event) { return _this2.setState({ hideDescription: event.target.checked }); } }), "Hide description (to show resize)?")), !hideDescription && React.createElement(_ContentBox.ContentBoxParagraph, null, "This component decorates ", React.createElement("code", null, "List"), ", ", React.createElement("code", null, "Table"), ", or any other component and automatically manages its width and height. It uses Sebastian Decima's", ' ', React.createElement("a", { href: "https://github.com/sdecima/javascript-detect-element-resize", target: "_blank" }, "element resize event"), ' ', "to determine the appropriate size. In this example", ' ', React.createElement("code", null, "AutoSizer"), " grows to fill the remaining width and height of this flex column."), React.createElement("div", { className: _AutoSizerExample["default"].AutoSizerWrapper }, React.createElement(_AutoSizer["default"], null, function (_ref2) { var width = _ref2.width, height = _ref2.height; return React.createElement(_List["default"], { className: _AutoSizerExample["default"].List, height: height, rowCount: list.size, rowHeight: 30, rowRenderer: _this2._rowRenderer, width: width }); }))); } }]); return AutoSizerExample; }(React.PureComponent), (0, _defineProperty2["default"])(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : {}), _temp); exports["default"] = AutoSizerExample; (0, _defineProperty2["default"])(AutoSizerExample, "contextTypes", { list: _propTypes["default"].instanceOf(_immutable.List).isRequired });dist/commonjs/AutoSizer/AutoSizer.ssr.js000064400000001631151676725770014402 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var React = _interopRequireWildcard(require("react")); var ReactDOMServer = _interopRequireWildcard(require("react-dom/server")); var _AutoSizer = _interopRequireDefault(require("./AutoSizer")); /** * @jest-environment node */ test('should render content with default widths and heights initially', function () { var rendered = ReactDOMServer.renderToString(React.createElement(_AutoSizer["default"], { defaultHeight: 100, defaultWidth: 200 }, function (_ref) { var height = _ref.height, width = _ref.width; return React.createElement("div", null, "height:".concat(height, ";width:").concat(width)); })); expect(rendered).toContain('height:100'); expect(rendered).toContain('width:200'); });dist/commonjs/Grid/defaultOverscanIndicesGetter.jest.js000064400000005312151676725770017352 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _defaultOverscanIndicesGetter = _interopRequireWildcard(require("./defaultOverscanIndicesGetter")); describe('overscanIndicesGetter', function () { function testHelper(_ref) { var cellCount = _ref.cellCount, startIndex = _ref.startIndex, stopIndex = _ref.stopIndex, overscanCellsCount = _ref.overscanCellsCount, scrollDirection = _ref.scrollDirection; return (0, _defaultOverscanIndicesGetter["default"])({ cellCount: cellCount, overscanCellsCount: overscanCellsCount, scrollDirection: scrollDirection, startIndex: startIndex, stopIndex: stopIndex }); } it('should not overscan if :overscanCellsCount is 0', function () { expect(testHelper({ cellCount: 100, startIndex: 10, stopIndex: 20, overscanCellsCount: 0, scrollDirection: _defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD })).toEqual({ overscanStartIndex: 10, overscanStopIndex: 20 }); expect(testHelper({ cellCount: 100, startIndex: 10, stopIndex: 20, overscanCellsCount: 0, scrollDirection: _defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD })).toEqual({ overscanStartIndex: 10, overscanStopIndex: 20 }); }); it('should overscan forward', function () { expect(testHelper({ cellCount: 100, startIndex: 20, stopIndex: 30, overscanCellsCount: 10, scrollDirection: _defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD })).toEqual({ overscanStartIndex: 20, overscanStopIndex: 40 }); }); it('should overscan backward', function () { expect(testHelper({ cellCount: 100, startIndex: 20, stopIndex: 30, overscanCellsCount: 10, scrollDirection: _defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD })).toEqual({ overscanStartIndex: 10, overscanStopIndex: 30 }); }); it('should not overscan beyond the start of the list', function () { expect(testHelper({ cellCount: 100, startIndex: 5, stopIndex: 15, overscanCellsCount: 10, scrollDirection: _defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD })).toEqual({ overscanStartIndex: 0, overscanStopIndex: 15 }); }); it('should not overscan beyond the end of the list', function () { expect(testHelper({ cellCount: 25, startIndex: 10, stopIndex: 20, overscanCellsCount: 10, scrollDirection: _defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD })).toEqual({ overscanStartIndex: 10, overscanStopIndex: 24 }); }); });dist/commonjs/Grid/types.js000064400000021152151676725770011753 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports.bpfrpt_proptype_VisibleCellRange = exports.bpfrpt_proptype_Alignment = exports.bpfrpt_proptype_OverscanIndicesGetter = exports.bpfrpt_proptype_OverscanIndices = exports.bpfrpt_proptype_OverscanIndicesGetterParams = exports.bpfrpt_proptype_RenderedSection = exports.bpfrpt_proptype_ScrollbarPresenceChange = exports.bpfrpt_proptype_Scroll = exports.bpfrpt_proptype_NoContentRenderer = exports.bpfrpt_proptype_CellSize = exports.bpfrpt_proptype_CellSizeGetter = exports.bpfrpt_proptype_CellRangeRenderer = exports.bpfrpt_proptype_CellRangeRendererParams = exports.bpfrpt_proptype_StyleCache = exports.bpfrpt_proptype_CellCache = exports.bpfrpt_proptype_CellRenderer = exports.bpfrpt_proptype_CellRendererParams = exports.bpfrpt_proptype_CellPosition = void 0; var React = _interopRequireWildcard(require("react")); var _ScalingCellSizeAndPositionManager = _interopRequireDefault(require("./utils/ScalingCellSizeAndPositionManager")); var _propTypes = _interopRequireDefault(require("prop-types")); var bpfrpt_proptype_CellPosition = process.env.NODE_ENV === 'production' ? null : { "columnIndex": _propTypes["default"].number.isRequired, "rowIndex": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_CellPosition = bpfrpt_proptype_CellPosition; var bpfrpt_proptype_CellRendererParams = process.env.NODE_ENV === 'production' ? null : { "columnIndex": _propTypes["default"].number.isRequired, "isScrolling": _propTypes["default"].bool.isRequired, "isVisible": _propTypes["default"].bool.isRequired, "key": _propTypes["default"].string.isRequired, "parent": _propTypes["default"].object.isRequired, "rowIndex": _propTypes["default"].number.isRequired, "style": _propTypes["default"].object.isRequired }; exports.bpfrpt_proptype_CellRendererParams = bpfrpt_proptype_CellRendererParams; var bpfrpt_proptype_CellRenderer = process.env.NODE_ENV === 'production' ? null : _propTypes["default"].func; exports.bpfrpt_proptype_CellRenderer = bpfrpt_proptype_CellRenderer; var bpfrpt_proptype_CellCache = process.env.NODE_ENV === 'production' ? null : _propTypes["default"].objectOf(_propTypes["default"].node.isRequired); exports.bpfrpt_proptype_CellCache = bpfrpt_proptype_CellCache; var bpfrpt_proptype_StyleCache = process.env.NODE_ENV === 'production' ? null : _propTypes["default"].objectOf(_propTypes["default"].object.isRequired); exports.bpfrpt_proptype_StyleCache = bpfrpt_proptype_StyleCache; var bpfrpt_proptype_CellRangeRendererParams = process.env.NODE_ENV === 'production' ? null : { "cellCache": _propTypes["default"].objectOf(_propTypes["default"].node.isRequired).isRequired, "cellRenderer": _propTypes["default"].func.isRequired, "columnSizeAndPositionManager": function columnSizeAndPositionManager() { return (typeof _ScalingCellSizeAndPositionManager["default"] === "function" ? _propTypes["default"].instanceOf(_ScalingCellSizeAndPositionManager["default"]).isRequired : _propTypes["default"].any.isRequired).apply(this, arguments); }, "columnStartIndex": _propTypes["default"].number.isRequired, "columnStopIndex": _propTypes["default"].number.isRequired, "deferredMeasurementCache": _propTypes["default"].object, "horizontalOffsetAdjustment": _propTypes["default"].number.isRequired, "isScrolling": _propTypes["default"].bool.isRequired, "isScrollingOptOut": _propTypes["default"].bool.isRequired, "parent": _propTypes["default"].object.isRequired, "rowSizeAndPositionManager": function rowSizeAndPositionManager() { return (typeof _ScalingCellSizeAndPositionManager["default"] === "function" ? _propTypes["default"].instanceOf(_ScalingCellSizeAndPositionManager["default"]).isRequired : _propTypes["default"].any.isRequired).apply(this, arguments); }, "rowStartIndex": _propTypes["default"].number.isRequired, "rowStopIndex": _propTypes["default"].number.isRequired, "scrollLeft": _propTypes["default"].number.isRequired, "scrollTop": _propTypes["default"].number.isRequired, "styleCache": _propTypes["default"].objectOf(_propTypes["default"].object.isRequired).isRequired, "verticalOffsetAdjustment": _propTypes["default"].number.isRequired, "visibleColumnIndices": _propTypes["default"].object.isRequired, "visibleRowIndices": _propTypes["default"].object.isRequired }; exports.bpfrpt_proptype_CellRangeRendererParams = bpfrpt_proptype_CellRangeRendererParams; var bpfrpt_proptype_CellRangeRenderer = process.env.NODE_ENV === 'production' ? null : _propTypes["default"].func; exports.bpfrpt_proptype_CellRangeRenderer = bpfrpt_proptype_CellRangeRenderer; var bpfrpt_proptype_CellSizeGetter = process.env.NODE_ENV === 'production' ? null : _propTypes["default"].func; exports.bpfrpt_proptype_CellSizeGetter = bpfrpt_proptype_CellSizeGetter; var bpfrpt_proptype_CellSize = process.env.NODE_ENV === 'production' ? null : _propTypes["default"].oneOfType([_propTypes["default"].func, _propTypes["default"].number]); exports.bpfrpt_proptype_CellSize = bpfrpt_proptype_CellSize; var bpfrpt_proptype_NoContentRenderer = process.env.NODE_ENV === 'production' ? null : _propTypes["default"].func; exports.bpfrpt_proptype_NoContentRenderer = bpfrpt_proptype_NoContentRenderer; var bpfrpt_proptype_Scroll = process.env.NODE_ENV === 'production' ? null : { "clientHeight": _propTypes["default"].number.isRequired, "clientWidth": _propTypes["default"].number.isRequired, "scrollHeight": _propTypes["default"].number.isRequired, "scrollLeft": _propTypes["default"].number.isRequired, "scrollTop": _propTypes["default"].number.isRequired, "scrollWidth": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_Scroll = bpfrpt_proptype_Scroll; var bpfrpt_proptype_ScrollbarPresenceChange = process.env.NODE_ENV === 'production' ? null : { "horizontal": _propTypes["default"].bool.isRequired, "vertical": _propTypes["default"].bool.isRequired, "size": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_ScrollbarPresenceChange = bpfrpt_proptype_ScrollbarPresenceChange; var bpfrpt_proptype_RenderedSection = process.env.NODE_ENV === 'production' ? null : { "columnOverscanStartIndex": _propTypes["default"].number.isRequired, "columnOverscanStopIndex": _propTypes["default"].number.isRequired, "columnStartIndex": _propTypes["default"].number.isRequired, "columnStopIndex": _propTypes["default"].number.isRequired, "rowOverscanStartIndex": _propTypes["default"].number.isRequired, "rowOverscanStopIndex": _propTypes["default"].number.isRequired, "rowStartIndex": _propTypes["default"].number.isRequired, "rowStopIndex": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_RenderedSection = bpfrpt_proptype_RenderedSection; var bpfrpt_proptype_OverscanIndicesGetterParams = process.env.NODE_ENV === 'production' ? null : { // One of SCROLL_DIRECTION_HORIZONTAL or SCROLL_DIRECTION_VERTICAL "direction": _propTypes["default"].oneOf(["horizontal", "vertical"]).isRequired, // One of SCROLL_DIRECTION_BACKWARD or SCROLL_DIRECTION_FORWARD "scrollDirection": _propTypes["default"].oneOf([-1, 1]).isRequired, // Number of rows or columns in the current axis "cellCount": _propTypes["default"].number.isRequired, // Maximum number of cells to over-render in either direction "overscanCellsCount": _propTypes["default"].number.isRequired, // Begin of range of visible cells "startIndex": _propTypes["default"].number.isRequired, // End of range of visible cells "stopIndex": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_OverscanIndicesGetterParams = bpfrpt_proptype_OverscanIndicesGetterParams; var bpfrpt_proptype_OverscanIndices = process.env.NODE_ENV === 'production' ? null : { "overscanStartIndex": _propTypes["default"].number.isRequired, "overscanStopIndex": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_OverscanIndices = bpfrpt_proptype_OverscanIndices; var bpfrpt_proptype_OverscanIndicesGetter = process.env.NODE_ENV === 'production' ? null : _propTypes["default"].func; exports.bpfrpt_proptype_OverscanIndicesGetter = bpfrpt_proptype_OverscanIndicesGetter; var bpfrpt_proptype_Alignment = process.env.NODE_ENV === 'production' ? null : _propTypes["default"].oneOf(["auto", "end", "start", "center"]); exports.bpfrpt_proptype_Alignment = bpfrpt_proptype_Alignment; var bpfrpt_proptype_VisibleCellRange = process.env.NODE_ENV === 'production' ? null : { "start": _propTypes["default"].number, "stop": _propTypes["default"].number }; exports.bpfrpt_proptype_VisibleCellRange = bpfrpt_proptype_VisibleCellRange;dist/commonjs/Grid/Grid.example.js000064400000033115151676725770013130 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _immutable = _interopRequireDefault(require("immutable")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _ContentBox = require("../demo/ContentBox"); var _LabeledInput = require("../demo/LabeledInput"); var _AutoSizer = _interopRequireDefault(require("../AutoSizer")); var _Grid = _interopRequireDefault(require("./Grid")); var _clsx2 = _interopRequireDefault(require("clsx")); var _GridExample = _interopRequireDefault(require("./Grid.example.css")); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var GridExample = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(GridExample, _React$PureComponent); function GridExample(props, context) { var _this; (0, _classCallCheck2["default"])(this, GridExample); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(GridExample).call(this, props, context)); _this.state = { columnCount: 1000, height: 300, overscanColumnCount: 0, overscanRowCount: 10, rowHeight: 40, rowCount: 1000, scrollToColumn: undefined, scrollToRow: undefined, useDynamicRowHeight: false }; _this._cellRenderer = _this._cellRenderer.bind((0, _assertThisInitialized2["default"])(_this)); _this._getColumnWidth = _this._getColumnWidth.bind((0, _assertThisInitialized2["default"])(_this)); _this._getRowClassName = _this._getRowClassName.bind((0, _assertThisInitialized2["default"])(_this)); _this._getRowHeight = _this._getRowHeight.bind((0, _assertThisInitialized2["default"])(_this)); _this._noContentRenderer = _this._noContentRenderer.bind((0, _assertThisInitialized2["default"])(_this)); _this._onColumnCountChange = _this._onColumnCountChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._onRowCountChange = _this._onRowCountChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._onScrollToColumnChange = _this._onScrollToColumnChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._onScrollToRowChange = _this._onScrollToRowChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._renderBodyCell = _this._renderBodyCell.bind((0, _assertThisInitialized2["default"])(_this)); _this._renderLeftSideCell = _this._renderLeftSideCell.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(GridExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, columnCount = _this$state.columnCount, height = _this$state.height, overscanColumnCount = _this$state.overscanColumnCount, overscanRowCount = _this$state.overscanRowCount, rowHeight = _this$state.rowHeight, rowCount = _this$state.rowCount, scrollToColumn = _this$state.scrollToColumn, scrollToRow = _this$state.scrollToRow, useDynamicRowHeight = _this$state.useDynamicRowHeight; return React.createElement(_ContentBox.ContentBox, null, React.createElement(_ContentBox.ContentBoxHeader, { text: "Grid", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/Grid/Grid.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/Grid.md" }), React.createElement(_ContentBox.ContentBoxParagraph, null, "Renders tabular data with virtualization along the vertical and horizontal axes. Row heights and column widths must be calculated ahead of time and specified as a fixed size or returned by a getter function."), React.createElement(_ContentBox.ContentBoxParagraph, null, React.createElement("label", { className: _GridExample["default"].checkboxLabel }, React.createElement("input", { "aria-label": "Use dynamic row height?", className: _GridExample["default"].checkbox, type: "checkbox", value: useDynamicRowHeight, onChange: function onChange(event) { return _this2._updateUseDynamicRowHeights(event.target.checked); } }), "Use dynamic row height?")), React.createElement(_LabeledInput.InputRow, null, React.createElement(_LabeledInput.LabeledInput, { label: "Num columns", name: "columnCount", onChange: this._onColumnCountChange, value: columnCount }), React.createElement(_LabeledInput.LabeledInput, { label: "Num rows", name: "rowCount", onChange: this._onRowCountChange, value: rowCount }), React.createElement(_LabeledInput.LabeledInput, { label: "Scroll to column", name: "onScrollToColumn", placeholder: "Index...", onChange: this._onScrollToColumnChange, value: scrollToColumn || '' }), React.createElement(_LabeledInput.LabeledInput, { label: "Scroll to row", name: "onScrollToRow", placeholder: "Index...", onChange: this._onScrollToRowChange, value: scrollToRow || '' }), React.createElement(_LabeledInput.LabeledInput, { label: "List height", name: "height", onChange: function onChange(event) { return _this2.setState({ height: parseInt(event.target.value, 10) || 1 }); }, value: height }), React.createElement(_LabeledInput.LabeledInput, { disabled: useDynamicRowHeight, label: "Row height", name: "rowHeight", onChange: function onChange(event) { return _this2.setState({ rowHeight: parseInt(event.target.value, 10) || 1 }); }, value: rowHeight }), React.createElement(_LabeledInput.LabeledInput, { label: "Overscan columns", name: "overscanColumnCount", onChange: function onChange(event) { return _this2.setState({ overscanColumnCount: parseInt(event.target.value, 10) || 0 }); }, value: overscanColumnCount }), React.createElement(_LabeledInput.LabeledInput, { label: "Overscan rows", name: "overscanRowCount", onChange: function onChange(event) { return _this2.setState({ overscanRowCount: parseInt(event.target.value, 10) || 0 }); }, value: overscanRowCount })), React.createElement(_AutoSizer["default"], { disableHeight: true }, function (_ref) { var width = _ref.width; return React.createElement(_Grid["default"], { cellRenderer: _this2._cellRenderer, className: _GridExample["default"].BodyGrid, columnWidth: _this2._getColumnWidth, columnCount: columnCount, height: height, noContentRenderer: _this2._noContentRenderer, overscanColumnCount: overscanColumnCount, overscanRowCount: overscanRowCount, rowHeight: useDynamicRowHeight ? _this2._getRowHeight : rowHeight, rowCount: rowCount, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow, width: width }); })); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref2) { var columnIndex = _ref2.columnIndex, key = _ref2.key, rowIndex = _ref2.rowIndex, style = _ref2.style; if (columnIndex === 0) { return this._renderLeftSideCell({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } else { return this._renderBodyCell({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } } }, { key: "_getColumnWidth", value: function _getColumnWidth(_ref3) { var index = _ref3.index; switch (index) { case 0: return 50; case 1: return 100; case 2: return 300; default: return 80; } } }, { key: "_getDatum", value: function _getDatum(index) { var list = this.context.list; return list.get(index % list.size); } }, { key: "_getRowClassName", value: function _getRowClassName(row) { return row % 2 === 0 ? _GridExample["default"].evenRow : _GridExample["default"].oddRow; } }, { key: "_getRowHeight", value: function _getRowHeight(_ref4) { var index = _ref4.index; return this._getDatum(index).size; } }, { key: "_noContentRenderer", value: function _noContentRenderer() { return React.createElement("div", { className: _GridExample["default"].noCells }, "No cells"); } }, { key: "_renderBodyCell", value: function _renderBodyCell(_ref5) { var columnIndex = _ref5.columnIndex, key = _ref5.key, rowIndex = _ref5.rowIndex, style = _ref5.style; var rowClass = this._getRowClassName(rowIndex); var datum = this._getDatum(rowIndex); var content; switch (columnIndex) { case 1: content = datum.name; break; case 2: content = datum.random; break; default: content = "r:".concat(rowIndex, ", c:").concat(columnIndex); break; } var classNames = (0, _clsx2["default"])(rowClass, _GridExample["default"].cell, (0, _defineProperty2["default"])({}, _GridExample["default"].centeredCell, columnIndex > 2)); return React.createElement("div", { className: classNames, key: key, style: style }, content); } }, { key: "_renderLeftSideCell", value: function _renderLeftSideCell(_ref6) { var key = _ref6.key, rowIndex = _ref6.rowIndex, style = _ref6.style; var datum = this._getDatum(rowIndex); var classNames = (0, _clsx2["default"])(_GridExample["default"].cell, _GridExample["default"].letterCell); // Don't modify styles. // These are frozen by React now (as of 16.0.0). // Since Grid caches and re-uses them, they aren't safe to modify. style = _objectSpread({}, style, { backgroundColor: datum.color }); return React.createElement("div", { className: classNames, key: key, style: style }, datum.name.charAt(0)); } }, { key: "_updateUseDynamicRowHeights", value: function _updateUseDynamicRowHeights(value) { this.setState({ useDynamicRowHeight: value }); } }, { key: "_onColumnCountChange", value: function _onColumnCountChange(event) { var columnCount = parseInt(event.target.value, 10) || 0; this.setState({ columnCount: columnCount }); } }, { key: "_onRowCountChange", value: function _onRowCountChange(event) { var rowCount = parseInt(event.target.value, 10) || 0; this.setState({ rowCount: rowCount }); } }, { key: "_onScrollToColumnChange", value: function _onScrollToColumnChange(event) { var columnCount = this.state.columnCount; var scrollToColumn = Math.min(columnCount - 1, parseInt(event.target.value, 10)); if (isNaN(scrollToColumn)) { scrollToColumn = undefined; } this.setState({ scrollToColumn: scrollToColumn }); } }, { key: "_onScrollToRowChange", value: function _onScrollToRowChange(event) { var rowCount = this.state.rowCount; var scrollToRow = Math.min(rowCount - 1, parseInt(event.target.value, 10)); if (isNaN(scrollToRow)) { scrollToRow = undefined; } this.setState({ scrollToRow: scrollToRow }); } }]); return GridExample; }(React.PureComponent); exports["default"] = GridExample; (0, _defineProperty2["default"])(GridExample, "contextTypes", { list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired });dist/commonjs/Grid/defaultCellRangeRenderer.js000064400000013456151676725770015507 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = defaultCellRangeRenderer; var _types = require("./types"); /** * Default implementation of cellRangeRenderer used by Grid. * This renderer supports cell-caching while the user is scrolling. */ function defaultCellRangeRenderer(_ref) { var cellCache = _ref.cellCache, cellRenderer = _ref.cellRenderer, columnSizeAndPositionManager = _ref.columnSizeAndPositionManager, columnStartIndex = _ref.columnStartIndex, columnStopIndex = _ref.columnStopIndex, deferredMeasurementCache = _ref.deferredMeasurementCache, horizontalOffsetAdjustment = _ref.horizontalOffsetAdjustment, isScrolling = _ref.isScrolling, isScrollingOptOut = _ref.isScrollingOptOut, parent = _ref.parent, rowSizeAndPositionManager = _ref.rowSizeAndPositionManager, rowStartIndex = _ref.rowStartIndex, rowStopIndex = _ref.rowStopIndex, styleCache = _ref.styleCache, verticalOffsetAdjustment = _ref.verticalOffsetAdjustment, visibleColumnIndices = _ref.visibleColumnIndices, visibleRowIndices = _ref.visibleRowIndices; var renderedCells = []; // Browsers have native size limits for elements (eg Chrome 33M pixels, IE 1.5M pixes). // User cannot scroll beyond these size limitations. // In order to work around this, ScalingCellSizeAndPositionManager compresses offsets. // We should never cache styles for compressed offsets though as this can lead to bugs. // See issue #576 for more. var areOffsetsAdjusted = columnSizeAndPositionManager.areOffsetsAdjusted() || rowSizeAndPositionManager.areOffsetsAdjusted(); var canCacheStyle = !isScrolling && !areOffsetsAdjusted; for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) { var rowDatum = rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex); for (var columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) { var columnDatum = columnSizeAndPositionManager.getSizeAndPositionOfCell(columnIndex); var isVisible = columnIndex >= visibleColumnIndices.start && columnIndex <= visibleColumnIndices.stop && rowIndex >= visibleRowIndices.start && rowIndex <= visibleRowIndices.stop; var key = "".concat(rowIndex, "-").concat(columnIndex); var style = void 0; // Cache style objects so shallow-compare doesn't re-render unnecessarily. if (canCacheStyle && styleCache[key]) { style = styleCache[key]; } else { // In deferred mode, cells will be initially rendered before we know their size. // Don't interfere with CellMeasurer's measurements by setting an invalid size. if (deferredMeasurementCache && !deferredMeasurementCache.has(rowIndex, columnIndex)) { // Position not-yet-measured cells at top/left 0,0, // And give them width/height of 'auto' so they can grow larger than the parent Grid if necessary. // Positioning them further to the right/bottom influences their measured size. style = { height: 'auto', left: 0, position: 'absolute', top: 0, width: 'auto' }; } else { style = { height: rowDatum.size, left: columnDatum.offset + horizontalOffsetAdjustment, position: 'absolute', top: rowDatum.offset + verticalOffsetAdjustment, width: columnDatum.size }; styleCache[key] = style; } } var cellRendererParams = { columnIndex: columnIndex, isScrolling: isScrolling, isVisible: isVisible, key: key, parent: parent, rowIndex: rowIndex, style: style }; var renderedCell = void 0; // Avoid re-creating cells while scrolling. // This can lead to the same cell being created many times and can cause performance issues for "heavy" cells. // If a scroll is in progress- cache and reuse cells. // This cache will be thrown away once scrolling completes. // However if we are scaling scroll positions and sizes, we should also avoid caching. // This is because the offset changes slightly as scroll position changes and caching leads to stale values. // For more info refer to issue #395 // // If isScrollingOptOut is specified, we always cache cells. // For more info refer to issue #1028 if ((isScrollingOptOut || isScrolling) && !horizontalOffsetAdjustment && !verticalOffsetAdjustment) { if (!cellCache[key]) { cellCache[key] = cellRenderer(cellRendererParams); } renderedCell = cellCache[key]; // If the user is no longer scrolling, don't cache cells. // This makes dynamic cell content difficult for users and would also lead to a heavier memory footprint. } else { renderedCell = cellRenderer(cellRendererParams); } if (renderedCell == null || renderedCell === false) { continue; } if (process.env.NODE_ENV !== 'production') { warnAboutMissingStyle(parent, renderedCell); } renderedCells.push(renderedCell); } } return renderedCells; } function warnAboutMissingStyle(parent, renderedCell) { if (process.env.NODE_ENV !== 'production') { if (renderedCell) { // If the direct child is a CellMeasurer, then we should check its child // See issue #611 if (renderedCell.type && renderedCell.type.__internalCellMeasurerFlag) { renderedCell = renderedCell.props.children; } if (renderedCell && renderedCell.props && renderedCell.props.style === undefined && parent.__warnedAboutMissingStyle !== true) { parent.__warnedAboutMissingStyle = true; console.warn('Rendered cell should include style property for positioning.'); } } } }dist/commonjs/Grid/Grid.js000064400000205267151676725770011507 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.DEFAULT_SCROLLING_RESET_TIME_INTERVAL = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var React = _interopRequireWildcard(require("react")); var _clsx = _interopRequireDefault(require("clsx")); var _calculateSizeAndPositionDataAndUpdateScrollOffset = _interopRequireDefault(require("./utils/calculateSizeAndPositionDataAndUpdateScrollOffset")); var _ScalingCellSizeAndPositionManager = _interopRequireDefault(require("./utils/ScalingCellSizeAndPositionManager")); var _createCallbackMemoizer = _interopRequireDefault(require("../utils/createCallbackMemoizer")); var _defaultOverscanIndicesGetter = _interopRequireWildcard(require("./defaultOverscanIndicesGetter")); var _updateScrollIndexHelper = _interopRequireDefault(require("./utils/updateScrollIndexHelper")); var _defaultCellRangeRenderer = _interopRequireDefault(require("./defaultCellRangeRenderer")); var _scrollbarSize = _interopRequireDefault(require("dom-helpers/scrollbarSize")); var _reactLifecyclesCompat = require("react-lifecycles-compat"); var _requestAnimationTimeout = require("../utils/requestAnimationTimeout"); var _types = require("./types"); var _propTypes = _interopRequireDefault(require("prop-types")); var _class, _temp; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * Specifies the number of milliseconds during which to disable pointer events while a scroll is in progress. * This improves performance and makes scrolling smoother. */ var DEFAULT_SCROLLING_RESET_TIME_INTERVAL = 150; /** * Controls whether the Grid updates the DOM element's scrollLeft/scrollTop based on the current state or just observes it. * This prevents Grid from interrupting mouse-wheel animations (see issue #2). */ exports.DEFAULT_SCROLLING_RESET_TIME_INTERVAL = DEFAULT_SCROLLING_RESET_TIME_INTERVAL; var SCROLL_POSITION_CHANGE_REASONS = { OBSERVED: 'observed', REQUESTED: 'requested' }; var renderNull = function renderNull() { return null; }; /** * Renders tabular data with virtualization along the vertical and horizontal axes. * Row heights and column widths must be known ahead of time and specified as properties. */ var Grid = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(Grid, _React$PureComponent); // Invokes onSectionRendered callback only when start/stop row or column indices change function Grid(props) { var _this; (0, _classCallCheck2["default"])(this, Grid); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(Grid).call(this, props)); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onGridRenderedMemoizer", (0, _createCallbackMemoizer["default"])()); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onScrollMemoizer", (0, _createCallbackMemoizer["default"])(false)); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_deferredInvalidateColumnIndex", null); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_deferredInvalidateRowIndex", null); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_recomputeScrollLeftFlag", false); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_recomputeScrollTopFlag", false); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_horizontalScrollBarSize", 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_verticalScrollBarSize", 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_scrollbarPresenceChanged", false); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_scrollingContainer", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_childrenToDisplay", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_columnStartIndex", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_columnStopIndex", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rowStartIndex", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rowStopIndex", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderedColumnStartIndex", 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderedColumnStopIndex", 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderedRowStartIndex", 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_renderedRowStopIndex", 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_initialScrollTop", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_initialScrollLeft", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_disablePointerEventsTimeoutId", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_styleCache", {}); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_cellCache", {}); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_debounceScrollEndedCallback", function () { _this._disablePointerEventsTimeoutId = null; // isScrolling is used to determine if we reset styleCache _this.setState({ isScrolling: false, needToResetStyleCache: false }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_invokeOnGridRenderedHelper", function () { var onSectionRendered = _this.props.onSectionRendered; _this._onGridRenderedMemoizer({ callback: onSectionRendered, indices: { columnOverscanStartIndex: _this._columnStartIndex, columnOverscanStopIndex: _this._columnStopIndex, columnStartIndex: _this._renderedColumnStartIndex, columnStopIndex: _this._renderedColumnStopIndex, rowOverscanStartIndex: _this._rowStartIndex, rowOverscanStopIndex: _this._rowStopIndex, rowStartIndex: _this._renderedRowStartIndex, rowStopIndex: _this._renderedRowStopIndex } }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_setScrollingContainerRef", function (ref) { _this._scrollingContainer = ref; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onScroll", function (event) { // In certain edge-cases React dispatches an onScroll event with an invalid target.scrollLeft / target.scrollTop. // This invalid event can be detected by comparing event.target to this component's scrollable DOM element. // See issue #404 for more information. if (event.target === _this._scrollingContainer) { _this.handleScrollEvent(event.target); } }); var columnSizeAndPositionManager = new _ScalingCellSizeAndPositionManager["default"]({ cellCount: props.columnCount, cellSizeGetter: function cellSizeGetter(params) { return Grid._wrapSizeGetter(props.columnWidth)(params); }, estimatedCellSize: Grid._getEstimatedColumnSize(props) }); var rowSizeAndPositionManager = new _ScalingCellSizeAndPositionManager["default"]({ cellCount: props.rowCount, cellSizeGetter: function cellSizeGetter(params) { return Grid._wrapSizeGetter(props.rowHeight)(params); }, estimatedCellSize: Grid._getEstimatedRowSize(props) }); _this.state = { instanceProps: { columnSizeAndPositionManager: columnSizeAndPositionManager, rowSizeAndPositionManager: rowSizeAndPositionManager, prevColumnWidth: props.columnWidth, prevRowHeight: props.rowHeight, prevColumnCount: props.columnCount, prevRowCount: props.rowCount, prevIsScrolling: props.isScrolling === true, prevScrollToColumn: props.scrollToColumn, prevScrollToRow: props.scrollToRow, scrollbarSize: 0, scrollbarSizeMeasured: false }, isScrolling: false, scrollDirectionHorizontal: _defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD, scrollDirectionVertical: _defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD, scrollLeft: 0, scrollTop: 0, scrollPositionChangeReason: null, needToResetStyleCache: false }; if (props.scrollToRow > 0) { _this._initialScrollTop = _this._getCalculatedScrollTop(props, _this.state); } if (props.scrollToColumn > 0) { _this._initialScrollLeft = _this._getCalculatedScrollLeft(props, _this.state); } return _this; } /** * Gets offsets for a given cell and alignment. */ (0, _createClass2["default"])(Grid, [{ key: "getOffsetForCell", value: function getOffsetForCell() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$alignment = _ref.alignment, alignment = _ref$alignment === void 0 ? this.props.scrollToAlignment : _ref$alignment, _ref$columnIndex = _ref.columnIndex, columnIndex = _ref$columnIndex === void 0 ? this.props.scrollToColumn : _ref$columnIndex, _ref$rowIndex = _ref.rowIndex, rowIndex = _ref$rowIndex === void 0 ? this.props.scrollToRow : _ref$rowIndex; var offsetProps = _objectSpread({}, this.props, { scrollToAlignment: alignment, scrollToColumn: columnIndex, scrollToRow: rowIndex }); return { scrollLeft: this._getCalculatedScrollLeft(offsetProps), scrollTop: this._getCalculatedScrollTop(offsetProps) }; } /** * Gets estimated total rows' height. */ }, { key: "getTotalRowsHeight", value: function getTotalRowsHeight() { return this.state.instanceProps.rowSizeAndPositionManager.getTotalSize(); } /** * Gets estimated total columns' width. */ }, { key: "getTotalColumnsWidth", value: function getTotalColumnsWidth() { return this.state.instanceProps.columnSizeAndPositionManager.getTotalSize(); } /** * This method handles a scroll event originating from an external scroll control. * It's an advanced method and should probably not be used unless you're implementing a custom scroll-bar solution. */ }, { key: "handleScrollEvent", value: function handleScrollEvent(_ref2) { var _ref2$scrollLeft = _ref2.scrollLeft, scrollLeftParam = _ref2$scrollLeft === void 0 ? 0 : _ref2$scrollLeft, _ref2$scrollTop = _ref2.scrollTop, scrollTopParam = _ref2$scrollTop === void 0 ? 0 : _ref2$scrollTop; // On iOS, we can arrive at negative offsets by swiping past the start. // To prevent flicker here, we make playing in the negative offset zone cause nothing to happen. if (scrollTopParam < 0) { return; } // Prevent pointer events from interrupting a smooth scroll this._debounceScrollEnded(); var _this$props = this.props, autoHeight = _this$props.autoHeight, autoWidth = _this$props.autoWidth, height = _this$props.height, width = _this$props.width; var instanceProps = this.state.instanceProps; // When this component is shrunk drastically, React dispatches a series of back-to-back scroll events, // Gradually converging on a scrollTop that is within the bounds of the new, smaller height. // This causes a series of rapid renders that is slow for long lists. // We can avoid that by doing some simple bounds checking to ensure that scroll offsets never exceed their bounds. var scrollbarSize = instanceProps.scrollbarSize; var totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(); var totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(); var scrollLeft = Math.min(Math.max(0, totalColumnsWidth - width + scrollbarSize), scrollLeftParam); var scrollTop = Math.min(Math.max(0, totalRowsHeight - height + scrollbarSize), scrollTopParam); // Certain devices (like Apple touchpad) rapid-fire duplicate events. // Don't force a re-render if this is the case. // The mouse may move faster then the animation frame does. // Use requestAnimationFrame to avoid over-updating. if (this.state.scrollLeft !== scrollLeft || this.state.scrollTop !== scrollTop) { // Track scrolling direction so we can more efficiently overscan rows to reduce empty space around the edges while scrolling. // Don't change direction for an axis unless scroll offset has changed. var scrollDirectionHorizontal = scrollLeft !== this.state.scrollLeft ? scrollLeft > this.state.scrollLeft ? _defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD : _defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD : this.state.scrollDirectionHorizontal; var scrollDirectionVertical = scrollTop !== this.state.scrollTop ? scrollTop > this.state.scrollTop ? _defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD : _defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD : this.state.scrollDirectionVertical; var newState = { isScrolling: true, scrollDirectionHorizontal: scrollDirectionHorizontal, scrollDirectionVertical: scrollDirectionVertical, scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS.OBSERVED }; if (!autoHeight) { newState.scrollTop = scrollTop; } if (!autoWidth) { newState.scrollLeft = scrollLeft; } newState.needToResetStyleCache = false; this.setState(newState); } this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft, scrollTop: scrollTop, totalColumnsWidth: totalColumnsWidth, totalRowsHeight: totalRowsHeight }); } /** * Invalidate Grid size and recompute visible cells. * This is a deferred wrapper for recomputeGridSize(). * It sets a flag to be evaluated on cDM/cDU to avoid unnecessary renders. * This method is intended for advanced use-cases like CellMeasurer. */ // @TODO (bvaughn) Add automated test coverage for this. }, { key: "invalidateCellSizeAfterRender", value: function invalidateCellSizeAfterRender(_ref3) { var columnIndex = _ref3.columnIndex, rowIndex = _ref3.rowIndex; this._deferredInvalidateColumnIndex = typeof this._deferredInvalidateColumnIndex === 'number' ? Math.min(this._deferredInvalidateColumnIndex, columnIndex) : columnIndex; this._deferredInvalidateRowIndex = typeof this._deferredInvalidateRowIndex === 'number' ? Math.min(this._deferredInvalidateRowIndex, rowIndex) : rowIndex; } /** * Pre-measure all columns and rows in a Grid. * Typically cells are only measured as needed and estimated sizes are used for cells that have not yet been measured. * This method ensures that the next call to getTotalSize() returns an exact size (as opposed to just an estimated one). */ }, { key: "measureAllCells", value: function measureAllCells() { var _this$props2 = this.props, columnCount = _this$props2.columnCount, rowCount = _this$props2.rowCount; var instanceProps = this.state.instanceProps; instanceProps.columnSizeAndPositionManager.getSizeAndPositionOfCell(columnCount - 1); instanceProps.rowSizeAndPositionManager.getSizeAndPositionOfCell(rowCount - 1); } /** * Forced recompute of row heights and column widths. * This function should be called if dynamic column or row sizes have changed but nothing else has. * Since Grid only receives :columnCount and :rowCount it has no way of detecting when the underlying data changes. */ }, { key: "recomputeGridSize", value: function recomputeGridSize() { var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref4$columnIndex = _ref4.columnIndex, columnIndex = _ref4$columnIndex === void 0 ? 0 : _ref4$columnIndex, _ref4$rowIndex = _ref4.rowIndex, rowIndex = _ref4$rowIndex === void 0 ? 0 : _ref4$rowIndex; var _this$props3 = this.props, scrollToColumn = _this$props3.scrollToColumn, scrollToRow = _this$props3.scrollToRow; var instanceProps = this.state.instanceProps; instanceProps.columnSizeAndPositionManager.resetCell(columnIndex); instanceProps.rowSizeAndPositionManager.resetCell(rowIndex); // Cell sizes may be determined by a function property. // In this case the cDU handler can't know if they changed. // Store this flag to let the next cDU pass know it needs to recompute the scroll offset. this._recomputeScrollLeftFlag = scrollToColumn >= 0 && (this.state.scrollDirectionHorizontal === _defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD ? columnIndex <= scrollToColumn : columnIndex >= scrollToColumn); this._recomputeScrollTopFlag = scrollToRow >= 0 && (this.state.scrollDirectionVertical === _defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD ? rowIndex <= scrollToRow : rowIndex >= scrollToRow); // Clear cell cache in case we are scrolling; // Invalid row heights likely mean invalid cached content as well. this._styleCache = {}; this._cellCache = {}; this.forceUpdate(); } /** * Ensure column and row are visible. */ }, { key: "scrollToCell", value: function scrollToCell(_ref5) { var columnIndex = _ref5.columnIndex, rowIndex = _ref5.rowIndex; var columnCount = this.props.columnCount; var props = this.props; // Don't adjust scroll offset for single-column grids (eg List, Table). // This can cause a funky scroll offset because of the vertical scrollbar width. if (columnCount > 1 && columnIndex !== undefined) { this._updateScrollLeftForScrollToColumn(_objectSpread({}, props, { scrollToColumn: columnIndex })); } if (rowIndex !== undefined) { this._updateScrollTopForScrollToRow(_objectSpread({}, props, { scrollToRow: rowIndex })); } } }, { key: "componentDidMount", value: function componentDidMount() { var _this$props4 = this.props, getScrollbarSize = _this$props4.getScrollbarSize, height = _this$props4.height, scrollLeft = _this$props4.scrollLeft, scrollToColumn = _this$props4.scrollToColumn, scrollTop = _this$props4.scrollTop, scrollToRow = _this$props4.scrollToRow, width = _this$props4.width; var instanceProps = this.state.instanceProps; // Reset initial offsets to be ignored in browser this._initialScrollTop = 0; this._initialScrollLeft = 0; // If cell sizes have been invalidated (eg we are using CellMeasurer) then reset cached positions. // We must do this at the start of the method as we may calculate and update scroll position below. this._handleInvalidatedGridSize(); // If this component was first rendered server-side, scrollbar size will be undefined. // In that event we need to remeasure. if (!instanceProps.scrollbarSizeMeasured) { this.setState(function (prevState) { var stateUpdate = _objectSpread({}, prevState, { needToResetStyleCache: false }); stateUpdate.instanceProps.scrollbarSize = getScrollbarSize(); stateUpdate.instanceProps.scrollbarSizeMeasured = true; return stateUpdate; }); } if (typeof scrollLeft === 'number' && scrollLeft >= 0 || typeof scrollTop === 'number' && scrollTop >= 0) { var stateUpdate = Grid._getScrollToPositionStateUpdate({ prevState: this.state, scrollLeft: scrollLeft, scrollTop: scrollTop }); if (stateUpdate) { stateUpdate.needToResetStyleCache = false; this.setState(stateUpdate); } } // refs don't work in `react-test-renderer` if (this._scrollingContainer) { // setting the ref's scrollLeft and scrollTop. // Somehow in MultiGrid the main grid doesn't trigger a update on mount. if (this._scrollingContainer.scrollLeft !== this.state.scrollLeft) { this._scrollingContainer.scrollLeft = this.state.scrollLeft; } if (this._scrollingContainer.scrollTop !== this.state.scrollTop) { this._scrollingContainer.scrollTop = this.state.scrollTop; } } // Don't update scroll offset if the size is 0; we don't render any cells in this case. // Setting a state may cause us to later thing we've updated the offce when we haven't. var sizeIsBiggerThanZero = height > 0 && width > 0; if (scrollToColumn >= 0 && sizeIsBiggerThanZero) { this._updateScrollLeftForScrollToColumn(); } if (scrollToRow >= 0 && sizeIsBiggerThanZero) { this._updateScrollTopForScrollToRow(); } // Update onRowsRendered callback this._invokeOnGridRenderedHelper(); // Initialize onScroll callback this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft || 0, scrollTop: scrollTop || 0, totalColumnsWidth: instanceProps.columnSizeAndPositionManager.getTotalSize(), totalRowsHeight: instanceProps.rowSizeAndPositionManager.getTotalSize() }); this._maybeCallOnScrollbarPresenceChange(); } /** * @private * This method updates scrollLeft/scrollTop in state for the following conditions: * 1) New scroll-to-cell props have been set */ }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { var _this2 = this; var _this$props5 = this.props, autoHeight = _this$props5.autoHeight, autoWidth = _this$props5.autoWidth, columnCount = _this$props5.columnCount, height = _this$props5.height, rowCount = _this$props5.rowCount, scrollToAlignment = _this$props5.scrollToAlignment, scrollToColumn = _this$props5.scrollToColumn, scrollToRow = _this$props5.scrollToRow, width = _this$props5.width; var _this$state = this.state, scrollLeft = _this$state.scrollLeft, scrollPositionChangeReason = _this$state.scrollPositionChangeReason, scrollTop = _this$state.scrollTop, instanceProps = _this$state.instanceProps; // If cell sizes have been invalidated (eg we are using CellMeasurer) then reset cached positions. // We must do this at the start of the method as we may calculate and update scroll position below. this._handleInvalidatedGridSize(); // Handle edge case where column or row count has only just increased over 0. // In this case we may have to restore a previously-specified scroll offset. // For more info see bvaughn/react-virtualized/issues/218 var columnOrRowCountJustIncreasedFromZero = columnCount > 0 && prevProps.columnCount === 0 || rowCount > 0 && prevProps.rowCount === 0; // Make sure requested changes to :scrollLeft or :scrollTop get applied. // Assigning to scrollLeft/scrollTop tells the browser to interrupt any running scroll animations, // And to discard any pending async changes to the scroll position that may have happened in the meantime (e.g. on a separate scrolling thread). // So we only set these when we require an adjustment of the scroll position. // See issue #2 for more information. if (scrollPositionChangeReason === SCROLL_POSITION_CHANGE_REASONS.REQUESTED) { // @TRICKY :autoHeight and :autoWidth properties instructs Grid to leave :scrollTop and :scrollLeft management to an external HOC (eg WindowScroller). // In this case we should avoid checking scrollingContainer.scrollTop and scrollingContainer.scrollLeft since it forces layout/flow. if (!autoWidth && scrollLeft >= 0 && (scrollLeft !== this._scrollingContainer.scrollLeft || columnOrRowCountJustIncreasedFromZero)) { this._scrollingContainer.scrollLeft = scrollLeft; } if (!autoHeight && scrollTop >= 0 && (scrollTop !== this._scrollingContainer.scrollTop || columnOrRowCountJustIncreasedFromZero)) { this._scrollingContainer.scrollTop = scrollTop; } } // Special case where the previous size was 0: // In this case we don't show any windowed cells at all. // So we should always recalculate offset afterwards. var sizeJustIncreasedFromZero = (prevProps.width === 0 || prevProps.height === 0) && height > 0 && width > 0; // Update scroll offsets if the current :scrollToColumn or :scrollToRow values requires it // @TODO Do we also need this check or can the one in componentWillUpdate() suffice? if (this._recomputeScrollLeftFlag) { this._recomputeScrollLeftFlag = false; this._updateScrollLeftForScrollToColumn(this.props); } else { (0, _updateScrollIndexHelper["default"])({ cellSizeAndPositionManager: instanceProps.columnSizeAndPositionManager, previousCellsCount: prevProps.columnCount, previousCellSize: prevProps.columnWidth, previousScrollToAlignment: prevProps.scrollToAlignment, previousScrollToIndex: prevProps.scrollToColumn, previousSize: prevProps.width, scrollOffset: scrollLeft, scrollToAlignment: scrollToAlignment, scrollToIndex: scrollToColumn, size: width, sizeJustIncreasedFromZero: sizeJustIncreasedFromZero, updateScrollIndexCallback: function updateScrollIndexCallback() { return _this2._updateScrollLeftForScrollToColumn(_this2.props); } }); } if (this._recomputeScrollTopFlag) { this._recomputeScrollTopFlag = false; this._updateScrollTopForScrollToRow(this.props); } else { (0, _updateScrollIndexHelper["default"])({ cellSizeAndPositionManager: instanceProps.rowSizeAndPositionManager, previousCellsCount: prevProps.rowCount, previousCellSize: prevProps.rowHeight, previousScrollToAlignment: prevProps.scrollToAlignment, previousScrollToIndex: prevProps.scrollToRow, previousSize: prevProps.height, scrollOffset: scrollTop, scrollToAlignment: scrollToAlignment, scrollToIndex: scrollToRow, size: height, sizeJustIncreasedFromZero: sizeJustIncreasedFromZero, updateScrollIndexCallback: function updateScrollIndexCallback() { return _this2._updateScrollTopForScrollToRow(_this2.props); } }); } // Update onRowsRendered callback if start/stop indices have changed this._invokeOnGridRenderedHelper(); // Changes to :scrollLeft or :scrollTop should also notify :onScroll listeners if (scrollLeft !== prevState.scrollLeft || scrollTop !== prevState.scrollTop) { var totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(); var totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(); this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft, scrollTop: scrollTop, totalColumnsWidth: totalColumnsWidth, totalRowsHeight: totalRowsHeight }); } this._maybeCallOnScrollbarPresenceChange(); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this._disablePointerEventsTimeoutId) { (0, _requestAnimationTimeout.cancelAnimationTimeout)(this._disablePointerEventsTimeoutId); } } /** * This method updates scrollLeft/scrollTop in state for the following conditions: * 1) Empty content (0 rows or columns) * 2) New scroll props overriding the current state * 3) Cells-count or cells-size has changed, making previous scroll offsets invalid */ }, { key: "render", value: function render() { var _this$props6 = this.props, autoContainerWidth = _this$props6.autoContainerWidth, autoHeight = _this$props6.autoHeight, autoWidth = _this$props6.autoWidth, className = _this$props6.className, containerProps = _this$props6.containerProps, containerRole = _this$props6.containerRole, containerStyle = _this$props6.containerStyle, height = _this$props6.height, id = _this$props6.id, noContentRenderer = _this$props6.noContentRenderer, role = _this$props6.role, style = _this$props6.style, tabIndex = _this$props6.tabIndex, width = _this$props6.width; var _this$state2 = this.state, instanceProps = _this$state2.instanceProps, needToResetStyleCache = _this$state2.needToResetStyleCache; var isScrolling = this._isScrolling(); var gridStyle = { boxSizing: 'border-box', direction: 'ltr', height: autoHeight ? 'auto' : height, position: 'relative', width: autoWidth ? 'auto' : width, WebkitOverflowScrolling: 'touch', willChange: 'transform' }; if (needToResetStyleCache) { this._styleCache = {}; } // calculate _styleCache here // if state.isScrolling (not from _isScrolling) then reset if (!this.state.isScrolling) { this._resetStyleCache(); } // calculate children to render here this._calculateChildrenToRender(this.props, this.state); var totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(); var totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(); // Force browser to hide scrollbars when we know they aren't necessary. // Otherwise once scrollbars appear they may not disappear again. // For more info see issue #116 var verticalScrollBarSize = totalRowsHeight > height ? instanceProps.scrollbarSize : 0; var horizontalScrollBarSize = totalColumnsWidth > width ? instanceProps.scrollbarSize : 0; if (horizontalScrollBarSize !== this._horizontalScrollBarSize || verticalScrollBarSize !== this._verticalScrollBarSize) { this._horizontalScrollBarSize = horizontalScrollBarSize; this._verticalScrollBarSize = verticalScrollBarSize; this._scrollbarPresenceChanged = true; } // Also explicitly init styles to 'auto' if scrollbars are required. // This works around an obscure edge case where external CSS styles have not yet been loaded, // But an initial scroll index of offset is set as an external prop. // Without this style, Grid would render the correct range of cells but would NOT update its internal offset. // This was originally reported via clauderic/react-infinite-calendar/issues/23 gridStyle.overflowX = totalColumnsWidth + verticalScrollBarSize <= width ? 'hidden' : 'auto'; gridStyle.overflowY = totalRowsHeight + horizontalScrollBarSize <= height ? 'hidden' : 'auto'; var childrenToDisplay = this._childrenToDisplay; var showNoContentRenderer = childrenToDisplay.length === 0 && height > 0 && width > 0; return React.createElement("div", (0, _extends2["default"])({ ref: this._setScrollingContainerRef }, containerProps, { "aria-label": this.props['aria-label'], "aria-readonly": this.props['aria-readonly'], className: (0, _clsx["default"])('ReactVirtualized__Grid', className), id: id, onScroll: this._onScroll, role: role, style: _objectSpread({}, gridStyle, {}, style), tabIndex: tabIndex }), childrenToDisplay.length > 0 && React.createElement("div", { className: "ReactVirtualized__Grid__innerScrollContainer", role: containerRole, style: _objectSpread({ width: autoContainerWidth ? 'auto' : totalColumnsWidth, height: totalRowsHeight, maxWidth: totalColumnsWidth, maxHeight: totalRowsHeight, overflow: 'hidden', pointerEvents: isScrolling ? 'none' : '', position: 'relative' }, containerStyle) }, childrenToDisplay), showNoContentRenderer && noContentRenderer()); } /* ---------------------------- Helper methods ---------------------------- */ }, { key: "_calculateChildrenToRender", value: function _calculateChildrenToRender() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; var cellRenderer = props.cellRenderer, cellRangeRenderer = props.cellRangeRenderer, columnCount = props.columnCount, deferredMeasurementCache = props.deferredMeasurementCache, height = props.height, overscanColumnCount = props.overscanColumnCount, overscanIndicesGetter = props.overscanIndicesGetter, overscanRowCount = props.overscanRowCount, rowCount = props.rowCount, width = props.width, isScrollingOptOut = props.isScrollingOptOut; var scrollDirectionHorizontal = state.scrollDirectionHorizontal, scrollDirectionVertical = state.scrollDirectionVertical, instanceProps = state.instanceProps; var scrollTop = this._initialScrollTop > 0 ? this._initialScrollTop : state.scrollTop; var scrollLeft = this._initialScrollLeft > 0 ? this._initialScrollLeft : state.scrollLeft; var isScrolling = this._isScrolling(props, state); this._childrenToDisplay = []; // Render only enough columns and rows to cover the visible area of the grid. if (height > 0 && width > 0) { var visibleColumnIndices = instanceProps.columnSizeAndPositionManager.getVisibleCellRange({ containerSize: width, offset: scrollLeft }); var visibleRowIndices = instanceProps.rowSizeAndPositionManager.getVisibleCellRange({ containerSize: height, offset: scrollTop }); var horizontalOffsetAdjustment = instanceProps.columnSizeAndPositionManager.getOffsetAdjustment({ containerSize: width, offset: scrollLeft }); var verticalOffsetAdjustment = instanceProps.rowSizeAndPositionManager.getOffsetAdjustment({ containerSize: height, offset: scrollTop }); // Store for _invokeOnGridRenderedHelper() this._renderedColumnStartIndex = visibleColumnIndices.start; this._renderedColumnStopIndex = visibleColumnIndices.stop; this._renderedRowStartIndex = visibleRowIndices.start; this._renderedRowStopIndex = visibleRowIndices.stop; var overscanColumnIndices = overscanIndicesGetter({ direction: 'horizontal', cellCount: columnCount, overscanCellsCount: overscanColumnCount, scrollDirection: scrollDirectionHorizontal, startIndex: typeof visibleColumnIndices.start === 'number' ? visibleColumnIndices.start : 0, stopIndex: typeof visibleColumnIndices.stop === 'number' ? visibleColumnIndices.stop : -1 }); var overscanRowIndices = overscanIndicesGetter({ direction: 'vertical', cellCount: rowCount, overscanCellsCount: overscanRowCount, scrollDirection: scrollDirectionVertical, startIndex: typeof visibleRowIndices.start === 'number' ? visibleRowIndices.start : 0, stopIndex: typeof visibleRowIndices.stop === 'number' ? visibleRowIndices.stop : -1 }); // Store for _invokeOnGridRenderedHelper() var columnStartIndex = overscanColumnIndices.overscanStartIndex; var columnStopIndex = overscanColumnIndices.overscanStopIndex; var rowStartIndex = overscanRowIndices.overscanStartIndex; var rowStopIndex = overscanRowIndices.overscanStopIndex; // Advanced use-cases (eg CellMeasurer) require batched measurements to determine accurate sizes. if (deferredMeasurementCache) { // If rows have a dynamic height, scan the rows we are about to render. // If any have not yet been measured, then we need to render all columns initially, // Because the height of the row is equal to the tallest cell within that row, // (And so we can't know the height without measuring all column-cells first). if (!deferredMeasurementCache.hasFixedHeight()) { for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) { if (!deferredMeasurementCache.has(rowIndex, 0)) { columnStartIndex = 0; columnStopIndex = columnCount - 1; break; } } } // If columns have a dynamic width, scan the columns we are about to render. // If any have not yet been measured, then we need to render all rows initially, // Because the width of the column is equal to the widest cell within that column, // (And so we can't know the width without measuring all row-cells first). if (!deferredMeasurementCache.hasFixedWidth()) { for (var columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) { if (!deferredMeasurementCache.has(0, columnIndex)) { rowStartIndex = 0; rowStopIndex = rowCount - 1; break; } } } } this._childrenToDisplay = cellRangeRenderer({ cellCache: this._cellCache, cellRenderer: cellRenderer, columnSizeAndPositionManager: instanceProps.columnSizeAndPositionManager, columnStartIndex: columnStartIndex, columnStopIndex: columnStopIndex, deferredMeasurementCache: deferredMeasurementCache, horizontalOffsetAdjustment: horizontalOffsetAdjustment, isScrolling: isScrolling, isScrollingOptOut: isScrollingOptOut, parent: this, rowSizeAndPositionManager: instanceProps.rowSizeAndPositionManager, rowStartIndex: rowStartIndex, rowStopIndex: rowStopIndex, scrollLeft: scrollLeft, scrollTop: scrollTop, styleCache: this._styleCache, verticalOffsetAdjustment: verticalOffsetAdjustment, visibleColumnIndices: visibleColumnIndices, visibleRowIndices: visibleRowIndices }); // update the indices this._columnStartIndex = columnStartIndex; this._columnStopIndex = columnStopIndex; this._rowStartIndex = rowStartIndex; this._rowStopIndex = rowStopIndex; } } /** * Sets an :isScrolling flag for a small window of time. * This flag is used to disable pointer events on the scrollable portion of the Grid. * This prevents jerky/stuttery mouse-wheel scrolling. */ }, { key: "_debounceScrollEnded", value: function _debounceScrollEnded() { var scrollingResetTimeInterval = this.props.scrollingResetTimeInterval; if (this._disablePointerEventsTimeoutId) { (0, _requestAnimationTimeout.cancelAnimationTimeout)(this._disablePointerEventsTimeoutId); } this._disablePointerEventsTimeoutId = (0, _requestAnimationTimeout.requestAnimationTimeout)(this._debounceScrollEndedCallback, scrollingResetTimeInterval); } }, { key: "_handleInvalidatedGridSize", /** * Check for batched CellMeasurer size invalidations. * This will occur the first time one or more previously unmeasured cells are rendered. */ value: function _handleInvalidatedGridSize() { if (typeof this._deferredInvalidateColumnIndex === 'number' && typeof this._deferredInvalidateRowIndex === 'number') { var columnIndex = this._deferredInvalidateColumnIndex; var rowIndex = this._deferredInvalidateRowIndex; this._deferredInvalidateColumnIndex = null; this._deferredInvalidateRowIndex = null; this.recomputeGridSize({ columnIndex: columnIndex, rowIndex: rowIndex }); } } }, { key: "_invokeOnScrollMemoizer", value: function _invokeOnScrollMemoizer(_ref6) { var _this3 = this; var scrollLeft = _ref6.scrollLeft, scrollTop = _ref6.scrollTop, totalColumnsWidth = _ref6.totalColumnsWidth, totalRowsHeight = _ref6.totalRowsHeight; this._onScrollMemoizer({ callback: function callback(_ref7) { var scrollLeft = _ref7.scrollLeft, scrollTop = _ref7.scrollTop; var _this3$props = _this3.props, height = _this3$props.height, onScroll = _this3$props.onScroll, width = _this3$props.width; onScroll({ clientHeight: height, clientWidth: width, scrollHeight: totalRowsHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: totalColumnsWidth }); }, indices: { scrollLeft: scrollLeft, scrollTop: scrollTop } }); } }, { key: "_isScrolling", value: function _isScrolling() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; // If isScrolling is defined in props, use it to override the value in state // This is a performance optimization for WindowScroller + Grid return Object.hasOwnProperty.call(props, 'isScrolling') ? Boolean(props.isScrolling) : Boolean(state.isScrolling); } }, { key: "_maybeCallOnScrollbarPresenceChange", value: function _maybeCallOnScrollbarPresenceChange() { if (this._scrollbarPresenceChanged) { var onScrollbarPresenceChange = this.props.onScrollbarPresenceChange; this._scrollbarPresenceChanged = false; onScrollbarPresenceChange({ horizontal: this._horizontalScrollBarSize > 0, size: this.state.instanceProps.scrollbarSize, vertical: this._verticalScrollBarSize > 0 }); } } }, { key: "scrollToPosition", /** * Scroll to the specified offset(s). * Useful for animating position changes. */ value: function scrollToPosition(_ref8) { var scrollLeft = _ref8.scrollLeft, scrollTop = _ref8.scrollTop; var stateUpdate = Grid._getScrollToPositionStateUpdate({ prevState: this.state, scrollLeft: scrollLeft, scrollTop: scrollTop }); if (stateUpdate) { stateUpdate.needToResetStyleCache = false; this.setState(stateUpdate); } } }, { key: "_getCalculatedScrollLeft", value: function _getCalculatedScrollLeft() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; return Grid._getCalculatedScrollLeft(props, state); } }, { key: "_updateScrollLeftForScrollToColumn", value: function _updateScrollLeftForScrollToColumn() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; var stateUpdate = Grid._getScrollLeftForScrollToColumnStateUpdate(props, state); if (stateUpdate) { stateUpdate.needToResetStyleCache = false; this.setState(stateUpdate); } } }, { key: "_getCalculatedScrollTop", value: function _getCalculatedScrollTop() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; return Grid._getCalculatedScrollTop(props, state); } }, { key: "_resetStyleCache", value: function _resetStyleCache() { var styleCache = this._styleCache; var cellCache = this._cellCache; var isScrollingOptOut = this.props.isScrollingOptOut; // Reset cell and style caches once scrolling stops. // This makes Grid simpler to use (since cells commonly change). // And it keeps the caches from growing too large. // Performance is most sensitive when a user is scrolling. // Don't clear visible cells from cellCache if isScrollingOptOut is specified. // This keeps the cellCache to a resonable size. this._cellCache = {}; this._styleCache = {}; // Copy over the visible cell styles so avoid unnecessary re-render. for (var rowIndex = this._rowStartIndex; rowIndex <= this._rowStopIndex; rowIndex++) { for (var columnIndex = this._columnStartIndex; columnIndex <= this._columnStopIndex; columnIndex++) { var key = "".concat(rowIndex, "-").concat(columnIndex); this._styleCache[key] = styleCache[key]; if (isScrollingOptOut) { this._cellCache[key] = cellCache[key]; } } } } }, { key: "_updateScrollTopForScrollToRow", value: function _updateScrollTopForScrollToRow() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; var stateUpdate = Grid._getScrollTopForScrollToRowStateUpdate(props, state); if (stateUpdate) { stateUpdate.needToResetStyleCache = false; this.setState(stateUpdate); } } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps, prevState) { var newState = {}; if (nextProps.columnCount === 0 && prevState.scrollLeft !== 0 || nextProps.rowCount === 0 && prevState.scrollTop !== 0) { newState.scrollLeft = 0; newState.scrollTop = 0; // only use scroll{Left,Top} from props if scrollTo{Column,Row} isn't specified // scrollTo{Column,Row} should override scroll{Left,Top} } else if (nextProps.scrollLeft !== prevState.scrollLeft && nextProps.scrollToColumn < 0 || nextProps.scrollTop !== prevState.scrollTop && nextProps.scrollToRow < 0) { Object.assign(newState, Grid._getScrollToPositionStateUpdate({ prevState: prevState, scrollLeft: nextProps.scrollLeft, scrollTop: nextProps.scrollTop })); } var instanceProps = prevState.instanceProps; // Initially we should not clearStyleCache newState.needToResetStyleCache = false; if (nextProps.columnWidth !== instanceProps.prevColumnWidth || nextProps.rowHeight !== instanceProps.prevRowHeight) { // Reset cache. set it to {} in render newState.needToResetStyleCache = true; } instanceProps.columnSizeAndPositionManager.configure({ cellCount: nextProps.columnCount, estimatedCellSize: Grid._getEstimatedColumnSize(nextProps), cellSizeGetter: Grid._wrapSizeGetter(nextProps.columnWidth) }); instanceProps.rowSizeAndPositionManager.configure({ cellCount: nextProps.rowCount, estimatedCellSize: Grid._getEstimatedRowSize(nextProps), cellSizeGetter: Grid._wrapSizeGetter(nextProps.rowHeight) }); if (instanceProps.prevColumnCount === 0 || instanceProps.prevRowCount === 0) { instanceProps.prevColumnCount = 0; instanceProps.prevRowCount = 0; } // If scrolling is controlled outside this component, clear cache when scrolling stops if (nextProps.autoHeight && nextProps.isScrolling === false && instanceProps.prevIsScrolling === true) { Object.assign(newState, { isScrolling: false }); } var maybeStateA; var maybeStateB; (0, _calculateSizeAndPositionDataAndUpdateScrollOffset["default"])({ cellCount: instanceProps.prevColumnCount, cellSize: typeof instanceProps.prevColumnWidth === 'number' ? instanceProps.prevColumnWidth : null, computeMetadataCallback: function computeMetadataCallback() { return instanceProps.columnSizeAndPositionManager.resetCell(0); }, computeMetadataCallbackProps: nextProps, nextCellsCount: nextProps.columnCount, nextCellSize: typeof nextProps.columnWidth === 'number' ? nextProps.columnWidth : null, nextScrollToIndex: nextProps.scrollToColumn, scrollToIndex: instanceProps.prevScrollToColumn, updateScrollOffsetForScrollToIndex: function updateScrollOffsetForScrollToIndex() { maybeStateA = Grid._getScrollLeftForScrollToColumnStateUpdate(nextProps, prevState); } }); (0, _calculateSizeAndPositionDataAndUpdateScrollOffset["default"])({ cellCount: instanceProps.prevRowCount, cellSize: typeof instanceProps.prevRowHeight === 'number' ? instanceProps.prevRowHeight : null, computeMetadataCallback: function computeMetadataCallback() { return instanceProps.rowSizeAndPositionManager.resetCell(0); }, computeMetadataCallbackProps: nextProps, nextCellsCount: nextProps.rowCount, nextCellSize: typeof nextProps.rowHeight === 'number' ? nextProps.rowHeight : null, nextScrollToIndex: nextProps.scrollToRow, scrollToIndex: instanceProps.prevScrollToRow, updateScrollOffsetForScrollToIndex: function updateScrollOffsetForScrollToIndex() { maybeStateB = Grid._getScrollTopForScrollToRowStateUpdate(nextProps, prevState); } }); instanceProps.prevColumnCount = nextProps.columnCount; instanceProps.prevColumnWidth = nextProps.columnWidth; instanceProps.prevIsScrolling = nextProps.isScrolling === true; instanceProps.prevRowCount = nextProps.rowCount; instanceProps.prevRowHeight = nextProps.rowHeight; instanceProps.prevScrollToColumn = nextProps.scrollToColumn; instanceProps.prevScrollToRow = nextProps.scrollToRow; // getting scrollBarSize (moved from componentWillMount) instanceProps.scrollbarSize = nextProps.getScrollbarSize(); if (instanceProps.scrollbarSize === undefined) { instanceProps.scrollbarSizeMeasured = false; instanceProps.scrollbarSize = 0; } else { instanceProps.scrollbarSizeMeasured = true; } newState.instanceProps = instanceProps; return _objectSpread({}, newState, {}, maybeStateA, {}, maybeStateB); } }, { key: "_getEstimatedColumnSize", value: function _getEstimatedColumnSize(props) { return typeof props.columnWidth === 'number' ? props.columnWidth : props.estimatedColumnSize; } }, { key: "_getEstimatedRowSize", value: function _getEstimatedRowSize(props) { return typeof props.rowHeight === 'number' ? props.rowHeight : props.estimatedRowSize; } }, { key: "_getScrollToPositionStateUpdate", /** * Get the updated state after scrolling to * scrollLeft and scrollTop */ value: function _getScrollToPositionStateUpdate(_ref9) { var prevState = _ref9.prevState, scrollLeft = _ref9.scrollLeft, scrollTop = _ref9.scrollTop; var newState = { scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS.REQUESTED }; if (typeof scrollLeft === 'number' && scrollLeft >= 0) { newState.scrollDirectionHorizontal = scrollLeft > prevState.scrollLeft ? _defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD : _defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD; newState.scrollLeft = scrollLeft; } if (typeof scrollTop === 'number' && scrollTop >= 0) { newState.scrollDirectionVertical = scrollTop > prevState.scrollTop ? _defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD : _defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD; newState.scrollTop = scrollTop; } if (typeof scrollLeft === 'number' && scrollLeft >= 0 && scrollLeft !== prevState.scrollLeft || typeof scrollTop === 'number' && scrollTop >= 0 && scrollTop !== prevState.scrollTop) { return newState; } return {}; } }, { key: "_wrapSizeGetter", value: function _wrapSizeGetter(value) { return typeof value === 'function' ? value : function () { return value; }; } }, { key: "_getCalculatedScrollLeft", value: function _getCalculatedScrollLeft(nextProps, prevState) { var columnCount = nextProps.columnCount, height = nextProps.height, scrollToAlignment = nextProps.scrollToAlignment, scrollToColumn = nextProps.scrollToColumn, width = nextProps.width; var scrollLeft = prevState.scrollLeft, instanceProps = prevState.instanceProps; if (columnCount > 0) { var finalColumn = columnCount - 1; var targetIndex = scrollToColumn < 0 ? finalColumn : Math.min(finalColumn, scrollToColumn); var totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(); var scrollBarSize = instanceProps.scrollbarSizeMeasured && totalRowsHeight > height ? instanceProps.scrollbarSize : 0; return instanceProps.columnSizeAndPositionManager.getUpdatedOffsetForIndex({ align: scrollToAlignment, containerSize: width - scrollBarSize, currentOffset: scrollLeft, targetIndex: targetIndex }); } return 0; } }, { key: "_getScrollLeftForScrollToColumnStateUpdate", value: function _getScrollLeftForScrollToColumnStateUpdate(nextProps, prevState) { var scrollLeft = prevState.scrollLeft; var calculatedScrollLeft = Grid._getCalculatedScrollLeft(nextProps, prevState); if (typeof calculatedScrollLeft === 'number' && calculatedScrollLeft >= 0 && scrollLeft !== calculatedScrollLeft) { return Grid._getScrollToPositionStateUpdate({ prevState: prevState, scrollLeft: calculatedScrollLeft, scrollTop: -1 }); } return {}; } }, { key: "_getCalculatedScrollTop", value: function _getCalculatedScrollTop(nextProps, prevState) { var height = nextProps.height, rowCount = nextProps.rowCount, scrollToAlignment = nextProps.scrollToAlignment, scrollToRow = nextProps.scrollToRow, width = nextProps.width; var scrollTop = prevState.scrollTop, instanceProps = prevState.instanceProps; if (rowCount > 0) { var finalRow = rowCount - 1; var targetIndex = scrollToRow < 0 ? finalRow : Math.min(finalRow, scrollToRow); var totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(); var scrollBarSize = instanceProps.scrollbarSizeMeasured && totalColumnsWidth > width ? instanceProps.scrollbarSize : 0; return instanceProps.rowSizeAndPositionManager.getUpdatedOffsetForIndex({ align: scrollToAlignment, containerSize: height - scrollBarSize, currentOffset: scrollTop, targetIndex: targetIndex }); } return 0; } }, { key: "_getScrollTopForScrollToRowStateUpdate", value: function _getScrollTopForScrollToRowStateUpdate(nextProps, prevState) { var scrollTop = prevState.scrollTop; var calculatedScrollTop = Grid._getCalculatedScrollTop(nextProps, prevState); if (typeof calculatedScrollTop === 'number' && calculatedScrollTop >= 0 && scrollTop !== calculatedScrollTop) { return Grid._getScrollToPositionStateUpdate({ prevState: prevState, scrollLeft: -1, scrollTop: calculatedScrollTop }); } return {}; } }]); return Grid; }(React.PureComponent), (0, _defineProperty2["default"])(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { "aria-label": _propTypes["default"].string.isRequired, "aria-readonly": _propTypes["default"].bool, /** * Set the width of the inner scrollable container to 'auto'. * This is useful for single-column Grids to ensure that the column doesn't extend below a vertical scrollbar. */ "autoContainerWidth": _propTypes["default"].bool.isRequired, /** * Removes fixed height from the scrollingContainer so that the total height of rows can stretch the window. * Intended for use with WindowScroller */ "autoHeight": _propTypes["default"].bool.isRequired, /** * Removes fixed width from the scrollingContainer so that the total width of rows can stretch the window. * Intended for use with WindowScroller */ "autoWidth": _propTypes["default"].bool.isRequired, /** Responsible for rendering a cell given an row and column index. */ "cellRenderer": function cellRenderer() { return (typeof _types.bpfrpt_proptype_CellRenderer === "function" ? _types.bpfrpt_proptype_CellRenderer.isRequired ? _types.bpfrpt_proptype_CellRenderer.isRequired : _types.bpfrpt_proptype_CellRenderer : _propTypes["default"].shape(_types.bpfrpt_proptype_CellRenderer).isRequired).apply(this, arguments); }, /** Responsible for rendering a group of cells given their index ranges. */ "cellRangeRenderer": function cellRangeRenderer() { return (typeof _types.bpfrpt_proptype_CellRangeRenderer === "function" ? _types.bpfrpt_proptype_CellRangeRenderer.isRequired ? _types.bpfrpt_proptype_CellRangeRenderer.isRequired : _types.bpfrpt_proptype_CellRangeRenderer : _propTypes["default"].shape(_types.bpfrpt_proptype_CellRangeRenderer).isRequired).apply(this, arguments); }, /** Optional custom CSS class name to attach to root Grid element. */ "className": _propTypes["default"].string, /** Number of columns in grid. */ "columnCount": _propTypes["default"].number.isRequired, /** Either a fixed column width (number) or a function that returns the width of a column given its index. */ "columnWidth": function columnWidth() { return (typeof _types.bpfrpt_proptype_CellSize === "function" ? _types.bpfrpt_proptype_CellSize.isRequired ? _types.bpfrpt_proptype_CellSize.isRequired : _types.bpfrpt_proptype_CellSize : _propTypes["default"].shape(_types.bpfrpt_proptype_CellSize).isRequired).apply(this, arguments); }, /** Unfiltered props for the Grid container. */ "containerProps": _propTypes["default"].object, /** ARIA role for the cell-container. */ "containerRole": _propTypes["default"].string.isRequired, /** Optional inline style applied to inner cell-container */ "containerStyle": _propTypes["default"].object.isRequired, /** * If CellMeasurer is used to measure this Grid's children, this should be a pointer to its CellMeasurerCache. * A shared CellMeasurerCache reference enables Grid and CellMeasurer to share measurement data. */ "deferredMeasurementCache": _propTypes["default"].object, /** * Used to estimate the total width of a Grid before all of its columns have actually been measured. * The estimated total width is adjusted as columns are rendered. */ "estimatedColumnSize": _propTypes["default"].number.isRequired, /** * Used to estimate the total height of a Grid before all of its rows have actually been measured. * The estimated total height is adjusted as rows are rendered. */ "estimatedRowSize": _propTypes["default"].number.isRequired, /** Exposed for testing purposes only. */ "getScrollbarSize": _propTypes["default"].func.isRequired, /** Height of Grid; this property determines the number of visible (vs virtualized) rows. */ "height": _propTypes["default"].number.isRequired, /** Optional custom id to attach to root Grid element. */ "id": _propTypes["default"].string, /** * Override internal is-scrolling state tracking. * This property is primarily intended for use with the WindowScroller component. */ "isScrolling": _propTypes["default"].bool, /** * Opt-out of isScrolling param passed to cellRangeRenderer. * To avoid the extra render when scroll stops. */ "isScrollingOptOut": _propTypes["default"].bool.isRequired, /** Optional renderer to be used in place of rows when either :rowCount or :columnCount is 0. */ "noContentRenderer": function noContentRenderer() { return (typeof _types.bpfrpt_proptype_NoContentRenderer === "function" ? _types.bpfrpt_proptype_NoContentRenderer.isRequired ? _types.bpfrpt_proptype_NoContentRenderer.isRequired : _types.bpfrpt_proptype_NoContentRenderer : _propTypes["default"].shape(_types.bpfrpt_proptype_NoContentRenderer).isRequired).apply(this, arguments); }, /** * Callback invoked whenever the scroll offset changes within the inner scrollable region. * This callback can be used to sync scrolling between lists, tables, or grids. */ "onScroll": _propTypes["default"].func.isRequired, /** * Called whenever a horizontal or vertical scrollbar is added or removed. * This prop is not intended for end-user use; * It is used by MultiGrid to support fixed-row/fixed-column scroll syncing. */ "onScrollbarPresenceChange": _propTypes["default"].func.isRequired, /** Callback invoked with information about the section of the Grid that was just rendered. */ "onSectionRendered": _propTypes["default"].func.isRequired, /** * Number of columns to render before/after the visible section of the grid. * These columns can help for smoother scrolling on touch devices or browsers that send scroll events infrequently. */ "overscanColumnCount": _propTypes["default"].number.isRequired, /** * Calculates the number of cells to overscan before and after a specified range. * This function ensures that overscanning doesn't exceed the available cells. */ "overscanIndicesGetter": function overscanIndicesGetter() { return (typeof _types.bpfrpt_proptype_OverscanIndicesGetter === "function" ? _types.bpfrpt_proptype_OverscanIndicesGetter.isRequired ? _types.bpfrpt_proptype_OverscanIndicesGetter.isRequired : _types.bpfrpt_proptype_OverscanIndicesGetter : _propTypes["default"].shape(_types.bpfrpt_proptype_OverscanIndicesGetter).isRequired).apply(this, arguments); }, /** * Number of rows to render above/below the visible section of the grid. * These rows can help for smoother scrolling on touch devices or browsers that send scroll events infrequently. */ "overscanRowCount": _propTypes["default"].number.isRequired, /** ARIA role for the grid element. */ "role": _propTypes["default"].string.isRequired, /** * Either a fixed row height (number) or a function that returns the height of a row given its index. * Should implement the following interface: ({ index: number }): number */ "rowHeight": function rowHeight() { return (typeof _types.bpfrpt_proptype_CellSize === "function" ? _types.bpfrpt_proptype_CellSize.isRequired ? _types.bpfrpt_proptype_CellSize.isRequired : _types.bpfrpt_proptype_CellSize : _propTypes["default"].shape(_types.bpfrpt_proptype_CellSize).isRequired).apply(this, arguments); }, /** Number of rows in grid. */ "rowCount": _propTypes["default"].number.isRequired, /** Wait this amount of time after the last scroll event before resetting Grid `pointer-events`. */ "scrollingResetTimeInterval": _propTypes["default"].number.isRequired, /** Horizontal offset. */ "scrollLeft": _propTypes["default"].number, /** * Controls scroll-to-cell behavior of the Grid. * The default ("auto") scrolls the least amount possible to ensure that the specified cell is fully visible. * Use "start" to align cells to the top/left of the Grid and "end" to align bottom/right. */ "scrollToAlignment": function scrollToAlignment() { return (typeof _types.bpfrpt_proptype_Alignment === "function" ? _types.bpfrpt_proptype_Alignment.isRequired ? _types.bpfrpt_proptype_Alignment.isRequired : _types.bpfrpt_proptype_Alignment : _propTypes["default"].shape(_types.bpfrpt_proptype_Alignment).isRequired).apply(this, arguments); }, /** Column index to ensure visible (by forcefully scrolling if necessary) */ "scrollToColumn": _propTypes["default"].number.isRequired, /** Vertical offset. */ "scrollTop": _propTypes["default"].number, /** Row index to ensure visible (by forcefully scrolling if necessary) */ "scrollToRow": _propTypes["default"].number.isRequired, /** Optional inline style */ "style": _propTypes["default"].object.isRequired, /** Tab index for focus */ "tabIndex": _propTypes["default"].number, /** Width of Grid; this property determines the number of visible (vs virtualized) columns. */ "width": _propTypes["default"].number.isRequired }), _temp); (0, _defineProperty2["default"])(Grid, "defaultProps", { 'aria-label': 'grid', 'aria-readonly': true, autoContainerWidth: false, autoHeight: false, autoWidth: false, cellRangeRenderer: _defaultCellRangeRenderer["default"], containerRole: 'rowgroup', containerStyle: {}, estimatedColumnSize: 100, estimatedRowSize: 30, getScrollbarSize: _scrollbarSize["default"], noContentRenderer: renderNull, onScroll: function onScroll() {}, onScrollbarPresenceChange: function onScrollbarPresenceChange() {}, onSectionRendered: function onSectionRendered() {}, overscanColumnCount: 0, overscanIndicesGetter: _defaultOverscanIndicesGetter["default"], overscanRowCount: 10, role: 'grid', scrollingResetTimeInterval: DEFAULT_SCROLLING_RESET_TIME_INTERVAL, scrollToAlignment: 'auto', scrollToColumn: -1, scrollToRow: -1, style: {}, tabIndex: 0, isScrollingOptOut: false }); (0, _reactLifecyclesCompat.polyfill)(Grid); var _default = Grid; exports["default"] = _default;dist/commonjs/Grid/Grid.jest.js000064400000300754151676725770012450 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _testUtils = require("react-dom/test-utils"); var _reactTestRenderer = _interopRequireDefault(require("react-test-renderer")); var _TestUtils = require("../TestUtils"); var _Grid = _interopRequireWildcard(require("./Grid")); var _defaultCellRangeRenderer = _interopRequireDefault(require("./defaultCellRangeRenderer")); var _CellMeasurer = require("../CellMeasurer"); var _defaultOverscanIndicesGetter = require("./defaultOverscanIndicesGetter"); var _maxElementSize = require("./utils/maxElementSize.js"); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var DEFAULT_COLUMN_WIDTH = 50; var DEFAULT_HEIGHT = 100; var DEFAULT_ROW_HEIGHT = 20; var DEFAULT_WIDTH = 200; var NUM_ROWS = 100; var NUM_COLUMNS = 50; function getScrollbarSize0() { return 0; } function getScrollbarSize20() { return 20; } describe('Grid', function () { function defaultCellRenderer(_ref) { var columnIndex = _ref.columnIndex, key = _ref.key, rowIndex = _ref.rowIndex, style = _ref.style; return React.createElement("div", { className: "gridItem", key: key, style: style }, "row:".concat(rowIndex, ", column:").concat(columnIndex)); } function simulateScroll(_ref2) { var grid = _ref2.grid, _ref2$scrollLeft = _ref2.scrollLeft, scrollLeft = _ref2$scrollLeft === void 0 ? 0 : _ref2$scrollLeft, _ref2$scrollTop = _ref2.scrollTop, scrollTop = _ref2$scrollTop === void 0 ? 0 : _ref2$scrollTop; var target = { scrollLeft: scrollLeft, scrollTop: scrollTop }; grid._scrollingContainer = target; // HACK to work around _onScroll target check _testUtils.Simulate.scroll((0, _reactDom.findDOMNode)(grid), { target: target }); } function getMarkup() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return React.createElement(_Grid["default"], (0, _extends2["default"])({ cellRenderer: defaultCellRenderer, columnCount: NUM_COLUMNS, columnWidth: DEFAULT_COLUMN_WIDTH, getScrollbarSize: getScrollbarSize0, height: DEFAULT_HEIGHT, overscanColumnCount: 0, overscanRowCount: 0, autoHeight: false, rowHeight: DEFAULT_ROW_HEIGHT, rowCount: NUM_ROWS, width: DEFAULT_WIDTH }, props)); } describe('number of rendered children', function () { it('should render enough children to fill the available area', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.querySelectorAll('.gridItem').length).toEqual(20); // 5 rows x 4 columns }); it('should not render more rows than available if the area is not filled', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ rowCount: 2 }))); expect(rendered.querySelectorAll('.gridItem').length).toEqual(8); // 2 rows x 4 columns }); it('should not render more columns than available if the area is not filled', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnCount: 2 }))); expect(rendered.querySelectorAll('.gridItem').length).toEqual(10); // 5 rows x 2 columns }); // Small performance tweak added in 5.5.6 it('should not render/parent cells that are null or false', function () { function cellRenderer(_ref3) { var columnIndex = _ref3.columnIndex, key = _ref3.key, rowIndex = _ref3.rowIndex, style = _ref3.style; if (columnIndex === 0) { return null; } else if (rowIndex === 0) { return false; } else { return React.createElement("div", { className: "cell", key: key, style: style }, "row:".concat(rowIndex, ", column:").concat(columnIndex)); } } var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnCount: 3, overscanColumnCount: 0, overscanRowCount: 0, rowCount: 3, cellRenderer: cellRenderer }))); expect(rendered.querySelectorAll('.cell').length).toEqual(4); // [1,1], [1,2], [2,1], and [2,2] expect(rendered.textContent).not.toContain('column:0'); expect(rendered.textContent).not.toContain('row:0'); }); it('should scroll to the last existing point when rows are removed', function () { var grid = (0, _TestUtils.render)(getMarkup({ rowCount: 15 })); simulateScroll({ grid: grid, scrollTop: 200 }); var updatedGrid = (0, _TestUtils.render)(getMarkup({ rowCount: 10 })); expect(updatedGrid.state.scrollTop).toEqual(100); }); it('should scroll to the last existing point when columns are removed', function () { var grid = (0, _TestUtils.render)(getMarkup({ columnCount: 12 })); simulateScroll({ grid: grid, scrollLeft: 400 }); var updatedGrid = (0, _TestUtils.render)(getMarkup({ columnCount: 8 })); expect(updatedGrid.state.scrollLeft).toEqual(200); }); it('should not scroll unseen rows are removed', function () { (0, _TestUtils.render)(getMarkup({ rowCount: 15 })); var updatedGrid = (0, _TestUtils.render)(getMarkup({ rowCount: 10 })); expect(updatedGrid.state.scrollTop).toEqual(0); }); it('should not scroll when unseen columns are removed', function () { (0, _TestUtils.render)(getMarkup({ columnCount: 12 })); var updatedGrid = (0, _TestUtils.render)(getMarkup({ columnCount: 8 })); expect(updatedGrid.state.scrollLeft).toEqual(0); }); }); describe('shows and hides scrollbars based on rendered content', function () { it('should set overflowX:hidden if columns fit within the available width and y-axis has no scrollbar', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnCount: 4, getScrollbarSize: getScrollbarSize20, rowCount: 5 }))); expect(rendered.style.overflowX).toEqual('hidden'); }); it('should set overflowX:hidden if columns and y-axis scrollbar fit within the available width', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnCount: 4, getScrollbarSize: getScrollbarSize20, width: 200 + getScrollbarSize20() }))); expect(rendered.style.overflowX).toEqual('hidden'); }); it('should leave overflowX:auto if columns require more than the available width', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnCount: 4, getScrollbarSize: getScrollbarSize20, width: 200 - 1, rowCount: 5 }))); expect(rendered.style.overflowX).not.toEqual('hidden'); }); it('should leave overflowX:auto if columns and y-axis scrollbar require more than the available width', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnCount: 4, getScrollbarSize: getScrollbarSize20, width: 200 + getScrollbarSize20() - 1 }))); expect(rendered.style.overflowX).not.toEqual('hidden'); }); it('should set overflowY:hidden if rows fit within the available width and xaxis has no scrollbar', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ getScrollbarSize: getScrollbarSize20, rowCount: 5, columnCount: 4 }))); expect(rendered.style.overflowY).toEqual('hidden'); }); it('should set overflowY:hidden if rows and x-axis scrollbar fit within the available width', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ getScrollbarSize: getScrollbarSize20, rowCount: 5, height: 100 + getScrollbarSize20() }))); expect(rendered.style.overflowY).toEqual('hidden'); }); it('should leave overflowY:auto if rows require more than the available width', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ getScrollbarSize: getScrollbarSize20, rowCount: 5, height: 100 - 1, columnCount: 4 }))); expect(rendered.style.overflowY).not.toEqual('hidden'); }); it('should leave overflowY:auto if rows and x-axis scrollbar require more than the available width', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ getScrollbarSize: getScrollbarSize20, rowCount: 5, height: 100 + getScrollbarSize20() - 1 }))); expect(rendered.style.overflowY).not.toEqual('hidden'); }); it('should accept styles that overwrite calculated ones', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, height: 1, rowCount: 1, style: { overflowY: 'visible', overflowX: 'visible' }, width: 1 }))); expect(rendered.style.overflowY).toEqual('visible'); expect(rendered.style.overflowX).toEqual('visible'); }); }); /** Tests scrolling via initial props */ describe(':scrollToColumn and :scrollToRow', function () { it('should scroll to the left', function () { var grid = (0, _TestUtils.render)(getMarkup({ scrollToColumn: 0 })); expect(grid.state.scrollLeft).toEqual(0); }); it('should scroll over to the middle', function () { var grid = (0, _TestUtils.render)(getMarkup({ scrollToColumn: 24 })); // 50 columns * 50 item width = 2,500 total item width // 4 columns can be visible at a time and :scrollLeft is initially 0, // So the minimum amount of scrolling leaves the 25th item at the right (just scrolled into view). expect(grid.state.scrollLeft).toEqual(1050); }); it('should scroll to the far right', function () { var grid = (0, _TestUtils.render)(getMarkup({ scrollToColumn: 49 })); // 50 columns * 50 item width = 2,500 total item width // Target offset for the last item then is 2,500 - 200 expect(grid.state.scrollLeft).toEqual(2300); }); it('should scroll to the top', function () { var grid = (0, _TestUtils.render)(getMarkup({ scrollToRow: 0 })); expect(grid.state.scrollTop).toEqual(0); }); it('should scroll down to the middle', function () { var grid = (0, _TestUtils.render)(getMarkup({ scrollToRow: 49 })); // 100 rows * 20 item height = 2,000 total item height // 5 rows can be visible at a time and :scrollTop is initially 0, // So the minimum amount of scrolling leaves the 50th item at the bottom (just scrolled into view). expect(grid.state.scrollTop).toEqual(900); }); it('should scroll to the bottom', function () { var grid = (0, _TestUtils.render)(getMarkup({ scrollToRow: 99 })); // 100 rows * 20 item height = 2,000 total item height // Target offset for the last item then is 2,000 - 100 expect(grid.state.scrollTop).toEqual(1900); }); it('should scroll to a row and column just added', function () { var grid = (0, _TestUtils.render)(getMarkup()); expect(grid.state.scrollLeft).toEqual(0); expect(grid.state.scrollTop).toEqual(0); grid = (0, _TestUtils.render)(getMarkup({ columnCount: NUM_COLUMNS + 1, rowCount: NUM_ROWS + 1, scrollToColumn: NUM_COLUMNS, scrollToRow: NUM_ROWS })); expect(grid.state.scrollLeft).toEqual(2350); expect(grid.state.scrollTop).toEqual(1920); }); it('should scroll back to a newly-added cell without a change in prop', function () { var grid = (0, _TestUtils.render)(getMarkup({ columnCount: NUM_COLUMNS, rowCount: NUM_ROWS, scrollToColumn: NUM_COLUMNS, scrollToRow: NUM_ROWS })); grid = (0, _TestUtils.render)(getMarkup({ columnCount: NUM_COLUMNS + 1, rowCount: NUM_ROWS + 1, scrollToColumn: NUM_COLUMNS, scrollToRow: NUM_ROWS })); expect(grid.state.scrollLeft).toEqual(2350); expect(grid.state.scrollTop).toEqual(1920); }); it('should scroll to the correct position for :scrollToAlignment "start"', function () { var grid = (0, _TestUtils.render)(getMarkup({ scrollToAlignment: 'start', scrollToColumn: 24, scrollToRow: 49 })); // 50 columns * 50 item width = 2,500 total item width // 100 rows * 20 item height = 2,000 total item height // 4 columns and 5 rows can be visible at a time. // The minimum amount of scrolling leaves the specified cell in the bottom/right corner (just scrolled into view). // Since alignment is set to "start" we should scroll past this point until the cell is aligned top/left. expect(grid.state.scrollLeft).toEqual(1200); expect(grid.state.scrollTop).toEqual(980); }); it('should scroll to the correct position for :scrollToAlignment "end"', function () { (0, _TestUtils.render)(getMarkup({ scrollToColumn: 99, scrollToRow: 99 })); var grid = (0, _TestUtils.render)(getMarkup({ scrollToAlignment: 'end', scrollToColumn: 24, scrollToRow: 49 })); // 50 columns * 50 item width = 2,500 total item width // 100 rows * 20 item height = 2,000 total item height // We first scroll past the specified cell and then back. // The minimum amount of scrolling then should leave the specified cell in the top/left corner (just scrolled into view). // Since alignment is set to "end" we should scroll past this point until the cell is aligned bottom/right. expect(grid.state.scrollLeft).toEqual(1050); expect(grid.state.scrollTop).toEqual(900); }); it('should scroll to the correct position for :scrollToAlignment "center"', function () { (0, _TestUtils.render)(getMarkup({ scrollToColumn: 99, scrollToRow: 99 })); var grid = (0, _TestUtils.render)(getMarkup({ scrollToAlignment: 'center', scrollToColumn: 24, scrollToRow: 49 })); // 50 columns * 50 item width = 2,500 total item width // Viewport width is 200 // Column 24 starts at 1,200, center point at 1,225, so... expect(grid.state.scrollLeft).toEqual(1125); // 100 rows * 20 item height = 2,000 total item height // Viewport height is 100 // Row 49 starts at 980, center point at 990, so... expect(grid.state.scrollTop).toEqual(940); }); // Tests issue #691 it('should set the correct :scrollLeft after height increases from 0', function () { _TestUtils.render.unmount(); expect((0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 0, scrollToColumn: 24 }))).scrollLeft || 0).toEqual(0); expect((0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 100, scrollToColumn: 24 }))).scrollLeft).toEqual(1050); }); // Tests issue #691 it('should set the correct :scrollTop after width increases from 0', function () { _TestUtils.render.unmount(); expect((0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToRow: 49, width: 0 }))).scrollTop || 0).toEqual(0); expect((0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToRow: 49, width: 100 }))).scrollTop).toEqual(900); }); // Tests issue #218 it('should set the correct :scrollTop after row and column counts increase from 0', function () { var expectedScrollTop = 100 * DEFAULT_ROW_HEIGHT - DEFAULT_HEIGHT + DEFAULT_ROW_HEIGHT; (0, _TestUtils.render)(getMarkup({ columnCount: 0, rowCount: 150, scrollToRow: 100 })); expect((0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnCount: 150, rowCount: 150, scrollToRow: 100 }))).scrollTop).toEqual(expectedScrollTop); }); it('should support scrollToCell() public method', function () { var grid = (0, _TestUtils.render)(getMarkup()); expect(grid.state.scrollLeft).toEqual(0); expect(grid.state.scrollTop).toEqual(0); grid.scrollToCell({ columnIndex: 24, rowIndex: 49 }); // 50 columns * 50 item width = 2,500 total item width // 4 columns can be visible at a time and :scrollLeft is initially 0, // So the minimum amount of scrolling leaves the 25th item at the right (just scrolled into view). expect(grid.state.scrollLeft).toEqual(1050); // 100 rows * 20 item height = 2,000 total item height // 5 rows can be visible at a time and :scrollTop is initially 0, // So the minimum amount of scrolling leaves the 50th item at the bottom (just scrolled into view). expect(grid.state.scrollTop).toEqual(900); // Change column without affecting row grid.scrollToCell({ columnIndex: 49 }); expect(grid.state.scrollLeft).toEqual(2300); expect(grid.state.scrollTop).toEqual(900); // Change row without affecting column grid.scrollToCell({ rowIndex: 99 }); expect(grid.state.scrollLeft).toEqual(2300); expect(grid.state.scrollTop).toEqual(1900); }); it('should support scrollToPosition() public method', function () { var grid = (0, _TestUtils.render)(getMarkup()); expect(grid.state.scrollLeft).toEqual(0); expect(grid.state.scrollTop).toEqual(0); grid.scrollToPosition({ scrollLeft: 50, scrollTop: 100 }); expect(grid.state.scrollLeft).toEqual(50); expect(grid.state.scrollTop).toEqual(100); // Change column without affecting row grid.scrollToPosition({ scrollLeft: 25 }); expect(grid.state.scrollLeft).toEqual(25); expect(grid.state.scrollTop).toEqual(100); // Change row without affecting column grid.scrollToPosition({ scrollTop: 50 }); expect(grid.state.scrollLeft).toEqual(25); expect(grid.state.scrollTop).toEqual(50); }); it('should support handleScrollEvent() public method', function () { var grid = (0, _TestUtils.render)(getMarkup()); expect(grid.state.scrollLeft).toEqual(0); expect(grid.state.scrollTop).toEqual(0); grid.handleScrollEvent({ scrollLeft: 50, scrollTop: 100 }); expect(grid.state.isScrolling).toEqual(true); expect(grid.state.scrollLeft).toEqual(50); expect(grid.state.scrollTop).toEqual(100); }); it('should support getOffsetForCell() public method', function () { var grid = (0, _TestUtils.render)(getMarkup()); var _grid$getOffsetForCel = grid.getOffsetForCell({ columnIndex: 24, rowIndex: 49 }), scrollLeft = _grid$getOffsetForCel.scrollLeft, scrollTop = _grid$getOffsetForCel.scrollTop; // 50 columns * 50 item width = 2,500 total item width // 4 columns can be visible at a time and :scrollLeft is initially 0, // So the minimum amount of scrolling leaves the 25th item at the right (just scrolled into view). expect(scrollLeft).toEqual(1050); // 100 rows * 20 item height = 2,000 total item height // 5 rows can be visible at a time and :scrollTop is initially 0, // So the minimum amount of scrolling leaves the 50th item at the bottom (just scrolled into view). expect(scrollTop).toEqual(900); }); it('should support getTotalRowsHeight() public method', function () { var grid = (0, _TestUtils.render)(getMarkup()); grid.recomputeGridSize(); var totalHeight = grid.getTotalRowsHeight(); // 100 rows * 20 item height = 2,000 total item height expect(totalHeight).toEqual(2000); }); it('should support getTotalColumnsWidth() public method', function () { var grid = (0, _TestUtils.render)(getMarkup()); grid.recomputeGridSize(); var totalWidth = grid.getTotalColumnsWidth(); // 50 columns * 50 item width = 2,500 total item width expect(totalWidth).toEqual(2500); }); // See issue #565 it('should update scroll position to account for changed cell sizes within a function prop wrapper', function () { var _rowHeight = 20; var props = { height: 100, rowCount: 100, rowHeight: function rowHeight(_ref4) { var index = _ref4.index; return index === 99 ? _rowHeight : 20; }, scrollToRow: 99 }; var grid = (0, _TestUtils.render)(getMarkup(props)); var node = (0, _reactDom.findDOMNode)(grid); expect(node.scrollTop).toBe(1900); _rowHeight = 40; grid.recomputeGridSize({ rowIndex: 99 }); expect(node.scrollTop).toBe(1920); }); it('should not restore scrollLeft when scrolling left and recomputeGridSize with columnIndex smaller than scrollToColumn', function () { var props = { columnWidth: 50, columnCount: 100, height: 100, rowCount: 100, rowHeight: 20, scrollToColumn: 50, scrollToRow: 50, width: 100 }; var grid = (0, _TestUtils.render)(getMarkup(props)); expect(grid.state.scrollLeft).toEqual(2450); simulateScroll({ grid: grid, scrollLeft: 2250 }); expect(grid.state.scrollLeft).toEqual(2250); expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD); grid.recomputeGridSize({ columnIndex: 30 }); expect(grid.state.scrollLeft).toEqual(2250); }); it('should not restore scrollTop when scrolling up and recomputeGridSize with rowIndex smaller than scrollToRow', function () { var props = { columnWidth: 50, columnCount: 100, height: 100, rowCount: 100, rowHeight: 20, scrollToColumn: 50, scrollToRow: 50, width: 100 }; var grid = (0, _TestUtils.render)(getMarkup(props)); expect(grid.state.scrollTop).toEqual(920); simulateScroll({ grid: grid, scrollTop: 720 }); expect(grid.state.scrollTop).toEqual(720); expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD); grid.recomputeGridSize({ rowIndex: 20 }); expect(grid.state.scrollTop).toEqual(720); }); it('should restore scroll offset for column when row count increases from 0 (and vice versa)', function () { var props = { columnWidth: 50, columnCount: 100, height: 100, rowCount: 100, rowHeight: 20, scrollToColumn: 50, scrollToRow: 50, width: 100 }; var grid = (0, _TestUtils.render)(getMarkup(props)); expect(grid.state.scrollLeft).toEqual(2450); expect(grid.state.scrollTop).toEqual(920); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { columnCount: 0 }))); expect(grid.state.scrollLeft).toEqual(0); expect(grid.state.scrollTop).toEqual(0); (0, _TestUtils.render)(getMarkup(props)); expect(grid.state.scrollLeft).toEqual(2450); expect(grid.state.scrollTop).toEqual(920); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { rowCount: 0 }))); expect(grid.state.scrollLeft).toEqual(0); expect(grid.state.scrollTop).toEqual(0); (0, _TestUtils.render)(getMarkup(props)); expect(grid.state.scrollLeft).toEqual(2450); expect(grid.state.scrollTop).toEqual(920); }); it('should take scrollbar size into account when aligning cells', function () { var grid = (0, _TestUtils.render)(getMarkup({ columnWidth: 50, columnCount: 100, getScrollbarSize: getScrollbarSize20, height: 100, rowCount: 100, rowHeight: 20, scrollToColumn: 50, scrollToRow: 50, width: 100 })); expect(grid.state.scrollLeft).toEqual(2450 + getScrollbarSize20()); expect(grid.state.scrollTop).toEqual(920 + getScrollbarSize20()); }); }); describe('property updates', function () { it('should update :scrollToColumn position when :columnWidth changes', function () { var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToColumn: 25 }))); expect(grid.textContent).toContain('column:25'); // Making columns taller pushes name off/beyond the scrolled area grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToColumn: 25, columnWidth: 20 }))); expect(grid.textContent).toContain('column:25'); }); it('should update :scrollToRow position when :rowHeight changes', function () { var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToRow: 50 }))); expect(grid.textContent).toContain('row:50'); // Making rows taller pushes name off/beyond the scrolled area grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToRow: 50, rowHeight: 20 }))); expect(grid.textContent).toContain('row:50'); }); it('should update :scrollToColumn position when :width changes', function () { var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToColumn: 25 }))); expect(grid.textContent).toContain('column:25'); // Making the grid narrower leaves only room for 1 item grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToColumn: 25, width: 50 }))); expect(grid.textContent).toContain('column:25'); }); it('should update :scrollToRow position when :height changes', function () { var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToRow: 50 }))); expect(grid.textContent).toContain('row:50'); // Making the grid shorter leaves only room for 1 item grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToRow: 50, height: 20 }))); expect(grid.textContent).toContain('row:50'); }); it('should update :scrollToColumn position when :scrollToColumn changes', function () { var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(grid.textContent).not.toContain('column:25'); grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToColumn: 25 }))); expect(grid.textContent).toContain('column:25'); }); it('should update :scrollToRow position when :scrollToRow changes', function () { var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(grid.textContent).not.toContain('row:50'); grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToRow: 50 }))); expect(grid.textContent).toContain('row:50'); }); it('should update scroll position if size shrinks smaller than the current scroll', function () { var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToColumn: 250 }))); grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToColumn: 250, columnCount: 10 }))); expect(grid.textContent).toContain('column:9'); }); it('should update scroll position if size shrinks smaller than the current scroll', function () { var grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToRow: 500 }))); grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); grid = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ scrollToRow: 500, rowCount: 10 }))); expect(grid.textContent).toContain('row:9'); }); }); describe('noContentRenderer', function () { it('should call :noContentRenderer if :columnCount is 0', function () { var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ noContentRenderer: function noContentRenderer() { return React.createElement("div", null, "No data"); }, columnCount: 0 }))); expect(list.textContent).toEqual('No data'); }); it('should call :noContentRenderer if :rowCount is 0', function () { var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ noContentRenderer: function noContentRenderer() { return React.createElement("div", null, "No data"); }, rowCount: 0 }))); expect(list.textContent).toEqual('No data'); }); // Sanity check for bvaughn/react-virtualized/pull/348 it('should render an empty body if :rowCount or :columnCount changes to 0', function () { function noContentRenderer() { return React.createElement("div", null, "No data"); } var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ noContentRenderer: noContentRenderer }))); expect(list.textContent).not.toEqual('No data'); list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ noContentRenderer: noContentRenderer, rowCount: 0 }))); expect(list.textContent).toEqual('No data'); list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ noContentRenderer: noContentRenderer }))); expect(list.textContent).not.toEqual('No data'); list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnCount: 0, noContentRenderer: noContentRenderer }))); expect(list.textContent).toEqual('No data'); }); it('should render an empty body if :columnCount is 0 and there is no :noContentRenderer', function () { var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnCount: 0 }))); expect(list.textContent).toEqual(''); }); it('should render an empty body if :rowCount is 0 and there is no :noContentRenderer', function () { var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ rowCount: 0 }))); expect(list.textContent).toEqual(''); }); it('should render an empty body there is a :noContentRenderer but :height or :width are 0', function () { var list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ height: 0, noContentRenderer: function noContentRenderer() { return React.createElement("div", null, "No data"); } }))); expect(list.textContent).toEqual(''); list = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ noContentRenderer: function noContentRenderer() { return React.createElement("div", null, "No data"); }, width: 0 }))); expect(list.textContent).toEqual(''); }); }); describe('onSectionRendered', function () { it('should call :onSectionRendered if at least one cell is rendered', function () { var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex; (0, _TestUtils.render)(getMarkup({ onSectionRendered: function onSectionRendered(params) { var _params; return _params = params, columnStartIndex = _params.columnStartIndex, columnStopIndex = _params.columnStopIndex, rowStartIndex = _params.rowStartIndex, rowStopIndex = _params.rowStopIndex, _params; } })); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(3); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(4); }); it('should not call :onSectionRendered unless the column or row start or stop indices have changed', function () { var numCalls = 0; var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex; var onSectionRendered = function onSectionRendered(params) { columnStartIndex = params.columnStartIndex; columnStopIndex = params.columnStopIndex; rowStartIndex = params.rowStartIndex; rowStopIndex = params.rowStopIndex; numCalls++; }; (0, _TestUtils.render)(getMarkup({ onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(1); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(3); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(4); (0, _TestUtils.render)(getMarkup({ onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(1); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(3); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(4); }); it('should call :onSectionRendered if the row or column start or stop indices have changed', function () { var numCalls = 0; var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex; var onSectionRendered = function onSectionRendered(params) { columnStartIndex = params.columnStartIndex; columnStopIndex = params.columnStopIndex; rowStartIndex = params.rowStartIndex; rowStopIndex = params.rowStopIndex; numCalls++; }; (0, _TestUtils.render)(getMarkup({ onSectionRendered: onSectionRendered })); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(3); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(4); (0, _TestUtils.render)(getMarkup({ height: 50, onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(2); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(3); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(2); (0, _TestUtils.render)(getMarkup({ height: 50, onSectionRendered: onSectionRendered, width: 100 })); expect(numCalls).toEqual(3); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(1); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(2); }); it('should not call :onSectionRendered if no cells are rendered', function () { var numCalls = 0; (0, _TestUtils.render)(getMarkup({ height: 0, onSectionRendered: function onSectionRendered() { return numCalls++; } })); expect(numCalls).toEqual(0); }); }); describe(':scrollLeft and :scrollTop properties', function () { it('should render correctly when an initial :scrollLeft and :scrollTop properties are specified', function () { var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex; (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ onSectionRendered: function onSectionRendered(params) { var _params2; return _params2 = params, columnStartIndex = _params2.columnStartIndex, columnStopIndex = _params2.columnStopIndex, rowStartIndex = _params2.rowStartIndex, rowStopIndex = _params2.rowStopIndex, _params2; }, scrollLeft: 250, scrollTop: 100 }))); expect(rowStartIndex).toEqual(5); expect(rowStopIndex).toEqual(9); expect(columnStartIndex).toEqual(5); expect(columnStopIndex).toEqual(8); }); it('should render correctly when :scrollLeft and :scrollTop properties are updated', function () { var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex; (0, _TestUtils.render)(getMarkup({ onSectionRendered: function onSectionRendered(params) { var _params3; return _params3 = params, columnStartIndex = _params3.columnStartIndex, columnStopIndex = _params3.columnStopIndex, rowStartIndex = _params3.rowStartIndex, rowStopIndex = _params3.rowStopIndex, _params3; } })); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(4); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(3); (0, _TestUtils.render)(getMarkup({ onSectionRendered: function onSectionRendered(params) { var _params4; return _params4 = params, columnStartIndex = _params4.columnStartIndex, columnStopIndex = _params4.columnStopIndex, rowStartIndex = _params4.rowStartIndex, rowStopIndex = _params4.rowStopIndex, _params4; }, scrollLeft: 250, scrollTop: 100 })); expect(rowStartIndex).toEqual(5); expect(rowStopIndex).toEqual(9); expect(columnStartIndex).toEqual(5); expect(columnStopIndex).toEqual(8); }); }); describe('styles, classNames, and ids', function () { it('should use the expected global CSS classNames', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.className).toEqual('ReactVirtualized__Grid'); }); it('should use a custom :className if specified', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ className: 'foo' }))); expect(rendered.className).toContain('foo'); }); it('should use a custom :id if specified', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ id: 'bar' }))); expect(rendered.getAttribute('id')).toEqual('bar'); }); it('should use a custom :style if specified', function () { var style = { backgroundColor: 'red' }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ style: style }))); expect(rendered.style.backgroundColor).toEqual('red'); }); it('should use a custom :containerStyle if specified', function () { var containerStyle = { backgroundColor: 'red' }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ containerStyle: containerStyle }))); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.backgroundColor).toEqual('red'); }); }); describe('onScroll', function () { it('should trigger callback when component is mounted', function () { var onScrollCalls = []; (0, _TestUtils.render)(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); }, scrollLeft: 50, scrollTop: 100 })); expect(onScrollCalls).toEqual([{ clientHeight: 100, clientWidth: 200, scrollHeight: 2000, scrollLeft: 50, scrollTop: 100, scrollWidth: 2500 }]); }); it('should trigger callback when component scrolls horizontally', function () { var onScrollCalls = []; var grid = (0, _TestUtils.render)(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); simulateScroll({ grid: grid, scrollLeft: 100, scrollTop: 0 }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: 100, clientWidth: 200, scrollHeight: 2000, scrollLeft: 100, scrollTop: 0, scrollWidth: 2500 }); }); it('should trigger callback when component scrolls vertically', function () { var onScrollCalls = []; var grid = (0, _TestUtils.render)(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); simulateScroll({ grid: grid, scrollLeft: 0, scrollTop: 100 }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: 100, clientWidth: 200, scrollHeight: 2000, scrollLeft: 0, scrollTop: 100, scrollWidth: 2500 }); }); it('should trigger callback with scrollLeft of 0 when total columns width is less than width', function () { var onScrollCalls = []; var grid = (0, _TestUtils.render)(getMarkup({ columnCount: 1, columnWidth: 50, onScroll: function onScroll(params) { return onScrollCalls.push(params); }, scrollLeft: 0, scrollTop: 10, width: 200 })); simulateScroll({ grid: grid, scrollLeft: 0, scrollTop: 0 }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: 100, clientWidth: 200, scrollHeight: 2000, scrollLeft: 0, scrollTop: 0, scrollWidth: 50 }); }); it('should trigger callback with scrollTop of 0 when total rows height is less than height', function () { var onScrollCalls = []; var grid = (0, _TestUtils.render)(getMarkup({ rowCount: 1, rowHeight: 50, onScroll: function onScroll(params) { return onScrollCalls.push(params); }, scrollLeft: 0, scrollTop: 10, height: 200 })); simulateScroll({ grid: grid, scrollLeft: 0, scrollTop: 0 }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: 200, clientWidth: 200, scrollHeight: 50, scrollLeft: 0, scrollTop: 0, scrollWidth: 2500 }); }); // Support use-cases like WindowScroller; enable them to stay in sync with scroll-to-cell changes. it('should trigger when :scrollToColumn or :scrollToRow are changed via props', function () { var onScrollCalls = []; (0, _TestUtils.render)(getMarkup()); (0, _TestUtils.render)(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); }, scrollToColumn: 24, scrollToRow: 49 })); expect(onScrollCalls).toEqual([{ clientHeight: 100, clientWidth: 200, scrollHeight: 2000, scrollLeft: 1050, scrollTop: 900, scrollWidth: 2500 }]); }); }); describe('overscanColumnCount & overscanRowCount', function () { function createHelper() { var _columnOverscanStartIndex, _columnOverscanStopIndex, _columnStartIndex, _columnStopIndex, _rowOverscanStartIndex, _rowOverscanStopIndex, _rowStartIndex, _rowStopIndex; function onSectionRendered(params) { _columnOverscanStartIndex = params.columnOverscanStartIndex; _columnOverscanStopIndex = params.columnOverscanStopIndex; _columnStartIndex = params.columnStartIndex; _columnStopIndex = params.columnStopIndex; _rowOverscanStartIndex = params.rowOverscanStartIndex; _rowOverscanStopIndex = params.rowOverscanStopIndex; _rowStartIndex = params.rowStartIndex; _rowStopIndex = params.rowStopIndex; } return { columnOverscanStartIndex: function columnOverscanStartIndex() { return _columnOverscanStartIndex; }, columnOverscanStopIndex: function columnOverscanStopIndex() { return _columnOverscanStopIndex; }, columnStartIndex: function columnStartIndex() { return _columnStartIndex; }, columnStopIndex: function columnStopIndex() { return _columnStopIndex; }, onSectionRendered: onSectionRendered, rowOverscanStartIndex: function rowOverscanStartIndex() { return _rowOverscanStartIndex; }, rowOverscanStopIndex: function rowOverscanStopIndex() { return _rowOverscanStopIndex; }, rowStartIndex: function rowStartIndex() { return _rowStartIndex; }, rowStopIndex: function rowStopIndex() { return _rowStopIndex; } }; } it('should not overscan if disabled', function () { var helper = createHelper(); (0, _TestUtils.render)(getMarkup({ onSectionRendered: helper.onSectionRendered })); expect(helper.columnOverscanStartIndex()).toEqual(helper.columnStartIndex()); expect(helper.columnOverscanStopIndex()).toEqual(helper.columnStopIndex()); expect(helper.rowOverscanStartIndex()).toEqual(helper.rowStartIndex()); expect(helper.rowOverscanStopIndex()).toEqual(helper.rowStopIndex()); }); it('should overscan the specified amount', function () { var helper = createHelper(); (0, _TestUtils.render)(getMarkup({ onSectionRendered: helper.onSectionRendered, overscanColumnCount: 2, overscanRowCount: 5, scrollToColumn: 25, scrollToRow: 50 })); expect(helper.columnOverscanStartIndex()).toEqual(22); expect(helper.columnOverscanStopIndex()).toEqual(27); expect(helper.columnStartIndex()).toEqual(22); expect(helper.columnStopIndex()).toEqual(25); expect(helper.rowOverscanStartIndex()).toEqual(46); expect(helper.rowOverscanStopIndex()).toEqual(55); expect(helper.rowStartIndex()).toEqual(46); expect(helper.rowStopIndex()).toEqual(50); }); it('should not overscan beyond the bounds of the grid', function () { var helper = createHelper(); (0, _TestUtils.render)(getMarkup({ onSectionRendered: helper.onSectionRendered, columnCount: 6, overscanColumnCount: 10, overscanRowCount: 10, rowCount: 5 })); expect(helper.columnOverscanStartIndex()).toEqual(0); expect(helper.columnOverscanStopIndex()).toEqual(5); expect(helper.columnStartIndex()).toEqual(0); expect(helper.columnStopIndex()).toEqual(3); expect(helper.rowOverscanStartIndex()).toEqual(0); expect(helper.rowOverscanStopIndex()).toEqual(4); expect(helper.rowStartIndex()).toEqual(0); expect(helper.rowStopIndex()).toEqual(4); }); it('should set the correct scroll direction', function () { // Do not pass in the initial state as props, otherwise the internal state is forbidden from updating itself var grid = (0, _TestUtils.render)(getMarkup()); // Simulate a scroll to set the initial internal state simulateScroll({ grid: grid, scrollLeft: 50, scrollTop: 50 }); expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); simulateScroll({ grid: grid, scrollLeft: 0, scrollTop: 0 }); expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD); expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD); simulateScroll({ grid: grid, scrollLeft: 100, scrollTop: 100 }); expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); }); it('should set the correct scroll direction when scroll position is updated from props', function () { var grid = (0, _TestUtils.render)(getMarkup({ scrollLeft: 50, scrollTop: 50 })); expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); grid = (0, _TestUtils.render)(getMarkup({ scrollLeft: 0, scrollTop: 0 })); expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD); expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD); grid = (0, _TestUtils.render)(getMarkup({ scrollLeft: 100, scrollTop: 100 })); expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); }); it('should not reset scroll direction for one axis when scrolled in another', function () { // Do not pass in the initial state as props, otherwise the internal state is forbidden from updating itself var grid = (0, _TestUtils.render)(getMarkup()); // Simulate a scroll to set the initial internal state simulateScroll({ grid: grid, scrollLeft: 0, scrollTop: 5 }); expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); simulateScroll({ grid: grid, scrollLeft: 5, scrollTop: 5 }); expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); simulateScroll({ grid: grid, scrollLeft: 5, scrollTop: 0 }); expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD); simulateScroll({ grid: grid, scrollLeft: 0, scrollTop: 0 }); expect(grid.state.scrollDirectionHorizontal).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD); expect(grid.state.scrollDirectionVertical).toEqual(_defaultOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD); }); it('should overscan in the direction being scrolled', function _callee(done) { var helper, onSectionRenderedResolve, onSectionRendered, grid, onSectionRenderedPromise; return _regenerator["default"].async(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: onSectionRendered = function _ref5(params) { helper.onSectionRendered(params); if (onSectionRenderedResolve) { onSectionRenderedResolve(); } }; helper = createHelper(); grid = (0, _TestUtils.render)(getMarkup({ onSectionRendered: onSectionRendered, overscanColumnCount: 2, overscanRowCount: 5 })); // Wait until the onSectionRendered handler / debouncer has processed onSectionRenderedPromise = new Promise(function (resolve) { onSectionRenderedResolve = resolve; }); simulateScroll({ grid: grid, scrollLeft: 200, scrollTop: 200 }); _context.next = 7; return _regenerator["default"].awrap(onSectionRenderedPromise); case 7: // It should overscan in the direction being scrolled while scroll is in progress expect(helper.columnOverscanStartIndex()).toEqual(4); expect(helper.columnOverscanStopIndex()).toEqual(9); expect(helper.columnStartIndex()).toEqual(4); expect(helper.columnStopIndex()).toEqual(7); expect(helper.rowOverscanStartIndex()).toEqual(10); expect(helper.rowOverscanStopIndex()).toEqual(19); expect(helper.rowStartIndex()).toEqual(10); expect(helper.rowStopIndex()).toEqual(14); // Wait until the onSectionRendered handler / debouncer has processed onSectionRenderedPromise = new Promise(function (resolve) { onSectionRenderedResolve = resolve; }); simulateScroll({ grid: grid, scrollLeft: 100, scrollTop: 100 }); _context.next = 19; return _regenerator["default"].awrap(onSectionRenderedPromise); case 19: // It reset overscan once scrolling has finished expect(helper.columnOverscanStartIndex()).toEqual(0); expect(helper.columnOverscanStopIndex()).toEqual(5); expect(helper.columnStartIndex()).toEqual(2); expect(helper.columnStopIndex()).toEqual(5); expect(helper.rowOverscanStartIndex()).toEqual(0); expect(helper.rowOverscanStopIndex()).toEqual(9); expect(helper.rowStartIndex()).toEqual(5); expect(helper.rowStopIndex()).toEqual(9); done(); case 28: case "end": return _context.stop(); } } }); }); }); describe('cellRangeRenderer', function () { it('should use a custom :cellRangeRenderer if specified', function () { var cellRangeRendererCalled = 0; var cellRangeRendererParams; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ cellRangeRenderer: function cellRangeRenderer(params) { cellRangeRendererParams = params; cellRangeRendererCalled++; return [React.createElement("div", { key: "0" }, "Fake content")]; } }))); expect(cellRangeRendererCalled).toEqual(1); expect(cellRangeRendererParams.columnStartIndex).toEqual(0); expect(cellRangeRendererParams.columnStopIndex).toEqual(3); expect(cellRangeRendererParams.rowStartIndex).toEqual(0); expect(cellRangeRendererParams.rowStopIndex).toEqual(4); expect(rendered.textContent).toContain('Fake content'); }); }); describe('estimated row and column sizes', function () { it('should not estimate sizes if actual sizes are numbers', function () { var grid = (0, _TestUtils.render)(getMarkup({ columnWidth: 100, estimatedColumnSize: 150, estimatedRowSize: 15, rowHeight: 20 })); expect(_Grid["default"]._getEstimatedColumnSize(grid.props)).toEqual(100); expect(_Grid["default"]._getEstimatedRowSize(grid.props)).toEqual(20); }); it('should estimate row and column sizes if actual sizes are functions', function () { var grid = (0, _TestUtils.render)(getMarkup({ columnWidth: function columnWidth() { return 100; }, estimatedColumnSize: 150, estimatedRowSize: 15, rowHeight: function rowHeight() { return 20; } })); expect(_Grid["default"]._getEstimatedColumnSize(grid.props)).toEqual(150); expect(_Grid["default"]._getEstimatedRowSize(grid.props)).toEqual(15); }); }); it('should pass the cellRenderer an :isScrolling flag when scrolling is in progress', function _callee2(done) { var cellRendererCalls, cellRenderer, grid; return _regenerator["default"].async(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: cellRenderer = function _ref7(_ref6) { var columnIndex = _ref6.columnIndex, isScrolling = _ref6.isScrolling, key = _ref6.key, rowIndex = _ref6.rowIndex, style = _ref6.style; cellRendererCalls.push(isScrolling); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); }; cellRendererCalls = []; grid = (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer })); expect(cellRendererCalls[0]).toEqual(false); cellRendererCalls.splice(0); // Give React time to process the queued setState() _context2.next = 7; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, 1); })); case 7: simulateScroll({ grid: grid, scrollTop: 100 }); expect(cellRendererCalls[0]).toEqual(true); done(); case 10: case "end": return _context2.stop(); } } }); }); it('should pass the cellRenderer an :isScrolling flag based on props override', function () { var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (_ref8) { var key = _ref8.key, style = _ref8.style; return React.createElement("div", { key: key, style: style }); }); (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer, isScrolling: true })); expect(cellRenderer).toHaveBeenCalled(); expect(cellRenderer.mock.calls[0][0].isScrolling).toBe(true); cellRenderer.mockReset(); (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer, isScrolling: false, width: DEFAULT_WIDTH + 1 })); expect(cellRenderer).toHaveBeenCalled(); expect(cellRenderer.mock.calls[0][0].isScrolling).toBe(false); }); it('should pass the cellRenderer an :isVisible flag', function () { var cellRendererCalls = []; function cellRenderer(props) { cellRendererCalls.push(props); return defaultCellRenderer(props); } (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer, height: DEFAULT_ROW_HEIGHT, overscanColumnCount: 1, overscanRowCount: 1, width: DEFAULT_COLUMN_WIDTH })); cellRendererCalls.forEach(function (props) { expect(props.isVisible).toEqual(props.columnIndex === 0 && props.rowIndex === 0); // Only the first cell is visible }); }); describe('cell caching', function () { it('should not cache cells if the Grid is not scrolling', function () { var cellRendererCalls = []; function cellRenderer(_ref9) { var columnIndex = _ref9.columnIndex, key = _ref9.key, rowIndex = _ref9.rowIndex, style = _ref9.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, scrollToRow: 0, width: 100 }; (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { scrollToRow: 0 }))); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); cellRendererCalls.splice(0); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { scrollToRow: 1 }))); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); }); it('should not cache cells if the offsets are not adjusted', function () { var cellRendererCalls = []; function cellRenderer(_ref10) { var columnIndex = _ref10.columnIndex, key = _ref10.key, rowIndex = _ref10.rowIndex, style = _ref10.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, rowCount: 100000, scrollToRow: 0, width: 100 }; (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { scrollToRow: 0 }))); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); cellRendererCalls.splice(0); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { scrollToRow: 1 }))); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); }); it('should cache a cell once it has been rendered while scrolling', function () { var cellRendererCalls = []; function cellRenderer(_ref11) { var columnIndex = _ref11.columnIndex, key = _ref11.key, rowIndex = _ref11.rowIndex, style = _ref11.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, width: 100 }; var grid = (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { scrollToRow: 0 }))); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); simulateScroll({ grid: grid, scrollTop: 1 }); cellRendererCalls.splice(0); // Rows 0-2 have already rendered but row 3 is not yet visible // This means that only row 3 should be newly-created // The others should come from the cache (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { scrollToRow: 3 }))); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 3 }]); }); it('should clear cache once :isScrolling is false', function _callee3(done) { var cellRendererCalls, cellRenderer, props, grid; return _regenerator["default"].async(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: cellRenderer = function _ref13(_ref12) { var columnIndex = _ref12.columnIndex, key = _ref12.key, rowIndex = _ref12.rowIndex, style = _ref12.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); }; cellRendererCalls = []; props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, scrollToRow: 0, width: 100 }; grid = (0, _TestUtils.render)(getMarkup(props)); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); simulateScroll({ grid: grid, scrollTop: 1 }); // Allow scrolling timeout to complete so that cell cache is reset _context3.next = 8; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, _Grid.DEFAULT_SCROLLING_RESET_TIME_INTERVAL * 2); })); case 8: cellRendererCalls.splice(0); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { scrollToRow: 1 }))); expect(cellRendererCalls.length).not.toEqual(0); done(); case 12: case "end": return _context3.stop(); } } }); }); it('should clear cache once :isScrolling via props is false', function _callee4() { var cellRenderer, props, scrollingStyle; return _regenerator["default"].async(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (params) { return React.createElement("div", { key: params.key, style: params.style }); }); props = { autoHeight: true, cellRenderer: cellRenderer, columnCount: 1, isScrolling: true, rowCount: 1 }; (0, _TestUtils.render)(getMarkup(props)); (0, _TestUtils.render)(getMarkup(props)); expect(cellRenderer).toHaveBeenCalledTimes(1); // Due to cell cache scrollingStyle = cellRenderer.mock.calls[0][0].style; cellRenderer.mockReset(); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { isScrolling: false }))); expect(cellRenderer.mock.calls[0][0].style).toBe(scrollingStyle); expect(cellRenderer).toHaveBeenCalledTimes(1); // Reset cache cellRenderer.mockReset(); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { isScrolling: true }))); expect(cellRenderer.mock.calls[0][0].style).not.toBe(scrollingStyle); expect(cellRenderer).toHaveBeenCalledTimes(1); // Only cached when scrolling case 15: case "end": return _context4.stop(); } } }); }); it('should clear cache if :recomputeGridSize is called', function () { var cellRendererCalls = []; function cellRenderer(_ref14) { var columnIndex = _ref14.columnIndex, key = _ref14.key, rowIndex = _ref14.rowIndex, style = _ref14.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, scrollTop: 0, width: 100 }; var grid = (0, _TestUtils.render)(getMarkup(props)); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); simulateScroll({ grid: grid, scrollTop: 1 }); cellRendererCalls.splice(0); grid.recomputeGridSize(); expect(cellRendererCalls.length).not.toEqual(0); }); it('should not clear cache if :isScrollingOptOut is true', function () { var cellRendererCalls = []; function cellRenderer(_ref15) { var columnIndex = _ref15.columnIndex, key = _ref15.key, rowIndex = _ref15.rowIndex, style = _ref15.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, scrollTop: 0, width: 100, isScrollingOptOut: true }; (0, _TestUtils.render)(getMarkup(props)); (0, _TestUtils.render)(getMarkup(props)); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); cellRendererCalls.splice(0); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { isScrolling: false }))); // Visible cells are cached expect(cellRendererCalls.length).toEqual(0); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { isScrolling: true }))); // Only cleared non-visible cells expect(cellRendererCalls.length).toEqual(0); }); it('should not trigger render by _debounceScrollEndedCallback if process slow table', function _callee5() { var scrollingResetTimeInterval, cellRangeRendererCalls, cellRangeRenderer, props, grid, i; return _regenerator["default"].async(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: cellRangeRenderer = function _ref16(props) { var startTime = Date.now(); while (Date.now() - startTime <= scrollingResetTimeInterval) { ; } // imitate very slow render cellRangeRendererCalls++; return (0, _defaultCellRangeRenderer["default"])(props); }; scrollingResetTimeInterval = 50; cellRangeRendererCalls = 0; props = { scrollingResetTimeInterval: scrollingResetTimeInterval, cellRangeRenderer: cellRangeRenderer }; grid = (0, _TestUtils.render)(getMarkup(props)); (0, _TestUtils.render)(getMarkup(props)); expect(cellRangeRendererCalls).toEqual(1); i = 1; case 8: if (!(i <= 5)) { _context5.next = 17; break; } cellRangeRendererCalls = 0; simulateScroll({ grid: grid, scrollTop: i }); // small wait for maybe early _debounceScrollEndedCallback _context5.next = 13; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, scrollingResetTimeInterval / 2); })); case 13: expect(cellRangeRendererCalls).toEqual(1); case 14: i++; _context5.next = 8; break; case 17: cellRangeRendererCalls = 0; // wait for real _debounceScrollEndedCallback _context5.next = 20; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, scrollingResetTimeInterval * 1.5); })); case 20: expect(cellRangeRendererCalls).toEqual(1); case 21: case "end": return _context5.stop(); } } }); }); it('should support a custom :scrollingResetTimeInterval prop', function _callee6(done) { var cellRendererCalls, scrollingResetTimeInterval, cellRenderer, props, grid; return _regenerator["default"].async(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: cellRenderer = function _ref18(_ref17) { var columnIndex = _ref17.columnIndex, key = _ref17.key, rowIndex = _ref17.rowIndex, style = _ref17.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); }; cellRendererCalls = []; scrollingResetTimeInterval = _Grid.DEFAULT_SCROLLING_RESET_TIME_INTERVAL * 2; props = { cellRenderer: cellRenderer, scrollingResetTimeInterval: scrollingResetTimeInterval }; grid = (0, _TestUtils.render)(getMarkup(props)); expect(cellRendererCalls.length > 0).toEqual(true); simulateScroll({ grid: grid, scrollTop: 1 }); _context6.next = 9; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, _Grid.DEFAULT_SCROLLING_RESET_TIME_INTERVAL); })); case 9: cellRendererCalls.splice(0); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { className: 'foo' }))); expect(cellRendererCalls.length).toEqual(0); _context6.next = 14; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, _Grid.DEFAULT_SCROLLING_RESET_TIME_INTERVAL * 2); })); case 14: cellRendererCalls.splice(0); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { className: 'bar' }))); expect(cellRendererCalls.length).not.toEqual(0); done(); case 18: case "end": return _context6.stop(); } } }); }); }); describe('measureAllCells', function () { it('should measure any unmeasured columns and rows', function () { var grid = (0, _TestUtils.render)(getMarkup({ columnCount: 10, columnWidth: function columnWidth() { return 100; }, estimatedColumnSize: 150, estimatedRowSize: 15, height: 0, rowCount: 10, rowHeight: function rowHeight() { return 20; }, width: 0 })); expect(grid.state.instanceProps.columnSizeAndPositionManager.getTotalSize()).toEqual(1500); expect(grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(150); grid.measureAllCells(); expect(grid.state.instanceProps.columnSizeAndPositionManager.getTotalSize()).toEqual(1000); expect(grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(200); }); }); describe('recomputeGridSize', function () { it('should recompute cell sizes and other values when called', function () { var columnIndices = []; var rowIndices = []; function columnWidth(_ref19) { var index = _ref19.index; columnIndices.push(index); return 10; } function rowHeight(_ref20) { var index = _ref20.index; rowIndices.push(index); return 10; } var props = { columnCount: 50, columnWidth: columnWidth, height: 50, rowHeight: rowHeight, rowCount: 50, width: 100 }; var component = (0, _TestUtils.render)(getMarkup(props)); columnIndices.splice(0); rowIndices.splice(0); component.recomputeGridSize(); // Only the rows required to fill the current viewport will be rendered expect(columnIndices[0]).toEqual(0); expect(columnIndices[columnIndices.length - 1]).toEqual(9); expect(rowIndices[0]).toEqual(0); expect(rowIndices[rowIndices.length - 1]).toEqual(4); columnIndices.splice(0); rowIndices.splice(0); component.recomputeGridSize({ columnIndex: 4, rowIndex: 2 }); // Only the rows required to fill the current viewport will be rendered expect(columnIndices[0]).toEqual(4); expect(columnIndices[columnIndices.length - 1]).toEqual(9); expect(rowIndices[0]).toEqual(2); expect(rowIndices[rowIndices.length - 1]).toEqual(4); }); }); describe('autoContainerWidth', function () { it('should set the innerScrollContainer width to auto to better support single-column HOCs', function () { var props = { autoContainerWidth: true }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props))); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('auto'); }); it('should set the innerScrollContainer width to :totalColumnsWidth unless :autoContainerWidth', function () { var props = { autoContainerWidth: false }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props))); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('2500px'); // 50 columns x 50px }); }); describe('autoHeight', function () { it('should set the container height to auto to adjust to innerScrollContainer height', function () { var props = { autoHeight: true }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props))); expect(rendered.style.height).toEqual('auto'); }); it('should have container height still affecting number of rows rendered', function () { var props = { height: 500, autoHeight: true }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props))); expect(rendered.querySelectorAll('.gridItem').length).toEqual(100); // 25 rows x 4 columns }); it('should have innerScrollContainer height to be equal number of rows * rowHeight', function () { var props = { autoHeight: true }; var grid = (0, _TestUtils.render)(getMarkup(props)); var rendered = (0, _reactDom.findDOMNode)(grid); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.height).toEqual('2000px'); // 100 rows * 20px rowHeight expect(grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(2000); }); }); describe('autoWidth', function () { it('should set the container width to auto to adjust to innerScrollContainer width', function () { var props = { autoWidth: true }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props))); expect(rendered.style.width).toEqual('auto'); }); it('should have container width still affecting number of columns rendered', function () { var props = { width: 500, autoWidth: true }; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(props))); expect(rendered.querySelectorAll('.gridItem').length).toEqual(50); // 5 rows x 10 columns }); it('should have innerScrollContainer width to be equal number of columns * columnWidth', function () { var props = { autoWidth: true }; var grid = (0, _TestUtils.render)(getMarkup(props)); var rendered = (0, _reactDom.findDOMNode)(grid); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('2500px'); // 50 columns * 50px columnWidth expect(grid.state.instanceProps.columnSizeAndPositionManager.getTotalSize()).toEqual(2500); }); }); describe('tabIndex', function () { it('should be focusable by default', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.tabIndex).toEqual(0); }); it('should allow tabIndex to be overridden', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ tabIndex: -1 }))); expect(rendered.tabIndex).toEqual(-1); }); }); describe('role', function () { it('should have grid role by default', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.getAttribute('role')).toEqual('grid'); }); it('should allow role to be overridden', function () { var role = null; var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ role: role }))); expect(rendered.getAttribute('role')).toEqual(role); }); }); describe('pure', function () { it('should not re-render unless props have changed', function () { var cellRendererCalled = false; function cellRenderer(_ref21) { var key = _ref21.key, style = _ref21.style; cellRendererCalled = true; return React.createElement("div", { key: key, style: style }); } var markup = getMarkup({ cellRenderer: cellRenderer }); (0, _TestUtils.render)(markup); expect(cellRendererCalled).toEqual(true); cellRendererCalled = false; (0, _TestUtils.render)(markup); expect(cellRendererCalled).toEqual(false); }); it('should not re-render grid components if they extend PureComponent', function () { var componentUpdates = 0; var GridComponent = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(GridComponent, _React$PureComponent); function GridComponent() { (0, _classCallCheck2["default"])(this, GridComponent); return (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(GridComponent).apply(this, arguments)); } (0, _createClass2["default"])(GridComponent, [{ key: "componentDidUpdate", value: function componentDidUpdate() { componentUpdates++; } }, { key: "render", value: function render() { var _this$props = this.props, columnIndex = _this$props.columnIndex, rowIndex = _this$props.rowIndex, style = _this$props.style; return React.createElement("div", { className: "gridItem", style: style }, "row:".concat(rowIndex, ", column:").concat(columnIndex)); } }]); return GridComponent; }(React.PureComponent); function cellRenderer(_ref22) { var columnIndex = _ref22.columnIndex, key = _ref22.key, rowIndex = _ref22.rowIndex, style = _ref22.style; return React.createElement(GridComponent, { key: key, columnIndex: columnIndex, rowIndex: rowIndex, style: style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, scrollTop: 0, width: 100 }; var grid = (0, _TestUtils.render)(getMarkup(props)); simulateScroll({ grid: grid, scrollToIndex: 1 }); expect(componentUpdates).toEqual(0); }); it('should clear all but the visible rows from the style cache once :isScrolling is false', function _callee7(done) { var props, grid; return _regenerator["default"].async(function _callee7$(_context7) { while (1) { switch (_context7.prev = _context7.next) { case 0: props = { columnWidth: 50, height: 100, overscanColumnCount: 0, overscanRowCount: 0, rowHeight: 50, width: 100 }; grid = (0, _TestUtils.render)(getMarkup(props)); expect(Object.keys(grid._styleCache).length).toBe(4); simulateScroll({ grid: grid, scrollTop: 50 }); expect(Object.keys(grid._styleCache).length).toBe(6); // Allow scrolling timeout to complete so that cell cache is reset _context7.next = 7; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, _Grid.DEFAULT_SCROLLING_RESET_TIME_INTERVAL * 2); })); case 7: expect(Object.keys(grid._styleCache).length).toBe(4); done(); case 9: case "end": return _context7.stop(); } } }); }); it('should clear style cache if :recomputeGridSize is called', function () { var props = { columnWidth: 50, height: 100, overscanColumnCount: 0, overscanRowCount: 0, rowHeight: 50, width: 100 }; var grid = (0, _TestUtils.render)(getMarkup(props)); expect(Object.keys(grid._styleCache).length).toBe(4); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { scrollTop: 50 }))); expect(Object.keys(grid._styleCache).length).toBe(6); grid.recomputeGridSize(); expect(Object.keys(grid._styleCache).length).toBe(4); }); it('should clear style cache if cell sizes change', function () { var cellRendererCalls = []; function cellRenderer(params) { cellRendererCalls.push(params); return React.createElement("div", { key: params.key, style: params.style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 100, overscanColumnCount: 0, overscanRowCount: 0, rowHeight: 100, width: 100 }; (0, _TestUtils.render)(getMarkup(props)); expect(cellRendererCalls.length).toEqual(1); expect(cellRendererCalls[0].style.width).toEqual(100); (0, _TestUtils.render)(getMarkup(_objectSpread({}, props, { columnWidth: 50, width: 50 }))); expect(cellRendererCalls.length).toEqual(2); expect(cellRendererCalls[1].style.width).toEqual(50); }); }); it('should not pull from the style cache while scrolling if there is an offset adjustment', function () { var cellRendererCalls = []; function cellRenderer(params) { cellRendererCalls.push(params); return React.createElement("div", { key: params.key, style: params.style }); } var grid = (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer, width: 100, height: 100, rowHeight: 100, columnWidth: 100, rowCount: (0, _maxElementSize.getMaxElementSize)() * 2 / 100, // lots of offset scrollTop: 2000 })); simulateScroll({ grid: grid, scrollTop: 2100 }); // cellRendererCalls[0] is the element at rowIndex 0 // only two calls. Since the scrollTop is updated in getDerivedStateFromProps var firstProps = cellRendererCalls[0]; var secondProps = cellRendererCalls[1]; expect(cellRendererCalls.length).toEqual(2); expect(firstProps.style).not.toBe(secondProps.style); }); it('should only cache styles when a :deferredMeasurementCache is provided if the cell has already been measured', function () { var cache = new _CellMeasurer.CellMeasurerCache({ fixedWidth: true }); cache.set(0, 0, 100, 100); cache.set(1, 1, 100, 100); var grid = (0, _TestUtils.render)(getMarkup({ columnCount: 2, deferredMeasurementCache: cache, rowCount: 2 })); var keys = Object.keys(grid._styleCache); expect(keys).toEqual(['0-0', '1-1']); }); describe('DEV warnings', function () { it('should warn about cells that forget to include the :style property', function () { spyOn(console, 'warn'); function cellRenderer(params) { return React.createElement("div", { key: params.key }); } (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer })); expect(console.warn).toHaveBeenCalledWith('Rendered cell should include style property for positioning.'); expect(console.warn).toHaveBeenCalledTimes(1); }); it('should warn about CellMeasurer measured cells that forget to include the :style property', function () { spyOn(console, 'warn'); var cache = new _CellMeasurer.CellMeasurerCache({ fixedWidth: true }); var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (params) { return React.createElement(_CellMeasurer.CellMeasurer, { cache: cache, columnIndex: params.columnIndex, key: params.key, parent: params.parent, rowIndex: params.rowIndex, style: params.style }, React.createElement("div", null)); }); (0, _TestUtils.render)(getMarkup({ cellRenderer: cellRenderer, columnCount: 1, deferredMeasurementCache: cache, rowCount: 1 })); expect(console.warn).toHaveBeenCalledWith('Rendered cell should include style property for positioning.'); expect(console.warn).toHaveBeenCalledTimes(1); }); }); describe('deferredMeasurementCache', function () { it('invalidateCellSizeAfterRender should invalidate cache and refresh displayed cells after mount', function () { var cache = new _CellMeasurer.CellMeasurerCache({ fixedWidth: true }); var invalidateCellSizeAfterRender = true; var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (params) { // Don't get stuck in a loop if (invalidateCellSizeAfterRender) { invalidateCellSizeAfterRender = false; params.parent.invalidateCellSizeAfterRender({ columnIndex: 1, rowIndex: 0 }); } return React.createElement("div", { key: params.key, style: params.style }); }); var props = { cellRenderer: cellRenderer, columnCount: 2, deferredMeasurementCache: cache, rowCount: 2 }; (0, _TestUtils.render)(getMarkup(props)); // 4 times for initial render + 4 once cellCache was cleared expect(cellRenderer).toHaveBeenCalledTimes(8); }); it('should invalidate cache and refresh displayed cells after update', function () { var cache = new _CellMeasurer.CellMeasurerCache({ fixedWidth: true }); var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (params) { return React.createElement("div", { key: params.key, style: params.style }); }); var props = { cellRenderer: cellRenderer, columnCount: 2, deferredMeasurementCache: cache, rowCount: 2 }; var grid = (0, _TestUtils.render)(getMarkup(props)); expect(cellRenderer).toHaveBeenCalledTimes(4); var invalidateCellSizeAfterRender = false; cellRenderer.mockReset(); cellRenderer.mockImplementation(function (params) { // Don't get stuck in a loop if (invalidateCellSizeAfterRender) { invalidateCellSizeAfterRender = false; params.parent.invalidateCellSizeAfterRender({ columnIndex: 1, rowIndex: 0 }); } return React.createElement("div", { key: params.key, style: params.style }); }); invalidateCellSizeAfterRender = true; grid.recomputeGridSize(); // 4 times for initial render + 4 once cellCache was cleared expect(cellRenderer).toHaveBeenCalledTimes(8); }); it('should not cache cells until they have been measured by CellMeasurer', function () { var cache = new _CellMeasurer.CellMeasurerCache({ fixedWidth: true }); // Fake measure cell 0,0 but not cell 0,1 cache.set(0, 0, 100, 30); var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (params) { return React.createElement("div", { key: params.key, style: params.style }); }); var props = { cellRenderer: cellRenderer, columnCount: 2, deferredMeasurementCache: cache, rowCount: 1 }; // Trigger 2 renders // The second render should re-use the style for cell 0,0 // But should not re-use the style for cell 0,1 since it was not measured var grid = (0, _TestUtils.render)(getMarkup(props)); grid.forceUpdate(); // 0,0 - 0,1 - 0,0 - 0,1 expect(cellRenderer).toHaveBeenCalledTimes(4); var style00A = cellRenderer.mock.calls[0][0].style; var style01A = cellRenderer.mock.calls[1][0].style; var style00B = cellRenderer.mock.calls[2][0].style; var style01B = cellRenderer.mock.calls[3][0].style; expect(style00A).toBe(style00B); expect(style01A).not.toBe(style01B); }); }); describe('onScrollbarPresenceChange', function () { it('should not trigger on-mount if scrollbars are hidden', function () { var onScrollbarPresenceChange = jest.fn(); (0, _TestUtils.render)(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 1 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); }); it('should trigger on-mount if scrollbars are visible', function () { var onScrollbarPresenceChange = jest.fn(); (0, _TestUtils.render)(getMarkup({ columnCount: 100, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 100 })); expect(onScrollbarPresenceChange).toHaveBeenCalled(); var args = onScrollbarPresenceChange.mock.calls[0][0]; expect(args.horizontal).toBe(true); expect(args.size).toBe(getScrollbarSize20()); expect(args.vertical).toBe(true); }); it('should trigger on-update if scrollbar visibility has changed', function () { var onScrollbarPresenceChange = jest.fn(); (0, _TestUtils.render)(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 1 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); (0, _TestUtils.render)(getMarkup({ columnCount: 100, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 100 })); expect(onScrollbarPresenceChange).toHaveBeenCalled(); var args = onScrollbarPresenceChange.mock.calls[0][0]; expect(args.horizontal).toBe(true); expect(args.size).toBe(getScrollbarSize20()); expect(args.vertical).toBe(true); }); it('should not trigger on-update if scrollbar visibility does not change', function () { var onScrollbarPresenceChange = jest.fn(); (0, _TestUtils.render)(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 1 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); (0, _TestUtils.render)(getMarkup({ columnCount: 2, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 2 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); }); }); it('should not complain when using react-test-renderer', function () { var instance = _reactTestRenderer["default"].create(getMarkup()).getInstance(); expect(instance).toBeTruthy(); }); });dist/commonjs/Grid/accessibilityOverscanIndicesGetter.js000064400000003422151676725770017611 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = defaultOverscanIndicesGetter; exports.SCROLL_DIRECTION_VERTICAL = exports.SCROLL_DIRECTION_HORIZONTAL = exports.SCROLL_DIRECTION_FORWARD = exports.SCROLL_DIRECTION_BACKWARD = void 0; var _types = require("./types"); var SCROLL_DIRECTION_BACKWARD = -1; exports.SCROLL_DIRECTION_BACKWARD = SCROLL_DIRECTION_BACKWARD; var SCROLL_DIRECTION_FORWARD = 1; exports.SCROLL_DIRECTION_FORWARD = SCROLL_DIRECTION_FORWARD; var SCROLL_DIRECTION_HORIZONTAL = 'horizontal'; exports.SCROLL_DIRECTION_HORIZONTAL = SCROLL_DIRECTION_HORIZONTAL; var SCROLL_DIRECTION_VERTICAL = 'vertical'; /** * Calculates the number of cells to overscan before and after a specified range. * This function ensures that overscanning doesn't exceed the available cells. */ exports.SCROLL_DIRECTION_VERTICAL = SCROLL_DIRECTION_VERTICAL; function defaultOverscanIndicesGetter(_ref) { var cellCount = _ref.cellCount, overscanCellsCount = _ref.overscanCellsCount, scrollDirection = _ref.scrollDirection, startIndex = _ref.startIndex, stopIndex = _ref.stopIndex; // Make sure we render at least 1 cell extra before and after (except near boundaries) // This is necessary in order to support keyboard navigation (TAB/SHIFT+TAB) in some cases // For more info see issues #625 overscanCellsCount = Math.max(1, overscanCellsCount); if (scrollDirection === SCROLL_DIRECTION_FORWARD) { return { overscanStartIndex: Math.max(0, startIndex - 1), overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount) }; } else { return { overscanStartIndex: Math.max(0, startIndex - overscanCellsCount), overscanStopIndex: Math.min(cellCount - 1, stopIndex + 1) }; } }dist/commonjs/Grid/utils/maxElementSize.js000064400000001104151676725770014674 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getMaxElementSize = void 0; var DEFAULT_MAX_ELEMENT_SIZE = 1500000; var CHROME_MAX_ELEMENT_SIZE = 1.67771e7; var isBrowser = function isBrowser() { return typeof window !== 'undefined'; }; var isChrome = function isChrome() { return !!window.chrome; }; var getMaxElementSize = function getMaxElementSize() { if (isBrowser()) { if (isChrome()) { return CHROME_MAX_ELEMENT_SIZE; } } return DEFAULT_MAX_ELEMENT_SIZE; }; exports.getMaxElementSize = getMaxElementSize;dist/commonjs/Grid/utils/updateScrollIndexHelper.js000064400000004531151676725770016542 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = updateScrollIndexHelper; var _ScalingCellSizeAndPositionManager = _interopRequireDefault(require("./ScalingCellSizeAndPositionManager.js")); var _types = require("../types"); function updateScrollIndexHelper(_ref) { var cellSize = _ref.cellSize, cellSizeAndPositionManager = _ref.cellSizeAndPositionManager, previousCellsCount = _ref.previousCellsCount, previousCellSize = _ref.previousCellSize, previousScrollToAlignment = _ref.previousScrollToAlignment, previousScrollToIndex = _ref.previousScrollToIndex, previousSize = _ref.previousSize, scrollOffset = _ref.scrollOffset, scrollToAlignment = _ref.scrollToAlignment, scrollToIndex = _ref.scrollToIndex, size = _ref.size, sizeJustIncreasedFromZero = _ref.sizeJustIncreasedFromZero, updateScrollIndexCallback = _ref.updateScrollIndexCallback; var cellCount = cellSizeAndPositionManager.getCellCount(); var hasScrollToIndex = scrollToIndex >= 0 && scrollToIndex < cellCount; var sizeHasChanged = size !== previousSize || sizeJustIncreasedFromZero || !previousCellSize || typeof cellSize === 'number' && cellSize !== previousCellSize; // If we have a new scroll target OR if height/row-height has changed, // We should ensure that the scroll target is visible. if (hasScrollToIndex && (sizeHasChanged || scrollToAlignment !== previousScrollToAlignment || scrollToIndex !== previousScrollToIndex)) { updateScrollIndexCallback(scrollToIndex); // If we don't have a selected item but list size or number of children have decreased, // Make sure we aren't scrolled too far past the current content. } else if (!hasScrollToIndex && cellCount > 0 && (size < previousSize || cellCount < previousCellsCount)) { // We need to ensure that the current scroll offset is still within the collection's range. // To do this, we don't need to measure everything; CellMeasurer would perform poorly. // Just check to make sure we're still okay. // Only adjust the scroll position if we've scrolled below the last set of rows. if (scrollOffset > cellSizeAndPositionManager.getTotalSize() - size) { updateScrollIndexCallback(cellCount - 1); } } }dist/commonjs/Grid/utils/ScalingCellSizeAndPositionManager.jest.js000064400000014355151676725770021400 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _ScalingCellSizeAndPositionManager = _interopRequireDefault(require("./ScalingCellSizeAndPositionManager")); describe('ScalingCellSizeAndPositionManager', function () { function init() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$cellCount = _ref.cellCount, cellCount = _ref$cellCount === void 0 ? 10 : _ref$cellCount, _ref$cellSize = _ref.cellSize, cellSize = _ref$cellSize === void 0 ? 10 : _ref$cellSize, _ref$estimatedCellSiz = _ref.estimatedCellSize, estimatedCellSize = _ref$estimatedCellSiz === void 0 ? 10 : _ref$estimatedCellSiz, _ref$maxScrollSize = _ref.maxScrollSize, maxScrollSize = _ref$maxScrollSize === void 0 ? 50 : _ref$maxScrollSize; var cellSizeAndPositionManager = new _ScalingCellSizeAndPositionManager["default"]({ cellCount: cellCount, cellSizeGetter: function cellSizeGetter() { return cellSize; }, estimatedCellSize: estimatedCellSize, maxScrollSize: maxScrollSize }); return cellSizeAndPositionManager; } describe('_getOffsetPercentage', function () { it('should return the correct offset fraction', function () { var expectations = [{ offset: 0, expectedOffsetPercentage: 0 }, { offset: 35, expectedOffsetPercentage: 0.5 }, { offset: 70, expectedOffsetPercentage: 1 }]; var instance = init(); expectations.forEach(function (expectation) { expect(instance._getOffsetPercentage({ containerSize: 30, offset: expectation.offset, totalSize: 100 })).toBe(expectation.expectedOffsetPercentage); }); }); }); describe('getOffsetAdjustment', function () { it('should always return 0 as the adjustment for unscaled lists', function () { var maxScrollSizes = [100, 150]; maxScrollSizes.forEach(function (maxScrollSize) { var instance = init({ cellCount: 10, maxScrollSize: maxScrollSize }); var offsets = [0, 35, 70]; offsets.forEach(function (offset) { expect(instance.getOffsetAdjustment({ containerSize: 30, offset: offset })).toBe(0); }); }); }); it('should properly scale an offset at the beginning, middle, and end of the list', function () { var offsetsAndExpectedAdjustements = [{ offset: 0, expectedAdjustment: -0 }, { offset: 10, expectedAdjustment: -25 }, { offset: 20, expectedAdjustment: -50 }]; var instance = init(); offsetsAndExpectedAdjustements.forEach(function (offsetAndExpectedAdjustement) { expect(instance.getOffsetAdjustment({ containerSize: 30, offset: offsetAndExpectedAdjustement.offset })).toBe(offsetAndExpectedAdjustement.expectedAdjustment); }); }); }); describe('getTotalSize', function () { it('should return :totalSize if it is not greater than :maxScrollSize', function () { var maxScrollSizes = [500, 750]; maxScrollSizes.forEach(function (maxScrollSize) { var instance = init({ cellCount: 50, maxScrollSize: maxScrollSize }); expect(instance.getTotalSize()).toEqual(500); }); }); it('should return :maxScrollSize if :totalSize is greater', function () { var instance = init({ cellCount: 100, maxScrollSize: 100 }); expect(instance.getTotalSize()).toEqual(100); }); }); describe('getUpdatedOffsetForIndex', function () { it('should scroll to a cell before the current range', function () { var data = [{ targetIndex: 0, expectedOffset: 0 }, { targetIndex: 1, expectedOffset: 3 }, // (unsafe: 10) { targetIndex: 2, expectedOffset: 6 } // (unsafe: 20) ]; var instance = init(); data.forEach(function (datum) { expect(instance.getUpdatedOffsetForIndex({ containerSize: 30, currentOffset: 10, // (unsafe: 35) targetIndex: datum.targetIndex })).toBe(datum.expectedOffset); }); }); it('should scroll to a cell after the current range', function () { var data = [{ targetIndex: 7, expectedOffset: 14 }, // (unsafe: 50) { targetIndex: 9, expectedOffset: 20 } // (unsafe: 70) ]; var instance = init(); data.forEach(function (datum) { expect(instance.getUpdatedOffsetForIndex({ containerSize: 30, currentOffset: 0, targetIndex: datum.targetIndex })).toBe(datum.expectedOffset); }); }); it('should not scroll to a cell already visible within the current range', function () { var instance = init(); expect(instance.getUpdatedOffsetForIndex({ containerSize: 30, currentOffset: 10, // (unsafe: 35) targetIndex: 4 })).toBe(10); }); }); describe('getVisibleCellRange', function () { it('should correct identify the first set of cells', function () { var instance = init(); expect(instance.getVisibleCellRange({ containerSize: 30, offset: 0 })).toEqual({ start: 0, stop: 2 }); }); it('should correct identify cells in the middle', function () { var instance = init(); expect(instance.getVisibleCellRange({ containerSize: 30, offset: 2.85 // (unsafe: 10) })).toEqual({ start: 1, stop: 3 }); }); it('should correct identify partially visible cells', function () { var instance = init(); expect(instance.getVisibleCellRange({ containerSize: 30, offset: 10 // (unsafe: 35) })).toEqual({ start: 3, stop: 6 }); }); it('should correct identify the last set of cells', function () { var instance = init(); expect(instance.getVisibleCellRange({ containerSize: 30, offset: 20 })).toEqual({ start: 7, stop: 9 }); }); }); });dist/commonjs/Grid/utils/CellSizeAndPositionManager.js000064400000025204151676725770017126 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _types = require("../types"); /** * Just-in-time calculates and caches size and position information for a collection of cells. */ var CellSizeAndPositionManager = /*#__PURE__*/ function () { // Cache of size and position data for cells, mapped by cell index. // Note that invalid values may exist in this map so only rely on cells up to this._lastMeasuredIndex // Measurements for cells up to this index can be trusted; cells afterward should be estimated. // Used in deferred mode to track which cells have been queued for measurement. function CellSizeAndPositionManager(_ref) { var cellCount = _ref.cellCount, cellSizeGetter = _ref.cellSizeGetter, estimatedCellSize = _ref.estimatedCellSize; (0, _classCallCheck2["default"])(this, CellSizeAndPositionManager); (0, _defineProperty2["default"])(this, "_cellSizeAndPositionData", {}); (0, _defineProperty2["default"])(this, "_lastMeasuredIndex", -1); (0, _defineProperty2["default"])(this, "_lastBatchedIndex", -1); (0, _defineProperty2["default"])(this, "_cellCount", void 0); (0, _defineProperty2["default"])(this, "_cellSizeGetter", void 0); (0, _defineProperty2["default"])(this, "_estimatedCellSize", void 0); this._cellSizeGetter = cellSizeGetter; this._cellCount = cellCount; this._estimatedCellSize = estimatedCellSize; } (0, _createClass2["default"])(CellSizeAndPositionManager, [{ key: "areOffsetsAdjusted", value: function areOffsetsAdjusted() { return false; } }, { key: "configure", value: function configure(_ref2) { var cellCount = _ref2.cellCount, estimatedCellSize = _ref2.estimatedCellSize, cellSizeGetter = _ref2.cellSizeGetter; this._cellCount = cellCount; this._estimatedCellSize = estimatedCellSize; this._cellSizeGetter = cellSizeGetter; } }, { key: "getCellCount", value: function getCellCount() { return this._cellCount; } }, { key: "getEstimatedCellSize", value: function getEstimatedCellSize() { return this._estimatedCellSize; } }, { key: "getLastMeasuredIndex", value: function getLastMeasuredIndex() { return this._lastMeasuredIndex; } }, { key: "getOffsetAdjustment", value: function getOffsetAdjustment() { return 0; } /** * This method returns the size and position for the cell at the specified index. * It just-in-time calculates (or used cached values) for cells leading up to the index. */ }, { key: "getSizeAndPositionOfCell", value: function getSizeAndPositionOfCell(index) { if (index < 0 || index >= this._cellCount) { throw Error("Requested index ".concat(index, " is outside of range 0..").concat(this._cellCount)); } if (index > this._lastMeasuredIndex) { var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); var offset = lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size; for (var i = this._lastMeasuredIndex + 1; i <= index; i++) { var size = this._cellSizeGetter({ index: i }); // undefined or NaN probably means a logic error in the size getter. // null means we're using CellMeasurer and haven't yet measured a given index. if (size === undefined || isNaN(size)) { throw Error("Invalid size returned for cell ".concat(i, " of value ").concat(size)); } else if (size === null) { this._cellSizeAndPositionData[i] = { offset: offset, size: 0 }; this._lastBatchedIndex = index; } else { this._cellSizeAndPositionData[i] = { offset: offset, size: size }; offset += size; this._lastMeasuredIndex = index; } } } return this._cellSizeAndPositionData[index]; } }, { key: "getSizeAndPositionOfLastMeasuredCell", value: function getSizeAndPositionOfLastMeasuredCell() { return this._lastMeasuredIndex >= 0 ? this._cellSizeAndPositionData[this._lastMeasuredIndex] : { offset: 0, size: 0 }; } /** * Total size of all cells being measured. * This value will be completely estimated initially. * As cells are measured, the estimate will be updated. */ }, { key: "getTotalSize", value: function getTotalSize() { var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); var totalSizeOfMeasuredCells = lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size; var numUnmeasuredCells = this._cellCount - this._lastMeasuredIndex - 1; var totalSizeOfUnmeasuredCells = numUnmeasuredCells * this._estimatedCellSize; return totalSizeOfMeasuredCells + totalSizeOfUnmeasuredCells; } /** * Determines a new offset that ensures a certain cell is visible, given the current offset. * If the cell is already visible then the current offset will be returned. * If the current offset is too great or small, it will be adjusted just enough to ensure the specified index is visible. * * @param align Desired alignment within container; one of "auto" (default), "start", or "end" * @param containerSize Size (width or height) of the container viewport * @param currentOffset Container's current (x or y) offset * @param totalSize Total size (width or height) of all cells * @return Offset to use to ensure the specified cell is visible */ }, { key: "getUpdatedOffsetForIndex", value: function getUpdatedOffsetForIndex(_ref3) { var _ref3$align = _ref3.align, align = _ref3$align === void 0 ? 'auto' : _ref3$align, containerSize = _ref3.containerSize, currentOffset = _ref3.currentOffset, targetIndex = _ref3.targetIndex; if (containerSize <= 0) { return 0; } var datum = this.getSizeAndPositionOfCell(targetIndex); var maxOffset = datum.offset; var minOffset = maxOffset - containerSize + datum.size; var idealOffset; switch (align) { case 'start': idealOffset = maxOffset; break; case 'end': idealOffset = minOffset; break; case 'center': idealOffset = maxOffset - (containerSize - datum.size) / 2; break; default: idealOffset = Math.max(minOffset, Math.min(maxOffset, currentOffset)); break; } var totalSize = this.getTotalSize(); return Math.max(0, Math.min(totalSize - containerSize, idealOffset)); } }, { key: "getVisibleCellRange", value: function getVisibleCellRange(params) { var containerSize = params.containerSize, offset = params.offset; var totalSize = this.getTotalSize(); if (totalSize === 0) { return {}; } var maxOffset = offset + containerSize; var start = this._findNearestCell(offset); var datum = this.getSizeAndPositionOfCell(start); offset = datum.offset + datum.size; var stop = start; while (offset < maxOffset && stop < this._cellCount - 1) { stop++; offset += this.getSizeAndPositionOfCell(stop).size; } return { start: start, stop: stop }; } /** * Clear all cached values for cells after the specified index. * This method should be called for any cell that has changed its size. * It will not immediately perform any calculations; they'll be performed the next time getSizeAndPositionOfCell() is called. */ }, { key: "resetCell", value: function resetCell(index) { this._lastMeasuredIndex = Math.min(this._lastMeasuredIndex, index - 1); } }, { key: "_binarySearch", value: function _binarySearch(high, low, offset) { while (low <= high) { var middle = low + Math.floor((high - low) / 2); var currentOffset = this.getSizeAndPositionOfCell(middle).offset; if (currentOffset === offset) { return middle; } else if (currentOffset < offset) { low = middle + 1; } else if (currentOffset > offset) { high = middle - 1; } } if (low > 0) { return low - 1; } else { return 0; } } }, { key: "_exponentialSearch", value: function _exponentialSearch(index, offset) { var interval = 1; while (index < this._cellCount && this.getSizeAndPositionOfCell(index).offset < offset) { index += interval; interval *= 2; } return this._binarySearch(Math.min(index, this._cellCount - 1), Math.floor(index / 2), offset); } /** * Searches for the cell (index) nearest the specified offset. * * If no exact match is found the next lowest cell index will be returned. * This allows partially visible cells (with offsets just before/above the fold) to be visible. */ }, { key: "_findNearestCell", value: function _findNearestCell(offset) { if (isNaN(offset)) { throw Error("Invalid offset ".concat(offset, " specified")); } // Our search algorithms find the nearest match at or below the specified offset. // So make sure the offset is at least 0 or no match will be found. offset = Math.max(0, offset); var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); var lastMeasuredIndex = Math.max(0, this._lastMeasuredIndex); if (lastMeasuredCellSizeAndPosition.offset >= offset) { // If we've already measured cells within this range just use a binary search as it's faster. return this._binarySearch(lastMeasuredIndex, 0, offset); } else { // If we haven't yet measured this high, fallback to an exponential search with an inner binary search. // The exponential search avoids pre-computing sizes for the full set of cells as a binary search would. // The overall complexity for this approach is O(log n). return this._exponentialSearch(lastMeasuredIndex, offset); } } }]); return CellSizeAndPositionManager; }(); exports["default"] = CellSizeAndPositionManager;dist/commonjs/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset.jest.js000064400000007760151676725770024572 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _calculateSizeAndPositionDataAndUpdateScrollOffset = _interopRequireDefault(require("./calculateSizeAndPositionDataAndUpdateScrollOffset")); describe('calculateSizeAndPositionDataAndUpdateScrollOffset', function () { function helper() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$cellCount = _ref.cellCount, cellCount = _ref$cellCount === void 0 ? 100 : _ref$cellCount, _ref$cellSize = _ref.cellSize, cellSize = _ref$cellSize === void 0 ? 10 : _ref$cellSize, _ref$computeMetadataC = _ref.computeMetadataCallbackProps, computeMetadataCallbackProps = _ref$computeMetadataC === void 0 ? {} : _ref$computeMetadataC, _ref$nextCellsCount = _ref.nextCellsCount, nextCellsCount = _ref$nextCellsCount === void 0 ? 100 : _ref$nextCellsCount, _ref$nextCellSize = _ref.nextCellSize, nextCellSize = _ref$nextCellSize === void 0 ? 10 : _ref$nextCellSize, nextScrollToIndex = _ref.nextScrollToIndex, scrollToIndex = _ref.scrollToIndex; var computeMetadataCallbackCalls = []; var updateScrollOffsetForScrollToIndexCalls = []; (0, _calculateSizeAndPositionDataAndUpdateScrollOffset["default"])({ cellCount: cellCount, cellSize: cellSize, computeMetadataCallback: function computeMetadataCallback(params) { return computeMetadataCallbackCalls.push(params); }, computeMetadataCallbackProps: computeMetadataCallbackProps, nextCellsCount: nextCellsCount, nextCellSize: nextCellSize, nextScrollToIndex: nextScrollToIndex, scrollToIndex: scrollToIndex, updateScrollOffsetForScrollToIndex: function updateScrollOffsetForScrollToIndex(params) { return updateScrollOffsetForScrollToIndexCalls.push(params); } }); return { computeMetadataCallbackCalls: computeMetadataCallbackCalls, updateScrollOffsetForScrollToIndexCalls: updateScrollOffsetForScrollToIndexCalls }; } it('should call :computeMetadataCallback if :cellCount has changed', function () { var _helper = helper({ cellCount: 100, nextCellsCount: 200 }), computeMetadataCallbackCalls = _helper.computeMetadataCallbackCalls; expect(computeMetadataCallbackCalls.length).toEqual(1); }); it('should call :computeMetadataCallback if numeric :cellSize has changed', function () { var _helper2 = helper({ cellSize: 10, nextCellSize: 20 }), computeMetadataCallbackCalls = _helper2.computeMetadataCallbackCalls; expect(computeMetadataCallbackCalls.length).toEqual(1); }); it('should not call :computeMetadataCallback if :cellSize callback has changed', function () { var _helper3 = helper({ cellSize: function cellSize() {}, nextCellSize: function nextCellSize() {} }), computeMetadataCallbackCalls = _helper3.computeMetadataCallbackCalls; expect(computeMetadataCallbackCalls.length).toEqual(0); }); it('should not call :updateScrollOffsetForScrollToIndex if :scrollToIndex is not specified', function () { var _helper4 = helper(), updateScrollOffsetForScrollToIndexCalls = _helper4.updateScrollOffsetForScrollToIndexCalls; expect(updateScrollOffsetForScrollToIndexCalls.length).toEqual(0); }); it('should not call :updateScrollOffsetForScrollToIndex if :scrollToIndex has also changed', function () { var _helper5 = helper({ scrollToIndex: 10, nextScrollToIndex: 20 }), updateScrollOffsetForScrollToIndexCalls = _helper5.updateScrollOffsetForScrollToIndexCalls; expect(updateScrollOffsetForScrollToIndexCalls.length).toEqual(0); }); it('should not call :computeMetadataCallback if the above conditions are not true', function () { var _helper6 = helper(), computeMetadataCallbackCalls = _helper6.computeMetadataCallbackCalls; expect(computeMetadataCallbackCalls.length).toEqual(0); }); });dist/commonjs/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset.js000064400000002633151676725770023620 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = calculateSizeAndPositionDataAndUpdateScrollOffset; /** * Helper method that determines when to recalculate row or column metadata. */ function calculateSizeAndPositionDataAndUpdateScrollOffset(_ref) { var cellCount = _ref.cellCount, cellSize = _ref.cellSize, computeMetadataCallback = _ref.computeMetadataCallback, computeMetadataCallbackProps = _ref.computeMetadataCallbackProps, nextCellsCount = _ref.nextCellsCount, nextCellSize = _ref.nextCellSize, nextScrollToIndex = _ref.nextScrollToIndex, scrollToIndex = _ref.scrollToIndex, updateScrollOffsetForScrollToIndex = _ref.updateScrollOffsetForScrollToIndex; // Don't compare cell sizes if they are functions because inline functions would cause infinite loops. // In that event users should use the manual recompute methods to inform of changes. if (cellCount !== nextCellsCount || (typeof cellSize === 'number' || typeof nextCellSize === 'number') && cellSize !== nextCellSize) { computeMetadataCallback(computeMetadataCallbackProps); // Updated cell metadata may have hidden the previous scrolled-to item. // In this case we should also update the scrollTop to ensure it stays visible. if (scrollToIndex >= 0 && scrollToIndex === nextScrollToIndex) { updateScrollOffsetForScrollToIndex(); } } }dist/commonjs/Grid/utils/ScalingCellSizeAndPositionManager.js000064400000015660151676725770020434 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _CellSizeAndPositionManager = _interopRequireDefault(require("./CellSizeAndPositionManager")); var _maxElementSize = require("./maxElementSize.js"); var _types = require("../types"); /** * Extends CellSizeAndPositionManager and adds scaling behavior for lists that are too large to fit within a browser's native limits. */ var ScalingCellSizeAndPositionManager = /*#__PURE__*/ function () { function ScalingCellSizeAndPositionManager(_ref) { var _ref$maxScrollSize = _ref.maxScrollSize, maxScrollSize = _ref$maxScrollSize === void 0 ? (0, _maxElementSize.getMaxElementSize)() : _ref$maxScrollSize, params = (0, _objectWithoutProperties2["default"])(_ref, ["maxScrollSize"]); (0, _classCallCheck2["default"])(this, ScalingCellSizeAndPositionManager); (0, _defineProperty2["default"])(this, "_cellSizeAndPositionManager", void 0); (0, _defineProperty2["default"])(this, "_maxScrollSize", void 0); // Favor composition over inheritance to simplify IE10 support this._cellSizeAndPositionManager = new _CellSizeAndPositionManager["default"](params); this._maxScrollSize = maxScrollSize; } (0, _createClass2["default"])(ScalingCellSizeAndPositionManager, [{ key: "areOffsetsAdjusted", value: function areOffsetsAdjusted() { return this._cellSizeAndPositionManager.getTotalSize() > this._maxScrollSize; } }, { key: "configure", value: function configure(params) { this._cellSizeAndPositionManager.configure(params); } }, { key: "getCellCount", value: function getCellCount() { return this._cellSizeAndPositionManager.getCellCount(); } }, { key: "getEstimatedCellSize", value: function getEstimatedCellSize() { return this._cellSizeAndPositionManager.getEstimatedCellSize(); } }, { key: "getLastMeasuredIndex", value: function getLastMeasuredIndex() { return this._cellSizeAndPositionManager.getLastMeasuredIndex(); } /** * Number of pixels a cell at the given position (offset) should be shifted in order to fit within the scaled container. * The offset passed to this function is scaled (safe) as well. */ }, { key: "getOffsetAdjustment", value: function getOffsetAdjustment(_ref2) { var containerSize = _ref2.containerSize, offset = _ref2.offset; var totalSize = this._cellSizeAndPositionManager.getTotalSize(); var safeTotalSize = this.getTotalSize(); var offsetPercentage = this._getOffsetPercentage({ containerSize: containerSize, offset: offset, totalSize: safeTotalSize }); return Math.round(offsetPercentage * (safeTotalSize - totalSize)); } }, { key: "getSizeAndPositionOfCell", value: function getSizeAndPositionOfCell(index) { return this._cellSizeAndPositionManager.getSizeAndPositionOfCell(index); } }, { key: "getSizeAndPositionOfLastMeasuredCell", value: function getSizeAndPositionOfLastMeasuredCell() { return this._cellSizeAndPositionManager.getSizeAndPositionOfLastMeasuredCell(); } /** See CellSizeAndPositionManager#getTotalSize */ }, { key: "getTotalSize", value: function getTotalSize() { return Math.min(this._maxScrollSize, this._cellSizeAndPositionManager.getTotalSize()); } /** See CellSizeAndPositionManager#getUpdatedOffsetForIndex */ }, { key: "getUpdatedOffsetForIndex", value: function getUpdatedOffsetForIndex(_ref3) { var _ref3$align = _ref3.align, align = _ref3$align === void 0 ? 'auto' : _ref3$align, containerSize = _ref3.containerSize, currentOffset = _ref3.currentOffset, targetIndex = _ref3.targetIndex; currentOffset = this._safeOffsetToOffset({ containerSize: containerSize, offset: currentOffset }); var offset = this._cellSizeAndPositionManager.getUpdatedOffsetForIndex({ align: align, containerSize: containerSize, currentOffset: currentOffset, targetIndex: targetIndex }); return this._offsetToSafeOffset({ containerSize: containerSize, offset: offset }); } /** See CellSizeAndPositionManager#getVisibleCellRange */ }, { key: "getVisibleCellRange", value: function getVisibleCellRange(_ref4) { var containerSize = _ref4.containerSize, offset = _ref4.offset; offset = this._safeOffsetToOffset({ containerSize: containerSize, offset: offset }); return this._cellSizeAndPositionManager.getVisibleCellRange({ containerSize: containerSize, offset: offset }); } }, { key: "resetCell", value: function resetCell(index) { this._cellSizeAndPositionManager.resetCell(index); } }, { key: "_getOffsetPercentage", value: function _getOffsetPercentage(_ref5) { var containerSize = _ref5.containerSize, offset = _ref5.offset, totalSize = _ref5.totalSize; return totalSize <= containerSize ? 0 : offset / (totalSize - containerSize); } }, { key: "_offsetToSafeOffset", value: function _offsetToSafeOffset(_ref6) { var containerSize = _ref6.containerSize, offset = _ref6.offset; var totalSize = this._cellSizeAndPositionManager.getTotalSize(); var safeTotalSize = this.getTotalSize(); if (totalSize === safeTotalSize) { return offset; } else { var offsetPercentage = this._getOffsetPercentage({ containerSize: containerSize, offset: offset, totalSize: totalSize }); return Math.round(offsetPercentage * (safeTotalSize - containerSize)); } } }, { key: "_safeOffsetToOffset", value: function _safeOffsetToOffset(_ref7) { var containerSize = _ref7.containerSize, offset = _ref7.offset; var totalSize = this._cellSizeAndPositionManager.getTotalSize(); var safeTotalSize = this.getTotalSize(); if (totalSize === safeTotalSize) { return offset; } else { var offsetPercentage = this._getOffsetPercentage({ containerSize: containerSize, offset: offset, totalSize: safeTotalSize }); return Math.round(offsetPercentage * (totalSize - containerSize)); } } }]); return ScalingCellSizeAndPositionManager; }(); exports["default"] = ScalingCellSizeAndPositionManager;dist/commonjs/Grid/utils/updateScrollIndexHelper.jest.js000064400000015461151676725770017512 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.getCellSizeAndPositionManager = getCellSizeAndPositionManager; var _updateScrollIndexHelper = _interopRequireDefault(require("./updateScrollIndexHelper")); var _CellSizeAndPositionManager = _interopRequireDefault(require("./CellSizeAndPositionManager")); // Default cell sizes and offsets for use in shared tests function getCellSizeAndPositionManager(_ref) { var _ref$cellCount = _ref.cellCount, cellCount = _ref$cellCount === void 0 ? CELL_SIZES.length : _ref$cellCount, _ref$estimatedCellSiz = _ref.estimatedCellSize, estimatedCellSize = _ref$estimatedCellSiz === void 0 ? 10 : _ref$estimatedCellSiz; return new _CellSizeAndPositionManager["default"]({ cellCount: cellCount, cellSizeGetter: function cellSizeGetter(_ref2) { var index = _ref2.index; return CELL_SIZES[index % CELL_SIZES.length]; }, estimatedCellSize: estimatedCellSize }); } var CELL_SIZES = [10, // 0: 0..0 (min) 20, // 1: 0..10 15, // 2: 0..30 10, // 3: 5..45 15, // 4: 20..55 30, // 5: 50..70 20, // 6: 70..100 10, // 7: 80..110 30 // 8: 110..110 (max) ]; describe('updateScrollIndexHelper', function () { function helper() { var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref3$cellCount = _ref3.cellCount, cellCount = _ref3$cellCount === void 0 ? undefined : _ref3$cellCount, cellSizeAndPositionManager = _ref3.cellSizeAndPositionManager, _ref3$cellSize = _ref3.cellSize, cellSize = _ref3$cellSize === void 0 ? 10 : _ref3$cellSize, _ref3$previousCellsCo = _ref3.previousCellsCount, previousCellsCount = _ref3$previousCellsCo === void 0 ? undefined : _ref3$previousCellsCo, _ref3$previousCellSiz = _ref3.previousCellSize, previousCellSize = _ref3$previousCellSiz === void 0 ? 10 : _ref3$previousCellSiz, _ref3$previousScrollT = _ref3.previousScrollToAlignment, previousScrollToAlignment = _ref3$previousScrollT === void 0 ? 'auto' : _ref3$previousScrollT, previousScrollToIndex = _ref3.previousScrollToIndex, _ref3$previousSize = _ref3.previousSize, previousSize = _ref3$previousSize === void 0 ? 50 : _ref3$previousSize, _ref3$scrollOffset = _ref3.scrollOffset, scrollOffset = _ref3$scrollOffset === void 0 ? 0 : _ref3$scrollOffset, _ref3$scrollToAlignme = _ref3.scrollToAlignment, scrollToAlignment = _ref3$scrollToAlignme === void 0 ? 'auto' : _ref3$scrollToAlignme, scrollToIndex = _ref3.scrollToIndex, _ref3$size = _ref3.size, size = _ref3$size === void 0 ? 50 : _ref3$size; cellSizeAndPositionManager = cellSizeAndPositionManager || getCellSizeAndPositionManager({ cellCount: cellCount }); cellCount = cellCount === undefined ? cellSizeAndPositionManager.getCellCount() : cellCount; previousCellsCount = previousCellsCount === undefined ? cellCount : previousCellsCount; var updateScrollIndexCallbackCalled = false; function updateScrollIndexCallback() { updateScrollIndexCallbackCalled = true; } (0, _updateScrollIndexHelper["default"])({ cellCount: cellCount, cellSizeAndPositionManager: cellSizeAndPositionManager, cellSize: cellSize, previousCellsCount: previousCellsCount, previousCellSize: previousCellSize, previousScrollToAlignment: previousScrollToAlignment, previousScrollToIndex: previousScrollToIndex, previousSize: previousSize, scrollOffset: scrollOffset, scrollToAlignment: scrollToAlignment, scrollToIndex: scrollToIndex, size: size, updateScrollIndexCallback: updateScrollIndexCallback }); return updateScrollIndexCallbackCalled; } it('should not call :updateScrollIndexCallback if there is no :scrollToIndex and size has not changed', function () { expect(helper()).toEqual(false); }); it('should not call :updateScrollIndexCallback if an invalid :scrollToIndex has been specified', function () { expect(helper({ size: 100, previousSize: 50, scrollToIndex: -1 })).toEqual(false); }); it('should call :updateScrollIndexCallback if there is a :scrollToIndex and :size has changed', function () { expect(helper({ cellCount: 100, size: 100, previousSize: 50, scrollToIndex: 10 })).toEqual(true); }); it('should call :updateScrollIndexCallback if there is a :scrollToIndex and :cellSize has changed', function () { expect(helper({ cellCount: 100, cellSize: 15, previousCellSize: 20, scrollToIndex: 10 })).toEqual(true); }); it('should call :updateScrollIndexCallback if previous :scrollToIndex has changed', function () { expect(helper({ cellCount: 15, previousScrollToIndex: 20, scrollToIndex: 10 })).toEqual(true); }); it('should call :updateScrollIndexCallback if :cellCount has been reduced past the current scroll offset', function () { expect(helper({ previousCellsCount: 100, scrollOffset: 510 })).toEqual(true); }); it('should call :updateScrollIndexCallback if there is no :scrollToIndex but :size has been reduced', function () { expect(helper({ previousSize: 100, scrollOffset: 510, size: 50 })).toEqual(true); }); it('should not measure rows if :size or :cellCount have been reduced but only use already measured (or estimated) total size', function () { var cellSizeAndPositionManager = { getCellCount: function getCellCount() { return CELL_SIZES.length; }, getTotalSize: function getTotalSize() { return 560; } }; expect(helper({ cellSizeAndPositionManager: cellSizeAndPositionManager, previousSize: 100, scrollOffset: 510, size: 50 })).toEqual(false); }); it('should not call :updateScrollIndexCallback if there is no :scrollToIndex but :cellCount has been increased', function () { expect(helper({ cellCount: 100, previousCellsCount: 50 })).toEqual(false); }); it('should not call :updateScrollIndexCallback if there is no :scrollToIndex but :size has been increased', function () { expect(helper({ previousSize: 50, size: 100 })).toEqual(false); }); it('should call :updateScrollIndexCallback if :scrollToAlignment has changed', function () { expect(helper({ previousScrollToAlignment: 'start', scrollToAlignment: 'end', scrollToIndex: 5 })).toEqual(true); }); it('should not call :updateScrollIndexCallback if :scrollToAlignment has changed but there is no :scrollToIndex', function () { expect(helper({ previousScrollToAlignment: 'start', scrollToAlignment: 'end' })).toEqual(false); }); });dist/commonjs/Grid/utils/CellSizeAndPositionManager.jest.js000064400000043472151676725770020101 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _CellSizeAndPositionManager = _interopRequireDefault(require("./CellSizeAndPositionManager")); describe('CellSizeAndPositionManager', function () { function getCellSizeAndPositionManager() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$cellCount = _ref.cellCount, cellCount = _ref$cellCount === void 0 ? 100 : _ref$cellCount, _ref$estimatedCellSiz = _ref.estimatedCellSize, estimatedCellSize = _ref$estimatedCellSiz === void 0 ? 15 : _ref$estimatedCellSiz; var cellSizeGetterCalls = []; var cellSizeAndPositionManager = new _CellSizeAndPositionManager["default"]({ cellCount: cellCount, cellSizeGetter: function cellSizeGetter(_ref2) { var index = _ref2.index; cellSizeGetterCalls.push(index); return 10; }, estimatedCellSize: estimatedCellSize }); return { cellSizeAndPositionManager: cellSizeAndPositionManager, cellSizeGetterCalls: cellSizeGetterCalls }; } describe('configure', function () { it('should update inner :cellCount and :estimatedCellSize', function () { var _getCellSizeAndPositi = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi.cellSizeAndPositionManager; expect(cellSizeAndPositionManager.getCellCount()).toEqual(100); expect(cellSizeAndPositionManager.getEstimatedCellSize()).toEqual(15); cellSizeAndPositionManager.configure({ cellCount: 20, estimatedCellSize: 30 }); expect(cellSizeAndPositionManager.getCellCount()).toEqual(20); expect(cellSizeAndPositionManager.getEstimatedCellSize()).toEqual(30); }); }); describe('findNearestCell', function () { it('should error if given NaN', function () { var _getCellSizeAndPositi2 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi2.cellSizeAndPositionManager; expect(function () { return cellSizeAndPositionManager._findNearestCell(NaN); }).toThrow(); }); it('should gracefully handle offets outisde of bounds (to account for elastic scrolling)', function () { var _getCellSizeAndPositi3 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi3.cellSizeAndPositionManager; expect(cellSizeAndPositionManager._findNearestCell(-100)).toEqual(0); expect(cellSizeAndPositionManager._findNearestCell(1234567890)).toEqual(99); }); it('should find the first cell', function () { var _getCellSizeAndPositi4 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi4.cellSizeAndPositionManager; expect(cellSizeAndPositionManager._findNearestCell(0)).toEqual(0); expect(cellSizeAndPositionManager._findNearestCell(9)).toEqual(0); }); it('should find the last cell', function () { var _getCellSizeAndPositi5 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi5.cellSizeAndPositionManager; expect(cellSizeAndPositionManager._findNearestCell(990)).toEqual(99); expect(cellSizeAndPositionManager._findNearestCell(991)).toEqual(99); }); it('should find the a cell that exactly matches a specified offset in the middle', function () { var _getCellSizeAndPositi6 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi6.cellSizeAndPositionManager; expect(cellSizeAndPositionManager._findNearestCell(100)).toEqual(10); }); it('should find the cell closest to (but before) the specified offset in the middle', function () { var _getCellSizeAndPositi7 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi7.cellSizeAndPositionManager; expect(cellSizeAndPositionManager._findNearestCell(101)).toEqual(10); }); }); describe('getSizeAndPositionOfCell', function () { it('should error if an invalid index is specified', function () { var _getCellSizeAndPositi8 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi8.cellSizeAndPositionManager; expect(function () { return cellSizeAndPositionManager.getSizeAndPositionOfCell(-1); }).toThrow(); expect(function () { return cellSizeAndPositionManager.getSizeAndPositionOfCell(100); }).toThrow(); }); it('should return the correct size and position information for the requested cell', function () { var _getCellSizeAndPositi9 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi9.cellSizeAndPositionManager; expect(cellSizeAndPositionManager.getSizeAndPositionOfCell(0).offset).toEqual(0); expect(cellSizeAndPositionManager.getSizeAndPositionOfCell(0).size).toEqual(10); expect(cellSizeAndPositionManager.getSizeAndPositionOfCell(1).offset).toEqual(10); expect(cellSizeAndPositionManager.getSizeAndPositionOfCell(2).offset).toEqual(20); }); it('should only measure the necessary cells to return the information requested', function () { var _getCellSizeAndPositi10 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi10.cellSizeAndPositionManager, cellSizeGetterCalls = _getCellSizeAndPositi10.cellSizeGetterCalls; cellSizeAndPositionManager.getSizeAndPositionOfCell(0); expect(cellSizeGetterCalls).toEqual([0]); }); it('should just-in-time measure all cells up to the requested cell if no cells have yet been measured', function () { var _getCellSizeAndPositi11 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi11.cellSizeAndPositionManager, cellSizeGetterCalls = _getCellSizeAndPositi11.cellSizeGetterCalls; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); expect(cellSizeGetterCalls).toEqual([0, 1, 2, 3, 4, 5]); }); it('should just-in-time measure cells up to the requested cell if some but not all cells have been measured', function () { var _getCellSizeAndPositi12 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi12.cellSizeAndPositionManager, cellSizeGetterCalls = _getCellSizeAndPositi12.cellSizeGetterCalls; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); cellSizeGetterCalls.splice(0); cellSizeAndPositionManager.getSizeAndPositionOfCell(10); expect(cellSizeGetterCalls).toEqual([6, 7, 8, 9, 10]); }); it('should return cached size and position data if cell has already been measured', function () { var _getCellSizeAndPositi13 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi13.cellSizeAndPositionManager, cellSizeGetterCalls = _getCellSizeAndPositi13.cellSizeGetterCalls; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); cellSizeGetterCalls.splice(0); cellSizeAndPositionManager.getSizeAndPositionOfCell(5); expect(cellSizeGetterCalls).toEqual([]); }); }); describe('getSizeAndPositionOfLastMeasuredCell', function () { it('should return an empty object if no cached cells are present', function () { var _getCellSizeAndPositi14 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi14.cellSizeAndPositionManager; expect(cellSizeAndPositionManager.getSizeAndPositionOfLastMeasuredCell()).toEqual({ offset: 0, size: 0 }); }); it('should return size and position data for the highest/last measured cell', function () { var _getCellSizeAndPositi15 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi15.cellSizeAndPositionManager; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); expect(cellSizeAndPositionManager.getSizeAndPositionOfLastMeasuredCell()).toEqual({ offset: 50, size: 10 }); }); }); describe('getTotalSize', function () { it('should calculate total size based purely on :estimatedCellSize if no measurements have been done', function () { var _getCellSizeAndPositi16 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi16.cellSizeAndPositionManager; expect(cellSizeAndPositionManager.getTotalSize()).toEqual(1500); }); it('should calculate total size based on a mixture of actual cell sizes and :estimatedCellSize if some cells have been measured', function () { var _getCellSizeAndPositi17 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi17.cellSizeAndPositionManager; cellSizeAndPositionManager.getSizeAndPositionOfCell(49); expect(cellSizeAndPositionManager.getTotalSize()).toEqual(1250); }); it('should calculate total size based on the actual measured sizes if all cells have been measured', function () { var _getCellSizeAndPositi18 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi18.cellSizeAndPositionManager; cellSizeAndPositionManager.getSizeAndPositionOfCell(99); expect(cellSizeAndPositionManager.getTotalSize()).toEqual(1000); }); }); describe('getUpdatedOffsetForIndex', function () { function getUpdatedOffsetForIndexHelper(_ref3) { var _ref3$align = _ref3.align, align = _ref3$align === void 0 ? 'auto' : _ref3$align, _ref3$cellCount = _ref3.cellCount, cellCount = _ref3$cellCount === void 0 ? 10 : _ref3$cellCount, _ref3$cellSize = _ref3.cellSize, cellSize = _ref3$cellSize === void 0 ? 10 : _ref3$cellSize, _ref3$containerSize = _ref3.containerSize, containerSize = _ref3$containerSize === void 0 ? 50 : _ref3$containerSize, _ref3$currentOffset = _ref3.currentOffset, currentOffset = _ref3$currentOffset === void 0 ? 0 : _ref3$currentOffset, _ref3$estimatedCellSi = _ref3.estimatedCellSize, estimatedCellSize = _ref3$estimatedCellSi === void 0 ? 15 : _ref3$estimatedCellSi, _ref3$targetIndex = _ref3.targetIndex, targetIndex = _ref3$targetIndex === void 0 ? 0 : _ref3$targetIndex; var cellSizeAndPositionManager = new _CellSizeAndPositionManager["default"]({ cellCount: cellCount, cellSizeGetter: function cellSizeGetter() { return cellSize; }, estimatedCellSize: estimatedCellSize }); return cellSizeAndPositionManager.getUpdatedOffsetForIndex({ align: align, containerSize: containerSize, currentOffset: currentOffset, targetIndex: targetIndex }); } it('should scroll to the beginning', function () { expect(getUpdatedOffsetForIndexHelper({ currentOffset: 100, targetIndex: 0 })).toEqual(0); }); it('should scroll to the end', function () { expect(getUpdatedOffsetForIndexHelper({ currentOffset: 0, targetIndex: 9 })).toEqual(50); }); it('should scroll forward to the middle', function () { expect(getUpdatedOffsetForIndexHelper({ currentOffset: 0, targetIndex: 6 })).toEqual(20); }); it('should scroll backward to the middle', function () { expect(getUpdatedOffsetForIndexHelper({ currentOffset: 50, targetIndex: 2 })).toEqual(20); }); it('should not scroll if an item is already visible', function () { expect(getUpdatedOffsetForIndexHelper({ currentOffset: 20, targetIndex: 3 })).toEqual(20); }); it('should honor specified :align values', function () { expect(getUpdatedOffsetForIndexHelper({ align: 'auto', currentOffset: 0, targetIndex: 5 })).toEqual(10); expect(getUpdatedOffsetForIndexHelper({ align: 'start', currentOffset: 0, targetIndex: 5 })).toEqual(50); expect(getUpdatedOffsetForIndexHelper({ align: 'auto', currentOffset: 50, targetIndex: 4 })).toEqual(40); expect(getUpdatedOffsetForIndexHelper({ align: 'end', currentOffset: 50, targetIndex: 5 })).toEqual(10); expect(getUpdatedOffsetForIndexHelper({ align: 'center', currentOffset: 50, targetIndex: 5 })).toEqual(30); }); it('should not scroll past the safe bounds even if the specified :align requests it', function () { expect(getUpdatedOffsetForIndexHelper({ align: 'end', currentOffset: 50, targetIndex: 0 })).toEqual(0); expect(getUpdatedOffsetForIndexHelper({ align: 'center', currentOffset: 50, targetIndex: 1 })).toEqual(0); expect(getUpdatedOffsetForIndexHelper({ align: 'start', currentOffset: 0, targetIndex: 9 })).toEqual(50); // TRICKY: We would expect this to be positioned at 50. // But since the :estimatedCellSize is 15 and we only measure up to the 8th item, // The helper assumes it can scroll farther than it actually can. // Not sure if this edge case is worth "fixing" or just acknowledging... expect(getUpdatedOffsetForIndexHelper({ align: 'center', currentOffset: 0, targetIndex: 8 })).toEqual(55); }); it('should always return an offset of 0 when :containerSize is 0', function () { expect(getUpdatedOffsetForIndexHelper({ containerSize: 0, currentOffset: 50, targetIndex: 2 })).toEqual(0); }); }); describe('getVisibleCellRange', function () { it('should not return any indices if :cellCount is 0', function () { var _getCellSizeAndPositi19 = getCellSizeAndPositionManager({ cellCount: 0 }), cellSizeAndPositionManager = _getCellSizeAndPositi19.cellSizeAndPositionManager; var _cellSizeAndPositionM = cellSizeAndPositionManager.getVisibleCellRange({ containerSize: 50, offset: 0 }), start = _cellSizeAndPositionM.start, stop = _cellSizeAndPositionM.stop; expect(start).toEqual(undefined); expect(stop).toEqual(undefined); }); it('should return a visible range of cells for the beginning of the list', function () { var _getCellSizeAndPositi20 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi20.cellSizeAndPositionManager; var _cellSizeAndPositionM2 = cellSizeAndPositionManager.getVisibleCellRange({ containerSize: 50, offset: 0 }), start = _cellSizeAndPositionM2.start, stop = _cellSizeAndPositionM2.stop; expect(start).toEqual(0); expect(stop).toEqual(4); }); it('should return a visible range of cells for the middle of the list where some are partially visible', function () { var _getCellSizeAndPositi21 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi21.cellSizeAndPositionManager; var _cellSizeAndPositionM3 = cellSizeAndPositionManager.getVisibleCellRange({ containerSize: 50, offset: 425 }), start = _cellSizeAndPositionM3.start, stop = _cellSizeAndPositionM3.stop; // 42 and 47 are partially visible expect(start).toEqual(42); expect(stop).toEqual(47); }); it('should return a visible range of cells for the end of the list', function () { var _getCellSizeAndPositi22 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi22.cellSizeAndPositionManager; var _cellSizeAndPositionM4 = cellSizeAndPositionManager.getVisibleCellRange({ containerSize: 50, offset: 950 }), start = _cellSizeAndPositionM4.start, stop = _cellSizeAndPositionM4.stop; expect(start).toEqual(95); expect(stop).toEqual(99); }); }); describe('resetCell', function () { it('should clear size and position metadata for the specified index and all cells after it', function () { var _getCellSizeAndPositi23 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi23.cellSizeAndPositionManager; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); cellSizeAndPositionManager.resetCell(3); expect(cellSizeAndPositionManager.getLastMeasuredIndex()).toEqual(2); cellSizeAndPositionManager.resetCell(0); expect(cellSizeAndPositionManager.getLastMeasuredIndex()).toEqual(-1); }); it('should not clear size and position metadata for cells before the specified index', function () { var _getCellSizeAndPositi24 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi24.cellSizeAndPositionManager, cellSizeGetterCalls = _getCellSizeAndPositi24.cellSizeGetterCalls; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); cellSizeGetterCalls.splice(0); cellSizeAndPositionManager.resetCell(3); cellSizeAndPositionManager.getSizeAndPositionOfCell(4); expect(cellSizeGetterCalls).toEqual([3, 4]); }); it('should not skip over any unmeasured or previously-cleared cells', function () { var _getCellSizeAndPositi25 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi25.cellSizeAndPositionManager; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); cellSizeAndPositionManager.resetCell(2); expect(cellSizeAndPositionManager.getLastMeasuredIndex()).toEqual(1); cellSizeAndPositionManager.resetCell(4); expect(cellSizeAndPositionManager.getLastMeasuredIndex()).toEqual(1); cellSizeAndPositionManager.resetCell(0); expect(cellSizeAndPositionManager.getLastMeasuredIndex()).toEqual(-1); }); }); });dist/commonjs/Grid/index.js000064400000005161151676725770011720 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function get() { return _Grid["default"]; } }); Object.defineProperty(exports, "Grid", { enumerable: true, get: function get() { return _Grid["default"]; } }); Object.defineProperty(exports, "accessibilityOverscanIndicesGetter", { enumerable: true, get: function get() { return _accessibilityOverscanIndicesGetter["default"]; } }); Object.defineProperty(exports, "defaultCellRangeRenderer", { enumerable: true, get: function get() { return _defaultCellRangeRenderer["default"]; } }); Object.defineProperty(exports, "defaultOverscanIndicesGetter", { enumerable: true, get: function get() { return _defaultOverscanIndicesGetter["default"]; } }); Object.defineProperty(exports, "bpfrpt_proptype_NoContentRenderer", { enumerable: true, get: function get() { return _types.bpfrpt_proptype_NoContentRenderer; } }); Object.defineProperty(exports, "bpfrpt_proptype_Alignment", { enumerable: true, get: function get() { return _types.bpfrpt_proptype_Alignment; } }); Object.defineProperty(exports, "bpfrpt_proptype_CellPosition", { enumerable: true, get: function get() { return _types.bpfrpt_proptype_CellPosition; } }); Object.defineProperty(exports, "bpfrpt_proptype_CellSize", { enumerable: true, get: function get() { return _types.bpfrpt_proptype_CellSize; } }); Object.defineProperty(exports, "bpfrpt_proptype_OverscanIndicesGetter", { enumerable: true, get: function get() { return _types.bpfrpt_proptype_OverscanIndicesGetter; } }); Object.defineProperty(exports, "bpfrpt_proptype_RenderedSection", { enumerable: true, get: function get() { return _types.bpfrpt_proptype_RenderedSection; } }); Object.defineProperty(exports, "bpfrpt_proptype_CellRendererParams", { enumerable: true, get: function get() { return _types.bpfrpt_proptype_CellRendererParams; } }); Object.defineProperty(exports, "bpfrpt_proptype_Scroll", { enumerable: true, get: function get() { return _types.bpfrpt_proptype_Scroll; } }); var _Grid = _interopRequireDefault(require("./Grid")); var _accessibilityOverscanIndicesGetter = _interopRequireDefault(require("./accessibilityOverscanIndicesGetter")); var _defaultCellRangeRenderer = _interopRequireDefault(require("./defaultCellRangeRenderer")); var _defaultOverscanIndicesGetter = _interopRequireDefault(require("./defaultOverscanIndicesGetter")); var _types = require("./types");dist/commonjs/Grid/Grid.ssr.js000064400000003503151676725770012302 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var React = _interopRequireWildcard(require("react")); var ReactDOMServer = _interopRequireWildcard(require("react-dom/server")); var _Grid = _interopRequireDefault(require("./Grid")); /** * * @jest-environment node */ test('should render Grid with dom server', function () { var rendered = ReactDOMServer.renderToString(React.createElement(_Grid["default"], { cellRenderer: function cellRenderer(_ref) { var style = _ref.style, key = _ref.key, rowIndex = _ref.rowIndex, columnIndex = _ref.columnIndex; return React.createElement("div", { style: style, key: key }, rowIndex + ':' + columnIndex); }, columnCount: 1000, columnWidth: 20, height: 500, rowCount: 1000, rowHeight: 20, width: 500 })); expect(rendered).toContain('0:0'); expect(rendered).toContain('24:24'); expect(rendered).not.toContain('25:25'); }); test('should support :scrollToColumn and :scrollToRow in server render', function () { var rendered = ReactDOMServer.renderToString(React.createElement(_Grid["default"], { cellRenderer: function cellRenderer(_ref2) { var style = _ref2.style, key = _ref2.key, rowIndex = _ref2.rowIndex, columnIndex = _ref2.columnIndex; return React.createElement("div", { style: style, key: key }, rowIndex + ':' + columnIndex); }, columnCount: 1000, columnWidth: 20, scrollToColumn: 250, height: 500, rowCount: 1000, rowHeight: 20, scrollToRow: 250, width: 500 })); expect(rendered).toContain('250:250'); expect(rendered).not.toContain('0:0'); });dist/commonjs/Grid/accessibilityOverscanIndicesGetter.jest.js000064400000005441151676725770020560 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _accessibilityOverscanIndicesGetter = _interopRequireWildcard(require("./accessibilityOverscanIndicesGetter")); describe('overscanIndicesGetter', function () { function testHelper(_ref) { var cellCount = _ref.cellCount, startIndex = _ref.startIndex, stopIndex = _ref.stopIndex, overscanCellsCount = _ref.overscanCellsCount, scrollDirection = _ref.scrollDirection; return (0, _accessibilityOverscanIndicesGetter["default"])({ cellCount: cellCount, overscanCellsCount: overscanCellsCount, scrollDirection: scrollDirection, startIndex: startIndex, stopIndex: stopIndex }); } it('should still overscan by 1 (for keyboard accessibility) if :overscanCellsCount is 0', function () { expect(testHelper({ cellCount: 100, startIndex: 10, stopIndex: 20, overscanCellsCount: 0, scrollDirection: _accessibilityOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD })).toEqual({ overscanStartIndex: 9, overscanStopIndex: 21 }); expect(testHelper({ cellCount: 100, startIndex: 10, stopIndex: 20, overscanCellsCount: 0, scrollDirection: _accessibilityOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD })).toEqual({ overscanStartIndex: 9, overscanStopIndex: 21 }); }); it('should overscan forward', function () { expect(testHelper({ cellCount: 100, startIndex: 20, stopIndex: 30, overscanCellsCount: 10, scrollDirection: _accessibilityOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD })).toEqual({ overscanStartIndex: 19, overscanStopIndex: 40 }); }); it('should overscan backward', function () { expect(testHelper({ cellCount: 100, startIndex: 20, stopIndex: 30, overscanCellsCount: 10, scrollDirection: _accessibilityOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD })).toEqual({ overscanStartIndex: 10, overscanStopIndex: 31 }); }); it('should not overscan beyond the start of the list', function () { expect(testHelper({ cellCount: 100, startIndex: 5, stopIndex: 15, overscanCellsCount: 10, scrollDirection: _accessibilityOverscanIndicesGetter.SCROLL_DIRECTION_BACKWARD })).toEqual({ overscanStartIndex: 0, overscanStopIndex: 16 }); }); it('should not overscan beyond the end of the list', function () { expect(testHelper({ cellCount: 25, startIndex: 10, stopIndex: 20, overscanCellsCount: 10, scrollDirection: _accessibilityOverscanIndicesGetter.SCROLL_DIRECTION_FORWARD })).toEqual({ overscanStartIndex: 9, overscanStopIndex: 24 }); }); });dist/commonjs/Grid/defaultOverscanIndicesGetter.js000064400000002771151676725770016414 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = defaultOverscanIndicesGetter; exports.SCROLL_DIRECTION_VERTICAL = exports.SCROLL_DIRECTION_HORIZONTAL = exports.SCROLL_DIRECTION_FORWARD = exports.SCROLL_DIRECTION_BACKWARD = void 0; var _types = require("./types"); var SCROLL_DIRECTION_BACKWARD = -1; exports.SCROLL_DIRECTION_BACKWARD = SCROLL_DIRECTION_BACKWARD; var SCROLL_DIRECTION_FORWARD = 1; exports.SCROLL_DIRECTION_FORWARD = SCROLL_DIRECTION_FORWARD; var SCROLL_DIRECTION_HORIZONTAL = 'horizontal'; exports.SCROLL_DIRECTION_HORIZONTAL = SCROLL_DIRECTION_HORIZONTAL; var SCROLL_DIRECTION_VERTICAL = 'vertical'; /** * Calculates the number of cells to overscan before and after a specified range. * This function ensures that overscanning doesn't exceed the available cells. */ exports.SCROLL_DIRECTION_VERTICAL = SCROLL_DIRECTION_VERTICAL; function defaultOverscanIndicesGetter(_ref) { var cellCount = _ref.cellCount, overscanCellsCount = _ref.overscanCellsCount, scrollDirection = _ref.scrollDirection, startIndex = _ref.startIndex, stopIndex = _ref.stopIndex; if (scrollDirection === SCROLL_DIRECTION_FORWARD) { return { overscanStartIndex: Math.max(0, startIndex), overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount) }; } else { return { overscanStartIndex: Math.max(0, startIndex - overscanCellsCount), overscanStopIndex: Math.min(cellCount - 1, stopIndex) }; } }dist/commonjs/jest-setup.js000064400000000202151676725770012016 0ustar00"use strict"; jest.mock('dom-helpers/scrollbarSize', function () { return function getScrollbarSize() { return 20; }; });dist/commonjs/WindowScroller/WindowScroller.e2e.js000064400000023462151676725770016334 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); /** * @jest-environment jest-environment-puppeteer */ var bootstrap = function bootstrap() { var page, scripts, _i, _scripts, path; return _regenerator["default"].async(function bootstrap$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return _regenerator["default"].awrap(global.browser.newPage()); case 2: page = _context.sent; scripts = ['./node_modules/react/umd/react.development.js', './node_modules/react-dom/umd/react-dom.development.js', './dist/umd/react-virtualized.js']; _i = 0, _scripts = scripts; case 5: if (!(_i < _scripts.length)) { _context.next = 12; break; } path = _scripts[_i]; _context.next = 9; return _regenerator["default"].awrap(page.addScriptTag({ path: path })); case 9: _i++; _context.next = 5; break; case 12: return _context.abrupt("return", page); case 13: case "end": return _context.stop(); } } }); }; var renderWindowScroller = function renderWindowScroller(_ref) { var scrollElement = _ref.scrollElement; var render = window.ReactDOM.render; var createElement = window.React.createElement; var WindowScroller = window.ReactVirtualized.WindowScroller; var container = document.createElement('div'); container.id = 'container'; container.style.margin = '100px'; container.style.padding = '50px'; document.body.appendChild(container); document.body.style.margin = 0; if (scrollElement === 'container') { container.style.width = '100%'; container.style.height = '100%'; container.style.overflow = 'auto'; } render(createElement(WindowScroller, { scrollElement: scrollElement === 'container' ? container : window, onScroll: window.scrollFn, onResize: window.resizeFn }, function () { return createElement('div', { style: { width: 2000, height: 3000 } }); }), container); }; var delay = function delay(time) { return new Promise(function (resolve) { return setTimeout(resolve, time); }); }; test('save position after resize and then scroll in window', function _callee() { var page, scrollFn, resizeFn; return _regenerator["default"].async(function _callee$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _context2.next = 2; return _regenerator["default"].awrap(bootstrap()); case 2: page = _context2.sent; scrollFn = jest.fn(); resizeFn = jest.fn(); _context2.next = 7; return _regenerator["default"].awrap(page.exposeFunction('scrollFn', scrollFn)); case 7: _context2.next = 9; return _regenerator["default"].awrap(page.exposeFunction('resizeFn', resizeFn)); case 9: _context2.next = 11; return _regenerator["default"].awrap(page.setViewport({ width: 400, height: 600 })); case 11: _context2.next = 13; return _regenerator["default"].awrap(page.evaluate(renderWindowScroller, { scrollElement: 'window' })); case 13: _context2.next = 15; return _regenerator["default"].awrap(page.evaluate(function () { return window.scrollTo(610, 830); })); case 15: _context2.next = 17; return _regenerator["default"].awrap(delay(100)); case 17: _context2.next = 19; return _regenerator["default"].awrap(page.setViewport({ width: 300, height: 500 })); case 19: _context2.next = 21; return _regenerator["default"].awrap(delay(100)); case 21: _context2.next = 23; return _regenerator["default"].awrap(page.evaluate(function () { return window.scrollTo(620, 840); })); case 23: _context2.next = 25; return _regenerator["default"].awrap(delay(100)); case 25: _context2.next = 27; return _regenerator["default"].awrap(page.close()); case 27: expect(scrollFn.mock.calls).toEqual([[{ scrollLeft: 610 - 150, scrollTop: 830 - 150 }], [{ scrollLeft: 620 - 150, scrollTop: 840 - 150 }]]); expect(resizeFn.mock.calls).toEqual([[{ width: 300, height: 500 }]]); case 29: case "end": return _context2.stop(); } } }); }); test('save position after resize and then scroll in container', function _callee2() { var page, scrollFn, resizeFn; return _regenerator["default"].async(function _callee2$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.next = 2; return _regenerator["default"].awrap(bootstrap()); case 2: page = _context3.sent; scrollFn = jest.fn(); resizeFn = jest.fn(); _context3.next = 7; return _regenerator["default"].awrap(page.exposeFunction('scrollFn', scrollFn)); case 7: _context3.next = 9; return _regenerator["default"].awrap(page.exposeFunction('resizeFn', resizeFn)); case 9: _context3.next = 11; return _regenerator["default"].awrap(page.setViewport({ width: 400, height: 600 })); case 11: _context3.next = 13; return _regenerator["default"].awrap(page.evaluate(renderWindowScroller, { scrollElement: 'container' })); case 13: _context3.next = 15; return _regenerator["default"].awrap(page.$eval('#container', function (el) { return el.scrollTo(610, 830); })); case 15: _context3.next = 17; return _regenerator["default"].awrap(delay(100)); case 17: _context3.next = 19; return _regenerator["default"].awrap(page.setViewport({ width: 300, height: 500 })); case 19: _context3.next = 21; return _regenerator["default"].awrap(delay(100)); case 21: _context3.next = 23; return _regenerator["default"].awrap(page.$eval('#container', function (el) { return el.scrollTo(620, 840); })); case 23: _context3.next = 25; return _regenerator["default"].awrap(delay(100)); case 25: _context3.next = 27; return _regenerator["default"].awrap(page.close()); case 27: expect(scrollFn.mock.calls).toEqual([[{ scrollLeft: 610 - 50, scrollTop: 830 - 50 }], [{ scrollLeft: 620 - 50, scrollTop: 840 - 50 }]]); expect(resizeFn.mock.calls).toEqual([[{ width: 500, height: 700 }], [{ width: 400, height: 600 }]]); case 29: case "end": return _context3.stop(); } } }); }); test('react on container resize without window changing', function _callee3() { var page, resizeFn; return _regenerator["default"].async(function _callee3$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: _context4.next = 2; return _regenerator["default"].awrap(bootstrap()); case 2: page = _context4.sent; resizeFn = jest.fn(); _context4.next = 6; return _regenerator["default"].awrap(page.exposeFunction('resizeFn', resizeFn)); case 6: _context4.next = 8; return _regenerator["default"].awrap(page.evaluate(function () { var render = window.ReactDOM.render; var createElement = window.React.createElement; var WindowScroller = window.ReactVirtualized.WindowScroller; var wrapper = document.createElement('div'); wrapper.id = 'wrapper'; Object.assign(wrapper.style, { width: '1000px', height: '800px', display: 'flex' }); var container = document.createElement('div'); Object.assign(container.style, { flex: '1' }); wrapper.appendChild(container); document.body.style.margin = 0; document.body.appendChild(wrapper); render(createElement(WindowScroller, { scrollElement: container, onResize: window.resizeFn }, function () { return null; }), container); })); case 8: _context4.next = 10; return _regenerator["default"].awrap(delay(100)); case 10: _context4.next = 12; return _regenerator["default"].awrap(page.$eval('#wrapper', function (el) { el.style.width = '500px'; el.style.height = '700px'; })); case 12: _context4.next = 14; return _regenerator["default"].awrap(delay(100)); case 14: _context4.next = 16; return _regenerator["default"].awrap(page.close()); case 16: expect(resizeFn.mock.calls).toEqual([[{ width: 1000, height: 800 }], [{ width: 500, height: 700 }]]); case 17: case "end": return _context4.stop(); } } }); });dist/commonjs/WindowScroller/WindowScroller.example.js000064400000020606151676725770017311 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _clsx2 = _interopRequireDefault(require("clsx")); var _immutable = _interopRequireDefault(require("immutable")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _ContentBox = require("../demo/ContentBox"); var _LabeledInput = require("../demo/LabeledInput"); var _WindowScroller = _interopRequireDefault(require("./WindowScroller")); var _List = _interopRequireDefault(require("../List")); var _AutoSizer = _interopRequireDefault(require("../AutoSizer")); var _WindowScrollerExample = _interopRequireDefault(require("./WindowScroller.example.css")); var _class, _temp; var WindowScrollerExample = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(WindowScrollerExample, _React$PureComponent); function WindowScrollerExample() { var _getPrototypeOf2; var _this; (0, _classCallCheck2["default"])(this, WindowScrollerExample); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(WindowScrollerExample)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", { scrollToIndex: -1, showHeaderText: true }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_windowScroller", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_hideHeader", function () { var showHeaderText = _this.state.showHeaderText; _this.setState({ showHeaderText: !showHeaderText }, function () { if (_this._windowScroller) { _this._windowScroller.updatePosition(); } }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rowRenderer", function (_ref) { var _clsx; var index = _ref.index, isScrolling = _ref.isScrolling, isVisible = _ref.isVisible, key = _ref.key, style = _ref.style; var list = _this.context.list; var row = list.get(index); var className = (0, _clsx2["default"])(_WindowScrollerExample["default"].row, (_clsx = {}, (0, _defineProperty2["default"])(_clsx, _WindowScrollerExample["default"].rowScrolling, isScrolling), (0, _defineProperty2["default"])(_clsx, "isVisible", isVisible), _clsx)); return React.createElement("div", { key: key, className: className, style: style }, row.name); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_setRef", function (windowScroller) { _this._windowScroller = windowScroller; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onCheckboxChange", function (event) { _this.context.setScrollingCustomElement(event.target.checked); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onScrollToRowChange", function (event) { var list = _this.context.list; var scrollToIndex = Math.min(list.size - 1, parseInt(event.target.value, 10)); if (isNaN(scrollToIndex)) { scrollToIndex = undefined; } setTimeout(function () { _this.setState({ scrollToIndex: scrollToIndex }); }, 0); }); return _this; } (0, _createClass2["default"])(WindowScrollerExample, [{ key: "render", value: function render() { var _this2 = this; var _this$context = this.context, customElement = _this$context.customElement, isScrollingCustomElement = _this$context.isScrollingCustomElement, list = _this$context.list; var _this$state = this.state, scrollToIndex = _this$state.scrollToIndex, showHeaderText = _this$state.showHeaderText; return React.createElement(_ContentBox.ContentBox, null, React.createElement(_ContentBox.ContentBoxHeader, { text: "WindowScroller", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/WindowScroller/WindowScroller.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/WindowScroller.md" }), showHeaderText && React.createElement(_ContentBox.ContentBoxParagraph, null, "This component decorates ", React.createElement("code", null, "List"), ", ", React.createElement("code", null, "Table"), ", or any other component and manages the window scroll to scroll through the list"), showHeaderText && React.createElement(_ContentBox.ContentBoxParagraph, null, React.createElement("button", { onClick: this._hideHeader }, "Hide header text")), React.createElement(_ContentBox.ContentBoxParagraph, null, React.createElement("label", { className: _WindowScrollerExample["default"].checkboxLabel }, React.createElement("input", { "aria-label": "Use custom element for scrolling", className: _WindowScrollerExample["default"].checkbox, type: "checkbox", checked: isScrollingCustomElement, onChange: this._onCheckboxChange }), "Use custom element for scrolling")), React.createElement(_LabeledInput.InputRow, null, React.createElement(_LabeledInput.LabeledInput, { label: "Scroll to", name: "onScrollToRow", placeholder: "Index...", onChange: this._onScrollToRowChange, value: scrollToIndex || '' })), React.createElement(_WindowScroller["default"], { ref: this._setRef, scrollElement: isScrollingCustomElement ? customElement : window }, function (_ref2) { var height = _ref2.height, isScrolling = _ref2.isScrolling, registerChild = _ref2.registerChild, onChildScroll = _ref2.onChildScroll, scrollTop = _ref2.scrollTop; return React.createElement("div", { className: _WindowScrollerExample["default"].WindowScrollerWrapper }, React.createElement(_AutoSizer["default"], { disableHeight: true }, function (_ref3) { var width = _ref3.width; return React.createElement("div", { ref: registerChild }, React.createElement(_List["default"], { ref: function ref(el) { window.listEl = el; }, autoHeight: true, className: _WindowScrollerExample["default"].List, height: height, isScrolling: isScrolling, onScroll: onChildScroll, overscanRowCount: 2, rowCount: list.size, rowHeight: 30, rowRenderer: _this2._rowRenderer, scrollToIndex: scrollToIndex, scrollTop: scrollTop, width: width })); })); })); } }]); return WindowScrollerExample; }(React.PureComponent), (0, _defineProperty2["default"])(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : {}), _temp); exports["default"] = WindowScrollerExample; (0, _defineProperty2["default"])(WindowScrollerExample, "contextTypes", { customElement: _propTypes["default"].any, isScrollingCustomElement: _propTypes["default"].bool.isRequired, list: _propTypes["default"].instanceOf(_immutable["default"].List).isRequired, setScrollingCustomElement: _propTypes["default"].func });dist/commonjs/WindowScroller/utils/dimensions.js000064400000005305151676725770016211 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getDimensions = getDimensions; exports.getPositionOffset = getPositionOffset; exports.getScrollOffset = getScrollOffset; /** * Gets the dimensions of the element, accounting for API differences between * `window` and other DOM elements. */ // TODO Move this into WindowScroller and import from there var isWindow = function isWindow(element) { return element === window; }; var getBoundingBox = function getBoundingBox(element) { return element.getBoundingClientRect(); }; function getDimensions(scrollElement, props) { if (!scrollElement) { return { height: props.serverHeight, width: props.serverWidth }; } else if (isWindow(scrollElement)) { var _window = window, innerHeight = _window.innerHeight, innerWidth = _window.innerWidth; return { height: typeof innerHeight === 'number' ? innerHeight : 0, width: typeof innerWidth === 'number' ? innerWidth : 0 }; } else { return getBoundingBox(scrollElement); } } /** * Gets the vertical and horizontal position of an element within its scroll container. * Elements that have been “scrolled past” return negative values. * Handles edge-case where a user is navigating back (history) from an already-scrolled page. * In this case the body’s top or left position will be a negative number and this element’s top or left will be increased (by that amount). */ function getPositionOffset(element, container) { if (isWindow(container) && document.documentElement) { var containerElement = document.documentElement; var elementRect = getBoundingBox(element); var containerRect = getBoundingBox(containerElement); return { top: elementRect.top - containerRect.top, left: elementRect.left - containerRect.left }; } else { var scrollOffset = getScrollOffset(container); var _elementRect = getBoundingBox(element); var _containerRect = getBoundingBox(container); return { top: _elementRect.top + scrollOffset.top - _containerRect.top, left: _elementRect.left + scrollOffset.left - _containerRect.left }; } } /** * Gets the vertical and horizontal scroll amount of the element, accounting for IE compatibility * and API differences between `window` and other DOM elements. */ function getScrollOffset(element) { if (isWindow(element) && document.documentElement) { return { top: 'scrollY' in window ? window.scrollY : document.documentElement.scrollTop, left: 'scrollX' in window ? window.scrollX : document.documentElement.scrollLeft }; } else { return { top: element.scrollTop, left: element.scrollLeft }; } }dist/commonjs/WindowScroller/utils/onScroll.js000064400000005040151676725770015630 0ustar00"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.registerScrollListener = registerScrollListener; exports.unregisterScrollListener = unregisterScrollListener; var _requestAnimationTimeout = require("../../utils/requestAnimationTimeout"); var _WindowScroller = require("../WindowScroller.js"); var mountedInstances = []; var originalBodyPointerEvents = null; var disablePointerEventsTimeoutId = null; function enablePointerEventsIfDisabled() { if (disablePointerEventsTimeoutId) { disablePointerEventsTimeoutId = null; if (document.body && originalBodyPointerEvents != null) { document.body.style.pointerEvents = originalBodyPointerEvents; } originalBodyPointerEvents = null; } } function enablePointerEventsAfterDelayCallback() { enablePointerEventsIfDisabled(); mountedInstances.forEach(function (instance) { return instance.__resetIsScrolling(); }); } function enablePointerEventsAfterDelay() { if (disablePointerEventsTimeoutId) { (0, _requestAnimationTimeout.cancelAnimationTimeout)(disablePointerEventsTimeoutId); } var maximumTimeout = 0; mountedInstances.forEach(function (instance) { maximumTimeout = Math.max(maximumTimeout, instance.props.scrollingResetTimeInterval); }); disablePointerEventsTimeoutId = (0, _requestAnimationTimeout.requestAnimationTimeout)(enablePointerEventsAfterDelayCallback, maximumTimeout); } function onScrollWindow(event) { if (event.currentTarget === window && originalBodyPointerEvents == null && document.body) { originalBodyPointerEvents = document.body.style.pointerEvents; document.body.style.pointerEvents = 'none'; } enablePointerEventsAfterDelay(); mountedInstances.forEach(function (instance) { if (instance.props.scrollElement === event.currentTarget) { instance.__handleWindowScrollEvent(); } }); } function registerScrollListener(component, element) { if (!mountedInstances.some(function (instance) { return instance.props.scrollElement === element; })) { element.addEventListener('scroll', onScrollWindow); } mountedInstances.push(component); } function unregisterScrollListener(component, element) { mountedInstances = mountedInstances.filter(function (instance) { return instance !== component; }); if (!mountedInstances.length) { element.removeEventListener('scroll', onScrollWindow); if (disablePointerEventsTimeoutId) { (0, _requestAnimationTimeout.cancelAnimationTimeout)(disablePointerEventsTimeoutId); enablePointerEventsIfDisabled(); } } }dist/commonjs/WindowScroller/index.js000064400000001211151676725770014000 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "WindowScroller", { enumerable: true, get: function get() { return _WindowScroller["default"]; } }); Object.defineProperty(exports, "IS_SCROLLING_TIMEOUT", { enumerable: true, get: function get() { return _WindowScroller.IS_SCROLLING_TIMEOUT; } }); exports["default"] = void 0; var _WindowScroller = _interopRequireWildcard(require("./WindowScroller")); var _default = _WindowScroller["default"]; exports["default"] = _default;dist/commonjs/WindowScroller/WindowScroller.jest.js000064400000046047151676725770016632 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _TestUtils = require("../TestUtils"); var _WindowScroller = _interopRequireWildcard(require("./WindowScroller")); function mockGetBoundingClientRectForHeader(_ref) { var _ref$documentOffset = _ref.documentOffset, documentOffset = _ref$documentOffset === void 0 ? 0 : _ref$documentOffset, height = _ref.height, width = _ref.width; // Mock the WindowScroller element and window separately // The only way to mock the former (before its created) is globally Element.prototype.getBoundingClientRect = jest.fn(function () { return { top: height, left: width }; }); document.documentElement.getBoundingClientRect = jest.fn(function () { return { top: documentOffset, left: documentOffset }; }); } function getMarkup() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, headerElements = _ref2.headerElements, documentOffset = _ref2.documentOffset, renderFn = _ref2.renderFn, props = (0, _objectWithoutProperties2["default"])(_ref2, ["headerElements", "documentOffset", "renderFn"]); var windowScroller = React.createElement(_WindowScroller["default"], props, function (params) { return React.createElement("div", null, renderFn && renderFn(params)); }); // JSDome doesn't implement a working getBoundingClientRect() // But WindowScroller requires it mockGetBoundingClientRectForHeader({ documentOffset: documentOffset, height: headerElements ? headerElements.props.style.height : 0, width: headerElements ? headerElements.props.style.width : 0 }); if (headerElements) { return React.createElement("div", null, headerElements, windowScroller); } else { return windowScroller; } } function simulateWindowScroll(_ref3) { var _ref3$scrollX = _ref3.scrollX, scrollX = _ref3$scrollX === void 0 ? 0 : _ref3$scrollX, _ref3$scrollY = _ref3.scrollY, scrollY = _ref3$scrollY === void 0 ? 0 : _ref3$scrollY; document.body.style.height = '10000px'; window.scrollX = scrollX; window.scrollY = scrollY; document.dispatchEvent(new window.Event('scroll', { bubbles: true })); document.body.style.height = ''; } function simulateWindowResize(_ref4) { var _ref4$height = _ref4.height, height = _ref4$height === void 0 ? 0 : _ref4$height, _ref4$width = _ref4.width, width = _ref4$width === void 0 ? 0 : _ref4$width; window.innerHeight = height; window.innerWidth = width; document.dispatchEvent(new window.Event('resize', { bubbles: true })); } describe('WindowScroller', function () { // Set default window height and scroll position between tests beforeEach(function () { window.scrollY = 0; window.scrollX = 0; window.innerHeight = 500; window.innerWidth = 500; }); // Starts updating scrollTop only when the top position is reached it('should have correct top and left properties to be defined on :_positionFromTop and :_positionFromLeft', function () { var component = (0, _TestUtils.render)(getMarkup()); var rendered = (0, _reactDom.findDOMNode)(component); var _rendered$getBounding = rendered.getBoundingClientRect(), top = _rendered$getBounding.top, left = _rendered$getBounding.left; expect(component._positionFromTop).toEqual(top); expect(component._positionFromLeft).toEqual(left); }); it('should allow passing child element with registerChild of children function param', function () { var scrollElement = document.createElement('div'); scrollElement.scrollTop = 100; scrollElement.scrollLeft = 150; scrollElement.getBoundingClientRect = function () { return { top: 200, left: 250 }; }; var child = document.createElement('div'); child.getBoundingClientRect = function () { return { top: 300, left: 350 }; }; var renderFn = jest.fn(); var component = (0, _TestUtils.render)(getMarkup({ scrollElement: scrollElement, renderFn: renderFn })); renderFn.mock.calls[0][0].registerChild(child); expect(component._positionFromTop).toEqual(300 + 100 - 200); expect(component._positionFromLeft).toEqual(350 + 150 - 250); }); it('should warn on passing non-element or not null', function () { var warnFn = jest.spyOn(console, 'warn'); var renderFn = jest.fn(); (0, _TestUtils.render)(getMarkup({ renderFn: renderFn })); renderFn.mock.calls[0][0].registerChild(1); renderFn.mock.calls[0][0].registerChild(document.createElement('div')); renderFn.mock.calls[0][0].registerChild(null); expect(warnFn).toHaveBeenCalledTimes(1); warnFn.mockRestore(); }); // Test edge-case reported in bvaughn/react-virtualized/pull/346 it('should have correct top and left properties to be defined on :_positionFromTop and :_positionFromLeft if documentElement is scrolled', function () { _TestUtils.render.unmount(); // Simulate scrolled documentElement var component = (0, _TestUtils.render)(getMarkup({ documentOffset: -100 })); var rendered = (0, _reactDom.findDOMNode)(component); var _rendered$getBounding2 = rendered.getBoundingClientRect(), top = _rendered$getBounding2.top, left = _rendered$getBounding2.left; expect(component._positionFromTop).toEqual(top + 100); expect(component._positionFromLeft).toEqual(left + 100); // Reset override delete document.documentElement.getBoundingClientRect; }); it('inherits the window height and passes it to child component', function () { var renderFn = jest.fn(); var component = (0, _TestUtils.render)(getMarkup({ renderFn: renderFn })); expect(component.state.height).toEqual(window.innerHeight); expect(component.state.height).toEqual(500); expect(renderFn).lastCalledWith(expect.objectContaining({ height: 500 })); }); it('should restore pointerEvents on body after IS_SCROLLING_TIMEOUT', function _callee() { return _regenerator["default"].async(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: (0, _TestUtils.render)(getMarkup()); document.body.style.pointerEvents = 'all'; simulateWindowScroll({ scrollY: 5000 }); expect(document.body.style.pointerEvents).toEqual('none'); _context.next = 6; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, _WindowScroller.IS_SCROLLING_TIMEOUT + 100); })); case 6: expect(document.body.style.pointerEvents).toEqual('all'); case 7: case "end": return _context.stop(); } } }); }); it('should restore pointerEvents on body after unmount', function () { (0, _TestUtils.render)(getMarkup()); document.body.style.pointerEvents = 'all'; simulateWindowScroll({ scrollY: 5000 }); expect(document.body.style.pointerEvents).toEqual('none'); _TestUtils.render.unmount(); expect(document.body.style.pointerEvents).toEqual('all'); }); describe('onScroll', function () { it('should trigger callback when window scrolls', function _callee2() { var onScroll; return _regenerator["default"].async(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: onScroll = jest.fn(); (0, _TestUtils.render)(getMarkup({ onScroll: onScroll })); simulateWindowScroll({ scrollY: 5000 }); // Allow scrolling timeout to complete so that the component computes state _context2.next = 5; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, 150); })); case 5: expect(onScroll).toHaveBeenCalledWith({ scrollLeft: 0, scrollTop: 5000 }); simulateWindowScroll({ scrollX: 2500, scrollY: 5000 }); // Allow scrolling timeout to complete so that the component computes state _context2.next = 9; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, 150); })); case 9: expect(onScroll).toHaveBeenCalledWith({ scrollLeft: 2500, scrollTop: 5000 }); case 10: case "end": return _context2.stop(); } } }); }); it('should update :scrollTop when window is scrolled', function _callee3() { var renderFn, component, componentScrollTop; return _regenerator["default"].async(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: renderFn = jest.fn(); component = (0, _TestUtils.render)(getMarkup({ renderFn: renderFn })); // Initial load of the component should have 0 scrollTop expect(renderFn).lastCalledWith(expect.objectContaining({ scrollTop: 0 })); simulateWindowScroll({ scrollY: 5000 }); // Allow scrolling timeout to complete so that the component computes state _context3.next = 6; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, 150); })); case 6: componentScrollTop = window.scrollY - component._positionFromTop; expect(component.state.scrollTop).toEqual(componentScrollTop); expect(renderFn).lastCalledWith(expect.objectContaining({ scrollTop: componentScrollTop })); case 9: case "end": return _context3.stop(); } } }); }); it('should specify :isScrolling when scrolling and reset after scrolling', function _callee4() { var renderFn; return _regenerator["default"].async(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: renderFn = jest.fn(); (0, _TestUtils.render)(getMarkup({ renderFn: renderFn })); simulateWindowScroll({ scrollY: 5000 }); expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: true })); _context4.next = 6; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, 250); })); case 6: expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: false })); case 7: case "end": return _context4.stop(); } } }); }); it('should support a custom :scrollingResetTimeInterval prop', function _callee5() { var renderFn; return _regenerator["default"].async(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: renderFn = jest.fn(); (0, _TestUtils.render)(getMarkup({ scrollingResetTimeInterval: 500, renderFn: renderFn })); expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: false })); simulateWindowScroll({ scrollY: 5000 }); expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: true })); _context5.next = 7; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, 100); })); case 7: expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: true })); _context5.next = 10; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, 100); })); case 10: expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: true })); _context5.next = 13; return _regenerator["default"].awrap(new Promise(function (resolve) { return setTimeout(resolve, 400); })); case 13: expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: false })); case 14: case "end": return _context5.stop(); } } }); }); }); describe('onResize', function () { it('should trigger callback on init and when window resizes', function () { var resizeFn = jest.fn(); (0, _TestUtils.render)(getMarkup({ onResize: resizeFn })); simulateWindowResize({ height: 1000, width: 1024 }); expect(resizeFn).toHaveBeenCalledTimes(1); expect(resizeFn).lastCalledWith({ height: 1000, width: 1024 }); }); it('should update height when window resizes', function () { var renderFn = jest.fn(); var component = (0, _TestUtils.render)(getMarkup({ renderFn: renderFn })); // Initial load of the component should have the same window height = 500 expect(component.state.height).toEqual(window.innerHeight); expect(component.state.height).toEqual(500); expect(renderFn).lastCalledWith(expect.objectContaining({ height: 500 })); simulateWindowResize({ height: 1000 }); expect(component.state.height).toEqual(window.innerHeight); expect(component.state.height).toEqual(1000); expect(renderFn).lastCalledWith(expect.objectContaining({ height: 1000 })); }); }); describe('updatePosition', function () { it('should calculate the initial offset from the top of the page when mounted', function () { var windowScroller; (0, _TestUtils.render)(getMarkup({ headerElements: React.createElement("div", { style: { height: 100 } }), ref: function ref(_ref5) { windowScroller = _ref5; } })); expect(windowScroller._positionFromTop).toBe(100); }); it('should recalculate the offset from the top when the window resizes', function () { var windowScroller; (0, _TestUtils.render)(getMarkup({ headerElements: React.createElement("div", { id: "header", style: { height: 100, width: 150 } }), ref: function ref(_ref6) { windowScroller = _ref6; } })); expect(windowScroller._positionFromTop).toBe(100); expect(windowScroller._positionFromLeft).toBe(150); mockGetBoundingClientRectForHeader({ height: 200, width: 300 }); expect(windowScroller._positionFromTop).toBe(100); expect(windowScroller._positionFromLeft).toBe(150); simulateWindowResize({ height: 1000, width: 1000 }); expect(windowScroller._positionFromTop).toBe(200); expect(windowScroller._positionFromLeft).toBe(300); }); it('should recalculate the offset from the top if called externally', function () { var windowScroller; (0, _TestUtils.render)(getMarkup({ headerElements: React.createElement("div", { id: "header", style: { height: 100, width: 150 } }), ref: function ref(_ref7) { windowScroller = _ref7; } })); expect(windowScroller._positionFromTop).toBe(100); expect(windowScroller._positionFromLeft).toBe(150); mockGetBoundingClientRectForHeader({ height: 200, width: 300 }); windowScroller.updatePosition(); expect(windowScroller._positionFromTop).toBe(200); expect(windowScroller._positionFromLeft).toBe(300); }); }); describe('when child scrolls', function () { var originalScrollTo; beforeEach(function () { originalScrollTo = window.scrollTo; window.scrollTo = function (scrollX, scrollY) { return simulateWindowScroll({ scrollX: scrollX, scrollY: scrollY }); }; }); afterEach(function () { window.scrollTo = originalScrollTo; _TestUtils.render.unmount(); }); it('should scroll the scrollElement (when it is window) the desired amount', function () { var renderFn = jest.fn(); var windowScroller; (0, _TestUtils.render)(getMarkup({ ref: function ref(_ref8) { windowScroller = _ref8; }, renderFn: renderFn })); renderFn.mock.calls[0][0].onChildScroll({ scrollTop: 200 }); expect(window.scrollY).toEqual(200 + windowScroller._positionFromTop); }); it('should not scroll the scrollElement if trying to scroll to where we already are', function () { var renderFn = jest.fn(); (0, _TestUtils.render)(getMarkup({ renderFn: renderFn })); simulateWindowScroll({ scrollY: 200 }); window.scrollTo = jest.fn(); renderFn.mock.calls[0][0].onChildScroll({ scrollTop: 200 }); expect(window.scrollTo).not.toHaveBeenCalled(); }); it('should scroll the scrollElement (when it is an element) the desired amount', function () { var windowScroller; var renderFn = jest.fn(); var divEl = document.createElement('div'); (0, _TestUtils.render)(getMarkup({ ref: function ref(_ref9) { windowScroller = _ref9; }, renderFn: renderFn, scrollElement: divEl })); renderFn.mock.calls[0][0].onChildScroll({ scrollTop: 200 }); expect(divEl.scrollTop).toEqual(200 + windowScroller._positionFromTop); }); it('should update own scrollTop', function () { var renderFn = jest.fn(); (0, _TestUtils.render)(getMarkup({ renderFn: renderFn })); renderFn.mock.calls[0][0].onChildScroll({ scrollTop: 200 }); expect(renderFn).lastCalledWith(expect.objectContaining({ scrollTop: 200 })); }); }); });dist/commonjs/WindowScroller/WindowScroller.ssr.js000064400000001646151676725770016470 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var React = _interopRequireWildcard(require("react")); var ReactDOMServer = _interopRequireWildcard(require("react-dom/server")); var _WindowScroller = _interopRequireDefault(require("./WindowScroller")); /** * @jest-environment node */ test('should render content with default widths and heights initially', function () { var rendered = ReactDOMServer.renderToString(React.createElement(_WindowScroller["default"], { serverHeight: 100, serverWidth: 200 }, function (_ref) { var height = _ref.height, width = _ref.width; return React.createElement("div", null, "height:".concat(height, ";width:").concat(width)); })); expect(rendered).toContain('height:100'); expect(rendered).toContain('width:200'); });dist/commonjs/WindowScroller/WindowScroller.js000064400000026737151676725770015672 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.IS_SCROLLING_TIMEOUT = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var React = _interopRequireWildcard(require("react")); var ReactDOM = _interopRequireWildcard(require("react-dom")); var _onScroll = require("./utils/onScroll"); var _dimensions = require("./utils/dimensions"); var _detectElementResize = _interopRequireDefault(require("../vendor/detectElementResize")); var _propTypes = _interopRequireDefault(require("prop-types")); var _class, _temp; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * Specifies the number of miliseconds during which to disable pointer events while a scroll is in progress. * This improves performance and makes scrolling smoother. */ var IS_SCROLLING_TIMEOUT = 150; exports.IS_SCROLLING_TIMEOUT = IS_SCROLLING_TIMEOUT; var getWindow = function getWindow() { return typeof window !== 'undefined' ? window : undefined; }; var WindowScroller = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(WindowScroller, _React$PureComponent); function WindowScroller() { var _getPrototypeOf2; var _this; (0, _classCallCheck2["default"])(this, WindowScroller); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(WindowScroller)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_window", getWindow()); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_isMounted", false); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_positionFromTop", 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_positionFromLeft", 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_detectElementResize", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_child", void 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", _objectSpread({}, (0, _dimensions.getDimensions)(_this.props.scrollElement, _this.props), { isScrolling: false, scrollLeft: 0, scrollTop: 0 })); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_registerChild", function (element) { if (element && !(element instanceof Element)) { console.warn('WindowScroller registerChild expects to be passed Element or null'); } _this._child = element; _this.updatePosition(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onChildScroll", function (_ref) { var scrollTop = _ref.scrollTop; if (_this.state.scrollTop === scrollTop) { return; } var scrollElement = _this.props.scrollElement; if (scrollElement) { if (typeof scrollElement.scrollTo === 'function') { scrollElement.scrollTo(0, scrollTop + _this._positionFromTop); } else { scrollElement.scrollTop = scrollTop + _this._positionFromTop; } } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_registerResizeListener", function (element) { if (element === window) { window.addEventListener('resize', _this._onResize, false); } else { _this._detectElementResize.addResizeListener(element, _this._onResize); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_unregisterResizeListener", function (element) { if (element === window) { window.removeEventListener('resize', _this._onResize, false); } else if (element) { _this._detectElementResize.removeResizeListener(element, _this._onResize); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onResize", function () { _this.updatePosition(); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "__handleWindowScrollEvent", function () { if (!_this._isMounted) { return; } var onScroll = _this.props.onScroll; var scrollElement = _this.props.scrollElement; if (scrollElement) { var scrollOffset = (0, _dimensions.getScrollOffset)(scrollElement); var scrollLeft = Math.max(0, scrollOffset.left - _this._positionFromLeft); var scrollTop = Math.max(0, scrollOffset.top - _this._positionFromTop); _this.setState({ isScrolling: true, scrollLeft: scrollLeft, scrollTop: scrollTop }); onScroll({ scrollLeft: scrollLeft, scrollTop: scrollTop }); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "__resetIsScrolling", function () { _this.setState({ isScrolling: false }); }); return _this; } (0, _createClass2["default"])(WindowScroller, [{ key: "updatePosition", value: function updatePosition() { var scrollElement = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props.scrollElement; var onResize = this.props.onResize; var _this$state = this.state, height = _this$state.height, width = _this$state.width; var thisNode = this._child || ReactDOM.findDOMNode(this); if (thisNode instanceof Element && scrollElement) { var offset = (0, _dimensions.getPositionOffset)(thisNode, scrollElement); this._positionFromTop = offset.top; this._positionFromLeft = offset.left; } var dimensions = (0, _dimensions.getDimensions)(scrollElement, this.props); if (height !== dimensions.height || width !== dimensions.width) { this.setState({ height: dimensions.height, width: dimensions.width }); onResize({ height: dimensions.height, width: dimensions.width }); } } }, { key: "componentDidMount", value: function componentDidMount() { var scrollElement = this.props.scrollElement; this._detectElementResize = (0, _detectElementResize["default"])(); this.updatePosition(scrollElement); if (scrollElement) { (0, _onScroll.registerScrollListener)(this, scrollElement); this._registerResizeListener(scrollElement); } this._isMounted = true; } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { var scrollElement = this.props.scrollElement; var prevScrollElement = prevProps.scrollElement; if (prevScrollElement !== scrollElement && prevScrollElement != null && scrollElement != null) { this.updatePosition(scrollElement); (0, _onScroll.unregisterScrollListener)(this, prevScrollElement); (0, _onScroll.registerScrollListener)(this, scrollElement); this._unregisterResizeListener(prevScrollElement); this._registerResizeListener(scrollElement); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { var scrollElement = this.props.scrollElement; if (scrollElement) { (0, _onScroll.unregisterScrollListener)(this, scrollElement); this._unregisterResizeListener(scrollElement); } this._isMounted = false; } }, { key: "render", value: function render() { var children = this.props.children; var _this$state2 = this.state, isScrolling = _this$state2.isScrolling, scrollTop = _this$state2.scrollTop, scrollLeft = _this$state2.scrollLeft, height = _this$state2.height, width = _this$state2.width; return children({ onChildScroll: this._onChildScroll, registerChild: this._registerChild, height: height, isScrolling: isScrolling, scrollLeft: scrollLeft, scrollTop: scrollTop, width: width }); } }]); return WindowScroller; }(React.PureComponent), (0, _defineProperty2["default"])(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { /** * Function responsible for rendering children. * This function should implement the following signature: * ({ height, isScrolling, scrollLeft, scrollTop, width }) => PropTypes.element */ "children": _propTypes["default"].func.isRequired, /** Callback to be invoked on-resize: ({ height, width }) */ "onResize": _propTypes["default"].func.isRequired, /** Callback to be invoked on-scroll: ({ scrollLeft, scrollTop }) */ "onScroll": _propTypes["default"].func.isRequired, /** Element to attach scroll event listeners. Defaults to window. */ "scrollElement": _propTypes["default"].oneOfType([_propTypes["default"].any, function () { return (typeof Element === "function" ? _propTypes["default"].instanceOf(Element) : _propTypes["default"].any).apply(this, arguments); }]), /** * Wait this amount of time after the last scroll event before resetting child `pointer-events`. */ "scrollingResetTimeInterval": _propTypes["default"].number.isRequired, /** Height used for server-side rendering */ "serverHeight": _propTypes["default"].number.isRequired, /** Width used for server-side rendering */ "serverWidth": _propTypes["default"].number.isRequired }), _temp); exports["default"] = WindowScroller; (0, _defineProperty2["default"])(WindowScroller, "defaultProps", { onResize: function onResize() {}, onScroll: function onScroll() {}, scrollingResetTimeInterval: IS_SCROLLING_TIMEOUT, scrollElement: getWindow(), serverHeight: 0, serverWidth: 0 });dist/commonjs/ArrowKeyStepper/types.js000064400000001055151676725770014174 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.bpfrpt_proptype_ScrollIndices = void 0; var _propTypes = _interopRequireDefault(require("prop-types")); var bpfrpt_proptype_ScrollIndices = process.env.NODE_ENV === 'production' ? null : { "scrollToColumn": _propTypes["default"].number.isRequired, "scrollToRow": _propTypes["default"].number.isRequired }; exports.bpfrpt_proptype_ScrollIndices = bpfrpt_proptype_ScrollIndices;dist/commonjs/ArrowKeyStepper/ArrowKeyStepper.jest.js000064400000024552151676725770017111 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _TestUtils = require("../TestUtils"); var _ArrowKeyStepper = _interopRequireDefault(require("./ArrowKeyStepper")); var _testUtils = require("react-dom/test-utils"); function renderTextContent(scrollToColumn, scrollToRow) { return "scrollToColumn:".concat(scrollToColumn, ", scrollToRow:").concat(scrollToRow); } function ChildComponent(_ref) { var scrollToColumn = _ref.scrollToColumn, scrollToRow = _ref.scrollToRow; return React.createElement("div", null, renderTextContent(scrollToColumn, scrollToRow)); } describe('ArrowKeyStepper', function () { function renderHelper() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var onSectionRenderedCallback; var component = (0, _TestUtils.render)(React.createElement(_ArrowKeyStepper["default"], (0, _extends2["default"])({ columnCount: 10, mode: "edges", rowCount: 10 }, props), function (_ref2) { var onSectionRendered = _ref2.onSectionRendered, scrollToColumn = _ref2.scrollToColumn, scrollToRow = _ref2.scrollToRow; onSectionRenderedCallback = onSectionRendered; return React.createElement(ChildComponent, { scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }); })); var node = (0, _reactDom.findDOMNode)(component); return { component: component, node: node, onSectionRendered: onSectionRenderedCallback }; } function assertCurrentScrollTo(node, scrollToColumn, scrollToRow) { expect(node.textContent).toEqual(renderTextContent(scrollToColumn, scrollToRow)); } it('should use a custom :className if one is specified', function () { var _renderHelper = renderHelper({ className: 'foo' }), node = _renderHelper.node; expect(node.className).toEqual('foo'); }); it('should update :scrollToColumn and :scrollToRow in response to arrow keys', function () { var _renderHelper2 = renderHelper(), node = _renderHelper2.node; assertCurrentScrollTo(node, 0, 0); _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 0, 1); _testUtils.Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 1, 1); _testUtils.Simulate.keyDown(node, { key: 'ArrowUp' }); assertCurrentScrollTo(node, 1, 0); _testUtils.Simulate.keyDown(node, { key: 'ArrowLeft' }); assertCurrentScrollTo(node, 0, 0); }); it('should not scroll past the row and column boundaries provided', function () { var _renderHelper3 = renderHelper({ columnCount: 2, rowCount: 2 }), node = _renderHelper3.node; _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 0, 1); _testUtils.Simulate.keyDown(node, { key: 'ArrowUp' }); _testUtils.Simulate.keyDown(node, { key: 'ArrowUp' }); _testUtils.Simulate.keyDown(node, { key: 'ArrowUp' }); assertCurrentScrollTo(node, 0, 0); _testUtils.Simulate.keyDown(node, { key: 'ArrowRight' }); _testUtils.Simulate.keyDown(node, { key: 'ArrowRight' }); _testUtils.Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 1, 0); _testUtils.Simulate.keyDown(node, { key: 'ArrowLeft' }); _testUtils.Simulate.keyDown(node, { key: 'ArrowLeft' }); _testUtils.Simulate.keyDown(node, { key: 'ArrowLeft' }); assertCurrentScrollTo(node, 0, 0); }); it('should accept initial :scrollToColumn and :scrollToRow values via props', function () { var _renderHelper4 = renderHelper({ mode: 'cells', scrollToColumn: 2, scrollToRow: 4 }), node = _renderHelper4.node; assertCurrentScrollTo(node, 2, 4); _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 2, 5); _testUtils.Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 3, 5); }); it('should accept updated :scrollToColumn and :scrollToRow values via props', function () { var _renderHelper5 = renderHelper({ mode: 'cells', scrollToColumn: 2, scrollToRow: 4 }), node = _renderHelper5.node; _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 2, 5); renderHelper({ mode: 'cells', scrollToColumn: 1, scrollToRow: 1 }); _testUtils.Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 2, 1); _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 2, 2); }); it('should accept updated :scrollToColumn and :scrollToRow values via setScrollIndexes()', function () { var _renderHelper6 = renderHelper({ mode: 'cells', scrollToColumn: 2, scrollToRow: 4 }), component = _renderHelper6.component, node = _renderHelper6.node; _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 2, 5); component.setScrollIndexes({ scrollToColumn: 1, scrollToRow: 1 }); _testUtils.Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 2, 1); _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 2, 2); }); it('should not update :scrollToColumn or :scrollToRow when :disabled', function () { var _renderHelper7 = renderHelper({ disabled: true }), node = _renderHelper7.node; assertCurrentScrollTo(node, 0, 0); _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 0, 0); _testUtils.Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 0, 0); }); it('should call :onScrollToChange for key down', function () { [true, false].forEach(function () { var onScrollToChange = jest.fn(); var _renderHelper8 = renderHelper({ isControlled: true, onScrollToChange: onScrollToChange }), node = _renderHelper8.node; expect(onScrollToChange.mock.calls).toHaveLength(0); _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); expect(onScrollToChange.mock.calls).toHaveLength(1); var _onScrollToChange$moc = onScrollToChange.mock.calls[0][0], scrollToColumn = _onScrollToChange$moc.scrollToColumn, scrollToRow = _onScrollToChange$moc.scrollToRow; expect(scrollToColumn).toEqual(0); expect(scrollToRow).toEqual(1); }); }); it('should not call :onScrollToChange for prop update', function () { var numCalls = 0; var onScrollToChange = function onScrollToChange() { numCalls++; }; var _renderHelper9 = renderHelper({ onScrollToChange: onScrollToChange, scrollToColumn: 0, scrollToRow: 0 }), node = _renderHelper9.node; renderHelper({ isControlled: true, onScrollToChange: onScrollToChange, node: node, scrollToColumn: 0, scrollToRow: 1 }); expect(numCalls).toEqual(0); }); describe('mode === "edges"', function () { it('should update :scrollToColumn and :scrollToRow relative to the most recent :onSectionRendered event', function () { var _renderHelper10 = renderHelper(), node = _renderHelper10.node, onSectionRendered = _renderHelper10.onSectionRendered; onSectionRendered({ // Simulate a scroll columnStartIndex: 0, columnStopIndex: 4, rowStartIndex: 4, rowStopIndex: 6 }); _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 0, 7); onSectionRendered({ // Simulate a scroll columnStartIndex: 5, columnStopIndex: 10, rowStartIndex: 2, rowStopIndex: 4 }); _testUtils.Simulate.keyDown(node, { key: 'ArrowUp' }); assertCurrentScrollTo(node, 0, 1); onSectionRendered({ // Simulate a scroll columnStartIndex: 4, columnStopIndex: 8, rowStartIndex: 5, rowStopIndex: 10 }); _testUtils.Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 9, 1); onSectionRendered({ // Simulate a scroll columnStartIndex: 2, columnStopIndex: 4, rowStartIndex: 2, rowStopIndex: 4 }); _testUtils.Simulate.keyDown(node, { key: 'ArrowLeft' }); assertCurrentScrollTo(node, 1, 1); }); }); describe('mode === "cells"', function () { it('should update :scrollToColumn and :scrollToRow relative to the most recent :onSectionRendered event', function () { var _renderHelper11 = renderHelper({ mode: 'cells', scrollToColumn: 5, scrollToRow: 5 }), node = _renderHelper11.node, onSectionRendered = _renderHelper11.onSectionRendered; onSectionRendered({ // Simulate a scroll columnStartIndex: 10, columnStopIndex: 10, rowStartIndex: 15, rowStopIndex: 15 }); _testUtils.Simulate.keyDown(node, { key: 'ArrowUp' }); assertCurrentScrollTo(node, 5, 4); _testUtils.Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 5, 5); onSectionRendered({ // Simulate a scroll columnStartIndex: 10, columnStopIndex: 10, rowStartIndex: 15, rowStopIndex: 15 }); _testUtils.Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 6, 5); _testUtils.Simulate.keyDown(node, { key: 'ArrowLeft' }); assertCurrentScrollTo(node, 5, 5); }); }); });dist/commonjs/ArrowKeyStepper/index.js000064400000001325151676725770014137 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function get() { return _ArrowKeyStepper["default"]; } }); Object.defineProperty(exports, "ArrowKeyStepper", { enumerable: true, get: function get() { return _ArrowKeyStepper["default"]; } }); Object.defineProperty(exports, "bpfrpt_proptype_ScrollIndices", { enumerable: true, get: function get() { return _types.bpfrpt_proptype_ScrollIndices; } }); var _ArrowKeyStepper = _interopRequireDefault(require("./ArrowKeyStepper")); var _types = require("./types");dist/commonjs/ArrowKeyStepper/ArrowKeyStepper.js000064400000022145151676725770016141 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var React = _interopRequireWildcard(require("react")); var _reactLifecyclesCompat = require("react-lifecycles-compat"); var _Grid = require("../Grid"); var _types = require("./types"); var _propTypes = _interopRequireDefault(require("prop-types")); var _class, _temp; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } var ArrowKeyStepper = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(ArrowKeyStepper, _React$PureComponent); function ArrowKeyStepper() { var _getPrototypeOf2; var _this; (0, _classCallCheck2["default"])(this, ArrowKeyStepper); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(ArrowKeyStepper)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", { scrollToColumn: 0, scrollToRow: 0, instanceProps: { prevScrollToColumn: 0, prevScrollToRow: 0 } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_columnStartIndex", 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_columnStopIndex", 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rowStartIndex", 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_rowStopIndex", 0); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onKeyDown", function (event) { var _this$props = _this.props, columnCount = _this$props.columnCount, disabled = _this$props.disabled, mode = _this$props.mode, rowCount = _this$props.rowCount; if (disabled) { return; } var _this$_getScrollState = _this._getScrollState(), scrollToColumnPrevious = _this$_getScrollState.scrollToColumn, scrollToRowPrevious = _this$_getScrollState.scrollToRow; var _this$_getScrollState2 = _this._getScrollState(), scrollToColumn = _this$_getScrollState2.scrollToColumn, scrollToRow = _this$_getScrollState2.scrollToRow; // The above cases all prevent default event event behavior. // This is to keep the grid from scrolling after the snap-to update. switch (event.key) { case 'ArrowDown': scrollToRow = mode === 'cells' ? Math.min(scrollToRow + 1, rowCount - 1) : Math.min(_this._rowStopIndex + 1, rowCount - 1); break; case 'ArrowLeft': scrollToColumn = mode === 'cells' ? Math.max(scrollToColumn - 1, 0) : Math.max(_this._columnStartIndex - 1, 0); break; case 'ArrowRight': scrollToColumn = mode === 'cells' ? Math.min(scrollToColumn + 1, columnCount - 1) : Math.min(_this._columnStopIndex + 1, columnCount - 1); break; case 'ArrowUp': scrollToRow = mode === 'cells' ? Math.max(scrollToRow - 1, 0) : Math.max(_this._rowStartIndex - 1, 0); break; } if (scrollToColumn !== scrollToColumnPrevious || scrollToRow !== scrollToRowPrevious) { event.preventDefault(); _this._updateScrollState({ scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }); } }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onSectionRendered", function (_ref) { var columnStartIndex = _ref.columnStartIndex, columnStopIndex = _ref.columnStopIndex, rowStartIndex = _ref.rowStartIndex, rowStopIndex = _ref.rowStopIndex; _this._columnStartIndex = columnStartIndex; _this._columnStopIndex = columnStopIndex; _this._rowStartIndex = rowStartIndex; _this._rowStopIndex = rowStopIndex; }); return _this; } (0, _createClass2["default"])(ArrowKeyStepper, [{ key: "setScrollIndexes", value: function setScrollIndexes(_ref2) { var scrollToColumn = _ref2.scrollToColumn, scrollToRow = _ref2.scrollToRow; this.setState({ scrollToRow: scrollToRow, scrollToColumn: scrollToColumn }); } }, { key: "render", value: function render() { var _this$props2 = this.props, className = _this$props2.className, children = _this$props2.children; var _this$_getScrollState3 = this._getScrollState(), scrollToColumn = _this$_getScrollState3.scrollToColumn, scrollToRow = _this$_getScrollState3.scrollToRow; return React.createElement("div", { className: className, onKeyDown: this._onKeyDown }, children({ onSectionRendered: this._onSectionRendered, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow })); } }, { key: "_getScrollState", value: function _getScrollState() { return this.props.isControlled ? this.props : this.state; } }, { key: "_updateScrollState", value: function _updateScrollState(_ref3) { var scrollToColumn = _ref3.scrollToColumn, scrollToRow = _ref3.scrollToRow; var _this$props3 = this.props, isControlled = _this$props3.isControlled, onScrollToChange = _this$props3.onScrollToChange; if (typeof onScrollToChange === 'function') { onScrollToChange({ scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }); } if (!isControlled) { this.setState({ scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }); } } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps, prevState) { if (nextProps.isControlled) { return {}; } if (nextProps.scrollToColumn !== prevState.instanceProps.prevScrollToColumn || nextProps.scrollToRow !== prevState.instanceProps.prevScrollToRow) { return _objectSpread({}, prevState, { scrollToColumn: nextProps.scrollToColumn, scrollToRow: nextProps.scrollToRow, instanceProps: { prevScrollToColumn: nextProps.scrollToColumn, prevScrollToRow: nextProps.scrollToRow } }); } return {}; } }]); return ArrowKeyStepper; }(React.PureComponent), (0, _defineProperty2["default"])(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { "children": _propTypes["default"].func.isRequired, "className": _propTypes["default"].string, "columnCount": _propTypes["default"].number.isRequired, "disabled": _propTypes["default"].bool.isRequired, "isControlled": _propTypes["default"].bool.isRequired, "mode": _propTypes["default"].oneOf(["cells", "edges"]).isRequired, "onScrollToChange": _propTypes["default"].func, "rowCount": _propTypes["default"].number.isRequired, "scrollToColumn": _propTypes["default"].number.isRequired, "scrollToRow": _propTypes["default"].number.isRequired }), _temp); (0, _defineProperty2["default"])(ArrowKeyStepper, "defaultProps", { disabled: false, isControlled: false, mode: 'edges', scrollToColumn: 0, scrollToRow: 0 }); (0, _reactLifecyclesCompat.polyfill)(ArrowKeyStepper); var _default = ArrowKeyStepper; exports["default"] = _default;dist/commonjs/ArrowKeyStepper/ArrowKeyStepper.example.js000064400000022224151676725770017571 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf3 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var React = _interopRequireWildcard(require("react")); var _ContentBox = require("../demo/ContentBox"); var _ = _interopRequireWildcard(require("./")); var _AutoSizer = _interopRequireDefault(require("../AutoSizer")); var _Grid = _interopRequireDefault(require("../Grid")); var _clsx2 = _interopRequireDefault(require("clsx")); var _ArrowKeyStepperExample = _interopRequireDefault(require("./ArrowKeyStepper.example.css")); var _class, _temp; var ArrowKeyStepperExample = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(ArrowKeyStepperExample, _React$PureComponent); function ArrowKeyStepperExample() { var _getPrototypeOf2; var _this; (0, _classCallCheck2["default"])(this, ArrowKeyStepperExample); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = (0, _possibleConstructorReturn2["default"])(this, (_getPrototypeOf2 = (0, _getPrototypeOf3["default"])(ArrowKeyStepperExample)).call.apply(_getPrototypeOf2, [this].concat(args))); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "state", { mode: 'edges', isClickable: true, scrollToColumn: 0, scrollToRow: 0 }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_getColumnWidth", function (_ref) { var index = _ref.index; return (1 + index % 3) * 60; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_getRowHeight", function (_ref2) { var index = _ref2.index; return (1 + index % 3) * 30; }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_cellRenderer", function (_ref3) { var columnIndex = _ref3.columnIndex, key = _ref3.key, rowIndex = _ref3.rowIndex, scrollToColumn = _ref3.scrollToColumn, scrollToRow = _ref3.scrollToRow, style = _ref3.style; var className = (0, _clsx2["default"])(_ArrowKeyStepperExample["default"].Cell, (0, _defineProperty2["default"])({}, _ArrowKeyStepperExample["default"].FocusedCell, columnIndex === scrollToColumn && rowIndex === scrollToRow)); return React.createElement("span", { role: "none", className: className, key: key, onClick: _this.state.isClickable && function () { return _this._selectCell({ scrollToColumn: columnIndex, scrollToRow: rowIndex }); }, style: style }, "r:".concat(rowIndex, ", c:").concat(columnIndex)); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_selectCell", function (_ref4) { var scrollToColumn = _ref4.scrollToColumn, scrollToRow = _ref4.scrollToRow; _this.setState({ scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }); }); (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_onClickableChange", function (event) { if (event.target instanceof HTMLInputElement) { _this.setState({ isClickable: event.target.checked, scrollToColumn: 0, scrollToRow: 0 }); } }); return _this; } (0, _createClass2["default"])(ArrowKeyStepperExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, mode = _this$state.mode, isClickable = _this$state.isClickable, scrollToColumn = _this$state.scrollToColumn, scrollToRow = _this$state.scrollToRow; return React.createElement(_ContentBox.ContentBox, null, React.createElement(_ContentBox.ContentBoxHeader, { text: "ArrowKeyStepper", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/ArrowKeyStepper/ArrowKeyStepper.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/ArrowKeyStepper.md" }), React.createElement(_ContentBox.ContentBoxParagraph, null, "This high-order component decorates a ", React.createElement("code", null, "List"), ",", ' ', React.createElement("code", null, "Table"), ", or ", React.createElement("code", null, "Grid"), " and responds to arrow-key events by scrolling one row or column at a time. Focus in the `Grid` below and use the left, right, up, or down arrow keys to move around within the grid."), React.createElement(_ContentBox.ContentBoxParagraph, null, "Note that unlike the other HOCs in react-virtualized, the", ' ', React.createElement("code", null, "ArrowKeyStepper"), " adds a ", React.createElement("code", null, "<div>"), " element around its children in order to attach a key-down event handler."), React.createElement(_ContentBox.ContentBoxParagraph, null, React.createElement("strong", null, "mode"), ":", React.createElement("label", null, React.createElement("input", { "aria-label": "Set mode equal to \"cells\"", checked: mode === 'cells', className: _ArrowKeyStepperExample["default"].Radio, type: "radio", onChange: function onChange(event) { return event.target.checked && _this2.setState({ mode: 'cells' }); }, value: "cells" }), "cells"), React.createElement("label", null, React.createElement("input", { "aria-label": "Set mode equal to \"edges\"", checked: mode === 'edges', className: _ArrowKeyStepperExample["default"].Radio, type: "radio", onChange: function onChange(event) { return event.target.checked && _this2.setState({ mode: 'edges' }); }, value: "edges" }), "edges (default)")), React.createElement(_ContentBox.ContentBoxParagraph, null, React.createElement("label", { className: _ArrowKeyStepperExample["default"].checkboxLabel }, React.createElement("input", { "aria-label": "Enable click selection? (resets selection)", className: _ArrowKeyStepperExample["default"].checkbox, type: "checkbox", checked: isClickable, onChange: this._onClickableChange }), "Enable click selection? (resets selection)")), React.createElement(_["default"], { columnCount: 100, isControlled: isClickable, onScrollToChange: isClickable ? this._selectCell : undefined, mode: mode, rowCount: 100, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }, function (_ref5) { var onSectionRendered = _ref5.onSectionRendered, scrollToColumn = _ref5.scrollToColumn, scrollToRow = _ref5.scrollToRow; return React.createElement("div", null, React.createElement(_ContentBox.ContentBoxParagraph, null, "Most-recently-stepped column: ".concat(scrollToColumn, ", row: ").concat(scrollToRow)), React.createElement(_AutoSizer["default"], { disableHeight: true }, function (_ref6) { var width = _ref6.width; return React.createElement(_Grid["default"], { className: _ArrowKeyStepperExample["default"].Grid, columnWidth: _this2._getColumnWidth, columnCount: 100, height: 200, onSectionRendered: onSectionRendered, cellRenderer: function cellRenderer(_ref7) { var columnIndex = _ref7.columnIndex, key = _ref7.key, rowIndex = _ref7.rowIndex, style = _ref7.style; return _this2._cellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow, style: style }); }, rowHeight: _this2._getRowHeight, rowCount: 100, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow, width: width }); })); })); } }]); return ArrowKeyStepperExample; }(React.PureComponent), (0, _defineProperty2["default"])(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : {}), _temp); exports["default"] = ArrowKeyStepperExample;dist/commonjs/ColumnSizer/ColumnSizer.example.js000064400000015564151676725770016112 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var React = _interopRequireWildcard(require("react")); var _ColumnSizerExample = _interopRequireDefault(require("./ColumnSizer.example.css")); var _AutoSizer = _interopRequireDefault(require("../AutoSizer")); var _ColumnSizer = _interopRequireDefault(require("./ColumnSizer")); var _Grid = _interopRequireDefault(require("../Grid")); var _ContentBox = require("../demo/ContentBox"); var _LabeledInput = require("../demo/LabeledInput"); var ColumnSizerExample = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(ColumnSizerExample, _React$PureComponent); function ColumnSizerExample(props) { var _this; (0, _classCallCheck2["default"])(this, ColumnSizerExample); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(ColumnSizerExample).call(this, props)); _this.state = { columnMaxWidth: 100, columnMinWidth: 75, columnCount: 10 }; _this._noColumnMaxWidthChange = _this._noColumnMaxWidthChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._noColumnMinWidthChange = _this._noColumnMinWidthChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._onColumnCountChange = _this._onColumnCountChange.bind((0, _assertThisInitialized2["default"])(_this)); _this._noContentRenderer = _this._noContentRenderer.bind((0, _assertThisInitialized2["default"])(_this)); _this._cellRenderer = _this._cellRenderer.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(ColumnSizerExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, columnMaxWidth = _this$state.columnMaxWidth, columnMinWidth = _this$state.columnMinWidth, columnCount = _this$state.columnCount; return React.createElement(_ContentBox.ContentBox, null, React.createElement(_ContentBox.ContentBoxHeader, { text: "ColumnSizer", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/ColumnSizer/ColumnSizer.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/ColumnSizer.md" }), React.createElement(_ContentBox.ContentBoxParagraph, null, "This component decorates a ", React.createElement("code", null, "Grid"), " and calculates the width of its columns based on the current (", React.createElement("code", null, "Grid"), ") width."), React.createElement(_LabeledInput.InputRow, null, React.createElement(_LabeledInput.LabeledInput, { label: "Num Columns", name: "columnCount", onChange: this._onColumnCountChange, value: columnCount }), React.createElement(_LabeledInput.LabeledInput, { label: "Column Min Width", name: "columnMinWidth", onChange: this._noColumnMinWidthChange, value: columnMinWidth }), React.createElement(_LabeledInput.LabeledInput, { label: "Column Max Width", name: "columnMaxWidth", onChange: this._noColumnMaxWidthChange, value: columnMaxWidth })), React.createElement("div", null, React.createElement(_AutoSizer["default"], { disableHeight: true }, function (_ref) { var width = _ref.width; return React.createElement(_ColumnSizer["default"], { columnMaxWidth: columnMaxWidth, columnMinWidth: columnMinWidth, columnCount: columnCount, key: "GridColumnSizer", width: width }, function (_ref2) { var adjustedWidth = _ref2.adjustedWidth, columnWidth = _ref2.columnWidth, registerChild = _ref2.registerChild; return React.createElement("div", { className: _ColumnSizerExample["default"].GridContainer, style: { height: 50, width: adjustedWidth } }, React.createElement(_Grid["default"], { ref: registerChild, columnWidth: columnWidth, columnCount: columnCount, height: 50, noContentRenderer: _this2._noContentRenderer, cellRenderer: _this2._cellRenderer, rowHeight: 50, rowCount: 1, width: adjustedWidth })); }); }))); } }, { key: "_noColumnMaxWidthChange", value: function _noColumnMaxWidthChange(event) { var columnMaxWidth = parseInt(event.target.value, 10); if (isNaN(columnMaxWidth)) { columnMaxWidth = undefined; } else { columnMaxWidth = Math.min(1000, columnMaxWidth); } this.setState({ columnMaxWidth: columnMaxWidth }); } }, { key: "_noColumnMinWidthChange", value: function _noColumnMinWidthChange(event) { var columnMinWidth = parseInt(event.target.value, 10); if (isNaN(columnMinWidth)) { columnMinWidth = undefined; } else { columnMinWidth = Math.max(1, columnMinWidth); } this.setState({ columnMinWidth: columnMinWidth }); } }, { key: "_onColumnCountChange", value: function _onColumnCountChange(event) { this.setState({ columnCount: parseInt(event.target.value, 10) || 0 }); } }, { key: "_noContentRenderer", value: function _noContentRenderer() { return React.createElement("div", { className: _ColumnSizerExample["default"].noCells }, "No cells"); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref3) { var columnIndex = _ref3.columnIndex, key = _ref3.key, rowIndex = _ref3.rowIndex, style = _ref3.style; var className = columnIndex === 0 ? _ColumnSizerExample["default"].firstCell : _ColumnSizerExample["default"].cell; return React.createElement("div", { className: className, key: key, style: style }, "R:".concat(rowIndex, ", C:").concat(columnIndex)); } }]); return ColumnSizerExample; }(React.PureComponent); exports["default"] = ColumnSizerExample;dist/commonjs/ColumnSizer/index.js000064400000000731151676725770013303 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "ColumnSizer", { enumerable: true, get: function get() { return _ColumnSizer["default"]; } }); exports["default"] = void 0; var _ColumnSizer = _interopRequireDefault(require("./ColumnSizer")); var _default = _ColumnSizer["default"]; exports["default"] = _default;dist/commonjs/ColumnSizer/ColumnSizer.js000064400000011237151676725770014451 0ustar00"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _propTypes = _interopRequireDefault(require("prop-types")); var React = _interopRequireWildcard(require("react")); /** * High-order component that auto-calculates column-widths for `Grid` cells. */ var ColumnSizer = /*#__PURE__*/ function (_React$PureComponent) { (0, _inherits2["default"])(ColumnSizer, _React$PureComponent); function ColumnSizer(props, context) { var _this; (0, _classCallCheck2["default"])(this, ColumnSizer); _this = (0, _possibleConstructorReturn2["default"])(this, (0, _getPrototypeOf2["default"])(ColumnSizer).call(this, props, context)); _this._registerChild = _this._registerChild.bind((0, _assertThisInitialized2["default"])(_this)); return _this; } (0, _createClass2["default"])(ColumnSizer, [{ key: "componentDidUpdate", value: function componentDidUpdate(prevProps) { var _this$props = this.props, columnMaxWidth = _this$props.columnMaxWidth, columnMinWidth = _this$props.columnMinWidth, columnCount = _this$props.columnCount, width = _this$props.width; if (columnMaxWidth !== prevProps.columnMaxWidth || columnMinWidth !== prevProps.columnMinWidth || columnCount !== prevProps.columnCount || width !== prevProps.width) { if (this._registeredChild) { this._registeredChild.recomputeGridSize(); } } } }, { key: "render", value: function render() { var _this$props2 = this.props, children = _this$props2.children, columnMaxWidth = _this$props2.columnMaxWidth, columnMinWidth = _this$props2.columnMinWidth, columnCount = _this$props2.columnCount, width = _this$props2.width; var safeColumnMinWidth = columnMinWidth || 1; var safeColumnMaxWidth = columnMaxWidth ? Math.min(columnMaxWidth, width) : width; var columnWidth = width / columnCount; columnWidth = Math.max(safeColumnMinWidth, columnWidth); columnWidth = Math.min(safeColumnMaxWidth, columnWidth); columnWidth = Math.floor(columnWidth); var adjustedWidth = Math.min(width, columnWidth * columnCount); return children({ adjustedWidth: adjustedWidth, columnWidth: columnWidth, getColumnWidth: function getColumnWidth() { return columnWidth; }, registerChild: this._registerChild }); } }, { key: "_registerChild", value: function _registerChild(child) { if (child && typeof child.recomputeGridSize !== 'function') { throw Error('Unexpected child type registered; only Grid/MultiGrid children are supported.'); } this._registeredChild = child; if (this._registeredChild) { this._registeredChild.recomputeGridSize(); } } }]); return ColumnSizer; }(React.PureComponent); exports["default"] = ColumnSizer; ColumnSizer.propTypes = process.env.NODE_ENV !== "production" ? { /** * Function responsible for rendering a virtualized Grid. * This function should implement the following signature: * ({ adjustedWidth, getColumnWidth, registerChild }) => PropTypes.element * * The specified :getColumnWidth function should be passed to the Grid's :columnWidth property. * The :registerChild should be passed to the Grid's :ref property. * The :adjustedWidth property is optional; it reflects the lesser of the overall width or the width of all columns. */ children: _propTypes["default"].func.isRequired, /** Optional maximum allowed column width */ columnMaxWidth: _propTypes["default"].number, /** Optional minimum allowed column width */ columnMinWidth: _propTypes["default"].number, /** Number of columns in Grid or Table child */ columnCount: _propTypes["default"].number.isRequired, /** Width of Grid or Table child */ width: _propTypes["default"].number.isRequired } : {};dist/commonjs/ColumnSizer/ColumnSizer.jest.js000064400000012412151676725770015411 0ustar00"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var React = _interopRequireWildcard(require("react")); var _reactDom = require("react-dom"); var _TestUtils = require("../TestUtils"); var _ColumnSizer = _interopRequireDefault(require("./ColumnSizer")); var _Grid = _interopRequireDefault(require("../Grid")); describe('ColumnSizer', function () { function getMarkup() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$columnMinWidth = _ref.columnMinWidth, columnMinWidth = _ref$columnMinWidth === void 0 ? undefined : _ref$columnMinWidth, _ref$columnMaxWidth = _ref.columnMaxWidth, columnMaxWidth = _ref$columnMaxWidth === void 0 ? undefined : _ref$columnMaxWidth, _ref$columnCount = _ref.columnCount, columnCount = _ref$columnCount === void 0 ? 10 : _ref$columnCount, _ref$width = _ref.width, width = _ref$width === void 0 ? 200 : _ref$width; function cellRenderer(_ref2) { var columnIndex = _ref2.columnIndex, key = _ref2.key, rowIndex = _ref2.rowIndex, style = _ref2.style; return React.createElement("div", { className: "gridItem", key: key, style: style }, "row:".concat(rowIndex, ", column:").concat(columnIndex)); } return React.createElement(_ColumnSizer["default"], { columnMinWidth: columnMinWidth, columnMaxWidth: columnMaxWidth, columnCount: columnCount, width: width }, function (_ref3) { var adjustedWidth = _ref3.adjustedWidth, columnWidth = _ref3.columnWidth, registerChild = _ref3.registerChild; return React.createElement("div", null, React.createElement(_Grid["default"], { columnCount: columnCount, columnWidth: columnWidth, height: 50, ref: registerChild, cellRenderer: cellRenderer, rowHeight: 50, rowCount: 1, width: adjustedWidth }), React.createElement("div", { className: "debug" }, "adjustedWidth:".concat(adjustedWidth, " columnWidth:").concat(columnWidth))); }); } it('should distribute column widths evenly if no min/max boundaries have been set', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(rendered.querySelector('.debug').textContent).toContain('columnWidth:20'); }); it('should respect :columnMaxWidth if specified', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnMaxWidth: 10 }))); expect(rendered.querySelector('.debug').textContent).toContain('columnWidth:10'); }); it('should respect :columnMinWidth if specified', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnMinWidth: 30 }))); expect(rendered.querySelector('.debug').textContent).toContain('columnWidth:30'); }); describe('recomputeGridSize', function () { function helper(updatedProps, expectedTextContent) { var renderedA = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup())); expect(renderedA.querySelector('.debug').textContent).toContain('columnWidth:20'); var renderedB = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup(updatedProps))); expect(renderedB.querySelector('.debug').textContent).toContain(expectedTextContent); } it('should recompute metadata sizes if :columnMinWidth changes', function () { helper({ columnMinWidth: 30 }, 'columnWidth:30'); }); it('should recompute metadata sizes if :columnMaxWidth changes', function () { helper({ columnMaxWidth: 15 }, 'columnWidth:15'); }); it('should recompute metadata sizes if :width changes', function () { helper({ width: 300 }, 'columnWidth:30'); }); it('should recompute metadata sizes if :columnCount changes', function () { helper({ columnCount: 2 }, 'columnWidth:100'); }); }); it('should pass the :width as :adjustedWidth if columns require more than the :width to be displayed', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnMinWidth: 30 }))); expect(rendered.querySelector('.debug').textContent).toContain('adjustedWidth:200'); }); it('should pass an :adjustedWidth if columns require less than the :width to be displayed', function () { var rendered = (0, _reactDom.findDOMNode)((0, _TestUtils.render)(getMarkup({ columnMaxWidth: 10 }))); expect(rendered.querySelector('.debug').textContent).toContain('adjustedWidth:100'); }); it('should error if the registered child is not a Grid or a MultiGrid', function () { spyOn(console, 'error'); expect(function () { (0, _TestUtils.render)(React.createElement(_ColumnSizer["default"], { columnMinWidth: 100, columnMaxWidth: 100, columnCount: 100, width: 100 }, function (_ref4) { var registerChild = _ref4.registerChild; return React.createElement("div", { ref: registerChild }); })); }).toThrow(); }); });dist/es/ScrollSync/ScrollSync.js000064400000005467151676725770012705 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import PropTypes from 'prop-types'; import * as React from 'react'; /** * HOC that simplifies the process of synchronizing scrolling between two or more virtualized components. */ var ScrollSync = /*#__PURE__*/ function (_React$PureComponent) { _inherits(ScrollSync, _React$PureComponent); function ScrollSync(props, context) { var _this; _classCallCheck(this, ScrollSync); _this = _possibleConstructorReturn(this, _getPrototypeOf(ScrollSync).call(this, props, context)); _this.state = { clientHeight: 0, clientWidth: 0, scrollHeight: 0, scrollLeft: 0, scrollTop: 0, scrollWidth: 0 }; _this._onScroll = _this._onScroll.bind(_assertThisInitialized(_this)); return _this; } _createClass(ScrollSync, [{ key: "render", value: function render() { var children = this.props.children; var _this$state = this.state, clientHeight = _this$state.clientHeight, clientWidth = _this$state.clientWidth, scrollHeight = _this$state.scrollHeight, scrollLeft = _this$state.scrollLeft, scrollTop = _this$state.scrollTop, scrollWidth = _this$state.scrollWidth; return children({ clientHeight: clientHeight, clientWidth: clientWidth, onScroll: this._onScroll, scrollHeight: scrollHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: scrollWidth }); } }, { key: "_onScroll", value: function _onScroll(_ref) { var clientHeight = _ref.clientHeight, clientWidth = _ref.clientWidth, scrollHeight = _ref.scrollHeight, scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, scrollWidth = _ref.scrollWidth; this.setState({ clientHeight: clientHeight, clientWidth: clientWidth, scrollHeight: scrollHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: scrollWidth }); } }]); return ScrollSync; }(React.PureComponent); export { ScrollSync as default }; ScrollSync.propTypes = process.env.NODE_ENV !== "production" ? { /** * Function responsible for rendering 2 or more virtualized components. * This function should implement the following signature: * ({ onScroll, scrollLeft, scrollTop }) => PropTypes.element */ children: PropTypes.func.isRequired } : {};dist/es/ScrollSync/index.js000064400000000130151676725770011677 0ustar00import ScrollSync from './ScrollSync'; export default ScrollSync; export { ScrollSync };dist/es/ScrollSync/ScrollSync.example.js000064400000023426151676725770014332 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import * as React from 'react'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import AutoSizer from '../AutoSizer'; import Grid from '../Grid'; import ScrollSync from './ScrollSync'; import clsx from 'clsx'; import styles from './ScrollSync.example.css'; import scrollbarSize from 'dom-helpers/scrollbarSize'; var LEFT_COLOR_FROM = hexToRgb('#471061'); var LEFT_COLOR_TO = hexToRgb('#BC3959'); var TOP_COLOR_FROM = hexToRgb('#000000'); var TOP_COLOR_TO = hexToRgb('#333333'); var GridExample = /*#__PURE__*/ function (_React$PureComponent) { _inherits(GridExample, _React$PureComponent); function GridExample(props, context) { var _this; _classCallCheck(this, GridExample); _this = _possibleConstructorReturn(this, _getPrototypeOf(GridExample).call(this, props, context)); _this.state = { columnWidth: 75, columnCount: 50, height: 300, overscanColumnCount: 0, overscanRowCount: 5, rowHeight: 40, rowCount: 100 }; _this._renderBodyCell = _this._renderBodyCell.bind(_assertThisInitialized(_this)); _this._renderHeaderCell = _this._renderHeaderCell.bind(_assertThisInitialized(_this)); _this._renderLeftSideCell = _this._renderLeftSideCell.bind(_assertThisInitialized(_this)); return _this; } _createClass(GridExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, columnCount = _this$state.columnCount, columnWidth = _this$state.columnWidth, height = _this$state.height, overscanColumnCount = _this$state.overscanColumnCount, overscanRowCount = _this$state.overscanRowCount, rowHeight = _this$state.rowHeight, rowCount = _this$state.rowCount; return React.createElement(ContentBox, null, React.createElement(ContentBoxHeader, { text: "ScrollSync", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/ScrollSync/ScrollSync.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/ScrollSync.md" }), React.createElement(ContentBoxParagraph, null, "High order component that simplifies the process of synchronizing scrolling between two or more virtualized components."), React.createElement(ContentBoxParagraph, null, "This example shows two ", React.createElement("code", null, "Grid"), "s and one ", React.createElement("code", null, "List"), ' ', "configured to mimic a spreadsheet with a fixed header and first column. It also shows how a scroll callback can be used to control UI properties such as background color."), React.createElement(ScrollSync, null, function (_ref) { var clientHeight = _ref.clientHeight, clientWidth = _ref.clientWidth, onScroll = _ref.onScroll, scrollHeight = _ref.scrollHeight, scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, scrollWidth = _ref.scrollWidth; var x = scrollLeft / (scrollWidth - clientWidth); var y = scrollTop / (scrollHeight - clientHeight); var leftBackgroundColor = mixColors(LEFT_COLOR_FROM, LEFT_COLOR_TO, y); var leftColor = '#ffffff'; var topBackgroundColor = mixColors(TOP_COLOR_FROM, TOP_COLOR_TO, x); var topColor = '#ffffff'; var middleBackgroundColor = mixColors(leftBackgroundColor, topBackgroundColor, 0.5); var middleColor = '#ffffff'; return React.createElement("div", { className: styles.GridRow }, React.createElement("div", { className: styles.LeftSideGridContainer, style: { position: 'absolute', left: 0, top: 0, color: leftColor, backgroundColor: "rgb(".concat(topBackgroundColor.r, ",").concat(topBackgroundColor.g, ",").concat(topBackgroundColor.b, ")") } }, React.createElement(Grid, { cellRenderer: _this2._renderLeftHeaderCell, className: styles.HeaderGrid, width: columnWidth, height: rowHeight, rowHeight: rowHeight, columnWidth: columnWidth, rowCount: 1, columnCount: 1 })), React.createElement("div", { className: styles.LeftSideGridContainer, style: { position: 'absolute', left: 0, top: rowHeight, color: leftColor, backgroundColor: "rgb(".concat(leftBackgroundColor.r, ",").concat(leftBackgroundColor.g, ",").concat(leftBackgroundColor.b, ")") } }, React.createElement(Grid, { overscanColumnCount: overscanColumnCount, overscanRowCount: overscanRowCount, cellRenderer: _this2._renderLeftSideCell, columnWidth: columnWidth, columnCount: 1, className: styles.LeftSideGrid, height: height - scrollbarSize(), rowHeight: rowHeight, rowCount: rowCount, scrollTop: scrollTop, width: columnWidth })), React.createElement("div", { className: styles.GridColumn }, React.createElement(AutoSizer, { disableHeight: true }, function (_ref2) { var width = _ref2.width; return React.createElement("div", null, React.createElement("div", { style: { backgroundColor: "rgb(".concat(topBackgroundColor.r, ",").concat(topBackgroundColor.g, ",").concat(topBackgroundColor.b, ")"), color: topColor, height: rowHeight, width: width - scrollbarSize() } }, React.createElement(Grid, { className: styles.HeaderGrid, columnWidth: columnWidth, columnCount: columnCount, height: rowHeight, overscanColumnCount: overscanColumnCount, cellRenderer: _this2._renderHeaderCell, rowHeight: rowHeight, rowCount: 1, scrollLeft: scrollLeft, width: width - scrollbarSize() })), React.createElement("div", { style: { backgroundColor: "rgb(".concat(middleBackgroundColor.r, ",").concat(middleBackgroundColor.g, ",").concat(middleBackgroundColor.b, ")"), color: middleColor, height: height, width: width } }, React.createElement(Grid, { className: styles.BodyGrid, columnWidth: columnWidth, columnCount: columnCount, height: height, onScroll: onScroll, overscanColumnCount: overscanColumnCount, overscanRowCount: overscanRowCount, cellRenderer: _this2._renderBodyCell, rowHeight: rowHeight, rowCount: rowCount, width: width }))); }))); })); } }, { key: "_renderBodyCell", value: function _renderBodyCell(_ref3) { var columnIndex = _ref3.columnIndex, key = _ref3.key, rowIndex = _ref3.rowIndex, style = _ref3.style; if (columnIndex < 1) { return; } return this._renderLeftSideCell({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } }, { key: "_renderHeaderCell", value: function _renderHeaderCell(_ref4) { var columnIndex = _ref4.columnIndex, key = _ref4.key, rowIndex = _ref4.rowIndex, style = _ref4.style; if (columnIndex < 1) { return; } return this._renderLeftHeaderCell({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } }, { key: "_renderLeftHeaderCell", value: function _renderLeftHeaderCell(_ref5) { var columnIndex = _ref5.columnIndex, key = _ref5.key, style = _ref5.style; return React.createElement("div", { className: styles.headerCell, key: key, style: style }, "C".concat(columnIndex)); } }, { key: "_renderLeftSideCell", value: function _renderLeftSideCell(_ref6) { var columnIndex = _ref6.columnIndex, key = _ref6.key, rowIndex = _ref6.rowIndex, style = _ref6.style; var rowClass = rowIndex % 2 === 0 ? columnIndex % 2 === 0 ? styles.evenRow : styles.oddRow : columnIndex % 2 !== 0 ? styles.evenRow : styles.oddRow; var classNames = clsx(rowClass, styles.cell); return React.createElement("div", { className: classNames, key: key, style: style }, "R".concat(rowIndex, ", C").concat(columnIndex)); } }]); return GridExample; }(React.PureComponent); export { GridExample as default }; function hexToRgb(hex) { var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; } /** * Ported from sass implementation in C * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209 */ function mixColors(color1, color2, amount) { var weight1 = amount; var weight2 = 1 - amount; var r = Math.round(weight1 * color1.r + weight2 * color2.r); var g = Math.round(weight1 * color1.g + weight2 * color2.g); var b = Math.round(weight1 * color1.b + weight2 * color2.b); return { r: r, g: g, b: b }; }dist/es/ScrollSync/ScrollSync.jest.js000064400000005353151676725770013643 0ustar00import * as React from 'react'; import { findDOMNode } from 'react-dom'; import { render } from '../TestUtils'; import ScrollSync from './ScrollSync'; function ChildComponent(_ref) { var clientHeight = _ref.clientHeight, clientWidth = _ref.clientWidth, scrollHeight = _ref.scrollHeight, scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, scrollWidth = _ref.scrollWidth; return React.createElement("div", null, "clientHeight:".concat(clientHeight), "clientWidth:".concat(clientWidth), "scrollHeight:".concat(scrollHeight), "scrollLeft:".concat(scrollLeft), "scrollTop:".concat(scrollTop), "scrollWidth:".concat(scrollWidth)); } describe('ScrollSync', function () { it('should pass through an initial value of 0 for :scrollLeft and :scrollTop', function () { var component = render(React.createElement(ScrollSync, null, function (_ref2) { var clientHeight = _ref2.clientHeight, clientWidth = _ref2.clientWidth, scrollHeight = _ref2.scrollHeight, scrollLeft = _ref2.scrollLeft, scrollTop = _ref2.scrollTop, scrollWidth = _ref2.scrollWidth; return React.createElement(ChildComponent, { clientHeight: clientHeight, clientWidth: clientWidth, scrollHeight: scrollHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: scrollWidth }); })); expect(findDOMNode(component).textContent).toContain('clientHeight:0'); expect(findDOMNode(component).textContent).toContain('clientWidth:0'); expect(findDOMNode(component).textContent).toContain('scrollHeight:0'); expect(findDOMNode(component).textContent).toContain('scrollLeft:0'); expect(findDOMNode(component).textContent).toContain('scrollTop:0'); expect(findDOMNode(component).textContent).toContain('scrollWidth:0'); }); it('should update :scrollLeft and :scrollTop when :onScroll is called', function () { var onScroll; var component = render(React.createElement(ScrollSync, null, function (params) { onScroll = params.onScroll; return React.createElement(ChildComponent, params); })); onScroll({ clientHeight: 400, clientWidth: 200, scrollHeight: 1000, scrollLeft: 50, scrollTop: 100, scrollWidth: 500 }); expect(findDOMNode(component).textContent).toContain('clientHeight:400'); expect(findDOMNode(component).textContent).toContain('clientWidth:200'); expect(findDOMNode(component).textContent).toContain('scrollHeight:1000'); expect(findDOMNode(component).textContent).toContain('scrollLeft:50'); expect(findDOMNode(component).textContent).toContain('scrollTop:100'); expect(findDOMNode(component).textContent).toContain('scrollWidth:500'); }); });dist/es/Masonry/Masonry.js000064400000045324151676725770011573 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; var _class, _temp; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import clsx from 'clsx'; import * as React from 'react'; import { polyfill } from 'react-lifecycles-compat'; import PositionCache from './PositionCache'; import { requestAnimationTimeout, cancelAnimationTimeout } from '../utils/requestAnimationTimeout'; var emptyObject = {}; /** * Specifies the number of miliseconds during which to disable pointer events while a scroll is in progress. * This improves performance and makes scrolling smoother. */ export var DEFAULT_SCROLLING_RESET_TIME_INTERVAL = 150; /** * This component efficiently displays arbitrarily positioned cells using windowing techniques. * Cell position is determined by an injected `cellPositioner` property. * Windowing is vertical; this component does not support horizontal scrolling. * * Rendering occurs in two phases: * 1) First pass uses estimated cell sizes (provided by the cache) to determine how many cells to measure in a batch. * Batch size is chosen using a fast, naive layout algorithm that stacks images in order until the viewport has been filled. * After measurement is complete (componentDidMount or componentDidUpdate) this component evaluates positioned cells * in order to determine if another measurement pass is required (eg if actual cell sizes were less than estimated sizes). * All measurements are permanently cached (keyed by `keyMapper`) for performance purposes. * 2) Second pass uses the external `cellPositioner` to layout cells. * At this time the positioner has access to cached size measurements for all cells. * The positions it returns are cached by Masonry for fast access later. * Phase one is repeated if the user scrolls beyond the current layout's bounds. * If the layout is invalidated due to eg a resize, cached positions can be cleared using `recomputeCellPositions()`. * * Animation constraints: * Simple animations are supported (eg translate/slide into place on initial reveal). * More complex animations are not (eg flying from one position to another on resize). * * Layout constraints: * This component supports multi-column layout. * The height of each item may vary. * The width of each item must not exceed the width of the column it is "in". * The left position of all items within a column must align. * (Items may not span multiple columns.) */ var Masonry = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { _inherits(Masonry, _React$PureComponent); function Masonry() { var _getPrototypeOf2; var _this; _classCallCheck(this, Masonry); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(Masonry)).call.apply(_getPrototypeOf2, [this].concat(args))); _defineProperty(_assertThisInitialized(_this), "state", { isScrolling: false, scrollTop: 0 }); _defineProperty(_assertThisInitialized(_this), "_debounceResetIsScrollingId", void 0); _defineProperty(_assertThisInitialized(_this), "_invalidateOnUpdateStartIndex", null); _defineProperty(_assertThisInitialized(_this), "_invalidateOnUpdateStopIndex", null); _defineProperty(_assertThisInitialized(_this), "_positionCache", new PositionCache()); _defineProperty(_assertThisInitialized(_this), "_startIndex", null); _defineProperty(_assertThisInitialized(_this), "_startIndexMemoized", null); _defineProperty(_assertThisInitialized(_this), "_stopIndex", null); _defineProperty(_assertThisInitialized(_this), "_stopIndexMemoized", null); _defineProperty(_assertThisInitialized(_this), "_debounceResetIsScrollingCallback", function () { _this.setState({ isScrolling: false }); }); _defineProperty(_assertThisInitialized(_this), "_setScrollingContainerRef", function (ref) { _this._scrollingContainer = ref; }); _defineProperty(_assertThisInitialized(_this), "_onScroll", function (event) { var height = _this.props.height; var eventScrollTop = event.currentTarget.scrollTop; // When this component is shrunk drastically, React dispatches a series of back-to-back scroll events, // Gradually converging on a scrollTop that is within the bounds of the new, smaller height. // This causes a series of rapid renders that is slow for long lists. // We can avoid that by doing some simple bounds checking to ensure that scroll offsets never exceed their bounds. var scrollTop = Math.min(Math.max(0, _this._getEstimatedTotalHeight() - height), eventScrollTop); // On iOS, we can arrive at negative offsets by swiping past the start or end. // Avoid re-rendering in this case as it can cause problems; see #532 for more. if (eventScrollTop !== scrollTop) { return; } // Prevent pointer events from interrupting a smooth scroll _this._debounceResetIsScrolling(); // Certain devices (like Apple touchpad) rapid-fire duplicate events. // Don't force a re-render if this is the case. // The mouse may move faster then the animation frame does. // Use requestAnimationFrame to avoid over-updating. if (_this.state.scrollTop !== scrollTop) { _this.setState({ isScrolling: true, scrollTop: scrollTop }); } }); return _this; } _createClass(Masonry, [{ key: "clearCellPositions", value: function clearCellPositions() { this._positionCache = new PositionCache(); this.forceUpdate(); } // HACK This method signature was intended for Grid }, { key: "invalidateCellSizeAfterRender", value: function invalidateCellSizeAfterRender(_ref) { var index = _ref.rowIndex; if (this._invalidateOnUpdateStartIndex === null) { this._invalidateOnUpdateStartIndex = index; this._invalidateOnUpdateStopIndex = index; } else { this._invalidateOnUpdateStartIndex = Math.min(this._invalidateOnUpdateStartIndex, index); this._invalidateOnUpdateStopIndex = Math.max(this._invalidateOnUpdateStopIndex, index); } } }, { key: "recomputeCellPositions", value: function recomputeCellPositions() { var stopIndex = this._positionCache.count - 1; this._positionCache = new PositionCache(); this._populatePositionCache(0, stopIndex); this.forceUpdate(); } }, { key: "componentDidMount", value: function componentDidMount() { this._checkInvalidateOnUpdate(); this._invokeOnScrollCallback(); this._invokeOnCellsRenderedCallback(); } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { this._checkInvalidateOnUpdate(); this._invokeOnScrollCallback(); this._invokeOnCellsRenderedCallback(); if (this.props.scrollTop !== prevProps.scrollTop) { this._debounceResetIsScrolling(); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this._debounceResetIsScrollingId) { cancelAnimationTimeout(this._debounceResetIsScrollingId); } } }, { key: "render", value: function render() { var _this2 = this; var _this$props = this.props, autoHeight = _this$props.autoHeight, cellCount = _this$props.cellCount, cellMeasurerCache = _this$props.cellMeasurerCache, cellRenderer = _this$props.cellRenderer, className = _this$props.className, height = _this$props.height, id = _this$props.id, keyMapper = _this$props.keyMapper, overscanByPixels = _this$props.overscanByPixels, role = _this$props.role, style = _this$props.style, tabIndex = _this$props.tabIndex, width = _this$props.width, rowDirection = _this$props.rowDirection; var _this$state = this.state, isScrolling = _this$state.isScrolling, scrollTop = _this$state.scrollTop; var children = []; var estimateTotalHeight = this._getEstimatedTotalHeight(); var shortestColumnSize = this._positionCache.shortestColumnSize; var measuredCellCount = this._positionCache.count; var startIndex = 0; var stopIndex; this._positionCache.range(Math.max(0, scrollTop - overscanByPixels), height + overscanByPixels * 2, function (index, left, top) { var _style; if (typeof stopIndex === 'undefined') { startIndex = index; stopIndex = index; } else { startIndex = Math.min(startIndex, index); stopIndex = Math.max(stopIndex, index); } children.push(cellRenderer({ index: index, isScrolling: isScrolling, key: keyMapper(index), parent: _this2, style: (_style = { height: cellMeasurerCache.getHeight(index) }, _defineProperty(_style, rowDirection === 'ltr' ? 'left' : 'right', left), _defineProperty(_style, "position", 'absolute'), _defineProperty(_style, "top", top), _defineProperty(_style, "width", cellMeasurerCache.getWidth(index)), _style) })); }); // We need to measure additional cells for this layout if (shortestColumnSize < scrollTop + height + overscanByPixels && measuredCellCount < cellCount) { var batchSize = Math.min(cellCount - measuredCellCount, Math.ceil((scrollTop + height + overscanByPixels - shortestColumnSize) / cellMeasurerCache.defaultHeight * width / cellMeasurerCache.defaultWidth)); for (var _index = measuredCellCount; _index < measuredCellCount + batchSize; _index++) { stopIndex = _index; children.push(cellRenderer({ index: _index, isScrolling: isScrolling, key: keyMapper(_index), parent: this, style: { width: cellMeasurerCache.getWidth(_index) } })); } } this._startIndex = startIndex; this._stopIndex = stopIndex; return React.createElement("div", { ref: this._setScrollingContainerRef, "aria-label": this.props['aria-label'], className: clsx('ReactVirtualized__Masonry', className), id: id, onScroll: this._onScroll, role: role, style: _objectSpread({ boxSizing: 'border-box', direction: 'ltr', height: autoHeight ? 'auto' : height, overflowX: 'hidden', overflowY: estimateTotalHeight < height ? 'hidden' : 'auto', position: 'relative', width: width, WebkitOverflowScrolling: 'touch', willChange: 'transform' }, style), tabIndex: tabIndex }, React.createElement("div", { className: "ReactVirtualized__Masonry__innerScrollContainer", style: { width: '100%', height: estimateTotalHeight, maxWidth: '100%', maxHeight: estimateTotalHeight, overflow: 'hidden', pointerEvents: isScrolling ? 'none' : '', position: 'relative' } }, children)); } }, { key: "_checkInvalidateOnUpdate", value: function _checkInvalidateOnUpdate() { if (typeof this._invalidateOnUpdateStartIndex === 'number') { var startIndex = this._invalidateOnUpdateStartIndex; var stopIndex = this._invalidateOnUpdateStopIndex; this._invalidateOnUpdateStartIndex = null; this._invalidateOnUpdateStopIndex = null; // Query external layout logic for position of newly-measured cells this._populatePositionCache(startIndex, stopIndex); this.forceUpdate(); } } }, { key: "_debounceResetIsScrolling", value: function _debounceResetIsScrolling() { var scrollingResetTimeInterval = this.props.scrollingResetTimeInterval; if (this._debounceResetIsScrollingId) { cancelAnimationTimeout(this._debounceResetIsScrollingId); } this._debounceResetIsScrollingId = requestAnimationTimeout(this._debounceResetIsScrollingCallback, scrollingResetTimeInterval); } }, { key: "_getEstimatedTotalHeight", value: function _getEstimatedTotalHeight() { var _this$props2 = this.props, cellCount = _this$props2.cellCount, cellMeasurerCache = _this$props2.cellMeasurerCache, width = _this$props2.width; var estimatedColumnCount = Math.max(1, Math.floor(width / cellMeasurerCache.defaultWidth)); return this._positionCache.estimateTotalHeight(cellCount, estimatedColumnCount, cellMeasurerCache.defaultHeight); } }, { key: "_invokeOnScrollCallback", value: function _invokeOnScrollCallback() { var _this$props3 = this.props, height = _this$props3.height, onScroll = _this$props3.onScroll; var scrollTop = this.state.scrollTop; if (this._onScrollMemoized !== scrollTop) { onScroll({ clientHeight: height, scrollHeight: this._getEstimatedTotalHeight(), scrollTop: scrollTop }); this._onScrollMemoized = scrollTop; } } }, { key: "_invokeOnCellsRenderedCallback", value: function _invokeOnCellsRenderedCallback() { if (this._startIndexMemoized !== this._startIndex || this._stopIndexMemoized !== this._stopIndex) { var onCellsRendered = this.props.onCellsRendered; onCellsRendered({ startIndex: this._startIndex, stopIndex: this._stopIndex }); this._startIndexMemoized = this._startIndex; this._stopIndexMemoized = this._stopIndex; } } }, { key: "_populatePositionCache", value: function _populatePositionCache(startIndex, stopIndex) { var _this$props4 = this.props, cellMeasurerCache = _this$props4.cellMeasurerCache, cellPositioner = _this$props4.cellPositioner; for (var _index2 = startIndex; _index2 <= stopIndex; _index2++) { var _cellPositioner = cellPositioner(_index2), left = _cellPositioner.left, top = _cellPositioner.top; this._positionCache.setPosition(_index2, left, top, cellMeasurerCache.getHeight(_index2)); } } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps, prevState) { if (nextProps.scrollTop !== undefined && prevState.scrollTop !== nextProps.scrollTop) { return { isScrolling: true, scrollTop: nextProps.scrollTop }; } return null; } }]); return Masonry; }(React.PureComponent), _defineProperty(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { "autoHeight": PropTypes.bool.isRequired, "cellCount": PropTypes.number.isRequired, "cellMeasurerCache": function cellMeasurerCache() { return (typeof CellMeasurerCache === "function" ? PropTypes.instanceOf(CellMeasurerCache).isRequired : PropTypes.any.isRequired).apply(this, arguments); }, "cellPositioner": function cellPositioner() { return (typeof Positioner === "function" ? PropTypes.instanceOf(Positioner).isRequired : PropTypes.any.isRequired).apply(this, arguments); }, "cellRenderer": function cellRenderer() { return (typeof CellRenderer === "function" ? PropTypes.instanceOf(CellRenderer).isRequired : PropTypes.any.isRequired).apply(this, arguments); }, "className": PropTypes.string, "height": PropTypes.number.isRequired, "id": PropTypes.string, "keyMapper": function keyMapper() { return (typeof KeyMapper === "function" ? PropTypes.instanceOf(KeyMapper).isRequired : PropTypes.any.isRequired).apply(this, arguments); }, "onCellsRendered": function onCellsRendered() { return (typeof OnCellsRenderedCallback === "function" ? PropTypes.instanceOf(OnCellsRenderedCallback) : PropTypes.any).apply(this, arguments); }, "onScroll": function onScroll() { return (typeof OnScrollCallback === "function" ? PropTypes.instanceOf(OnScrollCallback) : PropTypes.any).apply(this, arguments); }, "overscanByPixels": PropTypes.number.isRequired, "role": PropTypes.string.isRequired, "scrollingResetTimeInterval": PropTypes.number.isRequired, "style": function style(props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } }, "tabIndex": PropTypes.number.isRequired, "width": PropTypes.number.isRequired, "rowDirection": PropTypes.string.isRequired, "scrollTop": PropTypes.number }), _temp); _defineProperty(Masonry, "defaultProps", { autoHeight: false, keyMapper: identity, onCellsRendered: noop, onScroll: noop, overscanByPixels: 20, role: 'grid', scrollingResetTimeInterval: DEFAULT_SCROLLING_RESET_TIME_INTERVAL, style: emptyObject, tabIndex: 0, rowDirection: 'ltr' }); function identity(value) { return value; } function noop() {} var bpfrpt_proptype_CellMeasurerCache = process.env.NODE_ENV === 'production' ? null : { "defaultHeight": PropTypes.number.isRequired, "defaultWidth": PropTypes.number.isRequired, "getHeight": PropTypes.func.isRequired, "getWidth": PropTypes.func.isRequired }; polyfill(Masonry); export default Masonry; var bpfrpt_proptype_Positioner = process.env.NODE_ENV === 'production' ? null : PropTypes.func; import { bpfrpt_proptype_AnimationTimeoutId } from "../utils/requestAnimationTimeout"; import PropTypes from "prop-types"; export { bpfrpt_proptype_CellMeasurerCache }; export { bpfrpt_proptype_Positioner };dist/es/Masonry/createCellPositioner.js000064400000002620151676725770014252 0ustar00export default function createCellPositioner(_ref) { var cellMeasurerCache = _ref.cellMeasurerCache, columnCount = _ref.columnCount, columnWidth = _ref.columnWidth, _ref$spacer = _ref.spacer, spacer = _ref$spacer === void 0 ? 0 : _ref$spacer; var columnHeights; initOrResetDerivedValues(); function cellPositioner(index) { // Find the shortest column and use it. var columnIndex = 0; for (var i = 1; i < columnHeights.length; i++) { if (columnHeights[i] < columnHeights[columnIndex]) { columnIndex = i; } } var left = columnIndex * (columnWidth + spacer); var top = columnHeights[columnIndex] || 0; columnHeights[columnIndex] = top + cellMeasurerCache.getHeight(index) + spacer; return { left: left, top: top }; } function initOrResetDerivedValues() { // Track the height of each column. // Layout algorithm below always inserts into the shortest column. columnHeights = []; for (var i = 0; i < columnCount; i++) { columnHeights[i] = 0; } } function reset(params) { columnCount = params.columnCount; columnWidth = params.columnWidth; spacer = params.spacer; initOrResetDerivedValues(); } cellPositioner.reset = reset; return cellPositioner; } import { bpfrpt_proptype_CellMeasurerCache } from "./Masonry"; import { bpfrpt_proptype_Positioner } from "./Masonry";dist/es/Masonry/PositionCache.js000064400000005373151676725770012673 0ustar00import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import createIntervalTree from '../vendor/intervalTree'; // Position cache requirements: // O(log(n)) lookup of cells to render for a given viewport size // O(1) lookup of shortest measured column (so we know when to enter phase 1) var PositionCache = /*#__PURE__*/ function () { function PositionCache() { _classCallCheck(this, PositionCache); _defineProperty(this, "_columnSizeMap", {}); _defineProperty(this, "_intervalTree", createIntervalTree()); _defineProperty(this, "_leftMap", {}); } _createClass(PositionCache, [{ key: "estimateTotalHeight", value: function estimateTotalHeight(cellCount, columnCount, defaultCellHeight) { var unmeasuredCellCount = cellCount - this.count; return this.tallestColumnSize + Math.ceil(unmeasuredCellCount / columnCount) * defaultCellHeight; } // Render all cells visible within the viewport range defined. }, { key: "range", value: function range(scrollTop, clientHeight, renderCallback) { var _this = this; this._intervalTree.queryInterval(scrollTop, scrollTop + clientHeight, function (_ref) { var _ref2 = _slicedToArray(_ref, 3), top = _ref2[0], _ = _ref2[1], index = _ref2[2]; return renderCallback(index, _this._leftMap[index], top); }); } }, { key: "setPosition", value: function setPosition(index, left, top, height) { this._intervalTree.insert([top, top + height, index]); this._leftMap[index] = left; var columnSizeMap = this._columnSizeMap; var columnHeight = columnSizeMap[left]; if (columnHeight === undefined) { columnSizeMap[left] = top + height; } else { columnSizeMap[left] = Math.max(columnHeight, top + height); } } }, { key: "count", get: function get() { return this._intervalTree.count; } }, { key: "shortestColumnSize", get: function get() { var columnSizeMap = this._columnSizeMap; var size = 0; for (var i in columnSizeMap) { var height = columnSizeMap[i]; size = size === 0 ? height : Math.min(size, height); } return size; } }, { key: "tallestColumnSize", get: function get() { var columnSizeMap = this._columnSizeMap; var size = 0; for (var i in columnSizeMap) { var height = columnSizeMap[i]; size = Math.max(size, height); } return size; } }]); return PositionCache; }(); export { PositionCache as default };dist/es/Masonry/index.js000064400000000235151676725770011242 0ustar00import createCellPositioner from './createCellPositioner'; import Masonry from './Masonry'; export default Masonry; export { createCellPositioner, Masonry };dist/es/Masonry/Masonry.jest.js000064400000042211151676725770012527 0ustar00import _extends from "@babel/runtime/helpers/extends"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import * as React from 'react'; import { findDOMNode } from 'react-dom'; import { Simulate } from 'react-dom/test-utils'; import { render } from '../TestUtils'; import createCellPositionerUtil from './createCellPositioner'; import Masonry from './Masonry'; import { CellMeasurer, CellMeasurerCache } from '../CellMeasurer'; var ALTERNATING_CELL_HEIGHTS = [100, 50, 100, 150]; var CELL_SIZE_MULTIPLIER = 50; var COLUMN_COUNT = 3; function assertVisibleCells(rendered, text) { expect(Array.from(rendered.querySelectorAll('.cell')).map(function (node) { return node.textContent; }).sort().join(',')).toEqual(text); } function createCellMeasurerCache() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return new CellMeasurerCache(_objectSpread({ defaultHeight: CELL_SIZE_MULTIPLIER, defaultWidth: CELL_SIZE_MULTIPLIER, fixedWidth: true, keyMapper: function keyMapper(index) { return index; } }, props)); } function createCellPositioner(cache) { return createCellPositionerUtil({ cellMeasurerCache: cache, columnCount: COLUMN_COUNT, columnWidth: CELL_SIZE_MULTIPLIER }); } function createCellRenderer(cache, renderCallback) { renderCallback = typeof renderCallback === 'function' ? renderCallback : function (index) { return index; }; return function cellRenderer(_ref) { var index = _ref.index, isScrolling = _ref.isScrolling, key = _ref.key, parent = _ref.parent, style = _ref.style; var height = ALTERNATING_CELL_HEIGHTS[index % ALTERNATING_CELL_HEIGHTS.length]; var width = CELL_SIZE_MULTIPLIER; return React.createElement(CellMeasurer, { cache: cache, index: index, key: key, parent: parent }, React.createElement("div", { className: "cell", ref: function ref(_ref2) { if (_ref2) { // Accounts for the fact that JSDom doesn't support measurements. Object.defineProperty(_ref2, 'offsetHeight', { configurable: true, value: height }); Object.defineProperty(_ref2, 'offsetWidth', { configurable: true, value: width }); } }, style: _objectSpread({}, style, { minHeight: height, minWidth: width }) }, renderCallback(index, { index: index, isScrolling: isScrolling, key: key, parent: parent, style: style }))); }; } function getMarkup() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var cellMeasurerCache = props.cellMeasurerCache || createCellMeasurerCache(); return React.createElement(Masonry, _extends({ cellCount: 1000, cellMeasurerCache: cellMeasurerCache, cellPositioner: createCellPositioner(cellMeasurerCache), cellRenderer: createCellRenderer(cellMeasurerCache), columnCount: COLUMN_COUNT, height: CELL_SIZE_MULTIPLIER * 2, overscanByPixels: CELL_SIZE_MULTIPLIER, width: CELL_SIZE_MULTIPLIER * COLUMN_COUNT }, props)); } function simulateScroll(masonry) { var scrollTop = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var target = { scrollTop: scrollTop }; masonry._scrollingContainer = target; // HACK to work around _onScroll target check var masonryNode = findDOMNode(masonry); masonryNode.scrollTop = scrollTop; Simulate.scroll(masonryNode); } describe('Masonry', function () { beforeEach(render.unmount); describe('layout and measuring', function () { it('should measure only enough cells required for initial render', function () { // avg cell size: CELL_SIZE_MULTIPLIER // width: CELL_SIZE_MULTIPLIER * 3 // height: CELL_SIZE_MULTIPLIER * 2 // overcsan by: CELL_SIZE_MULTIPLIER // Expected to measure 9 cells var cellMeasurerCache = createCellMeasurerCache(); render(getMarkup({ cellMeasurerCache: cellMeasurerCache })); for (var i = 0; i <= 8; i++) { expect(cellMeasurerCache.has(i)).toBe(true); } expect(cellMeasurerCache.has(9)).toBe(false); }); it('should not measure cells while scrolling until they are needed', function () { // Expected to measure 9 cells var cellMeasurerCache = createCellMeasurerCache(); var renderCallback = jest.fn().mockImplementation(function (index) { return index; }); var cellRenderer = createCellRenderer(cellMeasurerCache, renderCallback); var rendered = findDOMNode(render(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellRenderer: cellRenderer }))); renderCallback.mockClear(); // Scroll a little bit, but not so much to require re-measuring simulateScroll(rendered, 51); // Verify that render was only called enough times to fill view port (no extra for measuring) expect(renderCallback).toHaveBeenCalledTimes(9); }); it('should measure additional cells on scroll when it runs out of measured cells', function () { var cellMeasurerCache = createCellMeasurerCache(); var renderCallback = jest.fn().mockImplementation(function (index) { return index; }); var cellRenderer = createCellRenderer(cellMeasurerCache, renderCallback); var rendered = findDOMNode(render(getMarkup({ cellRenderer: cellRenderer, cellMeasurerCache: cellMeasurerCache }))); expect(cellMeasurerCache.has(9)).toBe(false); renderCallback.mockClear(); simulateScroll(rendered, 101); expect(cellMeasurerCache.has(9)).toBe(true); expect(cellMeasurerCache.has(10)).toBe(false); }); // Masonry used to do a render pass for only unmeasured cells, // But this resulting in removing (and later re-adding) measured cells from the DOM, // Which was bad for performance. See GitHub issue #875 it('should not remove previously-measured cells when measuring new ones', function () { var log = []; var cellMeasurerCache = createCellMeasurerCache(); var renderCallback = function renderCallback(index) { log.push(index); }; var cellRenderer = createCellRenderer(cellMeasurerCache, renderCallback); var rendered = findDOMNode(render(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellRenderer: cellRenderer }))); // Expected to have rendered twice: // 1st time to measure 9 cells (b'c of esimated size) // 2nd time to render and position 9 cells (b'c of actual size) expect(log).toHaveLength(18); log.splice(0); simulateScroll(rendered, 101); // Expected to have rendered twice: // 1st time to measure additional cells (based on estimated size) // 2nd time to render and position with new cells // The 1st render should also have included the pre-measured cells, // To prevent them from being removed, recreated, and re-added to the DOM. expect(log).toHaveLength(18); }); it('should only render enough cells to fill the viewport', function () { var rendered = findDOMNode(render(getMarkup({ overscanByPixels: 0 }))); assertVisibleCells(rendered, '0,1,2,3,4,5'); simulateScroll(rendered, 51); assertVisibleCells(rendered, '0,2,3,4,5,6'); simulateScroll(rendered, 101); assertVisibleCells(rendered, '3,4,5,6,7,8'); simulateScroll(rendered, 1001); assertVisibleCells(rendered, '30,31,32,33,34,35'); }); it('should only render enough cells to fill the viewport plus overscanByPixels', function () { var rendered = findDOMNode(render(getMarkup({ overscanByPixels: 100 }))); assertVisibleCells(rendered, '0,1,10,11,2,3,4,5,6,7,8,9'); simulateScroll(rendered, 51); assertVisibleCells(rendered, '0,1,10,11,2,3,4,5,6,7,8,9'); simulateScroll(rendered, 101); assertVisibleCells(rendered, '0,1,10,11,2,3,4,5,6,7,8,9'); simulateScroll(rendered, 1001); assertVisibleCells(rendered, '26,27,28,29,30,31,32,33,34,35,36,37'); }); it('should still render correctly when autoHeight is true (eg WindowScroller)', function () { // Share instances between renders to avoid resetting state in ways we don't intend var cellMeasurerCache = createCellMeasurerCache(); var cellPositioner = createCellPositioner(cellMeasurerCache); var rendered = findDOMNode(render(getMarkup({ autoHeight: true, cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner }))); assertVisibleCells(rendered, '0,1,2,3,4,5,6,7,8'); rendered = findDOMNode(render(getMarkup({ autoHeight: true, cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner, scrollTop: 51 }))); assertVisibleCells(rendered, '0,1,2,3,4,5,6,7,8'); rendered = findDOMNode(render(getMarkup({ autoHeight: true, cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner, scrollTop: 101 }))); assertVisibleCells(rendered, '0,2,3,4,5,6,7,8,9'); rendered = findDOMNode(render(getMarkup({ autoHeight: true, cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner, scrollTop: 1001 }))); assertVisibleCells(rendered, '27,29,30,31,32,33,34,35,36'); }); it('should set right instead of left in a cell styles for rtl row direction', function () { // Share instances between renders to avoid resetting state in ways we don't intend var cellMeasurerCache = createCellMeasurerCache(); var cellPositioner = createCellPositioner(cellMeasurerCache); var rendered = findDOMNode(render(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner, rowDirection: 'rtl' }))); Array.from(rendered.querySelectorAll('.cell')).map(function (node) { expect(node.style.right).toMatch(/px/); }); }); it('should consider scroll only of the container element and not of any ancestor element', function () { var cellMeasurerCache = createCellMeasurerCache(); var renderScrollableCell = function renderScrollableCell(index) { return React.createElement("div", { style: { height: '50px', overflow: 'visible' }, id: "scrollable-cell-".concat(index) }, React.createElement("div", { style: { height: '500px' } }, index)); }; var cellRenderer = createCellRenderer(cellMeasurerCache, renderScrollableCell); var rendered = findDOMNode(render(getMarkup({ overscanByPixels: 0, cellMeasurerCache: cellMeasurerCache, cellRenderer: cellRenderer }))); assertVisibleCells(rendered, '0,1,2,3,4,5'); var cellEl = rendered.querySelector('#scrollable-cell-1'); Simulate.scroll(cellEl, { target: { scrollTop: 100 } }); assertVisibleCells(rendered, '0,1,2,3,4,5'); }); }); describe('recomputeCellPositions', function () { it('should refresh all cell positions', function () { // Share instances between renders to avoid resetting state in ways we don't intend var cellMeasurerCache = createCellMeasurerCache(); var cellPositioner = jest.fn().mockImplementation(createCellPositioner(cellMeasurerCache)); var rendered = findDOMNode(render(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner }))); assertVisibleCells(rendered, '0,1,2,3,4,5,6,7,8'); cellPositioner.mockImplementation(function (index) { return { left: 0, top: index * CELL_SIZE_MULTIPLIER }; }); var component = render(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellPositioner: cellPositioner })); rendered = findDOMNode(component); assertVisibleCells(rendered, '0,1,2,3,4,5,6,7,8'); component.recomputeCellPositions(); assertVisibleCells(rendered, '0,1,2,3,4'); }); it('should not reset measurement cache', function () { var cellMeasurerCache = createCellMeasurerCache(); var component = render(getMarkup({ cellMeasurerCache: cellMeasurerCache })); var rendered = findDOMNode(component); simulateScroll(rendered, 101); expect(cellMeasurerCache.has(9)).toBe(true); simulateScroll(rendered, 0); component.recomputeCellPositions(); for (var i = 0; i <= 9; i++) { expect(cellMeasurerCache.has(i)).toBe(true); } }); }); describe('isScrolling', function () { it('should be true for cellRenderer while scrolling is in progress', function () { var cellMeasurerCache = createCellMeasurerCache(); var renderCallback = jest.fn().mockImplementation(function (index) { return index; }); var cellRenderer = createCellRenderer(cellMeasurerCache, renderCallback); var rendered = findDOMNode(render(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellRenderer: cellRenderer }))); renderCallback.mockClear(); simulateScroll(rendered, 51); expect(renderCallback.mock.calls[0][1].isScrolling).toEqual(true); }); it('should be reset after a small debounce when scrolling stops', function () { var cellMeasurerCache = createCellMeasurerCache(); var renderCallback = jest.fn().mockImplementation(function (index) { return index; }); var cellRenderer = createCellRenderer(cellMeasurerCache, renderCallback); var rendered = findDOMNode(render(getMarkup({ cellMeasurerCache: cellMeasurerCache, cellRenderer: cellRenderer }))); simulateScroll(rendered, 51); renderCallback.mockClear(); setTimeout(function () { expect(renderCallback.mock.calls[0][1].isScrolling).toEqual(false); }, 0); }); }); describe('callbacks', function () { it('should call onCellsRendered when rendered cells change', function () { var onCellsRendered = jest.fn(); var rendered = findDOMNode(render(getMarkup({ onCellsRendered: onCellsRendered }))); expect(onCellsRendered.mock.calls).toEqual([[{ startIndex: 0, stopIndex: 8 }]]); simulateScroll(rendered, 51); expect(onCellsRendered.mock.calls).toEqual([[{ startIndex: 0, stopIndex: 8 }]]); simulateScroll(rendered, 101); expect(onCellsRendered.mock.calls).toEqual([[{ startIndex: 0, stopIndex: 8 }], [{ startIndex: 0, stopIndex: 9 }]]); }); it('should call onScroll when scroll position changes', function () { var onScroll = jest.fn(); var rendered = findDOMNode(render(getMarkup({ onScroll: onScroll }))); expect(onScroll.mock.calls).toEqual([[{ clientHeight: 100, scrollHeight: 16900, scrollTop: 0 }]]); simulateScroll(rendered, 51); expect(onScroll.mock.calls).toEqual([[{ clientHeight: 100, scrollHeight: 16900, scrollTop: 0 }], [{ clientHeight: 100, scrollHeight: 16900, scrollTop: 51 }]]); simulateScroll(rendered, 0); expect(onScroll.mock.calls).toEqual([[{ clientHeight: 100, scrollHeight: 16900, scrollTop: 0 }], [{ clientHeight: 100, scrollHeight: 16900, scrollTop: 51 }], [{ clientHeight: 100, scrollHeight: 16900, scrollTop: 0 }]]); }); }); describe('keyMapper', function () { it('should pass the correct key to rendered cells', function () { var keyMapper = jest.fn().mockImplementation(function (index) { return "key:".concat(index); }); var cellRenderer = jest.fn().mockImplementation(function (_ref3) { var index = _ref3.index, key = _ref3.key, style = _ref3.style; return React.createElement("div", { key: key, style: style }, index); }); findDOMNode(render(getMarkup({ cellRenderer: cellRenderer, keyMapper: keyMapper }))); expect(keyMapper).toHaveBeenCalled(); expect(cellRenderer).toHaveBeenCalled(); expect(cellRenderer.mock.calls[0][0].key).toEqual('key:0'); }); }); });dist/es/Masonry/Masonry.example.js000064400000026201151676725770013216 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import Immutable from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import { LabeledInput, InputRow } from '../demo/LabeledInput'; import { CellMeasurer, CellMeasurerCache } from '../CellMeasurer'; import AutoSizer from '../AutoSizer'; import WindowScroller from '../WindowScroller'; import createCellPositioner from './createCellPositioner'; import Masonry from './Masonry'; import styles from './Masonry.example.css'; var GridExample = /*#__PURE__*/ function (_React$PureComponent) { _inherits(GridExample, _React$PureComponent); function GridExample(props, context) { var _this; _classCallCheck(this, GridExample); _this = _possibleConstructorReturn(this, _getPrototypeOf(GridExample).call(this, props, context)); _defineProperty(_assertThisInitialized(_this), "_resetList", function () { var ROW_HEIGHTS = [25, 50, 75, 100]; var list = _this.context.list; list.forEach(function (datum) { datum.size = ROW_HEIGHTS[Math.floor(Math.random() * ROW_HEIGHTS.length)]; }); _this._cache.clearAll(); _this._resetCellPositioner(); _this._masonry.clearCellPositions(); }); _this._columnCount = 0; _this._cache = new CellMeasurerCache({ defaultHeight: 250, defaultWidth: 200, fixedWidth: true }); _this.state = { columnWidth: 200, height: 300, gutterSize: 10, overscanByPixels: 0, windowScrollerEnabled: false }; _this._cellRenderer = _this._cellRenderer.bind(_assertThisInitialized(_this)); _this._onResize = _this._onResize.bind(_assertThisInitialized(_this)); _this._renderAutoSizer = _this._renderAutoSizer.bind(_assertThisInitialized(_this)); _this._renderMasonry = _this._renderMasonry.bind(_assertThisInitialized(_this)); _this._setMasonryRef = _this._setMasonryRef.bind(_assertThisInitialized(_this)); return _this; } _createClass(GridExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, columnWidth = _this$state.columnWidth, height = _this$state.height, gutterSize = _this$state.gutterSize, overscanByPixels = _this$state.overscanByPixels, windowScrollerEnabled = _this$state.windowScrollerEnabled; var child; if (windowScrollerEnabled) { child = React.createElement(WindowScroller, { overscanByPixels: overscanByPixels }, this._renderAutoSizer); } else { child = this._renderAutoSizer({ height: height }); } return React.createElement(ContentBox, null, React.createElement(ContentBoxHeader, { text: "Masonry", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/Masonry/Masonry.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/Masonry.md" }), React.createElement(ContentBoxParagraph, null, "Optimized for masonry layouts. Cells are j.i.t. measured and layed out as a user scrolls. Sizes are cached so that resize/reflow is fast and does not require re-measuring."), React.createElement(ContentBoxParagraph, null, React.createElement("label", { className: styles.checkboxLabel }, React.createElement("input", { "aria-label": "Use WindowScroller?", checked: windowScrollerEnabled, className: styles.checkbox, type: "checkbox", onChange: function onChange(event) { // HACK Because this demo switches between using WindowScroller and not, // It's easier to clear the cache when toggling modes to avoid a partially stale state. _this2._cache.clearAll(); _this2.setState({ windowScrollerEnabled: event.target.checked }); } }), "Use ", React.createElement("code", null, "WindowScroller"), "?"), React.createElement("label", { className: styles.checkboxLabel }, React.createElement("button", { onClick: this._resetList }, "Reset List Data"))), React.createElement(InputRow, null, React.createElement(LabeledInput, { label: "Height", name: "height", onChange: function onChange(event) { _this2.setState({ height: parseInt(event.target.value, 10) || 300 }); }, value: height }), React.createElement(LabeledInput, { label: "Column Width", name: "columnWidth", onChange: function onChange(event) { _this2._cache.clearAll(); _this2.setState({ columnWidth: parseInt(event.target.value, 10) || 200 }, function () { _this2._calculateColumnCount(); _this2._resetCellPositioner(); _this2._masonry.clearCellPositions(); }); }, value: columnWidth }), React.createElement(LabeledInput, { label: "Gutter Size", name: "gutterSize", onChange: function onChange(event) { _this2.setState({ gutterSize: parseInt(event.target.value, 10) || 10 }, function () { _this2._calculateColumnCount(); _this2._resetCellPositioner(); _this2._masonry.recomputeCellPositions(); }); }, value: gutterSize }), React.createElement(LabeledInput, { label: "Overscan (px)", name: "overscanByPixels", onChange: function onChange(event) { _this2.setState({ overscanByPixels: parseInt(event.target.value, 10) || 0 }); }, value: overscanByPixels })), child); } }, { key: "_calculateColumnCount", value: function _calculateColumnCount() { var _this$state2 = this.state, columnWidth = _this$state2.columnWidth, gutterSize = _this$state2.gutterSize; this._columnCount = Math.floor(this._width / (columnWidth + gutterSize)); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref) { var index = _ref.index, key = _ref.key, parent = _ref.parent, style = _ref.style; var list = this.context.list; var columnWidth = this.state.columnWidth; var datum = list.get(index % list.size); return React.createElement(CellMeasurer, { cache: this._cache, index: index, key: key, parent: parent }, React.createElement("div", { className: styles.Cell, style: _objectSpread({}, style, { width: columnWidth }) }, React.createElement("div", { style: { backgroundColor: datum.color, borderRadius: '0.5rem', height: datum.size * 3, marginBottom: '0.5rem', width: '100%', fontSize: 20, color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center' } }, index), datum.random)); } }, { key: "_initCellPositioner", value: function _initCellPositioner() { if (typeof this._cellPositioner === 'undefined') { var _this$state3 = this.state, columnWidth = _this$state3.columnWidth, gutterSize = _this$state3.gutterSize; this._cellPositioner = createCellPositioner({ cellMeasurerCache: this._cache, columnCount: this._columnCount, columnWidth: columnWidth, spacer: gutterSize }); } } }, { key: "_onResize", value: function _onResize(_ref2) { var width = _ref2.width; this._width = width; this._calculateColumnCount(); this._resetCellPositioner(); this._masonry.recomputeCellPositions(); } }, { key: "_renderAutoSizer", value: function _renderAutoSizer(_ref3) { var height = _ref3.height, scrollTop = _ref3.scrollTop; this._height = height; this._scrollTop = scrollTop; var overscanByPixels = this.state.overscanByPixels; return React.createElement(AutoSizer, { disableHeight: true, height: height, onResize: this._onResize, overscanByPixels: overscanByPixels, scrollTop: this._scrollTop }, this._renderMasonry); } }, { key: "_renderMasonry", value: function _renderMasonry(_ref4) { var width = _ref4.width; this._width = width; this._calculateColumnCount(); this._initCellPositioner(); var _this$state4 = this.state, height = _this$state4.height, overscanByPixels = _this$state4.overscanByPixels, windowScrollerEnabled = _this$state4.windowScrollerEnabled; return React.createElement(Masonry, { autoHeight: windowScrollerEnabled, cellCount: 1000, cellMeasurerCache: this._cache, cellPositioner: this._cellPositioner, cellRenderer: this._cellRenderer, height: windowScrollerEnabled ? this._height : height, overscanByPixels: overscanByPixels, ref: this._setMasonryRef, scrollTop: this._scrollTop, width: width }); } // This is a bit of a hack to simulate newly loaded cells }, { key: "_resetCellPositioner", value: function _resetCellPositioner() { var _this$state5 = this.state, columnWidth = _this$state5.columnWidth, gutterSize = _this$state5.gutterSize; this._cellPositioner.reset({ columnCount: this._columnCount, columnWidth: columnWidth, spacer: gutterSize }); } }, { key: "_setMasonryRef", value: function _setMasonryRef(ref) { this._masonry = ref; } }]); return GridExample; }(React.PureComponent); _defineProperty(GridExample, "contextTypes", { list: PropTypes.instanceOf(Immutable.List).isRequired }); export { GridExample as default };dist/es/utils/TestHelper.js000064400000001004151676725770011715 0ustar00import initCellMetadata from './initCellMetadata'; // Default cell sizes and offsets for use in below tests export function getCellMetadata() { var cellSizes = [10, // 0: 0..0 (min) 20, // 1: 0..10 15, // 2: 0..30 10, // 3: 5..45 15, // 4: 20..55 30, // 5: 50..70 20, // 6: 70..100 10, // 7: 80..110 30 // 8: 110..110 (max) ]; return initCellMetadata({ cellCount: cellSizes.length, size: function size(_ref) { var index = _ref.index; return cellSizes[index]; } }); }dist/es/utils/createCallbackMemoizer.jest.js000064400000013535151676725770015206 0ustar00import createCallbackMemoizer from './createCallbackMemoizer'; describe('createCallbackMemoizer', function () { function OnRowsRendered() { var _numCalls = 0; var _overscanStartIndex; var _overscanStopIndex; var _startIndex; var _stopIndex; return { numCalls: function numCalls() { return _numCalls; }, overscanStartIndex: function overscanStartIndex() { return _overscanStartIndex; }, overscanStopIndex: function overscanStopIndex() { return _overscanStopIndex; }, startIndex: function startIndex() { return _startIndex; }, stopIndex: function stopIndex() { return _stopIndex; }, update: function update(params) { _overscanStartIndex = params.overscanStartIndex; _overscanStopIndex = params.overscanStopIndex; _startIndex = params.startIndex; _stopIndex = params.stopIndex; _numCalls++; } }; } it('should not call onRowsRendered if startIndex or stopIndex are invalid', function () { var util = new OnRowsRendered(); var helper = createCallbackMemoizer(); helper({ callback: util.update, indices: { startIndex: 0, stopIndex: undefined } }); expect(util.numCalls()).toEqual(0); helper({ callback: util.update, indices: { startIndex: undefined, stopIndex: 0 } }); expect(util.numCalls()).toEqual(0); }); it('should call onRowsRendered if startIndex and stopIndex are valid', function () { var util = new OnRowsRendered(); var helper = createCallbackMemoizer(); helper({ callback: util.update, indices: { startIndex: 0, stopIndex: 1 } }); expect(util.numCalls()).toEqual(1); expect(util.startIndex()).toEqual(0); expect(util.stopIndex()).toEqual(1); }); it('should call onRowsRendered if startIndex and stopIndex are invalid but :requireAllKeys is false', function () { var util = new OnRowsRendered(); var helper = createCallbackMemoizer(false); helper({ callback: util.update, indices: { startIndex: undefined, stopIndex: 1 } }); expect(util.numCalls()).toEqual(1); expect(util.startIndex()).toEqual(undefined); expect(util.stopIndex()).toEqual(1); }); it('should not call onRowsRendered if startIndex or stopIndex have not changed', function () { var util = new OnRowsRendered(); var helper = createCallbackMemoizer(); helper({ callback: util.update, indices: { startIndex: 0, stopIndex: 1 } }); expect(util.numCalls()).toEqual(1); expect(util.startIndex()).toEqual(0); expect(util.stopIndex()).toEqual(1); helper({ callback: util.update, indices: { startIndex: 0, stopIndex: 1 } }); expect(util.numCalls()).toEqual(1); }); it('should not call onRowsRendered if startIndex or stopIndex have changed', function () { var util = new OnRowsRendered(); var helper = createCallbackMemoizer(); helper({ callback: util.update, indices: { startIndex: 0, stopIndex: 1 } }); expect(util.numCalls()).toEqual(1); expect(util.startIndex()).toEqual(0); expect(util.stopIndex()).toEqual(1); helper({ callback: util.update, indices: { startIndex: 1, stopIndex: 1 } }); expect(util.numCalls()).toEqual(2); expect(util.startIndex()).toEqual(1); expect(util.stopIndex()).toEqual(1); helper({ callback: util.update, indices: { startIndex: 1, stopIndex: 2 } }); expect(util.numCalls()).toEqual(3); expect(util.startIndex()).toEqual(1); expect(util.stopIndex()).toEqual(2); }); it('should call onRowsRendered if :overscanCellsCount changes', function () { var util = new OnRowsRendered(); var helper = createCallbackMemoizer(); helper({ callback: util.update, indices: { overscanStartIndex: 0, overscanStopIndex: 2, startIndex: 0, stopIndex: 1 } }); expect(util.numCalls()).toEqual(1); expect(util.startIndex()).toEqual(0); expect(util.stopIndex()).toEqual(1); expect(util.overscanStartIndex()).toEqual(0); expect(util.overscanStopIndex()).toEqual(2); helper({ callback: util.update, indices: { overscanStartIndex: 0, overscanStopIndex: 3, startIndex: 0, stopIndex: 1 } }); expect(util.numCalls()).toEqual(2); expect(util.startIndex()).toEqual(0); expect(util.stopIndex()).toEqual(1); expect(util.overscanStartIndex()).toEqual(0); expect(util.overscanStopIndex()).toEqual(3); }); it('should support an array of indices', function () { var numCalls = 0; var indices; var callback = function callback(params) { indices = params; numCalls++; }; var helper = createCallbackMemoizer(); helper({ callback: callback, indices: [0, 1, 2] }); expect(numCalls).toEqual(1); expect(indices).toEqual([0, 1, 2]); helper({ callback: callback, indices: [0, 1] }); expect(numCalls).toEqual(2); expect(indices).toEqual([0, 1]); }); it('should support an attribute containing an array of indices', function () { var numCalls = 0; var indices; var callback = function callback(params) { indices = params.indices; numCalls++; }; var helper = createCallbackMemoizer(); helper({ callback: callback, indices: { indices: [0, 1, 2] } }); expect(numCalls).toEqual(1); expect(indices).toEqual([0, 1, 2]); helper({ callback: callback, indices: { indices: [0, 1] } }); expect(numCalls).toEqual(2); expect(indices).toEqual([0, 1]); }); });dist/es/utils/requestAnimationTimeout.js000064400000002137151676725770014545 0ustar00import { caf, raf } from './animationFrame'; var bpfrpt_proptype_AnimationTimeoutId = process.env.NODE_ENV === 'production' ? null : { "id": PropTypes.number.isRequired }; export var cancelAnimationTimeout = function cancelAnimationTimeout(frame) { return caf(frame.id); }; /** * Recursively calls requestAnimationFrame until a specified delay has been met or exceeded. * When the delay time has been reached the function you're timing out will be called. * * Credit: Joe Lambert (https://gist.github.com/joelambert/1002116#file-requesttimeout-js) */ export var requestAnimationTimeout = function requestAnimationTimeout(callback, delay) { var start; // wait for end of processing current event handler, because event handler may be long Promise.resolve().then(function () { start = Date.now(); }); var timeout = function timeout() { if (Date.now() - start >= delay) { callback.call(); } else { frame.id = raf(timeout); } }; var frame = { id: raf(timeout) }; return frame; }; import PropTypes from "prop-types"; export { bpfrpt_proptype_AnimationTimeoutId };dist/es/utils/createCallbackMemoizer.js000064400000001744151676725770014241 0ustar00/** * Helper utility that updates the specified callback whenever any of the specified indices have changed. */ export default function createCallbackMemoizer() { var requireAllKeys = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; var cachedIndices = {}; return function (_ref) { var callback = _ref.callback, indices = _ref.indices; var keys = Object.keys(indices); var allInitialized = !requireAllKeys || keys.every(function (key) { var value = indices[key]; return Array.isArray(value) ? value.length > 0 : value >= 0; }); var indexChanged = keys.length !== Object.keys(cachedIndices).length || keys.some(function (key) { var cachedValue = cachedIndices[key]; var value = indices[key]; return Array.isArray(value) ? cachedValue.join(',') !== value.join(',') : cachedValue !== value; }); cachedIndices = indices; if (allInitialized && indexChanged) { callback(indices); } }; }dist/es/utils/initCellMetadata.js000064400000001713151676725770013051 0ustar00/** * Initializes metadata for an axis and its cells. * This data is used to determine which cells are visible given a container size and scroll position. * * @param cellCount Total number of cells. * @param size Either a fixed size or a function that returns the size for a given given an index. * @return Object mapping cell index to cell metadata (size, offset) */ export default function initCellMetadata(_ref) { var cellCount = _ref.cellCount, size = _ref.size; var sizeGetter = typeof size === 'function' ? size : function () { return size; }; var cellMetadata = []; var offset = 0; for (var i = 0; i < cellCount; i++) { var _size = sizeGetter({ index: i }); if (_size == null || isNaN(_size)) { throw Error("Invalid size returned for cell ".concat(i, " of value ").concat(_size)); } cellMetadata[i] = { size: _size, offset: offset }; offset += _size; } return cellMetadata; }dist/es/utils/animationFrame.js000064400000001446151676725770012602 0ustar00// Properly handle server-side rendering. var win; if (typeof window !== 'undefined') { win = window; } else if (typeof self !== 'undefined') { win = self; } else { win = {}; } // requestAnimationFrame() shim by Paul Irish // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ var request = win.requestAnimationFrame || win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame || win.oRequestAnimationFrame || win.msRequestAnimationFrame || function (callback) { return win.setTimeout(callback, 1000 / 60); }; var cancel = win.cancelAnimationFrame || win.webkitCancelAnimationFrame || win.mozCancelAnimationFrame || win.oCancelAnimationFrame || win.msCancelAnimationFrame || function (id) { win.clearTimeout(id); }; export var raf = request; export var caf = cancel;dist/es/utils/getUpdatedOffsetForIndex.jest.js000064400000003715151676725770015511 0ustar00import getUpdatedOffsetForIndex from './getUpdatedOffsetForIndex'; import { getCellMetadata } from './TestHelper'; describe('getUpdatedOffsetForIndex', function () { function testHelper(targetIndex, currentOffset) { var cellMetadata = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getCellMetadata(); return getUpdatedOffsetForIndex({ cellOffset: cellMetadata[targetIndex].offset, cellSize: cellMetadata[targetIndex].size, containerSize: 50, currentOffset: currentOffset }); } it('should scroll to the beginning', function () { expect(testHelper(0, 100)).toEqual(0); }); it('should scroll forward to the middle', function () { expect(testHelper(4, 0)).toEqual(20); }); it('should scroll backward to the middle', function () { expect(testHelper(2, 100)).toEqual(30); }); it('should not scroll if an item is already visible', function () { expect(testHelper(2, 20)).toEqual(20); }); it('should scroll to the end', function () { expect(testHelper(8, 0)).toEqual(110); }); it('should honor specified :align values', function () { expect(getUpdatedOffsetForIndex({ align: 'auto', cellOffset: 50, cellSize: 10, containerSize: 50, currentOffset: 0 })).toEqual(10); expect(getUpdatedOffsetForIndex({ align: 'start', cellOffset: 50, cellSize: 10, containerSize: 50, currentOffset: 0 })).toEqual(50); expect(getUpdatedOffsetForIndex({ align: 'auto', cellOffset: 50, cellSize: 10, containerSize: 50, currentOffset: 100 })).toEqual(50); expect(getUpdatedOffsetForIndex({ align: 'end', cellOffset: 50, cellSize: 10, containerSize: 50, currentOffset: 100 })).toEqual(10); expect(getUpdatedOffsetForIndex({ align: 'center', cellOffset: 50, cellSize: 10, containerSize: 50, currentOffset: 100 })).toEqual(30); }); });dist/es/utils/getUpdatedOffsetForIndex.js000064400000002507151676725770014543 0ustar00/** * Determines a new offset that ensures a certain cell is visible, given the current offset. * If the cell is already visible then the current offset will be returned. * If the current offset is too great or small, it will be adjusted just enough to ensure the specified index is visible. * * @param align Desired alignment within container; one of "auto" (default), "start", or "end" * @param cellOffset Offset (x or y) position for cell * @param cellSize Size (width or height) of cell * @param containerSize Total size (width or height) of the container * @param currentOffset Container's current (x or y) offset * @return Offset to use to ensure the specified cell is visible */ export default function getUpdatedOffsetForIndex(_ref) { var _ref$align = _ref.align, align = _ref$align === void 0 ? 'auto' : _ref$align, cellOffset = _ref.cellOffset, cellSize = _ref.cellSize, containerSize = _ref.containerSize, currentOffset = _ref.currentOffset; var maxOffset = cellOffset; var minOffset = maxOffset - containerSize + cellSize; switch (align) { case 'start': return maxOffset; case 'end': return minOffset; case 'center': return maxOffset - (containerSize - cellSize) / 2; default: return Math.max(minOffset, Math.min(maxOffset, currentOffset)); } }dist/es/index.js000064400000002032151676725770007607 0ustar00export { ArrowKeyStepper } from './ArrowKeyStepper'; export { AutoSizer } from './AutoSizer'; export { CellMeasurer, CellMeasurerCache } from './CellMeasurer'; export { Collection } from './Collection'; export { ColumnSizer } from './ColumnSizer'; export { accessibilityOverscanIndicesGetter, defaultCellRangeRenderer, defaultOverscanIndicesGetter, Grid } from './Grid'; export { InfiniteLoader } from './InfiniteLoader'; export { List } from './List'; export { createCellPositioner as createMasonryCellPositioner, Masonry } from './Masonry'; export { MultiGrid } from './MultiGrid'; export { ScrollSync } from './ScrollSync'; export { createMultiSort as createTableMultiSort, defaultCellDataGetter as defaultTableCellDataGetter, defaultCellRenderer as defaultTableCellRenderer, defaultHeaderRenderer as defaultTableHeaderRenderer, defaultHeaderRowRenderer as defaultTableHeaderRowRenderer, defaultRowRenderer as defaultTableRowRenderer, Table, Column, SortDirection, SortIndicator } from './Table'; export { WindowScroller } from './WindowScroller';dist/es/Table/createMultiSort.jest.js000064400000015020151676725770013622 0ustar00import createMultiSort from './createMultiSort'; describe('createMultiSort', function () { function simulate(sort, dataKey) { var eventModifier = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; var defaultSortDirection = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'ASC'; sort({ defaultSortDirection: defaultSortDirection, event: { ctrlKey: eventModifier === 'control', metaKey: eventModifier === 'meta', shiftKey: eventModifier === 'shift' }, sortBy: dataKey }); } it('errors if the user did not specify a sort callback', function () { expect(createMultiSort).toThrow(); }); it('sets the correct default values', function () { var multiSort = createMultiSort(jest.fn(), { defaultSortBy: ['a', 'b'], defaultSortDirection: { a: 'ASC', b: 'DESC' } }); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('DESC'); }); it('sets the correct default sparse values', function () { var multiSort = createMultiSort(jest.fn(), { defaultSortBy: ['a', 'b'] }); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('ASC'); }); describe('on click', function () { it('sets the correct default value for a field', function () { var multiSort = createMultiSort(jest.fn()); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toBe('ASC'); simulate(multiSort.sort, 'b', '', 'DESC'); expect(multiSort.sortBy).toEqual(['b']); expect(multiSort.sortDirection.b).toBe('DESC'); }); it('toggles a field value', function () { var multiSort = createMultiSort(jest.fn()); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toBe('ASC'); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toBe('DESC'); simulate(multiSort.sort, 'b', '', 'DESC'); expect(multiSort.sortBy).toEqual(['b']); expect(multiSort.sortDirection.b).toBe('DESC'); simulate(multiSort.sort, 'b', '', 'DESC'); expect(multiSort.sortBy).toEqual(['b']); expect(multiSort.sortDirection.b).toBe('ASC'); }); it('resets sort-by fields', function () { var multiSort = createMultiSort(jest.fn(), { defaultSortBy: ['a', 'b'] }); expect(multiSort.sortBy).toEqual(['a', 'b']); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); }); it('resets sort-direction fields', function () { var multiSort = createMultiSort(jest.fn(), { defaultSortBy: ['a', 'b'], defaultSortDirection: { a: 'DESC', b: 'ASC' } }); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toEqual('DESC'); expect(multiSort.sortDirection.b).toEqual('ASC'); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toEqual('ASC'); expect(multiSort.sortDirection.b).toEqual(undefined); simulate(multiSort.sort, 'b'); expect(multiSort.sortBy).toEqual(['b']); expect(multiSort.sortDirection.a).toEqual(undefined); expect(multiSort.sortDirection.b).toEqual('ASC'); }); }); describe('on shift click', function () { it('appends a field to the sort by list', function () { var multiSort = createMultiSort(jest.fn()); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toBe('ASC'); simulate(multiSort.sort, 'b', 'shift'); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('ASC'); }); it('toggles an appended field value', function () { var multiSort = createMultiSort(jest.fn()); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toBe('ASC'); simulate(multiSort.sort, 'b', 'shift'); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('ASC'); simulate(multiSort.sort, 'a', 'shift'); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('DESC'); expect(multiSort.sortDirection.b).toBe('ASC'); simulate(multiSort.sort, 'a', 'shift'); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('ASC'); }); it('able to shift+click more than once', function () { var multiSort = createMultiSort(jest.fn()); simulate(multiSort.sort, 'a'); expect(multiSort.sortBy).toEqual(['a']); expect(multiSort.sortDirection.a).toBe('ASC'); simulate(multiSort.sort, 'b', 'shift'); expect(multiSort.sortBy).toEqual(['a', 'b']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('ASC'); simulate(multiSort.sort, 'b'); expect(multiSort.sortBy).toEqual(['b']); expect(multiSort.sortDirection.b).toBe('DESC'); simulate(multiSort.sort, 'a', 'shift'); expect(multiSort.sortBy).toEqual(['b', 'a']); expect(multiSort.sortDirection.a).toBe('ASC'); expect(multiSort.sortDirection.b).toBe('DESC'); }); }); ['control', 'meta'].forEach(function (modifier) { describe("".concat(modifier, " click"), function () { it('removes a field from the sort by list', function () { var multiSort = createMultiSort(jest.fn(), { defaultSortBy: ['a', 'b'] }); expect(multiSort.sortBy).toEqual(['a', 'b']); simulate(multiSort.sort, 'a', modifier); expect(multiSort.sortBy).toEqual(['b']); simulate(multiSort.sort, 'b', modifier); expect(multiSort.sortBy).toEqual([]); }); it('ignores fields not in the list on control click', function () { var multiSort = createMultiSort(jest.fn(), { defaultSortBy: ['a', 'b'] }); expect(multiSort.sortBy).toEqual(['a', 'b']); simulate(multiSort.sort, 'c', modifier); expect(multiSort.sortBy).toEqual(['a', 'b']); }); }); }); });dist/es/Table/createMultiSort.js000064400000004336151676725770012666 0ustar00export default function createMultiSort(sortCallback) { var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, defaultSortBy = _ref.defaultSortBy, _ref$defaultSortDirec = _ref.defaultSortDirection, defaultSortDirection = _ref$defaultSortDirec === void 0 ? {} : _ref$defaultSortDirec; if (!sortCallback) { throw Error("Required parameter \"sortCallback\" not specified"); } var sortBy = defaultSortBy || []; var sortDirection = {}; sortBy.forEach(function (dataKey) { sortDirection[dataKey] = defaultSortDirection[dataKey] !== undefined ? defaultSortDirection[dataKey] : 'ASC'; }); function sort(_ref2) { var defaultSortDirection = _ref2.defaultSortDirection, event = _ref2.event, dataKey = _ref2.sortBy; if (event.shiftKey) { // Shift + click appends a column to existing criteria if (sortDirection[dataKey] !== undefined) { sortDirection[dataKey] = sortDirection[dataKey] === 'ASC' ? 'DESC' : 'ASC'; } else { sortDirection[dataKey] = defaultSortDirection; sortBy.push(dataKey); } } else if (event.ctrlKey || event.metaKey) { // Control + click removes column from sort (if pressent) var index = sortBy.indexOf(dataKey); if (index >= 0) { sortBy.splice(index, 1); delete sortDirection[dataKey]; } } else { // Clear sortBy array of all non-selected keys sortBy.length = 0; sortBy.push(dataKey); // Clear sortDirection object of all non-selected keys var sortDirectionKeys = Object.keys(sortDirection); sortDirectionKeys.forEach(function (key) { if (key !== dataKey) delete sortDirection[key]; }); // If key is already selected, reverse sort direction. // Else, set sort direction to default direction. if (sortDirection[dataKey] !== undefined) { sortDirection[dataKey] = sortDirection[dataKey] === 'ASC' ? 'DESC' : 'ASC'; } else { sortDirection[dataKey] = defaultSortDirection; } } // Notify application code sortCallback({ sortBy: sortBy, sortDirection: sortDirection }); } return { sort: sort, sortBy: sortBy, sortDirection: sortDirection }; }dist/es/Table/Column.js000064400000006765151676725770011005 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import PropTypes from 'prop-types'; import * as React from 'react'; import defaultHeaderRenderer from './defaultHeaderRenderer'; import defaultCellRenderer from './defaultCellRenderer'; import defaultCellDataGetter from './defaultCellDataGetter'; import SortDirection from './SortDirection'; /** * Describes the header and cell contents of a table column. */ var Column = /*#__PURE__*/ function (_React$Component) { _inherits(Column, _React$Component); function Column() { _classCallCheck(this, Column); return _possibleConstructorReturn(this, _getPrototypeOf(Column).apply(this, arguments)); } return Column; }(React.Component); _defineProperty(Column, "defaultProps", { cellDataGetter: defaultCellDataGetter, cellRenderer: defaultCellRenderer, defaultSortDirection: SortDirection.ASC, flexGrow: 0, flexShrink: 1, headerRenderer: defaultHeaderRenderer, style: {} }); export { Column as default }; Column.propTypes = process.env.NODE_ENV !== "production" ? { /** Optional aria-label value to set on the column header */ 'aria-label': PropTypes.string, /** * Callback responsible for returning a cell's data, given its :dataKey * ({ columnData: any, dataKey: string, rowData: any }): any */ cellDataGetter: PropTypes.func, /** * Callback responsible for rendering a cell's contents. * ({ cellData: any, columnData: any, dataKey: string, rowData: any, rowIndex: number }): node */ cellRenderer: PropTypes.func, /** Optional CSS class to apply to cell */ className: PropTypes.string, /** Optional additional data passed to this column's :cellDataGetter */ columnData: PropTypes.object, /** Uniquely identifies the row-data attribute corresponding to this cell */ dataKey: PropTypes.any.isRequired, /** Optional direction to be used when clicked the first time */ defaultSortDirection: PropTypes.oneOf([SortDirection.ASC, SortDirection.DESC]), /** If sort is enabled for the table at large, disable it for this column */ disableSort: PropTypes.bool, /** Flex grow style; defaults to 0 */ flexGrow: PropTypes.number, /** Flex shrink style; defaults to 1 */ flexShrink: PropTypes.number, /** Optional CSS class to apply to this column's header */ headerClassName: PropTypes.string, /** * Optional callback responsible for rendering a column header contents. * ({ columnData: object, dataKey: string, disableSort: boolean, label: node, sortBy: string, sortDirection: string }): PropTypes.node */ headerRenderer: PropTypes.func.isRequired, /** Optional inline style to apply to this column's header */ headerStyle: PropTypes.object, /** Optional id to set on the column header */ id: PropTypes.string, /** Header label for this column */ label: PropTypes.node, /** Maximum width of column; this property will only be used if :flexGrow is > 0. */ maxWidth: PropTypes.number, /** Minimum width of column. */ minWidth: PropTypes.number, /** Optional inline style to apply to cell */ style: PropTypes.object, /** Flex basis (width) for this column; This value can grow or shrink based on :flexGrow and :flexShrink properties. */ width: PropTypes.number.isRequired } : {};dist/es/Table/Table.jest.js000064400000145270151676725770011536 0ustar00import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _inherits from "@babel/runtime/helpers/inherits"; import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import * as React from 'react'; import { findDOMNode } from 'react-dom'; import { render } from '../TestUtils'; import { Simulate } from 'react-dom/test-utils'; import Immutable from 'immutable'; import Column from './Column'; import Table from './Table'; import SortDirection from './SortDirection'; describe('Table', function () { var array = []; for (var i = 0; i < 100; i++) { array.push({ id: i, name: "Name ".concat(i), email: "user-".concat(i, "@treasure-data.com") }); } var list = Immutable.fromJS(array); // Works with an Immutable List of Maps function immutableRowGetter(_ref) { var index = _ref.index; return list.get(index); } // Works with an Array of Objects function vanillaRowGetter(_ref2) { var index = _ref2.index; return array[index]; } // Override default behavior of overscanning by at least 1 (for accessibility) // Because it makes for simple tests below function overscanIndicesGetter(_ref3) { var startIndex = _ref3.startIndex, stopIndex = _ref3.stopIndex; return { overscanStartIndex: startIndex, overscanStopIndex: stopIndex }; } function getMarkup() { var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, cellDataGetter = _ref4.cellDataGetter, cellRenderer = _ref4.cellRenderer, _ref4$columnData = _ref4.columnData, columnData = _ref4$columnData === void 0 ? { data: 123 } : _ref4$columnData, columnID = _ref4.columnID, columnStyle = _ref4.columnStyle, columnHeaderStyle = _ref4.columnHeaderStyle, _ref4$disableSort = _ref4.disableSort, disableSort = _ref4$disableSort === void 0 ? false : _ref4$disableSort, headerRenderer = _ref4.headerRenderer, maxWidth = _ref4.maxWidth, minWidth = _ref4.minWidth, defaultSortDirection = _ref4.defaultSortDirection, label = _ref4.label, flexTableProps = _objectWithoutProperties(_ref4, ["cellDataGetter", "cellRenderer", "columnData", "columnID", "columnStyle", "columnHeaderStyle", "disableSort", "headerRenderer", "maxWidth", "minWidth", "defaultSortDirection", "label"]); return React.createElement(Table, _extends({ headerHeight: 20, height: 100, overscanRowCount: 0, overscanIndicesGetter: overscanIndicesGetter, rowCount: list.size, rowGetter: immutableRowGetter, rowHeight: 10, width: 100 }, flexTableProps), React.createElement(Column, { label: label || 'Name', dataKey: "name", columnData: columnData, width: 50, cellRenderer: cellRenderer, cellDataGetter: cellDataGetter, headerRenderer: headerRenderer, disableSort: disableSort, defaultSortDirection: defaultSortDirection, style: columnStyle, headerStyle: columnHeaderStyle, id: columnID }), React.createElement(Column, { label: "Email", dataKey: "email", maxWidth: maxWidth, minWidth: minWidth, width: 50 }), false, true, null, undefined); } beforeEach(function () { return jest.resetModules(); }); describe('children', function () { it('should accept Column children', function () { var children = [React.createElement(Column, { dataKey: "foo", width: 100 })]; var result = Table.propTypes.children({ children: children }, 'children', 'Table'); expect(result instanceof Error).toEqual(false); }); it('should accept subclasses of Column as children', function () { var AnotherColumn = /*#__PURE__*/ function (_Column) { _inherits(AnotherColumn, _Column); function AnotherColumn() { _classCallCheck(this, AnotherColumn); return _possibleConstructorReturn(this, _getPrototypeOf(AnotherColumn).apply(this, arguments)); } return AnotherColumn; }(Column); var children = [React.createElement(AnotherColumn, { dataKey: "foo", width: 100 })]; var result = Table.propTypes.children({ children: children }, 'children', 'Table'); expect(result instanceof Error).toEqual(false); }); it('should not accept non-Column children', function () { var children = [React.createElement("div", null)]; var result = Table.propTypes.children({ children: children }, 'children', 'Table'); expect(result instanceof Error).toEqual(true); }); it('should accept falsy children to allow easier dynamic showing/hiding of columns', function () { var children = [false, React.createElement(Column, { dataKey: "foo", width: 100 }), null]; var result = Table.propTypes.children({ children: children }, 'children', 'Table'); expect(result instanceof Error).toEqual(false); }); }); describe('height', function () { it('should subtract header row height from the inner Grid height if headers are enabled', function () { var rendered = findDOMNode(render(getMarkup({ headerHeight: 10, overscanRowCount: 0, rowHeight: 20, height: 50 }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); expect(rows.length).toEqual(2); }); it('should not subtract header row height from the inner Grid height if headers are disabled', function () { var rendered = findDOMNode(render(getMarkup({ disableHeader: true, headerHeight: 10, overscanRowCount: 0, rowHeight: 20, height: 50 }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); expect(rows.length).toEqual(3); }); }); describe('initial rendering', function () { // Ensure that both Immutable Lists of Maps and Arrays of Objects are supported var useImmutable = [true, false]; useImmutable.forEach(function (useImmutable) { it('should render the correct number of rows', function () { var rendered = findDOMNode(render(getMarkup({ rowGetter: useImmutable ? immutableRowGetter : vanillaRowGetter }))); // 100px height should fit 1 header (20px) and 8 rows (10px each) - expect(rendered.querySelectorAll('.ReactVirtualized__Table__headerRow').length).toEqual(1); expect(rendered.querySelectorAll('.ReactVirtualized__Table__row').length).toEqual(8); }); it('should render the expected headers', function () { var rendered = findDOMNode(render(getMarkup({ rowGetter: useImmutable ? immutableRowGetter : vanillaRowGetter }))); var columns = rendered.querySelectorAll('.ReactVirtualized__Table__headerColumn'); expect(columns.length).toEqual(2); expect(columns[0].textContent).toEqual('Name'); expect(columns[1].textContent).toEqual('Email'); }); it('should render the expected rows and columns', function () { var rendered = findDOMNode(render(getMarkup({ rowGetter: useImmutable ? immutableRowGetter : vanillaRowGetter, headerHeight: 10, rowHeight: 20, height: 50 }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); expect(rows.length).toEqual(2); Array.from(rows).forEach(function (row, index) { var rowData = list.get(index); var columns = row.querySelectorAll('.ReactVirtualized__Table__rowColumn'); expect(columns.length).toEqual(2); expect(columns[0].textContent).toEqual(rowData.get('name')); expect(columns[1].textContent).toEqual(rowData.get('email')); }); }); }); it('should support a :rowHeight function', function () { var rowHeight = function rowHeight(_ref5) { var index = _ref5.index; return 10 + index * 10; }; var rendered = findDOMNode(render(getMarkup({ rowHeight: rowHeight, rowCount: 3 }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); Array.from(rows).forEach(function (row, index) { expect(Number.parseInt(row.style.height, 10)).toEqual(rowHeight({ index: index })); }); }); it('should support :minWidth and :maxWidth values for a column', function () { var rendered = findDOMNode(render(getMarkup({ maxWidth: 75, minWidth: 25, rowCount: 1 }))); var columns = rendered.querySelectorAll('.ReactVirtualized__Table__rowColumn'); var emailColumn = columns[1]; expect(Number.parseInt(emailColumn.style.maxWidth, 10)).toEqual(75); expect(Number.parseInt(emailColumn.style.minWidth, 10)).toEqual(25); }); }); describe('measureAllRows', function () { it('should measure any unmeasured rows', function () { var rendered = render(getMarkup({ estimatedRowSize: 15, height: 0, rowCount: 10, rowHeight: function rowHeight() { return 20; }, width: 0 })); expect(rendered.Grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(150); rendered.measureAllRows(); expect(rendered.Grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(200); }); }); describe('recomputeRowHeights', function () { it('should recompute row heights and other values when called', function () { var indices = []; var rowHeight = function rowHeight(_ref6) { var index = _ref6.index; indices.push(index); return 10; }; var component = render(getMarkup({ rowHeight: rowHeight, rowCount: 50 })); indices.splice(0); component.recomputeRowHeights(); // Only the rows required to fill the current viewport will be rendered expect(indices[0]).toEqual(0); expect(indices[indices.length - 1]).toEqual(7); indices.splice(0); component.recomputeRowHeights(4); expect(indices[0]).toEqual(4); expect(indices[indices.length - 1]).toEqual(7); }); }); describe('forceUpdateGrid', function () { it('should refresh inner Grid content when called', function () { var marker = 'a'; function cellRenderer(_ref7) { var rowIndex = _ref7.rowIndex; return "".concat(rowIndex).concat(marker); } var component = render(getMarkup({ cellRenderer: cellRenderer })); var node = findDOMNode(component); expect(node.textContent).toContain('1a'); marker = 'b'; component.forceUpdateGrid(); expect(node.textContent).toContain('1b'); }); }); describe('custom getter functions', function () { it('should use a custom cellDataGetter if specified', function () { var rendered = findDOMNode(render(getMarkup({ cellDataGetter: function cellDataGetter(_ref8) { var dataKey = _ref8.dataKey, rowData = _ref8.rowData; return "Custom ".concat(dataKey, " for row ").concat(rowData.get('id')); } }))); var nameColumns = rendered.querySelectorAll('.ReactVirtualized__Table__rowColumn:first-of-type'); Array.from(nameColumns).forEach(function (nameColumn, index) { expect(nameColumn.textContent).toEqual("Custom name for row ".concat(index)); }); }); it('should use a custom cellRenderer if specified', function () { var rendered = findDOMNode(render(getMarkup({ cellRenderer: function cellRenderer(_ref9) { var cellData = _ref9.cellData; return "Custom ".concat(cellData); } }))); var nameColumns = rendered.querySelectorAll('.ReactVirtualized__Table__rowColumn:first-of-type'); Array.from(nameColumns).forEach(function (nameColumn, index) { var rowData = list.get(index); expect(nameColumn.textContent).toEqual("Custom ".concat(rowData.get('name'))); }); }); it('should set the rendered cell content as the cell :title if it is a string', function () { var rendered = findDOMNode(render(getMarkup({ cellRenderer: function cellRenderer() { return 'Custom'; } }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__rowColumn:first-of-type'); expect(nameColumn.getAttribute('title')).toContain('Custom'); }); it('should not set a cell :title if the rendered cell content is not a string', function () { var rendered = findDOMNode(render(getMarkup({ cellRenderer: function cellRenderer() { return React.createElement("div", null, "Custom"); } }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__rowColumn:first-of-type'); expect(nameColumn.getAttribute('title')).toEqual(null); }); it('should set the rendered header label as header :title if it is a string', function () { var rendered = findDOMNode(render(getMarkup({ label: 'Custom' }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerTruncatedText:first-of-type'); expect(nameColumn.getAttribute('title')).toContain('Custom'); }); it('should not set a header :title if the rendered header label is not a string', function () { var rendered = findDOMNode(render(getMarkup({ label: React.createElement("div", null, "Custom") }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerTruncatedText:first-of-type'); expect(nameColumn.getAttribute('title')).toEqual(null); }); }); describe('sorting', function () { it('should not render sort indicators if no sort function is provided', function () { var rendered = findDOMNode(render(getMarkup())); var nameColumn = rendered.querySelectorAll('.ReactVirtualized__Table__headerColumn:first-of-type'); expect(nameColumn.className || '').not.toContain('ReactVirtualized__Table__sortableHeaderColumn'); }); it('should not render sort indicators for non-sortable columns', function () { var rendered = findDOMNode(render(getMarkup({ disableSort: true, sort: function sort() {} }))); var nameColumn = rendered.querySelectorAll('.ReactVirtualized__Table__headerColumn:first-of-type'); expect(nameColumn.className || '').not.toContain('ReactVirtualized__Table__sortableHeaderColumn'); expect(rendered.querySelectorAll('.ReactVirtualized__Table__sortableHeaderColumn').length).toEqual(1); // Email only }); it('should render sortable column headers as sortable', function () { var rendered = findDOMNode(render(getMarkup({ sort: function sort() {} }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); expect(nameColumn.className).toContain('ReactVirtualized__Table__sortableHeaderColumn'); expect(rendered.querySelectorAll('.ReactVirtualized__Table__sortableHeaderColumn').length).toEqual(2); // Email and Name }); it('should render the correct sort indicator by the current sort-by column', function () { var sortDirections = [SortDirection.ASC, SortDirection.DESC]; sortDirections.forEach(function (sortDirection) { var rendered = findDOMNode(render(getMarkup({ sort: function sort() {}, sortBy: 'name', sortDirection: sortDirection }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); expect(nameColumn.querySelector('.ReactVirtualized__Table__sortableHeaderIcon')).not.toEqual(null); expect(nameColumn.querySelector(".ReactVirtualized__Table__sortableHeaderIcon--".concat(sortDirection))).not.toEqual(null); }); }); it('should call sort with the correct arguments when the current sort-by column header is clicked', function () { var sortDirections = [SortDirection.ASC, SortDirection.DESC]; sortDirections.forEach(function (sortDirection) { var sortCalls = []; var rendered = findDOMNode(render(getMarkup({ sort: function sort(_ref10) { var sortBy = _ref10.sortBy, sortDirection = _ref10.sortDirection; return sortCalls.push({ sortBy: sortBy, sortDirection: sortDirection }); }, sortBy: 'name', sortDirection: sortDirection }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); Simulate.click(nameColumn); expect(sortCalls.length).toEqual(1); var _sortCalls$ = sortCalls[0], sortBy = _sortCalls$.sortBy, newSortDirection = _sortCalls$.sortDirection; var expectedSortDirection = sortDirection === SortDirection.ASC ? SortDirection.DESC : SortDirection.ASC; expect(sortBy).toEqual('name'); expect(newSortDirection).toEqual(expectedSortDirection); }); }); it('should call sort with the correct arguments when a new sort-by column header is clicked', function () { var sortCalls = []; var rendered = findDOMNode(render(getMarkup({ sort: function sort(_ref11) { var sortBy = _ref11.sortBy, sortDirection = _ref11.sortDirection; return sortCalls.push({ sortBy: sortBy, sortDirection: sortDirection }); }, sortBy: 'email', sortDirection: SortDirection.ASC }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); Simulate.click(nameColumn); expect(sortCalls.length).toEqual(1); var _sortCalls$2 = sortCalls[0], sortBy = _sortCalls$2.sortBy, sortDirection = _sortCalls$2.sortDirection; expect(sortBy).toEqual('name'); expect(sortDirection).toEqual(SortDirection.ASC); }); it('should call sort when a column header is activated via ENTER or SPACE key', function () { var sortCalls = []; var rendered = findDOMNode(render(getMarkup({ sort: function sort(_ref12) { var sortBy = _ref12.sortBy, sortDirection = _ref12.sortDirection; return sortCalls.push({ sortBy: sortBy, sortDirection: sortDirection }); }, sortBy: 'name' }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); expect(sortCalls.length).toEqual(0); Simulate.keyDown(nameColumn, { key: ' ' }); expect(sortCalls.length).toEqual(1); Simulate.keyDown(nameColumn, { key: 'Enter' }); expect(sortCalls.length).toEqual(2); Simulate.keyDown(nameColumn, { key: 'F' }); expect(sortCalls.length).toEqual(2); }); it('should honor the default sort order on first click of the column', function () { var sortDirections = [SortDirection.ASC, SortDirection.DESC]; sortDirections.forEach(function (sortDirection) { var sortCalls = []; var rendered = findDOMNode(render(getMarkup({ sort: function sort(_ref13) { var sortBy = _ref13.sortBy, sortDirection = _ref13.sortDirection; return sortCalls.push({ sortBy: sortBy, sortDirection: sortDirection }); }, defaultSortDirection: sortDirection }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); Simulate.click(nameColumn); expect(sortCalls.length).toEqual(1); var _sortCalls$3 = sortCalls[0], sortBy = _sortCalls$3.sortBy, newSortDirection = _sortCalls$3.sortDirection; expect(sortBy).toEqual('name'); expect(newSortDirection).toEqual(sortDirection); }); }); }); describe('headerRowRenderer', function () { it('should render a custom header row if one is provided', function () { var headerRowRenderer = jest.fn().mockReturnValue(React.createElement("div", null, "foo bar")); var rendered = findDOMNode(render(getMarkup({ headerHeight: 33, headerRowRenderer: headerRowRenderer, rowClassName: 'someRowClass' }))); expect(rendered.textContent).toContain('foo bar'); expect(headerRowRenderer).toHaveBeenCalled(); var params = headerRowRenderer.mock.calls[0][0]; expect(params.className).toContain('someRowClass'); expect(params.columns).toHaveLength(2); expect(params.style.height).toBe(33); }); }); describe('headerRenderer', function () { it('should render a custom header if one is provided', function () { var columnData = { foo: 'foo', bar: 'bar' }; var headerRendererCalls = []; var rendered = findDOMNode(render(getMarkup({ columnData: columnData, headerRenderer: function headerRenderer(params) { headerRendererCalls.push(params); return 'custom header'; }, sortBy: 'name', sortDirection: SortDirection.ASC }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); expect(nameColumn.textContent).toContain('custom header'); expect(headerRendererCalls.length).toBeTruthy(); var headerRendererCall = headerRendererCalls[0]; expect(headerRendererCall.columnData).toEqual(columnData); expect(headerRendererCall.dataKey).toEqual('name'); expect(headerRendererCall.disableSort).toEqual(false); expect(headerRendererCall.label).toEqual('Name'); expect(headerRendererCall.sortBy).toEqual('name'); expect(headerRendererCall.sortDirection).toEqual(SortDirection.ASC); }); it('should honor sort for custom headers', function () { var sortCalls = []; var rendered = findDOMNode(render(getMarkup({ headerRenderer: function headerRenderer() { return 'custom header'; }, sort: function sort(_ref14) { var sortBy = _ref14.sortBy, sortDirection = _ref14.sortDirection; return sortCalls.push([sortBy, sortDirection]); }, sortBy: 'name', sortDirection: SortDirection.ASC }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); Simulate.click(nameColumn); expect(sortCalls.length).toEqual(1); var sortCall = sortCalls[0]; expect(sortCall[0]).toEqual('name'); expect(sortCall[1]).toEqual(SortDirection.DESC); }); it('should honor :onHeaderClick for custom header', function () { var columnData = { foo: 'foo', bar: 'bar' }; var onHeaderClick = jest.fn(); var rendered = findDOMNode(render(getMarkup({ columnData: columnData, headerRenderer: function headerRenderer() { return 'custom header'; }, onHeaderClick: onHeaderClick }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); Simulate.click(nameColumn); expect(onHeaderClick).toHaveBeenCalledTimes(1); var params = onHeaderClick.mock.calls[0][0]; expect(params.dataKey).toEqual('name'); expect(params.columnData).toEqual(columnData); expect(params.event.type).toEqual('click'); }); }); describe('noRowsRenderer', function () { it('should call :noRowsRenderer if :rowCount is 0', function () { var rendered = render(getMarkup({ noRowsRenderer: function noRowsRenderer() { return React.createElement("div", null, "No rows!"); }, rowCount: 0 })); var bodyDOMNode = findDOMNode(rendered.Grid); expect(bodyDOMNode.textContent).toEqual('No rows!'); }); it('should render an empty body if :rowCount is 0 and there is no :noRowsRenderer', function () { var rendered = render(getMarkup({ rowCount: 0 })); var bodyDOMNode = findDOMNode(rendered.Grid); expect(bodyDOMNode.textContent).toEqual(''); }); }); describe('onColumnClick', function () { it('should call :onColumnClick with the correct arguments when a column is clicked', function () { var onColumnClick = jest.fn(); var rendered = findDOMNode(render(getMarkup({ onColumnClick: onColumnClick }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__rowColumn:first-of-type'); Simulate.click(nameColumn); expect(onColumnClick).toHaveBeenCalledTimes(1); var params = onColumnClick.mock.calls[0][0]; expect(params.dataKey).toEqual('name'); expect(params.columnData.data).toEqual(123); expect(params.event.type).toEqual('click'); }); }); describe('onHeaderClick', function () { it('should call :onHeaderClick with the correct arguments when a column header is clicked and sorting is disabled', function () { var onHeaderClick = jest.fn(); var rendered = findDOMNode(render(getMarkup({ disableSort: true, onHeaderClick: onHeaderClick }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); Simulate.click(nameColumn); expect(onHeaderClick).toHaveBeenCalledTimes(1); var params = onHeaderClick.mock.calls[0][0]; expect(params.dataKey).toEqual('name'); expect(params.columnData.data).toEqual(123); expect(params.event.type).toEqual('click'); }); it('should call :onHeaderClick with the correct arguments when a column header is clicked and sorting is enabled', function () { var onHeaderClick = jest.fn(); var rendered = findDOMNode(render(getMarkup({ disableSort: false, onHeaderClick: onHeaderClick }))); var nameColumn = rendered.querySelector('.ReactVirtualized__Table__headerColumn:first-of-type'); Simulate.click(nameColumn); expect(onHeaderClick).toHaveBeenCalledTimes(1); var params = onHeaderClick.mock.calls[0][0]; expect(params.dataKey).toEqual('name'); expect(params.columnData.data).toEqual(123); expect(params.event.type).toEqual('click'); }); }); describe('onRowClick', function () { it('should call :onRowClick with the correct :rowIndex when a row is clicked', function () { var onRowClick = jest.fn(); var rendered = findDOMNode(render(getMarkup({ onRowClick: onRowClick }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); Simulate.click(rows[0]); Simulate.click(rows[3]); expect(onRowClick).toHaveBeenCalledTimes(2); expect(onRowClick.mock.calls.map(function (call) { return call[0].index; })).toEqual([0, 3]); }); }); describe('onRowDoubleClick', function () { it('should call :onRowDoubleClick with the correct :rowIndex when a row is clicked', function () { var onRowDoubleClick = jest.fn(); var rendered = findDOMNode(render(getMarkup({ onRowDoubleClick: onRowDoubleClick }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); Simulate.doubleClick(rows[0]); Simulate.doubleClick(rows[3]); expect(onRowDoubleClick).toHaveBeenCalledTimes(2); expect(onRowDoubleClick.mock.calls.map(function (call) { return call[0].index; })).toEqual([0, 3]); }); }); describe('onRowRightClick', function () { it('should call :onRowRightClick with the correct :rowIndex when a row is right-clicked', function () { var onRowRightClick = jest.fn(); var rendered = findDOMNode(render(getMarkup({ onRowRightClick: onRowRightClick }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); Simulate.contextMenu(rows[0]); Simulate.contextMenu(rows[3]); expect(onRowRightClick).toHaveBeenCalledTimes(2); expect(onRowRightClick.mock.calls.map(function (call) { return call[0].index; })).toEqual([0, 3]); }); }); describe('onRowMouseOver/Out', function () { it('should call :onRowMouseOver and :onRowMouseOut with the correct :rowIndex when the mouse is moved over rows', function () { var onRowMouseOver = jest.fn(); var onRowMouseOut = jest.fn(); var rendered = findDOMNode(render(getMarkup({ onRowMouseOver: onRowMouseOver, onRowMouseOut: onRowMouseOut }))); var simulateMouseOver = function simulateMouseOver(from, to) { Simulate.mouseOut(from, { relatedTarget: to }); Simulate.mouseOver(to, { relatedTarget: from }); }; var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); simulateMouseOver(rows[0], rows[1]); simulateMouseOver(rows[1], rows[2]); simulateMouseOver(rows[2], rows[3]); expect(onRowMouseOver).toHaveBeenCalled(); expect(onRowMouseOut).toHaveBeenCalled(); expect(onRowMouseOver.mock.calls.map(function (call) { return call[0].index; })).toEqual([1, 2, 3]); expect(onRowMouseOut.mock.calls.map(function (call) { return call[0].index; })).toEqual([0, 1, 2]); }); }); describe('rowClassName', function () { it('should render a static classname given :rowClassName as a string', function () { var staticClassName = 'staticClass'; var rendered = findDOMNode(render(getMarkup({ rowClassName: staticClassName }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); Array.from(rows).forEach(function (row) { expect(row.className).toContain(staticClassName); }); }); it('should render dynamic classname given :rowClassName as a function', function () { var rendered = findDOMNode(render(getMarkup({ rowClassName: function rowClassName(_ref15) { var index = _ref15.index; return index % 2 === 0 ? 'even' : 'odd'; } }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); Array.from(rows).forEach(function (row, index) { if (index % 2 === 0) { expect(row.className).toContain('even'); expect(row.className).not.toContain('odd'); } else { expect(row.className).toContain('odd'); expect(row.className).not.toContain('even'); } }); }); }); describe('onRowsRendered', function () { it('should call :onRowsRendered at least one row is rendered', function () { var startIndex, stopIndex; render(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params; return _params = params, startIndex = _params.startIndex, stopIndex = _params.stopIndex, _params; } })); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(7); }); it('should not call :onRowsRendered unless the start or stop indices have changed', function () { var numCalls = 0; var startIndex; var stopIndex; var onRowsRendered = function onRowsRendered(params) { startIndex = params.startIndex; stopIndex = params.stopIndex; numCalls++; }; render(getMarkup({ onRowsRendered: onRowsRendered })); expect(numCalls).toEqual(1); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(7); render(getMarkup({ onRowsRendered: onRowsRendered })); expect(numCalls).toEqual(1); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(7); }); it('should call :onRowsRendered if the start or stop indices have changed', function () { var numCalls = 0; var startIndex; var stopIndex; var onRowsRendered = function onRowsRendered(params) { startIndex = params.startIndex; stopIndex = params.stopIndex; numCalls++; }; render(getMarkup({ onRowsRendered: onRowsRendered })); expect(numCalls).toEqual(1); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(7); render(getMarkup({ height: 50, onRowsRendered: onRowsRendered })); expect(numCalls).toEqual(2); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(2); }); it('should not call :onRowsRendered if no rows are rendered', function () { var startIndex, stopIndex; render(getMarkup({ height: 0, onRowsRendered: function onRowsRendered(params) { var _params2; return _params2 = params, startIndex = _params2.startIndex, stopIndex = _params2.stopIndex, _params2; } })); expect(startIndex).toEqual(undefined); expect(stopIndex).toEqual(undefined); }); }); describe(':scrollTop property', function () { it('should render correctly when an initial :scrollTop property is specified', function () { var startIndex, stopIndex; render(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params3; return _params3 = params, startIndex = _params3.startIndex, stopIndex = _params3.stopIndex, _params3; }, scrollTop: 80 })); expect(startIndex).toEqual(8); expect(stopIndex).toEqual(15); }); it('should render correctly when :scrollTop property is updated', function () { var startIndex, stopIndex; render(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params4; return _params4 = params, startIndex = _params4.startIndex, stopIndex = _params4.stopIndex, _params4; } })); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(7); render(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params5; return _params5 = params, startIndex = _params5.startIndex, stopIndex = _params5.stopIndex, _params5; }, scrollTop: 80 })); expect(startIndex).toEqual(8); expect(stopIndex).toEqual(15); }); }); describe('styles, classNames, and ids', function () { it('should use the expected global CSS classNames', function () { var node = findDOMNode(render(getMarkup({ sort: function sort() {}, sortBy: 'name', sortDirection: SortDirection.ASC }))); expect(node.className).toEqual('ReactVirtualized__Table'); expect(node.querySelector('.ReactVirtualized__Table__headerRow')).toBeTruthy(); expect(node.querySelector('.ReactVirtualized__Table__rowColumn')).toBeTruthy(); expect(node.querySelector('.ReactVirtualized__Table__headerColumn')).toBeTruthy(); expect(node.querySelector('.ReactVirtualized__Table__row')).toBeTruthy(); expect(node.querySelector('.ReactVirtualized__Table__sortableHeaderColumn')).toBeTruthy(); expect(node.querySelector('.ReactVirtualized__Table__sortableHeaderIcon')).toBeTruthy(); }); it('should use a custom :className if specified', function () { var node = findDOMNode(render(getMarkup({ className: 'foo', headerClassName: 'bar', rowClassName: 'baz' }))); expect(node.className).toContain('foo'); expect(node.querySelectorAll('.bar').length).toEqual(2); expect(node.querySelectorAll('.baz').length).toEqual(9); }); it('should use a custom :id if specified', function () { var node = findDOMNode(render(getMarkup({ id: 'bar' }))); expect(node.getAttribute('id')).toEqual('bar'); }); it('should not set :id on the inner Grid', function () { var node = findDOMNode(render(getMarkup({ id: 'bar' }))); var grid = node.querySelector('.ReactVirtualized__Grid'); expect(grid.getAttribute('id')).not.toEqual('bar'); }); it('should use custom :styles if specified', function () { var columnStyle = { backgroundColor: 'red', overflow: 'visible' }; var headerStyle = { backgroundColor: 'blue' }; var columnHeaderStyle = { color: 'yellow' }; var rowStyle = { backgroundColor: 'green' }; var style = { backgroundColor: 'orange' }; var node = findDOMNode(render(getMarkup({ columnStyle: columnStyle, headerStyle: headerStyle, columnHeaderStyle: columnHeaderStyle, rowStyle: rowStyle, style: style }))); expect(node.querySelector('.ReactVirtualized__Table__rowColumn').style.backgroundColor).toEqual('red'); expect(node.querySelector('.ReactVirtualized__Table__rowColumn').style.overflow).toEqual('visible'); expect(node.querySelector('.ReactVirtualized__Table__headerColumn').style.backgroundColor).toEqual('blue'); expect(node.querySelector('.ReactVirtualized__Table__headerColumn').style.color).toEqual('yellow'); expect(node.querySelector('.ReactVirtualized__Table__row').style.backgroundColor).toEqual('green'); expect(node.style.backgroundColor).toEqual('orange'); }); it('should render dynamic style given :rowStyle as a function', function () { var rendered = findDOMNode(render(getMarkup({ rowStyle: function rowStyle(_ref16) { var index = _ref16.index; return index % 2 === 0 ? { backgroundColor: 'red' } : { backgroundColor: 'green' }; } }))); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); Array.from(rows).forEach(function (row, index) { if (index % 2 === 0) { expect(row.style.backgroundColor).toEqual('red'); } else { expect(row.style.backgroundColor).toEqual('green'); } }); }); it('should pass :gridClassName and :gridStyle to the inner Grid', function () { var rendered = findDOMNode(render(getMarkup({ gridClassName: 'foo', gridStyle: { backgroundColor: 'red' } }))); var grid = rendered.querySelector('.ReactVirtualized__Grid'); expect(grid.className).toContain('foo'); expect(grid.style.backgroundColor).toEqual('red'); }); }); describe('overscanRowCount', function () { it('should not overscan by default', function () { var mock = jest.fn(); mock.mockImplementation(overscanIndicesGetter); render(getMarkup({ overscanIndicesGetter: mock })); expect(mock.mock.calls[0][0].overscanCellsCount).toEqual(0); expect(mock.mock.calls[1][0].overscanCellsCount).toEqual(0); }); it('should overscan the specified amount', function () { var mock = jest.fn(); mock.mockImplementation(overscanIndicesGetter); render(getMarkup({ overscanIndicesGetter: mock, overscanRowCount: 10 })); expect(mock.mock.calls[0][0].overscanCellsCount).toEqual(0); expect(mock.mock.calls[1][0].overscanCellsCount).toEqual(10); }); }); describe('onScroll', function () { it('should trigger callback when component initially mounts', function () { var onScrollCalls = []; render(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); expect(onScrollCalls).toEqual([{ clientHeight: 80, scrollHeight: 1000, scrollTop: 0 }]); }); it('should trigger callback when component scrolls', function () { var onScrollCalls = []; var rendered = render(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); var target = { scrollLeft: 0, scrollTop: 100 }; rendered.Grid._scrollingContainer = target; // HACK to work around _onScroll target check Simulate.scroll(findDOMNode(rendered.Grid), { target: target }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: 80, scrollHeight: 1000, scrollTop: 100 }); }); }); describe('a11y properties', function () { it('should set aria role on the table', function () { var node = findDOMNode(render(getMarkup())); expect(node.getAttribute('role')).toEqual('grid'); }); it('should set aria col/row count on the table', function () { var node = findDOMNode(render(getMarkup())); expect(node.getAttribute('aria-colcount')).toEqual('2'); expect(node.getAttribute('aria-rowcount')).toEqual("".concat(list.size)); }); it('should pass down aria labels on the table', function () { var node = findDOMNode(render(getMarkup({ 'aria-label': 'my-table-label', 'aria-labelledby': 'my-table-label-id' }))); expect(node.getAttribute('aria-label')).toEqual('my-table-label'); expect(node.getAttribute('aria-labelledby')).toEqual('my-table-label-id'); }); it('should set aria role on the header row', function () { var rendered = findDOMNode(render(getMarkup())); var row = rendered.querySelector('.ReactVirtualized__Table__headerRow'); expect(row.getAttribute('role')).toEqual('row'); }); it('should set appropriate aria role on the grid', function () { var rendered = findDOMNode(render(getMarkup())); var grid = rendered.querySelector('.ReactVirtualized__Table__Grid'); expect(grid.getAttribute('role')).toEqual('rowgroup'); }); it('should set aria role on a row', function () { var rendered = findDOMNode(render(getMarkup())); var row = rendered.querySelector('.ReactVirtualized__Table__row'); expect(row.getAttribute('role')).toEqual('row'); }); it('should set aria rowindex on a row', function () { var rendered = findDOMNode(render(getMarkup())); var rows = rendered.querySelectorAll('.ReactVirtualized__Table__row'); expect(rows[0].getAttribute('aria-rowindex')).toEqual('1'); expect(rows[1].getAttribute('aria-rowindex')).toEqual('2'); }); it('should set aria role on a cell', function () { var rendered = findDOMNode(render(getMarkup())); var cell = rendered.querySelector('.ReactVirtualized__Table__rowColumn'); expect(cell.getAttribute('role')).toEqual('gridcell'); }); it('should set aria colindex on a cell', function () { var rendered = findDOMNode(render(getMarkup())); var cells = rendered.querySelectorAll('.ReactVirtualized__Table__rowColumn'); expect(cells[0].getAttribute('aria-colindex')).toEqual('1'); expect(cells[1].getAttribute('aria-colindex')).toEqual('2'); }); it('should set aria-describedby on a cell when the column has an id', function () { var columnID = 'column-header-test'; var rendered = findDOMNode(render(getMarkup({ columnID: columnID }))); var cell = rendered.querySelector('.ReactVirtualized__Table__rowColumn'); expect(cell.getAttribute('aria-describedby')).toEqual(columnID); }); it('should attach a11y properties to a row if :onRowClick is specified', function () { var rendered = findDOMNode(render(getMarkup({ onRowClick: function onRowClick() {} }))); var row = rendered.querySelector('.ReactVirtualized__Table__row'); expect(row.getAttribute('aria-label')).toEqual('row'); expect(row.tabIndex).toEqual(0); }); it('should not attach a11y properties to a row if no :onRowClick is specified', function () { var rendered = findDOMNode(render(getMarkup({ onRowClick: null }))); var row = rendered.querySelector('.ReactVirtualized__Table__row'); expect(row.getAttribute('aria-label')).toEqual(null); expect(row.tabIndex).toEqual(-1); }); it('should set aria role on a header column', function () { var rendered = findDOMNode(render(getMarkup())); var header = rendered.querySelector('.ReactVirtualized__Table__headerColumn'); expect(header.getAttribute('role')).toEqual('columnheader'); }); it('should set aria-sort ascending on a header column if the column is sorted ascending', function () { var rendered = findDOMNode(render(getMarkup({ sortBy: 'name', sortDirection: SortDirection.ASC }))); var header = rendered.querySelector('.ReactVirtualized__Table__headerColumn'); expect(header.getAttribute('aria-sort')).toEqual('ascending'); }); it('should set aria-sort descending on a header column if the column is sorted descending', function () { var rendered = findDOMNode(render(getMarkup({ sortBy: 'name', sortDirection: SortDirection.DESC }))); var header = rendered.querySelector('.ReactVirtualized__Table__headerColumn'); expect(header.getAttribute('aria-sort')).toEqual('descending'); }); it('should set aria-sort to "none" if the column is sortable but not the current sort', function () { var rendered = findDOMNode(render(getMarkup({ disableSort: true, sort: jest.fn() }))); var headers = rendered.querySelectorAll('.ReactVirtualized__Table__headerColumn'); // the first column is not sortable expect(headers[0].getAttribute('aria-sort')).toBe(null); // the second column is sortable expect(headers[1].getAttribute('aria-sort')).toEqual('none'); }); it('should set id on a header column when the column has an id', function () { var columnID = 'column-header-test'; var rendered = findDOMNode(render(getMarkup({ columnID: columnID }))); var header = rendered.querySelector('.ReactVirtualized__Table__headerColumn'); expect(header.getAttribute('id')).toEqual(columnID); }); it('should attach a11y properties to a header column if sort is enabled', function () { var rendered = findDOMNode(render(getMarkup({ disableSort: false, sort: function sort() {} }))); var row = rendered.querySelector('.ReactVirtualized__Table__headerColumn'); expect(row.getAttribute('aria-label')).toEqual('Name'); expect(row.tabIndex).toEqual(0); }); it('should not attach a11y properties to a header column if sort is not enabled', function () { var rendered = findDOMNode(render(getMarkup({ disableSort: true }))); var row = rendered.querySelector('.ReactVirtualized__Table__headerColumn'); expect(row.getAttribute('aria-label')).toEqual(null); expect(row.tabIndex).toEqual(-1); }); }); describe('tabIndex', function () { it('should be focusable by default', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.querySelector('.ReactVirtualized__Grid').tabIndex).toEqual(0); }); it('should allow tabIndex to be overridden', function () { var rendered = findDOMNode(render(getMarkup({ tabIndex: -1 }))); expect(rendered.querySelector('.ReactVirtualized__Grid').tabIndex).toEqual(-1); }); }); describe('pure', function () { it('should not re-render unless props have changed', function () { var headerRendererCalled = false; var cellRendererCalled = false; function headerRenderer() { headerRendererCalled = true; return 'foo'; } function cellRenderer() { cellRendererCalled = true; return 'foo'; } var markup = getMarkup({ headerRenderer: headerRenderer, cellRenderer: cellRenderer }); render(markup); expect(headerRendererCalled).toEqual(true); expect(cellRendererCalled).toEqual(true); headerRendererCalled = false; cellRendererCalled = false; render(markup); expect(headerRendererCalled).toEqual(false); expect(cellRendererCalled).toEqual(false); }); it('should re-render both the Table and the inner Grid whenever an external property changes', function () { var headerRendererCalled = false; var cellRendererCalled = false; function headerRenderer() { headerRendererCalled = true; return 'foo'; } function cellRenderer() { cellRendererCalled = true; return 'foo'; } var initialProperties = { autoHeight: false, cellRenderer: cellRenderer, estimatedRowSize: 15, headerRenderer: headerRenderer, overscanRowCount: 1, rowHeight: 15, rowCount: 20, scrollToAlignment: 'auto', scrollTop: 0, sortBy: 'name', sortDirection: SortDirection.ASC, tabIndex: null }; var changedProperties = { autoHeight: true, estimatedRowSize: 10, overscanRowCount: 0, rowHeight: 10, rowCount: 10, scrollToAlignment: 'center', scrollTop: 1, sortBy: 'email', sortDirection: SortDirection.DESC, tabIndex: 1 }; Object.entries(changedProperties).forEach(function (_ref17) { var _ref18 = _slicedToArray(_ref17, 2), key = _ref18[0], value = _ref18[1]; render.unmount(); // Reset render(getMarkup(initialProperties)); headerRendererCalled = true; cellRendererCalled = false; render(getMarkup(_objectSpread({}, initialProperties, _defineProperty({}, key, value)))); expect(headerRendererCalled).toEqual(true); expect(cellRendererCalled).toEqual(true); }); }); }); it('should set the width of the single-column inner Grid to auto', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('auto'); }); it('should relay the Grid :parent param to the Column :cellRenderer', function () { var cellRenderer = jest.fn().mockReturnValue(null); findDOMNode(render(getMarkup({ cellRenderer: cellRenderer }))); expect(cellRenderer.mock.calls[0][0].parent).not.toBeUndefined(); }); });dist/es/Table/types.js000064400000007230151676725770010700 0ustar00var bpfrpt_proptype_CellDataGetterParams = process.env.NODE_ENV === 'production' ? null : { "columnData": PropTypes.any, "dataKey": PropTypes.string.isRequired, "rowData": function rowData(props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } } }; var bpfrpt_proptype_CellRendererParams = process.env.NODE_ENV === 'production' ? null : { "cellData": PropTypes.any, "columnData": PropTypes.any, "dataKey": PropTypes.string.isRequired, "rowData": function rowData(props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } }, "rowIndex": PropTypes.number.isRequired }; var bpfrpt_proptype_HeaderRowRendererParams = process.env.NODE_ENV === 'production' ? null : { "className": PropTypes.string.isRequired, "columns": PropTypes.arrayOf(function (props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } }).isRequired, "style": function style(props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } } }; var bpfrpt_proptype_HeaderRendererParams = process.env.NODE_ENV === 'production' ? null : { "columnData": PropTypes.any, "dataKey": PropTypes.string.isRequired, "disableSort": PropTypes.bool, "label": PropTypes.any, "sortBy": PropTypes.string, "sortDirection": PropTypes.string }; var bpfrpt_proptype_RowRendererParams = process.env.NODE_ENV === 'production' ? null : { "className": PropTypes.string.isRequired, "columns": PropTypes.arrayOf(function (props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } }).isRequired, "index": PropTypes.number.isRequired, "isScrolling": PropTypes.bool.isRequired, "onRowClick": PropTypes.func, "onRowDoubleClick": PropTypes.func, "onRowMouseOver": PropTypes.func, "onRowMouseOut": PropTypes.func, "rowData": function rowData(props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } }, "style": function style(props, propName, componentName) { if (!Object.prototype.hasOwnProperty.call(props, propName)) { throw new Error("Prop `".concat(propName, "` has type 'any' or 'mixed', but was not provided to `").concat(componentName, "`. Pass undefined or any other value.")); } }, "key": PropTypes.string.isRequired }; import PropTypes from "prop-types"; export { bpfrpt_proptype_CellDataGetterParams }; export { bpfrpt_proptype_CellRendererParams }; export { bpfrpt_proptype_HeaderRowRendererParams }; export { bpfrpt_proptype_HeaderRendererParams }; export { bpfrpt_proptype_RowRendererParams };dist/es/Table/Table.js000064400000065011151676725770010564 0ustar00import _extends from "@babel/runtime/helpers/extends"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import clsx from 'clsx'; import Column from './Column'; import PropTypes from 'prop-types'; import * as React from 'react'; import { findDOMNode } from 'react-dom'; import Grid, { accessibilityOverscanIndicesGetter } from '../Grid'; import defaultRowRenderer from './defaultRowRenderer'; import defaultHeaderRowRenderer from './defaultHeaderRowRenderer'; import SortDirection from './SortDirection'; /** * Table component with fixed headers and virtualized rows for improved performance with large data sets. * This component expects explicit width, height, and padding parameters. */ var Table = /*#__PURE__*/ function (_React$PureComponent) { _inherits(Table, _React$PureComponent); function Table(props) { var _this; _classCallCheck(this, Table); _this = _possibleConstructorReturn(this, _getPrototypeOf(Table).call(this, props)); _this.state = { scrollbarWidth: 0 }; _this._createColumn = _this._createColumn.bind(_assertThisInitialized(_this)); _this._createRow = _this._createRow.bind(_assertThisInitialized(_this)); _this._onScroll = _this._onScroll.bind(_assertThisInitialized(_this)); _this._onSectionRendered = _this._onSectionRendered.bind(_assertThisInitialized(_this)); _this._setRef = _this._setRef.bind(_assertThisInitialized(_this)); return _this; } _createClass(Table, [{ key: "forceUpdateGrid", value: function forceUpdateGrid() { if (this.Grid) { this.Grid.forceUpdate(); } } /** See Grid#getOffsetForCell */ }, { key: "getOffsetForRow", value: function getOffsetForRow(_ref) { var alignment = _ref.alignment, index = _ref.index; if (this.Grid) { var _this$Grid$getOffsetF = this.Grid.getOffsetForCell({ alignment: alignment, rowIndex: index }), scrollTop = _this$Grid$getOffsetF.scrollTop; return scrollTop; } return 0; } /** CellMeasurer compatibility */ }, { key: "invalidateCellSizeAfterRender", value: function invalidateCellSizeAfterRender(_ref2) { var columnIndex = _ref2.columnIndex, rowIndex = _ref2.rowIndex; if (this.Grid) { this.Grid.invalidateCellSizeAfterRender({ rowIndex: rowIndex, columnIndex: columnIndex }); } } /** See Grid#measureAllCells */ }, { key: "measureAllRows", value: function measureAllRows() { if (this.Grid) { this.Grid.measureAllCells(); } } /** CellMeasurer compatibility */ }, { key: "recomputeGridSize", value: function recomputeGridSize() { var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref3$columnIndex = _ref3.columnIndex, columnIndex = _ref3$columnIndex === void 0 ? 0 : _ref3$columnIndex, _ref3$rowIndex = _ref3.rowIndex, rowIndex = _ref3$rowIndex === void 0 ? 0 : _ref3$rowIndex; if (this.Grid) { this.Grid.recomputeGridSize({ rowIndex: rowIndex, columnIndex: columnIndex }); } } /** See Grid#recomputeGridSize */ }, { key: "recomputeRowHeights", value: function recomputeRowHeights() { var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (this.Grid) { this.Grid.recomputeGridSize({ rowIndex: index }); } } /** See Grid#scrollToPosition */ }, { key: "scrollToPosition", value: function scrollToPosition() { var scrollTop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (this.Grid) { this.Grid.scrollToPosition({ scrollTop: scrollTop }); } } /** See Grid#scrollToCell */ }, { key: "scrollToRow", value: function scrollToRow() { var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (this.Grid) { this.Grid.scrollToCell({ columnIndex: 0, rowIndex: index }); } } }, { key: "getScrollbarWidth", value: function getScrollbarWidth() { if (this.Grid) { var _Grid = findDOMNode(this.Grid); var clientWidth = _Grid.clientWidth || 0; var offsetWidth = _Grid.offsetWidth || 0; return offsetWidth - clientWidth; } return 0; } }, { key: "componentDidMount", value: function componentDidMount() { this._setScrollbarWidth(); } }, { key: "componentDidUpdate", value: function componentDidUpdate() { this._setScrollbarWidth(); } }, { key: "render", value: function render() { var _this2 = this; var _this$props = this.props, children = _this$props.children, className = _this$props.className, disableHeader = _this$props.disableHeader, gridClassName = _this$props.gridClassName, gridStyle = _this$props.gridStyle, headerHeight = _this$props.headerHeight, headerRowRenderer = _this$props.headerRowRenderer, height = _this$props.height, id = _this$props.id, noRowsRenderer = _this$props.noRowsRenderer, rowClassName = _this$props.rowClassName, rowStyle = _this$props.rowStyle, scrollToIndex = _this$props.scrollToIndex, style = _this$props.style, width = _this$props.width; var scrollbarWidth = this.state.scrollbarWidth; var availableRowsHeight = disableHeader ? height : height - headerHeight; var rowClass = typeof rowClassName === 'function' ? rowClassName({ index: -1 }) : rowClassName; var rowStyleObject = typeof rowStyle === 'function' ? rowStyle({ index: -1 }) : rowStyle; // Precompute and cache column styles before rendering rows and columns to speed things up this._cachedColumnStyles = []; React.Children.toArray(children).forEach(function (column, index) { var flexStyles = _this2._getFlexStyleForColumn(column, column.props.style); _this2._cachedColumnStyles[index] = _objectSpread({ overflow: 'hidden' }, flexStyles); }); // Note that we specify :rowCount, :scrollbarWidth, :sortBy, and :sortDirection as properties on Grid even though these have nothing to do with Grid. // This is done because Grid is a pure component and won't update unless its properties or state has changed. // Any property that should trigger a re-render of Grid then is specified here to avoid a stale display. return React.createElement("div", { "aria-label": this.props['aria-label'], "aria-labelledby": this.props['aria-labelledby'], "aria-colcount": React.Children.toArray(children).length, "aria-rowcount": this.props.rowCount, className: clsx('ReactVirtualized__Table', className), id: id, role: "grid", style: style }, !disableHeader && headerRowRenderer({ className: clsx('ReactVirtualized__Table__headerRow', rowClass), columns: this._getHeaderColumns(), style: _objectSpread({ height: headerHeight, overflow: 'hidden', paddingRight: scrollbarWidth, width: width }, rowStyleObject) }), React.createElement(Grid, _extends({}, this.props, { "aria-readonly": null, autoContainerWidth: true, className: clsx('ReactVirtualized__Table__Grid', gridClassName), cellRenderer: this._createRow, columnWidth: width, columnCount: 1, height: availableRowsHeight, id: undefined, noContentRenderer: noRowsRenderer, onScroll: this._onScroll, onSectionRendered: this._onSectionRendered, ref: this._setRef, role: "rowgroup", scrollbarWidth: scrollbarWidth, scrollToRow: scrollToIndex, style: _objectSpread({}, gridStyle, { overflowX: 'hidden' }) }))); } }, { key: "_createColumn", value: function _createColumn(_ref4) { var column = _ref4.column, columnIndex = _ref4.columnIndex, isScrolling = _ref4.isScrolling, parent = _ref4.parent, rowData = _ref4.rowData, rowIndex = _ref4.rowIndex; var onColumnClick = this.props.onColumnClick; var _column$props = column.props, cellDataGetter = _column$props.cellDataGetter, cellRenderer = _column$props.cellRenderer, className = _column$props.className, columnData = _column$props.columnData, dataKey = _column$props.dataKey, id = _column$props.id; var cellData = cellDataGetter({ columnData: columnData, dataKey: dataKey, rowData: rowData }); var renderedCell = cellRenderer({ cellData: cellData, columnData: columnData, columnIndex: columnIndex, dataKey: dataKey, isScrolling: isScrolling, parent: parent, rowData: rowData, rowIndex: rowIndex }); var onClick = function onClick(event) { onColumnClick && onColumnClick({ columnData: columnData, dataKey: dataKey, event: event }); }; var style = this._cachedColumnStyles[columnIndex]; var title = typeof renderedCell === 'string' ? renderedCell : null; // Avoid using object-spread syntax with multiple objects here, // Since it results in an extra method call to 'babel-runtime/helpers/extends' // See PR https://github.com/bvaughn/react-virtualized/pull/942 return React.createElement("div", { "aria-colindex": columnIndex + 1, "aria-describedby": id, className: clsx('ReactVirtualized__Table__rowColumn', className), key: 'Row' + rowIndex + '-' + 'Col' + columnIndex, onClick: onClick, role: "gridcell", style: style, title: title }, renderedCell); } }, { key: "_createHeader", value: function _createHeader(_ref5) { var column = _ref5.column, index = _ref5.index; var _this$props2 = this.props, headerClassName = _this$props2.headerClassName, headerStyle = _this$props2.headerStyle, onHeaderClick = _this$props2.onHeaderClick, sort = _this$props2.sort, sortBy = _this$props2.sortBy, sortDirection = _this$props2.sortDirection; var _column$props2 = column.props, columnData = _column$props2.columnData, dataKey = _column$props2.dataKey, defaultSortDirection = _column$props2.defaultSortDirection, disableSort = _column$props2.disableSort, headerRenderer = _column$props2.headerRenderer, id = _column$props2.id, label = _column$props2.label; var sortEnabled = !disableSort && sort; var classNames = clsx('ReactVirtualized__Table__headerColumn', headerClassName, column.props.headerClassName, { ReactVirtualized__Table__sortableHeaderColumn: sortEnabled }); var style = this._getFlexStyleForColumn(column, _objectSpread({}, headerStyle, {}, column.props.headerStyle)); var renderedHeader = headerRenderer({ columnData: columnData, dataKey: dataKey, disableSort: disableSort, label: label, sortBy: sortBy, sortDirection: sortDirection }); var headerOnClick, headerOnKeyDown, headerTabIndex, headerAriaSort, headerAriaLabel; if (sortEnabled || onHeaderClick) { // If this is a sortable header, clicking it should update the table data's sorting. var isFirstTimeSort = sortBy !== dataKey; // If this is the firstTime sort of this column, use the column default sort order. // Otherwise, invert the direction of the sort. var newSortDirection = isFirstTimeSort ? defaultSortDirection : sortDirection === SortDirection.DESC ? SortDirection.ASC : SortDirection.DESC; var onClick = function onClick(event) { sortEnabled && sort({ defaultSortDirection: defaultSortDirection, event: event, sortBy: dataKey, sortDirection: newSortDirection }); onHeaderClick && onHeaderClick({ columnData: columnData, dataKey: dataKey, event: event }); }; var onKeyDown = function onKeyDown(event) { if (event.key === 'Enter' || event.key === ' ') { onClick(event); } }; headerAriaLabel = column.props['aria-label'] || label || dataKey; headerAriaSort = 'none'; headerTabIndex = 0; headerOnClick = onClick; headerOnKeyDown = onKeyDown; } if (sortBy === dataKey) { headerAriaSort = sortDirection === SortDirection.ASC ? 'ascending' : 'descending'; } // Avoid using object-spread syntax with multiple objects here, // Since it results in an extra method call to 'babel-runtime/helpers/extends' // See PR https://github.com/bvaughn/react-virtualized/pull/942 return React.createElement("div", { "aria-label": headerAriaLabel, "aria-sort": headerAriaSort, className: classNames, id: id, key: 'Header-Col' + index, onClick: headerOnClick, onKeyDown: headerOnKeyDown, role: "columnheader", style: style, tabIndex: headerTabIndex }, renderedHeader); } }, { key: "_createRow", value: function _createRow(_ref6) { var _this3 = this; var index = _ref6.rowIndex, isScrolling = _ref6.isScrolling, key = _ref6.key, parent = _ref6.parent, style = _ref6.style; var _this$props3 = this.props, children = _this$props3.children, onRowClick = _this$props3.onRowClick, onRowDoubleClick = _this$props3.onRowDoubleClick, onRowRightClick = _this$props3.onRowRightClick, onRowMouseOver = _this$props3.onRowMouseOver, onRowMouseOut = _this$props3.onRowMouseOut, rowClassName = _this$props3.rowClassName, rowGetter = _this$props3.rowGetter, rowRenderer = _this$props3.rowRenderer, rowStyle = _this$props3.rowStyle; var scrollbarWidth = this.state.scrollbarWidth; var rowClass = typeof rowClassName === 'function' ? rowClassName({ index: index }) : rowClassName; var rowStyleObject = typeof rowStyle === 'function' ? rowStyle({ index: index }) : rowStyle; var rowData = rowGetter({ index: index }); var columns = React.Children.toArray(children).map(function (column, columnIndex) { return _this3._createColumn({ column: column, columnIndex: columnIndex, isScrolling: isScrolling, parent: parent, rowData: rowData, rowIndex: index, scrollbarWidth: scrollbarWidth }); }); var className = clsx('ReactVirtualized__Table__row', rowClass); var flattenedStyle = _objectSpread({}, style, { height: this._getRowHeight(index), overflow: 'hidden', paddingRight: scrollbarWidth }, rowStyleObject); return rowRenderer({ className: className, columns: columns, index: index, isScrolling: isScrolling, key: key, onRowClick: onRowClick, onRowDoubleClick: onRowDoubleClick, onRowRightClick: onRowRightClick, onRowMouseOver: onRowMouseOver, onRowMouseOut: onRowMouseOut, rowData: rowData, style: flattenedStyle }); } /** * Determines the flex-shrink, flex-grow, and width values for a cell (header or column). */ }, { key: "_getFlexStyleForColumn", value: function _getFlexStyleForColumn(column) { var customStyle = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var flexValue = "".concat(column.props.flexGrow, " ").concat(column.props.flexShrink, " ").concat(column.props.width, "px"); var style = _objectSpread({}, customStyle, { flex: flexValue, msFlex: flexValue, WebkitFlex: flexValue }); if (column.props.maxWidth) { style.maxWidth = column.props.maxWidth; } if (column.props.minWidth) { style.minWidth = column.props.minWidth; } return style; } }, { key: "_getHeaderColumns", value: function _getHeaderColumns() { var _this4 = this; var _this$props4 = this.props, children = _this$props4.children, disableHeader = _this$props4.disableHeader; var items = disableHeader ? [] : React.Children.toArray(children); return items.map(function (column, index) { return _this4._createHeader({ column: column, index: index }); }); } }, { key: "_getRowHeight", value: function _getRowHeight(rowIndex) { var rowHeight = this.props.rowHeight; return typeof rowHeight === 'function' ? rowHeight({ index: rowIndex }) : rowHeight; } }, { key: "_onScroll", value: function _onScroll(_ref7) { var clientHeight = _ref7.clientHeight, scrollHeight = _ref7.scrollHeight, scrollTop = _ref7.scrollTop; var onScroll = this.props.onScroll; onScroll({ clientHeight: clientHeight, scrollHeight: scrollHeight, scrollTop: scrollTop }); } }, { key: "_onSectionRendered", value: function _onSectionRendered(_ref8) { var rowOverscanStartIndex = _ref8.rowOverscanStartIndex, rowOverscanStopIndex = _ref8.rowOverscanStopIndex, rowStartIndex = _ref8.rowStartIndex, rowStopIndex = _ref8.rowStopIndex; var onRowsRendered = this.props.onRowsRendered; onRowsRendered({ overscanStartIndex: rowOverscanStartIndex, overscanStopIndex: rowOverscanStopIndex, startIndex: rowStartIndex, stopIndex: rowStopIndex }); } }, { key: "_setRef", value: function _setRef(ref) { this.Grid = ref; } }, { key: "_setScrollbarWidth", value: function _setScrollbarWidth() { var scrollbarWidth = this.getScrollbarWidth(); this.setState({ scrollbarWidth: scrollbarWidth }); } }]); return Table; }(React.PureComponent); _defineProperty(Table, "defaultProps", { disableHeader: false, estimatedRowSize: 30, headerHeight: 0, headerStyle: {}, noRowsRenderer: function noRowsRenderer() { return null; }, onRowsRendered: function onRowsRendered() { return null; }, onScroll: function onScroll() { return null; }, overscanIndicesGetter: accessibilityOverscanIndicesGetter, overscanRowCount: 10, rowRenderer: defaultRowRenderer, headerRowRenderer: defaultHeaderRowRenderer, rowStyle: {}, scrollToAlignment: 'auto', scrollToIndex: -1, style: {} }); export { Table as default }; Table.propTypes = process.env.NODE_ENV !== "production" ? { /** This is just set on the grid top element. */ 'aria-label': PropTypes.string, /** This is just set on the grid top element. */ 'aria-labelledby': PropTypes.string, /** * Removes fixed height from the scrollingContainer so that the total height * of rows can stretch the window. Intended for use with WindowScroller */ autoHeight: PropTypes.bool, /** One or more Columns describing the data displayed in this row */ children: function children(props) { var children = React.Children.toArray(props.children); for (var i = 0; i < children.length; i++) { var childType = children[i].type; if (childType !== Column && !(childType.prototype instanceof Column)) { return new Error('Table only accepts children of type Column'); } } }, /** Optional CSS class name */ className: PropTypes.string, /** Disable rendering the header at all */ disableHeader: PropTypes.bool, /** * Used to estimate the total height of a Table before all of its rows have actually been measured. * The estimated total height is adjusted as rows are rendered. */ estimatedRowSize: PropTypes.number.isRequired, /** Optional custom CSS class name to attach to inner Grid element. */ gridClassName: PropTypes.string, /** Optional inline style to attach to inner Grid element. */ gridStyle: PropTypes.object, /** Optional CSS class to apply to all column headers */ headerClassName: PropTypes.string, /** Fixed height of header row */ headerHeight: PropTypes.number.isRequired, /** * Responsible for rendering a table row given an array of columns: * Should implement the following interface: ({ * className: string, * columns: any[], * style: any * }): PropTypes.node */ headerRowRenderer: PropTypes.func, /** Optional custom inline style to attach to table header columns. */ headerStyle: PropTypes.object, /** Fixed/available height for out DOM element */ height: PropTypes.number.isRequired, /** Optional id */ id: PropTypes.string, /** Optional renderer to be used in place of table body rows when rowCount is 0 */ noRowsRenderer: PropTypes.func, /** * Optional callback when a column is clicked. * ({ columnData: any, dataKey: string }): void */ onColumnClick: PropTypes.func, /** * Optional callback when a column's header is clicked. * ({ columnData: any, dataKey: string }): void */ onHeaderClick: PropTypes.func, /** * Callback invoked when a user clicks on a table row. * ({ index: number }): void */ onRowClick: PropTypes.func, /** * Callback invoked when a user double-clicks on a table row. * ({ index: number }): void */ onRowDoubleClick: PropTypes.func, /** * Callback invoked when the mouse leaves a table row. * ({ index: number }): void */ onRowMouseOut: PropTypes.func, /** * Callback invoked when a user moves the mouse over a table row. * ({ index: number }): void */ onRowMouseOver: PropTypes.func, /** * Callback invoked when a user right-clicks on a table row. * ({ index: number }): void */ onRowRightClick: PropTypes.func, /** * Callback invoked with information about the slice of rows that were just rendered. * ({ startIndex, stopIndex }): void */ onRowsRendered: PropTypes.func, /** * Callback invoked whenever the scroll offset changes within the inner scrollable region. * This callback can be used to sync scrolling between lists, tables, or grids. * ({ clientHeight, scrollHeight, scrollTop }): void */ onScroll: PropTypes.func.isRequired, /** See Grid#overscanIndicesGetter */ overscanIndicesGetter: PropTypes.func.isRequired, /** * Number of rows to render above/below the visible bounds of the list. * These rows can help for smoother scrolling on touch devices. */ overscanRowCount: PropTypes.number.isRequired, /** * Optional CSS class to apply to all table rows (including the header row). * This property can be a CSS class name (string) or a function that returns a class name. * If a function is provided its signature should be: ({ index: number }): string */ rowClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), /** * Callback responsible for returning a data row given an index. * ({ index: number }): any */ rowGetter: PropTypes.func.isRequired, /** * Either a fixed row height (number) or a function that returns the height of a row given its index. * ({ index: number }): number */ rowHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.func]).isRequired, /** Number of rows in table. */ rowCount: PropTypes.number.isRequired, /** * Responsible for rendering a table row given an array of columns: * Should implement the following interface: ({ * className: string, * columns: Array, * index: number, * isScrolling: boolean, * onRowClick: ?Function, * onRowDoubleClick: ?Function, * onRowMouseOver: ?Function, * onRowMouseOut: ?Function, * rowData: any, * style: any * }): PropTypes.node */ rowRenderer: PropTypes.func, /** Optional custom inline style to attach to table rows. */ rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired, /** See Grid#scrollToAlignment */ scrollToAlignment: PropTypes.oneOf(['auto', 'end', 'start', 'center']).isRequired, /** Row index to ensure visible (by forcefully scrolling if necessary) */ scrollToIndex: PropTypes.number.isRequired, /** Vertical offset. */ scrollTop: PropTypes.number, /** * Sort function to be called if a sortable header is clicked. * Should implement the following interface: ({ * defaultSortDirection: 'ASC' | 'DESC', * event: MouseEvent, * sortBy: string, * sortDirection: SortDirection * }): void */ sort: PropTypes.func, /** Table data is currently sorted by this :dataKey (if it is sorted at all) */ sortBy: PropTypes.string, /** Table data is currently sorted in this direction (if it is sorted at all) */ sortDirection: PropTypes.oneOf([SortDirection.ASC, SortDirection.DESC]), /** Optional inline style */ style: PropTypes.object, /** Tab index for focus */ tabIndex: PropTypes.number, /** Width of list */ width: PropTypes.number.isRequired } : {}; import { bpfrpt_proptype_CellPosition } from "../Grid";dist/es/Table/defaultCellRenderer.js000064400000000624151676725770013447 0ustar00/** * Default cell renderer that displays an attribute as a simple string * You should override the column's cellRenderer if your data is some other type of object. */ export default function defaultCellRenderer(_ref) { var cellData = _ref.cellData; if (cellData == null) { return ''; } else { return String(cellData); } } import { bpfrpt_proptype_CellRendererParams } from "./types";dist/es/Table/defaultRowRenderer.js000064400000004316151676725770013341 0ustar00import _extends from "@babel/runtime/helpers/extends"; import * as React from 'react'; /** * Default row renderer for Table. */ export default function defaultRowRenderer(_ref) { var className = _ref.className, columns = _ref.columns, index = _ref.index, key = _ref.key, onRowClick = _ref.onRowClick, onRowDoubleClick = _ref.onRowDoubleClick, onRowMouseOut = _ref.onRowMouseOut, onRowMouseOver = _ref.onRowMouseOver, onRowRightClick = _ref.onRowRightClick, rowData = _ref.rowData, style = _ref.style; var a11yProps = { 'aria-rowindex': index + 1 }; if (onRowClick || onRowDoubleClick || onRowMouseOut || onRowMouseOver || onRowRightClick) { a11yProps['aria-label'] = 'row'; a11yProps.tabIndex = 0; if (onRowClick) { a11yProps.onClick = function (event) { return onRowClick({ event: event, index: index, rowData: rowData }); }; } if (onRowDoubleClick) { a11yProps.onDoubleClick = function (event) { return onRowDoubleClick({ event: event, index: index, rowData: rowData }); }; } if (onRowMouseOut) { a11yProps.onMouseOut = function (event) { return onRowMouseOut({ event: event, index: index, rowData: rowData }); }; } if (onRowMouseOver) { a11yProps.onMouseOver = function (event) { return onRowMouseOver({ event: event, index: index, rowData: rowData }); }; } if (onRowRightClick) { a11yProps.onContextMenu = function (event) { return onRowRightClick({ event: event, index: index, rowData: rowData }); }; } } return React.createElement("div", _extends({}, a11yProps, { className: className, key: key, role: "row", style: style }), columns); } defaultRowRenderer.propTypes = process.env.NODE_ENV === 'production' ? null : bpfrpt_proptype_RowRendererParams === PropTypes.any ? {} : bpfrpt_proptype_RowRendererParams; import { bpfrpt_proptype_RowRendererParams } from "./types"; import PropTypes from "prop-types";dist/es/Table/index.js000064400000001306151676725770010641 0ustar00import createMultiSort from './createMultiSort'; import defaultCellDataGetter from './defaultCellDataGetter'; import defaultCellRenderer from './defaultCellRenderer'; import defaultHeaderRowRenderer from './defaultHeaderRowRenderer.js'; import defaultHeaderRenderer from './defaultHeaderRenderer'; import defaultRowRenderer from './defaultRowRenderer'; import Column from './Column'; import SortDirection from './SortDirection'; import SortIndicator from './SortIndicator'; import Table from './Table'; export default Table; export { createMultiSort, defaultCellDataGetter, defaultCellRenderer, defaultHeaderRowRenderer, defaultHeaderRenderer, defaultRowRenderer, Column, SortDirection, SortIndicator, Table };dist/es/Table/SortIndicator.js000064400000002121151676725770012312 0ustar00import clsx from 'clsx'; import PropTypes from 'prop-types'; import * as React from 'react'; import SortDirection from './SortDirection'; /** * Displayed beside a header to indicate that a Table is currently sorted by this column. */ export default function SortIndicator(_ref) { var sortDirection = _ref.sortDirection; var classNames = clsx('ReactVirtualized__Table__sortableHeaderIcon', { 'ReactVirtualized__Table__sortableHeaderIcon--ASC': sortDirection === SortDirection.ASC, 'ReactVirtualized__Table__sortableHeaderIcon--DESC': sortDirection === SortDirection.DESC }); return React.createElement("svg", { className: classNames, width: 18, height: 18, viewBox: "0 0 24 24" }, sortDirection === SortDirection.ASC ? React.createElement("path", { d: "M7 14l5-5 5 5z" }) : React.createElement("path", { d: "M7 10l5 5 5-5z" }), React.createElement("path", { d: "M0 0h24v24H0z", fill: "none" })); } SortIndicator.propTypes = process.env.NODE_ENV !== "production" ? { sortDirection: PropTypes.oneOf([SortDirection.ASC, SortDirection.DESC]) } : {};dist/es/Table/Table.example.js000064400000027052151676725770012221 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import Immutable from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import { LabeledInput, InputRow } from '../demo/LabeledInput'; import AutoSizer from '../AutoSizer'; import Column from './Column'; import Table from './Table'; import SortDirection from './SortDirection'; import SortIndicator from './SortIndicator'; import styles from './Table.example.css'; var TableExample = /*#__PURE__*/ function (_React$PureComponent) { _inherits(TableExample, _React$PureComponent); function TableExample(props, context) { var _this; _classCallCheck(this, TableExample); _this = _possibleConstructorReturn(this, _getPrototypeOf(TableExample).call(this, props, context)); var sortBy = 'index'; var sortDirection = SortDirection.ASC; var sortedList = _this._sortList({ sortBy: sortBy, sortDirection: sortDirection }); _this.state = { disableHeader: false, headerHeight: 30, height: 270, hideIndexRow: false, overscanRowCount: 10, rowHeight: 40, rowCount: 1000, scrollToIndex: undefined, sortBy: sortBy, sortDirection: sortDirection, sortedList: sortedList, useDynamicRowHeight: false }; _this._getRowHeight = _this._getRowHeight.bind(_assertThisInitialized(_this)); _this._headerRenderer = _this._headerRenderer.bind(_assertThisInitialized(_this)); _this._noRowsRenderer = _this._noRowsRenderer.bind(_assertThisInitialized(_this)); _this._onRowCountChange = _this._onRowCountChange.bind(_assertThisInitialized(_this)); _this._onScrollToRowChange = _this._onScrollToRowChange.bind(_assertThisInitialized(_this)); _this._rowClassName = _this._rowClassName.bind(_assertThisInitialized(_this)); _this._sort = _this._sort.bind(_assertThisInitialized(_this)); return _this; } _createClass(TableExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, disableHeader = _this$state.disableHeader, headerHeight = _this$state.headerHeight, height = _this$state.height, hideIndexRow = _this$state.hideIndexRow, overscanRowCount = _this$state.overscanRowCount, rowHeight = _this$state.rowHeight, rowCount = _this$state.rowCount, scrollToIndex = _this$state.scrollToIndex, sortBy = _this$state.sortBy, sortDirection = _this$state.sortDirection, sortedList = _this$state.sortedList, useDynamicRowHeight = _this$state.useDynamicRowHeight; var rowGetter = function rowGetter(_ref) { var index = _ref.index; return _this2._getDatum(sortedList, index); }; return React.createElement(ContentBox, null, React.createElement(ContentBoxHeader, { text: "Table", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/Table/Table.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/Table.md" }), React.createElement(ContentBoxParagraph, null, "The table layout below is created with flexboxes. This allows it to have a fixed header and scrollable body content. It also makes use of", ' ', React.createElement("code", null, "Grid"), " for windowing table content so that large lists are rendered efficiently. Adjust its configurable properties below to see how it reacts."), React.createElement(ContentBoxParagraph, null, React.createElement("label", { className: styles.checkboxLabel }, React.createElement("input", { "aria-label": "Use dynamic row heights?", checked: useDynamicRowHeight, className: styles.checkbox, type: "checkbox", onChange: function onChange(event) { return _this2._updateUseDynamicRowHeight(event.target.checked); } }), "Use dynamic row heights?"), React.createElement("label", { className: styles.checkboxLabel }, React.createElement("input", { "aria-label": "Hide index?", checked: hideIndexRow, className: styles.checkbox, type: "checkbox", onChange: function onChange(event) { return _this2.setState({ hideIndexRow: event.target.checked }); } }), "Hide index?"), React.createElement("label", { className: styles.checkboxLabel }, React.createElement("input", { "aria-label": "Hide header?", checked: disableHeader, className: styles.checkbox, type: "checkbox", onChange: function onChange(event) { return _this2.setState({ disableHeader: event.target.checked }); } }), "Hide header?")), React.createElement(InputRow, null, React.createElement(LabeledInput, { label: "Num rows", name: "rowCount", onChange: this._onRowCountChange, value: rowCount }), React.createElement(LabeledInput, { label: "Scroll to", name: "onScrollToRow", placeholder: "Index...", onChange: this._onScrollToRowChange, value: scrollToIndex || '' }), React.createElement(LabeledInput, { label: "List height", name: "height", onChange: function onChange(event) { return _this2.setState({ height: parseInt(event.target.value, 10) || 1 }); }, value: height }), React.createElement(LabeledInput, { disabled: useDynamicRowHeight, label: "Row height", name: "rowHeight", onChange: function onChange(event) { return _this2.setState({ rowHeight: parseInt(event.target.value, 10) || 1 }); }, value: rowHeight }), React.createElement(LabeledInput, { label: "Header height", name: "headerHeight", onChange: function onChange(event) { return _this2.setState({ headerHeight: parseInt(event.target.value, 10) || 1 }); }, value: headerHeight }), React.createElement(LabeledInput, { label: "Overscan", name: "overscanRowCount", onChange: function onChange(event) { return _this2.setState({ overscanRowCount: parseInt(event.target.value, 10) || 0 }); }, value: overscanRowCount })), React.createElement("div", null, React.createElement(AutoSizer, { disableHeight: true }, function (_ref2) { var width = _ref2.width; return React.createElement(Table, { ref: "Table", disableHeader: disableHeader, headerClassName: styles.headerColumn, headerHeight: headerHeight, height: height, noRowsRenderer: _this2._noRowsRenderer, overscanRowCount: overscanRowCount, rowClassName: _this2._rowClassName, rowHeight: useDynamicRowHeight ? _this2._getRowHeight : rowHeight, rowGetter: rowGetter, rowCount: rowCount, scrollToIndex: scrollToIndex, sort: _this2._sort, sortBy: sortBy, sortDirection: sortDirection, width: width }, !hideIndexRow && React.createElement(Column, { label: "Index", cellDataGetter: function cellDataGetter(_ref3) { var rowData = _ref3.rowData; return rowData.index; }, dataKey: "index", disableSort: !_this2._isSortEnabled(), width: 60 }), React.createElement(Column, { dataKey: "name", disableSort: !_this2._isSortEnabled(), headerRenderer: _this2._headerRenderer, width: 90 }), React.createElement(Column, { width: 210, disableSort: true, label: "The description label is really long so that it will be truncated", dataKey: "random", className: styles.exampleColumn, cellRenderer: function cellRenderer(_ref4) { var cellData = _ref4.cellData; return cellData; }, flexGrow: 1 })); }))); } }, { key: "_getDatum", value: function _getDatum(list, index) { return list.get(index % list.size); } }, { key: "_getRowHeight", value: function _getRowHeight(_ref5) { var index = _ref5.index; var list = this.context.list; return this._getDatum(list, index).size; } }, { key: "_headerRenderer", value: function _headerRenderer(_ref6) { var dataKey = _ref6.dataKey, sortBy = _ref6.sortBy, sortDirection = _ref6.sortDirection; return React.createElement("div", null, "Full Name", sortBy === dataKey && React.createElement(SortIndicator, { sortDirection: sortDirection })); } }, { key: "_isSortEnabled", value: function _isSortEnabled() { var list = this.context.list; var rowCount = this.state.rowCount; return rowCount <= list.size; } }, { key: "_noRowsRenderer", value: function _noRowsRenderer() { return React.createElement("div", { className: styles.noRows }, "No rows"); } }, { key: "_onRowCountChange", value: function _onRowCountChange(event) { var rowCount = parseInt(event.target.value, 10) || 0; this.setState({ rowCount: rowCount }); } }, { key: "_onScrollToRowChange", value: function _onScrollToRowChange(event) { var rowCount = this.state.rowCount; var scrollToIndex = Math.min(rowCount - 1, parseInt(event.target.value, 10)); if (isNaN(scrollToIndex)) { scrollToIndex = undefined; } this.setState({ scrollToIndex: scrollToIndex }); } }, { key: "_rowClassName", value: function _rowClassName(_ref7) { var index = _ref7.index; if (index < 0) { return styles.headerRow; } else { return index % 2 === 0 ? styles.evenRow : styles.oddRow; } } }, { key: "_sort", value: function _sort(_ref8) { var sortBy = _ref8.sortBy, sortDirection = _ref8.sortDirection; var sortedList = this._sortList({ sortBy: sortBy, sortDirection: sortDirection }); this.setState({ sortBy: sortBy, sortDirection: sortDirection, sortedList: sortedList }); } }, { key: "_sortList", value: function _sortList(_ref9) { var sortBy = _ref9.sortBy, sortDirection = _ref9.sortDirection; var list = this.context.list; return list.sortBy(function (item) { return item[sortBy]; }).update(function (list) { return sortDirection === SortDirection.DESC ? list.reverse() : list; }); } }, { key: "_updateUseDynamicRowHeight", value: function _updateUseDynamicRowHeight(value) { this.setState({ useDynamicRowHeight: value }); } }]); return TableExample; }(React.PureComponent); _defineProperty(TableExample, "contextTypes", { list: PropTypes.instanceOf(Immutable.List).isRequired }); export { TableExample as default };dist/es/Table/SortDirection.js000064400000000525151676725770012324 0ustar00var SortDirection = { /** * Sort items in ascending order. * This means arranging from the lowest value to the highest (e.g. a-z, 0-9). */ ASC: 'ASC', /** * Sort items in descending order. * This means arranging from the highest value to the lowest (e.g. z-a, 9-0). */ DESC: 'DESC' }; export default SortDirection;dist/es/Table/defaultHeaderRenderer.js000064400000001752151676725770013763 0ustar00import * as React from 'react'; import SortIndicator from './SortIndicator'; /** * Default table header renderer. */ export default function defaultHeaderRenderer(_ref) { var dataKey = _ref.dataKey, label = _ref.label, sortBy = _ref.sortBy, sortDirection = _ref.sortDirection; var showSortIndicator = sortBy === dataKey; var children = [React.createElement("span", { className: "ReactVirtualized__Table__headerTruncatedText", key: "label", title: typeof label === 'string' ? label : null }, label)]; if (showSortIndicator) { children.push(React.createElement(SortIndicator, { key: "SortIndicator", sortDirection: sortDirection })); } return children; } defaultHeaderRenderer.propTypes = process.env.NODE_ENV === 'production' ? null : bpfrpt_proptype_HeaderRendererParams === PropTypes.any ? {} : bpfrpt_proptype_HeaderRendererParams; import { bpfrpt_proptype_HeaderRendererParams } from "./types"; import PropTypes from "prop-types";dist/es/Table/Column.jest.js000064400000005011151676725770011730 0ustar00import * as React from 'react'; import Immutable from 'immutable'; import defaultCellDataGetter from './defaultCellDataGetter'; import defaultCellRenderer from './defaultCellRenderer'; import defaultHeaderRenderer from './defaultHeaderRenderer'; describe('Column', function () { var rowData = Immutable.Map({ foo: 'Foo', bar: 1 }); describe('defaultCellDataGetter', function () { it('should return a value for specified attributes', function () { expect(defaultCellDataGetter({ dataKey: 'foo', rowData: rowData })).toEqual('Foo'); expect(defaultCellDataGetter({ dataKey: 'bar', rowData: rowData })).toEqual(1); }); it('should return undefined for missing attributes', function () { expect(defaultCellDataGetter({ dataKey: 'baz', rowData: rowData })).toEqual(undefined); }); }); describe('defaultCellRenderer', function () { it('should render a value for specified attributes', function () { expect(defaultCellRenderer({ cellData: 'Foo', dataKey: 'foo', rowData: rowData, rowIndex: 0 })).toEqual('Foo'); expect(defaultCellRenderer({ cellData: 1, dataKey: 'bar', rowData: rowData, rowIndex: 0 })).toEqual('1'); }); it('should render empty string for null or missing attributes', function () { expect(defaultCellRenderer({ cellData: null, dataKey: 'baz', rowData: rowData, rowIndex: 0 })).toEqual(''); expect(defaultCellRenderer({ cellData: undefined, dataKey: 'baz', rowData: rowData, rowIndex: 0 })).toEqual(''); }); }); describe('defaultHeaderRenderer', function () { it('should render a value for specified attributes', function () { expect(defaultHeaderRenderer({ dataKey: 'foo', label: 'squirrel' })[0].props.children).toEqual('squirrel'); var label = React.createElement("div", { className: "rabbit" }, "Rabbit"); expect(defaultHeaderRenderer({ dataKey: 'bar', label: label })[0].props.children).toEqual(label); }); it('should render empty string for null or missing attributes', function () { expect(defaultHeaderRenderer({ dataKey: 'foo', label: null })[0].props.children).toBeNull(); expect(defaultHeaderRenderer({ dataKey: 'bar', label: undefined })[0].props.children).toBeUndefined(); }); }); });dist/es/Table/defaultCellDataGetter.js000064400000001054151676725770013723 0ustar00/** * Default accessor for returning a cell value for a given attribute. * This function expects to operate on either a vanilla Object or an Immutable Map. * You should override the column's cellDataGetter if your data is some other type of object. */ export default function defaultCellDataGetter(_ref) { var dataKey = _ref.dataKey, rowData = _ref.rowData; if (typeof rowData.get === 'function') { return rowData.get(dataKey); } else { return rowData[dataKey]; } } import { bpfrpt_proptype_CellDataGetterParams } from "./types";dist/es/Table/defaultHeaderRowRenderer.js000064400000001112151676725770014441 0ustar00import * as React from 'react'; export default function defaultHeaderRowRenderer(_ref) { var className = _ref.className, columns = _ref.columns, style = _ref.style; return React.createElement("div", { className: className, role: "row", style: style }, columns); } defaultHeaderRowRenderer.propTypes = process.env.NODE_ENV === 'production' ? null : bpfrpt_proptype_HeaderRowRendererParams === PropTypes.any ? {} : bpfrpt_proptype_HeaderRowRendererParams; import { bpfrpt_proptype_HeaderRowRendererParams } from "./types"; import PropTypes from "prop-types";dist/es/CellMeasurer/CellMeasurer.DynamicWidthMultiGrid.example.js000064400000010372151676725770021312 0ustar00import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import Immutable from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import CellMeasurer from './CellMeasurer'; import CellMeasurerCache from './CellMeasurerCache'; import MultiGrid from '../MultiGrid'; import styles from './CellMeasurer.example.css'; var DynamicWidthMultiGrid = /*#__PURE__*/ function (_React$PureComponent) { _inherits(DynamicWidthMultiGrid, _React$PureComponent); function DynamicWidthMultiGrid(props, context) { var _this; _classCallCheck(this, DynamicWidthMultiGrid); _this = _possibleConstructorReturn(this, _getPrototypeOf(DynamicWidthMultiGrid).call(this, props, context)); _this._cache = new CellMeasurerCache({ defaultHeight: 30, defaultWidth: 150, fixedHeight: true }); _this._cellRenderer = _this._cellRenderer.bind(_assertThisInitialized(_this)); return _this; } _createClass(DynamicWidthMultiGrid, [{ key: "render", value: function render() { var width = this.props.width; return React.createElement(MultiGrid, { className: styles.BodyGrid, columnCount: 50, columnWidth: this._cache.columnWidth, deferredMeasurementCache: this._cache, fixedColumnCount: 1, fixedRowCount: 0, height: 400, overscanColumnCount: 0, overscanRowCount: 0, cellRenderer: this._cellRenderer, rowCount: 50, rowHeight: 30, width: width }); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref) { var columnIndex = _ref.columnIndex, key = _ref.key, parent = _ref.parent, rowIndex = _ref.rowIndex, style = _ref.style; var _this$props = this.props, getClassName = _this$props.getClassName, getContent = _this$props.getContent, list = _this$props.list; var datum = list.get((rowIndex + columnIndex) % list.size); var classNames = getClassName({ columnIndex: columnIndex, rowIndex: rowIndex }); var content = getContent({ index: rowIndex, datum: datum, "long": false }); if (columnIndex === 0) { content = content.substr(0, 50); } return React.createElement(CellMeasurer, { cache: this._cache, columnIndex: columnIndex, key: key, parent: parent, rowIndex: rowIndex }, React.createElement("div", { className: classNames, style: _objectSpread({}, style, { whiteSpace: 'nowrap' }) }, content)); } }]); return DynamicWidthMultiGrid; }(React.PureComponent); export { DynamicWidthMultiGrid as default }; DynamicWidthMultiGrid.propTypes = process.env.NODE_ENV !== "production" ? { getClassName: PropTypes.func.isRequired, getContent: PropTypes.func.isRequired, list: PropTypes.instanceOf(Immutable.List).isRequired, width: PropTypes.number.isRequired } : {};dist/es/CellMeasurer/types.js000064400000000642151676725770012234 0ustar00var bpfrpt_proptype_CellMeasureCache = process.env.NODE_ENV === 'production' ? null : { "hasFixedWidth": PropTypes.func.isRequired, "hasFixedHeight": PropTypes.func.isRequired, "has": PropTypes.func.isRequired, "set": PropTypes.func.isRequired, "getHeight": PropTypes.func.isRequired, "getWidth": PropTypes.func.isRequired }; import PropTypes from "prop-types"; export { bpfrpt_proptype_CellMeasureCache };dist/es/CellMeasurer/CellMeasurerCache.js000064400000017010151676725770014374 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; export var DEFAULT_HEIGHT = 30; export var DEFAULT_WIDTH = 100; // Enables more intelligent mapping of a given column and row index to an item ID. // This prevents a cell cache from being invalidated when its parent collection is modified. /** * Caches measurements for a given cell. */ var CellMeasurerCache = /*#__PURE__*/ function () { function CellMeasurerCache() { var _this = this; var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, CellMeasurerCache); _defineProperty(this, "_cellHeightCache", {}); _defineProperty(this, "_cellWidthCache", {}); _defineProperty(this, "_columnWidthCache", {}); _defineProperty(this, "_rowHeightCache", {}); _defineProperty(this, "_defaultHeight", void 0); _defineProperty(this, "_defaultWidth", void 0); _defineProperty(this, "_minHeight", void 0); _defineProperty(this, "_minWidth", void 0); _defineProperty(this, "_keyMapper", void 0); _defineProperty(this, "_hasFixedHeight", void 0); _defineProperty(this, "_hasFixedWidth", void 0); _defineProperty(this, "_columnCount", 0); _defineProperty(this, "_rowCount", 0); _defineProperty(this, "columnWidth", function (_ref) { var index = _ref.index; var key = _this._keyMapper(0, index); return _this._columnWidthCache[key] !== undefined ? _this._columnWidthCache[key] : _this._defaultWidth; }); _defineProperty(this, "rowHeight", function (_ref2) { var index = _ref2.index; var key = _this._keyMapper(index, 0); return _this._rowHeightCache[key] !== undefined ? _this._rowHeightCache[key] : _this._defaultHeight; }); var defaultHeight = params.defaultHeight, defaultWidth = params.defaultWidth, fixedHeight = params.fixedHeight, fixedWidth = params.fixedWidth, keyMapper = params.keyMapper, minHeight = params.minHeight, minWidth = params.minWidth; this._hasFixedHeight = fixedHeight === true; this._hasFixedWidth = fixedWidth === true; this._minHeight = minHeight || 0; this._minWidth = minWidth || 0; this._keyMapper = keyMapper || defaultKeyMapper; this._defaultHeight = Math.max(this._minHeight, typeof defaultHeight === 'number' ? defaultHeight : DEFAULT_HEIGHT); this._defaultWidth = Math.max(this._minWidth, typeof defaultWidth === 'number' ? defaultWidth : DEFAULT_WIDTH); if (process.env.NODE_ENV !== 'production') { if (this._hasFixedHeight === false && this._hasFixedWidth === false) { console.warn("CellMeasurerCache should only measure a cell's width or height. " + 'You have configured CellMeasurerCache to measure both. ' + 'This will result in poor performance.'); } if (this._hasFixedHeight === false && this._defaultHeight === 0) { console.warn('Fixed height CellMeasurerCache should specify a :defaultHeight greater than 0. ' + 'Failing to do so will lead to unnecessary layout and poor performance.'); } if (this._hasFixedWidth === false && this._defaultWidth === 0) { console.warn('Fixed width CellMeasurerCache should specify a :defaultWidth greater than 0. ' + 'Failing to do so will lead to unnecessary layout and poor performance.'); } } } _createClass(CellMeasurerCache, [{ key: "clear", value: function clear(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var key = this._keyMapper(rowIndex, columnIndex); delete this._cellHeightCache[key]; delete this._cellWidthCache[key]; this._updateCachedColumnAndRowSizes(rowIndex, columnIndex); } }, { key: "clearAll", value: function clearAll() { this._cellHeightCache = {}; this._cellWidthCache = {}; this._columnWidthCache = {}; this._rowHeightCache = {}; this._rowCount = 0; this._columnCount = 0; } }, { key: "hasFixedHeight", value: function hasFixedHeight() { return this._hasFixedHeight; } }, { key: "hasFixedWidth", value: function hasFixedWidth() { return this._hasFixedWidth; } }, { key: "getHeight", value: function getHeight(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; if (this._hasFixedHeight) { return this._defaultHeight; } else { var _key = this._keyMapper(rowIndex, columnIndex); return this._cellHeightCache[_key] !== undefined ? Math.max(this._minHeight, this._cellHeightCache[_key]) : this._defaultHeight; } } }, { key: "getWidth", value: function getWidth(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; if (this._hasFixedWidth) { return this._defaultWidth; } else { var _key2 = this._keyMapper(rowIndex, columnIndex); return this._cellWidthCache[_key2] !== undefined ? Math.max(this._minWidth, this._cellWidthCache[_key2]) : this._defaultWidth; } } }, { key: "has", value: function has(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var key = this._keyMapper(rowIndex, columnIndex); return this._cellHeightCache[key] !== undefined; } }, { key: "set", value: function set(rowIndex, columnIndex, width, height) { var key = this._keyMapper(rowIndex, columnIndex); if (columnIndex >= this._columnCount) { this._columnCount = columnIndex + 1; } if (rowIndex >= this._rowCount) { this._rowCount = rowIndex + 1; } // Size is cached per cell so we don't have to re-measure if cells are re-ordered. this._cellHeightCache[key] = height; this._cellWidthCache[key] = width; this._updateCachedColumnAndRowSizes(rowIndex, columnIndex); } }, { key: "_updateCachedColumnAndRowSizes", value: function _updateCachedColumnAndRowSizes(rowIndex, columnIndex) { // :columnWidth and :rowHeight are derived based on all cells in a column/row. // Pre-cache these derived values for faster lookup later. // Reads are expected to occur more frequently than writes in this case. // Only update non-fixed dimensions though to avoid doing unnecessary work. if (!this._hasFixedWidth) { var columnWidth = 0; for (var i = 0; i < this._rowCount; i++) { columnWidth = Math.max(columnWidth, this.getWidth(i, columnIndex)); } var columnKey = this._keyMapper(0, columnIndex); this._columnWidthCache[columnKey] = columnWidth; } if (!this._hasFixedHeight) { var rowHeight = 0; for (var _i = 0; _i < this._columnCount; _i++) { rowHeight = Math.max(rowHeight, this.getHeight(rowIndex, _i)); } var rowKey = this._keyMapper(rowIndex, 0); this._rowHeightCache[rowKey] = rowHeight; } } }, { key: "defaultHeight", get: function get() { return this._defaultHeight; } }, { key: "defaultWidth", get: function get() { return this._defaultWidth; } }]); return CellMeasurerCache; }(); export { CellMeasurerCache as default }; function defaultKeyMapper(rowIndex, columnIndex) { return "".concat(rowIndex, "-").concat(columnIndex); } import { bpfrpt_proptype_CellMeasureCache } from "./types";dist/es/CellMeasurer/CellMeasurer.DynamicHeightGrid.example.js000064400000010004151676725770020420 0ustar00import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import Immutable from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import CellMeasurer from './CellMeasurer'; import CellMeasurerCache from './CellMeasurerCache'; import Grid from '../Grid'; import styles from './CellMeasurer.example.css'; var DynamicHeightGrid = /*#__PURE__*/ function (_React$PureComponent) { _inherits(DynamicHeightGrid, _React$PureComponent); function DynamicHeightGrid(props, context) { var _this; _classCallCheck(this, DynamicHeightGrid); _this = _possibleConstructorReturn(this, _getPrototypeOf(DynamicHeightGrid).call(this, props, context)); _this._cache = new CellMeasurerCache({ defaultWidth: 150, fixedWidth: true }); _this._cellRenderer = _this._cellRenderer.bind(_assertThisInitialized(_this)); return _this; } _createClass(DynamicHeightGrid, [{ key: "render", value: function render() { var width = this.props.width; return React.createElement(Grid, { className: styles.BodyGrid, columnCount: 50, columnWidth: 150, deferredMeasurementCache: this._cache, height: 400, overscanColumnCount: 0, overscanRowCount: 2, cellRenderer: this._cellRenderer, rowCount: 1000, rowHeight: this._cache.rowHeight, width: width }); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref) { var columnIndex = _ref.columnIndex, key = _ref.key, parent = _ref.parent, rowIndex = _ref.rowIndex, style = _ref.style; var _this$props = this.props, getClassName = _this$props.getClassName, getContent = _this$props.getContent, list = _this$props.list; var datum = list.get((rowIndex + columnIndex) % list.size); var classNames = getClassName({ columnIndex: columnIndex, rowIndex: rowIndex }); var content = getContent({ index: rowIndex, datum: datum }); return React.createElement(CellMeasurer, { cache: this._cache, columnIndex: columnIndex, key: key, parent: parent, rowIndex: rowIndex }, React.createElement("div", { className: classNames, style: _objectSpread({}, style, { width: 150 }) }, content)); } }]); return DynamicHeightGrid; }(React.PureComponent); export { DynamicHeightGrid as default }; DynamicHeightGrid.propTypes = process.env.NODE_ENV !== "production" ? { getClassName: PropTypes.func.isRequired, getContent: PropTypes.func.isRequired, list: PropTypes.instanceOf(Immutable.List).isRequired, width: PropTypes.number.isRequired } : {};dist/es/CellMeasurer/index.js000064400000000250151676725770012172 0ustar00import CellMeasurer from './CellMeasurer'; import CellMeasurerCache from './CellMeasurerCache'; export default CellMeasurer; export { CellMeasurer, CellMeasurerCache };dist/es/CellMeasurer/CellMeasurer.example.js000064400000012213151676725770015102 0ustar00import _extends from "@babel/runtime/helpers/extends"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import Immutable from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import AutoSizer from '../AutoSizer'; import clsx from 'clsx'; import styles from './CellMeasurer.example.css'; import DynamicWidthGrid from './CellMeasurer.DynamicWidthGrid.example.js'; import DynamicHeightGrid from './CellMeasurer.DynamicHeightGrid.example.js'; import DynamicWidthMultiGrid from './CellMeasurer.DynamicWidthMultiGrid.example.js'; import DynamicHeightList from './CellMeasurer.DynamicHeightList.example.js'; import DynamicHeightTableColumn from './CellMeasurer.DynamicHeightTableColumn.example.js'; var demoComponents = [DynamicWidthGrid, DynamicHeightGrid, DynamicWidthMultiGrid, DynamicHeightList, DynamicHeightTableColumn]; var CellMeasurerExample = /*#__PURE__*/ function (_React$PureComponent) { _inherits(CellMeasurerExample, _React$PureComponent); function CellMeasurerExample(props, context) { var _this; _classCallCheck(this, CellMeasurerExample); _this = _possibleConstructorReturn(this, _getPrototypeOf(CellMeasurerExample).call(this, props, context)); _this.state = { currentTab: 0 }; _this._onClick = _this._onClick.bind(_assertThisInitialized(_this)); return _this; } _createClass(CellMeasurerExample, [{ key: "render", value: function render() { var list = this.context.list; var currentTab = this.state.currentTab; var buttonProps = { currentTab: currentTab, onClick: this._onClick }; var DemoComponent = demoComponents[currentTab]; return React.createElement(ContentBox, null, React.createElement(ContentBoxHeader, { text: "CellMeasurer", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/CellMeasurer/CellMeasurer.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/CellMeasurer.md" }), React.createElement(ContentBoxParagraph, null, "This component can be used to just-in-time measure dynamic content (eg. messages in a chat interface)."), React.createElement(AutoSizer, { disableHeight: true }, function (_ref) { var width = _ref.width; return React.createElement("div", { style: { width: width } }, React.createElement("div", null, React.createElement("strong", null, "Grid"), ":", React.createElement(Tab, _extends({ id: 0 }, buttonProps), "dynamic width text"), React.createElement(Tab, _extends({ id: 1 }, buttonProps), "dynamic height text"), React.createElement("strong", null, "MultiGrid"), ":", React.createElement(Tab, _extends({ id: 2 }, buttonProps), "dynamic width text"), React.createElement("strong", null, "List"), ":", React.createElement(Tab, _extends({ id: 3 }, buttonProps), "dynamic height image"), React.createElement("strong", null, "Table"), ":", React.createElement(Tab, _extends({ id: 4 }, buttonProps), "mixed fixed and dynamic height text")), React.createElement(DemoComponent, { getClassName: getClassName, getContent: getContent, list: list, width: width })); })); } }, { key: "_onClick", value: function _onClick(id) { this.setState({ currentTab: id }); } }]); return CellMeasurerExample; }(React.PureComponent); _defineProperty(CellMeasurerExample, "contextTypes", { list: PropTypes.instanceOf(Immutable.List).isRequired }); export { CellMeasurerExample as default }; function getClassName(_ref2) { var columnIndex = _ref2.columnIndex, rowIndex = _ref2.rowIndex; var rowClass = rowIndex % 2 === 0 ? styles.evenRow : styles.oddRow; return clsx(rowClass, styles.cell, _defineProperty({}, styles.centeredCell, columnIndex > 2)); } function getContent(_ref3) { var index = _ref3.index, datum = _ref3.datum, _ref3$long = _ref3["long"], _long = _ref3$long === void 0 ? true : _ref3$long; switch (index % 3) { case 0: return datum.color; case 1: return datum.name; case 2: return _long ? datum.randomLong : datum.random; } } function Tab(_ref4) { var children = _ref4.children, currentTab = _ref4.currentTab, id = _ref4.id, _onClick2 = _ref4.onClick; var classNames = clsx(styles.Tab, _defineProperty({}, styles.ActiveTab, currentTab === id)); return React.createElement("button", { className: classNames, onClick: function onClick() { return _onClick2(id); } }, children); }dist/es/CellMeasurer/CellMeasurer.DynamicHeightTableColumn.example.js000064400000007470151676725770021755 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import Immutable from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import CellMeasurer from './CellMeasurer'; import CellMeasurerCache from './CellMeasurerCache'; import { Column, Table } from '../Table'; import styles from './CellMeasurer.example.css'; var DynamicHeightTableColumn = /*#__PURE__*/ function (_React$PureComponent) { _inherits(DynamicHeightTableColumn, _React$PureComponent); function DynamicHeightTableColumn() { var _getPrototypeOf2; var _this; _classCallCheck(this, DynamicHeightTableColumn); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(DynamicHeightTableColumn)).call.apply(_getPrototypeOf2, [this].concat(args))); _defineProperty(_assertThisInitialized(_this), "_cache", new CellMeasurerCache({ fixedWidth: true, minHeight: 25 })); _defineProperty(_assertThisInitialized(_this), "_lastRenderedWidth", _this.props.width); _defineProperty(_assertThisInitialized(_this), "_columnCellRenderer", function (_ref) { var dataKey = _ref.dataKey, parent = _ref.parent, rowIndex = _ref.rowIndex; var list = _this.props.list; var datum = list.get(rowIndex % list.size); var content = rowIndex % 5 === 0 ? '' : datum.randomLong; return React.createElement(CellMeasurer, { cache: _this._cache, columnIndex: 0, key: dataKey, parent: parent, rowIndex: rowIndex }, React.createElement("div", { className: styles.tableColumn, style: { whiteSpace: 'normal' } }, content)); }); _defineProperty(_assertThisInitialized(_this), "_rowGetter", function (_ref2) { var index = _ref2.index; var list = _this.props.list; return list.get(index % list.size); }); return _this; } _createClass(DynamicHeightTableColumn, [{ key: "render", value: function render() { var width = this.props.width; if (this._lastRenderedWidth !== this.props.width) { this._lastRenderedWidth = this.props.width; this._cache.clearAll(); } return React.createElement(Table, { deferredMeasurementCache: this._cache, headerHeight: 20, height: 400, overscanRowCount: 2, rowClassName: styles.tableRow, rowHeight: this._cache.rowHeight, rowGetter: this._rowGetter, rowCount: 1000, width: width }, React.createElement(Column, { className: styles.tableColumn, dataKey: "name", label: "Name", width: 125 }), React.createElement(Column, { className: styles.tableColumn, dataKey: "color", label: "Color", width: 75 }), React.createElement(Column, { width: width - 200, dataKey: "random", label: "Dynamic text", cellRenderer: this._columnCellRenderer })); } }]); return DynamicHeightTableColumn; }(React.PureComponent); export { DynamicHeightTableColumn as default }; DynamicHeightTableColumn.propTypes = process.env.NODE_ENV !== "production" ? { list: PropTypes.instanceOf(Immutable.List).isRequired, width: PropTypes.number.isRequired } : {};dist/es/CellMeasurer/CellMeasurer.jest.js000064400000025003151676725770014415 0ustar00import * as React from 'react'; import { findDOMNode } from 'react-dom'; import { render } from '../TestUtils'; import CellMeasurer from './CellMeasurer'; import CellMeasurerCache, { DEFAULT_HEIGHT, DEFAULT_WIDTH } from './CellMeasurerCache'; // Accounts for the fact that JSDom doesn't support measurements. function mockClientWidthAndHeight(_ref) { var height = _ref.height, width = _ref.width; var object = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : HTMLElement.prototype; var heightFn = jest.fn().mockReturnValue(height); var widthFn = jest.fn().mockReturnValue(width); Object.defineProperty(object, 'offsetHeight', { configurable: true, get: heightFn }); Object.defineProperty(object, 'offsetWidth', { configurable: true, get: widthFn }); return { heightFn: heightFn, widthFn: widthFn }; } function createParent() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, cache = _ref2.cache, _ref2$invalidateCellS = _ref2.invalidateCellSizeAfterRender, invalidateCellSizeAfterRender = _ref2$invalidateCellS === void 0 ? jest.fn() : _ref2$invalidateCellS; return { invalidateCellSizeAfterRender: invalidateCellSizeAfterRender, props: { deferredMeasurementCache: cache } }; } function renderHelper() { var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref3$cache = _ref3.cache, cache = _ref3$cache === void 0 ? new CellMeasurerCache({ fixedWidth: true }) : _ref3$cache, _ref3$children = _ref3.children, children = _ref3$children === void 0 ? React.createElement("div", null) : _ref3$children, parent = _ref3.parent; render(React.createElement(CellMeasurer, { cache: cache, columnIndex: 0, parent: parent, rowIndex: 0, style: {} }, children)); } describe('CellMeasurer', function () { it('componentDidMount() should measure content that is not already in the cache', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); var parent = createParent({ cache: cache }); var _mockClientWidthAndHe = mockClientWidthAndHeight({ height: 20, width: 100 }), heightFn = _mockClientWidthAndHe.heightFn, widthFn = _mockClientWidthAndHe.widthFn; expect(heightFn).toHaveBeenCalledTimes(0); expect(widthFn).toHaveBeenCalledTimes(0); expect(cache.has(0, 0)).toBe(false); renderHelper({ cache: cache, parent: parent }); expect(parent.invalidateCellSizeAfterRender).toHaveBeenCalled(); expect(heightFn).toHaveBeenCalledTimes(1); expect(widthFn).toHaveBeenCalledTimes(1); expect(cache.has(0, 0)).toBe(true); expect(cache.getWidth(0, 0)).toBe(100); expect(cache.getHeight(0, 0)).toBe(20); }); it('componentDidMount() should not measure content that is already in the cache', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); cache.set(0, 0, 100, 20); var parent = createParent({ cache: cache }); var _mockClientWidthAndHe2 = mockClientWidthAndHeight({ height: 20, width: 100 }), heightFn = _mockClientWidthAndHe2.heightFn, widthFn = _mockClientWidthAndHe2.widthFn; expect(cache.has(0, 0)).toBe(true); renderHelper({ cache: cache, parent: parent }); expect(parent.invalidateCellSizeAfterRender).not.toHaveBeenCalled(); expect(heightFn).toHaveBeenCalledTimes(0); expect(widthFn).toHaveBeenCalledTimes(0); }); it('componentDidUpdate() should measure content that is not already in the cache', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); var parent = createParent({ cache: cache }); renderHelper({ cache: cache, parent: parent }); cache.clear(0, 0); parent.invalidateCellSizeAfterRender.mockReset(); expect(cache.has(0, 0)).toBe(false); expect(cache.getWidth(0, 0)).toBe(DEFAULT_WIDTH); expect(cache.getHeight(0, 0)).toBe(DEFAULT_HEIGHT); var _mockClientWidthAndHe3 = mockClientWidthAndHeight({ height: 20, width: 100 }), heightFn = _mockClientWidthAndHe3.heightFn, widthFn = _mockClientWidthAndHe3.widthFn; renderHelper({ cache: cache, parent: parent }); expect(cache.has(0, 0)).toBe(true); expect(parent.invalidateCellSizeAfterRender).toHaveBeenCalled(); expect(heightFn).toHaveBeenCalledTimes(1); expect(widthFn).toHaveBeenCalledTimes(1); expect(cache.getWidth(0, 0)).toBe(100); expect(cache.getHeight(0, 0)).toBe(20); }); it('componentDidUpdate() should not measure content that is already in the cache', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); cache.set(0, 0, 100, 20); var parent = createParent({ cache: cache }); expect(cache.has(0, 0)).toBe(true); var _mockClientWidthAndHe4 = mockClientWidthAndHeight({ height: 20, width: 100 }), heightFn = _mockClientWidthAndHe4.heightFn, widthFn = _mockClientWidthAndHe4.widthFn; renderHelper({ cache: cache, parent: parent }); renderHelper({ cache: cache, parent: parent }); expect(parent.invalidateCellSizeAfterRender).not.toHaveBeenCalled(); expect(heightFn).toHaveBeenCalledTimes(0); expect(widthFn).toHaveBeenCalledTimes(0); }); it('registerChild() should measure content that is not already in the cache', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); var parent = createParent({ cache: cache }); var element = document.createElement('div'); var _mockClientWidthAndHe5 = mockClientWidthAndHeight({ height: 20, width: 100 }, element), heightFn = _mockClientWidthAndHe5.heightFn, widthFn = _mockClientWidthAndHe5.widthFn; expect(heightFn).toHaveBeenCalledTimes(0); expect(widthFn).toHaveBeenCalledTimes(0); expect(cache.has(0, 0)).toBe(false); renderHelper({ cache: cache, parent: parent, children: function children(_ref4) { var registerChild = _ref4.registerChild; registerChild(element); return null; } }); expect(parent.invalidateCellSizeAfterRender).toHaveBeenCalled(); expect(heightFn).toHaveBeenCalledTimes(1); expect(widthFn).toHaveBeenCalledTimes(1); expect(cache.has(0, 0)).toBe(true); expect(cache.getWidth(0, 0)).toBe(100); expect(cache.getHeight(0, 0)).toBe(20); }); it('registerChild() should not measure content that is already in the cache', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); cache.set(0, 0, 100, 20); var parent = createParent({ cache: cache }); var element = document.createElement('div'); var _mockClientWidthAndHe6 = mockClientWidthAndHeight({ height: 20, width: 100 }, element), heightFn = _mockClientWidthAndHe6.heightFn, widthFn = _mockClientWidthAndHe6.widthFn; expect(cache.has(0, 0)).toBe(true); renderHelper({ cache: cache, parent: parent, children: function children(_ref5) { var registerChild = _ref5.registerChild; registerChild(element); return null; } }); expect(parent.invalidateCellSizeAfterRender).not.toHaveBeenCalled(); expect(heightFn).toHaveBeenCalledTimes(0); expect(widthFn).toHaveBeenCalledTimes(0); }); it('should pass a :measure param to a function child', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); var children = jest.fn().mockReturnValue(React.createElement("div", null)); renderHelper({ cache: cache, children: children }); expect(children).toHaveBeenCalled(); var params = children.mock.calls[0][0]; expect(typeof params.measure === 'function').toBe(true); }); it('should still update cache without a parent Grid', function () { jest.spyOn(console, 'warn'); mockClientWidthAndHeight({ height: 20, width: 100 }); var cache = new CellMeasurerCache({ fixedWidth: true }); renderHelper({ cache: cache }); // No parent Grid expect(cache.has(0, 0)).toBe(true); expect(console.warn).not.toHaveBeenCalled(); }); // See issue #593 it('should explicitly set width/height style to "auto" before re-measuring', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); var parent = createParent({ cache: cache }); var child = jest.fn().mockReturnValue(React.createElement("div", { style: { width: 100, height: 30 } })); var measurer; var node = findDOMNode(render(React.createElement(CellMeasurer, { ref: function ref(_ref6) { measurer = _ref6; }, cache: cache, columnIndex: 0, parent: parent, rowIndex: 0, style: {} }, child))); var styleHeights = [30]; var styleWidths = [100]; Object.defineProperties(node.style, { height: { get: function get() { return styleHeights[styleHeights.length - 1]; }, set: function set(value) { return styleHeights.push(value); } }, width: { get: function get() { return styleWidths[styleWidths.length - 1]; }, set: function set(value) { return styleWidths.push(value); } } }); var _measurer$_getCellMea = measurer._getCellMeasurements(node), height = _measurer$_getCellMea.height, width = _measurer$_getCellMea.width; expect(height).toBeGreaterThan(0); expect(width).toBeGreaterThan(0); expect(styleHeights).toEqual([30, 'auto', 30]); expect(styleWidths).toEqual([100, 100]); }); // See issue #660 it('should reset width/height style values after measuring with style "auto"', function () { var cache = new CellMeasurerCache({ fixedHeight: true }); var parent = createParent({ cache: cache }); var child = jest.fn().mockReturnValue(React.createElement("div", { style: { width: 100, height: 30 } })); var node = findDOMNode(render(React.createElement(CellMeasurer, { cache: cache, columnIndex: 0, parent: parent, rowIndex: 0, style: {} }, child))); node.style.width = 200; node.style.height = 60; child.mock.calls[0][0].measure(); expect(node.style.height).toBe('30px'); expect(node.style.width).toBe('100px'); }); });dist/es/CellMeasurer/CellMeasurer.js000064400000016251151676725770013456 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; var _class, _temp; import * as React from 'react'; import { findDOMNode } from 'react-dom'; /** * Wraps a cell and measures its rendered content. * Measurements are stored in a per-cell cache. * Cached-content is not be re-measured. */ var CellMeasurer = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { _inherits(CellMeasurer, _React$PureComponent); function CellMeasurer() { var _getPrototypeOf2; var _this; _classCallCheck(this, CellMeasurer); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(CellMeasurer)).call.apply(_getPrototypeOf2, [this].concat(args))); _defineProperty(_assertThisInitialized(_this), "_child", void 0); _defineProperty(_assertThisInitialized(_this), "_measure", function () { var _this$props = _this.props, cache = _this$props.cache, _this$props$columnInd = _this$props.columnIndex, columnIndex = _this$props$columnInd === void 0 ? 0 : _this$props$columnInd, parent = _this$props.parent, _this$props$rowIndex = _this$props.rowIndex, rowIndex = _this$props$rowIndex === void 0 ? _this.props.index || 0 : _this$props$rowIndex; var _this$_getCellMeasure = _this._getCellMeasurements(), height = _this$_getCellMeasure.height, width = _this$_getCellMeasure.width; if (height !== cache.getHeight(rowIndex, columnIndex) || width !== cache.getWidth(rowIndex, columnIndex)) { cache.set(rowIndex, columnIndex, width, height); if (parent && typeof parent.recomputeGridSize === 'function') { parent.recomputeGridSize({ columnIndex: columnIndex, rowIndex: rowIndex }); } } }); _defineProperty(_assertThisInitialized(_this), "_registerChild", function (element) { if (element && !(element instanceof Element)) { console.warn('CellMeasurer registerChild expects to be passed Element or null'); } _this._child = element; if (element) { _this._maybeMeasureCell(); } }); return _this; } _createClass(CellMeasurer, [{ key: "componentDidMount", value: function componentDidMount() { this._maybeMeasureCell(); } }, { key: "componentDidUpdate", value: function componentDidUpdate() { this._maybeMeasureCell(); } }, { key: "render", value: function render() { var children = this.props.children; return typeof children === 'function' ? children({ measure: this._measure, registerChild: this._registerChild }) : children; } }, { key: "_getCellMeasurements", value: function _getCellMeasurements() { var cache = this.props.cache; var node = this._child || findDOMNode(this); // TODO Check for a bad combination of fixedWidth and missing numeric width or vice versa with height if (node && node.ownerDocument && node.ownerDocument.defaultView && node instanceof node.ownerDocument.defaultView.HTMLElement) { var styleWidth = node.style.width; var styleHeight = node.style.height; // If we are re-measuring a cell that has already been measured, // It will have a hard-coded width/height from the previous measurement. // The fact that we are measuring indicates this measurement is probably stale, // So explicitly clear it out (eg set to "auto") so we can recalculate. // See issue #593 for more info. // Even if we are measuring initially- if we're inside of a MultiGrid component, // Explicitly clear width/height before measuring to avoid being tainted by another Grid. // eg top/left Grid renders before bottom/right Grid // Since the CellMeasurerCache is shared between them this taints derived cell size values. if (!cache.hasFixedWidth()) { node.style.width = 'auto'; } if (!cache.hasFixedHeight()) { node.style.height = 'auto'; } var height = Math.ceil(node.offsetHeight); var width = Math.ceil(node.offsetWidth); // Reset after measuring to avoid breaking styles; see #660 if (styleWidth) { node.style.width = styleWidth; } if (styleHeight) { node.style.height = styleHeight; } return { height: height, width: width }; } else { return { height: 0, width: 0 }; } } }, { key: "_maybeMeasureCell", value: function _maybeMeasureCell() { var _this$props2 = this.props, cache = _this$props2.cache, _this$props2$columnIn = _this$props2.columnIndex, columnIndex = _this$props2$columnIn === void 0 ? 0 : _this$props2$columnIn, parent = _this$props2.parent, _this$props2$rowIndex = _this$props2.rowIndex, rowIndex = _this$props2$rowIndex === void 0 ? this.props.index || 0 : _this$props2$rowIndex; if (!cache.has(rowIndex, columnIndex)) { var _this$_getCellMeasure2 = this._getCellMeasurements(), height = _this$_getCellMeasure2.height, width = _this$_getCellMeasure2.width; cache.set(rowIndex, columnIndex, width, height); // If size has changed, let Grid know to re-render. if (parent && typeof parent.invalidateCellSizeAfterRender === 'function') { parent.invalidateCellSizeAfterRender({ columnIndex: columnIndex, rowIndex: rowIndex }); } } } }]); return CellMeasurer; }(React.PureComponent), _defineProperty(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { "cache": function cache() { return (typeof bpfrpt_proptype_CellMeasureCache === "function" ? bpfrpt_proptype_CellMeasureCache.isRequired ? bpfrpt_proptype_CellMeasureCache.isRequired : bpfrpt_proptype_CellMeasureCache : PropTypes.shape(bpfrpt_proptype_CellMeasureCache).isRequired).apply(this, arguments); }, "children": PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired, "columnIndex": PropTypes.number, "index": PropTypes.number, "parent": PropTypes.shape({ invalidateCellSizeAfterRender: PropTypes.func, recomputeGridSize: PropTypes.func }).isRequired, "rowIndex": PropTypes.number }), _temp); // Used for DEV mode warning check _defineProperty(CellMeasurer, "__internalCellMeasurerFlag", false); export { CellMeasurer as default }; if (process.env.NODE_ENV !== 'production') { CellMeasurer.__internalCellMeasurerFlag = true; } import { bpfrpt_proptype_CellMeasureCache } from "./types"; import PropTypes from "prop-types";dist/es/CellMeasurer/CellMeasurer.DynamicWidthGrid.example.js000064400000010067151676725770020300 0ustar00import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import Immutable from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import CellMeasurer from './CellMeasurer'; import CellMeasurerCache from './CellMeasurerCache'; import Grid from '../Grid'; import styles from './CellMeasurer.example.css'; var DynamicWidthGrid = /*#__PURE__*/ function (_React$PureComponent) { _inherits(DynamicWidthGrid, _React$PureComponent); function DynamicWidthGrid(props, context) { var _this; _classCallCheck(this, DynamicWidthGrid); _this = _possibleConstructorReturn(this, _getPrototypeOf(DynamicWidthGrid).call(this, props, context)); _this._cache = new CellMeasurerCache({ defaultWidth: 100, fixedHeight: true }); _this._cellRenderer = _this._cellRenderer.bind(_assertThisInitialized(_this)); return _this; } _createClass(DynamicWidthGrid, [{ key: "render", value: function render() { var width = this.props.width; return React.createElement(Grid, { className: styles.BodyGrid, columnCount: 1000, columnWidth: this._cache.columnWidth, deferredMeasurementCache: this._cache, height: 400, overscanColumnCount: 0, overscanRowCount: 2, cellRenderer: this._cellRenderer, rowCount: 50, rowHeight: 35, width: width }); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref) { var columnIndex = _ref.columnIndex, key = _ref.key, parent = _ref.parent, rowIndex = _ref.rowIndex, style = _ref.style; var _this$props = this.props, getClassName = _this$props.getClassName, getContent = _this$props.getContent, list = _this$props.list; var datum = list.get((rowIndex + columnIndex) % list.size); var classNames = getClassName({ columnIndex: columnIndex, rowIndex: rowIndex }); var content = getContent({ index: columnIndex, datum: datum, "long": false }); return React.createElement(CellMeasurer, { cache: this._cache, columnIndex: columnIndex, key: key, parent: parent, rowIndex: rowIndex }, React.createElement("div", { className: classNames, style: _objectSpread({}, style, { height: 35, whiteSpace: 'nowrap' }) }, content)); } }]); return DynamicWidthGrid; }(React.PureComponent); export { DynamicWidthGrid as default }; DynamicWidthGrid.propTypes = process.env.NODE_ENV !== "production" ? { getClassName: PropTypes.func.isRequired, getContent: PropTypes.func.isRequired, list: PropTypes.instanceOf(Immutable.List).isRequired, width: PropTypes.number.isRequired } : {};dist/es/CellMeasurer/CellMeasurer.DynamicHeightList.example.js000064400000006243151676725770020460 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import Immutable from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import CellMeasurer from './CellMeasurer'; import CellMeasurerCache from './CellMeasurerCache'; import List from '../List'; import styles from './CellMeasurer.example.css'; var DynamicHeightList = /*#__PURE__*/ function (_React$PureComponent) { _inherits(DynamicHeightList, _React$PureComponent); function DynamicHeightList(props, context) { var _this; _classCallCheck(this, DynamicHeightList); _this = _possibleConstructorReturn(this, _getPrototypeOf(DynamicHeightList).call(this, props, context)); _this._cache = new CellMeasurerCache({ fixedWidth: true, minHeight: 50 }); _this._rowRenderer = _this._rowRenderer.bind(_assertThisInitialized(_this)); return _this; } _createClass(DynamicHeightList, [{ key: "render", value: function render() { var width = this.props.width; return React.createElement(List, { className: styles.BodyGrid, deferredMeasurementCache: this._cache, height: 400, overscanRowCount: 0, rowCount: 1000, rowHeight: this._cache.rowHeight, rowRenderer: this._rowRenderer, width: width }); } }, { key: "_rowRenderer", value: function _rowRenderer(_ref) { var index = _ref.index, key = _ref.key, parent = _ref.parent, style = _ref.style; var _this$props = this.props, getClassName = _this$props.getClassName, list = _this$props.list; var datum = list.get(index % list.size); var classNames = getClassName({ columnIndex: 0, rowIndex: index }); var imageWidth = 300; var imageHeight = datum.size * (1 + index % 3); var source = "https://www.fillmurray.com/".concat(imageWidth, "/").concat(imageHeight); return React.createElement(CellMeasurer, { cache: this._cache, columnIndex: 0, key: key, rowIndex: index, parent: parent }, function (_ref2) { var measure = _ref2.measure, registerChild = _ref2.registerChild; return React.createElement("div", { ref: registerChild, className: classNames, style: style }, React.createElement("img", { onLoad: measure, src: source, style: { width: imageWidth } })); }); } }]); return DynamicHeightList; }(React.PureComponent); export { DynamicHeightList as default }; DynamicHeightList.propTypes = process.env.NODE_ENV !== "production" ? { getClassName: PropTypes.func.isRequired, list: PropTypes.instanceOf(Immutable.List).isRequired, width: PropTypes.number.isRequired } : {};dist/es/CellMeasurer/CellMeasurerCache.jest.js000064400000021565151676725770015352 0ustar00import CellMeasurerCache, { DEFAULT_HEIGHT, DEFAULT_WIDTH } from './CellMeasurerCache'; describe('CellMeasurerCache', function () { it('should override defaultHeight/defaultWidth if minHeight/minWidth are greater', function () { var cache = new CellMeasurerCache({ defaultHeight: 20, defaultWidth: 100, fixedHeight: true, fixedWidth: true, minHeight: 30, minWidth: 150 }); cache.set(0, 0, 50, 10); expect(cache.getHeight(0, 0)).toBe(30); expect(cache.getWidth(0, 0)).toBe(150); expect(cache.rowHeight({ index: 0 })).toBe(30); expect(cache.columnWidth({ index: 0 })).toBe(150); }); it('should correctly report cache status', function () { var cache = new CellMeasurerCache({ fixedHeight: true, fixedWidth: true }); expect(cache.has(0, 0)).toBe(false); }); it('should cache cells', function () { var cache = new CellMeasurerCache({ fixedHeight: true, fixedWidth: true }); cache.set(0, 0, 100, 20); expect(cache.has(0, 0)).toBe(true); }); it('should return the correct default sizes for uncached cells if specified', function () { spyOn(console, 'warn'); // Ignore warning about variable width and height var cache = new CellMeasurerCache({ defaultHeight: 20, defaultWidth: 100, minHeight: 15, minWidth: 80 }); expect(cache.getWidth(0, 0)).toBe(100); expect(cache.getHeight(0, 0)).toBe(20); cache.set(0, 0, 70, 10); expect(cache.getWidth(0, 0)).toBe(80); expect(cache.getHeight(0, 0)).toBe(15); }); it('should clear a single cached cell', function () { var cache = new CellMeasurerCache({ fixedHeight: true, fixedWidth: true }); cache.set(0, 0, 100, 20); cache.set(1, 0, 100, 20); expect(cache.has(0, 0)).toBe(true); expect(cache.has(1, 0)).toBe(true); cache.clear(0, 0); expect(cache.has(0, 0)).toBe(false); expect(cache.has(1, 0)).toBe(true); }); it('should clear a single cached row cell in column 0 when columnIndex param is absent', function () { var cache = new CellMeasurerCache({ fixedHeight: true, fixedWidth: true }); cache.set(0, 0, 100, 20); cache.set(1, 0, 100, 20); expect(cache.has(0, 0)).toBe(true); expect(cache.has(1, 0)).toBe(true); cache.clear(0); expect(cache.has(0, 0)).toBe(false); expect(cache.has(1, 0)).toBe(true); }); it('should clear all cached cells', function () { var cache = new CellMeasurerCache({ fixedHeight: true, fixedWidth: true }); cache.set(0, 0, 100, 20); cache.set(1, 0, 100, 20); expect(cache.has(0, 0)).toBe(true); expect(cache.has(1, 0)).toBe(true); cache.clearAll(); expect(cache.has(0, 0)).toBe(false); expect(cache.has(1, 0)).toBe(false); }); it('should clear row and column counts when clearing all cells', function () { var cache = new CellMeasurerCache({ fixedHeight: true, fixedWidth: true }); cache.set(0, 0, 100, 20); cache.set(1, 0, 100, 20); expect(cache._rowCount).toBe(2); expect(cache._columnCount).toBe(1); cache.clearAll(); expect(cache._rowCount).toBe(0); expect(cache._columnCount).toBe(0); }); it('should support a custom :keyMapper', function () { var keyMapper = jest.fn(); keyMapper.mockReturnValue('a'); spyOn(console, 'warn'); // Ignore warning about variable width and height var cache = new CellMeasurerCache({ defaultHeight: 30, defaultWidth: 50, keyMapper: keyMapper }); cache.set(0, 0, 100, 20); expect(cache.has(0, 0)).toBe(true); // Changing the returned key should cause cache misses keyMapper.mockReset(); keyMapper.mockReturnValue('b'); expect(cache.has(0, 0)).toBe(false); expect(cache.columnWidth(0)).toBe(50); expect(cache.rowHeight(0)).toBe(30); expect(keyMapper.mock.calls).toHaveLength(3); // Restoring it should fix keyMapper.mockReset(); keyMapper.mockReturnValue('a'); expect(cache.has(0, 0)).toBe(true); expect(cache.columnWidth(0)).toBe(100); expect(cache.rowHeight(0)).toBe(20); expect(keyMapper.mock.calls).toHaveLength(3); }); it('should provide a Grid-compatible :columnWidth method', function () { var cache = new CellMeasurerCache({ fixedHeight: true }); expect(cache.columnWidth({ index: 0 })).toBe(DEFAULT_WIDTH); cache.set(0, 0, 100, 50); expect(cache.columnWidth({ index: 0 })).toBe(100); expect(cache.columnWidth({ index: 1 })).toBe(DEFAULT_WIDTH); cache.set(1, 0, 75, 50); expect(cache.columnWidth({ index: 0 })).toBe(100); cache.set(2, 0, 125, 50); expect(cache.columnWidth({ index: 0 })).toBe(125); }); it('should provide a Grid-compatible :rowHeight method', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); expect(cache.rowHeight({ index: 0 })).toBe(DEFAULT_HEIGHT); cache.set(0, 0, 100, 50); expect(cache.rowHeight({ index: 0 })).toBe(50); expect(cache.rowHeight({ index: 1 })).toBe(DEFAULT_HEIGHT); cache.set(0, 1, 100, 25); expect(cache.rowHeight({ index: 0 })).toBe(50); cache.set(0, 2, 100, 75); expect(cache.rowHeight({ index: 0 })).toBe(75); }); it('should return the :defaultWidth for :columnWidth if not measured', function () { var cache = new CellMeasurerCache({ defaultWidth: 25, fixedHeight: true, fixedWidth: true }); expect(cache.columnWidth({ index: 0 })).toBe(25); }); it('should return the :defaultHeight for :rowHeight if not measured', function () { var cache = new CellMeasurerCache({ defaultHeight: 25, fixedHeight: true, fixedWidth: true }); expect(cache.rowHeight({ index: 0 })).toBe(25); }); it('should recalculate cached :columnWidth when cells are cleared', function () { var cache = new CellMeasurerCache({ fixedHeight: true }); expect(cache.columnWidth({ index: 0 })).toBe(DEFAULT_WIDTH); cache.set(0, 0, 125, 50); expect(cache.columnWidth({ index: 0 })).toBe(125); cache.set(1, 0, 150, 50); expect(cache.columnWidth({ index: 0 })).toBe(150); cache.clear(1, 0); expect(cache.columnWidth({ index: 0 })).toBe(125); cache.clear(0, 0); expect(cache.columnWidth({ index: 0 })).toBe(DEFAULT_WIDTH); cache.set(0, 0, 125, 50); expect(cache.columnWidth({ index: 0 })).toBe(125); cache.clearAll(); expect(cache.columnWidth({ index: 0 })).toBe(DEFAULT_WIDTH); }); it('should recalculate cached :rowHeight when cells are cleared', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); expect(cache.rowHeight({ index: 0 })).toBe(DEFAULT_HEIGHT); cache.set(0, 0, 125, 50); expect(cache.rowHeight({ index: 0 })).toBe(50); cache.set(0, 1, 150, 75); expect(cache.rowHeight({ index: 0 })).toBe(75); cache.clear(0, 1); expect(cache.rowHeight({ index: 0 })).toBe(50); cache.clear(0, 0); expect(cache.rowHeight({ index: 0 })).toBe(DEFAULT_HEIGHT); cache.set(0, 0, 125, 50); expect(cache.rowHeight({ index: 0 })).toBe(50); cache.clearAll(); expect(cache.rowHeight({ index: 0 })).toBe(DEFAULT_HEIGHT); }); describe('DEV mode', function () { it('should warn about dynamic width and height configurations', function () { spyOn(console, 'warn'); var cache = new CellMeasurerCache({ fixedHeight: false, fixedWidth: false }); expect(cache.hasFixedHeight()).toBe(false); expect(cache.hasFixedWidth()).toBe(false); expect(console.warn).toHaveBeenCalledWith("CellMeasurerCache should only measure a cell's width or height. " + 'You have configured CellMeasurerCache to measure both. ' + 'This will result in poor performance.'); }); it('should warn about dynamic width with a defaultWidth of 0', function () { spyOn(console, 'warn'); var cache = new CellMeasurerCache({ defaultWidth: 0, fixedHeight: true }); expect(cache.getWidth(0, 0)).toBe(0); expect(console.warn).toHaveBeenCalledWith('Fixed width CellMeasurerCache should specify a :defaultWidth greater than 0. ' + 'Failing to do so will lead to unnecessary layout and poor performance.'); }); it('should warn about dynamic height with a defaultHeight of 0', function () { spyOn(console, 'warn'); var cache = new CellMeasurerCache({ defaultHeight: 0, fixedWidth: true }); expect(cache.getHeight(0, 0)).toBe(0); expect(console.warn).toHaveBeenCalledWith('Fixed height CellMeasurerCache should specify a :defaultHeight greater than 0. ' + 'Failing to do so will lead to unnecessary layout and poor performance.'); }); }); });dist/es/InfiniteLoader/InfiniteLoader.jest.js000064400000044107151676725770015245 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _regeneratorRuntime from "@babel/runtime/regenerator"; import InfiniteLoader, { forceUpdateReactVirtualizedComponent, isRangeVisible, scanForUnloadedRanges } from './InfiniteLoader'; import * as React from 'react'; import List from '../List'; import { render } from '../TestUtils'; describe('InfiniteLoader', function () { var innerOnRowsRendered; var isRowLoadedCalls = []; var isRowLoadedMap = {}; var loadMoreRowsCalls = []; var rowRendererCalls = []; beforeEach(function () { isRowLoadedCalls = []; isRowLoadedMap = {}; loadMoreRowsCalls = []; rowRendererCalls = []; }); function defaultIsRowLoaded(_ref) { var index = _ref.index; isRowLoadedCalls.push(index); return !!isRowLoadedMap[index]; } function defaultLoadMoreRows(_ref2) { var startIndex = _ref2.startIndex, stopIndex = _ref2.stopIndex; loadMoreRowsCalls.push({ startIndex: startIndex, stopIndex: stopIndex }); } function rowRenderer(_ref3) { var index = _ref3.index, key = _ref3.key, style = _ref3.style; rowRendererCalls.push(index); return React.createElement("div", { key: key, style: style }); } function getMarkup() { var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref4$height = _ref4.height, height = _ref4$height === void 0 ? 100 : _ref4$height, _ref4$isRowLoaded = _ref4.isRowLoaded, isRowLoaded = _ref4$isRowLoaded === void 0 ? defaultIsRowLoaded : _ref4$isRowLoaded, _ref4$loadMoreRows = _ref4.loadMoreRows, loadMoreRows = _ref4$loadMoreRows === void 0 ? defaultLoadMoreRows : _ref4$loadMoreRows, _ref4$minimumBatchSiz = _ref4.minimumBatchSize, minimumBatchSize = _ref4$minimumBatchSiz === void 0 ? 1 : _ref4$minimumBatchSiz, _ref4$rowHeight = _ref4.rowHeight, rowHeight = _ref4$rowHeight === void 0 ? 20 : _ref4$rowHeight, _ref4$rowCount = _ref4.rowCount, rowCount = _ref4$rowCount === void 0 ? 100 : _ref4$rowCount, scrollToIndex = _ref4.scrollToIndex, _ref4$threshold = _ref4.threshold, threshold = _ref4$threshold === void 0 ? 10 : _ref4$threshold, _ref4$width = _ref4.width, width = _ref4$width === void 0 ? 200 : _ref4$width; return React.createElement(InfiniteLoader, { isRowLoaded: isRowLoaded, loadMoreRows: loadMoreRows, minimumBatchSize: minimumBatchSize, rowCount: rowCount, threshold: threshold }, function (_ref5) { var onRowsRendered = _ref5.onRowsRendered, registerChild = _ref5.registerChild; innerOnRowsRendered = onRowsRendered; return React.createElement(List, { ref: registerChild, height: height, onRowsRendered: onRowsRendered, rowHeight: rowHeight, rowRenderer: rowRenderer, rowCount: rowCount, scrollToIndex: scrollToIndex, width: width }); }); } it('should call :isRowLoaded for all rows within the threshold each time a range of rows are rendered', function () { render(getMarkup()); expect(isRowLoadedCalls).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]); }); it('should call :isRowLoaded for all rows within the rowCount each time a range of rows are rendered', function () { render(getMarkup({ rowCount: 10 })); expect(isRowLoadedCalls).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); }); it('should call :loadMoreRows for unloaded rows within the threshold', function () { render(getMarkup()); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 14 }]); }); it('should call :loadMoreRows for unloaded rows within the rowCount', function () { render(getMarkup({ rowCount: 10 })); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 9 }]); }); it('should :forceUpdate once rows have loaded if :loadMoreRows returns a Promise', function _callee(done) { var savedResolve, loadMoreRows; return _regeneratorRuntime.async(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: loadMoreRows = function _ref6() { return new Promise(function (resolve) { savedResolve = resolve; }); }; render(getMarkup({ loadMoreRows: loadMoreRows })); rowRendererCalls.splice(0); _context.next = 5; return _regeneratorRuntime.awrap(savedResolve()); case 5: expect(rowRendererCalls.length > 0).toEqual(true); done(); case 7: case "end": return _context.stop(); } } }); }); it('should not :forceUpdate once rows have loaded rows are no longer visible', function _callee2(done) { var resolves, loadMoreRows; return _regeneratorRuntime.async(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: loadMoreRows = function _ref7() { return new Promise(function (resolve) { resolves.push(resolve); }); }; resolves = []; render(getMarkup({ loadMoreRows: loadMoreRows })); // Simulate a new range of rows being loaded innerOnRowsRendered({ startIndex: 100, stopIndex: 101 }); rowRendererCalls.splice(0); _context2.next = 7; return _regeneratorRuntime.awrap(resolves[0]()); case 7: // Resolve the first request only, not the simulated row-change expect(rowRendererCalls.length).toEqual(0); done(); case 9: case "end": return _context2.stop(); } } }); }); describe('minimumBatchSize', function () { it('should respect the specified :minimumBatchSize when scrolling down', function () { render(getMarkup({ minimumBatchSize: 10, threshold: 0 })); expect(loadMoreRowsCalls.length).toEqual(1); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 9 }]); }); it('should respect the specified :minimumBatchSize when scrolling up', function () { render(getMarkup({ minimumBatchSize: 10, scrollToIndex: 20, threshold: 0 })); loadMoreRowsCalls.splice(0); render(getMarkup({ isRowLoaded: function isRowLoaded(_ref8) { var index = _ref8.index; return index >= 20; }, minimumBatchSize: 10, scrollToIndex: 15, threshold: 0 })); expect(loadMoreRowsCalls.length).toEqual(1); expect(loadMoreRowsCalls).toEqual([{ startIndex: 10, stopIndex: 19 }]); }); it('should not interfere with :threshold', function () { render(getMarkup({ minimumBatchSize: 10, threshold: 10 })); expect(loadMoreRowsCalls.length).toEqual(1); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 14 }]); }); it('should respect the specified :minimumBatchSize if a user scrolls past the previous range', function () { var isRowLoadedIndices = {}; function isRowLoaded(_ref9) { var index = _ref9.index; if (!isRowLoadedIndices[index]) { isRowLoadedIndices[index] = true; return false; } else { return true; } } render(getMarkup({ isRowLoaded: isRowLoaded, minimumBatchSize: 10, threshold: 0 })); // Simulate a new range of rows being loaded innerOnRowsRendered({ startIndex: 5, stopIndex: 10 }); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 9 }, { startIndex: 10, stopIndex: 19 }]); }); it('should not exceed ending boundaries if :minimumBatchSize is larger than needed', function () { render(getMarkup({ minimumBatchSize: 10, rowCount: 25, threshold: 0 })); // Simulate a new range of rows being loaded innerOnRowsRendered({ startIndex: 18, stopIndex: 22 }); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 9 }, { startIndex: 15, stopIndex: 24 }]); }); it('should not exceed beginning boundaries if :minimumBatchSize is larger than needed', function () { render(getMarkup({ minimumBatchSize: 10, scrollToIndex: 15, threshold: 0 })); loadMoreRowsCalls.splice(0); render(getMarkup({ isRowLoaded: function isRowLoaded(_ref10) { var index = _ref10.index; return index >= 6; }, minimumBatchSize: 10, scrollToIndex: 2, threshold: 0 })); expect(loadMoreRowsCalls.length).toEqual(1); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 5 }]); }); }); // Verifies improved memoization; see bvaughn/react-virtualized/issues/345 it('should memoize calls to :loadMoreRows (not calling unless unloaded ranges have changed)', function () { render(getMarkup({ isRowLoaded: function isRowLoaded() { return false; }, minimumBatchSize: 20, threshold: 0 })); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 19 }]); innerOnRowsRendered({ startIndex: 0, stopIndex: 15 }); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 19 }]); loadMoreRowsCalls.splice(0); innerOnRowsRendered({ startIndex: 0, stopIndex: 20 }); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 20 }]); }); it('resetLoadMoreRowsCache should reset memoized state', function () { var component = render(getMarkup({ isRowLoaded: function isRowLoaded() { return false; }, minimumBatchSize: 20, threshold: 0 })); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 19 }]); innerOnRowsRendered({ startIndex: 0, stopIndex: 15 }); loadMoreRowsCalls.splice(0); expect(loadMoreRowsCalls).toEqual([]); component.resetLoadMoreRowsCache(); innerOnRowsRendered({ startIndex: 0, stopIndex: 15 }); expect(loadMoreRowsCalls).toEqual([{ startIndex: 0, stopIndex: 19 }]); }); it('resetLoadMoreRowsCache should call :loadMoreRows if :autoReload parameter is true', function () { var component = render(getMarkup({ isRowLoaded: function isRowLoaded() { return false; }, minimumBatchSize: 1, threshold: 0 })); // Simulate a new range of rows being loaded loadMoreRowsCalls.splice(0); innerOnRowsRendered({ startIndex: 0, stopIndex: 10 }); component.resetLoadMoreRowsCache(true); expect(loadMoreRowsCalls[loadMoreRowsCalls.length - 1]).toEqual({ startIndex: 0, stopIndex: 10 }); // Simulate a new range of rows being loaded loadMoreRowsCalls.splice(0); innerOnRowsRendered({ startIndex: 20, stopIndex: 30 }); expect(loadMoreRowsCalls[loadMoreRowsCalls.length - 1]).toEqual({ startIndex: 20, stopIndex: 30 }); loadMoreRowsCalls.splice(0); component.resetLoadMoreRowsCache(true); expect(loadMoreRowsCalls[loadMoreRowsCalls.length - 1]).toEqual({ startIndex: 20, stopIndex: 30 }); }); }); describe('scanForUnloadedRanges', function () { function createIsRowLoaded(rows) { return function (_ref11) { var index = _ref11.index; return rows[index]; }; } it('should return an empty array for a range of rows that have all been loaded', function () { expect(scanForUnloadedRanges({ isRowLoaded: createIsRowLoaded([true, true, true]), startIndex: 0, stopIndex: 2 })).toEqual([]); }); it('return a range of only 1 unloaded row', function () { expect(scanForUnloadedRanges({ isRowLoaded: createIsRowLoaded([true, false, true]), startIndex: 0, stopIndex: 2 })).toEqual([{ startIndex: 1, stopIndex: 1 }]); }); it('return a range of multiple unloaded rows', function () { expect(scanForUnloadedRanges({ isRowLoaded: createIsRowLoaded([false, false, true]), startIndex: 0, stopIndex: 2 })).toEqual([{ startIndex: 0, stopIndex: 1 }]); }); it('return multiple ranges of unloaded rows', function () { expect(scanForUnloadedRanges({ isRowLoaded: createIsRowLoaded([true, false, false, true, false, true, false]), startIndex: 0, stopIndex: 6 })).toEqual([{ startIndex: 1, stopIndex: 2 }, { startIndex: 4, stopIndex: 4 }, { startIndex: 6, stopIndex: 6 }]); }); }); describe('isRangeVisible', function () { it('first row(s) are visible', function () { expect(isRangeVisible({ lastRenderedStartIndex: 10, lastRenderedStopIndex: 20, startIndex: 20, stopIndex: 30 })).toEqual(true); }); it('last row(s) are visible', function () { expect(isRangeVisible({ lastRenderedStartIndex: 10, lastRenderedStopIndex: 20, startIndex: 0, stopIndex: 10 })).toEqual(true); }); it('all row(s) are visible', function () { expect(isRangeVisible({ lastRenderedStartIndex: 10, lastRenderedStopIndex: 20, startIndex: 12, stopIndex: 14 })).toEqual(true); }); it('no row(s) are visible', function () { expect(isRangeVisible({ lastRenderedStartIndex: 10, lastRenderedStopIndex: 20, startIndex: 0, stopIndex: 9 })).toEqual(false); expect(isRangeVisible({ lastRenderedStartIndex: 10, lastRenderedStopIndex: 20, startIndex: 21, stopIndex: 30 })).toEqual(false); }); }); describe('forceUpdateReactVirtualizedComponent', function () { it('should call :recomputeGridSize if defined', function () { var recomputeGridSize = jest.fn(); var TestComponent = /*#__PURE__*/ function (_React$Component) { _inherits(TestComponent, _React$Component); function TestComponent() { var _getPrototypeOf2; var _this; _classCallCheck(this, TestComponent); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(TestComponent)).call.apply(_getPrototypeOf2, [this].concat(args))); _defineProperty(_assertThisInitialized(_this), "recomputeGridSize", recomputeGridSize); return _this; } _createClass(TestComponent, [{ key: "render", value: function render() { return React.createElement("div", null); } }]); return TestComponent; }(React.Component); forceUpdateReactVirtualizedComponent(render(React.createElement(TestComponent, null)), 10); expect(recomputeGridSize).toHaveBeenCalledTimes(1); expect(recomputeGridSize).toHaveBeenCalledWith(10); }); it('should called :recomputeRowHeights if defined', function () { var recomputeRowHeights = jest.fn(); var TestComponent = /*#__PURE__*/ function (_React$Component2) { _inherits(TestComponent, _React$Component2); function TestComponent() { var _getPrototypeOf3; var _this2; _classCallCheck(this, TestComponent); for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } _this2 = _possibleConstructorReturn(this, (_getPrototypeOf3 = _getPrototypeOf(TestComponent)).call.apply(_getPrototypeOf3, [this].concat(args))); _defineProperty(_assertThisInitialized(_this2), "recomputeRowHeights", recomputeRowHeights); return _this2; } _createClass(TestComponent, [{ key: "render", value: function render() { return React.createElement("div", null); } }]); return TestComponent; }(React.Component); forceUpdateReactVirtualizedComponent(render(React.createElement(TestComponent, null)), 10); expect(recomputeRowHeights).toHaveBeenCalledTimes(1); expect(recomputeRowHeights).toHaveBeenCalledWith(10); }); it('should call :forceUpdate otherwise', function () { var forceUpdate = jest.fn(); var TestComponent = /*#__PURE__*/ function (_React$Component3) { _inherits(TestComponent, _React$Component3); function TestComponent() { var _getPrototypeOf4; var _this3; _classCallCheck(this, TestComponent); for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { args[_key3] = arguments[_key3]; } _this3 = _possibleConstructorReturn(this, (_getPrototypeOf4 = _getPrototypeOf(TestComponent)).call.apply(_getPrototypeOf4, [this].concat(args))); _defineProperty(_assertThisInitialized(_this3), "forceUpdate", forceUpdate); return _this3; } _createClass(TestComponent, [{ key: "render", value: function render() { return React.createElement("div", null); } }]); return TestComponent; }(React.Component); forceUpdateReactVirtualizedComponent(render(React.createElement(TestComponent, null)), 10); expect(forceUpdate).toHaveBeenCalledTimes(1); }); });dist/es/InfiniteLoader/index.js000064400000000150151676725770012502 0ustar00import InfiniteLoader from './InfiniteLoader'; export default InfiniteLoader; export { InfiniteLoader };dist/es/InfiniteLoader/InfiniteLoader.example.js000064400000015062151676725770015731 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import * as React from 'react'; import PropTypes from 'prop-types'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import Immutable from 'immutable'; import AutoSizer from '../AutoSizer'; import InfiniteLoader from './InfiniteLoader'; import List from '../List'; import styles from './InfiniteLoader.example.css'; var STATUS_LOADING = 1; var STATUS_LOADED = 2; var InfiniteLoaderExample = /*#__PURE__*/ function (_React$PureComponent) { _inherits(InfiniteLoaderExample, _React$PureComponent); function InfiniteLoaderExample(props) { var _this; _classCallCheck(this, InfiniteLoaderExample); _this = _possibleConstructorReturn(this, _getPrototypeOf(InfiniteLoaderExample).call(this, props)); _this.state = { loadedRowCount: 0, loadedRowsMap: {}, loadingRowCount: 0 }; _this._timeoutIdMap = {}; _this._clearData = _this._clearData.bind(_assertThisInitialized(_this)); _this._isRowLoaded = _this._isRowLoaded.bind(_assertThisInitialized(_this)); _this._loadMoreRows = _this._loadMoreRows.bind(_assertThisInitialized(_this)); _this._rowRenderer = _this._rowRenderer.bind(_assertThisInitialized(_this)); return _this; } _createClass(InfiniteLoaderExample, [{ key: "componentWillUnmount", value: function componentWillUnmount() { Object.keys(this._timeoutIdMap).forEach(function (timeoutId) { clearTimeout(timeoutId); }); } }, { key: "render", value: function render() { var _this2 = this; var list = this.context.list; var _this$state = this.state, loadedRowCount = _this$state.loadedRowCount, loadingRowCount = _this$state.loadingRowCount; return React.createElement(ContentBox, null, React.createElement(ContentBoxHeader, { text: "InfiniteLoader", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/InfiniteLoader/InfiniteLoader.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/InfiniteLoader.md" }), React.createElement(ContentBoxParagraph, null, "This component manages just-in-time data fetching to ensure that the all visible rows have been loaded. It also uses a threshold to determine how early to pre-fetch rows (before a user scrolls to them)."), React.createElement(ContentBoxParagraph, null, React.createElement("div", { className: styles.cacheButtonAndCountRow }, React.createElement("button", { className: styles.button, onClick: this._clearData }, "Flush Cached Data"), React.createElement("div", { className: styles.cacheCountRow }, loadingRowCount, " loading, ", loadedRowCount, " loaded"))), React.createElement(InfiniteLoader, { isRowLoaded: this._isRowLoaded, loadMoreRows: this._loadMoreRows, rowCount: list.size }, function (_ref) { var onRowsRendered = _ref.onRowsRendered, registerChild = _ref.registerChild; return React.createElement(AutoSizer, { disableHeight: true }, function (_ref2) { var width = _ref2.width; return React.createElement(List, { ref: registerChild, className: styles.List, height: 200, onRowsRendered: onRowsRendered, rowCount: list.size, rowHeight: 30, rowRenderer: _this2._rowRenderer, width: width }); }); })); } }, { key: "_clearData", value: function _clearData() { this.setState({ loadedRowCount: 0, loadedRowsMap: {}, loadingRowCount: 0 }); } }, { key: "_isRowLoaded", value: function _isRowLoaded(_ref3) { var index = _ref3.index; var loadedRowsMap = this.state.loadedRowsMap; return !!loadedRowsMap[index]; // STATUS_LOADING or STATUS_LOADED } }, { key: "_loadMoreRows", value: function _loadMoreRows(_ref4) { var _this3 = this; var startIndex = _ref4.startIndex, stopIndex = _ref4.stopIndex; var _this$state2 = this.state, loadedRowsMap = _this$state2.loadedRowsMap, loadingRowCount = _this$state2.loadingRowCount; var increment = stopIndex - startIndex + 1; for (var i = startIndex; i <= stopIndex; i++) { loadedRowsMap[i] = STATUS_LOADING; } this.setState({ loadingRowCount: loadingRowCount + increment }); var timeoutId = setTimeout(function () { var _this3$state = _this3.state, loadedRowCount = _this3$state.loadedRowCount, loadingRowCount = _this3$state.loadingRowCount; delete _this3._timeoutIdMap[timeoutId]; for (var i = startIndex; i <= stopIndex; i++) { loadedRowsMap[i] = STATUS_LOADED; } _this3.setState({ loadingRowCount: loadingRowCount - increment, loadedRowCount: loadedRowCount + increment }); promiseResolver(); }, 1000 + Math.round(Math.random() * 2000)); this._timeoutIdMap[timeoutId] = true; var promiseResolver; return new Promise(function (resolve) { promiseResolver = resolve; }); } }, { key: "_rowRenderer", value: function _rowRenderer(_ref5) { var index = _ref5.index, key = _ref5.key, style = _ref5.style; var list = this.context.list; var loadedRowsMap = this.state.loadedRowsMap; var row = list.get(index); var content; if (loadedRowsMap[index] === STATUS_LOADED) { content = row.name; } else { content = React.createElement("div", { className: styles.placeholder, style: { width: row.size } }); } return React.createElement("div", { className: styles.row, key: key, style: style }, content); } }]); return InfiniteLoaderExample; }(React.PureComponent); _defineProperty(InfiniteLoaderExample, "contextTypes", { list: PropTypes.instanceOf(Immutable.List).isRequired }); export { InfiniteLoaderExample as default };dist/es/InfiniteLoader/InfiniteLoader.js000064400000023756151676725770014310 0ustar00import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import * as React from 'react'; import PropTypes from 'prop-types'; import createCallbackMemoizer from '../utils/createCallbackMemoizer'; /** * Higher-order component that manages lazy-loading for "infinite" data. * This component decorates a virtual component and just-in-time prefetches rows as a user scrolls. * It is intended as a convenience component; fork it if you'd like finer-grained control over data-loading. */ var InfiniteLoader = /*#__PURE__*/ function (_React$PureComponent) { _inherits(InfiniteLoader, _React$PureComponent); function InfiniteLoader(props, context) { var _this; _classCallCheck(this, InfiniteLoader); _this = _possibleConstructorReturn(this, _getPrototypeOf(InfiniteLoader).call(this, props, context)); _this._loadMoreRowsMemoizer = createCallbackMemoizer(); _this._onRowsRendered = _this._onRowsRendered.bind(_assertThisInitialized(_this)); _this._registerChild = _this._registerChild.bind(_assertThisInitialized(_this)); return _this; } _createClass(InfiniteLoader, [{ key: "resetLoadMoreRowsCache", value: function resetLoadMoreRowsCache(autoReload) { this._loadMoreRowsMemoizer = createCallbackMemoizer(); if (autoReload) { this._doStuff(this._lastRenderedStartIndex, this._lastRenderedStopIndex); } } }, { key: "render", value: function render() { var children = this.props.children; return children({ onRowsRendered: this._onRowsRendered, registerChild: this._registerChild }); } }, { key: "_loadUnloadedRanges", value: function _loadUnloadedRanges(unloadedRanges) { var _this2 = this; var loadMoreRows = this.props.loadMoreRows; unloadedRanges.forEach(function (unloadedRange) { var promise = loadMoreRows(unloadedRange); if (promise) { promise.then(function () { // Refresh the visible rows if any of them have just been loaded. // Otherwise they will remain in their unloaded visual state. if (isRangeVisible({ lastRenderedStartIndex: _this2._lastRenderedStartIndex, lastRenderedStopIndex: _this2._lastRenderedStopIndex, startIndex: unloadedRange.startIndex, stopIndex: unloadedRange.stopIndex })) { if (_this2._registeredChild) { forceUpdateReactVirtualizedComponent(_this2._registeredChild, _this2._lastRenderedStartIndex); } } }); } }); } }, { key: "_onRowsRendered", value: function _onRowsRendered(_ref) { var startIndex = _ref.startIndex, stopIndex = _ref.stopIndex; this._lastRenderedStartIndex = startIndex; this._lastRenderedStopIndex = stopIndex; this._doStuff(startIndex, stopIndex); } }, { key: "_doStuff", value: function _doStuff(startIndex, stopIndex) { var _ref2, _this3 = this; var _this$props = this.props, isRowLoaded = _this$props.isRowLoaded, minimumBatchSize = _this$props.minimumBatchSize, rowCount = _this$props.rowCount, threshold = _this$props.threshold; var unloadedRanges = scanForUnloadedRanges({ isRowLoaded: isRowLoaded, minimumBatchSize: minimumBatchSize, rowCount: rowCount, startIndex: Math.max(0, startIndex - threshold), stopIndex: Math.min(rowCount - 1, stopIndex + threshold) }); // For memoize comparison var squashedUnloadedRanges = (_ref2 = []).concat.apply(_ref2, _toConsumableArray(unloadedRanges.map(function (_ref3) { var startIndex = _ref3.startIndex, stopIndex = _ref3.stopIndex; return [startIndex, stopIndex]; }))); this._loadMoreRowsMemoizer({ callback: function callback() { _this3._loadUnloadedRanges(unloadedRanges); }, indices: { squashedUnloadedRanges: squashedUnloadedRanges } }); } }, { key: "_registerChild", value: function _registerChild(registeredChild) { this._registeredChild = registeredChild; } }]); return InfiniteLoader; }(React.PureComponent); /** * Determines if the specified start/stop range is visible based on the most recently rendered range. */ _defineProperty(InfiniteLoader, "defaultProps", { minimumBatchSize: 10, rowCount: 0, threshold: 15 }); export { InfiniteLoader as default }; InfiniteLoader.propTypes = process.env.NODE_ENV !== "production" ? { /** * Function responsible for rendering a virtualized component. * This function should implement the following signature: * ({ onRowsRendered, registerChild }) => PropTypes.element * * The specified :onRowsRendered function should be passed through to the child's :onRowsRendered property. * The :registerChild callback should be set as the virtualized component's :ref. */ children: PropTypes.func.isRequired, /** * Function responsible for tracking the loaded state of each row. * It should implement the following signature: ({ index: number }): boolean */ isRowLoaded: PropTypes.func.isRequired, /** * Callback to be invoked when more rows must be loaded. * It should implement the following signature: ({ startIndex, stopIndex }): Promise * The returned Promise should be resolved once row data has finished loading. * It will be used to determine when to refresh the list with the newly-loaded data. * This callback may be called multiple times in reaction to a single scroll event. */ loadMoreRows: PropTypes.func.isRequired, /** * Minimum number of rows to be loaded at a time. * This property can be used to batch requests to reduce HTTP requests. */ minimumBatchSize: PropTypes.number.isRequired, /** * Number of rows in list; can be arbitrary high number if actual number is unknown. */ rowCount: PropTypes.number.isRequired, /** * Threshold at which to pre-fetch data. * A threshold X means that data will start loading when a user scrolls within X rows. * This value defaults to 15. */ threshold: PropTypes.number.isRequired } : {}; export function isRangeVisible(_ref4) { var lastRenderedStartIndex = _ref4.lastRenderedStartIndex, lastRenderedStopIndex = _ref4.lastRenderedStopIndex, startIndex = _ref4.startIndex, stopIndex = _ref4.stopIndex; return !(startIndex > lastRenderedStopIndex || stopIndex < lastRenderedStartIndex); } /** * Returns all of the ranges within a larger range that contain unloaded rows. */ export function scanForUnloadedRanges(_ref5) { var isRowLoaded = _ref5.isRowLoaded, minimumBatchSize = _ref5.minimumBatchSize, rowCount = _ref5.rowCount, startIndex = _ref5.startIndex, stopIndex = _ref5.stopIndex; var unloadedRanges = []; var rangeStartIndex = null; var rangeStopIndex = null; for (var index = startIndex; index <= stopIndex; index++) { var loaded = isRowLoaded({ index: index }); if (!loaded) { rangeStopIndex = index; if (rangeStartIndex === null) { rangeStartIndex = index; } } else if (rangeStopIndex !== null) { unloadedRanges.push({ startIndex: rangeStartIndex, stopIndex: rangeStopIndex }); rangeStartIndex = rangeStopIndex = null; } } // If :rangeStopIndex is not null it means we haven't ran out of unloaded rows. // Scan forward to try filling our :minimumBatchSize. if (rangeStopIndex !== null) { var potentialStopIndex = Math.min(Math.max(rangeStopIndex, rangeStartIndex + minimumBatchSize - 1), rowCount - 1); for (var _index = rangeStopIndex + 1; _index <= potentialStopIndex; _index++) { if (!isRowLoaded({ index: _index })) { rangeStopIndex = _index; } else { break; } } unloadedRanges.push({ startIndex: rangeStartIndex, stopIndex: rangeStopIndex }); } // Check to see if our first range ended prematurely. // In this case we should scan backwards to try filling our :minimumBatchSize. if (unloadedRanges.length) { var firstUnloadedRange = unloadedRanges[0]; while (firstUnloadedRange.stopIndex - firstUnloadedRange.startIndex + 1 < minimumBatchSize && firstUnloadedRange.startIndex > 0) { var _index2 = firstUnloadedRange.startIndex - 1; if (!isRowLoaded({ index: _index2 })) { firstUnloadedRange.startIndex = _index2; } else { break; } } } return unloadedRanges; } /** * Since RV components use shallowCompare we need to force a render (even though props haven't changed). * However InfiniteLoader may wrap a Grid or it may wrap a Table or List. * In the first case the built-in React forceUpdate() method is sufficient to force a re-render, * But in the latter cases we need to use the RV-specific forceUpdateGrid() method. * Else the inner Grid will not be re-rendered and visuals may be stale. * * Additionally, while a Grid is scrolling the cells can be cached, * So it's important to invalidate that cache by recalculating sizes * before forcing a rerender. */ export function forceUpdateReactVirtualizedComponent(component) { var currentIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var recomputeSize = typeof component.recomputeGridSize === 'function' ? component.recomputeGridSize : component.recomputeRowHeights; if (recomputeSize) { recomputeSize.call(component, currentIndex); } else { component.forceUpdate(); } }dist/es/vendor/intervalTree.js000064400000022050151676725770012443 0ustar00/** * Binary Search Bounds * https://github.com/mikolalysenko/interval-tree-1d * Mikola Lysenko * * Inlined because of Content Security Policy issue caused by the use of `new Function(...)` syntax in an upstream dependency. * Issue reported here: https://github.com/mikolalysenko/binary-search-bounds/issues/5 **/ import bounds from './binarySearchBounds'; var NOT_FOUND = 0; var SUCCESS = 1; var EMPTY = 2; function IntervalTreeNode(mid, left, right, leftPoints, rightPoints) { this.mid = mid; this.left = left; this.right = right; this.leftPoints = leftPoints; this.rightPoints = rightPoints; this.count = (left ? left.count : 0) + (right ? right.count : 0) + leftPoints.length; } var proto = IntervalTreeNode.prototype; function copy(a, b) { a.mid = b.mid; a.left = b.left; a.right = b.right; a.leftPoints = b.leftPoints; a.rightPoints = b.rightPoints; a.count = b.count; } function rebuild(node, intervals) { var ntree = createIntervalTree(intervals); node.mid = ntree.mid; node.left = ntree.left; node.right = ntree.right; node.leftPoints = ntree.leftPoints; node.rightPoints = ntree.rightPoints; node.count = ntree.count; } function rebuildWithInterval(node, interval) { var intervals = node.intervals([]); intervals.push(interval); rebuild(node, intervals); } function rebuildWithoutInterval(node, interval) { var intervals = node.intervals([]); var idx = intervals.indexOf(interval); if (idx < 0) { return NOT_FOUND; } intervals.splice(idx, 1); rebuild(node, intervals); return SUCCESS; } proto.intervals = function (result) { result.push.apply(result, this.leftPoints); if (this.left) { this.left.intervals(result); } if (this.right) { this.right.intervals(result); } return result; }; proto.insert = function (interval) { var weight = this.count - this.leftPoints.length; this.count += 1; if (interval[1] < this.mid) { if (this.left) { if (4 * (this.left.count + 1) > 3 * (weight + 1)) { rebuildWithInterval(this, interval); } else { this.left.insert(interval); } } else { this.left = createIntervalTree([interval]); } } else if (interval[0] > this.mid) { if (this.right) { if (4 * (this.right.count + 1) > 3 * (weight + 1)) { rebuildWithInterval(this, interval); } else { this.right.insert(interval); } } else { this.right = createIntervalTree([interval]); } } else { var l = bounds.ge(this.leftPoints, interval, compareBegin); var r = bounds.ge(this.rightPoints, interval, compareEnd); this.leftPoints.splice(l, 0, interval); this.rightPoints.splice(r, 0, interval); } }; proto.remove = function (interval) { var weight = this.count - this.leftPoints; if (interval[1] < this.mid) { if (!this.left) { return NOT_FOUND; } var rw = this.right ? this.right.count : 0; if (4 * rw > 3 * (weight - 1)) { return rebuildWithoutInterval(this, interval); } var r = this.left.remove(interval); if (r === EMPTY) { this.left = null; this.count -= 1; return SUCCESS; } else if (r === SUCCESS) { this.count -= 1; } return r; } else if (interval[0] > this.mid) { if (!this.right) { return NOT_FOUND; } var lw = this.left ? this.left.count : 0; if (4 * lw > 3 * (weight - 1)) { return rebuildWithoutInterval(this, interval); } var r = this.right.remove(interval); if (r === EMPTY) { this.right = null; this.count -= 1; return SUCCESS; } else if (r === SUCCESS) { this.count -= 1; } return r; } else { if (this.count === 1) { if (this.leftPoints[0] === interval) { return EMPTY; } else { return NOT_FOUND; } } if (this.leftPoints.length === 1 && this.leftPoints[0] === interval) { if (this.left && this.right) { var p = this; var n = this.left; while (n.right) { p = n; n = n.right; } if (p === this) { n.right = this.right; } else { var l = this.left; var r = this.right; p.count -= n.count; p.right = n.left; n.left = l; n.right = r; } copy(this, n); this.count = (this.left ? this.left.count : 0) + (this.right ? this.right.count : 0) + this.leftPoints.length; } else if (this.left) { copy(this, this.left); } else { copy(this, this.right); } return SUCCESS; } for (var l = bounds.ge(this.leftPoints, interval, compareBegin); l < this.leftPoints.length; ++l) { if (this.leftPoints[l][0] !== interval[0]) { break; } if (this.leftPoints[l] === interval) { this.count -= 1; this.leftPoints.splice(l, 1); for (var r = bounds.ge(this.rightPoints, interval, compareEnd); r < this.rightPoints.length; ++r) { if (this.rightPoints[r][1] !== interval[1]) { break; } else if (this.rightPoints[r] === interval) { this.rightPoints.splice(r, 1); return SUCCESS; } } } } return NOT_FOUND; } }; function reportLeftRange(arr, hi, cb) { for (var i = 0; i < arr.length && arr[i][0] <= hi; ++i) { var r = cb(arr[i]); if (r) { return r; } } } function reportRightRange(arr, lo, cb) { for (var i = arr.length - 1; i >= 0 && arr[i][1] >= lo; --i) { var r = cb(arr[i]); if (r) { return r; } } } function reportRange(arr, cb) { for (var i = 0; i < arr.length; ++i) { var r = cb(arr[i]); if (r) { return r; } } } proto.queryPoint = function (x, cb) { if (x < this.mid) { if (this.left) { var r = this.left.queryPoint(x, cb); if (r) { return r; } } return reportLeftRange(this.leftPoints, x, cb); } else if (x > this.mid) { if (this.right) { var r = this.right.queryPoint(x, cb); if (r) { return r; } } return reportRightRange(this.rightPoints, x, cb); } else { return reportRange(this.leftPoints, cb); } }; proto.queryInterval = function (lo, hi, cb) { if (lo < this.mid && this.left) { var r = this.left.queryInterval(lo, hi, cb); if (r) { return r; } } if (hi > this.mid && this.right) { var r = this.right.queryInterval(lo, hi, cb); if (r) { return r; } } if (hi < this.mid) { return reportLeftRange(this.leftPoints, hi, cb); } else if (lo > this.mid) { return reportRightRange(this.rightPoints, lo, cb); } else { return reportRange(this.leftPoints, cb); } }; function compareNumbers(a, b) { return a - b; } function compareBegin(a, b) { var d = a[0] - b[0]; if (d) { return d; } return a[1] - b[1]; } function compareEnd(a, b) { var d = a[1] - b[1]; if (d) { return d; } return a[0] - b[0]; } function createIntervalTree(intervals) { if (intervals.length === 0) { return null; } var pts = []; for (var i = 0; i < intervals.length; ++i) { pts.push(intervals[i][0], intervals[i][1]); } pts.sort(compareNumbers); var mid = pts[pts.length >> 1]; var leftIntervals = []; var rightIntervals = []; var centerIntervals = []; for (var i = 0; i < intervals.length; ++i) { var s = intervals[i]; if (s[1] < mid) { leftIntervals.push(s); } else if (mid < s[0]) { rightIntervals.push(s); } else { centerIntervals.push(s); } } //Split center intervals var leftPoints = centerIntervals; var rightPoints = centerIntervals.slice(); leftPoints.sort(compareBegin); rightPoints.sort(compareEnd); return new IntervalTreeNode(mid, createIntervalTree(leftIntervals), createIntervalTree(rightIntervals), leftPoints, rightPoints); } //User friendly wrapper that makes it possible to support empty trees function IntervalTree(root) { this.root = root; } var tproto = IntervalTree.prototype; tproto.insert = function (interval) { if (this.root) { this.root.insert(interval); } else { this.root = new IntervalTreeNode(interval[0], null, null, [interval], [interval]); } }; tproto.remove = function (interval) { if (this.root) { var r = this.root.remove(interval); if (r === EMPTY) { this.root = null; } return r !== NOT_FOUND; } return false; }; tproto.queryPoint = function (p, cb) { if (this.root) { return this.root.queryPoint(p, cb); } }; tproto.queryInterval = function (lo, hi, cb) { if (lo <= hi && this.root) { return this.root.queryInterval(lo, hi, cb); } }; Object.defineProperty(tproto, 'count', { get: function get() { if (this.root) { return this.root.count; } return 0; } }); Object.defineProperty(tproto, 'intervals', { get: function get() { if (this.root) { return this.root.intervals([]); } return []; } }); export default function createWrapper(intervals) { if (!intervals || intervals.length === 0) { return new IntervalTree(null); } return new IntervalTree(createIntervalTree(intervals)); }dist/es/vendor/binarySearchBounds.js000064400000007666151676725770013604 0ustar00/** * Binary Search Bounds * https://github.com/mikolalysenko/binary-search-bounds * Mikola Lysenko * * Inlined because of Content Security Policy issue caused by the use of `new Function(...)` syntax. * Issue reported here: https://github.com/mikolalysenko/binary-search-bounds/issues/5 **/ function _GEA(a, l, h, y) { var i = h + 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (x >= y) { i = m; h = m - 1; } else { l = m + 1; } } return i; } function _GEP(a, l, h, y, c) { var i = h + 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (c(x, y) >= 0) { i = m; h = m - 1; } else { l = m + 1; } } return i; } function dispatchBsearchGE(a, y, c, l, h) { if (typeof c === 'function') { return _GEP(a, l === void 0 ? 0 : l | 0, h === void 0 ? a.length - 1 : h | 0, y, c); } else { return _GEA(a, c === void 0 ? 0 : c | 0, l === void 0 ? a.length - 1 : l | 0, y); } } function _GTA(a, l, h, y) { var i = h + 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (x > y) { i = m; h = m - 1; } else { l = m + 1; } } return i; } function _GTP(a, l, h, y, c) { var i = h + 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (c(x, y) > 0) { i = m; h = m - 1; } else { l = m + 1; } } return i; } function dispatchBsearchGT(a, y, c, l, h) { if (typeof c === 'function') { return _GTP(a, l === void 0 ? 0 : l | 0, h === void 0 ? a.length - 1 : h | 0, y, c); } else { return _GTA(a, c === void 0 ? 0 : c | 0, l === void 0 ? a.length - 1 : l | 0, y); } } function _LTA(a, l, h, y) { var i = l - 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (x < y) { i = m; l = m + 1; } else { h = m - 1; } } return i; } function _LTP(a, l, h, y, c) { var i = l - 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (c(x, y) < 0) { i = m; l = m + 1; } else { h = m - 1; } } return i; } function dispatchBsearchLT(a, y, c, l, h) { if (typeof c === 'function') { return _LTP(a, l === void 0 ? 0 : l | 0, h === void 0 ? a.length - 1 : h | 0, y, c); } else { return _LTA(a, c === void 0 ? 0 : c | 0, l === void 0 ? a.length - 1 : l | 0, y); } } function _LEA(a, l, h, y) { var i = l - 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (x <= y) { i = m; l = m + 1; } else { h = m - 1; } } return i; } function _LEP(a, l, h, y, c) { var i = l - 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (c(x, y) <= 0) { i = m; l = m + 1; } else { h = m - 1; } } return i; } function dispatchBsearchLE(a, y, c, l, h) { if (typeof c === 'function') { return _LEP(a, l === void 0 ? 0 : l | 0, h === void 0 ? a.length - 1 : h | 0, y, c); } else { return _LEA(a, c === void 0 ? 0 : c | 0, l === void 0 ? a.length - 1 : l | 0, y); } } function _EQA(a, l, h, y) { l - 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; if (x === y) { return m; } else if (x <= y) { l = m + 1; } else { h = m - 1; } } return -1; } function _EQP(a, l, h, y, c) { l - 1; while (l <= h) { var m = l + h >>> 1, x = a[m]; var p = c(x, y); if (p === 0) { return m; } else if (p <= 0) { l = m + 1; } else { h = m - 1; } } return -1; } function dispatchBsearchEQ(a, y, c, l, h) { if (typeof c === 'function') { return _EQP(a, l === void 0 ? 0 : l | 0, h === void 0 ? a.length - 1 : h | 0, y, c); } else { return _EQA(a, c === void 0 ? 0 : c | 0, l === void 0 ? a.length - 1 : l | 0, y); } } export default { ge: dispatchBsearchGE, gt: dispatchBsearchGT, lt: dispatchBsearchLT, le: dispatchBsearchLE, eq: dispatchBsearchEQ };dist/es/vendor/detectElementResize.js000064400000020201151676725770013737 0ustar00/** * Detect Element Resize. * https://github.com/sdecima/javascript-detect-element-resize * Sebastian Decima * * Forked from version 0.5.3; includes the following modifications: * 1) Guard against unsafe 'window' and 'document' references (to support SSR). * 2) Defer initialization code via a top-level function wrapper (to support SSR). * 3) Avoid unnecessary reflows by not measuring size for scroll events bubbling from children. * 4) Add nonce for style element. * 5) Added support for injecting custom window object **/ export default function createDetectElementResize(nonce, hostWindow) { // Check `document` and `window` in case of server-side rendering var _window; if (typeof hostWindow !== 'undefined') { _window = hostWindow; } else if (typeof window !== 'undefined') { _window = window; } else if (typeof self !== 'undefined') { _window = self; } else { _window = global; } var attachEvent = typeof _window.document !== 'undefined' && _window.document.attachEvent; if (!attachEvent) { var requestFrame = function () { var raf = _window.requestAnimationFrame || _window.mozRequestAnimationFrame || _window.webkitRequestAnimationFrame || function (fn) { return _window.setTimeout(fn, 20); }; return function (fn) { return raf(fn); }; }(); var cancelFrame = function () { var cancel = _window.cancelAnimationFrame || _window.mozCancelAnimationFrame || _window.webkitCancelAnimationFrame || _window.clearTimeout; return function (id) { return cancel(id); }; }(); var resetTriggers = function resetTriggers(element) { var triggers = element.__resizeTriggers__, expand = triggers.firstElementChild, contract = triggers.lastElementChild, expandChild = expand.firstElementChild; contract.scrollLeft = contract.scrollWidth; contract.scrollTop = contract.scrollHeight; expandChild.style.width = expand.offsetWidth + 1 + 'px'; expandChild.style.height = expand.offsetHeight + 1 + 'px'; expand.scrollLeft = expand.scrollWidth; expand.scrollTop = expand.scrollHeight; }; var checkTriggers = function checkTriggers(element) { return element.offsetWidth != element.__resizeLast__.width || element.offsetHeight != element.__resizeLast__.height; }; var scrollListener = function scrollListener(e) { // Don't measure (which forces) reflow for scrolls that happen inside of children! if (e.target.className && typeof e.target.className.indexOf === 'function' && e.target.className.indexOf('contract-trigger') < 0 && e.target.className.indexOf('expand-trigger') < 0) { return; } var element = this; resetTriggers(this); if (this.__resizeRAF__) { cancelFrame(this.__resizeRAF__); } this.__resizeRAF__ = requestFrame(function () { if (checkTriggers(element)) { element.__resizeLast__.width = element.offsetWidth; element.__resizeLast__.height = element.offsetHeight; element.__resizeListeners__.forEach(function (fn) { fn.call(element, e); }); } }); }; /* Detect CSS Animations support to detect element display/re-attach */ var animation = false, keyframeprefix = '', animationstartevent = 'animationstart', domPrefixes = 'Webkit Moz O ms'.split(' '), startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '), pfx = ''; { var elm = _window.document.createElement('fakeelement'); if (elm.style.animationName !== undefined) { animation = true; } if (animation === false) { for (var i = 0; i < domPrefixes.length; i++) { if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) { pfx = domPrefixes[i]; keyframeprefix = '-' + pfx.toLowerCase() + '-'; animationstartevent = startEvents[i]; animation = true; break; } } } } var animationName = 'resizeanim'; var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } '; var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; '; } var createStyles = function createStyles(doc) { if (!doc.getElementById('detectElementResize')) { //opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360 var css = (animationKeyframes ? animationKeyframes : '') + '.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' + '.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: " "; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; z-index: -1; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }', head = doc.head || doc.getElementsByTagName('head')[0], style = doc.createElement('style'); style.id = 'detectElementResize'; style.type = 'text/css'; if (nonce != null) { style.setAttribute('nonce', nonce); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(doc.createTextNode(css)); } head.appendChild(style); } }; var addResizeListener = function addResizeListener(element, fn) { if (attachEvent) { element.attachEvent('onresize', fn); } else { if (!element.__resizeTriggers__) { var doc = element.ownerDocument; var elementStyle = _window.getComputedStyle(element); if (elementStyle && elementStyle.position == 'static') { element.style.position = 'relative'; } createStyles(doc); element.__resizeLast__ = {}; element.__resizeListeners__ = []; (element.__resizeTriggers__ = doc.createElement('div')).className = 'resize-triggers'; var resizeTriggersHtml = '<div class="expand-trigger"><div></div></div>' + '<div class="contract-trigger"></div>'; if (window.trustedTypes) { var staticPolicy = trustedTypes.createPolicy('react-virtualized-auto-sizer', { createHTML: function createHTML() { return resizeTriggersHtml; } }); element.__resizeTriggers__.innerHTML = staticPolicy.createHTML(''); } else { element.__resizeTriggers__.innerHTML = resizeTriggersHtml; } element.appendChild(element.__resizeTriggers__); resetTriggers(element); element.addEventListener('scroll', scrollListener, true); /* Listen for a css animation to detect element display/re-attach */ if (animationstartevent) { element.__resizeTriggers__.__animationListener__ = function animationListener(e) { if (e.animationName == animationName) { resetTriggers(element); } }; element.__resizeTriggers__.addEventListener(animationstartevent, element.__resizeTriggers__.__animationListener__); } } element.__resizeListeners__.push(fn); } }; var removeResizeListener = function removeResizeListener(element, fn) { if (attachEvent) { element.detachEvent('onresize', fn); } else { element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1); if (!element.__resizeListeners__.length) { element.removeEventListener('scroll', scrollListener, true); if (element.__resizeTriggers__.__animationListener__) { element.__resizeTriggers__.removeEventListener(animationstartevent, element.__resizeTriggers__.__animationListener__); element.__resizeTriggers__.__animationListener__ = null; } try { element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__); } catch (e) {// Preact compat; see developit/preact-compat/issues/228 } } } }; return { addResizeListener: addResizeListener, removeResizeListener: removeResizeListener }; }dist/es/Collection/Section.js000064400000003111151676725770012176 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; /** * A section of the Window. * Window Sections are used to group nearby cells. * This enables us to more quickly determine which cells to display in a given region of the Window. * Sections have a fixed size and contain 0 to many cells (tracked by their indices). */ var Section = /*#__PURE__*/ function () { function Section(_ref) { var height = _ref.height, width = _ref.width, x = _ref.x, y = _ref.y; _classCallCheck(this, Section); this.height = height; this.width = width; this.x = x; this.y = y; this._indexMap = {}; this._indices = []; } /** Add a cell to this section. */ _createClass(Section, [{ key: "addCellIndex", value: function addCellIndex(_ref2) { var index = _ref2.index; if (!this._indexMap[index]) { this._indexMap[index] = true; this._indices.push(index); } } /** Get all cell indices that have been added to this section. */ }, { key: "getCellIndices", value: function getCellIndices() { return this._indices; } /** Intended for debugger/test purposes only */ }, { key: "toString", value: function toString() { return "".concat(this.x, ",").concat(this.y, " ").concat(this.width, "x").concat(this.height); } }]); return Section; }(); export { Section as default }; import { bpfrpt_proptype_Index } from "./types"; import { bpfrpt_proptype_SizeAndPositionInfo } from "./types";dist/es/Collection/types.js000064400000002115151676725770011741 0ustar00var bpfrpt_proptype_Index = process.env.NODE_ENV === 'production' ? null : { "index": PropTypes.number.isRequired }; var bpfrpt_proptype_PositionInfo = process.env.NODE_ENV === 'production' ? null : { "x": PropTypes.number.isRequired, "y": PropTypes.number.isRequired }; var bpfrpt_proptype_ScrollPosition = process.env.NODE_ENV === 'production' ? null : { "scrollLeft": PropTypes.number.isRequired, "scrollTop": PropTypes.number.isRequired }; var bpfrpt_proptype_SizeAndPositionInfo = process.env.NODE_ENV === 'production' ? null : { "height": PropTypes.number.isRequired, "width": PropTypes.number.isRequired, "x": PropTypes.number.isRequired, "y": PropTypes.number.isRequired }; var bpfrpt_proptype_SizeInfo = process.env.NODE_ENV === 'production' ? null : { "height": PropTypes.number.isRequired, "width": PropTypes.number.isRequired }; import PropTypes from "prop-types"; export { bpfrpt_proptype_Index }; export { bpfrpt_proptype_PositionInfo }; export { bpfrpt_proptype_ScrollPosition }; export { bpfrpt_proptype_SizeAndPositionInfo }; export { bpfrpt_proptype_SizeInfo };dist/es/Collection/SectionManager.js000064400000010050151676725770013471 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; /** * Window Sections are used to group nearby cells. * This enables us to more quickly determine which cells to display in a given region of the Window. * */ import Section from './Section'; var SECTION_SIZE = 100; /** * Contains 0 to many Sections. * Grows (and adds Sections) dynamically as cells are registered. * Automatically adds cells to the appropriate Section(s). */ var SectionManager = /*#__PURE__*/ function () { function SectionManager() { var sectionSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : SECTION_SIZE; _classCallCheck(this, SectionManager); this._sectionSize = sectionSize; this._cellMetadata = []; this._sections = {}; } /** * Gets all cell indices contained in the specified region. * A region may encompass 1 or more Sections. */ _createClass(SectionManager, [{ key: "getCellIndices", value: function getCellIndices(_ref) { var height = _ref.height, width = _ref.width, x = _ref.x, y = _ref.y; var indices = {}; this.getSections({ height: height, width: width, x: x, y: y }).forEach(function (section) { return section.getCellIndices().forEach(function (index) { indices[index] = index; }); }); // Object keys are strings; this function returns numbers return Object.keys(indices).map(function (index) { return indices[index]; }); } /** Get size and position information for the cell specified. */ }, { key: "getCellMetadata", value: function getCellMetadata(_ref2) { var index = _ref2.index; return this._cellMetadata[index]; } /** Get all Sections overlapping the specified region. */ }, { key: "getSections", value: function getSections(_ref3) { var height = _ref3.height, width = _ref3.width, x = _ref3.x, y = _ref3.y; var sectionXStart = Math.floor(x / this._sectionSize); var sectionXStop = Math.floor((x + width - 1) / this._sectionSize); var sectionYStart = Math.floor(y / this._sectionSize); var sectionYStop = Math.floor((y + height - 1) / this._sectionSize); var sections = []; for (var sectionX = sectionXStart; sectionX <= sectionXStop; sectionX++) { for (var sectionY = sectionYStart; sectionY <= sectionYStop; sectionY++) { var key = "".concat(sectionX, ".").concat(sectionY); if (!this._sections[key]) { this._sections[key] = new Section({ height: this._sectionSize, width: this._sectionSize, x: sectionX * this._sectionSize, y: sectionY * this._sectionSize }); } sections.push(this._sections[key]); } } return sections; } /** Total number of Sections based on the currently registered cells. */ }, { key: "getTotalSectionCount", value: function getTotalSectionCount() { return Object.keys(this._sections).length; } /** Intended for debugger/test purposes only */ }, { key: "toString", value: function toString() { var _this = this; return Object.keys(this._sections).map(function (index) { return _this._sections[index].toString(); }); } /** Adds a cell to the appropriate Sections and registers it metadata for later retrievable. */ }, { key: "registerCell", value: function registerCell(_ref4) { var cellMetadatum = _ref4.cellMetadatum, index = _ref4.index; this._cellMetadata[index] = cellMetadatum; this.getSections(cellMetadatum).forEach(function (section) { return section.addCellIndex({ index: index }); }); } }]); return SectionManager; }(); export { SectionManager as default }; import { bpfrpt_proptype_Index } from "./types"; import { bpfrpt_proptype_SizeAndPositionInfo } from "./types";dist/es/Collection/Collection.example.js000064400000021704151676725770014327 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import PropTypes from 'prop-types'; import * as React from 'react'; import Immutable from 'immutable'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import { LabeledInput, InputRow } from '../demo/LabeledInput'; import AutoSizer from '../AutoSizer'; import Collection from './Collection'; import styles from './Collection.example.css'; // Defines a pattern of sizes and positions for a range of 10 rotating cells // These cells cover an area of 600 (wide) x 400 (tall) var GUTTER_SIZE = 3; var CELL_WIDTH = 75; var CollectionExample = /*#__PURE__*/ function (_React$PureComponent) { _inherits(CollectionExample, _React$PureComponent); function CollectionExample(props, context) { var _this; _classCallCheck(this, CollectionExample); _this = _possibleConstructorReturn(this, _getPrototypeOf(CollectionExample).call(this, props, context)); _this.state = { cellCount: context.list.size, columnCount: _this._getColumnCount(context.list.size), height: 300, horizontalOverscanSize: 0, scrollToCell: undefined, showScrollingPlaceholder: false, verticalOverscanSize: 0 }; _this._columnYMap = []; _this._cellRenderer = _this._cellRenderer.bind(_assertThisInitialized(_this)); _this._cellSizeAndPositionGetter = _this._cellSizeAndPositionGetter.bind(_assertThisInitialized(_this)); _this._noContentRenderer = _this._noContentRenderer.bind(_assertThisInitialized(_this)); _this._onCellCountChange = _this._onCellCountChange.bind(_assertThisInitialized(_this)); _this._onHeightChange = _this._onHeightChange.bind(_assertThisInitialized(_this)); _this._onHorizontalOverscanSizeChange = _this._onHorizontalOverscanSizeChange.bind(_assertThisInitialized(_this)); _this._onScrollToCellChange = _this._onScrollToCellChange.bind(_assertThisInitialized(_this)); _this._onVerticalOverscanSizeChange = _this._onVerticalOverscanSizeChange.bind(_assertThisInitialized(_this)); return _this; } _createClass(CollectionExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, cellCount = _this$state.cellCount, height = _this$state.height, horizontalOverscanSize = _this$state.horizontalOverscanSize, scrollToCell = _this$state.scrollToCell, showScrollingPlaceholder = _this$state.showScrollingPlaceholder, verticalOverscanSize = _this$state.verticalOverscanSize; return React.createElement(ContentBox, null, React.createElement(ContentBoxHeader, { text: "Collection", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/Collection/Collection.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/Collection.md" }), React.createElement(ContentBoxParagraph, null, "Renders scattered or non-linear data. Unlike ", React.createElement("code", null, "Grid"), ", which renders checkerboard data, ", React.createElement("code", null, "Collection"), " can render arbitrarily positioned- even overlapping- data."), React.createElement(ContentBoxParagraph, null, React.createElement("label", { className: styles.checkboxLabel }, React.createElement("input", { "aria-label": "Show placeholder while scrolling?", checked: showScrollingPlaceholder, className: styles.checkbox, type: "checkbox", onChange: function onChange(event) { return _this2.setState({ showScrollingPlaceholder: event.target.checked }); } }), "Show placeholder while scrolling?")), React.createElement(InputRow, null, React.createElement(LabeledInput, { label: "Num cells", name: "cellCount", onChange: this._onCellCountChange, value: cellCount }), React.createElement(LabeledInput, { label: "Scroll to cell", name: "onScrollToCell", placeholder: "Index...", onChange: this._onScrollToCellChange, value: scrollToCell || '' }), React.createElement(LabeledInput, { label: "Height", name: "height", onChange: this._onHeightChange, value: height }), React.createElement(LabeledInput, { label: "Horizontal Overscan", name: "horizontalOverscanSize", onChange: this._onHorizontalOverscanSizeChange, value: horizontalOverscanSize }), React.createElement(LabeledInput, { label: "Vertical Overscan", name: "verticalOverscanSize", onChange: this._onVerticalOverscanSizeChange, value: verticalOverscanSize })), React.createElement(AutoSizer, { disableHeight: true }, function (_ref) { var width = _ref.width; return React.createElement(Collection, { cellCount: cellCount, cellRenderer: _this2._cellRenderer, cellSizeAndPositionGetter: _this2._cellSizeAndPositionGetter, className: styles.collection, height: height, horizontalOverscanSize: horizontalOverscanSize, noContentRenderer: _this2._noContentRenderer, scrollToCell: scrollToCell, verticalOverscanSize: verticalOverscanSize, width: width }); })); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref2) { var index = _ref2.index, isScrolling = _ref2.isScrolling, key = _ref2.key, style = _ref2.style; var list = this.context.list; var showScrollingPlaceholder = this.state.showScrollingPlaceholder; var datum = list.get(index % list.size); // Customize style style.backgroundColor = datum.color; return React.createElement("div", { className: styles.cell, key: key, style: style }, showScrollingPlaceholder && isScrolling ? '...' : index); } }, { key: "_cellSizeAndPositionGetter", value: function _cellSizeAndPositionGetter(_ref3) { var index = _ref3.index; var list = this.context.list; var columnCount = this.state.columnCount; var columnPosition = index % (columnCount || 1); var datum = list.get(index % list.size); // Poor man's Masonry layout; columns won't all line up equally with the bottom. var height = datum.size; var width = CELL_WIDTH; var x = columnPosition * (GUTTER_SIZE + width); var y = this._columnYMap[columnPosition] || 0; this._columnYMap[columnPosition] = y + height + GUTTER_SIZE; return { height: height, width: width, x: x, y: y }; } }, { key: "_getColumnCount", value: function _getColumnCount(cellCount) { return Math.round(Math.sqrt(cellCount)); } }, { key: "_onHorizontalOverscanSizeChange", value: function _onHorizontalOverscanSizeChange(event) { var horizontalOverscanSize = parseInt(event.target.value, 10) || 0; this.setState({ horizontalOverscanSize: horizontalOverscanSize }); } }, { key: "_noContentRenderer", value: function _noContentRenderer() { return React.createElement("div", { className: styles.noCells }, "No cells"); } }, { key: "_onCellCountChange", value: function _onCellCountChange(event) { var cellCount = parseInt(event.target.value, 10) || 0; this._columnYMap = []; this.setState({ cellCount: cellCount, columnCount: this._getColumnCount(cellCount) }); } }, { key: "_onHeightChange", value: function _onHeightChange(event) { var height = parseInt(event.target.value, 10) || 0; this.setState({ height: height }); } }, { key: "_onScrollToCellChange", value: function _onScrollToCellChange(event) { var cellCount = this.state.cellCount; var scrollToCell = Math.min(cellCount - 1, parseInt(event.target.value, 10)); if (isNaN(scrollToCell)) { scrollToCell = undefined; } this.setState({ scrollToCell: scrollToCell }); } }, { key: "_onVerticalOverscanSizeChange", value: function _onVerticalOverscanSizeChange(event) { var verticalOverscanSize = parseInt(event.target.value, 10) || 0; this.setState({ verticalOverscanSize: verticalOverscanSize }); } }]); return CollectionExample; }(React.PureComponent); _defineProperty(CollectionExample, "contextTypes", { list: PropTypes.instanceOf(Immutable.List).isRequired }); export { CollectionExample as default };dist/es/Collection/Section.jest.js000064400000003062151676725770013147 0ustar00import Section from './Section'; describe('Section', function () { function helper() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$height = _ref.height, height = _ref$height === void 0 ? 100 : _ref$height, _ref$width = _ref.width, width = _ref$width === void 0 ? 200 : _ref$width, _ref$x = _ref.x, x = _ref$x === void 0 ? 0 : _ref$x, _ref$y = _ref.y, y = _ref$y === void 0 ? 0 : _ref$y; return new Section({ height: height, width: width, x: x, y: y }); } it('should add a new cell index', function () { var section = helper(); expect(section.getCellIndices()).toEqual([]); section.addCellIndex({ index: 0 }); expect(section.getCellIndices()).toEqual([0]); section.addCellIndex({ index: 1 }); expect(section.getCellIndices()).toEqual([0, 1]); }); it('should not add a duplicate cell index', function () { var section = helper(); section.addCellIndex({ index: 0 }); section.addCellIndex({ index: 1 }); section.addCellIndex({ index: 0 }); section.addCellIndex({ index: 1 }); section.addCellIndex({ index: 2 }); expect(section.getCellIndices()).toEqual([0, 1, 2]); }); it('should define a working toString() method for debugging', function () { var section = helper({ height: 100, width: 200, x: 25, y: 50 }); expect(section.toString()).toEqual('25,50 200x100'); }); });dist/es/Collection/utils/calculateSizeAndPositionData.js000064400000002534151676725770017474 0ustar00import SectionManager from '../SectionManager'; export default function calculateSizeAndPositionData(_ref) { var cellCount = _ref.cellCount, cellSizeAndPositionGetter = _ref.cellSizeAndPositionGetter, sectionSize = _ref.sectionSize; var cellMetadata = []; var sectionManager = new SectionManager(sectionSize); var height = 0; var width = 0; for (var index = 0; index < cellCount; index++) { var cellMetadatum = cellSizeAndPositionGetter({ index: index }); if (cellMetadatum.height == null || isNaN(cellMetadatum.height) || cellMetadatum.width == null || isNaN(cellMetadatum.width) || cellMetadatum.x == null || isNaN(cellMetadatum.x) || cellMetadatum.y == null || isNaN(cellMetadatum.y)) { throw Error("Invalid metadata returned for cell ".concat(index, ":\n x:").concat(cellMetadatum.x, ", y:").concat(cellMetadatum.y, ", width:").concat(cellMetadatum.width, ", height:").concat(cellMetadatum.height)); } height = Math.max(height, cellMetadatum.y + cellMetadatum.height); width = Math.max(width, cellMetadatum.x + cellMetadatum.width); cellMetadata[index] = cellMetadatum; sectionManager.registerCell({ cellMetadatum: cellMetadatum, index: index }); } return { cellMetadata: cellMetadata, height: height, sectionManager: sectionManager, width: width }; }dist/es/Collection/utils/calculateSizeAndPositionData.jest.js000064400000002132151676725770020432 0ustar00import calculateSizeAndPositionData from './calculateSizeAndPositionData'; describe('calculateSizeAndPositionData', function () { it('should query for size and position of each cell', function () { var cellSizeAndPositionGetterCalls = []; function cellSizeAndPositionGetter(_ref) { var index = _ref.index; cellSizeAndPositionGetterCalls.push(index); return { x: index * 50, y: 0, width: 50, height: 50 }; } var _calculateSizeAndPosi = calculateSizeAndPositionData({ cellCount: 3, cellSizeAndPositionGetter: cellSizeAndPositionGetter }), sectionManager = _calculateSizeAndPosi.sectionManager; expect(cellSizeAndPositionGetterCalls).toEqual([0, 1, 2]); expect(sectionManager.getTotalSectionCount()).toEqual(2); }); it('should throw an error if invalid metadata is returned for a cell', function () { expect(function () { return calculateSizeAndPositionData({ cellCount: 3, cellSizeAndPositionGetter: function cellSizeAndPositionGetter() {} }); }).toThrow(); }); });dist/es/Collection/index.js000064400000000130151676725770011677 0ustar00import Collection from './Collection'; export default Collection; export { Collection };dist/es/Collection/Collection.js000064400000021157151676725770012677 0ustar00import _extends from "@babel/runtime/helpers/extends"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import PropTypes from 'prop-types'; import * as React from 'react'; import CollectionView from './CollectionView'; import _calculateSizeAndPositionData from './utils/calculateSizeAndPositionData'; import getUpdatedOffsetForIndex from '../utils/getUpdatedOffsetForIndex'; /** * Renders scattered or non-linear data. * Unlike Grid, which renders checkerboard data, Collection can render arbitrarily positioned- even overlapping- data. */ var Collection = /*#__PURE__*/ function (_React$PureComponent) { _inherits(Collection, _React$PureComponent); function Collection(props, context) { var _this; _classCallCheck(this, Collection); _this = _possibleConstructorReturn(this, _getPrototypeOf(Collection).call(this, props, context)); _this._cellMetadata = []; _this._lastRenderedCellIndices = []; // Cell cache during scroll (for performance) _this._cellCache = []; _this._isScrollingChange = _this._isScrollingChange.bind(_assertThisInitialized(_this)); _this._setCollectionViewRef = _this._setCollectionViewRef.bind(_assertThisInitialized(_this)); return _this; } _createClass(Collection, [{ key: "forceUpdate", value: function forceUpdate() { if (this._collectionView !== undefined) { this._collectionView.forceUpdate(); } } /** See Collection#recomputeCellSizesAndPositions */ }, { key: "recomputeCellSizesAndPositions", value: function recomputeCellSizesAndPositions() { this._cellCache = []; this._collectionView.recomputeCellSizesAndPositions(); } /** React lifecycle methods */ }, { key: "render", value: function render() { var props = _extends({}, this.props); return React.createElement(CollectionView, _extends({ cellLayoutManager: this, isScrollingChange: this._isScrollingChange, ref: this._setCollectionViewRef }, props)); } /** CellLayoutManager interface */ }, { key: "calculateSizeAndPositionData", value: function calculateSizeAndPositionData() { var _this$props = this.props, cellCount = _this$props.cellCount, cellSizeAndPositionGetter = _this$props.cellSizeAndPositionGetter, sectionSize = _this$props.sectionSize; var data = _calculateSizeAndPositionData({ cellCount: cellCount, cellSizeAndPositionGetter: cellSizeAndPositionGetter, sectionSize: sectionSize }); this._cellMetadata = data.cellMetadata; this._sectionManager = data.sectionManager; this._height = data.height; this._width = data.width; } /** * Returns the most recently rendered set of cell indices. */ }, { key: "getLastRenderedIndices", value: function getLastRenderedIndices() { return this._lastRenderedCellIndices; } /** * Calculates the minimum amount of change from the current scroll position to ensure the specified cell is (fully) visible. */ }, { key: "getScrollPositionForCell", value: function getScrollPositionForCell(_ref) { var align = _ref.align, cellIndex = _ref.cellIndex, height = _ref.height, scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, width = _ref.width; var cellCount = this.props.cellCount; if (cellIndex >= 0 && cellIndex < cellCount) { var cellMetadata = this._cellMetadata[cellIndex]; scrollLeft = getUpdatedOffsetForIndex({ align: align, cellOffset: cellMetadata.x, cellSize: cellMetadata.width, containerSize: width, currentOffset: scrollLeft, targetIndex: cellIndex }); scrollTop = getUpdatedOffsetForIndex({ align: align, cellOffset: cellMetadata.y, cellSize: cellMetadata.height, containerSize: height, currentOffset: scrollTop, targetIndex: cellIndex }); } return { scrollLeft: scrollLeft, scrollTop: scrollTop }; } }, { key: "getTotalSize", value: function getTotalSize() { return { height: this._height, width: this._width }; } }, { key: "cellRenderers", value: function cellRenderers(_ref2) { var _this2 = this; var height = _ref2.height, isScrolling = _ref2.isScrolling, width = _ref2.width, x = _ref2.x, y = _ref2.y; var _this$props2 = this.props, cellGroupRenderer = _this$props2.cellGroupRenderer, cellRenderer = _this$props2.cellRenderer; // Store for later calls to getLastRenderedIndices() this._lastRenderedCellIndices = this._sectionManager.getCellIndices({ height: height, width: width, x: x, y: y }); return cellGroupRenderer({ cellCache: this._cellCache, cellRenderer: cellRenderer, cellSizeAndPositionGetter: function cellSizeAndPositionGetter(_ref3) { var index = _ref3.index; return _this2._sectionManager.getCellMetadata({ index: index }); }, indices: this._lastRenderedCellIndices, isScrolling: isScrolling }); } }, { key: "_isScrollingChange", value: function _isScrollingChange(isScrolling) { if (!isScrolling) { this._cellCache = []; } } }, { key: "_setCollectionViewRef", value: function _setCollectionViewRef(ref) { this._collectionView = ref; } }]); return Collection; }(React.PureComponent); _defineProperty(Collection, "defaultProps", { 'aria-label': 'grid', cellGroupRenderer: defaultCellGroupRenderer }); export { Collection as default }; Collection.propTypes = process.env.NODE_ENV !== "production" ? { 'aria-label': PropTypes.string, /** * Number of cells in Collection. */ cellCount: PropTypes.number.isRequired, /** * Responsible for rendering a group of cells given their indices. * Should implement the following interface: ({ * cellSizeAndPositionGetter:Function, * indices: Array<number>, * cellRenderer: Function * }): Array<PropTypes.node> */ cellGroupRenderer: PropTypes.func.isRequired, /** * Responsible for rendering a cell given an row and column index. * Should implement the following interface: ({ index: number, key: string, style: object }): PropTypes.element */ cellRenderer: PropTypes.func.isRequired, /** * Callback responsible for returning size and offset/position information for a given cell (index). * ({ index: number }): { height: number, width: number, x: number, y: number } */ cellSizeAndPositionGetter: PropTypes.func.isRequired, /** * Optionally override the size of the sections a Collection's cells are split into. */ sectionSize: PropTypes.number } : {}; function defaultCellGroupRenderer(_ref4) { var cellCache = _ref4.cellCache, cellRenderer = _ref4.cellRenderer, cellSizeAndPositionGetter = _ref4.cellSizeAndPositionGetter, indices = _ref4.indices, isScrolling = _ref4.isScrolling; return indices.map(function (index) { var cellMetadata = cellSizeAndPositionGetter({ index: index }); var cellRendererProps = { index: index, isScrolling: isScrolling, key: index, style: { height: cellMetadata.height, left: cellMetadata.x, position: 'absolute', top: cellMetadata.y, width: cellMetadata.width } }; // Avoid re-creating cells while scrolling. // This can lead to the same cell being created many times and can cause performance issues for "heavy" cells. // If a scroll is in progress- cache and reuse cells. // This cache will be thrown away once scrolling complets. if (isScrolling) { if (!(index in cellCache)) { cellCache[index] = cellRenderer(cellRendererProps); } return cellCache[index]; } else { return cellRenderer(cellRendererProps); } }).filter(function (renderedCell) { return !!renderedCell; }); } import { bpfrpt_proptype_ScrollPosition } from "./types"; import { bpfrpt_proptype_SizeInfo } from "./types";dist/es/Collection/TestData.js000064400000001476151676725770012317 0ustar00/* 0 1 2 3 4 5 ┏━━━┯━━━┯━━━┓ 0┃0 0┊1 3┊6 6┃ 1┃0 0┊2 3┊6 6┃ ┠┈┈┈┼┈┈┈┼┈┈┈┨ 2┃4 4┊4 3┊7 8┃ 3┃4 4┊4 5┊9 9┃ ┗━━━┷━━━┷━━━┛ Sections to Cells map: 0.0 [0] 1.0 [1, 2, 3] 2.0 [6] 0.1 [4] 1.1 [3, 4, 5] 2.1 [7, 8, 9] */ export var CELLS = [{ x: 0, y: 0, width: 2, height: 2 }, { x: 2, y: 0, width: 1, height: 1 }, { x: 2, y: 1, width: 1, height: 1 }, { x: 3, y: 0, width: 1, height: 3 }, { x: 0, y: 2, width: 3, height: 2 }, { x: 3, y: 3, width: 1, height: 1 }, { x: 4, y: 0, width: 2, height: 2 }, { x: 4, y: 2, width: 1, height: 1 }, { x: 5, y: 2, width: 1, height: 1 }, { x: 4, y: 3, width: 2, height: 1 }]; export var SECTION_SIZE = 2;dist/es/Collection/SectionManager.jest.js000064400000005247151676725770014451 0ustar00import SectionManager from './SectionManager'; import { CELLS, SECTION_SIZE } from './TestData'; function initSectionManager() { var sectionManager = new SectionManager(SECTION_SIZE); CELLS.forEach(function (cellMetadatum, index) { sectionManager.registerCell({ cellMetadatum: cellMetadatum, index: index }); }); return sectionManager; } function verifySections(sectionManager, sizeAndPosition, expectedSizeAndPositionInfos) { var sections = sectionManager.getSections(sizeAndPosition); expect(sections.length).toEqual(expectedSizeAndPositionInfos.length); expectedSizeAndPositionInfos.forEach(function (sizeAndPosition) { var match = sections.find(function (section) { return section.x === sizeAndPosition.x && section.y === sizeAndPosition.y; }); expect(!!match).toEqual(true); }); } describe('SectionManager', function () { it('creates the appropriate number of Sections', function () { var sectionManager = initSectionManager(); expect(sectionManager.getTotalSectionCount()).toEqual(6); }); it('returns the proper Sections based on the specified area', function () { var sectionManager = initSectionManager(); verifySections(sectionManager, { x: 0, y: 0, width: 1, height: 1 }, [{ x: 0, y: 0 }]); verifySections(sectionManager, { x: 1, y: 1, width: 1, height: 1 }, [{ x: 0, y: 0 }]); verifySections(sectionManager, { x: 0, y: 0, width: 4, height: 4 }, [{ x: 0, y: 0 }, { x: 2, y: 0 }, { x: 0, y: 2 }, { x: 2, y: 2 }]); verifySections(sectionManager, { x: 4, y: 0, width: 2, height: 3 }, [{ x: 4, y: 0 }, { x: 4, y: 2 }]); }); it('assigns cells to the appropriate sections', function () { var sectionManager = initSectionManager(); expect(sectionManager.getCellIndices({ x: 0, y: 0, width: 2, height: 2 })).toEqual([0]); expect(sectionManager.getCellIndices({ x: 2, y: 0, width: 2, height: 2 })).toEqual([1, 2, 3]); expect(sectionManager.getCellIndices({ x: 4, y: 0, width: 2, height: 2 })).toEqual([6]); expect(sectionManager.getCellIndices({ x: 0, y: 2, width: 2, height: 2 })).toEqual([4]); expect(sectionManager.getCellIndices({ x: 2, y: 2, width: 2, height: 2 })).toEqual([3, 4, 5]); expect(sectionManager.getCellIndices({ x: 4, y: 2, width: 2, height: 2 })).toEqual([7, 8, 9]); }); });dist/es/Collection/CollectionView.js000064400000056774151676725770013547 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import clsx from 'clsx'; import PropTypes from 'prop-types'; import * as React from 'react'; import { polyfill } from 'react-lifecycles-compat'; import createCallbackMemoizer from '../utils/createCallbackMemoizer'; import getScrollbarSize from 'dom-helpers/scrollbarSize'; // @TODO Merge Collection and CollectionView /** * Specifies the number of milliseconds during which to disable pointer events while a scroll is in progress. * This improves performance and makes scrolling smoother. */ var IS_SCROLLING_TIMEOUT = 150; /** * Controls whether the Grid updates the DOM element's scrollLeft/scrollTop based on the current state or just observes it. * This prevents Grid from interrupting mouse-wheel animations (see issue #2). */ var SCROLL_POSITION_CHANGE_REASONS = { OBSERVED: 'observed', REQUESTED: 'requested' }; /** * Monitors changes in properties (eg. cellCount) and state (eg. scroll offsets) to determine when rendering needs to occur. * This component does not render any visible content itself; it defers to the specified :cellLayoutManager. */ var CollectionView = /*#__PURE__*/ function (_React$PureComponent) { _inherits(CollectionView, _React$PureComponent); // Invokes callbacks only when their values have changed. function CollectionView() { var _getPrototypeOf2; var _this; _classCallCheck(this, CollectionView); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(CollectionView)).call.apply(_getPrototypeOf2, [this].concat(args))); // If this component is being rendered server-side, getScrollbarSize() will return undefined. // We handle this case in componentDidMount() _defineProperty(_assertThisInitialized(_this), "state", { isScrolling: false, scrollLeft: 0, scrollTop: 0 }); _defineProperty(_assertThisInitialized(_this), "_calculateSizeAndPositionDataOnNextUpdate", false); _defineProperty(_assertThisInitialized(_this), "_onSectionRenderedMemoizer", createCallbackMemoizer()); _defineProperty(_assertThisInitialized(_this), "_onScrollMemoizer", createCallbackMemoizer(false)); _defineProperty(_assertThisInitialized(_this), "_invokeOnSectionRenderedHelper", function () { var _this$props = _this.props, cellLayoutManager = _this$props.cellLayoutManager, onSectionRendered = _this$props.onSectionRendered; _this._onSectionRenderedMemoizer({ callback: onSectionRendered, indices: { indices: cellLayoutManager.getLastRenderedIndices() } }); }); _defineProperty(_assertThisInitialized(_this), "_setScrollingContainerRef", function (ref) { _this._scrollingContainer = ref; }); _defineProperty(_assertThisInitialized(_this), "_updateScrollPositionForScrollToCell", function () { var _this$props2 = _this.props, cellLayoutManager = _this$props2.cellLayoutManager, height = _this$props2.height, scrollToAlignment = _this$props2.scrollToAlignment, scrollToCell = _this$props2.scrollToCell, width = _this$props2.width; var _this$state = _this.state, scrollLeft = _this$state.scrollLeft, scrollTop = _this$state.scrollTop; if (scrollToCell >= 0) { var scrollPosition = cellLayoutManager.getScrollPositionForCell({ align: scrollToAlignment, cellIndex: scrollToCell, height: height, scrollLeft: scrollLeft, scrollTop: scrollTop, width: width }); if (scrollPosition.scrollLeft !== scrollLeft || scrollPosition.scrollTop !== scrollTop) { _this._setScrollPosition(scrollPosition); } } }); _defineProperty(_assertThisInitialized(_this), "_onScroll", function (event) { // In certain edge-cases React dispatches an onScroll event with an invalid target.scrollLeft / target.scrollTop. // This invalid event can be detected by comparing event.target to this component's scrollable DOM element. // See issue #404 for more information. if (event.target !== _this._scrollingContainer) { return; } // Prevent pointer events from interrupting a smooth scroll _this._enablePointerEventsAfterDelay(); // When this component is shrunk drastically, React dispatches a series of back-to-back scroll events, // Gradually converging on a scrollTop that is within the bounds of the new, smaller height. // This causes a series of rapid renders that is slow for long lists. // We can avoid that by doing some simple bounds checking to ensure that scrollTop never exceeds the total height. var _this$props3 = _this.props, cellLayoutManager = _this$props3.cellLayoutManager, height = _this$props3.height, isScrollingChange = _this$props3.isScrollingChange, width = _this$props3.width; var scrollbarSize = _this._scrollbarSize; var _cellLayoutManager$ge = cellLayoutManager.getTotalSize(), totalHeight = _cellLayoutManager$ge.height, totalWidth = _cellLayoutManager$ge.width; var scrollLeft = Math.max(0, Math.min(totalWidth - width + scrollbarSize, event.target.scrollLeft)); var scrollTop = Math.max(0, Math.min(totalHeight - height + scrollbarSize, event.target.scrollTop)); // Certain devices (like Apple touchpad) rapid-fire duplicate events. // Don't force a re-render if this is the case. // The mouse may move faster then the animation frame does. // Use requestAnimationFrame to avoid over-updating. if (_this.state.scrollLeft !== scrollLeft || _this.state.scrollTop !== scrollTop) { // Browsers with cancelable scroll events (eg. Firefox) interrupt scrolling animations if scrollTop/scrollLeft is set. // Other browsers (eg. Safari) don't scroll as well without the help under certain conditions (DOM or style changes during scrolling). // All things considered, this seems to be the best current work around that I'm aware of. // For more information see https://github.com/bvaughn/react-virtualized/pull/124 var scrollPositionChangeReason = event.cancelable ? SCROLL_POSITION_CHANGE_REASONS.OBSERVED : SCROLL_POSITION_CHANGE_REASONS.REQUESTED; // Synchronously set :isScrolling the first time (since _setNextState will reschedule its animation frame each time it's called) if (!_this.state.isScrolling) { isScrollingChange(true); } _this.setState({ isScrolling: true, scrollLeft: scrollLeft, scrollPositionChangeReason: scrollPositionChangeReason, scrollTop: scrollTop }); } _this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft, scrollTop: scrollTop, totalWidth: totalWidth, totalHeight: totalHeight }); }); _this._scrollbarSize = getScrollbarSize(); if (_this._scrollbarSize === undefined) { _this._scrollbarSizeMeasured = false; _this._scrollbarSize = 0; } else { _this._scrollbarSizeMeasured = true; } return _this; } /** * Forced recompute of cell sizes and positions. * This function should be called if cell sizes have changed but nothing else has. * Since cell positions are calculated by callbacks, the collection view has no way of detecting when the underlying data has changed. */ _createClass(CollectionView, [{ key: "recomputeCellSizesAndPositions", value: function recomputeCellSizesAndPositions() { this._calculateSizeAndPositionDataOnNextUpdate = true; this.forceUpdate(); } /* ---------------------------- Component lifecycle methods ---------------------------- */ /** * @private * This method updates scrollLeft/scrollTop in state for the following conditions: * 1) Empty content (0 rows or columns) * 2) New scroll props overriding the current state * 3) Cells-count or cells-size has changed, making previous scroll offsets invalid */ }, { key: "componentDidMount", value: function componentDidMount() { var _this$props4 = this.props, cellLayoutManager = _this$props4.cellLayoutManager, scrollLeft = _this$props4.scrollLeft, scrollToCell = _this$props4.scrollToCell, scrollTop = _this$props4.scrollTop; // If this component was first rendered server-side, scrollbar size will be undefined. // In that event we need to remeasure. if (!this._scrollbarSizeMeasured) { this._scrollbarSize = getScrollbarSize(); this._scrollbarSizeMeasured = true; this.setState({}); } if (scrollToCell >= 0) { this._updateScrollPositionForScrollToCell(); } else if (scrollLeft >= 0 || scrollTop >= 0) { this._setScrollPosition({ scrollLeft: scrollLeft, scrollTop: scrollTop }); } // Update onSectionRendered callback. this._invokeOnSectionRenderedHelper(); var _cellLayoutManager$ge2 = cellLayoutManager.getTotalSize(), totalHeight = _cellLayoutManager$ge2.height, totalWidth = _cellLayoutManager$ge2.width; // Initialize onScroll callback. this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft || 0, scrollTop: scrollTop || 0, totalHeight: totalHeight, totalWidth: totalWidth }); } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { var _this$props5 = this.props, height = _this$props5.height, scrollToAlignment = _this$props5.scrollToAlignment, scrollToCell = _this$props5.scrollToCell, width = _this$props5.width; var _this$state2 = this.state, scrollLeft = _this$state2.scrollLeft, scrollPositionChangeReason = _this$state2.scrollPositionChangeReason, scrollTop = _this$state2.scrollTop; // Make sure requested changes to :scrollLeft or :scrollTop get applied. // Assigning to scrollLeft/scrollTop tells the browser to interrupt any running scroll animations, // And to discard any pending async changes to the scroll position that may have happened in the meantime (e.g. on a separate scrolling thread). // So we only set these when we require an adjustment of the scroll position. // See issue #2 for more information. if (scrollPositionChangeReason === SCROLL_POSITION_CHANGE_REASONS.REQUESTED) { if (scrollLeft >= 0 && scrollLeft !== prevState.scrollLeft && scrollLeft !== this._scrollingContainer.scrollLeft) { this._scrollingContainer.scrollLeft = scrollLeft; } if (scrollTop >= 0 && scrollTop !== prevState.scrollTop && scrollTop !== this._scrollingContainer.scrollTop) { this._scrollingContainer.scrollTop = scrollTop; } } // Update scroll offsets if the current :scrollToCell values requires it if (height !== prevProps.height || scrollToAlignment !== prevProps.scrollToAlignment || scrollToCell !== prevProps.scrollToCell || width !== prevProps.width) { this._updateScrollPositionForScrollToCell(); } // Update onRowsRendered callback if start/stop indices have changed this._invokeOnSectionRenderedHelper(); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this._disablePointerEventsTimeoutId) { clearTimeout(this._disablePointerEventsTimeoutId); } } }, { key: "render", value: function render() { var _this$props6 = this.props, autoHeight = _this$props6.autoHeight, cellCount = _this$props6.cellCount, cellLayoutManager = _this$props6.cellLayoutManager, className = _this$props6.className, height = _this$props6.height, horizontalOverscanSize = _this$props6.horizontalOverscanSize, id = _this$props6.id, noContentRenderer = _this$props6.noContentRenderer, style = _this$props6.style, verticalOverscanSize = _this$props6.verticalOverscanSize, width = _this$props6.width; var _this$state3 = this.state, isScrolling = _this$state3.isScrolling, scrollLeft = _this$state3.scrollLeft, scrollTop = _this$state3.scrollTop; // Memoization reset if (this._lastRenderedCellCount !== cellCount || this._lastRenderedCellLayoutManager !== cellLayoutManager || this._calculateSizeAndPositionDataOnNextUpdate) { this._lastRenderedCellCount = cellCount; this._lastRenderedCellLayoutManager = cellLayoutManager; this._calculateSizeAndPositionDataOnNextUpdate = false; cellLayoutManager.calculateSizeAndPositionData(); } var _cellLayoutManager$ge3 = cellLayoutManager.getTotalSize(), totalHeight = _cellLayoutManager$ge3.height, totalWidth = _cellLayoutManager$ge3.width; // Safely expand the rendered area by the specified overscan amount var left = Math.max(0, scrollLeft - horizontalOverscanSize); var top = Math.max(0, scrollTop - verticalOverscanSize); var right = Math.min(totalWidth, scrollLeft + width + horizontalOverscanSize); var bottom = Math.min(totalHeight, scrollTop + height + verticalOverscanSize); var childrenToDisplay = height > 0 && width > 0 ? cellLayoutManager.cellRenderers({ height: bottom - top, isScrolling: isScrolling, width: right - left, x: left, y: top }) : []; var collectionStyle = { boxSizing: 'border-box', direction: 'ltr', height: autoHeight ? 'auto' : height, position: 'relative', WebkitOverflowScrolling: 'touch', width: width, willChange: 'transform' }; // Force browser to hide scrollbars when we know they aren't necessary. // Otherwise once scrollbars appear they may not disappear again. // For more info see issue #116 var verticalScrollBarSize = totalHeight > height ? this._scrollbarSize : 0; var horizontalScrollBarSize = totalWidth > width ? this._scrollbarSize : 0; // Also explicitly init styles to 'auto' if scrollbars are required. // This works around an obscure edge case where external CSS styles have not yet been loaded, // But an initial scroll index of offset is set as an external prop. // Without this style, Grid would render the correct range of cells but would NOT update its internal offset. // This was originally reported via clauderic/react-infinite-calendar/issues/23 collectionStyle.overflowX = totalWidth + verticalScrollBarSize <= width ? 'hidden' : 'auto'; collectionStyle.overflowY = totalHeight + horizontalScrollBarSize <= height ? 'hidden' : 'auto'; return React.createElement("div", { ref: this._setScrollingContainerRef, "aria-label": this.props['aria-label'], className: clsx('ReactVirtualized__Collection', className), id: id, onScroll: this._onScroll, role: "grid", style: _objectSpread({}, collectionStyle, {}, style), tabIndex: 0 }, cellCount > 0 && React.createElement("div", { className: "ReactVirtualized__Collection__innerScrollContainer", style: { height: totalHeight, maxHeight: totalHeight, maxWidth: totalWidth, overflow: 'hidden', pointerEvents: isScrolling ? 'none' : '', width: totalWidth } }, childrenToDisplay), cellCount === 0 && noContentRenderer()); } /* ---------------------------- Helper methods ---------------------------- */ /** * Sets an :isScrolling flag for a small window of time. * This flag is used to disable pointer events on the scrollable portion of the Collection. * This prevents jerky/stuttery mouse-wheel scrolling. */ }, { key: "_enablePointerEventsAfterDelay", value: function _enablePointerEventsAfterDelay() { var _this2 = this; if (this._disablePointerEventsTimeoutId) { clearTimeout(this._disablePointerEventsTimeoutId); } this._disablePointerEventsTimeoutId = setTimeout(function () { var isScrollingChange = _this2.props.isScrollingChange; isScrollingChange(false); _this2._disablePointerEventsTimeoutId = null; _this2.setState({ isScrolling: false }); }, IS_SCROLLING_TIMEOUT); } }, { key: "_invokeOnScrollMemoizer", value: function _invokeOnScrollMemoizer(_ref) { var _this3 = this; var scrollLeft = _ref.scrollLeft, scrollTop = _ref.scrollTop, totalHeight = _ref.totalHeight, totalWidth = _ref.totalWidth; this._onScrollMemoizer({ callback: function callback(_ref2) { var scrollLeft = _ref2.scrollLeft, scrollTop = _ref2.scrollTop; var _this3$props = _this3.props, height = _this3$props.height, onScroll = _this3$props.onScroll, width = _this3$props.width; onScroll({ clientHeight: height, clientWidth: width, scrollHeight: totalHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: totalWidth }); }, indices: { scrollLeft: scrollLeft, scrollTop: scrollTop } }); } }, { key: "_setScrollPosition", value: function _setScrollPosition(_ref3) { var scrollLeft = _ref3.scrollLeft, scrollTop = _ref3.scrollTop; var newState = { scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS.REQUESTED }; if (scrollLeft >= 0) { newState.scrollLeft = scrollLeft; } if (scrollTop >= 0) { newState.scrollTop = scrollTop; } if (scrollLeft >= 0 && scrollLeft !== this.state.scrollLeft || scrollTop >= 0 && scrollTop !== this.state.scrollTop) { this.setState(newState); } } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps, prevState) { if (nextProps.cellCount === 0 && (prevState.scrollLeft !== 0 || prevState.scrollTop !== 0)) { return { scrollLeft: 0, scrollTop: 0, scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS.REQUESTED }; } else if (nextProps.scrollLeft !== prevState.scrollLeft || nextProps.scrollTop !== prevState.scrollTop) { return { scrollLeft: nextProps.scrollLeft != null ? nextProps.scrollLeft : prevState.scrollLeft, scrollTop: nextProps.scrollTop != null ? nextProps.scrollTop : prevState.scrollTop, scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS.REQUESTED }; } return null; } }]); return CollectionView; }(React.PureComponent); _defineProperty(CollectionView, "defaultProps", { 'aria-label': 'grid', horizontalOverscanSize: 0, noContentRenderer: function noContentRenderer() { return null; }, onScroll: function onScroll() { return null; }, onSectionRendered: function onSectionRendered() { return null; }, scrollToAlignment: 'auto', scrollToCell: -1, style: {}, verticalOverscanSize: 0 }); CollectionView.propTypes = process.env.NODE_ENV !== "production" ? { 'aria-label': PropTypes.string, /** * Removes fixed height from the scrollingContainer so that the total height * of rows can stretch the window. Intended for use with WindowScroller */ autoHeight: PropTypes.bool, /** * Number of cells in collection. */ cellCount: PropTypes.number.isRequired, /** * Calculates cell sizes and positions and manages rendering the appropriate cells given a specified window. */ cellLayoutManager: PropTypes.object.isRequired, /** * Optional custom CSS class name to attach to root Collection element. */ className: PropTypes.string, /** * Height of Collection; this property determines the number of visible (vs virtualized) rows. */ height: PropTypes.number.isRequired, /** * Optional custom id to attach to root Collection element. */ id: PropTypes.string, /** * Enables the `Collection` to horiontally "overscan" its content similar to how `Grid` does. * This can reduce flicker around the edges when a user scrolls quickly. */ horizontalOverscanSize: PropTypes.number.isRequired, isScrollingChange: PropTypes.func, /** * Optional renderer to be used in place of rows when either :rowCount or :cellCount is 0. */ noContentRenderer: PropTypes.func.isRequired, /** * Callback invoked whenever the scroll offset changes within the inner scrollable region. * This callback can be used to sync scrolling between lists, tables, or grids. * ({ clientHeight, clientWidth, scrollHeight, scrollLeft, scrollTop, scrollWidth }): void */ onScroll: PropTypes.func.isRequired, /** * Callback invoked with information about the section of the Collection that was just rendered. * This callback is passed a named :indices parameter which is an Array of the most recently rendered section indices. */ onSectionRendered: PropTypes.func.isRequired, /** * Horizontal offset. */ scrollLeft: PropTypes.number, /** * Controls scroll-to-cell behavior of the Grid. * The default ("auto") scrolls the least amount possible to ensure that the specified cell is fully visible. * Use "start" to align cells to the top/left of the Grid and "end" to align bottom/right. */ scrollToAlignment: PropTypes.oneOf(['auto', 'end', 'start', 'center']).isRequired, /** * Cell index to ensure visible (by forcefully scrolling if necessary). */ scrollToCell: PropTypes.number.isRequired, /** * Vertical offset. */ scrollTop: PropTypes.number, /** * Optional custom inline style to attach to root Collection element. */ style: PropTypes.object, /** * Enables the `Collection` to vertically "overscan" its content similar to how `Grid` does. * This can reduce flicker around the edges when a user scrolls quickly. */ verticalOverscanSize: PropTypes.number.isRequired, /** * Width of Collection; this property determines the number of visible (vs virtualized) columns. */ width: PropTypes.number.isRequired } : {}; polyfill(CollectionView); export default CollectionView;dist/es/Collection/Collection.jest.js000064400000071444151676725770013647 0ustar00import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _regeneratorRuntime from "@babel/runtime/regenerator"; import _typeof from "@babel/runtime/helpers/typeof"; import _extends from "@babel/runtime/helpers/extends"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } /** * Tests Collection and CollectionView. * */ import getScrollbarSize from 'dom-helpers/scrollbarSize'; import * as React from 'react'; import { findDOMNode } from 'react-dom'; import { Simulate } from 'react-dom/test-utils'; import { render } from '../TestUtils'; import Collection from './Collection'; import { CELLS, SECTION_SIZE } from './TestData'; describe('Collection', function () { function defaultCellRenderer(_ref) { var index = _ref.index, key = _ref.key, style = _ref.style; return React.createElement("div", { className: "cell", key: key, style: style }, "cell:", index); } function getMarkup() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var _props$cellCount = props.cellCount, cellCount = _props$cellCount === void 0 ? CELLS.length : _props$cellCount; function defaultCellSizeAndPositionGetter(_ref2) { var index = _ref2.index; index %= cellCount; return CELLS[index]; } return React.createElement(Collection, _extends({ cellCount: cellCount, cellRenderer: defaultCellRenderer, cellSizeAndPositionGetter: defaultCellSizeAndPositionGetter, height: SECTION_SIZE, sectionSize: SECTION_SIZE, width: SECTION_SIZE * 2 }, props)); } function simulateScroll(_ref3) { var collection = _ref3.collection, _ref3$scrollLeft = _ref3.scrollLeft, scrollLeft = _ref3$scrollLeft === void 0 ? 0 : _ref3$scrollLeft, _ref3$scrollTop = _ref3.scrollTop, scrollTop = _ref3$scrollTop === void 0 ? 0 : _ref3$scrollTop; var target = { scrollLeft: scrollLeft, scrollTop: scrollTop }; collection._collectionView._scrollingContainer = target; // HACK to work around _onScroll target check Simulate.scroll(findDOMNode(collection), { target: target }); } function compareArrays(array1, array2) { expect(array1.length).toEqual(array2.length); array2.forEach(function (value) { expect(array1).toContain(value); }); } describe('number of rendered children', function () { it('should render enough children to fill the available area', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.querySelectorAll('.cell').length).toEqual(4); }); it('should not render more cells than available if the area is not filled', function () { var rendered = findDOMNode(render(getMarkup({ cellCount: 2 }))); expect(rendered.querySelectorAll('.cell').length).toEqual(2); }); // Small performance tweak added in 5.5.6 it('should not render/parent cells that are null or false', function () { function cellRenderer(_ref4) { var index = _ref4.index, key = _ref4.key, style = _ref4.style; if (index > 2) { return null; } else { return React.createElement("div", { className: "cell", key: key, style: style }, index); } } var rendered = findDOMNode(render(getMarkup({ cellRenderer: cellRenderer }))); expect(rendered.querySelectorAll('.cell').length).toEqual(3); }); }); describe('shows and hides scrollbars based on rendered content', function () { var scrollbarSize; beforeAll(function () { scrollbarSize = getScrollbarSize(); }); it('should set overflowX:hidden if columns fit within the available width and y-axis has no scrollbar', function () { var rendered = findDOMNode(render(getMarkup({ height: 4, width: 6 }))); expect(rendered.style.overflowX).toEqual('hidden'); }); it('should set overflowX:hidden if columns and y-axis scrollbar fit within the available width', function () { var rendered = findDOMNode(render(getMarkup({ height: 1, width: 6 + scrollbarSize }))); expect(rendered.style.overflowX).toEqual('hidden'); }); it('should leave overflowX:auto if columns require more than the available width', function () { var rendered = findDOMNode(render(getMarkup({ width: 1 }))); expect(rendered.style.overflowX).not.toEqual('hidden'); }); it('should leave overflowX:auto if columns and y-axis scrollbar require more than the available width', function () { var rendered = findDOMNode(render(getMarkup({ height: 1, width: 6 + scrollbarSize - 1 }))); expect(rendered.style.overflowX).not.toEqual('hidden'); }); it('should set overflowY:hidden if rows fit within the available width and xaxis has no scrollbar', function () { var rendered = findDOMNode(render(getMarkup({ height: 4, width: 6 }))); expect(rendered.style.overflowY).toEqual('hidden'); }); it('should set overflowY:hidden if rows and x-axis scrollbar fit within the available width', function () { var rendered = findDOMNode(render(getMarkup({ height: 4 + scrollbarSize, width: 1 }))); expect(rendered.style.overflowY).toEqual('hidden'); }); it('should leave overflowY:auto if rows require more than the available height', function () { var rendered = findDOMNode(render(getMarkup({ height: 1 }))); expect(rendered.style.overflowY).not.toEqual('hidden'); }); it('should leave overflowY:auto if rows and y-axis scrollbar require more than the available height', function () { var rendered = findDOMNode(render(getMarkup({ height: 4 + scrollbarSize - 1, width: 1 }))); expect(rendered.style.overflowY).not.toEqual('hidden'); }); it('should accept styles that overwrite calculated ones', function () { var rendered = findDOMNode(render(getMarkup({ height: 1, style: { overflowX: 'auto', overflowY: 'auto' }, width: 1 }))); expect(rendered.style.overflowX).toEqual('auto'); expect(rendered.style.overflowY).toEqual('auto'); }); }); describe('autoHeight', function () { it('should set the container height to auto to adjust to innerScrollContainer height', function () { var props = { autoHeight: true }; var rendered = findDOMNode(render(getMarkup(props))); expect(rendered.style.height).toEqual('auto'); }); it('should have container height still affecting number of rows rendered', function () { var indices; var props = { autoHeight: true, height: 500, onSectionRendered: function onSectionRendered(params) { indices = params.indices; } }; findDOMNode(render(getMarkup(props))); compareArrays(indices, [0, 1, 2, 3, 4, 5]); }); it('should have innerScrollContainer height to be equal number of rows * rowHeight', function () { var props = { autoHeight: true }; var rendered = findDOMNode(render(getMarkup(props))); expect(rendered.querySelector('.ReactVirtualized__Collection__innerScrollContainer').style.height).toEqual('4px'); }); }); describe(':scrollToCell', function () { it('should scroll to the top/left', function () { var collection = render(getMarkup({ scrollToCell: 0 })); expect(collection._collectionView.state.scrollLeft).toEqual(0); expect(collection._collectionView.state.scrollTop).toEqual(0); }); it('should scroll over to the middle', function () { var collection = render(getMarkup({ scrollToCell: 7 })); expect(collection._collectionView.state.scrollLeft).toEqual(1); expect(collection._collectionView.state.scrollTop).toEqual(1); }); it('should scroll to the bottom/right', function () { var collection = render(getMarkup({ scrollToCell: 9 })); expect(collection._collectionView.state.scrollLeft).toEqual(2); expect(collection._collectionView.state.scrollTop).toEqual(2); }); it('should honor the specified :scrollToAlignment', function () { var collection = render(getMarkup({ scrollToAlignment: 'start', scrollToCell: 2, width: SECTION_SIZE })); // Minimum amount of scrolling ("auto") would be 0,0 expect(collection._collectionView.state.scrollLeft).toEqual(2); expect(collection._collectionView.state.scrollTop).toEqual(1); collection = render(getMarkup({ scrollToAlignment: 'end', scrollToCell: 2, width: SECTION_SIZE })); // This cell would already by visible by "auto" rules expect(collection._collectionView.state.scrollLeft).toEqual(1); expect(collection._collectionView.state.scrollTop).toEqual(0); collection = render(getMarkup({ scrollToAlignment: 'center', scrollToCell: 4, width: SECTION_SIZE })); // This cell doesn't fit entirely in the viewport but we center it anyway. expect(collection._collectionView.state.scrollLeft).toEqual(0.5); expect(collection._collectionView.state.scrollTop).toEqual(2); }); it('should scroll to a cell just added', function () { var collection = render(getMarkup({ cellCount: 4 })); expect(collection._collectionView.state.scrollLeft).toEqual(0); expect(collection._collectionView.state.scrollTop).toEqual(0); collection = render(getMarkup({ cellCount: 8, scrollToCell: 7 })); expect(collection._collectionView.state.scrollLeft).toEqual(1); expect(collection._collectionView.state.scrollTop).toEqual(1); }); }); describe('property updates', function () { it('should update :scrollToCell position when :width changes', function () { var collection = findDOMNode(render(getMarkup({ scrollToCell: 3 }))); expect(collection.textContent).toContain('cell:3'); // Making the collection narrower leaves only room for 1 item collection = findDOMNode(render(getMarkup({ scrollToCell: 3, width: 1 }))); expect(collection.textContent).toContain('cell:3'); }); it('should update :scrollToCell position when :height changes', function () { var collection = findDOMNode(render(getMarkup({ scrollToCell: 4 }))); expect(collection.textContent).toContain('cell:4'); // Making the collection shorter leaves only room for 1 item collection = findDOMNode(render(getMarkup({ scrollToCell: 4, height: 1 }))); expect(collection.textContent).toContain('cell:4'); }); it('should update scroll position when :scrollToCell changes', function () { var collection = findDOMNode(render(getMarkup())); expect(collection.textContent).not.toContain('cell:9'); collection = findDOMNode(render(getMarkup({ scrollToCell: 9 }))); expect(collection.textContent).toContain('cell:9'); }); }); describe('noContentRenderer', function () { it('should call :noContentRenderer if :cellCount is 0', function () { var list = findDOMNode(render(getMarkup({ noContentRenderer: function noContentRenderer() { return React.createElement("div", null, "No data"); }, cellCount: 0 }))); expect(list.textContent).toEqual('No data'); }); it('should render an empty body if :cellCount is 0 and there is no :noContentRenderer', function () { var list = findDOMNode(render(getMarkup({ cellCount: 0 }))); expect(list.textContent).toEqual(''); }); it('should not show the :noContentRenderer when there are children, even if no children are currently visible (sparse)', function () { var offscreenSizeAndPosition = { x: SECTION_SIZE * 3, y: SECTION_SIZE * 3, width: 1, height: 1 }; function cellSizeAndPositionGetter() { return offscreenSizeAndPosition; } var list = findDOMNode(render(getMarkup({ cellCount: 1, cellSizeAndPositionGetter: cellSizeAndPositionGetter, noContentRenderer: function noContentRenderer() { return React.createElement("div", null, "No data"); } }))); expect(list.textContent).not.toEqual('No data'); }); }); describe('onSectionRendered', function () { it('should call :onSectionRendered if at least one cell is rendered', function () { var indices; render(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; } })); compareArrays(indices, [0, 1, 2, 3]); }); it('should not call :onSectionRendered unless the rendered indices have changed', function () { var numCalls = 0; var indices; var onSectionRendered = function onSectionRendered(params) { indices = params.indices; numCalls++; }; render(getMarkup({ onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(1); compareArrays(indices, [0, 1, 2, 3]); render(getMarkup({ onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(1); compareArrays(indices, [0, 1, 2, 3]); }); it('should call :onSectionRendered if the rendered indices have changed', function () { var numCalls = 0; var indices; var onSectionRendered = function onSectionRendered(params) { indices = params.indices; numCalls++; }; render(getMarkup({ onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(1); compareArrays(indices, [0, 1, 2, 3]); render(getMarkup({ height: SECTION_SIZE * 2, onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(2); compareArrays(indices, [0, 1, 2, 3, 4, 5]); render(getMarkup({ height: SECTION_SIZE * 2, onSectionRendered: onSectionRendered, width: SECTION_SIZE })); expect(numCalls).toEqual(3); expect(indices).toEqual([0, 4]); }); it('should not call :onSectionRendered if no cells are rendered', function () { var numCalls = 0; render(getMarkup({ height: 0, onSectionRendered: function onSectionRendered() { return numCalls++; } })); expect(numCalls).toEqual(0); }); }); describe(':scrollLeft and :scrollTop properties', function () { it('should render correctly when an initial :scrollLeft and :scrollTop properties are specified', function () { var indices; var collection = render(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; }, scrollLeft: 2, scrollTop: 2 })); compareArrays(indices, [3, 4, 5, 7, 8, 9]); expect(collection._collectionView.state.scrollPositionChangeReason).toEqual('requested'); }); it('should render correctly when :scrollLeft and :scrollTop properties are updated', function () { var indices; render(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; } })); compareArrays(indices, [0, 1, 2, 3]); var collection = render(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; }, scrollLeft: 2, scrollTop: 2 })); compareArrays(indices, [3, 4, 5, 7, 8, 9]); expect(collection._collectionView.state.scrollPositionChangeReason).toEqual('requested'); }); }); describe('styles, classNames, and ids', function () { it('should use the expected global CSS classNames', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.className).toEqual('ReactVirtualized__Collection'); }); it('should use a custom :className if specified', function () { var rendered = findDOMNode(render(getMarkup({ className: 'foo' }))); expect(rendered.className).toContain('foo'); }); it('should use a custom :id if specified', function () { var rendered = findDOMNode(render(getMarkup({ id: 'bar' }))); expect(rendered.getAttribute('id')).toEqual('bar'); }); it('should use a custom :style if specified', function () { var style = { backgroundColor: 'red' }; var rendered = findDOMNode(render(getMarkup({ style: style }))); expect(rendered.style.backgroundColor).toEqual('red'); }); }); describe('onScroll', function () { it('should trigger callback when component is mounted', function () { var onScrollCalls = []; render(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); }, scrollLeft: 2, scrollTop: 1 })); expect(onScrollCalls).toEqual([{ clientHeight: SECTION_SIZE, clientWidth: SECTION_SIZE * 2, scrollHeight: 4, scrollLeft: 2, scrollTop: 1, scrollWidth: 6 }]); }); it('should trigger callback when component scrolls horizontally', function () { var onScrollCalls = []; var collection = render(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); simulateScroll({ collection: collection, scrollLeft: 1, scrollTop: 0 }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: SECTION_SIZE, clientWidth: SECTION_SIZE * 2, scrollHeight: 4, scrollLeft: 1, scrollTop: 0, scrollWidth: 6 }); }); it('should trigger callback when component scrolls vertically', function () { var onScrollCalls = []; var collection = render(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); simulateScroll({ collection: collection, scrollLeft: 0, scrollTop: 2 }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: SECTION_SIZE, clientWidth: SECTION_SIZE * 2, scrollHeight: 4, scrollLeft: 0, scrollTop: 2, scrollWidth: 6 }); }); it('should not allow negative scroll values', function () { var onScrollCalls = []; var collection = render(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); simulateScroll({ collection: collection, scrollLeft: -1, scrollTop: -1 }); expect(onScrollCalls.length).toEqual(1); expect(onScrollCalls[0].scrollLeft).toEqual(0); expect(onScrollCalls[0].scrollTop).toEqual(0); }); }); describe('cellGroupRenderer', function () { it('should use a custom :cellGroupRenderer if specified', function () { var cellGroupRendererCalled = 0; var cellGroupRendererParams; var cellRenderer = function cellRenderer(_ref5) { var index = _ref5.index, key = _ref5.key, style = _ref5.style; return React.createElement("div", { key: key, style: style }, index); }; findDOMNode(render(getMarkup({ cellRenderer: cellRenderer, cellGroupRenderer: function cellGroupRenderer(params) { cellGroupRendererParams = params; cellGroupRendererCalled++; return [React.createElement("div", { key: "0" }, "Fake content")]; } }))); expect(cellGroupRendererCalled).toEqual(1); expect(cellGroupRendererParams.cellRenderer).toEqual(cellRenderer); expect(_typeof(cellGroupRendererParams.cellSizeAndPositionGetter)).toEqual('function'); compareArrays(cellGroupRendererParams.indices, [0, 1, 2, 3]); }); }); it('should pass the cellRenderer an :isScrolling flag when scrolling is in progress', function _callee(done) { var cellRendererCalls, cellRenderer, collection; return _regeneratorRuntime.async(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: cellRenderer = function _ref7(_ref6) { var index = _ref6.index, isScrolling = _ref6.isScrolling, key = _ref6.key, style = _ref6.style; cellRendererCalls.push(isScrolling); return defaultCellRenderer({ index: index, key: key, style: style }); }; cellRendererCalls = []; collection = render(getMarkup({ cellRenderer: cellRenderer })); expect(cellRendererCalls[0]).toEqual(false); cellRendererCalls.splice(0); simulateScroll({ collection: collection, scrollTop: 1 }); // Give React time to process the queued setState() _context.next = 8; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, 1); })); case 8: expect(cellRendererCalls[0]).toEqual(true); done(); case 10: case "end": return _context.stop(); } } }); }); describe('horizontalOverscanSize and verticalOverscanSize', function () { it('should include the horizontal and vertical overscan size when rendering cells', function () { var indices; render(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; }, height: 1, horizontalOverscanSize: 2, sectionSize: 1, scrollLeft: 2, scrollTop: 2, width: 1, verticalOverscanSize: 1 })); compareArrays(indices, [0, 2, 3, 4, 5, 6, 7, 9]); }); it('should not exceed the top/left borders regardless of overscan size', function () { var indices; render(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; }, height: 2, horizontalOverscanSize: 1, sectionSize: 1, scrollLeft: 0, scrollTop: 0, width: 1, verticalOverscanSize: 2 })); compareArrays(indices, [0, 4]); }); it('should not exceed the bottom/right borders regardless of overscan size', function () { var indices; render(getMarkup({ onSectionRendered: function onSectionRendered(params) { indices = params.indices; }, height: 2, horizontalOverscanSize: 1, sectionSize: 1, scrollLeft: 5, scrollTop: 2, width: 1, verticalOverscanSize: 2 })); compareArrays(indices, [6, 7, 8, 9]); }); }); describe('cell caching', function () { it('should not cache cells if the Grid is not scrolling', function () { var cellRendererCalls = []; function cellRenderer(_ref8) { var isScrolling = _ref8.isScrolling, index = _ref8.index, key = _ref8.key, style = _ref8.style; cellRendererCalls.push({ isScrolling: isScrolling, index: index }); return defaultCellRenderer({ index: index, key: key, style: style }); } var props = { cellRenderer: cellRenderer, scrollLeft: 0, scrollTop: 0 }; findDOMNode(render(getMarkup(props))); expect(cellRendererCalls.length).toEqual(4); cellRendererCalls.forEach(function (call) { return expect(call.isScrolling).toEqual(false); }); cellRendererCalls.splice(0); render(getMarkup(_objectSpread({}, props, { foo: 'bar' // Force re-render }))); expect(cellRendererCalls.length).toEqual(4); cellRendererCalls.forEach(function (call) { return expect(call.isScrolling).toEqual(false); }); }); it.skip('should cache a cell once it has been rendered while scrolling', function () { var cellRendererCalls = []; function cellRenderer(_ref9) { var isScrolling = _ref9.isScrolling, index = _ref9.index, key = _ref9.key, style = _ref9.style; cellRendererCalls.push({ isScrolling: isScrolling, index: index }); return defaultCellRenderer({ index: index, key: key, style: style }); } var props = { cellRenderer: cellRenderer, scrollLeft: 0, scrollTop: 0 }; var collection = render(getMarkup(props)); expect(cellRendererCalls.length).toEqual(4); cellRendererCalls.forEach(function (call) { return expect(call.isScrolling).toEqual(false); }); // FIXME: simulate scroll is not triggering cells to render in cache // Scroll a little bit; newly-rendered cells will be cached. simulateScroll({ collection: collection, scrollTop: 2 }); cellRendererCalls.splice(0); // At this point cells 4 and 5 have been rendered, // But cells 7, 8, and 9 have not. render(getMarkup(_objectSpread({}, props, { scrollLeft: 1, scrollTop: 3 }))); expect(cellRendererCalls.length).toEqual(3); cellRendererCalls.forEach(function (call) { return expect(call.isScrolling).toEqual(true); }); }); it('should clear cache once :isScrolling is false', function _callee2(done) { var cellRendererCalls, cellRenderer, props, collection; return _regeneratorRuntime.async(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: cellRenderer = function _ref11(_ref10) { var isScrolling = _ref10.isScrolling, index = _ref10.index, key = _ref10.key, style = _ref10.style; cellRendererCalls.push({ isScrolling: isScrolling, index: index }); return defaultCellRenderer({ isScrolling: isScrolling, index: index, key: key, style: style }); }; cellRendererCalls = []; props = { cellRenderer: cellRenderer, scrollLeft: 0, scrollTop: 0 }; collection = render(getMarkup(props)); simulateScroll({ collection: collection, scrollTop: 1 }); // Allow scrolling timeout to complete so that cell cache is reset _context2.next = 7; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, 500); })); case 7: cellRendererCalls.splice(0); render(getMarkup(_objectSpread({}, props, { scrollTop: 1 }))); expect(cellRendererCalls.length).not.toEqual(0); done(); case 11: case "end": return _context2.stop(); } } }); }); }); // See issue #568 for more it('forceUpdate will also forceUpdate the inner CollectionView', function () { var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (_ref12) { var key = _ref12.key; return React.createElement("div", { key: key }); }); var rendered = render(getMarkup({ cellRenderer: cellRenderer })); expect(cellRenderer).toHaveBeenCalled(); cellRenderer.mockReset(); rendered.forceUpdate(); expect(cellRenderer).toHaveBeenCalled(); }); });dist/es/MultiGrid/MultiGrid.js000064400000075071151676725770012315 0ustar00import _extends from "@babel/runtime/helpers/extends"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import PropTypes from 'prop-types'; import * as React from 'react'; import { polyfill } from 'react-lifecycles-compat'; import CellMeasurerCacheDecorator from './CellMeasurerCacheDecorator'; import Grid from '../Grid'; var SCROLLBAR_SIZE_BUFFER = 20; /** * Renders 1, 2, or 4 Grids depending on configuration. * A main (body) Grid will always be rendered. * Optionally, 1-2 Grids for sticky header rows will also be rendered. * If no sticky columns, only 1 sticky header Grid will be rendered. * If sticky columns, 2 sticky header Grids will be rendered. */ var MultiGrid = /*#__PURE__*/ function (_React$PureComponent) { _inherits(MultiGrid, _React$PureComponent); function MultiGrid(props, context) { var _this; _classCallCheck(this, MultiGrid); _this = _possibleConstructorReturn(this, _getPrototypeOf(MultiGrid).call(this, props, context)); _defineProperty(_assertThisInitialized(_this), "state", { scrollLeft: 0, scrollTop: 0, scrollbarSize: 0, showHorizontalScrollbar: false, showVerticalScrollbar: false }); _defineProperty(_assertThisInitialized(_this), "_deferredInvalidateColumnIndex", null); _defineProperty(_assertThisInitialized(_this), "_deferredInvalidateRowIndex", null); _defineProperty(_assertThisInitialized(_this), "_bottomLeftGridRef", function (ref) { _this._bottomLeftGrid = ref; }); _defineProperty(_assertThisInitialized(_this), "_bottomRightGridRef", function (ref) { _this._bottomRightGrid = ref; }); _defineProperty(_assertThisInitialized(_this), "_cellRendererBottomLeftGrid", function (_ref) { var rowIndex = _ref.rowIndex, rest = _objectWithoutProperties(_ref, ["rowIndex"]); var _this$props = _this.props, cellRenderer = _this$props.cellRenderer, fixedRowCount = _this$props.fixedRowCount, rowCount = _this$props.rowCount; if (rowIndex === rowCount - fixedRowCount) { return React.createElement("div", { key: rest.key, style: _objectSpread({}, rest.style, { height: SCROLLBAR_SIZE_BUFFER }) }); } else { return cellRenderer(_objectSpread({}, rest, { parent: _assertThisInitialized(_this), rowIndex: rowIndex + fixedRowCount })); } }); _defineProperty(_assertThisInitialized(_this), "_cellRendererBottomRightGrid", function (_ref2) { var columnIndex = _ref2.columnIndex, rowIndex = _ref2.rowIndex, rest = _objectWithoutProperties(_ref2, ["columnIndex", "rowIndex"]); var _this$props2 = _this.props, cellRenderer = _this$props2.cellRenderer, fixedColumnCount = _this$props2.fixedColumnCount, fixedRowCount = _this$props2.fixedRowCount; return cellRenderer(_objectSpread({}, rest, { columnIndex: columnIndex + fixedColumnCount, parent: _assertThisInitialized(_this), rowIndex: rowIndex + fixedRowCount })); }); _defineProperty(_assertThisInitialized(_this), "_cellRendererTopRightGrid", function (_ref3) { var columnIndex = _ref3.columnIndex, rest = _objectWithoutProperties(_ref3, ["columnIndex"]); var _this$props3 = _this.props, cellRenderer = _this$props3.cellRenderer, columnCount = _this$props3.columnCount, fixedColumnCount = _this$props3.fixedColumnCount; if (columnIndex === columnCount - fixedColumnCount) { return React.createElement("div", { key: rest.key, style: _objectSpread({}, rest.style, { width: SCROLLBAR_SIZE_BUFFER }) }); } else { return cellRenderer(_objectSpread({}, rest, { columnIndex: columnIndex + fixedColumnCount, parent: _assertThisInitialized(_this) })); } }); _defineProperty(_assertThisInitialized(_this), "_columnWidthRightGrid", function (_ref4) { var index = _ref4.index; var _this$props4 = _this.props, columnCount = _this$props4.columnCount, fixedColumnCount = _this$props4.fixedColumnCount, columnWidth = _this$props4.columnWidth; var _this$state = _this.state, scrollbarSize = _this$state.scrollbarSize, showHorizontalScrollbar = _this$state.showHorizontalScrollbar; // An extra cell is added to the count // This gives the smaller Grid extra room for offset, // In case the main (bottom right) Grid has a scrollbar // If no scrollbar, the extra space is overflow:hidden anyway if (showHorizontalScrollbar && index === columnCount - fixedColumnCount) { return scrollbarSize; } return typeof columnWidth === 'function' ? columnWidth({ index: index + fixedColumnCount }) : columnWidth; }); _defineProperty(_assertThisInitialized(_this), "_onScroll", function (scrollInfo) { var scrollLeft = scrollInfo.scrollLeft, scrollTop = scrollInfo.scrollTop; _this.setState({ scrollLeft: scrollLeft, scrollTop: scrollTop }); var onScroll = _this.props.onScroll; if (onScroll) { onScroll(scrollInfo); } }); _defineProperty(_assertThisInitialized(_this), "_onScrollbarPresenceChange", function (_ref5) { var horizontal = _ref5.horizontal, size = _ref5.size, vertical = _ref5.vertical; var _this$state2 = _this.state, showHorizontalScrollbar = _this$state2.showHorizontalScrollbar, showVerticalScrollbar = _this$state2.showVerticalScrollbar; if (horizontal !== showHorizontalScrollbar || vertical !== showVerticalScrollbar) { _this.setState({ scrollbarSize: size, showHorizontalScrollbar: horizontal, showVerticalScrollbar: vertical }); var onScrollbarPresenceChange = _this.props.onScrollbarPresenceChange; if (typeof onScrollbarPresenceChange === 'function') { onScrollbarPresenceChange({ horizontal: horizontal, size: size, vertical: vertical }); } } }); _defineProperty(_assertThisInitialized(_this), "_onScrollLeft", function (scrollInfo) { var scrollLeft = scrollInfo.scrollLeft; _this._onScroll({ scrollLeft: scrollLeft, scrollTop: _this.state.scrollTop }); }); _defineProperty(_assertThisInitialized(_this), "_onScrollTop", function (scrollInfo) { var scrollTop = scrollInfo.scrollTop; _this._onScroll({ scrollTop: scrollTop, scrollLeft: _this.state.scrollLeft }); }); _defineProperty(_assertThisInitialized(_this), "_rowHeightBottomGrid", function (_ref6) { var index = _ref6.index; var _this$props5 = _this.props, fixedRowCount = _this$props5.fixedRowCount, rowCount = _this$props5.rowCount, rowHeight = _this$props5.rowHeight; var _this$state3 = _this.state, scrollbarSize = _this$state3.scrollbarSize, showVerticalScrollbar = _this$state3.showVerticalScrollbar; // An extra cell is added to the count // This gives the smaller Grid extra room for offset, // In case the main (bottom right) Grid has a scrollbar // If no scrollbar, the extra space is overflow:hidden anyway if (showVerticalScrollbar && index === rowCount - fixedRowCount) { return scrollbarSize; } return typeof rowHeight === 'function' ? rowHeight({ index: index + fixedRowCount }) : rowHeight; }); _defineProperty(_assertThisInitialized(_this), "_topLeftGridRef", function (ref) { _this._topLeftGrid = ref; }); _defineProperty(_assertThisInitialized(_this), "_topRightGridRef", function (ref) { _this._topRightGrid = ref; }); var deferredMeasurementCache = props.deferredMeasurementCache, _fixedColumnCount = props.fixedColumnCount, _fixedRowCount = props.fixedRowCount; _this._maybeCalculateCachedStyles(true); if (deferredMeasurementCache) { _this._deferredMeasurementCacheBottomLeftGrid = _fixedRowCount > 0 ? new CellMeasurerCacheDecorator({ cellMeasurerCache: deferredMeasurementCache, columnIndexOffset: 0, rowIndexOffset: _fixedRowCount }) : deferredMeasurementCache; _this._deferredMeasurementCacheBottomRightGrid = _fixedColumnCount > 0 || _fixedRowCount > 0 ? new CellMeasurerCacheDecorator({ cellMeasurerCache: deferredMeasurementCache, columnIndexOffset: _fixedColumnCount, rowIndexOffset: _fixedRowCount }) : deferredMeasurementCache; _this._deferredMeasurementCacheTopRightGrid = _fixedColumnCount > 0 ? new CellMeasurerCacheDecorator({ cellMeasurerCache: deferredMeasurementCache, columnIndexOffset: _fixedColumnCount, rowIndexOffset: 0 }) : deferredMeasurementCache; } return _this; } _createClass(MultiGrid, [{ key: "forceUpdateGrids", value: function forceUpdateGrids() { this._bottomLeftGrid && this._bottomLeftGrid.forceUpdate(); this._bottomRightGrid && this._bottomRightGrid.forceUpdate(); this._topLeftGrid && this._topLeftGrid.forceUpdate(); this._topRightGrid && this._topRightGrid.forceUpdate(); } /** See Grid#invalidateCellSizeAfterRender */ }, { key: "invalidateCellSizeAfterRender", value: function invalidateCellSizeAfterRender() { var _ref7 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref7$columnIndex = _ref7.columnIndex, columnIndex = _ref7$columnIndex === void 0 ? 0 : _ref7$columnIndex, _ref7$rowIndex = _ref7.rowIndex, rowIndex = _ref7$rowIndex === void 0 ? 0 : _ref7$rowIndex; this._deferredInvalidateColumnIndex = typeof this._deferredInvalidateColumnIndex === 'number' ? Math.min(this._deferredInvalidateColumnIndex, columnIndex) : columnIndex; this._deferredInvalidateRowIndex = typeof this._deferredInvalidateRowIndex === 'number' ? Math.min(this._deferredInvalidateRowIndex, rowIndex) : rowIndex; } /** See Grid#measureAllCells */ }, { key: "measureAllCells", value: function measureAllCells() { this._bottomLeftGrid && this._bottomLeftGrid.measureAllCells(); this._bottomRightGrid && this._bottomRightGrid.measureAllCells(); this._topLeftGrid && this._topLeftGrid.measureAllCells(); this._topRightGrid && this._topRightGrid.measureAllCells(); } /** See Grid#recomputeGridSize */ }, { key: "recomputeGridSize", value: function recomputeGridSize() { var _ref8 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref8$columnIndex = _ref8.columnIndex, columnIndex = _ref8$columnIndex === void 0 ? 0 : _ref8$columnIndex, _ref8$rowIndex = _ref8.rowIndex, rowIndex = _ref8$rowIndex === void 0 ? 0 : _ref8$rowIndex; var _this$props6 = this.props, fixedColumnCount = _this$props6.fixedColumnCount, fixedRowCount = _this$props6.fixedRowCount; var adjustedColumnIndex = Math.max(0, columnIndex - fixedColumnCount); var adjustedRowIndex = Math.max(0, rowIndex - fixedRowCount); this._bottomLeftGrid && this._bottomLeftGrid.recomputeGridSize({ columnIndex: columnIndex, rowIndex: adjustedRowIndex }); this._bottomRightGrid && this._bottomRightGrid.recomputeGridSize({ columnIndex: adjustedColumnIndex, rowIndex: adjustedRowIndex }); this._topLeftGrid && this._topLeftGrid.recomputeGridSize({ columnIndex: columnIndex, rowIndex: rowIndex }); this._topRightGrid && this._topRightGrid.recomputeGridSize({ columnIndex: adjustedColumnIndex, rowIndex: rowIndex }); this._leftGridWidth = null; this._topGridHeight = null; this._maybeCalculateCachedStyles(true); } }, { key: "componentDidMount", value: function componentDidMount() { var _this$props7 = this.props, scrollLeft = _this$props7.scrollLeft, scrollTop = _this$props7.scrollTop; if (scrollLeft > 0 || scrollTop > 0) { var newState = {}; if (scrollLeft > 0) { newState.scrollLeft = scrollLeft; } if (scrollTop > 0) { newState.scrollTop = scrollTop; } this.setState(newState); } this._handleInvalidatedGridSize(); } }, { key: "componentDidUpdate", value: function componentDidUpdate() { this._handleInvalidatedGridSize(); } }, { key: "render", value: function render() { var _this$props8 = this.props, onScroll = _this$props8.onScroll, onSectionRendered = _this$props8.onSectionRendered, onScrollbarPresenceChange = _this$props8.onScrollbarPresenceChange, scrollLeftProp = _this$props8.scrollLeft, scrollToColumn = _this$props8.scrollToColumn, scrollTopProp = _this$props8.scrollTop, scrollToRow = _this$props8.scrollToRow, rest = _objectWithoutProperties(_this$props8, ["onScroll", "onSectionRendered", "onScrollbarPresenceChange", "scrollLeft", "scrollToColumn", "scrollTop", "scrollToRow"]); this._prepareForRender(); // Don't render any of our Grids if there are no cells. // This mirrors what Grid does, // And prevents us from recording inaccurage measurements when used with CellMeasurer. if (this.props.width === 0 || this.props.height === 0) { return null; } // scrollTop and scrollLeft props are explicitly filtered out and ignored var _this$state4 = this.state, scrollLeft = _this$state4.scrollLeft, scrollTop = _this$state4.scrollTop; return React.createElement("div", { style: this._containerOuterStyle }, React.createElement("div", { style: this._containerTopStyle }, this._renderTopLeftGrid(rest), this._renderTopRightGrid(_objectSpread({}, rest, { onScroll: onScroll, scrollLeft: scrollLeft }))), React.createElement("div", { style: this._containerBottomStyle }, this._renderBottomLeftGrid(_objectSpread({}, rest, { onScroll: onScroll, scrollTop: scrollTop })), this._renderBottomRightGrid(_objectSpread({}, rest, { onScroll: onScroll, onSectionRendered: onSectionRendered, scrollLeft: scrollLeft, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow, scrollTop: scrollTop })))); } }, { key: "_getBottomGridHeight", value: function _getBottomGridHeight(props) { var height = props.height; var topGridHeight = this._getTopGridHeight(props); return height - topGridHeight; } }, { key: "_getLeftGridWidth", value: function _getLeftGridWidth(props) { var fixedColumnCount = props.fixedColumnCount, columnWidth = props.columnWidth; if (this._leftGridWidth == null) { if (typeof columnWidth === 'function') { var leftGridWidth = 0; for (var index = 0; index < fixedColumnCount; index++) { leftGridWidth += columnWidth({ index: index }); } this._leftGridWidth = leftGridWidth; } else { this._leftGridWidth = columnWidth * fixedColumnCount; } } return this._leftGridWidth; } }, { key: "_getRightGridWidth", value: function _getRightGridWidth(props) { var width = props.width; var leftGridWidth = this._getLeftGridWidth(props); return width - leftGridWidth; } }, { key: "_getTopGridHeight", value: function _getTopGridHeight(props) { var fixedRowCount = props.fixedRowCount, rowHeight = props.rowHeight; if (this._topGridHeight == null) { if (typeof rowHeight === 'function') { var topGridHeight = 0; for (var index = 0; index < fixedRowCount; index++) { topGridHeight += rowHeight({ index: index }); } this._topGridHeight = topGridHeight; } else { this._topGridHeight = rowHeight * fixedRowCount; } } return this._topGridHeight; } }, { key: "_handleInvalidatedGridSize", value: function _handleInvalidatedGridSize() { if (typeof this._deferredInvalidateColumnIndex === 'number') { var columnIndex = this._deferredInvalidateColumnIndex; var rowIndex = this._deferredInvalidateRowIndex; this._deferredInvalidateColumnIndex = null; this._deferredInvalidateRowIndex = null; this.recomputeGridSize({ columnIndex: columnIndex, rowIndex: rowIndex }); this.forceUpdate(); } } /** * Avoid recreating inline styles each render; this bypasses Grid's shallowCompare. * This method recalculates styles only when specific props change. */ }, { key: "_maybeCalculateCachedStyles", value: function _maybeCalculateCachedStyles(resetAll) { var _this$props9 = this.props, columnWidth = _this$props9.columnWidth, enableFixedColumnScroll = _this$props9.enableFixedColumnScroll, enableFixedRowScroll = _this$props9.enableFixedRowScroll, height = _this$props9.height, fixedColumnCount = _this$props9.fixedColumnCount, fixedRowCount = _this$props9.fixedRowCount, rowHeight = _this$props9.rowHeight, style = _this$props9.style, styleBottomLeftGrid = _this$props9.styleBottomLeftGrid, styleBottomRightGrid = _this$props9.styleBottomRightGrid, styleTopLeftGrid = _this$props9.styleTopLeftGrid, styleTopRightGrid = _this$props9.styleTopRightGrid, width = _this$props9.width; var sizeChange = resetAll || height !== this._lastRenderedHeight || width !== this._lastRenderedWidth; var leftSizeChange = resetAll || columnWidth !== this._lastRenderedColumnWidth || fixedColumnCount !== this._lastRenderedFixedColumnCount; var topSizeChange = resetAll || fixedRowCount !== this._lastRenderedFixedRowCount || rowHeight !== this._lastRenderedRowHeight; if (resetAll || sizeChange || style !== this._lastRenderedStyle) { this._containerOuterStyle = _objectSpread({ height: height, overflow: 'visible', // Let :focus outline show through width: width }, style); } if (resetAll || sizeChange || topSizeChange) { this._containerTopStyle = { height: this._getTopGridHeight(this.props), position: 'relative', width: width }; this._containerBottomStyle = { height: height - this._getTopGridHeight(this.props), overflow: 'visible', // Let :focus outline show through position: 'relative', width: width }; } if (resetAll || styleBottomLeftGrid !== this._lastRenderedStyleBottomLeftGrid) { this._bottomLeftGridStyle = _objectSpread({ left: 0, overflowX: 'hidden', overflowY: enableFixedColumnScroll ? 'auto' : 'hidden', position: 'absolute' }, styleBottomLeftGrid); } if (resetAll || leftSizeChange || styleBottomRightGrid !== this._lastRenderedStyleBottomRightGrid) { this._bottomRightGridStyle = _objectSpread({ left: this._getLeftGridWidth(this.props), position: 'absolute' }, styleBottomRightGrid); } if (resetAll || styleTopLeftGrid !== this._lastRenderedStyleTopLeftGrid) { this._topLeftGridStyle = _objectSpread({ left: 0, overflowX: 'hidden', overflowY: 'hidden', position: 'absolute', top: 0 }, styleTopLeftGrid); } if (resetAll || leftSizeChange || styleTopRightGrid !== this._lastRenderedStyleTopRightGrid) { this._topRightGridStyle = _objectSpread({ left: this._getLeftGridWidth(this.props), overflowX: enableFixedRowScroll ? 'auto' : 'hidden', overflowY: 'hidden', position: 'absolute', top: 0 }, styleTopRightGrid); } this._lastRenderedColumnWidth = columnWidth; this._lastRenderedFixedColumnCount = fixedColumnCount; this._lastRenderedFixedRowCount = fixedRowCount; this._lastRenderedHeight = height; this._lastRenderedRowHeight = rowHeight; this._lastRenderedStyle = style; this._lastRenderedStyleBottomLeftGrid = styleBottomLeftGrid; this._lastRenderedStyleBottomRightGrid = styleBottomRightGrid; this._lastRenderedStyleTopLeftGrid = styleTopLeftGrid; this._lastRenderedStyleTopRightGrid = styleTopRightGrid; this._lastRenderedWidth = width; } }, { key: "_prepareForRender", value: function _prepareForRender() { if (this._lastRenderedColumnWidth !== this.props.columnWidth || this._lastRenderedFixedColumnCount !== this.props.fixedColumnCount) { this._leftGridWidth = null; } if (this._lastRenderedFixedRowCount !== this.props.fixedRowCount || this._lastRenderedRowHeight !== this.props.rowHeight) { this._topGridHeight = null; } this._maybeCalculateCachedStyles(); this._lastRenderedColumnWidth = this.props.columnWidth; this._lastRenderedFixedColumnCount = this.props.fixedColumnCount; this._lastRenderedFixedRowCount = this.props.fixedRowCount; this._lastRenderedRowHeight = this.props.rowHeight; } }, { key: "_renderBottomLeftGrid", value: function _renderBottomLeftGrid(props) { var enableFixedColumnScroll = props.enableFixedColumnScroll, fixedColumnCount = props.fixedColumnCount, fixedRowCount = props.fixedRowCount, rowCount = props.rowCount, hideBottomLeftGridScrollbar = props.hideBottomLeftGridScrollbar; var showVerticalScrollbar = this.state.showVerticalScrollbar; if (!fixedColumnCount) { return null; } var additionalRowCount = showVerticalScrollbar ? 1 : 0, height = this._getBottomGridHeight(props), width = this._getLeftGridWidth(props), scrollbarSize = this.state.showVerticalScrollbar ? this.state.scrollbarSize : 0, gridWidth = hideBottomLeftGridScrollbar ? width + scrollbarSize : width; var bottomLeftGrid = React.createElement(Grid, _extends({}, props, { cellRenderer: this._cellRendererBottomLeftGrid, className: this.props.classNameBottomLeftGrid, columnCount: fixedColumnCount, deferredMeasurementCache: this._deferredMeasurementCacheBottomLeftGrid, height: height, onScroll: enableFixedColumnScroll ? this._onScrollTop : undefined, ref: this._bottomLeftGridRef, rowCount: Math.max(0, rowCount - fixedRowCount) + additionalRowCount, rowHeight: this._rowHeightBottomGrid, style: this._bottomLeftGridStyle, tabIndex: null, width: gridWidth })); if (hideBottomLeftGridScrollbar) { return React.createElement("div", { className: "BottomLeftGrid_ScrollWrapper", style: _objectSpread({}, this._bottomLeftGridStyle, { height: height, width: width, overflowY: 'hidden' }) }, bottomLeftGrid); } return bottomLeftGrid; } }, { key: "_renderBottomRightGrid", value: function _renderBottomRightGrid(props) { var columnCount = props.columnCount, fixedColumnCount = props.fixedColumnCount, fixedRowCount = props.fixedRowCount, rowCount = props.rowCount, scrollToColumn = props.scrollToColumn, scrollToRow = props.scrollToRow; return React.createElement(Grid, _extends({}, props, { cellRenderer: this._cellRendererBottomRightGrid, className: this.props.classNameBottomRightGrid, columnCount: Math.max(0, columnCount - fixedColumnCount), columnWidth: this._columnWidthRightGrid, deferredMeasurementCache: this._deferredMeasurementCacheBottomRightGrid, height: this._getBottomGridHeight(props), onScroll: this._onScroll, onScrollbarPresenceChange: this._onScrollbarPresenceChange, ref: this._bottomRightGridRef, rowCount: Math.max(0, rowCount - fixedRowCount), rowHeight: this._rowHeightBottomGrid, scrollToColumn: scrollToColumn - fixedColumnCount, scrollToRow: scrollToRow - fixedRowCount, style: this._bottomRightGridStyle, width: this._getRightGridWidth(props) })); } }, { key: "_renderTopLeftGrid", value: function _renderTopLeftGrid(props) { var fixedColumnCount = props.fixedColumnCount, fixedRowCount = props.fixedRowCount; if (!fixedColumnCount || !fixedRowCount) { return null; } return React.createElement(Grid, _extends({}, props, { className: this.props.classNameTopLeftGrid, columnCount: fixedColumnCount, height: this._getTopGridHeight(props), ref: this._topLeftGridRef, rowCount: fixedRowCount, style: this._topLeftGridStyle, tabIndex: null, width: this._getLeftGridWidth(props) })); } }, { key: "_renderTopRightGrid", value: function _renderTopRightGrid(props) { var columnCount = props.columnCount, enableFixedRowScroll = props.enableFixedRowScroll, fixedColumnCount = props.fixedColumnCount, fixedRowCount = props.fixedRowCount, scrollLeft = props.scrollLeft, hideTopRightGridScrollbar = props.hideTopRightGridScrollbar; var _this$state5 = this.state, showHorizontalScrollbar = _this$state5.showHorizontalScrollbar, scrollbarSize = _this$state5.scrollbarSize; if (!fixedRowCount) { return null; } var additionalColumnCount = showHorizontalScrollbar ? 1 : 0, height = this._getTopGridHeight(props), width = this._getRightGridWidth(props), additionalHeight = showHorizontalScrollbar ? scrollbarSize : 0; var gridHeight = height, style = this._topRightGridStyle; if (hideTopRightGridScrollbar) { gridHeight = height + additionalHeight; style = _objectSpread({}, this._topRightGridStyle, { left: 0 }); } var topRightGrid = React.createElement(Grid, _extends({}, props, { cellRenderer: this._cellRendererTopRightGrid, className: this.props.classNameTopRightGrid, columnCount: Math.max(0, columnCount - fixedColumnCount) + additionalColumnCount, columnWidth: this._columnWidthRightGrid, deferredMeasurementCache: this._deferredMeasurementCacheTopRightGrid, height: gridHeight, onScroll: enableFixedRowScroll ? this._onScrollLeft : undefined, ref: this._topRightGridRef, rowCount: fixedRowCount, scrollLeft: scrollLeft, style: style, tabIndex: null, width: width })); if (hideTopRightGridScrollbar) { return React.createElement("div", { className: "TopRightGrid_ScrollWrapper", style: _objectSpread({}, this._topRightGridStyle, { height: height, width: width, overflowX: 'hidden' }) }, topRightGrid); } return topRightGrid; } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps, prevState) { if (nextProps.scrollLeft !== prevState.scrollLeft || nextProps.scrollTop !== prevState.scrollTop) { return { scrollLeft: nextProps.scrollLeft != null && nextProps.scrollLeft >= 0 ? nextProps.scrollLeft : prevState.scrollLeft, scrollTop: nextProps.scrollTop != null && nextProps.scrollTop >= 0 ? nextProps.scrollTop : prevState.scrollTop }; } return null; } }]); return MultiGrid; }(React.PureComponent); _defineProperty(MultiGrid, "defaultProps", { classNameBottomLeftGrid: '', classNameBottomRightGrid: '', classNameTopLeftGrid: '', classNameTopRightGrid: '', enableFixedColumnScroll: false, enableFixedRowScroll: false, fixedColumnCount: 0, fixedRowCount: 0, scrollToColumn: -1, scrollToRow: -1, style: {}, styleBottomLeftGrid: {}, styleBottomRightGrid: {}, styleTopLeftGrid: {}, styleTopRightGrid: {}, hideTopRightGridScrollbar: false, hideBottomLeftGridScrollbar: false }); MultiGrid.propTypes = process.env.NODE_ENV !== "production" ? { classNameBottomLeftGrid: PropTypes.string.isRequired, classNameBottomRightGrid: PropTypes.string.isRequired, classNameTopLeftGrid: PropTypes.string.isRequired, classNameTopRightGrid: PropTypes.string.isRequired, enableFixedColumnScroll: PropTypes.bool.isRequired, enableFixedRowScroll: PropTypes.bool.isRequired, fixedColumnCount: PropTypes.number.isRequired, fixedRowCount: PropTypes.number.isRequired, onScrollbarPresenceChange: PropTypes.func, style: PropTypes.object.isRequired, styleBottomLeftGrid: PropTypes.object.isRequired, styleBottomRightGrid: PropTypes.object.isRequired, styleTopLeftGrid: PropTypes.object.isRequired, styleTopRightGrid: PropTypes.object.isRequired, hideTopRightGridScrollbar: PropTypes.bool, hideBottomLeftGridScrollbar: PropTypes.bool } : {}; polyfill(MultiGrid); export default MultiGrid;dist/es/MultiGrid/CellMeasurerCacheDecorator.js000064400000007072151676725770015563 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import { CellMeasurerCache } from '../CellMeasurer'; /** * Caches measurements for a given cell. */ var CellMeasurerCacheDecorator = /*#__PURE__*/ function () { function CellMeasurerCacheDecorator() { var _this = this; var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, CellMeasurerCacheDecorator); _defineProperty(this, "_cellMeasurerCache", void 0); _defineProperty(this, "_columnIndexOffset", void 0); _defineProperty(this, "_rowIndexOffset", void 0); _defineProperty(this, "columnWidth", function (_ref) { var index = _ref.index; _this._cellMeasurerCache.columnWidth({ index: index + _this._columnIndexOffset }); }); _defineProperty(this, "rowHeight", function (_ref2) { var index = _ref2.index; _this._cellMeasurerCache.rowHeight({ index: index + _this._rowIndexOffset }); }); var cellMeasurerCache = params.cellMeasurerCache, _params$columnIndexOf = params.columnIndexOffset, columnIndexOffset = _params$columnIndexOf === void 0 ? 0 : _params$columnIndexOf, _params$rowIndexOffse = params.rowIndexOffset, rowIndexOffset = _params$rowIndexOffse === void 0 ? 0 : _params$rowIndexOffse; this._cellMeasurerCache = cellMeasurerCache; this._columnIndexOffset = columnIndexOffset; this._rowIndexOffset = rowIndexOffset; } _createClass(CellMeasurerCacheDecorator, [{ key: "clear", value: function clear(rowIndex, columnIndex) { this._cellMeasurerCache.clear(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset); } }, { key: "clearAll", value: function clearAll() { this._cellMeasurerCache.clearAll(); } }, { key: "hasFixedHeight", value: function hasFixedHeight() { return this._cellMeasurerCache.hasFixedHeight(); } }, { key: "hasFixedWidth", value: function hasFixedWidth() { return this._cellMeasurerCache.hasFixedWidth(); } }, { key: "getHeight", value: function getHeight(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return this._cellMeasurerCache.getHeight(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset); } }, { key: "getWidth", value: function getWidth(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return this._cellMeasurerCache.getWidth(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset); } }, { key: "has", value: function has(rowIndex) { var columnIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; return this._cellMeasurerCache.has(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset); } }, { key: "set", value: function set(rowIndex, columnIndex, width, height) { this._cellMeasurerCache.set(rowIndex + this._rowIndexOffset, columnIndex + this._columnIndexOffset, width, height); } }, { key: "defaultHeight", get: function get() { return this._cellMeasurerCache.defaultHeight; } }, { key: "defaultWidth", get: function get() { return this._cellMeasurerCache.defaultWidth; } }]); return CellMeasurerCacheDecorator; }(); export { CellMeasurerCacheDecorator as default };dist/es/MultiGrid/index.js000064400000000124151676725770011507 0ustar00import MultiGrid from './MultiGrid'; export default MultiGrid; export { MultiGrid };dist/es/MultiGrid/MultiGrid.jest.js000064400000057403151676725770013260 0ustar00import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _extends from "@babel/runtime/helpers/extends"; import * as React from 'react'; import { findDOMNode } from 'react-dom'; import { render } from '../TestUtils'; import MultiGrid from './MultiGrid'; import { CellMeasurerCache } from '../CellMeasurer'; // These tests only focus on what MultiGrid does specifically. // The inner Grid component is tested in depth elsewhere. describe('MultiGrid', function () { function defaultCellRenderer(_ref) { var columnIndex = _ref.columnIndex, key = _ref.key, rowIndex = _ref.rowIndex, style = _ref.style; return React.createElement("div", { className: "gridItem", key: key, style: style }, "row:".concat(rowIndex, ", column:").concat(columnIndex)); } function getMarkup() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return React.createElement(MultiGrid, _extends({ cellRenderer: defaultCellRenderer, columnCount: 50, columnWidth: 50, fixedColumnCount: 2, fixedRowCount: 1, height: 300, overscanColumnCount: 0, overscanRowCount: 0, autoHeight: false, rowHeight: 20, rowCount: 100, width: 400 }, props)); } describe('fixed columns and rows', function () { it('should render 4 Grids when configured for fixed columns and rows', function () { var rendered = findDOMNode(render(getMarkup({ fixedColumnCount: 1, fixedRowCount: 1 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(4); var _grids = _slicedToArray(grids, 4), topLeft = _grids[0], topRight = _grids[1], bottomLeft = _grids[2], bottomRight = _grids[3]; expect(topLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(topLeft.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(topRight.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(topRight.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(bottomLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(bottomLeft.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto'); }); it('should render 2 Grids when configured for fixed columns only', function () { var rendered = findDOMNode(render(getMarkup({ fixedColumnCount: 1, fixedRowCount: 0 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(2); var _grids2 = _slicedToArray(grids, 2), bottomLeft = _grids2[0], bottomRight = _grids2[1]; expect(bottomLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(bottomLeft.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto'); }); it('should render 2 Grids when configured for fixed rows only', function () { var rendered = findDOMNode(render(getMarkup({ fixedColumnCount: 0, fixedRowCount: 1 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(2); var _grids3 = _slicedToArray(grids, 2), topRight = _grids3[0], bottomRight = _grids3[1]; expect(topRight.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(topRight.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto'); }); it('should render 1 Grid when configured for neither fixed columns and rows', function () { var rendered = findDOMNode(render(getMarkup({ fixedColumnCount: 0, fixedRowCount: 0 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(1); var _grids4 = _slicedToArray(grids, 1), bottomRight = _grids4[0]; expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto'); }); it('should adjust the number of Grids when fixed column or row counts change', function () { var rendered = findDOMNode(render(getMarkup({ fixedColumnCount: 2, fixedRowCount: 1 }))); expect(rendered.querySelectorAll('.ReactVirtualized__Grid').length).toEqual(4); rendered = findDOMNode(render(getMarkup({ fixedColumnCount: 0, fixedRowCount: 0 }))); expect(rendered.querySelectorAll('.ReactVirtualized__Grid').length).toEqual(1); rendered = findDOMNode(render(getMarkup({ fixedColumnCount: 0, fixedRowCount: 2 }))); expect(rendered.querySelectorAll('.ReactVirtualized__Grid').length).toEqual(2); }); it('should allow scrolling of fixed Grids when configured for fixed columns and rows with scroll interaction', function () { var rendered = findDOMNode(render(getMarkup({ enableFixedColumnScroll: true, enableFixedRowScroll: true, fixedColumnCount: 1, fixedRowCount: 1 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(4); var _grids5 = _slicedToArray(grids, 4), topLeft = _grids5[0], topRight = _grids5[1], bottomLeft = _grids5[2], bottomRight = _grids5[3]; expect(topLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(topLeft.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(topRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(topRight.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(bottomLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(bottomLeft.style.getPropertyValue('overflow-y')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto'); }); }); describe('hideTopRightGridScrollbar, hideBottomLeftGridScrollbar should hide the scrollbars', function () { function getScrollbarSize20() { return 20; } it('should add scroll wrappers to hide scroll bar when configured for fixed columns and rows with scroll interaction', function () { var rendered = findDOMNode(render(getMarkup({ enableFixedColumnScroll: true, enableFixedRowScroll: true, fixedColumnCount: 1, fixedRowCount: 1, hideTopRightGridScrollbar: true, hideBottomLeftGridScrollbar: true, getScrollbarSize: getScrollbarSize20 }))); var wrappers = rendered.querySelectorAll('.TopRightGrid_ScrollWrapper'); expect(wrappers.length).toEqual(1); var _wrappers = wrappers, _wrappers2 = _slicedToArray(_wrappers, 1), topRightWrapper = _wrappers2[0]; wrappers = rendered.querySelectorAll('.BottomLeftGrid_ScrollWrapper'); expect(wrappers.length).toEqual(1); var _wrappers3 = wrappers, _wrappers4 = _slicedToArray(_wrappers3, 1), bottomLeftWrapper = _wrappers4[0]; expect(topRightWrapper.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(topRightWrapper.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(bottomLeftWrapper.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(bottomLeftWrapper.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(topRightWrapper.style.getPropertyValue('height')).toEqual('20px'); expect(bottomLeftWrapper.style.getPropertyValue('height')).toEqual('280px'); expect(topRightWrapper.style.getPropertyValue('width')).toEqual('350px'); expect(bottomLeftWrapper.style.getPropertyValue('width')).toEqual('50px'); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(4); var _grids6 = _slicedToArray(grids, 4), topLeft = _grids6[0], topRight = _grids6[1], bottomLeft = _grids6[2], bottomRight = _grids6[3]; expect(topLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(topLeft.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(topRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(topRight.style.getPropertyValue('overflow-y')).toEqual('hidden'); expect(topRight.style.getPropertyValue('height')).toEqual('40px'); expect(bottomLeft.style.getPropertyValue('overflow-x')).toEqual('hidden'); expect(bottomLeft.style.getPropertyValue('overflow-y')).toEqual('auto'); expect(bottomLeft.style.getPropertyValue('width')).toEqual('70px'); expect(bottomRight.style.getPropertyValue('overflow-x')).toEqual('auto'); expect(bottomRight.style.getPropertyValue('overflow-y')).toEqual('auto'); }); }); describe('#recomputeGridSize', function () { it('should clear calculated cached styles in recomputeGridSize', function () { var fixedRowHeight = 75; var fixedColumnWidth = 100; function variableRowHeight(_ref2) { var index = _ref2.index; if (index === 0) { return fixedRowHeight; } return 20; } function variableColumnWidth(_ref3) { var index = _ref3.index; if (index === 0) { return fixedColumnWidth; } return 50; } var multiGrid; var rendered = findDOMNode(render(getMarkup({ fixedColumnCount: 1, fixedRowCount: 1, rowHeight: variableRowHeight, columnWidth: variableColumnWidth, ref: function ref(_ref4) { multiGrid = _ref4; } }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(grids.length).toEqual(4); var _grids7 = _slicedToArray(grids, 4), topLeft = _grids7[0], topRight = _grids7[1], bottomLeft = _grids7[2], bottomRight = _grids7[3]; expect(topLeft.style.getPropertyValue('height')).toEqual('75px'); expect(topRight.style.getPropertyValue('height')).toEqual('75px'); expect(bottomLeft.style.getPropertyValue('height')).toEqual('225px'); expect(bottomRight.style.getPropertyValue('height')).toEqual('225px'); expect(topLeft.style.getPropertyValue('width')).toEqual('100px'); expect(topRight.style.getPropertyValue('width')).toEqual('300px'); expect(bottomLeft.style.getPropertyValue('width')).toEqual('100px'); expect(bottomRight.style.getPropertyValue('width')).toEqual('300px'); expect(multiGrid._topGridHeight).toEqual(75); expect(multiGrid._leftGridWidth).toEqual(100); fixedRowHeight = 125; fixedColumnWidth = 75; multiGrid.recomputeGridSize(); expect(multiGrid._topGridHeight).toEqual(125); expect(multiGrid._leftGridWidth).toEqual(75); multiGrid.forceUpdate(); var gridsAfter = rendered.querySelectorAll('.ReactVirtualized__Grid'); expect(gridsAfter.length).toEqual(4); var _gridsAfter = _slicedToArray(gridsAfter, 4), topLeftAfter = _gridsAfter[0], topRightAfter = _gridsAfter[1], bottomLeftAfter = _gridsAfter[2], bottomRightAfter = _gridsAfter[3]; expect(topLeftAfter.style.getPropertyValue('height')).toEqual('125px'); expect(topRightAfter.style.getPropertyValue('height')).toEqual('125px'); expect(bottomLeftAfter.style.getPropertyValue('height')).toEqual('175px'); expect(bottomRightAfter.style.getPropertyValue('height')).toEqual('175px'); expect(topLeftAfter.style.getPropertyValue('width')).toEqual('75px'); expect(topRightAfter.style.getPropertyValue('width')).toEqual('325px'); expect(bottomLeftAfter.style.getPropertyValue('width')).toEqual('75px'); expect(bottomRightAfter.style.getPropertyValue('width')).toEqual('325px'); }); }); describe('scrollToColumn and scrollToRow', function () { it('should adjust :scrollLeft for the main Grid when scrollToColumn is used', function () { var rendered = findDOMNode(render(getMarkup({ columnWidth: 50, fixedColumnCount: 2, scrollToAlignment: 'start', scrollToColumn: 19 }))); // Bottom-right Grid is the last Grid var grid = rendered.querySelectorAll('.ReactVirtualized__Grid')[3]; // 20th column, less 2 for the fixed-column Grid, 50px column width expect(grid.scrollLeft).toEqual(850); }); it('should adjust :scrollTop for the main Grid when scrollToRow is used', function () { var rendered = findDOMNode(render(getMarkup({ fixedRowCount: 1, rowHeight: 50, scrollToAlignment: 'start', scrollToRow: 19 }))); // Bottom-right Grid is the last Grid var grid = rendered.querySelectorAll('.ReactVirtualized__Grid')[3]; // 20th row, less 1 for the fixed-row Grid, 50px row width expect(grid.scrollTop).toEqual(900); }); }); describe('#forceUpdateGrids', function () { it('should call forceUpdate() on inner Grids', function () { var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (_ref5) { var key = _ref5.key; return React.createElement("div", { key: key, style: {} }); }); var rendered = render(getMarkup({ cellRenderer: cellRenderer, columnCount: 2, fixedColumnCount: 1, fixedRowCount: 1, rowCount: 2 })); expect(cellRenderer.mock.calls).toHaveLength(4); cellRenderer.mockReset(); rendered.forceUpdateGrids(); expect(cellRenderer.mock.calls).toHaveLength(4); }); }); describe('#invalidateCellSizeAfterRender', function () { it('should call invalidateCellSizeAfterRender() on inner Grids', function () { var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (_ref6) { var key = _ref6.key; return React.createElement("div", { key: key, style: {} }); }); var rendered = render(getMarkup({ cellRenderer: cellRenderer, columnCount: 2, fixedColumnCount: 1, fixedRowCount: 1, rowCount: 2 })); cellRenderer.mockReset(); rendered.invalidateCellSizeAfterRender({ columnIndex: 0, rowIndex: 0 }); rendered.forceUpdate(); expect(cellRenderer.mock.calls).toHaveLength(4); }); it('should specify itself as the :parent for CellMeasurer rendered cells', function () { // HACK For some reason, using Jest mock broke here var savedParent; function cellRenderer(_ref7) { var key = _ref7.key, parent = _ref7.parent; savedParent = parent; return React.createElement("div", { key: key, style: {} }); } var rendered = render(getMarkup({ cellRenderer: cellRenderer, columnCount: 2, fixedColumnCount: 1, fixedRowCount: 1, rowCount: 2 })); expect(savedParent).toBe(rendered); }); }); describe('styles', function () { it('should support custom style for the outer MultiGrid wrapper element', function () { var rendered = findDOMNode(render(getMarkup({ style: { backgroundColor: 'black' } }))); expect(rendered.style.backgroundColor).toEqual('black'); }); it('should support custom styles for each Grid', function () { var rendered = findDOMNode(render(getMarkup({ fixedColumnCount: 2, fixedRowCount: 1, styleBottomLeftGrid: { backgroundColor: 'green' }, styleBottomRightGrid: { backgroundColor: 'red' }, styleTopLeftGrid: { backgroundColor: 'blue' }, styleTopRightGrid: { backgroundColor: 'purple' } }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); var topLeftGrid = grids[0]; var topRightGrid = grids[1]; var bottomLeftGrid = grids[2]; var bottomRightGrid = grids[3]; expect(topLeftGrid.style.backgroundColor).toEqual('blue'); expect(topRightGrid.style.backgroundColor).toEqual('purple'); expect(bottomLeftGrid.style.backgroundColor).toEqual('green'); expect(bottomRightGrid.style.backgroundColor).toEqual('red'); }); }); describe('scrollTop and scrollLeft', function () { it('should adjust :scrollLeft for top-right and main grids when scrollLeft is used', function () { var rendered = findDOMNode(render(getMarkup({ columnWidth: 50, fixedColumnCount: 2, scrollLeft: 850 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); var topRightGrid = grids[1]; var bottomRightGrid = grids[3]; expect(topRightGrid.scrollLeft).toEqual(850); expect(bottomRightGrid.scrollLeft).toEqual(850); }); it('should adjust :scrollTop for bottom-left and main grids when scrollTop is used', function () { var rendered = findDOMNode(render(getMarkup({ columnWidth: 50, fixedColumnCount: 2, scrollTop: 500 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); var bottomLeftGrid = grids[2]; var bottomRightGrid = grids[3]; expect(bottomLeftGrid.scrollTop).toEqual(500); expect(bottomRightGrid.scrollTop).toEqual(500); }); it('should adjust :scrollTop and :scrollLeft when scrollTop and scrollLeft change', function () { render(getMarkup()); var rendered = findDOMNode(render(getMarkup({ scrollTop: 750, scrollLeft: 900 }))); var grids = rendered.querySelectorAll('.ReactVirtualized__Grid'); var topRightGrid = grids[1]; var bottomLeftGrid = grids[2]; var bottomRightGrid = grids[3]; expect(topRightGrid.scrollLeft).toEqual(900); expect(bottomRightGrid.scrollLeft).toEqual(900); expect(bottomLeftGrid.scrollTop).toEqual(750); expect(bottomRightGrid.scrollTop).toEqual(750); }); it('should not crash when decreasing :rowCount', function () { render(getMarkup()); var updated = render(getMarkup({ rowCount: 2 })); expect(updated.props.rowCount).toEqual(2); }); it('should not crash when decreasing :columnCount', function () { render(getMarkup()); var updated = render(getMarkup({ columnCount: 3 })); expect(updated.props.columnCount).toEqual(3); }); }); describe('deferredMeasurementCache', function () { function getDeferredMeasurementCache() { var deferredMeasurementCache = new CellMeasurerCache({ fixedHeight: true, fixedWidth: true }); deferredMeasurementCache._columnIndices = {}; deferredMeasurementCache._rowIndices = {}; deferredMeasurementCache.has = function (rowIndex, columnIndex) { deferredMeasurementCache._columnIndices[columnIndex] = columnIndex; deferredMeasurementCache._rowIndices[rowIndex] = rowIndex; return true; }; return deferredMeasurementCache; } it('should wrap top-right and bottom-right deferredMeasurementCache if fixedColumnCount is > 0', function () { var deferredMeasurementCache = getDeferredMeasurementCache(); render(getMarkup({ deferredMeasurementCache: deferredMeasurementCache, columnCount: 3, fixedColumnCount: 1, fixedRowCount: 0, rowCount: 1 })); expect(Object.keys(deferredMeasurementCache._columnIndices)).toEqual(['0', '1', '2']); }); it('should not wrap top-right and bottom-right deferredMeasurementCache if fixedColumnCount is 0', function () { var deferredMeasurementCache = getDeferredMeasurementCache(); render(getMarkup({ deferredMeasurementCache: deferredMeasurementCache, columnCount: 2, fixedColumnCount: 0, fixedRowCount: 0, rowCount: 1 })); expect(Object.keys(deferredMeasurementCache._columnIndices)).toEqual(['0', '1']); }); it('should wrap bottom-left and bottom-right deferredMeasurementCache if fixedRowCount is > 0', function () { var deferredMeasurementCache = getDeferredMeasurementCache(); render(getMarkup({ deferredMeasurementCache: deferredMeasurementCache, columnCount: 1, fixedColumnCount: 0, fixedRowCount: 1, rowCount: 3 })); expect(Object.keys(deferredMeasurementCache._rowIndices)).toEqual(['0', '1', '2']); }); it('should not wrap bottom-left and bottom-right deferredMeasurementCache if fixedRowCount is 0', function () { var deferredMeasurementCache = getDeferredMeasurementCache(); render(getMarkup({ deferredMeasurementCache: deferredMeasurementCache, columnCount: 1, fixedColumnCount: 0, fixedRowCount: 0, rowCount: 2 })); expect(Object.keys(deferredMeasurementCache._rowIndices)).toEqual(['0', '1']); }); }); describe('onScrollbarPresenceChange', function () { function getScrollbarSize20() { return 20; } it('should not trigger on-mount if scrollbars are hidden', function () { var onScrollbarPresenceChange = jest.fn(); render(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 1 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); }); it('should trigger on-mount if scrollbars are visible', function () { var onScrollbarPresenceChange = jest.fn(); render(getMarkup({ columnCount: 100, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 100 })); expect(onScrollbarPresenceChange).toHaveBeenCalled(); var args = onScrollbarPresenceChange.mock.calls[0][0]; expect(args.horizontal).toBe(true); expect(args.size).toBe(getScrollbarSize20()); expect(args.vertical).toBe(true); }); it('should trigger on-update if scrollbar visibility has changed', function () { var onScrollbarPresenceChange = jest.fn(); render(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 1 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); render(getMarkup({ columnCount: 100, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 100 })); expect(onScrollbarPresenceChange).toHaveBeenCalled(); var args = onScrollbarPresenceChange.mock.calls[0][0]; expect(args.horizontal).toBe(true); expect(args.size).toBe(getScrollbarSize20()); expect(args.vertical).toBe(true); }); it('should not trigger on-update if scrollbar visibility does not change', function () { var onScrollbarPresenceChange = jest.fn(); render(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 1 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); render(getMarkup({ columnCount: 2, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 2 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); }); }); });dist/es/MultiGrid/MultiGrid.example.js000064400000011660151676725770013741 0ustar00import _extends from "@babel/runtime/helpers/extends"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import Immutable from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import { LabeledInput, InputRow } from '../demo/LabeledInput'; import AutoSizer from '../AutoSizer'; import MultiGrid from './MultiGrid'; import styles from './MultiGrid.example.css'; var STYLE = { border: '1px solid #ddd' }; var STYLE_BOTTOM_LEFT_GRID = { borderRight: '2px solid #aaa', backgroundColor: '#f7f7f7' }; var STYLE_TOP_LEFT_GRID = { borderBottom: '2px solid #aaa', borderRight: '2px solid #aaa', fontWeight: 'bold' }; var STYLE_TOP_RIGHT_GRID = { borderBottom: '2px solid #aaa', fontWeight: 'bold' }; var MultiGridExample = /*#__PURE__*/ function (_React$PureComponent) { _inherits(MultiGridExample, _React$PureComponent); function MultiGridExample(props, context) { var _this; _classCallCheck(this, MultiGridExample); _this = _possibleConstructorReturn(this, _getPrototypeOf(MultiGridExample).call(this, props, context)); _this.state = { fixedColumnCount: 2, fixedRowCount: 1, scrollToColumn: 0, scrollToRow: 0 }; _this._cellRenderer = _this._cellRenderer.bind(_assertThisInitialized(_this)); _this._onFixedColumnCountChange = _this._createEventHandler('fixedColumnCount'); _this._onFixedRowCountChange = _this._createEventHandler('fixedRowCount'); _this._onScrollToColumnChange = _this._createEventHandler('scrollToColumn'); _this._onScrollToRowChange = _this._createEventHandler('scrollToRow'); return _this; } _createClass(MultiGridExample, [{ key: "render", value: function render() { var _this2 = this; return React.createElement(ContentBox, null, React.createElement(ContentBoxHeader, { text: "MultiGrid", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/MultiGrid/MultiGrid.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/MultiGrid.md" }), React.createElement(ContentBoxParagraph, null, "This component stitches together several grids to provide a fixed column/row interface."), React.createElement(InputRow, null, this._createLabeledInput('fixedColumnCount', this._onFixedColumnCountChange), this._createLabeledInput('fixedRowCount', this._onFixedRowCountChange), this._createLabeledInput('scrollToColumn', this._onScrollToColumnChange), this._createLabeledInput('scrollToRow', this._onScrollToRowChange)), React.createElement(AutoSizer, { disableHeight: true }, function (_ref) { var width = _ref.width; return React.createElement(MultiGrid, _extends({}, _this2.state, { cellRenderer: _this2._cellRenderer, columnWidth: 75, columnCount: 50, enableFixedColumnScroll: true, enableFixedRowScroll: true, height: 300, rowHeight: 40, rowCount: 100, style: STYLE, styleBottomLeftGrid: STYLE_BOTTOM_LEFT_GRID, styleTopLeftGrid: STYLE_TOP_LEFT_GRID, styleTopRightGrid: STYLE_TOP_RIGHT_GRID, width: width, hideTopRightGridScrollbar: true, hideBottomLeftGridScrollbar: true })); })); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref2) { var columnIndex = _ref2.columnIndex, key = _ref2.key, rowIndex = _ref2.rowIndex, style = _ref2.style; return React.createElement("div", { className: styles.Cell, key: key, style: style }, columnIndex, ", ", rowIndex); } }, { key: "_createEventHandler", value: function _createEventHandler(property) { var _this3 = this; return function (event) { var value = parseInt(event.target.value, 10) || 0; _this3.setState(_defineProperty({}, property, value)); }; } }, { key: "_createLabeledInput", value: function _createLabeledInput(property, eventHandler) { var value = this.state[property]; return React.createElement(LabeledInput, { label: property, name: property, onChange: eventHandler, value: value }); } }]); return MultiGridExample; }(React.PureComponent); _defineProperty(MultiGridExample, "contextTypes", { list: PropTypes.instanceOf(Immutable.List).isRequired }); export { MultiGridExample as default };dist/es/List/List.js000064400000030405151676725770010333 0ustar00import _extends from "@babel/runtime/helpers/extends"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; var _class, _temp; import Grid, { accessibilityOverscanIndicesGetter } from '../Grid'; import * as React from 'react'; import clsx from 'clsx'; /** * It is inefficient to create and manage a large list of DOM elements within a scrolling container * if only a few of those elements are visible. The primary purpose of this component is to improve * performance by only rendering the DOM nodes that a user is able to see based on their current * scroll position. * * This component renders a virtualized list of elements with either fixed or dynamic heights. */ var List = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { _inherits(List, _React$PureComponent); function List() { var _getPrototypeOf2; var _this; _classCallCheck(this, List); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(List)).call.apply(_getPrototypeOf2, [this].concat(args))); _defineProperty(_assertThisInitialized(_this), "Grid", void 0); _defineProperty(_assertThisInitialized(_this), "_cellRenderer", function (_ref) { var parent = _ref.parent, rowIndex = _ref.rowIndex, style = _ref.style, isScrolling = _ref.isScrolling, isVisible = _ref.isVisible, key = _ref.key; var rowRenderer = _this.props.rowRenderer; // TRICKY The style object is sometimes cached by Grid. // This prevents new style objects from bypassing shallowCompare(). // However as of React 16, style props are auto-frozen (at least in dev mode) // Check to make sure we can still modify the style before proceeding. // https://github.com/facebook/react/commit/977357765b44af8ff0cfea327866861073095c12#commitcomment-20648713 var widthDescriptor = Object.getOwnPropertyDescriptor(style, 'width'); if (widthDescriptor && widthDescriptor.writable) { // By default, List cells should be 100% width. // This prevents them from flowing under a scrollbar (if present). style.width = '100%'; } return rowRenderer({ index: rowIndex, style: style, isScrolling: isScrolling, isVisible: isVisible, key: key, parent: parent }); }); _defineProperty(_assertThisInitialized(_this), "_setRef", function (ref) { _this.Grid = ref; }); _defineProperty(_assertThisInitialized(_this), "_onScroll", function (_ref2) { var clientHeight = _ref2.clientHeight, scrollHeight = _ref2.scrollHeight, scrollTop = _ref2.scrollTop; var onScroll = _this.props.onScroll; onScroll({ clientHeight: clientHeight, scrollHeight: scrollHeight, scrollTop: scrollTop }); }); _defineProperty(_assertThisInitialized(_this), "_onSectionRendered", function (_ref3) { var rowOverscanStartIndex = _ref3.rowOverscanStartIndex, rowOverscanStopIndex = _ref3.rowOverscanStopIndex, rowStartIndex = _ref3.rowStartIndex, rowStopIndex = _ref3.rowStopIndex; var onRowsRendered = _this.props.onRowsRendered; onRowsRendered({ overscanStartIndex: rowOverscanStartIndex, overscanStopIndex: rowOverscanStopIndex, startIndex: rowStartIndex, stopIndex: rowStopIndex }); }); return _this; } _createClass(List, [{ key: "forceUpdateGrid", value: function forceUpdateGrid() { if (this.Grid) { this.Grid.forceUpdate(); } } /** See Grid#getOffsetForCell */ }, { key: "getOffsetForRow", value: function getOffsetForRow(_ref4) { var alignment = _ref4.alignment, index = _ref4.index; if (this.Grid) { var _this$Grid$getOffsetF = this.Grid.getOffsetForCell({ alignment: alignment, rowIndex: index, columnIndex: 0 }), scrollTop = _this$Grid$getOffsetF.scrollTop; return scrollTop; } return 0; } /** CellMeasurer compatibility */ }, { key: "invalidateCellSizeAfterRender", value: function invalidateCellSizeAfterRender(_ref5) { var columnIndex = _ref5.columnIndex, rowIndex = _ref5.rowIndex; if (this.Grid) { this.Grid.invalidateCellSizeAfterRender({ rowIndex: rowIndex, columnIndex: columnIndex }); } } /** See Grid#measureAllCells */ }, { key: "measureAllRows", value: function measureAllRows() { if (this.Grid) { this.Grid.measureAllCells(); } } /** CellMeasurer compatibility */ }, { key: "recomputeGridSize", value: function recomputeGridSize() { var _ref6 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref6$columnIndex = _ref6.columnIndex, columnIndex = _ref6$columnIndex === void 0 ? 0 : _ref6$columnIndex, _ref6$rowIndex = _ref6.rowIndex, rowIndex = _ref6$rowIndex === void 0 ? 0 : _ref6$rowIndex; if (this.Grid) { this.Grid.recomputeGridSize({ rowIndex: rowIndex, columnIndex: columnIndex }); } } /** See Grid#recomputeGridSize */ }, { key: "recomputeRowHeights", value: function recomputeRowHeights() { var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (this.Grid) { this.Grid.recomputeGridSize({ rowIndex: index, columnIndex: 0 }); } } /** See Grid#scrollToPosition */ }, { key: "scrollToPosition", value: function scrollToPosition() { var scrollTop = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (this.Grid) { this.Grid.scrollToPosition({ scrollTop: scrollTop }); } } /** See Grid#scrollToCell */ }, { key: "scrollToRow", value: function scrollToRow() { var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; if (this.Grid) { this.Grid.scrollToCell({ columnIndex: 0, rowIndex: index }); } } }, { key: "render", value: function render() { var _this$props = this.props, className = _this$props.className, noRowsRenderer = _this$props.noRowsRenderer, scrollToIndex = _this$props.scrollToIndex, width = _this$props.width; var classNames = clsx('ReactVirtualized__List', className); return React.createElement(Grid, _extends({}, this.props, { autoContainerWidth: true, cellRenderer: this._cellRenderer, className: classNames, columnWidth: width, columnCount: 1, noContentRenderer: noRowsRenderer, onScroll: this._onScroll, onSectionRendered: this._onSectionRendered, ref: this._setRef, scrollToRow: scrollToIndex })); } }]); return List; }(React.PureComponent), _defineProperty(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { "aria-label": PropTypes.string, /** * Removes fixed height from the scrollingContainer so that the total height * of rows can stretch the window. Intended for use with WindowScroller */ "autoHeight": PropTypes.bool.isRequired, /** Optional CSS class name */ "className": PropTypes.string, /** * Used to estimate the total height of a List before all of its rows have actually been measured. * The estimated total height is adjusted as rows are rendered. */ "estimatedRowSize": PropTypes.number.isRequired, /** Height constraint for list (determines how many actual rows are rendered) */ "height": PropTypes.number.isRequired, /** Optional renderer to be used in place of rows when rowCount is 0 */ "noRowsRenderer": function noRowsRenderer() { return (typeof bpfrpt_proptype_NoContentRenderer === "function" ? bpfrpt_proptype_NoContentRenderer.isRequired ? bpfrpt_proptype_NoContentRenderer.isRequired : bpfrpt_proptype_NoContentRenderer : PropTypes.shape(bpfrpt_proptype_NoContentRenderer).isRequired).apply(this, arguments); }, /** Callback invoked with information about the slice of rows that were just rendered. */ "onRowsRendered": PropTypes.func.isRequired, /** * Callback invoked whenever the scroll offset changes within the inner scrollable region. * This callback can be used to sync scrolling between lists, tables, or grids. */ "onScroll": PropTypes.func.isRequired, /** See Grid#overscanIndicesGetter */ "overscanIndicesGetter": function overscanIndicesGetter() { return (typeof bpfrpt_proptype_OverscanIndicesGetter === "function" ? bpfrpt_proptype_OverscanIndicesGetter.isRequired ? bpfrpt_proptype_OverscanIndicesGetter.isRequired : bpfrpt_proptype_OverscanIndicesGetter : PropTypes.shape(bpfrpt_proptype_OverscanIndicesGetter).isRequired).apply(this, arguments); }, /** * Number of rows to render above/below the visible bounds of the list. * These rows can help for smoother scrolling on touch devices. */ "overscanRowCount": PropTypes.number.isRequired, /** Either a fixed row height (number) or a function that returns the height of a row given its index. */ "rowHeight": function rowHeight() { return (typeof bpfrpt_proptype_CellSize === "function" ? bpfrpt_proptype_CellSize.isRequired ? bpfrpt_proptype_CellSize.isRequired : bpfrpt_proptype_CellSize : PropTypes.shape(bpfrpt_proptype_CellSize).isRequired).apply(this, arguments); }, /** Responsible for rendering a row given an index; ({ index: number }): node */ "rowRenderer": function rowRenderer() { return (typeof bpfrpt_proptype_RowRenderer === "function" ? bpfrpt_proptype_RowRenderer.isRequired ? bpfrpt_proptype_RowRenderer.isRequired : bpfrpt_proptype_RowRenderer : PropTypes.shape(bpfrpt_proptype_RowRenderer).isRequired).apply(this, arguments); }, /** Number of rows in list. */ "rowCount": PropTypes.number.isRequired, /** See Grid#scrollToAlignment */ "scrollToAlignment": function scrollToAlignment() { return (typeof bpfrpt_proptype_Alignment === "function" ? bpfrpt_proptype_Alignment.isRequired ? bpfrpt_proptype_Alignment.isRequired : bpfrpt_proptype_Alignment : PropTypes.shape(bpfrpt_proptype_Alignment).isRequired).apply(this, arguments); }, /** Row index to ensure visible (by forcefully scrolling if necessary) */ "scrollToIndex": PropTypes.number.isRequired, /** Vertical offset. */ "scrollTop": PropTypes.number, /** Optional inline style */ "style": PropTypes.object.isRequired, /** Tab index for focus */ "tabIndex": PropTypes.number, /** Width of list */ "width": PropTypes.number.isRequired }), _temp); _defineProperty(List, "defaultProps", { autoHeight: false, estimatedRowSize: 30, onScroll: function onScroll() {}, noRowsRenderer: function noRowsRenderer() { return null; }, onRowsRendered: function onRowsRendered() {}, overscanIndicesGetter: accessibilityOverscanIndicesGetter, overscanRowCount: 10, scrollToAlignment: 'auto', scrollToIndex: -1, style: {} }); export { List as default }; import { bpfrpt_proptype_NoContentRenderer } from "../Grid"; import { bpfrpt_proptype_Alignment } from "../Grid"; import { bpfrpt_proptype_CellSize } from "../Grid"; import { bpfrpt_proptype_CellPosition } from "../Grid"; import { bpfrpt_proptype_OverscanIndicesGetter } from "../Grid"; import { bpfrpt_proptype_RenderedSection } from "../Grid"; import { bpfrpt_proptype_CellRendererParams } from "../Grid"; import { bpfrpt_proptype_Scroll as bpfrpt_proptype_GridScroll } from "../Grid"; import { bpfrpt_proptype_RowRenderer } from "./types"; import { bpfrpt_proptype_RenderedRows } from "./types"; import { bpfrpt_proptype_Scroll } from "./types"; import PropTypes from "prop-types";dist/es/List/types.js000064400000002210151676725770010555 0ustar00import * as React from 'react'; var bpfrpt_proptype_RowRendererParams = process.env.NODE_ENV === 'production' ? null : { "index": PropTypes.number.isRequired, "isScrolling": PropTypes.bool.isRequired, "isVisible": PropTypes.bool.isRequired, "key": PropTypes.string.isRequired, "parent": PropTypes.object.isRequired, "style": PropTypes.object.isRequired }; var bpfrpt_proptype_RowRenderer = process.env.NODE_ENV === 'production' ? null : PropTypes.func; var bpfrpt_proptype_RenderedRows = process.env.NODE_ENV === 'production' ? null : { "overscanStartIndex": PropTypes.number.isRequired, "overscanStopIndex": PropTypes.number.isRequired, "startIndex": PropTypes.number.isRequired, "stopIndex": PropTypes.number.isRequired }; var bpfrpt_proptype_Scroll = process.env.NODE_ENV === 'production' ? null : { "clientHeight": PropTypes.number.isRequired, "scrollHeight": PropTypes.number.isRequired, "scrollTop": PropTypes.number.isRequired }; import PropTypes from "prop-types"; export { bpfrpt_proptype_RowRendererParams }; export { bpfrpt_proptype_RowRenderer }; export { bpfrpt_proptype_RenderedRows }; export { bpfrpt_proptype_Scroll };dist/es/List/index.js000064400000000266151676725770010531 0ustar00export { default } from './List'; export { default as List } from './List'; import { bpfrpt_proptype_RowRendererParams } from "./types"; export { bpfrpt_proptype_RowRendererParams };dist/es/List/List.jest.js000064400000043744151676725770011311 0ustar00import _extends from "@babel/runtime/helpers/extends"; import * as React from 'react'; import { findDOMNode } from 'react-dom'; import { render } from '../TestUtils'; import { Simulate } from 'react-dom/test-utils'; import Immutable from 'immutable'; import List from './List'; import { defaultOverscanIndicesGetter } from '../Grid'; describe('List', function () { var array = []; for (var i = 0; i < 100; i++) { array.push("Name ".concat(i)); } var names = Immutable.fromJS(array); // Override default behavior of overscanning by at least 1 (for accessibility) // Because it makes for simple tests below function overscanIndicesGetter(_ref) { var startIndex = _ref.startIndex, stopIndex = _ref.stopIndex; return { overscanStartIndex: startIndex, overscanStopIndex: stopIndex }; } function getMarkup() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; function rowRenderer(_ref2) { var index = _ref2.index, key = _ref2.key, style = _ref2.style; return React.createElement("div", { className: "listItem", key: key, style: style }, names.get(index)); } return React.createElement(List, _extends({ height: 100, overscanIndicesGetter: overscanIndicesGetter, overscanRowCount: 0, rowHeight: 10, rowCount: names.size, rowRenderer: rowRenderer, width: 100 }, props)); } describe('number of rendered children', function () { it('should render enough children to fill the view', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.querySelectorAll('.listItem').length).toEqual(10); }); it('should not render more children than available if the list is not filled', function () { var rendered = findDOMNode(render(getMarkup({ rowCount: 5 }))); expect(rendered.querySelectorAll('.listItem').length).toEqual(5); }); }); describe('scrollToPosition', function () { it('should scroll to the top', function () { var instance = render(getMarkup({ rowHeight: 10 })); instance.scrollToPosition(100); var rendered = findDOMNode(instance); expect(rendered.textContent).toContain('Name 10'); expect(rendered.textContent).toContain('Name 19'); }); }); /** Tests scrolling via initial props */ describe('scrollToIndex', function () { it('should scroll to the top', function () { var rendered = findDOMNode(render(getMarkup({ scrollToIndex: 0 }))); expect(rendered.textContent).toContain('Name 0'); }); it('should scroll down to the middle', function () { var rendered = findDOMNode(render(getMarkup({ scrollToIndex: 49 }))); // 100 items * 10 item height = 1,000 total item height // 10 items can be visible at a time and :scrollTop is initially 0, // So the minimum amount of scrolling leaves the 50th item at the bottom (just scrolled into view). expect(rendered.textContent).toContain('Name 49'); }); it('should scroll to the bottom', function () { var rendered = findDOMNode(render(getMarkup({ scrollToIndex: 99 }))); // 100 height - 10 header = 90 available scroll space. // 100 items * 10 item height = 1,000 total item height // Target height for the last item then is 1000 - 90 expect(rendered.textContent).toContain('Name 99'); }); it('should scroll to the correct position for :scrollToAlignment "start"', function () { var rendered = findDOMNode(render(getMarkup({ scrollToAlignment: 'start', scrollToIndex: 49 }))); // 100 items * 10 item height = 1,000 total item height; 10 items can be visible at a time. expect(rendered.textContent).toContain('Name 49'); expect(rendered.textContent).toContain('Name 58'); }); it('should scroll to the correct position for :scrollToAlignment "end"', function () { render(getMarkup({ scrollToIndex: 99 })); var rendered = findDOMNode(render(getMarkup({ scrollToAlignment: 'end', scrollToIndex: 49 }))); // 100 items * 10 item height = 1,000 total item height; 10 items can be visible at a time. expect(rendered.textContent).toContain('Name 40'); expect(rendered.textContent).toContain('Name 49'); }); it('should scroll to the correct position for :scrollToAlignment "center"', function () { render(getMarkup({ scrollToIndex: 99 })); var rendered = findDOMNode(render(getMarkup({ scrollToAlignment: 'center', scrollToIndex: 49 }))); // 100 items * 10 item height = 1,000 total item height; 11 items can be visible at a time (the first and last item are only partially visible) expect(rendered.textContent).toContain('Name 44'); expect(rendered.textContent).toContain('Name 54'); }); }); describe('property updates', function () { it('should update :scrollToIndex position when :rowHeight changes', function () { var rendered = findDOMNode(render(getMarkup({ scrollToIndex: 50 }))); expect(rendered.textContent).toContain('Name 50'); // Making rows taller pushes name off/beyond the scrolled area rendered = findDOMNode(render(getMarkup({ scrollToIndex: 50, rowHeight: 20 }))); expect(rendered.textContent).toContain('Name 50'); }); it('should update :scrollToIndex position when :height changes', function () { var rendered = findDOMNode(render(getMarkup({ scrollToIndex: 50 }))); expect(rendered.textContent).toContain('Name 50'); // Making the list shorter leaves only room for 1 item rendered = findDOMNode(render(getMarkup({ scrollToIndex: 50, height: 20 }))); expect(rendered.textContent).toContain('Name 50'); }); it('should update :scrollToIndex position when :scrollToIndex changes', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.textContent).not.toContain('Name 50'); rendered = findDOMNode(render(getMarkup({ scrollToIndex: 50 }))); expect(rendered.textContent).toContain('Name 50'); }); it('should update scroll position if size shrinks smaller than the current scroll', function () { findDOMNode(render(getMarkup({ scrollToIndex: 500 }))); findDOMNode(render(getMarkup())); var rendered = findDOMNode(render(getMarkup({ scrollToIndex: 500, rowCount: 10 }))); expect(rendered.textContent).toContain('Name 9'); }); }); describe('noRowsRenderer', function () { it('should call :noRowsRenderer if :rowCount is 0', function () { var rendered = findDOMNode(render(getMarkup({ noRowsRenderer: function noRowsRenderer() { return React.createElement("div", null, "No rows!"); }, rowCount: 0 }))); expect(rendered.textContent).toEqual('No rows!'); }); it('should render an empty body if :rowCount is 0 and there is no :noRowsRenderer', function () { var rendered = findDOMNode(render(getMarkup({ rowCount: 0 }))); expect(rendered.textContent).toEqual(''); }); }); describe('onRowsRendered', function () { it('should call :onRowsRendered if at least one row is rendered', function () { var startIndex, stopIndex; render(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params; return _params = params, startIndex = _params.startIndex, stopIndex = _params.stopIndex, _params; } })); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(9); }); it('should not call :onRowsRendered unless the start or stop indices have changed', function () { var numCalls = 0; var startIndex; var stopIndex; var onRowsRendered = function onRowsRendered(params) { startIndex = params.startIndex; stopIndex = params.stopIndex; numCalls++; }; findDOMNode(render(getMarkup({ onRowsRendered: onRowsRendered }))); expect(numCalls).toEqual(1); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(9); findDOMNode(render(getMarkup({ onRowsRendered: onRowsRendered }))); expect(numCalls).toEqual(1); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(9); }); it('should call :onRowsRendered if the start or stop indices have changed', function () { var numCalls = 0; var startIndex; var stopIndex; var onRowsRendered = function onRowsRendered(params) { startIndex = params.startIndex; stopIndex = params.stopIndex; numCalls++; }; findDOMNode(render(getMarkup({ onRowsRendered: onRowsRendered }))); expect(numCalls).toEqual(1); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(9); findDOMNode(render(getMarkup({ height: 50, onRowsRendered: onRowsRendered }))); expect(numCalls).toEqual(2); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(4); }); it('should not call :onRowsRendered if no rows are rendered', function () { var startIndex, stopIndex; render(getMarkup({ height: 0, onRowsRendered: function onRowsRendered(params) { var _params2; return _params2 = params, startIndex = _params2.startIndex, stopIndex = _params2.stopIndex, _params2; } })); expect(startIndex).toEqual(undefined); expect(stopIndex).toEqual(undefined); }); }); describe(':scrollTop property', function () { it('should render correctly when an initial :scrollTop property is specified', function () { var startIndex, stopIndex; render(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params3; return _params3 = params, startIndex = _params3.startIndex, stopIndex = _params3.stopIndex, _params3; }, scrollTop: 100 })); expect(startIndex).toEqual(10); expect(stopIndex).toEqual(19); }); it('should render correctly when :scrollTop property is updated', function () { var startIndex, stopIndex; findDOMNode(render(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params4; return _params4 = params, startIndex = _params4.startIndex, stopIndex = _params4.stopIndex, _params4; } }))); expect(startIndex).toEqual(0); expect(stopIndex).toEqual(9); findDOMNode(render(getMarkup({ onRowsRendered: function onRowsRendered(params) { var _params5; return _params5 = params, startIndex = _params5.startIndex, stopIndex = _params5.stopIndex, _params5; }, scrollTop: 100 }))); expect(startIndex).toEqual(10); expect(stopIndex).toEqual(19); }); }); describe('styles, classNames, and ids', function () { it('should use the expected global CSS classNames', function () { var node = findDOMNode(render(getMarkup())); expect(node.className).toContain('ReactVirtualized__List'); }); it('should use a custom :className if specified', function () { var node = findDOMNode(render(getMarkup({ className: 'foo' }))); expect(node.className).toContain('foo'); }); it('should use a custom :id if specified', function () { var node = findDOMNode(render(getMarkup({ id: 'bar' }))); expect(node.getAttribute('id')).toEqual('bar'); }); it('should use a custom :style if specified', function () { var style = { backgroundColor: 'red' }; var rendered = findDOMNode(render(getMarkup({ style: style }))); expect(rendered.style.backgroundColor).toEqual('red'); }); it('should set the width of a row to be 100% by default', function () { var rendered = findDOMNode(render(getMarkup())); var cell = rendered.querySelector('.listItem'); expect(cell.style.width).toEqual('100%'); }); }); describe('overscanRowCount', function () { it('should not overscan by default', function () { var mock = jest.fn(); mock.mockImplementation(overscanIndicesGetter); render(getMarkup({ overscanIndicesGetter: mock })); expect(mock.mock.calls[0][0].overscanCellsCount).toEqual(0); expect(mock.mock.calls[1][0].overscanCellsCount).toEqual(0); }); it('should overscan the specified amount', function () { var mock = jest.fn(); mock.mockImplementation(overscanIndicesGetter); render(getMarkup({ overscanIndicesGetter: mock, overscanRowCount: 10 })); expect(mock.mock.calls[0][0].overscanCellsCount).toEqual(0); expect(mock.mock.calls[1][0].overscanCellsCount).toEqual(10); }); }); describe('onScroll', function () { it('should trigger callback when component initially mounts', function () { var onScrollCalls = []; render(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); expect(onScrollCalls).toEqual([{ clientHeight: 100, scrollHeight: 1000, scrollTop: 0 }]); }); it('should trigger callback when component scrolls', function () { var onScrollCalls = []; var rendered = render(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); var target = { scrollLeft: 0, scrollTop: 100 }; rendered.Grid._scrollingContainer = target; // HACK to work around _onScroll target check Simulate.scroll(findDOMNode(rendered), { target: target }); expect(onScrollCalls[onScrollCalls.length - 1]).toEqual({ clientHeight: 100, scrollHeight: 1000, scrollTop: 100 }); }); }); describe('measureAllRows', function () { it('should measure any unmeasured rows', function () { var rendered = render(getMarkup({ estimatedRowSize: 15, height: 0, rowCount: 10, rowHeight: function rowHeight() { return 20; }, width: 0 })); expect(rendered.Grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(150); rendered.measureAllRows(); expect(rendered.Grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(200); }); }); describe('recomputeRowHeights', function () { it('should recompute row heights and other values when called', function () { var indices = []; var rowHeight = function rowHeight(_ref3) { var index = _ref3.index; indices.push(index); return 10; }; var component = render(getMarkup({ rowHeight: rowHeight, rowCount: 50 })); indices.splice(0); component.recomputeRowHeights(); // Only the rows required to fill the current viewport will be rendered expect(indices[0]).toEqual(0); expect(indices[indices.length - 1]).toEqual(9); indices.splice(0); component.recomputeRowHeights(4); expect(indices[0]).toEqual(4); expect(indices[indices.length - 1]).toEqual(9); }); }); describe('forceUpdateGrid', function () { it('should refresh inner Grid content when called', function () { var marker = 'a'; function rowRenderer(_ref4) { var index = _ref4.index, key = _ref4.key, style = _ref4.style; return React.createElement("div", { key: key, style: style }, index, marker); } var component = render(getMarkup({ rowRenderer: rowRenderer })); var node = findDOMNode(component); expect(node.textContent).toContain('1a'); marker = 'b'; component.forceUpdateGrid(); expect(node.textContent).toContain('1b'); }); }); describe('tabIndex', function () { it('should be focusable by default', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.tabIndex).toEqual(0); }); it('should allow tabIndex to be overridden', function () { var rendered = findDOMNode(render(getMarkup({ tabIndex: -1 }))); expect(rendered.tabIndex).toEqual(-1); }); }); it('should pass the cellRenderer an :isVisible flag', function () { var rowRendererCalls = []; function rowRenderer(props) { rowRendererCalls.push(props); return null; } findDOMNode(render(getMarkup({ height: 50, overscanIndicesGetter: defaultOverscanIndicesGetter, overscanRowCount: 1, rowHeight: 50, rowRenderer: rowRenderer }))); expect(rowRendererCalls[0].isVisible).toEqual(true); expect(rowRendererCalls[1].isVisible).toEqual(false); }); it('should relay the Grid :parent param to the :rowRenderer', function () { var rowRenderer = jest.fn().mockReturnValue(null); findDOMNode(render(getMarkup({ rowRenderer: rowRenderer }))); expect(rowRenderer.mock.calls[0][0].parent).not.toBeUndefined(); }); describe('pure', function () { it('should not re-render unless props have changed', function () { var rowRendererCalled = false; function rowRenderer(_ref5) { var index = _ref5.index, key = _ref5.key, style = _ref5.style; rowRendererCalled = true; return React.createElement("div", { key: key, style: style }, index); } var markup = getMarkup({ rowRenderer: rowRenderer }); render(markup); expect(rowRendererCalled).toEqual(true); rowRendererCalled = false; render(markup); expect(rowRendererCalled).toEqual(false); }); }); it('should set the width of the single-column inner Grid to auto', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('auto'); }); });dist/es/List/List.example.js000064400000021360151676725770011765 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import clsx from 'clsx'; import Immutable from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import styles from './List.example.css'; import AutoSizer from '../AutoSizer'; import List from './List'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import { LabeledInput, InputRow } from '../demo/LabeledInput'; var ListExample = /*#__PURE__*/ function (_React$PureComponent) { _inherits(ListExample, _React$PureComponent); function ListExample(props, context) { var _this; _classCallCheck(this, ListExample); _this = _possibleConstructorReturn(this, _getPrototypeOf(ListExample).call(this, props, context)); _this.state = { listHeight: 300, listRowHeight: 50, overscanRowCount: 10, rowCount: context.list.size, scrollToIndex: undefined, showScrollingPlaceholder: false, useDynamicRowHeight: false }; _this._getRowHeight = _this._getRowHeight.bind(_assertThisInitialized(_this)); _this._noRowsRenderer = _this._noRowsRenderer.bind(_assertThisInitialized(_this)); _this._onRowCountChange = _this._onRowCountChange.bind(_assertThisInitialized(_this)); _this._onScrollToRowChange = _this._onScrollToRowChange.bind(_assertThisInitialized(_this)); _this._rowRenderer = _this._rowRenderer.bind(_assertThisInitialized(_this)); return _this; } _createClass(ListExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, listHeight = _this$state.listHeight, listRowHeight = _this$state.listRowHeight, overscanRowCount = _this$state.overscanRowCount, rowCount = _this$state.rowCount, scrollToIndex = _this$state.scrollToIndex, showScrollingPlaceholder = _this$state.showScrollingPlaceholder, useDynamicRowHeight = _this$state.useDynamicRowHeight; return React.createElement(ContentBox, null, React.createElement(ContentBoxHeader, { text: "List", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/List/List.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/List.md" }), React.createElement(ContentBoxParagraph, null, "The list below is windowed (or \"virtualized\") meaning that only the visible rows are rendered. Adjust its configurable properties below to see how it reacts."), React.createElement(ContentBoxParagraph, null, React.createElement("label", { className: styles.checkboxLabel }, React.createElement("input", { "aria-label": "Use dynamic row heights?", checked: useDynamicRowHeight, className: styles.checkbox, type: "checkbox", onChange: function onChange(event) { return _this2.setState({ useDynamicRowHeight: event.target.checked }); } }), "Use dynamic row heights?"), React.createElement("label", { className: styles.checkboxLabel }, React.createElement("input", { "aria-label": "Show scrolling placeholder?", checked: showScrollingPlaceholder, className: styles.checkbox, type: "checkbox", onChange: function onChange(event) { return _this2.setState({ showScrollingPlaceholder: event.target.checked }); } }), "Show scrolling placeholder?")), React.createElement(InputRow, null, React.createElement(LabeledInput, { label: "Num rows", name: "rowCount", onChange: this._onRowCountChange, value: rowCount }), React.createElement(LabeledInput, { label: "Scroll to", name: "onScrollToRow", placeholder: "Index...", onChange: this._onScrollToRowChange, value: scrollToIndex || '' }), React.createElement(LabeledInput, { label: "List height", name: "listHeight", onChange: function onChange(event) { return _this2.setState({ listHeight: parseInt(event.target.value, 10) || 1 }); }, value: listHeight }), React.createElement(LabeledInput, { disabled: useDynamicRowHeight, label: "Row height", name: "listRowHeight", onChange: function onChange(event) { return _this2.setState({ listRowHeight: parseInt(event.target.value, 10) || 1 }); }, value: listRowHeight }), React.createElement(LabeledInput, { label: "Overscan", name: "overscanRowCount", onChange: function onChange(event) { return _this2.setState({ overscanRowCount: parseInt(event.target.value, 10) || 0 }); }, value: overscanRowCount })), React.createElement("div", null, React.createElement(AutoSizer, { disableHeight: true }, function (_ref) { var width = _ref.width; return React.createElement(List, { ref: "List", className: styles.List, height: listHeight, overscanRowCount: overscanRowCount, noRowsRenderer: _this2._noRowsRenderer, rowCount: rowCount, rowHeight: useDynamicRowHeight ? _this2._getRowHeight : listRowHeight, rowRenderer: _this2._rowRenderer, scrollToIndex: scrollToIndex, width: width }); }))); } }, { key: "_getDatum", value: function _getDatum(index) { var list = this.context.list; return list.get(index % list.size); } }, { key: "_getRowHeight", value: function _getRowHeight(_ref2) { var index = _ref2.index; return this._getDatum(index).size; } }, { key: "_noRowsRenderer", value: function _noRowsRenderer() { return React.createElement("div", { className: styles.noRows }, "No rows"); } }, { key: "_onRowCountChange", value: function _onRowCountChange(event) { var rowCount = parseInt(event.target.value, 10) || 0; this.setState({ rowCount: rowCount }); } }, { key: "_onScrollToRowChange", value: function _onScrollToRowChange(event) { var rowCount = this.state.rowCount; var scrollToIndex = Math.min(rowCount - 1, parseInt(event.target.value, 10)); if (isNaN(scrollToIndex)) { scrollToIndex = undefined; } this.setState({ scrollToIndex: scrollToIndex }); } }, { key: "_rowRenderer", value: function _rowRenderer(_ref3) { var index = _ref3.index, isScrolling = _ref3.isScrolling, key = _ref3.key, style = _ref3.style; var _this$state2 = this.state, showScrollingPlaceholder = _this$state2.showScrollingPlaceholder, useDynamicRowHeight = _this$state2.useDynamicRowHeight; if (showScrollingPlaceholder && isScrolling) { return React.createElement("div", { className: clsx(styles.row, styles.isScrollingPlaceholder), key: key, style: style }, "Scrolling..."); } var datum = this._getDatum(index); var additionalContent; if (useDynamicRowHeight) { switch (datum.size) { case 75: additionalContent = React.createElement("div", null, "It is medium-sized."); break; case 100: additionalContent = React.createElement("div", null, "It is large-sized.", React.createElement("br", null), "It has a 3rd row."); break; } } return React.createElement("div", { className: styles.row, key: key, style: style }, React.createElement("div", { className: styles.letter, style: { backgroundColor: datum.color } }, datum.name.charAt(0)), React.createElement("div", null, React.createElement("div", { className: styles.name }, datum.name), React.createElement("div", { className: styles.index }, "This is row ", index), additionalContent), useDynamicRowHeight && React.createElement("span", { className: styles.height }, datum.size, "px")); } }]); return ListExample; }(React.PureComponent); _defineProperty(ListExample, "contextTypes", { list: PropTypes.instanceOf(Immutable.List).isRequired }); export { ListExample as default };dist/es/AutoSizer/AutoSizer.jest.js000064400000030312151676725770013320 0ustar00import _regeneratorRuntime from "@babel/runtime/regenerator"; import * as React from 'react'; import { findDOMNode } from 'react-dom'; import { render } from '../TestUtils'; import AutoSizer from './AutoSizer'; function DefaultChildComponent(_ref) { var height = _ref.height, width = _ref.width, foo = _ref.foo, bar = _ref.bar; return React.createElement("div", null, "width:".concat(width, ", height:").concat(height, ", foo:").concat(foo, ", bar:").concat(bar)); } describe('AutoSizer', function () { function getMarkup() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref2$bar = _ref2.bar, bar = _ref2$bar === void 0 ? 123 : _ref2$bar, _ref2$ChildComponent = _ref2.ChildComponent, ChildComponent = _ref2$ChildComponent === void 0 ? DefaultChildComponent : _ref2$ChildComponent, _ref2$className = _ref2.className, className = _ref2$className === void 0 ? undefined : _ref2$className, _ref2$defaultHeight = _ref2.defaultHeight, defaultHeight = _ref2$defaultHeight === void 0 ? undefined : _ref2$defaultHeight, _ref2$defaultWidth = _ref2.defaultWidth, defaultWidth = _ref2$defaultWidth === void 0 ? undefined : _ref2$defaultWidth, _ref2$disableHeight = _ref2.disableHeight, disableHeight = _ref2$disableHeight === void 0 ? false : _ref2$disableHeight, _ref2$disableWidth = _ref2.disableWidth, disableWidth = _ref2$disableWidth === void 0 ? false : _ref2$disableWidth, _ref2$foo = _ref2.foo, foo = _ref2$foo === void 0 ? 456 : _ref2$foo, _ref2$height = _ref2.height, height = _ref2$height === void 0 ? 100 : _ref2$height, onResize = _ref2.onResize, _ref2$paddingBottom = _ref2.paddingBottom, paddingBottom = _ref2$paddingBottom === void 0 ? 0 : _ref2$paddingBottom, _ref2$paddingLeft = _ref2.paddingLeft, paddingLeft = _ref2$paddingLeft === void 0 ? 0 : _ref2$paddingLeft, _ref2$paddingRight = _ref2.paddingRight, paddingRight = _ref2$paddingRight === void 0 ? 0 : _ref2$paddingRight, _ref2$paddingTop = _ref2.paddingTop, paddingTop = _ref2$paddingTop === void 0 ? 0 : _ref2$paddingTop, _ref2$style = _ref2.style, style = _ref2$style === void 0 ? undefined : _ref2$style, _ref2$width = _ref2.width, width = _ref2$width === void 0 ? 200 : _ref2$width; var wrapperStyle = { boxSizing: 'border-box', height: height, paddingBottom: paddingBottom, paddingLeft: paddingLeft, paddingRight: paddingRight, paddingTop: paddingTop, width: width }; mockOffsetSize(width, height); return React.createElement("div", { style: wrapperStyle }, React.createElement(AutoSizer, { className: className, defaultHeight: defaultHeight, defaultWidth: defaultWidth, disableHeight: disableHeight, disableWidth: disableWidth, onResize: onResize, style: style }, function (_ref3) { var height = _ref3.height, width = _ref3.width; return React.createElement(ChildComponent, { width: disableWidth ? undefined : width, height: disableHeight ? undefined : height, bar: bar, foo: foo }); })); } // AutoSizer uses offsetWidth and offsetHeight. // Jest runs in JSDom which doesn't support measurements APIs. function mockOffsetSize(width, height) { Object.defineProperty(HTMLElement.prototype, 'offsetHeight', { configurable: true, value: height }); Object.defineProperty(HTMLElement.prototype, 'offsetWidth', { configurable: true, value: width }); } it('should relay properties to ChildComponent or React child', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.textContent).toContain('foo:456'); expect(rendered.textContent).toContain('bar:123'); }); it('should set the correct initial width and height of ChildComponent or React child', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.textContent).toContain('height:100'); expect(rendered.textContent).toContain('width:200'); }); it('should account for padding when calculating the available width and height', function () { var rendered = findDOMNode(render(getMarkup({ paddingBottom: 10, paddingLeft: 4, paddingRight: 4, paddingTop: 15 }))); expect(rendered.textContent).toContain('height:75'); expect(rendered.textContent).toContain('width:192'); }); it('should not update :width if :disableWidth is true', function () { var rendered = findDOMNode(render(getMarkup({ disableWidth: true }))); expect(rendered.textContent).toContain('height:100'); expect(rendered.textContent).toContain('width:undefined'); }); it('should not update :height if :disableHeight is true', function () { var rendered = findDOMNode(render(getMarkup({ disableHeight: true }))); expect(rendered.textContent).toContain('height:undefined'); expect(rendered.textContent).toContain('width:200'); }); function simulateResize(_ref4) { var element, height, width, trigger; return _regeneratorRuntime.async(function simulateResize$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: element = _ref4.element, height = _ref4.height, width = _ref4.width; mockOffsetSize(width, height); // Trigger detectElementResize library by faking a scroll event // TestUtils Simulate doesn't work here in JSDom so we manually dispatch trigger = element.querySelector('.contract-trigger'); trigger.dispatchEvent(new Event('scroll')); // Allow requestAnimationFrame to be invoked before continuing _context.next = 6; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, 100); })); case 6: case "end": return _context.stop(); } } }); } it('should update :height after a resize event', function _callee(done) { var rendered; return _regeneratorRuntime.async(function _callee$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: rendered = findDOMNode(render(getMarkup({ height: 100, width: 200 }))); expect(rendered.textContent).toContain('height:100'); expect(rendered.textContent).toContain('width:200'); _context2.next = 5; return _regeneratorRuntime.awrap(simulateResize({ element: rendered, height: 400, width: 300 })); case 5: expect(rendered.textContent).toContain('height:400'); expect(rendered.textContent).toContain('width:300'); done(); case 8: case "end": return _context2.stop(); } } }); }); describe('onResize and (re)render', function () { it('should trigger when size changes', function _callee2(done) { var onResize, ChildComponent, rendered; return _regeneratorRuntime.async(function _callee2$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: onResize = jest.fn(); ChildComponent = jest.fn().mockImplementation(DefaultChildComponent); rendered = findDOMNode(render(getMarkup({ ChildComponent: ChildComponent, height: 100, onResize: onResize, width: 200 }))); ChildComponent.mockClear(); // TODO Improve initial check in version 10; see AutoSizer render() expect(onResize).toHaveBeenCalledTimes(1); _context3.next = 7; return _regeneratorRuntime.awrap(simulateResize({ element: rendered, height: 400, width: 300 })); case 7: expect(ChildComponent).toHaveBeenCalledTimes(1); expect(onResize).toHaveBeenCalledTimes(2); done(); case 10: case "end": return _context3.stop(); } } }); }); it('should only trigger when height changes for disableWidth == true', function _callee3(done) { var onResize, ChildComponent, rendered; return _regeneratorRuntime.async(function _callee3$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: onResize = jest.fn(); ChildComponent = jest.fn().mockImplementation(DefaultChildComponent); rendered = findDOMNode(render(getMarkup({ ChildComponent: ChildComponent, disableWidth: true, height: 100, onResize: onResize, width: 200 }))); ChildComponent.mockClear(); // TODO Improve initial check in version 10; see AutoSizer render() expect(onResize).toHaveBeenCalledTimes(1); _context4.next = 7; return _regeneratorRuntime.awrap(simulateResize({ element: rendered, height: 100, width: 300 })); case 7: expect(ChildComponent).toHaveBeenCalledTimes(0); expect(onResize).toHaveBeenCalledTimes(1); _context4.next = 11; return _regeneratorRuntime.awrap(simulateResize({ element: rendered, height: 200, width: 300 })); case 11: expect(ChildComponent).toHaveBeenCalledTimes(1); expect(onResize).toHaveBeenCalledTimes(2); done(); case 14: case "end": return _context4.stop(); } } }); }); it('should only trigger when width changes for disableHeight == true', function _callee4(done) { var onResize, ChildComponent, rendered; return _regeneratorRuntime.async(function _callee4$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: onResize = jest.fn(); ChildComponent = jest.fn().mockImplementation(DefaultChildComponent); rendered = findDOMNode(render(getMarkup({ ChildComponent: ChildComponent, disableHeight: true, height: 100, onResize: onResize, width: 200 }))); ChildComponent.mockClear(); // TODO Improve initial check in version 10; see AutoSizer render() expect(onResize).toHaveBeenCalledTimes(1); _context5.next = 7; return _regeneratorRuntime.awrap(simulateResize({ element: rendered, height: 200, width: 200 })); case 7: expect(ChildComponent).toHaveBeenCalledTimes(0); expect(onResize).toHaveBeenCalledTimes(1); _context5.next = 11; return _regeneratorRuntime.awrap(simulateResize({ element: rendered, height: 200, width: 300 })); case 11: expect(ChildComponent).toHaveBeenCalledTimes(1); expect(onResize).toHaveBeenCalledTimes(2); done(); case 14: case "end": return _context5.stop(); } } }); }); }); describe('className and style', function () { it('should use a custom :className if specified', function () { var rendered = findDOMNode(render(getMarkup({ className: 'foo' }))); expect(rendered.firstChild.className).toContain('foo'); }); it('should use a custom :style if specified', function () { var style = { backgroundColor: 'red' }; var rendered = findDOMNode(render(getMarkup({ style: style }))); expect(rendered.firstChild.style.backgroundColor).toEqual('red'); }); }); });dist/es/AutoSizer/index.js.flow000064400000000141151676725770012501 0ustar00// @flow export {default} from './AutoSizer'; export {default as AutoSizer} from './AutoSizer'; dist/es/AutoSizer/AutoSizer.js000064400000020205151676725770012354 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; var _class, _temp; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import * as React from 'react'; import createDetectElementResize from '../vendor/detectElementResize'; var AutoSizer = (_temp = _class = /*#__PURE__*/ function (_React$Component) { _inherits(AutoSizer, _React$Component); function AutoSizer() { var _getPrototypeOf2; var _this; _classCallCheck(this, AutoSizer); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(AutoSizer)).call.apply(_getPrototypeOf2, [this].concat(args))); _defineProperty(_assertThisInitialized(_this), "state", { height: _this.props.defaultHeight || 0, width: _this.props.defaultWidth || 0 }); _defineProperty(_assertThisInitialized(_this), "_parentNode", void 0); _defineProperty(_assertThisInitialized(_this), "_autoSizer", void 0); _defineProperty(_assertThisInitialized(_this), "_window", void 0); _defineProperty(_assertThisInitialized(_this), "_detectElementResize", void 0); _defineProperty(_assertThisInitialized(_this), "_onResize", function () { var _this$props = _this.props, disableHeight = _this$props.disableHeight, disableWidth = _this$props.disableWidth, onResize = _this$props.onResize; if (_this._parentNode) { // Guard against AutoSizer component being removed from the DOM immediately after being added. // This can result in invalid style values which can result in NaN values if we don't handle them. // See issue #150 for more context. var height = _this._parentNode.offsetHeight || 0; var width = _this._parentNode.offsetWidth || 0; var win = _this._window || window; var style = win.getComputedStyle(_this._parentNode) || {}; var paddingLeft = parseInt(style.paddingLeft, 10) || 0; var paddingRight = parseInt(style.paddingRight, 10) || 0; var paddingTop = parseInt(style.paddingTop, 10) || 0; var paddingBottom = parseInt(style.paddingBottom, 10) || 0; var newHeight = height - paddingTop - paddingBottom; var newWidth = width - paddingLeft - paddingRight; if (!disableHeight && _this.state.height !== newHeight || !disableWidth && _this.state.width !== newWidth) { _this.setState({ height: height - paddingTop - paddingBottom, width: width - paddingLeft - paddingRight }); onResize({ height: height, width: width }); } } }); _defineProperty(_assertThisInitialized(_this), "_setRef", function (autoSizer) { _this._autoSizer = autoSizer; }); return _this; } _createClass(AutoSizer, [{ key: "componentDidMount", value: function componentDidMount() { var nonce = this.props.nonce; if (this._autoSizer && this._autoSizer.parentNode && this._autoSizer.parentNode.ownerDocument && this._autoSizer.parentNode.ownerDocument.defaultView && this._autoSizer.parentNode instanceof this._autoSizer.parentNode.ownerDocument.defaultView.HTMLElement) { // Delay access of parentNode until mount. // This handles edge-cases where the component has already been unmounted before its ref has been set, // As well as libraries like react-lite which have a slightly different lifecycle. this._parentNode = this._autoSizer.parentNode; this._window = this._autoSizer.parentNode.ownerDocument.defaultView; // Defer requiring resize handler in order to support server-side rendering. // See issue #41 this._detectElementResize = createDetectElementResize(nonce, this._window); this._detectElementResize.addResizeListener(this._parentNode, this._onResize); this._onResize(); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this._detectElementResize && this._parentNode) { this._detectElementResize.removeResizeListener(this._parentNode, this._onResize); } } }, { key: "render", value: function render() { var _this$props2 = this.props, children = _this$props2.children, className = _this$props2.className, disableHeight = _this$props2.disableHeight, disableWidth = _this$props2.disableWidth, style = _this$props2.style; var _this$state = this.state, height = _this$state.height, width = _this$state.width; // Outer div should not force width/height since that may prevent containers from shrinking. // Inner component should overflow and use calculated width/height. // See issue #68 for more information. var outerStyle = { overflow: 'visible' }; var childParams = {}; if (!disableHeight) { outerStyle.height = 0; childParams.height = height; } if (!disableWidth) { outerStyle.width = 0; childParams.width = width; } /** * TODO: Avoid rendering children before the initial measurements have been collected. * At best this would just be wasting cycles. * Add this check into version 10 though as it could break too many ref callbacks in version 9. * Note that if default width/height props were provided this would still work with SSR. if ( height !== 0 && width !== 0 ) { child = children({ height, width }) } */ return React.createElement("div", { className: className, ref: this._setRef, style: _objectSpread({}, outerStyle, {}, style) }, children(childParams)); } }]); return AutoSizer; }(React.Component), _defineProperty(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { /** Function responsible for rendering children.*/ "children": PropTypes.func.isRequired, /** Optional custom CSS class name to attach to root AutoSizer element. */ "className": PropTypes.string, /** Default height to use for initial render; useful for SSR */ "defaultHeight": PropTypes.number, /** Default width to use for initial render; useful for SSR */ "defaultWidth": PropTypes.number, /** Disable dynamic :height property */ "disableHeight": PropTypes.bool.isRequired, /** Disable dynamic :width property */ "disableWidth": PropTypes.bool.isRequired, /** Nonce of the inlined stylesheet for Content Security Policy */ "nonce": PropTypes.string, /** Callback to be invoked on-resize */ "onResize": PropTypes.func.isRequired, /** Optional inline style */ "style": PropTypes.object }), _temp); _defineProperty(AutoSizer, "defaultProps", { onResize: function onResize() {}, disableHeight: false, disableWidth: false, style: {} }); export { AutoSizer as default }; import PropTypes from "prop-types";dist/es/AutoSizer/index.js000064400000000132151676725770011533 0ustar00export { default } from './AutoSizer'; export { default as AutoSizer } from './AutoSizer';dist/es/AutoSizer/AutoSizer.js.flow000064400000013034151676725770013324 0ustar00/** @flow */ import * as React from 'react'; import createDetectElementResize from '../vendor/detectElementResize'; type Size = { height: number, width: number, }; type Props = { /** Function responsible for rendering children.*/ children: Size => React.Element<*>, /** Optional custom CSS class name to attach to root AutoSizer element. */ className?: string, /** Default height to use for initial render; useful for SSR */ defaultHeight?: number, /** Default width to use for initial render; useful for SSR */ defaultWidth?: number, /** Disable dynamic :height property */ disableHeight: boolean, /** Disable dynamic :width property */ disableWidth: boolean, /** Nonce of the inlined stylesheet for Content Security Policy */ nonce?: string, /** Callback to be invoked on-resize */ onResize: Size => void, /** Optional inline style */ style: ?Object, }; type State = { height: number, width: number, }; type ResizeHandler = (element: HTMLElement, onResize: () => void) => void; type DetectElementResize = { addResizeListener: ResizeHandler, removeResizeListener: ResizeHandler, }; export default class AutoSizer extends React.Component<Props, State> { static defaultProps = { onResize: () => {}, disableHeight: false, disableWidth: false, style: {}, }; state = { height: this.props.defaultHeight || 0, width: this.props.defaultWidth || 0, }; _parentNode: ?HTMLElement; _autoSizer: ?HTMLElement; _window: ?any; // uses any instead of Window because Flow doesn't have window type _detectElementResize: DetectElementResize; componentDidMount() { const {nonce} = this.props; if ( this._autoSizer && this._autoSizer.parentNode && this._autoSizer.parentNode.ownerDocument && this._autoSizer.parentNode.ownerDocument.defaultView && this._autoSizer.parentNode instanceof this._autoSizer.parentNode.ownerDocument.defaultView.HTMLElement ) { // Delay access of parentNode until mount. // This handles edge-cases where the component has already been unmounted before its ref has been set, // As well as libraries like react-lite which have a slightly different lifecycle. this._parentNode = this._autoSizer.parentNode; this._window = this._autoSizer.parentNode.ownerDocument.defaultView; // Defer requiring resize handler in order to support server-side rendering. // See issue #41 this._detectElementResize = createDetectElementResize( nonce, this._window, ); this._detectElementResize.addResizeListener( this._parentNode, this._onResize, ); this._onResize(); } } componentWillUnmount() { if (this._detectElementResize && this._parentNode) { this._detectElementResize.removeResizeListener( this._parentNode, this._onResize, ); } } render() { const { children, className, disableHeight, disableWidth, style, } = this.props; const {height, width} = this.state; // Outer div should not force width/height since that may prevent containers from shrinking. // Inner component should overflow and use calculated width/height. // See issue #68 for more information. const outerStyle: Object = {overflow: 'visible'}; const childParams: Object = {}; if (!disableHeight) { outerStyle.height = 0; childParams.height = height; } if (!disableWidth) { outerStyle.width = 0; childParams.width = width; } /** * TODO: Avoid rendering children before the initial measurements have been collected. * At best this would just be wasting cycles. * Add this check into version 10 though as it could break too many ref callbacks in version 9. * Note that if default width/height props were provided this would still work with SSR. if ( height !== 0 && width !== 0 ) { child = children({ height, width }) } */ return ( <div className={className} ref={this._setRef} style={{ ...outerStyle, ...style, }}> {children(childParams)} </div> ); } _onResize = () => { const {disableHeight, disableWidth, onResize} = this.props; if (this._parentNode) { // Guard against AutoSizer component being removed from the DOM immediately after being added. // This can result in invalid style values which can result in NaN values if we don't handle them. // See issue #150 for more context. const height = this._parentNode.offsetHeight || 0; const width = this._parentNode.offsetWidth || 0; const win = this._window || window; const style = win.getComputedStyle(this._parentNode) || {}; const paddingLeft = parseInt(style.paddingLeft, 10) || 0; const paddingRight = parseInt(style.paddingRight, 10) || 0; const paddingTop = parseInt(style.paddingTop, 10) || 0; const paddingBottom = parseInt(style.paddingBottom, 10) || 0; const newHeight = height - paddingTop - paddingBottom; const newWidth = width - paddingLeft - paddingRight; if ( (!disableHeight && this.state.height !== newHeight) || (!disableWidth && this.state.width !== newWidth) ) { this.setState({ height: height - paddingTop - paddingBottom, width: width - paddingLeft - paddingRight, }); onResize({height, width}); } } }; _setRef = (autoSizer: ?HTMLElement) => { this._autoSizer = autoSizer; }; } dist/es/AutoSizer/AutoSizer.example.js000064400000010733151676725770014013 0ustar00import _extends from "@babel/runtime/helpers/extends"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; var _class, _temp; import { List as ImmutableList } from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import AutoSizer from './AutoSizer'; import List from '../List'; import styles from './AutoSizer.example.css'; var AutoSizerExample = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { _inherits(AutoSizerExample, _React$PureComponent); function AutoSizerExample() { var _getPrototypeOf2; var _this; _classCallCheck(this, AutoSizerExample); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(AutoSizerExample)).call.apply(_getPrototypeOf2, [this].concat(args))); _defineProperty(_assertThisInitialized(_this), "state", { hideDescription: false }); _defineProperty(_assertThisInitialized(_this), "_rowRenderer", function (_ref) { var index = _ref.index, key = _ref.key, style = _ref.style; var list = _this.context.list; var row = list.get(index); return React.createElement("div", { key: key, className: styles.row, style: style }, row.name); }); return _this; } _createClass(AutoSizerExample, [{ key: "render", value: function render() { var _this2 = this; var list = this.context.list; var hideDescription = this.state.hideDescription; return React.createElement(ContentBox, _extends({}, this.props, { style: { height: 400 } }), React.createElement(ContentBoxHeader, { text: "AutoSizer", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/AutoSizer/AutoSizer.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/AutoSizer.md" }), React.createElement(ContentBoxParagraph, null, React.createElement("label", { className: styles.checkboxLabel }, React.createElement("input", { "aria-label": "Hide description (to show resize)?", className: styles.checkbox, type: "checkbox", checked: hideDescription, onChange: function onChange(event) { return _this2.setState({ hideDescription: event.target.checked }); } }), "Hide description (to show resize)?")), !hideDescription && React.createElement(ContentBoxParagraph, null, "This component decorates ", React.createElement("code", null, "List"), ", ", React.createElement("code", null, "Table"), ", or any other component and automatically manages its width and height. It uses Sebastian Decima's", ' ', React.createElement("a", { href: "https://github.com/sdecima/javascript-detect-element-resize", target: "_blank" }, "element resize event"), ' ', "to determine the appropriate size. In this example", ' ', React.createElement("code", null, "AutoSizer"), " grows to fill the remaining width and height of this flex column."), React.createElement("div", { className: styles.AutoSizerWrapper }, React.createElement(AutoSizer, null, function (_ref2) { var width = _ref2.width, height = _ref2.height; return React.createElement(List, { className: styles.List, height: height, rowCount: list.size, rowHeight: 30, rowRenderer: _this2._rowRenderer, width: width }); }))); } }]); return AutoSizerExample; }(React.PureComponent), _defineProperty(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : {}), _temp); _defineProperty(AutoSizerExample, "contextTypes", { list: PropTypes.instanceOf(ImmutableList).isRequired }); export { AutoSizerExample as default }; import { bpfrpt_proptype_RowRendererParams } from "../List";dist/es/AutoSizer/AutoSizer.ssr.js000064400000001201151676725770013155 0ustar00/** * @jest-environment node */ import * as React from 'react'; import * as ReactDOMServer from 'react-dom/server'; import AutoSizer from './AutoSizer'; test('should render content with default widths and heights initially', function () { var rendered = ReactDOMServer.renderToString(React.createElement(AutoSizer, { defaultHeight: 100, defaultWidth: 200 }, function (_ref) { var height = _ref.height, width = _ref.width; return React.createElement("div", null, "height:".concat(height, ";width:").concat(width)); })); expect(rendered).toContain('height:100'); expect(rendered).toContain('width:200'); });dist/es/Grid/defaultOverscanIndicesGetter.jest.js000064400000004652151676725770016142 0ustar00import overscanIndicesGetter, { SCROLL_DIRECTION_BACKWARD, SCROLL_DIRECTION_FORWARD } from './defaultOverscanIndicesGetter'; describe('overscanIndicesGetter', function () { function testHelper(_ref) { var cellCount = _ref.cellCount, startIndex = _ref.startIndex, stopIndex = _ref.stopIndex, overscanCellsCount = _ref.overscanCellsCount, scrollDirection = _ref.scrollDirection; return overscanIndicesGetter({ cellCount: cellCount, overscanCellsCount: overscanCellsCount, scrollDirection: scrollDirection, startIndex: startIndex, stopIndex: stopIndex }); } it('should not overscan if :overscanCellsCount is 0', function () { expect(testHelper({ cellCount: 100, startIndex: 10, stopIndex: 20, overscanCellsCount: 0, scrollDirection: SCROLL_DIRECTION_BACKWARD })).toEqual({ overscanStartIndex: 10, overscanStopIndex: 20 }); expect(testHelper({ cellCount: 100, startIndex: 10, stopIndex: 20, overscanCellsCount: 0, scrollDirection: SCROLL_DIRECTION_FORWARD })).toEqual({ overscanStartIndex: 10, overscanStopIndex: 20 }); }); it('should overscan forward', function () { expect(testHelper({ cellCount: 100, startIndex: 20, stopIndex: 30, overscanCellsCount: 10, scrollDirection: SCROLL_DIRECTION_FORWARD })).toEqual({ overscanStartIndex: 20, overscanStopIndex: 40 }); }); it('should overscan backward', function () { expect(testHelper({ cellCount: 100, startIndex: 20, stopIndex: 30, overscanCellsCount: 10, scrollDirection: SCROLL_DIRECTION_BACKWARD })).toEqual({ overscanStartIndex: 10, overscanStopIndex: 30 }); }); it('should not overscan beyond the start of the list', function () { expect(testHelper({ cellCount: 100, startIndex: 5, stopIndex: 15, overscanCellsCount: 10, scrollDirection: SCROLL_DIRECTION_BACKWARD })).toEqual({ overscanStartIndex: 0, overscanStopIndex: 15 }); }); it('should not overscan beyond the end of the list', function () { expect(testHelper({ cellCount: 25, startIndex: 10, stopIndex: 20, overscanCellsCount: 10, scrollDirection: SCROLL_DIRECTION_FORWARD })).toEqual({ overscanStartIndex: 10, overscanStopIndex: 24 }); }); });dist/es/Grid/types.js000064400000014131151676725770010534 0ustar00import * as React from 'react'; import ScalingCellSizeAndPositionManager from './utils/ScalingCellSizeAndPositionManager'; var bpfrpt_proptype_CellPosition = process.env.NODE_ENV === 'production' ? null : { "columnIndex": PropTypes.number.isRequired, "rowIndex": PropTypes.number.isRequired }; var bpfrpt_proptype_CellRendererParams = process.env.NODE_ENV === 'production' ? null : { "columnIndex": PropTypes.number.isRequired, "isScrolling": PropTypes.bool.isRequired, "isVisible": PropTypes.bool.isRequired, "key": PropTypes.string.isRequired, "parent": PropTypes.object.isRequired, "rowIndex": PropTypes.number.isRequired, "style": PropTypes.object.isRequired }; var bpfrpt_proptype_CellRenderer = process.env.NODE_ENV === 'production' ? null : PropTypes.func; var bpfrpt_proptype_CellCache = process.env.NODE_ENV === 'production' ? null : PropTypes.objectOf(PropTypes.node.isRequired); var bpfrpt_proptype_StyleCache = process.env.NODE_ENV === 'production' ? null : PropTypes.objectOf(PropTypes.object.isRequired); var bpfrpt_proptype_CellRangeRendererParams = process.env.NODE_ENV === 'production' ? null : { "cellCache": PropTypes.objectOf(PropTypes.node.isRequired).isRequired, "cellRenderer": PropTypes.func.isRequired, "columnSizeAndPositionManager": function columnSizeAndPositionManager() { return (typeof ScalingCellSizeAndPositionManager === "function" ? PropTypes.instanceOf(ScalingCellSizeAndPositionManager).isRequired : PropTypes.any.isRequired).apply(this, arguments); }, "columnStartIndex": PropTypes.number.isRequired, "columnStopIndex": PropTypes.number.isRequired, "deferredMeasurementCache": PropTypes.object, "horizontalOffsetAdjustment": PropTypes.number.isRequired, "isScrolling": PropTypes.bool.isRequired, "isScrollingOptOut": PropTypes.bool.isRequired, "parent": PropTypes.object.isRequired, "rowSizeAndPositionManager": function rowSizeAndPositionManager() { return (typeof ScalingCellSizeAndPositionManager === "function" ? PropTypes.instanceOf(ScalingCellSizeAndPositionManager).isRequired : PropTypes.any.isRequired).apply(this, arguments); }, "rowStartIndex": PropTypes.number.isRequired, "rowStopIndex": PropTypes.number.isRequired, "scrollLeft": PropTypes.number.isRequired, "scrollTop": PropTypes.number.isRequired, "styleCache": PropTypes.objectOf(PropTypes.object.isRequired).isRequired, "verticalOffsetAdjustment": PropTypes.number.isRequired, "visibleColumnIndices": PropTypes.object.isRequired, "visibleRowIndices": PropTypes.object.isRequired }; var bpfrpt_proptype_CellRangeRenderer = process.env.NODE_ENV === 'production' ? null : PropTypes.func; var bpfrpt_proptype_CellSizeGetter = process.env.NODE_ENV === 'production' ? null : PropTypes.func; var bpfrpt_proptype_CellSize = process.env.NODE_ENV === 'production' ? null : PropTypes.oneOfType([PropTypes.func, PropTypes.number]); var bpfrpt_proptype_NoContentRenderer = process.env.NODE_ENV === 'production' ? null : PropTypes.func; var bpfrpt_proptype_Scroll = process.env.NODE_ENV === 'production' ? null : { "clientHeight": PropTypes.number.isRequired, "clientWidth": PropTypes.number.isRequired, "scrollHeight": PropTypes.number.isRequired, "scrollLeft": PropTypes.number.isRequired, "scrollTop": PropTypes.number.isRequired, "scrollWidth": PropTypes.number.isRequired }; var bpfrpt_proptype_ScrollbarPresenceChange = process.env.NODE_ENV === 'production' ? null : { "horizontal": PropTypes.bool.isRequired, "vertical": PropTypes.bool.isRequired, "size": PropTypes.number.isRequired }; var bpfrpt_proptype_RenderedSection = process.env.NODE_ENV === 'production' ? null : { "columnOverscanStartIndex": PropTypes.number.isRequired, "columnOverscanStopIndex": PropTypes.number.isRequired, "columnStartIndex": PropTypes.number.isRequired, "columnStopIndex": PropTypes.number.isRequired, "rowOverscanStartIndex": PropTypes.number.isRequired, "rowOverscanStopIndex": PropTypes.number.isRequired, "rowStartIndex": PropTypes.number.isRequired, "rowStopIndex": PropTypes.number.isRequired }; var bpfrpt_proptype_OverscanIndicesGetterParams = process.env.NODE_ENV === 'production' ? null : { // One of SCROLL_DIRECTION_HORIZONTAL or SCROLL_DIRECTION_VERTICAL "direction": PropTypes.oneOf(["horizontal", "vertical"]).isRequired, // One of SCROLL_DIRECTION_BACKWARD or SCROLL_DIRECTION_FORWARD "scrollDirection": PropTypes.oneOf([-1, 1]).isRequired, // Number of rows or columns in the current axis "cellCount": PropTypes.number.isRequired, // Maximum number of cells to over-render in either direction "overscanCellsCount": PropTypes.number.isRequired, // Begin of range of visible cells "startIndex": PropTypes.number.isRequired, // End of range of visible cells "stopIndex": PropTypes.number.isRequired }; var bpfrpt_proptype_OverscanIndices = process.env.NODE_ENV === 'production' ? null : { "overscanStartIndex": PropTypes.number.isRequired, "overscanStopIndex": PropTypes.number.isRequired }; var bpfrpt_proptype_OverscanIndicesGetter = process.env.NODE_ENV === 'production' ? null : PropTypes.func; var bpfrpt_proptype_Alignment = process.env.NODE_ENV === 'production' ? null : PropTypes.oneOf(["auto", "end", "start", "center"]); var bpfrpt_proptype_VisibleCellRange = process.env.NODE_ENV === 'production' ? null : { "start": PropTypes.number, "stop": PropTypes.number }; import PropTypes from "prop-types"; export { bpfrpt_proptype_CellPosition }; export { bpfrpt_proptype_CellRendererParams }; export { bpfrpt_proptype_CellRenderer }; export { bpfrpt_proptype_CellCache }; export { bpfrpt_proptype_StyleCache }; export { bpfrpt_proptype_CellRangeRendererParams }; export { bpfrpt_proptype_CellRangeRenderer }; export { bpfrpt_proptype_CellSizeGetter }; export { bpfrpt_proptype_CellSize }; export { bpfrpt_proptype_NoContentRenderer }; export { bpfrpt_proptype_Scroll }; export { bpfrpt_proptype_ScrollbarPresenceChange }; export { bpfrpt_proptype_RenderedSection }; export { bpfrpt_proptype_OverscanIndicesGetterParams }; export { bpfrpt_proptype_OverscanIndices }; export { bpfrpt_proptype_OverscanIndicesGetter }; export { bpfrpt_proptype_Alignment }; export { bpfrpt_proptype_VisibleCellRange };dist/es/Grid/Grid.example.js000064400000030336151676725770011714 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import Immutable from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import { LabeledInput, InputRow } from '../demo/LabeledInput'; import AutoSizer from '../AutoSizer'; import Grid from './Grid'; import clsx from 'clsx'; import styles from './Grid.example.css'; var GridExample = /*#__PURE__*/ function (_React$PureComponent) { _inherits(GridExample, _React$PureComponent); function GridExample(props, context) { var _this; _classCallCheck(this, GridExample); _this = _possibleConstructorReturn(this, _getPrototypeOf(GridExample).call(this, props, context)); _this.state = { columnCount: 1000, height: 300, overscanColumnCount: 0, overscanRowCount: 10, rowHeight: 40, rowCount: 1000, scrollToColumn: undefined, scrollToRow: undefined, useDynamicRowHeight: false }; _this._cellRenderer = _this._cellRenderer.bind(_assertThisInitialized(_this)); _this._getColumnWidth = _this._getColumnWidth.bind(_assertThisInitialized(_this)); _this._getRowClassName = _this._getRowClassName.bind(_assertThisInitialized(_this)); _this._getRowHeight = _this._getRowHeight.bind(_assertThisInitialized(_this)); _this._noContentRenderer = _this._noContentRenderer.bind(_assertThisInitialized(_this)); _this._onColumnCountChange = _this._onColumnCountChange.bind(_assertThisInitialized(_this)); _this._onRowCountChange = _this._onRowCountChange.bind(_assertThisInitialized(_this)); _this._onScrollToColumnChange = _this._onScrollToColumnChange.bind(_assertThisInitialized(_this)); _this._onScrollToRowChange = _this._onScrollToRowChange.bind(_assertThisInitialized(_this)); _this._renderBodyCell = _this._renderBodyCell.bind(_assertThisInitialized(_this)); _this._renderLeftSideCell = _this._renderLeftSideCell.bind(_assertThisInitialized(_this)); return _this; } _createClass(GridExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, columnCount = _this$state.columnCount, height = _this$state.height, overscanColumnCount = _this$state.overscanColumnCount, overscanRowCount = _this$state.overscanRowCount, rowHeight = _this$state.rowHeight, rowCount = _this$state.rowCount, scrollToColumn = _this$state.scrollToColumn, scrollToRow = _this$state.scrollToRow, useDynamicRowHeight = _this$state.useDynamicRowHeight; return React.createElement(ContentBox, null, React.createElement(ContentBoxHeader, { text: "Grid", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/Grid/Grid.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/Grid.md" }), React.createElement(ContentBoxParagraph, null, "Renders tabular data with virtualization along the vertical and horizontal axes. Row heights and column widths must be calculated ahead of time and specified as a fixed size or returned by a getter function."), React.createElement(ContentBoxParagraph, null, React.createElement("label", { className: styles.checkboxLabel }, React.createElement("input", { "aria-label": "Use dynamic row height?", className: styles.checkbox, type: "checkbox", value: useDynamicRowHeight, onChange: function onChange(event) { return _this2._updateUseDynamicRowHeights(event.target.checked); } }), "Use dynamic row height?")), React.createElement(InputRow, null, React.createElement(LabeledInput, { label: "Num columns", name: "columnCount", onChange: this._onColumnCountChange, value: columnCount }), React.createElement(LabeledInput, { label: "Num rows", name: "rowCount", onChange: this._onRowCountChange, value: rowCount }), React.createElement(LabeledInput, { label: "Scroll to column", name: "onScrollToColumn", placeholder: "Index...", onChange: this._onScrollToColumnChange, value: scrollToColumn || '' }), React.createElement(LabeledInput, { label: "Scroll to row", name: "onScrollToRow", placeholder: "Index...", onChange: this._onScrollToRowChange, value: scrollToRow || '' }), React.createElement(LabeledInput, { label: "List height", name: "height", onChange: function onChange(event) { return _this2.setState({ height: parseInt(event.target.value, 10) || 1 }); }, value: height }), React.createElement(LabeledInput, { disabled: useDynamicRowHeight, label: "Row height", name: "rowHeight", onChange: function onChange(event) { return _this2.setState({ rowHeight: parseInt(event.target.value, 10) || 1 }); }, value: rowHeight }), React.createElement(LabeledInput, { label: "Overscan columns", name: "overscanColumnCount", onChange: function onChange(event) { return _this2.setState({ overscanColumnCount: parseInt(event.target.value, 10) || 0 }); }, value: overscanColumnCount }), React.createElement(LabeledInput, { label: "Overscan rows", name: "overscanRowCount", onChange: function onChange(event) { return _this2.setState({ overscanRowCount: parseInt(event.target.value, 10) || 0 }); }, value: overscanRowCount })), React.createElement(AutoSizer, { disableHeight: true }, function (_ref) { var width = _ref.width; return React.createElement(Grid, { cellRenderer: _this2._cellRenderer, className: styles.BodyGrid, columnWidth: _this2._getColumnWidth, columnCount: columnCount, height: height, noContentRenderer: _this2._noContentRenderer, overscanColumnCount: overscanColumnCount, overscanRowCount: overscanRowCount, rowHeight: useDynamicRowHeight ? _this2._getRowHeight : rowHeight, rowCount: rowCount, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow, width: width }); })); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref2) { var columnIndex = _ref2.columnIndex, key = _ref2.key, rowIndex = _ref2.rowIndex, style = _ref2.style; if (columnIndex === 0) { return this._renderLeftSideCell({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } else { return this._renderBodyCell({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } } }, { key: "_getColumnWidth", value: function _getColumnWidth(_ref3) { var index = _ref3.index; switch (index) { case 0: return 50; case 1: return 100; case 2: return 300; default: return 80; } } }, { key: "_getDatum", value: function _getDatum(index) { var list = this.context.list; return list.get(index % list.size); } }, { key: "_getRowClassName", value: function _getRowClassName(row) { return row % 2 === 0 ? styles.evenRow : styles.oddRow; } }, { key: "_getRowHeight", value: function _getRowHeight(_ref4) { var index = _ref4.index; return this._getDatum(index).size; } }, { key: "_noContentRenderer", value: function _noContentRenderer() { return React.createElement("div", { className: styles.noCells }, "No cells"); } }, { key: "_renderBodyCell", value: function _renderBodyCell(_ref5) { var columnIndex = _ref5.columnIndex, key = _ref5.key, rowIndex = _ref5.rowIndex, style = _ref5.style; var rowClass = this._getRowClassName(rowIndex); var datum = this._getDatum(rowIndex); var content; switch (columnIndex) { case 1: content = datum.name; break; case 2: content = datum.random; break; default: content = "r:".concat(rowIndex, ", c:").concat(columnIndex); break; } var classNames = clsx(rowClass, styles.cell, _defineProperty({}, styles.centeredCell, columnIndex > 2)); return React.createElement("div", { className: classNames, key: key, style: style }, content); } }, { key: "_renderLeftSideCell", value: function _renderLeftSideCell(_ref6) { var key = _ref6.key, rowIndex = _ref6.rowIndex, style = _ref6.style; var datum = this._getDatum(rowIndex); var classNames = clsx(styles.cell, styles.letterCell); // Don't modify styles. // These are frozen by React now (as of 16.0.0). // Since Grid caches and re-uses them, they aren't safe to modify. style = _objectSpread({}, style, { backgroundColor: datum.color }); return React.createElement("div", { className: classNames, key: key, style: style }, datum.name.charAt(0)); } }, { key: "_updateUseDynamicRowHeights", value: function _updateUseDynamicRowHeights(value) { this.setState({ useDynamicRowHeight: value }); } }, { key: "_onColumnCountChange", value: function _onColumnCountChange(event) { var columnCount = parseInt(event.target.value, 10) || 0; this.setState({ columnCount: columnCount }); } }, { key: "_onRowCountChange", value: function _onRowCountChange(event) { var rowCount = parseInt(event.target.value, 10) || 0; this.setState({ rowCount: rowCount }); } }, { key: "_onScrollToColumnChange", value: function _onScrollToColumnChange(event) { var columnCount = this.state.columnCount; var scrollToColumn = Math.min(columnCount - 1, parseInt(event.target.value, 10)); if (isNaN(scrollToColumn)) { scrollToColumn = undefined; } this.setState({ scrollToColumn: scrollToColumn }); } }, { key: "_onScrollToRowChange", value: function _onScrollToRowChange(event) { var rowCount = this.state.rowCount; var scrollToRow = Math.min(rowCount - 1, parseInt(event.target.value, 10)); if (isNaN(scrollToRow)) { scrollToRow = undefined; } this.setState({ scrollToRow: scrollToRow }); } }]); return GridExample; }(React.PureComponent); _defineProperty(GridExample, "contextTypes", { list: PropTypes.instanceOf(Immutable.List).isRequired }); export { GridExample as default };dist/es/Grid/defaultCellRangeRenderer.js000064400000013337151676725770014267 0ustar00/** * Default implementation of cellRangeRenderer used by Grid. * This renderer supports cell-caching while the user is scrolling. */ export default function defaultCellRangeRenderer(_ref) { var cellCache = _ref.cellCache, cellRenderer = _ref.cellRenderer, columnSizeAndPositionManager = _ref.columnSizeAndPositionManager, columnStartIndex = _ref.columnStartIndex, columnStopIndex = _ref.columnStopIndex, deferredMeasurementCache = _ref.deferredMeasurementCache, horizontalOffsetAdjustment = _ref.horizontalOffsetAdjustment, isScrolling = _ref.isScrolling, isScrollingOptOut = _ref.isScrollingOptOut, parent = _ref.parent, rowSizeAndPositionManager = _ref.rowSizeAndPositionManager, rowStartIndex = _ref.rowStartIndex, rowStopIndex = _ref.rowStopIndex, styleCache = _ref.styleCache, verticalOffsetAdjustment = _ref.verticalOffsetAdjustment, visibleColumnIndices = _ref.visibleColumnIndices, visibleRowIndices = _ref.visibleRowIndices; var renderedCells = []; // Browsers have native size limits for elements (eg Chrome 33M pixels, IE 1.5M pixes). // User cannot scroll beyond these size limitations. // In order to work around this, ScalingCellSizeAndPositionManager compresses offsets. // We should never cache styles for compressed offsets though as this can lead to bugs. // See issue #576 for more. var areOffsetsAdjusted = columnSizeAndPositionManager.areOffsetsAdjusted() || rowSizeAndPositionManager.areOffsetsAdjusted(); var canCacheStyle = !isScrolling && !areOffsetsAdjusted; for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) { var rowDatum = rowSizeAndPositionManager.getSizeAndPositionOfCell(rowIndex); for (var columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) { var columnDatum = columnSizeAndPositionManager.getSizeAndPositionOfCell(columnIndex); var isVisible = columnIndex >= visibleColumnIndices.start && columnIndex <= visibleColumnIndices.stop && rowIndex >= visibleRowIndices.start && rowIndex <= visibleRowIndices.stop; var key = "".concat(rowIndex, "-").concat(columnIndex); var style = void 0; // Cache style objects so shallow-compare doesn't re-render unnecessarily. if (canCacheStyle && styleCache[key]) { style = styleCache[key]; } else { // In deferred mode, cells will be initially rendered before we know their size. // Don't interfere with CellMeasurer's measurements by setting an invalid size. if (deferredMeasurementCache && !deferredMeasurementCache.has(rowIndex, columnIndex)) { // Position not-yet-measured cells at top/left 0,0, // And give them width/height of 'auto' so they can grow larger than the parent Grid if necessary. // Positioning them further to the right/bottom influences their measured size. style = { height: 'auto', left: 0, position: 'absolute', top: 0, width: 'auto' }; } else { style = { height: rowDatum.size, left: columnDatum.offset + horizontalOffsetAdjustment, position: 'absolute', top: rowDatum.offset + verticalOffsetAdjustment, width: columnDatum.size }; styleCache[key] = style; } } var cellRendererParams = { columnIndex: columnIndex, isScrolling: isScrolling, isVisible: isVisible, key: key, parent: parent, rowIndex: rowIndex, style: style }; var renderedCell = void 0; // Avoid re-creating cells while scrolling. // This can lead to the same cell being created many times and can cause performance issues for "heavy" cells. // If a scroll is in progress- cache and reuse cells. // This cache will be thrown away once scrolling completes. // However if we are scaling scroll positions and sizes, we should also avoid caching. // This is because the offset changes slightly as scroll position changes and caching leads to stale values. // For more info refer to issue #395 // // If isScrollingOptOut is specified, we always cache cells. // For more info refer to issue #1028 if ((isScrollingOptOut || isScrolling) && !horizontalOffsetAdjustment && !verticalOffsetAdjustment) { if (!cellCache[key]) { cellCache[key] = cellRenderer(cellRendererParams); } renderedCell = cellCache[key]; // If the user is no longer scrolling, don't cache cells. // This makes dynamic cell content difficult for users and would also lead to a heavier memory footprint. } else { renderedCell = cellRenderer(cellRendererParams); } if (renderedCell == null || renderedCell === false) { continue; } if (process.env.NODE_ENV !== 'production') { warnAboutMissingStyle(parent, renderedCell); } renderedCells.push(renderedCell); } } return renderedCells; } function warnAboutMissingStyle(parent, renderedCell) { if (process.env.NODE_ENV !== 'production') { if (renderedCell) { // If the direct child is a CellMeasurer, then we should check its child // See issue #611 if (renderedCell.type && renderedCell.type.__internalCellMeasurerFlag) { renderedCell = renderedCell.props.children; } if (renderedCell && renderedCell.props && renderedCell.props.style === undefined && parent.__warnedAboutMissingStyle !== true) { parent.__warnedAboutMissingStyle = true; console.warn('Rendered cell should include style property for positioning.'); } } } } import { bpfrpt_proptype_CellRangeRendererParams } from "./types";dist/es/Grid/Grid.js000064400000200300151676725770010250 0ustar00import _extends from "@babel/runtime/helpers/extends"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; var _class, _temp; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import * as React from 'react'; import clsx from 'clsx'; import calculateSizeAndPositionDataAndUpdateScrollOffset from './utils/calculateSizeAndPositionDataAndUpdateScrollOffset'; import ScalingCellSizeAndPositionManager from './utils/ScalingCellSizeAndPositionManager'; import createCallbackMemoizer from '../utils/createCallbackMemoizer'; import defaultOverscanIndicesGetter, { SCROLL_DIRECTION_BACKWARD, SCROLL_DIRECTION_FORWARD } from './defaultOverscanIndicesGetter'; import updateScrollIndexHelper from './utils/updateScrollIndexHelper'; import defaultCellRangeRenderer from './defaultCellRangeRenderer'; import scrollbarSize from 'dom-helpers/scrollbarSize'; import { polyfill } from 'react-lifecycles-compat'; import { requestAnimationTimeout, cancelAnimationTimeout } from '../utils/requestAnimationTimeout'; /** * Specifies the number of milliseconds during which to disable pointer events while a scroll is in progress. * This improves performance and makes scrolling smoother. */ export var DEFAULT_SCROLLING_RESET_TIME_INTERVAL = 150; /** * Controls whether the Grid updates the DOM element's scrollLeft/scrollTop based on the current state or just observes it. * This prevents Grid from interrupting mouse-wheel animations (see issue #2). */ var SCROLL_POSITION_CHANGE_REASONS = { OBSERVED: 'observed', REQUESTED: 'requested' }; var renderNull = function renderNull() { return null; }; /** * Renders tabular data with virtualization along the vertical and horizontal axes. * Row heights and column widths must be known ahead of time and specified as properties. */ var Grid = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { _inherits(Grid, _React$PureComponent); // Invokes onSectionRendered callback only when start/stop row or column indices change function Grid(props) { var _this; _classCallCheck(this, Grid); _this = _possibleConstructorReturn(this, _getPrototypeOf(Grid).call(this, props)); _defineProperty(_assertThisInitialized(_this), "_onGridRenderedMemoizer", createCallbackMemoizer()); _defineProperty(_assertThisInitialized(_this), "_onScrollMemoizer", createCallbackMemoizer(false)); _defineProperty(_assertThisInitialized(_this), "_deferredInvalidateColumnIndex", null); _defineProperty(_assertThisInitialized(_this), "_deferredInvalidateRowIndex", null); _defineProperty(_assertThisInitialized(_this), "_recomputeScrollLeftFlag", false); _defineProperty(_assertThisInitialized(_this), "_recomputeScrollTopFlag", false); _defineProperty(_assertThisInitialized(_this), "_horizontalScrollBarSize", 0); _defineProperty(_assertThisInitialized(_this), "_verticalScrollBarSize", 0); _defineProperty(_assertThisInitialized(_this), "_scrollbarPresenceChanged", false); _defineProperty(_assertThisInitialized(_this), "_scrollingContainer", void 0); _defineProperty(_assertThisInitialized(_this), "_childrenToDisplay", void 0); _defineProperty(_assertThisInitialized(_this), "_columnStartIndex", void 0); _defineProperty(_assertThisInitialized(_this), "_columnStopIndex", void 0); _defineProperty(_assertThisInitialized(_this), "_rowStartIndex", void 0); _defineProperty(_assertThisInitialized(_this), "_rowStopIndex", void 0); _defineProperty(_assertThisInitialized(_this), "_renderedColumnStartIndex", 0); _defineProperty(_assertThisInitialized(_this), "_renderedColumnStopIndex", 0); _defineProperty(_assertThisInitialized(_this), "_renderedRowStartIndex", 0); _defineProperty(_assertThisInitialized(_this), "_renderedRowStopIndex", 0); _defineProperty(_assertThisInitialized(_this), "_initialScrollTop", void 0); _defineProperty(_assertThisInitialized(_this), "_initialScrollLeft", void 0); _defineProperty(_assertThisInitialized(_this), "_disablePointerEventsTimeoutId", void 0); _defineProperty(_assertThisInitialized(_this), "_styleCache", {}); _defineProperty(_assertThisInitialized(_this), "_cellCache", {}); _defineProperty(_assertThisInitialized(_this), "_debounceScrollEndedCallback", function () { _this._disablePointerEventsTimeoutId = null; // isScrolling is used to determine if we reset styleCache _this.setState({ isScrolling: false, needToResetStyleCache: false }); }); _defineProperty(_assertThisInitialized(_this), "_invokeOnGridRenderedHelper", function () { var onSectionRendered = _this.props.onSectionRendered; _this._onGridRenderedMemoizer({ callback: onSectionRendered, indices: { columnOverscanStartIndex: _this._columnStartIndex, columnOverscanStopIndex: _this._columnStopIndex, columnStartIndex: _this._renderedColumnStartIndex, columnStopIndex: _this._renderedColumnStopIndex, rowOverscanStartIndex: _this._rowStartIndex, rowOverscanStopIndex: _this._rowStopIndex, rowStartIndex: _this._renderedRowStartIndex, rowStopIndex: _this._renderedRowStopIndex } }); }); _defineProperty(_assertThisInitialized(_this), "_setScrollingContainerRef", function (ref) { _this._scrollingContainer = ref; }); _defineProperty(_assertThisInitialized(_this), "_onScroll", function (event) { // In certain edge-cases React dispatches an onScroll event with an invalid target.scrollLeft / target.scrollTop. // This invalid event can be detected by comparing event.target to this component's scrollable DOM element. // See issue #404 for more information. if (event.target === _this._scrollingContainer) { _this.handleScrollEvent(event.target); } }); var columnSizeAndPositionManager = new ScalingCellSizeAndPositionManager({ cellCount: props.columnCount, cellSizeGetter: function cellSizeGetter(params) { return Grid._wrapSizeGetter(props.columnWidth)(params); }, estimatedCellSize: Grid._getEstimatedColumnSize(props) }); var rowSizeAndPositionManager = new ScalingCellSizeAndPositionManager({ cellCount: props.rowCount, cellSizeGetter: function cellSizeGetter(params) { return Grid._wrapSizeGetter(props.rowHeight)(params); }, estimatedCellSize: Grid._getEstimatedRowSize(props) }); _this.state = { instanceProps: { columnSizeAndPositionManager: columnSizeAndPositionManager, rowSizeAndPositionManager: rowSizeAndPositionManager, prevColumnWidth: props.columnWidth, prevRowHeight: props.rowHeight, prevColumnCount: props.columnCount, prevRowCount: props.rowCount, prevIsScrolling: props.isScrolling === true, prevScrollToColumn: props.scrollToColumn, prevScrollToRow: props.scrollToRow, scrollbarSize: 0, scrollbarSizeMeasured: false }, isScrolling: false, scrollDirectionHorizontal: SCROLL_DIRECTION_FORWARD, scrollDirectionVertical: SCROLL_DIRECTION_FORWARD, scrollLeft: 0, scrollTop: 0, scrollPositionChangeReason: null, needToResetStyleCache: false }; if (props.scrollToRow > 0) { _this._initialScrollTop = _this._getCalculatedScrollTop(props, _this.state); } if (props.scrollToColumn > 0) { _this._initialScrollLeft = _this._getCalculatedScrollLeft(props, _this.state); } return _this; } /** * Gets offsets for a given cell and alignment. */ _createClass(Grid, [{ key: "getOffsetForCell", value: function getOffsetForCell() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$alignment = _ref.alignment, alignment = _ref$alignment === void 0 ? this.props.scrollToAlignment : _ref$alignment, _ref$columnIndex = _ref.columnIndex, columnIndex = _ref$columnIndex === void 0 ? this.props.scrollToColumn : _ref$columnIndex, _ref$rowIndex = _ref.rowIndex, rowIndex = _ref$rowIndex === void 0 ? this.props.scrollToRow : _ref$rowIndex; var offsetProps = _objectSpread({}, this.props, { scrollToAlignment: alignment, scrollToColumn: columnIndex, scrollToRow: rowIndex }); return { scrollLeft: this._getCalculatedScrollLeft(offsetProps), scrollTop: this._getCalculatedScrollTop(offsetProps) }; } /** * Gets estimated total rows' height. */ }, { key: "getTotalRowsHeight", value: function getTotalRowsHeight() { return this.state.instanceProps.rowSizeAndPositionManager.getTotalSize(); } /** * Gets estimated total columns' width. */ }, { key: "getTotalColumnsWidth", value: function getTotalColumnsWidth() { return this.state.instanceProps.columnSizeAndPositionManager.getTotalSize(); } /** * This method handles a scroll event originating from an external scroll control. * It's an advanced method and should probably not be used unless you're implementing a custom scroll-bar solution. */ }, { key: "handleScrollEvent", value: function handleScrollEvent(_ref2) { var _ref2$scrollLeft = _ref2.scrollLeft, scrollLeftParam = _ref2$scrollLeft === void 0 ? 0 : _ref2$scrollLeft, _ref2$scrollTop = _ref2.scrollTop, scrollTopParam = _ref2$scrollTop === void 0 ? 0 : _ref2$scrollTop; // On iOS, we can arrive at negative offsets by swiping past the start. // To prevent flicker here, we make playing in the negative offset zone cause nothing to happen. if (scrollTopParam < 0) { return; } // Prevent pointer events from interrupting a smooth scroll this._debounceScrollEnded(); var _this$props = this.props, autoHeight = _this$props.autoHeight, autoWidth = _this$props.autoWidth, height = _this$props.height, width = _this$props.width; var instanceProps = this.state.instanceProps; // When this component is shrunk drastically, React dispatches a series of back-to-back scroll events, // Gradually converging on a scrollTop that is within the bounds of the new, smaller height. // This causes a series of rapid renders that is slow for long lists. // We can avoid that by doing some simple bounds checking to ensure that scroll offsets never exceed their bounds. var scrollbarSize = instanceProps.scrollbarSize; var totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(); var totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(); var scrollLeft = Math.min(Math.max(0, totalColumnsWidth - width + scrollbarSize), scrollLeftParam); var scrollTop = Math.min(Math.max(0, totalRowsHeight - height + scrollbarSize), scrollTopParam); // Certain devices (like Apple touchpad) rapid-fire duplicate events. // Don't force a re-render if this is the case. // The mouse may move faster then the animation frame does. // Use requestAnimationFrame to avoid over-updating. if (this.state.scrollLeft !== scrollLeft || this.state.scrollTop !== scrollTop) { // Track scrolling direction so we can more efficiently overscan rows to reduce empty space around the edges while scrolling. // Don't change direction for an axis unless scroll offset has changed. var scrollDirectionHorizontal = scrollLeft !== this.state.scrollLeft ? scrollLeft > this.state.scrollLeft ? SCROLL_DIRECTION_FORWARD : SCROLL_DIRECTION_BACKWARD : this.state.scrollDirectionHorizontal; var scrollDirectionVertical = scrollTop !== this.state.scrollTop ? scrollTop > this.state.scrollTop ? SCROLL_DIRECTION_FORWARD : SCROLL_DIRECTION_BACKWARD : this.state.scrollDirectionVertical; var newState = { isScrolling: true, scrollDirectionHorizontal: scrollDirectionHorizontal, scrollDirectionVertical: scrollDirectionVertical, scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS.OBSERVED }; if (!autoHeight) { newState.scrollTop = scrollTop; } if (!autoWidth) { newState.scrollLeft = scrollLeft; } newState.needToResetStyleCache = false; this.setState(newState); } this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft, scrollTop: scrollTop, totalColumnsWidth: totalColumnsWidth, totalRowsHeight: totalRowsHeight }); } /** * Invalidate Grid size and recompute visible cells. * This is a deferred wrapper for recomputeGridSize(). * It sets a flag to be evaluated on cDM/cDU to avoid unnecessary renders. * This method is intended for advanced use-cases like CellMeasurer. */ // @TODO (bvaughn) Add automated test coverage for this. }, { key: "invalidateCellSizeAfterRender", value: function invalidateCellSizeAfterRender(_ref3) { var columnIndex = _ref3.columnIndex, rowIndex = _ref3.rowIndex; this._deferredInvalidateColumnIndex = typeof this._deferredInvalidateColumnIndex === 'number' ? Math.min(this._deferredInvalidateColumnIndex, columnIndex) : columnIndex; this._deferredInvalidateRowIndex = typeof this._deferredInvalidateRowIndex === 'number' ? Math.min(this._deferredInvalidateRowIndex, rowIndex) : rowIndex; } /** * Pre-measure all columns and rows in a Grid. * Typically cells are only measured as needed and estimated sizes are used for cells that have not yet been measured. * This method ensures that the next call to getTotalSize() returns an exact size (as opposed to just an estimated one). */ }, { key: "measureAllCells", value: function measureAllCells() { var _this$props2 = this.props, columnCount = _this$props2.columnCount, rowCount = _this$props2.rowCount; var instanceProps = this.state.instanceProps; instanceProps.columnSizeAndPositionManager.getSizeAndPositionOfCell(columnCount - 1); instanceProps.rowSizeAndPositionManager.getSizeAndPositionOfCell(rowCount - 1); } /** * Forced recompute of row heights and column widths. * This function should be called if dynamic column or row sizes have changed but nothing else has. * Since Grid only receives :columnCount and :rowCount it has no way of detecting when the underlying data changes. */ }, { key: "recomputeGridSize", value: function recomputeGridSize() { var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref4$columnIndex = _ref4.columnIndex, columnIndex = _ref4$columnIndex === void 0 ? 0 : _ref4$columnIndex, _ref4$rowIndex = _ref4.rowIndex, rowIndex = _ref4$rowIndex === void 0 ? 0 : _ref4$rowIndex; var _this$props3 = this.props, scrollToColumn = _this$props3.scrollToColumn, scrollToRow = _this$props3.scrollToRow; var instanceProps = this.state.instanceProps; instanceProps.columnSizeAndPositionManager.resetCell(columnIndex); instanceProps.rowSizeAndPositionManager.resetCell(rowIndex); // Cell sizes may be determined by a function property. // In this case the cDU handler can't know if they changed. // Store this flag to let the next cDU pass know it needs to recompute the scroll offset. this._recomputeScrollLeftFlag = scrollToColumn >= 0 && (this.state.scrollDirectionHorizontal === SCROLL_DIRECTION_FORWARD ? columnIndex <= scrollToColumn : columnIndex >= scrollToColumn); this._recomputeScrollTopFlag = scrollToRow >= 0 && (this.state.scrollDirectionVertical === SCROLL_DIRECTION_FORWARD ? rowIndex <= scrollToRow : rowIndex >= scrollToRow); // Clear cell cache in case we are scrolling; // Invalid row heights likely mean invalid cached content as well. this._styleCache = {}; this._cellCache = {}; this.forceUpdate(); } /** * Ensure column and row are visible. */ }, { key: "scrollToCell", value: function scrollToCell(_ref5) { var columnIndex = _ref5.columnIndex, rowIndex = _ref5.rowIndex; var columnCount = this.props.columnCount; var props = this.props; // Don't adjust scroll offset for single-column grids (eg List, Table). // This can cause a funky scroll offset because of the vertical scrollbar width. if (columnCount > 1 && columnIndex !== undefined) { this._updateScrollLeftForScrollToColumn(_objectSpread({}, props, { scrollToColumn: columnIndex })); } if (rowIndex !== undefined) { this._updateScrollTopForScrollToRow(_objectSpread({}, props, { scrollToRow: rowIndex })); } } }, { key: "componentDidMount", value: function componentDidMount() { var _this$props4 = this.props, getScrollbarSize = _this$props4.getScrollbarSize, height = _this$props4.height, scrollLeft = _this$props4.scrollLeft, scrollToColumn = _this$props4.scrollToColumn, scrollTop = _this$props4.scrollTop, scrollToRow = _this$props4.scrollToRow, width = _this$props4.width; var instanceProps = this.state.instanceProps; // Reset initial offsets to be ignored in browser this._initialScrollTop = 0; this._initialScrollLeft = 0; // If cell sizes have been invalidated (eg we are using CellMeasurer) then reset cached positions. // We must do this at the start of the method as we may calculate and update scroll position below. this._handleInvalidatedGridSize(); // If this component was first rendered server-side, scrollbar size will be undefined. // In that event we need to remeasure. if (!instanceProps.scrollbarSizeMeasured) { this.setState(function (prevState) { var stateUpdate = _objectSpread({}, prevState, { needToResetStyleCache: false }); stateUpdate.instanceProps.scrollbarSize = getScrollbarSize(); stateUpdate.instanceProps.scrollbarSizeMeasured = true; return stateUpdate; }); } if (typeof scrollLeft === 'number' && scrollLeft >= 0 || typeof scrollTop === 'number' && scrollTop >= 0) { var stateUpdate = Grid._getScrollToPositionStateUpdate({ prevState: this.state, scrollLeft: scrollLeft, scrollTop: scrollTop }); if (stateUpdate) { stateUpdate.needToResetStyleCache = false; this.setState(stateUpdate); } } // refs don't work in `react-test-renderer` if (this._scrollingContainer) { // setting the ref's scrollLeft and scrollTop. // Somehow in MultiGrid the main grid doesn't trigger a update on mount. if (this._scrollingContainer.scrollLeft !== this.state.scrollLeft) { this._scrollingContainer.scrollLeft = this.state.scrollLeft; } if (this._scrollingContainer.scrollTop !== this.state.scrollTop) { this._scrollingContainer.scrollTop = this.state.scrollTop; } } // Don't update scroll offset if the size is 0; we don't render any cells in this case. // Setting a state may cause us to later thing we've updated the offce when we haven't. var sizeIsBiggerThanZero = height > 0 && width > 0; if (scrollToColumn >= 0 && sizeIsBiggerThanZero) { this._updateScrollLeftForScrollToColumn(); } if (scrollToRow >= 0 && sizeIsBiggerThanZero) { this._updateScrollTopForScrollToRow(); } // Update onRowsRendered callback this._invokeOnGridRenderedHelper(); // Initialize onScroll callback this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft || 0, scrollTop: scrollTop || 0, totalColumnsWidth: instanceProps.columnSizeAndPositionManager.getTotalSize(), totalRowsHeight: instanceProps.rowSizeAndPositionManager.getTotalSize() }); this._maybeCallOnScrollbarPresenceChange(); } /** * @private * This method updates scrollLeft/scrollTop in state for the following conditions: * 1) New scroll-to-cell props have been set */ }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { var _this2 = this; var _this$props5 = this.props, autoHeight = _this$props5.autoHeight, autoWidth = _this$props5.autoWidth, columnCount = _this$props5.columnCount, height = _this$props5.height, rowCount = _this$props5.rowCount, scrollToAlignment = _this$props5.scrollToAlignment, scrollToColumn = _this$props5.scrollToColumn, scrollToRow = _this$props5.scrollToRow, width = _this$props5.width; var _this$state = this.state, scrollLeft = _this$state.scrollLeft, scrollPositionChangeReason = _this$state.scrollPositionChangeReason, scrollTop = _this$state.scrollTop, instanceProps = _this$state.instanceProps; // If cell sizes have been invalidated (eg we are using CellMeasurer) then reset cached positions. // We must do this at the start of the method as we may calculate and update scroll position below. this._handleInvalidatedGridSize(); // Handle edge case where column or row count has only just increased over 0. // In this case we may have to restore a previously-specified scroll offset. // For more info see bvaughn/react-virtualized/issues/218 var columnOrRowCountJustIncreasedFromZero = columnCount > 0 && prevProps.columnCount === 0 || rowCount > 0 && prevProps.rowCount === 0; // Make sure requested changes to :scrollLeft or :scrollTop get applied. // Assigning to scrollLeft/scrollTop tells the browser to interrupt any running scroll animations, // And to discard any pending async changes to the scroll position that may have happened in the meantime (e.g. on a separate scrolling thread). // So we only set these when we require an adjustment of the scroll position. // See issue #2 for more information. if (scrollPositionChangeReason === SCROLL_POSITION_CHANGE_REASONS.REQUESTED) { // @TRICKY :autoHeight and :autoWidth properties instructs Grid to leave :scrollTop and :scrollLeft management to an external HOC (eg WindowScroller). // In this case we should avoid checking scrollingContainer.scrollTop and scrollingContainer.scrollLeft since it forces layout/flow. if (!autoWidth && scrollLeft >= 0 && (scrollLeft !== this._scrollingContainer.scrollLeft || columnOrRowCountJustIncreasedFromZero)) { this._scrollingContainer.scrollLeft = scrollLeft; } if (!autoHeight && scrollTop >= 0 && (scrollTop !== this._scrollingContainer.scrollTop || columnOrRowCountJustIncreasedFromZero)) { this._scrollingContainer.scrollTop = scrollTop; } } // Special case where the previous size was 0: // In this case we don't show any windowed cells at all. // So we should always recalculate offset afterwards. var sizeJustIncreasedFromZero = (prevProps.width === 0 || prevProps.height === 0) && height > 0 && width > 0; // Update scroll offsets if the current :scrollToColumn or :scrollToRow values requires it // @TODO Do we also need this check or can the one in componentWillUpdate() suffice? if (this._recomputeScrollLeftFlag) { this._recomputeScrollLeftFlag = false; this._updateScrollLeftForScrollToColumn(this.props); } else { updateScrollIndexHelper({ cellSizeAndPositionManager: instanceProps.columnSizeAndPositionManager, previousCellsCount: prevProps.columnCount, previousCellSize: prevProps.columnWidth, previousScrollToAlignment: prevProps.scrollToAlignment, previousScrollToIndex: prevProps.scrollToColumn, previousSize: prevProps.width, scrollOffset: scrollLeft, scrollToAlignment: scrollToAlignment, scrollToIndex: scrollToColumn, size: width, sizeJustIncreasedFromZero: sizeJustIncreasedFromZero, updateScrollIndexCallback: function updateScrollIndexCallback() { return _this2._updateScrollLeftForScrollToColumn(_this2.props); } }); } if (this._recomputeScrollTopFlag) { this._recomputeScrollTopFlag = false; this._updateScrollTopForScrollToRow(this.props); } else { updateScrollIndexHelper({ cellSizeAndPositionManager: instanceProps.rowSizeAndPositionManager, previousCellsCount: prevProps.rowCount, previousCellSize: prevProps.rowHeight, previousScrollToAlignment: prevProps.scrollToAlignment, previousScrollToIndex: prevProps.scrollToRow, previousSize: prevProps.height, scrollOffset: scrollTop, scrollToAlignment: scrollToAlignment, scrollToIndex: scrollToRow, size: height, sizeJustIncreasedFromZero: sizeJustIncreasedFromZero, updateScrollIndexCallback: function updateScrollIndexCallback() { return _this2._updateScrollTopForScrollToRow(_this2.props); } }); } // Update onRowsRendered callback if start/stop indices have changed this._invokeOnGridRenderedHelper(); // Changes to :scrollLeft or :scrollTop should also notify :onScroll listeners if (scrollLeft !== prevState.scrollLeft || scrollTop !== prevState.scrollTop) { var totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(); var totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(); this._invokeOnScrollMemoizer({ scrollLeft: scrollLeft, scrollTop: scrollTop, totalColumnsWidth: totalColumnsWidth, totalRowsHeight: totalRowsHeight }); } this._maybeCallOnScrollbarPresenceChange(); } }, { key: "componentWillUnmount", value: function componentWillUnmount() { if (this._disablePointerEventsTimeoutId) { cancelAnimationTimeout(this._disablePointerEventsTimeoutId); } } /** * This method updates scrollLeft/scrollTop in state for the following conditions: * 1) Empty content (0 rows or columns) * 2) New scroll props overriding the current state * 3) Cells-count or cells-size has changed, making previous scroll offsets invalid */ }, { key: "render", value: function render() { var _this$props6 = this.props, autoContainerWidth = _this$props6.autoContainerWidth, autoHeight = _this$props6.autoHeight, autoWidth = _this$props6.autoWidth, className = _this$props6.className, containerProps = _this$props6.containerProps, containerRole = _this$props6.containerRole, containerStyle = _this$props6.containerStyle, height = _this$props6.height, id = _this$props6.id, noContentRenderer = _this$props6.noContentRenderer, role = _this$props6.role, style = _this$props6.style, tabIndex = _this$props6.tabIndex, width = _this$props6.width; var _this$state2 = this.state, instanceProps = _this$state2.instanceProps, needToResetStyleCache = _this$state2.needToResetStyleCache; var isScrolling = this._isScrolling(); var gridStyle = { boxSizing: 'border-box', direction: 'ltr', height: autoHeight ? 'auto' : height, position: 'relative', width: autoWidth ? 'auto' : width, WebkitOverflowScrolling: 'touch', willChange: 'transform' }; if (needToResetStyleCache) { this._styleCache = {}; } // calculate _styleCache here // if state.isScrolling (not from _isScrolling) then reset if (!this.state.isScrolling) { this._resetStyleCache(); } // calculate children to render here this._calculateChildrenToRender(this.props, this.state); var totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(); var totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(); // Force browser to hide scrollbars when we know they aren't necessary. // Otherwise once scrollbars appear they may not disappear again. // For more info see issue #116 var verticalScrollBarSize = totalRowsHeight > height ? instanceProps.scrollbarSize : 0; var horizontalScrollBarSize = totalColumnsWidth > width ? instanceProps.scrollbarSize : 0; if (horizontalScrollBarSize !== this._horizontalScrollBarSize || verticalScrollBarSize !== this._verticalScrollBarSize) { this._horizontalScrollBarSize = horizontalScrollBarSize; this._verticalScrollBarSize = verticalScrollBarSize; this._scrollbarPresenceChanged = true; } // Also explicitly init styles to 'auto' if scrollbars are required. // This works around an obscure edge case where external CSS styles have not yet been loaded, // But an initial scroll index of offset is set as an external prop. // Without this style, Grid would render the correct range of cells but would NOT update its internal offset. // This was originally reported via clauderic/react-infinite-calendar/issues/23 gridStyle.overflowX = totalColumnsWidth + verticalScrollBarSize <= width ? 'hidden' : 'auto'; gridStyle.overflowY = totalRowsHeight + horizontalScrollBarSize <= height ? 'hidden' : 'auto'; var childrenToDisplay = this._childrenToDisplay; var showNoContentRenderer = childrenToDisplay.length === 0 && height > 0 && width > 0; return React.createElement("div", _extends({ ref: this._setScrollingContainerRef }, containerProps, { "aria-label": this.props['aria-label'], "aria-readonly": this.props['aria-readonly'], className: clsx('ReactVirtualized__Grid', className), id: id, onScroll: this._onScroll, role: role, style: _objectSpread({}, gridStyle, {}, style), tabIndex: tabIndex }), childrenToDisplay.length > 0 && React.createElement("div", { className: "ReactVirtualized__Grid__innerScrollContainer", role: containerRole, style: _objectSpread({ width: autoContainerWidth ? 'auto' : totalColumnsWidth, height: totalRowsHeight, maxWidth: totalColumnsWidth, maxHeight: totalRowsHeight, overflow: 'hidden', pointerEvents: isScrolling ? 'none' : '', position: 'relative' }, containerStyle) }, childrenToDisplay), showNoContentRenderer && noContentRenderer()); } /* ---------------------------- Helper methods ---------------------------- */ }, { key: "_calculateChildrenToRender", value: function _calculateChildrenToRender() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; var cellRenderer = props.cellRenderer, cellRangeRenderer = props.cellRangeRenderer, columnCount = props.columnCount, deferredMeasurementCache = props.deferredMeasurementCache, height = props.height, overscanColumnCount = props.overscanColumnCount, overscanIndicesGetter = props.overscanIndicesGetter, overscanRowCount = props.overscanRowCount, rowCount = props.rowCount, width = props.width, isScrollingOptOut = props.isScrollingOptOut; var scrollDirectionHorizontal = state.scrollDirectionHorizontal, scrollDirectionVertical = state.scrollDirectionVertical, instanceProps = state.instanceProps; var scrollTop = this._initialScrollTop > 0 ? this._initialScrollTop : state.scrollTop; var scrollLeft = this._initialScrollLeft > 0 ? this._initialScrollLeft : state.scrollLeft; var isScrolling = this._isScrolling(props, state); this._childrenToDisplay = []; // Render only enough columns and rows to cover the visible area of the grid. if (height > 0 && width > 0) { var visibleColumnIndices = instanceProps.columnSizeAndPositionManager.getVisibleCellRange({ containerSize: width, offset: scrollLeft }); var visibleRowIndices = instanceProps.rowSizeAndPositionManager.getVisibleCellRange({ containerSize: height, offset: scrollTop }); var horizontalOffsetAdjustment = instanceProps.columnSizeAndPositionManager.getOffsetAdjustment({ containerSize: width, offset: scrollLeft }); var verticalOffsetAdjustment = instanceProps.rowSizeAndPositionManager.getOffsetAdjustment({ containerSize: height, offset: scrollTop }); // Store for _invokeOnGridRenderedHelper() this._renderedColumnStartIndex = visibleColumnIndices.start; this._renderedColumnStopIndex = visibleColumnIndices.stop; this._renderedRowStartIndex = visibleRowIndices.start; this._renderedRowStopIndex = visibleRowIndices.stop; var overscanColumnIndices = overscanIndicesGetter({ direction: 'horizontal', cellCount: columnCount, overscanCellsCount: overscanColumnCount, scrollDirection: scrollDirectionHorizontal, startIndex: typeof visibleColumnIndices.start === 'number' ? visibleColumnIndices.start : 0, stopIndex: typeof visibleColumnIndices.stop === 'number' ? visibleColumnIndices.stop : -1 }); var overscanRowIndices = overscanIndicesGetter({ direction: 'vertical', cellCount: rowCount, overscanCellsCount: overscanRowCount, scrollDirection: scrollDirectionVertical, startIndex: typeof visibleRowIndices.start === 'number' ? visibleRowIndices.start : 0, stopIndex: typeof visibleRowIndices.stop === 'number' ? visibleRowIndices.stop : -1 }); // Store for _invokeOnGridRenderedHelper() var columnStartIndex = overscanColumnIndices.overscanStartIndex; var columnStopIndex = overscanColumnIndices.overscanStopIndex; var rowStartIndex = overscanRowIndices.overscanStartIndex; var rowStopIndex = overscanRowIndices.overscanStopIndex; // Advanced use-cases (eg CellMeasurer) require batched measurements to determine accurate sizes. if (deferredMeasurementCache) { // If rows have a dynamic height, scan the rows we are about to render. // If any have not yet been measured, then we need to render all columns initially, // Because the height of the row is equal to the tallest cell within that row, // (And so we can't know the height without measuring all column-cells first). if (!deferredMeasurementCache.hasFixedHeight()) { for (var rowIndex = rowStartIndex; rowIndex <= rowStopIndex; rowIndex++) { if (!deferredMeasurementCache.has(rowIndex, 0)) { columnStartIndex = 0; columnStopIndex = columnCount - 1; break; } } } // If columns have a dynamic width, scan the columns we are about to render. // If any have not yet been measured, then we need to render all rows initially, // Because the width of the column is equal to the widest cell within that column, // (And so we can't know the width without measuring all row-cells first). if (!deferredMeasurementCache.hasFixedWidth()) { for (var columnIndex = columnStartIndex; columnIndex <= columnStopIndex; columnIndex++) { if (!deferredMeasurementCache.has(0, columnIndex)) { rowStartIndex = 0; rowStopIndex = rowCount - 1; break; } } } } this._childrenToDisplay = cellRangeRenderer({ cellCache: this._cellCache, cellRenderer: cellRenderer, columnSizeAndPositionManager: instanceProps.columnSizeAndPositionManager, columnStartIndex: columnStartIndex, columnStopIndex: columnStopIndex, deferredMeasurementCache: deferredMeasurementCache, horizontalOffsetAdjustment: horizontalOffsetAdjustment, isScrolling: isScrolling, isScrollingOptOut: isScrollingOptOut, parent: this, rowSizeAndPositionManager: instanceProps.rowSizeAndPositionManager, rowStartIndex: rowStartIndex, rowStopIndex: rowStopIndex, scrollLeft: scrollLeft, scrollTop: scrollTop, styleCache: this._styleCache, verticalOffsetAdjustment: verticalOffsetAdjustment, visibleColumnIndices: visibleColumnIndices, visibleRowIndices: visibleRowIndices }); // update the indices this._columnStartIndex = columnStartIndex; this._columnStopIndex = columnStopIndex; this._rowStartIndex = rowStartIndex; this._rowStopIndex = rowStopIndex; } } /** * Sets an :isScrolling flag for a small window of time. * This flag is used to disable pointer events on the scrollable portion of the Grid. * This prevents jerky/stuttery mouse-wheel scrolling. */ }, { key: "_debounceScrollEnded", value: function _debounceScrollEnded() { var scrollingResetTimeInterval = this.props.scrollingResetTimeInterval; if (this._disablePointerEventsTimeoutId) { cancelAnimationTimeout(this._disablePointerEventsTimeoutId); } this._disablePointerEventsTimeoutId = requestAnimationTimeout(this._debounceScrollEndedCallback, scrollingResetTimeInterval); } }, { key: "_handleInvalidatedGridSize", /** * Check for batched CellMeasurer size invalidations. * This will occur the first time one or more previously unmeasured cells are rendered. */ value: function _handleInvalidatedGridSize() { if (typeof this._deferredInvalidateColumnIndex === 'number' && typeof this._deferredInvalidateRowIndex === 'number') { var columnIndex = this._deferredInvalidateColumnIndex; var rowIndex = this._deferredInvalidateRowIndex; this._deferredInvalidateColumnIndex = null; this._deferredInvalidateRowIndex = null; this.recomputeGridSize({ columnIndex: columnIndex, rowIndex: rowIndex }); } } }, { key: "_invokeOnScrollMemoizer", value: function _invokeOnScrollMemoizer(_ref6) { var _this3 = this; var scrollLeft = _ref6.scrollLeft, scrollTop = _ref6.scrollTop, totalColumnsWidth = _ref6.totalColumnsWidth, totalRowsHeight = _ref6.totalRowsHeight; this._onScrollMemoizer({ callback: function callback(_ref7) { var scrollLeft = _ref7.scrollLeft, scrollTop = _ref7.scrollTop; var _this3$props = _this3.props, height = _this3$props.height, onScroll = _this3$props.onScroll, width = _this3$props.width; onScroll({ clientHeight: height, clientWidth: width, scrollHeight: totalRowsHeight, scrollLeft: scrollLeft, scrollTop: scrollTop, scrollWidth: totalColumnsWidth }); }, indices: { scrollLeft: scrollLeft, scrollTop: scrollTop } }); } }, { key: "_isScrolling", value: function _isScrolling() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; // If isScrolling is defined in props, use it to override the value in state // This is a performance optimization for WindowScroller + Grid return Object.hasOwnProperty.call(props, 'isScrolling') ? Boolean(props.isScrolling) : Boolean(state.isScrolling); } }, { key: "_maybeCallOnScrollbarPresenceChange", value: function _maybeCallOnScrollbarPresenceChange() { if (this._scrollbarPresenceChanged) { var onScrollbarPresenceChange = this.props.onScrollbarPresenceChange; this._scrollbarPresenceChanged = false; onScrollbarPresenceChange({ horizontal: this._horizontalScrollBarSize > 0, size: this.state.instanceProps.scrollbarSize, vertical: this._verticalScrollBarSize > 0 }); } } }, { key: "scrollToPosition", /** * Scroll to the specified offset(s). * Useful for animating position changes. */ value: function scrollToPosition(_ref8) { var scrollLeft = _ref8.scrollLeft, scrollTop = _ref8.scrollTop; var stateUpdate = Grid._getScrollToPositionStateUpdate({ prevState: this.state, scrollLeft: scrollLeft, scrollTop: scrollTop }); if (stateUpdate) { stateUpdate.needToResetStyleCache = false; this.setState(stateUpdate); } } }, { key: "_getCalculatedScrollLeft", value: function _getCalculatedScrollLeft() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; return Grid._getCalculatedScrollLeft(props, state); } }, { key: "_updateScrollLeftForScrollToColumn", value: function _updateScrollLeftForScrollToColumn() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; var stateUpdate = Grid._getScrollLeftForScrollToColumnStateUpdate(props, state); if (stateUpdate) { stateUpdate.needToResetStyleCache = false; this.setState(stateUpdate); } } }, { key: "_getCalculatedScrollTop", value: function _getCalculatedScrollTop() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; return Grid._getCalculatedScrollTop(props, state); } }, { key: "_resetStyleCache", value: function _resetStyleCache() { var styleCache = this._styleCache; var cellCache = this._cellCache; var isScrollingOptOut = this.props.isScrollingOptOut; // Reset cell and style caches once scrolling stops. // This makes Grid simpler to use (since cells commonly change). // And it keeps the caches from growing too large. // Performance is most sensitive when a user is scrolling. // Don't clear visible cells from cellCache if isScrollingOptOut is specified. // This keeps the cellCache to a resonable size. this._cellCache = {}; this._styleCache = {}; // Copy over the visible cell styles so avoid unnecessary re-render. for (var rowIndex = this._rowStartIndex; rowIndex <= this._rowStopIndex; rowIndex++) { for (var columnIndex = this._columnStartIndex; columnIndex <= this._columnStopIndex; columnIndex++) { var key = "".concat(rowIndex, "-").concat(columnIndex); this._styleCache[key] = styleCache[key]; if (isScrollingOptOut) { this._cellCache[key] = cellCache[key]; } } } } }, { key: "_updateScrollTopForScrollToRow", value: function _updateScrollTopForScrollToRow() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props; var state = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.state; var stateUpdate = Grid._getScrollTopForScrollToRowStateUpdate(props, state); if (stateUpdate) { stateUpdate.needToResetStyleCache = false; this.setState(stateUpdate); } } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps, prevState) { var newState = {}; if (nextProps.columnCount === 0 && prevState.scrollLeft !== 0 || nextProps.rowCount === 0 && prevState.scrollTop !== 0) { newState.scrollLeft = 0; newState.scrollTop = 0; // only use scroll{Left,Top} from props if scrollTo{Column,Row} isn't specified // scrollTo{Column,Row} should override scroll{Left,Top} } else if (nextProps.scrollLeft !== prevState.scrollLeft && nextProps.scrollToColumn < 0 || nextProps.scrollTop !== prevState.scrollTop && nextProps.scrollToRow < 0) { Object.assign(newState, Grid._getScrollToPositionStateUpdate({ prevState: prevState, scrollLeft: nextProps.scrollLeft, scrollTop: nextProps.scrollTop })); } var instanceProps = prevState.instanceProps; // Initially we should not clearStyleCache newState.needToResetStyleCache = false; if (nextProps.columnWidth !== instanceProps.prevColumnWidth || nextProps.rowHeight !== instanceProps.prevRowHeight) { // Reset cache. set it to {} in render newState.needToResetStyleCache = true; } instanceProps.columnSizeAndPositionManager.configure({ cellCount: nextProps.columnCount, estimatedCellSize: Grid._getEstimatedColumnSize(nextProps), cellSizeGetter: Grid._wrapSizeGetter(nextProps.columnWidth) }); instanceProps.rowSizeAndPositionManager.configure({ cellCount: nextProps.rowCount, estimatedCellSize: Grid._getEstimatedRowSize(nextProps), cellSizeGetter: Grid._wrapSizeGetter(nextProps.rowHeight) }); if (instanceProps.prevColumnCount === 0 || instanceProps.prevRowCount === 0) { instanceProps.prevColumnCount = 0; instanceProps.prevRowCount = 0; } // If scrolling is controlled outside this component, clear cache when scrolling stops if (nextProps.autoHeight && nextProps.isScrolling === false && instanceProps.prevIsScrolling === true) { Object.assign(newState, { isScrolling: false }); } var maybeStateA; var maybeStateB; calculateSizeAndPositionDataAndUpdateScrollOffset({ cellCount: instanceProps.prevColumnCount, cellSize: typeof instanceProps.prevColumnWidth === 'number' ? instanceProps.prevColumnWidth : null, computeMetadataCallback: function computeMetadataCallback() { return instanceProps.columnSizeAndPositionManager.resetCell(0); }, computeMetadataCallbackProps: nextProps, nextCellsCount: nextProps.columnCount, nextCellSize: typeof nextProps.columnWidth === 'number' ? nextProps.columnWidth : null, nextScrollToIndex: nextProps.scrollToColumn, scrollToIndex: instanceProps.prevScrollToColumn, updateScrollOffsetForScrollToIndex: function updateScrollOffsetForScrollToIndex() { maybeStateA = Grid._getScrollLeftForScrollToColumnStateUpdate(nextProps, prevState); } }); calculateSizeAndPositionDataAndUpdateScrollOffset({ cellCount: instanceProps.prevRowCount, cellSize: typeof instanceProps.prevRowHeight === 'number' ? instanceProps.prevRowHeight : null, computeMetadataCallback: function computeMetadataCallback() { return instanceProps.rowSizeAndPositionManager.resetCell(0); }, computeMetadataCallbackProps: nextProps, nextCellsCount: nextProps.rowCount, nextCellSize: typeof nextProps.rowHeight === 'number' ? nextProps.rowHeight : null, nextScrollToIndex: nextProps.scrollToRow, scrollToIndex: instanceProps.prevScrollToRow, updateScrollOffsetForScrollToIndex: function updateScrollOffsetForScrollToIndex() { maybeStateB = Grid._getScrollTopForScrollToRowStateUpdate(nextProps, prevState); } }); instanceProps.prevColumnCount = nextProps.columnCount; instanceProps.prevColumnWidth = nextProps.columnWidth; instanceProps.prevIsScrolling = nextProps.isScrolling === true; instanceProps.prevRowCount = nextProps.rowCount; instanceProps.prevRowHeight = nextProps.rowHeight; instanceProps.prevScrollToColumn = nextProps.scrollToColumn; instanceProps.prevScrollToRow = nextProps.scrollToRow; // getting scrollBarSize (moved from componentWillMount) instanceProps.scrollbarSize = nextProps.getScrollbarSize(); if (instanceProps.scrollbarSize === undefined) { instanceProps.scrollbarSizeMeasured = false; instanceProps.scrollbarSize = 0; } else { instanceProps.scrollbarSizeMeasured = true; } newState.instanceProps = instanceProps; return _objectSpread({}, newState, {}, maybeStateA, {}, maybeStateB); } }, { key: "_getEstimatedColumnSize", value: function _getEstimatedColumnSize(props) { return typeof props.columnWidth === 'number' ? props.columnWidth : props.estimatedColumnSize; } }, { key: "_getEstimatedRowSize", value: function _getEstimatedRowSize(props) { return typeof props.rowHeight === 'number' ? props.rowHeight : props.estimatedRowSize; } }, { key: "_getScrollToPositionStateUpdate", /** * Get the updated state after scrolling to * scrollLeft and scrollTop */ value: function _getScrollToPositionStateUpdate(_ref9) { var prevState = _ref9.prevState, scrollLeft = _ref9.scrollLeft, scrollTop = _ref9.scrollTop; var newState = { scrollPositionChangeReason: SCROLL_POSITION_CHANGE_REASONS.REQUESTED }; if (typeof scrollLeft === 'number' && scrollLeft >= 0) { newState.scrollDirectionHorizontal = scrollLeft > prevState.scrollLeft ? SCROLL_DIRECTION_FORWARD : SCROLL_DIRECTION_BACKWARD; newState.scrollLeft = scrollLeft; } if (typeof scrollTop === 'number' && scrollTop >= 0) { newState.scrollDirectionVertical = scrollTop > prevState.scrollTop ? SCROLL_DIRECTION_FORWARD : SCROLL_DIRECTION_BACKWARD; newState.scrollTop = scrollTop; } if (typeof scrollLeft === 'number' && scrollLeft >= 0 && scrollLeft !== prevState.scrollLeft || typeof scrollTop === 'number' && scrollTop >= 0 && scrollTop !== prevState.scrollTop) { return newState; } return {}; } }, { key: "_wrapSizeGetter", value: function _wrapSizeGetter(value) { return typeof value === 'function' ? value : function () { return value; }; } }, { key: "_getCalculatedScrollLeft", value: function _getCalculatedScrollLeft(nextProps, prevState) { var columnCount = nextProps.columnCount, height = nextProps.height, scrollToAlignment = nextProps.scrollToAlignment, scrollToColumn = nextProps.scrollToColumn, width = nextProps.width; var scrollLeft = prevState.scrollLeft, instanceProps = prevState.instanceProps; if (columnCount > 0) { var finalColumn = columnCount - 1; var targetIndex = scrollToColumn < 0 ? finalColumn : Math.min(finalColumn, scrollToColumn); var totalRowsHeight = instanceProps.rowSizeAndPositionManager.getTotalSize(); var scrollBarSize = instanceProps.scrollbarSizeMeasured && totalRowsHeight > height ? instanceProps.scrollbarSize : 0; return instanceProps.columnSizeAndPositionManager.getUpdatedOffsetForIndex({ align: scrollToAlignment, containerSize: width - scrollBarSize, currentOffset: scrollLeft, targetIndex: targetIndex }); } return 0; } }, { key: "_getScrollLeftForScrollToColumnStateUpdate", value: function _getScrollLeftForScrollToColumnStateUpdate(nextProps, prevState) { var scrollLeft = prevState.scrollLeft; var calculatedScrollLeft = Grid._getCalculatedScrollLeft(nextProps, prevState); if (typeof calculatedScrollLeft === 'number' && calculatedScrollLeft >= 0 && scrollLeft !== calculatedScrollLeft) { return Grid._getScrollToPositionStateUpdate({ prevState: prevState, scrollLeft: calculatedScrollLeft, scrollTop: -1 }); } return {}; } }, { key: "_getCalculatedScrollTop", value: function _getCalculatedScrollTop(nextProps, prevState) { var height = nextProps.height, rowCount = nextProps.rowCount, scrollToAlignment = nextProps.scrollToAlignment, scrollToRow = nextProps.scrollToRow, width = nextProps.width; var scrollTop = prevState.scrollTop, instanceProps = prevState.instanceProps; if (rowCount > 0) { var finalRow = rowCount - 1; var targetIndex = scrollToRow < 0 ? finalRow : Math.min(finalRow, scrollToRow); var totalColumnsWidth = instanceProps.columnSizeAndPositionManager.getTotalSize(); var scrollBarSize = instanceProps.scrollbarSizeMeasured && totalColumnsWidth > width ? instanceProps.scrollbarSize : 0; return instanceProps.rowSizeAndPositionManager.getUpdatedOffsetForIndex({ align: scrollToAlignment, containerSize: height - scrollBarSize, currentOffset: scrollTop, targetIndex: targetIndex }); } return 0; } }, { key: "_getScrollTopForScrollToRowStateUpdate", value: function _getScrollTopForScrollToRowStateUpdate(nextProps, prevState) { var scrollTop = prevState.scrollTop; var calculatedScrollTop = Grid._getCalculatedScrollTop(nextProps, prevState); if (typeof calculatedScrollTop === 'number' && calculatedScrollTop >= 0 && scrollTop !== calculatedScrollTop) { return Grid._getScrollToPositionStateUpdate({ prevState: prevState, scrollLeft: -1, scrollTop: calculatedScrollTop }); } return {}; } }]); return Grid; }(React.PureComponent), _defineProperty(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { "aria-label": PropTypes.string.isRequired, "aria-readonly": PropTypes.bool, /** * Set the width of the inner scrollable container to 'auto'. * This is useful for single-column Grids to ensure that the column doesn't extend below a vertical scrollbar. */ "autoContainerWidth": PropTypes.bool.isRequired, /** * Removes fixed height from the scrollingContainer so that the total height of rows can stretch the window. * Intended for use with WindowScroller */ "autoHeight": PropTypes.bool.isRequired, /** * Removes fixed width from the scrollingContainer so that the total width of rows can stretch the window. * Intended for use with WindowScroller */ "autoWidth": PropTypes.bool.isRequired, /** Responsible for rendering a cell given an row and column index. */ "cellRenderer": function cellRenderer() { return (typeof bpfrpt_proptype_CellRenderer === "function" ? bpfrpt_proptype_CellRenderer.isRequired ? bpfrpt_proptype_CellRenderer.isRequired : bpfrpt_proptype_CellRenderer : PropTypes.shape(bpfrpt_proptype_CellRenderer).isRequired).apply(this, arguments); }, /** Responsible for rendering a group of cells given their index ranges. */ "cellRangeRenderer": function cellRangeRenderer() { return (typeof bpfrpt_proptype_CellRangeRenderer === "function" ? bpfrpt_proptype_CellRangeRenderer.isRequired ? bpfrpt_proptype_CellRangeRenderer.isRequired : bpfrpt_proptype_CellRangeRenderer : PropTypes.shape(bpfrpt_proptype_CellRangeRenderer).isRequired).apply(this, arguments); }, /** Optional custom CSS class name to attach to root Grid element. */ "className": PropTypes.string, /** Number of columns in grid. */ "columnCount": PropTypes.number.isRequired, /** Either a fixed column width (number) or a function that returns the width of a column given its index. */ "columnWidth": function columnWidth() { return (typeof bpfrpt_proptype_CellSize === "function" ? bpfrpt_proptype_CellSize.isRequired ? bpfrpt_proptype_CellSize.isRequired : bpfrpt_proptype_CellSize : PropTypes.shape(bpfrpt_proptype_CellSize).isRequired).apply(this, arguments); }, /** Unfiltered props for the Grid container. */ "containerProps": PropTypes.object, /** ARIA role for the cell-container. */ "containerRole": PropTypes.string.isRequired, /** Optional inline style applied to inner cell-container */ "containerStyle": PropTypes.object.isRequired, /** * If CellMeasurer is used to measure this Grid's children, this should be a pointer to its CellMeasurerCache. * A shared CellMeasurerCache reference enables Grid and CellMeasurer to share measurement data. */ "deferredMeasurementCache": PropTypes.object, /** * Used to estimate the total width of a Grid before all of its columns have actually been measured. * The estimated total width is adjusted as columns are rendered. */ "estimatedColumnSize": PropTypes.number.isRequired, /** * Used to estimate the total height of a Grid before all of its rows have actually been measured. * The estimated total height is adjusted as rows are rendered. */ "estimatedRowSize": PropTypes.number.isRequired, /** Exposed for testing purposes only. */ "getScrollbarSize": PropTypes.func.isRequired, /** Height of Grid; this property determines the number of visible (vs virtualized) rows. */ "height": PropTypes.number.isRequired, /** Optional custom id to attach to root Grid element. */ "id": PropTypes.string, /** * Override internal is-scrolling state tracking. * This property is primarily intended for use with the WindowScroller component. */ "isScrolling": PropTypes.bool, /** * Opt-out of isScrolling param passed to cellRangeRenderer. * To avoid the extra render when scroll stops. */ "isScrollingOptOut": PropTypes.bool.isRequired, /** Optional renderer to be used in place of rows when either :rowCount or :columnCount is 0. */ "noContentRenderer": function noContentRenderer() { return (typeof bpfrpt_proptype_NoContentRenderer === "function" ? bpfrpt_proptype_NoContentRenderer.isRequired ? bpfrpt_proptype_NoContentRenderer.isRequired : bpfrpt_proptype_NoContentRenderer : PropTypes.shape(bpfrpt_proptype_NoContentRenderer).isRequired).apply(this, arguments); }, /** * Callback invoked whenever the scroll offset changes within the inner scrollable region. * This callback can be used to sync scrolling between lists, tables, or grids. */ "onScroll": PropTypes.func.isRequired, /** * Called whenever a horizontal or vertical scrollbar is added or removed. * This prop is not intended for end-user use; * It is used by MultiGrid to support fixed-row/fixed-column scroll syncing. */ "onScrollbarPresenceChange": PropTypes.func.isRequired, /** Callback invoked with information about the section of the Grid that was just rendered. */ "onSectionRendered": PropTypes.func.isRequired, /** * Number of columns to render before/after the visible section of the grid. * These columns can help for smoother scrolling on touch devices or browsers that send scroll events infrequently. */ "overscanColumnCount": PropTypes.number.isRequired, /** * Calculates the number of cells to overscan before and after a specified range. * This function ensures that overscanning doesn't exceed the available cells. */ "overscanIndicesGetter": function overscanIndicesGetter() { return (typeof bpfrpt_proptype_OverscanIndicesGetter === "function" ? bpfrpt_proptype_OverscanIndicesGetter.isRequired ? bpfrpt_proptype_OverscanIndicesGetter.isRequired : bpfrpt_proptype_OverscanIndicesGetter : PropTypes.shape(bpfrpt_proptype_OverscanIndicesGetter).isRequired).apply(this, arguments); }, /** * Number of rows to render above/below the visible section of the grid. * These rows can help for smoother scrolling on touch devices or browsers that send scroll events infrequently. */ "overscanRowCount": PropTypes.number.isRequired, /** ARIA role for the grid element. */ "role": PropTypes.string.isRequired, /** * Either a fixed row height (number) or a function that returns the height of a row given its index. * Should implement the following interface: ({ index: number }): number */ "rowHeight": function rowHeight() { return (typeof bpfrpt_proptype_CellSize === "function" ? bpfrpt_proptype_CellSize.isRequired ? bpfrpt_proptype_CellSize.isRequired : bpfrpt_proptype_CellSize : PropTypes.shape(bpfrpt_proptype_CellSize).isRequired).apply(this, arguments); }, /** Number of rows in grid. */ "rowCount": PropTypes.number.isRequired, /** Wait this amount of time after the last scroll event before resetting Grid `pointer-events`. */ "scrollingResetTimeInterval": PropTypes.number.isRequired, /** Horizontal offset. */ "scrollLeft": PropTypes.number, /** * Controls scroll-to-cell behavior of the Grid. * The default ("auto") scrolls the least amount possible to ensure that the specified cell is fully visible. * Use "start" to align cells to the top/left of the Grid and "end" to align bottom/right. */ "scrollToAlignment": function scrollToAlignment() { return (typeof bpfrpt_proptype_Alignment === "function" ? bpfrpt_proptype_Alignment.isRequired ? bpfrpt_proptype_Alignment.isRequired : bpfrpt_proptype_Alignment : PropTypes.shape(bpfrpt_proptype_Alignment).isRequired).apply(this, arguments); }, /** Column index to ensure visible (by forcefully scrolling if necessary) */ "scrollToColumn": PropTypes.number.isRequired, /** Vertical offset. */ "scrollTop": PropTypes.number, /** Row index to ensure visible (by forcefully scrolling if necessary) */ "scrollToRow": PropTypes.number.isRequired, /** Optional inline style */ "style": PropTypes.object.isRequired, /** Tab index for focus */ "tabIndex": PropTypes.number, /** Width of Grid; this property determines the number of visible (vs virtualized) columns. */ "width": PropTypes.number.isRequired }), _temp); _defineProperty(Grid, "defaultProps", { 'aria-label': 'grid', 'aria-readonly': true, autoContainerWidth: false, autoHeight: false, autoWidth: false, cellRangeRenderer: defaultCellRangeRenderer, containerRole: 'rowgroup', containerStyle: {}, estimatedColumnSize: 100, estimatedRowSize: 30, getScrollbarSize: scrollbarSize, noContentRenderer: renderNull, onScroll: function onScroll() {}, onScrollbarPresenceChange: function onScrollbarPresenceChange() {}, onSectionRendered: function onSectionRendered() {}, overscanColumnCount: 0, overscanIndicesGetter: defaultOverscanIndicesGetter, overscanRowCount: 10, role: 'grid', scrollingResetTimeInterval: DEFAULT_SCROLLING_RESET_TIME_INTERVAL, scrollToAlignment: 'auto', scrollToColumn: -1, scrollToRow: -1, style: {}, tabIndex: 0, isScrollingOptOut: false }); polyfill(Grid); export default Grid; import { bpfrpt_proptype_CellRenderer } from "./types"; import { bpfrpt_proptype_CellRangeRenderer } from "./types"; import { bpfrpt_proptype_CellPosition } from "./types"; import { bpfrpt_proptype_CellSize } from "./types"; import { bpfrpt_proptype_CellSizeGetter } from "./types"; import { bpfrpt_proptype_NoContentRenderer } from "./types"; import { bpfrpt_proptype_Scroll } from "./types"; import { bpfrpt_proptype_ScrollbarPresenceChange } from "./types"; import { bpfrpt_proptype_RenderedSection } from "./types"; import { bpfrpt_proptype_OverscanIndicesGetter } from "./types"; import { bpfrpt_proptype_Alignment } from "./types"; import { bpfrpt_proptype_CellCache } from "./types"; import { bpfrpt_proptype_StyleCache } from "./types"; import { bpfrpt_proptype_AnimationTimeoutId } from "../utils/requestAnimationTimeout"; import PropTypes from "prop-types";dist/es/Grid/Grid.jest.js000064400000266253151676725770011237 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _inherits from "@babel/runtime/helpers/inherits"; import _regeneratorRuntime from "@babel/runtime/regenerator"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _extends from "@babel/runtime/helpers/extends"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import * as React from 'react'; import { findDOMNode } from 'react-dom'; import { Simulate } from 'react-dom/test-utils'; import TestRenderer from 'react-test-renderer'; import { render } from '../TestUtils'; import Grid, { DEFAULT_SCROLLING_RESET_TIME_INTERVAL } from './Grid'; import defaultCellRangeRenderer from './defaultCellRangeRenderer'; import { CellMeasurer, CellMeasurerCache } from '../CellMeasurer'; import { SCROLL_DIRECTION_BACKWARD, SCROLL_DIRECTION_FORWARD } from './defaultOverscanIndicesGetter'; import { getMaxElementSize } from './utils/maxElementSize.js'; var DEFAULT_COLUMN_WIDTH = 50; var DEFAULT_HEIGHT = 100; var DEFAULT_ROW_HEIGHT = 20; var DEFAULT_WIDTH = 200; var NUM_ROWS = 100; var NUM_COLUMNS = 50; function getScrollbarSize0() { return 0; } function getScrollbarSize20() { return 20; } describe('Grid', function () { function defaultCellRenderer(_ref) { var columnIndex = _ref.columnIndex, key = _ref.key, rowIndex = _ref.rowIndex, style = _ref.style; return React.createElement("div", { className: "gridItem", key: key, style: style }, "row:".concat(rowIndex, ", column:").concat(columnIndex)); } function simulateScroll(_ref2) { var grid = _ref2.grid, _ref2$scrollLeft = _ref2.scrollLeft, scrollLeft = _ref2$scrollLeft === void 0 ? 0 : _ref2$scrollLeft, _ref2$scrollTop = _ref2.scrollTop, scrollTop = _ref2$scrollTop === void 0 ? 0 : _ref2$scrollTop; var target = { scrollLeft: scrollLeft, scrollTop: scrollTop }; grid._scrollingContainer = target; // HACK to work around _onScroll target check Simulate.scroll(findDOMNode(grid), { target: target }); } function getMarkup() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return React.createElement(Grid, _extends({ cellRenderer: defaultCellRenderer, columnCount: NUM_COLUMNS, columnWidth: DEFAULT_COLUMN_WIDTH, getScrollbarSize: getScrollbarSize0, height: DEFAULT_HEIGHT, overscanColumnCount: 0, overscanRowCount: 0, autoHeight: false, rowHeight: DEFAULT_ROW_HEIGHT, rowCount: NUM_ROWS, width: DEFAULT_WIDTH }, props)); } describe('number of rendered children', function () { it('should render enough children to fill the available area', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.querySelectorAll('.gridItem').length).toEqual(20); // 5 rows x 4 columns }); it('should not render more rows than available if the area is not filled', function () { var rendered = findDOMNode(render(getMarkup({ rowCount: 2 }))); expect(rendered.querySelectorAll('.gridItem').length).toEqual(8); // 2 rows x 4 columns }); it('should not render more columns than available if the area is not filled', function () { var rendered = findDOMNode(render(getMarkup({ columnCount: 2 }))); expect(rendered.querySelectorAll('.gridItem').length).toEqual(10); // 5 rows x 2 columns }); // Small performance tweak added in 5.5.6 it('should not render/parent cells that are null or false', function () { function cellRenderer(_ref3) { var columnIndex = _ref3.columnIndex, key = _ref3.key, rowIndex = _ref3.rowIndex, style = _ref3.style; if (columnIndex === 0) { return null; } else if (rowIndex === 0) { return false; } else { return React.createElement("div", { className: "cell", key: key, style: style }, "row:".concat(rowIndex, ", column:").concat(columnIndex)); } } var rendered = findDOMNode(render(getMarkup({ columnCount: 3, overscanColumnCount: 0, overscanRowCount: 0, rowCount: 3, cellRenderer: cellRenderer }))); expect(rendered.querySelectorAll('.cell').length).toEqual(4); // [1,1], [1,2], [2,1], and [2,2] expect(rendered.textContent).not.toContain('column:0'); expect(rendered.textContent).not.toContain('row:0'); }); it('should scroll to the last existing point when rows are removed', function () { var grid = render(getMarkup({ rowCount: 15 })); simulateScroll({ grid: grid, scrollTop: 200 }); var updatedGrid = render(getMarkup({ rowCount: 10 })); expect(updatedGrid.state.scrollTop).toEqual(100); }); it('should scroll to the last existing point when columns are removed', function () { var grid = render(getMarkup({ columnCount: 12 })); simulateScroll({ grid: grid, scrollLeft: 400 }); var updatedGrid = render(getMarkup({ columnCount: 8 })); expect(updatedGrid.state.scrollLeft).toEqual(200); }); it('should not scroll unseen rows are removed', function () { render(getMarkup({ rowCount: 15 })); var updatedGrid = render(getMarkup({ rowCount: 10 })); expect(updatedGrid.state.scrollTop).toEqual(0); }); it('should not scroll when unseen columns are removed', function () { render(getMarkup({ columnCount: 12 })); var updatedGrid = render(getMarkup({ columnCount: 8 })); expect(updatedGrid.state.scrollLeft).toEqual(0); }); }); describe('shows and hides scrollbars based on rendered content', function () { it('should set overflowX:hidden if columns fit within the available width and y-axis has no scrollbar', function () { var rendered = findDOMNode(render(getMarkup({ columnCount: 4, getScrollbarSize: getScrollbarSize20, rowCount: 5 }))); expect(rendered.style.overflowX).toEqual('hidden'); }); it('should set overflowX:hidden if columns and y-axis scrollbar fit within the available width', function () { var rendered = findDOMNode(render(getMarkup({ columnCount: 4, getScrollbarSize: getScrollbarSize20, width: 200 + getScrollbarSize20() }))); expect(rendered.style.overflowX).toEqual('hidden'); }); it('should leave overflowX:auto if columns require more than the available width', function () { var rendered = findDOMNode(render(getMarkup({ columnCount: 4, getScrollbarSize: getScrollbarSize20, width: 200 - 1, rowCount: 5 }))); expect(rendered.style.overflowX).not.toEqual('hidden'); }); it('should leave overflowX:auto if columns and y-axis scrollbar require more than the available width', function () { var rendered = findDOMNode(render(getMarkup({ columnCount: 4, getScrollbarSize: getScrollbarSize20, width: 200 + getScrollbarSize20() - 1 }))); expect(rendered.style.overflowX).not.toEqual('hidden'); }); it('should set overflowY:hidden if rows fit within the available width and xaxis has no scrollbar', function () { var rendered = findDOMNode(render(getMarkup({ getScrollbarSize: getScrollbarSize20, rowCount: 5, columnCount: 4 }))); expect(rendered.style.overflowY).toEqual('hidden'); }); it('should set overflowY:hidden if rows and x-axis scrollbar fit within the available width', function () { var rendered = findDOMNode(render(getMarkup({ getScrollbarSize: getScrollbarSize20, rowCount: 5, height: 100 + getScrollbarSize20() }))); expect(rendered.style.overflowY).toEqual('hidden'); }); it('should leave overflowY:auto if rows require more than the available width', function () { var rendered = findDOMNode(render(getMarkup({ getScrollbarSize: getScrollbarSize20, rowCount: 5, height: 100 - 1, columnCount: 4 }))); expect(rendered.style.overflowY).not.toEqual('hidden'); }); it('should leave overflowY:auto if rows and x-axis scrollbar require more than the available width', function () { var rendered = findDOMNode(render(getMarkup({ getScrollbarSize: getScrollbarSize20, rowCount: 5, height: 100 + getScrollbarSize20() - 1 }))); expect(rendered.style.overflowY).not.toEqual('hidden'); }); it('should accept styles that overwrite calculated ones', function () { var rendered = findDOMNode(render(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, height: 1, rowCount: 1, style: { overflowY: 'visible', overflowX: 'visible' }, width: 1 }))); expect(rendered.style.overflowY).toEqual('visible'); expect(rendered.style.overflowX).toEqual('visible'); }); }); /** Tests scrolling via initial props */ describe(':scrollToColumn and :scrollToRow', function () { it('should scroll to the left', function () { var grid = render(getMarkup({ scrollToColumn: 0 })); expect(grid.state.scrollLeft).toEqual(0); }); it('should scroll over to the middle', function () { var grid = render(getMarkup({ scrollToColumn: 24 })); // 50 columns * 50 item width = 2,500 total item width // 4 columns can be visible at a time and :scrollLeft is initially 0, // So the minimum amount of scrolling leaves the 25th item at the right (just scrolled into view). expect(grid.state.scrollLeft).toEqual(1050); }); it('should scroll to the far right', function () { var grid = render(getMarkup({ scrollToColumn: 49 })); // 50 columns * 50 item width = 2,500 total item width // Target offset for the last item then is 2,500 - 200 expect(grid.state.scrollLeft).toEqual(2300); }); it('should scroll to the top', function () { var grid = render(getMarkup({ scrollToRow: 0 })); expect(grid.state.scrollTop).toEqual(0); }); it('should scroll down to the middle', function () { var grid = render(getMarkup({ scrollToRow: 49 })); // 100 rows * 20 item height = 2,000 total item height // 5 rows can be visible at a time and :scrollTop is initially 0, // So the minimum amount of scrolling leaves the 50th item at the bottom (just scrolled into view). expect(grid.state.scrollTop).toEqual(900); }); it('should scroll to the bottom', function () { var grid = render(getMarkup({ scrollToRow: 99 })); // 100 rows * 20 item height = 2,000 total item height // Target offset for the last item then is 2,000 - 100 expect(grid.state.scrollTop).toEqual(1900); }); it('should scroll to a row and column just added', function () { var grid = render(getMarkup()); expect(grid.state.scrollLeft).toEqual(0); expect(grid.state.scrollTop).toEqual(0); grid = render(getMarkup({ columnCount: NUM_COLUMNS + 1, rowCount: NUM_ROWS + 1, scrollToColumn: NUM_COLUMNS, scrollToRow: NUM_ROWS })); expect(grid.state.scrollLeft).toEqual(2350); expect(grid.state.scrollTop).toEqual(1920); }); it('should scroll back to a newly-added cell without a change in prop', function () { var grid = render(getMarkup({ columnCount: NUM_COLUMNS, rowCount: NUM_ROWS, scrollToColumn: NUM_COLUMNS, scrollToRow: NUM_ROWS })); grid = render(getMarkup({ columnCount: NUM_COLUMNS + 1, rowCount: NUM_ROWS + 1, scrollToColumn: NUM_COLUMNS, scrollToRow: NUM_ROWS })); expect(grid.state.scrollLeft).toEqual(2350); expect(grid.state.scrollTop).toEqual(1920); }); it('should scroll to the correct position for :scrollToAlignment "start"', function () { var grid = render(getMarkup({ scrollToAlignment: 'start', scrollToColumn: 24, scrollToRow: 49 })); // 50 columns * 50 item width = 2,500 total item width // 100 rows * 20 item height = 2,000 total item height // 4 columns and 5 rows can be visible at a time. // The minimum amount of scrolling leaves the specified cell in the bottom/right corner (just scrolled into view). // Since alignment is set to "start" we should scroll past this point until the cell is aligned top/left. expect(grid.state.scrollLeft).toEqual(1200); expect(grid.state.scrollTop).toEqual(980); }); it('should scroll to the correct position for :scrollToAlignment "end"', function () { render(getMarkup({ scrollToColumn: 99, scrollToRow: 99 })); var grid = render(getMarkup({ scrollToAlignment: 'end', scrollToColumn: 24, scrollToRow: 49 })); // 50 columns * 50 item width = 2,500 total item width // 100 rows * 20 item height = 2,000 total item height // We first scroll past the specified cell and then back. // The minimum amount of scrolling then should leave the specified cell in the top/left corner (just scrolled into view). // Since alignment is set to "end" we should scroll past this point until the cell is aligned bottom/right. expect(grid.state.scrollLeft).toEqual(1050); expect(grid.state.scrollTop).toEqual(900); }); it('should scroll to the correct position for :scrollToAlignment "center"', function () { render(getMarkup({ scrollToColumn: 99, scrollToRow: 99 })); var grid = render(getMarkup({ scrollToAlignment: 'center', scrollToColumn: 24, scrollToRow: 49 })); // 50 columns * 50 item width = 2,500 total item width // Viewport width is 200 // Column 24 starts at 1,200, center point at 1,225, so... expect(grid.state.scrollLeft).toEqual(1125); // 100 rows * 20 item height = 2,000 total item height // Viewport height is 100 // Row 49 starts at 980, center point at 990, so... expect(grid.state.scrollTop).toEqual(940); }); // Tests issue #691 it('should set the correct :scrollLeft after height increases from 0', function () { render.unmount(); expect(findDOMNode(render(getMarkup({ height: 0, scrollToColumn: 24 }))).scrollLeft || 0).toEqual(0); expect(findDOMNode(render(getMarkup({ height: 100, scrollToColumn: 24 }))).scrollLeft).toEqual(1050); }); // Tests issue #691 it('should set the correct :scrollTop after width increases from 0', function () { render.unmount(); expect(findDOMNode(render(getMarkup({ scrollToRow: 49, width: 0 }))).scrollTop || 0).toEqual(0); expect(findDOMNode(render(getMarkup({ scrollToRow: 49, width: 100 }))).scrollTop).toEqual(900); }); // Tests issue #218 it('should set the correct :scrollTop after row and column counts increase from 0', function () { var expectedScrollTop = 100 * DEFAULT_ROW_HEIGHT - DEFAULT_HEIGHT + DEFAULT_ROW_HEIGHT; render(getMarkup({ columnCount: 0, rowCount: 150, scrollToRow: 100 })); expect(findDOMNode(render(getMarkup({ columnCount: 150, rowCount: 150, scrollToRow: 100 }))).scrollTop).toEqual(expectedScrollTop); }); it('should support scrollToCell() public method', function () { var grid = render(getMarkup()); expect(grid.state.scrollLeft).toEqual(0); expect(grid.state.scrollTop).toEqual(0); grid.scrollToCell({ columnIndex: 24, rowIndex: 49 }); // 50 columns * 50 item width = 2,500 total item width // 4 columns can be visible at a time and :scrollLeft is initially 0, // So the minimum amount of scrolling leaves the 25th item at the right (just scrolled into view). expect(grid.state.scrollLeft).toEqual(1050); // 100 rows * 20 item height = 2,000 total item height // 5 rows can be visible at a time and :scrollTop is initially 0, // So the minimum amount of scrolling leaves the 50th item at the bottom (just scrolled into view). expect(grid.state.scrollTop).toEqual(900); // Change column without affecting row grid.scrollToCell({ columnIndex: 49 }); expect(grid.state.scrollLeft).toEqual(2300); expect(grid.state.scrollTop).toEqual(900); // Change row without affecting column grid.scrollToCell({ rowIndex: 99 }); expect(grid.state.scrollLeft).toEqual(2300); expect(grid.state.scrollTop).toEqual(1900); }); it('should support scrollToPosition() public method', function () { var grid = render(getMarkup()); expect(grid.state.scrollLeft).toEqual(0); expect(grid.state.scrollTop).toEqual(0); grid.scrollToPosition({ scrollLeft: 50, scrollTop: 100 }); expect(grid.state.scrollLeft).toEqual(50); expect(grid.state.scrollTop).toEqual(100); // Change column without affecting row grid.scrollToPosition({ scrollLeft: 25 }); expect(grid.state.scrollLeft).toEqual(25); expect(grid.state.scrollTop).toEqual(100); // Change row without affecting column grid.scrollToPosition({ scrollTop: 50 }); expect(grid.state.scrollLeft).toEqual(25); expect(grid.state.scrollTop).toEqual(50); }); it('should support handleScrollEvent() public method', function () { var grid = render(getMarkup()); expect(grid.state.scrollLeft).toEqual(0); expect(grid.state.scrollTop).toEqual(0); grid.handleScrollEvent({ scrollLeft: 50, scrollTop: 100 }); expect(grid.state.isScrolling).toEqual(true); expect(grid.state.scrollLeft).toEqual(50); expect(grid.state.scrollTop).toEqual(100); }); it('should support getOffsetForCell() public method', function () { var grid = render(getMarkup()); var _grid$getOffsetForCel = grid.getOffsetForCell({ columnIndex: 24, rowIndex: 49 }), scrollLeft = _grid$getOffsetForCel.scrollLeft, scrollTop = _grid$getOffsetForCel.scrollTop; // 50 columns * 50 item width = 2,500 total item width // 4 columns can be visible at a time and :scrollLeft is initially 0, // So the minimum amount of scrolling leaves the 25th item at the right (just scrolled into view). expect(scrollLeft).toEqual(1050); // 100 rows * 20 item height = 2,000 total item height // 5 rows can be visible at a time and :scrollTop is initially 0, // So the minimum amount of scrolling leaves the 50th item at the bottom (just scrolled into view). expect(scrollTop).toEqual(900); }); it('should support getTotalRowsHeight() public method', function () { var grid = render(getMarkup()); grid.recomputeGridSize(); var totalHeight = grid.getTotalRowsHeight(); // 100 rows * 20 item height = 2,000 total item height expect(totalHeight).toEqual(2000); }); it('should support getTotalColumnsWidth() public method', function () { var grid = render(getMarkup()); grid.recomputeGridSize(); var totalWidth = grid.getTotalColumnsWidth(); // 50 columns * 50 item width = 2,500 total item width expect(totalWidth).toEqual(2500); }); // See issue #565 it('should update scroll position to account for changed cell sizes within a function prop wrapper', function () { var _rowHeight = 20; var props = { height: 100, rowCount: 100, rowHeight: function rowHeight(_ref4) { var index = _ref4.index; return index === 99 ? _rowHeight : 20; }, scrollToRow: 99 }; var grid = render(getMarkup(props)); var node = findDOMNode(grid); expect(node.scrollTop).toBe(1900); _rowHeight = 40; grid.recomputeGridSize({ rowIndex: 99 }); expect(node.scrollTop).toBe(1920); }); it('should not restore scrollLeft when scrolling left and recomputeGridSize with columnIndex smaller than scrollToColumn', function () { var props = { columnWidth: 50, columnCount: 100, height: 100, rowCount: 100, rowHeight: 20, scrollToColumn: 50, scrollToRow: 50, width: 100 }; var grid = render(getMarkup(props)); expect(grid.state.scrollLeft).toEqual(2450); simulateScroll({ grid: grid, scrollLeft: 2250 }); expect(grid.state.scrollLeft).toEqual(2250); expect(grid.state.scrollDirectionHorizontal).toEqual(SCROLL_DIRECTION_BACKWARD); grid.recomputeGridSize({ columnIndex: 30 }); expect(grid.state.scrollLeft).toEqual(2250); }); it('should not restore scrollTop when scrolling up and recomputeGridSize with rowIndex smaller than scrollToRow', function () { var props = { columnWidth: 50, columnCount: 100, height: 100, rowCount: 100, rowHeight: 20, scrollToColumn: 50, scrollToRow: 50, width: 100 }; var grid = render(getMarkup(props)); expect(grid.state.scrollTop).toEqual(920); simulateScroll({ grid: grid, scrollTop: 720 }); expect(grid.state.scrollTop).toEqual(720); expect(grid.state.scrollDirectionVertical).toEqual(SCROLL_DIRECTION_BACKWARD); grid.recomputeGridSize({ rowIndex: 20 }); expect(grid.state.scrollTop).toEqual(720); }); it('should restore scroll offset for column when row count increases from 0 (and vice versa)', function () { var props = { columnWidth: 50, columnCount: 100, height: 100, rowCount: 100, rowHeight: 20, scrollToColumn: 50, scrollToRow: 50, width: 100 }; var grid = render(getMarkup(props)); expect(grid.state.scrollLeft).toEqual(2450); expect(grid.state.scrollTop).toEqual(920); render(getMarkup(_objectSpread({}, props, { columnCount: 0 }))); expect(grid.state.scrollLeft).toEqual(0); expect(grid.state.scrollTop).toEqual(0); render(getMarkup(props)); expect(grid.state.scrollLeft).toEqual(2450); expect(grid.state.scrollTop).toEqual(920); render(getMarkup(_objectSpread({}, props, { rowCount: 0 }))); expect(grid.state.scrollLeft).toEqual(0); expect(grid.state.scrollTop).toEqual(0); render(getMarkup(props)); expect(grid.state.scrollLeft).toEqual(2450); expect(grid.state.scrollTop).toEqual(920); }); it('should take scrollbar size into account when aligning cells', function () { var grid = render(getMarkup({ columnWidth: 50, columnCount: 100, getScrollbarSize: getScrollbarSize20, height: 100, rowCount: 100, rowHeight: 20, scrollToColumn: 50, scrollToRow: 50, width: 100 })); expect(grid.state.scrollLeft).toEqual(2450 + getScrollbarSize20()); expect(grid.state.scrollTop).toEqual(920 + getScrollbarSize20()); }); }); describe('property updates', function () { it('should update :scrollToColumn position when :columnWidth changes', function () { var grid = findDOMNode(render(getMarkup({ scrollToColumn: 25 }))); expect(grid.textContent).toContain('column:25'); // Making columns taller pushes name off/beyond the scrolled area grid = findDOMNode(render(getMarkup({ scrollToColumn: 25, columnWidth: 20 }))); expect(grid.textContent).toContain('column:25'); }); it('should update :scrollToRow position when :rowHeight changes', function () { var grid = findDOMNode(render(getMarkup({ scrollToRow: 50 }))); expect(grid.textContent).toContain('row:50'); // Making rows taller pushes name off/beyond the scrolled area grid = findDOMNode(render(getMarkup({ scrollToRow: 50, rowHeight: 20 }))); expect(grid.textContent).toContain('row:50'); }); it('should update :scrollToColumn position when :width changes', function () { var grid = findDOMNode(render(getMarkup({ scrollToColumn: 25 }))); expect(grid.textContent).toContain('column:25'); // Making the grid narrower leaves only room for 1 item grid = findDOMNode(render(getMarkup({ scrollToColumn: 25, width: 50 }))); expect(grid.textContent).toContain('column:25'); }); it('should update :scrollToRow position when :height changes', function () { var grid = findDOMNode(render(getMarkup({ scrollToRow: 50 }))); expect(grid.textContent).toContain('row:50'); // Making the grid shorter leaves only room for 1 item grid = findDOMNode(render(getMarkup({ scrollToRow: 50, height: 20 }))); expect(grid.textContent).toContain('row:50'); }); it('should update :scrollToColumn position when :scrollToColumn changes', function () { var grid = findDOMNode(render(getMarkup())); expect(grid.textContent).not.toContain('column:25'); grid = findDOMNode(render(getMarkup({ scrollToColumn: 25 }))); expect(grid.textContent).toContain('column:25'); }); it('should update :scrollToRow position when :scrollToRow changes', function () { var grid = findDOMNode(render(getMarkup())); expect(grid.textContent).not.toContain('row:50'); grid = findDOMNode(render(getMarkup({ scrollToRow: 50 }))); expect(grid.textContent).toContain('row:50'); }); it('should update scroll position if size shrinks smaller than the current scroll', function () { var grid = findDOMNode(render(getMarkup({ scrollToColumn: 250 }))); grid = findDOMNode(render(getMarkup())); grid = findDOMNode(render(getMarkup({ scrollToColumn: 250, columnCount: 10 }))); expect(grid.textContent).toContain('column:9'); }); it('should update scroll position if size shrinks smaller than the current scroll', function () { var grid = findDOMNode(render(getMarkup({ scrollToRow: 500 }))); grid = findDOMNode(render(getMarkup())); grid = findDOMNode(render(getMarkup({ scrollToRow: 500, rowCount: 10 }))); expect(grid.textContent).toContain('row:9'); }); }); describe('noContentRenderer', function () { it('should call :noContentRenderer if :columnCount is 0', function () { var list = findDOMNode(render(getMarkup({ noContentRenderer: function noContentRenderer() { return React.createElement("div", null, "No data"); }, columnCount: 0 }))); expect(list.textContent).toEqual('No data'); }); it('should call :noContentRenderer if :rowCount is 0', function () { var list = findDOMNode(render(getMarkup({ noContentRenderer: function noContentRenderer() { return React.createElement("div", null, "No data"); }, rowCount: 0 }))); expect(list.textContent).toEqual('No data'); }); // Sanity check for bvaughn/react-virtualized/pull/348 it('should render an empty body if :rowCount or :columnCount changes to 0', function () { function noContentRenderer() { return React.createElement("div", null, "No data"); } var list = findDOMNode(render(getMarkup({ noContentRenderer: noContentRenderer }))); expect(list.textContent).not.toEqual('No data'); list = findDOMNode(render(getMarkup({ noContentRenderer: noContentRenderer, rowCount: 0 }))); expect(list.textContent).toEqual('No data'); list = findDOMNode(render(getMarkup({ noContentRenderer: noContentRenderer }))); expect(list.textContent).not.toEqual('No data'); list = findDOMNode(render(getMarkup({ columnCount: 0, noContentRenderer: noContentRenderer }))); expect(list.textContent).toEqual('No data'); }); it('should render an empty body if :columnCount is 0 and there is no :noContentRenderer', function () { var list = findDOMNode(render(getMarkup({ columnCount: 0 }))); expect(list.textContent).toEqual(''); }); it('should render an empty body if :rowCount is 0 and there is no :noContentRenderer', function () { var list = findDOMNode(render(getMarkup({ rowCount: 0 }))); expect(list.textContent).toEqual(''); }); it('should render an empty body there is a :noContentRenderer but :height or :width are 0', function () { var list = findDOMNode(render(getMarkup({ height: 0, noContentRenderer: function noContentRenderer() { return React.createElement("div", null, "No data"); } }))); expect(list.textContent).toEqual(''); list = findDOMNode(render(getMarkup({ noContentRenderer: function noContentRenderer() { return React.createElement("div", null, "No data"); }, width: 0 }))); expect(list.textContent).toEqual(''); }); }); describe('onSectionRendered', function () { it('should call :onSectionRendered if at least one cell is rendered', function () { var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex; render(getMarkup({ onSectionRendered: function onSectionRendered(params) { var _params; return _params = params, columnStartIndex = _params.columnStartIndex, columnStopIndex = _params.columnStopIndex, rowStartIndex = _params.rowStartIndex, rowStopIndex = _params.rowStopIndex, _params; } })); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(3); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(4); }); it('should not call :onSectionRendered unless the column or row start or stop indices have changed', function () { var numCalls = 0; var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex; var onSectionRendered = function onSectionRendered(params) { columnStartIndex = params.columnStartIndex; columnStopIndex = params.columnStopIndex; rowStartIndex = params.rowStartIndex; rowStopIndex = params.rowStopIndex; numCalls++; }; render(getMarkup({ onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(1); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(3); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(4); render(getMarkup({ onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(1); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(3); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(4); }); it('should call :onSectionRendered if the row or column start or stop indices have changed', function () { var numCalls = 0; var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex; var onSectionRendered = function onSectionRendered(params) { columnStartIndex = params.columnStartIndex; columnStopIndex = params.columnStopIndex; rowStartIndex = params.rowStartIndex; rowStopIndex = params.rowStopIndex; numCalls++; }; render(getMarkup({ onSectionRendered: onSectionRendered })); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(3); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(4); render(getMarkup({ height: 50, onSectionRendered: onSectionRendered })); expect(numCalls).toEqual(2); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(3); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(2); render(getMarkup({ height: 50, onSectionRendered: onSectionRendered, width: 100 })); expect(numCalls).toEqual(3); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(1); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(2); }); it('should not call :onSectionRendered if no cells are rendered', function () { var numCalls = 0; render(getMarkup({ height: 0, onSectionRendered: function onSectionRendered() { return numCalls++; } })); expect(numCalls).toEqual(0); }); }); describe(':scrollLeft and :scrollTop properties', function () { it('should render correctly when an initial :scrollLeft and :scrollTop properties are specified', function () { var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex; findDOMNode(render(getMarkup({ onSectionRendered: function onSectionRendered(params) { var _params2; return _params2 = params, columnStartIndex = _params2.columnStartIndex, columnStopIndex = _params2.columnStopIndex, rowStartIndex = _params2.rowStartIndex, rowStopIndex = _params2.rowStopIndex, _params2; }, scrollLeft: 250, scrollTop: 100 }))); expect(rowStartIndex).toEqual(5); expect(rowStopIndex).toEqual(9); expect(columnStartIndex).toEqual(5); expect(columnStopIndex).toEqual(8); }); it('should render correctly when :scrollLeft and :scrollTop properties are updated', function () { var columnStartIndex, columnStopIndex, rowStartIndex, rowStopIndex; render(getMarkup({ onSectionRendered: function onSectionRendered(params) { var _params3; return _params3 = params, columnStartIndex = _params3.columnStartIndex, columnStopIndex = _params3.columnStopIndex, rowStartIndex = _params3.rowStartIndex, rowStopIndex = _params3.rowStopIndex, _params3; } })); expect(rowStartIndex).toEqual(0); expect(rowStopIndex).toEqual(4); expect(columnStartIndex).toEqual(0); expect(columnStopIndex).toEqual(3); render(getMarkup({ onSectionRendered: function onSectionRendered(params) { var _params4; return _params4 = params, columnStartIndex = _params4.columnStartIndex, columnStopIndex = _params4.columnStopIndex, rowStartIndex = _params4.rowStartIndex, rowStopIndex = _params4.rowStopIndex, _params4; }, scrollLeft: 250, scrollTop: 100 })); expect(rowStartIndex).toEqual(5); expect(rowStopIndex).toEqual(9); expect(columnStartIndex).toEqual(5); expect(columnStopIndex).toEqual(8); }); }); describe('styles, classNames, and ids', function () { it('should use the expected global CSS classNames', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.className).toEqual('ReactVirtualized__Grid'); }); it('should use a custom :className if specified', function () { var rendered = findDOMNode(render(getMarkup({ className: 'foo' }))); expect(rendered.className).toContain('foo'); }); it('should use a custom :id if specified', function () { var rendered = findDOMNode(render(getMarkup({ id: 'bar' }))); expect(rendered.getAttribute('id')).toEqual('bar'); }); it('should use a custom :style if specified', function () { var style = { backgroundColor: 'red' }; var rendered = findDOMNode(render(getMarkup({ style: style }))); expect(rendered.style.backgroundColor).toEqual('red'); }); it('should use a custom :containerStyle if specified', function () { var containerStyle = { backgroundColor: 'red' }; var rendered = findDOMNode(render(getMarkup({ containerStyle: containerStyle }))); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.backgroundColor).toEqual('red'); }); }); describe('onScroll', function () { it('should trigger callback when component is mounted', function () { var onScrollCalls = []; render(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); }, scrollLeft: 50, scrollTop: 100 })); expect(onScrollCalls).toEqual([{ clientHeight: 100, clientWidth: 200, scrollHeight: 2000, scrollLeft: 50, scrollTop: 100, scrollWidth: 2500 }]); }); it('should trigger callback when component scrolls horizontally', function () { var onScrollCalls = []; var grid = render(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); simulateScroll({ grid: grid, scrollLeft: 100, scrollTop: 0 }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: 100, clientWidth: 200, scrollHeight: 2000, scrollLeft: 100, scrollTop: 0, scrollWidth: 2500 }); }); it('should trigger callback when component scrolls vertically', function () { var onScrollCalls = []; var grid = render(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); } })); simulateScroll({ grid: grid, scrollLeft: 0, scrollTop: 100 }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: 100, clientWidth: 200, scrollHeight: 2000, scrollLeft: 0, scrollTop: 100, scrollWidth: 2500 }); }); it('should trigger callback with scrollLeft of 0 when total columns width is less than width', function () { var onScrollCalls = []; var grid = render(getMarkup({ columnCount: 1, columnWidth: 50, onScroll: function onScroll(params) { return onScrollCalls.push(params); }, scrollLeft: 0, scrollTop: 10, width: 200 })); simulateScroll({ grid: grid, scrollLeft: 0, scrollTop: 0 }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: 100, clientWidth: 200, scrollHeight: 2000, scrollLeft: 0, scrollTop: 0, scrollWidth: 50 }); }); it('should trigger callback with scrollTop of 0 when total rows height is less than height', function () { var onScrollCalls = []; var grid = render(getMarkup({ rowCount: 1, rowHeight: 50, onScroll: function onScroll(params) { return onScrollCalls.push(params); }, scrollLeft: 0, scrollTop: 10, height: 200 })); simulateScroll({ grid: grid, scrollLeft: 0, scrollTop: 0 }); expect(onScrollCalls.length).toEqual(2); expect(onScrollCalls[1]).toEqual({ clientHeight: 200, clientWidth: 200, scrollHeight: 50, scrollLeft: 0, scrollTop: 0, scrollWidth: 2500 }); }); // Support use-cases like WindowScroller; enable them to stay in sync with scroll-to-cell changes. it('should trigger when :scrollToColumn or :scrollToRow are changed via props', function () { var onScrollCalls = []; render(getMarkup()); render(getMarkup({ onScroll: function onScroll(params) { return onScrollCalls.push(params); }, scrollToColumn: 24, scrollToRow: 49 })); expect(onScrollCalls).toEqual([{ clientHeight: 100, clientWidth: 200, scrollHeight: 2000, scrollLeft: 1050, scrollTop: 900, scrollWidth: 2500 }]); }); }); describe('overscanColumnCount & overscanRowCount', function () { function createHelper() { var _columnOverscanStartIndex, _columnOverscanStopIndex, _columnStartIndex, _columnStopIndex, _rowOverscanStartIndex, _rowOverscanStopIndex, _rowStartIndex, _rowStopIndex; function onSectionRendered(params) { _columnOverscanStartIndex = params.columnOverscanStartIndex; _columnOverscanStopIndex = params.columnOverscanStopIndex; _columnStartIndex = params.columnStartIndex; _columnStopIndex = params.columnStopIndex; _rowOverscanStartIndex = params.rowOverscanStartIndex; _rowOverscanStopIndex = params.rowOverscanStopIndex; _rowStartIndex = params.rowStartIndex; _rowStopIndex = params.rowStopIndex; } return { columnOverscanStartIndex: function columnOverscanStartIndex() { return _columnOverscanStartIndex; }, columnOverscanStopIndex: function columnOverscanStopIndex() { return _columnOverscanStopIndex; }, columnStartIndex: function columnStartIndex() { return _columnStartIndex; }, columnStopIndex: function columnStopIndex() { return _columnStopIndex; }, onSectionRendered: onSectionRendered, rowOverscanStartIndex: function rowOverscanStartIndex() { return _rowOverscanStartIndex; }, rowOverscanStopIndex: function rowOverscanStopIndex() { return _rowOverscanStopIndex; }, rowStartIndex: function rowStartIndex() { return _rowStartIndex; }, rowStopIndex: function rowStopIndex() { return _rowStopIndex; } }; } it('should not overscan if disabled', function () { var helper = createHelper(); render(getMarkup({ onSectionRendered: helper.onSectionRendered })); expect(helper.columnOverscanStartIndex()).toEqual(helper.columnStartIndex()); expect(helper.columnOverscanStopIndex()).toEqual(helper.columnStopIndex()); expect(helper.rowOverscanStartIndex()).toEqual(helper.rowStartIndex()); expect(helper.rowOverscanStopIndex()).toEqual(helper.rowStopIndex()); }); it('should overscan the specified amount', function () { var helper = createHelper(); render(getMarkup({ onSectionRendered: helper.onSectionRendered, overscanColumnCount: 2, overscanRowCount: 5, scrollToColumn: 25, scrollToRow: 50 })); expect(helper.columnOverscanStartIndex()).toEqual(22); expect(helper.columnOverscanStopIndex()).toEqual(27); expect(helper.columnStartIndex()).toEqual(22); expect(helper.columnStopIndex()).toEqual(25); expect(helper.rowOverscanStartIndex()).toEqual(46); expect(helper.rowOverscanStopIndex()).toEqual(55); expect(helper.rowStartIndex()).toEqual(46); expect(helper.rowStopIndex()).toEqual(50); }); it('should not overscan beyond the bounds of the grid', function () { var helper = createHelper(); render(getMarkup({ onSectionRendered: helper.onSectionRendered, columnCount: 6, overscanColumnCount: 10, overscanRowCount: 10, rowCount: 5 })); expect(helper.columnOverscanStartIndex()).toEqual(0); expect(helper.columnOverscanStopIndex()).toEqual(5); expect(helper.columnStartIndex()).toEqual(0); expect(helper.columnStopIndex()).toEqual(3); expect(helper.rowOverscanStartIndex()).toEqual(0); expect(helper.rowOverscanStopIndex()).toEqual(4); expect(helper.rowStartIndex()).toEqual(0); expect(helper.rowStopIndex()).toEqual(4); }); it('should set the correct scroll direction', function () { // Do not pass in the initial state as props, otherwise the internal state is forbidden from updating itself var grid = render(getMarkup()); // Simulate a scroll to set the initial internal state simulateScroll({ grid: grid, scrollLeft: 50, scrollTop: 50 }); expect(grid.state.scrollDirectionHorizontal).toEqual(SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(SCROLL_DIRECTION_FORWARD); simulateScroll({ grid: grid, scrollLeft: 0, scrollTop: 0 }); expect(grid.state.scrollDirectionHorizontal).toEqual(SCROLL_DIRECTION_BACKWARD); expect(grid.state.scrollDirectionVertical).toEqual(SCROLL_DIRECTION_BACKWARD); simulateScroll({ grid: grid, scrollLeft: 100, scrollTop: 100 }); expect(grid.state.scrollDirectionHorizontal).toEqual(SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(SCROLL_DIRECTION_FORWARD); }); it('should set the correct scroll direction when scroll position is updated from props', function () { var grid = render(getMarkup({ scrollLeft: 50, scrollTop: 50 })); expect(grid.state.scrollDirectionHorizontal).toEqual(SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(SCROLL_DIRECTION_FORWARD); grid = render(getMarkup({ scrollLeft: 0, scrollTop: 0 })); expect(grid.state.scrollDirectionHorizontal).toEqual(SCROLL_DIRECTION_BACKWARD); expect(grid.state.scrollDirectionVertical).toEqual(SCROLL_DIRECTION_BACKWARD); grid = render(getMarkup({ scrollLeft: 100, scrollTop: 100 })); expect(grid.state.scrollDirectionHorizontal).toEqual(SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(SCROLL_DIRECTION_FORWARD); }); it('should not reset scroll direction for one axis when scrolled in another', function () { // Do not pass in the initial state as props, otherwise the internal state is forbidden from updating itself var grid = render(getMarkup()); // Simulate a scroll to set the initial internal state simulateScroll({ grid: grid, scrollLeft: 0, scrollTop: 5 }); expect(grid.state.scrollDirectionHorizontal).toEqual(SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(SCROLL_DIRECTION_FORWARD); simulateScroll({ grid: grid, scrollLeft: 5, scrollTop: 5 }); expect(grid.state.scrollDirectionHorizontal).toEqual(SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(SCROLL_DIRECTION_FORWARD); simulateScroll({ grid: grid, scrollLeft: 5, scrollTop: 0 }); expect(grid.state.scrollDirectionHorizontal).toEqual(SCROLL_DIRECTION_FORWARD); expect(grid.state.scrollDirectionVertical).toEqual(SCROLL_DIRECTION_BACKWARD); simulateScroll({ grid: grid, scrollLeft: 0, scrollTop: 0 }); expect(grid.state.scrollDirectionHorizontal).toEqual(SCROLL_DIRECTION_BACKWARD); expect(grid.state.scrollDirectionVertical).toEqual(SCROLL_DIRECTION_BACKWARD); }); it('should overscan in the direction being scrolled', function _callee(done) { var helper, onSectionRenderedResolve, onSectionRendered, grid, onSectionRenderedPromise; return _regeneratorRuntime.async(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: onSectionRendered = function _ref5(params) { helper.onSectionRendered(params); if (onSectionRenderedResolve) { onSectionRenderedResolve(); } }; helper = createHelper(); grid = render(getMarkup({ onSectionRendered: onSectionRendered, overscanColumnCount: 2, overscanRowCount: 5 })); // Wait until the onSectionRendered handler / debouncer has processed onSectionRenderedPromise = new Promise(function (resolve) { onSectionRenderedResolve = resolve; }); simulateScroll({ grid: grid, scrollLeft: 200, scrollTop: 200 }); _context.next = 7; return _regeneratorRuntime.awrap(onSectionRenderedPromise); case 7: // It should overscan in the direction being scrolled while scroll is in progress expect(helper.columnOverscanStartIndex()).toEqual(4); expect(helper.columnOverscanStopIndex()).toEqual(9); expect(helper.columnStartIndex()).toEqual(4); expect(helper.columnStopIndex()).toEqual(7); expect(helper.rowOverscanStartIndex()).toEqual(10); expect(helper.rowOverscanStopIndex()).toEqual(19); expect(helper.rowStartIndex()).toEqual(10); expect(helper.rowStopIndex()).toEqual(14); // Wait until the onSectionRendered handler / debouncer has processed onSectionRenderedPromise = new Promise(function (resolve) { onSectionRenderedResolve = resolve; }); simulateScroll({ grid: grid, scrollLeft: 100, scrollTop: 100 }); _context.next = 19; return _regeneratorRuntime.awrap(onSectionRenderedPromise); case 19: // It reset overscan once scrolling has finished expect(helper.columnOverscanStartIndex()).toEqual(0); expect(helper.columnOverscanStopIndex()).toEqual(5); expect(helper.columnStartIndex()).toEqual(2); expect(helper.columnStopIndex()).toEqual(5); expect(helper.rowOverscanStartIndex()).toEqual(0); expect(helper.rowOverscanStopIndex()).toEqual(9); expect(helper.rowStartIndex()).toEqual(5); expect(helper.rowStopIndex()).toEqual(9); done(); case 28: case "end": return _context.stop(); } } }); }); }); describe('cellRangeRenderer', function () { it('should use a custom :cellRangeRenderer if specified', function () { var cellRangeRendererCalled = 0; var cellRangeRendererParams; var rendered = findDOMNode(render(getMarkup({ cellRangeRenderer: function cellRangeRenderer(params) { cellRangeRendererParams = params; cellRangeRendererCalled++; return [React.createElement("div", { key: "0" }, "Fake content")]; } }))); expect(cellRangeRendererCalled).toEqual(1); expect(cellRangeRendererParams.columnStartIndex).toEqual(0); expect(cellRangeRendererParams.columnStopIndex).toEqual(3); expect(cellRangeRendererParams.rowStartIndex).toEqual(0); expect(cellRangeRendererParams.rowStopIndex).toEqual(4); expect(rendered.textContent).toContain('Fake content'); }); }); describe('estimated row and column sizes', function () { it('should not estimate sizes if actual sizes are numbers', function () { var grid = render(getMarkup({ columnWidth: 100, estimatedColumnSize: 150, estimatedRowSize: 15, rowHeight: 20 })); expect(Grid._getEstimatedColumnSize(grid.props)).toEqual(100); expect(Grid._getEstimatedRowSize(grid.props)).toEqual(20); }); it('should estimate row and column sizes if actual sizes are functions', function () { var grid = render(getMarkup({ columnWidth: function columnWidth() { return 100; }, estimatedColumnSize: 150, estimatedRowSize: 15, rowHeight: function rowHeight() { return 20; } })); expect(Grid._getEstimatedColumnSize(grid.props)).toEqual(150); expect(Grid._getEstimatedRowSize(grid.props)).toEqual(15); }); }); it('should pass the cellRenderer an :isScrolling flag when scrolling is in progress', function _callee2(done) { var cellRendererCalls, cellRenderer, grid; return _regeneratorRuntime.async(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: cellRenderer = function _ref7(_ref6) { var columnIndex = _ref6.columnIndex, isScrolling = _ref6.isScrolling, key = _ref6.key, rowIndex = _ref6.rowIndex, style = _ref6.style; cellRendererCalls.push(isScrolling); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); }; cellRendererCalls = []; grid = render(getMarkup({ cellRenderer: cellRenderer })); expect(cellRendererCalls[0]).toEqual(false); cellRendererCalls.splice(0); // Give React time to process the queued setState() _context2.next = 7; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, 1); })); case 7: simulateScroll({ grid: grid, scrollTop: 100 }); expect(cellRendererCalls[0]).toEqual(true); done(); case 10: case "end": return _context2.stop(); } } }); }); it('should pass the cellRenderer an :isScrolling flag based on props override', function () { var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (_ref8) { var key = _ref8.key, style = _ref8.style; return React.createElement("div", { key: key, style: style }); }); render(getMarkup({ cellRenderer: cellRenderer, isScrolling: true })); expect(cellRenderer).toHaveBeenCalled(); expect(cellRenderer.mock.calls[0][0].isScrolling).toBe(true); cellRenderer.mockReset(); render(getMarkup({ cellRenderer: cellRenderer, isScrolling: false, width: DEFAULT_WIDTH + 1 })); expect(cellRenderer).toHaveBeenCalled(); expect(cellRenderer.mock.calls[0][0].isScrolling).toBe(false); }); it('should pass the cellRenderer an :isVisible flag', function () { var cellRendererCalls = []; function cellRenderer(props) { cellRendererCalls.push(props); return defaultCellRenderer(props); } render(getMarkup({ cellRenderer: cellRenderer, height: DEFAULT_ROW_HEIGHT, overscanColumnCount: 1, overscanRowCount: 1, width: DEFAULT_COLUMN_WIDTH })); cellRendererCalls.forEach(function (props) { expect(props.isVisible).toEqual(props.columnIndex === 0 && props.rowIndex === 0); // Only the first cell is visible }); }); describe('cell caching', function () { it('should not cache cells if the Grid is not scrolling', function () { var cellRendererCalls = []; function cellRenderer(_ref9) { var columnIndex = _ref9.columnIndex, key = _ref9.key, rowIndex = _ref9.rowIndex, style = _ref9.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, scrollToRow: 0, width: 100 }; render(getMarkup(_objectSpread({}, props, { scrollToRow: 0 }))); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); cellRendererCalls.splice(0); render(getMarkup(_objectSpread({}, props, { scrollToRow: 1 }))); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); }); it('should not cache cells if the offsets are not adjusted', function () { var cellRendererCalls = []; function cellRenderer(_ref10) { var columnIndex = _ref10.columnIndex, key = _ref10.key, rowIndex = _ref10.rowIndex, style = _ref10.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, rowCount: 100000, scrollToRow: 0, width: 100 }; render(getMarkup(_objectSpread({}, props, { scrollToRow: 0 }))); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); cellRendererCalls.splice(0); render(getMarkup(_objectSpread({}, props, { scrollToRow: 1 }))); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); }); it('should cache a cell once it has been rendered while scrolling', function () { var cellRendererCalls = []; function cellRenderer(_ref11) { var columnIndex = _ref11.columnIndex, key = _ref11.key, rowIndex = _ref11.rowIndex, style = _ref11.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, width: 100 }; var grid = render(getMarkup(_objectSpread({}, props, { scrollToRow: 0 }))); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); simulateScroll({ grid: grid, scrollTop: 1 }); cellRendererCalls.splice(0); // Rows 0-2 have already rendered but row 3 is not yet visible // This means that only row 3 should be newly-created // The others should come from the cache render(getMarkup(_objectSpread({}, props, { scrollToRow: 3 }))); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 3 }]); }); it('should clear cache once :isScrolling is false', function _callee3(done) { var cellRendererCalls, cellRenderer, props, grid; return _regeneratorRuntime.async(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: cellRenderer = function _ref13(_ref12) { var columnIndex = _ref12.columnIndex, key = _ref12.key, rowIndex = _ref12.rowIndex, style = _ref12.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); }; cellRendererCalls = []; props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, scrollToRow: 0, width: 100 }; grid = render(getMarkup(props)); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); simulateScroll({ grid: grid, scrollTop: 1 }); // Allow scrolling timeout to complete so that cell cache is reset _context3.next = 8; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, DEFAULT_SCROLLING_RESET_TIME_INTERVAL * 2); })); case 8: cellRendererCalls.splice(0); render(getMarkup(_objectSpread({}, props, { scrollToRow: 1 }))); expect(cellRendererCalls.length).not.toEqual(0); done(); case 12: case "end": return _context3.stop(); } } }); }); it('should clear cache once :isScrolling via props is false', function _callee4() { var cellRenderer, props, scrollingStyle; return _regeneratorRuntime.async(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (params) { return React.createElement("div", { key: params.key, style: params.style }); }); props = { autoHeight: true, cellRenderer: cellRenderer, columnCount: 1, isScrolling: true, rowCount: 1 }; render(getMarkup(props)); render(getMarkup(props)); expect(cellRenderer).toHaveBeenCalledTimes(1); // Due to cell cache scrollingStyle = cellRenderer.mock.calls[0][0].style; cellRenderer.mockReset(); render(getMarkup(_objectSpread({}, props, { isScrolling: false }))); expect(cellRenderer.mock.calls[0][0].style).toBe(scrollingStyle); expect(cellRenderer).toHaveBeenCalledTimes(1); // Reset cache cellRenderer.mockReset(); render(getMarkup(_objectSpread({}, props, { isScrolling: true }))); expect(cellRenderer.mock.calls[0][0].style).not.toBe(scrollingStyle); expect(cellRenderer).toHaveBeenCalledTimes(1); // Only cached when scrolling case 15: case "end": return _context4.stop(); } } }); }); it('should clear cache if :recomputeGridSize is called', function () { var cellRendererCalls = []; function cellRenderer(_ref14) { var columnIndex = _ref14.columnIndex, key = _ref14.key, rowIndex = _ref14.rowIndex, style = _ref14.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, scrollTop: 0, width: 100 }; var grid = render(getMarkup(props)); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); simulateScroll({ grid: grid, scrollTop: 1 }); cellRendererCalls.splice(0); grid.recomputeGridSize(); expect(cellRendererCalls.length).not.toEqual(0); }); it('should not clear cache if :isScrollingOptOut is true', function () { var cellRendererCalls = []; function cellRenderer(_ref15) { var columnIndex = _ref15.columnIndex, key = _ref15.key, rowIndex = _ref15.rowIndex, style = _ref15.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, scrollTop: 0, width: 100, isScrollingOptOut: true }; render(getMarkup(props)); render(getMarkup(props)); expect(cellRendererCalls).toEqual([{ columnIndex: 0, rowIndex: 0 }, { columnIndex: 0, rowIndex: 1 }]); cellRendererCalls.splice(0); render(getMarkup(_objectSpread({}, props, { isScrolling: false }))); // Visible cells are cached expect(cellRendererCalls.length).toEqual(0); render(getMarkup(_objectSpread({}, props, { isScrolling: true }))); // Only cleared non-visible cells expect(cellRendererCalls.length).toEqual(0); }); it('should not trigger render by _debounceScrollEndedCallback if process slow table', function _callee5() { var scrollingResetTimeInterval, cellRangeRendererCalls, cellRangeRenderer, props, grid, i; return _regeneratorRuntime.async(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: cellRangeRenderer = function _ref16(props) { var startTime = Date.now(); while (Date.now() - startTime <= scrollingResetTimeInterval) { ; } // imitate very slow render cellRangeRendererCalls++; return defaultCellRangeRenderer(props); }; scrollingResetTimeInterval = 50; cellRangeRendererCalls = 0; props = { scrollingResetTimeInterval: scrollingResetTimeInterval, cellRangeRenderer: cellRangeRenderer }; grid = render(getMarkup(props)); render(getMarkup(props)); expect(cellRangeRendererCalls).toEqual(1); i = 1; case 8: if (!(i <= 5)) { _context5.next = 17; break; } cellRangeRendererCalls = 0; simulateScroll({ grid: grid, scrollTop: i }); // small wait for maybe early _debounceScrollEndedCallback _context5.next = 13; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, scrollingResetTimeInterval / 2); })); case 13: expect(cellRangeRendererCalls).toEqual(1); case 14: i++; _context5.next = 8; break; case 17: cellRangeRendererCalls = 0; // wait for real _debounceScrollEndedCallback _context5.next = 20; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, scrollingResetTimeInterval * 1.5); })); case 20: expect(cellRangeRendererCalls).toEqual(1); case 21: case "end": return _context5.stop(); } } }); }); it('should support a custom :scrollingResetTimeInterval prop', function _callee6(done) { var cellRendererCalls, scrollingResetTimeInterval, cellRenderer, props, grid; return _regeneratorRuntime.async(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: cellRenderer = function _ref18(_ref17) { var columnIndex = _ref17.columnIndex, key = _ref17.key, rowIndex = _ref17.rowIndex, style = _ref17.style; cellRendererCalls.push({ columnIndex: columnIndex, rowIndex: rowIndex }); return defaultCellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, style: style }); }; cellRendererCalls = []; scrollingResetTimeInterval = DEFAULT_SCROLLING_RESET_TIME_INTERVAL * 2; props = { cellRenderer: cellRenderer, scrollingResetTimeInterval: scrollingResetTimeInterval }; grid = render(getMarkup(props)); expect(cellRendererCalls.length > 0).toEqual(true); simulateScroll({ grid: grid, scrollTop: 1 }); _context6.next = 9; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, DEFAULT_SCROLLING_RESET_TIME_INTERVAL); })); case 9: cellRendererCalls.splice(0); render(getMarkup(_objectSpread({}, props, { className: 'foo' }))); expect(cellRendererCalls.length).toEqual(0); _context6.next = 14; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, DEFAULT_SCROLLING_RESET_TIME_INTERVAL * 2); })); case 14: cellRendererCalls.splice(0); render(getMarkup(_objectSpread({}, props, { className: 'bar' }))); expect(cellRendererCalls.length).not.toEqual(0); done(); case 18: case "end": return _context6.stop(); } } }); }); }); describe('measureAllCells', function () { it('should measure any unmeasured columns and rows', function () { var grid = render(getMarkup({ columnCount: 10, columnWidth: function columnWidth() { return 100; }, estimatedColumnSize: 150, estimatedRowSize: 15, height: 0, rowCount: 10, rowHeight: function rowHeight() { return 20; }, width: 0 })); expect(grid.state.instanceProps.columnSizeAndPositionManager.getTotalSize()).toEqual(1500); expect(grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(150); grid.measureAllCells(); expect(grid.state.instanceProps.columnSizeAndPositionManager.getTotalSize()).toEqual(1000); expect(grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(200); }); }); describe('recomputeGridSize', function () { it('should recompute cell sizes and other values when called', function () { var columnIndices = []; var rowIndices = []; function columnWidth(_ref19) { var index = _ref19.index; columnIndices.push(index); return 10; } function rowHeight(_ref20) { var index = _ref20.index; rowIndices.push(index); return 10; } var props = { columnCount: 50, columnWidth: columnWidth, height: 50, rowHeight: rowHeight, rowCount: 50, width: 100 }; var component = render(getMarkup(props)); columnIndices.splice(0); rowIndices.splice(0); component.recomputeGridSize(); // Only the rows required to fill the current viewport will be rendered expect(columnIndices[0]).toEqual(0); expect(columnIndices[columnIndices.length - 1]).toEqual(9); expect(rowIndices[0]).toEqual(0); expect(rowIndices[rowIndices.length - 1]).toEqual(4); columnIndices.splice(0); rowIndices.splice(0); component.recomputeGridSize({ columnIndex: 4, rowIndex: 2 }); // Only the rows required to fill the current viewport will be rendered expect(columnIndices[0]).toEqual(4); expect(columnIndices[columnIndices.length - 1]).toEqual(9); expect(rowIndices[0]).toEqual(2); expect(rowIndices[rowIndices.length - 1]).toEqual(4); }); }); describe('autoContainerWidth', function () { it('should set the innerScrollContainer width to auto to better support single-column HOCs', function () { var props = { autoContainerWidth: true }; var rendered = findDOMNode(render(getMarkup(props))); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('auto'); }); it('should set the innerScrollContainer width to :totalColumnsWidth unless :autoContainerWidth', function () { var props = { autoContainerWidth: false }; var rendered = findDOMNode(render(getMarkup(props))); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('2500px'); // 50 columns x 50px }); }); describe('autoHeight', function () { it('should set the container height to auto to adjust to innerScrollContainer height', function () { var props = { autoHeight: true }; var rendered = findDOMNode(render(getMarkup(props))); expect(rendered.style.height).toEqual('auto'); }); it('should have container height still affecting number of rows rendered', function () { var props = { height: 500, autoHeight: true }; var rendered = findDOMNode(render(getMarkup(props))); expect(rendered.querySelectorAll('.gridItem').length).toEqual(100); // 25 rows x 4 columns }); it('should have innerScrollContainer height to be equal number of rows * rowHeight', function () { var props = { autoHeight: true }; var grid = render(getMarkup(props)); var rendered = findDOMNode(grid); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.height).toEqual('2000px'); // 100 rows * 20px rowHeight expect(grid.state.instanceProps.rowSizeAndPositionManager.getTotalSize()).toEqual(2000); }); }); describe('autoWidth', function () { it('should set the container width to auto to adjust to innerScrollContainer width', function () { var props = { autoWidth: true }; var rendered = findDOMNode(render(getMarkup(props))); expect(rendered.style.width).toEqual('auto'); }); it('should have container width still affecting number of columns rendered', function () { var props = { width: 500, autoWidth: true }; var rendered = findDOMNode(render(getMarkup(props))); expect(rendered.querySelectorAll('.gridItem').length).toEqual(50); // 5 rows x 10 columns }); it('should have innerScrollContainer width to be equal number of columns * columnWidth', function () { var props = { autoWidth: true }; var grid = render(getMarkup(props)); var rendered = findDOMNode(grid); expect(rendered.querySelector('.ReactVirtualized__Grid__innerScrollContainer').style.width).toEqual('2500px'); // 50 columns * 50px columnWidth expect(grid.state.instanceProps.columnSizeAndPositionManager.getTotalSize()).toEqual(2500); }); }); describe('tabIndex', function () { it('should be focusable by default', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.tabIndex).toEqual(0); }); it('should allow tabIndex to be overridden', function () { var rendered = findDOMNode(render(getMarkup({ tabIndex: -1 }))); expect(rendered.tabIndex).toEqual(-1); }); }); describe('role', function () { it('should have grid role by default', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.getAttribute('role')).toEqual('grid'); }); it('should allow role to be overridden', function () { var role = null; var rendered = findDOMNode(render(getMarkup({ role: role }))); expect(rendered.getAttribute('role')).toEqual(role); }); }); describe('pure', function () { it('should not re-render unless props have changed', function () { var cellRendererCalled = false; function cellRenderer(_ref21) { var key = _ref21.key, style = _ref21.style; cellRendererCalled = true; return React.createElement("div", { key: key, style: style }); } var markup = getMarkup({ cellRenderer: cellRenderer }); render(markup); expect(cellRendererCalled).toEqual(true); cellRendererCalled = false; render(markup); expect(cellRendererCalled).toEqual(false); }); it('should not re-render grid components if they extend PureComponent', function () { var componentUpdates = 0; var GridComponent = /*#__PURE__*/ function (_React$PureComponent) { _inherits(GridComponent, _React$PureComponent); function GridComponent() { _classCallCheck(this, GridComponent); return _possibleConstructorReturn(this, _getPrototypeOf(GridComponent).apply(this, arguments)); } _createClass(GridComponent, [{ key: "componentDidUpdate", value: function componentDidUpdate() { componentUpdates++; } }, { key: "render", value: function render() { var _this$props = this.props, columnIndex = _this$props.columnIndex, rowIndex = _this$props.rowIndex, style = _this$props.style; return React.createElement("div", { className: "gridItem", style: style }, "row:".concat(rowIndex, ", column:").concat(columnIndex)); } }]); return GridComponent; }(React.PureComponent); function cellRenderer(_ref22) { var columnIndex = _ref22.columnIndex, key = _ref22.key, rowIndex = _ref22.rowIndex, style = _ref22.style; return React.createElement(GridComponent, { key: key, columnIndex: columnIndex, rowIndex: rowIndex, style: style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 40, rowHeight: 20, scrollTop: 0, width: 100 }; var grid = render(getMarkup(props)); simulateScroll({ grid: grid, scrollToIndex: 1 }); expect(componentUpdates).toEqual(0); }); it('should clear all but the visible rows from the style cache once :isScrolling is false', function _callee7(done) { var props, grid; return _regeneratorRuntime.async(function _callee7$(_context7) { while (1) { switch (_context7.prev = _context7.next) { case 0: props = { columnWidth: 50, height: 100, overscanColumnCount: 0, overscanRowCount: 0, rowHeight: 50, width: 100 }; grid = render(getMarkup(props)); expect(Object.keys(grid._styleCache).length).toBe(4); simulateScroll({ grid: grid, scrollTop: 50 }); expect(Object.keys(grid._styleCache).length).toBe(6); // Allow scrolling timeout to complete so that cell cache is reset _context7.next = 7; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, DEFAULT_SCROLLING_RESET_TIME_INTERVAL * 2); })); case 7: expect(Object.keys(grid._styleCache).length).toBe(4); done(); case 9: case "end": return _context7.stop(); } } }); }); it('should clear style cache if :recomputeGridSize is called', function () { var props = { columnWidth: 50, height: 100, overscanColumnCount: 0, overscanRowCount: 0, rowHeight: 50, width: 100 }; var grid = render(getMarkup(props)); expect(Object.keys(grid._styleCache).length).toBe(4); render(getMarkup(_objectSpread({}, props, { scrollTop: 50 }))); expect(Object.keys(grid._styleCache).length).toBe(6); grid.recomputeGridSize(); expect(Object.keys(grid._styleCache).length).toBe(4); }); it('should clear style cache if cell sizes change', function () { var cellRendererCalls = []; function cellRenderer(params) { cellRendererCalls.push(params); return React.createElement("div", { key: params.key, style: params.style }); } var props = { cellRenderer: cellRenderer, columnWidth: 100, height: 100, overscanColumnCount: 0, overscanRowCount: 0, rowHeight: 100, width: 100 }; render(getMarkup(props)); expect(cellRendererCalls.length).toEqual(1); expect(cellRendererCalls[0].style.width).toEqual(100); render(getMarkup(_objectSpread({}, props, { columnWidth: 50, width: 50 }))); expect(cellRendererCalls.length).toEqual(2); expect(cellRendererCalls[1].style.width).toEqual(50); }); }); it('should not pull from the style cache while scrolling if there is an offset adjustment', function () { var cellRendererCalls = []; function cellRenderer(params) { cellRendererCalls.push(params); return React.createElement("div", { key: params.key, style: params.style }); } var grid = render(getMarkup({ cellRenderer: cellRenderer, width: 100, height: 100, rowHeight: 100, columnWidth: 100, rowCount: getMaxElementSize() * 2 / 100, // lots of offset scrollTop: 2000 })); simulateScroll({ grid: grid, scrollTop: 2100 }); // cellRendererCalls[0] is the element at rowIndex 0 // only two calls. Since the scrollTop is updated in getDerivedStateFromProps var firstProps = cellRendererCalls[0]; var secondProps = cellRendererCalls[1]; expect(cellRendererCalls.length).toEqual(2); expect(firstProps.style).not.toBe(secondProps.style); }); it('should only cache styles when a :deferredMeasurementCache is provided if the cell has already been measured', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); cache.set(0, 0, 100, 100); cache.set(1, 1, 100, 100); var grid = render(getMarkup({ columnCount: 2, deferredMeasurementCache: cache, rowCount: 2 })); var keys = Object.keys(grid._styleCache); expect(keys).toEqual(['0-0', '1-1']); }); describe('DEV warnings', function () { it('should warn about cells that forget to include the :style property', function () { spyOn(console, 'warn'); function cellRenderer(params) { return React.createElement("div", { key: params.key }); } render(getMarkup({ cellRenderer: cellRenderer })); expect(console.warn).toHaveBeenCalledWith('Rendered cell should include style property for positioning.'); expect(console.warn).toHaveBeenCalledTimes(1); }); it('should warn about CellMeasurer measured cells that forget to include the :style property', function () { spyOn(console, 'warn'); var cache = new CellMeasurerCache({ fixedWidth: true }); var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (params) { return React.createElement(CellMeasurer, { cache: cache, columnIndex: params.columnIndex, key: params.key, parent: params.parent, rowIndex: params.rowIndex, style: params.style }, React.createElement("div", null)); }); render(getMarkup({ cellRenderer: cellRenderer, columnCount: 1, deferredMeasurementCache: cache, rowCount: 1 })); expect(console.warn).toHaveBeenCalledWith('Rendered cell should include style property for positioning.'); expect(console.warn).toHaveBeenCalledTimes(1); }); }); describe('deferredMeasurementCache', function () { it('invalidateCellSizeAfterRender should invalidate cache and refresh displayed cells after mount', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); var invalidateCellSizeAfterRender = true; var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (params) { // Don't get stuck in a loop if (invalidateCellSizeAfterRender) { invalidateCellSizeAfterRender = false; params.parent.invalidateCellSizeAfterRender({ columnIndex: 1, rowIndex: 0 }); } return React.createElement("div", { key: params.key, style: params.style }); }); var props = { cellRenderer: cellRenderer, columnCount: 2, deferredMeasurementCache: cache, rowCount: 2 }; render(getMarkup(props)); // 4 times for initial render + 4 once cellCache was cleared expect(cellRenderer).toHaveBeenCalledTimes(8); }); it('should invalidate cache and refresh displayed cells after update', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (params) { return React.createElement("div", { key: params.key, style: params.style }); }); var props = { cellRenderer: cellRenderer, columnCount: 2, deferredMeasurementCache: cache, rowCount: 2 }; var grid = render(getMarkup(props)); expect(cellRenderer).toHaveBeenCalledTimes(4); var invalidateCellSizeAfterRender = false; cellRenderer.mockReset(); cellRenderer.mockImplementation(function (params) { // Don't get stuck in a loop if (invalidateCellSizeAfterRender) { invalidateCellSizeAfterRender = false; params.parent.invalidateCellSizeAfterRender({ columnIndex: 1, rowIndex: 0 }); } return React.createElement("div", { key: params.key, style: params.style }); }); invalidateCellSizeAfterRender = true; grid.recomputeGridSize(); // 4 times for initial render + 4 once cellCache was cleared expect(cellRenderer).toHaveBeenCalledTimes(8); }); it('should not cache cells until they have been measured by CellMeasurer', function () { var cache = new CellMeasurerCache({ fixedWidth: true }); // Fake measure cell 0,0 but not cell 0,1 cache.set(0, 0, 100, 30); var cellRenderer = jest.fn(); cellRenderer.mockImplementation(function (params) { return React.createElement("div", { key: params.key, style: params.style }); }); var props = { cellRenderer: cellRenderer, columnCount: 2, deferredMeasurementCache: cache, rowCount: 1 }; // Trigger 2 renders // The second render should re-use the style for cell 0,0 // But should not re-use the style for cell 0,1 since it was not measured var grid = render(getMarkup(props)); grid.forceUpdate(); // 0,0 - 0,1 - 0,0 - 0,1 expect(cellRenderer).toHaveBeenCalledTimes(4); var style00A = cellRenderer.mock.calls[0][0].style; var style01A = cellRenderer.mock.calls[1][0].style; var style00B = cellRenderer.mock.calls[2][0].style; var style01B = cellRenderer.mock.calls[3][0].style; expect(style00A).toBe(style00B); expect(style01A).not.toBe(style01B); }); }); describe('onScrollbarPresenceChange', function () { it('should not trigger on-mount if scrollbars are hidden', function () { var onScrollbarPresenceChange = jest.fn(); render(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 1 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); }); it('should trigger on-mount if scrollbars are visible', function () { var onScrollbarPresenceChange = jest.fn(); render(getMarkup({ columnCount: 100, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 100 })); expect(onScrollbarPresenceChange).toHaveBeenCalled(); var args = onScrollbarPresenceChange.mock.calls[0][0]; expect(args.horizontal).toBe(true); expect(args.size).toBe(getScrollbarSize20()); expect(args.vertical).toBe(true); }); it('should trigger on-update if scrollbar visibility has changed', function () { var onScrollbarPresenceChange = jest.fn(); render(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 1 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); render(getMarkup({ columnCount: 100, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 100 })); expect(onScrollbarPresenceChange).toHaveBeenCalled(); var args = onScrollbarPresenceChange.mock.calls[0][0]; expect(args.horizontal).toBe(true); expect(args.size).toBe(getScrollbarSize20()); expect(args.vertical).toBe(true); }); it('should not trigger on-update if scrollbar visibility does not change', function () { var onScrollbarPresenceChange = jest.fn(); render(getMarkup({ columnCount: 1, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 1 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); render(getMarkup({ columnCount: 2, getScrollbarSize: getScrollbarSize20, onScrollbarPresenceChange: onScrollbarPresenceChange, rowCount: 2 })); expect(onScrollbarPresenceChange).not.toHaveBeenCalled(); }); }); it('should not complain when using react-test-renderer', function () { var instance = TestRenderer.create(getMarkup()).getInstance(); expect(instance).toBeTruthy(); }); });dist/es/Grid/accessibilityOverscanIndicesGetter.js000064400000002601151676725770016371 0ustar00export var SCROLL_DIRECTION_BACKWARD = -1; export var SCROLL_DIRECTION_FORWARD = 1; export var SCROLL_DIRECTION_HORIZONTAL = 'horizontal'; export var SCROLL_DIRECTION_VERTICAL = 'vertical'; /** * Calculates the number of cells to overscan before and after a specified range. * This function ensures that overscanning doesn't exceed the available cells. */ export default function defaultOverscanIndicesGetter(_ref) { var cellCount = _ref.cellCount, overscanCellsCount = _ref.overscanCellsCount, scrollDirection = _ref.scrollDirection, startIndex = _ref.startIndex, stopIndex = _ref.stopIndex; // Make sure we render at least 1 cell extra before and after (except near boundaries) // This is necessary in order to support keyboard navigation (TAB/SHIFT+TAB) in some cases // For more info see issues #625 overscanCellsCount = Math.max(1, overscanCellsCount); if (scrollDirection === SCROLL_DIRECTION_FORWARD) { return { overscanStartIndex: Math.max(0, startIndex - 1), overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount) }; } else { return { overscanStartIndex: Math.max(0, startIndex - overscanCellsCount), overscanStopIndex: Math.min(cellCount - 1, stopIndex + 1) }; } } import { bpfrpt_proptype_OverscanIndicesGetterParams } from "./types"; import { bpfrpt_proptype_OverscanIndices } from "./types";dist/es/Grid/utils/maxElementSize.js000064400000000647151676725770013471 0ustar00var DEFAULT_MAX_ELEMENT_SIZE = 1500000; var CHROME_MAX_ELEMENT_SIZE = 1.67771e7; var isBrowser = function isBrowser() { return typeof window !== 'undefined'; }; var isChrome = function isChrome() { return !!window.chrome; }; export var getMaxElementSize = function getMaxElementSize() { if (isBrowser()) { if (isChrome()) { return CHROME_MAX_ELEMENT_SIZE; } } return DEFAULT_MAX_ELEMENT_SIZE; };dist/es/Grid/utils/updateScrollIndexHelper.js000064400000004626151676725770015331 0ustar00import ScalingCellSizeAndPositionManager from './ScalingCellSizeAndPositionManager.js'; /** * Helper function that determines when to update scroll offsets to ensure that a scroll-to-index remains visible. * This function also ensures that the scroll ofset isn't past the last column/row of cells. */ export default function updateScrollIndexHelper(_ref) { var cellSize = _ref.cellSize, cellSizeAndPositionManager = _ref.cellSizeAndPositionManager, previousCellsCount = _ref.previousCellsCount, previousCellSize = _ref.previousCellSize, previousScrollToAlignment = _ref.previousScrollToAlignment, previousScrollToIndex = _ref.previousScrollToIndex, previousSize = _ref.previousSize, scrollOffset = _ref.scrollOffset, scrollToAlignment = _ref.scrollToAlignment, scrollToIndex = _ref.scrollToIndex, size = _ref.size, sizeJustIncreasedFromZero = _ref.sizeJustIncreasedFromZero, updateScrollIndexCallback = _ref.updateScrollIndexCallback; var cellCount = cellSizeAndPositionManager.getCellCount(); var hasScrollToIndex = scrollToIndex >= 0 && scrollToIndex < cellCount; var sizeHasChanged = size !== previousSize || sizeJustIncreasedFromZero || !previousCellSize || typeof cellSize === 'number' && cellSize !== previousCellSize; // If we have a new scroll target OR if height/row-height has changed, // We should ensure that the scroll target is visible. if (hasScrollToIndex && (sizeHasChanged || scrollToAlignment !== previousScrollToAlignment || scrollToIndex !== previousScrollToIndex)) { updateScrollIndexCallback(scrollToIndex); // If we don't have a selected item but list size or number of children have decreased, // Make sure we aren't scrolled too far past the current content. } else if (!hasScrollToIndex && cellCount > 0 && (size < previousSize || cellCount < previousCellsCount)) { // We need to ensure that the current scroll offset is still within the collection's range. // To do this, we don't need to measure everything; CellMeasurer would perform poorly. // Just check to make sure we're still okay. // Only adjust the scroll position if we've scrolled below the last set of rows. if (scrollOffset > cellSizeAndPositionManager.getTotalSize() - size) { updateScrollIndexCallback(cellCount - 1); } } } import { bpfrpt_proptype_Alignment } from "../types"; import { bpfrpt_proptype_CellSize } from "../types";dist/es/Grid/utils/ScalingCellSizeAndPositionManager.jest.js000064400000014136151676725770020157 0ustar00import ScalingCellSizeAndPositionManager from './ScalingCellSizeAndPositionManager'; describe('ScalingCellSizeAndPositionManager', function () { function init() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$cellCount = _ref.cellCount, cellCount = _ref$cellCount === void 0 ? 10 : _ref$cellCount, _ref$cellSize = _ref.cellSize, cellSize = _ref$cellSize === void 0 ? 10 : _ref$cellSize, _ref$estimatedCellSiz = _ref.estimatedCellSize, estimatedCellSize = _ref$estimatedCellSiz === void 0 ? 10 : _ref$estimatedCellSiz, _ref$maxScrollSize = _ref.maxScrollSize, maxScrollSize = _ref$maxScrollSize === void 0 ? 50 : _ref$maxScrollSize; var cellSizeAndPositionManager = new ScalingCellSizeAndPositionManager({ cellCount: cellCount, cellSizeGetter: function cellSizeGetter() { return cellSize; }, estimatedCellSize: estimatedCellSize, maxScrollSize: maxScrollSize }); return cellSizeAndPositionManager; } describe('_getOffsetPercentage', function () { it('should return the correct offset fraction', function () { var expectations = [{ offset: 0, expectedOffsetPercentage: 0 }, { offset: 35, expectedOffsetPercentage: 0.5 }, { offset: 70, expectedOffsetPercentage: 1 }]; var instance = init(); expectations.forEach(function (expectation) { expect(instance._getOffsetPercentage({ containerSize: 30, offset: expectation.offset, totalSize: 100 })).toBe(expectation.expectedOffsetPercentage); }); }); }); describe('getOffsetAdjustment', function () { it('should always return 0 as the adjustment for unscaled lists', function () { var maxScrollSizes = [100, 150]; maxScrollSizes.forEach(function (maxScrollSize) { var instance = init({ cellCount: 10, maxScrollSize: maxScrollSize }); var offsets = [0, 35, 70]; offsets.forEach(function (offset) { expect(instance.getOffsetAdjustment({ containerSize: 30, offset: offset })).toBe(0); }); }); }); it('should properly scale an offset at the beginning, middle, and end of the list', function () { var offsetsAndExpectedAdjustements = [{ offset: 0, expectedAdjustment: -0 }, { offset: 10, expectedAdjustment: -25 }, { offset: 20, expectedAdjustment: -50 }]; var instance = init(); offsetsAndExpectedAdjustements.forEach(function (offsetAndExpectedAdjustement) { expect(instance.getOffsetAdjustment({ containerSize: 30, offset: offsetAndExpectedAdjustement.offset })).toBe(offsetAndExpectedAdjustement.expectedAdjustment); }); }); }); describe('getTotalSize', function () { it('should return :totalSize if it is not greater than :maxScrollSize', function () { var maxScrollSizes = [500, 750]; maxScrollSizes.forEach(function (maxScrollSize) { var instance = init({ cellCount: 50, maxScrollSize: maxScrollSize }); expect(instance.getTotalSize()).toEqual(500); }); }); it('should return :maxScrollSize if :totalSize is greater', function () { var instance = init({ cellCount: 100, maxScrollSize: 100 }); expect(instance.getTotalSize()).toEqual(100); }); }); describe('getUpdatedOffsetForIndex', function () { it('should scroll to a cell before the current range', function () { var data = [{ targetIndex: 0, expectedOffset: 0 }, { targetIndex: 1, expectedOffset: 3 }, // (unsafe: 10) { targetIndex: 2, expectedOffset: 6 } // (unsafe: 20) ]; var instance = init(); data.forEach(function (datum) { expect(instance.getUpdatedOffsetForIndex({ containerSize: 30, currentOffset: 10, // (unsafe: 35) targetIndex: datum.targetIndex })).toBe(datum.expectedOffset); }); }); it('should scroll to a cell after the current range', function () { var data = [{ targetIndex: 7, expectedOffset: 14 }, // (unsafe: 50) { targetIndex: 9, expectedOffset: 20 } // (unsafe: 70) ]; var instance = init(); data.forEach(function (datum) { expect(instance.getUpdatedOffsetForIndex({ containerSize: 30, currentOffset: 0, targetIndex: datum.targetIndex })).toBe(datum.expectedOffset); }); }); it('should not scroll to a cell already visible within the current range', function () { var instance = init(); expect(instance.getUpdatedOffsetForIndex({ containerSize: 30, currentOffset: 10, // (unsafe: 35) targetIndex: 4 })).toBe(10); }); }); describe('getVisibleCellRange', function () { it('should correct identify the first set of cells', function () { var instance = init(); expect(instance.getVisibleCellRange({ containerSize: 30, offset: 0 })).toEqual({ start: 0, stop: 2 }); }); it('should correct identify cells in the middle', function () { var instance = init(); expect(instance.getVisibleCellRange({ containerSize: 30, offset: 2.85 // (unsafe: 10) })).toEqual({ start: 1, stop: 3 }); }); it('should correct identify partially visible cells', function () { var instance = init(); expect(instance.getVisibleCellRange({ containerSize: 30, offset: 10 // (unsafe: 35) })).toEqual({ start: 3, stop: 6 }); }); it('should correct identify the last set of cells', function () { var instance = init(); expect(instance.getVisibleCellRange({ containerSize: 30, offset: 20 })).toEqual({ start: 7, stop: 9 }); }); }); });dist/es/Grid/utils/CellSizeAndPositionManager.js000064400000024566151676725770015722 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; /** * Just-in-time calculates and caches size and position information for a collection of cells. */ var CellSizeAndPositionManager = /*#__PURE__*/ function () { // Cache of size and position data for cells, mapped by cell index. // Note that invalid values may exist in this map so only rely on cells up to this._lastMeasuredIndex // Measurements for cells up to this index can be trusted; cells afterward should be estimated. // Used in deferred mode to track which cells have been queued for measurement. function CellSizeAndPositionManager(_ref) { var cellCount = _ref.cellCount, cellSizeGetter = _ref.cellSizeGetter, estimatedCellSize = _ref.estimatedCellSize; _classCallCheck(this, CellSizeAndPositionManager); _defineProperty(this, "_cellSizeAndPositionData", {}); _defineProperty(this, "_lastMeasuredIndex", -1); _defineProperty(this, "_lastBatchedIndex", -1); _defineProperty(this, "_cellCount", void 0); _defineProperty(this, "_cellSizeGetter", void 0); _defineProperty(this, "_estimatedCellSize", void 0); this._cellSizeGetter = cellSizeGetter; this._cellCount = cellCount; this._estimatedCellSize = estimatedCellSize; } _createClass(CellSizeAndPositionManager, [{ key: "areOffsetsAdjusted", value: function areOffsetsAdjusted() { return false; } }, { key: "configure", value: function configure(_ref2) { var cellCount = _ref2.cellCount, estimatedCellSize = _ref2.estimatedCellSize, cellSizeGetter = _ref2.cellSizeGetter; this._cellCount = cellCount; this._estimatedCellSize = estimatedCellSize; this._cellSizeGetter = cellSizeGetter; } }, { key: "getCellCount", value: function getCellCount() { return this._cellCount; } }, { key: "getEstimatedCellSize", value: function getEstimatedCellSize() { return this._estimatedCellSize; } }, { key: "getLastMeasuredIndex", value: function getLastMeasuredIndex() { return this._lastMeasuredIndex; } }, { key: "getOffsetAdjustment", value: function getOffsetAdjustment() { return 0; } /** * This method returns the size and position for the cell at the specified index. * It just-in-time calculates (or used cached values) for cells leading up to the index. */ }, { key: "getSizeAndPositionOfCell", value: function getSizeAndPositionOfCell(index) { if (index < 0 || index >= this._cellCount) { throw Error("Requested index ".concat(index, " is outside of range 0..").concat(this._cellCount)); } if (index > this._lastMeasuredIndex) { var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); var offset = lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size; for (var i = this._lastMeasuredIndex + 1; i <= index; i++) { var size = this._cellSizeGetter({ index: i }); // undefined or NaN probably means a logic error in the size getter. // null means we're using CellMeasurer and haven't yet measured a given index. if (size === undefined || isNaN(size)) { throw Error("Invalid size returned for cell ".concat(i, " of value ").concat(size)); } else if (size === null) { this._cellSizeAndPositionData[i] = { offset: offset, size: 0 }; this._lastBatchedIndex = index; } else { this._cellSizeAndPositionData[i] = { offset: offset, size: size }; offset += size; this._lastMeasuredIndex = index; } } } return this._cellSizeAndPositionData[index]; } }, { key: "getSizeAndPositionOfLastMeasuredCell", value: function getSizeAndPositionOfLastMeasuredCell() { return this._lastMeasuredIndex >= 0 ? this._cellSizeAndPositionData[this._lastMeasuredIndex] : { offset: 0, size: 0 }; } /** * Total size of all cells being measured. * This value will be completely estimated initially. * As cells are measured, the estimate will be updated. */ }, { key: "getTotalSize", value: function getTotalSize() { var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); var totalSizeOfMeasuredCells = lastMeasuredCellSizeAndPosition.offset + lastMeasuredCellSizeAndPosition.size; var numUnmeasuredCells = this._cellCount - this._lastMeasuredIndex - 1; var totalSizeOfUnmeasuredCells = numUnmeasuredCells * this._estimatedCellSize; return totalSizeOfMeasuredCells + totalSizeOfUnmeasuredCells; } /** * Determines a new offset that ensures a certain cell is visible, given the current offset. * If the cell is already visible then the current offset will be returned. * If the current offset is too great or small, it will be adjusted just enough to ensure the specified index is visible. * * @param align Desired alignment within container; one of "auto" (default), "start", or "end" * @param containerSize Size (width or height) of the container viewport * @param currentOffset Container's current (x or y) offset * @param totalSize Total size (width or height) of all cells * @return Offset to use to ensure the specified cell is visible */ }, { key: "getUpdatedOffsetForIndex", value: function getUpdatedOffsetForIndex(_ref3) { var _ref3$align = _ref3.align, align = _ref3$align === void 0 ? 'auto' : _ref3$align, containerSize = _ref3.containerSize, currentOffset = _ref3.currentOffset, targetIndex = _ref3.targetIndex; if (containerSize <= 0) { return 0; } var datum = this.getSizeAndPositionOfCell(targetIndex); var maxOffset = datum.offset; var minOffset = maxOffset - containerSize + datum.size; var idealOffset; switch (align) { case 'start': idealOffset = maxOffset; break; case 'end': idealOffset = minOffset; break; case 'center': idealOffset = maxOffset - (containerSize - datum.size) / 2; break; default: idealOffset = Math.max(minOffset, Math.min(maxOffset, currentOffset)); break; } var totalSize = this.getTotalSize(); return Math.max(0, Math.min(totalSize - containerSize, idealOffset)); } }, { key: "getVisibleCellRange", value: function getVisibleCellRange(params) { var containerSize = params.containerSize, offset = params.offset; var totalSize = this.getTotalSize(); if (totalSize === 0) { return {}; } var maxOffset = offset + containerSize; var start = this._findNearestCell(offset); var datum = this.getSizeAndPositionOfCell(start); offset = datum.offset + datum.size; var stop = start; while (offset < maxOffset && stop < this._cellCount - 1) { stop++; offset += this.getSizeAndPositionOfCell(stop).size; } return { start: start, stop: stop }; } /** * Clear all cached values for cells after the specified index. * This method should be called for any cell that has changed its size. * It will not immediately perform any calculations; they'll be performed the next time getSizeAndPositionOfCell() is called. */ }, { key: "resetCell", value: function resetCell(index) { this._lastMeasuredIndex = Math.min(this._lastMeasuredIndex, index - 1); } }, { key: "_binarySearch", value: function _binarySearch(high, low, offset) { while (low <= high) { var middle = low + Math.floor((high - low) / 2); var currentOffset = this.getSizeAndPositionOfCell(middle).offset; if (currentOffset === offset) { return middle; } else if (currentOffset < offset) { low = middle + 1; } else if (currentOffset > offset) { high = middle - 1; } } if (low > 0) { return low - 1; } else { return 0; } } }, { key: "_exponentialSearch", value: function _exponentialSearch(index, offset) { var interval = 1; while (index < this._cellCount && this.getSizeAndPositionOfCell(index).offset < offset) { index += interval; interval *= 2; } return this._binarySearch(Math.min(index, this._cellCount - 1), Math.floor(index / 2), offset); } /** * Searches for the cell (index) nearest the specified offset. * * If no exact match is found the next lowest cell index will be returned. * This allows partially visible cells (with offsets just before/above the fold) to be visible. */ }, { key: "_findNearestCell", value: function _findNearestCell(offset) { if (isNaN(offset)) { throw Error("Invalid offset ".concat(offset, " specified")); } // Our search algorithms find the nearest match at or below the specified offset. // So make sure the offset is at least 0 or no match will be found. offset = Math.max(0, offset); var lastMeasuredCellSizeAndPosition = this.getSizeAndPositionOfLastMeasuredCell(); var lastMeasuredIndex = Math.max(0, this._lastMeasuredIndex); if (lastMeasuredCellSizeAndPosition.offset >= offset) { // If we've already measured cells within this range just use a binary search as it's faster. return this._binarySearch(lastMeasuredIndex, 0, offset); } else { // If we haven't yet measured this high, fallback to an exponential search with an inner binary search. // The exponential search avoids pre-computing sizes for the full set of cells as a binary search would. // The overall complexity for this approach is O(log n). return this._exponentialSearch(lastMeasuredIndex, offset); } } }]); return CellSizeAndPositionManager; }(); export { CellSizeAndPositionManager as default }; import { bpfrpt_proptype_Alignment } from "../types"; import { bpfrpt_proptype_CellSizeGetter } from "../types"; import { bpfrpt_proptype_VisibleCellRange } from "../types";dist/es/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset.jest.js000064400000007534151676725770023353 0ustar00import calculateSizeAndPositionDataAndUpdateScrollOffset from './calculateSizeAndPositionDataAndUpdateScrollOffset'; describe('calculateSizeAndPositionDataAndUpdateScrollOffset', function () { function helper() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$cellCount = _ref.cellCount, cellCount = _ref$cellCount === void 0 ? 100 : _ref$cellCount, _ref$cellSize = _ref.cellSize, cellSize = _ref$cellSize === void 0 ? 10 : _ref$cellSize, _ref$computeMetadataC = _ref.computeMetadataCallbackProps, computeMetadataCallbackProps = _ref$computeMetadataC === void 0 ? {} : _ref$computeMetadataC, _ref$nextCellsCount = _ref.nextCellsCount, nextCellsCount = _ref$nextCellsCount === void 0 ? 100 : _ref$nextCellsCount, _ref$nextCellSize = _ref.nextCellSize, nextCellSize = _ref$nextCellSize === void 0 ? 10 : _ref$nextCellSize, nextScrollToIndex = _ref.nextScrollToIndex, scrollToIndex = _ref.scrollToIndex; var computeMetadataCallbackCalls = []; var updateScrollOffsetForScrollToIndexCalls = []; calculateSizeAndPositionDataAndUpdateScrollOffset({ cellCount: cellCount, cellSize: cellSize, computeMetadataCallback: function computeMetadataCallback(params) { return computeMetadataCallbackCalls.push(params); }, computeMetadataCallbackProps: computeMetadataCallbackProps, nextCellsCount: nextCellsCount, nextCellSize: nextCellSize, nextScrollToIndex: nextScrollToIndex, scrollToIndex: scrollToIndex, updateScrollOffsetForScrollToIndex: function updateScrollOffsetForScrollToIndex(params) { return updateScrollOffsetForScrollToIndexCalls.push(params); } }); return { computeMetadataCallbackCalls: computeMetadataCallbackCalls, updateScrollOffsetForScrollToIndexCalls: updateScrollOffsetForScrollToIndexCalls }; } it('should call :computeMetadataCallback if :cellCount has changed', function () { var _helper = helper({ cellCount: 100, nextCellsCount: 200 }), computeMetadataCallbackCalls = _helper.computeMetadataCallbackCalls; expect(computeMetadataCallbackCalls.length).toEqual(1); }); it('should call :computeMetadataCallback if numeric :cellSize has changed', function () { var _helper2 = helper({ cellSize: 10, nextCellSize: 20 }), computeMetadataCallbackCalls = _helper2.computeMetadataCallbackCalls; expect(computeMetadataCallbackCalls.length).toEqual(1); }); it('should not call :computeMetadataCallback if :cellSize callback has changed', function () { var _helper3 = helper({ cellSize: function cellSize() {}, nextCellSize: function nextCellSize() {} }), computeMetadataCallbackCalls = _helper3.computeMetadataCallbackCalls; expect(computeMetadataCallbackCalls.length).toEqual(0); }); it('should not call :updateScrollOffsetForScrollToIndex if :scrollToIndex is not specified', function () { var _helper4 = helper(), updateScrollOffsetForScrollToIndexCalls = _helper4.updateScrollOffsetForScrollToIndexCalls; expect(updateScrollOffsetForScrollToIndexCalls.length).toEqual(0); }); it('should not call :updateScrollOffsetForScrollToIndex if :scrollToIndex has also changed', function () { var _helper5 = helper({ scrollToIndex: 10, nextScrollToIndex: 20 }), updateScrollOffsetForScrollToIndexCalls = _helper5.updateScrollOffsetForScrollToIndexCalls; expect(updateScrollOffsetForScrollToIndexCalls.length).toEqual(0); }); it('should not call :computeMetadataCallback if the above conditions are not true', function () { var _helper6 = helper(), computeMetadataCallbackCalls = _helper6.computeMetadataCallbackCalls; expect(computeMetadataCallbackCalls.length).toEqual(0); }); });dist/es/Grid/utils/calculateSizeAndPositionDataAndUpdateScrollOffset.js000064400000002421151676725770022375 0ustar00/** * Helper method that determines when to recalculate row or column metadata. */ export default function calculateSizeAndPositionDataAndUpdateScrollOffset(_ref) { var cellCount = _ref.cellCount, cellSize = _ref.cellSize, computeMetadataCallback = _ref.computeMetadataCallback, computeMetadataCallbackProps = _ref.computeMetadataCallbackProps, nextCellsCount = _ref.nextCellsCount, nextCellSize = _ref.nextCellSize, nextScrollToIndex = _ref.nextScrollToIndex, scrollToIndex = _ref.scrollToIndex, updateScrollOffsetForScrollToIndex = _ref.updateScrollOffsetForScrollToIndex; // Don't compare cell sizes if they are functions because inline functions would cause infinite loops. // In that event users should use the manual recompute methods to inform of changes. if (cellCount !== nextCellsCount || (typeof cellSize === 'number' || typeof nextCellSize === 'number') && cellSize !== nextCellSize) { computeMetadataCallback(computeMetadataCallbackProps); // Updated cell metadata may have hidden the previous scrolled-to item. // In this case we should also update the scrollTop to ensure it stays visible. if (scrollToIndex >= 0 && scrollToIndex === nextScrollToIndex) { updateScrollOffsetForScrollToIndex(); } } }dist/es/Grid/utils/ScalingCellSizeAndPositionManager.js000064400000015170151676725770017212 0ustar00import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import CellSizeAndPositionManager from './CellSizeAndPositionManager'; import { getMaxElementSize } from './maxElementSize.js'; /** * Extends CellSizeAndPositionManager and adds scaling behavior for lists that are too large to fit within a browser's native limits. */ var ScalingCellSizeAndPositionManager = /*#__PURE__*/ function () { function ScalingCellSizeAndPositionManager(_ref) { var _ref$maxScrollSize = _ref.maxScrollSize, maxScrollSize = _ref$maxScrollSize === void 0 ? getMaxElementSize() : _ref$maxScrollSize, params = _objectWithoutProperties(_ref, ["maxScrollSize"]); _classCallCheck(this, ScalingCellSizeAndPositionManager); _defineProperty(this, "_cellSizeAndPositionManager", void 0); _defineProperty(this, "_maxScrollSize", void 0); // Favor composition over inheritance to simplify IE10 support this._cellSizeAndPositionManager = new CellSizeAndPositionManager(params); this._maxScrollSize = maxScrollSize; } _createClass(ScalingCellSizeAndPositionManager, [{ key: "areOffsetsAdjusted", value: function areOffsetsAdjusted() { return this._cellSizeAndPositionManager.getTotalSize() > this._maxScrollSize; } }, { key: "configure", value: function configure(params) { this._cellSizeAndPositionManager.configure(params); } }, { key: "getCellCount", value: function getCellCount() { return this._cellSizeAndPositionManager.getCellCount(); } }, { key: "getEstimatedCellSize", value: function getEstimatedCellSize() { return this._cellSizeAndPositionManager.getEstimatedCellSize(); } }, { key: "getLastMeasuredIndex", value: function getLastMeasuredIndex() { return this._cellSizeAndPositionManager.getLastMeasuredIndex(); } /** * Number of pixels a cell at the given position (offset) should be shifted in order to fit within the scaled container. * The offset passed to this function is scaled (safe) as well. */ }, { key: "getOffsetAdjustment", value: function getOffsetAdjustment(_ref2) { var containerSize = _ref2.containerSize, offset = _ref2.offset; var totalSize = this._cellSizeAndPositionManager.getTotalSize(); var safeTotalSize = this.getTotalSize(); var offsetPercentage = this._getOffsetPercentage({ containerSize: containerSize, offset: offset, totalSize: safeTotalSize }); return Math.round(offsetPercentage * (safeTotalSize - totalSize)); } }, { key: "getSizeAndPositionOfCell", value: function getSizeAndPositionOfCell(index) { return this._cellSizeAndPositionManager.getSizeAndPositionOfCell(index); } }, { key: "getSizeAndPositionOfLastMeasuredCell", value: function getSizeAndPositionOfLastMeasuredCell() { return this._cellSizeAndPositionManager.getSizeAndPositionOfLastMeasuredCell(); } /** See CellSizeAndPositionManager#getTotalSize */ }, { key: "getTotalSize", value: function getTotalSize() { return Math.min(this._maxScrollSize, this._cellSizeAndPositionManager.getTotalSize()); } /** See CellSizeAndPositionManager#getUpdatedOffsetForIndex */ }, { key: "getUpdatedOffsetForIndex", value: function getUpdatedOffsetForIndex(_ref3) { var _ref3$align = _ref3.align, align = _ref3$align === void 0 ? 'auto' : _ref3$align, containerSize = _ref3.containerSize, currentOffset = _ref3.currentOffset, targetIndex = _ref3.targetIndex; currentOffset = this._safeOffsetToOffset({ containerSize: containerSize, offset: currentOffset }); var offset = this._cellSizeAndPositionManager.getUpdatedOffsetForIndex({ align: align, containerSize: containerSize, currentOffset: currentOffset, targetIndex: targetIndex }); return this._offsetToSafeOffset({ containerSize: containerSize, offset: offset }); } /** See CellSizeAndPositionManager#getVisibleCellRange */ }, { key: "getVisibleCellRange", value: function getVisibleCellRange(_ref4) { var containerSize = _ref4.containerSize, offset = _ref4.offset; offset = this._safeOffsetToOffset({ containerSize: containerSize, offset: offset }); return this._cellSizeAndPositionManager.getVisibleCellRange({ containerSize: containerSize, offset: offset }); } }, { key: "resetCell", value: function resetCell(index) { this._cellSizeAndPositionManager.resetCell(index); } }, { key: "_getOffsetPercentage", value: function _getOffsetPercentage(_ref5) { var containerSize = _ref5.containerSize, offset = _ref5.offset, totalSize = _ref5.totalSize; return totalSize <= containerSize ? 0 : offset / (totalSize - containerSize); } }, { key: "_offsetToSafeOffset", value: function _offsetToSafeOffset(_ref6) { var containerSize = _ref6.containerSize, offset = _ref6.offset; var totalSize = this._cellSizeAndPositionManager.getTotalSize(); var safeTotalSize = this.getTotalSize(); if (totalSize === safeTotalSize) { return offset; } else { var offsetPercentage = this._getOffsetPercentage({ containerSize: containerSize, offset: offset, totalSize: totalSize }); return Math.round(offsetPercentage * (safeTotalSize - containerSize)); } } }, { key: "_safeOffsetToOffset", value: function _safeOffsetToOffset(_ref7) { var containerSize = _ref7.containerSize, offset = _ref7.offset; var totalSize = this._cellSizeAndPositionManager.getTotalSize(); var safeTotalSize = this.getTotalSize(); if (totalSize === safeTotalSize) { return offset; } else { var offsetPercentage = this._getOffsetPercentage({ containerSize: containerSize, offset: offset, totalSize: safeTotalSize }); return Math.round(offsetPercentage * (totalSize - containerSize)); } } }]); return ScalingCellSizeAndPositionManager; }(); export { ScalingCellSizeAndPositionManager as default }; import { bpfrpt_proptype_Alignment } from "../types"; import { bpfrpt_proptype_CellSizeGetter } from "../types"; import { bpfrpt_proptype_VisibleCellRange } from "../types";dist/es/Grid/utils/updateScrollIndexHelper.jest.js000064400000014762151676725770016277 0ustar00import updateScrollIndexHelper from './updateScrollIndexHelper'; import CellSizeAndPositionManager from './CellSizeAndPositionManager'; // Default cell sizes and offsets for use in shared tests export function getCellSizeAndPositionManager(_ref) { var _ref$cellCount = _ref.cellCount, cellCount = _ref$cellCount === void 0 ? CELL_SIZES.length : _ref$cellCount, _ref$estimatedCellSiz = _ref.estimatedCellSize, estimatedCellSize = _ref$estimatedCellSiz === void 0 ? 10 : _ref$estimatedCellSiz; return new CellSizeAndPositionManager({ cellCount: cellCount, cellSizeGetter: function cellSizeGetter(_ref2) { var index = _ref2.index; return CELL_SIZES[index % CELL_SIZES.length]; }, estimatedCellSize: estimatedCellSize }); } var CELL_SIZES = [10, // 0: 0..0 (min) 20, // 1: 0..10 15, // 2: 0..30 10, // 3: 5..45 15, // 4: 20..55 30, // 5: 50..70 20, // 6: 70..100 10, // 7: 80..110 30 // 8: 110..110 (max) ]; describe('updateScrollIndexHelper', function () { function helper() { var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref3$cellCount = _ref3.cellCount, cellCount = _ref3$cellCount === void 0 ? undefined : _ref3$cellCount, cellSizeAndPositionManager = _ref3.cellSizeAndPositionManager, _ref3$cellSize = _ref3.cellSize, cellSize = _ref3$cellSize === void 0 ? 10 : _ref3$cellSize, _ref3$previousCellsCo = _ref3.previousCellsCount, previousCellsCount = _ref3$previousCellsCo === void 0 ? undefined : _ref3$previousCellsCo, _ref3$previousCellSiz = _ref3.previousCellSize, previousCellSize = _ref3$previousCellSiz === void 0 ? 10 : _ref3$previousCellSiz, _ref3$previousScrollT = _ref3.previousScrollToAlignment, previousScrollToAlignment = _ref3$previousScrollT === void 0 ? 'auto' : _ref3$previousScrollT, previousScrollToIndex = _ref3.previousScrollToIndex, _ref3$previousSize = _ref3.previousSize, previousSize = _ref3$previousSize === void 0 ? 50 : _ref3$previousSize, _ref3$scrollOffset = _ref3.scrollOffset, scrollOffset = _ref3$scrollOffset === void 0 ? 0 : _ref3$scrollOffset, _ref3$scrollToAlignme = _ref3.scrollToAlignment, scrollToAlignment = _ref3$scrollToAlignme === void 0 ? 'auto' : _ref3$scrollToAlignme, scrollToIndex = _ref3.scrollToIndex, _ref3$size = _ref3.size, size = _ref3$size === void 0 ? 50 : _ref3$size; cellSizeAndPositionManager = cellSizeAndPositionManager || getCellSizeAndPositionManager({ cellCount: cellCount }); cellCount = cellCount === undefined ? cellSizeAndPositionManager.getCellCount() : cellCount; previousCellsCount = previousCellsCount === undefined ? cellCount : previousCellsCount; var updateScrollIndexCallbackCalled = false; function updateScrollIndexCallback() { updateScrollIndexCallbackCalled = true; } updateScrollIndexHelper({ cellCount: cellCount, cellSizeAndPositionManager: cellSizeAndPositionManager, cellSize: cellSize, previousCellsCount: previousCellsCount, previousCellSize: previousCellSize, previousScrollToAlignment: previousScrollToAlignment, previousScrollToIndex: previousScrollToIndex, previousSize: previousSize, scrollOffset: scrollOffset, scrollToAlignment: scrollToAlignment, scrollToIndex: scrollToIndex, size: size, updateScrollIndexCallback: updateScrollIndexCallback }); return updateScrollIndexCallbackCalled; } it('should not call :updateScrollIndexCallback if there is no :scrollToIndex and size has not changed', function () { expect(helper()).toEqual(false); }); it('should not call :updateScrollIndexCallback if an invalid :scrollToIndex has been specified', function () { expect(helper({ size: 100, previousSize: 50, scrollToIndex: -1 })).toEqual(false); }); it('should call :updateScrollIndexCallback if there is a :scrollToIndex and :size has changed', function () { expect(helper({ cellCount: 100, size: 100, previousSize: 50, scrollToIndex: 10 })).toEqual(true); }); it('should call :updateScrollIndexCallback if there is a :scrollToIndex and :cellSize has changed', function () { expect(helper({ cellCount: 100, cellSize: 15, previousCellSize: 20, scrollToIndex: 10 })).toEqual(true); }); it('should call :updateScrollIndexCallback if previous :scrollToIndex has changed', function () { expect(helper({ cellCount: 15, previousScrollToIndex: 20, scrollToIndex: 10 })).toEqual(true); }); it('should call :updateScrollIndexCallback if :cellCount has been reduced past the current scroll offset', function () { expect(helper({ previousCellsCount: 100, scrollOffset: 510 })).toEqual(true); }); it('should call :updateScrollIndexCallback if there is no :scrollToIndex but :size has been reduced', function () { expect(helper({ previousSize: 100, scrollOffset: 510, size: 50 })).toEqual(true); }); it('should not measure rows if :size or :cellCount have been reduced but only use already measured (or estimated) total size', function () { var cellSizeAndPositionManager = { getCellCount: function getCellCount() { return CELL_SIZES.length; }, getTotalSize: function getTotalSize() { return 560; } }; expect(helper({ cellSizeAndPositionManager: cellSizeAndPositionManager, previousSize: 100, scrollOffset: 510, size: 50 })).toEqual(false); }); it('should not call :updateScrollIndexCallback if there is no :scrollToIndex but :cellCount has been increased', function () { expect(helper({ cellCount: 100, previousCellsCount: 50 })).toEqual(false); }); it('should not call :updateScrollIndexCallback if there is no :scrollToIndex but :size has been increased', function () { expect(helper({ previousSize: 50, size: 100 })).toEqual(false); }); it('should call :updateScrollIndexCallback if :scrollToAlignment has changed', function () { expect(helper({ previousScrollToAlignment: 'start', scrollToAlignment: 'end', scrollToIndex: 5 })).toEqual(true); }); it('should not call :updateScrollIndexCallback if :scrollToAlignment has changed but there is no :scrollToIndex', function () { expect(helper({ previousScrollToAlignment: 'start', scrollToAlignment: 'end' })).toEqual(false); }); });dist/es/Grid/utils/CellSizeAndPositionManager.jest.js000064400000043237151676725770016662 0ustar00import CellSizeAndPositionManager from './CellSizeAndPositionManager'; describe('CellSizeAndPositionManager', function () { function getCellSizeAndPositionManager() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$cellCount = _ref.cellCount, cellCount = _ref$cellCount === void 0 ? 100 : _ref$cellCount, _ref$estimatedCellSiz = _ref.estimatedCellSize, estimatedCellSize = _ref$estimatedCellSiz === void 0 ? 15 : _ref$estimatedCellSiz; var cellSizeGetterCalls = []; var cellSizeAndPositionManager = new CellSizeAndPositionManager({ cellCount: cellCount, cellSizeGetter: function cellSizeGetter(_ref2) { var index = _ref2.index; cellSizeGetterCalls.push(index); return 10; }, estimatedCellSize: estimatedCellSize }); return { cellSizeAndPositionManager: cellSizeAndPositionManager, cellSizeGetterCalls: cellSizeGetterCalls }; } describe('configure', function () { it('should update inner :cellCount and :estimatedCellSize', function () { var _getCellSizeAndPositi = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi.cellSizeAndPositionManager; expect(cellSizeAndPositionManager.getCellCount()).toEqual(100); expect(cellSizeAndPositionManager.getEstimatedCellSize()).toEqual(15); cellSizeAndPositionManager.configure({ cellCount: 20, estimatedCellSize: 30 }); expect(cellSizeAndPositionManager.getCellCount()).toEqual(20); expect(cellSizeAndPositionManager.getEstimatedCellSize()).toEqual(30); }); }); describe('findNearestCell', function () { it('should error if given NaN', function () { var _getCellSizeAndPositi2 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi2.cellSizeAndPositionManager; expect(function () { return cellSizeAndPositionManager._findNearestCell(NaN); }).toThrow(); }); it('should gracefully handle offets outisde of bounds (to account for elastic scrolling)', function () { var _getCellSizeAndPositi3 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi3.cellSizeAndPositionManager; expect(cellSizeAndPositionManager._findNearestCell(-100)).toEqual(0); expect(cellSizeAndPositionManager._findNearestCell(1234567890)).toEqual(99); }); it('should find the first cell', function () { var _getCellSizeAndPositi4 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi4.cellSizeAndPositionManager; expect(cellSizeAndPositionManager._findNearestCell(0)).toEqual(0); expect(cellSizeAndPositionManager._findNearestCell(9)).toEqual(0); }); it('should find the last cell', function () { var _getCellSizeAndPositi5 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi5.cellSizeAndPositionManager; expect(cellSizeAndPositionManager._findNearestCell(990)).toEqual(99); expect(cellSizeAndPositionManager._findNearestCell(991)).toEqual(99); }); it('should find the a cell that exactly matches a specified offset in the middle', function () { var _getCellSizeAndPositi6 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi6.cellSizeAndPositionManager; expect(cellSizeAndPositionManager._findNearestCell(100)).toEqual(10); }); it('should find the cell closest to (but before) the specified offset in the middle', function () { var _getCellSizeAndPositi7 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi7.cellSizeAndPositionManager; expect(cellSizeAndPositionManager._findNearestCell(101)).toEqual(10); }); }); describe('getSizeAndPositionOfCell', function () { it('should error if an invalid index is specified', function () { var _getCellSizeAndPositi8 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi8.cellSizeAndPositionManager; expect(function () { return cellSizeAndPositionManager.getSizeAndPositionOfCell(-1); }).toThrow(); expect(function () { return cellSizeAndPositionManager.getSizeAndPositionOfCell(100); }).toThrow(); }); it('should return the correct size and position information for the requested cell', function () { var _getCellSizeAndPositi9 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi9.cellSizeAndPositionManager; expect(cellSizeAndPositionManager.getSizeAndPositionOfCell(0).offset).toEqual(0); expect(cellSizeAndPositionManager.getSizeAndPositionOfCell(0).size).toEqual(10); expect(cellSizeAndPositionManager.getSizeAndPositionOfCell(1).offset).toEqual(10); expect(cellSizeAndPositionManager.getSizeAndPositionOfCell(2).offset).toEqual(20); }); it('should only measure the necessary cells to return the information requested', function () { var _getCellSizeAndPositi10 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi10.cellSizeAndPositionManager, cellSizeGetterCalls = _getCellSizeAndPositi10.cellSizeGetterCalls; cellSizeAndPositionManager.getSizeAndPositionOfCell(0); expect(cellSizeGetterCalls).toEqual([0]); }); it('should just-in-time measure all cells up to the requested cell if no cells have yet been measured', function () { var _getCellSizeAndPositi11 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi11.cellSizeAndPositionManager, cellSizeGetterCalls = _getCellSizeAndPositi11.cellSizeGetterCalls; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); expect(cellSizeGetterCalls).toEqual([0, 1, 2, 3, 4, 5]); }); it('should just-in-time measure cells up to the requested cell if some but not all cells have been measured', function () { var _getCellSizeAndPositi12 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi12.cellSizeAndPositionManager, cellSizeGetterCalls = _getCellSizeAndPositi12.cellSizeGetterCalls; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); cellSizeGetterCalls.splice(0); cellSizeAndPositionManager.getSizeAndPositionOfCell(10); expect(cellSizeGetterCalls).toEqual([6, 7, 8, 9, 10]); }); it('should return cached size and position data if cell has already been measured', function () { var _getCellSizeAndPositi13 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi13.cellSizeAndPositionManager, cellSizeGetterCalls = _getCellSizeAndPositi13.cellSizeGetterCalls; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); cellSizeGetterCalls.splice(0); cellSizeAndPositionManager.getSizeAndPositionOfCell(5); expect(cellSizeGetterCalls).toEqual([]); }); }); describe('getSizeAndPositionOfLastMeasuredCell', function () { it('should return an empty object if no cached cells are present', function () { var _getCellSizeAndPositi14 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi14.cellSizeAndPositionManager; expect(cellSizeAndPositionManager.getSizeAndPositionOfLastMeasuredCell()).toEqual({ offset: 0, size: 0 }); }); it('should return size and position data for the highest/last measured cell', function () { var _getCellSizeAndPositi15 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi15.cellSizeAndPositionManager; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); expect(cellSizeAndPositionManager.getSizeAndPositionOfLastMeasuredCell()).toEqual({ offset: 50, size: 10 }); }); }); describe('getTotalSize', function () { it('should calculate total size based purely on :estimatedCellSize if no measurements have been done', function () { var _getCellSizeAndPositi16 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi16.cellSizeAndPositionManager; expect(cellSizeAndPositionManager.getTotalSize()).toEqual(1500); }); it('should calculate total size based on a mixture of actual cell sizes and :estimatedCellSize if some cells have been measured', function () { var _getCellSizeAndPositi17 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi17.cellSizeAndPositionManager; cellSizeAndPositionManager.getSizeAndPositionOfCell(49); expect(cellSizeAndPositionManager.getTotalSize()).toEqual(1250); }); it('should calculate total size based on the actual measured sizes if all cells have been measured', function () { var _getCellSizeAndPositi18 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi18.cellSizeAndPositionManager; cellSizeAndPositionManager.getSizeAndPositionOfCell(99); expect(cellSizeAndPositionManager.getTotalSize()).toEqual(1000); }); }); describe('getUpdatedOffsetForIndex', function () { function getUpdatedOffsetForIndexHelper(_ref3) { var _ref3$align = _ref3.align, align = _ref3$align === void 0 ? 'auto' : _ref3$align, _ref3$cellCount = _ref3.cellCount, cellCount = _ref3$cellCount === void 0 ? 10 : _ref3$cellCount, _ref3$cellSize = _ref3.cellSize, cellSize = _ref3$cellSize === void 0 ? 10 : _ref3$cellSize, _ref3$containerSize = _ref3.containerSize, containerSize = _ref3$containerSize === void 0 ? 50 : _ref3$containerSize, _ref3$currentOffset = _ref3.currentOffset, currentOffset = _ref3$currentOffset === void 0 ? 0 : _ref3$currentOffset, _ref3$estimatedCellSi = _ref3.estimatedCellSize, estimatedCellSize = _ref3$estimatedCellSi === void 0 ? 15 : _ref3$estimatedCellSi, _ref3$targetIndex = _ref3.targetIndex, targetIndex = _ref3$targetIndex === void 0 ? 0 : _ref3$targetIndex; var cellSizeAndPositionManager = new CellSizeAndPositionManager({ cellCount: cellCount, cellSizeGetter: function cellSizeGetter() { return cellSize; }, estimatedCellSize: estimatedCellSize }); return cellSizeAndPositionManager.getUpdatedOffsetForIndex({ align: align, containerSize: containerSize, currentOffset: currentOffset, targetIndex: targetIndex }); } it('should scroll to the beginning', function () { expect(getUpdatedOffsetForIndexHelper({ currentOffset: 100, targetIndex: 0 })).toEqual(0); }); it('should scroll to the end', function () { expect(getUpdatedOffsetForIndexHelper({ currentOffset: 0, targetIndex: 9 })).toEqual(50); }); it('should scroll forward to the middle', function () { expect(getUpdatedOffsetForIndexHelper({ currentOffset: 0, targetIndex: 6 })).toEqual(20); }); it('should scroll backward to the middle', function () { expect(getUpdatedOffsetForIndexHelper({ currentOffset: 50, targetIndex: 2 })).toEqual(20); }); it('should not scroll if an item is already visible', function () { expect(getUpdatedOffsetForIndexHelper({ currentOffset: 20, targetIndex: 3 })).toEqual(20); }); it('should honor specified :align values', function () { expect(getUpdatedOffsetForIndexHelper({ align: 'auto', currentOffset: 0, targetIndex: 5 })).toEqual(10); expect(getUpdatedOffsetForIndexHelper({ align: 'start', currentOffset: 0, targetIndex: 5 })).toEqual(50); expect(getUpdatedOffsetForIndexHelper({ align: 'auto', currentOffset: 50, targetIndex: 4 })).toEqual(40); expect(getUpdatedOffsetForIndexHelper({ align: 'end', currentOffset: 50, targetIndex: 5 })).toEqual(10); expect(getUpdatedOffsetForIndexHelper({ align: 'center', currentOffset: 50, targetIndex: 5 })).toEqual(30); }); it('should not scroll past the safe bounds even if the specified :align requests it', function () { expect(getUpdatedOffsetForIndexHelper({ align: 'end', currentOffset: 50, targetIndex: 0 })).toEqual(0); expect(getUpdatedOffsetForIndexHelper({ align: 'center', currentOffset: 50, targetIndex: 1 })).toEqual(0); expect(getUpdatedOffsetForIndexHelper({ align: 'start', currentOffset: 0, targetIndex: 9 })).toEqual(50); // TRICKY: We would expect this to be positioned at 50. // But since the :estimatedCellSize is 15 and we only measure up to the 8th item, // The helper assumes it can scroll farther than it actually can. // Not sure if this edge case is worth "fixing" or just acknowledging... expect(getUpdatedOffsetForIndexHelper({ align: 'center', currentOffset: 0, targetIndex: 8 })).toEqual(55); }); it('should always return an offset of 0 when :containerSize is 0', function () { expect(getUpdatedOffsetForIndexHelper({ containerSize: 0, currentOffset: 50, targetIndex: 2 })).toEqual(0); }); }); describe('getVisibleCellRange', function () { it('should not return any indices if :cellCount is 0', function () { var _getCellSizeAndPositi19 = getCellSizeAndPositionManager({ cellCount: 0 }), cellSizeAndPositionManager = _getCellSizeAndPositi19.cellSizeAndPositionManager; var _cellSizeAndPositionM = cellSizeAndPositionManager.getVisibleCellRange({ containerSize: 50, offset: 0 }), start = _cellSizeAndPositionM.start, stop = _cellSizeAndPositionM.stop; expect(start).toEqual(undefined); expect(stop).toEqual(undefined); }); it('should return a visible range of cells for the beginning of the list', function () { var _getCellSizeAndPositi20 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi20.cellSizeAndPositionManager; var _cellSizeAndPositionM2 = cellSizeAndPositionManager.getVisibleCellRange({ containerSize: 50, offset: 0 }), start = _cellSizeAndPositionM2.start, stop = _cellSizeAndPositionM2.stop; expect(start).toEqual(0); expect(stop).toEqual(4); }); it('should return a visible range of cells for the middle of the list where some are partially visible', function () { var _getCellSizeAndPositi21 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi21.cellSizeAndPositionManager; var _cellSizeAndPositionM3 = cellSizeAndPositionManager.getVisibleCellRange({ containerSize: 50, offset: 425 }), start = _cellSizeAndPositionM3.start, stop = _cellSizeAndPositionM3.stop; // 42 and 47 are partially visible expect(start).toEqual(42); expect(stop).toEqual(47); }); it('should return a visible range of cells for the end of the list', function () { var _getCellSizeAndPositi22 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi22.cellSizeAndPositionManager; var _cellSizeAndPositionM4 = cellSizeAndPositionManager.getVisibleCellRange({ containerSize: 50, offset: 950 }), start = _cellSizeAndPositionM4.start, stop = _cellSizeAndPositionM4.stop; expect(start).toEqual(95); expect(stop).toEqual(99); }); }); describe('resetCell', function () { it('should clear size and position metadata for the specified index and all cells after it', function () { var _getCellSizeAndPositi23 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi23.cellSizeAndPositionManager; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); cellSizeAndPositionManager.resetCell(3); expect(cellSizeAndPositionManager.getLastMeasuredIndex()).toEqual(2); cellSizeAndPositionManager.resetCell(0); expect(cellSizeAndPositionManager.getLastMeasuredIndex()).toEqual(-1); }); it('should not clear size and position metadata for cells before the specified index', function () { var _getCellSizeAndPositi24 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi24.cellSizeAndPositionManager, cellSizeGetterCalls = _getCellSizeAndPositi24.cellSizeGetterCalls; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); cellSizeGetterCalls.splice(0); cellSizeAndPositionManager.resetCell(3); cellSizeAndPositionManager.getSizeAndPositionOfCell(4); expect(cellSizeGetterCalls).toEqual([3, 4]); }); it('should not skip over any unmeasured or previously-cleared cells', function () { var _getCellSizeAndPositi25 = getCellSizeAndPositionManager(), cellSizeAndPositionManager = _getCellSizeAndPositi25.cellSizeAndPositionManager; cellSizeAndPositionManager.getSizeAndPositionOfCell(5); cellSizeAndPositionManager.resetCell(2); expect(cellSizeAndPositionManager.getLastMeasuredIndex()).toEqual(1); cellSizeAndPositionManager.resetCell(4); expect(cellSizeAndPositionManager.getLastMeasuredIndex()).toEqual(1); cellSizeAndPositionManager.resetCell(0); expect(cellSizeAndPositionManager.getLastMeasuredIndex()).toEqual(-1); }); }); });dist/es/Grid/index.js000064400000002171151676725770010500 0ustar00export { default } from './Grid'; export { default as Grid } from './Grid'; export { default as accessibilityOverscanIndicesGetter } from './accessibilityOverscanIndicesGetter'; export { default as defaultCellRangeRenderer } from './defaultCellRangeRenderer'; export { default as defaultOverscanIndicesGetter } from './defaultOverscanIndicesGetter'; import { bpfrpt_proptype_NoContentRenderer } from "./types"; export { bpfrpt_proptype_NoContentRenderer }; import { bpfrpt_proptype_Alignment } from "./types"; export { bpfrpt_proptype_Alignment }; import { bpfrpt_proptype_CellPosition } from "./types"; export { bpfrpt_proptype_CellPosition }; import { bpfrpt_proptype_CellSize } from "./types"; export { bpfrpt_proptype_CellSize }; import { bpfrpt_proptype_OverscanIndicesGetter } from "./types"; export { bpfrpt_proptype_OverscanIndicesGetter }; import { bpfrpt_proptype_RenderedSection } from "./types"; export { bpfrpt_proptype_RenderedSection }; import { bpfrpt_proptype_CellRendererParams } from "./types"; export { bpfrpt_proptype_CellRendererParams }; import { bpfrpt_proptype_Scroll } from "./types"; export { bpfrpt_proptype_Scroll };dist/es/Grid/Grid.ssr.js000064400000003037151676725770011066 0ustar00/** * * @jest-environment node */ import * as React from 'react'; import * as ReactDOMServer from 'react-dom/server'; import Grid from './Grid'; test('should render Grid with dom server', function () { var rendered = ReactDOMServer.renderToString(React.createElement(Grid, { cellRenderer: function cellRenderer(_ref) { var style = _ref.style, key = _ref.key, rowIndex = _ref.rowIndex, columnIndex = _ref.columnIndex; return React.createElement("div", { style: style, key: key }, rowIndex + ':' + columnIndex); }, columnCount: 1000, columnWidth: 20, height: 500, rowCount: 1000, rowHeight: 20, width: 500 })); expect(rendered).toContain('0:0'); expect(rendered).toContain('24:24'); expect(rendered).not.toContain('25:25'); }); test('should support :scrollToColumn and :scrollToRow in server render', function () { var rendered = ReactDOMServer.renderToString(React.createElement(Grid, { cellRenderer: function cellRenderer(_ref2) { var style = _ref2.style, key = _ref2.key, rowIndex = _ref2.rowIndex, columnIndex = _ref2.columnIndex; return React.createElement("div", { style: style, key: key }, rowIndex + ':' + columnIndex); }, columnCount: 1000, columnWidth: 20, scrollToColumn: 250, height: 500, rowCount: 1000, rowHeight: 20, scrollToRow: 250, width: 500 })); expect(rendered).toContain('250:250'); expect(rendered).not.toContain('0:0'); });dist/es/Grid/accessibilityOverscanIndicesGetter.jest.js000064400000004721151676725770017342 0ustar00import overscanIndicesGetter, { SCROLL_DIRECTION_BACKWARD, SCROLL_DIRECTION_FORWARD } from './accessibilityOverscanIndicesGetter'; describe('overscanIndicesGetter', function () { function testHelper(_ref) { var cellCount = _ref.cellCount, startIndex = _ref.startIndex, stopIndex = _ref.stopIndex, overscanCellsCount = _ref.overscanCellsCount, scrollDirection = _ref.scrollDirection; return overscanIndicesGetter({ cellCount: cellCount, overscanCellsCount: overscanCellsCount, scrollDirection: scrollDirection, startIndex: startIndex, stopIndex: stopIndex }); } it('should still overscan by 1 (for keyboard accessibility) if :overscanCellsCount is 0', function () { expect(testHelper({ cellCount: 100, startIndex: 10, stopIndex: 20, overscanCellsCount: 0, scrollDirection: SCROLL_DIRECTION_BACKWARD })).toEqual({ overscanStartIndex: 9, overscanStopIndex: 21 }); expect(testHelper({ cellCount: 100, startIndex: 10, stopIndex: 20, overscanCellsCount: 0, scrollDirection: SCROLL_DIRECTION_FORWARD })).toEqual({ overscanStartIndex: 9, overscanStopIndex: 21 }); }); it('should overscan forward', function () { expect(testHelper({ cellCount: 100, startIndex: 20, stopIndex: 30, overscanCellsCount: 10, scrollDirection: SCROLL_DIRECTION_FORWARD })).toEqual({ overscanStartIndex: 19, overscanStopIndex: 40 }); }); it('should overscan backward', function () { expect(testHelper({ cellCount: 100, startIndex: 20, stopIndex: 30, overscanCellsCount: 10, scrollDirection: SCROLL_DIRECTION_BACKWARD })).toEqual({ overscanStartIndex: 10, overscanStopIndex: 31 }); }); it('should not overscan beyond the start of the list', function () { expect(testHelper({ cellCount: 100, startIndex: 5, stopIndex: 15, overscanCellsCount: 10, scrollDirection: SCROLL_DIRECTION_BACKWARD })).toEqual({ overscanStartIndex: 0, overscanStopIndex: 16 }); }); it('should not overscan beyond the end of the list', function () { expect(testHelper({ cellCount: 25, startIndex: 10, stopIndex: 20, overscanCellsCount: 10, scrollDirection: SCROLL_DIRECTION_FORWARD })).toEqual({ overscanStartIndex: 9, overscanStopIndex: 24 }); }); });dist/es/Grid/defaultOverscanIndicesGetter.js000064400000002150151676725770015165 0ustar00export var SCROLL_DIRECTION_BACKWARD = -1; export var SCROLL_DIRECTION_FORWARD = 1; export var SCROLL_DIRECTION_HORIZONTAL = 'horizontal'; export var SCROLL_DIRECTION_VERTICAL = 'vertical'; /** * Calculates the number of cells to overscan before and after a specified range. * This function ensures that overscanning doesn't exceed the available cells. */ export default function defaultOverscanIndicesGetter(_ref) { var cellCount = _ref.cellCount, overscanCellsCount = _ref.overscanCellsCount, scrollDirection = _ref.scrollDirection, startIndex = _ref.startIndex, stopIndex = _ref.stopIndex; if (scrollDirection === SCROLL_DIRECTION_FORWARD) { return { overscanStartIndex: Math.max(0, startIndex), overscanStopIndex: Math.min(cellCount - 1, stopIndex + overscanCellsCount) }; } else { return { overscanStartIndex: Math.max(0, startIndex - overscanCellsCount), overscanStopIndex: Math.min(cellCount - 1, stopIndex) }; } } import { bpfrpt_proptype_OverscanIndicesGetterParams } from "./types"; import { bpfrpt_proptype_OverscanIndices } from "./types";dist/es/jest-setup.js000064400000000163151676725770010606 0ustar00jest.mock('dom-helpers/scrollbarSize', function () { return function getScrollbarSize() { return 20; }; });dist/es/WindowScroller/WindowScroller.e2e.js000064400000023044151676725770015112 0ustar00import _regeneratorRuntime from "@babel/runtime/regenerator"; /** * @jest-environment jest-environment-puppeteer */ var bootstrap = function bootstrap() { var page, scripts, _i, _scripts, path; return _regeneratorRuntime.async(function bootstrap$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return _regeneratorRuntime.awrap(global.browser.newPage()); case 2: page = _context.sent; scripts = ['./node_modules/react/umd/react.development.js', './node_modules/react-dom/umd/react-dom.development.js', './dist/umd/react-virtualized.js']; _i = 0, _scripts = scripts; case 5: if (!(_i < _scripts.length)) { _context.next = 12; break; } path = _scripts[_i]; _context.next = 9; return _regeneratorRuntime.awrap(page.addScriptTag({ path: path })); case 9: _i++; _context.next = 5; break; case 12: return _context.abrupt("return", page); case 13: case "end": return _context.stop(); } } }); }; var renderWindowScroller = function renderWindowScroller(_ref) { var scrollElement = _ref.scrollElement; var render = window.ReactDOM.render; var createElement = window.React.createElement; var WindowScroller = window.ReactVirtualized.WindowScroller; var container = document.createElement('div'); container.id = 'container'; container.style.margin = '100px'; container.style.padding = '50px'; document.body.appendChild(container); document.body.style.margin = 0; if (scrollElement === 'container') { container.style.width = '100%'; container.style.height = '100%'; container.style.overflow = 'auto'; } render(createElement(WindowScroller, { scrollElement: scrollElement === 'container' ? container : window, onScroll: window.scrollFn, onResize: window.resizeFn }, function () { return createElement('div', { style: { width: 2000, height: 3000 } }); }), container); }; var delay = function delay(time) { return new Promise(function (resolve) { return setTimeout(resolve, time); }); }; test('save position after resize and then scroll in window', function _callee() { var page, scrollFn, resizeFn; return _regeneratorRuntime.async(function _callee$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: _context2.next = 2; return _regeneratorRuntime.awrap(bootstrap()); case 2: page = _context2.sent; scrollFn = jest.fn(); resizeFn = jest.fn(); _context2.next = 7; return _regeneratorRuntime.awrap(page.exposeFunction('scrollFn', scrollFn)); case 7: _context2.next = 9; return _regeneratorRuntime.awrap(page.exposeFunction('resizeFn', resizeFn)); case 9: _context2.next = 11; return _regeneratorRuntime.awrap(page.setViewport({ width: 400, height: 600 })); case 11: _context2.next = 13; return _regeneratorRuntime.awrap(page.evaluate(renderWindowScroller, { scrollElement: 'window' })); case 13: _context2.next = 15; return _regeneratorRuntime.awrap(page.evaluate(function () { return window.scrollTo(610, 830); })); case 15: _context2.next = 17; return _regeneratorRuntime.awrap(delay(100)); case 17: _context2.next = 19; return _regeneratorRuntime.awrap(page.setViewport({ width: 300, height: 500 })); case 19: _context2.next = 21; return _regeneratorRuntime.awrap(delay(100)); case 21: _context2.next = 23; return _regeneratorRuntime.awrap(page.evaluate(function () { return window.scrollTo(620, 840); })); case 23: _context2.next = 25; return _regeneratorRuntime.awrap(delay(100)); case 25: _context2.next = 27; return _regeneratorRuntime.awrap(page.close()); case 27: expect(scrollFn.mock.calls).toEqual([[{ scrollLeft: 610 - 150, scrollTop: 830 - 150 }], [{ scrollLeft: 620 - 150, scrollTop: 840 - 150 }]]); expect(resizeFn.mock.calls).toEqual([[{ width: 300, height: 500 }]]); case 29: case "end": return _context2.stop(); } } }); }); test('save position after resize and then scroll in container', function _callee2() { var page, scrollFn, resizeFn; return _regeneratorRuntime.async(function _callee2$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: _context3.next = 2; return _regeneratorRuntime.awrap(bootstrap()); case 2: page = _context3.sent; scrollFn = jest.fn(); resizeFn = jest.fn(); _context3.next = 7; return _regeneratorRuntime.awrap(page.exposeFunction('scrollFn', scrollFn)); case 7: _context3.next = 9; return _regeneratorRuntime.awrap(page.exposeFunction('resizeFn', resizeFn)); case 9: _context3.next = 11; return _regeneratorRuntime.awrap(page.setViewport({ width: 400, height: 600 })); case 11: _context3.next = 13; return _regeneratorRuntime.awrap(page.evaluate(renderWindowScroller, { scrollElement: 'container' })); case 13: _context3.next = 15; return _regeneratorRuntime.awrap(page.$eval('#container', function (el) { return el.scrollTo(610, 830); })); case 15: _context3.next = 17; return _regeneratorRuntime.awrap(delay(100)); case 17: _context3.next = 19; return _regeneratorRuntime.awrap(page.setViewport({ width: 300, height: 500 })); case 19: _context3.next = 21; return _regeneratorRuntime.awrap(delay(100)); case 21: _context3.next = 23; return _regeneratorRuntime.awrap(page.$eval('#container', function (el) { return el.scrollTo(620, 840); })); case 23: _context3.next = 25; return _regeneratorRuntime.awrap(delay(100)); case 25: _context3.next = 27; return _regeneratorRuntime.awrap(page.close()); case 27: expect(scrollFn.mock.calls).toEqual([[{ scrollLeft: 610 - 50, scrollTop: 830 - 50 }], [{ scrollLeft: 620 - 50, scrollTop: 840 - 50 }]]); expect(resizeFn.mock.calls).toEqual([[{ width: 500, height: 700 }], [{ width: 400, height: 600 }]]); case 29: case "end": return _context3.stop(); } } }); }); test('react on container resize without window changing', function _callee3() { var page, resizeFn; return _regeneratorRuntime.async(function _callee3$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: _context4.next = 2; return _regeneratorRuntime.awrap(bootstrap()); case 2: page = _context4.sent; resizeFn = jest.fn(); _context4.next = 6; return _regeneratorRuntime.awrap(page.exposeFunction('resizeFn', resizeFn)); case 6: _context4.next = 8; return _regeneratorRuntime.awrap(page.evaluate(function () { var render = window.ReactDOM.render; var createElement = window.React.createElement; var WindowScroller = window.ReactVirtualized.WindowScroller; var wrapper = document.createElement('div'); wrapper.id = 'wrapper'; Object.assign(wrapper.style, { width: '1000px', height: '800px', display: 'flex' }); var container = document.createElement('div'); Object.assign(container.style, { flex: '1' }); wrapper.appendChild(container); document.body.style.margin = 0; document.body.appendChild(wrapper); render(createElement(WindowScroller, { scrollElement: container, onResize: window.resizeFn }, function () { return null; }), container); })); case 8: _context4.next = 10; return _regeneratorRuntime.awrap(delay(100)); case 10: _context4.next = 12; return _regeneratorRuntime.awrap(page.$eval('#wrapper', function (el) { el.style.width = '500px'; el.style.height = '700px'; })); case 12: _context4.next = 14; return _regeneratorRuntime.awrap(delay(100)); case 14: _context4.next = 16; return _regeneratorRuntime.awrap(page.close()); case 16: expect(resizeFn.mock.calls).toEqual([[{ width: 1000, height: 800 }], [{ width: 500, height: 700 }]]); case 17: case "end": return _context4.stop(); } } }); });dist/es/WindowScroller/WindowScroller.example.js000064400000015763151676725770016103 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; var _class, _temp; import clsx from 'clsx'; import Immutable from 'immutable'; import PropTypes from 'prop-types'; import * as React from 'react'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import { LabeledInput, InputRow } from '../demo/LabeledInput'; import WindowScroller from './WindowScroller'; import List from '../List'; import AutoSizer from '../AutoSizer'; import styles from './WindowScroller.example.css'; var WindowScrollerExample = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { _inherits(WindowScrollerExample, _React$PureComponent); function WindowScrollerExample() { var _getPrototypeOf2; var _this; _classCallCheck(this, WindowScrollerExample); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(WindowScrollerExample)).call.apply(_getPrototypeOf2, [this].concat(args))); _defineProperty(_assertThisInitialized(_this), "state", { scrollToIndex: -1, showHeaderText: true }); _defineProperty(_assertThisInitialized(_this), "_windowScroller", void 0); _defineProperty(_assertThisInitialized(_this), "_hideHeader", function () { var showHeaderText = _this.state.showHeaderText; _this.setState({ showHeaderText: !showHeaderText }, function () { if (_this._windowScroller) { _this._windowScroller.updatePosition(); } }); }); _defineProperty(_assertThisInitialized(_this), "_rowRenderer", function (_ref) { var _clsx; var index = _ref.index, isScrolling = _ref.isScrolling, isVisible = _ref.isVisible, key = _ref.key, style = _ref.style; var list = _this.context.list; var row = list.get(index); var className = clsx(styles.row, (_clsx = {}, _defineProperty(_clsx, styles.rowScrolling, isScrolling), _defineProperty(_clsx, "isVisible", isVisible), _clsx)); return React.createElement("div", { key: key, className: className, style: style }, row.name); }); _defineProperty(_assertThisInitialized(_this), "_setRef", function (windowScroller) { _this._windowScroller = windowScroller; }); _defineProperty(_assertThisInitialized(_this), "_onCheckboxChange", function (event) { _this.context.setScrollingCustomElement(event.target.checked); }); _defineProperty(_assertThisInitialized(_this), "_onScrollToRowChange", function (event) { var list = _this.context.list; var scrollToIndex = Math.min(list.size - 1, parseInt(event.target.value, 10)); if (isNaN(scrollToIndex)) { scrollToIndex = undefined; } setTimeout(function () { _this.setState({ scrollToIndex: scrollToIndex }); }, 0); }); return _this; } _createClass(WindowScrollerExample, [{ key: "render", value: function render() { var _this2 = this; var _this$context = this.context, customElement = _this$context.customElement, isScrollingCustomElement = _this$context.isScrollingCustomElement, list = _this$context.list; var _this$state = this.state, scrollToIndex = _this$state.scrollToIndex, showHeaderText = _this$state.showHeaderText; return React.createElement(ContentBox, null, React.createElement(ContentBoxHeader, { text: "WindowScroller", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/WindowScroller/WindowScroller.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/WindowScroller.md" }), showHeaderText && React.createElement(ContentBoxParagraph, null, "This component decorates ", React.createElement("code", null, "List"), ", ", React.createElement("code", null, "Table"), ", or any other component and manages the window scroll to scroll through the list"), showHeaderText && React.createElement(ContentBoxParagraph, null, React.createElement("button", { onClick: this._hideHeader }, "Hide header text")), React.createElement(ContentBoxParagraph, null, React.createElement("label", { className: styles.checkboxLabel }, React.createElement("input", { "aria-label": "Use custom element for scrolling", className: styles.checkbox, type: "checkbox", checked: isScrollingCustomElement, onChange: this._onCheckboxChange }), "Use custom element for scrolling")), React.createElement(InputRow, null, React.createElement(LabeledInput, { label: "Scroll to", name: "onScrollToRow", placeholder: "Index...", onChange: this._onScrollToRowChange, value: scrollToIndex || '' })), React.createElement(WindowScroller, { ref: this._setRef, scrollElement: isScrollingCustomElement ? customElement : window }, function (_ref2) { var height = _ref2.height, isScrolling = _ref2.isScrolling, registerChild = _ref2.registerChild, onChildScroll = _ref2.onChildScroll, scrollTop = _ref2.scrollTop; return React.createElement("div", { className: styles.WindowScrollerWrapper }, React.createElement(AutoSizer, { disableHeight: true }, function (_ref3) { var width = _ref3.width; return React.createElement("div", { ref: registerChild }, React.createElement(List, { ref: function ref(el) { window.listEl = el; }, autoHeight: true, className: styles.List, height: height, isScrolling: isScrolling, onScroll: onChildScroll, overscanRowCount: 2, rowCount: list.size, rowHeight: 30, rowRenderer: _this2._rowRenderer, scrollToIndex: scrollToIndex, scrollTop: scrollTop, width: width })); })); })); } }]); return WindowScrollerExample; }(React.PureComponent), _defineProperty(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : {}), _temp); _defineProperty(WindowScrollerExample, "contextTypes", { customElement: PropTypes.any, isScrollingCustomElement: PropTypes.bool.isRequired, list: PropTypes.instanceOf(Immutable.List).isRequired, setScrollingCustomElement: PropTypes.func }); export { WindowScrollerExample as default };dist/es/WindowScroller/index.js.flow000064400000000240151676725770013531 0ustar00// @flow import WindowScroller, {IS_SCROLLING_TIMEOUT} from './WindowScroller'; export default WindowScroller; export {WindowScroller, IS_SCROLLING_TIMEOUT}; dist/es/WindowScroller/utils/dimensions.js000064400000005006151676725770014771 0ustar00/** * Gets the dimensions of the element, accounting for API differences between * `window` and other DOM elements. */ // TODO Move this into WindowScroller and import from there var isWindow = function isWindow(element) { return element === window; }; var getBoundingBox = function getBoundingBox(element) { return element.getBoundingClientRect(); }; export function getDimensions(scrollElement, props) { if (!scrollElement) { return { height: props.serverHeight, width: props.serverWidth }; } else if (isWindow(scrollElement)) { var _window = window, innerHeight = _window.innerHeight, innerWidth = _window.innerWidth; return { height: typeof innerHeight === 'number' ? innerHeight : 0, width: typeof innerWidth === 'number' ? innerWidth : 0 }; } else { return getBoundingBox(scrollElement); } } /** * Gets the vertical and horizontal position of an element within its scroll container. * Elements that have been “scrolled past” return negative values. * Handles edge-case where a user is navigating back (history) from an already-scrolled page. * In this case the body’s top or left position will be a negative number and this element’s top or left will be increased (by that amount). */ export function getPositionOffset(element, container) { if (isWindow(container) && document.documentElement) { var containerElement = document.documentElement; var elementRect = getBoundingBox(element); var containerRect = getBoundingBox(containerElement); return { top: elementRect.top - containerRect.top, left: elementRect.left - containerRect.left }; } else { var scrollOffset = getScrollOffset(container); var _elementRect = getBoundingBox(element); var _containerRect = getBoundingBox(container); return { top: _elementRect.top + scrollOffset.top - _containerRect.top, left: _elementRect.left + scrollOffset.left - _containerRect.left }; } } /** * Gets the vertical and horizontal scroll amount of the element, accounting for IE compatibility * and API differences between `window` and other DOM elements. */ export function getScrollOffset(element) { if (isWindow(element) && document.documentElement) { return { top: 'scrollY' in window ? window.scrollY : document.documentElement.scrollTop, left: 'scrollX' in window ? window.scrollX : document.documentElement.scrollLeft }; } else { return { top: element.scrollTop, left: element.scrollLeft }; } }dist/es/WindowScroller/utils/dimensions.js.flow000064400000005255151676725770015745 0ustar00// @flow /** * Gets the dimensions of the element, accounting for API differences between * `window` and other DOM elements. */ type Dimensions = { height: number, width: number, }; // TODO Move this into WindowScroller and import from there type WindowScrollerProps = { serverHeight: number, serverWidth: number, }; const isWindow = element => element === window; const getBoundingBox = element => element.getBoundingClientRect(); export function getDimensions( scrollElement: ?Element, props: WindowScrollerProps, ): Dimensions { if (!scrollElement) { return { height: props.serverHeight, width: props.serverWidth, }; } else if (isWindow(scrollElement)) { const {innerHeight, innerWidth} = window; return { height: typeof innerHeight === 'number' ? innerHeight : 0, width: typeof innerWidth === 'number' ? innerWidth : 0, }; } else { return getBoundingBox(scrollElement); } } /** * Gets the vertical and horizontal position of an element within its scroll container. * Elements that have been “scrolled past” return negative values. * Handles edge-case where a user is navigating back (history) from an already-scrolled page. * In this case the body’s top or left position will be a negative number and this element’s top or left will be increased (by that amount). */ export function getPositionOffset(element: Element, container: Element) { if (isWindow(container) && document.documentElement) { const containerElement = document.documentElement; const elementRect = getBoundingBox(element); const containerRect = getBoundingBox(containerElement); return { top: elementRect.top - containerRect.top, left: elementRect.left - containerRect.left, }; } else { const scrollOffset = getScrollOffset(container); const elementRect = getBoundingBox(element); const containerRect = getBoundingBox(container); return { top: elementRect.top + scrollOffset.top - containerRect.top, left: elementRect.left + scrollOffset.left - containerRect.left, }; } } /** * Gets the vertical and horizontal scroll amount of the element, accounting for IE compatibility * and API differences between `window` and other DOM elements. */ export function getScrollOffset(element: Element) { if (isWindow(element) && document.documentElement) { return { top: 'scrollY' in window ? window.scrollY : document.documentElement.scrollTop, left: 'scrollX' in window ? window.scrollX : document.documentElement.scrollLeft, }; } else { return { top: element.scrollTop, left: element.scrollLeft, }; } } dist/es/WindowScroller/utils/onScroll.js000064400000004462151676725770014421 0ustar00import { requestAnimationTimeout, cancelAnimationTimeout } from '../../utils/requestAnimationTimeout'; var mountedInstances = []; var originalBodyPointerEvents = null; var disablePointerEventsTimeoutId = null; function enablePointerEventsIfDisabled() { if (disablePointerEventsTimeoutId) { disablePointerEventsTimeoutId = null; if (document.body && originalBodyPointerEvents != null) { document.body.style.pointerEvents = originalBodyPointerEvents; } originalBodyPointerEvents = null; } } function enablePointerEventsAfterDelayCallback() { enablePointerEventsIfDisabled(); mountedInstances.forEach(function (instance) { return instance.__resetIsScrolling(); }); } function enablePointerEventsAfterDelay() { if (disablePointerEventsTimeoutId) { cancelAnimationTimeout(disablePointerEventsTimeoutId); } var maximumTimeout = 0; mountedInstances.forEach(function (instance) { maximumTimeout = Math.max(maximumTimeout, instance.props.scrollingResetTimeInterval); }); disablePointerEventsTimeoutId = requestAnimationTimeout(enablePointerEventsAfterDelayCallback, maximumTimeout); } function onScrollWindow(event) { if (event.currentTarget === window && originalBodyPointerEvents == null && document.body) { originalBodyPointerEvents = document.body.style.pointerEvents; document.body.style.pointerEvents = 'none'; } enablePointerEventsAfterDelay(); mountedInstances.forEach(function (instance) { if (instance.props.scrollElement === event.currentTarget) { instance.__handleWindowScrollEvent(); } }); } export function registerScrollListener(component, element) { if (!mountedInstances.some(function (instance) { return instance.props.scrollElement === element; })) { element.addEventListener('scroll', onScrollWindow); } mountedInstances.push(component); } export function unregisterScrollListener(component, element) { mountedInstances = mountedInstances.filter(function (instance) { return instance !== component; }); if (!mountedInstances.length) { element.removeEventListener('scroll', onScrollWindow); if (disablePointerEventsTimeoutId) { cancelAnimationTimeout(disablePointerEventsTimeoutId); enablePointerEventsIfDisabled(); } } } import { bpfrpt_proptype_WindowScroller } from "../WindowScroller.js";dist/es/WindowScroller/utils/onScroll.js.flow000064400000004535151676725770015370 0ustar00// @flow import { requestAnimationTimeout, cancelAnimationTimeout, } from '../../utils/requestAnimationTimeout'; import type WindowScroller from '../WindowScroller.js'; let mountedInstances = []; let originalBodyPointerEvents = null; let disablePointerEventsTimeoutId = null; function enablePointerEventsIfDisabled() { if (disablePointerEventsTimeoutId) { disablePointerEventsTimeoutId = null; if (document.body && originalBodyPointerEvents != null) { document.body.style.pointerEvents = originalBodyPointerEvents; } originalBodyPointerEvents = null; } } function enablePointerEventsAfterDelayCallback() { enablePointerEventsIfDisabled(); mountedInstances.forEach(instance => instance.__resetIsScrolling()); } function enablePointerEventsAfterDelay() { if (disablePointerEventsTimeoutId) { cancelAnimationTimeout(disablePointerEventsTimeoutId); } var maximumTimeout = 0; mountedInstances.forEach(instance => { maximumTimeout = Math.max( maximumTimeout, instance.props.scrollingResetTimeInterval, ); }); disablePointerEventsTimeoutId = requestAnimationTimeout( enablePointerEventsAfterDelayCallback, maximumTimeout, ); } function onScrollWindow(event: Event) { if ( event.currentTarget === window && originalBodyPointerEvents == null && document.body ) { originalBodyPointerEvents = document.body.style.pointerEvents; document.body.style.pointerEvents = 'none'; } enablePointerEventsAfterDelay(); mountedInstances.forEach(instance => { if (instance.props.scrollElement === event.currentTarget) { instance.__handleWindowScrollEvent(); } }); } export function registerScrollListener( component: WindowScroller, element: Element, ) { if ( !mountedInstances.some(instance => instance.props.scrollElement === element) ) { element.addEventListener('scroll', onScrollWindow); } mountedInstances.push(component); } export function unregisterScrollListener( component: WindowScroller, element: Element, ) { mountedInstances = mountedInstances.filter( instance => instance !== component, ); if (!mountedInstances.length) { element.removeEventListener('scroll', onScrollWindow); if (disablePointerEventsTimeoutId) { cancelAnimationTimeout(disablePointerEventsTimeoutId); enablePointerEventsIfDisabled(); } } } dist/es/WindowScroller/index.js000064400000000230151676725770012562 0ustar00import WindowScroller, { IS_SCROLLING_TIMEOUT } from './WindowScroller'; export default WindowScroller; export { WindowScroller, IS_SCROLLING_TIMEOUT };dist/es/WindowScroller/WindowScroller.jest.js000064400000044465151676725770015416 0ustar00import _regeneratorRuntime from "@babel/runtime/regenerator"; import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties"; import * as React from 'react'; import { findDOMNode } from 'react-dom'; import { render } from '../TestUtils'; import WindowScroller, { IS_SCROLLING_TIMEOUT } from './WindowScroller'; function mockGetBoundingClientRectForHeader(_ref) { var _ref$documentOffset = _ref.documentOffset, documentOffset = _ref$documentOffset === void 0 ? 0 : _ref$documentOffset, height = _ref.height, width = _ref.width; // Mock the WindowScroller element and window separately // The only way to mock the former (before its created) is globally Element.prototype.getBoundingClientRect = jest.fn(function () { return { top: height, left: width }; }); document.documentElement.getBoundingClientRect = jest.fn(function () { return { top: documentOffset, left: documentOffset }; }); } function getMarkup() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, headerElements = _ref2.headerElements, documentOffset = _ref2.documentOffset, renderFn = _ref2.renderFn, props = _objectWithoutProperties(_ref2, ["headerElements", "documentOffset", "renderFn"]); var windowScroller = React.createElement(WindowScroller, props, function (params) { return React.createElement("div", null, renderFn && renderFn(params)); }); // JSDome doesn't implement a working getBoundingClientRect() // But WindowScroller requires it mockGetBoundingClientRectForHeader({ documentOffset: documentOffset, height: headerElements ? headerElements.props.style.height : 0, width: headerElements ? headerElements.props.style.width : 0 }); if (headerElements) { return React.createElement("div", null, headerElements, windowScroller); } else { return windowScroller; } } function simulateWindowScroll(_ref3) { var _ref3$scrollX = _ref3.scrollX, scrollX = _ref3$scrollX === void 0 ? 0 : _ref3$scrollX, _ref3$scrollY = _ref3.scrollY, scrollY = _ref3$scrollY === void 0 ? 0 : _ref3$scrollY; document.body.style.height = '10000px'; window.scrollX = scrollX; window.scrollY = scrollY; document.dispatchEvent(new window.Event('scroll', { bubbles: true })); document.body.style.height = ''; } function simulateWindowResize(_ref4) { var _ref4$height = _ref4.height, height = _ref4$height === void 0 ? 0 : _ref4$height, _ref4$width = _ref4.width, width = _ref4$width === void 0 ? 0 : _ref4$width; window.innerHeight = height; window.innerWidth = width; document.dispatchEvent(new window.Event('resize', { bubbles: true })); } describe('WindowScroller', function () { // Set default window height and scroll position between tests beforeEach(function () { window.scrollY = 0; window.scrollX = 0; window.innerHeight = 500; window.innerWidth = 500; }); // Starts updating scrollTop only when the top position is reached it('should have correct top and left properties to be defined on :_positionFromTop and :_positionFromLeft', function () { var component = render(getMarkup()); var rendered = findDOMNode(component); var _rendered$getBounding = rendered.getBoundingClientRect(), top = _rendered$getBounding.top, left = _rendered$getBounding.left; expect(component._positionFromTop).toEqual(top); expect(component._positionFromLeft).toEqual(left); }); it('should allow passing child element with registerChild of children function param', function () { var scrollElement = document.createElement('div'); scrollElement.scrollTop = 100; scrollElement.scrollLeft = 150; scrollElement.getBoundingClientRect = function () { return { top: 200, left: 250 }; }; var child = document.createElement('div'); child.getBoundingClientRect = function () { return { top: 300, left: 350 }; }; var renderFn = jest.fn(); var component = render(getMarkup({ scrollElement: scrollElement, renderFn: renderFn })); renderFn.mock.calls[0][0].registerChild(child); expect(component._positionFromTop).toEqual(300 + 100 - 200); expect(component._positionFromLeft).toEqual(350 + 150 - 250); }); it('should warn on passing non-element or not null', function () { var warnFn = jest.spyOn(console, 'warn'); var renderFn = jest.fn(); render(getMarkup({ renderFn: renderFn })); renderFn.mock.calls[0][0].registerChild(1); renderFn.mock.calls[0][0].registerChild(document.createElement('div')); renderFn.mock.calls[0][0].registerChild(null); expect(warnFn).toHaveBeenCalledTimes(1); warnFn.mockRestore(); }); // Test edge-case reported in bvaughn/react-virtualized/pull/346 it('should have correct top and left properties to be defined on :_positionFromTop and :_positionFromLeft if documentElement is scrolled', function () { render.unmount(); // Simulate scrolled documentElement var component = render(getMarkup({ documentOffset: -100 })); var rendered = findDOMNode(component); var _rendered$getBounding2 = rendered.getBoundingClientRect(), top = _rendered$getBounding2.top, left = _rendered$getBounding2.left; expect(component._positionFromTop).toEqual(top + 100); expect(component._positionFromLeft).toEqual(left + 100); // Reset override delete document.documentElement.getBoundingClientRect; }); it('inherits the window height and passes it to child component', function () { var renderFn = jest.fn(); var component = render(getMarkup({ renderFn: renderFn })); expect(component.state.height).toEqual(window.innerHeight); expect(component.state.height).toEqual(500); expect(renderFn).lastCalledWith(expect.objectContaining({ height: 500 })); }); it('should restore pointerEvents on body after IS_SCROLLING_TIMEOUT', function _callee() { return _regeneratorRuntime.async(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: render(getMarkup()); document.body.style.pointerEvents = 'all'; simulateWindowScroll({ scrollY: 5000 }); expect(document.body.style.pointerEvents).toEqual('none'); _context.next = 6; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, IS_SCROLLING_TIMEOUT + 100); })); case 6: expect(document.body.style.pointerEvents).toEqual('all'); case 7: case "end": return _context.stop(); } } }); }); it('should restore pointerEvents on body after unmount', function () { render(getMarkup()); document.body.style.pointerEvents = 'all'; simulateWindowScroll({ scrollY: 5000 }); expect(document.body.style.pointerEvents).toEqual('none'); render.unmount(); expect(document.body.style.pointerEvents).toEqual('all'); }); describe('onScroll', function () { it('should trigger callback when window scrolls', function _callee2() { var onScroll; return _regeneratorRuntime.async(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: onScroll = jest.fn(); render(getMarkup({ onScroll: onScroll })); simulateWindowScroll({ scrollY: 5000 }); // Allow scrolling timeout to complete so that the component computes state _context2.next = 5; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, 150); })); case 5: expect(onScroll).toHaveBeenCalledWith({ scrollLeft: 0, scrollTop: 5000 }); simulateWindowScroll({ scrollX: 2500, scrollY: 5000 }); // Allow scrolling timeout to complete so that the component computes state _context2.next = 9; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, 150); })); case 9: expect(onScroll).toHaveBeenCalledWith({ scrollLeft: 2500, scrollTop: 5000 }); case 10: case "end": return _context2.stop(); } } }); }); it('should update :scrollTop when window is scrolled', function _callee3() { var renderFn, component, componentScrollTop; return _regeneratorRuntime.async(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: renderFn = jest.fn(); component = render(getMarkup({ renderFn: renderFn })); // Initial load of the component should have 0 scrollTop expect(renderFn).lastCalledWith(expect.objectContaining({ scrollTop: 0 })); simulateWindowScroll({ scrollY: 5000 }); // Allow scrolling timeout to complete so that the component computes state _context3.next = 6; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, 150); })); case 6: componentScrollTop = window.scrollY - component._positionFromTop; expect(component.state.scrollTop).toEqual(componentScrollTop); expect(renderFn).lastCalledWith(expect.objectContaining({ scrollTop: componentScrollTop })); case 9: case "end": return _context3.stop(); } } }); }); it('should specify :isScrolling when scrolling and reset after scrolling', function _callee4() { var renderFn; return _regeneratorRuntime.async(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: renderFn = jest.fn(); render(getMarkup({ renderFn: renderFn })); simulateWindowScroll({ scrollY: 5000 }); expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: true })); _context4.next = 6; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, 250); })); case 6: expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: false })); case 7: case "end": return _context4.stop(); } } }); }); it('should support a custom :scrollingResetTimeInterval prop', function _callee5() { var renderFn; return _regeneratorRuntime.async(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: renderFn = jest.fn(); render(getMarkup({ scrollingResetTimeInterval: 500, renderFn: renderFn })); expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: false })); simulateWindowScroll({ scrollY: 5000 }); expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: true })); _context5.next = 7; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, 100); })); case 7: expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: true })); _context5.next = 10; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, 100); })); case 10: expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: true })); _context5.next = 13; return _regeneratorRuntime.awrap(new Promise(function (resolve) { return setTimeout(resolve, 400); })); case 13: expect(renderFn).lastCalledWith(expect.objectContaining({ isScrolling: false })); case 14: case "end": return _context5.stop(); } } }); }); }); describe('onResize', function () { it('should trigger callback on init and when window resizes', function () { var resizeFn = jest.fn(); render(getMarkup({ onResize: resizeFn })); simulateWindowResize({ height: 1000, width: 1024 }); expect(resizeFn).toHaveBeenCalledTimes(1); expect(resizeFn).lastCalledWith({ height: 1000, width: 1024 }); }); it('should update height when window resizes', function () { var renderFn = jest.fn(); var component = render(getMarkup({ renderFn: renderFn })); // Initial load of the component should have the same window height = 500 expect(component.state.height).toEqual(window.innerHeight); expect(component.state.height).toEqual(500); expect(renderFn).lastCalledWith(expect.objectContaining({ height: 500 })); simulateWindowResize({ height: 1000 }); expect(component.state.height).toEqual(window.innerHeight); expect(component.state.height).toEqual(1000); expect(renderFn).lastCalledWith(expect.objectContaining({ height: 1000 })); }); }); describe('updatePosition', function () { it('should calculate the initial offset from the top of the page when mounted', function () { var windowScroller; render(getMarkup({ headerElements: React.createElement("div", { style: { height: 100 } }), ref: function ref(_ref5) { windowScroller = _ref5; } })); expect(windowScroller._positionFromTop).toBe(100); }); it('should recalculate the offset from the top when the window resizes', function () { var windowScroller; render(getMarkup({ headerElements: React.createElement("div", { id: "header", style: { height: 100, width: 150 } }), ref: function ref(_ref6) { windowScroller = _ref6; } })); expect(windowScroller._positionFromTop).toBe(100); expect(windowScroller._positionFromLeft).toBe(150); mockGetBoundingClientRectForHeader({ height: 200, width: 300 }); expect(windowScroller._positionFromTop).toBe(100); expect(windowScroller._positionFromLeft).toBe(150); simulateWindowResize({ height: 1000, width: 1000 }); expect(windowScroller._positionFromTop).toBe(200); expect(windowScroller._positionFromLeft).toBe(300); }); it('should recalculate the offset from the top if called externally', function () { var windowScroller; render(getMarkup({ headerElements: React.createElement("div", { id: "header", style: { height: 100, width: 150 } }), ref: function ref(_ref7) { windowScroller = _ref7; } })); expect(windowScroller._positionFromTop).toBe(100); expect(windowScroller._positionFromLeft).toBe(150); mockGetBoundingClientRectForHeader({ height: 200, width: 300 }); windowScroller.updatePosition(); expect(windowScroller._positionFromTop).toBe(200); expect(windowScroller._positionFromLeft).toBe(300); }); }); describe('when child scrolls', function () { var originalScrollTo; beforeEach(function () { originalScrollTo = window.scrollTo; window.scrollTo = function (scrollX, scrollY) { return simulateWindowScroll({ scrollX: scrollX, scrollY: scrollY }); }; }); afterEach(function () { window.scrollTo = originalScrollTo; render.unmount(); }); it('should scroll the scrollElement (when it is window) the desired amount', function () { var renderFn = jest.fn(); var windowScroller; render(getMarkup({ ref: function ref(_ref8) { windowScroller = _ref8; }, renderFn: renderFn })); renderFn.mock.calls[0][0].onChildScroll({ scrollTop: 200 }); expect(window.scrollY).toEqual(200 + windowScroller._positionFromTop); }); it('should not scroll the scrollElement if trying to scroll to where we already are', function () { var renderFn = jest.fn(); render(getMarkup({ renderFn: renderFn })); simulateWindowScroll({ scrollY: 200 }); window.scrollTo = jest.fn(); renderFn.mock.calls[0][0].onChildScroll({ scrollTop: 200 }); expect(window.scrollTo).not.toHaveBeenCalled(); }); it('should scroll the scrollElement (when it is an element) the desired amount', function () { var windowScroller; var renderFn = jest.fn(); var divEl = document.createElement('div'); render(getMarkup({ ref: function ref(_ref9) { windowScroller = _ref9; }, renderFn: renderFn, scrollElement: divEl })); renderFn.mock.calls[0][0].onChildScroll({ scrollTop: 200 }); expect(divEl.scrollTop).toEqual(200 + windowScroller._positionFromTop); }); it('should update own scrollTop', function () { var renderFn = jest.fn(); render(getMarkup({ renderFn: renderFn })); renderFn.mock.calls[0][0].onChildScroll({ scrollTop: 200 }); expect(renderFn).lastCalledWith(expect.objectContaining({ scrollTop: 200 })); }); }); });dist/es/WindowScroller/WindowScroller.ssr.js000064400000001216151676725770015243 0ustar00/** * @jest-environment node */ import * as React from 'react'; import * as ReactDOMServer from 'react-dom/server'; import WindowScroller from './WindowScroller'; test('should render content with default widths and heights initially', function () { var rendered = ReactDOMServer.renderToString(React.createElement(WindowScroller, { serverHeight: 100, serverWidth: 200 }, function (_ref) { var height = _ref.height, width = _ref.width; return React.createElement("div", null, "height:".concat(height, ";width:").concat(width)); })); expect(rendered).toContain('height:100'); expect(rendered).toContain('width:200'); });dist/es/WindowScroller/WindowScroller.js000064400000024100151676725770014432 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; var _class, _temp; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { registerScrollListener, unregisterScrollListener } from './utils/onScroll'; import { getDimensions, getPositionOffset, getScrollOffset } from './utils/dimensions'; import createDetectElementResize from '../vendor/detectElementResize'; /** * Specifies the number of miliseconds during which to disable pointer events while a scroll is in progress. * This improves performance and makes scrolling smoother. */ export var IS_SCROLLING_TIMEOUT = 150; var getWindow = function getWindow() { return typeof window !== 'undefined' ? window : undefined; }; var WindowScroller = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { _inherits(WindowScroller, _React$PureComponent); function WindowScroller() { var _getPrototypeOf2; var _this; _classCallCheck(this, WindowScroller); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(WindowScroller)).call.apply(_getPrototypeOf2, [this].concat(args))); _defineProperty(_assertThisInitialized(_this), "_window", getWindow()); _defineProperty(_assertThisInitialized(_this), "_isMounted", false); _defineProperty(_assertThisInitialized(_this), "_positionFromTop", 0); _defineProperty(_assertThisInitialized(_this), "_positionFromLeft", 0); _defineProperty(_assertThisInitialized(_this), "_detectElementResize", void 0); _defineProperty(_assertThisInitialized(_this), "_child", void 0); _defineProperty(_assertThisInitialized(_this), "state", _objectSpread({}, getDimensions(_this.props.scrollElement, _this.props), { isScrolling: false, scrollLeft: 0, scrollTop: 0 })); _defineProperty(_assertThisInitialized(_this), "_registerChild", function (element) { if (element && !(element instanceof Element)) { console.warn('WindowScroller registerChild expects to be passed Element or null'); } _this._child = element; _this.updatePosition(); }); _defineProperty(_assertThisInitialized(_this), "_onChildScroll", function (_ref) { var scrollTop = _ref.scrollTop; if (_this.state.scrollTop === scrollTop) { return; } var scrollElement = _this.props.scrollElement; if (scrollElement) { if (typeof scrollElement.scrollTo === 'function') { scrollElement.scrollTo(0, scrollTop + _this._positionFromTop); } else { scrollElement.scrollTop = scrollTop + _this._positionFromTop; } } }); _defineProperty(_assertThisInitialized(_this), "_registerResizeListener", function (element) { if (element === window) { window.addEventListener('resize', _this._onResize, false); } else { _this._detectElementResize.addResizeListener(element, _this._onResize); } }); _defineProperty(_assertThisInitialized(_this), "_unregisterResizeListener", function (element) { if (element === window) { window.removeEventListener('resize', _this._onResize, false); } else if (element) { _this._detectElementResize.removeResizeListener(element, _this._onResize); } }); _defineProperty(_assertThisInitialized(_this), "_onResize", function () { _this.updatePosition(); }); _defineProperty(_assertThisInitialized(_this), "__handleWindowScrollEvent", function () { if (!_this._isMounted) { return; } var onScroll = _this.props.onScroll; var scrollElement = _this.props.scrollElement; if (scrollElement) { var scrollOffset = getScrollOffset(scrollElement); var scrollLeft = Math.max(0, scrollOffset.left - _this._positionFromLeft); var scrollTop = Math.max(0, scrollOffset.top - _this._positionFromTop); _this.setState({ isScrolling: true, scrollLeft: scrollLeft, scrollTop: scrollTop }); onScroll({ scrollLeft: scrollLeft, scrollTop: scrollTop }); } }); _defineProperty(_assertThisInitialized(_this), "__resetIsScrolling", function () { _this.setState({ isScrolling: false }); }); return _this; } _createClass(WindowScroller, [{ key: "updatePosition", value: function updatePosition() { var scrollElement = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props.scrollElement; var onResize = this.props.onResize; var _this$state = this.state, height = _this$state.height, width = _this$state.width; var thisNode = this._child || ReactDOM.findDOMNode(this); if (thisNode instanceof Element && scrollElement) { var offset = getPositionOffset(thisNode, scrollElement); this._positionFromTop = offset.top; this._positionFromLeft = offset.left; } var dimensions = getDimensions(scrollElement, this.props); if (height !== dimensions.height || width !== dimensions.width) { this.setState({ height: dimensions.height, width: dimensions.width }); onResize({ height: dimensions.height, width: dimensions.width }); } } }, { key: "componentDidMount", value: function componentDidMount() { var scrollElement = this.props.scrollElement; this._detectElementResize = createDetectElementResize(); this.updatePosition(scrollElement); if (scrollElement) { registerScrollListener(this, scrollElement); this._registerResizeListener(scrollElement); } this._isMounted = true; } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { var scrollElement = this.props.scrollElement; var prevScrollElement = prevProps.scrollElement; if (prevScrollElement !== scrollElement && prevScrollElement != null && scrollElement != null) { this.updatePosition(scrollElement); unregisterScrollListener(this, prevScrollElement); registerScrollListener(this, scrollElement); this._unregisterResizeListener(prevScrollElement); this._registerResizeListener(scrollElement); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { var scrollElement = this.props.scrollElement; if (scrollElement) { unregisterScrollListener(this, scrollElement); this._unregisterResizeListener(scrollElement); } this._isMounted = false; } }, { key: "render", value: function render() { var children = this.props.children; var _this$state2 = this.state, isScrolling = _this$state2.isScrolling, scrollTop = _this$state2.scrollTop, scrollLeft = _this$state2.scrollLeft, height = _this$state2.height, width = _this$state2.width; return children({ onChildScroll: this._onChildScroll, registerChild: this._registerChild, height: height, isScrolling: isScrolling, scrollLeft: scrollLeft, scrollTop: scrollTop, width: width }); } }]); return WindowScroller; }(React.PureComponent), _defineProperty(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { /** * Function responsible for rendering children. * This function should implement the following signature: * ({ height, isScrolling, scrollLeft, scrollTop, width }) => PropTypes.element */ "children": PropTypes.func.isRequired, /** Callback to be invoked on-resize: ({ height, width }) */ "onResize": PropTypes.func.isRequired, /** Callback to be invoked on-scroll: ({ scrollLeft, scrollTop }) */ "onScroll": PropTypes.func.isRequired, /** Element to attach scroll event listeners. Defaults to window. */ "scrollElement": PropTypes.oneOfType([PropTypes.any, function () { return (typeof Element === "function" ? PropTypes.instanceOf(Element) : PropTypes.any).apply(this, arguments); }]), /** * Wait this amount of time after the last scroll event before resetting child `pointer-events`. */ "scrollingResetTimeInterval": PropTypes.number.isRequired, /** Height used for server-side rendering */ "serverHeight": PropTypes.number.isRequired, /** Width used for server-side rendering */ "serverWidth": PropTypes.number.isRequired }), _temp); _defineProperty(WindowScroller, "defaultProps", { onResize: function onResize() {}, onScroll: function onScroll() {}, scrollingResetTimeInterval: IS_SCROLLING_TIMEOUT, scrollElement: getWindow(), serverHeight: 0, serverWidth: 0 }); export { WindowScroller as default }; import PropTypes from "prop-types";dist/es/WindowScroller/WindowScroller.js.flow000064400000015352151676725770015411 0ustar00// @flow import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { registerScrollListener, unregisterScrollListener, } from './utils/onScroll'; import { getDimensions, getPositionOffset, getScrollOffset, } from './utils/dimensions'; import createDetectElementResize from '../vendor/detectElementResize'; type Props = { /** * Function responsible for rendering children. * This function should implement the following signature: * ({ height, isScrolling, scrollLeft, scrollTop, width }) => PropTypes.element */ children: ({ onChildScroll: ({scrollTop: number}) => void, registerChild: (?Element) => void, height: number, isScrolling: boolean, scrollLeft: number, scrollTop: number, width: number, }) => React.Node, /** Callback to be invoked on-resize: ({ height, width }) */ onResize: ({height: number, width: number}) => void, /** Callback to be invoked on-scroll: ({ scrollLeft, scrollTop }) */ onScroll: ({scrollLeft: number, scrollTop: number}) => void, /** Element to attach scroll event listeners. Defaults to window. */ scrollElement: ?(typeof window | Element), /** * Wait this amount of time after the last scroll event before resetting child `pointer-events`. */ scrollingResetTimeInterval: number, /** Height used for server-side rendering */ serverHeight: number, /** Width used for server-side rendering */ serverWidth: number, }; type State = { height: number, width: number, isScrolling: boolean, scrollLeft: number, scrollTop: number, }; type ResizeHandler = (element: Element, onResize: () => void) => void; type DetectElementResize = { addResizeListener: ResizeHandler, removeResizeListener: ResizeHandler, }; /** * Specifies the number of miliseconds during which to disable pointer events while a scroll is in progress. * This improves performance and makes scrolling smoother. */ export const IS_SCROLLING_TIMEOUT = 150; const getWindow = () => (typeof window !== 'undefined' ? window : undefined); export default class WindowScroller extends React.PureComponent<Props, State> { static defaultProps = { onResize: () => {}, onScroll: () => {}, scrollingResetTimeInterval: IS_SCROLLING_TIMEOUT, scrollElement: getWindow(), serverHeight: 0, serverWidth: 0, }; _window = getWindow(); _isMounted = false; _positionFromTop = 0; _positionFromLeft = 0; _detectElementResize: DetectElementResize; _child: ?Element; state = { ...getDimensions(this.props.scrollElement, this.props), isScrolling: false, scrollLeft: 0, scrollTop: 0, }; updatePosition(scrollElement: ?Element = this.props.scrollElement) { const {onResize} = this.props; const {height, width} = this.state; const thisNode = this._child || ReactDOM.findDOMNode(this); if (thisNode instanceof Element && scrollElement) { const offset = getPositionOffset(thisNode, scrollElement); this._positionFromTop = offset.top; this._positionFromLeft = offset.left; } const dimensions = getDimensions(scrollElement, this.props); if (height !== dimensions.height || width !== dimensions.width) { this.setState({ height: dimensions.height, width: dimensions.width, }); onResize({ height: dimensions.height, width: dimensions.width, }); } } componentDidMount() { const scrollElement = this.props.scrollElement; this._detectElementResize = createDetectElementResize(); this.updatePosition(scrollElement); if (scrollElement) { registerScrollListener(this, scrollElement); this._registerResizeListener(scrollElement); } this._isMounted = true; } componentDidUpdate(prevProps: Props, prevState: State) { const {scrollElement} = this.props; const {scrollElement: prevScrollElement} = prevProps; if ( prevScrollElement !== scrollElement && prevScrollElement != null && scrollElement != null ) { this.updatePosition(scrollElement); unregisterScrollListener(this, prevScrollElement); registerScrollListener(this, scrollElement); this._unregisterResizeListener(prevScrollElement); this._registerResizeListener(scrollElement); } } componentWillUnmount() { const scrollElement = this.props.scrollElement; if (scrollElement) { unregisterScrollListener(this, scrollElement); this._unregisterResizeListener(scrollElement); } this._isMounted = false; } render() { const {children} = this.props; const {isScrolling, scrollTop, scrollLeft, height, width} = this.state; return children({ onChildScroll: this._onChildScroll, registerChild: this._registerChild, height, isScrolling, scrollLeft, scrollTop, width, }); } _registerChild = element => { if (element && !(element instanceof Element)) { console.warn( 'WindowScroller registerChild expects to be passed Element or null', ); } this._child = element; this.updatePosition(); }; _onChildScroll = ({scrollTop}) => { if (this.state.scrollTop === scrollTop) { return; } const scrollElement = this.props.scrollElement; if (scrollElement) { if (typeof scrollElement.scrollTo === 'function') { scrollElement.scrollTo(0, scrollTop + this._positionFromTop); } else { scrollElement.scrollTop = scrollTop + this._positionFromTop; } } }; _registerResizeListener = element => { if (element === window) { window.addEventListener('resize', this._onResize, false); } else { this._detectElementResize.addResizeListener(element, this._onResize); } }; _unregisterResizeListener = element => { if (element === window) { window.removeEventListener('resize', this._onResize, false); } else if (element) { this._detectElementResize.removeResizeListener(element, this._onResize); } }; _onResize = () => { this.updatePosition(); }; // Referenced by utils/onScroll __handleWindowScrollEvent = () => { if (!this._isMounted) { return; } const {onScroll} = this.props; const scrollElement = this.props.scrollElement; if (scrollElement) { const scrollOffset = getScrollOffset(scrollElement); const scrollLeft = Math.max( 0, scrollOffset.left - this._positionFromLeft, ); const scrollTop = Math.max(0, scrollOffset.top - this._positionFromTop); this.setState({ isScrolling: true, scrollLeft, scrollTop, }); onScroll({ scrollLeft, scrollTop, }); } }; // Referenced by utils/onScroll __resetIsScrolling = () => { this.setState({ isScrolling: false, }); }; } dist/es/ArrowKeyStepper/types.js000064400000000403151676725770012752 0ustar00var bpfrpt_proptype_ScrollIndices = process.env.NODE_ENV === 'production' ? null : { "scrollToColumn": PropTypes.number.isRequired, "scrollToRow": PropTypes.number.isRequired }; import PropTypes from "prop-types"; export { bpfrpt_proptype_ScrollIndices };dist/es/ArrowKeyStepper/ArrowKeyStepper.jest.js000064400000023136151676725770015670 0ustar00import _extends from "@babel/runtime/helpers/extends"; import * as React from 'react'; import { findDOMNode } from 'react-dom'; import { render } from '../TestUtils'; import ArrowKeyStepper from './ArrowKeyStepper'; import { Simulate } from 'react-dom/test-utils'; function renderTextContent(scrollToColumn, scrollToRow) { return "scrollToColumn:".concat(scrollToColumn, ", scrollToRow:").concat(scrollToRow); } function ChildComponent(_ref) { var scrollToColumn = _ref.scrollToColumn, scrollToRow = _ref.scrollToRow; return React.createElement("div", null, renderTextContent(scrollToColumn, scrollToRow)); } describe('ArrowKeyStepper', function () { function renderHelper() { var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var onSectionRenderedCallback; var component = render(React.createElement(ArrowKeyStepper, _extends({ columnCount: 10, mode: "edges", rowCount: 10 }, props), function (_ref2) { var onSectionRendered = _ref2.onSectionRendered, scrollToColumn = _ref2.scrollToColumn, scrollToRow = _ref2.scrollToRow; onSectionRenderedCallback = onSectionRendered; return React.createElement(ChildComponent, { scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }); })); var node = findDOMNode(component); return { component: component, node: node, onSectionRendered: onSectionRenderedCallback }; } function assertCurrentScrollTo(node, scrollToColumn, scrollToRow) { expect(node.textContent).toEqual(renderTextContent(scrollToColumn, scrollToRow)); } it('should use a custom :className if one is specified', function () { var _renderHelper = renderHelper({ className: 'foo' }), node = _renderHelper.node; expect(node.className).toEqual('foo'); }); it('should update :scrollToColumn and :scrollToRow in response to arrow keys', function () { var _renderHelper2 = renderHelper(), node = _renderHelper2.node; assertCurrentScrollTo(node, 0, 0); Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 0, 1); Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 1, 1); Simulate.keyDown(node, { key: 'ArrowUp' }); assertCurrentScrollTo(node, 1, 0); Simulate.keyDown(node, { key: 'ArrowLeft' }); assertCurrentScrollTo(node, 0, 0); }); it('should not scroll past the row and column boundaries provided', function () { var _renderHelper3 = renderHelper({ columnCount: 2, rowCount: 2 }), node = _renderHelper3.node; Simulate.keyDown(node, { key: 'ArrowDown' }); Simulate.keyDown(node, { key: 'ArrowDown' }); Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 0, 1); Simulate.keyDown(node, { key: 'ArrowUp' }); Simulate.keyDown(node, { key: 'ArrowUp' }); Simulate.keyDown(node, { key: 'ArrowUp' }); assertCurrentScrollTo(node, 0, 0); Simulate.keyDown(node, { key: 'ArrowRight' }); Simulate.keyDown(node, { key: 'ArrowRight' }); Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 1, 0); Simulate.keyDown(node, { key: 'ArrowLeft' }); Simulate.keyDown(node, { key: 'ArrowLeft' }); Simulate.keyDown(node, { key: 'ArrowLeft' }); assertCurrentScrollTo(node, 0, 0); }); it('should accept initial :scrollToColumn and :scrollToRow values via props', function () { var _renderHelper4 = renderHelper({ mode: 'cells', scrollToColumn: 2, scrollToRow: 4 }), node = _renderHelper4.node; assertCurrentScrollTo(node, 2, 4); Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 2, 5); Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 3, 5); }); it('should accept updated :scrollToColumn and :scrollToRow values via props', function () { var _renderHelper5 = renderHelper({ mode: 'cells', scrollToColumn: 2, scrollToRow: 4 }), node = _renderHelper5.node; Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 2, 5); renderHelper({ mode: 'cells', scrollToColumn: 1, scrollToRow: 1 }); Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 2, 1); Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 2, 2); }); it('should accept updated :scrollToColumn and :scrollToRow values via setScrollIndexes()', function () { var _renderHelper6 = renderHelper({ mode: 'cells', scrollToColumn: 2, scrollToRow: 4 }), component = _renderHelper6.component, node = _renderHelper6.node; Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 2, 5); component.setScrollIndexes({ scrollToColumn: 1, scrollToRow: 1 }); Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 2, 1); Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 2, 2); }); it('should not update :scrollToColumn or :scrollToRow when :disabled', function () { var _renderHelper7 = renderHelper({ disabled: true }), node = _renderHelper7.node; assertCurrentScrollTo(node, 0, 0); Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 0, 0); Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 0, 0); }); it('should call :onScrollToChange for key down', function () { [true, false].forEach(function () { var onScrollToChange = jest.fn(); var _renderHelper8 = renderHelper({ isControlled: true, onScrollToChange: onScrollToChange }), node = _renderHelper8.node; expect(onScrollToChange.mock.calls).toHaveLength(0); Simulate.keyDown(node, { key: 'ArrowDown' }); expect(onScrollToChange.mock.calls).toHaveLength(1); var _onScrollToChange$moc = onScrollToChange.mock.calls[0][0], scrollToColumn = _onScrollToChange$moc.scrollToColumn, scrollToRow = _onScrollToChange$moc.scrollToRow; expect(scrollToColumn).toEqual(0); expect(scrollToRow).toEqual(1); }); }); it('should not call :onScrollToChange for prop update', function () { var numCalls = 0; var onScrollToChange = function onScrollToChange() { numCalls++; }; var _renderHelper9 = renderHelper({ onScrollToChange: onScrollToChange, scrollToColumn: 0, scrollToRow: 0 }), node = _renderHelper9.node; renderHelper({ isControlled: true, onScrollToChange: onScrollToChange, node: node, scrollToColumn: 0, scrollToRow: 1 }); expect(numCalls).toEqual(0); }); describe('mode === "edges"', function () { it('should update :scrollToColumn and :scrollToRow relative to the most recent :onSectionRendered event', function () { var _renderHelper10 = renderHelper(), node = _renderHelper10.node, onSectionRendered = _renderHelper10.onSectionRendered; onSectionRendered({ // Simulate a scroll columnStartIndex: 0, columnStopIndex: 4, rowStartIndex: 4, rowStopIndex: 6 }); Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 0, 7); onSectionRendered({ // Simulate a scroll columnStartIndex: 5, columnStopIndex: 10, rowStartIndex: 2, rowStopIndex: 4 }); Simulate.keyDown(node, { key: 'ArrowUp' }); assertCurrentScrollTo(node, 0, 1); onSectionRendered({ // Simulate a scroll columnStartIndex: 4, columnStopIndex: 8, rowStartIndex: 5, rowStopIndex: 10 }); Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 9, 1); onSectionRendered({ // Simulate a scroll columnStartIndex: 2, columnStopIndex: 4, rowStartIndex: 2, rowStopIndex: 4 }); Simulate.keyDown(node, { key: 'ArrowLeft' }); assertCurrentScrollTo(node, 1, 1); }); }); describe('mode === "cells"', function () { it('should update :scrollToColumn and :scrollToRow relative to the most recent :onSectionRendered event', function () { var _renderHelper11 = renderHelper({ mode: 'cells', scrollToColumn: 5, scrollToRow: 5 }), node = _renderHelper11.node, onSectionRendered = _renderHelper11.onSectionRendered; onSectionRendered({ // Simulate a scroll columnStartIndex: 10, columnStopIndex: 10, rowStartIndex: 15, rowStopIndex: 15 }); Simulate.keyDown(node, { key: 'ArrowUp' }); assertCurrentScrollTo(node, 5, 4); Simulate.keyDown(node, { key: 'ArrowDown' }); assertCurrentScrollTo(node, 5, 5); onSectionRendered({ // Simulate a scroll columnStartIndex: 10, columnStopIndex: 10, rowStartIndex: 15, rowStopIndex: 15 }); Simulate.keyDown(node, { key: 'ArrowRight' }); assertCurrentScrollTo(node, 6, 5); Simulate.keyDown(node, { key: 'ArrowLeft' }); assertCurrentScrollTo(node, 5, 5); }); }); });dist/es/ArrowKeyStepper/index.js000064400000000317151676725770012721 0ustar00export { default } from './ArrowKeyStepper'; export { default as ArrowKeyStepper } from './ArrowKeyStepper'; import { bpfrpt_proptype_ScrollIndices } from "./types"; export { bpfrpt_proptype_ScrollIndices };dist/es/ArrowKeyStepper/ArrowKeyStepper.js000064400000020317151676725770014722 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; var _class, _temp; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } import * as React from 'react'; import { polyfill } from 'react-lifecycles-compat'; /** * This HOC decorates a virtualized component and responds to arrow-key events by scrolling one row or column at a time. */ var ArrowKeyStepper = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { _inherits(ArrowKeyStepper, _React$PureComponent); function ArrowKeyStepper() { var _getPrototypeOf2; var _this; _classCallCheck(this, ArrowKeyStepper); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(ArrowKeyStepper)).call.apply(_getPrototypeOf2, [this].concat(args))); _defineProperty(_assertThisInitialized(_this), "state", { scrollToColumn: 0, scrollToRow: 0, instanceProps: { prevScrollToColumn: 0, prevScrollToRow: 0 } }); _defineProperty(_assertThisInitialized(_this), "_columnStartIndex", 0); _defineProperty(_assertThisInitialized(_this), "_columnStopIndex", 0); _defineProperty(_assertThisInitialized(_this), "_rowStartIndex", 0); _defineProperty(_assertThisInitialized(_this), "_rowStopIndex", 0); _defineProperty(_assertThisInitialized(_this), "_onKeyDown", function (event) { var _this$props = _this.props, columnCount = _this$props.columnCount, disabled = _this$props.disabled, mode = _this$props.mode, rowCount = _this$props.rowCount; if (disabled) { return; } var _this$_getScrollState = _this._getScrollState(), scrollToColumnPrevious = _this$_getScrollState.scrollToColumn, scrollToRowPrevious = _this$_getScrollState.scrollToRow; var _this$_getScrollState2 = _this._getScrollState(), scrollToColumn = _this$_getScrollState2.scrollToColumn, scrollToRow = _this$_getScrollState2.scrollToRow; // The above cases all prevent default event event behavior. // This is to keep the grid from scrolling after the snap-to update. switch (event.key) { case 'ArrowDown': scrollToRow = mode === 'cells' ? Math.min(scrollToRow + 1, rowCount - 1) : Math.min(_this._rowStopIndex + 1, rowCount - 1); break; case 'ArrowLeft': scrollToColumn = mode === 'cells' ? Math.max(scrollToColumn - 1, 0) : Math.max(_this._columnStartIndex - 1, 0); break; case 'ArrowRight': scrollToColumn = mode === 'cells' ? Math.min(scrollToColumn + 1, columnCount - 1) : Math.min(_this._columnStopIndex + 1, columnCount - 1); break; case 'ArrowUp': scrollToRow = mode === 'cells' ? Math.max(scrollToRow - 1, 0) : Math.max(_this._rowStartIndex - 1, 0); break; } if (scrollToColumn !== scrollToColumnPrevious || scrollToRow !== scrollToRowPrevious) { event.preventDefault(); _this._updateScrollState({ scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }); } }); _defineProperty(_assertThisInitialized(_this), "_onSectionRendered", function (_ref) { var columnStartIndex = _ref.columnStartIndex, columnStopIndex = _ref.columnStopIndex, rowStartIndex = _ref.rowStartIndex, rowStopIndex = _ref.rowStopIndex; _this._columnStartIndex = columnStartIndex; _this._columnStopIndex = columnStopIndex; _this._rowStartIndex = rowStartIndex; _this._rowStopIndex = rowStopIndex; }); return _this; } _createClass(ArrowKeyStepper, [{ key: "setScrollIndexes", value: function setScrollIndexes(_ref2) { var scrollToColumn = _ref2.scrollToColumn, scrollToRow = _ref2.scrollToRow; this.setState({ scrollToRow: scrollToRow, scrollToColumn: scrollToColumn }); } }, { key: "render", value: function render() { var _this$props2 = this.props, className = _this$props2.className, children = _this$props2.children; var _this$_getScrollState3 = this._getScrollState(), scrollToColumn = _this$_getScrollState3.scrollToColumn, scrollToRow = _this$_getScrollState3.scrollToRow; return React.createElement("div", { className: className, onKeyDown: this._onKeyDown }, children({ onSectionRendered: this._onSectionRendered, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow })); } }, { key: "_getScrollState", value: function _getScrollState() { return this.props.isControlled ? this.props : this.state; } }, { key: "_updateScrollState", value: function _updateScrollState(_ref3) { var scrollToColumn = _ref3.scrollToColumn, scrollToRow = _ref3.scrollToRow; var _this$props3 = this.props, isControlled = _this$props3.isControlled, onScrollToChange = _this$props3.onScrollToChange; if (typeof onScrollToChange === 'function') { onScrollToChange({ scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }); } if (!isControlled) { this.setState({ scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }); } } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(nextProps, prevState) { if (nextProps.isControlled) { return {}; } if (nextProps.scrollToColumn !== prevState.instanceProps.prevScrollToColumn || nextProps.scrollToRow !== prevState.instanceProps.prevScrollToRow) { return _objectSpread({}, prevState, { scrollToColumn: nextProps.scrollToColumn, scrollToRow: nextProps.scrollToRow, instanceProps: { prevScrollToColumn: nextProps.scrollToColumn, prevScrollToRow: nextProps.scrollToRow } }); } return {}; } }]); return ArrowKeyStepper; }(React.PureComponent), _defineProperty(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : { "children": PropTypes.func.isRequired, "className": PropTypes.string, "columnCount": PropTypes.number.isRequired, "disabled": PropTypes.bool.isRequired, "isControlled": PropTypes.bool.isRequired, "mode": PropTypes.oneOf(["cells", "edges"]).isRequired, "onScrollToChange": PropTypes.func, "rowCount": PropTypes.number.isRequired, "scrollToColumn": PropTypes.number.isRequired, "scrollToRow": PropTypes.number.isRequired }), _temp); _defineProperty(ArrowKeyStepper, "defaultProps", { disabled: false, isControlled: false, mode: 'edges', scrollToColumn: 0, scrollToRow: 0 }); polyfill(ArrowKeyStepper); export default ArrowKeyStepper; import { bpfrpt_proptype_RenderedSection } from "../Grid"; import { bpfrpt_proptype_ScrollIndices } from "./types"; import PropTypes from "prop-types";dist/es/ArrowKeyStepper/ArrowKeyStepper.example.js000064400000017741151676725770016363 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; var _class, _temp; import * as React from 'react'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import ArrowKeyStepper from './'; import AutoSizer from '../AutoSizer'; import Grid from '../Grid'; import clsx from 'clsx'; import styles from './ArrowKeyStepper.example.css'; var ArrowKeyStepperExample = (_temp = _class = /*#__PURE__*/ function (_React$PureComponent) { _inherits(ArrowKeyStepperExample, _React$PureComponent); function ArrowKeyStepperExample() { var _getPrototypeOf2; var _this; _classCallCheck(this, ArrowKeyStepperExample); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _possibleConstructorReturn(this, (_getPrototypeOf2 = _getPrototypeOf(ArrowKeyStepperExample)).call.apply(_getPrototypeOf2, [this].concat(args))); _defineProperty(_assertThisInitialized(_this), "state", { mode: 'edges', isClickable: true, scrollToColumn: 0, scrollToRow: 0 }); _defineProperty(_assertThisInitialized(_this), "_getColumnWidth", function (_ref) { var index = _ref.index; return (1 + index % 3) * 60; }); _defineProperty(_assertThisInitialized(_this), "_getRowHeight", function (_ref2) { var index = _ref2.index; return (1 + index % 3) * 30; }); _defineProperty(_assertThisInitialized(_this), "_cellRenderer", function (_ref3) { var columnIndex = _ref3.columnIndex, key = _ref3.key, rowIndex = _ref3.rowIndex, scrollToColumn = _ref3.scrollToColumn, scrollToRow = _ref3.scrollToRow, style = _ref3.style; var className = clsx(styles.Cell, _defineProperty({}, styles.FocusedCell, columnIndex === scrollToColumn && rowIndex === scrollToRow)); return React.createElement("span", { role: "none", className: className, key: key, onClick: _this.state.isClickable && function () { return _this._selectCell({ scrollToColumn: columnIndex, scrollToRow: rowIndex }); }, style: style }, "r:".concat(rowIndex, ", c:").concat(columnIndex)); }); _defineProperty(_assertThisInitialized(_this), "_selectCell", function (_ref4) { var scrollToColumn = _ref4.scrollToColumn, scrollToRow = _ref4.scrollToRow; _this.setState({ scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }); }); _defineProperty(_assertThisInitialized(_this), "_onClickableChange", function (event) { if (event.target instanceof HTMLInputElement) { _this.setState({ isClickable: event.target.checked, scrollToColumn: 0, scrollToRow: 0 }); } }); return _this; } _createClass(ArrowKeyStepperExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, mode = _this$state.mode, isClickable = _this$state.isClickable, scrollToColumn = _this$state.scrollToColumn, scrollToRow = _this$state.scrollToRow; return React.createElement(ContentBox, null, React.createElement(ContentBoxHeader, { text: "ArrowKeyStepper", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/ArrowKeyStepper/ArrowKeyStepper.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/ArrowKeyStepper.md" }), React.createElement(ContentBoxParagraph, null, "This high-order component decorates a ", React.createElement("code", null, "List"), ",", ' ', React.createElement("code", null, "Table"), ", or ", React.createElement("code", null, "Grid"), " and responds to arrow-key events by scrolling one row or column at a time. Focus in the `Grid` below and use the left, right, up, or down arrow keys to move around within the grid."), React.createElement(ContentBoxParagraph, null, "Note that unlike the other HOCs in react-virtualized, the", ' ', React.createElement("code", null, "ArrowKeyStepper"), " adds a ", React.createElement("code", null, "<div>"), " element around its children in order to attach a key-down event handler."), React.createElement(ContentBoxParagraph, null, React.createElement("strong", null, "mode"), ":", React.createElement("label", null, React.createElement("input", { "aria-label": "Set mode equal to \"cells\"", checked: mode === 'cells', className: styles.Radio, type: "radio", onChange: function onChange(event) { return event.target.checked && _this2.setState({ mode: 'cells' }); }, value: "cells" }), "cells"), React.createElement("label", null, React.createElement("input", { "aria-label": "Set mode equal to \"edges\"", checked: mode === 'edges', className: styles.Radio, type: "radio", onChange: function onChange(event) { return event.target.checked && _this2.setState({ mode: 'edges' }); }, value: "edges" }), "edges (default)")), React.createElement(ContentBoxParagraph, null, React.createElement("label", { className: styles.checkboxLabel }, React.createElement("input", { "aria-label": "Enable click selection? (resets selection)", className: styles.checkbox, type: "checkbox", checked: isClickable, onChange: this._onClickableChange }), "Enable click selection? (resets selection)")), React.createElement(ArrowKeyStepper, { columnCount: 100, isControlled: isClickable, onScrollToChange: isClickable ? this._selectCell : undefined, mode: mode, rowCount: 100, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow }, function (_ref5) { var onSectionRendered = _ref5.onSectionRendered, scrollToColumn = _ref5.scrollToColumn, scrollToRow = _ref5.scrollToRow; return React.createElement("div", null, React.createElement(ContentBoxParagraph, null, "Most-recently-stepped column: ".concat(scrollToColumn, ", row: ").concat(scrollToRow)), React.createElement(AutoSizer, { disableHeight: true }, function (_ref6) { var width = _ref6.width; return React.createElement(Grid, { className: styles.Grid, columnWidth: _this2._getColumnWidth, columnCount: 100, height: 200, onSectionRendered: onSectionRendered, cellRenderer: function cellRenderer(_ref7) { var columnIndex = _ref7.columnIndex, key = _ref7.key, rowIndex = _ref7.rowIndex, style = _ref7.style; return _this2._cellRenderer({ columnIndex: columnIndex, key: key, rowIndex: rowIndex, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow, style: style }); }, rowHeight: _this2._getRowHeight, rowCount: 100, scrollToColumn: scrollToColumn, scrollToRow: scrollToRow, width: width }); })); })); } }]); return ArrowKeyStepperExample; }(React.PureComponent), _defineProperty(_class, "propTypes", process.env.NODE_ENV === 'production' ? null : {}), _temp); export { ArrowKeyStepperExample as default }; import { bpfrpt_proptype_ScrollIndices } from "./";dist/es/ColumnSizer/ColumnSizer.example.js000064400000013671151676725770014671 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import * as React from 'react'; import styles from './ColumnSizer.example.css'; import AutoSizer from '../AutoSizer'; import ColumnSizer from './ColumnSizer'; import Grid from '../Grid'; import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/ContentBox'; import { LabeledInput, InputRow } from '../demo/LabeledInput'; var ColumnSizerExample = /*#__PURE__*/ function (_React$PureComponent) { _inherits(ColumnSizerExample, _React$PureComponent); function ColumnSizerExample(props) { var _this; _classCallCheck(this, ColumnSizerExample); _this = _possibleConstructorReturn(this, _getPrototypeOf(ColumnSizerExample).call(this, props)); _this.state = { columnMaxWidth: 100, columnMinWidth: 75, columnCount: 10 }; _this._noColumnMaxWidthChange = _this._noColumnMaxWidthChange.bind(_assertThisInitialized(_this)); _this._noColumnMinWidthChange = _this._noColumnMinWidthChange.bind(_assertThisInitialized(_this)); _this._onColumnCountChange = _this._onColumnCountChange.bind(_assertThisInitialized(_this)); _this._noContentRenderer = _this._noContentRenderer.bind(_assertThisInitialized(_this)); _this._cellRenderer = _this._cellRenderer.bind(_assertThisInitialized(_this)); return _this; } _createClass(ColumnSizerExample, [{ key: "render", value: function render() { var _this2 = this; var _this$state = this.state, columnMaxWidth = _this$state.columnMaxWidth, columnMinWidth = _this$state.columnMinWidth, columnCount = _this$state.columnCount; return React.createElement(ContentBox, null, React.createElement(ContentBoxHeader, { text: "ColumnSizer", sourceLink: "https://github.com/bvaughn/react-virtualized/blob/master/source/ColumnSizer/ColumnSizer.example.js", docsLink: "https://github.com/bvaughn/react-virtualized/blob/master/docs/ColumnSizer.md" }), React.createElement(ContentBoxParagraph, null, "This component decorates a ", React.createElement("code", null, "Grid"), " and calculates the width of its columns based on the current (", React.createElement("code", null, "Grid"), ") width."), React.createElement(InputRow, null, React.createElement(LabeledInput, { label: "Num Columns", name: "columnCount", onChange: this._onColumnCountChange, value: columnCount }), React.createElement(LabeledInput, { label: "Column Min Width", name: "columnMinWidth", onChange: this._noColumnMinWidthChange, value: columnMinWidth }), React.createElement(LabeledInput, { label: "Column Max Width", name: "columnMaxWidth", onChange: this._noColumnMaxWidthChange, value: columnMaxWidth })), React.createElement("div", null, React.createElement(AutoSizer, { disableHeight: true }, function (_ref) { var width = _ref.width; return React.createElement(ColumnSizer, { columnMaxWidth: columnMaxWidth, columnMinWidth: columnMinWidth, columnCount: columnCount, key: "GridColumnSizer", width: width }, function (_ref2) { var adjustedWidth = _ref2.adjustedWidth, columnWidth = _ref2.columnWidth, registerChild = _ref2.registerChild; return React.createElement("div", { className: styles.GridContainer, style: { height: 50, width: adjustedWidth } }, React.createElement(Grid, { ref: registerChild, columnWidth: columnWidth, columnCount: columnCount, height: 50, noContentRenderer: _this2._noContentRenderer, cellRenderer: _this2._cellRenderer, rowHeight: 50, rowCount: 1, width: adjustedWidth })); }); }))); } }, { key: "_noColumnMaxWidthChange", value: function _noColumnMaxWidthChange(event) { var columnMaxWidth = parseInt(event.target.value, 10); if (isNaN(columnMaxWidth)) { columnMaxWidth = undefined; } else { columnMaxWidth = Math.min(1000, columnMaxWidth); } this.setState({ columnMaxWidth: columnMaxWidth }); } }, { key: "_noColumnMinWidthChange", value: function _noColumnMinWidthChange(event) { var columnMinWidth = parseInt(event.target.value, 10); if (isNaN(columnMinWidth)) { columnMinWidth = undefined; } else { columnMinWidth = Math.max(1, columnMinWidth); } this.setState({ columnMinWidth: columnMinWidth }); } }, { key: "_onColumnCountChange", value: function _onColumnCountChange(event) { this.setState({ columnCount: parseInt(event.target.value, 10) || 0 }); } }, { key: "_noContentRenderer", value: function _noContentRenderer() { return React.createElement("div", { className: styles.noCells }, "No cells"); } }, { key: "_cellRenderer", value: function _cellRenderer(_ref3) { var columnIndex = _ref3.columnIndex, key = _ref3.key, rowIndex = _ref3.rowIndex, style = _ref3.style; var className = columnIndex === 0 ? styles.firstCell : styles.cell; return React.createElement("div", { className: className, key: key, style: style }, "R:".concat(rowIndex, ", C:").concat(columnIndex)); } }]); return ColumnSizerExample; }(React.PureComponent); export { ColumnSizerExample as default };dist/es/ColumnSizer/index.js000064400000000134151676725770012062 0ustar00import ColumnSizer from './ColumnSizer'; export default ColumnSizer; export { ColumnSizer };dist/es/ColumnSizer/ColumnSizer.js000064400000010000151676725770013216 0ustar00import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/inherits"; import PropTypes from 'prop-types'; import * as React from 'react'; /** * High-order component that auto-calculates column-widths for `Grid` cells. */ var ColumnSizer = /*#__PURE__*/ function (_React$PureComponent) { _inherits(ColumnSizer, _React$PureComponent); function ColumnSizer(props, context) { var _this; _classCallCheck(this, ColumnSizer); _this = _possibleConstructorReturn(this, _getPrototypeOf(ColumnSizer).call(this, props, context)); _this._registerChild = _this._registerChild.bind(_assertThisInitialized(_this)); return _this; } _createClass(ColumnSizer, [{ key: "componentDidUpdate", value: function componentDidUpdate(prevProps) { var _this$props = this.props, columnMaxWidth = _this$props.columnMaxWidth, columnMinWidth = _this$props.columnMinWidth, columnCount = _this$props.columnCount, width = _this$props.width; if (columnMaxWidth !== prevProps.columnMaxWidth || columnMinWidth !== prevProps.columnMinWidth || columnCount !== prevProps.columnCount || width !== prevProps.width) { if (this._registeredChild) { this._registeredChild.recomputeGridSize(); } } } }, { key: "render", value: function render() { var _this$props2 = this.props, children = _this$props2.children, columnMaxWidth = _this$props2.columnMaxWidth, columnMinWidth = _this$props2.columnMinWidth, columnCount = _this$props2.columnCount, width = _this$props2.width; var safeColumnMinWidth = columnMinWidth || 1; var safeColumnMaxWidth = columnMaxWidth ? Math.min(columnMaxWidth, width) : width; var columnWidth = width / columnCount; columnWidth = Math.max(safeColumnMinWidth, columnWidth); columnWidth = Math.min(safeColumnMaxWidth, columnWidth); columnWidth = Math.floor(columnWidth); var adjustedWidth = Math.min(width, columnWidth * columnCount); return children({ adjustedWidth: adjustedWidth, columnWidth: columnWidth, getColumnWidth: function getColumnWidth() { return columnWidth; }, registerChild: this._registerChild }); } }, { key: "_registerChild", value: function _registerChild(child) { if (child && typeof child.recomputeGridSize !== 'function') { throw Error('Unexpected child type registered; only Grid/MultiGrid children are supported.'); } this._registeredChild = child; if (this._registeredChild) { this._registeredChild.recomputeGridSize(); } } }]); return ColumnSizer; }(React.PureComponent); export { ColumnSizer as default }; ColumnSizer.propTypes = process.env.NODE_ENV !== "production" ? { /** * Function responsible for rendering a virtualized Grid. * This function should implement the following signature: * ({ adjustedWidth, getColumnWidth, registerChild }) => PropTypes.element * * The specified :getColumnWidth function should be passed to the Grid's :columnWidth property. * The :registerChild should be passed to the Grid's :ref property. * The :adjustedWidth property is optional; it reflects the lesser of the overall width or the width of all columns. */ children: PropTypes.func.isRequired, /** Optional maximum allowed column width */ columnMaxWidth: PropTypes.number, /** Optional minimum allowed column width */ columnMinWidth: PropTypes.number, /** Number of columns in Grid or Table child */ columnCount: PropTypes.number.isRequired, /** Width of Grid or Table child */ width: PropTypes.number.isRequired } : {};dist/es/ColumnSizer/ColumnSizer.jest.js000064400000011352151676725770014175 0ustar00import * as React from 'react'; import { findDOMNode } from 'react-dom'; import { render } from '../TestUtils'; import ColumnSizer from './ColumnSizer'; import Grid from '../Grid'; describe('ColumnSizer', function () { function getMarkup() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$columnMinWidth = _ref.columnMinWidth, columnMinWidth = _ref$columnMinWidth === void 0 ? undefined : _ref$columnMinWidth, _ref$columnMaxWidth = _ref.columnMaxWidth, columnMaxWidth = _ref$columnMaxWidth === void 0 ? undefined : _ref$columnMaxWidth, _ref$columnCount = _ref.columnCount, columnCount = _ref$columnCount === void 0 ? 10 : _ref$columnCount, _ref$width = _ref.width, width = _ref$width === void 0 ? 200 : _ref$width; function cellRenderer(_ref2) { var columnIndex = _ref2.columnIndex, key = _ref2.key, rowIndex = _ref2.rowIndex, style = _ref2.style; return React.createElement("div", { className: "gridItem", key: key, style: style }, "row:".concat(rowIndex, ", column:").concat(columnIndex)); } return React.createElement(ColumnSizer, { columnMinWidth: columnMinWidth, columnMaxWidth: columnMaxWidth, columnCount: columnCount, width: width }, function (_ref3) { var adjustedWidth = _ref3.adjustedWidth, columnWidth = _ref3.columnWidth, registerChild = _ref3.registerChild; return React.createElement("div", null, React.createElement(Grid, { columnCount: columnCount, columnWidth: columnWidth, height: 50, ref: registerChild, cellRenderer: cellRenderer, rowHeight: 50, rowCount: 1, width: adjustedWidth }), React.createElement("div", { className: "debug" }, "adjustedWidth:".concat(adjustedWidth, " columnWidth:").concat(columnWidth))); }); } it('should distribute column widths evenly if no min/max boundaries have been set', function () { var rendered = findDOMNode(render(getMarkup())); expect(rendered.querySelector('.debug').textContent).toContain('columnWidth:20'); }); it('should respect :columnMaxWidth if specified', function () { var rendered = findDOMNode(render(getMarkup({ columnMaxWidth: 10 }))); expect(rendered.querySelector('.debug').textContent).toContain('columnWidth:10'); }); it('should respect :columnMinWidth if specified', function () { var rendered = findDOMNode(render(getMarkup({ columnMinWidth: 30 }))); expect(rendered.querySelector('.debug').textContent).toContain('columnWidth:30'); }); describe('recomputeGridSize', function () { function helper(updatedProps, expectedTextContent) { var renderedA = findDOMNode(render(getMarkup())); expect(renderedA.querySelector('.debug').textContent).toContain('columnWidth:20'); var renderedB = findDOMNode(render(getMarkup(updatedProps))); expect(renderedB.querySelector('.debug').textContent).toContain(expectedTextContent); } it('should recompute metadata sizes if :columnMinWidth changes', function () { helper({ columnMinWidth: 30 }, 'columnWidth:30'); }); it('should recompute metadata sizes if :columnMaxWidth changes', function () { helper({ columnMaxWidth: 15 }, 'columnWidth:15'); }); it('should recompute metadata sizes if :width changes', function () { helper({ width: 300 }, 'columnWidth:30'); }); it('should recompute metadata sizes if :columnCount changes', function () { helper({ columnCount: 2 }, 'columnWidth:100'); }); }); it('should pass the :width as :adjustedWidth if columns require more than the :width to be displayed', function () { var rendered = findDOMNode(render(getMarkup({ columnMinWidth: 30 }))); expect(rendered.querySelector('.debug').textContent).toContain('adjustedWidth:200'); }); it('should pass an :adjustedWidth if columns require less than the :width to be displayed', function () { var rendered = findDOMNode(render(getMarkup({ columnMaxWidth: 10 }))); expect(rendered.querySelector('.debug').textContent).toContain('adjustedWidth:100'); }); it('should error if the registered child is not a Grid or a MultiGrid', function () { spyOn(console, 'error'); expect(function () { render(React.createElement(ColumnSizer, { columnMinWidth: 100, columnMaxWidth: 100, columnCount: 100, width: 100 }, function (_ref4) { var registerChild = _ref4.registerChild; return React.createElement("div", { ref: registerChild }); })); }).toThrow(); }); });styles.css000064400000011406151676725770006632 0ustar00/* Collection default theme */ .ReactVirtualized__Collection { } .ReactVirtualized__Collection__innerScrollContainer { } /* Grid default theme */ .ReactVirtualized__Grid { } .ReactVirtualized__Grid__innerScrollContainer { } /* Table default theme */ .ReactVirtualized__Table { } .ReactVirtualized__Table__Grid { } .ReactVirtualized__Table__headerRow { font-weight: 700; text-transform: uppercase; display: -webkit-box; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; -webkit-box-align: center; align-items: center; } .ReactVirtualized__Table__row { display: -webkit-box; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; flex-direction: row; -webkit-box-align: center; align-items: center; } .ReactVirtualized__Table__headerTruncatedText { display: inline-block; max-width: 100%; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } .ReactVirtualized__Table__headerColumn, .ReactVirtualized__Table__rowColumn { margin-right: 10px; min-width: 0px; } .ReactVirtualized__Table__rowColumn { text-overflow: ellipsis; white-space: nowrap; } .ReactVirtualized__Table__headerColumn:first-of-type, .ReactVirtualized__Table__rowColumn:first-of-type { margin-left: 10px; } .ReactVirtualized__Table__sortableHeaderColumn { cursor: pointer; } .ReactVirtualized__Table__sortableHeaderIconContainer { display: -webkit-box; display: flex; -webkit-box-align: center; align-items: center; } .ReactVirtualized__Table__sortableHeaderIcon { -webkit-box-flex: 0; flex: 0 0 24px; height: 1em; width: 1em; fill: currentColor; } /* List default theme */ .ReactVirtualized__List { } /*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNvdXJjZS9zdHlsZXMuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDZCQUE2Qjs7QUFFN0I7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHVCQUF1Qjs7QUFFdkI7QUFDQTs7QUFFQTtBQUNBOztBQUVBLHdCQUF3Qjs7QUFFeEI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0VBQ0UsZ0JBQWdCO0VBQ2hCLHlCQUF5QjtFQUN6QixvQkFBYTtFQUFiLGFBQWE7RUFDYiw4QkFBbUI7RUFBbkIsNkJBQW1CO1VBQW5CLG1CQUFtQjtFQUNuQix5QkFBbUI7VUFBbkIsbUJBQW1CO0FBQ3JCO0FBQ0E7RUFDRSxvQkFBYTtFQUFiLGFBQWE7RUFDYiw4QkFBbUI7RUFBbkIsNkJBQW1CO1VBQW5CLG1CQUFtQjtFQUNuQix5QkFBbUI7VUFBbkIsbUJBQW1CO0FBQ3JCOztBQUVBO0VBQ0UscUJBQXFCO0VBQ3JCLGVBQWU7RUFDZixtQkFBbUI7RUFDbkIsdUJBQXVCO0VBQ3ZCLGdCQUFnQjtBQUNsQjs7QUFFQTs7RUFFRSxrQkFBa0I7RUFDbEIsY0FBYztBQUNoQjtBQUNBO0VBQ0UsdUJBQXVCO0VBQ3ZCLG1CQUFtQjtBQUNyQjs7QUFFQTs7RUFFRSxpQkFBaUI7QUFDbkI7QUFDQTtFQUNFLGVBQWU7QUFDakI7O0FBRUE7RUFDRSxvQkFBYTtFQUFiLGFBQWE7RUFDYix5QkFBbUI7VUFBbkIsbUJBQW1CO0FBQ3JCO0FBQ0E7RUFDRSxtQkFBYztVQUFkLGNBQWM7RUFDZCxXQUFXO0VBQ1gsVUFBVTtFQUNWLGtCQUFrQjtBQUNwQjs7QUFFQSx1QkFBdUI7O0FBRXZCO0FBQ0EiLCJmaWxlIjoic3R5bGVzLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi8qIENvbGxlY3Rpb24gZGVmYXVsdCB0aGVtZSAqL1xuXG4uUmVhY3RWaXJ0dWFsaXplZF9fQ29sbGVjdGlvbiB7XG59XG5cbi5SZWFjdFZpcnR1YWxpemVkX19Db2xsZWN0aW9uX19pbm5lclNjcm9sbENvbnRhaW5lciB7XG59XG5cbi8qIEdyaWQgZGVmYXVsdCB0aGVtZSAqL1xuXG4uUmVhY3RWaXJ0dWFsaXplZF9fR3JpZCB7XG59XG5cbi5SZWFjdFZpcnR1YWxpemVkX19HcmlkX19pbm5lclNjcm9sbENvbnRhaW5lciB7XG59XG5cbi8qIFRhYmxlIGRlZmF1bHQgdGhlbWUgKi9cblxuLlJlYWN0VmlydHVhbGl6ZWRfX1RhYmxlIHtcbn1cblxuLlJlYWN0VmlydHVhbGl6ZWRfX1RhYmxlX19HcmlkIHtcbn1cblxuLlJlYWN0VmlydHVhbGl6ZWRfX1RhYmxlX19oZWFkZXJSb3cge1xuICBmb250LXdlaWdodDogNzAwO1xuICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlO1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuLlJlYWN0VmlydHVhbGl6ZWRfX1RhYmxlX19yb3cge1xuICBkaXNwbGF5OiBmbGV4O1xuICBmbGV4LWRpcmVjdGlvbjogcm93O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuXG4uUmVhY3RWaXJ0dWFsaXplZF9fVGFibGVfX2hlYWRlclRydW5jYXRlZFRleHQge1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIG1heC13aWR0aDogMTAwJTtcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIG92ZXJmbG93OiBoaWRkZW47XG59XG5cbi5SZWFjdFZpcnR1YWxpemVkX19UYWJsZV9faGVhZGVyQ29sdW1uLFxuLlJlYWN0VmlydHVhbGl6ZWRfX1RhYmxlX19yb3dDb2x1bW4ge1xuICBtYXJnaW4tcmlnaHQ6IDEwcHg7XG4gIG1pbi13aWR0aDogMHB4O1xufVxuLlJlYWN0VmlydHVhbGl6ZWRfX1RhYmxlX19yb3dDb2x1bW4ge1xuICB0ZXh0LW92ZXJmbG93OiBlbGxpcHNpcztcbiAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbn1cblxuLlJlYWN0VmlydHVhbGl6ZWRfX1RhYmxlX19oZWFkZXJDb2x1bW46Zmlyc3Qtb2YtdHlwZSxcbi5SZWFjdFZpcnR1YWxpemVkX19UYWJsZV9fcm93Q29sdW1uOmZpcnN0LW9mLXR5cGUge1xuICBtYXJnaW4tbGVmdDogMTBweDtcbn1cbi5SZWFjdFZpcnR1YWxpemVkX19UYWJsZV9fc29ydGFibGVIZWFkZXJDb2x1bW4ge1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi5SZWFjdFZpcnR1YWxpemVkX19UYWJsZV9fc29ydGFibGVIZWFkZXJJY29uQ29udGFpbmVyIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbn1cbi5SZWFjdFZpcnR1YWxpemVkX19UYWJsZV9fc29ydGFibGVIZWFkZXJJY29uIHtcbiAgZmxleDogMCAwIDI0cHg7XG4gIGhlaWdodDogMWVtO1xuICB3aWR0aDogMWVtO1xuICBmaWxsOiBjdXJyZW50Q29sb3I7XG59XG5cbi8qIExpc3QgZGVmYXVsdCB0aGVtZSAqL1xuXG4uUmVhY3RWaXJ0dWFsaXplZF9fTGlzdCB7XG59XG4iXX0= */README.md000064400000047607151676725770006070 0ustar00[<img src="https://cloud.githubusercontent.com/assets/29597/11737732/0ca1e55e-9f91-11e5-97f3-098f2f8ed866.png" alt="React virtualized" data-canonical-src="https://cloud.githubusercontent.com/assets/29597/11737732/0ca1e55e-9f91-11e5-97f3-098f2f8ed866.png" width="330" height="100" />](http://bvaughn.github.io/react-virtualized/) React components for efficiently rendering large lists and tabular data. Check out [the demo](https://bvaughn.github.io/react-virtualized/) for some examples. ### If you like this project, 🎉 [become a sponsor](https://github.com/sponsors/bvaughn/) or ☕ [buy me a coffee](http://givebrian.coffee/) ### Sponsors The following wonderful companies have sponsored react-virtualized: <a href="https://www.treasuredata.com/"><img width="64" height="64" title="Treasure Data" src="https://cloud.githubusercontent.com/assets/29597/17391516/962647f8-59cb-11e6-83be-aa1bac299dd0.png"></a> <a href="https://developer.hpe.com/"><img width="64" height="64" title="HPE Dev" src="https://user-images.githubusercontent.com/5983843/37311298-1c3a711a-261d-11e8-9129-ef1589d7063f.png"></a> <a href="https://opencollective.com/react-virtualized/sponsor/0/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/1/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/2/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/3/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/4/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/5/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/6/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/7/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/8/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/9/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/10/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/10/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/11/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/11/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/12/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/12/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/13/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/13/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/14/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/14/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/15/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/15/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/16/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/16/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/17/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/17/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/18/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/18/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/19/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/19/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/20/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/20/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/21/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/21/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/22/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/22/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/23/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/23/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/24/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/24/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/25/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/25/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/26/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/26/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/27/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/27/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/28/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/28/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/sponsor/29/website" target="_blank"><img src="https://opencollective.com/react-virtualized/sponsor/29/avatar.svg"></a> [Learn more about becoming a sponsor!](https://opencollective.com/react-virtualized#sponsor) <a href="https://opencollective.com/react-virtualized/backer/0/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/0/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/1/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/1/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/2/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/2/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/3/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/3/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/4/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/4/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/5/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/5/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/6/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/6/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/7/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/7/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/8/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/8/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/9/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/9/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/10/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/10/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/11/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/11/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/12/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/12/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/13/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/13/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/14/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/14/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/15/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/15/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/16/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/16/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/17/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/17/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/18/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/18/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/19/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/19/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/20/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/20/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/21/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/21/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/22/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/22/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/23/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/23/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/24/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/24/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/25/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/25/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/26/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/26/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/27/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/27/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/28/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/28/avatar.svg"></a> <a href="https://opencollective.com/react-virtualized/backer/29/website" target="_blank"><img src="https://opencollective.com/react-virtualized/backer/29/avatar.svg"></a> ## A word about `react-window` If you're considering adding `react-virtualized` to a project, take a look at [`react-window`](https://github.com/bvaughn/react-window) as a possible lighter-weight alternative. [Learn more about how the two libraries compare here.](https://github.com/bvaughn/react-window#how-is-react-window-different-from-react-virtualized) ## Getting started Install `react-virtualized` using npm. ```shell npm install react-virtualized --save ``` ES6, CommonJS, and UMD builds are available with each distribution. For example: ```js // Most of react-virtualized's styles are functional (eg position, size). // Functional styles are applied directly to DOM elements. // The Table component ships with a few presentational styles as well. // They are optional, but if you want them you will need to also import the CSS file. // This only needs to be done once; probably during your application's bootstrapping process. import 'react-virtualized/styles.css'; // You can import any component you want as a named export from 'react-virtualized', eg import {Column, Table} from 'react-virtualized'; // But if you only use a few react-virtualized components, // And you're concerned about increasing your application's bundle size, // You can directly import only the components you need, like so: import AutoSizer from 'react-virtualized/dist/commonjs/AutoSizer'; import List from 'react-virtualized/dist/commonjs/List'; ``` Note webpack 4 makes this optimization itself, see the [documentation](https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free). If the above syntax looks too cumbersome, or you import react-virtualized components from a lot of places, you can also configure a Webpack alias. For example: ```js // Partial webpack.config.js { alias: { 'react-virtualized/List': 'react-virtualized/dist/es/List', }, ...rest } ``` Then you can just import like so: ```js import List from 'react-virtualized/List'; // Now you can use <List {...props} /> ``` You can also use a global-friendly UMD build: ```html <link rel="stylesheet" href="path-to-react-virtualized/styles.css" /> <script src="path-to-react-virtualized/dist/umd/react-virtualized.js"></script> ``` Now you're ready to start using the components. You can learn more about which components react-virtualized has to offer [below](#documentation). ## Dependencies React Virtualized has very few dependencies and most are managed by NPM automatically. However the following peer dependencies must be specified by your project in order to avoid version conflicts: [`react`](https://www.npmjs.com/package/react), [`react-dom`](https://www.npmjs.com/package/react-dom). NPM will not automatically install these for you but it will show you a warning message with instructions on how to install them. ## Pure Components By default all react-virtualized components use [`shallowCompare`](https://facebook.github.io/react/docs/shallow-compare.html) to avoid re-rendering unless props or state has changed. This occasionally confuses users when a collection's data changes (eg `['a','b','c']` => `['d','e','f']`) but props do not (eg `array.length`). The solution to this is to let react-virtualized know that something external has changed. This can be done a couple of different ways. ###### Pass-thru props The `shallowCompare` method will detect changes to any props, even if they aren't declared as `propTypes`. This means you can also pass through additional properties that affect cell rendering to ensure changes are detected. For example, if you're using `List` to render a list of items that may be re-sorted after initial render- react-virtualized would not normally detect the sort operation because none of the properties it deals with change. However you can pass through the additional sort property to trigger a re-render. For example: ```js <List {...listProps} sortBy={sortBy} /> ``` ###### Public methods `Grid` and `Collection` components can be forcefully re-rendered using [`forceUpdate`](https://facebook.github.io/react/docs/component-api.html#forceupdate). For `Table` and `List`, you'll need to call [`forceUpdateGrid`](https://github.com/bvaughn/react-virtualized/blob/master/docs/Table.md#forceupdategrid) to ensure that the inner `Grid` is also updated. For `MultiGrid`, you'll need to call [`forceUpdateGrids`](https://github.com/bvaughn/react-virtualized/blob/master/docs/MultiGrid.md#forceupdategrids) to ensure that the inner `Grid`s are updated. ## Documentation API documentation available [here](docs/README.md). There are also a couple of how-to guides: - [Customizing classes and styles](docs/customizingStyles.md) - [Displaying items in reverse order](docs/reverseList.md) - [Using AutoSizer](docs/usingAutoSizer.md) - [Creating an infinite-loading list](docs/creatingAnInfiniteLoadingList.md) - [Natural sort Table](docs/tableWithNaturalSort.md) - [Sorting a Table by multiple columns](docs/multiColumnSortTable.md) ## Examples Examples for each component can be seen in [the documentation](docs/README.md). Here are some online demos of each component: - [ArrowKeyStepper](https://bvaughn.github.io/react-virtualized/#/components/ArrowKeyStepper) - [AutoSizer](https://bvaughn.github.io/react-virtualized/#/components/AutoSizer) - [CellMeasurer](https://bvaughn.github.io/react-virtualized/#/components/CellMeasurer) - [Collection](https://bvaughn.github.io/react-virtualized/#/components/Collection) - [ColumnSizer](https://bvaughn.github.io/react-virtualized/#/components/ColumnSizer) - [Grid](https://bvaughn.github.io/react-virtualized/#/components/Grid) - [InfiniteLoader](https://bvaughn.github.io/react-virtualized/#/components/InfiniteLoader) - [List](https://bvaughn.github.io/react-virtualized/#/components/List) - [Masonry](https://bvaughn.github.io/react-virtualized/#/components/Masonry) - [MultiGrid](https://bvaughn.github.io/react-virtualized/#/components/MultiGrid) - [ScrollSync](https://bvaughn.github.io/react-virtualized/#/components/ScrollSync) - [Table](https://bvaughn.github.io/react-virtualized/#/components/Table) - [WindowScroller](https://bvaughn.github.io/react-virtualized/#/components/WindowScroller) And here are some "recipe" type demos: - [Table with resizable (drag and drop) columns](https://codesandbox.io/s/j30k46l7xw) - [Collapsable tree view](https://rawgit.com/bvaughn/react-virtualized/master/playground/tree.html) - [Full-page grid (spreadsheet)](https://rawgit.com/bvaughn/react-virtualized/master/playground/grid.html) - [Dynamic cell measuring](https://rawgit.com/bvaughn/react-virtualized/master/playground/chat.html) - [Cell hover effects](https://rawgit.com/bvaughn/react-virtualized/master/playground/hover.html) ## Supported Browsers react-virtualized aims to support all evergreen browsers and recent mobile browsers for iOS and Android. IE 9+ is also supported (although IE 9 will require some user-defined, custom CSS since flexbox layout is not supported). If you find a browser-specific problem, please report it along with a repro case. The easiest way to do this is probably by forking [this Plunker](https://plnkr.co/edit/6syKo8cx3RfoO96hXFT1). ## Friends Here are some great components built on top of react-virtualized: - [react-infinite-calendar](https://github.com/clauderic/react-infinite-calendar): Infinite scrolling date-picker with localization, themes, keyboard support, and more - [react-sortable-hoc](https://github.com/clauderic/react-sortable-hoc): Higher-order components to turn any list into an animated, touch-friendly, sortable list - [react-sortable-tree](https://github.com/fritz-c/react-sortable-tree): Drag-and-drop sortable representation of hierarchical data - [react-virtualized-checkbox](https://github.com/emilebres/react-virtualized-checkbox): Checkbox group component with virtualization for large number of options - [react-virtualized-select](https://github.com/bvaughn/react-virtualized-select): Drop-down menu for React with windowing to support large numbers of options. - [react-virtualized-tree](https://github.com/diogofcunha/react-virtualized-tree/): A reactive tree component that aims to render large sets of tree structured data in an elegant and performant way - [react-timeline-9000](https://github.com/BHP-DevHub/react-timeline-9000/): A calendar timeline component that is capable of displaying and interacting with a large number of items ## Contributions Use [GitHub issues](https://github.com/bvaughn/react-virtualized/issues) for requests. I actively welcome pull requests; learn how to [contribute](https://github.com/bvaughn/react-virtualized/blob/master/CONTRIBUTING.md). ## Changelog Changes are tracked in the [changelog](https://github.com/bvaughn/react-virtualized/blob/master/CHANGELOG.md). ## License _react-virtualized_ is available under the MIT License.
/home/emeraadmin/.razor/.././www/node_modules/parse-filepath/../../4d695/react-virtualized.tar