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

@pyrophire/ix-libs

v22.0.1

Published

Component libraries for the IX team

Readme

@pyrophire/ix-libs

Publish Package

Angular 21+ standalone components, services, and pipes used across IX applications.

This README is generated from the current source implementation in projects/ix-libs/src/lib and documents every exported feature except ix-table and ix-table-header (intentionally excluded).


Contents


Requirements

@pyrophire/[email protected] peer dependencies:

  • @angular/* ^21.0.0
  • @angular/material ^21.0.0
  • rxjs ^7.8.0
  • tslib ^2.3.1

Install

npm install @pyrophire/ix-libs

If you use provideIxIcons(), copy icon assets from the package into your app build output:

{
  "projects": {
    "your-app": {
      "architect": {
        "build": {
          "options": {
            "assets": [
              {
                "glob": "**/*",
                "input": "./node_modules/@pyrophire/ix-libs/ix-img/",
                "output": "./ix-img"
              }
            ]
          }
        }
      }
    }
  }
}

Quick Start

// main.ts
import { bootstrapApplication } from '@angular/platform-browser';
import { provideAnimations } from '@angular/platform-browser/animations';
import { provideIxIcons } from '@pyrophire/ix-libs';
import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent, {
  providers: [provideAnimations(), provideIxIcons()]
});
// any standalone component
import { Component } from '@angular/core';
import {
  ScrollTopButtonComponent,
  ThemeButtonComponent,
  ScrollBarProgressComponent,
  AmPmPipe
} from '@pyrophire/ix-libs';

@Component({
  standalone: true,
  selector: 'app-demo',
  imports: [ScrollTopButtonComponent, ThemeButtonComponent, ScrollBarProgressComponent, AmPmPipe],
  template: `
    <ix-theme-button></ix-theme-button>
    <ix-scroll-progress [config]="progressConfig"></ix-scroll-progress>
    <ix-scroll-button color="primary"></ix-scroll-button>
    <div>{{ '13:45:00' | ampm }}</div>
  `
})
export class DemoComponent {
  progressConfig = { position: 'fixed', top: 0, left: 0, right: 0, barColor: '#1976d2', backgroundColor: '#e0e0e0' };
}

Quick Reference

1) Install + Bootstrap

npm install @pyrophire/ix-libs
import { provideIxIcons } from '@pyrophire/ix-libs';

bootstrapApplication(AppComponent, {
  providers: [provideIxIcons()]
});

2) Import what you use

import {
  ThemeButtonComponent,
  ThemeMenuItemComponent,
  ScrollTopButtonComponent,
  ScrollBarProgressComponent,
  IxDarkService,
  IxLocalStorageService,
  AmPmPipe,
  CamelToTitlePipe,
  FileSizePipe,
  PhonePipe,
  SafePipe
} from '@pyrophire/ix-libs';

3) Use in template

<ix-theme-button></ix-theme-button>
<ix-scroll-progress [config]="{ position: 'fixed', top: 0, left: 0, right: 0 }"></ix-scroll-progress>
<ix-scroll-button color="primary"></ix-scroll-button>

<div>{{ '14:30:00' | ampm }}</div>
<div>{{ 'firstName' | c2t }}</div>
<div>{{ 1048576 | filesize }}</div>

4) Feature map

  • Theme switching: IxDarkService, ix-theme-button, ix-theme-menu-item
  • Scroll helpers: ix-scroll-button, ix-scroll-progress, ScrollButtonService
  • Data transforms: ampm, c2t, filesize, phone, safe
  • Storage/forms utilities: IxLocalStorageService, IxSessionStorageService, IxFormsHelperService
  • Material SVG icons: provideIxIcons() + svgIcon="ix-*"

Public API (Documented Here)

From src/public_api.ts, excluding intentionally ignored exports:

  • provideIxIcons
  • IxDarkService
  • AmPmPipe
  • CamelToTitlePipe
  • FileSizePipe
  • PhonePipe
  • SafePipe
  • ProgressBarConfig
  • ScrollBarProgressComponent
  • ScrollTopButtonComponent
  • ScrollButtonService
  • ThemeButtonComponent
  • ThemeMenuItemComponent
  • IxFormsHelperService
  • IxLocalStorageService
  • IxSessionStorageService

Excluded in this README by request:

  • IxTableComponent
  • IxTableHeaderComponent

Icons (provideIxIcons)

Provider that registers SVG icons with Angular Material MatIconRegistry at app bootstrap.

Setup

  1. Copy ix-img assets into your app output (see Install).
  2. Add provideIxIcons() to app providers.
  3. Use icons via svgIcon on <mat-icon>.

Registered icon names

  • ix-file-pdf
  • ix-file-doc
  • ix-file-excel
  • ix-file-html
  • ix-file-csv
  • ix-save-csv
  • ix-export
  • ix-dialog

Example

<mat-icon svgIcon="ix-file-pdf" aria-label="PDF"></mat-icon>
<mat-icon svgIcon="ix-export" aria-label="Export"></mat-icon>

Theming

The theming utilities are class-based and expect light / dark classes to exist in your global theme styles.

IxDarkService

Service for dark/light mode preference, body class toggling, and persistence.

IxDarkService injection

import { IxDarkService } from '@pyrophire/ix-libs';

constructor(private darkService: IxDarkService) {}

IxDarkService public members

  • prefersDark: boolean — result of matchMedia('(prefers-color-scheme: dark)')
  • localStorageLightDark: string — persisted preference from storage key DarkModePref
  • themeStream: ReplaySubject<string> — emits 'light' / 'dark'

IxDarkService public methods

  • setDarkModePreference(): void
    • Applies stored preference if present, otherwise system preference.
    • Updates body classes and emits theme.
  • toggleDarkLightMode(): void
    • Switches between light and dark.
    • Persists to storage and updates body classes.
  • theme(): string
    • Returns current theme from internal signal ('light' or 'dark').

IxDarkService example

this.darkService.setDarkModePreference();
this.darkService.themeStream.subscribe((theme) => {
  console.log('Theme changed:', theme);
});

this.darkService.toggleDarkLightMode();

ThemeButtonComponent (ix-theme-button)

Standalone Material icon button that toggles dark mode via IxDarkService.

ThemeButton import

import { ThemeButtonComponent } from '@pyrophire/ix-libs';

ThemeButton template usage

<ix-theme-button></ix-theme-button>

ThemeButton behavior

  • Calls setDarkModePreference() during component initialization.
  • Click triggers toggleDarkMode() which delegates to IxDarkService.toggleDarkLightMode().
  • Icon classes reflect current theme.

ThemeMenuItemComponent (ix-theme-menu-item)

Material menu item variant of the theme toggle control.

ThemeMenuItem import

import { ThemeMenuItemComponent } from '@pyrophire/ix-libs';

ThemeMenuItem template usage

<mat-menu #menu="matMenu">
  <ix-theme-menu-item></ix-theme-menu-item>
</mat-menu>

ThemeMenuItem behavior

  • Same theme interaction pattern as ThemeButtonComponent.
  • Intended for placement inside a Material menu.

Scroll Features

ScrollTopButtonComponent (ix-scroll-button)

Floating action button that appears after scrolling past a threshold and scrolls a target container back to top.

ScrollTopButton import

import { ScrollTopButtonComponent } from '@pyrophire/ix-libs';

ScrollTopButton inputs

  • color ('primary' | 'accent' | undefined, default: undefined) — adds Material color class on the button.
  • scrollableElementId (string, default: 'ix-scroll-container') — target element ID watched for scroll.
  • isScrollableInput (boolean, default: false) — forces button logic to treat container as scrollable.
  • scrollHeightTrigger (number, default: 100) — pixels scrolled before showing button.
  • verticalButtonPosition ('top' | 'bottom', default: 'bottom') — vertical position class.
  • horizontalButtonPosition ('left' | 'right', default: 'right') — horizontal position class.

ScrollTopButton template usage

<ix-scroll-button
  color="primary"
  scrollableElementId="page-content"
  [scrollHeightTrigger]="200"
  verticalButtonPosition="bottom"
  horizontalButtonPosition="right">
</ix-scroll-button>

ScrollTopButton requirements

  • Target element must exist in the DOM with the given ID.
  • Target element should be an actual scroll container (overflow: auto|scroll) with constrained height if not body-level scrolling.

ScrollButtonService

Service used by ScrollTopButtonComponent, also available for direct use.

ScrollButtonService injection

import { ScrollButtonService } from '@pyrophire/ix-libs';

constructor(private scrollButtonService: ScrollButtonService) {}

ScrollButtonService public methods

  • setContainerId(id?: string): void
    • Sets internal container ID; defaults to body ID ix-scroll-container.
  • isScrollable(id?: string): boolean
    • Returns whether scrollHeight > clientHeight.
  • checkScroll(id?: string): Observable<boolean>
    • Observable wrapper for scrollability check.
  • scrollToTop(id?: string): void
    • Smooth-scrolls container to top.
  • scrollElementIntoView(id: string, location: 'start' | 'end'): void
    • Calls element.scrollIntoView({ behavior: 'smooth', block: location }).
  • startScrollMarking(): void
    • Debug helper that periodically marks scrollable elements.
  • stopScrollMarking(): void
    • Stops debug marking subscription.

ScrollButtonService example

this.scrollButtonService.scrollToTop('page-content');
this.scrollButtonService.scrollElementIntoView('footer', 'start');

ScrollBarProgressComponent (ix-scroll-progress)

Top/bottom/side progress bar that tracks document scroll percentage.

ScrollBarProgress import

import { ScrollBarProgressComponent } from '@pyrophire/ix-libs';

ScrollBarProgress input

  • config (ProgressBarConfig) — colors and position values for the progress container and bar.

ScrollBarProgress template usage

<ix-scroll-progress [config]="progressConfig"></ix-scroll-progress>

ScrollBarProgress example config

import { ProgressBarConfig } from '@pyrophire/ix-libs';

progressConfig: ProgressBarConfig = {
  position: 'fixed',
  top: 0,
  left: 0,
  right: 0,
  backgroundColor: '#bdbdbd',
  barColor: '#3f51b5'
};

ScrollBarProgress public methods

  • bottomReached(): boolean — true when computed progress is greater than 99.
  • progressBarProcess(): number — computes percent and updates internal bar width.

ProgressBarConfig

Model for ix-scroll-progress:

export class ProgressBarConfig {
  backgroundColor: string;
  barColor: string;
  position: 'sticky' | 'fixed' | 'absolute' | 'relative';
  top?: number | string;
  left?: number | string;
  bottom?: number | string;
  right?: number | string;
}

Pipes

All pipes are standalone and can be imported directly into standalone components.

import {
  AmPmPipe,
  CamelToTitlePipe,
  FileSizePipe,
  PhonePipe,
  SafePipe
} from '@pyrophire/ix-libs';

AmPmPipe (ampm)

Converts a time-like string (HH:mm or HH:mm:ss) into 12-hour format with AM/PM.

{{ '00:10:00' | ampm }}   <!-- 12:10:00  AM -->
{{ '13:45' | ampm }}      <!-- 1:45  PM -->

CamelToTitlePipe (c2t)

Converts camelCase/PascalCase-ish text into spaced title text.

{{ 'firstName' | c2t }}      <!-- First Name -->
{{ 'HTMLParser2' | c2t }}    <!-- H T M L Parser 2 -->

FileSizePipe (filesize)

Formats bytes into human-readable units. Accepts a number or number array.

{{ 2048 | filesize }}              <!-- 2 KB -->
{{ [512, 1048576] | filesize }}    <!-- ['512 Bytes', '1 MB'] -->

PhonePipe (phone)

Formats a digit string into US phone format (xxx) xxx-xxxx and appends extension text when extra digits are present.

{{ '5551234567' | phone }}         <!-- (555) 123-4567 -->
{{ '5551234567123' | phone }}      <!-- (555) 123-4567 ext: 123 -->

SafePipe (safe)

Bypasses Angular sanitization using DomSanitizer for explicit trust cases.

Supported types:

  • html
  • style
  • script
  • url
  • sms / text (prepends sms:)
  • mailto / email (prepends mailto:)
  • tel (prepends tel:)
  • resourceUrl
<div [innerHTML]="htmlSnippet | safe:'html'"></div>
<a [href]="'[email protected]' | safe:'mailto'">Email support</a>
<iframe [src]="videoUrl | safe:'resourceUrl'"></iframe>

Security note: only pass trusted content. This pipe explicitly bypasses Angular's built-in protections.


Shared Utilities

IxFormsHelperService

Helper methods for Angular forms.

IxFormsHelperService injection

import { IxFormsHelperService } from '@pyrophire/ix-libs';

constructor(private formsHelper: IxFormsHelperService) {}

IxFormsHelperService public methods

  • getDirtyValues(form): any
    • Recursively returns only fields marked dirty.
  • hasValidationError(control: UntypedFormControl, errorCode: string): boolean
    • True when control has error and has been touched.
  • requiredLabel(label: string, control: any): string
    • Adds * suffix if control appears to include required validator.

IxFormsHelperService example

const patchPayload = this.formsHelper.getDirtyValues(this.form);
const showRequired = this.formsHelper.hasValidationError(this.form.controls['name'], 'required');
const label = this.formsHelper.requiredLabel('First Name', this.form.controls['firstName']);

IxLocalStorageService

Wrapper around window.localStorage with in-memory fallback at window.ix.

IxLocalStorageService public properties

  • localStorageFeatureAvailable: boolean

IxLocalStorageService public methods

  • setItem(key: string, value: string | object | any[]): void
  • getItem(key: string): any (JSON parsed if possible)
  • removeItem(key: string): void
  • clear(): void

IxLocalStorageService example

this.localStorageService.setItem('filters', { status: 'open' });
const filters = this.localStorageService.getItem('filters');
this.localStorageService.removeItem('filters');

IxSessionStorageService

Wrapper around window.sessionStorage with in-memory fallback at window.ix.

IxSessionStorageService public properties

  • sessionStorageFeatureAvailable: boolean

IxSessionStorageService public methods

  • setItem(key: string, value: string | object | any[]): void
  • getItem(key: string): any (JSON parsed if possible)
  • removeItem(key: string): void
  • clear(): void

IxSessionStorageService example

this.sessionStorageService.setItem('draft', this.form.value);
const draft = this.sessionStorageService.getItem('draft');

Notes and Caveats

  • ix-tlc-auth folders currently exist in source tree but are empty and are not exported in public_api.ts.
  • IxDarkService requires your app theme to react to body.light / body.dark classes.
  • ScrollButtonService methods assume target elements exist; pass valid IDs.
  • ScrollBarProgressComponent uses an internal element ID (progressBar), so multiple instances on one page can conflict.
  • SafePipe intentionally bypasses sanitization; use only with trusted data.

License

MIT