Skip to content

Commit ffd512f

Browse files
committed
feat: Add once-option
1 parent 59c1291 commit ffd512f

File tree

9 files changed

+78
-8
lines changed

9 files changed

+78
-8
lines changed

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import { useIsVisible } from "react-is-visible"
6767
const SomeComponent = () => {
6868
const nodeRef = useRef()
6969
const isVisible = useIsVisible(nodeRef)
70+
/* const isVisible = useIsVisible(nodeRef, { once: true }) */
7071

7172
return (
7273
<h1 ref={nodeRef}>
@@ -85,6 +86,7 @@ import { withIsVisible } from "react-is-visible"
8586
const SomeComponent = ({ isVisible }) => <h1>{isVisible && `I'm visible!`}</h1>
8687

8788
export default withIsVisible(SomeComponent)
89+
/* export default withIsVisible(SomeComponent, { once: true }) */
8890
```
8991

9092
or as a decorator
@@ -105,12 +107,14 @@ class SomeClass extends React.Component {
105107

106108
#### [Render Prop](#render-prop)
107109

110+
The `once`-prop is optional, but if passed, the `isVisible`-flag will only trigger once.
111+
108112
```jsx
109113
import React from "react"
110114
import IsVisible from "react-is-visible"
111115

112116
const App = () => (
113-
<IsVisible>
117+
<IsVisible once>
114118
{isVisible => <h1>{isVisible ? `I'm visible!` : `I'm not visible!`}</h1>}
115119
</IsVisible>
116120
)

src/IsVisible.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ class IsVisible extends React.PureComponent {
2525
isVisible: isIntersecting,
2626
})
2727
}
28+
29+
if (isIntersecting && this.props.once) {
30+
this.unwatch()
31+
}
2832
}
2933

3034
render() {

src/__tests__/hook.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const FunctionalComponent = props => {
1515

1616
describe('useIsVisible', () => {
1717
it('renders', () => {
18-
const { getByText, unmount, rerender } = render(
18+
const { getByText, rerender } = render(
1919
<FunctionalComponent>Functional</FunctionalComponent>
2020
)
2121

@@ -25,7 +25,7 @@ describe('useIsVisible', () => {
2525
})
2626

2727
it('passes its state as props to a Functional Component', () => {
28-
const { getByTestId, unmount, rerender } = render(
28+
const { getByTestId, rerender } = render(
2929
<FunctionalComponent>Functional</FunctionalComponent>
3030
)
3131

src/useIsVisible.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,19 @@ import { useEffect, useState } from 'react'
22

33
import VO from './VisibilityObserver'
44

5-
function useIsVisible(nodeRef) {
5+
const defaultOptions = {
6+
once: false,
7+
};
8+
9+
function useIsVisible(nodeRef, { once } = defaultOptions) {
610
const [isVisible, setVisible] = useState(false)
711

812
function handleVisibilityChange({ isIntersecting }) {
913
setVisible(isIntersecting)
14+
15+
if (isIntersecting && once) {
16+
VO.unwatch(nodeRef.current)
17+
}
1018
}
1119

1220
useEffect(() => VO.watch(nodeRef.current, handleVisibilityChange), [

src/withIsVisible.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ import IsVisible from './IsVisible'
77
const getDisplayName = WrappedComponent =>
88
WrappedComponent.displayName || WrappedComponent.name || 'Component'
99

10-
export const withIsVisible = WrappedComponent => {
10+
const defaultOptions = {
11+
once: false,
12+
};
13+
14+
export const withIsVisible = (WrappedComponent, { once } = defaultOptions)=> {
1115
const WithIsVisible = ({ forwardedRef, ...props }) => (
1216
<IsVisible
17+
once={once}
1318
children={isVisible => (
1419
<WrappedComponent {...props} isVisible={isVisible} ref={forwardedRef} />
1520
)}

stories/asHOC.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44

55
**Component definition:**
66

7+
Optionally takes a config-object as a second argument. The currently supported configurations are:
8+
```js
9+
{
10+
once: bool
11+
}
12+
```
13+
714
```jsx
815
import React from 'react'
916
import { withIsVisible } from 'react-is-visible'
@@ -17,6 +24,21 @@ const SomeComponent = ({ isVisible }) => (
1724
export default withIsVisible(SomeComponent)
1825
```
1926

27+
or
28+
29+
```jsx
30+
import React from 'react'
31+
import { withIsVisible } from 'react-is-visible'
32+
33+
const SomeComponent = ({ isVisible }) => (
34+
<h1>
35+
{isVisible && `I'm visible!`}
36+
</h1>
37+
)
38+
39+
export default withIsVisible(SomeComponent, { once: true })
40+
```
41+
2042
------------
2143

2244
**How to use:**

stories/asHook.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44

55
**Component definition:**
66

7+
Optionally takes a config-object as a second argument. The currently supported configurations are:
8+
```
9+
{
10+
once: bool
11+
}
12+
```
13+
714
```jsx
815
import React, { useRef } from 'react'
916
import { useIsVisible } from 'react-is-visible'
@@ -20,6 +27,24 @@ const SomeComponent = () => {
2027
}
2128
```
2229

30+
or
31+
32+
```jsx
33+
import React, { useRef } from 'react'
34+
import { useIsVisible } from 'react-is-visible'
35+
36+
const SomeComponent = () => {
37+
const nodeRef = useRef()
38+
const isVisible = useIsVisible(nodeRef, { once: true })
39+
40+
return (
41+
<h1 ref={nodeRef}>
42+
{isVisible && `I'm visible!`}
43+
</h1>
44+
)
45+
}
46+
```
47+
2348
------------
2449

2550
**How to use:**

stories/asRenderProp.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@
44

55
**How to use:**
66

7+
The `once`-prop is optional, but if passed, the `isVisible`-flag will only trigger once.
8+
79
```jsx
810
import React from 'react'
911
import IsVisible from 'react-is-visible'
1012

1113
const SomeComponent = () => (
12-
<IsVisible>
14+
<IsVisible once>
1315
{isVisible => (
1416
<h1>
1517
{isVisible && `I'm visible!`}
1618
</h1>
1719
)}
1820
</IsVisible>
1921
)
20-
```
22+
```

stories/index.stories.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ storiesOf('React Is Visible', module)
8080
() => (
8181
<div style={wrapperStyling({ height: '200vh' })}>
8282
<h2 style={{ color: 'black', marginBottom: 'auto' }}>Scroll down</h2>
83-
<IsVisible>
83+
<IsVisible once>
8484
{isVisible => (
8585
<FunctionalComponent isVisible={isVisible}>
8686
I'm visible!

0 commit comments

Comments
 (0)