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

@ng-catbee/loader

v21.0.4

Published

A modern, customizable Angular library for displaying beautiful loading indicators and spinners with 50+ animation styles and featuring advanced options like fullscreen mode, custom templates, and multiple concurrent loaders.

Readme

@ng-catbee/loader

Catbee Loader for Angular

A modern, customizable Angular library for displaying beautiful loading indicators and spinners with 50+ animation styles and featuring advanced options like fullscreen mode, custom templates, and multiple concurrent loaders.

📦 Demo

Stackblitz

✨ Features

  • 🎨 50+ Animation Styles: Beautiful pre-built loading animations
  • 🎯 Multiple Loaders: Support for multiple named loaders simultaneously
  • 🎭 Customizable: Colors, sizes, animations, and custom templates
  • 📱 Fullscreen Mode: Optional fullscreen overlay with backdrop
  • ⏱️ Programmatic Control: Show/hide with optional delays
  • 🌐 SSR Compatible: Works seamlessly with Server-Side Rendering
  • 🎨 Custom Templates: Use your own HTML templates
  • 📦 Lightweight: Minimal bundle size with tree-shaking support
  • 🔧 Global Configuration: Configure defaults for all loaders

🧩 Angular Compatibility

| Angular Version | Supported | | --------------- | ------------------------------------------------------------ | | v17 and above | ✅ Fully supported |

This library is built and tested with Angular 20.x, and supports all modern standalone-based Angular projects (v17+).

🛠️ Installation

npm install @ng-catbee/loader

🔧 Configuration (Optional)

Standalone apps:

import { provideCatbeeLoader } from '@ng-catbee/loader';

export const appConfig: ApplicationConfig = {
  providers: [
    provideCatbeeLoader({
      animation: 'ball-spin-clockwise',
      size: 'medium',
      backgroundColor: 'rgba(0, 0, 0, 0.8)',
      loaderColor: '#ffffff',
      zIndex: 999999
    })
  ]
};

Module-based apps:

import { CatbeeLoaderModule } from '@ng-catbee/loader';

@NgModule({
  imports: [
    CatbeeLoaderModule.forRoot({
      animation: 'ball-spin-clockwise',
      size: 'medium',
      backgroundColor: 'rgba(0, 0, 0, 0.8)',
      loaderColor: '#ffffff',
      zIndex: 999999
    })
  ]
})
export class AppModule { }

Global configuration sets defaults. Override per-method by passing options.

📂 Import Animation Styles

Important: You must import the CSS file for the animation you want to use. Each animation has its own CSS file.

Option 1: Import in styles.css (Recommended)

/* Import the animation style you need */
@import 'node_modules/@ng-catbee/loader/css/ball-spin-clockwise.css';

/* Or import multiple animations */
@import 'node_modules/@ng-catbee/loader/css/ball-grid-pulse.css';
@import 'node_modules/@ng-catbee/loader/css/line-scale.css';

Option 2: Add to angular.json styles array

{
  "styles": [
    "src/styles.css",
    "node_modules/@ng-catbee/loader/css/ball-spin-clockwise.css",
    "node_modules/@ng-catbee/loader/css/line-scale.css"
  ]
}

💡 Preview all animations: https://labs.danielcardoso.net/load-awesome/animations.html

⚡ Quick Start

Basic Usage

import { Component, inject } from '@angular/core';
import { CatbeeLoader, CatbeeLoaderService } from '@ng-catbee/loader';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CatbeeLoader],
  template: `
    <catbee-loader />
    
    <button (click)="showLoader()">Show Loader</button>
    <button (click)="hideLoader()">Hide Loader</button>
  `,
})
export class AppComponent {
  private loaderService = inject(CatbeeLoaderService);

  async showLoader() {
    await this.loaderService.show();
  }

  async hideLoader() {
    await this.loaderService.hide();
  }
}

Customized Loader

import { Component, inject } from '@angular/core';
import { CatbeeLoader, CatbeeLoaderService } from '@ng-catbee/loader';

@Component({
  selector: 'app-custom',
  standalone: true,
  imports: [CatbeeLoader],
  template: `
    <catbee-loader
      name="custom"
      animation="ball-grid-pulse"
      size="large"
      [backgroundColor]="'rgba(0, 123, 255, 0.8)'"
      [loaderColor]="'#ffffff'"
      [fullscreen]="true"
      [message]="'Loading your data...'"
    />
  `,
})
export class CustomLoaderComponent {
  private loaderService = inject(CatbeeLoaderService);

  async loadData() {
    await this.loaderService.show('custom');
    
    try {
      // Perform async operations
      await this.fetchData();
    } finally {
      await this.loaderService.hide('custom');
    }
  }

  private async fetchData() {
    // Your data fetching logic
  }
}

Multiple Named Loaders

import { Component, inject } from '@angular/core';
import { CatbeeLoader, CatbeeLoaderService } from '@ng-catbee/loader';

@Component({
  selector: 'app-multi',
  standalone: true,
  imports: [CatbeeLoader],
  template: `
    <!-- Main content loader -->
    <catbee-loader 
      name="main" 
      animation="ball-spin-clockwise"
    />
    
    <!-- Sidebar loader -->
    <catbee-loader 
      name="sidebar" 
      animation="line-scale"
      [fullscreen]="false"
      [zIndex]="1000"
    />
  `,
})
export class MultiLoaderComponent {
  private loaderService = inject(CatbeeLoaderService);

  async loadContent() {
    // Show main loader
    await this.loaderService.show('main');
    await this.fetchMainContent();
    await this.loaderService.hide('main');
  }

  async loadSidebar() {
    // Show sidebar loader independently
    await this.loaderService.show('sidebar');
    await this.fetchSidebarData();
    await this.loaderService.hide('sidebar');
  }

  private async fetchMainContent() { /* ... */ }
  private async fetchSidebarData() { /* ... */ }
}

Runtime Options Override

import { Component, inject } from '@angular/core';
import { CatbeeLoaderService } from '@ng-catbee/loader';

@Component({
  selector: 'app-runtime',
  template: `<catbee-loader name="dynamic" />`,
})
export class RuntimeComponent {
  private loaderService = inject(CatbeeLoaderService);

  async showCustomLoader() {
    // Override component inputs at runtime
    await this.loaderService.show('dynamic', {
      backgroundColor: 'rgba(255, 0, 0, 0.5)',
      loaderColor: '#ffff00',
      size: 'large',
      animation: 'pacman',
      message: 'Processing...',
      fullscreen: false,
      zIndex: 10000
    });
    
    await this.processData();
    await this.loaderService.hide('dynamic');
  }

  private async processData() { /* ... */ }
}

Custom Templates

import { Component, inject } from '@angular/core';
import { CatbeeLoader, CatbeeLoaderService } from '@ng-catbee/loader';

@Component({
  selector: 'app-custom-template',
  standalone: true,
  imports: [CatbeeLoader],
  template: `
    <catbee-loader
      name="custom-template"
      [customTemplate]="customHtml"
    />
  `,
})
export class CustomTemplateComponent {
  private loaderService = inject(CatbeeLoaderService);

  customHtml = `
    <div style="text-align: center; color: white;">
      <h2>Please Wait...</h2>
      <div class="spinner">⏳</div>
      <p>We're preparing your content</p>
    </div>
  `;

  async showCustom() {
    await this.loaderService.show('custom-template');
  }
}

Blur Background Effect

import { Component, inject } from '@angular/core';
import { CatbeeLoader, CatbeeLoaderService } from '@ng-catbee/loader';

@Component({
  selector: 'app-blur-demo',
  standalone: true,
  imports: [CatbeeLoader],
  template: `
    <!-- Blur effect is only applied in fullscreen mode -->
    <catbee-loader
      name="blur-loader"
      [fullscreen]="true"
      [blurBackground]="true"
      [blurPixels]="10"
      animation="ball-spin-fade"
    />
  `,
})
export class BlurDemoComponent {
  private loaderService = inject(CatbeeLoaderService);

  async showWithBlur() {
    // Override blur settings at runtime
    await this.loaderService.show('blur-loader', {
      blurBackground: true,
      blurPixels: 15,
      message: 'Processing with blur effect...'
    });
  }
}

Note: The blur effect (blurBackground and blurPixels) only applies when fullscreen is true. This ensures optimal visual appearance and performance.

Service API

import { Component, inject } from '@angular/core';
import { CatbeeLoaderService } from '@ng-catbee/loader';

@Component({
  selector: 'app-service-demo',
  template: `<catbee-loader />`,
})
export class ServiceDemoComponent {
  private loaderService = inject(CatbeeLoaderService);

  async demonstrateAPI() {
    // Show loader
    await this.loaderService.show();

    // Check if visible
    const isVisible = this.loaderService.isVisible(); // true

    // Get loader state
    const state = this.loaderService.getState();
    console.log('Loader state:', state);

    // Get all visible loaders
    const visibleLoaders = this.loaderService.getVisibleLoaders();
    console.log('Visible loaders:', visibleLoaders);

    // Hide specific loader
    await this.loaderService.hide();
    // Hide all loaders at once
    await this.loaderService.hideAll();

    // Observe loader state changes
    this.loaderService.watch().subscribe(state => {
      console.log('Loader state changed:', state);
    });
  }
}

🎨 Available Animations

The library includes 50+ beautiful loading animations. Each animation requires its corresponding CSS file to be imported.

💡 Live Preview: See all animations in action at https://labs.danielcardoso.net/load-awesome/animations.html

Ball Animations:

  • ball-8bits, ball-atom, ball-beat, ball-circus, ball-climbing-dot
  • ball-clip-rotate, ball-clip-rotate-multiple, ball-clip-rotate-pulse
  • ball-elastic-dots, ball-fall, ball-fussion
  • ball-grid-beat, ball-grid-pulse, ball-newton-cradle
  • ball-pulse, ball-pulse-rise, ball-pulse-sync
  • ball-rotate, ball-running-dots, ball-scale
  • ball-scale-multiple, ball-scale-pulse
  • ball-scale-ripple, ball-scale-ripple-multiple
  • ball-spin, ball-spin-clockwise, ball-spin-clockwise-fade
  • ball-spin-clockwise-fade-rotating, ball-spin-fade, ball-spin-fade-rotating
  • ball-spin-rotate, ball-square-clockwise-spin, ball-square-spin
  • ball-triangle-path, ball-zig-zag, ball-zig-zag-deflect

Line Animations:

  • line-scale, line-scale-party
  • line-scale-pulse-out, line-scale-pulse-out-rapid
  • line-spin-clockwise-fade, line-spin-clockwise-fade-rotating
  • line-spin-fade, line-spin-fade-rotating

Other Animations:

  • cog, cube-transition, fire, pacman
  • square-jelly-box, square-loader, square-spin
  • timer, triangle-skew-spin

📚 API Reference

Component: <catbee-loader>

| Input | Type | Default | Description | |-------|------|---------|-------------| | name | string | 'default' | Unique identifier for the loader | | animation | LoaderAnimation | 'ball-spin-clockwise' | Animation style | | size | 'small' \| 'medium' \| 'large' | '' | Loader size | | backgroundColor | string | 'rgba(0,0,0,0.7)' | Overlay background color | | loaderColor | string | '#ffffff' | Loader/spinner color | | fullscreen | boolean | true | Fullscreen overlay mode | | zIndex | number | 999999 | CSS z-index value | | message | string | null | Optional loading message | | customTemplate | string | null | Custom HTML template | | width | string | '100%' | Loader container width | | height | string | '100%' | Loader container height | | blurBackground | boolean | false | Apply blur effect to background (fullscreen only) | | blurPixels | number | 5 | Amount of blur in pixels (requires blurBackground: true) |

Component Outputs

| Output | Type | Description | |--------|------|-------------| | visibleChange | EventEmitter<boolean> | Emits when loader visibility changes |

Service: CatbeeLoaderService

| Method | Parameters | Returns | Description | |--------|------------|---------|-------------| | show() | name: string, options?: LoaderDisplayOptions | Promise<void> | Show a loader | | hide() | name: string, delay?: number | Promise<void> | Hide a loader | | hideAll() | - | Promise<void> | Hide all active loaders | | isVisible() | name: string | boolean | Check if loader is visible | | getState() | name: string | LoaderState \| undefined | Get loader state | | getVisibleLoaders() | - | string[] | Get names of all visible loaders | | watch() | name: string | Observable<LoaderState> | Observe loader state changes |

LoaderDisplayOptions

interface LoaderDisplayOptions {
  backgroundColor?: string;
  loaderColor?: string;
  size?: LoaderSize;
  animation?: LoaderAnimation;
  fullscreen?: boolean;
  zIndex?: number;
  customTemplate?: string;
  message?: string;
  blurBackground?: boolean;
  blurPixels?: number;
  blockScroll?: boolean;
}

Global Configuration

export interface CatbeeLoaderGlobalConfig {
  animation?: CatbeeLoaderAnimation;
  size?: CatbeeLoaderSize;
  backgroundColor?: string;
  loaderColor?: string;
  zIndex?: number;
  fullscreen?: boolean;
  message?: string | null;
  customTemplate?: string | null;
  blurBackground?: boolean;
  blurPixels?: number;
  blockScroll?: boolean;
}

🎯 Common Use Cases

HTTP Interceptor Integration

import { HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';
import { CatbeeLoaderService } from '@ng-catbee/loader';
import { finalize } from 'rxjs/operators';

export const loaderInterceptor: HttpInterceptorFn = (req, next) => {
  const loaderService = inject(CatbeeLoaderService);
  
  loaderService.show('http-loader');
  
  return next(req).pipe(
    finalize(() => loaderService.hide('http-loader'))
  );
};

Route Guard with Loader

import { inject } from '@angular/core';
import { CanActivateFn } from '@angular/router';
import { CatbeeLoaderService } from '@ng-catbee/loader';

export const dataGuard: CanActivateFn = async (route, state) => {
  const loaderService = inject(CatbeeLoaderService);
  
  await loaderService.show('route-guard');
  
  try {
    // Fetch required data
    const hasAccess = await checkAccess();
    return hasAccess;
  } finally {
    await loaderService.hide('route-guard');
  }
};

async function checkAccess(): Promise<boolean> {
  // Your access check logic
  return true;
}

Form Submission

import { Component, inject } from '@angular/core';
import { CatbeeLoaderService } from '@ng-catbee/loader';

@Component({
  selector: 'app-form',
  template: `
    <catbee-loader name="form-submit" />
    <form (ngSubmit)="onSubmit()">
      <!-- form fields -->
      <button type="submit">Submit</button>
    </form>
  `,
})
export class FormComponent {
  private loaderService = inject(CatbeeLoaderService);

  async onSubmit() {
    await this.loaderService.show('form-submit', {
      message: 'Saving your changes...'
    });

    try {
      await this.saveForm();
      // Show success message
    } catch (error) {
      // Handle error
    } finally {
      await this.loaderService.hide('form-submit');
    }
  }

  private async saveForm() {
    // Your form submission logic
  }
}

📖 Documentation

💡 Full documentation available at https://catbee.in

📜 License

MIT © Catbee Technologies (see the LICENSE file for the full text)

🔗 Links