Spinner y overlay de carga para Angular | ng-hub-ui-loading

Componente de carga para Angular con indicadores spinner, dots, bars, pulse y ring en modo inline, overlay y fullscreen, más un servicio para overlays bloqueantes de toda la aplicación.

Ejemplos interactivos

Explora ejemplos en vivo que muestran cómo se comporta la librería en casos de uso habituales de Angular.

Bloque inline

`inline` es el modo por defecto porque una región todavía vacía debería reservar ya el espacio que ocupará su contenido: el bloque participa en el flujo normal del documento, así que nada salta cuando llega el contenido real. `message` se renderiza bajo el indicador, y todo lo proyectado entre las etiquetas se renderiza bajo el mensaje — el sitio para una acción de cancelar o un aviso de que la operación está tardando más de lo habitual. El host lleva `role="status"`, `aria-live="polite"` y `aria-busy="true"`, de modo que un lector de pantalla recoge el mensaje al aparecer sin interrumpir lo que ya estaba leyendo.

Fundamentos del bloque inline

Indicator only

Loading your workspace

With a message

Importing 1,248 rows

With projected content

The block is announced as role="status" with aria-live="polite", so a screen reader reads the message when it appears without interrupting whatever is being read.

Indicadores y acentos

La biblioteca incluye cinco indicadores puramente CSS — `spinner`, `dots`, `bars`, `pulse` y `ring` —, así que no arrastra ninguna imagen ni fuente de iconos. Tres pasos de tamaño preconfiguran `--hub-loading-size`, y el token sigue siendo sobrescribible por su cuenta cuando una maquetación necesita un tamaño que esos pasos no cubren. `color` no es un color CSS corriente: pasa por `resolveHubAccent()`, que interpreta un nombre suelto como `primary` como token del sistema de diseño y sigue el tema, mientras que un hex, un literal `oklch()` o una referencia `var(...)` se usan tal cual.

Variantes, tamaños y acentos

Variants
spinner
dots
bars
pulse
ring
Sizes
size="sm"
size="md"
size="lg"

Each step is a preset for the --hub-loading-size token. Override that token directly when a layout needs a size the three steps do not cover.

Accents
color="primary"
color="success"
color="danger"
color="#7c3aed"
color="var(--hub-sys-color-warning)"

A bare name resolves to var(--hub-sys-color-<name>) and tracks the active theme. A hex, an oklch() or a var(...) is used verbatim.

Overlay y fullscreen

`overlay` cubre una región en lugar de la página. Se posiciona en absoluto, así que el ancestro posicionado más cercano decide qué queda cubierto — dale `position: relative` a ese contenedor o el overlay se escapa hacia arriba, hasta el ancestro que resulte estar posicionado. Acotarlo así mantiene el resto de la pantalla desplazable y utilizable. `fullscreen` queda fijado al viewport y es lo que `HubLoadingService` monta sobre `document.body`, fuera de todo subárbol de componentes, de forma que ningún `overflow` ni contexto de apilamiento de un ancestro puede recortarlo. Ambos modos pintan el velo translúcido salvo que se desactive `backdrop`.

Overlay de contenedor

Order #4821

3 items · delivered 14 Aug 2026

Subtotal
212.00 €
Shipping
9.90 €
VAT (21%)
26.70 €
Total
248.60 €

Turn the backdrop off to keep the content readable underneath — useful when the work is a background refresh rather than something that invalidates what is on screen.

Servicio fullscreen

The overlay covers the whole viewport, so this demo dismisses it for you: every request releases its own reference, and a watchdog forces a hideAll() after 5 seconds no matter what.
References held
0
isLoading()
false
Calls

Nothing yet.

Pantalla completa dentro de un armazón

Workspace

The indicator below is declared here, inside the container's content — the place a real application would write it.

Restoring the last session…

Three documents, two of them shared.

Last sync: 23 Sep 2026, 09:14.

Notes

With hoisting off, the overlay still covers the window — the containment went in 22.15.0 — but it paints under this panel, because the container keeps a stacking context of its own. Leaving the subtree is the only fix that does not depend on what an ancestor declares.

The overlay clears itself after a couple of seconds, and a click anywhere on it dismisses it at once.

Marca y tematización

`image` cambia el indicador integrado por una marca propia, animada con `none`, `spin` o `pulse`: `spin` solo funciona bien sobre una marca radialmente simétrica, mientras que `pulse` mantiene un logotipo tipográfico derecho y legible. Todo lo visual vive en los tokens `--hub-loading-*`, declarados en `:where(.hub-loading)` para que cualquier ancestro pueda fijarlos — acento, tamaño, velocidad, grosor de trazo, separación, tamaño de imagen, color del texto y el tinte y desenfoque del backdrop. El mixin de Sass `hub-loading-theme()` fija toda la escalera de tokens en una sola llamada, y `provideHubLoading()` rebasa los valores por defecto de una aplicación entera sin tocar ninguna plantilla.

Imagen de marca

Preparing your report

imageAnimation="none"

Preparing your report

imageAnimation="spin"

Preparing your report

imageAnimation="pulse"

Any URL works — an asset path, an imported file or, as here, an inline data URI. Size the mark with --hub-loading-image-size rather than size, which drives the built-in indicators.

Tematización con variables CSS

Inline — accent, size, speed, thickness

Overlay preview

The backdrop tint and blur only apply in overlay and fullscreen modes. The tint is mixed from --hub-sys-surface-page, so it veils this text with the theme's own surface instead of a fixed colour — drop it to zero and the card stays fully legible underneath.

Refreshing

The same overrides written once, in Sass, are in the CSS tab — that is what hub-loading-theme() is for.

Barra de progreso de página

`hub-loading-bar` es la franja fina que avisa de que la página misma está en camino: la que va bajo la barra de navegación. Tres decisiones la hacen creíble. Cuenta a quienes la piden, así que una navegación y las tres peticiones que lanza la página son cuatro referencias, y la barra termina con la última, no con la primera. Espera antes de pintar nada: el trabajo que acaba dentro del periodo de gracia no llega a mostrar barra, porque una ruta de 40 ms que hace parpadear un indicador de progreso se lee como un fallo, no como velocidad. Y su avance se frena a medida que se llena y se detiene antes del final: aquí nadie conoce el porcentaje real, de modo que solo `complete()` puede mostrar el 100 %, porque solo `complete()` sabe que es cierto. Colócala con `mode="overlay"` dentro de una barra de navegación posicionada, o con `mode="fixed"` y `--hub-loading-bar-offset` cuando la barra de navegación también está fijada.

Barra de progreso de página

Acme
Orders

This page arrived without you watching a spinner.

progress 0% · painted: false

Progreso conocido y desconocido

Known percentage
[progress]="null"

A real value, so the bar announces it. Reaching 100% is the caller's call, not the trickle's.

No percentage at all
indeterminate

A sweep instead of a fill, for a stream or a job that reports no stages. No value is announced, because there is none.

Both bars are mode="inline", so each reserves its own row and nothing on the card moves when a bar appears or goes away.

Integración con router y HTTP

Dashboard
Callers
0
isActive()
false
progress()
0%
Calls

Nothing yet.

Barrido de derecha a izquierda

Loading results…
dir="ltr"

Sweeps left to right, with the text.

جارٍ تحميل النتائج…
dir="rtl"

يمسح من اليمين إلى اليسار، مع اتجاه النص.

The flip comes from [dir='rtl'] .hub-loading-bar, .hub-loading-bar[dir='rtl'], so the attribute counts wherever it sits — on <html>, on the region that changes direction, or on the <hub-loading-bar> element itself. The determinate fill needs no such treatment: it grows along the inline axis, which already reverses on its own.