/react-click-away-listener

:paw_prints: Tiny React Click Away Listener built with React Hooks

Primary LanguageTypeScriptMIT LicenseMIT

~700B React Click Away Listener

npm Coverage Status Test main downloads/month npm bundle size pullrequest firsttimersonly

Installation

npm install react-click-away-listener

or

yarn add react-click-away-listener
  • It's quite small in size! Just Bundlephobia minified, or Bundlephobia minified & gzipp’d.
  • It's built with TypeScript.
  • It works with React Portals (v2.0.0 onwards).
  • It supports mouse, touch and focus events.

Usage

import ClickAwayListener from 'react-click-away-listener';

const App = () => {
	const handleClickAway = () => {
		console.log('Maybe close the popup');
	};

	return (
		<div id="app">
			<ClickAwayListener onClickAway={handleClickAway}>
				<div>
					{' '}
					Triggers whenever a click event is registered outside this div element{' '}
				</div>
			</ClickAwayListener>
		</div>
	);
};

Caveats

v2.0.0 has breaking changes which uses the React.Children.only API.

Thus, the following caveats apply for the children of the <ClickAwayListener> component:

  1. You may pass only one child to the <ClickAwayListener> component.
  2. You may not pass plain text nodes to the <ClickAwayListener> component.

Violating the above caveats will result in the following error:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of `ClickAwayListener`.

If you have multiple child components to pass, you can simply wrap them around a React Fragment like so:

// Assume the `handleClickAway` function is defined.
<ClickAwayListener onClickAway={handleClickAway}>
	<>
		<p>First paragraph</p>
		<button>Example Button</button>
		<p>Second paragraph</p>
	</>
</ClickAwayListener>

Or if you only have text nodes, you can also wrap them in a React Fragment like so:

// Assume the `handleClickAway` function is defined.
<ClickAwayListener onClickAway={handleClickAway}>
	<>First text node Second text node</>
</ClickAwayListener>

Props

Name Type Default Description
onClickAway (event) => void Fires when a user clicks outside the click away component
mouseEvent 'click' |
'mousedown' |
'mouseup'
'click' The mouse event type that gets fired on ClickAway
touchEvent 'touchstart' |
'touchend'
'touchend' The touch event type that gets fired on ClickAway
focusEvent 'focusin' |
'focusout'
'focusin' The focus event type that gets fired on ClickAway

Examples

LICENSE

MIT