82 lines
2.9 KiB
TypeScript
82 lines
2.9 KiB
TypeScript
import { useEffect } from "react";
|
|
|
|
const useDetectLatinAndNumbers = () => {
|
|
useEffect(() => {
|
|
// تابعی برای اضافه کردن کلاسها
|
|
const addClassIfContainsLatinOrNumbers = (element: HTMLElement) => {
|
|
element.childNodes.forEach((node) => {
|
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
const textContent = node.nodeValue;
|
|
if (textContent) {
|
|
if (/\d/.test(textContent)) {
|
|
element.classList.add("has-number");
|
|
}
|
|
if (/[a-zA-Z]/.test(textContent)) {
|
|
element.classList.add("has-latin");
|
|
}
|
|
}
|
|
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
const el = node as HTMLElement;
|
|
|
|
// بررسی `input` و `textarea`
|
|
if (
|
|
el instanceof HTMLInputElement ||
|
|
el instanceof HTMLTextAreaElement
|
|
) {
|
|
const checkAndApplyClasses = () => {
|
|
// با استفاده از requestAnimationFrame برای جلوگیری از بههمریختگی در سافاری
|
|
requestAnimationFrame(() => {
|
|
if (/\d/.test(el.value)) {
|
|
el.classList.add("has-number");
|
|
} else {
|
|
el.classList.remove("has-number");
|
|
}
|
|
|
|
if (/[a-zA-Z]/.test(el.value)) {
|
|
el.classList.add("has-latin");
|
|
} else {
|
|
el.classList.remove("has-latin");
|
|
}
|
|
});
|
|
};
|
|
|
|
// مقدار اولیه را بررسی کنیم
|
|
checkAndApplyClasses();
|
|
|
|
// هر تغییری را بررسی کنیم
|
|
el.addEventListener("input", checkAndApplyClasses);
|
|
}
|
|
|
|
// باز هم اضافه کردن کلاس به سایر عناصر
|
|
addClassIfContainsLatinOrNumbers(el);
|
|
}
|
|
});
|
|
};
|
|
|
|
// استفاده از MutationObserver برای نظارت بر تغییرات DOM
|
|
const observer = new MutationObserver((mutationsList) => {
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
mutationsList.forEach((mutation: any) => {
|
|
// تایپ دقیقتر برای جلوگیری از خطا در تایپاسکریپت
|
|
if (
|
|
mutation.type === "childList" ||
|
|
mutation.type === "subtree" ||
|
|
mutation.type === "attributes"
|
|
) {
|
|
addClassIfContainsLatinOrNumbers(mutation.target as HTMLElement);
|
|
}
|
|
});
|
|
});
|
|
|
|
// شروع به نظارت بر تمام تغییرات در بدنه صفحه
|
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
|
|
// در نهایت، پاکسازی اثرات هنگام خروج از کامپوننت
|
|
return () => {
|
|
observer.disconnect();
|
|
};
|
|
}, []);
|
|
};
|
|
|
|
export default useDetectLatinAndNumbers;
|