Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Master : Add Intersection Observer Custom Hook #72

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,5 @@ yarn add react-recipes
| 🍷 [`useWhyDidYouUpdate`](./docs/useWhyDidYouUpdate.md) | - | (name, props) |
| 🥖 [`useWindowScroll`](./docs/useWindowScroll.md) | { x, y } | - |
| 🥮 [`useWindowSize`](./docs/useWindowSize.md) | { height, width } | (initialWidth, initialHeight) |
| 🥝 [`useWorker`](./docs/useWorker.md) | worker instance | (scriptPath, workerOptions, attributes) |
| 🥝 [`useWorker`](./docs/useWorker.md) | worker instance | (scriptPath, workerOptions, attributes)
| 👁 [`useIntersectionObserver`](./docs/useWorker.md) | { ref, isContentVisible } | (options) |
38 changes: 38 additions & 0 deletions docs/useIntersectionObserver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# 👁 `useIntersectionObserver`

A React hook to detect when an element becomes visible in the viewport using the Intersection Observer API.

## Arguments

- `options: Object`: Configuration options for the `IntersectionObserver` such as:
- `root: Element`: The element that is used as the viewport for checking visibility of the target (default is `null` for the browser viewport).
- `rootMargin: String`: Margin around the root element (e.g., `'0px'`, `'10px'`).
- `threshold: Number | Array`: A single number or array of numbers which indicate at what percentage of the target's visibility the observer's callback should be executed (e.g., `1.0` means the callback is invoked when 100% of the element is visible)

## Returns

- `[{ containerRef, isContentVisible }]`
- `containerRef: RefObject`: Ref to be attached to the DOM element you want to observe.
- `isContentVisible: Boolean`: Boolean flag indicating whether the element is currently visible in the viewport.
## Usage

```js
import useIntersectionObserver from "react-recipes";

function App() {
const options = {
root: null,
rootMargin: '0px',
threshold: 1.0,
};

const [{ containerRef, isContentVisible }] = useIntersectionObserver({ options });

return (
<div ref={containerRef}>
{isContentVisible ? <div>Load Only When it's visible in viewport Text</div> : null}
</div>
);
}

```
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ export { default as useWhyDidYouUpdate } from './useWhyDidYouUpdate';
export { default as useWindowScroll } from './useWindowScroll';
export { default as useWindowSize } from './useWindowSize';
export { default as useWorker } from './useWorker';
export { default as useIntersectionObserver } from './useIntersectionObserver';
53 changes: 53 additions & 0 deletions src/useIntersectionObserver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { useEffect, useRef, useState } from 'react';

/**
* useWorker hook
*
* @param {Object} options
* @return {Boolean} isContentVisible - Boolean flag
*/
const useIntersectionObserver = ({ options }) => {
const containerRef = useRef(null);
const [isContentVisible, setContentVisible] = useState(false);

//! Callback function of IntersectionObserver Function
const callbackFunction = (element) => {
const [entry] = element;
setContentVisible(entry.isIntersecting);
};

useEffect(() => {
//! Initialize IntersectionObserver and pass a callback function and options
const observer = new IntersectionObserver(callbackFunction, options);

if (containerRef.current) observer.observe(containerRef.current);

return () => {
if (containerRef.current) observer.unobserve(containerRef.current);
};
}, [containerRef, options]);

return [{ containerRef, isContentVisible }];
};

export default useIntersectionObserver;

// usage

// function App() {
// const options = {
// root: null,
// rootMargin: '0px',
// threshold: 1.0,
// };
//
// const [{ containerRef, isContentVisible }] = useIntersectionObserver({ options });

// return (
// <div
// ref={containerRef}
// >
// {isContentVisible ? <div>Load Only When it's visible in viewport Text</div> : null}
// </div>
// )
// }