Skip to content

Commit c8adda1

Browse files
n-sviridenkoBlagoja Evkoski
authored andcommitted
feat(components): Extend viewport awareness for horizontally scrollable views (#138)
1 parent 978d111 commit c8adda1

File tree

3 files changed

+46
-13
lines changed

3 files changed

+46
-13
lines changed

packages/components/src/viewport/aware/index.js

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ export default WrappedComponent => {
1010
constructor(props, context) {
1111
super(props, context)
1212
this.state = {
13-
componentOffset: null,
13+
componentOffsetX: null,
14+
componentOffsetY: null,
15+
componentWidth: null,
1416
componentHeight: null,
1517
inViewport: false,
1618
}
@@ -35,7 +37,9 @@ export default WrappedComponent => {
3537
if (!this.nodeHandle) return
3638
if (
3739
info.shouldMeasureLayout ||
38-
this.state.componentOffset == null ||
40+
this.state.componentOffsetX == null ||
41+
this.state.componentOffsetY == null ||
42+
this.state.componentWidth == null ||
3943
this.state.componentHeight == null
4044
) {
4145
if (!this._isMounted) return
@@ -45,29 +49,47 @@ export default WrappedComponent => {
4549
() => {},
4650
(offsetX, offsetY, width, height) => {
4751
if (!this._isMounted) return
48-
const inViewport = Utils.isInViewport(
49-
info.viewportOffset,
52+
const inVerticalViewport = Utils.isInViewport(
53+
info.viewportOffsetY,
5054
info.viewportHeight,
5155
offsetY,
5256
height,
5357
this.props.preTriggerRatio
5458
)
59+
const inHorizontalViewport = Utils.isInViewport(
60+
info.viewportOffsetX,
61+
info.viewportWidth,
62+
offsetX,
63+
width,
64+
this.props.preTriggerRatio
65+
)
66+
const inViewport = inVerticalViewport && inHorizontalViewport
5567
this._checkViewportEnterOrLeave(inViewport)
5668
this.setState({
57-
componentOffset: offsetY,
69+
componentOffsetY: offsetY,
70+
componentOffsetX: offsetX,
5871
componentHeight: height,
72+
componentWidth: width,
5973
inViewport,
6074
})
6175
}
6276
)
6377
} else {
64-
const inViewport = Utils.isInViewport(
65-
info.viewportOffset,
78+
const inVerticalViewport = Utils.isInViewport(
79+
info.viewportOffsetY,
6680
info.viewportHeight,
67-
this.state.componentOffset,
81+
this.state.componentOffsetY,
6882
this.state.componentHeight,
6983
this.props.preTriggerRatio
7084
)
85+
const inHorizontalViewport = Utils.isInViewport(
86+
info.viewportOffsetX,
87+
info.viewportWidth,
88+
this.state.componentOffsetX,
89+
this.state.componentWidth,
90+
this.props.preTriggerRatio
91+
)
92+
const inViewport = inVerticalViewport && inHorizontalViewport
7193
if (this._checkViewportEnterOrLeave(inViewport)) {
7294
this.setState({ inViewport })
7395
}

packages/components/src/viewport/tracker/__tests__/tracker.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ describe('ViewportTracker', () => {
2929

3030
expect(cb).toHaveBeenLastCalledWith({
3131
parentHandle: 42,
32-
viewportOffset: 0,
32+
viewportOffsetX: 0,
33+
viewportOffsetY: 0,
3334
viewportHeight: 40,
35+
viewportWidth: 10,
3436
shouldMeasureLayout: true,
3537
})
3638

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

4648
expect(cb).toHaveBeenLastCalledWith({
4749
parentHandle: 42,
48-
viewportOffset: 15,
50+
viewportOffsetX: 10,
51+
viewportOffsetY: 15,
52+
viewportWidth: 10,
4953
viewportHeight: 40,
5054
shouldMeasureLayout: false,
5155
})

packages/components/src/viewport/tracker/index.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ export default class ViewportTracker extends WithEvents(
1212
) {
1313
constructor(props, context) {
1414
super(props, context)
15+
this._viewportWidth = 0
1516
this._viewportHeight = 0
16-
this._viewportOffset = 0
17+
this._viewportOffsetX = 0
18+
this._viewportOffsetY = 0
1719
}
1820

1921
_onRef = ref => {
@@ -26,6 +28,7 @@ export default class ViewportTracker extends WithEvents(
2628
const childOnLayout = React.Children.only(this.props.children).props
2729
.onLayout
2830
childOnLayout && childOnLayout(event)
31+
this._viewportWidth = event.nativeEvent.layout.width
2932
this._viewportHeight = event.nativeEvent.layout.height
3033
this._onViewportChange()
3134
}
@@ -42,16 +45,20 @@ export default class ViewportTracker extends WithEvents(
4245
const childOnScroll = React.Children.only(this.props.children).props
4346
.onScroll
4447
childOnScroll && childOnScroll(event)
45-
this._viewportOffset = event.nativeEvent.contentOffset.y
48+
this._viewportOffsetX = event.nativeEvent.contentOffset.x
49+
this._viewportOffsetY = event.nativeEvent.contentOffset.y
4650
this._onViewportChange(false)
4751
}
4852

4953
_onViewportChange = (shouldMeasureLayout = true) => {
5054
this.nodeHandle &&
55+
this._viewportWidth > 0 &&
5156
this._viewportHeight > 0 &&
5257
this.notifyViewportListeners({
5358
parentHandle: this.nodeHandle,
54-
viewportOffset: this._viewportOffset,
59+
viewportOffsetX: this._viewportOffsetX,
60+
viewportOffsetY: this._viewportOffsetY,
61+
viewportWidth: this._viewportWidth,
5562
viewportHeight: this._viewportHeight,
5663
shouldMeasureLayout,
5764
})

0 commit comments

Comments
 (0)