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

appvn

v20.0.18

Published

Framework-agnostic logo + module launcher Web Component

Readme

appvn

Framework-agnostic Web Component library — works in Angular, React, Vue, and plain HTML.

Built with Lit. No framework peer dependency.

Author: @SmaxTeam from SmaxApp Dev Team


Compatibility

| Angular | appvn | |---------|-------| | >= 13.x | v20.x |


Getting Started

Step 1: Installation

npm install appvn

Step 2: Update angular.json

Add the bundle to scripts:

"scripts": [
  "node_modules/appvn/dist/appvn.umd.js"
]

Step 3: Add CUSTOM_ELEMENTS_SCHEMA

In every Angular module that uses <appvn-*> tags:

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@NgModule({
  declarations: [...],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class YourModule {}

Step 4: Use the components

Logo + Module Launcher

<appvn-logo
  [biz]="biz"
  [collapsed]="!isExpanded"
></appvn-logo>

The component self-manages: fetches biz list on drawer open, derives modules/groups/quickModules from biz.

Image Preview Lightbox

<appvn-image-preview
  [images]="product.images"
  [active-index]="selectedIndex"
  (change)="onImageChange($event.detail)">
  <img [src]="product.images[0]" style="cursor:zoom-in;" />
</appvn-image-preview>

API

<appvn-logo>

Inputs

| Input | Type | Default | Description | |-------|------|---------|-------------| | biz | IBiz | required | Current business (drives all module/group rendering) | | bizName | string? | — | Overrides trigger label (falls back to biz.module.name) | | collapsed | boolean | false | Hides trigger label text |

Auth token is read automatically from localStorage key access_token — no need to pass it.

The component derives currentModule, modules, moduleGroups, quickModules, and bizList internally from biz. No need to pass them separately.

CSS Custom Properties

| Property | Default | Description | |----------|---------|-------------| | --appvn-drawer-width | 380px | Drawer panel width | | --appvn-trigger-height | 60px | Trigger button height | | --appvn-trigger-gap | 8px | Gap between icon and label in trigger | | --appvn-trigger-icon-size | 30px | Icon container size (width & height) | | --appvn-trigger-icon-padding | 5px | Padding inside icon container | | --appvn-trigger-label-color | #ffffff | Trigger label color |

Styling note

:host renders as display: flex with border-bottom: 1px solid rgba(255,255,255,0.1) — the separator between logo area and sidebar content is built-in. No extra CSS needed in the host app.


<appvn-image-preview>

Inputs

| Input | Type | Default | Description | |-------|------|---------|-------------| | images | string[] | [] | Image URLs to preview | | active-index | number | 0 | Initially displayed image |

Outputs

| Output | event.detail | Description | |--------|----------------|-------------| | (open) | — | Lightbox opened | | (close) | — | Lightbox closed | | (change) | { index: number } | Active image changed |

Methods

| Method | Description | |--------|-------------| | show() | Open lightbox programmatically | | hide() | Close lightbox programmatically |

Keyboard

| Key | Action | |-----|--------| | Escape | Close | | | Previous / Next |


Interfaces

interface IModule {
  id: string;
  name: string;
  alias: string;
  icon: string;
  groupIds?: string[];
}

interface IGroup {
  id: string;
  name: string;
}

interface IBizGroup {
  id: string;
  name: string;
  modules?: { id: string }[];
}

interface IBiz {
  id: string;
  name: string;
  alias: string;
  picture?: string;
  module?: IModule;        // active module shown in trigger
  modules?: IModule[];     // full module list with name/alias/icon
  groups?: IBizGroup[];    // group structure (used to derive moduleGroups)
  user?: {
    modules?: IModule[];
    quickModules?: string[];
  };
}

Usage in Other Frameworks

React 19+

import 'appvn/appvn-logo';
import 'appvn/appvn-image-preview';

function Sidebar({ biz }) {
  return (
    <appvn-logo
      ref={el => { if (!el) return; el.biz = biz; }}
    />
  );
}

function Gallery({ images }) {
  return (
    <appvn-image-preview ref={el => { if (el) el.images = images; }}>
      <img src={images[0]} style={{ cursor: 'zoom-in' }} />
    </appvn-image-preview>
  );
}

Vue 3+

import 'appvn/appvn-logo';
import 'appvn/appvn-image-preview';
<template>
  <appvn-logo :biz="biz" />
  <appvn-image-preview :images="images" @change="onImageChange">
    <img :src="images[0]" style="cursor:zoom-in;" />
  </appvn-image-preview>
</template>

Plain HTML

<script src="node_modules/appvn/dist/appvn.umd.js"></script>

<appvn-logo id="logo"></appvn-logo>

<script>
  const logo = document.querySelector('#logo');
  logo.biz = {
    id: '1',
    name: 'My Biz',
    alias: 'mybiz',
    module: { id: 'm1', name: 'CRM', alias: 'crm', icon: '/icons/crm.png' },
    modules: [...],
    groups: [...],
    user: { quickModules: ['m1', 'm2'] },
  };
</script>

Local Development

npm install
npm run dev    # dev server at http://localhost:5173
npm run build  # outputs dist/appvn-logo.mjs + dist/appvn-image-preview.mjs + dist/appvn.umd.js

Testing locally in another project

"appvn": "file:/absolute/path/to/appvn-lib"
npm install
# after any change to the lib:
npm run build   # in appvn-lib
npm install     # in consuming project

Bundle Size

| Entry | Size | Gzipped | Use case | |-------|------|---------|----------| | appvn-logo.mjs | ~28 KB | ~6.8 KB | ES module import | | appvn-image-preview.mjs | ~23 KB | ~6.6 KB | ES module import | | shared Lit runtime | ~24 KB | ~7.3 KB | code-split, loaded once | | appvn.umd.js | ~65 KB | ~18 KB | Angular scripts[] |


License

MIT