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

@sajeevan-edrevel/icons

v0.5.7

Published

A production-ready, cross-framework design system and component library built with **Lit Web Components**, **TypeScript**, **Shadow DOM**, **CSS Custom Properties**, and **React Wrappers**.

Readme

Edrevel UI (@sajeevan-edrevel/ui) — Complete Architecture & Framework Usage Guide

A production-ready, cross-framework design system and component library built with Lit Web Components, TypeScript, Shadow DOM, CSS Custom Properties, and React Wrappers.

Designed for React, Next.js, Angular, Vue, Svelte, Micro Frontends, and Plain HTML/JS (Zero-Node) projects.


💡 Architecture Overview

Edrevel UI uses a single implementation source of truth based on W3C Standard Web Components:

                     EDREVEL DESIGN TOKENS
                               │
                               ▼
                @sajeevan-edrevel/tokens (CSS Variables)
                               │
                               ▼
              @sajeevan-edrevel/components (Lit Web Components + Shadow DOM)
                               │
       ┌───────────────────────┼───────────────────────┐
       ▼                       ▼                       ▼
Plain HTML (No Node)       Angular / Vue / Svelte  @sajeevan-edrevel/react (React Wrapper)
 (Standalone JS)          (Custom Elements)                    │
                                                      ┌────────┴────────┐
                                                      ▼                 ▼
                                                   React             Next.js
  1. Design Tokens (@sajeevan-edrevel/tokens): Primitive, semantic, and component CSS Custom Properties supporting Light Theme, Dark Theme (data-ed-theme="dark"), and custom theme overrides.
  2. Icons (@sajeevan-edrevel/icons): Accessible SVG icons.
  3. Utilities (@sajeevan-edrevel/utilities): Custom event dispatchers, focus management, and DOM helpers.
  4. Web Components (@sajeevan-edrevel/components): Lit Web Components (<ed-button>, <ed-kpi-card>, <ed-input>, etc.). Provides ES Modules and a standalone bundled JS file (dist/edrevel-components.bundle.js) for non-Node projects.
  5. React Wrappers (@sajeevan-edrevel/react): React component wrappers for React 18/19 and Next.js (<Button />, <KpiCard />, <Input />, etc.).
  6. All-in-One (@sajeevan-edrevel/ui): Single unified package importing tokens, components, and React wrappers.

🧩 Available Components

| Component | Web Component Tag | React Component | Description / Attributes | |---|---|---|---| | KPI Card | <ed-kpi-card> | <KpiCard /> | tag, stat, delta, delta-trend, sub, accent, accent-bg, compound, compare-grid, compare-cols | | Button | <ed-button> | <Button /> | variant (primary/secondary/danger/ghost), size (sm/md/lg), loading, disabled, ed-click | | Input | <ed-input> | <Input /> | label, placeholder, value, error, disabled, ed-input, ed-change | | Select | <ed-select> | <Select /> | label, options, value, placeholder, disabled, ed-change | | Checkbox | <ed-checkbox> | <Checkbox /> | label, checked, indeterminate, disabled, ed-change | | Modal | <ed-modal> | <Modal /> | title, open, size, ed-close | | Drawer | <ed-drawer> | <Drawer /> | title, open, position (left/right), ed-close | | Table | <ed-table> | <Table /> | columns, data, sortable, selectable, ed-sort, ed-select-change | | Pagination | <ed-pagination> | <Pagination /> | total, page-size, page, ed-page-change | | Empty State | <ed-empty-state> | <EmptyState /> | heading, description, compact, slotted action buttons |


📦 Package Installation

Install the main package or modular sub-packages:

# All-in-One package
npm install @sajeevan-edrevel/ui

# Or individual modular packages
npm install @sajeevan-edrevel/components @sajeevan-edrevel/tokens
# For React / Next.js
npm install @sajeevan-edrevel/react @sajeevan-edrevel/tokens

🌐 Usage across Frameworks

1. Plain HTML / JS (Zero-Node / Static CDN)

Link the design tokens stylesheet and standalone component bundle directly in your HTML <head>:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Plain HTML Demo</title>

  <!-- Import Design Tokens CSS -->
  <link rel="stylesheet" href="https://unpkg.com/@sajeevan-edrevel/tokens/dist/index.css" />

  <!-- Option A: Load All Components (Full Bundle) -->
  <script type="module" src="https://unpkg.com/@sajeevan-edrevel/components/dist/edrevel-components.bundle.js"></script>

  <!-- Option B: Load Only Specific Individual Components -->
  <!-- <script type="module" src="https://unpkg.com/@sajeevan-edrevel/components/dist/components/button.js"></script> -->
  <!-- <script type="module" src="https://unpkg.com/@sajeevan-edrevel/components/dist/components/input.js"></script> -->
  <!-- <script type="module" src="https://unpkg.com/@sajeevan-edrevel/components/dist/components/kpi-card.js"></script> -->
</head>
<body>
  <!-- Standard KPI Card -->
  <ed-kpi-card
    tag="INSIGHT"
    stat="123"
    delta="+4%"
    delta-trend="up"
    sub="Active Learners"
  ></ed-kpi-card>

  <!-- Button & Modal -->
  <ed-button id="open-btn" variant="primary">Open Modal</ed-button>

  <ed-modal id="demo-modal" title="Welcome to Edrevel UI">
    <p>Component loaded in plain HTML without Node!</p>
  </ed-modal>

  <script>
    document.querySelector('#open-btn').addEventListener('ed-click', () => {
      document.querySelector('#demo-modal').setAttribute('open', '');
    });
  </script>
</body>
</html>

2. React JS (Vite / Create React App / SPA)

Install packages:

npm install @sajeevan-edrevel/react @sajeevan-edrevel/tokens

Import styles in main.tsx or App.tsx:

import '@sajeevan-edrevel/tokens/css';

Use React component wrappers with type-safe props and ref support:

import React, { useState } from 'react';
import '@sajeevan-edrevel/tokens/css';
import { KpiCard, Button, Input, Select } from '@sajeevan-edrevel/react';

export default function Dashboard() {
  const [name, setName] = useState('');

  return (
    <div style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 16 }}>
      {/* KPI Card */}
      <KpiCard
        tag="INSIGHT"
        stat="1,240"
        delta="+12%"
        deltaTrend="up"
        sub="Active Students"
      />

      {/* Input & Button */}
      <Input
        label="Student Name"
        value={name}
        onInput={(e: any) => setName(e.detail.value)}
      />

      <Button variant="primary" onClick={() => alert(`Saved: ${name}`)}>
        Save Student
      </Button>
    </div>
  );
}

3. Next.js (App Router & Pages Router)

In Next.js App Router (app/page.tsx), declare "use client" when using interactive client components:

"use client";

import '@sajeevan-edrevel/tokens/css';
import { KpiCard, Button, Input, Modal } from '@sajeevan-edrevel/react';
import { useState } from 'react';

export default function NextPage() {
  const [open, setOpen] = useState(false);

  return (
    <main style={{ padding: 32 }}>
      <h1>Next.js Dashboard</h1>

      <KpiCard
        compound
        compareGrid
        compareCols={2}
        tag="PERFORMANCE"
        stat="89.4"
        delta="+3.2"
        deltaTrend="up"
        sub="Average Score"
      />

      <Button variant="primary" onClick={() => setOpen(true)}>
        Open Notification
      </Button>

      <Modal title="Next.js Integration" open={open} onClose={() => setOpen(false)}>
        <p>Edrevel UI components run seamlessly in Next.js!</p>
      </Modal>
    </main>
  );
}

4. Angular Applications

Install components:

npm install @sajeevan-edrevel/components @sajeevan-edrevel/tokens
  1. Import Design Tokens CSS in src/styles.css:

    @import "@sajeevan-edrevel/tokens/css";
  2. Register Custom Elements Schema in Angular component:

    import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
    import '@sajeevan-edrevel/components';
    
    @Component({
      selector: 'app-dashboard',
      standalone: true,
      templateUrl: './dashboard.component.html',
      schemas: [CUSTOM_ELEMENTS_SCHEMA] // 👈 Required for custom <ed-*> HTML tags
    })
    export class DashboardComponent {
      onCardClick() {
        console.log('KPI card clicked');
      }
    }
  3. Angular Template (dashboard.component.html):

    <ed-kpi-card
      tag="INSIGHT"
      stat="94.2%"
      delta="+1.8%"
      delta-trend="up"
      sub="Mastery Rate"
      (ed-click)="onCardClick()"
    ></ed-kpi-card>
    
    <ed-button variant="primary">Click Me</ed-button>

5. Vue.js 3 Applications

Install components:

npm install @sajeevan-edrevel/components @sajeevan-edrevel/tokens
  1. Configure vite.config.ts to recognize <ed-*> custom tags:

    import { defineConfig } from 'vite';
    import vue from '@vitejs/plugin-vue';
    
    export default defineConfig({
      plugins: [
        vue({
          template: {
            compilerOptions: {
              isCustomElement: (tag) => tag.startsWith('ed-')
            }
          }
        })
      ]
    });
  2. Usage in Vue SFC (App.vue):

    <script setup>
    import '@sajeevan-edrevel/tokens/css';
    import '@sajeevan-edrevel/components';
    </script>
    
    <template>
      <div style="padding: 24px;">
        <ed-kpi-card
          tag="ENROLLMENT"
          stat="13,043"
          sub="Enrolled Learners"
        ></ed-kpi-card>
    
        <ed-button variant="secondary">Vue Button</ed-button>
      </div>
    </template>

6. Svelte & SvelteKit

Install components:

npm install @sajeevan-edrevel/components @sajeevan-edrevel/tokens

Use directly in Svelte components (+page.svelte):

<script>
  import '@sajeevan-edrevel/tokens/css';
  import '@sajeevan-edrevel/components';
</script>

<main style="padding: 24px;">
  <ed-kpi-card
    accent="#10b981"
    accent-bg="#d1fae5"
    tag="COMPETENCY"
    stat="94.2%"
    delta="+1.8%"
    delta-trend="up"
    sub="Mastery Rate"
  ></ed-kpi-card>

  <ed-button variant="primary">Svelte Action</ed-button>
</main>

🎨 Dark Theme Support

Edrevel UI supports dark theme scoping out of the box using data-ed-theme="dark":

<!-- Apply to <body> or any container -->
<div data-ed-theme="dark" style="background: #0f172a; padding: 24px; color: white;">
  <ed-kpi-card
    tag="INSIGHT"
    stat="123"
    sub="Active Learners"
  ></ed-kpi-card>

  <ed-button variant="primary">Dark Primary</ed-button>
</div>

🎨 Theme Color Customization & Multi-Tenant Setup

Edrevel UI allows runtime theme customization per application or per tenant using @sajeevan-edrevel/tokens/js/tenant-theme.

Base Theme Customization Source

The base design token colors are managed in tokens/color.json:

{
  "brandPrimary": "#0e7ba0",
  "brandPrimaryHover": "#1497b8",
  "brandSecondary": "#d9952b",
  "action": "#0e7ba0",
  "actionHover": "#1497b8",
  "surfaceApp": "#eef2f7",
  "surfaceCard": "#ffffff",
  "textStrong": "#0e2440",
  "border": "#e2e8f0"
}

Framework Usage Guide for loadTenantTheme

1. Plain HTML / JS (CDN or Local)

Import the theme loader script and pass either a base CDN directory or a direct S3 JSON URL:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Plain HTML Theme Demo</title>

  <!-- 1. Design Tokens CSS -->
  <link rel="stylesheet" href="https://unpkg.com/@sajeevan-edrevel/tokens@latest/dist/index.css" />

  <!-- 2. Web Components JS Bundle -->
  <script type="module" src="https://unpkg.com/@sajeevan-edrevel/components@latest/dist/edrevel-components.bundle.js"></script>
</head>
<body>
  <ed-kpi-card tag="TENANT" stat="98.5%" sub="System Active"></ed-kpi-card>
  <ed-button variant="primary">Tenant Action</ed-button>

  <script type="module">
    import { loadTenantTheme } from "https://unpkg.com/@sajeevan-edrevel/tokens@latest/dist/tenant-theme.js";

    // Option A: Direct AWS S3 JSON URL
    await loadTenantTheme({
      baseUrl: "https://edrevel-design-tokens.s3.us-east-1.amazonaws.com/design-tokens/dev4.edrevel.com.json",
      root: document.documentElement
    });

    // Option B: Multi-tenant directory (fetches /themes/<hostname>.json automatically)
    /*
    await loadTenantTheme({
      baseUrl: "https://cdn.edrevel.com/design-tokens",
      root: document.documentElement
    });
    */
  </script>
</body>
</html>

2. React / Next.js Applications

Call loadTenantTheme() during application boot (e.g. inside useEffect in App.tsx or providers.tsx):

import React, { useEffect } from 'react';
import '@sajeevan-edrevel/tokens/css';
import { loadTenantTheme } from '@sajeevan-edrevel/tokens/js/tenant-theme';
import { Button, KpiCard } from '@sajeevan-edrevel/react';

export default function App() {
  useEffect(() => {
    // Loads theme dynamically based on current hostname or direct S3 JSON URL
    loadTenantTheme({
      baseUrl: 'https://edrevel-design-tokens.s3.us-east-1.amazonaws.com/design-tokens/dev4.edrevel.com.json',
      root: document.documentElement,
    });
  }, []);

  return (
    <div style={{ padding: 24 }}>
      <KpiCard tag="INSIGHT" stat="1,240" sub="Active Students" />
      <Button variant="primary">Save Record</Button>
    </div>
  );
}

3. Angular Applications

Call loadTenantTheme() inside APP_INITIALIZER or AppComponent.ngOnInit():

import { Component, OnInit, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { loadTenantTheme } from '@sajeevan-edrevel/tokens/js/tenant-theme';
import '@sajeevan-edrevel/components';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <div style="padding: 24px;">
      <ed-kpi-card tag="ANGULAR" stat="100%" sub="Tenant Theme Ready"></ed-kpi-card>
      <ed-button variant="primary">Angular Tenant Action</ed-button>
    </div>
  `,
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppComponent implements OnInit {
  async ngOnInit() {
    await loadTenantTheme({
      baseUrl: 'https://cdn.edrevel.com/design-tokens',
      root: document.documentElement
    });
  }
}

4. Instant Local Theme Override (applyTenantTheme)

If you want to test color overrides programmatically in any framework without an external HTTP fetch:

import { applyTenantTheme } from '@sajeevan-edrevel/tokens/js/tenant-theme';

// Programmatically apply custom theme colors
applyTenantTheme({
  action: "#6B3FB5",
  actionHover: "#8059C7",
  surfaceCard: "#F5F2FB",
  textStrong: "#24152F",
  border: "#D8CDE5"
}, document.documentElement);

5. Shadow DOM Embed Host Targeting

For embedded widgets or Shadow DOM hosts:

await loadTenantTheme({
  baseUrl: 'https://cdn.edrevel.com/design-tokens',
  root: document.querySelector('#embed-host')
});

6. Failure Behavior & Security Rules

  • Fail-Open Strategy: If a tenant JSON file is missing, invalid, returns 404, or hits a CORS error, loadTenantTheme() safely defaults to the base CSS theme without crashing.
  • Allowlist Protected: Only approved semantic color keys (brandPrimary, action, surfaceCard, textStrong, border, etc.) are mapped to CSS properties. Raw palette tokens (--ink, --ink-2, --ink-3) and arbitrary CSS injection are strictly blocked.

📄 License

MIT © Edrevel UI