use-click-outside
Detect click and touch events outside of specified element
Import
Source
Docs
Package
Usage
import { useState } from 'react';import { Paper, Button } from '@mantine/core';import { useClickOutside } from '@mantine/hooks';export function Demo() {const [opened, setOpened] = useState(false);const ref = useClickOutside(() => setOpened(false));return (<><Button onClick={() => setOpened(true)}>Open dropdown</Button>{opened && (<Paper elementRef={ref} shadow="sm"><span>Click outside to close</span></Paper>)}</>);}
API
Hook accepts 3 arguments:
handler
– function that will be called on outside clickevents
– optional list of events that indicate outside clicknodes
- optional list of nodes that should not trigger outside click event
Hook returns React ref object that should be passed to element on which outside clicks should be captured.
import { useClickOutside } from '@mantine/hooks';function Example() {const handleClickOutside = () => console.log('Clicked outside of div');const ref = useClickOutside(handleClickOutside);return <div ref={ref} />;}
Change events
By default use-click-outside listens to mousedown
and touchstart
events,
you can change these events by passing an array of events as second argument:
import { useState } from 'react';import { Paper, Button } from '@mantine/core';import { useClickOutside } from '@mantine/hooks';export function Demo() {const [opened, setOpened] = useState(false);const ref = useClickOutside(() => setOpened(false), ['mouseup', 'touchend']);return (<><Button onClick={() => setOpened(true)}>Open dropdown</Button>{opened && (<Paper elementRef={ref} shadow="sm"><span>Click outside to close</span></Paper>)}</>);}
Multiple nodes
In some cases you may want to trigger outside click event for multiple nodes, for example, when dropdown renders in portal. To do so provide third argument with an array of nodes which should not trigger outside click event:
// Will work only with useState, not useRefimport { useState } from 'react';import { useClickOutside } from '@mantine/hooks';import { Portal } from '@mantine/core';function Demo() {const [dropdown, setDropdown] = useState(null);const [control, setControl] = useState(null);useClickOutside(() => console.log('outside'), null, [control, dropdown]);return (// We cannot use root element ref as it does not contain dropdown<div><div ref={setControl}>Control</div><Portal><div ref={setDropdown}>Dropdown</div></Portal></div>);}
TypeScript
Definition
function useClickOutside<T extends HTMLElement = any>(handler: () => void,events?: string[] | null,nodes?: HTMLElement[]): React.MutableRefObject<T>;
Ref type
By default use-click-outside returns ref object with React.MutableRefObject<any>
type
as ref type does not matter in almost all cases. You can specify ref type by passing a type:
const ref = useClickOutside<HTMLDivElement>(onClickOutside);
Built by Vitaly Rtishchev and these awesome people