-
-
Save cferdinandi/7874a6d599fc4c085c69086978478004 to your computer and use it in GitHub Desktop.
This file contains 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> | |
<head> | |
<title>Toggle Password</title> | |
<style type="text/css"> | |
body { | |
margin: 1em auto; | |
max-width: 30em; | |
width: 88%; | |
} | |
label, | |
input:not([type="checkbox"]), | |
toggle-password { | |
display: block; | |
width: 100%; | |
} | |
input, | |
toggle-password { | |
margin-bottom: 1em; | |
} | |
toggle-password [aria-pressed="true"] [is-hidden], | |
toggle-password [aria-pressed="false"] [is-visible] { | |
display: none; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Toggle Password</h1> | |
<form> | |
<!-- A checkbox toggle --> | |
<toggle-password> | |
<label for="password-1">Password</label> | |
<input id="password-1" name="password" type="password" value="test1234"> | |
<label hidden> | |
<input toggle type="checkbox"> | |
Show password | |
</label> | |
</toggle-password> | |
<!-- A button toggle --> | |
<toggle-password> | |
<label for="password-2">Password</label> | |
<input id="password-2" name="password" type="password" value="test1234"> | |
<button toggle hidden> | |
Show password | |
</button> | |
</toggle-password> | |
<!-- Show password fields by default --> | |
<toggle-password visible> | |
<label for="password-3">Password</label> | |
<input id="password-3" name="password" type="password" value="test1234"> | |
<button toggle hidden> | |
<span is-hidden>Show Password</span> | |
<span is-visible>Hide Password</span> | |
</button> | |
</toggle-password> | |
</form> | |
<script> | |
customElements.define('toggle-password', class extends HTMLElement { | |
/** | |
* Instantiate the Web Component | |
*/ | |
constructor () { | |
// Get parent class properties | |
super(); | |
// Define properties | |
this.passwords = this.querySelectorAll('[type="password"]'); | |
this.trigger = this.querySelector('[toggle]'); | |
if (!this.trigger) return; | |
this.type = this.trigger.tagName.toLowerCase(); | |
this.visible = this.hasAttribute('visible'); | |
this.handler = this.createHandler(); | |
// Setup the UI | |
this.init(); | |
} | |
/** | |
* Show hidden elements and add ARIA | |
*/ | |
init () { | |
// Show hidden toggle | |
let hidden = this.trigger.closest('[hidden]'); | |
if (hidden) { | |
hidden.removeAttribute('hidden'); | |
} | |
// If toggle is a button, add aria-pressed | |
if (this.type === 'button') { | |
this.trigger.setAttribute('aria-pressed', this.visible); | |
this.trigger.setAttribute('type', 'button'); | |
} | |
// If passwords should be visible, show them by default | |
if (this.visible) { | |
this.show(); | |
} | |
} | |
/** | |
* Show passwords | |
*/ | |
show () { | |
for (let pw of this.passwords) { | |
pw.type = 'text'; | |
} | |
if (this.type === 'button') { | |
this.trigger.setAttribute('aria-pressed', true); | |
} | |
} | |
/** | |
* Hide password visibility | |
*/ | |
hide () { | |
for (let pw of this.passwords) { | |
pw.type = 'password'; | |
} | |
if (this.type === 'button') { | |
this.trigger.setAttribute('aria-pressed', false); | |
} | |
} | |
/** | |
* Toggle password visibility on or off | |
*/ | |
toggle () { | |
let show = this.type === 'button' ? this.trigger.getAttribute('aria-pressed') === 'false' : this.trigger.checked; | |
if (show) { | |
this.show(); | |
} else { | |
this.hide(); | |
} | |
} | |
/** | |
* Create the event handler | |
* @return {Function} The event handler function | |
*/ | |
createHandler () { | |
return (event) => { | |
this.toggle(); | |
}; | |
} | |
/** | |
* Start listening to clicks | |
*/ | |
connectedCallback () { | |
this.trigger.addEventListener('click', this.handler); | |
} | |
/** | |
* Stop listening to clicks | |
*/ | |
disconnectedCallback () { | |
this.trigger.removeEventListener('click', this.handler); | |
} | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment