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

pl-loading-trace

v1.0.7

Published

Angular loading overlay library — 74 CSS animations, HTTP & router auto-tracking, named overlays, determinate progress bars, runtime config API, Angular Signals.

Downloads

903

Readme

⚡ pl-loading-trace

The Angular loading overlay you actually want to use.

Zero boilerplate · 76 built-in animations · HTTP auto-tracking · Router tracking · Named overlays · Determinate progress bars · Runtime config API · Angular Signals

npm version Angular License: MIT Bundle size

🔴 Live Interactive Demo →

Try every animation, tweak config live, trigger HTTP / router events — all in the browser.

Demo preview

👆 Click the image to open the live demo


Table of Contents


1. Why pl-loading-trace?

Most loading libraries make you choose: either a full-screen spinner or a progress bar or per-component loaders. pl-loading-trace does all three, with a single component and a single config.

| Feature | pl-loading-trace | Typical spinner lib | |---|:---:|:---:| | HTTP auto-tracking (functional interceptor) | ✅ | ❌ | | Router navigation tracking | ✅ | ❌ | | Named overlays (per-card, per-button) | ✅ | ❌ | | 76 built-in CSS animations | ✅ | ~5 | | 23 determinate progress bar types | ✅ | ❌ | | Runtime config override via service | ✅ | ❌ | | Angular 19 Signals-native | ✅ | ❌ | | Zero dependencies | ✅ | ✅ | | Tree-shakeable | ✅ | ⚠️ |


2. Requirements

| Package | Version | |---|---| | @angular/core | ^19.2.0 | | @angular/common | ^19.2.0 | | @angular/router | compatible with Angular 19 |

Router tracking requires provideRouter(routes) (or RouterModule). If your app has no router, set enableRouterTracer: false.


3. Installation

npm install pl-loading-trace

4. Setup

4.1 Standalone app (Angular 17+)

app.config.ts

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { routes } from './app.routes';
import { providePlLoadingTrace, plLoadingHttpInterceptor } from 'pl-loading-trace';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideHttpClient(withInterceptors([plLoadingHttpInterceptor])),
    providePlLoadingTrace({
      shared: { debounceMs: 200 },
      http:   { animationType: 'spinner', modal: true },
      router: { animationType: 'bar' },
    }),
  ],
};

plLoadingHttpInterceptor is a functional interceptor (Angular 15+ style). For class-based interceptors, use PlLoadingHttpInterceptor with HTTP_INTERCEPTORS.

4.2 NgModule app

app.module.ts

import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { PlLoadingTraceModule, PlLoadingHttpInterceptor } from 'pl-loading-trace';

@NgModule({
  imports: [
    HttpClientModule,
    PlLoadingTraceModule.forRoot({
      shared: { debounceMs: 200 },
      http:   { animationType: 'spinner', modal: true },
      router: { animationType: 'bar' },
    }),
  ],
  providers: [
    {
      provide:  HTTP_INTERCEPTORS,
      useClass: PlLoadingHttpInterceptor,
      multi:    true,
    },
  ],
})
export class AppModule {}

5. Quick start

Drop <pl-loading-overlay> once in your root layout — that's it:

<!-- app.component.html -->

<!-- Top-of-page router bar -->
<pl-loading-overlay source="router" />

<!-- Full-screen HTTP overlay -->
<pl-loading-overlay source="http" />

<router-outlet />

Every HttpClient request and every router navigation will now trigger the appropriate overlay automatically.


6. Component inputs

| Input | Type | Default | Description | |---|---|---|---| | source | LoadingSource | 'http' | Which stream triggers this overlay | | contained | boolean | false | Fill nearest position: relative ancestor instead of the viewport | | name | string | '' | Register in PlLoadingRegistryService for manual/imperative control | | config | Partial<PlLoadingTraceConfig> | {} | Per-instance config (merged over global) | | progress | number \| null | null | Determinate progress value 0–100 (takes priority over config.progressValue) |

source values

| Value | Triggers when… | |---|---| | 'http' | Any tracked HttpClient request is pending | | 'router' | A router navigation is in progress | | 'both' | Either HTTP or router is active | | 'none' | Only via PlLoadingRegistryService — fully manual |


7. Configuration reference

7.1 PlLoadingTraceConfig — full reference

All properties are optional. Any omitted key falls back to its default.

| Property | Type | Default | Description | |---|---|---|---| | enableHttpTracer | boolean | true | Intercept HttpClient requests | | enableRouterTracer | boolean | true | Track router navigations | | animationType | AnimationType | 'spinner' | CSS animation to display (see §8) | | animationSpeed | number | 1000 | Animation cycle duration in ms | | position | LoadingPosition | 'center' | Where to place the spinner (ignored for bar type) | | modal | boolean | true | Show a semi-transparent backdrop | | backdropColor | string | 'rgba(0,0,0,0.55)' | Backdrop background (any CSS color) | | backdropBlur | number | 2 | Backdrop backdrop-filter: blur(Npx) | | color | string | '#3498db' | Primary animation color | | size | number | 40 | Animation size in px | | spinnerOpacity | number | 1 | Animation element opacity 0–1 | | barHeight | number | 5 | Track height in px (for bar type) | | barColorStart | string | (same as color) | Gradient start color for bar | | barColorEnd | string | '#2ecc71' | Gradient end color for bar | | label | string | '' | Text shown below the animation | | labelColor | string | (auto-contrast) | Label color; auto = white on modal, color on no-modal | | debounceMs | number | 150 | Start-only debounce in ms — requests shorter than this won't show the overlay. Configurable independently per source via http/router sections. | | excludeUrls | string[] | [] | URL substrings to skip in HTTP tracking | | customGifUrl | string | '' | GIF/image to use instead of CSS animation | | zIndex | number | 9999 | CSS z-index | | wrapperBg | string | 'transparent' | Spinner card background | | wrapperRadius | number | 12 | Spinner card border-radius in px | | wrapperPadding | number | 20 | Spinner card padding in px | | progressValue | number | 0 | Determinate progress 0–100 (static, for progress types) | | progressSegments | number | 20 | Segment / dot count for segmented progress types |

position values

'center' | 'top' | 'bottom' | 'top-left' | 'top-right'

7.2 PlLoadingTraceOptions — split config

interface PlLoadingTraceOptions {
  shared?: Partial<PlLoadingTraceConfig>; // applied to ALL overlays
  http?:   Partial<PlLoadingTraceConfig>; // HTTP overlays only (overrides shared)
  router?: Partial<PlLoadingTraceConfig>; // router overlays only (overrides shared)
}

7.3 Config resolution order

From lowest to highest priority — later entries win:

DEFAULT_CONFIG
  ← shared
    ← http    (source='http')   ┐
    ← router  (source='router') ┘
  ← [config]  (per-instance input binding, only defined keys)
  ← registry.setConfig / patchConfig  (runtime override — highest priority)

Named overlays (source="none") inherit from shared only.


8. Animation types

8.1 Indeterminate loaders (53)

All are CSS-only, have transparent backgrounds, and respect spinnerOpacity and animationSpeed.

| Name | Style | Best for | |---|---|---| | spinner | Classic rotating ring | HTTP requests | | dots | Three bouncing dots | Routing | | bar | Full-width gradient bar at top | Router navigation | | ring-fade | Segmented ring fading in/out | Dashboard | | pulse | Pulsing expanding circle | Manual trace | | ripple | Two expanding concentric rings | Save action | | orbit | Dot orbiting a center dot | Long task | | wave | Five vertical bars (audio wave) | Sync data | | bounce-bar | Three bars with staggered bounce | Inline card | | flip | Square flipping on 3 axes | Admin panel | | square-spin | Square rotating on multiple axes | Developer tool | | chase | Six dots chasing in a circle | Full overlay | | dna | Two interleaved vertical sine waves | Showcase | | ellipsis | Three dots expanding horizontally | Small widgets | | hourglass | Rotating hourglass shape | Processing | | infinity | Animated figure-eight (∞) | Background sync | | meteor | Comet streaking diagonally | Route change | | morph | Shape-morphing blob | Dashboard card | | neon-ring | Glowing neon spinning ring | Dark mode | | skeleton | Shimmer placeholder bar | Content loading | | typing | Three chat-bubble typing dots | Chat / logs | | windmill | Four-blade windmill | Demo | | cube-grid | 3×3 cubes pulsing in cascade | Grid data | | fading-circle | 12 dots around a clock face | Generic loading | | double-ring | Two concentric rings, opposite directions | Modal overlay | | radar | Radar sweep sector | Network trace | | jelly | Squash-and-stretch blob | Friendly UI | | rotate-plane | Single plane rotating in 3D | Admin action | | wandering-cubes | Two squares orbiting each other | Showcase | | grid-fade | 3×3 grid fading in cascade | Tables | | three-bounce | Three balls bouncing horizontally | Button loading | | arc | SVG arc with animated stroke-dashoffset | Default choice | | google-line | Material-style indeterminate bar | Router top bar | | route-progress | Progressive fill bar | Router navigation | | matrix-rain | Falling code characters | Dark / network | | terminal-cursor | Blinking block cursor | Developer UI | | cyber-scan | Horizontal scan line | Network tracing | | liquid-orb | Liquid blob orbiting | Full overlay | | elastic-dots | Elastically bouncing dots | HTTP loading | | gradient-ring | Ring with conic gradient | Modal loading | | data-stream | Flowing data particles | API calls | | network-nodes | Connected nodes pulsing | Network trace | | loading-stripes | Animated diagonal stripes bar | Progress bar | | glitch | RGB-offset glitch effect | Dark showcase | | halo-pulse | Dot with pulsing halo | Small loading | | ios-dots | iOS-style activity indicator | Inline loading | | android-bar | Material indeterminate bar | Top loading | | neon-bars | Neon equalizer bars | Dark UI | | rotating-dashes | Rotating dashed circle | Generic loading | | ping-dot | Network ping indicator | Network ping | | progress-pill | Animated pill bar | Button / card | | angular-orbit | Angular logo orbital animation | Angular library | | copilot-border | Glowing border that travels the container | AI / Chat box |

8.2 Determinate progress bars (23)

These types consume a progress value 0–100 and render it visually.
Feed the value via [progress] input, config.progressValue, or registry.setProgress(name, value).

| Name | Visual | Best for | |---|---|---| | progress-ring | SVG circular arc fill | File upload | | progress-segments | Rectangular segments ring | Batch operation | | progress-dots | High-density dot ring | Loading stage | | progress-bar | Horizontal fill bar with glow | File upload | | progress-striped | Animated diagonal stripes fill | Long operation | | progress-thin | 3 px NProgress-style line + glowing dot | Page transition | | progress-steps | Horizontal step circles | Wizard / onboarding | | progress-blocks | Vertical equalizer columns | Audio / media | | progress-battery | Battery shape with charging fill | Charge / energy | | progress-dial | Conic-gradient donut with % label | Dashboard metric | | progress-level | Liquid fill circle (bottom→top) | Liquid / fluid | | progress-arc | SVG half-circle speedometer gauge | Speed / score | | progress-counter | Large % number + thin conic ring | KPI / stat card | | progress-wave-bar | Wavy leading-edge fill bar | Liquid / upload | | progress-pixel | LED 10×2 pixel grid | Retro / game UI | | progress-clock | Conic dial + rotating clock hand | Timer / schedule | | progress-tower | Narrow vertical column fill | Storage / capacity | | progress-dots-row | Horizontal row of dot indicators | Step indicator | | progress-gradient-ring | SVG ring with linear-gradient stroke | Profile / avatar | | progress-text-fill | Giant % text filled bottom-up | Score / stat | | progress-neon-bar | Ultra-glow neon bar (multi-layer bloom) | Cyberpunk / game | | progress-scan | Fill bar with scanline on leading edge | Scan / process | | progress-split-bar | Symmetric fill from center outward | Symmetric load |


9. Services

9.1 PlLoadingStateService

Inject this to manually trigger the global loading state, or to read the resolved config signals.

import { inject } from '@angular/core';
import { PlLoadingStateService } from 'pl-loading-trace';

@Component({ ... })
export class MyComponent {
  private readonly loadingState = inject(PlLoadingStateService);

  async generateReport() {
    this.loadingState.setHttpLoading(true);
    try {
      await this.reportService.generate();
    } finally {
      this.loadingState.setHttpLoading(false);
    }
  }
}

Members

| Member | Type | Description | |---|---|---| | config | Signal<Required<PlLoadingTraceConfig>> | Resolved shared config | | httpConfig | Signal<Required<PlLoadingTraceConfig>> | Resolved HTTP config | | routerConfig | Signal<Required<PlLoadingTraceConfig>> | Resolved router config | | loading$ | Observable<boolean> | Combined HTTP + router stream | | httpLoading$ | Observable<boolean> | HTTP stream only | | routerLoading$ | Observable<boolean> | Router stream only | | setHttpLoading(v) | void | Manually set HTTP loading state | | setRouterLoading(v) | void | Manually set router loading state |


9.2 PlLoadingRegistryService

Full imperative control over any named overlay instance.

private readonly registry = inject(PlLoadingRegistryService);

Methods — loading control

| Method | Signature | Description | |---|---|---| | start | (name, label?) => void | Start loading; optionally set a dynamic label | | stop | (name) => void | Stop loading and clear the dynamic label | | toggle | (name, label?) => void | Toggle state | | isActive | (name) => boolean | Returns current active state (synchronous) | | register | (name) => Signal<boolean> | Read-only active signal (used by the component) | | registerLabel | (name) => Signal<string> | Read-only label signal |

Methods — determinate progress

| Method | Signature | Description | |---|---|---| | setProgress | (name, value: 0–100) => void | Set progress value | | resetProgress | (name) => void | Revert to config.progressValue | | startProgress | (name, label?) => void | start() + setProgress(0) combined | | completeProgress | (name, delayMs? = 300) => void | Set 100%, then stop after delay | | registerProgress | (name) => Signal<number \| null> | Read-only progress signal |

Methods — runtime config override

See §10 for full details.

| Method | Signature | Description | |---|---|---| | setConfig | (name, config) => void | Replace config override entirely. label is routed to the label signal | | patchConfig | (name, config) => void | Shallow-merge into existing override. Passing { label: '…' } alone is valid | | getConfig | (name) => Partial<PlLoadingTraceConfig> | Snapshot of current override including active label — use to save before a temporary change | | resetConfig | (name) => void | Remove all overrides and clear the dynamic label (revert to defaults) | | registerConfigOverride | (name) => Signal<…> | Read-only override signal (used by component) |


10. Runtime config override API

Every named overlay can have its config overridden at runtime via the registry — independently of the global config and the [config] input binding.

The priority chain is:

Global defaults  ←  [config] input  ←  registry.setConfig / patchConfig

The registry always wins. This means you can change any property — including animationType — without touching the template.

private readonly registry = inject(PlLoadingRegistryService);

// Replace the whole config override (label is routed to the label signal)
registry.setConfig('upload', {
  animationType: 'progress-neon-bar',
  color: '#ef4444',
  size: 80,
  label: 'Uploading…',
});

// Update only specific keys — passing { label } alone is valid
registry.patchConfig('upload', { color: '#10b981' });     // change color only
registry.patchConfig('upload', { label: '2 of 5…' });     // change label only

// Revert to template / global defaults (also clears dynamic label)
registry.resetConfig('upload');

Save and restore

Use getConfig() to snapshot the current state before a temporary change so it can be restored exactly:

// Save current state
const saved = this.registry.getConfig('status-badge');

// Temporary change
this.registry.patchConfig('status-badge', { color: '#ef4444', label: 'Error!' });

// Restore
this.registry.setConfig('status-badge', saved);

getConfig returns a Partial<PlLoadingTraceConfig> that includes the active label key so nothing is lost on restore.

Practical use: change animation on the fly

onUploadStart() {
  this.registry.setConfig('file-task', { animationType: 'progress-bar', color: '#3b82f6' });
  this.registry.startProgress('file-task');
}

onUploadProgress(pct: number) {
  this.registry.setProgress('file-task', pct);
}

onUploadDone() {
  this.registry.patchConfig('file-task', { color: '#22c55e' }); // go green
  this.registry.completeProgress('file-task', 600);
}

onUploadError() {
  this.registry.setConfig('file-task', { animationType: 'spinner', color: '#ef4444' });
  setTimeout(() => this.registry.stop('file-task'), 2000);
}

11. Practical examples

11.1 Full-screen HTTP spinner

<!-- app.component.html -->
<pl-loading-overlay source="http" />
<router-outlet />
providePlLoadingTrace({
  http: {
    animationType: 'spinner',
    color:         '#6c63ff',
    size:          56,
    modal:         true,
    backdropColor: 'rgba(0, 0, 0, 0.6)',
    backdropBlur:  4,
  },
})

11.2 Router navigation bar

<pl-loading-overlay source="router" />
providePlLoadingTrace({
  router: {
    animationType:  'bar',
    modal:          false,
    barColorStart:  '#6c63ff',
    barColorEnd:    '#ff6584',
    barHeight:      3,
  },
})

11.3 HTTP spinner + router bar combined

<pl-loading-overlay source="router" />
<pl-loading-overlay source="http" />
<router-outlet />
providePlLoadingTrace({
  shared: { debounceMs: 150 },
  http: {
    animationType: 'cube-grid',
    color:         '#3b82f6',
    modal:         true,
    backdropColor: 'rgba(15, 23, 42, 0.65)',
  },
  router: {
    animationType:  'bar',
    modal:          false,
    barColorStart:  '#818cf8',
    barColorEnd:    '#f472b6',
    barHeight:      4,
  },
})

11.4 Contained card spinner

The overlay fills the nearest position: relative ancestor instead of the viewport.

<div style="position: relative; width: 300px; height: 200px;">
  <pl-loading-overlay
    source="http"
    [contained]="true"
    [config]="{ animationType: 'ripple', color: '#10b981', size: 48, modal: false }" />

  <h3>Card title</h3>
  <p>Card content loaded via HTTP</p>
</div>

11.5 Named overlay — manual control

Use source="none" so the overlay only responds to registry calls.

<div class="product-card" style="position: relative; min-height: 100px;">
  <pl-loading-overlay
    name="save-product"
    source="none"
    [contained]="true"
    [config]="{ animationType: 'dots', color: '#f59e0b', modal: false }" />

  <h4>Product details</h4>
  <button (click)="save()">Save</button>
</div>
save() {
  this.registry.start('save-product', 'Saving…');
  this.api.saveProduct().subscribe({
    complete: () => this.registry.stop('save-product'),
    error:    () => this.registry.stop('save-product'),
  });
}

11.6 Named overlay on a button

<button style="position: relative; overflow: hidden; min-width: 110px;" (click)="upload()">
  <pl-loading-overlay
    name="upload-btn"
    source="none"
    [contained]="true"
    [config]="{ animationType: 'arc', color: '#fff', size: 18, modal: false, spinnerOpacity: 0.9 }" />
  Upload
</button>
upload() {
  this.registry.start('upload-btn');
  this.fileService.upload(file).pipe(
    finalize(() => this.registry.stop('upload-btn'))
  ).subscribe();
}

11.7 Determinate progress bar

Static value via [config] — useful for declarative templates:

<pl-loading-overlay
  source="none"
  name="install-progress"
  [config]="{
    animationType:  'progress-ring',
    color:          '#3b82f6',
    size:           72,
    modal:          false,
    progressValue:  42
  }" />

Or via the [progress] input (reactive):

<pl-loading-overlay
  source="none"
  name="install-progress"
  [config]="{ animationType: 'progress-ring', color: '#3b82f6', size: 72, modal: false }"
  [progress]="uploadPercent()" />

11.8 Dynamic progress with registry

startUpload() {
  this.registry.startProgress('upload', 'Uploading…');

  this.uploader.progress$.subscribe(pct => {
    this.registry.setProgress('upload', pct);
  });

  this.uploader.complete$.subscribe(() => {
    this.registry.completeProgress('upload', 500); // show 100% for 500ms, then hide
  });
}
<pl-loading-overlay
  name="upload"
  source="none"
  [contained]="true"
  [config]="{ animationType: 'progress-bar', color: '#3b82f6', size: 80, modal: false }" />

11.9 Runtime config change

// Show as indeterminate spinner while connecting
this.registry.setConfig('ws-status', { animationType: 'pulse', color: '#f59e0b', label: 'Connecting…' });
this.registry.start('ws-status');

// Connection established — switch to green progress ring
this.registry.setConfig('ws-status', { animationType: 'progress-ring', color: '#22c55e', label: 'Syncing…' });

// Change only the label without touching any other property
this.registry.patchConfig('ws-status', { label: 'Live' });

// Revert to template defaults (clears label too)
this.registry.resetConfig('ws-status');

Save / restore pattern

// Save state before a temporary error highlight
const saved = this.registry.getConfig('ws-status');
this.registry.patchConfig('ws-status', { color: '#ef4444', label: 'Reconnecting…' });

// After recovery, restore exact prior appearance
this.registry.setConfig('ws-status', saved);

11.10 Label text

<!-- Static label via [config] input -->
<pl-loading-overlay source="http" [config]="{ label: 'Loading data…', labelColor: '#ffffff' }" />
// Dynamic label — set on start, cleared automatically on stop
this.registry.start('my-overlay', 'Uploading file 1 of 3…');

// Change label only at any point (no other properties affected)
this.registry.patchConfig('my-overlay', { label: 'Uploading file 2 of 3…' });

// Label via setConfig / patchConfig has the same priority as start(name, label)
// — both route through the same internal label signal
this.registry.patchConfig('my-overlay', { label: 'Almost done…', color: '#10b981' });

Auto-contrast rules:

  • modal: true → label is white (readable on dark backdrop)
  • modal: false → label matches color (readable on page background)
  • Override with explicit labelColor when needed

11.11 Custom GIF

<pl-loading-overlay
  source="http"
  [config]="{ customGifUrl: '/assets/loading.gif', size: 80 }" />

11.12 Debounce (avoid flicker)

Requests shorter than debounceMs will not show the overlay at all. The overlay hides immediately when loading stops (start-only debounce). Default is 150 ms.

debounceMs can be set globally via shared, or overridden independently per source via the http / router sections:

providePlLoadingTrace({
  shared: { debounceMs: 150 },    // default for both
  http:   { debounceMs: 300 },    // HTTP overlay: only shows for requests > 300 ms
  router: { debounceMs: 0  },     // router bar: appears instantly
})

11.13 Exclude URLs from tracking

providePlLoadingTrace({
  http: {
    excludeUrls: ['/api/health', '/api/ping', 'analytics.google.com'],
  },
})

11.14 Split http / router config

providePlLoadingTrace({
  shared: {
    enableHttpTracer:   true,
    enableRouterTracer: true,
    debounceMs:         200,
  },
  http: {
    animationType: 'fading-circle',
    color:         '#6366f1',
    size:          52,
    modal:         true,
    label:         'Loading…',
  },
  router: {
    animationType:  'bar',
    modal:          false,
    barColorStart:  '#6366f1',
    barColorEnd:    '#ec4899',
    barHeight:      3,
  },
})

11.15 Multiple named cards grid

interface DemoCard {
  name: string;
  type: AnimationType;
  color: string;
  label?: string;
}

@Component({ ... })
export class DashboardComponent {
  readonly registry = inject(PlLoadingRegistryService);

  readonly cards: DemoCard[] = [
    { name: 'card-users',    type: 'spinner',       color: '#3b82f6', label: 'Loading users…' },
    { name: 'card-orders',   type: 'dots',          color: '#f59e0b' },
    { name: 'card-products', type: 'cube-grid',     color: '#10b981' },
    { name: 'card-stats',    type: 'fading-circle', color: '#ec4899' },
  ];

  start(card: DemoCard, ms = 3000) {
    this.registry.start(card.name, card.label);
    setTimeout(() => this.registry.stop(card.name), ms);
  }
}
<div class="cards-grid">
  @for (card of cards; track card.name) {
    <div class="card">
      <pl-loading-overlay
        [name]="card.name"
        source="none"
        [contained]="true"
        [config]="{ animationType: card.type, color: card.color, modal: false }" />

      <h4>{{ card.name }}</h4>
      <button (click)="start(card)">▶ Start</button>
      <button (click)="registry.stop(card.name)">■ Stop</button>
    </div>
  }
</div>
.cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 1rem;
}

.card {
  position: relative; /* required for [contained]="true" */
  min-height: 130px;
  border: 1px solid #e2e8f0;
  border-radius: 14px;
  padding: 1rem;
}

11.16 spinnerOpacity — transparent animation

<!-- Semi-transparent neon ring on a blurred backdrop -->
<pl-loading-overlay
  source="http"
  [config]="{
    animationType:  'neon-ring',
    spinnerOpacity: 0.6,
    modal:          true,
    backdropColor:  'rgba(0, 0, 0, 0.4)'
  }" />

<!-- Ghost shimmer — no backdrop, partially transparent skeleton -->
<pl-loading-overlay
  source="http"
  [contained]="true"
  [config]="{
    animationType:  'skeleton',
    spinnerOpacity: 0.35,
    modal:          false
  }" />

12. Exported symbols

| Symbol | Kind | Description | |---|---|---| | providePlLoadingTrace | function | Standalone provider factory | | PlLoadingTraceModule | NgModule | For NgModule apps (forRoot(options)) | | PlLoadingOverlayComponent | Component | The overlay component | | PlLoadingStateService | Injectable | Global loading state + config signals | | PlLoadingRegistryService | Injectable | Named overlay control + progress + runtime config | | PlLoadingHttpInterceptor | Injectable | Class-based HTTP interceptor | | plLoadingHttpInterceptor | HttpInterceptorFn | Functional HTTP interceptor | | PlRoutingTrackerService | Injectable | Router navigation tracker | | PL_LOADING_TRACE_CONFIG | InjectionToken | Config injection token | | PL_LOADING_TRACE_DEFAULT_CONFIG | const | Default config values | | PlLoadingTraceConfig | interface | Full config interface | | PlLoadingTraceOptions | interface | Split config interface | | AnimationType | type | Union of all 74 animation names | | AnimationSpeed | type | number (ms) | | LoadingPosition | type | 'center' \| 'top' \| 'bottom' \| 'top-left' \| 'top-right' | | LoadingSource | type | 'http' \| 'router' \| 'both' \| 'none' |


13. Building & Publishing

Build the library

npx ng build pl-loading-trace

Build artifacts land in dist/pl-loading-trace/.

Publish to npm

cd dist/pl-loading-trace
npm publish

Run the demo app

npm start          # development server → http://localhost:4200
npm run build      # production build
npm run deploy:demo # deploy to GitHub Pages

Run tests

ng test

Made with ❤️ by Luca Piciollo · MIT License