feat: add hidden char count toggle (#1780)

Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
This commit is contained in:
Melanie Kanavakatini 2022-02-24 03:11:09 +00:00 committed by GitHub
parent e802bba99c
commit 8f76e81582
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 74 additions and 5 deletions

2
jslib

@ -1 +1 @@
Subproject commit a6092916d80424b8bf4d34e321a0b58f15c7519d Subproject commit fdaa4f9fa5c6ff8beefcf4d896a8a7f02dc7e3e9

View File

@ -1866,5 +1866,8 @@
}, },
"leftOrganization": { "leftOrganization": {
"message": "You have left the organization." "message": "You have left the organization."
},
"toggleCharacterCount": {
"message": "Toggle character count"
} }
} }

View File

@ -69,6 +69,7 @@ import { StopClickDirective } from "jslib-angular/directives/stop-click.directiv
import { StopPropDirective } from "jslib-angular/directives/stop-prop.directive"; import { StopPropDirective } from "jslib-angular/directives/stop-prop.directive";
import { TrueFalseValueDirective } from "jslib-angular/directives/true-false-value.directive"; import { TrueFalseValueDirective } from "jslib-angular/directives/true-false-value.directive";
import { ColorPasswordCountPipe } from "jslib-angular/pipes/color-password-count.pipe";
import { ColorPasswordPipe } from "jslib-angular/pipes/color-password.pipe"; import { ColorPasswordPipe } from "jslib-angular/pipes/color-password.pipe";
import { I18nPipe } from "jslib-angular/pipes/i18n.pipe"; import { I18nPipe } from "jslib-angular/pipes/i18n.pipe";
import { SearchCiphersPipe } from "jslib-angular/pipes/search-ciphers.pipe"; import { SearchCiphersPipe } from "jslib-angular/pipes/search-ciphers.pipe";
@ -207,6 +208,7 @@ registerLocaleData(localeZhTw, "zh-TW");
CipherRowComponent, CipherRowComponent,
CiphersComponent, CiphersComponent,
CollectionsComponent, CollectionsComponent,
ColorPasswordCountPipe,
ColorPasswordPipe, ColorPasswordPipe,
CurrentTabComponent, CurrentTabComponent,
EnvironmentComponent, EnvironmentComponent,

View File

@ -120,6 +120,11 @@
} }
.action-buttons { .action-buttons {
&.count {
align-self: start;
margin-top: 10px;
}
.row-btn { .row-btn {
padding-left: 5px; padding-left: 5px;
padding-right: 5px; padding-right: 5px;
@ -255,6 +260,7 @@
display: block; display: block;
width: 100%; width: 100%;
margin-bottom: 5px; margin-bottom: 5px;
min-height: 1em;
@include themify($themes) { @include themify($themes) {
color: themed("mutedColor"); color: themed("mutedColor");
@ -305,6 +311,7 @@
.row-main { .row-main {
flex-grow: 1; flex-grow: 1;
min-width: 0; min-width: 0;
align-self: start;
} }
&.box-content-row-flex, &.box-content-row-flex,
@ -455,6 +462,7 @@
.action-buttons { .action-buttons {
display: flex; display: flex;
align-self: start;
margin-left: 5px; margin-left: 5px;
.row-btn { .row-btn {

View File

@ -164,6 +164,30 @@ p.lead {
} }
} }
.password-character {
display: inline-flex;
flex-direction: column;
align-items: center;
width: 30px;
height: 36px;
font-weight: 600;
&:nth-child(odd) {
@include themify($themes) {
background-color: themed("backgroundColor");
}
}
}
.password-count {
white-space: nowrap;
font-size: 8px;
@include themify($themes) {
color: themed("mutedColor") !important;
}
}
#duo-frame { #duo-frame {
background: url("../images/loading.svg") 0 0 no-repeat; background: url("../images/loading.svg") 0 0 no-repeat;
width: 100%; width: 100%;

View File

@ -10,10 +10,14 @@
{{ field.value || "&nbsp;" }} {{ field.value || "&nbsp;" }}
</div> </div>
<div *ngIf="field.type === fieldType.Hidden"> <div *ngIf="field.type === fieldType.Hidden">
<span [hidden]="!field.showValue" class="monospaced show-whitespace">{{ <span *ngIf="!field.showValue" class="monospaced">{{ field.maskedValue }}</span>
<span *ngIf="field.showValue && !field.showCount" class="monospaced show-whitespace">{{
field.value field.value
}}</span> }}</span>
<span [hidden]="field.showValue" class="monospaced">{{ field.maskedValue }}</span> <span
*ngIf="field.showValue && field.showCount"
[innerHTML]="field.value | colorPasswordCount"
></span>
</div> </div>
<div *ngIf="field.type === fieldType.Boolean"> <div *ngIf="field.type === fieldType.Boolean">
<i class="bwi bwi-check-square" *ngIf="field.value === 'true'" aria-hidden="true"></i> <i class="bwi bwi-check-square" *ngIf="field.value === 'true'" aria-hidden="true"></i>
@ -33,6 +37,18 @@
</div> </div>
</div> </div>
<div class="action-buttons"> <div class="action-buttons">
<button
type="button"
class="row-btn"
appStopClick
attr.aria-label="{{ 'toggleCharacterCount' | i18n }} {{ field.name }}"
appA11yTitle="{{ 'toggleCharacterCount' | i18n }}"
*ngIf="field.type === fieldType.Hidden && cipher.viewPassword && field.showValue"
(click)="toggleFieldCount(field)"
[attr.aria-pressed]="field.showCount"
>
<i class="bwi bwi-lg bwi-numbered-list" aria-hidden="true"></i>
</button>
<button <button
type="button" type="button"
class="row-btn" class="row-btn"

View File

@ -60,15 +60,19 @@
(dragstart)="setTextDataOnDrag($event, cipher.login.password)" (dragstart)="setTextDataOnDrag($event, cipher.login.password)"
>{{ "password" | i18n }}</span >{{ "password" | i18n }}</span
> >
<div [hidden]="showPassword" class="monospaced"> <div *ngIf="!showPassword" class="monospaced">
{{ cipher.login.maskedPassword }} {{ cipher.login.maskedPassword }}
</div> </div>
<div <div
[hidden]="!showPassword" *ngIf="showPassword && !showPasswordCount"
class="monospaced password-wrapper" class="monospaced password-wrapper"
appSelectCopy appSelectCopy
[innerHTML]="cipher.login.password | colorPassword" [innerHTML]="cipher.login.password | colorPassword"
></div> ></div>
<div
*ngIf="showPassword && showPasswordCount"
[innerHTML]="cipher.login.password | colorPasswordCount"
></div>
</div> </div>
<div class="action-buttons"> <div class="action-buttons">
<button <button
@ -93,6 +97,18 @@
aria-hidden="true" aria-hidden="true"
></i> ></i>
</button> </button>
<button
type="button"
class="row-btn"
appStopClick
attr.aria-label="{{ 'toggleCharacterCount' | i18n }} {{ 'password' | i18n }}"
appA11yTitle="{{ 'toggleCharacterCount' | i18n }}"
(click)="togglePasswordCount()"
*ngIf="showPassword"
[attr.aria-pressed]="showPasswordCount"
>
<i class="bwi bwi-lg bwi-numbered-list" aria-hidden="true"></i>
</button>
<button <button
type="button" type="button"
class="row-btn" class="row-btn"