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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@su-labs/theme

v1.0.3

Published

A robust and reactive Angular service for managing application themes. It provides a full-featured solution that supports dynamic switching, user preference persistence, and automatic system theme detection.

Readme

SuThemeService

A robust and reactive Angular service for managing application themes. It provides a full-featured solution that supports dynamic switching, user preference persistence, and automatic system theme detection.

Features

  • Reactive State: Uses Angular signals for efficient, reactive theme management.
  • System Theme Integration: Automatically follows the user's system theme preference (prefers-color-scheme).
  • Persistence: Remembers the user's last-selected theme using localStorage.
  • Configurable: Customizable with a configuration object for storage keys, CSS variable prefixes, and default themes.
  • Programmatic Control: Simple public API to set, get, and track the active theme.

Available Themes

The service currently supports the following theme names by default:

  • light
  • dark
  • contrast
  • custom
  • system (follows OS preference)

You can provide custom variables for any of these themes via the themes property in SuThemeConfig.

Usage

The SuThemeService must be initialized at application startup to load its configuration and initial theme.

Example 1: Global Initialization with provideAppInitializer

// main.ts or app.config.ts
import { provideAppInitializer, inject } from '@angular/core';
import { SuThemeService, SuThemeConfig } from '@su-labs/theme';

const myThemeConfig: SuThemeConfig = {
  // Optional: Set a default theme if none is saved
  defaultTheme: 'dark',
  // Optional: Provide custom CSS variables for any theme
  themes: {
    dark: {
      color: '#333',
      background: '#eee',
      'main-accent': '#007bff',
    },
  },
};

export const appConfig = {
  providers: [
    provideAppInitializer(() => {
      const themeService = inject(SuThemeService);
      themeService.init(myThemeConfig);
    }),
  ],
};

✅ This ensures the theme is loaded and applied before the application renders. The SuThemeService handles all the logic internally, including loading from localStorage and applying the initial theme.

Example 2: Using the Theme in a Component

Your service automatically applies CSS variables to the :root element. Your application stylesheets can use these variables, and the service will handle updating their values when the theme changes.


/* styles.css */
/* Use the CSS variables in your stylesheet */
body {
  color: var(--su-theme-color);
  background-color: var(--su-theme-background);
}

h1 {
  color: var(--su-theme-main-accent);
}

The service dynamically updates these variables based on the active theme, applying a combination of its internal defaults and any custom overrides you provide in the configuration.

Example 3: Dynamic Theme Switching

Use the setTheme() method to switch themes and the theme signal to read the current state.


import { Component, inject } from '@angular/core';
import { SuThemeService, SuThemeName } from '@su-labs/theme';

@Component({
  selector: 'app-theme-switcher',
  standalone: true,
  imports: [],
  template: `
    <h1>Dynamic Theme Switching</h1>
    <p>Current Theme: {{ themeService.theme() }}</p>
    <button (click)="setTheme('light')">Light</button>
    <button (click)="setTheme('dark')">Dark</button>
    <button (click)="setTheme('system')">System</button>
  `,
})
export class ThemeSwitcherComponent {
  // Use the service directly in the template
  public readonly themeService = inject(SuThemeService);

  setTheme(themeName: SuThemeName) {
    this.themeService.setTheme(themeName);
  }
}

✅ This correctly shows how to use your service's public API to switch between themes. The service handles the underlying logic, including persistence and CSS variable application.

Configuration Options

The service can be configured to fit your application's needs.

| Option | Description | Default Value | |--------------------|---------------------------------------------------------------|------------------| | storageKey | The key used to persist the selected theme in localStorage. | 'su:theme' | | cssVarPrefix | The prefix for all CSS variables managed by the service. | '--su-theme-' | | defaultTheme | The theme to use if no preference is saved in localStorage. | 'system' | | themes | An object with custom CSS variable overrides for each theme. | undefined |

Notes

  • The service safely handles properties and ignores null or undefined values, preventing issues like prototype pollution.

  • Works seamlessly with standalone components and reactive setups thanks to its signal-based API.

  • Persistence is handled automatically: The service saves the user's preference to localStorage when you call setTheme(..., true). On initialization, it automatically restores this saved preference. You do not need to add this logic in your components.

Contributing

If you find any bugs or have feature requests, please open an issue or submit a pull request on our GitHub repository.

To contribute code, please ensure your changes include unit tests to maintain code quality. Please see the main repository's README.md for details on the monorepo structure.

License

This project is licensed under the MIT License. See the LICENSE file for details.