const rules = { min: (value, min) => value.length >= min, upper: (value) => /[A-Z]/.test(value), lower: (value) => /[a-z]/.test(value), number: (value) => /\d/.test(value), symbol: (value) => /[^a-zA-Z0-9]/.test(value), email: (value, _min, email) => { if (!email) return true; return !value.toLowerCase().includes(email.toLowerCase()); }, match: (_value, _min, _email, confirm) => { if (!confirm) return false; return true; } }; export function initPasswordHints() { const containers = document.querySelectorAll('[data-password-hints]'); if (!containers.length) return; containers.forEach((container) => { const passwordSelector = container.dataset.passwordInput; const confirmSelector = container.dataset.confirmInput; const emailSelector = container.dataset.emailInput; const passwordInput = passwordSelector ? document.querySelector(passwordSelector) : null; const confirmInput = confirmSelector ? document.querySelector(confirmSelector) : null; const emailInput = emailSelector ? document.querySelector(emailSelector) : null; const minLength = Number.parseInt(container.dataset.minLength || '12', 10); const items = container.querySelectorAll('[data-rule]'); const setState = (item, state) => { item.classList.remove('is-valid', 'is-invalid'); if (state === 'valid') item.classList.add('is-valid'); if (state === 'invalid') item.classList.add('is-invalid'); }; const evaluate = () => { const password = passwordInput?.value ?? ''; const confirm = confirmInput?.value ?? ''; const email = emailInput?.value ?? ''; const hasValue = password.length > 0 || confirm.length > 0; items.forEach((item) => { const rule = item.dataset.rule; if (!rule) return; if (!hasValue) { setState(item, 'neutral'); return; } if (rule === 'match') { if (password === '' || confirm === '') { setState(item, 'neutral'); return; } setState(item, password === confirm ? 'valid' : 'invalid'); return; } const check = rules[rule]; if (!check) return; const ok = check(password, minLength, email, confirm); setState(item, ok ? 'valid' : 'invalid'); }); }; if (passwordInput) passwordInput.addEventListener('input', evaluate); if (confirmInput) confirmInput.addEventListener('input', evaluate); if (emailInput) emailInput.addEventListener('input', evaluate); evaluate(); }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initPasswordHints); } else { initPasswordHints(); }