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
Maintainers
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
🔴 Live Interactive Demo →
Try every animation, tweak config live, trigger HTTP / router events — all in the browser.
👆 Click the image to open the live demo
Table of Contents
- ⚡ pl-loading-trace
- 🔴 Live Interactive Demo →
- Table of Contents
- 1. Why pl-loading-trace?
- 2. Requirements
- 3. Installation
- 4. Setup
- 5. Quick start
- 6. Component inputs
- 7. Configuration reference
- 8. Animation types
- 9. Services
- 10. Runtime config override API
- 11. Practical examples
- 11.1 Full-screen HTTP spinner
- 11.2 Router navigation bar
- 11.3 HTTP spinner + router bar combined
- 11.4 Contained card spinner
- 11.5 Named overlay — manual control
- 11.6 Named overlay on a button
- 11.7 Determinate progress bar
- 11.8 Dynamic progress with registry
- 11.9 Runtime config change
- 11.10 Label text
- 11.11 Custom GIF
- 11.12 Debounce (avoid flicker)
- 11.13 Exclude URLs from tracking
- 11.14 Split http / router config
- 11.15 Multiple named cards grid
- 11.16 spinnerOpacity — transparent animation
- 12. Exported symbols
- 13. Building & Publishing
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)(orRouterModule). If your app has no router, setenableRouterTracer: false.
3. Installation
npm install pl-loading-trace4. 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' },
}),
],
};
plLoadingHttpInterceptoris a functional interceptor (Angular 15+ style). For class-based interceptors, usePlLoadingHttpInterceptorwithHTTP_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 / patchConfigThe 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 matchescolor(readable on page background)- Override with explicit
labelColorwhen 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-traceBuild artifacts land in dist/pl-loading-trace/.
Publish to npm
cd dist/pl-loading-trace
npm publishRun the demo app
npm start # development server → http://localhost:4200
npm run build # production build
npm run deploy:demo # deploy to GitHub PagesRun tests
ng testMade with ❤️ by Luca Piciollo · MIT License

