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

@lumston/ds-angular

v0.1.3

Published

Lumston Design System for Angular applications

Readme

@lumston/ds-angular

Angular component library for the Lumston Design System.

Requirements

  • Angular 17 or later
  • @angular/common, @angular/core, @angular/platform-browser

Installation

npm install @lumston/ds-angular

Default font

The library uses Nunito as its default font family via the --ls-font-family token. Nunito is not bundled — you must load it yourself.

Option 1 — Google Fonts (recommended):

Add the following <link> tags inside <head> in your index.html:

<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
  href="https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap"
  rel="stylesheet"
/>

Option 2 — Self-hosted:

Download the font files and add a @font-face declaration in your global stylesheet before the library import:

@font-face {
  font-family: 'Nunito';
  src: url('/assets/fonts/Nunito-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@import '@lumston/ds-angular/styles';

Override the font:

To use a different font, override the token after importing the library styles:

@import '@lumston/ds-angular/styles';

:root {
  --ls-font-family: 'Inter', sans-serif;
}

Dark theme

All components support dark mode out of the box. Dark styles activate when the dark class is present on <body>.

How it works

The library uses a CSS class strategy — no media query is required. Components listen for body.dark and switch their color tokens automatically:

/* Light mode — default */
.ls-header { background-color: var(--ls-header-bg, #ffffff); }

/* Dark mode — activated by body.dark */
body.dark .ls-header { background-color: var(--ls-header-bg-dark, #0e1726); }

Enabling dark mode

Toggle the dark class on <body> from your Angular service:

// theme.service.ts
export class ThemeService {
  setDark(enabled: boolean): void {
    document.body.classList.toggle('dark', enabled);
  }
}

Supporting light, dark, and system preferences

// theme.service.ts
import { Injectable } from '@angular/core';

type Theme = 'light' | 'dark' | 'system';

@Injectable({ providedIn: 'root' })
export class ThemeService {
  apply(theme: Theme): void {
    if (theme === 'dark') {
      document.body.classList.add('dark');
    } else if (theme === 'light') {
      document.body.classList.remove('dark');
    } else {
      const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
      document.body.classList.toggle('dark', prefersDark);
    }
  }

  watchSystem(): void {
    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
      document.body.classList.toggle('dark', e.matches);
    });
  }
}

Persisting the user preference

// On app initialization
const saved = localStorage.getItem('theme') as Theme | null;
this.themeService.apply(saved ?? 'system');

Overriding dark mode tokens

All dark variants are CSS custom properties. Override them after the library import:

@import '@lumston/ds-angular/styles';

body.dark {
  --ls-header-bg-dark: #1a1a2e;
  --ls-sidebar-bg-dark: #16213e;
  --ls-color-primary: #818cf8;
}

Components with dark mode support

| Component | Dark tokens | |---|---| | Header | --ls-header-bg-dark, --ls-header-shadow-dark | | Sidebar | --ls-sidebar-bg-dark, --ls-sidebar-header-bg-dark, --ls-sidebar-icon-color-dark, --ls-sidebar-sublink-indicator-color-dark | | Table | --ls-table-border-color, --ls-table-header-bg, --ls-table-header-color, --ls-table-cell-color, --ls-table-stripe-bg, --ls-table-hover-bg | | Stepper | --ls-stepper-connector-color, --ls-stepper-bg, --ls-stepper-text-color | | Drag | --ls-drag-ghost-bg, --ls-drag-drop-indicator-color | | Button (dark color) | --ls-color-dark-dm |

All dark token overrides must be placed inside a body.dark { } block, after the library stylesheet import.


Peer dependencies by component

Some components require additional packages that are not bundled with the library.

PhoneInputComponent (ls-phone-input)

Requires flag-icons for country flag rendering.

npm install flag-icons

Register the stylesheet once in your application, before the library styles:

Option 1 — global CSS file (styles.css):

@import 'flag-icons/css/flag-icons.min.css';
@import '@lumston/ds-angular/styles';

Option 2 — angular.json under styles:

"styles": [
  "node_modules/flag-icons/css/flag-icons.min.css",
  "node_modules/@lumston/ds-angular/styles/index.css",
  "src/styles.css"
]

flag-icons must be loaded before any component that uses flag sprites, so place it above the library stylesheet.


Importing styles

Add the library stylesheet once in your application's global CSS file (e.g. styles.css):

@import '@lumston/ds-angular/styles';

Or in angular.json under styles:

"styles": [
  "node_modules/@lumston/ds-angular/styles/index.css",
  "src/styles.css"
]

The stylesheet includes all design tokens (CSS custom properties), base reset rules, and component styles. It must be loaded before your application styles so that overrides work correctly.


Using components

All components are standalone. Import them directly in your Angular component or module:

import { ButtonComponent } from '@lumston/ds-angular';

@Component({
  standalone: true,
  imports: [ButtonComponent],
  template: `<ls-button variant="filled">Save</ls-button>`,
})
export class MyComponent {}

Overriding design tokens

The library exposes its entire palette and configuration as CSS custom properties on :root. You can override any token by redefining it after the library import in your global stylesheet.

Override globally

/* styles.css */
@import '@lumston/ds-angular/styles';

:root {
  /* Brand colors */
  --ls-color-primary: #ff6b35;
  --ls-color-primary-light: #fff0eb;
  --ls-color-primary-dark-light: rgba(255, 107, 53, 0.15);

  /* Typography */
  --ls-font-family: 'Inter', sans-serif;

  /* Border radius */
  --ls-border-radius-md: 0.25rem;
  --ls-border-radius-lg: 0.5rem;
  --ls-border-radius-full: 9999px;
}

Override per theme (scoped)

You can scope overrides to a CSS class to support multiple themes simultaneously:

.theme-corporate {
  --ls-color-primary: #1a3c6e;
  --ls-color-primary-light: #e8eef7;
  --ls-color-primary-dark-light: rgba(26, 60, 110, 0.15);
}

.theme-dark {
  --ls-color-primary: #818cf8;
  --ls-color-primary-light: #1e1b4b;
  --ls-color-primary-dark-light: rgba(129, 140, 248, 0.15);
}

Apply the class to a wrapper element in your template:

<div class="theme-corporate">
  <ls-button variant="filled">Submit</ls-button>
</div>

Available tokens

Colors

| Token | Default | Description | |---|---|---| | --ls-color-primary | #4361ee | Primary brand color | | --ls-color-primary-light | #eaf1ff | Primary tint background | | --ls-color-primary-dark-light | rgba(67,97,238,.15) | Primary overlay | | --ls-color-secondary | #805dca | Secondary brand color | | --ls-color-secondary-light | #ebe4f7 | Secondary tint background | | --ls-color-secondary-dark-light | rgba(128,93,202,.15) | Secondary overlay | | --ls-color-success | #00ab55 | Success state | | --ls-color-success-light | #ddf5f0 | Success tint background | | --ls-color-success-dark-light | rgba(0,171,85,.15) | Success overlay | | --ls-color-danger | #e7515a | Danger / destructive state | | --ls-color-danger-light | #fff5f5 | Danger tint background | | --ls-color-danger-dark-light | rgba(231,81,90,.15) | Danger overlay | | --ls-color-error | #e7515a | Error state (alias of danger) | | --ls-color-error-light | #fff5f5 | Error tint background | | --ls-color-error-dark-light | rgba(231,81,90,.15) | Error overlay | | --ls-color-warning | #e2a03f | Warning state | | --ls-color-warning-light | #fff9ed | Warning tint background | | --ls-color-warning-dark-light | rgba(226,160,63,.15) | Warning overlay | | --ls-color-info | #2196f3 | Informational state | | --ls-color-info-light | #e7f7ff | Info tint background | | --ls-color-info-dark-light | rgba(33,150,243,.15) | Info overlay | | --ls-color-dark | #3b3f5c | Dark neutral | | --ls-color-dark-dm | #8892a4 | Dark neutral adapted for dark mode (higher contrast on dark backgrounds) | | --ls-color-dark-light | #eaeaec | Dark tint background | | --ls-color-dark-dark-light | rgba(59,63,92,.15) | Dark overlay | | --ls-color-black | #0e1726 | Near-black | | --ls-color-black-light | #e3e4eb | Near-black tint | | --ls-color-black-dark-light | rgba(14,23,38,.15) | Near-black overlay | | --ls-color-white | #ffffff | White | | --ls-color-white-light | #e0e6ed | White variant | | --ls-color-white-dark | #888ea8 | White muted | | --ls-gradient-start | #ef1262 | Gradient start color | | --ls-gradient-end | #4361ee | Gradient end color |

Typography

| Token | Default | Description | |---|---|---| | --ls-font-family | 'Nunito', sans-serif | Base font family |

Transitions

| Token | Default | Description | |---|---|---| | --ls-transition-duration | 300ms | Default transition duration | | --ls-transition-accordion-duration | 400ms | Accordion expand/collapse duration |

Border radius

| Token | Default | Description | |---|---|---| | --ls-border-radius-md | 0.375rem | Medium border radius | | --ls-border-radius-lg | 0.5rem | Large border radius | | --ls-border-radius-full | 9999px | Pill / full border radius |

Inputs

| Token | Default | Description | |---|---|---| | --ls-color-input-border | #d0d2d6 | Input border color | | --ls-color-input-label | #3b3f5c | Input label color | | --ls-color-input-bg-filled | #f4f4f4 | Filled input background | | --ls-color-helper-text | #888ea8 | Helper / hint text color | | --ls-color-text-placeholder | #adb5bd | Placeholder text color |

Header

| Token | Default | Description | |---|---|---| | --ls-header-height | 56px | Minimum height of the header | | --ls-header-z-index | 40 | Stack order of the header | | --ls-header-padding-x | 1.25rem | Horizontal padding | | --ls-header-bg | #ffffff | Background color (light mode) | | --ls-header-bg-dark | #0e1726 | Background color (dark mode) | | --ls-header-shadow | 0 1px 3px 0 rgba(0,0,0,.08) | Box shadow (light mode) | | --ls-header-shadow-dark | 0 1px 3px 0 rgba(0,0,0,.3) | Box shadow (dark mode) | | --ls-header-gap | 0.375rem | Gap between header end slot items |

Sidebar

| Token | Default | Description | |---|---|---| | --ls-sidebar-width | 260px | Sidebar width | | --ls-sidebar-bg | #ffffff | Background color (light mode) | | --ls-sidebar-bg-dark | #0e1726 | Background color (dark mode) | | --ls-sidebar-z-index | 50 | Stack order of the sidebar | | --ls-sidebar-item-color | #506690 | Nav item text color | | --ls-sidebar-item-active-color | #4361ee | Active nav item text color | | --ls-sidebar-item-active-bg | rgba(67,97,238,.12) | Active nav item background | | --ls-sidebar-item-hover-color | #4361ee | Nav item text color on hover | | --ls-sidebar-item-hover-bg | rgba(0,0,0,.05) | Nav item background on hover | | --ls-sidebar-icon-color | #506690 | Icon color | | --ls-sidebar-icon-color-dark | #506690 | Icon color (dark mode) | | --ls-sidebar-header-bg | rgba(255,255,255,.3) | Section header background | | --ls-sidebar-header-bg-dark | rgba(0,0,0,.08) | Section header background (dark mode) | | --ls-sidebar-header-color | #888ea8 | Section header text color | | --ls-sidebar-sublink-indicator-color | #bfc9d4 | Sub-item connector line color | | --ls-sidebar-sublink-indicator-color-dark | #3b3f5c | Sub-item connector line color (dark mode) | | --ls-sidebar-head-padding | 0.75rem 1rem | Sidebar head area padding | | --ls-sidebar-head-height | 4rem | Sidebar head area height | | --ls-sidebar-close-color | #506690 | Close button icon color | | --ls-sidebar-close-hover-bg | rgba(0,0,0,.05) | Close button background on hover | | --ls-sidebar-close-hover-color | #4361ee | Close button icon color on hover |

Modal

| Token | Default | Description | |---|---|---| | --ls-modal-z-index | 1000 | Modal z-index | | --ls-modal-backdrop-bg | rgba(0,0,0,.5) | Modal backdrop color |

Drawer

| Token | Default | Description | |---|---|---| | --ls-drawer-z-index | 1200 | Drawer z-index | | --ls-drawer-backdrop-bg | rgba(0,0,0,.5) | Drawer backdrop color | | --ls-drawer-width | 320px | Drawer width (left/right) | | --ls-drawer-height | 280px | Drawer height (top/bottom) |

Menu

| Token | Default | Description | |---|---|---| | --ls-menu-z-index | 1001 | Dropdown menu z-index |

Select

| Token | Default | Description | |---|---|---| | --ls-select-bg | #ffffff | Select panel background | | --ls-select-border | #e0e6ed | Select panel border color | | --ls-select-option-hover | #f1f2f3 | Option background on hover |

Tab

| Token | Default | Description | |---|---|---| | --ls-tab-border-color | var(--ls-color-white-light) | Tab underline / border color |

Table

| Token | Default | Description | |---|---|---| | --ls-table-border-color | rgba(224,230,237,.4) | Table border color | | --ls-table-header-bg | #f6f8fa | Table header background | | --ls-table-header-color | #3b3f5c | Table header text color | | --ls-table-cell-color | #515365 | Table cell text color | | --ls-table-stripe-bg | rgba(224,230,237,.2) | Striped row background | | --ls-table-hover-bg | rgba(224,230,237,.2) | Row background on hover |

Date picker

| Token | Default | Description | |---|---|---| | --ls-color-dp-selected-bg | #4361ee | Selected date background | | --ls-color-dp-range-bg | #eaf1ff | Date range highlight background | | --ls-color-dp-cell-hover-bg | #f0f4ff | Date cell background on hover | | --ls-color-dp-disabled-text | #888ea8 | Disabled date text color |

Stepper

| Token | Default | Description | |---|---|---| | --ls-stepper-connector-color | #e0e6ed | Connector line color | | --ls-stepper-active-color | var(--ls-color-primary) | Active step indicator color | | --ls-stepper-complete-color | var(--ls-color-primary) | Completed step indicator color | | --ls-stepper-error-color | var(--ls-color-danger) | Error step indicator color | | --ls-stepper-disabled-opacity | 0.5 | Opacity for disabled steps | | --ls-stepper-bg | #ffffff | Step indicator background | | --ls-stepper-text-color | #3b3f5c | Step label text color | | --ls-stepper-icon-size | 2rem | Step indicator icon size | | --ls-stepper-transition-duration | var(--ls-transition-duration) | Step transition duration |

Color picker

| Token | Default | Description | |---|---|---| | --ls-cp-gap | 8px | Gap between color swatches | | --ls-cp-swatch-size | 28px | Swatch size (default) | | --ls-cp-swatch-size-sm | 20px | Swatch size (small) |

Drag

| Token | Default | Description | |---|---|---| | --ls-drag-drop-indicator-color | var(--ls-color-primary) | Drop zone indicator color | | --ls-drag-disabled-opacity | 0.5 | Opacity when drag is disabled | | --ls-drag-item-dragging-opacity | 0.4 | Opacity of the item being dragged | | --ls-drag-ghost-bg | #ffffff | Drag ghost element background |

Map

| Token | Default | Description | |---|---|---| | --ls-map-border-radius | var(--ls-border-radius-md) | Map container border radius | | --ls-map-disabled-opacity | 0.6 | Map opacity when disabled |