
The JavaScript project provides two Web Components that improve the user experience of standard HTML password input fields.
- <password-rules>: This component listens for input events and checks the entered password against a defined set of rules (e.g., minimum length, uppercase character requirement). It provides real-time feedback to the user as they type.
- <password-toggle>: This component adds a button that allows users to show or hide the password input value.
These components work together to create an accessible and more user-friendly password input experience. Users receive clear guidance on password requirements and can easily view or hide their input as needed.
How to use it:
1. Import the ‘password-rules.js’ and ‘password-toggle.js’ as modules into the document.
<script type="module" src="path/to/password-rules.js"></script> <script type="module" src="path/to/password-toggle.js"></script>
2. This example show show to use both web components with a standard password input:
- data-input-id: Links the component to the target password input’s ID.
- data-rules: Accepts a comma-separated list of regular expressions representing password rules.
- data-separator: (Optional) Specifies a custom separator for the data-rules list (default is a comma).
- data-rule-index: (Optional) Used on child elements to link them to specific rules. When a rule is met, the is-match class is toggled on the corresponding child element.
- data-status-id: Links the component to an element that displays the password visibility status (should have aria-live=”polite” for screen readers).
<label for="new-password">Password</label>
<div class="password-input-wrapper">
<input type="password" id="new-password" name="password" pattern="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{9,}$" autocomplete="new-password">
<div id="password-display-status" class="visually-hidden" aria-live="polite"></div>
<password-toggle data-input-id="new-password" data-status-id="password-display-status">
<button type="button">
<span class="visually-hidden">Toggle password visibility</span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256">
<path d="M228,175a8,8,0,0,1-10.92-3l-19-33.2A123.23,123.23,0,0,1,162,155.46l5.87,35.22a8,8,0,0,1-6.58,9.21A8.4,8.4,0,0,1,160,200a8,8,0,0,1-7.88-6.69l-5.77-34.58a133.06,133.06,0,0,1-36.68,0l-5.77,34.58A8,8,0,0,1,96,200a8.4,8.4,0,0,1-1.32-.11,8,8,0,0,1-6.58-9.21L94,155.46a123.23,123.23,0,0,1-36.06-16.69L39,172A8,8,0,1,1,25.06,164l20-35a153.47,153.47,0,0,1-19.3-20A8,8,0,1,1,38.22,99c16.6,20.54,45.64,45,89.78,45s73.18-24.49,89.78-45A8,8,0,1,1,230.22,109a153.47,153.47,0,0,1-19.3,20l20,35A8,8,0,0,1,228,175Z"></path>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256">
<path d="M247.31,124.76c-.35-.79-8.82-19.58-27.65-38.41C194.57,61.26,162.88,48,128,48S61.43,61.26,36.34,86.35C17.51,105.18,9,124,8.69,124.76a8,8,0,0,0,0,6.5c.35.79,8.82,19.57,27.65,38.4C61.43,194.74,93.12,208,128,208s66.57-13.26,91.66-38.34c18.83-18.83,27.3-37.61,27.65-38.4A8,8,0,0,0,247.31,124.76ZM128,192c-30.78,0-57.67-11.19-79.93-33.25A133.47,133.47,0,0,1,25,128,133.33,133.33,0,0,1,48.07,97.25C70.33,75.19,97.22,64,128,64s57.67,11.19,79.93,33.25A133.46,133.46,0,0,1,231.05,128C223.84,141.46,192.43,192,128,192Zm0-112a48,48,0,1,0,48,48A48.05,48.05,0,0,0,128,80Zm0,80a32,32,0,1,1,32-32A32,32,0,0,1,128,160Z"></path>
</svg>
</button>
</password-toggle>
</div>
<password-rules data-input-id="new-password" data-rules=".{9}, .*\d, [\W_], [a-z], [A-Z]">
<div class="password-rules__meter">
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
<div class="password-rules__score"></div>
</div>
<ul class="password-rules__checklist flow">
<li data-rule-index="0">Longer than 8 characters</li>
<li data-rule-index="3">Includes a lowercase letter</li>
<li data-rule-index="4">Includes an uppercase letter</li>
<li data-rule-index="1">Includes a number</li>
<li data-rule-index="2">Includes a special character</li>
</ul>
</password-rules>3. The <password-toggle> component wraps a button and enhances it with password visibility control. When the button is clicked:
- It toggles the type attribute of the linked password input between “password” (hidden) and “text” (visible).
- It updates the
aria-pressedattribute of the button to reflect the current visibility state. - It updates the
aria-labelattribute to provide a context-aware label (e.g., “Hide password” or “Show password”). - It updates the content of the linked status element to announce the visibility status to screen readers.
4. The <password-rules> component parses the data-rules attribute and creates an array of regular expressions. It then listens for input events on the linked password input:
- As the user types, it tests the current input value against each rule.
- If a rule is matched, it increments the
data-scoreattribute and adds theis-matchclass to any child element with a matchingdata-rule-index. - If a rule is no longer met, it decrements the
data-scoreand removes the is-match class. - It updates the CSS variables
--scoreand--totalto reflect the current score and the total number of rules.






