Skip to content

Commit ecdff74

Browse files
saitonakamuraRendez
andcommitted
feat(hooks): Hooks (#131)
* Add useIntersectionObserver hook It has almost the same api and reuses types It has tests and stories Migrate to ts Extracted common types Fixed some type flaws in observer.ts Added myself to AUTHORS * Review fixes * Increase code coverage * Fix storybook import paths for babel transforms Co-authored-by: Luis Merino <[email protected]>
1 parent ba82ef0 commit ecdff74

File tree

27 files changed

+765
-62
lines changed

27 files changed

+765
-62
lines changed

AUTHORS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
Luis Merino <[email protected]>
1+
Luis Merino <[email protected]>
2+
Michael Bashurov <[email protected]>

docs/docs/components/HigherOrderComponent/WithIntersectionObserver.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { Component } from 'react';
2-
import Observer from '../../../..';
2+
import Observer from '../../../../lib/es/src';
33

44
export default (threshold) => (BaseComponent) => {
55
const displayName =

docs/docs/components/Hook/Hook.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React, { useState } from 'react';
2+
import { useIntersectionObserver } from '../../../../lib/es/src';
3+
4+
const Hook = () => {
5+
const [visibility, setVisibility] = useState('invisible');
6+
7+
const handleChange = (entry) => {
8+
setVisibility(entry.isIntersecting ? 'visible' : 'invisible');
9+
};
10+
11+
const [ref] = useIntersectionObserver(handleChange);
12+
13+
return (
14+
<div>
15+
<div className={`header ${visibility}`}>{visibility}</div>
16+
<div className="body">
17+
<div ref={ref} className={`box ${visibility}`} />
18+
</div>
19+
</div>
20+
);
21+
};
22+
23+
export default Hook;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
Basic usage of **useIntersectionObserver** hook that changes the className of
2+
the observed **<div />** element when the visibility changes:
3+
4+
**useIntersectionObserver** have almost the same options as **<Observer />**
5+
element, except **onChange** handler comes as a first argument and every other
6+
option (root, threshold, rootMargin etc.) are second argument
7+
8+
```jsx
9+
import React, { useState } from 'react';
10+
import { useIntersectionObserver } from '@researchgate/react-intersection-observer';
11+
12+
const Hook = () => {
13+
const [visibility, setVisibility] = useState('invisible');
14+
15+
const handleChange = (entry) => {
16+
setVisibility(entry.isIntersecting ? 'visible' : 'invisible');
17+
};
18+
19+
const [ref] = useIntersectionObserver(handleChange, { threshold: 0 });
20+
21+
return (
22+
<div>
23+
<div className={`header ${visibility}`}>{visibility}</div>
24+
<div className="body">
25+
<div ref={ref} className={`box ${visibility}`} />
26+
</div>
27+
</div>
28+
);
29+
};
30+
31+
export default Hook;
32+
```

docs/docs/components/Hook/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import React from 'react';
2+
import withReadme from 'storybook-readme/with-readme';
3+
import Readme from './README.md';
4+
import Hook from './Hook';
5+
6+
export default withReadme(Readme, () => <Hook />);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React, { useState } from 'react';
2+
import { useIntersectionObserver } from '../../../../lib/es/src';
3+
4+
const HookOnlyOnce = () => {
5+
const [visibility, setVisibility] = useState('invisible');
6+
7+
const handleChange = (entry, unobserve) => {
8+
if (entry.isIntersecting) {
9+
setVisibility('visible');
10+
unobserve();
11+
}
12+
};
13+
14+
const [ref] = useIntersectionObserver(handleChange);
15+
16+
return (
17+
<div>
18+
<div className={`header ${visibility}`}>{visibility}</div>
19+
<div className="body">
20+
<div ref={ref} className={`box ${visibility}`} />
21+
</div>
22+
</div>
23+
);
24+
};
25+
26+
export default HookOnlyOnce;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
_Use the second argument of `onChange(event, unobserve)` to customize how you prefer to stop observing the target. You
3+
can also set the prop `disabled: true` in the options to achieve the same effect._
4+
5+
```jsx
6+
import React, { useState } from 'react';
7+
import { useIntersectionObserver } from '@researchgate/react-intersection-observer';
8+
9+
const HookOnlyOnce = () => {
10+
const [visibility, setVisibility] = useState('invisible');
11+
12+
const handleChange = (entry, unobserve) => {
13+
if (entry.isIntersecting) {
14+
setVisibility('visible');
15+
unobserve();
16+
}
17+
};
18+
19+
const [ref] = useIntersectionObserver(handleChange);
20+
21+
return (
22+
<div>
23+
<div className={`header ${visibility}`}>{visibility}</div>
24+
<div className="body">
25+
<div ref={ref} className={`box ${visibility}`} />
26+
</div>
27+
</div>
28+
);
29+
};
30+
31+
export default HookOnlyOnce;
32+
```
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import React from 'react';
2+
import withReadme from 'storybook-readme/with-readme';
3+
import Readme from './README.md';
4+
import HookOnlyOnce from './HookOnlyOnce';
5+
6+
export default withReadme(Readme, () => <HookOnlyOnce />);

docs/docs/components/ImpressionTracking/AdImpression.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33
import { action } from '@storybook/addon-actions';
4-
import Observer from '../../../..';
4+
import Observer from '../../../../lib/es/src';
55

66
const tracked = action('tracked');
77

docs/docs/components/OnlyOnce/OnlyOnce.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { Component } from 'react';
22
import { decorateAction } from '@storybook/addon-actions';
3-
import Observer from '../../../..';
3+
import Observer from '../../../../lib/es/src';
44

55
const storyBookAction = decorateAction([
66
(args) =>

0 commit comments

Comments
 (0)