13 changed files with 239 additions and 67 deletions
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
import { DialogModule, DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; |
||||
import { Component, Inject } from "@angular/core"; |
||||
import { Meta, moduleMetadata, Story } from "@storybook/angular"; |
||||
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; |
||||
|
||||
import { ButtonModule } from "../button"; |
||||
import { I18nMockService } from "../utils/i18n-mock.service"; |
||||
|
||||
import { DialogService } from "./dialog.service"; |
||||
import { DialogComponent } from "./dialog/dialog.component"; |
||||
import { DialogCloseDirective } from "./directives/dialog-close.directive"; |
||||
import { DialogTitleContainerDirective } from "./directives/dialog-title-container.directive"; |
||||
|
||||
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 bitDialogTitle>Dialog Title</span> |
||||
<span bitDialogContent> |
||||
Dialog body text goes here. |
||||
<br /> |
||||
Animal: {{ animal }} |
||||
</span> |
||||
<div bitDialogFooter 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: [ |
||||
DialogCloseDirective, |
||||
DialogComponent, |
||||
DialogTitleContainerDirective, |
||||
StoryDialogContentComponent, |
||||
], |
||||
imports: [ButtonModule, DialogModule], |
||||
providers: [ |
||||
DialogService, |
||||
{ |
||||
provide: I18nService, |
||||
useFactory: () => { |
||||
return new I18nMockService({ |
||||
close: "Close", |
||||
}); |
||||
}, |
||||
}, |
||||
], |
||||
}), |
||||
], |
||||
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({}); |
||||
@ -1,18 +1,15 @@
@@ -1,18 +1,15 @@
|
||||
import { DialogRef } from "@angular/cdk/dialog"; |
||||
import { Directive, Input, Optional } from "@angular/core"; |
||||
import { Directive, HostListener, 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() { |
||||
@HostListener("click") close(): void { |
||||
this.dialogRef.close(this.dialogResult); |
||||
} |
||||
} |
||||
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
import { CdkDialogContainer, DialogRef } from "@angular/cdk/dialog"; |
||||
import { Directive, HostBinding, Input, OnInit, Optional } from "@angular/core"; |
||||
|
||||
// Increments for each instance of this component
|
||||
let nextId = 0; |
||||
|
||||
@Directive({ |
||||
selector: "[bitDialogTitleContainer]", |
||||
}) |
||||
export class DialogTitleContainerDirective implements OnInit { |
||||
@HostBinding("id") id = `bit-dialog-title-${nextId++}`; |
||||
|
||||
@Input() simple = false; |
||||
|
||||
constructor(@Optional() private dialogRef: DialogRef<any>) {} |
||||
|
||||
ngOnInit(): void { |
||||
// Based on angular/components, licensed under MIT
|
||||
// https://github.com/angular/components/blob/14.2.0/src/material/dialog/dialog-content-directives.ts#L121-L128
|
||||
if (this.dialogRef) { |
||||
Promise.resolve().then(() => { |
||||
const container = this.dialogRef.containerInstance as CdkDialogContainer; |
||||
|
||||
if (container && !container._ariaLabelledBy) { |
||||
container._ariaLabelledBy = this.id; |
||||
} |
||||
}); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
import { Pipe, PipeTransform } from "@angular/core"; |
||||
|
||||
import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; |
||||
|
||||
/** |
||||
* Temporarily duplicate this pipe |
||||
*/ |
||||
@Pipe({ |
||||
name: "i18n", |
||||
}) |
||||
export class I18nPipe implements PipeTransform { |
||||
constructor(private i18nService: I18nService) {} |
||||
|
||||
transform(id: string, p1?: string, p2?: string, p3?: string): string { |
||||
return this.i18nService.t(id, p1, p2, p3); |
||||
} |
||||
} |
||||
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
export * from "./shared.module"; |
||||
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
import { CommonModule } from "@angular/common"; |
||||
import { NgModule } from "@angular/core"; |
||||
|
||||
import { I18nPipe } from "./i18n.pipe"; |
||||
|
||||
@NgModule({ |
||||
imports: [CommonModule], |
||||
declarations: [I18nPipe], |
||||
exports: [CommonModule, I18nPipe], |
||||
}) |
||||
export class SharedModule {} |
||||
Loading…
Reference in new issue