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

@dmaster/ui

v0.10.0

Published

Modern, premium Angular UI components. Standalone, signals-based, themeable via CSS variables.

Readme

@dmaster/ui

Premium Angular UI components. Standalone, signals-based, zoneless-ready, and fully themeable via CSS custom properties — with a clean, flat, pill-radius design language.

npm version npm downloads CI license Angular WCAG 2.1 AA docs

45 components · 3 languages (EN/ES/FR) in the docs · 0 third-party UI dependencies · 790+ tests

→ Browse every component live at dmasterui.com/components — each tile is the real, interactive component, not a screenshot.

▶ Try it now on StackBlitz — a minimal zoneless Angular 20 app already wired up with the library; no install needed. (Source: examples/starter.)


Why @dmaster/ui?

  • Modern Angular APIinput() / output() / model() signals, standalone components, no NgModules, no decorators
  • Zoneless-ready — designed for provideZonelessChangeDetection() from day one
  • Flat, pill-radius design language — flat colors, pill radii (border-radius: 9999px by default), elastic press scale, color × variant token system
  • Deeply themeable — light / dark / auto via data-dm-theme; every visual decision is a --dm-* CSS custom property you can override
  • Accessible by default — ARIA attributes on host elements, :focus-visible focus rings, touch targets ≥ 44px, prefers-reduced-motion support
  • CDK-powered overlays — tooltip, popover, menu, dialog, drawer, toast and command palette built on @angular/cdk, no third-party overlay dependencies
  • Three density levelscompact, comfortable, spacious via data-dm-density
  • Pay only for what you import — fully tree-shakeable: a button costs ~3.8 kB gzip, a card ~1.3 kB, the entire 45-component library ~92 kB (see Bundle size)

Installation

ng add @dmaster/ui

ng add installs @angular/cdk, registers the CDK overlay styles and wires the global stylesheet for you. Prefer manual setup?

npm install @dmaster/ui @angular/cdk

Peer dependencies: @angular/core, @angular/common, @angular/forms, @angular/cdk (^20) and rxjs


Quick start

1. Add the global styles in styles.scss:

@use '@dmaster/ui/styles/index';

No Sass in your build? Use the precompiled CSS instead — add it to the styles array in angular.json:

"styles": ["node_modules/@dmaster/ui/styles/dmaster-ui.css", "src/styles.css"]

2. Add CDK overlay styles in angular.json (required for tooltip, popover, menu, dialog, drawer, toast, command):

"styles": ["node_modules/@angular/cdk/overlay-prebuilt.css", "src/styles.scss"]

3. Register the provider (optional — sets default theme and density):

import { provideDmasterUI } from '@dmaster/ui';

bootstrapApplication(AppComponent, {
  providers: [provideDmasterUI({ theme: 'auto', density: 'comfortable' })],
});

4. Import and use any component:

import { DmButtonComponent, DmBadgeComponent } from '@dmaster/ui';

@Component({
  imports: [DmButtonComponent, DmBadgeComponent],
  template: `
    <dm-button color="primary" variant="solid">Save</dm-button>
    <dm-badge color="success" variant="flat">Active</dm-badge>
  `,
})
export class MyComponent {}

Engineering & quality gates

Every pull request clears the same automated bar before it can merge — these run on CI, not on trust:

  • Accessibility is a gate, not a claimaxe-core (WCAG 2.1 A + AA) scans every prerendered docs page in both light and dark themes, plus every opened overlay. Zero violations required. (details)
  • Visual regression — every route is screenshotted in light + dark and pixel-diffed against committed baselines, inside a pinned Playwright container so rendering is deterministic across machines and CI.
  • Real-consumer integration — the library is packed with npm pack and installed into a separate, isolated Angular app (examples/starter) that builds against the published tarball — catching exports-map, peer-dependency and type-resolution breakage the monorepo (whose paths point at source) never sees.
  • SSR safety — the docs site is fully statically prerendered on every build, so any component that reaches for a browser-only global fails CI immediately.
  • Package hygienepublint validates the published layout on every PR; releases go to npm with signed provenance (Sigstore attestation).
  • Tree-shake audit — per-component gzip cost is measured through the exact linker + minify pipeline the Angular CLI applies to published libraries, not a naive bundle. Reproducible with npm run size. (bundle table)

The four CI jobs — build/test/lint/publint, integration, a11y and visual — run in parallel and must all be green to merge.


Components

45 components across 8 categories. Every row links to its live docs page (playground, API table, a11y notes).

Primitives

| Component | Selector | Highlights | | ------------------------------------------------------ | ------------- | -------------------------------------------------------------------------- | | Skeleton | dm-skeleton | Shimmer placeholder, wave animation | | Spinner | dm-spinner | Animated indicator, 3 sizes | | Badge / Chip | dm-badge | 7 variants · 6 colors · dot, shadow, bordered | | Avatar | dm-avatar | Image + fallback initials, 5 sizes | | Keyboard Key | dm-kbd | Named keys resolve to their symbol (⌘, ⇧…), content projection | | Icon | dm-icon | Font ligature, registered SVG, or projected <svg> — 3 modes, 1 primitive |

Layout

| Component | Selector | Highlights | | ------------------------------------------------------- | -------------- | --------------------------------------------- | | Card | dm-card | Container queries, shadow variants | | Accordion | dm-accordion | Animated, single/multiple open, keyboard nav | | Divider | dm-divider | Horizontal/vertical, optional projected label |

Feedback

| Component | Selector | Highlights | | ----------------------------------------------------- | ------------- | -------------------------------------------------------- | | Progress | dm-progress | Determinate/indeterminate, striped, value label | | Alert | dm-alert | Color × variant, semantic icon, dismissible, action slot |

Buttons

| Component | Selector | Highlights | | ------------------------------------------------------------- | ----------------- | --------------------------------------------------------------------------------- | | Button | dm-button | 7 variants · 6 colors · idle/loading/success/error states · live region | | Button Group | dm-button-group | Attached bar with 1px seams, group-level color/variant/size cascade, split-button | | Copy Button | dm-copy-button | Copies text with a copy→check flip · dmCopyToClipboard directive · SSR-safe |

Forms

| Component | Selector | Highlights | | ------------------------------------------------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Switch | dm-switch | ControlValueAccessor, 3 sizes | | Checkbox | dm-checkbox | ControlValueAccessor, indeterminate state | | Radio Group | dm-radio-group + dm-radio | ControlValueAccessor, horizontal/vertical | | Select | dm-select | Single or multiple (chips), inline filter, groups, select-all, CVA — or server-driven: loadFn pages via rxResource, infinite scroll / load-more, debounced server search | | Autocomplete | dm-autocomplete | Free-text input with filtered suggestions, optionSelected event, keyboard nav, CVA | | Search Field | dm-search-field | Leading icon, clear button, Escape clears, Enter submits | | Date Picker | dm-date-picker | Day→month→year calendar, Intl-only (no date library), reactive locale (DM_DATE_LOCALE) | | Color Picker | dm-color-picker | Saturation/hue/alpha area, editable hex, swatches | | Slider | dm-slider | Pointer drag + full keyboard map, value bubble, marks | | Rating | dm-rating | Star rating, half stars, readonly fractional average, custom glyph, role="slider", CVA | | Number Input | dm-number-input | Spinbutton with ± controls, keyboard map, clamp/precision, Intl formatting, CVA | | OTP Input | dm-otp | One-time-code / PIN cells, 4 surface variants, group separators, paste distribution, CVA | | Toggle Group | dm-toggle-group + dm-toggle | Segmented control, single/multiple, radiogroup or aria-pressed, roving keyboard, CVA | | File Upload | dm-file-upload | Drag-and-drop dropzone, thumbnails, per-file progress, accept/size/count validation | | Form Field | dm-form-field + dmInput | Label, hint, error, wraps any native input/textarea/select | | Error | dm-error | Validation line, role="alert", no built-in icon (project your own) |

Navigation

| Component | Selector | Highlights | | ----------------------------------------------------------- | --------------------------------------- | ------------------------------------------------------ | | Breadcrumbs | dm-breadcrumbs + dm-breadcrumb-item | Router-agnostic, collapsible | | Tabs | dm-tabs + dm-tab + dm-tab-panel | 5 variants, sliding indicator, full-width, scroll-fade | | Pagination | dm-pagination | Windowed pager, two-way page binding | | Stepper | dm-stepper + dm-step | Horizontal/vertical wizard, linear mode, step states |

Data Display

| Component | Selector | Highlights | | ----------------------------------------------------------- | ---------------------------------- | ---------------------------------------------------------------- | | Table | dm-table | Search → sort → paginate pipeline, row selection, virtual scroll | | Tree | dm-tree | WAI-ARIA tree view, roving focus, single/multiple selection | | Timeline | dm-timeline + dm-timeline-item | Vertical/horizontal events, states, custom markers, alternate | | Empty state | dm-empty-state | Icon + title + description + actions, custom icon slot, 3 sizes |

Overlays (require CDK)

| Component | Selector / Service | Highlights | | --------------------------------------------------- | --------------------- | ------------------------------------------------- | | Tooltip | dmTooltip directive | 12 placements, open/close delay | | Popover | dm-popover | Rich floating panel, arrow follows the real flip | | Menu | dm-menu | WAI-ARIA menu, FocusKeyManager, typeahead | | Dialog | DmDialogService | Typed data, typed return, backdrop click to close | | Drawer | DmDrawerService | Slide-in panel over cdk/dialog | | Toast | DmToastService | Queued notifications, signal-driven state | | Command | dm-command | ⌘K command palette, fuzzy filter |


Theming

Everything is a CSS custom property — no Sass required to consume, no Tailwind lock-in, no runtime engine. Theme state lives on <html> attributes (data-dm-theme, data-dm-density), so it is SSR-safe and flips without a flash. Start from a prebuilt theme, then customize across four levels — from a one-line accent swap to a full custom theme.

Prebuilt themes

Nine curated palettes ship as tiny CSS files. Pick one at install — no code:

ng add @dmaster/ui                 # prompts for a theme
ng add @dmaster/ui --theme=ocean   # or pass it directly

…or add it to angular.json, right after the base styles:

"styles": [
  "node_modules/@angular/cdk/overlay-prebuilt.css",
  "node_modules/@dmaster/ui/styles/dmaster-ui.css",
  "node_modules/@dmaster/ui/themes/ocean.css" // ← recolors the whole app
]

Available: ocean · cobalt · iris · grape · rose · ember · sunset · forest · slate (plus the built-in blue, which needs no file). Each recolors the brand in both light and dark — the light/dark toggle keeps working — and every label color is gated at WCAG AA.

Custom theme — ng generate

Want your own? Scaffold one from a seed color — it writes the CSS (with every knob commented in) and wires it into angular.json:

ng generate @dmaster/ui:theme brand --primary=#e11d48
# switchable named theme instead of a global recolor:
ng generate @dmaster/ui:theme midnight --named --scheme=dark

The default is a global recolor (:root + [data-dm-theme='dark'], so light/dark keeps working). --named emits a [data-dm-theme='<name>'] block and prints the provideDmasterUI line to register it. Or just override a token by hand:

1. Override a token — the whole family cascades

Every visual decision is a --dm-* token, and each semantic color's family is derived from its base: the soft fill (-subtle) via color-mix(), and the hover shade (-hover) and tinted-text shade (-text) via OKLCH relative color syntax at a fixed, calibrated lightness. Changing one base color re-themes everything that uses it — fills, hovers, tint text, rings:

:root {
  --dm-primary: #7c3aed; /* hover, -subtle, -text and rings all re-derive */
  --dm-radius-full: 0.5rem; /* rectangular controls instead of pills */
  --dm-duration-base: 100ms; /* faster animations everywhere */
}

Because the derived shades sit at a fixed OKLCH lightness (and WCAG contrast is dominated by lightness), the derived text keeps its ≥4.5:1 ratio over its tint for arbitrary brand colors — a mid-tone orange, a teal, a crimson all come out AA out of the box.

Only -fg (the label over solid fills, usually white) stays explicit: if your brand color is very light, also set --dm-<color>-fg to a dark value — or register the palette as a named theme (below).

2. Light / dark / auto

provideDmasterUI({ theme: 'auto' }); // follows prefers-color-scheme, tracks OS live
inject(ThemeService).setTheme('dark'); // or 'light' | 'auto'
inject(ThemeService).toggle(); // flip the active scheme

3. Custom named themes

Register any number of named themes and switch between them at runtime. The name is stamped on <html data-dm-theme="…">; you author the matching CSS block:

provideDmasterUI({
  themes: {
    midnight: { scheme: 'dark', label: 'Midnight' },
    sand: { scheme: 'light', label: 'Sand' },
  },
});
[data-dm-theme='midnight'] {
  color-scheme: dark;
  --dm-bg: #0a0a12;
  --dm-primary: #8b5cf6;
  /* …only the tokens you want to change; the rest inherit the dark defaults */
}
const themes = inject(ThemeService);
themes.setTheme('midnight'); // apply
themes.themes(); // [{ name, scheme, label }] — build a picker
themes.scheme(); // 'dark' — the active theme's base scheme

4. Restyle a single component or a subtree

Because tokens are plain CSS custom properties, scoping an override to an element or a subtree re-themes only what's inside it — no global change, no component API needed:

/* every switch in the app turns green — components read the semantic tokens */
dm-switch {
  --dm-primary: var(--dm-success);
}

/* just this section and everything under it */
.pricing {
  --dm-primary: #0ea5e9;
  --dm-radius-lg: 0;
}

On top of that, every component exposes its own --dm-<component>-* design tokens (~300 across the library) for the decisions the semantic set doesn't cover — surface, radius, heights, part-specific knobs:

/* squarer, taller buttons app-wide — without touching the global radius scale */
:root {
  --dm-button-radius: 0.5rem;
  --dm-button-height: 3rem;
}

/* or one part of one component */
.data-panel {
  --dm-table-header-bg: var(--dm-bg-muted);
  --dm-switch-track-bg-checked: var(--dm-success);
}

Each component folder's README.md documents its tokens in a Design tokens table.

Overlays (tooltip, menu, dialog, drawer, toast, select, command) render at the document root via the Angular CDK, so a global override or a named theme (both applied on <html>) reaches them, but a subtree override does not. For a scoped theme inside a dialog or drawer, pass your theme class via panelClass:

this.dialog.open(CheckoutComponent, { panelClass: 'brand-theme' });

Density

Three density scales adjust control heights and spacing globally:

provideDmasterUI({ density: 'compact' }); // 'compact' | 'comfortable' | 'spacious'

SSR / prerendering

The library is server-safe: no component or service touches window, localStorage or browser-only APIs at construction time — matchMedia is feature-detected through Angular's DOCUMENT, and overlays only open on user interaction. The docs site itself is fully statically prerendered with @angular/ssr as a permanent smoke test.


Accessibility

Accessibility isn't a checkbox here — it's a gate. Every prerendered docs page (which exercises every component and variant) is scanned with axe-core for WCAG 2.1 Level A + AA compliance, in both light and dark themes, plus every overlay opened — and the suite must be green on every pull request.

Concretely, components ship with: semantic roles and ARIA wired on the host, full keyboard support (roving focus, typeahead, focus traps in overlays), visible :focus-visible rings, ≥44px touch targets, prefers-reduced-motion honored, and a color system where every text/fill pair — including the vivid flat / light / faded variants — clears the 4.5:1 contrast ratio in both themes. Icon-only dm-buttons take an ariaLabel; form controls forward validity through aria-describedby to dm-error.

Run it yourself against the prerendered build:

npm run build:app && npm run test:a11y

Bundle size

Fully tree-shakeable — your app only pays for the components it imports. Measured with the same pipeline the Angular CLI applies to published libraries (linker + minify + gzip, @angular/* and rxjs external):

| Import | Gzip | | ------------------------- | -------- | | DmCardComponent | ~1.3 kB | | DmBadgeComponent | ~1.8 kB | | DmButtonComponent | ~3.8 kB | | DmSelectComponent | ~10.1 kB | | DmTableComponent | ~11.8 kB | | Entire library (45) | ~92 kB | | Global CSS (tokens+reset) | ~4.7 kB |

Reproduce the full per-component table from the repo with npm run size.


Who is this for?

@dmaster/ui is a good fit for:

  • SaaS dashboards — tables, forms, overlays, and toasts out of the box
  • Admin panels — dense layouts with consistent design tokens and three density modes
  • Component-library starters — use as a base or reference architecture for signals-based Angular components
  • Teams migrating to zoneless Angular — built for provideZonelessChangeDetection() from day one

Compared to other Angular libraries

There's no shortage of component libraries in the Angular ecosystem. Here's how @dmaster/ui differs from the ones you're most likely evaluating alongside it — read this as "different tradeoffs," not "objectively better":

| | @dmaster/ui | Angular Material | PrimeNG | Taiga UI | Spartan · ng-primitives | | ------------------- | ---------------------------------------------------------------- | -------------------------------------------------- | -------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------ | | API style | input()/output()/model() signals, standalone, no NgModules | Mix of legacy + newer APIs, NgModule-based | NgModule + standalone hybrid | Signals, standalone | Signals, standalone | | What you get | Pre-styled components, own flat/pill design language | Pre-styled components (Material Design) | Pre-styled components, several theme presets | Pre-styled components, own design system | Unstyled primitives — copy-paste styled blocks you own, shadcn-style | | Theming | CSS custom properties only, no runtime engine | Sass theming API + Material 3 design tokens | Runtime theme switcher + design tokens | CSS custom properties | Tailwind-based, per-component | | Component count | 45 | Comprehensive Material Design set (CDK + Material) | Very large, kitchen-sink surface area | 130+ (their own count) | 55+ primitives (their own count) | | Zoneless | Built for it from day one | Supported | Supported | Supported | Supported | | Install model | ng add, then import & use | ng add, then import & use | Install & import | Install & import | CLI copies component source into your repo |

If you want a batteries-included, opinionated kit you install and start using immediately — that's @dmaster/ui, Angular Material, PrimeNG or Taiga UI, and the choice between them comes down to design language and API generation. If you want unstyled, accessible primitives you fully own the markup and CSS for, Spartan/ng-primitives is the better starting point.


Contributing

Issues and PRs are welcome on GitHub.


License

MIT © Diego Maestro