diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json
index bf29ff2fd2..a89ac05e4e 100644
--- a/apps/browser/src/_locales/en/messages.json
+++ b/apps/browser/src/_locales/en/messages.json
@@ -3628,5 +3628,8 @@
},
"addAccount": {
"message": "Add account"
+ },
+ "loading": {
+ "message": "Loading"
}
}
diff --git a/apps/browser/src/platform/popup/layout/popup-layout.mdx b/apps/browser/src/platform/popup/layout/popup-layout.mdx
index 6f72f325bf..b805805ad1 100644
--- a/apps/browser/src/platform/popup/layout/popup-layout.mdx
+++ b/apps/browser/src/platform/popup/layout/popup-layout.mdx
@@ -44,6 +44,14 @@ page looks nice when the extension is popped out.
- default
- Whatever content you want in `main`.
+**Inputs**
+
+- `loading`
+ - When `true`, displays a loading state overlay instead of the default content. Defaults to
+ `false`.
+- `loadingText`
+ - Custom text to be applied to the loading element for screenreaders only. Defaults to "Loading".
+
Basic usage example:
```html
@@ -137,8 +145,20 @@ When the browser extension is popped out, the "popout" button should not be pass
+# Other stories
+
## Centered Content
+An example of how to center the default content.
+
+
+## Loading
+
+An example of what the loading state looks like.
+
+
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 9883a5cfb6..f2208a8b8f 100644
--- a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts
+++ b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts
@@ -62,27 +62,6 @@ class VaultComponent {
protected data = Array.from(Array(20).keys());
}
-@Component({
- selector: "generator-placeholder",
- template: `
generator stuff here
`,
- standalone: true,
-})
-class GeneratorComponent {}
-
-@Component({
- selector: "send-placeholder",
- template: ` send some stuff
`,
- standalone: true,
-})
-class SendComponent {}
-
-@Component({
- selector: "settings-placeholder",
- template: ` change your settings
`,
- standalone: true,
-})
-class SettingsComponent {}
-
@Component({
selector: "mock-add-button",
template: `
@@ -186,7 +165,7 @@ class MockVaultPagePoppedComponent {}
-
+ Generator content here
`,
standalone: true,
@@ -196,7 +175,6 @@ class MockVaultPagePoppedComponent {}
MockAddButtonComponent,
MockPopoutButtonComponent,
MockCurrentAccountComponent,
- GeneratorComponent,
],
})
class MockGeneratorPageComponent {}
@@ -212,7 +190,7 @@ class MockGeneratorPageComponent {}
-
+ Send content here
`,
standalone: true,
@@ -222,7 +200,6 @@ class MockGeneratorPageComponent {}
MockAddButtonComponent,
MockPopoutButtonComponent,
MockCurrentAccountComponent,
- SendComponent,
],
})
class MockSendPageComponent {}
@@ -238,7 +215,7 @@ class MockSendPageComponent {}
-
+ Settings content here
`,
standalone: true,
@@ -248,7 +225,6 @@ class MockSendPageComponent {}
MockAddButtonComponent,
MockPopoutButtonComponent,
MockCurrentAccountComponent,
- SettingsComponent,
],
})
class MockSettingsPageComponent {}
@@ -312,6 +288,7 @@ export default {
useFactory: () => {
return new I18nMockService({
back: "Back",
+ loading: "Loading",
});
},
},
@@ -406,3 +383,19 @@ export const CenteredContent: Story = {
`,
}),
};
+
+export const Loading: Story = {
+ render: (args) => ({
+ props: args,
+ template: /* HTML */ `
+
+
+
+
+ Content would go here
+
+
+
+ `,
+ }),
+};
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 b3dcd626ae..87f91e781a 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,16 @@
-
-
+
+
+
+
+
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 1223a6f418..97a67fc852 100644
--- a/apps/browser/src/platform/popup/layout/popup-page.component.ts
+++ b/apps/browser/src/platform/popup/layout/popup-page.component.ts
@@ -1,4 +1,7 @@
-import { Component } from "@angular/core";
+import { CommonModule } from "@angular/common";
+import { Component, Input, inject } from "@angular/core";
+
+import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@Component({
selector: "popup-page",
@@ -7,5 +10,13 @@ import { Component } from "@angular/core";
host: {
class: "tw-h-full tw-flex tw-flex-col tw-flex-1 tw-overflow-y-auto",
},
+ imports: [CommonModule],
})
-export class PopupPageComponent {}
+export class PopupPageComponent {
+ protected i18nService = inject(I18nService);
+
+ @Input() loading = false;
+
+ /** Accessible loading label for the spinner. Defaults to "loading" */
+ @Input() loadingText?: string = this.i18nService.t("loading");
+}