detect-autofill-react
Version:
React hook to detect browser's autofill
53 lines (52 loc) • 1.7 kB
JavaScript
import { useState as m, useRef as E, useLayoutEffect as A } from "react";
import '../assets/use-detect-autofill.css';const v = (e) => {
const [f, l] = m(!1), c = /^grayscale\(.+\) brightness\((1)?.*\) contrast\(.+\) invert\(.+\) sepia\(.+\) saturate\(.+\)$/, d = E(null), s = (t) => {
t.classList.contains("error") ? (t.isAutofilled = !1, l(!1)) : t.isAutofilled || (t.isAutofilled = !0, t.setAttribute("autofilled", ""), t.dispatchEvent(
new CustomEvent("autofill", {
bubbles: !0,
cancelable: !0
})
), l(!0));
}, a = (t) => {
t.isAutofilled && (t.isAutofilled = !1, t.removeAttribute("autofilled"), t.dispatchEvent(
new CustomEvent("autofillcancel", {
bubbles: !0,
cancelable: !1
})
), l(!1));
};
return A(() => {
const t = (i) => {
const n = i.target;
i.animationName.includes("onautofillstart") ? s(n) : i.animationName.includes("autofillcancel") && a(n);
}, r = (i) => {
const n = i.target;
"data" in i ? a(n) : s(n);
}, o = (i) => {
const n = i.target, u = i.propertyName === "filter" && getComputedStyle(n).filter.match(c);
u && (u[1] ? s(n) : a(n));
};
return e && (e.addEventListener(
"animationstart",
t,
!0
), e.addEventListener("input", r, !0), e.addEventListener(
"transitionstart",
o,
!0
)), () => {
e && (e.removeEventListener(
"animationstart",
t,
!0
), e.removeEventListener("input", r, !0), e.removeEventListener(
"transitionstart",
o,
!0
));
};
}, [e]), { isAutofilled: f, autofillRef: d };
};
export {
v as useAutofillDetection
};