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

viv-angular-common-components

v0.1.4

Published

In this version we are currently offering reusable confirmation dialog, loader and toastr.

Downloads

8

Readme

Angular Material and Angular Bootstrap Common components library

In this version we are currently offering reusable confirmation dialog, loader and toastr.

Features

  • Toastr Notifications: Displays customizable toast notifications with different types (Success, Error, Info, Warning).
  • Loader Component: Displays customizable loaders with different types (Spinner, Overlay, Dot, Image, Loading).
  • Confirmation Dialogs: Support for both Material UI and Bootstrap-styled confirmation dialogs.
  • Rating Component: Customizable star rating system with support for Font Awesome, Bootstrap, or custom icons. Includes hover effects, read-only mode, and two-way binding.
  • Image slider: Fully customizable image slider with smooth transitions, navigation arrows and full responsiveness for all device sizes using Material UI dialog.

Installation

To add the confirmation dialog to your Angular project:

npm install angular-common-components --save

Once installed, add the necessary modules to your app.module.ts:

import { NotificationModule, ConfirmationModule, LoaderModule, RatingModule, RatingActiveDirective, RatingInactiveDirective, ImageSliderModule } from 'viv-angular-common-components';

...

@NgModule({
    ...
   imports: [
     ...
     NotificationModule
     ConfirmationModule,
     LoaderModule,
     RatingModule,
     RatingActiveDirective,
     RatingInactiveDirective,
     ImageSliderModule,
    ...
   ],
   ...
})

export class AppModule {}

Adding Styles and Scripts

Ensure that you add the necessary Material UI and Bootstrap styles and scripts to the angular.json file in your project to ensure that the dialogs are styled properly.

  1. Add Material UI and Bootstrap to angular.json
"styles": [
              "node_modules/ngx-toastr/toastr.css",
              "node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              ...
            ],
            "scripts": [
              "node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
            ]

Sample usage

Now you can use the angular-common-components component in your app components, for example in app.component.ts:

1. Toastr Notification

import { Component } from "@angular/core";
import { NotificationConfig, NotificationService, NotificationType } from "viv-angular-common-components";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrl: "./app.component.scss",
})
export class AppComponent {
  config: NotificationConfig = {
    message: "This is my error message.",
    title: "error",
    type: NotificationType.ERROR,
    config: {
      timeOut: 3000,
      positionClass: "toast-center-center",
      closeButton: false,
    },
    backgroundColor: "#000",
    textColor: "#ffffff",
  };

  constructor(private notification: NotificationService) {}

  showToastr() {
    this.notification.show(this.config);
  }
}

And in template file app.component.html:

<button (click)="showToastr()">Show success</button>

Styling dialog

1. NotificationConfig Interface

| Option | Type | Default Value | Description | | --------------- | ---------------------- | --------------------------- | --------------------------------------------------------------------------------------- | | message | string | "" | The message to be displayed in the notification. | | title | string(optional) | "" | The title to be displayed along with the message. | | type | NotificationType | "" | The type of notification: SUCCESS, ERROR, INFO, or WARNING. | | config | ToastrConfig(optional) | Customizable toastr options | Additional toastr configuration options such as timeOut, closeButton, progressBar, etc. | | backgroundColor | optional |""| Toastr background color. | | textColor | optional |""| Toastr text color. |

2. NotificationType Enum

| Option | Type | Description | | ------- | ------ | ---------------------------------- | | SUCCESS | string | Represents a success notification. | | ERROR | string | Represents an error notification. | | INFO | string | Represents an info notification. | | WARNING | string | Represents a warning notification. |

3. IndividualConfig Options

| Option | Type | Default Value | Description | | ----------------- | ----------------------------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | | toastComponent | Component | Toast | Angular component that will be used | | closeButton | boolean | false | Show close button | | timeOut | number | 5000 | Time to live in milliseconds | | extendedTimeOut | number | 1000 | Time to close after a user hovers over toast | | disableTimeOut | boolean or 'timeOut' or 'extendedTimeOut' | false | Disable both timeOut and extendedTimeOut when set to true. Allows specifying which timeOut to disable, either: timeOut or extendedTimeOut | | easing | string | 'ease-in' | Toast component easing | | easeTime | string | number | Time spent easing | | enableHtml | boolean | false | Allow html in message | | newestOnTop | boolean | true | New toast placement | | progressBar | boolean | false | Show progress bar | | progressAnimation | 'decreasing' or 'increasing' | 'decreasing' | Changes the animation of the progress bar. | | toastClass | string | 'ngx-toastr' | CSS class(es) for toast | | positionClass | string | 'toast-top-right' | CSS class(es) for toast container | | titleClass | string | 'toast-title' | CSS class(es) for inside toast on title | | messageClass | string | 'toast-message' | CSS class(es) for inside toast on message | | tapToDismiss | boolean | true | Close on click | | onActivateTick | boolean | false | Fires changeDetectorRef.detectChanges() when activated. Helps show toast from asynchronous events outside of Angular's change detection |

2. Confirmation dialog

(i). Using Material ui confirmation dialog:

import { ConfirmationDialogService, DialogConfig } from 'viv-angular-common-components';
@Component({...})
export class AppComponent {

const dialogData: DialogConfig = {
    title: 'Confirm Action',
    description: 'Are you sure you want to perform this action?',
    buttons: [
      {
        label: 'Yes',
        value: 'Yes',
        bgColor: '#4CAF50',
        textColor: '#ffffff',
      },
      {
        label: 'No',
        value: 'No',
        bgColor: '#f44336',
        textColor: '#ffffff',
      },
      {
        label: 'Cancel',
        value: 'Cancel',
        bgColor: '#FFC107',
        textColor: '#000000',
      },
    ],
    dialogWidth: '500px',
  };

    constructor(private confirmationDialogService: ConfirmationDialogService) {}

    openConfirmationDialog(){
      this.confirmationDialogService.openDialog(this.dialogData).subscribe((res)=>{
        if (res === 'Yes') {
          console.log('Action Confirm.');
        } else if (res === 'No') {
          console.log('Action denied.');
        } else if (res === 'Cancel') {
          console.log('Action cancelled.');
        }
      });
    }
}

And in template file app.component.html:

<button (click)="openConfirmationDialog()">Open Confirmation Dialog</button>
<div>
  <viv-confirmation-bootstrap-dialog></viv-confirmation-bootstrap-dialog>
</div>

(ii). Using Bootstrap confirmation dialog:

import { ConfirmationDialogService, DialogConfig } from 'viv-angular-common-components';
@Component({...})
export class AppComponent implements OnInit{

const dialogData: DialogConfig = {
    title: 'Confirm Action',
    description: 'Are you sure you want to perform this action?',
    buttons: [
      {
        label: 'Yes',
        value: 'Yes',
        bgColor: '#4CAF50',
        textColor: '#ffffff',
      },
      {
        label: 'No',
        value: 'No',
        bgColor: '#f44336',
        textColor: '#ffffff',
      },
      {
        label: 'Cancel',
        value: 'Cancel',
        bgColor: '#FFC107',
        textColor: '#000000',
      },
    ],
    dialogWidth: '500px',
  };

    constructor(private confirmationDialogService: ConfirmationService) {}

        ngOnInit(): void {
    this.confirmationDialogService.dialogClose$.subscribe((res: any) => {
      if (res === 'Yes') {
        console.log('Action Confirm.');
      } else if (res === 'No') {
        console.log('Action denied.');
      } else if (res === 'Cancel') {
        console.log('Action cancelled.');
      } else {
        console.log('No response.');
      }
    });
  }

  openBootstrapConfirmationDialog() {
    this.confirmationDialogService.openBootstrapDialog(this.dialogData);
  }

}

And in template file app.component.html:

<button (click)="openBootstrapDialog()">Open Bootstrap Confirmation</button>

Styling dialog

1. DialogConfig Interface

| Option | Type | Default Value | Description | | ----------- | ------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | title | string | "" | Dialog Title | | description | string | "" | Dialog Description or message to display in the dialog | | buttons | Array | ButtonConfig | An array of button objects that define the actions in the dialog. Each button should include: label, bgColor, textColor, and value. | | dialogWidth | string | "300px" | The width of the dialog |

2. ButtonConfig Interface

| Option | Type | Default Value | Description | | --------- | ------ | ------------- | ------------------------------------------------------------------ | | label | string | "" | The label (text) to display on the button. | | bgColor | string | #DB3030 | The background color for the button. | | textColor | string | #ffffff | The text color for the button. | | value | any | "" | The value returned when the button is clicked (e.g., "Yes", "No"). |

3. Loader

(i). Spinner loader:

import { Component } from "@angular/core";
import { LoaderConfig, LoaderService, LoaderType, NotificationService } from "viv-angular-common-components";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrl: "./app.component.scss",
})
export class AppComponent {
  loaderData: LoaderConfig = {
    loaderType: LoaderType.SPINNER,
    loaderColor: "#666633",
  };

  constructor(private loaderService: LoaderService) {}

  startLoading() {
    this.loaderService.show(this.loaderData);

    setTimeout(() => {
      this.loaderService.hide();
    }, 3000);
  }
}

And in template file app.component.html:

<button (click)="startLoading()">Show Spinner</button>
</div>
<div>
  <viv-loader></viv-loader>
</div>

(ii). Overlay loader:

import { Component } from "@angular/core";
import { LoaderConfig, LoaderService, LoaderType, NotificationService } from "viv-angular-common-components";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrl: "./app.component.scss",
})
export class AppComponent {
  loaderData: LoaderConfig = {
    loaderType: LoaderType.OVERLAY,
    loaderColor: "#666633",
  };

  constructor(private loaderService: LoaderService) {}

  startLoading() {
    this.loaderService.show(this.loaderData);

    setTimeout(() => {
      this.loaderService.hide();
    }, 3000);
  }
}

And in template file app.component.html:

<button (click)="startLoading()">Show Spinner</button>
</div>
<div>
  <viv-loader></viv-loader>
</div>

(iii). Dotted loader:

import { Component } from "@angular/core";
import { LoaderConfig, LoaderService, LoaderType, NotificationService } from "viv-angular-common-components";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrl: "./app.component.scss",
})
export class AppComponent {
  loaderData: LoaderConfig = {
    loaderType: LoaderType.DOT,
    loaderColor: "#666633",
  };

  constructor(private loaderService: LoaderService) {}

  startLoading() {
    this.loaderService.show(this.loaderData);

    setTimeout(() => {
      this.loaderService.hide();
    }, 3000);
  }
}

And in template file app.component.html:

<button (click)="startLoading()">Show Spinner</button>
</div>
<div>
  <viv-loader></viv-loader>
</div>

(iv). Image loader:

import { Component } from "@angular/core";
import { LoaderConfig, LoaderService, LoaderType, NotificationService } from "viv-angular-common-components";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrl: "./app.component.scss",
})
export class AppComponent {
  loaderData: LoaderConfig = {
    loaderType: LoaderType.IMAGE,
    imageUrl: "77.jpg",
    loaderColor: "#666633",
  };

  constructor(private loaderService: LoaderService) {}

  startLoading() {
    this.loaderService.show(this.loaderData);

    setTimeout(() => {
      this.loaderService.hide();
    }, 3000);
  }
}

And in template file app.component.html:

<button (click)="startLoading()">Show Spinner</button>
</div>
<div>
  <viv-loader></viv-loader>
</div>

(v). Loading loader:

import { Component } from "@angular/core";
import { LoaderConfig, LoaderService, LoaderType, NotificationService } from "viv-angular-common-components";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrl: "./app.component.scss",
})
export class AppComponent {
  loaderData: LoaderConfig = {
    loaderType: LoaderType.LOADING,
    loaderColor: "#666633",
  };

  constructor(private loaderService: LoaderService) {}

  startLoading() {
    this.loaderService.show(this.loaderData);

    setTimeout(() => {
      this.loaderService.hide();
    }, 3000);
  }
}

And in template file app.component.html:

<button (click)="startLoading()">Show Spinner</button>
</div>
<div>
  <viv-loader></viv-loader>
</div>

Styling dialog

1. LoaderConfig Interface

| Option | Type | Default Value | Description | | ----------- | ---------- | ------------- | -------------------------------------------- | | loadertYPE | LoaderType | "" | The type of loader to display. | | imageUrl | string | null | Optional image URL for custom loader images. | | loaderColor | string | #3498db | The color of the spinner loader. |

2. LoaderType enum

| Option | Type | Value | Description | | ------- | ------ | --------- | ----------------------------------------- | | BARS | string | 'loading' | Represents a bars loading loader. | | HEARTBEAT | string | 'loading' | Represents a hartbeat type loading loader. | | ORBIT | string | 'loading' | Represents a orbit typeloading loader. | | WAWE | string | 'loading' | Represents a wawe type loading loader. | | TEXTPULSE | string | 'loading' | Represents a simple text loding message. | | SPINNER | string | 'spinner' | Represents a circular spinner loader. | | OVERLAY | string | 'overlay' | Represents a full-screen overlay loader. | | DOT | string | 'dot' | Represents a dot-based loader animation. | | IMAGE | string | 'image' | Represents a custom image-based loader. | | LOADING | string | 'loading' | Represents a simple loading text message. |

1. Rating Component

Add FontAwesomeModule in this file app.module.ts:

import { NgModule } from '@angular/core';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  declarations: [AppComponent, ...],
  imports: [
    ...
    FontAwesomeModule,
  ],
  exports: [...],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

(i). Using Bootstrap icons:

import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrl: "./app.component.scss",
})
export class AppComponent implements OnInit {
  userRating: number = 2;

  onRatingChange(rating: number): void {
    console.log("New rating:", rating);
  }

  constructor() {}
}

And in template file app.component.html:

<viv-rating [(rating)]="userRating" [maxRating]="5" [iconSize]="'40px'" (ratingChange)="onRatingChange($event)">
  <i *ratingActive class="bi bi-star-fill" style="margin: 2px; color: #edb867"></i>
  <i *ratingInactive class="bi bi-star-fill" style="margin: 2px; color: #d2d2d2"></i>
</viv-rating>

(ii). Using fontawesome icons:

import { Component } from "@angular/core";
import { faStar } from "@fortawesome/free-solid-svg-icons";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrl: "./app.component.scss",
})
export class AppComponent implements OnInit {
  userRating: number = 2;
  faStar = faStar;

  onRatingChange(rating: number): void {
    console.log("New rating:", rating);
  }

  constructor() {}
}

And in template file app.component.html:

<viv-rating effect [(rating)]="userRating" [maxRating]="5" (ratingChange)="onRatingChange($event)">
  <fa-icon *ratingActive [icon]="faStar" [fixedWidth]="true" size="lg" style="color: #edb867" />
  <fa-icon *ratingInactive [icon]="faStar" [fixedWidth]="true" size="lg" style="color: #d2d2d2" />
</viv-rating>

Note: If we not pass icons then it set's default star icon.

Summary of New Inputs:

  • [(rating)]="userRating": Binds the rating value to a variable.
  • [maxRating]="5": Defines the maximum rating (default 5).
  • [readOnly]="false": Makes the component read-only (default false).
  • [iconSize]="'40px'": Allows you to set the icon size (default 24px).

Explanation:

  • (ratingChange)="onRatingChange($event)": This listens for the ratingChange event emitted by the viv-rating component when the rating is changed. The $event contains the new rating value.
  • onRatingChange(rating: number): This method in your AppComponent will be called whenever the rating changes, and you can use it to perform any additional logic, like logging the new rating.

5. Image slider

import { Component } from "@angular/core";
import { ImageSliderConfig, } from "viv-angular-common-components";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrl: "./app.component.scss",
})
export class AppComponent {
  images: ImageSliderConfig[] = [
    {
      image:
        '11.jpg'
      thumbImage:
        '11.jpg'
      title: 'My first Image',
    },
    {
      image:
        '22.jpg'
      thumbImage:
        '22.jpg'
      title: 'My second Image',
    },
    {
      image:
        '33.jpg'
      thumbImage:
        '33.jpg'
      title: 'My third Image',
    },
    {
      image:
        '44.jpg',
      thumbImage:
        '44.jpg',
      title: 'My fourth Image',
    },
    {
      image:
        '55.jpg',
      thumbImage:
        '55.jpg',
      title: 'My fifth title',
    },
  ];

}

And in template file app.component.html:

<viv-image-slider [images]="images"></viv-image-slider>

Styling dialog

1. ImageSliderConfig Interface

| Option | Type | Default Value | Description | | ---------- | ---------------- | ------------- | --------------------------------------------------- | | image | string | "" | The URL of the main image to display in the slider. | | thumbImage | string | "" | The URL of the thumbnail image. | | title | string(Optional) | "" | An optional title for the image. |

License

This library is open-source and distributed under the MIT License. See the LICENSE file for more details.