mirror of
https://github.com/bitwarden/browser.git
synced 2024-09-29 04:17:41 +02:00
[CL-63] Color password component (#4018)
This commit is contained in:
parent
a57424df75
commit
dc84a54928
@ -0,0 +1,79 @@
|
|||||||
|
import { Component, HostBinding, Input } from "@angular/core";
|
||||||
|
|
||||||
|
import { Utils } from "@bitwarden/common/misc/utils";
|
||||||
|
|
||||||
|
enum CharacterType {
|
||||||
|
Letter,
|
||||||
|
Emoji,
|
||||||
|
Special,
|
||||||
|
Number,
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "bit-color-password",
|
||||||
|
template: `<div
|
||||||
|
*ngFor="let character of passwordArray; index as i"
|
||||||
|
[class]="getCharacterClass(character)"
|
||||||
|
>
|
||||||
|
<span>{{ character }}</span>
|
||||||
|
<span *ngIf="showCount" class="tw-whitespace-nowrap tw-text-xs tw-leading-5 tw-text-main">{{
|
||||||
|
i + 1
|
||||||
|
}}</span>
|
||||||
|
</div>`,
|
||||||
|
})
|
||||||
|
export class ColorPasswordComponent {
|
||||||
|
@Input() private password: string = null;
|
||||||
|
@Input() showCount = false;
|
||||||
|
|
||||||
|
characterStyles: Record<CharacterType, string[]> = {
|
||||||
|
[CharacterType.Emoji]: [],
|
||||||
|
[CharacterType.Letter]: ["tw-text-main"],
|
||||||
|
[CharacterType.Special]: ["tw-text-danger"],
|
||||||
|
[CharacterType.Number]: ["tw-text-primary-500"],
|
||||||
|
};
|
||||||
|
|
||||||
|
@HostBinding("class")
|
||||||
|
get classList() {
|
||||||
|
return ["tw-min-w-0", "tw-whitespace-pre-wrap", "tw-break-all"];
|
||||||
|
}
|
||||||
|
|
||||||
|
get passwordArray() {
|
||||||
|
// Convert to an array to handle cases that strings have special characters, i.e.: emoji.
|
||||||
|
return Array.from(this.password);
|
||||||
|
}
|
||||||
|
|
||||||
|
getCharacterClass(character: string) {
|
||||||
|
const charType = this.getCharacterType(character);
|
||||||
|
const charClass = this.characterStyles[charType].concat("tw-inline-flex");
|
||||||
|
|
||||||
|
if (this.showCount) {
|
||||||
|
return charClass.concat([
|
||||||
|
"tw-inline-flex",
|
||||||
|
"tw-flex-col",
|
||||||
|
"tw-items-center",
|
||||||
|
"tw-w-7",
|
||||||
|
"tw-py-1",
|
||||||
|
"odd:tw-bg-secondary-100",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return charClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCharacterType(character: string): CharacterType {
|
||||||
|
if (character.match(Utils.regexpEmojiPresentation)) {
|
||||||
|
return CharacterType.Emoji;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (character.match(/\d/)) {
|
||||||
|
return CharacterType.Number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const specials = ["&", "<", ">", " "];
|
||||||
|
if (specials.includes(character) || character.match(/[^\w ]/)) {
|
||||||
|
return CharacterType.Special;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CharacterType.Letter;
|
||||||
|
}
|
||||||
|
}
|
11
libs/components/src/color-password/color-password.module.ts
Normal file
11
libs/components/src/color-password/color-password.module.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
import { NgModule } from "@angular/core";
|
||||||
|
|
||||||
|
import { ColorPasswordComponent } from "./color-password.component";
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [CommonModule],
|
||||||
|
exports: [ColorPasswordComponent],
|
||||||
|
declarations: [ColorPasswordComponent],
|
||||||
|
})
|
||||||
|
export class ColorPasswordModule {}
|
52
libs/components/src/color-password/color-password.stories.ts
Normal file
52
libs/components/src/color-password/color-password.stories.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import { Meta, Story } from "@storybook/angular";
|
||||||
|
|
||||||
|
import { ColorPasswordComponent } from "./color-password.component";
|
||||||
|
|
||||||
|
const examplePassword = "Wq$Jk😀7jDX#rS5Sdi!z";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: "Component Library/Color Password",
|
||||||
|
component: ColorPasswordComponent,
|
||||||
|
args: {
|
||||||
|
password: examplePassword,
|
||||||
|
showCount: false,
|
||||||
|
},
|
||||||
|
parameters: {
|
||||||
|
design: {
|
||||||
|
type: "figma",
|
||||||
|
url: "https://www.figma.com/file/6fvTDa3zfvgWdizLQ7nSTP/Numbered-Password",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as Meta;
|
||||||
|
|
||||||
|
const Template: Story<ColorPasswordComponent> = (args: ColorPasswordComponent) => ({
|
||||||
|
props: args,
|
||||||
|
template: `
|
||||||
|
<bit-color-password class="tw-text-base" [password]="password" [showCount]="showCount"></bit-color-password>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
const WrappedTemplate: Story<ColorPasswordComponent> = (args: ColorPasswordComponent) => ({
|
||||||
|
props: args,
|
||||||
|
template: `
|
||||||
|
<div class="tw-max-w-32">
|
||||||
|
<bit-color-password class="tw-text-base" [password]="password" [showCount]="showCount"></bit-color-password>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ColorPassword = Template.bind({});
|
||||||
|
|
||||||
|
export const WrappedColorPassword = WrappedTemplate.bind({});
|
||||||
|
|
||||||
|
export const ColorPasswordCount = Template.bind({});
|
||||||
|
ColorPasswordCount.args = {
|
||||||
|
password: examplePassword,
|
||||||
|
showCount: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WrappedColorPasswordCount = WrappedTemplate.bind({});
|
||||||
|
WrappedColorPasswordCount.args = {
|
||||||
|
password: examplePassword,
|
||||||
|
showCount: true,
|
||||||
|
};
|
1
libs/components/src/color-password/index.ts
Normal file
1
libs/components/src/color-password/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from "./color-password.module";
|
@ -14,4 +14,5 @@ export * from "./multi-select";
|
|||||||
export * from "./tabs";
|
export * from "./tabs";
|
||||||
export * from "./table";
|
export * from "./table";
|
||||||
export * from "./toggle-group";
|
export * from "./toggle-group";
|
||||||
|
export * from "./color-password";
|
||||||
export * from "./utils/i18n-mock.service";
|
export * from "./utils/i18n-mock.service";
|
||||||
|
Loading…
Reference in New Issue
Block a user