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

UIF - Prefer signal & change detection (#16940)

This commit is contained in:
Oscar Hinton
2025-10-21 18:52:40 +02:00
committed by GitHub
parent d3fc20f8b9
commit 65da23feaa
135 changed files with 503 additions and 51 deletions

View File

@@ -1,5 +1,7 @@
import { Component } from "@angular/core";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "popup-footer",
templateUrl: "popup-footer.component.html",

View File

@@ -16,6 +16,8 @@ import { PopupRouterCacheService } from "../view-cache/popup-router-cache.servic
import { PopupPageComponent } from "./popup-page.component";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "popup-header",
templateUrl: "popup-header.component.html",
@@ -23,13 +25,19 @@ import { PopupPageComponent } from "./popup-page.component";
})
export class PopupHeaderComponent {
private popupRouterCacheService = inject(PopupRouterCacheService);
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
protected pageContentScrolled: Signal<boolean> = inject(PopupPageComponent).isScrolled;
/** Background color */
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
background: "default" | "alt" = "default";
/** Display the back button, which uses Location.back() to go back one page in history */
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
get showBackButton() {
return this._showBackButton;
@@ -41,6 +49,8 @@ export class PopupHeaderComponent {
private _showBackButton = false;
/** Title string that will be inserted as an h1 */
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input({ required: true }) pageTitle: string;
/**
@@ -48,6 +58,8 @@ export class PopupHeaderComponent {
*
* If unset, will call `location.back()`
**/
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
backAction: FunctionReturningAwaitable = async () => {
return this.popupRouterCacheService.back();

View File

@@ -41,6 +41,8 @@ import { PopupHeaderComponent } from "./popup-header.component";
import { PopupPageComponent } from "./popup-page.component";
import { PopupTabNavigationComponent } from "./popup-tab-navigation.component";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "extension-container",
template: `
@@ -51,6 +53,8 @@ import { PopupTabNavigationComponent } from "./popup-tab-navigation.component";
})
class ExtensionContainerComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "extension-popped-container",
template: `
@@ -62,6 +66,8 @@ class ExtensionContainerComponent {}
})
class ExtensionPoppedContainerComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "vault-placeholder",
template: /*html*/ `
@@ -95,6 +101,8 @@ class VaultComponent {
protected data = Array.from(Array(20).keys());
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "mock-add-button",
template: `
@@ -107,6 +115,8 @@ class VaultComponent {
})
class MockAddButtonComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "mock-popout-button",
template: `
@@ -116,6 +126,8 @@ class MockAddButtonComponent {}
})
class MockPopoutButtonComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "mock-current-account",
template: `
@@ -127,6 +139,8 @@ class MockPopoutButtonComponent {}
})
class MockCurrentAccountComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "mock-search",
template: ` <bit-search placeholder="Search"> </bit-search> `,
@@ -134,6 +148,8 @@ class MockCurrentAccountComponent {}
})
class MockSearchComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "mock-banner",
template: `
@@ -145,6 +161,8 @@ class MockSearchComponent {}
})
class MockBannerComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "mock-vault-page",
template: `
@@ -172,6 +190,8 @@ class MockBannerComponent {}
})
class MockVaultPageComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "mock-vault-page-popped",
template: `
@@ -195,6 +215,8 @@ class MockVaultPageComponent {}
})
class MockVaultPagePoppedComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "mock-generator-page",
template: `
@@ -219,6 +241,8 @@ class MockVaultPagePoppedComponent {}
})
class MockGeneratorPageComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "mock-send-page",
template: `
@@ -243,6 +267,8 @@ class MockGeneratorPageComponent {}
})
class MockSendPageComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "mock-settings-page",
template: `
@@ -267,6 +293,8 @@ class MockSendPageComponent {}
})
class MockSettingsPageComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "mock-vault-subpage",
template: `

View File

@@ -4,6 +4,8 @@ import { booleanAttribute, Component, inject, Input, signal } from "@angular/cor
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { ScrollLayoutHostDirective } from "@bitwarden/components";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "popup-page",
templateUrl: "popup-page.component.html",
@@ -15,15 +17,23 @@ import { ScrollLayoutHostDirective } from "@bitwarden/components";
export class PopupPageComponent {
protected i18nService = inject(I18nService);
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input() loading = false;
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input({ transform: booleanAttribute })
disablePadding = false;
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
protected scrolled = signal(false);
isScrolled = this.scrolled.asReadonly();
/** Accessible loading label for the spinner. Defaults to "loading" */
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input() loadingText?: string = this.i18nService.t("loading");
handleScroll(event: Event) {

View File

@@ -15,6 +15,8 @@ export type NavButton = {
showBerry?: boolean;
};
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "popup-tab-navigation",
templateUrl: "popup-tab-navigation.component.html",
@@ -24,6 +26,8 @@ export type NavButton = {
},
})
export class PopupTabNavigationComponent {
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input() navButtons: NavButton[] = [];
constructor(private i18nService: I18nService) {}

View File

@@ -29,6 +29,8 @@ export interface ExtensionAnonLayoutWrapperData extends AnonLayoutWrapperData {
hideFooter?: boolean;
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
templateUrl: "extension-anon-layout-wrapper.component.html",
imports: [

View File

@@ -164,6 +164,8 @@ type Story = StoryObj<ExtensionAnonLayoutWrapperComponent>;
// Default Example
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-default-primary-outlet-example-component",
template: "<p>Primary Outlet Example: <br> your primary component goes here</p>",
@@ -171,6 +173,8 @@ type Story = StoryObj<ExtensionAnonLayoutWrapperComponent>;
})
class DefaultPrimaryOutletExampleComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-default-secondary-outlet-example-component",
template: "<p>Secondary Outlet Example: <br> your secondary component goes here</p>",
@@ -178,6 +182,8 @@ class DefaultPrimaryOutletExampleComponent {}
})
class DefaultSecondaryOutletExampleComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-default-env-selector-outlet-example-component",
template: "<p>Env Selector Outlet Example: <br> your env selector component goes here</p>",
@@ -261,6 +267,8 @@ const changedData: ExtensionAnonLayoutWrapperData = {
showLogo: false,
};
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-dynamic-content-example-component",
template: `

View File

@@ -7,6 +7,8 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { EnvironmentSelectorComponent } from "../components/environment-selector/environment-selector.component";
import { SharedModule } from "../shared";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "app-frontend-layout",
templateUrl: "frontend-layout.component.html",

View File

@@ -14,6 +14,8 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { UserId } from "@bitwarden/common/types/guid";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "app-header",
templateUrl: "./web-header.component.html",
@@ -23,11 +25,15 @@ export class WebHeaderComponent {
/**
* Custom title that overrides the route data `titleId`
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input() title: string;
/**
* Icon to show before the title
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input() icon: string;
protected routeData$: Observable<{ titleId: string }>;

View File

@@ -46,6 +46,8 @@ class MockStateService {
accounts$ = new BehaviorSubject({ "1": { profile: { name: "Foo" } } }).asObservable();
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "product-switcher",
template: `<button type="button" bitIconButton="bwi-filter" label="Switch products"></button>`,
@@ -53,6 +55,8 @@ class MockStateService {
})
class MockProductSwitcher {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "dynamic-avatar",
template: `<bit-avatar [text]="name$ | async"></bit-avatar>`,
@@ -68,6 +72,8 @@ class MockDynamicAvatar implements Partial<DynamicAvatarComponent> {
),
);
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
text?: string;

View File

@@ -14,6 +14,8 @@ import { DialogService, NavigationModule } from "@bitwarden/components";
import { OrganizationWarningsModule } from "@bitwarden/web-vault/app/billing/organizations/warnings/organization-warnings.module";
import { OrganizationWarningsService } from "@bitwarden/web-vault/app/billing/organizations/warnings/services";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "org-switcher",
templateUrl: "org-switcher.component.html",
@@ -43,20 +45,28 @@ export class OrgSwitcherComponent {
* const smFilter = (org: Organization) => org.canAccessSecretsManager
* // <org-switcher [filter]="smFilter">
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
filter: (org: Organization) => boolean = () => true;
/**
* Is `true` if the expanded content is visible
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
open = false;
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output()
openChange = new EventEmitter<boolean>();
/**
* Visibility of the New Organization button
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
hideNewButton = false;

View File

@@ -16,6 +16,8 @@ import { ProductSwitcherItem, ProductSwitcherService } from "../shared/product-s
import { NavigationProductSwitcherComponent } from "./navigation-switcher.component";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "app-upgrade-nav-button",
template: "<div>Upgrade Nav Button</div>",

View File

@@ -3,6 +3,8 @@ import { map, Observable } from "rxjs";
import { ProductSwitcherItem, ProductSwitcherService } from "../shared/product-switcher.service";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "navigation-product-switcher",
templateUrl: "./navigation-switcher.component.html",

View File

@@ -37,6 +37,8 @@ class MockOrganizationService implements Partial<OrganizationService> {
return MockOrganizationService._orgs.asObservable();
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
set mockOrgs(orgs: Organization[]) {
MockOrganizationService._orgs.next(orgs);
@@ -54,6 +56,8 @@ class MockProviderService implements Partial<ProviderService> {
return MockProviderService._providers.asObservable();
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
set mockProviders(providers: Provider[]) {
MockProviderService._providers.next(providers);
@@ -93,6 +97,8 @@ class MockConfigService implements Partial<ConfigService> {
}
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "story-layout",
template: `<ng-content></ng-content>`,
@@ -100,6 +106,8 @@ class MockConfigService implements Partial<ConfigService> {
})
class StoryLayoutComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "story-content",
template: ``,

View File

@@ -6,12 +6,16 @@ import { MenuComponent } from "@bitwarden/components";
import { ProductSwitcherService } from "./shared/product-switcher.service";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "product-switcher-content",
templateUrl: "./product-switcher-content.component.html",
standalone: false,
})
export class ProductSwitcherContentComponent {
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@ViewChild("menu")
menu: MenuComponent;

View File

@@ -5,6 +5,8 @@ import { AfterViewInit, ChangeDetectorRef, Component, Input } from "@angular/cor
import { IconButtonType } from "@bitwarden/components/src/icon-button/icon-button.component";
import { ProductSwitcherService } from "./shared/product-switcher.service";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "product-switcher",
templateUrl: "./product-switcher.component.html",
@@ -14,6 +16,8 @@ export class ProductSwitcherComponent implements AfterViewInit {
/**
* Passed to the product switcher's `bitIconButton`
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
buttonType: IconButtonType = "main";

View File

@@ -37,6 +37,8 @@ class MockOrganizationService implements Partial<OrganizationService> {
return MockOrganizationService._orgs.asObservable();
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
set mockOrgs(orgs: Organization[]) {
MockOrganizationService._orgs.next(orgs);
@@ -54,6 +56,8 @@ class MockProviderService implements Partial<ProviderService> {
return MockProviderService._providers.asObservable();
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
set mockProviders(providers: Provider[]) {
MockProviderService._providers.next(providers);
@@ -93,6 +97,8 @@ class MockConfigService implements Partial<ConfigService> {
}
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "story-layout",
template: `<ng-content></ng-content>`,
@@ -100,6 +106,8 @@ class MockConfigService implements Partial<ConfigService> {
})
class StoryLayoutComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "story-content",
template: ``,

View File

@@ -4,6 +4,8 @@ import { Component } from "@angular/core";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { NavigationModule } from "@bitwarden/components";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "app-toggle-width",
template: `<bit-nav-item

View File

@@ -16,6 +16,8 @@ import { BillingFreeFamiliesNavItemComponent } from "../billing/shared/billing-f
import { WebLayoutModule } from "./web-layout.module";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "app-user-layout",
templateUrl: "user-layout.component.html",

View File

@@ -5,6 +5,8 @@ import { LayoutComponent } from "@bitwarden/components";
import { ProductSwitcherModule } from "./product-switcher/product-switcher.module";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "app-layout",
templateUrl: "web-layout.component.html",

View File

@@ -6,11 +6,15 @@ import { SideNavVariant, NavigationModule } from "@bitwarden/components";
import { ProductSwitcherModule } from "./product-switcher/product-switcher.module";
import { ToggleWidthComponent } from "./toggle-width.component";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "app-side-nav",
templateUrl: "web-side-nav.component.html",
imports: [CommonModule, NavigationModule, ProductSwitcherModule, ToggleWidthComponent],
})
export class WebSideNavComponent {
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input() variant: SideNavVariant = "primary";
}

View File

@@ -6,7 +6,7 @@ import { setA11yTitleAndAriaLabel } from "./set-a11y-title-and-aria-label";
selector: "[appA11yTitle]",
})
export class A11yTitleDirective {
title = input.required<string>({ alias: "appA11yTitle" });
readonly title = input.required<string>({ alias: "appA11yTitle" });
constructor(private el: ElementRef) {
const originalTitle = this.el.nativeElement.getAttribute("title");

View File

@@ -46,6 +46,8 @@ export interface AnonLayoutWrapperData {
hideBackgroundIllustration?: boolean;
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
templateUrl: "anon-layout-wrapper.component.html",
imports: [AnonLayoutComponent, RouterModule],

View File

@@ -103,6 +103,8 @@ type Story = StoryObj<AnonLayoutWrapperComponent>;
// Default Example
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-default-primary-outlet-example-component",
template: "<p>Primary Outlet Example: <br> your primary component goes here</p>",
@@ -110,6 +112,8 @@ type Story = StoryObj<AnonLayoutWrapperComponent>;
})
export class DefaultPrimaryOutletExampleComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-default-secondary-outlet-example-component",
template: "<p>Secondary Outlet Example: <br> your secondary component goes here</p>",
@@ -117,6 +121,8 @@ export class DefaultPrimaryOutletExampleComponent {}
})
export class DefaultSecondaryOutletExampleComponent {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-default-env-selector-outlet-example-component",
template: "<p>Env Selector Outlet Example: <br> your env selector component goes here</p>",
@@ -192,6 +198,8 @@ const changedData: AnonLayoutWrapperData = {
pageIcon: RegistrationCheckEmailIcon,
};
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-dynamic-content-example-component",
template: `

View File

@@ -27,6 +27,8 @@ import { TypographyModule } from "../typography";
export type AnonLayoutMaxWidth = "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "auth-anon-layout",
templateUrl: "./anon-layout.component.html",

View File

@@ -1,5 +1,7 @@
import { Component } from "@angular/core";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "app-root",
template: "",

View File

@@ -39,6 +39,8 @@ const template = `
<button class="tw-me-2" type="button" buttonType="muted" bitIconButton="bwi-star" label="Delete" bitFormButton [bitAction]="delete">Delete</button>
</form>`;
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "app-promise-example",
template,
@@ -84,6 +86,8 @@ class PromiseExampleComponent {
};
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "app-observable-example",
template,

View File

@@ -20,6 +20,8 @@ const template = /*html*/ `
</button>
<button type="button" label="Delete" bitIconButton="bwi-trash" buttonType="danger" [bitAction]="action"></button>`;
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template,
selector: "app-promise-example",
@@ -37,6 +39,8 @@ class PromiseExampleComponent {
};
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template,
selector: "app-action-resolves-quickly",
@@ -55,6 +59,8 @@ class ActionResolvesQuicklyComponent {
};
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template,
selector: "app-observable-example",
@@ -66,6 +72,8 @@ class ObservableExampleComponent {
};
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template,
selector: "app-rejected-promise-example",

View File

@@ -19,6 +19,8 @@ const SizeClasses: Record<SizeTypes, string[]> = {
* A variance in color across the avatar component is important as it is used in Account Switching as a
* visual indicator to recognize which of a personal or work account a user is logged into.
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-avatar",
template: `

View File

@@ -8,6 +8,8 @@ function transformMaxItems(value: number | undefined) {
return value == undefined ? undefined : Math.max(1, value);
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-badge-list",
templateUrl: "badge-list.component.html",

View File

@@ -55,6 +55,8 @@ const hoverStyles: Record<BadgeVariant, string[]> = {
* > `NOTE:` The `disabled` state only applies to buttons.
*
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "span[bitBadge], a[bitBadge], button[bitBadge]",
providers: [{ provide: FocusableElement, useExisting: BadgeComponent }],

View File

@@ -23,6 +23,8 @@ const defaultIcon: Record<BannerType, string> = {
* - Avoid stacking multiple banners.
* - Banners can contain a button or anchor that uses the `bitLink` directive with `linkType="secondary"`.
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-banner",
templateUrl: "./banner.component.html",
@@ -40,6 +42,8 @@ export class BannerComponent implements OnInit {
readonly useAlertRole = input(true);
readonly showClose = input(true);
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output() onClose = new EventEmitter<void>();
ngOnInit(): void {

View File

@@ -1,6 +1,8 @@
import { Component, EventEmitter, Output, TemplateRef, input, viewChild } from "@angular/core";
import { QueryParamsHandling } from "@angular/router";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-breadcrumb",
templateUrl: "./breadcrumb.component.html",
@@ -14,6 +16,8 @@ export class BreadcrumbComponent {
readonly queryParamsHandling = input<QueryParamsHandling>();
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output()
click = new EventEmitter();

View File

@@ -15,6 +15,8 @@ import { BreadcrumbComponent } from "./breadcrumb.component";
* Bitwarden uses this component to indicate the user's current location in a set of data organized in
* containers (Collections, Folders, or Projects).
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-breadcrumbs",
templateUrl: "./breadcrumbs.component.html",
@@ -25,6 +27,8 @@ export class BreadcrumbsComponent {
private breadcrumbs: BreadcrumbComponent[] = [];
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@ContentChildren(BreadcrumbComponent)
protected set breadcrumbList(value: QueryList<BreadcrumbComponent>) {
this.breadcrumbs = value.toArray();

View File

@@ -18,6 +18,8 @@ interface Breadcrumb {
route: string;
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template: "",
})

View File

@@ -56,6 +56,8 @@ describe("Button", () => {
});
});
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "test-app",
template: `

View File

@@ -57,6 +57,8 @@ const buttonStyles: Record<ButtonType, string[]> = {
unstyled: [],
};
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "button[bitButton], a[bitButton]",
templateUrl: "button.component.html",
@@ -97,7 +99,7 @@ export class ButtonComponent implements ButtonLikeAbstraction {
.concat(buttonSizeStyles[this.size() || "default"]);
}
protected disabledAttr = computed(() => {
protected readonly disabledAttr = computed(() => {
const disabled = this.disabled() != null && this.disabled() !== false;
return disabled || this.loading();
});
@@ -110,7 +112,7 @@ export class ButtonComponent implements ButtonLikeAbstraction {
* We can't use `disabledAttr` for this, because it returns `true` when `loading` is `true`.
* We only want to show disabled styles during loading if `showLoadingStyles` is `true`.
*/
protected showDisabledStyles = computed(() => {
protected readonly showDisabledStyles = computed(() => {
return this.showLoadingStyle() || (this.disabledAttr() && this.loading() === false);
});
@@ -134,11 +136,11 @@ export class ButtonComponent implements ButtonLikeAbstraction {
* This pattern of converting a signal to an observable and back to a signal is not
* recommended. TODO -- find better way to use debounce with signals (CL-596)
*/
protected showLoadingStyle = toSignal(
protected readonly showLoadingStyle = toSignal(
toObservable(this.loading).pipe(debounce((isLoading) => interval(isLoading ? 75 : 0))),
);
disabled = model<boolean>(false);
readonly disabled = model<boolean>(false);
private el = inject(ElementRef<HTMLButtonElement>);
constructor() {

View File

@@ -28,6 +28,8 @@ let nextId = 0;
* sparingly, as they command a large amount of visual attention. Avoid using more than 1 callout in
* the same location.
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-callout",
templateUrl: "callout.component.html",

View File

@@ -3,6 +3,8 @@ import { NgControl, Validators } from "@angular/forms";
import { BitFormControlAbstraction } from "../form-control";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "input[type=checkbox][bitCheckbox]",
template: "",

View File

@@ -28,6 +28,8 @@ const template = /*html*/ `
</form>
`;
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "app-example",
template,
@@ -38,10 +40,14 @@ class ExampleComponent {
checkbox: [false, Validators.requiredTrue],
});
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input() set checked(value: boolean) {
this.formObj.patchValue({ checkbox: value });
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input() set disabled(disable: boolean) {
if (disable) {
this.formObj.disable();

View File

@@ -35,6 +35,8 @@ export type ChipSelectOption<T> = Option<T> & {
/**
* `<bit-chip-select>` is a select element that is commonly used to filter items in lists or tables.
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-chip-select",
templateUrl: "chip-select.component.html",
@@ -49,6 +51,8 @@ export type ChipSelectOption<T> = Option<T> & {
})
export class ChipSelectComponent<T = unknown> implements ControlValueAccessor, AfterViewInit {
readonly menu = viewChild(MenuComponent);
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@ViewChildren(MenuItemDirective) menuItems?: QueryList<MenuItemDirective>;
readonly chipSelectButton = viewChild<ElementRef<HTMLButtonElement>>("chipSelectButton");
@@ -63,6 +67,8 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor, A
// TODO: Skipped for signal migration because:
// Accessor inputs cannot be migrated as they are too complex.
/** The select options to render */
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input({ required: true })
get options(): ChipSelectOption<T>[] {
return this._options;
@@ -75,6 +81,8 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor, A
/** Disables the entire chip */
// TODO: Skipped for signal migration because:
// Your application code writes to the input. This prevents migration.
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input({ transform: booleanAttribute }) disabled = false;
/** Chip will stretch to full width of its container */
@@ -83,7 +91,7 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor, A
/**
* We have `:focus-within` and `:focus-visible` but no `:focus-visible-within`
*/
protected focusVisibleWithin = signal(false);
protected readonly focusVisibleWithin = signal(false);
@HostListener("focusin", ["$event.target"])
onFocusIn(target: HTMLElement) {
this.focusVisibleWithin.set(target.matches("[data-fvw-target]:focus-visible"));

View File

@@ -9,6 +9,8 @@ type CharacterType = "letter" | "emoji" | "special" | "number";
* the logic for displaying letters as `text-main`, numbers as `primary`, and special symbols as
* `danger`.
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-color-password",
template: `@for (character of passwordCharArray(); track $index; let i = $index) {
@@ -21,11 +23,11 @@ type CharacterType = "letter" | "emoji" | "special" | "number";
}`,
})
export class ColorPasswordComponent {
password = input<string>("");
showCount = input<boolean>(false);
readonly password = input<string>("");
readonly showCount = input<boolean>(false);
// Convert to an array to handle cases that strings have special characters, i.e.: emoji.
passwordCharArray = computed(() => {
readonly passwordCharArray = computed(() => {
return Array.from(this.password() ?? "");
});

View File

@@ -3,6 +3,8 @@ import { Component } from "@angular/core";
/**
* bit-container is a minimally styled component that limits the max width of its content to the tailwind theme variable '4xl'. '4xl' is equal to the value of 56rem
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-container",
templateUrl: "container.component.html",

View File

@@ -9,6 +9,8 @@ import { ToastService, CopyClickListener, COPY_CLICK_LISTENER } from "../";
import { CopyClickDirective } from "./copy-click.directive";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template: `
<button type="button" appCopyClick="no toast shown" #noToast></button>
@@ -25,9 +27,17 @@ import { CopyClickDirective } from "./copy-click.directive";
imports: [CopyClickDirective],
})
class TestCopyClickComponent {
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@ViewChild("noToast") noToastButton!: ElementRef<HTMLButtonElement>;
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@ViewChild("infoToast") infoToastButton!: ElementRef<HTMLButtonElement>;
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@ViewChild("successToast") successToastButton!: ElementRef<HTMLButtonElement>;
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@ViewChild("toastWithLabel") toastWithLabelButton!: ElementRef<HTMLButtonElement>;
}

View File

@@ -26,11 +26,11 @@ export const COPY_CLICK_LISTENER = new InjectionToken<CopyClickListener>("CopyCl
selector: "[appCopyClick]",
})
export class CopyClickDirective {
private _showToast = computed(() => {
private readonly _showToast = computed(() => {
return this.showToast() !== undefined;
});
private toastVariant = computed(() => {
private readonly toastVariant = computed(() => {
const showToast = this.showToast();
// When the `showToast` is set without a value, an empty string will be passed
if (showToast === "" || showToast === undefined) {
@@ -68,7 +68,7 @@ export class CopyClickDirective {
* <app-component [appCopyClick]="value to copy" showToast="info"/></app-component>
* ```
*/
showToast = input<ToastVariant | "">();
readonly showToast = input<ToastVariant | "">();
@HostListener("click") onClick() {
const valueToCopy = this.valueToCopy();

View File

@@ -21,6 +21,8 @@ interface Animal {
animal: string;
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template: `
<bit-layout>
@@ -62,6 +64,8 @@ class StoryDialogComponent {
}
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template: `
<bit-dialog title="Dialog Title" dialogSize="large">
@@ -91,6 +95,8 @@ class StoryDialogContentComponent {
}
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template: `
<bit-dialog

View File

@@ -26,6 +26,8 @@ import { DialogRef } from "../dialog.service";
import { DialogCloseDirective } from "../directives/dialog-close.directive";
import { DialogTitleContainerDirective } from "../directives/dialog-title-container.directive";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-dialog",
templateUrl: "./dialog.component.html",
@@ -47,8 +49,8 @@ import { DialogTitleContainerDirective } from "../directives/dialog-title-contai
})
export class DialogComponent {
private readonly destroyRef = inject(DestroyRef);
private scrollableBody = viewChild.required(CdkScrollable);
private scrollBottom = viewChild.required<ElementRef<HTMLDivElement>>("scrollBottom");
private readonly scrollableBody = viewChild.required(CdkScrollable);
private readonly scrollBottom = viewChild.required<ElementRef<HTMLDivElement>>("scrollBottom");
protected dialogRef = inject(DialogRef, { optional: true });
protected bodyHasScrolledFrom = hasScrolledFrom(this.scrollableBody);

View File

@@ -26,6 +26,8 @@ const DEFAULT_COLOR: Record<SimpleDialogType, string> = {
danger: "tw-text-danger",
};
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
templateUrl: "./simple-configurable-dialog.component.html",
imports: [

View File

@@ -10,6 +10,8 @@ import { CalloutModule } from "../../../callout";
import { I18nMockService } from "../../../utils/i18n-mock.service";
import { DialogModule } from "../../dialog.module";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template: `
@for (group of dialogs; track group) {

View File

@@ -9,6 +9,8 @@ import { DialogTitleContainerDirective } from "../directives/dialog-title-contai
})
export class IconDirective {}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-simple-dialog",
templateUrl: "./simple-dialog.component.html",
@@ -16,12 +18,14 @@ export class IconDirective {}
imports: [DialogTitleContainerDirective, TypographyDirective],
})
export class SimpleDialogComponent {
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@ContentChild(IconDirective) icon!: IconDirective;
/**
* Optional flag to hide the dialog's center icon. Defaults to false.
*/
hideIcon = input(false, { transform: booleanAttribute });
readonly hideIcon = input(false, { transform: booleanAttribute });
get hasIcon() {
return this.icon != null;

View File

@@ -15,6 +15,8 @@ interface Animal {
animal: string;
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template: `
<button type="button" bitButton (click)="openSimpleDialog()">Open Simple Dialog</button>
@@ -57,6 +59,8 @@ class StoryDialogComponent {
}
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template: `
<bit-simple-dialog>
@@ -87,6 +91,8 @@ class SimpleDialogContent {
}
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template: `
<bit-simple-dialog>
@@ -116,6 +122,8 @@ class NonDismissableWithPrimaryButtonContent {
}
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template: `
<bit-simple-dialog>

View File

@@ -34,12 +34,16 @@ let nextId = 0;
* ```
*
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-disclosure",
template: `<ng-content></ng-content>`,
})
export class DisclosureComponent {
/** Emits the visibility of the disclosure content */
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output() openChange = new EventEmitter<boolean>();
private _open?: boolean;
@@ -48,6 +52,8 @@ export class DisclosureComponent {
*/
// TODO: Skipped for signal migration because:
// Accessor inputs cannot be migrated as they are too complex.
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input({ transform: booleanAttribute }) set open(isOpen: boolean) {
this._open = isOpen;
this.openChange.emit(isOpen);

View File

@@ -24,7 +24,7 @@ export class DrawerHeaderComponent {
/**
* The title to display
*/
title = input.required<string>();
readonly title = input.required<string>();
/** We don't want to set the HTML title attribute with `this.title` */
@HostBinding("attr.title")

View File

@@ -10,7 +10,7 @@ import { Directive, signal } from "@angular/core";
selector: "[bitDrawerHost]",
})
export class DrawerHostDirective {
private _portal = signal<Portal<unknown> | undefined>(undefined);
private readonly _portal = signal<Portal<unknown> | undefined>(undefined);
/** The portal to display */
portal = this._portal.asReadonly();

View File

@@ -25,7 +25,7 @@ import { DrawerService } from "./drawer.service";
})
export class DrawerComponent {
private drawerHost = inject(DrawerService);
private portal = viewChild.required(CdkPortal);
private readonly portal = viewChild.required(CdkPortal);
/**
* Whether or not the drawer is open.
@@ -33,7 +33,7 @@ export class DrawerComponent {
* Note: Does not support implicit boolean transform due to Angular limitation. Must be bound explicitly `[open]="true"` instead of just `open`.
* https://github.com/angular/angular/issues/55166#issuecomment-2032150999
**/
open = model<boolean>(false);
readonly open = model<boolean>(false);
/**
* The ARIA role of the drawer.
@@ -43,7 +43,7 @@ export class DrawerComponent {
* - [navigation](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/navigation_role)
* - For drawers that primary contain links to other content.
*/
role = input<"complementary" | "navigation">("complementary");
readonly role = input<"complementary" | "navigation">("complementary");
constructor() {
effect(

View File

@@ -3,7 +3,7 @@ import { Injectable, signal } from "@angular/core";
@Injectable({ providedIn: "root" })
export class DrawerService {
private _portal = signal<Portal<unknown> | undefined>(undefined);
private readonly _portal = signal<Portal<unknown> | undefined>(undefined);
/** The portal to display */
portal = this._portal.asReadonly();

View File

@@ -8,6 +8,8 @@ import { TypographyDirective } from "../typography/typography.directive";
import { BitFormControlAbstraction } from "./form-control.abstraction";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-form-control",
templateUrl: "form-control.component.html",

View File

@@ -6,6 +6,8 @@ import { FormControlComponent } from "./form-control.component";
// Increments for each instance of this component
let nextId = 0;
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-label",
templateUrl: "label.component.html",

View File

@@ -3,6 +3,8 @@ import { AbstractControl, UntypedFormGroup } from "@angular/forms";
import { I18nPipe } from "@bitwarden/ui-common";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-error-summary",
template: ` @if (errorCount > 0) {

View File

@@ -5,6 +5,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
// Increments for each instance of this component
let nextId = 0;
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-error",
template: `<i class="bwi bwi-error"></i> {{ displayError }}`,

View File

@@ -22,6 +22,8 @@ import { inputBorderClasses } from "../input/input.directive";
import { BitErrorComponent } from "./error.component";
import { BitFormFieldControl } from "./form-field-control";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-form-field",
templateUrl: "./form-field.component.html",
@@ -42,11 +44,13 @@ export class BitFormFieldComponent implements AfterContentChecked {
/** If `true`, remove the bottom border for `readonly` inputs */
// TODO: Skipped for signal migration because:
// Your application code writes to the input. This prevents migration.
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input({ transform: booleanAttribute })
disableReadOnlyBorder = false;
protected prefixHasChildren = signal(false);
protected suffixHasChildren = signal(false);
protected readonly prefixHasChildren = signal(false);
protected readonly suffixHasChildren = signal(false);
get inputBorderClasses(): string {
const shouldFocusBorderAppear = this.defaultContentIsFocused();
@@ -87,7 +91,7 @@ export class BitFormFieldComponent implements AfterContentChecked {
* This is necessary because the `tw-group/bit-form-field` wraps the input and any prefix/suffix
* buttons
*/
protected defaultContentIsFocused = signal(false);
protected readonly defaultContentIsFocused = signal(false);
@HostListener("focusin", ["$event.target"])
onFocusIn(target: HTMLElement) {
this.defaultContentIsFocused.set(target.matches("[data-default-content] *:focus-visible"));

View File

@@ -27,6 +27,8 @@ export class BitPasswordInputToggleDirective implements AfterContentInit, OnChan
* Whether the input is toggled to show the password.
*/
readonly toggled = model(false);
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output() toggledChange = new EventEmitter<boolean>();
@HostBinding("attr.title") title = this.i18nService.t("toggleVisibility");

View File

@@ -13,6 +13,8 @@ import { BitFormFieldComponent } from "./form-field.component";
import { FormFieldModule } from "./form-field.module";
import { BitPasswordInputToggleDirective } from "./password-input-toggle.directive";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "test-form-field",
template: `

View File

@@ -81,6 +81,8 @@ const sizes: Record<IconButtonSize, string[]> = {
* Similar to the main button components, spacing between multiple icon buttons should be .5rem.
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "button[bitIconButton]:not(button[bitButton])",
templateUrl: "icon-button.component.html",
@@ -143,7 +145,7 @@ export class BitIconButtonComponent implements ButtonLikeAbstraction, FocusableE
return [this.icon(), "!tw-m-0"];
}
protected disabledAttr = computed(() => {
protected readonly disabledAttr = computed(() => {
const disabled = this.disabled() != null && this.disabled() !== false;
return disabled || this.loading();
});
@@ -156,7 +158,7 @@ export class BitIconButtonComponent implements ButtonLikeAbstraction, FocusableE
* We can't use `disabledAttr` for this, because it returns `true` when `loading` is `true`.
* We only want to show disabled styles during loading if `showLoadingStyles` is `true`.
*/
protected showDisabledStyles = computed(() => {
protected readonly showDisabledStyles = computed(() => {
return this.showLoadingStyle() || (this.disabledAttr() && this.loading() === false);
});
@@ -174,7 +176,7 @@ export class BitIconButtonComponent implements ButtonLikeAbstraction, FocusableE
* This pattern of converting a signal to an observable and back to a signal is not
* recommended. TODO -- find better way to use debounce with signals (CL-596)
*/
protected showLoadingStyle = toSignal(
protected readonly showLoadingStyle = toSignal(
toObservable(this.loading).pipe(debounce((isLoading) => interval(isLoading ? 75 : 0))),
);

View File

@@ -56,6 +56,8 @@ const shapeStyles: Record<IconTileShape, Record<IconTileSize, string[]>> = {
* - Create visual hierarchy in lists or cards
* - Show app or service icons in a consistent format
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-icon-tile",
templateUrl: "icon-tile.component.html",

View File

@@ -3,6 +3,8 @@ import { DomSanitizer, SafeHtml } from "@angular/platform-browser";
import { Icon, isIcon } from "@bitwarden/assets/svg";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-icon",
host: {

View File

@@ -74,6 +74,8 @@ export class BitInputDirective implements BitFormFieldControl {
// TODO: Skipped for signal migration because:
// Accessor inputs cannot be migrated as they are too complex.
@HostBinding()
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
get required() {
return this._required ?? this.ngControl?.control?.hasValidator(Validators.required) ?? false;

View File

@@ -1,5 +1,7 @@
import { Component } from "@angular/core";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-item-action",
imports: [],

View File

@@ -29,7 +29,7 @@ import { TypographyModule } from "../typography";
export class ItemContentComponent implements AfterContentChecked {
readonly endSlot = viewChild<ElementRef<HTMLDivElement>>("endSlot");
protected endSlotHasChildren = signal(false);
protected readonly endSlotHasChildren = signal(false);
/**
* Determines whether text will truncate or wrap.

View File

@@ -22,7 +22,7 @@ export class ItemComponent {
/**
* We have `:focus-within` and `:focus-visible` but no `:focus-visible-within`
*/
protected focusVisibleWithin = signal(false);
protected readonly focusVisibleWithin = signal(false);
@HostListener("focusin", ["$event.target"])
onFocusIn(target: HTMLElement) {
this.focusVisibleWithin.set(target.matches("[data-fvw-target]:focus-visible"));

View File

@@ -12,6 +12,8 @@ import { SharedModule } from "../shared";
import { ScrollLayoutHostDirective } from "./scroll-layout.directive";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-layout",
templateUrl: "layout.component.html",
@@ -34,7 +36,7 @@ export class LayoutComponent {
protected sideNavService = inject(SideNavService);
protected drawerPortal = inject(DrawerService).portal;
private mainContent = viewChild.required<ElementRef<HTMLElement>>("main");
private readonly mainContent = viewChild.required<ElementRef<HTMLElement>>("main");
protected focusMainContent() {
this.mainContent().nativeElement.focus();
}
@@ -45,7 +47,7 @@ export class LayoutComponent {
*
* @see https://github.com/angular/components/issues/10247#issuecomment-384060265
**/
private skipLink = viewChild.required<ElementRef<HTMLElement>>("skipLink");
private readonly skipLink = viewChild.required<ElementRef<HTMLElement>>("skipLink");
handleKeydown(ev: KeyboardEvent) {
if (isNothingFocused()) {
ev.preventDefault();

View File

@@ -17,7 +17,7 @@ import { filter, fromEvent, Observable, switchMap } from "rxjs";
**/
@Injectable({ providedIn: "root" })
export class ScrollLayoutService {
scrollableRef = signal<ElementRef<HTMLElement> | null>(null);
readonly scrollableRef = signal<ElementRef<HTMLElement> | null>(null);
scrollableRef$ = toObservable(this.scrollableRef);
}

View File

@@ -99,7 +99,7 @@ export class AnchorLinkDirective extends LinkDirective {
export class ButtonLinkDirective extends LinkDirective {
private el = inject(ElementRef<HTMLButtonElement>);
disabled = input(false, { transform: booleanAttribute });
readonly disabled = input(false, { transform: booleanAttribute });
@HostBinding("class") get classList() {
return ["before:-tw-inset-y-[0.25rem]"]

View File

@@ -1,5 +1,7 @@
import { Component } from "@angular/core";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-menu-divider",
templateUrl: "./menu-divider.component.html",

View File

@@ -3,6 +3,8 @@ import { coerceBooleanProperty } from "@angular/cdk/coercion";
import { NgClass } from "@angular/common";
import { Component, ElementRef, HostBinding, Input } from "@angular/core";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "[bitMenuItem]",
templateUrl: "menu-item.component.html",
@@ -42,6 +44,8 @@ export class MenuItemDirective implements FocusableOption {
// TODO: Skipped for signal migration because:
// This input overrides a field from a superclass, while the superclass field
// is not migrated.
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input({ transform: coerceBooleanProperty }) disabled?: boolean = false;
constructor(public elementRef: ElementRef<HTMLButtonElement>) {}

View File

@@ -68,6 +68,8 @@ describe("Menu", () => {
});
});
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "test-app",
template: `

View File

@@ -12,6 +12,8 @@ import {
import { MenuItemDirective } from "./menu-item.directive";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-menu",
templateUrl: "./menu.component.html",
@@ -20,6 +22,8 @@ import { MenuItemDirective } from "./menu-item.directive";
})
export class MenuComponent implements AfterContentInit {
readonly templateRef = viewChild.required(TemplateRef);
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output() closed = new EventEmitter<void>();
readonly menuItems = contentChildren(MenuItemDirective, { descendants: true });
keyManager?: FocusKeyManager<MenuItemDirective>;

View File

@@ -34,6 +34,8 @@ import { SelectItemView } from "./models/select-item-view";
// Increments for each instance of this component
let nextId = 0;
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-multi-select",
templateUrl: "./multi-select.component.html",
@@ -64,6 +66,8 @@ export class MultiSelectComponent implements OnInit, BitFormFieldControl, Contro
readonly loading = input(false);
// TODO: Skipped for signal migration because:
// Your application code writes to the input. This prevents migration.
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input({ transform: booleanAttribute }) disabled?: boolean;
// Internal tracking of selected items
@@ -79,6 +83,8 @@ export class MultiSelectComponent implements OnInit, BitFormFieldControl, Contro
/**Implemented as part of NG_VALUE_ACCESSOR */
private notifyOnTouched?: () => void;
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output() onItemsConfirmed = new EventEmitter<any[]>();
constructor(
@@ -208,6 +214,8 @@ export class MultiSelectComponent implements OnInit, BitFormFieldControl, Contro
// TODO: Skipped for signal migration because:
// Accessor inputs cannot be migrated as they are too complex.
@HostBinding("attr.required")
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
get required() {
return this._required ?? this.ngControl?.control?.hasValidator(Validators.required) ?? false;

View File

@@ -61,5 +61,7 @@ export abstract class NavBaseComponent {
/**
* Fires when main content is clicked
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output() mainContentClicked: EventEmitter<MouseEvent> = new EventEmitter();
}

View File

@@ -3,6 +3,8 @@ import { Component } from "@angular/core";
import { SideNavService } from "./side-nav.service";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-nav-divider",
templateUrl: "./nav-divider.component.html",

View File

@@ -19,6 +19,8 @@ import { NavBaseComponent } from "./nav-base.component";
import { NavGroupAbstraction, NavItemComponent } from "./nav-item.component";
import { SideNavService } from "./side-nav.service";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-nav-group",
templateUrl: "./nav-group.component.html",
@@ -51,6 +53,8 @@ export class NavGroupComponent extends NavBaseComponent {
*/
readonly hideIfEmpty = input(false, { transform: booleanAttribute });
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output()
openChange = new EventEmitter<boolean>();

View File

@@ -12,6 +12,8 @@ import { I18nMockService } from "../utils/i18n-mock.service";
import { NavGroupComponent } from "./nav-group.component";
import { NavigationModule } from "./navigation.module";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
template: "",
})

View File

@@ -13,6 +13,8 @@ export abstract class NavGroupAbstraction {
abstract setOpen(open: boolean): void;
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-nav-item",
templateUrl: "./nav-item.component.html",

View File

@@ -8,6 +8,8 @@ import { BitIconComponent } from "../icon/icon.component";
import { SideNavService } from "./side-nav.service";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-nav-logo",
templateUrl: "./nav-logo.component.html",

View File

@@ -11,6 +11,8 @@ import { SideNavService } from "./side-nav.service";
export type SideNavVariant = "primary" | "secondary";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-side-nav",
templateUrl: "side-nav.component.html",

View File

@@ -7,6 +7,8 @@ import { BitIconComponent } from "../icon/icon.component";
/**
* Component for displaying a message when there are no items to display. Expects title, description and button slots.
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-no-items",
templateUrl: "./no-items.component.html",

View File

@@ -5,6 +5,8 @@ import { IconButtonModule } from "../icon-button/icon-button.module";
import { SharedModule } from "../shared/shared.module";
import { TypographyModule } from "../typography";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-popover",
imports: [A11yModule, IconButtonModule, SharedModule, TypographyModule],
@@ -14,5 +16,7 @@ import { TypographyModule } from "../typography";
export class PopoverComponent {
readonly templateRef = viewChild.required(TemplateRef);
readonly title = input("");
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output() closed = new EventEmitter();
}

View File

@@ -20,6 +20,8 @@ const BackgroundClasses: Record<BackgroundType, string[]> = {
/**
* Progress indicators may be used to visually indicate progress or to visually measure some other value, such as a password strength indicator.
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-progress",
templateUrl: "./progress.component.html",

View File

@@ -53,6 +53,8 @@ describe("RadioButton", () => {
});
});
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "test-component",
template: `

View File

@@ -7,6 +7,8 @@ import { RadioInputComponent } from "./radio-input.component";
let nextId = 0;
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-radio-button",
templateUrl: "radio-button.component.html",

View File

@@ -63,6 +63,8 @@ describe("RadioGroupComponent", () => {
});
});
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "test-app",
template: `

View File

@@ -8,6 +8,8 @@ import { BitLabel } from "../form-control/label.component";
let nextId = 0;
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-radio-group",
templateUrl: "radio-group.component.html",

View File

@@ -5,6 +5,8 @@ import { BitFormControlAbstraction } from "../form-control";
let nextId = 0;
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "input[type=radio][bitRadio]",
template: "",

View File

@@ -13,6 +13,8 @@ export class ResizeObserverDirective implements OnDestroy {
}
});
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output()
resize = new EventEmitter();

View File

@@ -18,6 +18,8 @@ let nextId = 0;
/**
* Do not nest Search components inside another `<form>`, as they already contain their own standalone `<form>` element for searching.
*/
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-search",
templateUrl: "./search.component.html",
@@ -45,10 +47,12 @@ export class SearchComponent implements ControlValueAccessor, FocusableElement {
// Use `type="text"` for Safari to improve rendering performance
protected inputType = isBrowserSafariApi() ? ("text" as const) : ("search" as const);
protected isInputFocused = signal(false);
protected isFormHovered = signal(false);
protected readonly isInputFocused = signal(false);
protected readonly isFormHovered = signal(false);
protected showResetButton = computed(() => this.isInputFocused() || this.isFormHovered());
protected readonly showResetButton = computed(
() => this.isInputFocused() || this.isFormHovered(),
);
readonly disabled = model<boolean>();
readonly placeholder = input<string>();

View File

@@ -2,6 +2,8 @@ import { Component } from "@angular/core";
import { TypographyModule } from "../typography";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-section-header",
templateUrl: "./section-header.component.html",

View File

@@ -2,6 +2,8 @@ import { coerceBooleanProperty } from "@angular/cdk/coercion";
import { CommonModule } from "@angular/common";
import { Component, input } from "@angular/core";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-section",
imports: [CommonModule],

View File

@@ -2,6 +2,8 @@ import { Component, booleanAttribute, input } from "@angular/core";
import { MappedOptionComponent } from "./option";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-option",
template: `<ng-template><ng-content></ng-content></ng-template>`,

View File

@@ -9,6 +9,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
import { SelectComponent } from "./select.component";
import { SelectModule } from "./select.module";
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
imports: [SelectModule, ReactiveFormsModule],
template: `

View File

@@ -34,6 +34,8 @@ import { OptionComponent } from "./option.component";
let nextId = 0;
// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush
// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
@Component({
selector: "bit-select",
templateUrl: "select.component.html",
@@ -50,10 +52,12 @@ export class SelectComponent<T> implements BitFormFieldControl, ControlValueAcce
readonly items = model<Option<T>[] | undefined>();
readonly placeholder = input(this.i18nService.t("selectPlaceholder"));
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
@Output() closed = new EventEmitter();
protected selectedValue = signal<T | undefined | null>(undefined);
selectedOption: Signal<Option<T> | null | undefined> = computed(() =>
protected readonly selectedValue = signal<T | undefined | null>(undefined);
readonly selectedOption: Signal<Option<T> | null | undefined> = computed(() =>
this.findSelectedOption(this.items(), this.selectedValue()),
);
protected searchInputId = `bit-select-search-input-${nextId++}`;
@@ -70,6 +74,8 @@ export class SelectComponent<T> implements BitFormFieldControl, ControlValueAcce
}
}
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@ContentChildren(OptionComponent)
protected set options(value: QueryList<OptionComponent<T>>) {
if (value == null || value.length == 0) {
@@ -94,6 +100,8 @@ export class SelectComponent<T> implements BitFormFieldControl, ControlValueAcce
}
// TODO: Skipped for signal migration because:
// Accessor inputs cannot be migrated as they are too complex.
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
get disabled() {
return this._disabled ?? this.ngControl?.disabled ?? false;
@@ -166,6 +174,8 @@ export class SelectComponent<T> implements BitFormFieldControl, ControlValueAcce
// TODO: Skipped for signal migration because:
// Accessor inputs cannot be migrated as they are too complex.
@HostBinding("attr.required")
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
// eslint-disable-next-line @angular-eslint/prefer-signals
@Input()
get required() {
return this._required ?? this.ngControl?.control?.hasValidator(Validators.required) ?? false;

Some files were not shown because too many files have changed in this diff Show More