Skip to content

React

typescript
import { useIntentClick } from 'intent-click/react';

function DeleteButton() {
    const handleClick = (event: PointerEvent) => {
        // Guaranteed: intentional click
        console.log('Intent click at', event.clientX, event.clientY);
    };

    const ref = useIntentClick<HTMLButtonElement>(handleClick, {
        threshold: 'auto',
        longPressDelay: 500,
        onLongPress: (event) => {
            console.log('Long press detected');
        },
        onIntentCancel: (reason) => {
            console.log('Intent cancelled:', reason);
        },
    });

    return <button ref={ref}>Delete Account</button>;
}

Options

All options are optional:

typescript
interface IntentClickOptions {
    // Movement threshold in CSS pixels. 'auto' = 4px * devicePixelRatio
    threshold?: number | 'auto';

    // Duration in ms after which it's considered a long press
    longPressDelay?: number;

    // Callback when long press is detected
    onLongPress?: (event: PointerEvent) => void;

    // Callback when intent is cancelled (drag, scroll, concurrent pointer)
    onIntentCancel?: (reason: 'drag' | 'scroll' | 'concurrent-pointer' | 'pointercancel' | 'timeout') => void;
}

Important Notes

Memoize Options

When passing an object literal, wrap it in useMemo:

typescript
// ❌ Bad: creates new object on every render
const ref = useIntentClick(handleClick, { threshold: 10 });

// ✅ Good: memoize options
const options = useMemo(() => ({ threshold: 10 }), []);
const ref = useIntentClick(handleClick, options);

Strict Mode

In React Strict Mode, mount/unmount may happen twice in dev. The engine is idempotent to destroy().

Cleanup

Cleanup is automatic when the component unmounts. No need to manually call destroy().