-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: use clickOutside hooks docs added
- Loading branch information
Showing
2 changed files
with
91 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# useClickOutside | ||
|
||
The `useClickOutside` hook is a custom React hook designed to detect interactions outside a specified HTML element. It is particularly useful for implementing dropdowns, modals, or any UI component that requires closing or reacting to outside clicks or interactions. | ||
|
||
### Props | ||
|
||
- `handler (event: Event) => void`: The callback function that gets triggered when an interaction outside the referenced element is detected.. | ||
- `events EventType[]` (Optional): An array of event types to listen for. Defaults to `['mousedown']`. Supported values: `"mousedown"`, `"mouseup"`, `"touchstart"`, `"touchend"`, `"focusin"`, `"focusout"` | ||
- `listenCapturing boolean` (Optional): Indicates whether event listeners should use the capturing phase. Defaults to true. | ||
|
||
### Returns | ||
|
||
- `RefObject<T>` A React ref object that should be attached to the target HTML element you want to monitor. | ||
|
||
## The Hook | ||
|
||
```ts filename="useClickOutside.ts" copy | ||
import { useIsomorphicEffect } from "hooks/useIsomorphicEffect"; | ||
import { RefObject, useRef } from "react"; | ||
|
||
type EventType = | ||
| "mousedown" | ||
| "mouseup" | ||
| "touchstart" | ||
| "touchend" | ||
| "focusin" | ||
| "focusout"; | ||
|
||
export function useClickOutside<T extends HTMLElement = HTMLElement>( | ||
handler: (event: Event) => void, | ||
events: EventType[] = ["mousedown"], | ||
listenCapturing: boolean = true | ||
): RefObject<T> { | ||
const ref = useRef<T>(null); | ||
|
||
useIsomorphicEffect(() => { | ||
function handleClickOutside(event: Event) { | ||
if (typeof window === "undefined") return; | ||
|
||
if (ref.current && !ref.current.contains(event.target as Node)) { | ||
handler(event); | ||
} | ||
} | ||
|
||
events.forEach((eventType) => { | ||
document.addEventListener(eventType, handleClickOutside, listenCapturing); | ||
}); | ||
|
||
return () => { | ||
events.forEach((eventType) => { | ||
document.removeEventListener( | ||
eventType, | ||
handleClickOutside, | ||
listenCapturing | ||
); | ||
}); | ||
}; | ||
}, [handler, events, listenCapturing]); | ||
|
||
return ref; | ||
} | ||
``` | ||
|
||
## Usage | ||
|
||
```tsx filename="UseClickOutsideDemo.tsx" copy | ||
import React, { useState } from "react"; | ||
import { useClickOutside } from "hooks/useClickOutside"; | ||
|
||
function Dropdown() { | ||
const [isOpen, setIsOpen] = useState(false); | ||
|
||
const ref = useClickOutside<HTMLDivElement>(() => { | ||
setIsOpen(false); // Close the dropdown when clicking outside | ||
}); | ||
|
||
return ( | ||
<div> | ||
<button onClick={() => setIsOpen((prev) => !prev)}> | ||
Toggle Dropdown | ||
</button> | ||
{isOpen && ( | ||
<div ref={ref} style={{ border: "1px solid black", padding: "10px" }}> | ||
<p>Dropdown Content</p> | ||
</div> | ||
)} | ||
</div> | ||
); | ||
} | ||
``` |