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

primus-angular-ui-legacy

v0.0.4

Published

Primus SaaS Angular UI modules and services (legacy Angular 16-20).

Readme

Primus SaaS Angular UI (Legacy)

Angular components and services for integrating Primus SaaS modules on Angular 16-20.

Install

npm install primus-angular-ui-legacy

Requirements

  • Angular 16.x, 17.x, 18.x, 19.x, or 20.x
  • RxJS 7.x or 8.x
  • Chart.js 4.x (for chart components)

Using Angular 21.x? Install primus-angular-ui instead.

Legacy vs Angular 21+ highlights

primus-angular-ui-legacy includes dashboard features that are not yet in the Angular 21+ package:

  • Dashboard layout slots and layout options (layout, sidebarWidth, stickyHeader, etc.)
  • Dashboard grid breakpoints, gaps, and primus-grid-item spans
  • Data table template columns (primusColumn) and pagination (paginated, pageSize)
  • Chart components (primus-line-chart, primus-bar-chart, primus-pie-chart, primus-area-chart, primus-sparkline)
  • Activity feed (primus-activity-feed)

For a full feature comparison, see packages/docs/docs/frontend/getting-started/angular-legacy-matrix.md.

Module setup

import { PrimusUiModule } from 'primus-angular-ui-legacy';

@NgModule({
  imports: [
    PrimusUiModule.forRoot({
      apiBaseUrl: 'https://api.yourdomain.com',
      authToken: () => localStorage.getItem('primus_token')
    })
  ]
})
export class AppModule {}

Standalone setup

import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient } from '@angular/common/http';
import { providePrimus, providePrimusTheme } from 'primus-angular-ui-legacy';

bootstrapApplication(AppComponent, {
  providers: [
    provideHttpClient(),
    providePrimus({
      apiBaseUrl: 'https://api.yourdomain.com',
      authToken: () => localStorage.getItem('primus_token')
    }),
    providePrimusTheme({ defaultTheme: 'light' })
  ]
});

Standalone component imports

Import the Primus components you use into each standalone component:

import { Component } from '@angular/core';
import { PrimusLoginComponent } from 'primus-angular-ui-legacy';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [PrimusLoginComponent],
  template: `
    <primus-login
      [showEmailLogin]="true"
      [socialProviders]="['google']">
    </primus-login>
  `
})
export class AppComponent {}

You can also import PrimusUiModule into a standalone component if you prefer module-style grouping.

Components

<primus-ai-copilot></primus-ai-copilot>
<primus-login (loggedIn)="onLogin($event)"></primus-login>
<primus-user-profile></primus-user-profile>
<primus-notification-center></primus-notification-center>
<primus-notification-feed></primus-notification-feed>
<primus-feature-flag-toggle flagKey="beta-dashboard"></primus-feature-flag-toggle>
<primus-checkout-form></primus-checkout-form>
<primus-file-uploader></primus-file-uploader>
<primus-stats-card label="Monthly Revenue" [value]="'$142k'" delta="+12%" trend="up"></primus-stats-card>
<primus-dashboard></primus-dashboard>
<primus-dashboard-grid [columns]="3"></primus-dashboard-grid>
<primus-grid-item></primus-grid-item>
<primus-line-chart></primus-line-chart>
<primus-bar-chart></primus-bar-chart>
<primus-pie-chart></primus-pie-chart>
<primus-area-chart></primus-area-chart>
<primus-sparkline></primus-sparkline>
<primus-log-viewer></primus-log-viewer>
<primus-security-scan-panel></primus-security-scan-panel>
<primus-security-dashboard></primus-security-dashboard>
<primus-document-viewer templateId="invoice-template"></primus-document-viewer>
<primus-account-card></primus-account-card>
<primus-account-dashboard></primus-account-dashboard>
<primus-claim-tracker></primus-claim-tracker>
<primus-claim-status-tracker></primus-claim-status-tracker>
<primus-credit-card></primus-credit-card>
<primus-credit-score-card></primus-credit-score-card>
<primus-kyc-verification></primus-kyc-verification>
<primus-loan-calculator></primus-loan-calculator>
<primus-transaction-history></primus-transaction-history>
<primus-policy-card></primus-policy-card>
<primus-premium-calculator></primus-premium-calculator>
<primus-quote-comparison></primus-quote-comparison>
<primus-agent-directory></primus-agent-directory>
<primus-fraud-detection-dashboard></primus-fraud-detection-dashboard>
<primus-modal></primus-modal>
<primus-data-table></primus-data-table>
<primus-metric-card></primus-metric-card>
<primus-activity-feed></primus-activity-feed>
<primus-progress-ring></primus-progress-ring>
<primus-button></primus-button>
<primus-form-field></primus-form-field>
<primus-input></primus-input>
<primus-textarea></primus-textarea>
<primus-select></primus-select>
<primus-radio-group></primus-radio-group>
<primus-toggle></primus-toggle>
<primus-date-picker></primus-date-picker>
<primus-date-range-picker></primus-date-range-picker>
<primus-filter-bar></primus-filter-bar>
<primus-search></primus-search>
<primus-export-menu></primus-export-menu>
<primus-header></primus-header>
<primus-sidebar></primus-sidebar>
<primus-layout></primus-layout>
<primus-stepper></primus-stepper>
<primus-wizard></primus-wizard>
<primus-wizard-nav></primus-wizard-nav>
<primus-summary-card></primus-summary-card>
<primus-section></primus-section>
<primus-theme-toggle></primus-theme-toggle>

Primitives demo

A brand-agnostic composition example lives in:

  • examples/angular-primus-ui-primitives-demo/primus-primitives-demo.component.ts
  • examples/angular-primus-ui-primitives-demo/primus-primitives-demo.component.html
  • examples/angular-primus-ui-primitives-demo/primus-primitives-demo.component.css

Primitive APIs (new)

primus-form-field

  • Inputs: label, hint, error, required, forId
  • Slot: default

primus-input

  • Inputs: label, placeholder, type, name, id, value, disabled, required, hint, error
  • Output: valueChange

primus-select

  • Inputs: label, placeholder, options, value, name, id, disabled, required, hint, error, allowEmpty
  • Output: valueChange

primus-radio-group

  • Inputs: label, hint, error, required, name, options, value, disabled, inline
  • Output: valueChange

primus-toggle

  • Inputs: label, description, checked, disabled, hint, error
  • Output: checkedChange

primus-textarea

  • Inputs: label, placeholder, name, value, rows, maxLength, disabled, required, hint, error, id
  • Output: valueChange

primus-date-picker

  • Inputs: label, placeholder, name, value, min, max, disabled, required, hint, error, id
  • Output: valueChange

primus-stepper

  • Inputs: steps, activeStep, orientation, completedSteps, errorSteps, disabledSteps, clickable, linear
  • Output: stepSelected

primus-wizard

  • Inputs: title, subtitle
  • Slots: [wizard-steps], [wizard-content], [wizard-actions]

primus-wizard-nav

  • Inputs: backLabel, nextLabel, backDisabled, nextDisabled, showBack, showNext, align, backVariant, nextVariant
  • Outputs: back, next

primus-summary-card

  • Inputs: title, subtitle, actionLabel
  • Output: action
  • Slot: [summary-actions]

primus-section

  • Inputs: title, subtitle
  • Slot: [section-actions]

Theming

All primitives use CSS variables set by PrimusThemeService (for example --primus-text, --primus-border, --primus-accent, --primus-error). You can override them at the app root for custom themes.

For dashboard-specific theming and tokens, use providePrimusDashboard:

import { providePrimusDashboard } from 'primus-angular-ui-legacy';

bootstrapApplication(AppComponent, {
  providers: [
    providePrimusDashboard({
      theme: {
        colors: {
          primary: '#3b82f6',
          background: '#ffffff',
          surface: '#f8fafc',
          text: '#0f172a'
        },
        spacing: {
          sm: '8px',
          md: '16px',
          lg: '24px'
        },
        borderRadius: 8,
        darkMode: 'auto'
      }
    })
  ]
});

Validation patterns

  • Use the error input on form components to show error text and mark inputs as invalid.
  • Use the hint input for helper text when there is no error.

Accessibility notes

  • Stepper items are buttons and support keyboard focus.
  • Toggles expose role="switch" and aria-checked.
  • Inputs set aria-invalid when error is provided.

Component prop highlights (one by one)

Notification Center

<primus-notification-center
  [apiUrl]="'https://api.yourdomain.com'"
  theme="dark"
  [pollInterval]="3000"
></primus-notification-center>

Notification Feed

<primus-notification-feed
  [apiUrl]="'https://api.yourdomain.com'"
  [pollInterval]="3000"
  [userId]="'user-123'"
></primus-notification-feed>

Checkout Form

<primus-checkout-form
  [amount]="499"
  currency="USD"
  [apiUrl]="'https://api.yourdomain.com'"
  (onSuccess)="handlePayment($event)"
  (onError)="handlePaymentError($event)"
></primus-checkout-form>

Security Dashboard

<primus-security-dashboard
  [apiUrl]="'https://api.yourdomain.com'"
></primus-security-dashboard>

Document Viewer (Document Mode)

<primus-document-viewer
  [document]="doc"
  (onClose)="closeViewer()"
  (onDownload)="downloadDoc()"
></primus-document-viewer>

File Uploader

<primus-file-uploader
  [apiUrl]="'https://api.yourdomain.com'"
  (onUploadComplete)="onFileUploaded($event)"
></primus-file-uploader>

AI Copilot

<primus-ai-copilot
  title="AI Copilot"
  placeholder="Ask me anything..."
  mode="complete"
  [apiUrl]="'https://api.yourdomain.com'"
  (responded)="handleAi($event)"
></primus-ai-copilot>

Login

<primus-login
  title="Welcome Back"
  subtitle="Enter your credentials"
  [showEmailLogin]="true"
  [socialProviders]="['google','github']"
  authEndpoint="/api/auth"
  theme="light"
  [useService]="true"
  (onLogin)="onLogin($event)"
  (onSocialLogin)="onSocial($event)"
></primus-login>

User Profile

<primus-user-profile
  [user]="currentUser"
  [showLogout]="true"
  [useService]="true"
  (loggedOut)="onLoggedOut()"
></primus-user-profile>

Data Table

<primus-data-table
  [columns]="columns"
  [data]="rows"
  [selectable]="true"
  (onRowClick)="onRowClick($event)"
  (onSelectionChange)="onSelection($event)"
></primus-data-table>

Metric Card

<primus-metric-card
  title="Monthly Revenue"
  [value]="'$98,200'"
  delta="+12%"
  trend="up"
  [sparkline]="[12, 15, 13, 18, 22]"
></primus-metric-card>

Activity Feed

<primus-activity-feed
  [items]="activities"
  [showTimestamps]="true"
></primus-activity-feed>

Progress Ring

<primus-progress-ring [value]="75" [max]="100" [size]="120"></primus-progress-ring>

Date Range Picker

<primus-date-range-picker
  [ranges]="['Today', 'Last 7 days', 'Last 30 days']"
  (rangeChange)="onDateRangeChange($event)"
></primus-date-range-picker>

Filter Bar

<primus-filter-bar
  [filters]="filterConfig"
  [activeFilters]="activeFilters"
  (filterChange)="onFilterChange($event)"
></primus-filter-bar>

Search

<primus-search
  placeholder="Search..."
  [debounce]="300"
  (search)="onSearch($event)"
></primus-search>

Export Menu

<primus-export-menu
  [formats]="['CSV', 'PDF', 'PNG']"
  (export)="handleExport($event)"
></primus-export-menu>

Modal

<primus-modal
  [open]="isOpen"
  title="Confirm Action"
  size="md"
  (onClose)="isOpen = false"
>
  Modal content goes here.
  <div modal-footer>
    <button>Confirm</button>
  </div>
</primus-modal>

Dashboard

<primus-dashboard
  title="Overview"
  subtitle="Key metrics"
></primus-dashboard>

Slots and layout options:

<primus-dashboard
  [layout]="'sidebar-content'"
  [showHeader]="true"
  [showFooter]="true"
  [sidebarWidth]="280"
>
  <div dashboard-actions>
    <primus-button variant="outline">Export</primus-button>
  </div>
  <div dashboard-sidebar>
    <primus-sidebar [items]="navItems"></primus-sidebar>
  </div>
  <div dashboard-content>
    <primus-dashboard-grid [columns]="2">
      <!-- cards -->
    </primus-dashboard-grid>
  </div>
  <div dashboard-footer>Last refreshed: 2m ago</div>
</primus-dashboard>

Dashboard Grid

<primus-dashboard-grid [columns]="3">
  <!-- dashboard cards here -->
</primus-dashboard-grid>

Grid item spans:

<primus-dashboard-grid [columns]="3">
  <primus-grid-item [colspan]="2">
    <!-- wide card -->
  </primus-grid-item>
  <primus-grid-item [colspan]="1">
    <!-- normal card -->
  </primus-grid-item>
</primus-dashboard-grid>

Line Chart

<primus-line-chart
  [labels]="['Mon', 'Tue', 'Wed', 'Thu']"
  [series]="[{ name: 'Revenue', data: [12, 18, 14, 22] }]"
></primus-line-chart>

Bar Chart

<primus-bar-chart
  [labels]="['Q1', 'Q2', 'Q3', 'Q4']"
  [series]="[{ name: 'Pipeline', data: [20, 14, 18, 26] }]"
  [stacked]="false"
></primus-bar-chart>

Pie Chart

<primus-pie-chart
  [labels]="['Direct', 'Referral', 'Paid']"
  [series]="[{ name: 'Traffic', data: [55, 25, 20] }]"
  [donut]="true"
></primus-pie-chart>

Area Chart

<primus-area-chart
  [labels]="['Jan', 'Feb', 'Mar', 'Apr']"
  [series]="[{ name: 'Active Users', data: [120, 140, 155, 180], fill: true }]"
></primus-area-chart>

Sparkline

<primus-sparkline
  [series]="[{ name: 'Trend', data: [12, 14, 11, 18, 17] }]"
  [height]="32"
></primus-sparkline>

Header

<primus-header
  [title]="'Primus Admin'"
  [breadcrumbs]="breadcrumbs"
  [user]="currentUser"
  (onUserClick)="onUserClick()"
></primus-header>

Sidebar

<primus-sidebar
  [items]="navItems"
  [activeId]="activeNavId"
  (onItemClick)="onNavClick($event)"
></primus-sidebar>

Layout

<primus-layout [sidebar]="true" [header]="true" [darkMode]="false">
  <!-- app content -->
</primus-layout>

Transaction History

<primus-transaction-history
  [transactions]="transactions"
  (onTransactionClick)="onTransactionClick($event)"
></primus-transaction-history>

Feature Flag Toggle

<primus-feature-flag-toggle
  flagKey="beta-dashboard"
  [apiUrl]="'https://api.yourdomain.com'"
  (toggled)="onFlagToggled($event)"
></primus-feature-flag-toggle>

KYC Verification

<primus-kyc-verification
  userId="user-123"
  [apiUrl]="'https://api.yourdomain.com'"
></primus-kyc-verification>

Credit Card

<primus-credit-card
  cardHolder="Jane Doe"
  last4="4242"
  expiry="12/26"
  brand="visa"
  variant="platinum"
></primus-credit-card>

Account Dashboard

<primus-account-dashboard
  [apiUrl]="'https://api.yourdomain.com'"
></primus-account-dashboard>

Credit Score Card

<primus-credit-score-card
  userId="user-123"
  [apiUrl]="'https://api.yourdomain.com'"
></primus-credit-score-card>

Loan Calculator

<primus-loan-calculator
  [apiUrl]="'https://api.yourdomain.com'"
></primus-loan-calculator>

Log Viewer

<primus-log-viewer></primus-log-viewer>

Fraud Detection Dashboard

<primus-fraud-detection-dashboard
  [apiUrl]="'https://api.yourdomain.com'"
></primus-fraud-detection-dashboard>

Claim Status Tracker

<primus-claim-status-tracker
  [apiUrl]="'https://api.yourdomain.com'"
></primus-claim-status-tracker>

Claim Tracker

<primus-claim-tracker
  [apiUrl]="'https://api.yourdomain.com'"
></primus-claim-tracker>

Policy Card

<primus-policy-card></primus-policy-card>

Premium Calculator

<primus-premium-calculator
  [apiUrl]="'https://api.yourdomain.com'"
></primus-premium-calculator>

Quote Comparison

<primus-quote-comparison
  [apiUrl]="'https://api.yourdomain.com'"
></primus-quote-comparison>

Agent Directory

<primus-agent-directory
  [apiUrl]="'https://api.yourdomain.com'"
></primus-agent-directory>

Button

<primus-button>Primary</primus-button>

Input

<primus-input label="Email" placeholder="[email protected]"></primus-input>

Form Field

<primus-form-field label="Company">
  <input type="text" />
</primus-form-field>

Textarea

<primus-textarea label="Notes" placeholder="Enter notes"></primus-textarea>

Select

<primus-select label="Plan" [options]="planOptions"></primus-select>

Radio Group

<primus-radio-group label="Billing" [options]="billingOptions"></primus-radio-group>

Toggle

<primus-toggle label="Enable alerts" [checked]="true"></primus-toggle>

Date Picker

<primus-date-picker label="Start date"></primus-date-picker>

Stats Card

<primus-stats-card label="Monthly Revenue" [value]="'$142k'" delta="+12%" trend="up"></primus-stats-card>

Theme Toggle

<primus-theme-toggle></primus-theme-toggle>

Stepper

<primus-stepper
  [steps]="steps"
  [activeStep]="1"
  [completedSteps]="[0]"
  (stepSelected)="onStepSelected($event)"
></primus-stepper>

Wizard

<primus-wizard title="Leave Request" subtitle="Step 1 of 3">
  <div wizard-steps>
    <primus-stepper
      [steps]="steps"
      [activeStep]="1"
      [completedSteps]="[0]"
    ></primus-stepper>
  </div>
  <div wizard-content>
    <!-- step content -->
  </div>
  <div wizard-actions>
    <primus-wizard-nav
      (back)="onBack()"
      (next)="onNext()"
    ></primus-wizard-nav>
  </div>
</primus-wizard>

Wizard Nav

<primus-wizard-nav
  backLabel="Back"
  nextLabel="Next"
  (back)="onBack()"
  (next)="onNext()"
></primus-wizard-nav>

Summary Card

<primus-summary-card title="Total Users" subtitle="Last 30 days">
  <div>24,910</div>
</primus-summary-card>

Section

<primus-section title="Settings">
  Section content here.
</primus-section>

React to Angular parity checklist

| React component | Angular selector | Notes | | --- | --- | --- | | AICopilot | primus-ai-copilot | Inputs: apiUrl, endpoint, mode, title, placeholder. Output: responded. | | UserProfile | primus-user-profile | Inputs: user, useService, showLogout, logoutEndpoint. Output: loggedOut. | | PrimusLogin | primus-login | Inputs: title, subtitle, logo, showEmailLogin, socialProviders, authEndpoint, theme, useService. Outputs: onLogin, onSocialLogin, loggedIn. | | PrimusNotificationCenter | primus-notification-center | Inputs: apiUrl, theme, pollInterval. | | NotificationFeed | primus-notification-feed | Inputs: apiUrl, pollInterval, userId. | | SecurityDashboard | primus-security-dashboard | Inputs: apiUrl, listEndpoint. | | DocumentViewer | primus-document-viewer | Inputs: document (or templateId/data/format). Outputs: onClose, onDownload. | | CheckoutForm | primus-checkout-form | Inputs: amount, currency, apiUrl. Outputs: onSuccess, onError. | | FileUploader | primus-file-uploader | Inputs: apiUrl, accept, multiple. Output: onUploadComplete. | | PrimusDataTable | primus-data-table | Inputs: columns, data, selectable. Outputs: onRowClick, onSelectionChange. | | PrimusModal | primus-modal | Inputs: open, title, size. Output: onClose. | | PrimusDashboard | primus-dashboard | See component inputs. | | PrimusDashboardGrid | primus-dashboard-grid | Inputs: columns. | | PrimusHeader | primus-header | Inputs: title, breadcrumbs, user. Output: onUserClick. | | PrimusSidebar | primus-sidebar | Inputs: items, activeId. Output: onItemClick. | | PrimusLayout | primus-layout | Inputs: sidebar, header, darkMode. | | TransactionHistory | primus-transaction-history | Outputs: transactionClick, onTransactionClick. | | FeatureFlagToggle | primus-feature-flag-toggle | Inputs: flagKey, apiUrl. Output: toggled. | | KYCVerification | primus-kyc-verification | Inputs: userId, apiUrl. | | CreditCardVisual | primus-credit-card | Inputs: cardHolder, last4, expiry, brand, variant. | | AccountDashboard | primus-account-dashboard | Inputs: apiUrl. | | CreditScoreCard | primus-credit-score-card | Inputs: userId, apiUrl. | | LoanCalculator | primus-loan-calculator | Inputs: apiUrl. | | LogViewer | primus-log-viewer | See component inputs. | | FraudDetectionDashboard | primus-fraud-detection-dashboard | Inputs: apiUrl. | | ClaimStatusTracker | primus-claim-status-tracker | Inputs: apiUrl. | | ClaimTracker | primus-claim-tracker | Inputs: apiUrl. | | PolicyCard | primus-policy-card | See component inputs. | | PremiumCalculator | primus-premium-calculator | Inputs: apiUrl. | | QuoteComparison | primus-quote-comparison | Inputs: apiUrl. | | AgentDirectory | primus-agent-directory | Inputs: apiUrl. |

Endpoint overrides

PrimusUiModule.forRoot({
  apiBaseUrl: 'https://api.yourdomain.com',
  endpoints: {
    authLogin: '/identity/login',
    notifications: '/notifications/realtime',
    featureFlagsToggle: '/feature-flags/{key}/toggle',
    paymentsCheckout: '/payments/create-intent',
    documentsRender: '/documents/render'
  }
});

Portal playground endpoints

PrimusUiModule.forRoot({
  apiBaseUrl: 'https://api.yourdomain.com',
  endpoints: {
    notifications: '/playground/notifications',
    featureFlags: '/playground/feature-flags',
    featureFlagsToggle: '/playground/feature-flags/{key}/toggle',
    paymentsCheckout: '/playground/payments/create-intent',
    storageUpload: '/playground/storage/upload',
    loggingQuery: '/playground/logging/query',
    securityScan: '/playground/security/scan',
    documentsRender: '/playground/documents/render'
  }
});