Angular のローディングスピナーとオーバーレイ | ng-hub-ui-loading
spinner・dots・bars・pulse・ring のインジケーターを inline・overlay・fullscreen の 3 モードで描画する Angular のローディングコンポーネント。アプリ全体を覆うオーバーレイ用のサービスも同梱。
最終更新 2026/09/16
概要
チームがこのライブラリを探す理由
セクション、コンテナ、あるいはアプリケーション全体で処理中であることを示す必要があり、しかもビューごとに独自のスピナーとスクリムを組み立てたくないときに ng-hub-ui-loading を使用してください。
インストール
npm install ng-hub-ui-loadingジャンプ
最適な用途
- ルートとデータの読み込み
- フォーム送信時のオーバーレイ
- アプリ全体をブロックする処理
- ブランド入りのスプラッシュ画面
- ナビゲーションバー下のページ進捗バー
について loading
ng-hub-ui-loading は、不確定なローディング状態を 3 つのモードで描画するスタンドアロンの Angular コンポーネントです。`inline` はドキュメントフロー内のブロックとして、`overlay` は親コンテナの上に絶対配置で、`fullscreen` はビューポートに固定して表示します。純粋な CSS のみで描かれる 5 種類のインジケーター — spinner、dots、bars、pulse、ring — を 3 段階のサイズで備え、任意のメッセージと、`none`・`spin`・`pulse` のいずれかで動く任意のブランド画像も指定できます。`HubLoadingService` は全画面オーバーレイをプログラムから制御し、同時に呼び出した側を参照カウントで管理するため、並行するリクエストが互いのオーバーレイを消し合うことはありません。色・サイズ・時間はすべて `--hub-loading-*` カスタムプロパティで、まとめて作り替えるための `hub-loading-theme()` Sass ミックスインも用意されています。`role=status`、`aria-live=polite`、`aria-busy` により標準でアクセシブルで、`prefers-reduced-motion` も尊重します。 併せて `hub-loading-bar` は、ページそのものが読み込み中であることを伝えます。ナビゲーションバーの下の細い帯で、ドキュメントフローに描くことも、位置指定したナビゲーションバーに付けることも、`--hub-loading-bar-offset` の位置でビューポートに固定することもできます。`HubLoadingBarService` も同じように呼び出し元を数え、猶予時間を置いて、すぐ終わる処理でバーを一瞬光らせないようにし、自力では決して届かない終端に向かって進みます。100 % を出せるのは `complete()` だけです。`provideHubLoadingBarRouter()` と `hubLoadingBarInterceptor` が、互いを知らないままナビゲーションと HTTP につなぎます。
機能ガイド
インラインブロック
`inline` が既定のモードなのは、まだ空の領域こそ、これから入る内容が占める場所をあらかじめ確保しておくべきだからです。ブロックは通常のドキュメントフローに参加するため、実際の内容が届いてもレイアウトが飛び跳ねません。`message` はインジケーターの下に描画され、タグの間に投影されたものはさらにその下に描画されます。キャンセル操作や「通常より時間がかかっています」といった注記を置く場所です。ホストは `role="status"`、`aria-live="polite"`、`aria-busy="true"` を備えているため、スクリーンリーダーは読み上げ中の内容を中断することなく、表示された時点でメッセージを拾います。
サンプル:
インラインブロックの基本
インラインブロックの有用な 3 形態: インジケーターのみ、メッセージ付き、そしてメッセージの下にキャンセル操作を投影したもの。
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.
コード
Import:
Template:
Component:
インジケーターとアクセント
ライブラリには純粋な CSS だけで描かれる 5 種類のインジケーター — `spinner`、`dots`、`bars`、`pulse`、`ring` — が同梱されており、画像アセットもアイコンフォントも一切引き込みません。3 段階のサイズが `--hub-loading-size` をプリセットしますが、その 3 段階で足りないレイアウトのために、トークン自体は個別に上書きできるままです。`color` は通常の CSS カラーではありません。値は `resolveHubAccent()` を通り、`primary` のような裸の名前はテーマに追随するデザインシステムのトークンとして解釈され、hex、`oklch()` リテラル、`var(...)` 参照はそのまま使われます。
サンプル:
バリアント・サイズ・アクセント
同梱の 5 種類のインジケーター、3 段階のサイズ、そしてアクセントが取りうる 3 つの形 — セマンティックな名前、CSS のカラーリテラル、`var(...)` 参照。
Variants
spinnerdotsbarspulseringSizes
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.
コード
Import:
Template:
Component:
オーバーレイとフルスクリーン
`overlay` はページ全体ではなく一つの領域を覆います。絶対配置されるため、何が覆われるかを決めるのは最も近い配置済みの祖先です。そのコンテナに `position: relative` を与えてください。さもなければオーバーレイは上方向へ抜け出し、たまたま配置されていた祖先まで届いてしまいます。範囲を限ることで、画面の残りはスクロールでき、操作可能なままになります。`fullscreen` はビューポートに固定され、`HubLoadingService` が `document.body` にマウントするのがこれです。あらゆるコンポーネントのサブツリーの外側なので、祖先の `overflow` やスタッキングコンテキストに切り取られることがありません。どちらのモードも、`backdrop` を切らない限り半透明のスクリムを描きます。
サンプル:
コンテナオーバーレイ
カード自身の `position: relative` によって 1 枚のカードに閉じ込められたオーバーレイ。ページの残りはスクロールできます。`backdrop` を切り替えると、バックグラウンド更新と、画面上の表示を無効にする処理との違いが分かります。
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.
コード
Import:
Template:
Component:
フルスクリーンサービス
TypeScript から操作する `HubLoadingService`。重なり合う 2 つのリクエストが参照カウンターの意味を示します。2 番目の呼び出し元がまだ参照を保持しているため最初の `hide()` ではオーバーレイは残り、`update()` は処理中にメッセージを書き換えます。
hideAll() after 5 seconds no matter what. Nothing yet.
コード
Import:
Template:
Component:
ブランディングとテーマ設定
`image` は組み込みのインジケーターを自前のマークに差し替え、`none`、`spin`、`pulse` で動かします。`spin` が自然に見えるのは放射対称なマークだけで、ワードマークを立てたまま読みやすく保つなら `pulse` です。見た目に関わるものはすべて `--hub-loading-*` トークンにあり、`:where(.hub-loading)` に宣言されているのでどの祖先からでも設定できます — アクセント、サイズ、速度、線の太さ、間隔、画像サイズ、テキスト色、そして backdrop の濃さとぼかしです。Sass ミックスイン `hub-loading-theme()` はこのトークン群を一度の呼び出しでまとめて設定し、`provideHubLoading()` はテンプレートに触れずにアプリケーション全体の既定値を置き換えます。
サンプル:
ブランド画像
組み込みインジケーターを置き換えるブランドマークを、3 種類の画像アニメーションそれぞれで表示し、`spin`・`pulse`・`none` の使い分けが見えるようにしています。
imageAnimation="none"imageAnimation="spin"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.
コード
Import:
Template:
Component:
CSS 変数によるテーマ設定
ラッパー要素に置いた `--hub-loading-*` トークンによるライブなテーマ設定。`overlay` と `fullscreen` モードでしか効かない backdrop の濃さとぼかしも含みます。
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.
The same overrides written once, in Sass, are in the CSS tab — that is what hub-loading-theme() is for.
コード
Import:
Template:
Component:
ページ進捗バー
`hub-loading-bar` は、ページそのものが読み込み中であることを伝える細い帯 — ナビゲーションバーの下に置くあれです。信頼できるものにしている判断が三つあります。呼び出し元を数えるので、1 回のナビゲーションとページが投げる 3 本のリクエストは 4 つの参照になり、バーは最初ではなく最後の 1 つで終わります。何かを描く前に待ちます。猶予時間のうちに終わった処理はバーをまったく表示しません。40 ms のルートで進捗バーが一瞬光るのは、速さではなく不具合に見えるからです。そして進み方は満ちるにつれて減速し、終端の手前で止まります。ここでは誰も本当の百分率を知らないので、100 % を出せるのは `complete()` だけです。それが真実だと知っているのが `complete()` だけだからです。配置は、位置指定したナビゲーションバーの中に `mode="overlay"` で、ナビゲーションバー自体が固定なら `mode="fixed"` と `--hub-loading-bar-offset` で行います。
サンプル:
ページ進捗バー
模擬ナビゲーションバーに吊るしたバー。三つのルートが三つの挙動を示します。ふつうのものは進み、遅いものは進行の減速が見え、40 ms のものはバーをまったく描きません。
Orders
This page arrived without you watching a spinner.
コード
Import:
Template:
Component:
既知の進捗と未知の進捗
`progress` をバインドするとバーは呼び出し元のものになり、`aria-valuenow` を公開します。`indeterminate` は代わりに往復し、値を伏せます。三つめの状態 `null` はバーを片付けます。
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
indeterminateA 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.
コード
Import:
Template:
Component:
ルーターと HTTP の連携
バーが呼び出し元を数える理由。ナビゲーション 1 回と 3 本のリクエストで参照は 4 つになり、バーは最後の 1 つで終わります。コードは `provideHubLoadingBarRouter()`、インターセプター、除外の指定を示します。
Nothing yet.
コード
Import:
Template:
Component:
右から左へのスイープ
同じ `indeterminate` のバーを `dir="ltr"` の下と `dir="rtl"` の下に並べています。スイープは `--hub-loading-bar-sweep-direction` に従って文字の流れと同じ向きに反転するので、ロケールごとに何かをバインドしたり複製したりする必要はありません。
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.
コード
Import:
Template:
Component:
主な機能
最近の変更
Version 22.2.1 - 9/16/26, 12:00 AM
changed: Repository, issue and README links follow the move to the hub-env organization. Issues for every Hub UI package are now gathered in hub-env/hub-ui, and the repository and bugs fields of the manifest point at the new addresses. No code, types or styles change.
Version 22.2.0 - 9/8/26, 12:00 AM
changed: <hub-loading> and <hub-loading-bar> keep their stylesheets to themselves. Both shipped with ViewEncapsulation.None, and neither reason recorded for it held any more. Retheming from a global stylesheet is answered by the tokens, not by the encapsulation mode: they are declared on the host at zero specificity, a custom property inherits down to every element inside, and a rule written against .hub-loading still reaches the host because the class is on the host element. And the overlay HubLoadingService mounts on document.body is a real component instance created through createComponent(), so it carries its own stylesheet with it. See BREAKING_CHANGES.md.
changed: The bar's RTL rule is written as :host-context([dir='rtl']). It was a hand-written pair of selectors, one for the attribute on an ancestor and one for the attribute on the bar itself, because dir is inherited and both spellings are legitimate. :host-context() is exactly that pair, and under emulated encapsulation Angular now compiles it, which it never did while the component was unencapsulated. Same behaviour, one selector.
added: ng-hub-ui-ds is declared as an optional peer dependency (>=22.0.0). Both stylesheets have always resolved their defaults through the --hub-sys-* / --hub-ref-* ladder and the manifest said nothing about it, so a consumer reading the package on npm could not tell that installing the token package is what hands the indicator and the bar the family palette and its dark mode. It stays optional: every token carries a literal fallback and the library renders without it.
Version 22.1.1 - 9/6/26, 12:00 AM
added: Both READMEs now document the BEM classes of the loading bar and add a Right-to-left section explaining that the indeterminate sweep reverses under dir="rtl" so it travels with the text. Both have worked since 22.1.0 with nothing in the documentation to find them by, which is the same as not having them.
changed: rxjs is now declared as a peer dependency, because hubLoadingBarInterceptor imports finalize from it on the published path and a strict installer such as pnpm with hoisting turned off had no reason to resolve it. Nothing changes under npm or yarn, where rxjs arrives hoisted as a peer of @angular/core.
fixed: The Angular badge and the opening line of both READMEs say 21+, the range package.json has always declared. Claiming 22+ turned away an application on Angular 21 that the library supports.
fixed: HubLoadingService.isLoading is described as what it computes, the reference counter rather than the mounted overlay. The README contradicted itself, since its own SSR section already explained that on the server the counter runs while the mount is skipped.
fixed: FUNCTIONALITIES.md marks the ariaLabel of hub-loading as covered, which the Inline playground control has made true since the page shipped, and adds the RTL row of the bar so the file stops omitting behaviour the stylesheet has.
fixed: Calling HubLoadingService.hide(), HubLoadingBarService.complete() or HubLoadingBarService.inc() from inside an effect() no longer subscribes that effect to the internal state of the service. Each of those paths read a tracked signal to decide what to do next, the counter, whether the bar is on screen, the current fill, so the effect woke up on state it does not own: a show() from anywhere else re-ran it and retired a reference it never registered, and inc() re-entered itself on every step. The untracked read that already guarded the bar counter now covers the three places that were left out.
Version 22.1.0 - 9/5/26, 12:00 AM
added: hub-loading-bar: the thin page-progress strip that sits under the navbar, in three placements — inline in the flow, overlay against a positioned ancestor, or fixed to the viewport at --hub-loading-bar-offset.
added: HubLoadingBarService, with reference-counted start() / complete(), an anti-flicker grace period so fast work never paints a bar at all — set delay to 0 to opt out and reveal synchronously — and a trickle that decelerates as it fills and stops short of the end, since only complete() may show 100%.
added: provideHubLoadingBarRouter(), which runs the bar for the length of a navigation, including one a guard rejects, and hubLoadingBarInterceptor with withoutHubLoadingBar() to keep polls and heartbeats out of the count.
added: Determinate mode through the progress input, which publishes aria-valuenow, and an indeterminate sweep. Both withhold the value while the number is invented, which is how ARIA marks a progressbar of unknown position.
added: provideHubLoadingBar(), the HUB_LOADING_BAR_CONFIG token, the exported hubLoadingBarTrickle() curve, thirteen --hub-loading-bar-* tokens and the hub-loading-bar-theme() Sass mixin.
Version 22.0.0 - 8/24/26, 12:00 AM
added: Initial release of hub-loading: one component covering the inline block, the container overlay and the fullscreen layer, with role="status", aria-live="polite" and aria-busy set on the host.
added: Five pure-CSS indicators — spinner, dots, bars, pulse and ring — in three size steps, with no image or font dependency.
added: Accent resolution through resolveHubAccent() from ng-hub-ui-utils: a bare name becomes a --hub-sys-color-* token and follows the theme, while a hex, an oklch() or a var(...) is used verbatim.
added: Optional image input with none, spin and pulse animations, replacing the built-in indicator with a brand mark.
added: HubLoadingService for the fullscreen overlay, with a reference counter so concurrent callers cannot unblock the screen out from under each other, plus update() to re-dress the live overlay and hideAll() to force the count to zero. SSR-safe: a no-op without a DOM.
added: provideHubLoading() and the HUB_LOADING_CONFIG token, supplying application-wide defaults to both the component and the service.
added: Theming through the --hub-loading-* token ladder and the hub-loading-theme() Sass mixin, shipped at ng-hub-ui-loading/styles.
関連ライブラリ
よくある質問
Angular で読み込みスピナーやオーバーレイを表示するには?
ng-hub-ui-loading をインストールし、処理中に `<hub-loading>` を表示します。既定ではドキュメントフローの中のインラインブロックです。`mode` を `overlay` にすると周囲のコンテナを覆い、`fullscreen` にすると画面全体を塞ぎます。アプリ全体のオーバーレイには `HubLoadingService` を注入し、処理の前後で `show()` と `hide()` を呼びます。
スピナー、スケルトン、プログレスバーのどれを使うべき?
これから来る内容の形が分かっているなら ng-hub-ui-skeleton です。プレースホルダーが場所を確保し、レイアウトのずれを防ぎます。待ち時間が不定、あるいは画面を塞ぐ必要があるとき——フォームの送信中、レポートの生成中——は ng-hub-ui-loading を使います。実際の進捗を示せる場合は、ng-hub-ui-metrics が確定的なバー・メーター・リングを描きます。
Angular の読み込みインジケーターの色を変えるには?
`color` 入力を設定します。セマンティックな名前、16 進リテラル、`oklch()` の値、あるいは自前トークンへの `var(...)` 参照を受け付けます。恒久的に変えるなら、色・サイズ・時間はすべて `--hub-loading-*` カスタムプロパティなので自分のスタイルシートで再定義でき、Sass ミックスイン `hub-loading-theme()` はコンポーネント全体を一か所で作り直します。`image` 入力は、読み込み状態にブランドを持たせたいときインジケーターをロゴに置き換えます。
Angular の読み込みコンポーネントはアクセシブルで SSR に対応していますか?
はい。ホストは `role=status`、`aria-live=polite`、`aria-busy` を備えたライブリージョンで、読み上げ文言は `ariaLabel` 入力で指定できます。アニメーションは `prefers-reduced-motion` の下ですべて無効になります。サーバー側にはマウント先の DOM がないため、`HubLoadingService` はカウンターだけを保持し、サーバーサイドレンダリングは安全なままです。
Angular でナビゲーションバーの下にページ読み込みバーを追加するには?
`position: relative` を持つナビゲーションバーの中に `<hub-loading-bar mode="overlay" placement="bottom">` を置くか、ナビゲーションバーも固定されている場合は `mode="fixed"` と `--hub-loading-bar-offset` を使います。次に `provideHubLoadingBarRouter()` を追加すると、ガードに拒否された遷移も含め、各ナビゲーションの間ずっとバーが動きます。`hubLoadingBarInterceptor` を加えれば、ページ到着時に発行されるリクエストも対象になります。バーは呼び出し元を参照カウントするため、両者は互いを知らないまま組み合わさり、`withoutHubLoadingBar()` は背景のポーリングをカウントから外します。