Last active
August 4, 2022 19:37
-
-
Save guiseek/1ed84c8ef4ae43c5d1d518b706bb8618 to your computer and use it in GitHub Desktop.
Password Strength Custom Element
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="pt-br"> | |
<head> | |
<meta charset="utf-8" /> | |
<title>Password Strength Custom Element</title> | |
<style> | |
body { | |
font-family: Arial, Helvetica, sans-serif; | |
} | |
fieldset, | |
label { | |
display: flex; | |
flex-direction: column; | |
} | |
fieldset { | |
row-gap: 8px; | |
} | |
progress { | |
width: 100%; | |
} | |
label { | |
row-gap: 2px; | |
} | |
</style> | |
</head> | |
<body> | |
<form> | |
<fieldset> | |
<legend>Password</legend> | |
<input minlength="6" is="password-strength" /> | |
<button type="submit">Submit</button> | |
</fieldset> | |
</form> | |
<script> | |
class PasswordStrengthElement extends HTMLInputElement { | |
connectedCallback() { | |
this.setAttribute('type', 'password') | |
const progress = document.createElement('progress') | |
progress.max = '100' | |
progress.value = '0' | |
this.insertAdjacentElement('afterend', progress) | |
this.oninput = () => this.checkPassword(progress) | |
} | |
checkPassword(progress) { | |
const conditions = [/[0-9]/g, /[a-z]/g, /[A-Z]/g, /[^a-zA-Z0-9]/g] | |
const message = 'A senha deve conter ' | |
const messages = [ | |
'números', | |
'letras minúsculas', | |
'letras maiúsculas', | |
'caracteres especiais', | |
'no mínimo 6 caracteres', | |
] | |
const validation = conditions.map((condition) => | |
condition.test(this.value) | |
) | |
validation.push(this.value.length >= this.minLength) | |
const score = validation.filter((v) => v === true) | |
const color = `hsl(${score.length * 15}, 100%, 50%)` | |
progress.value = +(score.length * 20) | |
progress.style.accentColor = color | |
if (validation.every((v) => v === true)) { | |
this.setCustomValidity('') | |
} else { | |
const position = validation.findIndex((v) => v === false) | |
this.setCustomValidity(message + messages.at(position)) | |
this.reportValidity() | |
} | |
} | |
} | |
customElements.define('password-strength', PasswordStrengthElement, { | |
extends: 'input', | |
}) | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment