react-haptic
Version:
React hooks for haptic feedback
52 lines (51 loc) • 1.55 kB
JavaScript
// src/index.ts
import { useCallback, useEffect, useRef } from "react";
var useHaptic = ({
hapticDuration = 100
} = {}) => {
const isBrowser = typeof window !== "undefined";
const labelRef = useRef(null);
const checkIosDevice = () => {
if (!isBrowser) return false;
const ua = navigator.userAgent;
const isIphone = /iPhone|iPod/.test(ua);
const isIpad = /iPad/.test(ua) || /Macintosh/.test(ua) && navigator.maxTouchPoints > 1;
return isIphone || isIpad;
};
const createHiddenSwitch = () => {
const label = document.createElement("label");
const input = document.createElement("input");
label.style.opacity = "0";
label.style.pointerEvents = "none";
label.style.position = "absolute";
label.style.left = "-9999px";
input.type = "checkbox";
input.setAttribute("switch", "");
label.appendChild(input);
return { label };
};
const canVibrate = isBrowser && !checkIosDevice() && Boolean(navigator?.vibrate);
useEffect(() => {
if (!isBrowser) return;
const { label } = createHiddenSwitch();
document.body.appendChild(label);
labelRef.current = label;
return () => {
if (label.parentNode === document.body) {
document.body.removeChild(label);
}
};
}, [isBrowser]);
const vibrate = useCallback(() => {
if (!isBrowser) return;
if (canVibrate) {
navigator.vibrate(hapticDuration);
} else {
labelRef.current?.click();
}
}, [canVibrate, hapticDuration]);
return { vibrate };
};
export {
useHaptic
};