1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-11-25 12:15:18 +01:00

[PM-1950] Add support for a loading state in dialogs (#5268)

This commit is contained in:
Oscar Hinton 2023-05-09 11:26:13 +02:00 committed by GitHub
parent 9bbaae6ef2
commit 96ba8b3233
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 44 deletions

View File

@ -20,8 +20,23 @@
></button> ></button>
</div> </div>
<div class="tw-overflow-y-auto tw-pb-8" [ngClass]="{ 'tw-p-4': !disablePadding }"> <div class="tw-relative tw-flex tw-flex-col tw-overflow-hidden">
<ng-content select="[bitDialogContent]"></ng-content> <div
*ngIf="loading"
class="tw-absolute tw-flex tw-h-full tw-w-full tw-items-center tw-justify-center"
>
<i class="bwi bwi-spinner bwi-spin bwi-3x"></i>
</div>
<div
class="tw-pb-8"
[ngClass]="{
'tw-p-4': !disablePadding,
'tw-overflow-y-auto': !loading,
'tw-invisible tw-overflow-y-hidden': loading
}"
>
<ng-content select="[bitDialogContent]"></ng-content>
</div>
</div> </div>
<div <div

View File

@ -9,9 +9,15 @@ import { fadeIn } from "../animations";
animations: [fadeIn], animations: [fadeIn],
}) })
export class DialogComponent { export class DialogComponent {
/**
* Dialog size, more complex dialogs should use large, otherwise default is fine.
*/
@Input() dialogSize: "small" | "default" | "large" = "default"; @Input() dialogSize: "small" | "default" | "large" = "default";
private _disablePadding = false; private _disablePadding = false;
/**
* Disable the built-in padding on the dialog, for use with tabbed dialogs.
*/
@Input() set disablePadding(value: boolean | "") { @Input() set disablePadding(value: boolean | "") {
this._disablePadding = coerceBooleanProperty(value); this._disablePadding = coerceBooleanProperty(value);
} }
@ -19,6 +25,11 @@ export class DialogComponent {
return this._disablePadding; return this._disablePadding;
} }
/**
* Mark the dialog as loading which replaces the content with a spinner.
*/
@Input() loading = false;
@HostBinding("class") get classes() { @HostBinding("class") get classes() {
return ["tw-flex", "tw-flex-col", "tw-max-h-screen", "tw-w-screen", "tw-p-4"].concat( return ["tw-flex", "tw-flex-col", "tw-max-h-screen", "tw-w-screen", "tw-p-4"].concat(
this.width this.width

View File

@ -32,6 +32,7 @@ export default {
}), }),
], ],
args: { args: {
loading: false,
dialogSize: "small", dialogSize: "small",
}, },
argTypes: { argTypes: {
@ -52,21 +53,22 @@ export default {
const Template: Story<DialogComponent> = (args: DialogComponent) => ({ const Template: Story<DialogComponent> = (args: DialogComponent) => ({
props: args, props: args,
template: ` template: `
<bit-dialog [dialogSize]="dialogSize" [disablePadding]="disablePadding"> <bit-dialog [dialogSize]="dialogSize" [loading]="loading" [disablePadding]="disablePadding">
<span bitDialogTitle>{{title}}</span> <span bitDialogTitle>{{title}}</span>
<span bitDialogContent>Dialog body text goes here.</span> <ng-container bitDialogContent>Dialog body text goes here.</ng-container>
<ng-container bitDialogFooter> <ng-container bitDialogFooter>
<button bitButton buttonType="primary">Save</button> <button bitButton buttonType="primary" [disabled]="loading">Save</button>
<button bitButton buttonType="secondary">Cancel</button> <button bitButton buttonType="secondary" [disabled]="loading">Cancel</button>
<button <button
class="tw-ml-auto" [disabled]="loading"
bitIconButton="bwi-trash" class="tw-ml-auto"
buttonType="danger" bitIconButton="bwi-trash"
size="default" buttonType="danger"
title="Delete" size="default"
aria-label="Delete"></button> title="Delete"
</ng-container> aria-label="Delete"></button>
</bit-dialog> </ng-container>
</bit-dialog>
`, `,
}); });
@ -94,23 +96,30 @@ Large.args = {
title: "Large", title: "Large",
}; };
export const Loading = Template.bind({});
Loading.args = {
dialogSize: "large",
loading: true,
title: "Loading",
};
const TemplateScrolling: Story<DialogComponent> = (args: DialogComponent) => ({ const TemplateScrolling: Story<DialogComponent> = (args: DialogComponent) => ({
props: args, props: args,
template: ` template: `
<bit-dialog [dialogSize]="dialogSize" [disablePadding]="disablePadding"> <bit-dialog [dialogSize]="dialogSize" [loading]="loading" [disablePadding]="disablePadding">
<span bitDialogTitle>Scrolling Example</span> <span bitDialogTitle>Scrolling Example</span>
<span bitDialogContent> <span bitDialogContent>
Dialog body text goes here.<br> Dialog body text goes here.<br>
<ng-container *ngFor="let _ of [].constructor(100)"> <ng-container *ngFor="let _ of [].constructor(100)">
repeating lines of characters <br> repeating lines of characters <br>
</ng-container>
end of sequence!
</span>
<ng-container bitDialogFooter>
<button bitButton buttonType="primary" [disabled]="loading">Save</button>
<button bitButton buttonType="secondary" [disabled]="loading">Cancel</button>
</ng-container> </ng-container>
end of sequence! </bit-dialog>
</span>
<ng-container bitDialogFooter>
<button bitButton buttonType="primary">Save</button>
<button bitButton buttonType="secondary">Cancel</button>
</ng-container>
</bit-dialog>
`, `,
}); });
@ -122,20 +131,20 @@ ScrollingContent.args = {
const TemplateTabbed: Story<DialogComponent> = (args: DialogComponent) => ({ const TemplateTabbed: Story<DialogComponent> = (args: DialogComponent) => ({
props: args, props: args,
template: ` template: `
<bit-dialog [dialogSize]="dialogSize" [disablePadding]="disablePadding"> <bit-dialog [dialogSize]="dialogSize" [disablePadding]="disablePadding">
<span bitDialogTitle>Tab Content Example</span> <span bitDialogTitle>Tab Content Example</span>
<span bitDialogContent> <span bitDialogContent>
<bit-tab-group> <bit-tab-group>
<bit-tab label="First Tab">First Tab Content</bit-tab> <bit-tab label="First Tab">First Tab Content</bit-tab>
<bit-tab label="Second Tab">Second Tab Content</bit-tab> <bit-tab label="Second Tab">Second Tab Content</bit-tab>
<bit-tab label="Third Tab">Third Tab Content</bit-tab> <bit-tab label="Third Tab">Third Tab Content</bit-tab>
</bit-tab-group> </bit-tab-group>
</span> </span>
<ng-container bitDialogFooter> <ng-container bitDialogFooter>
<button bitButton buttonType="primary">Save</button> <button bitButton buttonType="primary" [disabled]="loading">Save</button>
<button bitButton buttonType="secondary">Cancel</button> <button bitButton buttonType="secondary" [disabled]="loading">Cancel</button>
</ng-container> </ng-container>
</bit-dialog> </bit-dialog>
`, `,
}); });