⚡ pl-loading-trace

June 3, 2026 · View on GitHub

⚡ 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.

Featurepl-loading-traceTypical 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

PackageVersion
@angular/core^19.2.0
@angular/common^19.2.0
@angular/routercompatible 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

InputTypeDefaultDescription
sourceLoadingSource'http'Which stream triggers this overlay
containedbooleanfalseFill nearest position: relative ancestor instead of the viewport
namestring''Register in PlLoadingRegistryService for manual/imperative control
configPartial<PlLoadingTraceConfig>{}Per-instance config (merged over global)
progressnumber | nullnullDeterminate progress value 0–100 (takes priority over config.progressValue)

source values

ValueTriggers 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.

PropertyTypeDefaultDescription
enableHttpTracerbooleantrueIntercept HttpClient requests
enableRouterTracerbooleantrueTrack router navigations
animationTypeAnimationType'spinner'CSS animation to display (see §8)
animationSpeednumber1000Animation cycle duration in ms
positionLoadingPosition'center'Where to place the spinner (ignored for bar type)
modalbooleantrueShow a semi-transparent backdrop
backdropColorstring'rgba(0,0,0,0.55)'Backdrop background (any CSS color)
backdropBlurnumber2Backdrop backdrop-filter: blur(Npx)
colorstring'#3498db'Primary animation color
sizenumber40Animation size in px
spinnerOpacitynumber1Animation element opacity 0–1
barHeightnumber5Track height in px (for bar type)
barColorStartstring(same as color)Gradient start color for bar
barColorEndstring'#2ecc71'Gradient end color for bar
labelstring''Text shown below the animation
labelColorstring(auto-contrast)Label color; auto = white on modal, color on no-modal
debounceMsnumber150Start-only debounce in ms — requests shorter than this won't show the overlay. Configurable independently per source via http/router sections.
excludeUrlsstring[][]URL substrings to skip in HTTP tracking
customGifUrlstring''GIF/image to use instead of CSS animation
zIndexnumber9999CSS z-index
wrapperBgstring'transparent'Spinner card background
wrapperRadiusnumber12Spinner card border-radius in px
wrapperPaddingnumber20Spinner card padding in px
progressValuenumber0Determinate progress 0–100 (static, for progress types)
progressSegmentsnumber20Segment / 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.

NameStyleBest for
spinnerClassic rotating ringHTTP requests
dotsThree bouncing dotsRouting
barFull-width gradient bar at topRouter navigation
ring-fadeSegmented ring fading in/outDashboard
pulsePulsing expanding circleManual trace
rippleTwo expanding concentric ringsSave action
orbitDot orbiting a center dotLong task
waveFive vertical bars (audio wave)Sync data
bounce-barThree bars with staggered bounceInline card
flipSquare flipping on 3 axesAdmin panel
square-spinSquare rotating on multiple axesDeveloper tool
chaseSix dots chasing in a circleFull overlay
dnaTwo interleaved vertical sine wavesShowcase
ellipsisThree dots expanding horizontallySmall widgets
hourglassRotating hourglass shapeProcessing
infinityAnimated figure-eight (∞)Background sync
meteorComet streaking diagonallyRoute change
morphShape-morphing blobDashboard card
neon-ringGlowing neon spinning ringDark mode
skeletonShimmer placeholder barContent loading
typingThree chat-bubble typing dotsChat / logs
windmillFour-blade windmillDemo
`cube-grid$3 \times 3 \text{cubes} \text{pulsing} \text{in} \text{cascade}\text{Grid} \text{data}
$fading-circle`12 dots around a clock faceGeneric loading
double-ringTwo concentric rings, opposite directionsModal overlay
radarRadar sweep sectorNetwork trace
jellySquash-and-stretch blobFriendly UI
rotate-planeSingle plane rotating in 3DAdmin action
wandering-cubesTwo squares orbiting each otherShowcase
`grid-fade$3 \times 3 \text{grid} \text{fading} \text{in} \text{cascade}\text{Tables}
$three-bounce`Three balls bouncing horizontallyButton loading
arcSVG arc with animated stroke-dashoffsetDefault choice
google-lineMaterial-style indeterminate barRouter top bar
route-progressProgressive fill barRouter navigation
matrix-rainFalling code charactersDark / network
terminal-cursorBlinking block cursorDeveloper UI
cyber-scanHorizontal scan lineNetwork tracing
liquid-orbLiquid blob orbitingFull overlay
elastic-dotsElastically bouncing dotsHTTP loading
gradient-ringRing with conic gradientModal loading
data-streamFlowing data particlesAPI calls
network-nodesConnected nodes pulsingNetwork trace
loading-stripesAnimated diagonal stripes barProgress bar
glitchRGB-offset glitch effectDark showcase
halo-pulseDot with pulsing haloSmall loading
ios-dotsiOS-style activity indicatorInline loading
android-barMaterial indeterminate barTop loading
neon-barsNeon equalizer barsDark UI
rotating-dashesRotating dashed circleGeneric loading
ping-dotNetwork ping indicatorNetwork ping
progress-pillAnimated pill barButton / card
angular-orbitAngular logo orbital animationAngular library
copilot-borderGlowing border that travels the containerAI / 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).

NameVisualBest for
progress-ringSVG circular arc fillFile upload
progress-segmentsRectangular segments ringBatch operation
progress-dotsHigh-density dot ringLoading stage
progress-barHorizontal fill bar with glowFile upload
progress-stripedAnimated diagonal stripes fillLong operation
progress-thin3 px NProgress-style line + glowing dotPage transition
progress-stepsHorizontal step circlesWizard / onboarding
progress-blocksVertical equalizer columnsAudio / media
progress-batteryBattery shape with charging fillCharge / energy
progress-dialConic-gradient donut with % labelDashboard metric
progress-levelLiquid fill circle (bottom→top)Liquid / fluid
progress-arcSVG half-circle speedometer gaugeSpeed / score
progress-counterLarge % number + thin conic ringKPI / stat card
progress-wave-barWavy leading-edge fill barLiquid / upload
`progress-pixel$\text{LED} 10 \times 2 \text{pixel} \text{grid}\text{Retro} / \text{game} \text{UI}
$progress-clock`Conic dial + rotating clock handTimer / schedule
progress-towerNarrow vertical column fillStorage / capacity
progress-dots-rowHorizontal row of dot indicatorsStep indicator
progress-gradient-ringSVG ring with linear-gradient strokeProfile / avatar
progress-text-fillGiant % text filled bottom-upScore / stat
progress-neon-barUltra-glow neon bar (multi-layer bloom)Cyberpunk / game
progress-scanFill bar with scanline on leading edgeScan / process
progress-split-barSymmetric fill from center outwardSymmetric 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

MemberTypeDescription
configSignal<Required<PlLoadingTraceConfig>>Resolved shared config
httpConfigSignal<Required<PlLoadingTraceConfig>>Resolved HTTP config
routerConfigSignal<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)voidManually set HTTP loading state
setRouterLoading(v)voidManually set router loading state

9.2 PlLoadingRegistryService

Full imperative control over any named overlay instance.

private readonly registry = inject(PlLoadingRegistryService);

Methods — loading control

MethodSignatureDescription
start(name, label?) => voidStart loading; optionally set a dynamic label
stop(name) => voidStop loading and clear the dynamic label
toggle(name, label?) => voidToggle state
isActive(name) => booleanReturns 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

MethodSignatureDescription
setProgress(name, value: 0–100) => voidSet progress value
resetProgress(name) => voidRevert to config.progressValue
startProgress(name, label?) => voidstart() + setProgress(0) combined
completeProgress(name, delayMs? = 300) => voidSet 100%, then stop after delay
registerProgress(name) => Signal<number | null>Read-only progress signal

Methods — runtime config override

See §10 for full details.

MethodSignatureDescription
setConfig(name, config) => voidReplace config override entirely. label is routed to the label signal
patchConfig(name, config) => voidShallow-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) => voidRemove 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

SymbolKindDescription
providePlLoadingTracefunctionStandalone provider factory
PlLoadingTraceModuleNgModuleFor NgModule apps (forRoot(options))
PlLoadingOverlayComponentComponentThe overlay component
PlLoadingStateServiceInjectableGlobal loading state + config signals
PlLoadingRegistryServiceInjectableNamed overlay control + progress + runtime config
PlLoadingHttpInterceptorInjectableClass-based HTTP interceptor
plLoadingHttpInterceptorHttpInterceptorFnFunctional HTTP interceptor
PlRoutingTrackerServiceInjectableRouter navigation tracker
PL_LOADING_TRACE_CONFIGInjectionTokenConfig injection token
PL_LOADING_TRACE_DEFAULT_CONFIGconstDefault config values
PlLoadingTraceConfiginterfaceFull config interface
PlLoadingTraceOptionsinterfaceSplit config interface
AnimationTypetypeUnion of all 74 animation names
AnimationSpeedtypenumber (ms)
LoadingPositiontype'center' | 'top' | 'bottom' | 'top-left' | 'top-right'
LoadingSourcetype'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