1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-06 00:13:28 +00:00

Migrate remaining components to standalone in libs/components (#15053)

Migrates the remaining non standalone components from libs/components. Also resolved some linting ignores and applying strict typescript.
This commit is contained in:
Oscar Hinton
2025-06-05 09:52:53 +02:00
committed by GitHub
parent 7386a4fa9e
commit e8e2181252
12 changed files with 57 additions and 109 deletions

View File

@@ -85,11 +85,11 @@ import { IconComponent } from "./vault/components/icon.component";
TextDragDirective,
CopyClickDirective,
A11yTitleDirective,
AutofocusDirective,
],
declarations: [
A11yInvalidDirective,
ApiActionDirective,
AutofocusDirective,
BoxRowDirective,
DeprecatedCalloutComponent,
CopyTextDirective,

View File

@@ -1,7 +1,5 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { Component, DebugElement } from "@angular/core";
import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { By } from "@angular/platform-browser";
import { ButtonModule } from "./index";
@@ -13,21 +11,18 @@ describe("Button", () => {
let disabledButtonDebugElement: DebugElement;
let linkDebugElement: DebugElement;
beforeEach(waitForAsync(() => {
beforeEach(async () => {
TestBed.configureTestingModule({
imports: [ButtonModule],
declarations: [TestApp],
imports: [TestApp],
});
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
TestBed.compileComponents();
await TestBed.compileComponents();
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"));
}));
});
it("should not be disabled when loading and disabled are false", () => {
testAppComponent.loading = false;
@@ -85,11 +80,11 @@ describe("Button", () => {
<button id="disabled" type="button" bitButton disabled>Button</button>
`,
standalone: false,
imports: [ButtonModule],
})
class TestApp {
buttonType: string;
block: boolean;
disabled: boolean;
loading: boolean;
buttonType?: string;
block?: boolean;
disabled?: boolean;
loading?: boolean;
}

View File

@@ -1,18 +1,15 @@
import { DIALOG_DATA, DialogModule, DialogRef } from "@angular/cdk/dialog";
import { DIALOG_DATA, DialogRef } from "@angular/cdk/dialog";
import { Component, Inject } from "@angular/core";
import { provideAnimations } from "@angular/platform-browser/animations";
import { Meta, StoryObj, moduleMetadata } from "@storybook/angular";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { ButtonModule } from "../button";
import { IconButtonModule } from "../icon-button";
import { SharedModule } from "../shared";
import { I18nMockService } from "../utils/i18n-mock.service";
import { DialogComponent } from "./dialog/dialog.component";
import { DialogModule } from "./dialog.module";
import { DialogService } from "./dialog.service";
import { DialogCloseDirective } from "./directives/dialog-close.directive";
import { DialogTitleContainerDirective } from "./directives/dialog-title-container.directive";
interface Animal {
animal: string;
@@ -20,7 +17,7 @@ interface Animal {
@Component({
template: `<button bitButton type="button" (click)="openDialog()">Open Dialog</button>`,
standalone: false,
imports: [ButtonModule],
})
class StoryDialogComponent {
constructor(public dialogService: DialogService) {}
@@ -50,7 +47,7 @@ class StoryDialogComponent {
</ng-container>
</bit-dialog>
`,
standalone: false,
imports: [DialogModule, ButtonModule],
})
class StoryDialogContentComponent {
constructor(
@@ -68,17 +65,8 @@ export default {
component: StoryDialogComponent,
decorators: [
moduleMetadata({
declarations: [StoryDialogContentComponent],
imports: [
SharedModule,
ButtonModule,
DialogModule,
IconButtonModule,
DialogCloseDirective,
DialogComponent,
DialogTitleContainerDirective,
],
providers: [
provideAnimations(),
DialogService,
{
provide: I18nService,

View File

@@ -1,6 +1,6 @@
import { Component } from "@angular/core";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular";
import { provideAnimations } from "@angular/platform-browser/animations";
import { Meta, StoryObj, applicationConfig } from "@storybook/angular";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -31,7 +31,7 @@ import { DialogModule } from "../../dialog.module";
</bit-callout>
}
`,
standalone: false,
imports: [ButtonModule, CalloutModule, DialogModule],
})
class StoryDialogComponent {
protected dialogs: { title: string; dialogs: SimpleDialogOptions[] }[] = [
@@ -147,11 +147,9 @@ export default {
title: "Component Library/Dialogs/Service/SimpleConfigurable",
component: StoryDialogComponent,
decorators: [
moduleMetadata({
imports: [ButtonModule, BrowserAnimationsModule, DialogModule, CalloutModule],
}),
applicationConfig({
providers: [
provideAnimations(),
{
provide: I18nService,
useFactory: () => {

View File

@@ -1,13 +1,11 @@
import { DialogRef, DIALOG_DATA } from "@angular/cdk/dialog";
import { Component, Inject } from "@angular/core";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { provideAnimations } from "@angular/platform-browser/animations";
import { Meta, StoryObj, moduleMetadata } from "@storybook/angular";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { ButtonModule } from "../../button";
import { IconButtonModule } from "../../icon-button";
import { SharedModule } from "../../shared/shared.module";
import { I18nMockService } from "../../utils/i18n-mock.service";
import { DialogModule } from "../dialog.module";
import { DialogService } from "../dialog.service";
@@ -18,7 +16,7 @@ interface Animal {
@Component({
template: `<button type="button" bitButton (click)="openDialog()">Open Simple Dialog</button>`,
standalone: false,
imports: [ButtonModule],
})
class StoryDialogComponent {
constructor(public dialogService: DialogService) {}
@@ -49,7 +47,7 @@ class StoryDialogComponent {
</ng-container>
</bit-simple-dialog>
`,
standalone: false,
imports: [ButtonModule, DialogModule],
})
class StoryDialogContentComponent {
constructor(
@@ -67,15 +65,8 @@ export default {
component: StoryDialogComponent,
decorators: [
moduleMetadata({
declarations: [StoryDialogContentComponent],
imports: [
SharedModule,
IconButtonModule,
ButtonModule,
BrowserAnimationsModule,
DialogModule,
],
providers: [
provideAnimations(),
DialogService,
{
provide: I18nService,

View File

@@ -6,7 +6,6 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
import { IconButtonModule } from "../icon-button";
import { BitIconButtonComponent } from "../icon-button/icon-button.component";
import { InputModule } from "../input/input.module";
import { I18nMockService } from "../utils/i18n-mock.service";
import { BitFormFieldControl } from "./form-field-control";
@@ -25,7 +24,7 @@ import { BitPasswordInputToggleDirective } from "./password-input-toggle.directi
</bit-form-field>
</form>
`,
standalone: false,
imports: [FormFieldModule, IconButtonModule],
})
class TestFormFieldComponent {}
@@ -37,8 +36,7 @@ describe("PasswordInputToggle", () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [FormFieldModule, IconButtonModule, InputModule],
declarations: [TestFormFieldComponent],
imports: [TestFormFieldComponent],
providers: [
{
provide: I18nService,

View File

@@ -19,7 +19,6 @@ import { FocusableElement } from "../shared/focusable-element";
*/
@Directive({
selector: "[appAutofocus], [bitAutofocus]",
standalone: false,
})
export class AutofocusDirective implements AfterContentChecked {
@Input() set appAutofocus(condition: boolean | string) {

View File

@@ -1,5 +1,5 @@
import { Component } from "@angular/core";
import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { By } from "@angular/platform-browser";
import { MenuTriggerForDirective } from "./menu-trigger-for.directive";
@@ -16,19 +16,16 @@ describe("Menu", () => {
// The overlay is created outside the root debugElement, so we need to query its parent
const getBitMenuPanel = () => document.querySelector(".bit-menu-panel");
beforeEach(waitForAsync(() => {
beforeEach(async () => {
TestBed.configureTestingModule({
imports: [MenuModule],
declarations: [TestApp],
imports: [TestApp],
});
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
TestBed.compileComponents();
await TestBed.compileComponents();
fixture = TestBed.createComponent(TestApp);
fixture.detectChanges();
}));
});
it("should open when the trigger is clicked", async () => {
const buttonDebugElement = fixture.debugElement.query(By.directive(MenuTriggerForDirective));
@@ -73,6 +70,6 @@ describe("Menu", () => {
<a id="item2" bitMenuItem>Item 2</a>
</bit-menu>
`,
standalone: false,
imports: [MenuModule],
})
class TestApp {}

View File

@@ -1,7 +1,5 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { Component } from "@angular/core";
import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { By } from "@angular/platform-browser";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -17,26 +15,23 @@ describe("RadioButton", () => {
let testAppComponent: TestApp;
let radioButton: HTMLInputElement;
beforeEach(waitForAsync(() => {
beforeEach(async () => {
mockGroupComponent = new MockedButtonGroupComponent();
TestBed.configureTestingModule({
imports: [RadioButtonModule],
declarations: [TestApp],
imports: [TestApp],
providers: [
{ provide: RadioGroupComponent, useValue: mockGroupComponent },
{ provide: I18nService, useValue: new I18nMockService({}) },
],
});
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
TestBed.compileComponents();
await TestBed.compileComponents();
fixture = TestBed.createComponent(TestApp);
fixture.detectChanges();
testAppComponent = fixture.debugElement.componentInstance;
radioButton = fixture.debugElement.query(By.css("input[type=radio]")).nativeElement;
}));
});
it("should emit value when clicking on radio button", () => {
testAppComponent.value = "value";
@@ -77,7 +72,7 @@ class MockedButtonGroupComponent implements Partial<RadioGroupComponent> {
@Component({
selector: "test-app",
template: `<bit-radio-button [value]="value"><bit-label>Element</bit-label></bit-radio-button>`,
standalone: false,
imports: [RadioButtonModule],
})
class TestApp {
value?: string;

View File

@@ -1,5 +1,5 @@
import { Component } from "@angular/core";
import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { FormsModule } from "@angular/forms";
import { By } from "@angular/platform-browser";
@@ -16,16 +16,13 @@ describe("RadioGroupComponent", () => {
let buttonElements: RadioButtonComponent[];
let radioButtons: HTMLInputElement[];
beforeEach(waitForAsync(() => {
beforeEach(async () => {
TestBed.configureTestingModule({
imports: [FormsModule, RadioButtonModule],
declarations: [TestApp],
imports: [TestApp],
providers: [{ provide: I18nService, useValue: new I18nMockService({}) }],
});
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
TestBed.compileComponents();
await TestBed.compileComponents();
fixture = TestBed.createComponent(TestApp);
fixture.detectChanges();
testAppComponent = fixture.debugElement.componentInstance;
@@ -37,7 +34,7 @@ describe("RadioGroupComponent", () => {
.map((e) => e.nativeElement);
fixture.detectChanges();
}));
});
it("should select second element when setting selected to second", async () => {
testAppComponent.selected = "second";
@@ -75,7 +72,7 @@ describe("RadioGroupComponent", () => {
<bit-radio-button value="third">Third</bit-radio-button>
</bit-radio-group>
`,
standalone: false,
imports: [FormsModule, RadioButtonModule],
})
class TestApp {
selected?: string;

View File

@@ -1,7 +1,5 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { Component } from "@angular/core";
import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { By } from "@angular/platform-browser";
import { ToggleGroupModule } from "./toggle-group.module";
@@ -13,15 +11,12 @@ describe("Button", () => {
let buttonElements: ToggleComponent<unknown>[];
let radioButtons: HTMLInputElement[];
beforeEach(waitForAsync(() => {
beforeEach(async () => {
TestBed.configureTestingModule({
imports: [ToggleGroupModule],
declarations: [TestApp],
imports: [TestApp],
});
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
TestBed.compileComponents();
await TestBed.compileComponents();
fixture = TestBed.createComponent(TestApp);
testAppComponent = fixture.debugElement.componentInstance;
buttonElements = fixture.debugElement
@@ -32,7 +27,7 @@ describe("Button", () => {
.map((e) => e.nativeElement);
fixture.detectChanges();
}));
});
it("should select second element when setting selected to second", () => {
testAppComponent.selected = "second";
@@ -67,7 +62,7 @@ describe("Button", () => {
<bit-toggle value="third">Third</bit-toggle>
</bit-toggle-group>
`,
standalone: false,
imports: [ToggleGroupModule],
})
class TestApp {
selected?: string;

View File

@@ -1,7 +1,5 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { Component } from "@angular/core";
import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { By } from "@angular/platform-browser";
import { ToggleGroupComponent } from "./toggle-group.component";
@@ -13,22 +11,19 @@ describe("Button", () => {
let testAppComponent: TestApp;
let radioButton: HTMLInputElement;
beforeEach(waitForAsync(() => {
beforeEach(async () => {
mockGroupComponent = new MockedButtonGroupComponent();
TestBed.configureTestingModule({
imports: [ToggleGroupModule],
declarations: [TestApp],
imports: [TestApp],
providers: [{ provide: ToggleGroupComponent, useValue: mockGroupComponent }],
});
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
TestBed.compileComponents();
await TestBed.compileComponents();
fixture = TestBed.createComponent(TestApp);
testAppComponent = fixture.debugElement.componentInstance;
radioButton = fixture.debugElement.query(By.css("input[type=radio]")).nativeElement;
}));
});
it("should emit value when clicking on radio button", () => {
testAppComponent.value = "value";
@@ -69,7 +64,7 @@ class MockedButtonGroupComponent implements Partial<ToggleGroupComponent> {
@Component({
selector: "test-app",
template: ` <bit-toggle [value]="value">Element</bit-toggle>`,
standalone: false,
imports: [ToggleGroupModule],
})
class TestApp {
value?: string;