Skip to content

Commit 3e14556

Browse files
authored
Expose intersectionRatio value to callback and render fns (#152)
* Expose intersectionRatio value to callback and render fns * refactor: add intersectionRatio to index.d.ts
1 parent 2eef81c commit 3e14556

File tree

5 files changed

+24
-19
lines changed

5 files changed

+24
-19
lines changed

index.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React = require('react')
22

33
export interface RenderProps {
44
inView: boolean
5+
intersectionRatio: number
56
ref: React.RefObject<any>
67
}
78

@@ -57,7 +58,7 @@ export interface IntersectionObserverProps extends IntersectionOptions {
5758
tag?: string
5859

5960
/** Call this function whenever the in view state changes */
60-
onChange?: (inView: boolean) => void
61+
onChange?: (inView: boolean, intersectionRatio: number) => void
6162
}
6263

6364
export class InView extends React.Component<IntersectionObserverProps, {}> {}

src/__tests__/Observer.test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ it('Should recreate observer when rootMargin change', () => {
138138
it('Should trigger onChange callback', () => {
139139
const onChange = jest.fn()
140140
const wrapper = mount(<Observer onChange={onChange}>{plainChild}</Observer>)
141-
wrapper.instance().handleChange(true)
142-
expect(onChange).toHaveBeenLastCalledWith(true)
143-
wrapper.instance().handleChange(false)
144-
expect(onChange).toHaveBeenLastCalledWith(false)
141+
wrapper.instance().handleChange(true, 1)
142+
expect(onChange).toHaveBeenLastCalledWith(true, 1)
143+
wrapper.instance().handleChange(false, 0)
144+
expect(onChange).toHaveBeenLastCalledWith(false, 0)
145145
})
146146

147147
it('Should unobserve when triggerOnce comes into view', () => {

src/__tests__/intersection.test.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ it('should trigger onChange with ratio 0', () => {
121121
},
122122
])
123123

124-
expect(cb).toHaveBeenCalledWith(true)
124+
expect(cb).toHaveBeenCalledWith(true, 0)
125125
expect(instance.visible).toBe(true)
126126
})
127127

@@ -139,7 +139,7 @@ it('should trigger onChange with multiple thresholds ', () => {
139139
},
140140
])
141141

142-
expect(cb).toHaveBeenCalledWith(true)
142+
expect(cb).toHaveBeenCalledWith(true, 0)
143143
expect(instance.visible).toBe(true)
144144
})
145145

@@ -158,11 +158,11 @@ it('should trigger onChange with isIntersection', () => {
158158
},
159159
])
160160

161-
expect(cb).toHaveBeenCalledWith(true)
161+
expect(cb).toHaveBeenCalledWith(true, 0)
162162
expect(instance.visible).toBe(true)
163163
})
164164

165-
it('should not ensure threshold is 0 if undefined', () => {
165+
it('should ensure threshold is 0 if undefined', () => {
166166
const cb = jest.fn()
167167
const instance = observe(el, cb, { threshold: undefined })
168168
const calls = global.IntersectionObserver.mock.calls
@@ -176,7 +176,7 @@ it('should not ensure threshold is 0 if undefined', () => {
176176
},
177177
])
178178

179-
expect(cb).toHaveBeenCalledWith(true)
179+
expect(cb).toHaveBeenCalledWith(true, 0)
180180
expect(instance.visible).toBe(true)
181181
})
182182

@@ -195,7 +195,7 @@ it('should trigger onChange with isIntersection false', () => {
195195
},
196196
])
197197

198-
expect(cb).toHaveBeenCalledWith(false)
198+
expect(cb).toHaveBeenCalledWith(false, 0)
199199
expect(instance.visible).toBe(false)
200200
})
201201

src/index.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,25 @@ type Props = IntersectionOptions & {
2323
children?:
2424
| (({
2525
inView: boolean,
26+
intersectionRatio?: number,
2627
ref: (node: ?HTMLElement) => void,
2728
}) => React.Node)
2829
| React.Node,
2930
/** @deprecated replace render with children */
3031
render?: ({
3132
inView: boolean,
33+
intersectionRatio?: number,
3234
ref: (node: ?HTMLElement) => void,
3335
}) => React.Node,
3436
/** Element tag to use for the wrapping element when rendering a plain React.Node. Defaults to 'div' */
3537
tag?: string,
3638
/** Call this function whenever the in view state changes */
37-
onChange?: (inView: boolean) => void,
39+
onChange?: (inView: boolean, intersectionRatio: number) => void,
3840
}
3941

4042
type State = {
4143
inView: boolean,
44+
intersectionRatio: number,
4245
}
4346

4447
/**
@@ -58,6 +61,7 @@ export class InView extends React.Component<Props, State> {
5861

5962
state = {
6063
inView: false,
64+
intersectionRatio: 0,
6165
}
6266

6367
componentDidMount() {
@@ -124,10 +128,10 @@ export class InView extends React.Component<Props, State> {
124128
this.observeNode()
125129
}
126130

127-
handleChange = (inView: boolean) => {
128-
this.setState({ inView })
131+
handleChange = (inView: boolean, intersectionRatio: number) => {
132+
this.setState({ inView, intersectionRatio })
129133
if (this.props.onChange) {
130-
this.props.onChange(inView)
134+
this.props.onChange(inView, intersectionRatio)
131135
}
132136
}
133137

@@ -144,11 +148,11 @@ export class InView extends React.Component<Props, State> {
144148
...props
145149
} = this.props
146150

147-
const { inView } = this.state
151+
const { inView, intersectionRatio } = this.state
148152
const renderMethod = children || render
149153

150154
if (typeof renderMethod === 'function') {
151-
return renderMethod({ inView, ref: this.handleNode })
155+
return renderMethod({ inView, intersectionRatio, ref: this.handleNode })
152156
}
153157

154158
return React.createElement(

src/intersection.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @flow
22
import invariant from 'invariant'
33

4-
type Callback = (inView: boolean) => void
4+
type Callback = (inView: boolean, intersectionRatio: number) => void
55

66
type Instance = {
77
callback: Callback,
@@ -155,7 +155,7 @@ function onChange(changes) {
155155
}
156156

157157
instance.visible = inView
158-
instance.callback(inView)
158+
instance.callback(inView, intersectionRatio)
159159
}
160160
})
161161
}

0 commit comments

Comments
 (0)