npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sp1ne/angular

v0.0.13

Published

Angular UI shell library built on top of [Clarity Design System](https://clarity.design). Provides the full application frame — layout, navigation, routing infrastructure, and a set of built-in feature pages — for Identora applications.

Downloads

1,455

Readme

@sp1ne/angular

Angular UI shell library built on top of Clarity Design System. Provides the full application frame — layout, navigation, routing infrastructure, and a set of built-in feature pages — for Identora applications.

Requires @cl4im/angular.
Layout components, the route guard, and all shell pages depend on services provided by @cl4im/angular/core (AuthorizationService, ViewService, RealmAppsService). Both libraries must be registered in the same application.

Entry Points

| Import path | Purpose | |---|---| | @sp1ne/angular | Core providers, theme, density, Clarity re-exports | | @sp1ne/angular/layout | Layout, header, sidebar, navigation components | | @sp1ne/angular/routing | Hierarchical router components, view guard, component distributor | | @sp1ne/angular/shell | Route arrays, public/private pages, provideShell() |


Installation

npm install @sp1ne/angular

@cl4im/angular must also be installed — it is a peer dependency, not bundled here.


Setup

A minimal app.config.ts:

import { provideAuth }  from '@cl4im/angular/core';
import { provideUi }    from '@sp1ne/angular';
import { provideShell, APP_ROUTES } from '@sp1ne/angular/shell';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { provideAnimations } from '@angular/platform-browser/animations';
import { environment } from 'src/environments/environment';
import packageInfo from '../../package.json';
import { components } from './features/features.routes';
import { myAppRoutes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideAnimations(),
    provideHttpClient(),
    provideAuth(environment.auth),
    provideUi(),
    provideRouter([...myAppRoutes, ...APP_ROUTES]),
    provideShell({ appComponents: components, packageInfo }),
  ],
};

@sp1ne/angular

provideUi()

Registers ThemeService and DensityService initializers as APP_INITIALIZER so the theme and density are applied before the first render.

ThemeService

Manages light/dark theme switching. The active theme is persisted to localStorage and restored on startup.

import { ThemeService } from '@sp1ne/angular';

themeService.toggle();          // switch between light and dark
themeService.set('dark');       // set explicitly
themeService.current            // 'light' | 'dark'
themeService.theme$             // Observable<'light' | 'dark'>

DensityService

Controls Clarity's spacing density. Persisted to localStorage.

import { DensityService } from '@sp1ne/angular';

densityService.set('compact');  // 'default' | 'regular' | 'compact'
densityService.current          // DensitySetting

ClaritySharedModule

Re-exports ClarityModule, ClrButtonModule, ClrIconModule, and CdsModule with all icon sets pre-loaded (Core, Essential, Commerce, Chart, Media, Social, Technology, TextEdit, Travel, Mini). Import this module instead of individual Clarity imports.

import { ClaritySharedModule } from '@sp1ne/angular';

@sp1ne/angular/layout

Contains the four visual frame components. They are rendered automatically by LayoutComponent — you do not need to place them manually.

LayoutComponent (purp-layout)

Top-level shell wrapper. Composes HeaderComponent, SidebarComponent, and NavigationComponent. Used as the wrapper for all private routes in APP_ROUTES.

HeaderComponent (purp-header)

Top navigation bar. Features:

  • Application name from ViewService
  • App launcher (AppLauncherComponent) — lists other Identora apps in the realm
  • Theme toggle (light/dark)
  • Density toggle
  • Fullscreen toggle
  • Logout button

Depends on: AuthorizationService, ViewService, RealmAppsService.

SidebarComponent (purp-sidebar)

Left-side menu. Renders the navigation hierarchy (header → navigation → menu → items → submenus) derived from ViewService.currentView$. Also renders the docs navigation when applicable.

NavigationComponent (purp-navigation, ViewEncapsulation.None)

Breadcrumb bar + <router-outlet>. The component uses ViewEncapsulation.None so its container layout styles (.container-column, .container-row) apply globally — this is intentional and required for content pages to fill the available height correctly.

Depends on: ViewService for the breadcrumb trail.


@sp1ne/angular/routing

Hierarchical router components

The routing system maps the view hierarchy from the server into a chain of Angular route levels. Each component renders a <router-outlet> that activates the next level.

| Component | Selector | Route level | |---|---|---| | RouterComponent | router | 0 — root | | HeaderRouterComponent | app-header-router | 1 | | NavigationRouterComponent | app-navigation-router | 2 | | MenuRouterComponent | app-menu-router | 3 | | ItemRouterComponent | app-item-router | 4 | | SubmenuRouterComponent | app-submenu-router | 5 | | MultipageRouterComponent | app-multipage-router | 6 |

ComponentFactoryComponent (app-component-factory)

Dynamically instantiates the component that matches the current route's route_id. Components are registered at startup via COMPONENT_ROUTES and lazy-loaded on demand.

ViewGuard

CanActivate / CanActivateChild guard. On each navigation it:

  1. Reads the target URL
  2. Looks up the corresponding route in ViewService
  3. Updates the breadcrumb trail
  4. Allows or redirects the navigation

Applied automatically to all private routes inside APP_ROUTES.

ComponentDistributorService

Matches a route_id to a registered lazy component and renders it. Falls back to NoContentComponent if no match is found.

COMPONENT_ROUTES token

Used internally by provideShell() to register app-specific components alongside the library's built-in BASE_COMPONENTS.

ComponentRoute interface

interface ComponentRoute {
  route_id: string;                           // router_id from web.router
  component: () => Promise<Type<any>>;        // dynamic import
}

@sp1ne/angular/shell

provideShell(options: ShellOptions)

Registers all route components. Call once in app.config.ts.

interface ShellOptions {
  appComponents?: ComponentRoute[];   // app-specific lazy components
  packageInfo?: PackageInfo;          // package.json metadata for About pages
}

APP_ROUTES

The complete route array to pass to provideRouter. Includes:

  • PUBLIC_ROUTES/login, /callback, /logoff — no auth required
  • PRIVATE_ROUTES — everything else, wrapped in LayoutComponent with ViewGuard

Registering application components

Create features.routes.ts and list every lazy component the app can render, keyed by its router_id from web.router:

// src/app/features/features.routes.ts
import { ComponentRoute } from '@sp1ne/angular/routing';

export const components: ComponentRoute[] = [
  {
    route_id: 'e3f4a5b6-c7d8-4e9f-a0b1-c2d3e4f56789',  // web.router.router_id
    component: async () =>
      (await import('./dashboard/dashboard.component')).DashboardComponent,
  },
];

Pass components to provideShell({ appComponents: components }). The ComponentDistributorService will lazy-load the matching component when the route is activated.

Important: the key is router_id from web.router, not route_id from web.routes. For single-level routes (page_id only, no header/menu hierarchy), buildRouteStructure sets route.route_id = view.router_id, so both point to the same value. For multi-level routes use the router_id of the deepest level entry.

Built-in pages (BASE_COMPONENTS)

The following pages are registered automatically by provideShell() and do not need to be declared in features.routes.ts:

| Page | Description | |---|---| | HomeComponent | Default home/dashboard | | ProfileComponent | User profile | | ChangePictureComponent | Profile picture upload | | InfoComponent | Settings — general info | | ResourcesComponent | Settings — resources | | TokenComponent | API token viewer | | NotificationsComponent | Notification preferences | | ChatComponent | Chat interface | | AboutInfoComponent | App info from PackageInfo | | AboutResourcesComponent | App resources from PackageInfo |

Public route components

| Component | Path | Description | |---|---|---| | LoginComponent | /login | Initiates the OAuth flow via AuthorizationService.authorize() | | CallbackComponent | /callback | Handles the authorization code redirect, exchanges code for token | | LoggedOutComponent | /logoff | Shown after logout |


Dependency on @cl4im/angular

@sp1ne/angular does not re-export or bundle @cl4im/angular. The dependency is structural: layout and routing components inject services that must be provided externally by the consuming app.

| UI component / service | Auth dependency injected | |---|---| | HeaderComponent | AuthorizationService, ViewService, RealmAppsService | | SidebarComponent | ViewService | | NavigationComponent | ViewService | | ViewGuard | ViewService, AuthorizationService | | CallbackComponent | AuthorizationService | | LoginComponent | AuthorizationService | | ComponentDistributorService | ViewService (indirectly, via LoggerService) |

All of these are provided by provideAuth() from @cl4im/angular/core. If provideAuth() (or an equivalent { provide: AUTH_CONFIG, useValue: ... } + manual service provision) is missing from the application, the app will throw injection errors at runtime.

The minimum required setup:

// app.config.ts
providers: [
  provideAuth(environment.auth),  // @cl4im/angular/core — REQUIRED
  provideUi(),                    // @sp1ne/angular
  provideShell({ appComponents, packageInfo }),
  provideRouter([...appRoutes, ...APP_ROUTES]),
  provideHttpClient(),
  provideAnimations(),
]

Peer dependencies

| Package | Version | |---|---| | @angular/common | ^19.0.0 | | @angular/core | ^19.0.0 | | @angular/router | ^19.0.0 | | @angular/platform-browser | ^19.0.0 | | @clr/angular | ^17.0.0 | | @cds/core | ^17.0.0 | | rxjs | ^7.0.0 | | @cl4im/angular | ^0.1.0 |