Angular Skeleton Loader Component | ng-hub-ui-skeleton

Angular skeleton loading placeholders with reusable presets, inline DSL templates, responsive values and CSS variables for shimmer states.

Last updated Sep 6, 2026

Overview

Why teams search for this library

Choose this Angular skeleton library when loading states need to stay systematic, reusable and product-ready instead of degenerating into one-off shimmer markup.

Install

npm install ng-hub-ui-skeleton

Jump to

Ideal for

  • cards and feeds
  • data tables
  • forms
  • dashboards

About skeleton

ng-hub-ui-skeleton gives Angular teams a structured way to design loading placeholders: bundled presets for common UI patterns, a compact DSL for custom shapes and responsive values that adapt the same skeleton to multiple layouts.

Feature guides

Preset Catalogue

The bundled catalogue is intentionally broad because loading states are usually repeated business UI, not isolated placeholders. It includes card, list-item, table-row, detail-view, form-section, dashboard-widget, stat-card, chart-panel, profile-summary, master-detail, kanban-card, feed-item, search-result, table-toolbar, filter-bar and empty-state-skeleton. The idea is to let teams start from a production-oriented loading vocabulary instead of rebuilding the same shimmer blocks in every feature. In practice, that means table-heavy screens can start from `table-toolbar` plus repeated `table-row`, dashboard screens can mix `stat-card`, `chart-panel` and `dashboard-widget`, and content-led flows can reach for `card`, `feed-item` or `search-result` without writing new layout markup from scratch.

Examples:
Preset Catalogue Gallery

Shows the bundled presets together so teams can choose the closest starting point before authoring custom templates.

card

Content card with media, title and body lines.

list-item

Compact row with avatar and text.

table-row

Tabular data row placeholder.

detail-view

Detail screen with media and metadata.

form-section

Form group with responsive fields.

dashboard-widget

Panel with chart or metric content.

stat-card

Quick KPI summary card.

chart-panel

Large chart region with legend rows.

profile-summary

Profile hero with avatar and stats.

master-detail

List and detail layout together.

kanban-card

Small board card loading state.

feed-item

Activity or timeline row.

search-result

Search result with metadata lines.

table-toolbar

Toolbar with title, filters and actions.

filter-bar

Row of filter controls.

empty-state-skeleton

Illustrative empty or onboarding state.

card

Dense card variant for tighter layouts.

Code
Import:
Template:
Component:
Bundled Card Preset

Renders the built-in card skeleton with the default shimmer appearance.

Code
Import:
Template:
Component:
Dashboard Composition

Composes several presets to mock an analytics dashboard during loading.

Code
Import:
Template:
Component:

Compact DSL Authoring

Inline templates use a compact Emmet-like syntax because the library optimizes for fast iteration inside Angular codebases. Sibling composition uses `+`, nesting uses `>`, modifiers live inside parentheses, repeats use `*N`, and params are interpolated with `{{param}}`. That gives teams a compact authoring surface that still reads well in pull requests and allows small changes without rewriting a full object tree. The important point is not syntax cleverness: it is that layout intent stays close to the component usage and remains simple to diff, refactor and review.

Examples:
Compact DSL Patterns

Explains the core DSL building blocks with visual outputs for structure, params and responsive tokens.

Structure

`+` creates siblings and `>` nests children.

Params & repeats

Use {{param}} placeholders and *N repeaters to scale rows quickly.

Responsive values

Switch spacing or columns inline with compact breakpoint tokens.

Code
Import:
Template:
Component:
Inline Emmet-like Template

Defines a custom skeleton shape inline with params interpolation.

Code
Import:
Template:
Component:

Variants And Responsive Layouts

Loading states should not ignore layout density or breakpoints, because users notice when the skeleton bears no relation to the real UI. Presets can expose variants such as `compact`, and individual modifier values can switch across breakpoints using compact responsive tokens. That makes it possible to keep one semantic skeleton definition while adapting widths, column counts, spacing and sizing across mobile, tablet and desktop contexts. The practical result is fewer duplicated templates and much better alignment between the placeholder phase and the real rendered interface.

Examples:
Compact Variant

Compares the default card preset with its compact variant for denser interfaces.

Code
Import:
Template:
Component:
Responsive Table Layout

Uses responsive values inside the built-in presets to adapt from compact to wider layouts.

Code
Import:
Template:
Component:

Programmatic Registration And Theming

Bundled presets are the starting point, not the ceiling. Teams can register project-specific presets through Angular dependency injection and then consume them by name exactly like the built-in catalogue, which is critical when a product has its own repeated skeleton language. Visual tuning stays in CSS variables, so shimmer intensity, base colour, highlight colour, spacing and radius can align with the design system instead of leaking hardcoded values into feature components. This separation is important: structure belongs in presets and DSL, while visual policy belongs in theming.

Examples:
Programmatic Custom Preset

Registers a local preset and consumes it by name just like the bundled catalogue.

Code
Import:
Template:
Component:
Dashboard Composition

Composes several presets to mock an analytics dashboard during loading.

Code
Import:
Template:
Component:

Key features

Recent changes

Version 22.3.0 - 9/6/26, 12:00 AM

added: FUNCTIONALITIES.md now ships with the library, the same coverage table the rest of the family provides: which parts of the component, the DSL, the preset catalogue, the registry and the styling surface a live example actually demonstrates, and which are only prose. Nothing stated it before, so a reader had to open the documentation site and infer it.

changed: One preset registry is shared again instead of one per placeholder. The component listed HubSkeletonPresetRegistryService in its own providers, so every <hub-skeleton> on screen built a private instance and merged the sixteen bundled presets into a fresh Map, twenty times over on a screen with twenty placeholders, while the README described the service as the providedIn: 'root' singleton a consumer who injects it actually gets. The component now resolves the root instance, which changes where custom presets are read from: see BREAKING_CHANGES.md.

changed: Both READMEs teach the canonical ng-hub-ui-skeleton/styles entry for the theming mixin. They still reached for the deep path ng-hub-ui-skeleton/styles/mixins/skeleton-theme, which resolves but is not the entry 22.2.0 introduced and not what BREAKING_CHANGES.md, the mixin's own header and the generated mixin reference all show, so a reader comparing two sources had to guess which one was current.

fixed: The ariaLabel input is finally reachable by assistive technology. The container carried role="presentation" and aria-label at once, a conflict that costs the name whichever way a user agent resolves it, while every placeholder shape inside is aria-hidden, so nothing was left to carry the name either. A consumer setting the input, or relying on its non-empty default, got silence and had to announce the loading state from an outer element of their own. The container is now a polite role="status" region with aria-busy="true", matching ng-hub-ui-loading, and keeps the label as its accessible name.

fixed: The styles subpath the docs prescribe is now declared in the manifest exports. Since 22.2.0 the stylesheets have shipped at styles/, and both the README and BREAKING_CHANGES.md tell consumers to reach them with @use ng-hub-ui-skeleton/styles. The generated exports map declared only . and ./package.json, so anything that enforces the map, from Node subpath resolution to the Sass pkg: importer and bundlers that honour exports, refused the very import the documentation teaches. An Angular CLI build happened to survive because it resolves bare Sass specifiers through loadPaths instead, which is why the block went unnoticed. The theming entry and the skeleton-theme mixin are now declared explicitly, as the sibling libraries already do.

deprecated: HubSkeletonModule is deprecated and will be removed in 23.0.0. It imports and exports HubSkeletonComponent and provides nothing of its own, so importing the component directly is the whole migration; custom presets go through provideHubSkeletonPresets(), which never travelled through the module either. The class described itself as kept for compatibility with module-based apps but carried no @deprecated tag, so neither an editor nor the build warned anyone. See BREAKING_CHANGES.md.

Version 22.2.4 - 9/1/26, 12:00 AM

changed: The homepage in the manifest points at this library's own documentation page rather than at the site root. It is the link a registry shows beside the package and the one a reader clicks from it, and landing on a front page they then have to search is a worse answer than landing on the reference for the package they were already looking at. Metadata only — no code, no types, no styles change, and nothing a consumer imports is affected.

Version 22.2.3 - 8/17/26, 12:00 AM

fixed: The package shipped without its licence notice. package.json declared MIT, but no LICENSE file travelled in the tarball — and MIT itself requires the copyright notice to be included in distributions. The notice ships now.

Version 22.2.2 - 8/8/26, 12:00 AM

fixed: Documentation links now point at the canonical localized URLs. The README linked to https://hubui.dev/<path> with no locale prefix and no trailing slash, and both forms are 301-redirected, so every reader arriving from npm or GitHub landed on a redirect instead of the canonical page.

Version 22.2.1 - 7/28/26, 12:00 AM

added: Comprehensive test suite for the skeleton DSL parser and preset registry: full grammar coverage (node types, nesting, siblings, props, variants, multipliers, responsive tokens), every parser error path with its exact message, preset expansion/override/variant resolution, and component render round-trips. No runtime changes.

Version 22.2.0 - 7/7/26, 12:00 AM

changed: BREAKING (packaging) — SCSS ships at ng-hub-ui-skeleton/styles. The theme mixin now builds to dist/skeleton/styles/... (was dist/skeleton/src/lib/styles/...), so @use 'ng-hub-ui-skeleton/styles' resolves. Update any @use that reached into src/lib/styles.

Version 22.1.0 - 6/24/26, 12:00 AM

added: New hub-skeleton-theme() Sass mixin (styles/mixins/skeleton-theme) — theme the loading placeholders in one call: base / highlight surfaces (the shimmer gradient), corner radius, node gap and shimmer speed. Every parameter is optional and defaults to null, so only the ones you pass are emitted as --hub-skeleton-* overrides. Token-based, no Bootstrap dependency. (A skeleton is a neutral placeholder — there is no semantic colour variant; per-node sizes still come from the template DSL / presets.) The five theming tokens (--hub-skeleton-bg / -highlight / -radius / -gap / -animation-duration) are now documented in the design-token reference.

Version 22.0.0 - 6/17/26, 12:00 AM

changed: Aligned with Angular 22.

changed: README documentation standardized.

Version 0.1.1 - 6/14/26, 12:00 AM

changed: Replaced the deprecated ngStyle directive with the native [style] binding (Angular soft-deprecated ngStyle/ngClass in November 2024 in favour of native bindings, for better performance and smaller bundles).

Version 0.1.0 - 4/14/26, 12:00 AM

added: Added the initial dynamic skeleton component for Angular.

added: Added a compact Emmet-like DSL with preset composition and repeat support.

added: Added responsive property values, variants, and programmatic preset registration.

added: Added the first preset catalogue for cards, lists, tables, forms, dashboards, and empty states.

Frequently asked questions

How do I show skeleton loading placeholders in Angular?

Install ng-hub-ui-skeleton and render HubSkeletonComponent while your data is in flight. You describe the placeholder shape — lines, blocks, circles — and it animates a shimmer until the real content replaces it, which keeps the layout from jumping when the data lands.

Can I reuse the same skeleton shape across components?

Yes. HubSkeletonPreset registers a named shape once and reuses it wherever that layout appears, so a card placeholder is defined in one place instead of being copied into every list and detail view that renders a card.

How do I change the shimmer colour or speed of a skeleton?

Every colour, radius and animation of ng-hub-ui-skeleton is a CSS custom property, so you restyle it from your own stylesheet at runtime and it follows dark mode without rebuilding. HubSkeletonAppearance switches between the built-in shimmer and a plain static placeholder.

Should I use a skeleton or a spinner while data loads?

Use a skeleton when you know the shape of the content that is coming, because it reserves the space and avoids the layout shift a spinner leaves behind. A spinner fits better for short, indeterminate waits where the resulting layout is unknown.