Appearance
Common Pitfalls
React: Don't pass inline object
typescript
// ❌ Bad: new object on every render
useIntentClick(callback, { threshold: 10 });
// ✅ Good: memoize options
const options = useMemo(() => ({ threshold: 10 }), []);
useIntentClick(callback, options);React: Strict Mode double-mount
In React Strict Mode, mount/unmount happens twice in dev. The engine handles multiple destroy() calls gracefully.
Angular: Options are read once
intentClickOptions input is read in ngOnInit. Changing it later does not recreate the store.
Vue: Directive options changes
Similar to Angular: options passed to v-intent-click are read once on mount.
Ghost click not suppressed
Ghost click suppression only works within the same page. If you navigate away and back, the previous click coords are lost.
Long press fires on non-touch devices
Long press detection works on all devices. If you only want it on touch devices, detect first:
typescript
const isTouchDevice = window.matchMedia('(hover: none)').matches;
const options = {
longPressDelay: isTouchDevice ? 500 : undefined,
onLongPress: isTouchDevice ? handleLongPress : undefined,
};Concurrent pointer not detected
Concurrent pointer detection requires pointerdown on document. If you have a modal with pointer-events: none on the backdrop, events won't bubble.
Not working inside iframe
If pointerdown happens inside a cross-origin iframe and pointerup outside, the cycle is broken. This is a browser security limitation.
TypeScript: useIntentClick type errors
Ensure:
- You're passing a generic type:
useIntentClick<HTMLButtonElement>(...) - Your callback type is
(event: PointerEvent) => void
Event not received
Ensure the element has pointer-events: auto (not none).