= {
+ [SimpleDialogType.PRIMARY]: "tw-text-primary-500",
+ [SimpleDialogType.SUCCESS]: "tw-text-success",
+ [SimpleDialogType.INFO]: "tw-text-info",
+ [SimpleDialogType.WARNING]: "tw-text-warning",
+ [SimpleDialogType.DANGER]: "tw-text-danger",
+};
+
+@Component({
+ selector: "bit-simple-configurable-dialog",
+ templateUrl: "./simple-configurable-dialog.component.html",
+})
+export class SimpleConfigurableDialogComponent {
+ SimpleDialogType = SimpleDialogType;
+ SimpleDialogCloseType = SimpleDialogCloseType;
+
+ get iconClasses() {
+ return [
+ this.simpleDialogOpts.icon ?? DEFAULT_ICON[this.simpleDialogOpts.type],
+ DEFAULT_COLOR[this.simpleDialogOpts.type],
+ ];
+ }
+
+ title: string;
+ content: string;
+ acceptButtonText: string;
+ cancelButtonText: string;
+
+ showCancelButton = this.simpleDialogOpts.cancelButtonText !== null;
+
+ constructor(
+ public dialogRef: DialogRef,
+ private i18nService: I18nService,
+ @Inject(DIALOG_DATA) public simpleDialogOpts?: SimpleDialogOptions
+ ) {
+ this.localizeText();
+ }
+
+ private localizeText() {
+ this.title = this.translate(this.simpleDialogOpts.title);
+ this.content = this.translate(this.simpleDialogOpts.content);
+ this.acceptButtonText = this.translate(this.simpleDialogOpts.acceptButtonText, "yes");
+
+ if (this.showCancelButton) {
+ // If accept text is overridden, use cancel, otherwise no
+ this.cancelButtonText = this.translate(
+ this.simpleDialogOpts.cancelButtonText,
+ this.simpleDialogOpts.acceptButtonText !== undefined ? "cancel" : "no"
+ );
+ }
+ }
+
+ private translate(translation: string | Translation, defaultKey?: string): string {
+ // Translation interface use implies we must localize.
+ if (typeof translation === "object") {
+ return this.i18nService.t(translation.key, ...translation.placeholders);
+ }
+
+ // Use string that is already translated or use default key post translate
+ return translation ?? this.i18nService.t(defaultKey);
+ }
+}
diff --git a/libs/components/src/dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts b/libs/components/src/dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts
new file mode 100644
index 0000000000..fb0a47ce80
--- /dev/null
+++ b/libs/components/src/dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts
@@ -0,0 +1,255 @@
+import { DialogModule, DialogRef } from "@angular/cdk/dialog";
+import { Component } from "@angular/core";
+import { Meta, moduleMetadata, Story } from "@storybook/angular";
+import { firstValueFrom } from "rxjs";
+
+import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
+
+import { ButtonModule } from "../../button";
+import { CalloutModule } from "../../callout";
+import { IconButtonModule } from "../../icon-button";
+import { SharedModule } from "../../shared/shared.module";
+import { I18nMockService } from "../../utils/i18n-mock.service";
+import { DialogService } from "../dialog.service";
+import { DialogCloseDirective } from "../directives/dialog-close.directive";
+import { DialogTitleContainerDirective } from "../directives/dialog-title-container.directive";
+import { SimpleDialogComponent } from "../simple-dialog/simple-dialog.component";
+
+import { SimpleDialogCloseType } from "./models/simple-dialog-close-type.enum";
+import { SimpleDialogOptions } from "./models/simple-dialog-options";
+import { SimpleDialogType } from "./models/simple-dialog-type.enum";
+
+@Component({
+ selector: "app-story-dialog",
+ template: `
+ Dialog Type Examples:
+
+
+
+
+
+
+
+
+
+
+
+
+ Custom Button Examples:
+
+
+
+
+
+
+
+
+ Custom Icon Example:
+
+
+
+
+ Additional Examples:
+
+
+
+
+
+ {{ dialogCloseResult }}
+ undefined
+
+ `,
+})
+class StoryDialogComponent {
+ primaryLocalizedSimpleDialogOpts: SimpleDialogOptions = {
+ title: this.i18nService.t("primaryTypeSimpleDialog"),
+ content: this.i18nService.t("dialogContent"),
+ type: SimpleDialogType.PRIMARY,
+ };
+
+ successLocalizedSimpleDialogOpts: SimpleDialogOptions = {
+ title: this.i18nService.t("successTypeSimpleDialog"),
+ content: this.i18nService.t("dialogContent"),
+ type: SimpleDialogType.SUCCESS,
+ };
+
+ infoLocalizedSimpleDialogOpts: SimpleDialogOptions = {
+ title: this.i18nService.t("infoTypeSimpleDialog"),
+ content: this.i18nService.t("dialogContent"),
+ type: SimpleDialogType.INFO,
+ };
+
+ warningLocalizedSimpleDialogOpts: SimpleDialogOptions = {
+ title: this.i18nService.t("warningTypeSimpleDialog"),
+ content: this.i18nService.t("dialogContent"),
+ type: SimpleDialogType.WARNING,
+ };
+
+ dangerLocalizedSimpleDialogOpts: SimpleDialogOptions = {
+ title: this.i18nService.t("dangerTypeSimpleDialog"),
+ content: this.i18nService.t("dialogContent"),
+ type: SimpleDialogType.DANGER,
+ };
+
+ primarySingleBtnSimpleDialogOpts: SimpleDialogOptions = {
+ title: this.i18nService.t("primaryTypeSimpleDialog"),
+ content: this.i18nService.t("dialogContent"),
+ type: SimpleDialogType.PRIMARY,
+ acceptButtonText: "Ok",
+ cancelButtonText: null,
+ };
+
+ primaryCustomBtnsSimpleDialogOpts: SimpleDialogOptions = {
+ title: this.i18nService.t("primaryTypeSimpleDialog"),
+ content: this.i18nService.t("dialogContent"),
+ type: SimpleDialogType.PRIMARY,
+ acceptButtonText: this.i18nService.t("accept"),
+ cancelButtonText: this.i18nService.t("decline"),
+ };
+
+ primaryAcceptBtnOverrideSimpleDialogOpts: SimpleDialogOptions = {
+ title: this.i18nService.t("primaryTypeSimpleDialog"),
+ content: this.i18nService.t("dialogContent"),
+ type: SimpleDialogType.PRIMARY,
+ acceptButtonText: "Ok",
+ };
+
+ primaryCustomIconSimpleDialogOpts: SimpleDialogOptions = {
+ title: this.i18nService.t("primaryTypeSimpleDialog"),
+ content: this.i18nService.t("dialogContent"),
+ type: SimpleDialogType.PRIMARY,
+ icon: "bwi-family",
+ };
+
+ primaryDisableCloseSimpleDialogOpts: SimpleDialogOptions = {
+ title: this.i18nService.t("primaryTypeSimpleDialog"),
+ content: this.i18nService.t("dialogContent"),
+ type: SimpleDialogType.PRIMARY,
+ disableClose: true,
+ };
+
+ showCallout = false;
+ calloutType = "info";
+ dialogCloseResult: undefined | SimpleDialogCloseType;
+
+ constructor(public dialogService: DialogService, private i18nService: I18nService) {}
+
+ openSimpleConfigurableDialog(opts: SimpleDialogOptions) {
+ const dialogReference: DialogRef = this.dialogService.openSimpleDialog(opts);
+
+ firstValueFrom(dialogReference.closed).then((result: SimpleDialogCloseType | undefined) => {
+ this.showCallout = true;
+ this.dialogCloseResult = result;
+ if (result && result === SimpleDialogCloseType.ACCEPT) {
+ this.calloutType = "success";
+ } else {
+ this.calloutType = "info";
+ }
+ });
+ }
+}
+
+export default {
+ title: "Component Library/Dialogs/Service/SimpleConfigurable",
+ component: StoryDialogComponent,
+ decorators: [
+ moduleMetadata({
+ declarations: [DialogCloseDirective, DialogTitleContainerDirective, SimpleDialogComponent],
+ imports: [SharedModule, IconButtonModule, ButtonModule, DialogModule, CalloutModule],
+ providers: [
+ DialogService,
+ {
+ provide: I18nService,
+ useFactory: () => {
+ return new I18nMockService({
+ primaryTypeSimpleDialog: "Primary Type Simple Dialog",
+ successTypeSimpleDialog: "Success Type Simple Dialog",
+ infoTypeSimpleDialog: "Info Type Simple Dialog",
+ warningTypeSimpleDialog: "Warning Type Simple Dialog",
+ dangerTypeSimpleDialog: "Danger Type Simple Dialog",
+ dialogContent: "Dialog content goes here",
+ yes: "Yes",
+ no: "No",
+ ok: "Ok",
+ cancel: "Cancel",
+ accept: "Accept",
+ decline: "Decline",
+ });
+ },
+ },
+ ],
+ }),
+ ],
+ parameters: {
+ design: {
+ type: "figma",
+ url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library",
+ },
+ },
+} as Meta;
+
+const Template: Story = (args: StoryDialogComponent) => ({
+ props: args,
+});
+
+export const Default = Template.bind({});