Skip to content

Commit

Permalink
added deprecation warning for old offset syntax, and a test for backw…
Browse files Browse the repository at this point in the history
…ards compatibility
  • Loading branch information
joshwnj committed Apr 5, 2017
1 parent 34ffcf6 commit 2e8340d
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 4 deletions.
35 changes: 35 additions & 0 deletions lib/is-visible-with-offset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Tell whether the rect is visible, given an offset
//
// return: boolean
module.exports = function (offset, rect, containmentRect) {
var offsetDir = offset.direction;
var offsetVal = offset.value;

// Rules for checking different kind of offsets. In example if the element is
// 90px below viewport and offsetTop is 100, it is considered visible.
switch (offsetDir) {
case 'top':
return ((containmentRect.top + offsetVal) < rect.top) &&
(containmentRect.bottom > rect.bottom) &&
(containmentRect.left < rect.left) &&
(containmentRect.right > rect.right);

case 'left':
return ((containmentRect.left + offsetVal) < rect.left) &&
(containmentRect.bottom > rect.bottom) &&
(containmentRect.top < rect.top) &&
(containmentRect.right > rect.right);

case 'bottom':
return ((containmentRect.bottom - offsetVal) > rect.bottom) &&
(containmentRect.left < rect.left) &&
(containmentRect.right > rect.right) &&
(containmentRect.top < rect.top);

case 'right':
return ((containmentRect.right - offsetVal) > rect.right) &&
(containmentRect.left < rect.left) &&
(containmentRect.top < rect.top) &&
(containmentRect.bottom > rect.bottom);
}
}
21 changes: 21 additions & 0 deletions tests/visibility-sensor-spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,27 @@ describe('VisibilitySensor', function () {
ReactDOM.render(element, node);
});

it('should be backwards-compatible with old offset config', function (done) {
var firstTime = true;
node.setAttribute('style', 'position:absolute; width:100px; height:100px; top:51px');
var onChange = function (isVisible) {
if(firstTime) {
firstTime = false;
assert.equal(isVisible, true, 'Component starts out visible');
node.setAttribute('style', 'position:absolute; width:100px; height:100px; top:49px');
} else {
assert.equal(isVisible, false, 'Component has moved out of offset area');
done();
}
}

var element = (
<VisibilitySensor onChange={onChange} offset={{direction: 'top', value: 50}} intervalDelay={10} />
);

ReactDOM.render(element, node);
});

it('should work when using offset prop and moving to inside of offset area', function (done) {
var firstTime = true;
node.setAttribute('style', 'position:absolute; width:100px; height:100px; top:49px');
Expand Down
26 changes: 22 additions & 4 deletions visibility-sensor.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

var React = require('react');
var ReactDOM = require('react-dom');
var isVisibleWithOffset = require('./lib/is-visible-with-offset')

var containmentPropType = React.PropTypes.any;

Expand Down Expand Up @@ -46,10 +47,19 @@ module.exports = React.createClass({
React.PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
]),
delayedCall: React.PropTypes.bool,
offset: React.PropTypes.shape({
direction: React.PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
value: React.PropTypes.number
}),
offset: React.PropTypes.oneOfType([
React.PropTypes.shape({
top: React.PropTypes.number,
left: React.PropTypes.number,
bottom: React.PropTypes.number,
right: React.PropTypes.number
}),
// deprecated offset property
React.PropTypes.shape({
direction: React.PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
value: React.PropTypes.number
})
]),
scrollCheck: React.PropTypes.bool,
scrollDelay: React.PropTypes.number,
scrollThrottle: React.PropTypes.number,
Expand Down Expand Up @@ -275,6 +285,14 @@ module.exports = React.createClass({
: partialVisible
}

// Deprecated options for calculating offset.
if (typeof offset.direction === 'string' &&
typeof offset.value === 'number') {
console.warn('[notice] offset.direction and offset.value have been deprecated. They still work for now, but will be removed in next major version. Please upgrade to the new syntax: { %s: %d }', offset.direction, offset.value)

isVisible = isVisibleWithOffset(offset, rect, containmentRect);
}

var state = this.state;
// notify the parent when the value changes
if (this.state.isVisible !== isVisible) {
Expand Down

0 comments on commit 2e8340d

Please sign in to comment.