Skip to content

Commit

Permalink
feat(components): Extend viewport awareness for horizontally scrollab…
Browse files Browse the repository at this point in the history
…le views (#138)
  • Loading branch information
n-sviridenko authored and Blagoja Evkoski committed Jul 5, 2019
1 parent 978d111 commit c8adda1
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 13 deletions.
38 changes: 30 additions & 8 deletions packages/components/src/viewport/aware/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ export default WrappedComponent => {
constructor(props, context) {
super(props, context)
this.state = {
componentOffset: null,
componentOffsetX: null,
componentOffsetY: null,
componentWidth: null,
componentHeight: null,
inViewport: false,
}
Expand All @@ -35,7 +37,9 @@ export default WrappedComponent => {
if (!this.nodeHandle) return
if (
info.shouldMeasureLayout ||
this.state.componentOffset == null ||
this.state.componentOffsetX == null ||
this.state.componentOffsetY == null ||
this.state.componentWidth == null ||
this.state.componentHeight == null
) {
if (!this._isMounted) return
Expand All @@ -45,29 +49,47 @@ export default WrappedComponent => {
() => {},
(offsetX, offsetY, width, height) => {
if (!this._isMounted) return
const inViewport = Utils.isInViewport(
info.viewportOffset,
const inVerticalViewport = Utils.isInViewport(
info.viewportOffsetY,
info.viewportHeight,
offsetY,
height,
this.props.preTriggerRatio
)
const inHorizontalViewport = Utils.isInViewport(
info.viewportOffsetX,
info.viewportWidth,
offsetX,
width,
this.props.preTriggerRatio
)
const inViewport = inVerticalViewport && inHorizontalViewport
this._checkViewportEnterOrLeave(inViewport)
this.setState({
componentOffset: offsetY,
componentOffsetY: offsetY,
componentOffsetX: offsetX,
componentHeight: height,
componentWidth: width,
inViewport,
})
}
)
} else {
const inViewport = Utils.isInViewport(
info.viewportOffset,
const inVerticalViewport = Utils.isInViewport(
info.viewportOffsetY,
info.viewportHeight,
this.state.componentOffset,
this.state.componentOffsetY,
this.state.componentHeight,
this.props.preTriggerRatio
)
const inHorizontalViewport = Utils.isInViewport(
info.viewportOffsetX,
info.viewportWidth,
this.state.componentOffsetX,
this.state.componentWidth,
this.props.preTriggerRatio
)
const inViewport = inVerticalViewport && inHorizontalViewport
if (this._checkViewportEnterOrLeave(inViewport)) {
this.setState({ inViewport })
}
Expand Down
8 changes: 6 additions & 2 deletions packages/components/src/viewport/tracker/__tests__/tracker.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ describe('ViewportTracker', () => {

expect(cb).toHaveBeenLastCalledWith({
parentHandle: 42,
viewportOffset: 0,
viewportOffsetX: 0,
viewportOffsetY: 0,
viewportHeight: 40,
viewportWidth: 10,
shouldMeasureLayout: true,
})

Expand All @@ -45,7 +47,9 @@ describe('ViewportTracker', () => {

expect(cb).toHaveBeenLastCalledWith({
parentHandle: 42,
viewportOffset: 15,
viewportOffsetX: 10,
viewportOffsetY: 15,
viewportWidth: 10,
viewportHeight: 40,
shouldMeasureLayout: false,
})
Expand Down
13 changes: 10 additions & 3 deletions packages/components/src/viewport/tracker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ export default class ViewportTracker extends WithEvents(
) {
constructor(props, context) {
super(props, context)
this._viewportWidth = 0
this._viewportHeight = 0
this._viewportOffset = 0
this._viewportOffsetX = 0
this._viewportOffsetY = 0
}

_onRef = ref => {
Expand All @@ -26,6 +28,7 @@ export default class ViewportTracker extends WithEvents(
const childOnLayout = React.Children.only(this.props.children).props
.onLayout
childOnLayout && childOnLayout(event)
this._viewportWidth = event.nativeEvent.layout.width
this._viewportHeight = event.nativeEvent.layout.height
this._onViewportChange()
}
Expand All @@ -42,16 +45,20 @@ export default class ViewportTracker extends WithEvents(
const childOnScroll = React.Children.only(this.props.children).props
.onScroll
childOnScroll && childOnScroll(event)
this._viewportOffset = event.nativeEvent.contentOffset.y
this._viewportOffsetX = event.nativeEvent.contentOffset.x
this._viewportOffsetY = event.nativeEvent.contentOffset.y
this._onViewportChange(false)
}

_onViewportChange = (shouldMeasureLayout = true) => {
this.nodeHandle &&
this._viewportWidth > 0 &&
this._viewportHeight > 0 &&
this.notifyViewportListeners({
parentHandle: this.nodeHandle,
viewportOffset: this._viewportOffset,
viewportOffsetX: this._viewportOffsetX,
viewportOffsetY: this._viewportOffsetY,
viewportWidth: this._viewportWidth,
viewportHeight: this._viewportHeight,
shouldMeasureLayout,
})
Expand Down

0 comments on commit c8adda1

Please sign in to comment.