react-scroll-sync
Advanced tools
Comparing version
1678
dist/index.js
@@ -1,1553 +0,175 @@ | ||
(function webpackUniversalModuleDefinition(root, factory) { | ||
if(typeof exports === 'object' && typeof module === 'object') | ||
module.exports = factory(require("react")); | ||
else if(typeof define === 'function' && define.amd) | ||
define(["react"], factory); | ||
else if(typeof exports === 'object') | ||
exports["ScrollSync"] = factory(require("react")); | ||
else | ||
root["ScrollSync"] = factory(root["react"]); | ||
})(this, function(__WEBPACK_EXTERNAL_MODULE_4__) { | ||
return /******/ (function(modules) { // webpackBootstrap | ||
/******/ // The module cache | ||
/******/ var installedModules = {}; | ||
/******/ | ||
/******/ // The require function | ||
/******/ function __webpack_require__(moduleId) { | ||
/******/ | ||
/******/ // Check if module is in cache | ||
/******/ if(installedModules[moduleId]) { | ||
/******/ return installedModules[moduleId].exports; | ||
/******/ } | ||
/******/ // Create a new module (and put it into the cache) | ||
/******/ var module = installedModules[moduleId] = { | ||
/******/ i: moduleId, | ||
/******/ l: false, | ||
/******/ exports: {} | ||
/******/ }; | ||
/******/ | ||
/******/ // Execute the module function | ||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | ||
/******/ | ||
/******/ // Flag the module as loaded | ||
/******/ module.l = true; | ||
/******/ | ||
/******/ // Return the exports of the module | ||
/******/ return module.exports; | ||
/******/ } | ||
/******/ | ||
/******/ | ||
/******/ // expose the modules object (__webpack_modules__) | ||
/******/ __webpack_require__.m = modules; | ||
/******/ | ||
/******/ // expose the module cache | ||
/******/ __webpack_require__.c = installedModules; | ||
/******/ | ||
/******/ // identity function for calling harmony imports with the correct context | ||
/******/ __webpack_require__.i = function(value) { return value; }; | ||
/******/ | ||
/******/ // define getter function for harmony exports | ||
/******/ __webpack_require__.d = function(exports, name, getter) { | ||
/******/ if(!__webpack_require__.o(exports, name)) { | ||
/******/ Object.defineProperty(exports, name, { | ||
/******/ configurable: false, | ||
/******/ enumerable: true, | ||
/******/ get: getter | ||
/******/ }); | ||
/******/ } | ||
/******/ }; | ||
/******/ | ||
/******/ // getDefaultExport function for compatibility with non-harmony modules | ||
/******/ __webpack_require__.n = function(module) { | ||
/******/ var getter = module && module.__esModule ? | ||
/******/ function getDefault() { return module['default']; } : | ||
/******/ function getModuleExports() { return module; }; | ||
/******/ __webpack_require__.d(getter, 'a', getter); | ||
/******/ return getter; | ||
/******/ }; | ||
/******/ | ||
/******/ // Object.prototype.hasOwnProperty.call | ||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | ||
/******/ | ||
/******/ // __webpack_public_path__ | ||
/******/ __webpack_require__.p = ""; | ||
/******/ | ||
/******/ // Load entry module and return exports | ||
/******/ return __webpack_require__(__webpack_require__.s = 10); | ||
/******/ }) | ||
/************************************************************************/ | ||
/******/ ([ | ||
/* 0 */ | ||
/***/ (function(module, exports) { | ||
// src/components/ScrollSync.tsx | ||
import React, { useCallback, useRef } from "react"; | ||
// shim for using process in browser | ||
var process = module.exports = {}; | ||
// cached from whatever global is present so that test runners that stub it | ||
// don't break things. But we need to wrap it in a try catch in case it is | ||
// wrapped in strict mode code which doesn't define any globals. It's inside a | ||
// function because try/catches deoptimize in certain engines. | ||
var cachedSetTimeout; | ||
var cachedClearTimeout; | ||
function defaultSetTimout() { | ||
throw new Error('setTimeout has not been defined'); | ||
} | ||
function defaultClearTimeout () { | ||
throw new Error('clearTimeout has not been defined'); | ||
} | ||
(function () { | ||
try { | ||
if (typeof setTimeout === 'function') { | ||
cachedSetTimeout = setTimeout; | ||
} else { | ||
cachedSetTimeout = defaultSetTimout; | ||
} | ||
} catch (e) { | ||
cachedSetTimeout = defaultSetTimout; | ||
} | ||
try { | ||
if (typeof clearTimeout === 'function') { | ||
cachedClearTimeout = clearTimeout; | ||
} else { | ||
cachedClearTimeout = defaultClearTimeout; | ||
} | ||
} catch (e) { | ||
cachedClearTimeout = defaultClearTimeout; | ||
} | ||
} ()) | ||
function runTimeout(fun) { | ||
if (cachedSetTimeout === setTimeout) { | ||
//normal enviroments in sane situations | ||
return setTimeout(fun, 0); | ||
} | ||
// if setTimeout wasn't available but was latter defined | ||
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { | ||
cachedSetTimeout = setTimeout; | ||
return setTimeout(fun, 0); | ||
} | ||
try { | ||
// when when somebody has screwed with setTimeout but no I.E. maddness | ||
return cachedSetTimeout(fun, 0); | ||
} catch(e){ | ||
try { | ||
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally | ||
return cachedSetTimeout.call(null, fun, 0); | ||
} catch(e){ | ||
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error | ||
return cachedSetTimeout.call(this, fun, 0); | ||
} | ||
} | ||
} | ||
function runClearTimeout(marker) { | ||
if (cachedClearTimeout === clearTimeout) { | ||
//normal enviroments in sane situations | ||
return clearTimeout(marker); | ||
} | ||
// if clearTimeout wasn't available but was latter defined | ||
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { | ||
cachedClearTimeout = clearTimeout; | ||
return clearTimeout(marker); | ||
} | ||
try { | ||
// when when somebody has screwed with setTimeout but no I.E. maddness | ||
return cachedClearTimeout(marker); | ||
} catch (e){ | ||
try { | ||
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally | ||
return cachedClearTimeout.call(null, marker); | ||
} catch (e){ | ||
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. | ||
// Some versions of I.E. have different rules for clearTimeout vs setTimeout | ||
return cachedClearTimeout.call(this, marker); | ||
} | ||
} | ||
} | ||
var queue = []; | ||
var draining = false; | ||
var currentQueue; | ||
var queueIndex = -1; | ||
function cleanUpNextTick() { | ||
if (!draining || !currentQueue) { | ||
return; | ||
} | ||
draining = false; | ||
if (currentQueue.length) { | ||
queue = currentQueue.concat(queue); | ||
} else { | ||
queueIndex = -1; | ||
} | ||
if (queue.length) { | ||
drainQueue(); | ||
} | ||
} | ||
function drainQueue() { | ||
if (draining) { | ||
return; | ||
} | ||
var timeout = runTimeout(cleanUpNextTick); | ||
draining = true; | ||
var len = queue.length; | ||
while(len) { | ||
currentQueue = queue; | ||
queue = []; | ||
while (++queueIndex < len) { | ||
if (currentQueue) { | ||
currentQueue[queueIndex].run(); | ||
} | ||
} | ||
queueIndex = -1; | ||
len = queue.length; | ||
} | ||
currentQueue = null; | ||
draining = false; | ||
runClearTimeout(timeout); | ||
} | ||
process.nextTick = function (fun) { | ||
var args = new Array(arguments.length - 1); | ||
if (arguments.length > 1) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
args[i - 1] = arguments[i]; | ||
} | ||
} | ||
queue.push(new Item(fun, args)); | ||
if (queue.length === 1 && !draining) { | ||
runTimeout(drainQueue); | ||
} | ||
// src/hooks/useScrollSyncContext.ts | ||
import { createContext, useContext } from "react"; | ||
var ScrollSyncContext = createContext(void 0); | ||
var useScrollSyncContext = () => { | ||
const context = useContext(ScrollSyncContext); | ||
if (!context) { | ||
throw new Error( | ||
"useScrollSyncContext must be used within a ScrollSyncProvider" | ||
); | ||
} | ||
return context; | ||
}; | ||
// v8 likes predictible objects | ||
function Item(fun, array) { | ||
this.fun = fun; | ||
this.array = array; | ||
} | ||
Item.prototype.run = function () { | ||
this.fun.apply(null, this.array); | ||
}; | ||
process.title = 'browser'; | ||
process.browser = true; | ||
process.env = {}; | ||
process.argv = []; | ||
process.version = ''; // empty string to avoid regexp issues | ||
process.versions = {}; | ||
function noop() {} | ||
process.on = noop; | ||
process.addListener = noop; | ||
process.once = noop; | ||
process.off = noop; | ||
process.removeListener = noop; | ||
process.removeAllListeners = noop; | ||
process.emit = noop; | ||
process.prependListener = noop; | ||
process.prependOnceListener = noop; | ||
process.listeners = function (name) { return [] } | ||
process.binding = function (name) { | ||
throw new Error('process.binding is not supported'); | ||
}; | ||
process.cwd = function () { return '/' }; | ||
process.chdir = function (dir) { | ||
throw new Error('process.chdir is not supported'); | ||
}; | ||
process.umask = function() { return 0; }; | ||
/***/ }), | ||
/* 1 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/** | ||
* Copyright (c) 2013-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* | ||
*/ | ||
function makeEmptyFunction(arg) { | ||
return function () { | ||
return arg; | ||
}; | ||
} | ||
/** | ||
* This function accepts and discards inputs; it has no side effects. This is | ||
* primarily useful idiomatically for overridable function endpoints which | ||
* always need to be callable, since JS lacks a null-call idiom ala Cocoa. | ||
*/ | ||
var emptyFunction = function emptyFunction() {}; | ||
emptyFunction.thatReturns = makeEmptyFunction; | ||
emptyFunction.thatReturnsFalse = makeEmptyFunction(false); | ||
emptyFunction.thatReturnsTrue = makeEmptyFunction(true); | ||
emptyFunction.thatReturnsNull = makeEmptyFunction(null); | ||
emptyFunction.thatReturnsThis = function () { | ||
return this; | ||
}; | ||
emptyFunction.thatReturnsArgument = function (arg) { | ||
return arg; | ||
}; | ||
module.exports = emptyFunction; | ||
/***/ }), | ||
/* 2 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/* WEBPACK VAR INJECTION */(function(process) {/** | ||
* Copyright (c) 2013-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
*/ | ||
/** | ||
* Use invariant() to assert state which your program assumes to be true. | ||
* | ||
* Provide sprintf-style format (only %s is supported) and arguments | ||
* to provide information about what broke and what you were | ||
* expecting. | ||
* | ||
* The invariant message will be stripped in production, but the invariant | ||
* will remain to ensure logic does not differ in production. | ||
*/ | ||
var validateFormat = function validateFormat(format) {}; | ||
if (process.env.NODE_ENV !== 'production') { | ||
validateFormat = function validateFormat(format) { | ||
if (format === undefined) { | ||
throw new Error('invariant requires an error message argument'); | ||
// src/components/ScrollSync.tsx | ||
import { jsx } from "react/jsx-runtime"; | ||
var ScrollSync = ({ | ||
children, | ||
enabled = true, | ||
horizontal = true, | ||
onSync, | ||
proportional = true, | ||
vertical = true | ||
}) => { | ||
const panesRef = useRef({}); | ||
const findPane = useCallback((node, group) => { | ||
if (!panesRef.current[group]) { | ||
return false; | ||
} | ||
}; | ||
} | ||
function invariant(condition, format, a, b, c, d, e, f) { | ||
validateFormat(format); | ||
if (!condition) { | ||
var error; | ||
if (format === undefined) { | ||
error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.'); | ||
} else { | ||
var args = [a, b, c, d, e, f]; | ||
var argIndex = 0; | ||
error = new Error(format.replace(/%s/g, function () { | ||
return args[argIndex++]; | ||
})); | ||
error.name = 'Invariant Violation'; | ||
} | ||
error.framesToPop = 1; // we don't care about invariant's own frame | ||
throw error; | ||
} | ||
} | ||
module.exports = invariant; | ||
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) | ||
/***/ }), | ||
/* 3 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/** | ||
* Copyright 2013-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; | ||
module.exports = ReactPropTypesSecret; | ||
/***/ }), | ||
/* 4 */ | ||
/***/ (function(module, exports) { | ||
module.exports = __WEBPACK_EXTERNAL_MODULE_4__; | ||
/***/ }), | ||
/* 5 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _react = __webpack_require__(4); | ||
var _react2 = _interopRequireDefault(_react); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var ScrollSyncContext = _react2.default.createContext({ | ||
registerPane: function registerPane() {}, | ||
unregisterPane: function unregisterPane() {} | ||
}); | ||
exports.default = ScrollSyncContext; | ||
module.exports = exports['default']; | ||
/***/ }), | ||
/* 6 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/* WEBPACK VAR INJECTION */(function(process) {/** | ||
* Copyright 2014-2015, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
*/ | ||
var emptyFunction = __webpack_require__(1); | ||
/** | ||
* 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 warning = emptyFunction; | ||
if (process.env.NODE_ENV !== 'production') { | ||
(function () { | ||
var printWarning = function printWarning(format) { | ||
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { | ||
args[_key - 1] = arguments[_key]; | ||
return panesRef.current[group].find((pane) => pane === node); | ||
}, []); | ||
const syncScrollPosition = useCallback( | ||
(scrolledPane, pane) => { | ||
const { | ||
clientHeight, | ||
clientWidth, | ||
scrollHeight, | ||
scrollLeft, | ||
scrollTop, | ||
scrollWidth | ||
} = scrolledPane; | ||
const scrollTopOffset = scrollHeight - clientHeight; | ||
const scrollLeftOffset = scrollWidth - clientWidth; | ||
const paneHeight = pane.scrollHeight - clientHeight; | ||
const paneWidth = pane.scrollWidth - clientWidth; | ||
if (vertical && scrollTopOffset > 0) { | ||
pane.scrollTop = proportional ? paneHeight * scrollTop / scrollTopOffset : scrollTop; | ||
} | ||
var argIndex = 0; | ||
var message = 'Warning: ' + format.replace(/%s/g, function () { | ||
return args[argIndex++]; | ||
}); | ||
if (typeof console !== 'undefined') { | ||
console.error(message); | ||
if (horizontal && scrollLeftOffset > 0) { | ||
pane.scrollLeft = proportional ? paneWidth * scrollLeft / scrollLeftOffset : scrollLeft; | ||
} | ||
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) {} | ||
}; | ||
warning = function warning(condition, format) { | ||
if (format === undefined) { | ||
throw new Error('`warning(condition, format, ...args)` requires a warning ' + 'message argument'); | ||
} | ||
if (format.indexOf('Failed Composite propType: ') === 0) { | ||
return; // Ignore CompositeComponent proptype check. | ||
} | ||
if (!condition) { | ||
for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { | ||
args[_key2 - 2] = arguments[_key2]; | ||
}, | ||
[proportional, vertical, horizontal] | ||
); | ||
const removeEvents = useCallback((node) => { | ||
node.onscroll = null; | ||
}, []); | ||
const addEvents = useCallback( | ||
(node, groups) => { | ||
node.onscroll = () => { | ||
if (!enabled) return; | ||
window.requestAnimationFrame(() => { | ||
groups.forEach((group) => { | ||
panesRef.current[group]?.forEach((pane) => { | ||
if (node !== pane) { | ||
removeEvents(pane); | ||
syncScrollPosition(node, pane); | ||
window.requestAnimationFrame(() => { | ||
const paneGroups = Object.keys(panesRef.current).filter( | ||
(paneGroup) => panesRef.current[paneGroup].includes(pane) | ||
); | ||
addEvents(pane, paneGroups); | ||
}); | ||
} | ||
}); | ||
}); | ||
}); | ||
if (onSync) { | ||
onSync(node); | ||
} | ||
printWarning.apply(undefined, [format].concat(args)); | ||
} | ||
}; | ||
})(); | ||
} | ||
module.exports = warning; | ||
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) | ||
/***/ }), | ||
/* 7 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
/* WEBPACK VAR INJECTION */(function(process) {/** | ||
* Copyright 2013-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
if (process.env.NODE_ENV !== 'production') { | ||
var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' && | ||
Symbol.for && | ||
Symbol.for('react.element')) || | ||
0xeac7; | ||
var isValidElement = function(object) { | ||
return typeof object === 'object' && | ||
object !== null && | ||
object.$$typeof === REACT_ELEMENT_TYPE; | ||
}; | ||
// By explicitly using `prop-types` you are opting into new development behavior. | ||
// http://fb.me/prop-types-in-prod | ||
var throwOnDirectAccess = true; | ||
module.exports = __webpack_require__(13)(isValidElement, throwOnDirectAccess); | ||
} else { | ||
// By explicitly using `prop-types` you are opting into new production behavior. | ||
// http://fb.me/prop-types-in-prod | ||
module.exports = __webpack_require__(12)(); | ||
} | ||
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) | ||
/***/ }), | ||
/* 8 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
var _react = __webpack_require__(4); | ||
var _react2 = _interopRequireDefault(_react); | ||
var _propTypes = __webpack_require__(7); | ||
var _propTypes2 = _interopRequireDefault(_propTypes); | ||
var _ScrollSyncContext = __webpack_require__(5); | ||
var _ScrollSyncContext2 = _interopRequireDefault(_ScrollSyncContext); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | ||
/** | ||
* ScrollSync provider component | ||
* | ||
*/ | ||
var ScrollSync = function (_Component) { | ||
_inherits(ScrollSync, _Component); | ||
function ScrollSync() { | ||
var _ref; | ||
var _temp, _this, _ret; | ||
_classCallCheck(this, ScrollSync); | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = ScrollSync.__proto__ || Object.getPrototypeOf(ScrollSync)).call.apply(_ref, [this].concat(args))), _this), _this.panes = {}, _this.registerPane = function (node, groups) { | ||
groups.forEach(function (group) { | ||
if (!_this.panes[group]) { | ||
_this.panes[group] = []; | ||
}; | ||
}, | ||
[onSync, removeEvents, syncScrollPosition, enabled] | ||
); | ||
const registerPane = useCallback( | ||
(node, groups) => { | ||
groups.forEach((group) => { | ||
if (!panesRef.current[group]) { | ||
panesRef.current[group] = []; | ||
} | ||
if (!_this.findPane(node, group)) { | ||
if (_this.panes[group].length > 0) { | ||
_this.syncScrollPosition(_this.panes[group][0], node); | ||
if (!findPane(node, group)) { | ||
if (panesRef.current[group].length > 0) { | ||
syncScrollPosition(panesRef.current[group][0], node); | ||
} | ||
_this.panes[group].push(node); | ||
panesRef.current[group].push(node); | ||
} | ||
}); | ||
_this.addEvents(node, groups); | ||
}, _this.unregisterPane = function (node, groups) { | ||
groups.forEach(function (group) { | ||
if (_this.findPane(node, group)) { | ||
_this.removeEvents(node); | ||
_this.panes[group].splice(_this.panes[group].indexOf(node), 1); | ||
} | ||
}); | ||
}, _this.addEvents = function (node, groups) { | ||
/* For some reason element.addEventListener doesnt work with document.body */ | ||
node.onscroll = _this.handlePaneScroll.bind(_this, node, groups); // eslint-disable-line | ||
}, _this.removeEvents = function (node) { | ||
/* For some reason element.removeEventListener doesnt work with document.body */ | ||
node.onscroll = null; // eslint-disable-line | ||
}, _this.findPane = function (node, group) { | ||
if (!_this.panes[group]) { | ||
return false; | ||
} | ||
return _this.panes[group].find(function (pane) { | ||
return pane === node; | ||
}); | ||
}, _this.handlePaneScroll = function (node, groups) { | ||
if (!_this.props.enabled) { | ||
return; | ||
} | ||
window.requestAnimationFrame(function () { | ||
_this.syncScrollPositions(node, groups); | ||
}); | ||
}, _this.syncScrollPositions = function (scrolledPane, groups) { | ||
groups.forEach(function (group) { | ||
_this.panes[group].forEach(function (pane) { | ||
/* For all panes beside the currently scrolling one */ | ||
if (scrolledPane !== pane) { | ||
/* Remove event listeners from the node that we'll manipulate */ | ||
_this.removeEvents(pane, group); | ||
_this.syncScrollPosition(scrolledPane, pane); | ||
/* Re-attach event listeners after we're done scrolling */ | ||
window.requestAnimationFrame(function () { | ||
var paneGroups = Object.keys(_this.panes).filter(function (paneGroup) { | ||
return _this.panes[paneGroup].includes(pane); | ||
}); | ||
_this.addEvents(pane, paneGroups); | ||
}); | ||
addEvents(node, groups); | ||
}, | ||
[findPane, syncScrollPosition, addEvents] | ||
); | ||
const unregisterPane = useCallback( | ||
(node, groups) => { | ||
groups.forEach((group) => { | ||
if (findPane(node, group)) { | ||
removeEvents(node); | ||
const index = panesRef.current[group].indexOf(node); | ||
if (index !== -1) { | ||
panesRef.current[group].splice(index, 1); | ||
} | ||
}); | ||
}); | ||
if (_this.props.onSync) _this.props.onSync(scrolledPane); | ||
}, _temp), _possibleConstructorReturn(_this, _ret); | ||
} | ||
_createClass(ScrollSync, [{ | ||
key: 'getContextValue', | ||
value: function getContextValue() { | ||
return { | ||
registerPane: this.registerPane, | ||
unregisterPane: this.unregisterPane | ||
}; | ||
} | ||
}, { | ||
key: 'syncScrollPosition', | ||
value: function syncScrollPosition(scrolledPane, pane) { | ||
var scrollTop = scrolledPane.scrollTop, | ||
scrollHeight = scrolledPane.scrollHeight, | ||
clientHeight = scrolledPane.clientHeight, | ||
scrollLeft = scrolledPane.scrollLeft, | ||
scrollWidth = scrolledPane.scrollWidth, | ||
clientWidth = scrolledPane.clientWidth; | ||
var scrollTopOffset = scrollHeight - clientHeight; | ||
var scrollLeftOffset = scrollWidth - clientWidth; | ||
var _props = this.props, | ||
proportional = _props.proportional, | ||
vertical = _props.vertical, | ||
horizontal = _props.horizontal; | ||
/* Calculate the actual pane height */ | ||
var paneHeight = pane.scrollHeight - clientHeight; | ||
var paneWidth = pane.scrollWidth - clientWidth; | ||
/* Adjust the scrollTop position of it accordingly */ | ||
if (vertical && scrollTopOffset > 0) { | ||
pane.scrollTop = proportional ? paneHeight * scrollTop / scrollTopOffset : scrollTop; // eslint-disable-line | ||
} | ||
if (horizontal && scrollLeftOffset > 0) { | ||
pane.scrollLeft = proportional ? paneWidth * scrollLeft / scrollLeftOffset : scrollLeft; // eslint-disable-line | ||
} | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
return _react2.default.createElement( | ||
_ScrollSyncContext2.default.Provider, | ||
{ value: this.getContextValue() }, | ||
_react2.default.Children.only(this.props.children) | ||
); | ||
} | ||
}]); | ||
return ScrollSync; | ||
}(_react.Component); | ||
ScrollSync.propTypes = { | ||
/** | ||
* Callback to be invoked any time synchronization happens | ||
* | ||
* @param {Element} el The element that has received the scroll event | ||
*/ | ||
onSync: _propTypes2.default.func, | ||
children: _propTypes2.default.element.isRequired, | ||
proportional: _propTypes2.default.bool, | ||
vertical: _propTypes2.default.bool, | ||
horizontal: _propTypes2.default.bool, | ||
enabled: _propTypes2.default.bool | ||
}; | ||
ScrollSync.defaultProps = { | ||
proportional: true, | ||
vertical: true, | ||
horizontal: true, | ||
enabled: true | ||
}; | ||
exports.default = ScrollSync; | ||
module.exports = exports['default']; | ||
/***/ }), | ||
/* 9 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
var _react = __webpack_require__(4); | ||
var _propTypes = __webpack_require__(7); | ||
var _propTypes2 = _interopRequireDefault(_propTypes); | ||
var _ScrollSyncContext = __webpack_require__(5); | ||
var _ScrollSyncContext2 = _interopRequireDefault(_ScrollSyncContext); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | ||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint react/no-find-dom-node: 0 */ | ||
/** | ||
* ScrollSyncPane Component | ||
* | ||
* Wrap your content in it to keep its scroll position in sync with other panes | ||
* | ||
* @example ./example.md | ||
*/ | ||
var ScrollSyncPane = function (_Component) { | ||
_inherits(ScrollSyncPane, _Component); | ||
function ScrollSyncPane(props) { | ||
_classCallCheck(this, ScrollSyncPane); | ||
var _this = _possibleConstructorReturn(this, (ScrollSyncPane.__proto__ || Object.getPrototypeOf(ScrollSyncPane)).call(this, props)); | ||
_this.toArray = function (groups) { | ||
return [].concat(groups); | ||
}; | ||
_this.updateNode = function () { | ||
if (_this.props.attachTo) { | ||
_this.node = _this.props.attachTo.current; | ||
} else { | ||
_this.node = _this.childRef.current; | ||
} | ||
}; | ||
_this.childRef = props.innerRef ? props.innerRef : (0, _react.createRef)(); | ||
return _this; | ||
} | ||
_createClass(ScrollSyncPane, [{ | ||
key: 'componentDidMount', | ||
value: function componentDidMount() { | ||
if (this.props.enabled) { | ||
this.updateNode(); | ||
if (this.node) { | ||
this.context.registerPane(this.node, this.toArray(this.props.group)); | ||
} | ||
} | ||
} | ||
}, { | ||
key: 'componentDidUpdate', | ||
value: function componentDidUpdate(prevProps) { | ||
if (this.props.attachTo !== prevProps.attachTo) { | ||
if (this.node) { | ||
this.context.unregisterPane(this.node, this.toArray(prevProps.group)); | ||
} | ||
this.updateNode(); | ||
if (this.node) { | ||
this.context.registerPane(this.node, this.toArray(prevProps.group)); | ||
} | ||
} | ||
if (this.node && this.props.enabled !== prevProps.enabled) { | ||
if (this.props.enabled) { | ||
this.context.registerPane(this.node, this.toArray(prevProps.group)); | ||
} else { | ||
this.context.unregisterPane(this.node, this.toArray(prevProps.group)); | ||
} | ||
} | ||
if (this.node && this.props.enabled && this.props.group !== prevProps.group) { | ||
this.context.unregisterPane(this.node, this.toArray(prevProps.group)); | ||
this.context.registerPane(this.node, this.toArray(this.props.group)); | ||
} | ||
} | ||
}, { | ||
key: 'componentWillUnmount', | ||
value: function componentWillUnmount() { | ||
if (this.node && this.props.enabled) { | ||
this.context.unregisterPane(this.node, this.toArray(this.props.group)); | ||
} | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
if (this.props.attachTo) { | ||
return this.props.children; | ||
} | ||
return (0, _react.cloneElement)(_react.Children.only(this.props.children), { | ||
ref: this.childRef | ||
}); | ||
} | ||
}]); | ||
return ScrollSyncPane; | ||
}(_react.Component); | ||
ScrollSyncPane.contextType = _ScrollSyncContext2.default; | ||
ScrollSyncPane.propTypes = { | ||
children: _propTypes2.default.node.isRequired, | ||
attachTo: _propTypes2.default.oneOfType([_propTypes2.default.func, _propTypes2.default.shape({ current: _propTypes2.default.any })]), | ||
group: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.arrayOf(_propTypes2.default.string)]), | ||
enabled: _propTypes2.default.bool, | ||
innerRef: _propTypes2.default.oneOfType([// Either a function | ||
_propTypes2.default.func, _propTypes2.default.shape({ current: _propTypes2.default.any })]) | ||
}, | ||
[findPane, removeEvents] | ||
); | ||
return /* @__PURE__ */ jsx(ScrollSyncContext.Provider, { value: { registerPane, unregisterPane }, children: React.Children.only(children) }); | ||
}; | ||
ScrollSyncPane.defaultProps = { | ||
group: 'default', | ||
enabled: true | ||
}; | ||
exports.default = ScrollSyncPane; | ||
module.exports = exports['default']; | ||
/***/ }), | ||
/* 10 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _ScrollSync = __webpack_require__(8); | ||
Object.defineProperty(exports, 'ScrollSync', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_ScrollSync).default; | ||
} | ||
}); | ||
var _ScrollSyncPane = __webpack_require__(9); | ||
Object.defineProperty(exports, 'ScrollSyncPane', { | ||
enumerable: true, | ||
get: function get() { | ||
return _interopRequireDefault(_ScrollSyncPane).default; | ||
} | ||
}); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/***/ }), | ||
/* 11 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/* WEBPACK VAR INJECTION */(function(process) {/** | ||
* Copyright 2013-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
if (process.env.NODE_ENV !== 'production') { | ||
var invariant = __webpack_require__(2); | ||
var warning = __webpack_require__(6); | ||
var ReactPropTypesSecret = __webpack_require__(3); | ||
var loggedTypeFailures = {}; | ||
} | ||
/** | ||
* 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) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
for (var typeSpecName in typeSpecs) { | ||
if (typeSpecs.hasOwnProperty(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. | ||
invariant(typeof typeSpecs[typeSpecName] === 'function', '%s: %s type `%s` is invalid; it must be a function, usually from ' + 'React.PropTypes.', componentName || 'React class', location, typeSpecName); | ||
error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret); | ||
} catch (ex) { | ||
error = ex; | ||
} | ||
warning(!error || error instanceof Error, '%s: type specification of %s `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error); | ||
if (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] = true; | ||
var stack = getStack ? getStack() : ''; | ||
warning(false, 'Failed %s type: %s%s', location, error.message, stack != null ? stack : ''); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
module.exports = checkPropTypes; | ||
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) | ||
/***/ }), | ||
/* 12 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/** | ||
* Copyright 2013-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
var emptyFunction = __webpack_require__(1); | ||
var invariant = __webpack_require__(2); | ||
var ReactPropTypesSecret = __webpack_require__(3); | ||
module.exports = function() { | ||
function shim(props, propName, componentName, location, propFullName, secret) { | ||
if (secret === ReactPropTypesSecret) { | ||
// It is still safe when called from React. | ||
return; | ||
} | ||
invariant( | ||
false, | ||
'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' | ||
); | ||
}; | ||
shim.isRequired = shim; | ||
function getShim() { | ||
return shim; | ||
}; | ||
// Important! | ||
// Keep this list in sync with production version in `./factoryWithTypeCheckers.js`. | ||
var ReactPropTypes = { | ||
array: shim, | ||
bool: shim, | ||
func: shim, | ||
number: shim, | ||
object: shim, | ||
string: shim, | ||
symbol: shim, | ||
any: shim, | ||
arrayOf: getShim, | ||
element: shim, | ||
instanceOf: getShim, | ||
node: shim, | ||
objectOf: getShim, | ||
oneOf: getShim, | ||
oneOfType: getShim, | ||
shape: getShim | ||
}; | ||
ReactPropTypes.checkPropTypes = emptyFunction; | ||
ReactPropTypes.PropTypes = ReactPropTypes; | ||
return ReactPropTypes; | ||
}; | ||
/***/ }), | ||
/* 13 */ | ||
/***/ (function(module, exports, __webpack_require__) { | ||
"use strict"; | ||
/* WEBPACK VAR INJECTION */(function(process) {/** | ||
* Copyright 2013-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
var emptyFunction = __webpack_require__(1); | ||
var invariant = __webpack_require__(2); | ||
var warning = __webpack_require__(6); | ||
var ReactPropTypesSecret = __webpack_require__(3); | ||
var checkPropTypes = __webpack_require__(11); | ||
module.exports = function(isValidElement, throwOnDirectAccess) { | ||
/* global Symbol */ | ||
var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; | ||
var FAUX_ITERATOR_SYMBOL = '@@iterator'; // 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 getIteratorFn(maybeIterable) { | ||
var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]); | ||
if (typeof iteratorFn === 'function') { | ||
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 | ||
*/ | ||
var ANONYMOUS = '<<anonymous>>'; | ||
// Important! | ||
// Keep this list in sync with production version in `./factoryWithThrowingShims.js`. | ||
var ReactPropTypes = { | ||
array: createPrimitiveTypeChecker('array'), | ||
bool: createPrimitiveTypeChecker('boolean'), | ||
func: createPrimitiveTypeChecker('function'), | ||
number: createPrimitiveTypeChecker('number'), | ||
object: createPrimitiveTypeChecker('object'), | ||
string: createPrimitiveTypeChecker('string'), | ||
symbol: createPrimitiveTypeChecker('symbol'), | ||
any: createAnyTypeChecker(), | ||
arrayOf: createArrayOfTypeChecker, | ||
element: createElementTypeChecker(), | ||
instanceOf: createInstanceTypeChecker, | ||
node: createNodeChecker(), | ||
objectOf: createObjectOfTypeChecker, | ||
oneOf: createEnumTypeChecker, | ||
oneOfType: createUnionTypeChecker, | ||
shape: createShapeTypeChecker | ||
}; | ||
/** | ||
* 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 | ||
if (x === y) { | ||
// Steps 1-5, 7-10 | ||
// Steps 6.b-6.e: +0 != -0 | ||
return x !== 0 || 1 / x === 1 / y; | ||
// src/components/ScrollSyncPane.tsx | ||
import { | ||
cloneElement, | ||
useCallback as useCallback2, | ||
useEffect, | ||
useRef as useRef2 | ||
} from "react"; | ||
var castArray = (groups) => Array.isArray(groups) ? groups : [groups]; | ||
var ScrollSyncPane = ({ | ||
attachTo, | ||
children, | ||
enabled = true, | ||
group = "default", | ||
innerRef | ||
}) => { | ||
const context = useScrollSyncContext(); | ||
const childRef = useRef2(null); | ||
const nodeRef = useRef2(null); | ||
const updateNode = useCallback2(() => { | ||
if (attachTo) { | ||
nodeRef.current = typeof attachTo === "function" ? null : attachTo.current; | ||
} else { | ||
// Step 6.a: NaN == NaN | ||
return x !== x && y !== y; | ||
nodeRef.current = childRef.current; | ||
} | ||
} | ||
/*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. | ||
PropTypeError.prototype = Error.prototype; | ||
function createChainableTypeChecker(validate) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
var manualPropTypeCallCache = {}; | ||
var manualPropTypeWarningCount = 0; | ||
}, [attachTo]); | ||
useEffect(() => { | ||
updateNode(); | ||
if (enabled && nodeRef.current) { | ||
context.registerPane(nodeRef.current, castArray(group)); | ||
} | ||
function checkType(isRequired, props, propName, componentName, location, propFullName, secret) { | ||
componentName = componentName || ANONYMOUS; | ||
propFullName = propFullName || propName; | ||
if (secret !== ReactPropTypesSecret) { | ||
if (throwOnDirectAccess) { | ||
// New behavior only for users of `prop-types` package | ||
invariant( | ||
false, | ||
'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' | ||
); | ||
} else if (process.env.NODE_ENV !== 'production' && typeof console !== 'undefined') { | ||
// Old behavior for people using React.PropTypes | ||
var cacheKey = componentName + ':' + propName; | ||
if ( | ||
!manualPropTypeCallCache[cacheKey] && | ||
// Avoid spamming the console because they are often not actionable except for lib authors | ||
manualPropTypeWarningCount < 3 | ||
) { | ||
warning( | ||
false, | ||
'You are manually calling a React.PropTypes validation ' + | ||
'function for the `%s` prop on `%s`. 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.', | ||
propFullName, | ||
componentName | ||
); | ||
manualPropTypeCallCache[cacheKey] = true; | ||
manualPropTypeWarningCount++; | ||
} | ||
} | ||
return () => { | ||
if (enabled && nodeRef.current) { | ||
context.unregisterPane(nodeRef.current, castArray(group)); | ||
} | ||
if (props[propName] == null) { | ||
if (isRequired) { | ||
if (props[propName] === null) { | ||
return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.')); | ||
} | ||
return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.')); | ||
} | ||
return null; | ||
} else { | ||
return validate(props, propName, componentName, location, propFullName); | ||
} | ||
} | ||
var chainedCheckType = checkType.bind(null, false); | ||
chainedCheckType.isRequired = checkType.bind(null, true); | ||
return chainedCheckType; | ||
}; | ||
}, [context, enabled, group, attachTo, updateNode]); | ||
if (attachTo) { | ||
return children; | ||
} | ||
function createPrimitiveTypeChecker(expectedType) { | ||
function validate(props, propName, componentName, location, propFullName, secret) { | ||
var propValue = props[propName]; | ||
var propType = getPropType(propValue); | ||
if (propType !== expectedType) { | ||
// `propValue` being instance of, say, date/regexp, pass the 'object' | ||
// check, but we can offer a more precise error message here rather than | ||
// 'of type `object`'. | ||
var preciseType = getPreciseType(propValue); | ||
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + preciseType + '` supplied to `' + componentName + '`, expected ') + ('`' + expectedType + '`.')); | ||
return cloneElement(children, { | ||
ref: (node) => { | ||
childRef.current = node; | ||
if (typeof innerRef === "function") { | ||
innerRef(node); | ||
} else if (innerRef && node) { | ||
innerRef.current = node; | ||
} | ||
return null; | ||
} | ||
return createChainableTypeChecker(validate); | ||
} | ||
function createAnyTypeChecker() { | ||
return createChainableTypeChecker(emptyFunction.thatReturnsNull); | ||
} | ||
function createArrayOfTypeChecker(typeChecker) { | ||
function validate(props, propName, componentName, location, propFullName) { | ||
if (typeof typeChecker !== 'function') { | ||
return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside arrayOf.'); | ||
} | ||
var propValue = props[propName]; | ||
if (!Array.isArray(propValue)) { | ||
var propType = getPropType(propValue); | ||
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an array.')); | ||
} | ||
for (var i = 0; i < propValue.length; i++) { | ||
var error = typeChecker(propValue, i, componentName, location, propFullName + '[' + i + ']', ReactPropTypesSecret); | ||
if (error instanceof Error) { | ||
return error; | ||
} | ||
} | ||
return null; | ||
} | ||
return createChainableTypeChecker(validate); | ||
} | ||
function createElementTypeChecker() { | ||
function validate(props, propName, componentName, location, propFullName) { | ||
var propValue = props[propName]; | ||
if (!isValidElement(propValue)) { | ||
var propType = getPropType(propValue); | ||
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected a single ReactElement.')); | ||
} | ||
return null; | ||
} | ||
return createChainableTypeChecker(validate); | ||
} | ||
function createInstanceTypeChecker(expectedClass) { | ||
function validate(props, propName, componentName, location, propFullName) { | ||
if (!(props[propName] instanceof expectedClass)) { | ||
var expectedClassName = expectedClass.name || ANONYMOUS; | ||
var actualClassName = getClassName(props[propName]); | ||
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + actualClassName + '` supplied to `' + componentName + '`, expected ') + ('instance of `' + expectedClassName + '`.')); | ||
} | ||
return null; | ||
} | ||
return createChainableTypeChecker(validate); | ||
} | ||
function createEnumTypeChecker(expectedValues) { | ||
if (!Array.isArray(expectedValues)) { | ||
process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOf, expected an instance of array.') : void 0; | ||
return emptyFunction.thatReturnsNull; | ||
} | ||
function validate(props, propName, componentName, location, propFullName) { | ||
var propValue = props[propName]; | ||
for (var i = 0; i < expectedValues.length; i++) { | ||
if (is(propValue, expectedValues[i])) { | ||
return null; | ||
} | ||
} | ||
var valuesString = JSON.stringify(expectedValues); | ||
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of value `' + propValue + '` ' + ('supplied to `' + componentName + '`, expected one of ' + valuesString + '.')); | ||
} | ||
return createChainableTypeChecker(validate); | ||
} | ||
function createObjectOfTypeChecker(typeChecker) { | ||
function validate(props, propName, componentName, location, propFullName) { | ||
if (typeof typeChecker !== 'function') { | ||
return new PropTypeError('Property `' + propFullName + '` of component `' + componentName + '` has invalid PropType notation inside objectOf.'); | ||
} | ||
var propValue = props[propName]; | ||
var propType = getPropType(propValue); | ||
if (propType !== 'object') { | ||
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` of type ' + ('`' + propType + '` supplied to `' + componentName + '`, expected an object.')); | ||
} | ||
for (var key in propValue) { | ||
if (propValue.hasOwnProperty(key)) { | ||
var error = typeChecker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); | ||
if (error instanceof Error) { | ||
return error; | ||
} | ||
} | ||
} | ||
return null; | ||
} | ||
return createChainableTypeChecker(validate); | ||
} | ||
function createUnionTypeChecker(arrayOfTypeCheckers) { | ||
if (!Array.isArray(arrayOfTypeCheckers)) { | ||
process.env.NODE_ENV !== 'production' ? warning(false, 'Invalid argument supplied to oneOfType, expected an instance of array.') : void 0; | ||
return emptyFunction.thatReturnsNull; | ||
} | ||
for (var i = 0; i < arrayOfTypeCheckers.length; i++) { | ||
var checker = arrayOfTypeCheckers[i]; | ||
if (typeof checker !== 'function') { | ||
warning( | ||
false, | ||
'Invalid argument supplid to oneOfType. Expected an array of check functions, but ' + | ||
'received %s at index %s.', | ||
getPostfixForTypeWarning(checker), | ||
i | ||
); | ||
return emptyFunction.thatReturnsNull; | ||
} | ||
} | ||
function validate(props, propName, componentName, location, propFullName) { | ||
for (var i = 0; i < arrayOfTypeCheckers.length; i++) { | ||
var checker = arrayOfTypeCheckers[i]; | ||
if (checker(props, propName, componentName, location, propFullName, ReactPropTypesSecret) == null) { | ||
return null; | ||
} | ||
} | ||
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`.')); | ||
} | ||
return createChainableTypeChecker(validate); | ||
} | ||
function createNodeChecker() { | ||
function validate(props, propName, componentName, location, propFullName) { | ||
if (!isNode(props[propName])) { | ||
return new PropTypeError('Invalid ' + location + ' `' + propFullName + '` supplied to ' + ('`' + componentName + '`, expected a ReactNode.')); | ||
} | ||
return null; | ||
} | ||
return createChainableTypeChecker(validate); | ||
} | ||
function createShapeTypeChecker(shapeTypes) { | ||
function validate(props, propName, componentName, location, propFullName) { | ||
var propValue = props[propName]; | ||
var propType = getPropType(propValue); | ||
if (propType !== 'object') { | ||
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) { | ||
continue; | ||
} | ||
var error = checker(propValue, key, componentName, location, propFullName + '.' + key, ReactPropTypesSecret); | ||
if (error) { | ||
return error; | ||
} | ||
} | ||
return null; | ||
} | ||
return createChainableTypeChecker(validate); | ||
} | ||
function isNode(propValue) { | ||
switch (typeof propValue) { | ||
case 'number': | ||
case 'string': | ||
case 'undefined': | ||
return true; | ||
case 'boolean': | ||
return !propValue; | ||
case 'object': | ||
if (Array.isArray(propValue)) { | ||
return propValue.every(isNode); | ||
} | ||
if (propValue === null || isValidElement(propValue)) { | ||
return true; | ||
} | ||
var iteratorFn = getIteratorFn(propValue); | ||
if (iteratorFn) { | ||
var iterator = iteratorFn.call(propValue); | ||
var step; | ||
if (iteratorFn !== propValue.entries) { | ||
while (!(step = iterator.next()).done) { | ||
if (!isNode(step.value)) { | ||
return false; | ||
} | ||
} | ||
} else { | ||
// Iterator will provide entry [k,v] tuples rather than values. | ||
while (!(step = iterator.next()).done) { | ||
var entry = step.value; | ||
if (entry) { | ||
if (!isNode(entry[1])) { | ||
return false; | ||
} | ||
} | ||
} | ||
} | ||
} else { | ||
return false; | ||
} | ||
return true; | ||
default: | ||
return false; | ||
} | ||
} | ||
function isSymbol(propType, propValue) { | ||
// Native Symbol. | ||
if (propType === 'symbol') { | ||
return true; | ||
} | ||
// 19.4.3.5 Symbol.prototype[@@toStringTag] === 'Symbol' | ||
if (propValue['@@toStringTag'] === 'Symbol') { | ||
return true; | ||
} | ||
// Fallback for non-spec compliant Symbols which are polyfilled. | ||
if (typeof Symbol === 'function' && propValue instanceof Symbol) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
// Equivalent of `typeof` but with special handling for array and regexp. | ||
function getPropType(propValue) { | ||
var propType = typeof propValue; | ||
if (Array.isArray(propValue)) { | ||
return 'array'; | ||
} | ||
if (propValue instanceof RegExp) { | ||
// Old webkits (at least until Android 4.0) return 'function' rather than | ||
// 'object' for typeof a RegExp. We'll normalize this here so that /bla/ | ||
// passes PropTypes.object. | ||
return 'object'; | ||
} | ||
if (isSymbol(propType, propValue)) { | ||
return 'symbol'; | ||
} | ||
return propType; | ||
} | ||
// This handles more types than `getPropType`. Only used for error messages. | ||
// See `createPrimitiveTypeChecker`. | ||
function getPreciseType(propValue) { | ||
if (typeof propValue === 'undefined' || propValue === null) { | ||
return '' + propValue; | ||
} | ||
var propType = getPropType(propValue); | ||
if (propType === 'object') { | ||
if (propValue instanceof Date) { | ||
return 'date'; | ||
} else 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; | ||
} | ||
} | ||
// Returns class name of the object, if any. | ||
function getClassName(propValue) { | ||
if (!propValue.constructor || !propValue.constructor.name) { | ||
return ANONYMOUS; | ||
} | ||
return propValue.constructor.name; | ||
} | ||
ReactPropTypes.checkPropTypes = checkPropTypes; | ||
ReactPropTypes.PropTypes = ReactPropTypes; | ||
return ReactPropTypes; | ||
}); | ||
}; | ||
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) | ||
/***/ }) | ||
/******/ ]); | ||
}); | ||
export { | ||
ScrollSync, | ||
ScrollSyncPane | ||
}; | ||
//# sourceMappingURL=index.js.map |
105
package.json
{ | ||
"name": "react-scroll-sync", | ||
"version": "0.11.3", | ||
"version": "1.0.0", | ||
"description": "Synchronize scroll positions across multiple scrollable containers", | ||
"main": "dist/index.js", | ||
"type": "module", | ||
"types": "./dist/index.d.ts", | ||
"main": "./dist/index.cjs", | ||
"module": "./dist/index.mjs", | ||
"exports": { | ||
".": { | ||
"types": "./dist/index.d.ts", | ||
"module": "./dist/index.mjs", | ||
"main": "./dist/index.cjs", | ||
"umd": "./dist/index.js" | ||
} | ||
}, | ||
"files": [ | ||
"dist", | ||
"src" | ||
], | ||
"scripts": { | ||
"clean": "rimraf ./dist", | ||
"prebuild": "npm run lint", | ||
"build": "NODE_ENV=production npm run clean && webpack", | ||
"prepare": "npm run build", | ||
"lint": "eslint src --ext .js,.jsx", | ||
"build": "tsup", | ||
"build:storybook": " storybook build --output-dir public", | ||
"lint": "eslint .", | ||
"lint:fix": "npm run lint -- --fix", | ||
"lint:staged": "lint-staged", | ||
"styleguide:server": "styleguidist server", | ||
"styleguide:build": "styleguidist build" | ||
"prepare": "husky", | ||
"storybook": "storybook dev -p 6006", | ||
"validate:commit": "lint-staged", | ||
"validate:push": "npm run build" | ||
}, | ||
"lint-staged": { | ||
"*.js": [ | ||
"eslint --fix", | ||
"git add" | ||
] | ||
}, | ||
"pre-commit": "lint:staged", | ||
"repository": { | ||
@@ -35,47 +43,30 @@ "type": "git", | ||
"homepage": "https://github.com/okonet/react-scroll-sync#readme", | ||
"eslintConfig": { | ||
"extends": "okonet", | ||
"rules": { | ||
"react/forbid-prop-types": 0, | ||
"react/jsx-wrap-multilines": 0 | ||
}, | ||
"import/no-extraneous-dependencies": [ | ||
"error", | ||
{ | ||
"peerDependencies": [ | ||
"src/*.js" | ||
], | ||
"devDependencies": [ | ||
"**/*.test.js", | ||
"**/*.spec.js" | ||
] | ||
} | ||
] | ||
}, | ||
"devDependencies": { | ||
"babel-loader": "6.2.5", | ||
"babel-plugin-add-module-exports": "0.2.1", | ||
"babel-preset-es2015": "6.16.0", | ||
"babel-preset-react": "6.16.0", | ||
"babel-preset-stage-1": "6.16.0", | ||
"eslint": "3.7.1", | ||
"eslint-config-okonet": "1.1.1", | ||
"jest": "16.0.0", | ||
"lint-staged": "3.0.3", | ||
"npmpub": "3.1.0", | ||
"pre-commit": "1.1.3", | ||
"prop-types": "15.5.10", | ||
"react": "18.1.0", | ||
"react-dom": "18.1.0", | ||
"react-styleguidist": "6.5.3", | ||
"rimraf": "2.5.4", | ||
"webpack": "2.7.0" | ||
"@eslint/js": "9.27.0", | ||
"@storybook/addon-actions": "8.6.14", | ||
"@storybook/addon-docs": "^8.6.14", | ||
"@storybook/addon-essentials": "^8.6.14", | ||
"@storybook/addon-links": "^8.6.14", | ||
"@storybook/addon-webpack5-compiler-swc": "^3.0.0", | ||
"@storybook/react": "8.6.14", | ||
"@storybook/react-webpack5": "^8.6.14", | ||
"@types/node": "22.15.19", | ||
"@types/react": "19.1.4", | ||
"@types/react-dom": "19.1.5", | ||
"eslint": "9.27.0", | ||
"eslint-plugin-perfectionist": "4.13.0", | ||
"eslint-plugin-react": "7.37.5", | ||
"eslint-plugin-react-hooks": "5.2.0", | ||
"globals": "16.1.0", | ||
"husky": "9.1.7", | ||
"lint-staged": "16.0.0", | ||
"storybook": "8.6.14", | ||
"tsup": "8.5.0", | ||
"typescript": "5.8.3", | ||
"typescript-eslint": "8.32.1" | ||
}, | ||
"peerDependencies": { | ||
"react": "16.x || 17.x || 18.x", | ||
"react-dom": "16.x || 17.x || 18.x" | ||
}, | ||
"dependencies": { | ||
"prop-types": "^15.5.7" | ||
"react": "16.x || 17.x || 18.x || 19.x", | ||
"react-dom": "16.x || 17.x || 18.x || 19.x" | ||
} | ||
} |
# react-scroll-sync | ||
Synced scroll position across multiple scrollable elements | ||
@@ -21,52 +22,58 @@ | ||
``` | ||
## Usage | ||
```jsx | ||
import React, {Component} from 'react'; | ||
import { ScrollSync, ScrollSyncPane } from 'react-scroll-sync'; | ||
import { FC } from "react"; | ||
import { ScrollSync, ScrollSyncPane } from "react-scroll-sync"; | ||
export default class MyComponent extends Component { | ||
render() { | ||
<ScrollSync> | ||
<div style={{ display: 'flex', position: 'relative', height: 300 }}> | ||
<ScrollSyncPane> | ||
<div style={{overflow: 'auto'}}> | ||
<section style={{ height: 500 }}> | ||
<h1>Left Pane Content</h1> | ||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab aperiam doloribus | ||
dolorum | ||
est eum eveniet exercitationem iste labore minus, neque nobis odit officiis omnis | ||
possimus quasi rerum sed soluta veritatis.</p> | ||
</section> | ||
</div> | ||
</ScrollSyncPane> | ||
export const MyComponent: FC = () => { | ||
return ( | ||
<ScrollSync> | ||
<div style={{ display: "flex", position: "relative", height: 300 }}> | ||
<ScrollSyncPane> | ||
<div style={{ overflow: "auto" }}> | ||
<section style={{ height: 500 }}> | ||
<h1>Left Pane Content</h1> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab | ||
aperiam doloribus dolorum est eum eveniet exercitationem iste | ||
labore minus, neque nobis odit officiis omnis possimus quasi | ||
rerum sed soluta veritatis. | ||
</p> | ||
</section> | ||
</div> | ||
</ScrollSyncPane> | ||
<ScrollSyncPane> | ||
<div style={{overflow: 'auto'}}> | ||
<section style={{ height: 1000 }}> | ||
<h1>Middle Pane Content</h1> | ||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab aperiam doloribus | ||
dolorum | ||
est eum eveniet exercitationem iste labore minus, neque nobis odit officiis omnis | ||
possimus quasi rerum sed soluta veritatis.</p> | ||
</section> | ||
</div> | ||
</ScrollSyncPane> | ||
<ScrollSyncPane> | ||
<div style={{ overflow: "auto" }}> | ||
<section style={{ height: 1000 }}> | ||
<h1>Middle Pane Content</h1> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab | ||
aperiam doloribus dolorum est eum eveniet exercitationem iste | ||
labore minus, neque nobis odit officiis omnis possimus quasi | ||
rerum sed soluta veritatis. | ||
</p> | ||
</section> | ||
</div> | ||
</ScrollSyncPane> | ||
<ScrollSyncPane> | ||
<div style={{overflow: 'auto'}}> | ||
<section style={{ height: 2000 }}> | ||
<h1>Right Pane Content</h1> | ||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab aperiam doloribus | ||
dolorum | ||
est eum eveniet exercitationem iste labore minus, neque nobis odit officiis omnis | ||
possimus quasi rerum sed soluta veritatis.</p> | ||
</section> | ||
</div> | ||
</ScrollSyncPane> | ||
</div> | ||
</ScrollSync> | ||
} | ||
} | ||
<ScrollSyncPane> | ||
<div style={{ overflow: "auto" }}> | ||
<section style={{ height: 2000 }}> | ||
<h1>Right Pane Content</h1> | ||
<p> | ||
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab | ||
aperiam doloribus dolorum est eum eveniet exercitationem iste | ||
labore minus, neque nobis odit officiis omnis possimus quasi | ||
rerum sed soluta veritatis. | ||
</p> | ||
</section> | ||
</div> | ||
</ScrollSyncPane> | ||
</div> | ||
</ScrollSync> | ||
); | ||
}; | ||
``` |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
274066
98.86%2
-33.33%18
12.5%2615
62.73%0
-100%79
9.72%0
-100%Yes
NaN22
29.41%1
Infinity%+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed