UNPKG

react-detect-click-outside

Version:

Detects clicks outside React components, and also handles keypresses.

226 lines (151 loc) • 6.7 kB
# react-detect-click-outside A lightweight React hook that detects clicks outside elements and triggers a callback. Can also detect keypresses. šŸ“ˆ&nbsp;&nbsp;Over 7,600 weekly users (as of June 2022). šŸ‘&nbsp;&nbsp;Great for toggling dropdowns! _**Notice:** This package is looking for maintainers! Due to my professional and personal commitments, I don't have a whole lot of time to devote to maintaining this library. Some users have pointed out a few issues in the [Github repo](https://github.com/zhaluza/react-detect-click-outside/issues) - feel free to take a stab at them!_ <!-- TABLE OF CONTENTS --> ## Table of Contents - [Features](#features) - [Installation](#installation) - [Usage](#usage) - [Requirements](#requirements) <!-- ABOUT THE PROJECT --> ### Features - šŸ–± šŸ’»&nbsp;&nbsp;Detects clicks outside an element and/or keypresses. - šŸ”Ø&nbsp;&nbsp;Customizable: disable clicks, disable keypresses, or specify keys that will trigger the callback - šŸŽ£&nbsp;&nbsp;Built with React hooks - šŸ”„&nbsp;&nbsp;Written in TypeScript ### Installation Install with [Yarn](https://yarnpkg.com/): ```sh yarn add react-detect-click-outside ``` Or with [NPM](https://www.npmjs.com/): ```sh npm i react-detect-click-outside ``` Import into your component like so: ```javascript import { useDetectClickOutside } from 'react-detect-click-outside'; ``` <!-- USAGE EXAMPLES --> ## Usage Here's an [example](https://codesandbox.io/s/react-detect-click-outside-example-v2osy) of how to use the hook. This library was built with UI features like dropdowns in mind. Below is a quick and functioning example of how to include it in a dropdown component: ```javascript const Dropdown = ({ closeDropdown }) => { const ref = useDetectClickOutside({ onTriggered: closeDropdown }); return ( <div className="dropdown" ref={ref}> <p>This is a dropdown!</p> </div> ); }; ``` How to implement the hook inside a function component: 1. Assign the hook to a variable before the component's return statement (above we use `ref`). Pass an empty object into the hook as an argument. ```javascript const ref = useDetectClickOutside({}); ``` 2. The object you just passed into the `useDetectClickOutside` hook requires a property called `onTriggered`. The value of `onTriggered` must be a function — by default, it'll be called anytime a user clicks outside the component or hits the `Escape` key. In the example above, we used a function called `closeToggle`. This function is passed down from a parent component (let's call it `Container`) and controls a piece of state that determines whether the `Dropdown` component is visible. Here's a quick, trimmed-down example: ```javascript const Container = () => { const [displayDropdown, setDisplayDropdown] = useState(false); const closeDropdown = () => { setDisplayDropdown(false); } return ( { displayDropdown && <Dropdown/> } ) } ``` Now, go ahead and pass your callback into the `useDetectClickOutside` hook! ```javascript const ref = useDetectClickOutside({ onTriggered: closeDropdown }); ``` 3. Assign your `ref` constant (or whatever constant you assigned the `useDetectClickOutside` hook to) as a ref to the outermost element returned by your target component. ```javascript return ( <div className="dropdown" ref={ref}> <p>This is a dropdown!</p> </div> ); ``` Here's what the whole component should look like now: ```javascript const Dropdown = ({ closeDropdown }) => { const ref = useDetectClickOutside({ onTriggered: closeDropdown }); return ( <div className="dropdown" ref={ref}> <p>This is a dropdown!</p> </div> ); }; ``` Congrats! Your `useDetectClickOutside` should now trigger anytime a user clicks outside your component or presses the `Escape` key. Want to customize your hook? Check out some of the additional options below. ## Options The object passed into the `useDetectClickOutside` hook accepts the following properties. Note that only `onTriggered` is required. ### `onTriggered` (required) #### **Type:** `() => void` A callback function, e.g. one that toggles the visibility of the component. By default, this function is triggered by a click outside the component, and by an `Escape` keyup event. **Example:** ```javascript const ref = useDetectClickOutside({ onTriggered: closeDropdown }); ``` ### `disableClick` (optional) #### **Type:** `boolean` When passed to the hook, this option will prevent clicks from triggering the `onTriggered` callback when the component is in the DOM. This option is disabled by default. **Example:** ```javascript const ref = useDetectClickOutside({ onTriggered: closeDropdown, disableClick: true, }); ``` ### `disableTouch` (optional) #### **Type:** `boolean` When passed to the hook, this option will prevent touch events from triggering the `onTriggered` callback when the component is in the DOM. This option is disabled by default. **Example:** ```javascript const ref = useDetectClickOutside({ onTriggered: closeDropdown, disableTouch: true, }); ``` ### `disableKeys` (optional) #### **Type:** `boolean` This option will prevent keypresses from triggering the `onTriggered` callback when the component is in the DOM. This option is disabled by default. **Example:** ```javascript const ref = useDetectClickOutside({ onTriggered: closeDropdown, disableKeys: true, }); ``` ### `allowAnyKey` (optional) #### **Type:** `boolean` This option will let any keypress trigger the `onTriggered` callback when the component is in the DOM - not just the `Escape` key. This option is disabled by default. **Example:** ```javascript const ref = useDetectClickOutside({ onTriggered: closeDropdown, allowAnyKey: true, }); ``` ### `triggerKeys` (optional) #### **Type:** `string[]` An array of [key values](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) that will trigger the `onTriggered` callback. **Example:** ```javascript const ref = useDetectClickOutside({ onTriggered: closeDropdown, triggerKeys: ['Enter', 'Tab', 'x'], }); ``` _Note:_ This option overrides the default hook behavior of triggering the `onTriggered` callback with the `Escape` key. If you still wish to trigger the `onTriggered` function with `Escape`, you need to add it to the array (e.g. `triggerKeys=['Escape', 'Enter']`). <!-- REQUIREMENTS --> ## Requirements You must be using [React 16.8.0](https://reactjs.org/blog/2019/02/06/react-v16.8.0.html) or later. In other words, your version of React must support hooks.