npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ngx-st-dialog

v18.0.1

Published

- [Overview](#overview) - [Installation](#installation) - [Basic Usage](#basic-usage) - [Methods](#methods) - [Usage Examples](#usage-examples) - [Best Practices](#best-practices)

Readme

Dialog Service - Complete Documentation

Table of Contents


Overview

The StDialogService provides pre-configured Material Dialog components for common scenarios:

  • Confirmation Dialog: Yes/No confirmation
  • Delete Warning: Confirmation with auto-filtering for positive responses
  • Confirmation with Reason: Requires user to provide a reason
  • Info Dialog: Simple informational dialog

Features:

  • Pre-styled Material Design dialogs
  • Customizable labels
  • Optional reason input
  • Observable-based responses
  • Button color customization

Installation

npm install ngx-st-dialog

Import the module:

import { StDialogModule } from 'ngx-st-dialog';

@NgModule({
  imports: [StDialogModule]
})
export class AppModule { }

Basic Usage

// Component
import { StDialogService } from 'ngx-st-dialog';

@Component({...})
export class MyComponent {
  constructor(private dialogService: StDialogService) {}
  
  delete(): void {
    this.dialogService
      .showDeleteWarning('Delete this user?')
      .subscribe(() => {
        // User confirmed - delete the item
        this.userService.delete(userId).subscribe();
      });
  }
}

Methods

showConfirmation(message: string, yesLabel?: string, noLabel?: string)

  • Description: Shows a basic confirmation dialog with Yes/No buttons.
  • Returns: Observable<boolean> - true if user clicks Yes, false if No
  • Parameters:
    • message: Dialog message text
    • yesLabel: Label for confirm button (default: "Yes")
    • noLabel: Label for cancel button (default: "No")
  • Example:
    this.dialogService
      .showConfirmation('Save changes?', 'Save', 'Cancel')
      .subscribe(confirmed => {
        if (confirmed) {
          this.save();
        }
      });

showDeleteWarning(message?: string, yesLabel?: string, noLabel?: string)

  • Description: Shows a confirmation dialog specifically for delete operations. Automatically filters for positive responses only.
  • Returns: Observable<boolean> - Only emits if user confirms (filters out false values)
  • Parameters:
    • message: Dialog message text (default: "Do you want to delete?")
    • yesLabel: Label for confirm button (default: "Yes")
    • noLabel: Label for cancel button (default: "No")
  • Example:
    this.dialogService
      .showDeleteWarning('Delete this item?', 'Delete', 'Cancel')
      .subscribe(() => {
        // Only executes if user confirmed
        this.itemService.delete(itemId).subscribe();
      });

showConfirmationWithReason(message, yesLabel?, noLabel?, reasonLabel?, reasonRequired?, acceptButtonColor?)

  • Description: Shows a confirmation dialog with a required/optional reason input field.
  • Returns: Observable<{ confirmed: boolean, reason: string }> - Confirmation status and reason text
  • Parameters:
    • message: Dialog message text
    • yesLabel: Label for confirm button (default: "Yes")
    • noLabel: Label for cancel button (default: "No")
    • reasonLabel: Label for reason input (default: "Reason")
    • reasonRequired: Whether reason is required (default: true)
    • acceptButtonColor: Button color - 'warn' | 'primary' | 'accent' (default: "warn")
  • Example:
    this.dialogService
      .showConfirmationWithReason(
        'Reject this application?',
        'Reject',
        'Cancel',
        'Reason for rejection',
        true,
        'warn'
      )
      .subscribe(result => {
        if (result?.confirmed) {
          this.rejectApplication(result.reason);
        }
      });

showInfo(message: string, closeLabel: string)

  • Description: Shows a simple informational dialog with one close button.
  • Returns: Observable<void> - Emits when dialog is closed
  • Parameters:
    • message: Information message to display
    • closeLabel: Label for close button
  • Example:
    this.dialogService
      .showInfo('Operation completed successfully', 'OK')
      .subscribe(() => {
        console.log('Dialog closed');
      });

Usage Examples

Example 1: Delete Confirmation

// Component
@Component({
  selector: 'app-user-list',
  template: `
    <button (click)="deleteUser(user)">Delete</button>
  `
})
export class UserListComponent {
  constructor(
    private dialogService: StDialogService,
    private userService: UserService,
    private snackBar: StSnackBarService
  ) {}
  
  deleteUser(user: User): void {
    this.dialogService
      .showDeleteWarning(
        `Delete user ${user.name}?`,
        'Delete',
        'Cancel'
      )
      .subscribe(() => {
        // Only executes if confirmed
        this.userService.delete(user.id).subscribe(
          () => {
            this.snackBar.success('User deleted');
            this.loadUsers();
          },
          error => {
            this.snackBar.error('Failed to delete user');
          }
        );
      });
  }
}

Example 2: Save Confirmation

// Component
@Component({
  selector: 'app-form',
  template: `
    <form [formGroup]="form">
      <!-- Form fields -->
      <button (click)="save()">Save</button>
    </form>
  `
})
export class FormComponent {
  form = this.fb.group({...});
  
  constructor(
    private fb: FormBuilder,
    private dialogService: StDialogService,
    private dataService: DataService
  ) {}
  
  save(): void {
    this.dialogService
      .showConfirmation(
        'Save these changes?',
        'Save',
        'Cancel'
      )
      .subscribe(confirmed => {
        if (confirmed) {
          this.dataService.save(this.form.value).subscribe(
            () => console.log('Saved'),
            error => console.error('Save failed')
          );
        }
      });
  }
}

Example 3: Reject with Reason

// Component
@Component({
  selector: 'app-approval',
  template: `
    <button (click)="approve()">Approve</button>
    <button (click)="reject()">Reject</button>
  `
})
export class ApprovalComponent {
  @Input() application: Application;
  
  constructor(
    private dialogService: StDialogService,
    private applicationService: ApplicationService
  ) {}
  
  approve(): void {
    this.dialogService
      .showConfirmation('Approve this application?', 'Approve', 'Cancel')
      .subscribe(confirmed => {
        if (confirmed) {
          this.applicationService.approve(this.application.id).subscribe();
        }
      });
  }
  
  reject(): void {
    this.dialogService
      .showConfirmationWithReason(
        'Reject this application?',
        'Reject',
        'Cancel',
        'Reason for rejection',
        true,  // Reason required
        'warn'
      )
      .subscribe(result => {
        if (result?.confirmed) {
          this.applicationService
            .reject(this.application.id, result.reason)
            .subscribe();
        }
      });
  }
}

Example 4: Discard Changes

// Component
@Component({
  selector: 'app-editor',
  template: `
    <form [formGroup]="form">
      <!-- Editor -->
      <button (click)="save()">Save</button>
      <button (click)="discard()">Discard</button>
    </form>
  `
})
export class EditorComponent {
  form = this.fb.group({...});
  
  constructor(
    private fb: FormBuilder,
    private dialogService: StDialogService
  ) {}
  
  discard(): void {
    if (this.form.dirty) {
      this.dialogService
        .showConfirmation(
          'Discard unsaved changes?',
          'Discard',
          'Keep Editing'
        )
        .subscribe(confirmed => {
          if (confirmed) {
            this.form.reset();
            this.router.navigate(['/']);
          }
        });
    } else {
      this.router.navigate(['/']);
    }
  }
  
  save(): void {
    // Save logic
  }
}

Example 5: Cancel with Reason

// Component
@Component({
  selector: 'app-order',
  template: `
    <button (click)="cancelOrder()">Cancel Order</button>
  `
})
export class OrderComponent {
  @Input() order: Order;
  
  constructor(
    private dialogService: StDialogService,
    private orderService: OrderService
  ) {}
  
  cancelOrder(): void {
    this.dialogService
      .showConfirmationWithReason(
        `Cancel order #${this.order.id}?`,
        'Cancel Order',
        'Keep Order',
        'Cancellation reason',
        true,
        'warn'
      )
      .subscribe(result => {
        if (result?.confirmed) {
          this.orderService
            .cancel(this.order.id, result.reason)
            .subscribe(
              () => {
                this.snackBar.success('Order cancelled');
                this.loadOrder();
              },
              error => {
                this.snackBar.error('Failed to cancel order');
              }
            );
        }
      });
  }
}

Example 6: Information Dialog

// Component
@Component({
  selector: 'app-welcome',
  template: `
    <button (click)="showWelcome()">Show Welcome Message</button>
  `
})
export class WelcomeComponent {
  constructor(private dialogService: StDialogService) {}
  
  showWelcome(): void {
    this.dialogService
      .showInfo(
        'Welcome to our application! Here are some tips to get started...',
        'Got it'
      )
      .subscribe(() => {
        console.log('Welcome message acknowledged');
      });
  }
}

Example 7: Bulk Delete

// Component
@Component({
  selector: 'app-bulk-actions',
  template: `
    <button (click)="deleteSelected()">Delete Selected ({{ selectedCount }})</button>
  `
})
export class BulkActionsComponent {
  @Input() selectedItems: any[] = [];
  
  get selectedCount(): number {
    return this.selectedItems.length;
  }
  
  constructor(
    private dialogService: StDialogService,
    private itemService: ItemService
  ) {}
  
  deleteSelected(): void {
    if (this.selectedCount === 0) {
      this.snackBar.warning('No items selected');
      return;
    }
    
    this.dialogService
      .showDeleteWarning(
        `Delete ${this.selectedCount} items?`,
        'Delete All',
        'Cancel'
      )
      .subscribe(() => {
        this.itemService.bulkDelete(this.selectedItems).subscribe(
          () => {
            this.snackBar.success(`${this.selectedCount} items deleted`);
            this.selectedItems = [];
          },
          error => {
            this.snackBar.error('Failed to delete items');
          }
        );
      });
  }
}

Example 8: Navigation Guard

// Guard
@Injectable({
  providedIn: 'root'
})
export class UnsavedChangesGuard implements CanDeactivate<any> {
  constructor(private dialogService: StDialogService) {}
  
  canDeactivate(component: any): Observable<boolean> | boolean {
    if (component.form && component.form.dirty) {
      return this.dialogService.showConfirmation(
        'You have unsaved changes. Leave this page?',
        'Leave',
        'Stay'
      );
    }
    return true;
  }
}

Example 9: Optional Reason

// Component
@Component({
  selector: 'app-flag-content',
  template: `
    <button (click)="flagContent()">Flag as Inappropriate</button>
  `
})
export class FlagContentComponent {
  @Input() contentId: string;
  
  constructor(
    private dialogService: StDialogService,
    private contentService: ContentService
  ) {}
  
  flagContent(): void {
    this.dialogService
      .showConfirmationWithReason(
        'Flag this content as inappropriate?',
        'Flag',
        'Cancel',
        'Additional details (optional)',
        false,  // Reason not required
        'warn'
      )
      .subscribe(result => {
        if (result?.confirmed) {
          this.contentService
            .flag(this.contentId, result.reason || '')
            .subscribe();
        }
      });
  }
}

Best Practices

  1. Use showDeleteWarning for delete operations:

    // Automatically filters, no need to check result
    this.dialogService.showDeleteWarning('Delete?').subscribe(() => {
      this.delete();  // Only runs if confirmed
    });
  2. Use showConfirmation for other confirmations:

    this.dialogService.showConfirmation('Save?').subscribe(confirmed => {
      if (confirmed) {
        this.save();
      }
    });
  3. Provide clear, specific messages:

    showDeleteWarning('Delete user John Doe?')  // Good
    showDeleteWarning('Delete?')  // Less clear
  4. Use appropriate button labels:

    showConfirmation('Save changes?', 'Save', 'Discard')  // Clear
    showConfirmation('Save changes?', 'Yes', 'No')  // Less clear
  5. Require reasons for critical actions:

    showConfirmationWithReason(
      'Reject application?',
      'Reject',
      'Cancel',
      'Rejection reason',
      true  // Required
    )
  6. Use warn color for destructive actions:

    showConfirmationWithReason(..., 'warn')  // For deletes, rejects
    showConfirmationWithReason(..., 'primary')  // For normal actions
  7. Handle dialog cancellation:

    this.dialogService.showConfirmation('Save?').subscribe(confirmed => {
      if (confirmed) {
        this.save();
      } else {
        console.log('User cancelled');
      }
    });

Dialog Types

Confirmation Dialog

  • Two buttons: Yes/No (customizable labels)
  • Returns: true or false
  • Use for: General confirmations

Delete Warning

  • Two buttons: Yes/No (customizable labels)
  • Returns: Filtered observable (only emits on confirm)
  • Use for: Delete operations

Confirmation with Reason

  • Text input for reason
  • Can be required or optional
  • Returns: { confirmed: boolean, reason: string }
  • Use for: Actions requiring explanation

Info Dialog

  • Single close button
  • Returns: void
  • Use for: Informational messages

Common Use Cases

  1. Delete Confirmations: Confirm before deleting records
  2. Save Confirmations: Confirm before saving changes
  3. Discard Changes: Warn about unsaved changes
  4. Rejection Reasons: Require explanation for rejections
  5. Cancellation Reasons: Require explanation for cancellations
  6. Bulk Operations: Confirm bulk actions
  7. Navigation Guards: Prevent leaving with unsaved changes
  8. Info Messages: Display important information

This documentation covers all methods and usage patterns for the Dialog Service.