From 8cd39690ed884555c039291318d30e3bd9522c36 Mon Sep 17 00:00:00 2001 From: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> Date: Wed, 5 Nov 2025 14:05:15 -0600 Subject: [PATCH] [PM-27711] Loading Skeleton page (#17224) * convert popup page component to use inputs * disable overflow on popup page to allow content to naturally overflow * migrate popup-page to OnPush * add vault-loading-skeleton component * remove internal loading text * hide entire skeleton from screen readers --- .../popup/layout/popup-layout.stories.ts | 24 +++----------- .../popup/layout/popup-page.component.html | 18 ++++++----- .../popup/layout/popup-page.component.ts | 32 +++++++++---------- .../vault-loading-skeleton.component.html | 15 +++++++++ .../vault-loading-skeleton.component.ts | 17 ++++++++++ 5 files changed, 62 insertions(+), 44 deletions(-) create mode 100644 apps/browser/src/vault/popup/components/vault-loading-skeleton/vault-loading-skeleton.component.html create mode 100644 apps/browser/src/vault/popup/components/vault-loading-skeleton/vault-loading-skeleton.component.ts diff --git a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts index ca79a6d9d1..c6ffe1a641 100644 --- a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts +++ b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts @@ -29,11 +29,9 @@ import { SearchModule, SectionComponent, ScrollLayoutDirective, - SkeletonComponent, - SkeletonTextComponent, - SkeletonGroupComponent, } from "@bitwarden/components"; +import { VaultLoadingSkeletonComponent } from "../../../vault/popup/components/vault-loading-skeleton/vault-loading-skeleton.component"; import { PopupRouterCacheService } from "../view-cache/popup-router-cache.service"; import { PopupFooterComponent } from "./popup-footer.component"; @@ -366,9 +364,7 @@ export default { SectionComponent, IconButtonModule, BadgeModule, - SkeletonComponent, - SkeletonTextComponent, - SkeletonGroupComponent, + VaultLoadingSkeletonComponent, ], providers: [ { @@ -634,21 +630,9 @@ export const SkeletonLoading: Story = { template: /* HTML */ ` - + - - Loading... - - - @for (num of data; track $index) { - - - - - - } - - + diff --git a/apps/browser/src/platform/popup/layout/popup-page.component.html b/apps/browser/src/platform/popup/layout/popup-page.component.html index b53ef6e97e..a9184a9dd5 100644 --- a/apps/browser/src/platform/popup/layout/popup-page.component.html +++ b/apps/browser/src/platform/popup/layout/popup-page.component.html @@ -1,7 +1,7 @@ - @@ -37,9 +39,9 @@ - + diff --git a/apps/browser/src/platform/popup/layout/popup-page.component.ts b/apps/browser/src/platform/popup/layout/popup-page.component.ts index db5ea64169..4eed322bdb 100644 --- a/apps/browser/src/platform/popup/layout/popup-page.component.ts +++ b/apps/browser/src/platform/popup/layout/popup-page.component.ts @@ -1,11 +1,16 @@ import { CommonModule } from "@angular/common"; -import { booleanAttribute, Component, inject, Input, signal } from "@angular/core"; +import { + booleanAttribute, + ChangeDetectionStrategy, + Component, + inject, + input, + signal, +} from "@angular/core"; 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", @@ -13,28 +18,23 @@ import { ScrollLayoutHostDirective } from "@bitwarden/components"; class: "tw-h-full tw-flex tw-flex-col tw-overflow-y-hidden", }, imports: [CommonModule, ScrollLayoutHostDirective], + changeDetection: ChangeDetectionStrategy.OnPush, }) 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; + readonly loading = input(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; + readonly disablePadding = input(false, { transform: booleanAttribute }); - // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals - // eslint-disable-next-line @angular-eslint/prefer-signals - protected scrolled = signal(false); + /** Hides any overflow within the page content */ + readonly hideOverflow = input(false, { transform: booleanAttribute }); + + protected readonly 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"); + readonly loadingText = input(this.i18nService.t("loading")); handleScroll(event: Event) { this.scrolled.set((event.currentTarget as HTMLElement).scrollTop !== 0); diff --git a/apps/browser/src/vault/popup/components/vault-loading-skeleton/vault-loading-skeleton.component.html b/apps/browser/src/vault/popup/components/vault-loading-skeleton/vault-loading-skeleton.component.html new file mode 100644 index 0000000000..c9b990c2ee --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-loading-skeleton/vault-loading-skeleton.component.html @@ -0,0 +1,15 @@ + + + + @for (num of numberOfItems; track $index) { + + + + + + + + + } + + diff --git a/apps/browser/src/vault/popup/components/vault-loading-skeleton/vault-loading-skeleton.component.ts b/apps/browser/src/vault/popup/components/vault-loading-skeleton/vault-loading-skeleton.component.ts new file mode 100644 index 0000000000..23ae86387e --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-loading-skeleton/vault-loading-skeleton.component.ts @@ -0,0 +1,17 @@ +import { ChangeDetectionStrategy, Component } from "@angular/core"; + +import { + SkeletonComponent, + SkeletonGroupComponent, + SkeletonTextComponent, +} from "@bitwarden/components"; + +@Component({ + selector: "vault-loading-skeleton", + templateUrl: "./vault-loading-skeleton.component.html", + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [SkeletonGroupComponent, SkeletonComponent, SkeletonTextComponent], +}) +export class VaultLoadingSkeletonComponent { + protected readonly numberOfItems: null[] = new Array(15).fill(null); +}