use-click-away
shadcn-hooks/use-click-awayFreeHook
A hook to click away from an element
Install it
npx shadcn@latest add https://shadcn-hooks.com/r/use-click-away.jsonSource
1import { useEffectWithTarget } from '@/registry/hooks/use-effect-with-target'2import { useLatest } from '@/registry/hooks/use-latest'3import { getTargetElement } from '@/registry/lib/create-effect-with-target'4import type { BasicTarget } from '@/registry/lib/create-effect-with-target'56type DocumentEventKey = keyof DocumentEventMap78declare type TargetValue<T> = T | undefined | null910const checkIfAllInShadow = (targets: BasicTarget[]) => {11 return targets.every((item) => {12 const targetElement = getTargetElement(item)13 if (!targetElement) {14 return false15 }16 if (targetElement.getRootNode() instanceof ShadowRoot) {17 return true18 }19 return false20 })21}2223const getShadow = (node: TargetValue<Element>) => {24 if (!node) {25 return document26 }27 return node.getRootNode()28}2930const getDocumentOrShadow = (31 target: BasicTarget | BasicTarget[],32): Document | Node => {33 if (!target || !document.getRootNode) {34 return document35 }3637 const targets = Array.isArray(target) ? target : [target]3839 if (checkIfAllInShadow(targets)) {40 return getShadow(getTargetElement(targets[0]))41 }4243 return document44}4546export function useClickAway<T extends Event = Event>(47 onClickAway: (event: T) => void,48 target: BasicTarget | BasicTarget[],49 eventName: DocumentEventKey | DocumentEventKey[] = 'click',50) {51 const onClickAwayRef = useLatest(onClickAway)5253 useEffectWithTarget(54 () => {55 const handler = (event: any) => {56 const targets = Array.isArray(target) ? target : [target]57 if (58 targets.some((item) => {59 const targetElement = getTargetElement(item)60 return !targetElement || targetElement.contains(event.target)61 })62 ) {63 return64 }65 onClickAwayRef.current(event)66 }6768 const documentOrShadow = getDocumentOrShadow(target)6970 const eventNames = Array.isArray(eventName) ? eventName : [eventName]7172 eventNames.forEach((event) =>73 documentOrShadow.addEventListener(event, handler),74 )7576 return () => {77 eventNames.forEach((event) =>78 documentOrShadow.removeEventListener(event, handler),79 )80 }81 },82 Array.isArray(eventName) ? eventName : [eventName],83 target,84 )85}
What it pulls in
Other registry items
Files it writes
More from shadcn-hooks
All 58 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| use-active-elementuse-active-element | shadcn-hooks | Hooks | Free | no deps | |
| use-batteryuse-battery | shadcn-hooks | Hooks | Free | no deps | |
| use-booleanuse-boolean | shadcn-hooks | Hooks | Free | no deps | |
| use-click-any-whereuse-click-any-where | shadcn-hooks | Hooks | Free | no deps | |
| use-clipboarduse-clipboard | shadcn-hooks | Hooks | Free | no deps | |
| use-controllable-valueuse-controllable-value | shadcn-hooks | Hooks | Free | 1 dep | |
| use-counteruse-counter | shadcn-hooks | Hooks | Free | no deps | |
| use-creationuse-creation | shadcn-hooks | Hooks | Free | 1 dep |
