Skip to content

Commit

Permalink
* Added window undefined check for potential build-breaking issues.
Browse files Browse the repository at this point in the history
* Refined the isActiveElement.
* Added findDOMNode instead of the pure element to fix a bug where it returned a not working reference.
* Added position relative as standard css to the container to catch the is active elements.
* Added offset to the scrolling, default 10px.
* Updated readme.
* Version 1.2.0 > 1.2.1.
  • Loading branch information
Eward Somers committed May 29, 2018
1 parent 32d2a67 commit b70a9a8
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 31 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ A simple scrolling container for react.
| ExtraClass | String | Extra classname(s) to be added to the container div. |
| TopScroll | Bool | Should container detect the currently active top element. |
| TopScrollCallback | Func | Callback which provides the new active element. |
| TopScrollOffset | Number | This is a small offset for the active scrolling detection, default is 10 pixels. |

#### ScrollTo

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-simple-scroll-container",
"version": "1.2.0",
"version": "1.2.1",
"description": "A simple scroll container for React.",
"main": "lib/index.js",
"module": "es/index.js",
Expand Down
49 changes: 29 additions & 20 deletions src/components/ScrollContainer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,35 @@ class ScrollContainer extends React.Component {

elements = {};

handleScroll = (e) => {
// This should be updated to handle the detection when a scroll element is on top

getActiveElement = () => {
let result = this.state.activeElement;
const containerScrollTop = this.container.scrollTop;
const containerOffset = this.container.offsetHeight;

Object.keys(this.elements).map(key => {
const element = this.elements[key];
const remainingDistanceToTop = element.offsetTop - ((containerOffset + containerScrollTop) + element.offsetHeight /2);

if( remainingDistanceToTop < 0) {
// Do the call back with the active id
if(this.state.activeElement !== key) {
this.setState({
activeElement: key
});
this.props.topScrollCallback(key);


Object.keys(this.elements).forEach(key => {
const element = findDOMNode(this.elements[key]);
// if offset height === 0, the element is empty
if (element.offsetHeight !== 0) {
const isActive =
containerScrollTop >= element.offsetTop - this.props.topScrollOffset &&
containerScrollTop <= element.offsetHeight + element.offsetTop;

if (isActive) {
result = key
}
}
})
});
return result
};

handleScroll = e => {
const activeElement = this.getActiveElement();
if (this.state.activeElement !== activeElement) {
console.log('active!');
// Do the call back with the active id
this.setState({
activeElement: activeElement,
});
this.props.topScrollCallback(activeElement)
}
};

getNode = (name) => {
Expand All @@ -61,7 +68,7 @@ class ScrollContainer extends React.Component {
render() {
return (
<div
style={{overflowY: 'scroll', ...this.props.extraStyle}}
style={{overflowY: 'scroll', position: 'relative', ...this.props.extraStyle}}
id={this.props.containerId}
className={this.props.extraClassName}
onScroll={this.props.topScroll ? this.handleScroll : () => null}
Expand All @@ -76,6 +83,7 @@ ScrollContainer.defaultProps = {
containerId: '',
topScroll: false,
topScrollCallback: () => null,
topScrollOffset: 10,
extraStyle: {},
extraClassName: ''
};
Expand All @@ -84,6 +92,7 @@ ScrollContainer.propTypes = {
containerId: PropTypes.string,
topScroll: PropTypes.bool,
topScrollCallback: PropTypes.func,
topScrollOffset: PropTypes.number,
extraStyle: PropTypes.object,
extraClassName: PropTypes.string
};
Expand Down
7 changes: 5 additions & 2 deletions src/components/ScrollSection/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@ class ScrollSection extends React.Component {
return React.Children.map(this.props.children, child => {
return React.cloneElement(child, {
onChildHandler: this.props.onChildHandler,
ref: ref => (this._element = ref)
})
})
}

render() {
return <div id={this.props.sectionId}>{this.renderChildren()}</div>
return (
<div id={this.props.sectionId} ref={ref => (this._element = ref)}>
{this.renderChildren()}
</div>
)
}
}

Expand Down
18 changes: 10 additions & 8 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import scrollIntoView from 'scroll-into-view'
import ScrollSection from './components/ScrollSection/index'
import ScrollContainer from './components/ScrollContainer/index'

window.findReactComponent = function(el) {
for (const key in el) {
if (key.startsWith('__reactInternalInstance$')) {
const fiberNode = el[key];
if (typeof window !== 'undefined') {
window.findReactComponent = function (el) {
for (const key in el) {
if (key.startsWith('__reactInternalInstance$')) {
const fiberNode = el[key];

return fiberNode && fiberNode.return && fiberNode.return.stateNode;
return fiberNode && fiberNode.return && fiberNode.return.stateNode;
}
}
}
return null;
};
return null;
};
}

const ScrollTo = (sectionId, containerId = null, offset = 0, speed = 500) => {
let node = null;
Expand Down

0 comments on commit b70a9a8

Please sign in to comment.