mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-21 02:11:54 +01:00
[CL-285] Add default loading state to popup-page (#10040)
This commit is contained in:
parent
bc7c6dd04e
commit
154f15fa58
@ -3628,5 +3628,8 @@
|
||||
},
|
||||
"addAccount": {
|
||||
"message": "Add account"
|
||||
},
|
||||
"loading": {
|
||||
"message": "Loading"
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
<Story of={stories.PoppedOut} />
|
||||
</Canvas>
|
||||
|
||||
# Other stories
|
||||
|
||||
## Centered Content
|
||||
|
||||
An example of how to center the default content.
|
||||
|
||||
<Canvas>
|
||||
<Story of={stories.CenteredContent} />
|
||||
</Canvas>
|
||||
|
||||
## Loading
|
||||
|
||||
An example of what the loading state looks like.
|
||||
|
||||
<Canvas>
|
||||
<Story of={stories.Loading} />
|
||||
</Canvas>
|
||||
|
@ -62,27 +62,6 @@ class VaultComponent {
|
||||
protected data = Array.from(Array(20).keys());
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: "generator-placeholder",
|
||||
template: ` <div class="tw-text-main">generator stuff here</div> `,
|
||||
standalone: true,
|
||||
})
|
||||
class GeneratorComponent {}
|
||||
|
||||
@Component({
|
||||
selector: "send-placeholder",
|
||||
template: ` <div class="tw-text-main">send some stuff</div> `,
|
||||
standalone: true,
|
||||
})
|
||||
class SendComponent {}
|
||||
|
||||
@Component({
|
||||
selector: "settings-placeholder",
|
||||
template: ` <div class="tw-text-main">change your settings</div> `,
|
||||
standalone: true,
|
||||
})
|
||||
class SettingsComponent {}
|
||||
|
||||
@Component({
|
||||
selector: "mock-add-button",
|
||||
template: `
|
||||
@ -186,7 +165,7 @@ class MockVaultPagePoppedComponent {}
|
||||
<mock-current-account></mock-current-account>
|
||||
</ng-container>
|
||||
</popup-header>
|
||||
<generator-placeholder></generator-placeholder>
|
||||
<div class="tw-text-main">Generator content here</div>
|
||||
</popup-page>
|
||||
`,
|
||||
standalone: true,
|
||||
@ -196,7 +175,6 @@ class MockVaultPagePoppedComponent {}
|
||||
MockAddButtonComponent,
|
||||
MockPopoutButtonComponent,
|
||||
MockCurrentAccountComponent,
|
||||
GeneratorComponent,
|
||||
],
|
||||
})
|
||||
class MockGeneratorPageComponent {}
|
||||
@ -212,7 +190,7 @@ class MockGeneratorPageComponent {}
|
||||
<mock-current-account></mock-current-account>
|
||||
</ng-container>
|
||||
</popup-header>
|
||||
<send-placeholder></send-placeholder>
|
||||
<div class="tw-text-main">Send content here</div>
|
||||
</popup-page>
|
||||
`,
|
||||
standalone: true,
|
||||
@ -222,7 +200,6 @@ class MockGeneratorPageComponent {}
|
||||
MockAddButtonComponent,
|
||||
MockPopoutButtonComponent,
|
||||
MockCurrentAccountComponent,
|
||||
SendComponent,
|
||||
],
|
||||
})
|
||||
class MockSendPageComponent {}
|
||||
@ -238,7 +215,7 @@ class MockSendPageComponent {}
|
||||
<mock-current-account></mock-current-account>
|
||||
</ng-container>
|
||||
</popup-header>
|
||||
<settings-placeholder></settings-placeholder>
|
||||
<div class="tw-text-main">Settings content here</div>
|
||||
</popup-page>
|
||||
`,
|
||||
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 */ `
|
||||
<extension-container>
|
||||
<popup-tab-navigation>
|
||||
<popup-page [loading]="true">
|
||||
<popup-header slot="header" pageTitle="Page Header"></popup-header>
|
||||
Content would go here
|
||||
</popup-page>
|
||||
</popup-tab-navigation>
|
||||
</extension-container>
|
||||
`,
|
||||
}),
|
||||
};
|
||||
|
@ -1,7 +1,16 @@
|
||||
<ng-content select="[slot=header]"></ng-content>
|
||||
<main class="tw-bg-background-alt tw-flex-1 tw-overflow-y-auto tw-h-full">
|
||||
<div class="tw-max-w-screen-sm tw-mx-auto tw-p-3 tw-overflow-y-auto tw-h-full">
|
||||
<main class="tw-flex-1 tw-overflow-y-auto tw-h-full tw-relative tw-bg-background-alt">
|
||||
<div
|
||||
class="tw-max-w-screen-sm tw-mx-auto tw-p-3 tw-overflow-y-auto tw-h-full"
|
||||
[ngClass]="{ 'tw-invisible': loading }"
|
||||
>
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
<span
|
||||
class="tw-absolute tw-inset-0 tw-flex tw-items-center tw-justify-center tw-text-main"
|
||||
[ngClass]="{ 'tw-invisible': !loading }"
|
||||
>
|
||||
<i class="bwi bwi-spinner bwi-lg bwi-spin" [attr.aria-label]="loadingText"></i>
|
||||
</span>
|
||||
</main>
|
||||
<ng-content select="[slot=footer]"></ng-content>
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user