Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-scroll-into-view-if-needed

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-scroll-into-view-if-needed - npm Package Compare versions

Comparing version 1.0.3 to 2.0.0

2

coverage/coverage-final.json

@@ -1,2 +0,2 @@

{"/Users/justinschrader/Desktop/KOAN/opensource/react-scroll-into-view-if-needed/src/index.js": {"path":"/Users/justinschrader/Desktop/KOAN/opensource/react-scroll-into-view-if-needed/src/index.js","statementMap":{"0":{"start":{"line":41,"column":4},"end":{"line":41,"column":12}},"1":{"start":{"line":42,"column":4},"end":{"line":42,"column":28}},"2":{"start":{"line":46,"column":23},"end":{"line":46,"column":33}},"3":{"start":{"line":47,"column":4},"end":{"line":49,"column":5}},"4":{"start":{"line":48,"column":6},"end":{"line":48,"column":42}},"5":{"start":{"line":53,"column":36},"end":{"line":53,"column":46}},"6":{"start":{"line":54,"column":4},"end":{"line":56,"column":5}},"7":{"start":{"line":55,"column":6},"end":{"line":55,"column":42}},"8":{"start":{"line":60,"column":24},"end":{"line":60,"column":34}},"9":{"start":{"line":61,"column":30},"end":{"line":61,"column":39}},"10":{"start":{"line":62,"column":4},"end":{"line":62,"column":42}},"11":{"start":{"line":72,"column":8},"end":{"line":72,"column":18}},"12":{"start":{"line":73,"column":4},"end":{"line":73,"column":85}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":40,"column":2},"end":{"line":40,"column":3}},"loc":{"start":{"line":40,"column":16},"end":{"line":43,"column":3}},"line":40},"1":{"name":"(anonymous_1)","decl":{"start":{"line":45,"column":2},"end":{"line":45,"column":3}},"loc":{"start":{"line":45,"column":22},"end":{"line":50,"column":3}},"line":45},"2":{"name":"(anonymous_2)","decl":{"start":{"line":52,"column":2},"end":{"line":52,"column":3}},"loc":{"start":{"line":52,"column":33},"end":{"line":57,"column":3}},"line":52},"3":{"name":"(anonymous_3)","decl":{"start":{"line":59,"column":33},"end":{"line":59,"column":34}},"loc":{"start":{"line":59,"column":39},"end":{"line":63,"column":3}},"line":59},"4":{"name":"(anonymous_4)","decl":{"start":{"line":65,"column":2},"end":{"line":65,"column":3}},"loc":{"start":{"line":65,"column":11},"end":{"line":74,"column":3}},"line":65}},"branchMap":{"0":{"loc":{"start":{"line":47,"column":4},"end":{"line":49,"column":5}},"type":"if","locations":[{"start":{"line":47,"column":4},"end":{"line":49,"column":5}},{"start":{"line":47,"column":4},"end":{"line":49,"column":5}}],"line":47},"1":{"loc":{"start":{"line":54,"column":4},"end":{"line":56,"column":5}},"type":"if","locations":[{"start":{"line":54,"column":4},"end":{"line":56,"column":5}},{"start":{"line":54,"column":4},"end":{"line":56,"column":5}}],"line":54},"2":{"loc":{"start":{"line":54,"column":8},"end":{"line":54,"column":30}},"type":"binary-expr","locations":[{"start":{"line":54,"column":8},"end":{"line":54,"column":15}},{"start":{"line":54,"column":19},"end":{"line":54,"column":30}}],"line":54}},"s":{"0":6,"1":6,"2":6,"3":6,"4":4,"5":2,"6":2,"7":1,"8":5,"9":5,"10":5,"11":8,"12":8},"f":{"0":6,"1":6,"2":2,"3":5,"4":8},"b":{"0":[4,2],"1":[1,1],"2":[2,2]},"_coverageSchema":"332fd63041d2c1bcb487cc26dd0d5f7d97098a6c","hash":"893202e561bf79cf5b640faf9e0c890c0994fdb7"}
{"/Users/justin/Documents/opensource/react-scroll-into-view-if-needed/src/index.js": {"path":"/Users/justin/Documents/opensource/react-scroll-into-view-if-needed/src/index.js","statementMap":{"0":{"start":{"line":54,"column":4},"end":{"line":54,"column":12}},"1":{"start":{"line":55,"column":4},"end":{"line":55,"column":28}},"2":{"start":{"line":59,"column":23},"end":{"line":59,"column":33}},"3":{"start":{"line":60,"column":4},"end":{"line":62,"column":5}},"4":{"start":{"line":61,"column":6},"end":{"line":61,"column":42}},"5":{"start":{"line":66,"column":36},"end":{"line":66,"column":46}},"6":{"start":{"line":67,"column":4},"end":{"line":69,"column":5}},"7":{"start":{"line":68,"column":6},"end":{"line":68,"column":42}},"8":{"start":{"line":73,"column":24},"end":{"line":73,"column":34}},"9":{"start":{"line":74,"column":30},"end":{"line":74,"column":39}},"10":{"start":{"line":75,"column":4},"end":{"line":75,"column":42}},"11":{"start":{"line":85,"column":8},"end":{"line":85,"column":18}},"12":{"start":{"line":86,"column":4},"end":{"line":86,"column":85}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":53,"column":2},"end":{"line":53,"column":3}},"loc":{"start":{"line":53,"column":16},"end":{"line":56,"column":3}},"line":53},"1":{"name":"(anonymous_1)","decl":{"start":{"line":58,"column":2},"end":{"line":58,"column":3}},"loc":{"start":{"line":58,"column":22},"end":{"line":63,"column":3}},"line":58},"2":{"name":"(anonymous_2)","decl":{"start":{"line":65,"column":2},"end":{"line":65,"column":3}},"loc":{"start":{"line":65,"column":33},"end":{"line":70,"column":3}},"line":65},"3":{"name":"(anonymous_3)","decl":{"start":{"line":72,"column":33},"end":{"line":72,"column":34}},"loc":{"start":{"line":72,"column":39},"end":{"line":76,"column":3}},"line":72},"4":{"name":"(anonymous_4)","decl":{"start":{"line":78,"column":2},"end":{"line":78,"column":3}},"loc":{"start":{"line":78,"column":11},"end":{"line":87,"column":3}},"line":78}},"branchMap":{"0":{"loc":{"start":{"line":60,"column":4},"end":{"line":62,"column":5}},"type":"if","locations":[{"start":{"line":60,"column":4},"end":{"line":62,"column":5}},{"start":{"line":60,"column":4},"end":{"line":62,"column":5}}],"line":60},"1":{"loc":{"start":{"line":67,"column":4},"end":{"line":69,"column":5}},"type":"if","locations":[{"start":{"line":67,"column":4},"end":{"line":69,"column":5}},{"start":{"line":67,"column":4},"end":{"line":69,"column":5}}],"line":67},"2":{"loc":{"start":{"line":67,"column":8},"end":{"line":67,"column":30}},"type":"binary-expr","locations":[{"start":{"line":67,"column":8},"end":{"line":67,"column":15}},{"start":{"line":67,"column":19},"end":{"line":67,"column":30}}],"line":67}},"s":{"0":6,"1":6,"2":6,"3":6,"4":4,"5":2,"6":2,"7":1,"8":5,"9":5,"10":5,"11":8,"12":8},"f":{"0":6,"1":6,"2":2,"3":5,"4":8},"b":{"0":[4,2],"1":[1,1],"2":[2,2]},"_coverageSchema":"332fd63041d2c1bcb487cc26dd0d5f7d97098a6c","hash":"98a9df2996566acb5478860735af3682d1d98c7e"}
}
import { createElement, createRef, PureComponent } from 'react';
import PropTypes from 'prop-types';
/**
* https://github.com/gre/bezier-easing
* BezierEasing - use bezier curve for transition easing function
* by Gaëtan Renaudeau 2014 - 2015 – MIT License
*/
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
// These values are established by empiricism with tests (tradeoff: performance VS precision)
var NEWTON_ITERATIONS = 4;
var NEWTON_MIN_SLOPE = 0.001;
var SUBDIVISION_PRECISION = 0.0000001;
var SUBDIVISION_MAX_ITERATIONS = 10;
var isElement = function isElement(el) {
return el != null && typeof el == 'object' && el.nodeType === 1;
};
var kSplineTableSize = 11;
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
var hasScrollableSpace = function hasScrollableSpace(el, axis) {
if (axis === 'Y') {
return el.clientHeight < el.scrollHeight;
}
var float32ArraySupported = typeof Float32Array === 'function';
if (axis === 'X') {
return el.clientWidth < el.scrollWidth;
}
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
function C (aA1) { return 3.0 * aA1; }
return false;
};
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
var canOverflow = function canOverflow(el, axis) {
var overflowValue = window.getComputedStyle(el, null)['overflow' + axis];
return overflowValue !== 'visible' && overflowValue !== 'clip';
};
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
var isScrollable = function isScrollable(el) {
return hasScrollableSpace(el, 'Y') && canOverflow(el, 'Y') || hasScrollableSpace(el, 'X') && canOverflow(el, 'X');
};
function binarySubdivide (aX, aA, aB, mX1, mX2) {
var currentX, currentT, i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) {
aB = currentT;
} else {
aA = currentT;
}
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
return currentT;
}
var alignNearest = function alignNearest(scrollingEdgeStart, scrollingEdgeEnd, scrollingSize, elementEdgeStart, elementEdgeEnd, elementSize) {
if (elementEdgeStart < scrollingEdgeStart && elementEdgeEnd > scrollingEdgeEnd || elementEdgeStart > scrollingEdgeStart && elementEdgeEnd < scrollingEdgeEnd) {
return 0;
}
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
var currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0) {
return aGuessT;
}
var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
}
if (elementEdgeStart < scrollingEdgeStart && elementSize < scrollingSize || elementEdgeEnd > scrollingEdgeEnd && elementSize > scrollingSize) {
return elementEdgeStart - scrollingEdgeStart;
}
var src = function bezier (mX1, mY1, mX2, mY2) {
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
throw new Error('bezier x values must be in [0, 1] range');
if (elementEdgeEnd > scrollingEdgeEnd && elementSize < scrollingSize || elementEdgeStart < scrollingEdgeStart && elementSize > scrollingSize) {
return elementEdgeEnd - scrollingEdgeEnd;
}
// Precompute samples table
var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
if (mX1 !== mY1 || mX2 !== mY2) {
for (var i = 0; i < kSplineTableSize; ++i) {
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
return 0;
};
var compute = (function (target, options) {
if (options === void 0) {
options = {};
}
function getTForX (aX) {
var intervalStart = 0.0;
var currentSample = 1;
var lastSample = kSplineTableSize - 1;
var _scrollMode$block$inl = _extends({
scrollMode: 'always',
block: 'center',
inline: 'nearest'
}, options),
scrollMode = _scrollMode$block$inl.scrollMode,
block = _scrollMode$block$inl.block,
inline = _scrollMode$block$inl.inline,
boundary = _scrollMode$block$inl.boundary;
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
var checkBoundary = typeof boundary == 'function' ? boundary : function (parent) {
return parent !== boundary;
};
if (!isElement(target)) {
throw new Error('Element is required in scrollIntoView');
}
var targetRect = target.getBoundingClientRect();
var viewport = document.documentElement;
var frames = [];
var parent;
while (isElement(parent = target.parentNode) && checkBoundary(target)) {
if (isScrollable(parent) || parent === viewport) {
frames.push(parent);
}
--currentSample;
// Interpolate to provide an initial guess for t
var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
var guessForT = intervalStart + dist * kSampleStepSize;
target = parent;
}
var initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= NEWTON_MIN_SLOPE) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
} else if (initialSlope === 0.0) {
return guessForT;
} else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
var viewportWidth = window.visualViewport ? window.visualViewport.width : viewport.clientWidth;
var viewportHeight = window.visualViewport ? window.visualViewport.height : viewport.clientHeight;
var viewportX = window.scrollX || window.pageXOffset;
var viewportY = window.scrollY || window.pageYOffset;
if (scrollMode === 'if-needed') {
var isVisible = frames.every(function (frame) {
var frameRect = frame.getBoundingClientRect();
if (targetRect.top < frameRect.top) {
return false;
}
if (targetRect.bottom > frameRect.bottom) {
return false;
}
if (frame === viewport) {
if (targetRect.bottom > viewportHeight) {
return false;
}
if (targetRect.left > viewportWidth) {
return false;
}
}
return true;
});
if (isVisible) {
return [];
}
}
return function BezierEasing (x) {
if (mX1 === mY1 && mX2 === mY2) {
return x; // linear
var targetBlock;
var targetInline;
var computations = frames.map(function (frame) {
var frameRect = frame.getBoundingClientRect();
var blockScroll = 0;
var inlineScroll = 0;
if (block === 'start') {
if (!targetBlock) {
targetBlock = targetRect.top;
}
if (viewport === frame) {
blockScroll = viewportY + targetBlock;
} else {
var offset = Math.min(targetBlock - frameRect.top, frame.scrollHeight - frame.clientHeight - frame.scrollTop);
blockScroll = frame.scrollTop + offset;
targetBlock -= blockScroll - frame.scrollTop;
}
}
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
if (x === 0) {
return 0;
if (block === 'center') {
if (!targetBlock) {
targetBlock = targetRect.top + targetRect.height / 2;
}
if (viewport === frame) {
blockScroll = viewportY + targetBlock - frame.clientHeight / 2;
} else {
var _offset = 0 - Math.min(frameRect.top + frameRect.height / 2 - targetBlock, frame.scrollTop);
blockScroll = frame.scrollTop + _offset;
targetBlock += frame.scrollTop - blockScroll;
}
}
if (x === 1) {
return 1;
if (block === 'end') {
if (!targetBlock) {
targetBlock = targetRect.bottom;
}
if (viewport === frame) {
blockScroll = viewportY + targetBlock - frame.clientHeight;
} else {
var _offset2 = 0 - Math.min(frameRect.bottom - targetBlock, frame.scrollTop);
blockScroll = frame.scrollTop + _offset2;
targetBlock += frame.scrollTop - blockScroll;
}
}
return calcBezier(getTForX(x), mY1, mY2);
};
};
var src$1 = /*#__PURE__*/Object.freeze({
default: src,
__moduleExports: src
});
if (block === 'nearest') {
if (!targetBlock) {
targetBlock = targetRect.top;
}
var BezierEasing = ( src$1 && src ) || src$1;
if (viewport === frame) {
var _offset3 = alignNearest(viewportY, viewportY + viewportHeight, viewportHeight, viewportY + targetBlock, viewportY + targetBlock + targetRect.height, targetRect.height);
// Predefined set of animations. Similar to CSS easing functions
var animations = {
ease: BezierEasing(0.25, 0.1, 0.25, 1),
easeIn: BezierEasing(0.42, 0, 1, 1),
easeOut: BezierEasing(0, 0, 0.58, 1),
easeInOut: BezierEasing(0.42, 0, 0.58, 1),
linear: BezierEasing(0, 0, 1, 1)
};
blockScroll = viewportY + _offset3;
} else {
var _offset4 = alignNearest(frameRect.top, frameRect.bottom, frameRect.height, targetBlock, targetBlock + targetRect.height, targetRect.height);
blockScroll = frame.scrollTop + _offset4;
targetBlock -= _offset4;
}
}
var amator = animate;
if (inline === 'start') {
if (!targetInline) {
targetInline = targetRect.left;
}
function animate(source, target, options) {
var start= Object.create(null);
var diff = Object.create(null);
options = options || {};
// We let clients specify their own easing function
var easing = (typeof options.easing === 'function') ? options.easing : animations[options.easing];
if (viewport === frame) {
inlineScroll = viewportX + targetInline;
} else {
var _offset5 = Math.min(targetInline - frameRect.left, frame.scrollHeight - frame.clientLeft - frame.scrollLeft);
// if nothing is specified, default to ease (similar to CSS animations)
if (!easing) {
if (options.easing) {
console.warn('Unknown easing function in amator: ' + options.easing);
inlineScroll = frame.scrollLeft + _offset5;
targetInline -= inlineScroll - frame.scrollLeft;
}
}
easing = animations.ease;
}
var step = typeof options.step === 'function' ? options.step : noop;
var done = typeof options.done === 'function' ? options.done : noop;
if (inline === 'center') {
if (!targetInline) {
targetInline = targetRect.left + targetRect.width / 2;
}
var scheduler = getScheduler(options.scheduler);
if (viewport === frame) {
inlineScroll = viewportX + targetInline - frame.clientWidth / 2;
} else {
var _offset6 = 0 - Math.min(frameRect.left + frameRect.width / 2 - targetInline, frame.scrollLeft);
var keys = Object.keys(target);
keys.forEach(function(key) {
start[key] = source[key];
diff[key] = target[key] - source[key];
});
inlineScroll = frame.scrollLeft + _offset6;
targetInline += frame.scrollLeft - inlineScroll;
}
}
var durationInMs = options.duration || 400;
var durationInFrames = Math.max(1, durationInMs * 0.06); // 0.06 because 60 frames pers 1,000 ms
var previousAnimationId;
var frame = 0;
if (inline === 'end') {
if (!targetInline) {
targetInline = targetRect.right;
}
previousAnimationId = scheduler.next(loop);
if (viewport === frame) {
inlineScroll = viewportX + targetInline - frame.clientWidth;
} else {
var _offset7 = 0 - Math.min(frameRect.right - targetInline, frame.scrollLeft);
return {
cancel: cancel
}
inlineScroll = frame.scrollLeft + _offset7;
targetInline += frame.scrollLeft - inlineScroll;
}
}
function cancel() {
scheduler.cancel(previousAnimationId);
previousAnimationId = 0;
}
if (inline === 'nearest') {
if (!targetInline) {
targetInline = targetRect.left;
}
function loop() {
var t = easing(frame/durationInFrames);
frame += 1;
setValues(t);
if (frame <= durationInFrames) {
previousAnimationId = scheduler.next(loop);
step(source);
} else {
previousAnimationId = 0;
setTimeout(function() { done(source); }, 0);
if (viewport === frame) {
var _offset8 = alignNearest(viewportX, viewportX + viewportWidth, viewportWidth, viewportX + targetInline, viewportX + targetInline + targetRect.width, targetRect.width);
inlineScroll = viewportX + _offset8;
} else {
var _offset9 = alignNearest(frameRect.left, frameRect.right, frameRect.width, targetInline, targetInline + targetRect.width, targetRect.width);
inlineScroll = frame.scrollLeft + _offset9;
targetInline -= _offset9;
}
}
}
function setValues(t) {
keys.forEach(function(key) {
source[key] = diff[key] * t + start[key];
});
}
}
return {
el: frame,
top: blockScroll,
left: inlineScroll
};
});
return computations;
});
function noop() { }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function getScheduler(scheduler) {
if (!scheduler) {
var canRaf = typeof window !== 'undefined' && window.requestAnimationFrame;
return canRaf ? rafScheduler() : timeoutScheduler()
function _extends$1() { _extends$1 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
var supportsScrollBehavior;
var scrollIntoViewIfNeeded = (function (target, maybeOptions) {
if (maybeOptions === void 0) {
maybeOptions = true;
}
if (typeof scheduler.next !== 'function') throw new Error('Scheduler is supposed to have next(cb) function')
if (typeof scheduler.cancel !== 'function') throw new Error('Scheduler is supposed to have cancel(handle) function')
return scheduler
}
var options = {};
function rafScheduler() {
return {
next: window.requestAnimationFrame.bind(window),
cancel: window.cancelAnimationFrame.bind(window)
if (supportsScrollBehavior === undefined) {
supportsScrollBehavior = 'scrollBehavior' in document.documentElement.style;
}
}
function timeoutScheduler() {
return {
next: function(cb) {
return setTimeout(cb, 1000/60)
},
cancel: function (id) {
return clearTimeout(id)
}
if (maybeOptions === true || maybeOptions === null) {
options = {
block: 'start',
inline: 'nearest'
};
} else if (maybeOptions === false) {
options = {
block: 'end',
inline: 'nearest'
};
} else if (maybeOptions === Object(maybeOptions)) {
options = Object.keys(maybeOptions).length === 0 ? {
block: 'start',
inline: 'nearest'
} : _extends$1({
block: 'center',
inline: 'nearest'
}, maybeOptions);
}
}
var __assign = (undefined && undefined.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
var handleScroll = function (parent, _a) {
var scrollLeft = _a.scrollLeft, scrollTop = _a.scrollTop;
parent.scrollLeft = scrollLeft;
parent.scrollTop = scrollTop;
};
function calculate(target, options) {
if (!target || !(target instanceof HTMLElement))
throw new Error('Element is required in scrollIntoViewIfNeeded');
var config = __assign({ handleScroll: handleScroll }, options);
var defaultOffset = { top: 0, right: 0, bottom: 0, left: 0 };
config.offset = config.offset
? __assign({}, defaultOffset, config.offset) : defaultOffset;
function withinBounds(value, min, max, extent) {
if (config.centerIfNeeded === false ||
(max <= value + extent && value <= min + extent)) {
return Math.min(max, Math.max(min, value));
}
else {
return (min + max) / 2;
}
}
var offset = config.offset;
var offsetTop = offset.top;
var offsetLeft = offset.left;
var offsetBottom = offset.bottom;
var offsetRight = offset.right;
function makeArea(left, top, width, height) {
return {
left: left + offsetLeft,
top: top + offsetTop,
width: width,
height: height,
right: left + offsetLeft + width + offsetRight,
bottom: top + offsetTop + height + offsetBottom,
translate: function (x, y) {
return makeArea(x + left + offsetLeft, y + top + offsetTop, width, height);
},
relativeFromTo: function (lhs, rhs) {
var newLeft = left + offsetLeft, newTop = top + offsetTop;
lhs = lhs.offsetParent;
rhs = rhs.offsetParent;
if (lhs === rhs) {
return area;
}
for (; lhs; lhs = lhs.offsetParent) {
newLeft += lhs.offsetLeft + lhs.clientLeft;
newTop += lhs.offsetTop + lhs.clientTop;
}
for (; rhs; rhs = rhs.offsetParent) {
newLeft -= rhs.offsetLeft + rhs.clientLeft;
newTop -= rhs.offsetTop + rhs.clientTop;
}
return makeArea(newLeft, newTop, width, height);
},
};
}
var parent, area = makeArea(target.offsetLeft, target.offsetTop, target.offsetWidth, target.offsetHeight);
while ((parent = target.parentNode) instanceof HTMLElement &&
target !== config.boundary) {
var clientLeft = parent.offsetLeft + parent.clientLeft;
var clientTop = parent.offsetTop + parent.clientTop;
// Make area relative to parent's client area.
area = area
.relativeFromTo(target, parent)
.translate(-clientLeft, -clientTop);
var scrollLeft = withinBounds(parent.scrollLeft, area.right - parent.clientWidth, area.left, parent.clientWidth);
var scrollTop = withinBounds(parent.scrollTop, area.bottom - parent.clientHeight, area.top, parent.clientHeight);
// Pass the new coordinates to the handleScroll callback
config.handleScroll(parent, { scrollLeft: scrollLeft, scrollTop: scrollTop }, config);
// Determine actual scroll amount by reading back scroll properties.
area = area.translate(clientLeft - parent.scrollLeft, clientTop - parent.scrollTop);
target = parent;
}
}
var _options = options,
_options$behavior = _options.behavior,
behavior = _options$behavior === void 0 ? 'auto' : _options$behavior,
computeOptions = _objectWithoutProperties(_options, ["behavior"]);
var __assign$1 = (undefined && undefined.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
var instructions = compute(target, computeOptions);
if (typeof behavior == 'function') {
return behavior(instructions);
}
instructions.forEach(function (_ref) {
var el = _ref.el,
top = _ref.top,
left = _ref.left;
if (el.scroll && supportsScrollBehavior) {
el.scroll({
top: top,
left: left,
behavior: behavior
});
} else {
if (el === document.documentElement) {
window.scrollTo(left, top);
} else {
el.scrollTop = top;
el.scrollLeft = left;
}
}
return t;
};
var handleScroll$1 = function (parent, _a, config) {
var scrollLeft = _a.scrollLeft, scrollTop = _a.scrollTop;
if (config.duration) {
amator(parent, {
scrollLeft: scrollLeft,
scrollTop: scrollTop,
}, { duration: config.duration, easing: config.easing });
}
else {
parent.scrollLeft = scrollLeft;
parent.scrollTop = scrollTop;
}
};
function isBoolean(options) {
return typeof options === 'boolean';
}
function scrollIntoViewIfNeeded(target, options, animateOptions, finalElement, offsetOptions) {
if (offsetOptions === void 0) { offsetOptions = {}; }
if (!target || !(target instanceof HTMLElement))
throw new Error('Element is required in scrollIntoViewIfNeeded');
var config = { centerIfNeeded: false, handleScroll: handleScroll$1 };
if (isBoolean(options)) {
config.centerIfNeeded = options;
}
else {
config = __assign$1({}, config, options);
}
var defaultOffset = { top: 0, right: 0, bottom: 0, left: 0 };
config.offset = config.offset
? __assign$1({}, defaultOffset, config.offset) : defaultOffset;
if (animateOptions) {
config.duration = animateOptions.duration;
config.easing = animateOptions.easing;
}
if (finalElement) {
config.boundary = finalElement;
}
if (offsetOptions.offsetTop) {
config.offset.top = offsetOptions.offsetTop;
}
if (offsetOptions.offsetRight) {
config.offset.right = offsetOptions.offsetRight;
}
if (offsetOptions.offsetBottom) {
config.offset.bottom = offsetOptions.offsetBottom;
}
if (offsetOptions.offsetLeft) {
config.offset.left = offsetOptions.offsetLeft;
}
return calculate(target, config);
}
});
});

@@ -388,3 +349,3 @@ var classCallCheck = function (instance, Constructor) {

var _extends = Object.assign || function (target) {
var _extends$2 = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {

@@ -487,3 +448,3 @@ var source = arguments[i];

return createElement(elementType, _extends({ ref: this.node }, wrapperProps), children);
return createElement(elementType, _extends$2({ ref: this.node }, wrapperProps), children);
}

@@ -500,12 +461,7 @@ }]);

options: PropTypes.shape({
boundary: PropTypes.node,
centerIfNeeded: PropTypes.bool,
duration: PropTypes.number,
easing: PropTypes.oneOf(['ease', 'easeIn', 'easeOut', 'easeInOut', 'linear']),
offset: PropTypes.shape({
top: PropTypes.number,
right: PropTypes.number,
bottom: PropTypes.number,
left: PropTypes.number
})
behavior: PropTypes.oneOfType([PropTypes.oneOf(['auto', 'smooth', 'instant']), PropTypes.func]),
block: PropTypes.oneOf(['center', 'end', 'nearest', 'start']),
inline: PropTypes.oneOf(['center', 'end', 'nearest', 'start']),
scrollMode: PropTypes.oneOf(['always', 'if-needed']),
boundary: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
})

@@ -517,4 +473,4 @@ };

options: {
duration: 250,
easing: 'easeOut'
behavior: 'smooth',
scrollMode: 'if-needed'
}

@@ -521,0 +477,0 @@ };

@@ -139,12 +139,7 @@ import { createElement, createRef, PureComponent } from 'react';

options: PropTypes.shape({
boundary: PropTypes.node,
centerIfNeeded: PropTypes.bool,
duration: PropTypes.number,
easing: PropTypes.oneOf(['ease', 'easeIn', 'easeOut', 'easeInOut', 'linear']),
offset: PropTypes.shape({
top: PropTypes.number,
right: PropTypes.number,
bottom: PropTypes.number,
left: PropTypes.number
})
behavior: PropTypes.oneOfType([PropTypes.oneOf(['auto', 'smooth', 'instant']), PropTypes.func]),
block: PropTypes.oneOf(['center', 'end', 'nearest', 'start']),
inline: PropTypes.oneOf(['center', 'end', 'nearest', 'start']),
scrollMode: PropTypes.oneOf(['always', 'if-needed']),
boundary: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
})

@@ -156,4 +151,4 @@ };

options: {
duration: 250,
easing: 'easeOut'
behavior: 'smooth',
scrollMode: 'if-needed'
}

@@ -160,0 +155,0 @@ };

@@ -9,361 +9,322 @@ (function (global, factory) {

/**
* https://github.com/gre/bezier-easing
* BezierEasing - use bezier curve for transition easing function
* by Gaëtan Renaudeau 2014 - 2015 – MIT License
*/
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
// These values are established by empiricism with tests (tradeoff: performance VS precision)
var NEWTON_ITERATIONS = 4;
var NEWTON_MIN_SLOPE = 0.001;
var SUBDIVISION_PRECISION = 0.0000001;
var SUBDIVISION_MAX_ITERATIONS = 10;
var isElement = function isElement(el) {
return el != null && typeof el == 'object' && el.nodeType === 1;
};
var kSplineTableSize = 11;
var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
var hasScrollableSpace = function hasScrollableSpace(el, axis) {
if (axis === 'Y') {
return el.clientHeight < el.scrollHeight;
}
var float32ArraySupported = typeof Float32Array === 'function';
if (axis === 'X') {
return el.clientWidth < el.scrollWidth;
}
function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
function C (aA1) { return 3.0 * aA1; }
return false;
};
// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
var canOverflow = function canOverflow(el, axis) {
var overflowValue = window.getComputedStyle(el, null)['overflow' + axis];
return overflowValue !== 'visible' && overflowValue !== 'clip';
};
// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
var isScrollable = function isScrollable(el) {
return hasScrollableSpace(el, 'Y') && canOverflow(el, 'Y') || hasScrollableSpace(el, 'X') && canOverflow(el, 'X');
};
function binarySubdivide (aX, aA, aB, mX1, mX2) {
var currentX, currentT, i = 0;
do {
currentT = aA + (aB - aA) / 2.0;
currentX = calcBezier(currentT, mX1, mX2) - aX;
if (currentX > 0.0) {
aB = currentT;
} else {
aA = currentT;
}
} while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
return currentT;
}
var alignNearest = function alignNearest(scrollingEdgeStart, scrollingEdgeEnd, scrollingSize, elementEdgeStart, elementEdgeEnd, elementSize) {
if (elementEdgeStart < scrollingEdgeStart && elementEdgeEnd > scrollingEdgeEnd || elementEdgeStart > scrollingEdgeStart && elementEdgeEnd < scrollingEdgeEnd) {
return 0;
}
function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
var currentSlope = getSlope(aGuessT, mX1, mX2);
if (currentSlope === 0.0) {
return aGuessT;
}
var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
aGuessT -= currentX / currentSlope;
}
return aGuessT;
}
if (elementEdgeStart < scrollingEdgeStart && elementSize < scrollingSize || elementEdgeEnd > scrollingEdgeEnd && elementSize > scrollingSize) {
return elementEdgeStart - scrollingEdgeStart;
}
var src = function bezier (mX1, mY1, mX2, mY2) {
if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
throw new Error('bezier x values must be in [0, 1] range');
if (elementEdgeEnd > scrollingEdgeEnd && elementSize < scrollingSize || elementEdgeStart < scrollingEdgeStart && elementSize > scrollingSize) {
return elementEdgeEnd - scrollingEdgeEnd;
}
// Precompute samples table
var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
if (mX1 !== mY1 || mX2 !== mY2) {
for (var i = 0; i < kSplineTableSize; ++i) {
sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
}
return 0;
};
var compute = (function (target, options) {
if (options === void 0) {
options = {};
}
function getTForX (aX) {
var intervalStart = 0.0;
var currentSample = 1;
var lastSample = kSplineTableSize - 1;
var _scrollMode$block$inl = _extends({
scrollMode: 'always',
block: 'center',
inline: 'nearest'
}, options),
scrollMode = _scrollMode$block$inl.scrollMode,
block = _scrollMode$block$inl.block,
inline = _scrollMode$block$inl.inline,
boundary = _scrollMode$block$inl.boundary;
for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
intervalStart += kSampleStepSize;
var checkBoundary = typeof boundary == 'function' ? boundary : function (parent) {
return parent !== boundary;
};
if (!isElement(target)) {
throw new Error('Element is required in scrollIntoView');
}
var targetRect = target.getBoundingClientRect();
var viewport = document.documentElement;
var frames = [];
var parent;
while (isElement(parent = target.parentNode) && checkBoundary(target)) {
if (isScrollable(parent) || parent === viewport) {
frames.push(parent);
}
--currentSample;
// Interpolate to provide an initial guess for t
var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
var guessForT = intervalStart + dist * kSampleStepSize;
target = parent;
}
var initialSlope = getSlope(guessForT, mX1, mX2);
if (initialSlope >= NEWTON_MIN_SLOPE) {
return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
} else if (initialSlope === 0.0) {
return guessForT;
} else {
return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
var viewportWidth = window.visualViewport ? window.visualViewport.width : viewport.clientWidth;
var viewportHeight = window.visualViewport ? window.visualViewport.height : viewport.clientHeight;
var viewportX = window.scrollX || window.pageXOffset;
var viewportY = window.scrollY || window.pageYOffset;
if (scrollMode === 'if-needed') {
var isVisible = frames.every(function (frame) {
var frameRect = frame.getBoundingClientRect();
if (targetRect.top < frameRect.top) {
return false;
}
if (targetRect.bottom > frameRect.bottom) {
return false;
}
if (frame === viewport) {
if (targetRect.bottom > viewportHeight) {
return false;
}
if (targetRect.left > viewportWidth) {
return false;
}
}
return true;
});
if (isVisible) {
return [];
}
}
return function BezierEasing (x) {
if (mX1 === mY1 && mX2 === mY2) {
return x; // linear
var targetBlock;
var targetInline;
var computations = frames.map(function (frame) {
var frameRect = frame.getBoundingClientRect();
var blockScroll = 0;
var inlineScroll = 0;
if (block === 'start') {
if (!targetBlock) {
targetBlock = targetRect.top;
}
if (viewport === frame) {
blockScroll = viewportY + targetBlock;
} else {
var offset = Math.min(targetBlock - frameRect.top, frame.scrollHeight - frame.clientHeight - frame.scrollTop);
blockScroll = frame.scrollTop + offset;
targetBlock -= blockScroll - frame.scrollTop;
}
}
// Because JavaScript number are imprecise, we should guarantee the extremes are right.
if (x === 0) {
return 0;
if (block === 'center') {
if (!targetBlock) {
targetBlock = targetRect.top + targetRect.height / 2;
}
if (viewport === frame) {
blockScroll = viewportY + targetBlock - frame.clientHeight / 2;
} else {
var _offset = 0 - Math.min(frameRect.top + frameRect.height / 2 - targetBlock, frame.scrollTop);
blockScroll = frame.scrollTop + _offset;
targetBlock += frame.scrollTop - blockScroll;
}
}
if (x === 1) {
return 1;
if (block === 'end') {
if (!targetBlock) {
targetBlock = targetRect.bottom;
}
if (viewport === frame) {
blockScroll = viewportY + targetBlock - frame.clientHeight;
} else {
var _offset2 = 0 - Math.min(frameRect.bottom - targetBlock, frame.scrollTop);
blockScroll = frame.scrollTop + _offset2;
targetBlock += frame.scrollTop - blockScroll;
}
}
return calcBezier(getTForX(x), mY1, mY2);
};
};
var src$1 = /*#__PURE__*/Object.freeze({
default: src,
__moduleExports: src
});
if (block === 'nearest') {
if (!targetBlock) {
targetBlock = targetRect.top;
}
var BezierEasing = ( src$1 && src ) || src$1;
if (viewport === frame) {
var _offset3 = alignNearest(viewportY, viewportY + viewportHeight, viewportHeight, viewportY + targetBlock, viewportY + targetBlock + targetRect.height, targetRect.height);
// Predefined set of animations. Similar to CSS easing functions
var animations = {
ease: BezierEasing(0.25, 0.1, 0.25, 1),
easeIn: BezierEasing(0.42, 0, 1, 1),
easeOut: BezierEasing(0, 0, 0.58, 1),
easeInOut: BezierEasing(0.42, 0, 0.58, 1),
linear: BezierEasing(0, 0, 1, 1)
};
blockScroll = viewportY + _offset3;
} else {
var _offset4 = alignNearest(frameRect.top, frameRect.bottom, frameRect.height, targetBlock, targetBlock + targetRect.height, targetRect.height);
blockScroll = frame.scrollTop + _offset4;
targetBlock -= _offset4;
}
}
var amator = animate;
if (inline === 'start') {
if (!targetInline) {
targetInline = targetRect.left;
}
function animate(source, target, options) {
var start= Object.create(null);
var diff = Object.create(null);
options = options || {};
// We let clients specify their own easing function
var easing = (typeof options.easing === 'function') ? options.easing : animations[options.easing];
if (viewport === frame) {
inlineScroll = viewportX + targetInline;
} else {
var _offset5 = Math.min(targetInline - frameRect.left, frame.scrollHeight - frame.clientLeft - frame.scrollLeft);
// if nothing is specified, default to ease (similar to CSS animations)
if (!easing) {
if (options.easing) {
console.warn('Unknown easing function in amator: ' + options.easing);
inlineScroll = frame.scrollLeft + _offset5;
targetInline -= inlineScroll - frame.scrollLeft;
}
}
easing = animations.ease;
}
var step = typeof options.step === 'function' ? options.step : noop;
var done = typeof options.done === 'function' ? options.done : noop;
if (inline === 'center') {
if (!targetInline) {
targetInline = targetRect.left + targetRect.width / 2;
}
var scheduler = getScheduler(options.scheduler);
if (viewport === frame) {
inlineScroll = viewportX + targetInline - frame.clientWidth / 2;
} else {
var _offset6 = 0 - Math.min(frameRect.left + frameRect.width / 2 - targetInline, frame.scrollLeft);
var keys = Object.keys(target);
keys.forEach(function(key) {
start[key] = source[key];
diff[key] = target[key] - source[key];
});
inlineScroll = frame.scrollLeft + _offset6;
targetInline += frame.scrollLeft - inlineScroll;
}
}
var durationInMs = options.duration || 400;
var durationInFrames = Math.max(1, durationInMs * 0.06); // 0.06 because 60 frames pers 1,000 ms
var previousAnimationId;
var frame = 0;
if (inline === 'end') {
if (!targetInline) {
targetInline = targetRect.right;
}
previousAnimationId = scheduler.next(loop);
if (viewport === frame) {
inlineScroll = viewportX + targetInline - frame.clientWidth;
} else {
var _offset7 = 0 - Math.min(frameRect.right - targetInline, frame.scrollLeft);
return {
cancel: cancel
}
inlineScroll = frame.scrollLeft + _offset7;
targetInline += frame.scrollLeft - inlineScroll;
}
}
function cancel() {
scheduler.cancel(previousAnimationId);
previousAnimationId = 0;
}
if (inline === 'nearest') {
if (!targetInline) {
targetInline = targetRect.left;
}
function loop() {
var t = easing(frame/durationInFrames);
frame += 1;
setValues(t);
if (frame <= durationInFrames) {
previousAnimationId = scheduler.next(loop);
step(source);
} else {
previousAnimationId = 0;
setTimeout(function() { done(source); }, 0);
if (viewport === frame) {
var _offset8 = alignNearest(viewportX, viewportX + viewportWidth, viewportWidth, viewportX + targetInline, viewportX + targetInline + targetRect.width, targetRect.width);
inlineScroll = viewportX + _offset8;
} else {
var _offset9 = alignNearest(frameRect.left, frameRect.right, frameRect.width, targetInline, targetInline + targetRect.width, targetRect.width);
inlineScroll = frame.scrollLeft + _offset9;
targetInline -= _offset9;
}
}
}
function setValues(t) {
keys.forEach(function(key) {
source[key] = diff[key] * t + start[key];
});
}
}
return {
el: frame,
top: blockScroll,
left: inlineScroll
};
});
return computations;
});
function noop() { }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function getScheduler(scheduler) {
if (!scheduler) {
var canRaf = typeof window !== 'undefined' && window.requestAnimationFrame;
return canRaf ? rafScheduler() : timeoutScheduler()
function _extends$1() { _extends$1 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
var supportsScrollBehavior;
var scrollIntoViewIfNeeded = (function (target, maybeOptions) {
if (maybeOptions === void 0) {
maybeOptions = true;
}
if (typeof scheduler.next !== 'function') throw new Error('Scheduler is supposed to have next(cb) function')
if (typeof scheduler.cancel !== 'function') throw new Error('Scheduler is supposed to have cancel(handle) function')
return scheduler
}
var options = {};
function rafScheduler() {
return {
next: window.requestAnimationFrame.bind(window),
cancel: window.cancelAnimationFrame.bind(window)
if (supportsScrollBehavior === undefined) {
supportsScrollBehavior = 'scrollBehavior' in document.documentElement.style;
}
}
function timeoutScheduler() {
return {
next: function(cb) {
return setTimeout(cb, 1000/60)
},
cancel: function (id) {
return clearTimeout(id)
}
if (maybeOptions === true || maybeOptions === null) {
options = {
block: 'start',
inline: 'nearest'
};
} else if (maybeOptions === false) {
options = {
block: 'end',
inline: 'nearest'
};
} else if (maybeOptions === Object(maybeOptions)) {
options = Object.keys(maybeOptions).length === 0 ? {
block: 'start',
inline: 'nearest'
} : _extends$1({
block: 'center',
inline: 'nearest'
}, maybeOptions);
}
}
var __assign = (undefined && undefined.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
var handleScroll = function (parent, _a) {
var scrollLeft = _a.scrollLeft, scrollTop = _a.scrollTop;
parent.scrollLeft = scrollLeft;
parent.scrollTop = scrollTop;
};
function calculate(target, options) {
if (!target || !(target instanceof HTMLElement))
throw new Error('Element is required in scrollIntoViewIfNeeded');
var config = __assign({ handleScroll: handleScroll }, options);
var defaultOffset = { top: 0, right: 0, bottom: 0, left: 0 };
config.offset = config.offset
? __assign({}, defaultOffset, config.offset) : defaultOffset;
function withinBounds(value, min, max, extent) {
if (config.centerIfNeeded === false ||
(max <= value + extent && value <= min + extent)) {
return Math.min(max, Math.max(min, value));
}
else {
return (min + max) / 2;
}
}
var offset = config.offset;
var offsetTop = offset.top;
var offsetLeft = offset.left;
var offsetBottom = offset.bottom;
var offsetRight = offset.right;
function makeArea(left, top, width, height) {
return {
left: left + offsetLeft,
top: top + offsetTop,
width: width,
height: height,
right: left + offsetLeft + width + offsetRight,
bottom: top + offsetTop + height + offsetBottom,
translate: function (x, y) {
return makeArea(x + left + offsetLeft, y + top + offsetTop, width, height);
},
relativeFromTo: function (lhs, rhs) {
var newLeft = left + offsetLeft, newTop = top + offsetTop;
lhs = lhs.offsetParent;
rhs = rhs.offsetParent;
if (lhs === rhs) {
return area;
}
for (; lhs; lhs = lhs.offsetParent) {
newLeft += lhs.offsetLeft + lhs.clientLeft;
newTop += lhs.offsetTop + lhs.clientTop;
}
for (; rhs; rhs = rhs.offsetParent) {
newLeft -= rhs.offsetLeft + rhs.clientLeft;
newTop -= rhs.offsetTop + rhs.clientTop;
}
return makeArea(newLeft, newTop, width, height);
},
};
}
var parent, area = makeArea(target.offsetLeft, target.offsetTop, target.offsetWidth, target.offsetHeight);
while ((parent = target.parentNode) instanceof HTMLElement &&
target !== config.boundary) {
var clientLeft = parent.offsetLeft + parent.clientLeft;
var clientTop = parent.offsetTop + parent.clientTop;
// Make area relative to parent's client area.
area = area
.relativeFromTo(target, parent)
.translate(-clientLeft, -clientTop);
var scrollLeft = withinBounds(parent.scrollLeft, area.right - parent.clientWidth, area.left, parent.clientWidth);
var scrollTop = withinBounds(parent.scrollTop, area.bottom - parent.clientHeight, area.top, parent.clientHeight);
// Pass the new coordinates to the handleScroll callback
config.handleScroll(parent, { scrollLeft: scrollLeft, scrollTop: scrollTop }, config);
// Determine actual scroll amount by reading back scroll properties.
area = area.translate(clientLeft - parent.scrollLeft, clientTop - parent.scrollTop);
target = parent;
}
}
var _options = options,
_options$behavior = _options.behavior,
behavior = _options$behavior === void 0 ? 'auto' : _options$behavior,
computeOptions = _objectWithoutProperties(_options, ["behavior"]);
var __assign$1 = (undefined && undefined.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
var instructions = compute(target, computeOptions);
if (typeof behavior == 'function') {
return behavior(instructions);
}
instructions.forEach(function (_ref) {
var el = _ref.el,
top = _ref.top,
left = _ref.left;
if (el.scroll && supportsScrollBehavior) {
el.scroll({
top: top,
left: left,
behavior: behavior
});
} else {
if (el === document.documentElement) {
window.scrollTo(left, top);
} else {
el.scrollTop = top;
el.scrollLeft = left;
}
}
return t;
};
var handleScroll$1 = function (parent, _a, config) {
var scrollLeft = _a.scrollLeft, scrollTop = _a.scrollTop;
if (config.duration) {
amator(parent, {
scrollLeft: scrollLeft,
scrollTop: scrollTop,
}, { duration: config.duration, easing: config.easing });
}
else {
parent.scrollLeft = scrollLeft;
parent.scrollTop = scrollTop;
}
};
function isBoolean(options) {
return typeof options === 'boolean';
}
function scrollIntoViewIfNeeded(target, options, animateOptions, finalElement, offsetOptions) {
if (offsetOptions === void 0) { offsetOptions = {}; }
if (!target || !(target instanceof HTMLElement))
throw new Error('Element is required in scrollIntoViewIfNeeded');
var config = { centerIfNeeded: false, handleScroll: handleScroll$1 };
if (isBoolean(options)) {
config.centerIfNeeded = options;
}
else {
config = __assign$1({}, config, options);
}
var defaultOffset = { top: 0, right: 0, bottom: 0, left: 0 };
config.offset = config.offset
? __assign$1({}, defaultOffset, config.offset) : defaultOffset;
if (animateOptions) {
config.duration = animateOptions.duration;
config.easing = animateOptions.easing;
}
if (finalElement) {
config.boundary = finalElement;
}
if (offsetOptions.offsetTop) {
config.offset.top = offsetOptions.offsetTop;
}
if (offsetOptions.offsetRight) {
config.offset.right = offsetOptions.offsetRight;
}
if (offsetOptions.offsetBottom) {
config.offset.bottom = offsetOptions.offsetBottom;
}
if (offsetOptions.offsetLeft) {
config.offset.left = offsetOptions.offsetLeft;
}
return calculate(target, config);
}
});
});

@@ -394,3 +355,3 @@ var classCallCheck = function (instance, Constructor) {

var _extends = Object.assign || function (target) {
var _extends$2 = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {

@@ -493,3 +454,3 @@ var source = arguments[i];

return react.createElement(elementType, _extends({ ref: this.node }, wrapperProps), children);
return react.createElement(elementType, _extends$2({ ref: this.node }, wrapperProps), children);
}

@@ -506,12 +467,7 @@ }]);

options: PropTypes.shape({
boundary: PropTypes.node,
centerIfNeeded: PropTypes.bool,
duration: PropTypes.number,
easing: PropTypes.oneOf(['ease', 'easeIn', 'easeOut', 'easeInOut', 'linear']),
offset: PropTypes.shape({
top: PropTypes.number,
right: PropTypes.number,
bottom: PropTypes.number,
left: PropTypes.number
})
behavior: PropTypes.oneOfType([PropTypes.oneOf(['auto', 'smooth', 'instant']), PropTypes.func]),
block: PropTypes.oneOf(['center', 'end', 'nearest', 'start']),
inline: PropTypes.oneOf(['center', 'end', 'nearest', 'start']),
scrollMode: PropTypes.oneOf(['always', 'if-needed']),
boundary: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
})

@@ -523,4 +479,4 @@ };

options: {
duration: 250,
easing: 'easeOut'
behavior: 'smooth',
scrollMode: 'if-needed'
}

@@ -527,0 +483,0 @@ };

@@ -144,12 +144,7 @@ (function (global, factory) {

options: PropTypes.shape({
boundary: PropTypes.node,
centerIfNeeded: PropTypes.bool,
duration: PropTypes.number,
easing: PropTypes.oneOf(['ease', 'easeIn', 'easeOut', 'easeInOut', 'linear']),
offset: PropTypes.shape({
top: PropTypes.number,
right: PropTypes.number,
bottom: PropTypes.number,
left: PropTypes.number
})
behavior: PropTypes.oneOfType([PropTypes.oneOf(['auto', 'smooth', 'instant']), PropTypes.func]),
block: PropTypes.oneOf(['center', 'end', 'nearest', 'start']),
inline: PropTypes.oneOf(['center', 'end', 'nearest', 'start']),
scrollMode: PropTypes.oneOf(['always', 'if-needed']),
boundary: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
})

@@ -161,4 +156,4 @@ };

options: {
duration: 250,
easing: 'easeOut'
behavior: 'smooth',
scrollMode: 'if-needed'
}

@@ -165,0 +160,0 @@ };

{
"name": "react-scroll-into-view-if-needed",
"version": "1.0.3",
"version": "2.0.0",
"description": "A thin component wrapper around scroll-into-view-if-needed",

@@ -23,3 +23,3 @@ "main": "dist/umd/index.js",

"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-core": "^6.26.3",
"babel-eslint": "^8.2.3",

@@ -31,3 +31,3 @@ "babel-jest": "^22.4.3",

"babel-preset-stage-2": "^6.24.1",
"coveralls": "^3.0.0",
"coveralls": "^3.0.1",
"cross-env": "^5.1.4",

@@ -45,7 +45,7 @@ "enzyme": "^3.3.0",

"react-dom": "^16.3.2",
"rollup": "^0.58.1",
"rollup-plugin-babel": "^3.0.3",
"rollup-plugin-commonjs": "^9.1.0",
"rollup": "^0.58.2",
"rollup-plugin-babel": "^3.0.4",
"rollup-plugin-commonjs": "^9.1.3",
"rollup-plugin-node-resolve": "^3.3.0",
"scroll-into-view-if-needed": "^1.5.0"
"scroll-into-view-if-needed": "^2.1.5"
},

@@ -52,0 +52,0 @@ "scripts": {

@@ -32,12 +32,12 @@ [![Build Status](https://travis-ci.org/icd2k3/react-scroll-into-view-if-needed.svg?branch=master)](https://travis-ci.org/icd2k3/react-scroll-into-view-if-needed)

The standalone version does _not_ come bundled with [scroll-into-view-if-needed](https://www.npmjs.com/package/scroll-into-view-if-needed). Use this version if you'd like to maintain your own dependency for scroll-into-view-if-needed.
The standalone version does **not** come bundled with [scroll-into-view-if-needed](https://www.npmjs.com/package/scroll-into-view-if-needed). Use this version if you'd like to maintain your own dependency for scroll-into-view-if-needed, or if you're already using scroll-into-view-if-needed in other areas of your project.
ES version:
**ES version:**
`import ScrollIntoViewIfNeeded from 'react-scroll-into-view-if-needed/dist/es/standalone.js'`
UMD version:
**UMD version:**
`import ScrollIntoViewIfNeeded from 'react-scroll-into-view-if-needed/dist/umd/standalone.js'`
## Optional Props
#### active

@@ -49,2 +49,43 @@ > Type: `boolean`

```js
class Example extends React.PureComponent {
constructor(props) {
super(props);
this.state = { active: false };
}
handleScrollToggle = () => this.setState({ active: !this.state.active });
render() {
const { active } = this.state;
return (
<div>
<button onClick={this.handleScrollToggle}>Scroll</button>
<div style={{ paddingTop: 2000 }}>
<ScrollIntoViewIfNeeded active={active}>
<div>Hello</div>
</ScrollIntoViewIfNeeded>
</div>
</div>
);
}
}
```
#### options
> Type: `object`
> Default: `{ behavior: 'smooth', scrollMode: 'if-needed' }`
> Full list of options [here](https://www.npmjs.com/package/scroll-into-view-if-needed#api)
The `options` prop simply passes options to `scroll-into-view-if-needed`. See all the possible options in their [API documentation](https://www.npmjs.com/package/scroll-into-view-if-needed#api).
```js
<ScrollIntoViewIfNeeded options={{
scrollMode: 'always',
}}>
<div>Hello</div>
</ScrollIntoViewIfNeeded>
```
#### elementType

@@ -56,7 +97,14 @@ > Type: `string`

#### options
> Type: `object`
> Default: `{ duration: 250, easing: 'easeOut' }`
```js
<ScrollIntoViewIfNeeded elementType="span">
<div>Hello</div>
</ScrollIntoViewIfNeeded>
```
The `options` prop simply passes options to `scroll-into-view-if-needed`. See all the possible options in their [API documentation](https://www.npmjs.com/package/scroll-into-view-if-needed#api).
#### className, id, etc
You can also pass normal element attributes like `className` to the component.
## Upgrading from v1
This project has been updated along with `scroll-into-view-if-needed` and accepts the same `options`. Check out the [migration guide](https://www.npmjs.com/package/scroll-into-view-if-needed#breaking-api-changes-from-v1) over there!

@@ -18,4 +18,4 @@ import React from 'react';

expect(mockScroll).toHaveBeenCalledWith(null, {
duration: 250,
easing: 'easeOut',
behavior: 'smooth',
scrollMode: 'if-needed',
});

@@ -75,3 +75,3 @@ });

shallow(
<ScrollIntoViewIfNeeded options={{ centerIfNeeded: true }}>
<ScrollIntoViewIfNeeded options={{ block: 'center' }}>
<MockChild />

@@ -81,3 +81,3 @@ </ScrollIntoViewIfNeeded>,

expect(mockScroll).toHaveBeenLastCalledWith(null, { centerIfNeeded: true });
expect(mockScroll).toHaveBeenLastCalledWith(null, { block: 'center' });
});

@@ -13,18 +13,30 @@ import { createElement, createRef, PureComponent } from 'react';

options: PropTypes.shape({
boundary: PropTypes.node,
centerIfNeeded: PropTypes.bool,
duration: PropTypes.number,
easing: PropTypes.oneOf([
'ease',
'easeIn',
'easeOut',
'easeInOut',
'linear',
behavior: PropTypes.oneOfType([
PropTypes.oneOf([
'auto',
'smooth',
'instant',
]),
PropTypes.func,
]),
offset: PropTypes.shape({
top: PropTypes.number,
right: PropTypes.number,
bottom: PropTypes.number,
left: PropTypes.number,
}),
block: PropTypes.oneOf([
'center',
'end',
'nearest',
'start',
]),
inline: PropTypes.oneOf([
'center',
'end',
'nearest',
'start',
]),
scrollMode: PropTypes.oneOf([
'always',
'if-needed',
]),
boundary: PropTypes.oneOfType([
PropTypes.element,
PropTypes.func,
]),
}),

@@ -37,4 +49,4 @@ };

options: {
duration: 250,
easing: 'easeOut',
behavior: 'smooth',
scrollMode: 'if-needed',
},

@@ -41,0 +53,0 @@ };

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc