Skip to content

Commit

Permalink
Add button variant with live region support to password component (#130)
Browse files Browse the repository at this point in the history
* Add button variant with live region support

* Remove non-visual helper text

* Fix typo - remove blurb

* Move important live region note up higher

* remove aria-described in password markup update specs

* fix typo
  • Loading branch information
joe-watkins authored Jul 23, 2024
1 parent 0097ef5 commit 6e0885e
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 3 deletions.
25 changes: 23 additions & 2 deletions _checklist-web/password-input.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ wcag:

## Code examples

### Use semantic HTML
### Checkbox variant

- This semantic HTML contains all accessibility features by default.
- Placing the show password checkbox ahead of the password input increases discoverability for screen reader users.
Expand All @@ -84,14 +84,35 @@ wcag:
</example>
{:/}


### Button variant
- The button leads the input so screen reader and keyboard-only users can change the state before interacting with the field.
- The password field type toggles between type of <code>password</code> and <code>text</code>.
- A live region `role="status"` is used to automatically announce to screen reader users the current visibility of the password value. For example, "Password is currently visible".
- Avoid adding <code>aria-hidden="true"</code> or CSS <code>display: none;</code> to the live region container that receives the dynamic update as this may impact screen reader support.
- Ensure the dynamic text, that is added to the live region, is removed from the DOM after a short amount of time so screen reader users do not encounter this text while navigating beyond the form field.



{% highlight html %}
{% include /examples/input-password-with-button.html %}
{% endhighlight %}

{::nomarkdown}
<example>
{% include /examples/input-password-with-button.html %}
</example>
{:/}


## Developer notes

### Name
- Include `for="input-id` in each `<label>` label to associate it with the input
- Use `aria-label="Input name"` as a last resort if a `<label>` can't be used

### Role
- Identifies as some kind of secure input
- Identifies as some kind of secure input [or text when toggled to text]

### State
- The show password checkbox must indicate its state on focus
Expand Down
36 changes: 36 additions & 0 deletions _includes/examples/input-password-with-button.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

<form class="password-container button-variant" data-show-password="false" onsubmit="return false;">
<label for="password-b">
Password
<span class="helper" aria-hidden="true">
Required
</span>
</label>
<div class="password-wrapper">
<div id="password-toggle" class="password-toggle">
<button class="tertiary" type="button">
<span class="show-pass">
show <span class="hidden">password</span>
<svg xmlns="http://www.w3.org/2000/svg" height="1.3rem" role="img" aria-hidden="true" viewBox="0 0 576 512"><path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM144 256a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm144-64c0 35.3-28.7 64-64 64c-7.1 0-13.9-1.2-20.3-3.3c-5.5-1.8-11.9 1.6-11.7 7.4c.3 6.9 1.3 13.8 3.2 20.7c13.7 51.2 66.4 81.6 117.6 67.9s81.6-66.4 67.9-117.6c-11.1-41.5-47.8-69.4-88.6-71.1c-5.8-.2-9.2 6.1-7.4 11.7c2.1 6.4 3.3 13.2 3.3 20.3z"/></svg>
</span>
<span class="hide-pass">
hide <span class="hidden">password</span>
<svg xmlns="http://www.w3.org/2000/svg" height="1.3rem" role="img" aria-hidden="true" viewBox="0 0 640 512"><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c8.4-19.3 10.6-41.4 4.8-63.3c-11.1-41.5-47.8-69.4-88.6-71.1c-5.8-.2-9.2 6.1-7.4 11.7c2.1 6.4 3.3 13.2 3.3 20.3c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zM373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5L373 389.9z"/></svg>
</span>
</button>
</div>
<input type="password"
id="password-b"
aria-describedby="password-hint"
aria-required="true"
value="passwordhere"
required>
</div>
<div id="password-hint" class="hint">
Use any length of characters including emojis.
</div>
<!-- this is dynamically announced by the screen reader when updated but content is removed after a pause so it can't be discovered -->
<div class="password-live-region hidden" role="status">
<div id="password-state-status"></div>
</div>
</form>
41 changes: 41 additions & 0 deletions _sass/modules/_input-password.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,47 @@
display: grid;
}

// button variant
&.button-variant {
display: block;
.password-wrapper {
position: relative;
}
input {
width: 100%;
padding-right: 75px;
}
button {
padding: 4px;
border: none;
width: 75px;
height: 40px;
position: absolute;
top: 50%;
right: 0;
transform: translate(-4px, -50%);
outline-offset: -3px;
line-height: 32px;
svg {
margin-bottom: -4px;
}
&:before, &:after {
display: none;
}
}
.hide-pass, .password-live-region .shown-state {
display: none;
}
.show-pass, .hide-pass {

}
// state
&[data-show-password="true"]{
.hide-pass, .password-live-region .shown-state { display: block; }
.show-pass, .password-live-region .hidden-state { display: none; }
}
}

}

input[type='checkbox']#show-password {
Expand Down
49 changes: 48 additions & 1 deletion assets/scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -723,4 +723,51 @@ function formValidationDemo() {
}
});

}
}

// password button variant
const passwordButtonVariant = $(".password-container.button-variant");

passwordButtonVariant.each(function(idx, item) {
const $parent = item,
$btn = $(item).find("button")[0],
$inputField = $(item).find("input[type='password']"),
$liveRegion = $(item).find("#password-state-status");
// $toggleHint = $(item).find("#password-visiblity-toggle-status"),
statusMessage = {
hiddenPass: "Password is currently hidden",
visiblePass: "Password is currently visible"
};

function updateLiveregion(target,hintTarget,el,msg){
setTimeout(function() {
// hintTarget.html(msg);
el.innerHTML = msg;
target.append(el);
}, 400);
setTimeout(function(){
target.html("");
},1500);
}

$btn.addEventListener("click", (e) => {
const curState = $parent.getAttribute("data-show-password"),
liveRegionEl = document.createElement('span');

// clear the state containers to make room for update
$liveRegion.html("");
// $toggleHint.html("");

if (curState === "false" || curState === null) {
// show pass
$parent.setAttribute("data-show-password", "true");
$inputField.prop("type", "text");
updateLiveregion($liveRegion,liveRegionEl,statusMessage.visiblePass);
} else {
// hide pass
$parent.setAttribute("data-show-password", "false");
$inputField.prop("type", "password");
updateLiveregion($liveRegion,liveRegionEl,statusMessage.hiddenPass);
}
});
});

0 comments on commit 6e0885e

Please sign in to comment.