diff --git a/apps/web/src/app/accounts/register-form/register-form.component.html b/apps/web/src/app/accounts/register-form/register-form.component.html index 56364086ff9..d9456d5a6e9 100644 --- a/apps/web/src/app/accounts/register-form/register-form.component.html +++ b/apps/web/src/app/accounts/register-form/register-form.component.html @@ -114,7 +114,9 @@
- {{ "createAccount" | i18n }} + - {{ "logIn" | i18n }} +
diff --git a/apps/web/src/app/accounts/trial-initiation/billing.component.html b/apps/web/src/app/accounts/trial-initiation/billing.component.html index 4486d0672dd..0eb203f72ca 100644 --- a/apps/web/src/app/accounts/trial-initiation/billing.component.html +++ b/apps/web/src/app/accounts/trial-initiation/billing.component.html @@ -40,7 +40,9 @@
- {{ "startTrial" | i18n }} +
diff --git a/apps/web/src/app/organizations/settings/account.component.html b/apps/web/src/app/organizations/settings/account.component.html index 73a2f7872e7..1f2e145ae7a 100644 --- a/apps/web/src/app/organizations/settings/account.component.html +++ b/apps/web/src/app/organizations/settings/account.component.html @@ -66,9 +66,9 @@ - +
diff --git a/apps/web/src/app/organizations/users/enroll-master-password-reset.component.html b/apps/web/src/app/organizations/users/enroll-master-password-reset.component.html index 72f1bbdbda7..4d24e66764e 100644 --- a/apps/web/src/app/organizations/users/enroll-master-password-reset.component.html +++ b/apps/web/src/app/organizations/users/enroll-master-password-reset.component.html @@ -32,9 +32,9 @@
- +

{{ "reportError" | i18n }}...

diff --git a/apps/web/src/app/reports/pages/exposed-passwords-report.component.html b/apps/web/src/app/reports/pages/exposed-passwords-report.component.html index 2c5547efc7c..0fce002310b 100644 --- a/apps/web/src/app/reports/pages/exposed-passwords-report.component.html +++ b/apps/web/src/app/reports/pages/exposed-passwords-report.component.html @@ -2,9 +2,9 @@

{{ "exposedPasswordsReport" | i18n }}

{{ "exposedPasswordsReportDesc" | i18n }}

- +
{{ "noExposedPasswords" | i18n }} diff --git a/apps/web/src/app/settings/change-kdf.component.html b/apps/web/src/app/settings/change-kdf.component.html index b06cf01d060..1b3b62a03fb 100644 --- a/apps/web/src/app/settings/change-kdf.component.html +++ b/apps/web/src/app/settings/change-kdf.component.html @@ -71,7 +71,7 @@
- + diff --git a/apps/web/src/app/settings/change-password.component.html b/apps/web/src/app/settings/change-password.component.html index 6f36236a7ae..e74881db025 100644 --- a/apps/web/src/app/settings/change-password.component.html +++ b/apps/web/src/app/settings/change-password.component.html @@ -100,7 +100,7 @@
- + diff --git a/apps/web/src/app/settings/emergency-access-add-edit.component.html b/apps/web/src/app/settings/emergency-access-add-edit.component.html index 410489321a1..b438cee937c 100644 --- a/apps/web/src/app/settings/emergency-access-add-edit.component.html +++ b/apps/web/src/app/settings/emergency-access-add-edit.component.html @@ -100,9 +100,15 @@
- {{ - "submit" | i18n - }} + diff --git a/apps/web/src/app/settings/premium.component.html b/apps/web/src/app/settings/premium.component.html index 63995b457ac..13266fd9ca5 100644 --- a/apps/web/src/app/settings/premium.component.html +++ b/apps/web/src/app/settings/premium.component.html @@ -68,9 +68,9 @@ "licenseFileDesc" | i18n: "bitwarden_premium_license.json" }}
- +
@@ -118,7 +118,7 @@

{{ "paymentChargedAnnually" | i18n }} - + diff --git a/apps/web/src/app/settings/two-factor-setup.component.html b/apps/web/src/app/settings/two-factor-setup.component.html index 698e7fd9c07..b846fdb9816 100644 --- a/apps/web/src/app/settings/two-factor-setup.component.html +++ b/apps/web/src/app/settings/two-factor-setup.component.html @@ -77,9 +77,15 @@ {{ "deviceVerificationDesc" | i18n }} - + diff --git a/apps/web/src/app/shared/shared.module.ts b/apps/web/src/app/shared/shared.module.ts index 342948bb515..c0a076e545e 100644 --- a/apps/web/src/app/shared/shared.module.ts +++ b/apps/web/src/app/shared/shared.module.ts @@ -12,7 +12,6 @@ import { ButtonModule, CalloutModule, FormFieldModule, - SubmitButtonModule, MenuModule, IconModule, } from "@bitwarden/components"; @@ -44,7 +43,6 @@ import "./locales"; ButtonModule, MenuModule, FormFieldModule, - SubmitButtonModule, IconModule, ], exports: [ @@ -63,7 +61,6 @@ import "./locales"; ButtonModule, MenuModule, FormFieldModule, - SubmitButtonModule, IconModule, ], providers: [DatePipe], diff --git a/bitwarden_license/bit-web/src/app/organizations/manage/scim.component.html b/bitwarden_license/bit-web/src/app/organizations/manage/scim.component.html index 54fe44e073c..3d27448753f 100644 --- a/bitwarden_license/bit-web/src/app/organizations/manage/scim.component.html +++ b/bitwarden_license/bit-web/src/app/organizations/manage/scim.component.html @@ -81,7 +81,13 @@ {{ "scimApiKeyHelperText" | i18n }} - + diff --git a/libs/components/src/button/button.component.html b/libs/components/src/button/button.component.html new file mode 100644 index 00000000000..4875c159e92 --- /dev/null +++ b/libs/components/src/button/button.component.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/libs/components/src/button/button.directive.spec.ts b/libs/components/src/button/button.component.spec.ts similarity index 65% rename from libs/components/src/button/button.directive.spec.ts rename to libs/components/src/button/button.component.spec.ts index a7c3024e480..48aa8928e90 100644 --- a/libs/components/src/button/button.directive.spec.ts +++ b/libs/components/src/button/button.component.spec.ts @@ -8,6 +8,7 @@ describe("Button", () => { let fixture: ComponentFixture; let testAppComponent: TestApp; let buttonDebugElement: DebugElement; + let disabledButtonDebugElement: DebugElement; let linkDebugElement: DebugElement; beforeEach(waitForAsync(() => { @@ -20,6 +21,7 @@ describe("Button", () => { fixture = TestBed.createComponent(TestApp); testAppComponent = fixture.debugElement.componentInstance; buttonDebugElement = fixture.debugElement.query(By.css("button")); + disabledButtonDebugElement = fixture.debugElement.query(By.css("button#disabled")); linkDebugElement = fixture.debugElement.query(By.css("a")); })); @@ -60,16 +62,67 @@ describe("Button", () => { expect(buttonDebugElement.nativeElement.classList.contains("tw-block")).toBe(false); expect(linkDebugElement.nativeElement.classList.contains("tw-block")).toBe(false); }); + + it("should not be disabled when loading and disabled are false", () => { + testAppComponent.loading = false; + testAppComponent.disabled = false; + fixture.detectChanges(); + + expect(buttonDebugElement.attributes["loading"]).toBeFalsy(); + expect(linkDebugElement.attributes["loading"]).toBeFalsy(); + expect(buttonDebugElement.nativeElement.disabled).toBeFalsy(); + }); + + it("should be disabled when disabled is true", () => { + testAppComponent.disabled = true; + fixture.detectChanges(); + + expect(buttonDebugElement.nativeElement.disabled).toBeTruthy(); + // Anchor tags cannot be disabled. + }); + + it("should be disabled when attribute disabled is true", () => { + expect(disabledButtonDebugElement.nativeElement.disabled).toBeTruthy(); + }); + + it("should be disabled when loading is true", () => { + testAppComponent.loading = true; + fixture.detectChanges(); + + expect(buttonDebugElement.nativeElement.disabled).toBeTruthy(); + }); }); @Component({ selector: "test-app", template: ` - - Link + + + Link + + + `, }) class TestApp { buttonType: string; block: boolean; + disabled: boolean; + loading: boolean; } diff --git a/libs/components/src/button/button.directive.ts b/libs/components/src/button/button.component.ts similarity index 82% rename from libs/components/src/button/button.directive.ts rename to libs/components/src/button/button.component.ts index 5c4b0039aef..eeba83b8156 100644 --- a/libs/components/src/button/button.directive.ts +++ b/libs/components/src/button/button.component.ts @@ -1,4 +1,4 @@ -import { Input, HostBinding, Directive } from "@angular/core"; +import { Input, HostBinding, Component } from "@angular/core"; export type ButtonTypes = "primary" | "secondary" | "danger"; @@ -38,10 +38,11 @@ const buttonStyles: Record = { ], }; -@Directive({ +@Component({ selector: "button[bitButton], a[bitButton]", + templateUrl: "button.component.html", }) -export class ButtonDirective { +export class ButtonComponent { @HostBinding("class") get classList() { return [ "tw-font-semibold", @@ -65,6 +66,14 @@ export class ButtonDirective { .concat(buttonStyles[this.buttonType ?? "secondary"]); } + @HostBinding("attr.disabled") + get disabledAttr() { + const disabled = this.disabled != null && this.disabled !== false; + return disabled || this.loading ? true : null; + } + @Input() buttonType: ButtonTypes = null; @Input() block?: boolean; + @Input() loading = false; + @Input() disabled = false; } diff --git a/libs/components/src/button/button.module.ts b/libs/components/src/button/button.module.ts index c9c3822abfa..448e7c9dcf6 100644 --- a/libs/components/src/button/button.module.ts +++ b/libs/components/src/button/button.module.ts @@ -1,11 +1,11 @@ import { CommonModule } from "@angular/common"; import { NgModule } from "@angular/core"; -import { ButtonDirective } from "./button.directive"; +import { ButtonComponent } from "./button.component"; @NgModule({ imports: [CommonModule], - exports: [ButtonDirective], - declarations: [ButtonDirective], + exports: [ButtonComponent], + declarations: [ButtonComponent], }) export class ButtonModule {} diff --git a/libs/components/src/button/button.stories.ts b/libs/components/src/button/button.stories.ts index f09b8701b1b..4b9b88d48b1 100644 --- a/libs/components/src/button/button.stories.ts +++ b/libs/components/src/button/button.stories.ts @@ -1,12 +1,14 @@ import { Meta, Story } from "@storybook/angular"; -import { ButtonDirective } from "./button.directive"; +import { ButtonComponent } from "./button.component"; export default { title: "Component Library/Button", - component: ButtonDirective, + component: ButtonComponent, args: { buttonType: "primary", + disabled: false, + loading: false, }, parameters: { design: { @@ -16,11 +18,11 @@ export default { }, } as Meta; -const Template: Story = (args: ButtonDirective) => ({ +const Template: Story = (args: ButtonComponent) => ({ props: args, template: ` - - Link + + Link `, }); @@ -39,21 +41,50 @@ Danger.args = { buttonType: "danger", }; -const DisabledTemplate: Story = (args) => ({ +const AllStylesTemplate: Story = (args) => ({ props: args, template: ` - - - + + + `, }); -export const Disabled = DisabledTemplate.bind({}); -Disabled.args = { - size: "small", +export const Loading = AllStylesTemplate.bind({}); +Loading.args = { + disabled: false, + loading: true, }; -const BlockTemplate: Story = (args: ButtonDirective) => ({ +export const Disabled = AllStylesTemplate.bind({}); +Disabled.args = { + disabled: true, + loading: false, +}; + +const DisabledWithAttributeTemplate: Story = (args) => ({ + props: args, + template: ` + + + + + + + + + + + `, +}); + +export const DisabledWithAttribute = DisabledWithAttributeTemplate.bind({}); +DisabledWithAttribute.args = { + disabled: true, + loading: false, +}; + +const BlockTemplate: Story = (args: ButtonComponent) => ({ props: args, template: ` diff --git a/libs/components/src/button/index.ts b/libs/components/src/button/index.ts index 1bdd62ddbcf..ff86120cb11 100644 --- a/libs/components/src/button/index.ts +++ b/libs/components/src/button/index.ts @@ -1,2 +1,2 @@ -export * from "./button.directive"; +export * from "./button.component"; export * from "./button.module"; diff --git a/libs/components/src/index.ts b/libs/components/src/index.ts index 1f1ae6a8d2b..264c655d80f 100644 --- a/libs/components/src/index.ts +++ b/libs/components/src/index.ts @@ -7,7 +7,6 @@ export * from "./icon"; export * from "./icon-button"; export * from "./menu"; export * from "./dialog"; -export * from "./submit-button"; export * from "./link"; export * from "./tabs"; export * from "./toggle-group"; diff --git a/libs/components/src/submit-button/index.ts b/libs/components/src/submit-button/index.ts deleted file mode 100644 index ae7d96d2c1a..00000000000 --- a/libs/components/src/submit-button/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./submit-button.module"; diff --git a/libs/components/src/submit-button/submit-button.component.html b/libs/components/src/submit-button/submit-button.component.html deleted file mode 100644 index 9d9657ba7ee..00000000000 --- a/libs/components/src/submit-button/submit-button.component.html +++ /dev/null @@ -1,16 +0,0 @@ - diff --git a/libs/components/src/submit-button/submit-button.component.ts b/libs/components/src/submit-button/submit-button.component.ts deleted file mode 100644 index 27408349da7..00000000000 --- a/libs/components/src/submit-button/submit-button.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component, HostBinding, Input } from "@angular/core"; - -import { ButtonTypes } from "../button"; - -@Component({ - selector: "bit-submit-button", - templateUrl: "./submit-button.component.html", -}) -export class SubmitButtonComponent { - @Input() buttonType: ButtonTypes = "primary"; - @Input() disabled = false; - @Input() loading: boolean; - - @Input() block?: boolean; - - @HostBinding("class") get classList() { - return this.block == null || this.block === false ? [] : ["tw-w-full", "tw-block"]; - } -} diff --git a/libs/components/src/submit-button/submit-button.module.ts b/libs/components/src/submit-button/submit-button.module.ts deleted file mode 100644 index c7ab7567e64..00000000000 --- a/libs/components/src/submit-button/submit-button.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CommonModule } from "@angular/common"; -import { NgModule } from "@angular/core"; - -import { ButtonModule } from "../button"; - -import { SubmitButtonComponent } from "./submit-button.component"; - -@NgModule({ - imports: [CommonModule, ButtonModule], - exports: [SubmitButtonComponent], - declarations: [SubmitButtonComponent], -}) -export class SubmitButtonModule {} diff --git a/libs/components/src/submit-button/submit-button.stories.ts b/libs/components/src/submit-button/submit-button.stories.ts deleted file mode 100644 index cf19b1c8e4b..00000000000 --- a/libs/components/src/submit-button/submit-button.stories.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Meta, moduleMetadata, Story } from "@storybook/angular"; - -import { SubmitButtonComponent } from "./submit-button.component"; -import { SubmitButtonModule } from "./submit-button.module"; - -export default { - title: "Component Library/Submit Button", - component: SubmitButtonComponent, - decorators: [ - moduleMetadata({ - imports: [SubmitButtonModule], - }), - ], - args: { - buttonType: "primary", - loading: false, - block: false, - }, - parameters: { - design: { - type: "figma", - url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library?node-id=1881%3A16733", - }, - }, -} as Meta; - -const Template: Story = (args: SubmitButtonComponent) => ({ - props: args, - template: ` - Submit - `, -}); - -export const Primary = Template.bind({}); -Primary.args = {}; - -export const Loading = Template.bind({}); -Loading.args = { - loading: true, -}; - -export const Disabled = Template.bind({}); -Disabled.args = { - disabled: true, -};