mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-02 18:17:46 +01:00
[CL-46] Dialogs (#3237)
This commit is contained in:
parent
e7220644d1
commit
762fac062f
2
.github/workflows/chromatic.yml
vendored
2
.github/workflows/chromatic.yml
vendored
@ -39,4 +39,4 @@ jobs:
|
||||
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
|
||||
exitOnceUploaded: true
|
||||
onlyChanged: true
|
||||
externals: "[\"components/**/*.scss\", \"components/tailwind.config*.js\"]"
|
||||
externals: "[\"libs/components/**/*.scss\", \"libs/components/tailwind.config*.js\"]"
|
||||
|
18
libs/components/src/dialog/dialog-close.directive.ts
Normal file
18
libs/components/src/dialog/dialog-close.directive.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { DialogRef } from "@angular/cdk/dialog";
|
||||
import { Directive, Input, Optional } from "@angular/core";
|
||||
|
||||
@Directive({
|
||||
selector: "[bitDialogClose]",
|
||||
host: {
|
||||
"(click)": "close()",
|
||||
},
|
||||
})
|
||||
export class DialogCloseDirective {
|
||||
@Input("bit-dialog-close") dialogResult: any;
|
||||
|
||||
constructor(@Optional() public dialogRef: DialogRef<any>) {}
|
||||
|
||||
close() {
|
||||
this.dialogRef.close(this.dialogResult);
|
||||
}
|
||||
}
|
78
libs/components/src/dialog/dialog-service.stories.ts
Normal file
78
libs/components/src/dialog/dialog-service.stories.ts
Normal file
@ -0,0 +1,78 @@
|
||||
import { DialogModule, DialogRef, DIALOG_DATA } from "@angular/cdk/dialog";
|
||||
import { Component, Inject } from "@angular/core";
|
||||
import { Meta, moduleMetadata, Story } from "@storybook/angular";
|
||||
|
||||
import { ButtonModule } from "../button";
|
||||
|
||||
import { DialogCloseDirective } from "./dialog-close.directive";
|
||||
import { DialogService } from "./dialog.service";
|
||||
import { DialogComponent } from "./dialog/dialog.component";
|
||||
|
||||
interface Animal {
|
||||
animal: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: "app-story-dialog",
|
||||
template: `<button bitButton (click)="openDialog()">Open Dialog</button>`,
|
||||
})
|
||||
class StoryDialogComponent {
|
||||
constructor(public dialogService: DialogService) {}
|
||||
|
||||
openDialog() {
|
||||
this.dialogService.open(StoryDialogContentComponent, {
|
||||
data: {
|
||||
animal: "panda",
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: "story-dialog-content",
|
||||
template: `
|
||||
<bit-dialog [dialogSize]="large">
|
||||
<span bit-dialog-title>Dialog Title</span>
|
||||
<span bit-dialog-content>
|
||||
Dialog body text goes here.
|
||||
<br />
|
||||
Animal: {{ animal }}
|
||||
</span>
|
||||
<div bit-dialog-footer class="tw-flex tw-flex-row tw-gap-2">
|
||||
<button bitButton buttonType="primary" (click)="dialogRef.close()">Save</button>
|
||||
<button bitButton buttonType="secondary" bitDialogClose>Cancel</button>
|
||||
</div>
|
||||
</bit-dialog>
|
||||
`,
|
||||
})
|
||||
class StoryDialogContentComponent {
|
||||
constructor(public dialogRef: DialogRef, @Inject(DIALOG_DATA) private data: Animal) {}
|
||||
|
||||
get animal() {
|
||||
return this.data?.animal;
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
title: "Component Library/Dialogs/Service",
|
||||
component: StoryDialogComponent,
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
declarations: [DialogComponent, StoryDialogContentComponent, DialogCloseDirective],
|
||||
imports: [ButtonModule, DialogModule],
|
||||
providers: [DialogService],
|
||||
}),
|
||||
],
|
||||
parameters: {
|
||||
design: {
|
||||
type: "figma",
|
||||
url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library",
|
||||
},
|
||||
},
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<StoryDialogComponent> = (args: StoryDialogComponent) => ({
|
||||
props: args,
|
||||
});
|
||||
|
||||
export const Default = Template.bind({});
|
16
libs/components/src/dialog/dialog.module.ts
Normal file
16
libs/components/src/dialog/dialog.module.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { DialogModule as CdkDialogModule } from "@angular/cdk/dialog";
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { NgModule } from "@angular/core";
|
||||
|
||||
import { DialogCloseDirective } from "./dialog-close.directive";
|
||||
import { DialogService } from "./dialog.service";
|
||||
import { DialogComponent } from "./dialog/dialog.component";
|
||||
import { SimpleDialogComponent } from "./simple-dialog/simple-dialog.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, CdkDialogModule],
|
||||
declarations: [DialogCloseDirective, DialogComponent, SimpleDialogComponent],
|
||||
exports: [CdkDialogModule, DialogComponent, SimpleDialogComponent],
|
||||
providers: [DialogService],
|
||||
})
|
||||
export class DialogModule {}
|
18
libs/components/src/dialog/dialog.service.ts
Normal file
18
libs/components/src/dialog/dialog.service.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { Dialog, DialogConfig, DialogRef } from "@angular/cdk/dialog";
|
||||
import { ComponentType } from "@angular/cdk/overlay";
|
||||
import { Injectable, TemplateRef } from "@angular/core";
|
||||
|
||||
@Injectable()
|
||||
export class DialogService extends Dialog {
|
||||
override open<R = unknown, D = unknown, C = unknown>(
|
||||
componentOrTemplateRef: ComponentType<C> | TemplateRef<C>,
|
||||
config?: DialogConfig<D, DialogRef<R, C>>
|
||||
): DialogRef<R, C> {
|
||||
config = {
|
||||
backdropClass: ["tw-fixed", "tw-bg-black", "tw-bg-opacity-30", "tw-inset-0", "tw-z-40"],
|
||||
...config,
|
||||
};
|
||||
|
||||
return super.open(componentOrTemplateRef, config);
|
||||
}
|
||||
}
|
@ -6,20 +6,20 @@
|
||||
class="tw-flex tw-gap-4 tw-border-0 tw-border-b tw-border-solid tw-border-secondary-300 tw-p-4"
|
||||
>
|
||||
<h2 class="tw-mb-0 tw-grow tw-text-lg tw-uppercase">
|
||||
<ng-content select="[bit-modal-title]"></ng-content>
|
||||
<ng-content select="[bit-dialog-title]"></ng-content>
|
||||
</h2>
|
||||
<button class="tw-border-0 tw-bg-transparent tw-p-0">
|
||||
<button class="tw-border-0 tw-bg-transparent tw-p-0" bitDialogClose>
|
||||
<i class="bwi bwi-close tw-text-xs tw-font-bold tw-text-main" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="tw-overflow-y-auto tw-p-4 tw-pb-8">
|
||||
<ng-content select="[bit-modal-content]"></ng-content>
|
||||
<ng-content select="[bit-dialog-content]"></ng-content>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="tw-border-0 tw-border-t tw-border-solid tw-border-secondary-300 tw-bg-background-alt tw-p-4"
|
||||
>
|
||||
<ng-content select="[bit-modal-footer]"></ng-content>
|
||||
<ng-content select="[bit-dialog-footer]"></ng-content>
|
||||
</div>
|
||||
</div>
|
23
libs/components/src/dialog/dialog/dialog.component.ts
Normal file
23
libs/components/src/dialog/dialog/dialog.component.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { Component, Input } from "@angular/core";
|
||||
|
||||
@Component({
|
||||
selector: "bit-dialog",
|
||||
templateUrl: "./dialog.component.html",
|
||||
})
|
||||
export class DialogComponent {
|
||||
@Input() dialogSize: "small" | "default" | "large" = "default";
|
||||
|
||||
get width() {
|
||||
switch (this.dialogSize) {
|
||||
case "small": {
|
||||
return "tw-w-96";
|
||||
}
|
||||
case "large": {
|
||||
return "tw-w-75vw";
|
||||
}
|
||||
default: {
|
||||
return "tw-w-50vw";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
81
libs/components/src/dialog/dialog/dialog.stories.ts
Normal file
81
libs/components/src/dialog/dialog/dialog.stories.ts
Normal file
@ -0,0 +1,81 @@
|
||||
import { Meta, moduleMetadata, Story } from "@storybook/angular";
|
||||
|
||||
import { ButtonModule } from "../../button";
|
||||
|
||||
import { DialogComponent } from "./dialog.component";
|
||||
|
||||
export default {
|
||||
title: "Component Library/Dialogs/Dialog",
|
||||
component: DialogComponent,
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [ButtonModule],
|
||||
}),
|
||||
],
|
||||
args: {
|
||||
dialogSize: "small",
|
||||
},
|
||||
parameters: {
|
||||
design: {
|
||||
type: "figma",
|
||||
url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library",
|
||||
},
|
||||
},
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<DialogComponent> = (args: DialogComponent) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-dialog [dialogSize]="dialogSize">
|
||||
<span bit-dialog-title>{{title}}</span>
|
||||
<span bit-dialog-content>Dialog body text goes here.</span>
|
||||
<div bit-dialog-footer class="tw-flex tw-flex-row tw-gap-2">
|
||||
<button bitButton buttonType="primary">Save</button>
|
||||
<button bitButton buttonType="secondary">Cancel</button>
|
||||
</div>
|
||||
</bit-dialog>
|
||||
`,
|
||||
});
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
dialogSize: "default",
|
||||
title: "Default",
|
||||
};
|
||||
|
||||
export const Small = Template.bind({});
|
||||
Small.args = {
|
||||
dialogSize: "small",
|
||||
title: "Small",
|
||||
};
|
||||
|
||||
export const Large = Template.bind({});
|
||||
Large.args = {
|
||||
dialogSize: "large",
|
||||
title: "Large",
|
||||
};
|
||||
|
||||
const TemplateScrolling: Story<DialogComponent> = (args: DialogComponent) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-dialog [dialogSize]="dialogSize">
|
||||
<span bit-dialog-title>Scrolling Example</span>
|
||||
<span bit-dialog-content>
|
||||
Dialog body text goes here.<br>
|
||||
<ng-container *ngFor="let _ of [].constructor(100)">
|
||||
repeating lines of characters <br>
|
||||
</ng-container>
|
||||
end of sequence!
|
||||
</span>
|
||||
<div bit-dialog-footer class="tw-flex tw-flex-row tw-gap-2">
|
||||
<button bitButton buttonType="primary">Save</button>
|
||||
<button bitButton buttonType="secondary">Cancel</button>
|
||||
</div>
|
||||
</bit-dialog>
|
||||
`,
|
||||
});
|
||||
|
||||
export const ScrollingContent = TemplateScrolling.bind({});
|
||||
ScrollingContent.args = {
|
||||
dialogSize: "small",
|
||||
};
|
2
libs/components/src/dialog/index.ts
Normal file
2
libs/components/src/dialog/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from "./dialog.module";
|
||||
export * from "./dialog.service";
|
@ -2,18 +2,18 @@
|
||||
class="tw-my-4 tw-flex tw-max-h-screen tw-max-w-sm tw-flex-col tw-overflow-hidden tw-rounded tw-border tw-border-solid tw-border-secondary-300 tw-bg-text-contrast tw-text-main"
|
||||
>
|
||||
<div class="tw-flex tw-flex-col tw-items-center tw-gap-2 tw-px-4 tw-pt-4 tw-text-center">
|
||||
<ng-content *ngIf="hasIcon; else elseBlock" select="[bit-modal-icon]"></ng-content>
|
||||
<ng-content *ngIf="hasIcon; else elseBlock" select="[bit-dialog-icon]"></ng-content>
|
||||
<ng-template #elseBlock>
|
||||
<i class="bwi bwi-exclamation-triangle tw-text-3xl tw-text-warning" aria-hidden="true"></i>
|
||||
</ng-template>
|
||||
<h2 class="tw-mb-0 tw-text-base tw-font-semibold">
|
||||
<ng-content select="[bit-modal-title]"></ng-content>
|
||||
<ng-content select="[bit-dialog-title]"></ng-content>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="tw-overflow-y-auto tw-px-4 tw-pt-2 tw-pb-4 tw-text-center tw-text-base">
|
||||
<ng-content select="[bit-modal-content]"></ng-content>
|
||||
<ng-content select="[bit-dialog-content]"></ng-content>
|
||||
</div>
|
||||
<div class="tw-border-0 tw-border-t tw-border-solid tw-border-secondary-300 tw-p-4">
|
||||
<ng-content select="[bit-modal-footer]"></ng-content>
|
||||
<ng-content select="[bit-dialog-footer]"></ng-content>
|
||||
</div>
|
||||
</div>
|
@ -1,13 +1,13 @@
|
||||
import { Component, ContentChild, Directive } from "@angular/core";
|
||||
|
||||
@Directive({ selector: "[bit-modal-icon]" })
|
||||
@Directive({ selector: "[bit-dialog-icon]" })
|
||||
export class IconDirective {}
|
||||
|
||||
@Component({
|
||||
selector: "bit-simple-modal",
|
||||
templateUrl: "./modal-simple.component.html",
|
||||
selector: "bit-simple-dialog",
|
||||
templateUrl: "./simple-dialog.component.html",
|
||||
})
|
||||
export class ModalSimpleComponent {
|
||||
export class SimpleDialogComponent {
|
||||
@ContentChild(IconDirective) icon!: IconDirective;
|
||||
|
||||
get hasIcon() {
|
@ -0,0 +1,81 @@
|
||||
import { Meta, moduleMetadata, Story } from "@storybook/angular";
|
||||
|
||||
import { ButtonModule } from "../../button";
|
||||
|
||||
import { IconDirective, SimpleDialogComponent } from "./simple-dialog.component";
|
||||
|
||||
export default {
|
||||
title: "Component Library/Dialogs/Simple Dialog",
|
||||
component: SimpleDialogComponent,
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [ButtonModule],
|
||||
declarations: [IconDirective],
|
||||
}),
|
||||
],
|
||||
parameters: {
|
||||
design: {
|
||||
type: "figma",
|
||||
url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library",
|
||||
},
|
||||
},
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<SimpleDialogComponent> = (args: SimpleDialogComponent) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-simple-dialog>
|
||||
<span bit-dialog-title>Alert Dialog</span>
|
||||
<span bit-dialog-content>Message Content</span>
|
||||
<div bit-dialog-footer class="tw-flex tw-flex-row tw-gap-2">
|
||||
<button bitButton buttonType="primary">Yes</button>
|
||||
<button bitButton buttonType="secondary">No</button>
|
||||
</div>
|
||||
</bit-simple-dialog>
|
||||
`,
|
||||
});
|
||||
|
||||
export const Default = Template.bind({});
|
||||
|
||||
const TemplateWithIcon: Story<SimpleDialogComponent> = (args: SimpleDialogComponent) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-simple-dialog>
|
||||
<i bit-dialog-icon class="bwi bwi-star tw-text-3xl tw-text-success" aria-hidden="true"></i>
|
||||
<span bit-dialog-title>Premium Subscription Available</span>
|
||||
<span bit-dialog-content> Message Content</span>
|
||||
<div bit-dialog-footer class="tw-flex tw-flex-row tw-gap-2">
|
||||
<button bitButton buttonType="primary">Yes</button>
|
||||
<button bitButton buttonType="secondary">No</button>
|
||||
</div>
|
||||
</bit-simple-dialog>
|
||||
`,
|
||||
});
|
||||
|
||||
export const CustomIcon = TemplateWithIcon.bind({});
|
||||
|
||||
const TemplateScroll: Story<SimpleDialogComponent> = (args: SimpleDialogComponent) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-simple-dialog>
|
||||
<span bit-dialog-title>Alert Dialog</span>
|
||||
<span bit-dialog-content>
|
||||
Message Content
|
||||
Message text goes here.<br>
|
||||
<ng-container *ngFor="let _ of [].constructor(100)">
|
||||
repeating lines of characters <br>
|
||||
</ng-container>
|
||||
end of sequence!
|
||||
</span>
|
||||
<div bit-dialog-footer class="tw-flex tw-flex-row tw-gap-2">
|
||||
<button bitButton buttonType="primary">Yes</button>
|
||||
<button bitButton buttonType="secondary">No</button>
|
||||
</div>
|
||||
</bit-simple-dialog>
|
||||
`,
|
||||
});
|
||||
|
||||
export const ScrollingContent = TemplateScroll.bind({});
|
||||
ScrollingContent.args = {
|
||||
useDefaultIcon: true,
|
||||
};
|
@ -5,7 +5,7 @@ export * from "./callout";
|
||||
export * from "./form-field";
|
||||
export * from "./icon";
|
||||
export * from "./menu";
|
||||
export * from "./modal";
|
||||
export * from "./dialog";
|
||||
export * from "./submit-button";
|
||||
export * from "./tabs";
|
||||
export * from "./toggle-group";
|
||||
|
@ -1,3 +0,0 @@
|
||||
export * from "./modal.component";
|
||||
export * from "./modal-simple.component";
|
||||
export * from "./modal.module";
|
@ -1,85 +0,0 @@
|
||||
import { Meta, moduleMetadata, Story } from "@storybook/angular";
|
||||
|
||||
import { ButtonModule } from "../button";
|
||||
|
||||
import { IconDirective, ModalSimpleComponent } from "./modal-simple.component";
|
||||
|
||||
export default {
|
||||
title: "Component Library/Modals/Simple Modal",
|
||||
component: ModalSimpleComponent,
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [ButtonModule],
|
||||
declarations: [IconDirective],
|
||||
}),
|
||||
],
|
||||
parameters: {
|
||||
design: {
|
||||
type: "figma",
|
||||
url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library",
|
||||
},
|
||||
},
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<ModalSimpleComponent> = (args: ModalSimpleComponent) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-simple-modal>
|
||||
<span bit-modal-title> Alert Modal
|
||||
</span>
|
||||
<span bit-modal-content> Message Content
|
||||
</span>
|
||||
<div bit-modal-footer class="tw-flex tw-flex-row tw-gap-2">
|
||||
<button bitButton buttonType="primary"> Yes </button>
|
||||
<button bitButton buttonType="secondary"> No </button>
|
||||
</div>
|
||||
</bit-simple-modal>
|
||||
`,
|
||||
});
|
||||
|
||||
export const Default = Template.bind({});
|
||||
|
||||
const TemplateWithIcon: Story<ModalSimpleComponent> = (args: ModalSimpleComponent) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-simple-modal>
|
||||
<i bit-modal-icon class="bwi bwi-star tw-text-3xl tw-text-success" aria-hidden="true"></i>
|
||||
<span bit-modal-title> Premium Subscription Available
|
||||
</span>
|
||||
<span bit-modal-content> Message Content
|
||||
</span>
|
||||
<div bit-modal-footer class="tw-flex tw-flex-row tw-gap-2">
|
||||
<button bitButton buttonType="primary"> Yes </button>
|
||||
<button bitButton buttonType="secondary"> No </button>
|
||||
</div>
|
||||
</bit-simple-modal>
|
||||
`,
|
||||
});
|
||||
|
||||
export const CustomIcon = TemplateWithIcon.bind({});
|
||||
|
||||
const TemplateScroll: Story<ModalSimpleComponent> = (args: ModalSimpleComponent) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-simple-modal>
|
||||
<span bit-modal-title> Alert Modal
|
||||
</span>
|
||||
<span bit-modal-content> Message Content
|
||||
Message text goes here.<br>
|
||||
<ng-container *ngFor="let _ of [].constructor(100)">
|
||||
repeating lines of characters <br>
|
||||
</ng-container>
|
||||
end of sequence!
|
||||
</span>
|
||||
<div bit-modal-footer class="tw-flex tw-flex-row tw-gap-2">
|
||||
<button bitButton buttonType="primary"> Yes </button>
|
||||
<button bitButton buttonType="secondary"> No </button>
|
||||
</div>
|
||||
</bit-simple-modal>
|
||||
`,
|
||||
});
|
||||
|
||||
export const ScrollingContent = TemplateScroll.bind({});
|
||||
ScrollingContent.args = {
|
||||
useDefaultIcon: true,
|
||||
};
|
@ -1,23 +0,0 @@
|
||||
import { Component, Input } from "@angular/core";
|
||||
|
||||
@Component({
|
||||
selector: "bit-modal",
|
||||
templateUrl: "./modal.component.html",
|
||||
})
|
||||
export class ModalComponent {
|
||||
@Input() modalSize: "small" | "default" | "large";
|
||||
|
||||
get width() {
|
||||
switch (this.modalSize) {
|
||||
case "small": {
|
||||
return "tw-max-w-xs";
|
||||
}
|
||||
case "large": {
|
||||
return "tw-max-w-4xl";
|
||||
}
|
||||
default: {
|
||||
return "tw-max-w-xl";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { NgModule } from "@angular/core";
|
||||
|
||||
import { ModalSimpleComponent } from "./modal-simple.component";
|
||||
import { ModalComponent } from "./modal.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
exports: [ModalComponent, ModalSimpleComponent],
|
||||
declarations: [ModalComponent, ModalSimpleComponent],
|
||||
})
|
||||
export class ModalModule {}
|
@ -1,80 +0,0 @@
|
||||
import { Meta, moduleMetadata, Story } from "@storybook/angular";
|
||||
|
||||
import { ButtonModule } from "../button";
|
||||
|
||||
import { ModalComponent } from "./modal.component";
|
||||
|
||||
export default {
|
||||
title: "Component Library/Modals/Modal",
|
||||
component: ModalComponent,
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
imports: [ButtonModule],
|
||||
}),
|
||||
],
|
||||
args: {
|
||||
modalSize: "small",
|
||||
},
|
||||
parameters: {
|
||||
design: {
|
||||
type: "figma",
|
||||
url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library",
|
||||
},
|
||||
},
|
||||
} as Meta;
|
||||
|
||||
const Template: Story<ModalComponent> = (args: ModalComponent) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-modal [modalSize]="modalSize">
|
||||
<span bit-modal-title> Modal Title </span>
|
||||
<span bit-modal-content>
|
||||
Modal body text goes here.
|
||||
</span>
|
||||
<div bit-modal-footer class="tw-flex tw-flex-row tw-gap-2">
|
||||
<button bitButton buttonType="primary"> Save </button>
|
||||
<button bitButton buttonType="secondary"> Cancel </button>
|
||||
</div>
|
||||
</bit-modal>
|
||||
`,
|
||||
});
|
||||
|
||||
export const Default = Template.bind({});
|
||||
Default.args = {
|
||||
modalSize: "default",
|
||||
};
|
||||
|
||||
export const Small = Template.bind({});
|
||||
Small.args = {
|
||||
modalSize: "small",
|
||||
};
|
||||
|
||||
export const Large = Template.bind({});
|
||||
Large.args = {
|
||||
modalSize: "large",
|
||||
};
|
||||
|
||||
const TemplateScrolling: Story<ModalComponent> = (args: ModalComponent) => ({
|
||||
props: args,
|
||||
template: `
|
||||
<bit-modal [modalSize]="modalSize">
|
||||
<span bit-modal-title> Modal Title </span>
|
||||
<span bit-modal-content>
|
||||
Modal body text goes here.<br>
|
||||
<ng-container *ngFor="let _ of [].constructor(100)">
|
||||
repeating lines of characters <br>
|
||||
</ng-container>
|
||||
end of sequence!
|
||||
</span>
|
||||
<div bit-modal-footer class="tw-flex tw-flex-row tw-gap-2">
|
||||
<button bitButton buttonType="primary"> Save </button>
|
||||
<button bitButton buttonType="secondary"> Cancel </button>
|
||||
</div>
|
||||
</bit-modal>
|
||||
`,
|
||||
});
|
||||
|
||||
export const ScrollingContent = TemplateScrolling.bind({});
|
||||
ScrollingContent.args = {
|
||||
modalSize: "small",
|
||||
};
|
@ -10,6 +10,7 @@ module.exports = {
|
||||
colors: {
|
||||
transparent: colors.transparent,
|
||||
current: colors.current,
|
||||
black: colors.black,
|
||||
primary: {
|
||||
300: "var(--color-primary-300)",
|
||||
500: "var(--color-primary-500)",
|
||||
@ -68,6 +69,12 @@ module.exports = {
|
||||
DEFAULT: theme("colors.background"),
|
||||
...theme("colors"),
|
||||
}),
|
||||
extend: {
|
||||
width: {
|
||||
"50vw": "50vw",
|
||||
"75vw": "75vw",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user