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

hanap-labs

v4.1.2

Published

Shared UI toolkit package for components, helpers, and composables.

Downloads

9,600

Readme

hanap-labs

Shared UI toolkit package for components, helpers, and composables.

Build

npm install
npm run build

Public Entrypoints

  • Root entrypoint: hanap-labs
  • Components entrypoint: hanap-labs/components
  • Helpers entrypoint: hanap-labs/helpers
  • Composables entrypoint: hanap-labs/composables
  • Auto-import helper entrypoint: hanap-labs/auto-import

Consumption Modes

1) Manual Named Imports (Default)

Use named imports when you want explicit dependencies per file.

import { HLButton, formatLabel, usePopup } from "hanap-labs";

You can also import by module group:

import { HLButton } from "hanap-labs/components";
import type { HLButtonProps } from "hanap-labs/components";
import { formatLabel } from "hanap-labs/helpers";
import { usePopup } from "hanap-labs/composables";

2) Optional Auto-Import Integration

If a consumer app uses unplugin-vue-components and unplugin-auto-import, the toolkit exposes helper factories to wire components and composables in one place.

Install plugins in the consumer app:

npm install -D unplugin-vue-components unplugin-auto-import

Update the consumer app vite.config.ts:

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import Components from "unplugin-vue-components/vite";
import AutoImport from "unplugin-auto-import/vite";
import { createToolkitAutoImportOptions } from "hanap-labs/auto-import";

const toolkitAutoImport = createToolkitAutoImportOptions();

export default defineConfig({
  plugins: [
    vue(),
    Components({
      resolvers: toolkitAutoImport.components.resolvers,
    }),
    AutoImport({
      imports: toolkitAutoImport.composables.imports,
    }),
  ],
});

To scope auto-imports, pass selected names:

createToolkitAutoImportOptions({
  componentNames: ["HLButton"],
  composableNames: ["usePopup"],
});

Consumer Setup Checklist

Apply these steps in each consuming website:

  1. Install hanap-labs.
  2. Import toolkit styles once in your app entry:
    • import "hanap-labs/styles.css";
    • In Nuxt, add "hanap-labs/styles.css" to nuxt.config.ts under css.
  3. Choose a mode:
    • Keep manual named imports (default).
    • Enable optional auto-import using the Vite plugin setup above.
  4. Run the app build and confirm toolkit components/composables resolve correctly.

Global Overlay Setup (popup and notify)

The toolkit includes app-level overlay plugins:

  • createPopupPlugin() for popup host mounting
  • createNotifyPlugin() for toast/notify host mounting

Auto-mount (recommended)

Use auto-mount when you want the toolkit to create and mount hosts to document.body:

import { createApp } from "vue";
import App from "./App.vue";
import { createNotifyPlugin, createPopupPlugin } from "hanap-labs";

createApp(App).use(createPopupPlugin()).use(createNotifyPlugin()).mount("#app");

Manual mount target

Use manual targets when your app needs explicit host element control:

<div id="app"></div>
<div id="popup-root"></div>
<div id="notify-root"></div>
import { createApp } from "vue";
import App from "./App.vue";
import { createNotifyPlugin, createPopupPlugin } from "hanap-labs";

createApp(App)
  .use(createPopupPlugin({ mountId: "popup-root", autoMount: true }))
  .use(createNotifyPlugin({ mountId: "notify-root", autoMount: true }))
  .mount("#app");

Theming

The toolkit supports host-driven theming through CSS variables, plus .light / .dark mode.

Toolkit theme tokens are scoped to the .hanap-labs-theme (and .hanap-labs-font) class, so importing hanap-labs/styles.css does not overwrite your app :root styles.

  1. Add hanap-labs-theme (and optionally hanap-labs-font) to a wrapper element in your app (often body, #app, or a layout root).
  2. (Optional) Define host tokens in your app :root (and override them in .dark).
  3. Toggle .dark on a parent element (usually html or body) to enable dark mode.

Example wrapper:

<body class="hanap-labs-theme hanap-labs-font">
  <div id="app"></div>
</body>

Example:

:root {
  --primary: #15803d;
  --secondary: #9fcb98;
  --danger: #dc2626;
}

.dark {
  --primary: #85bb65;
  --secondary: #3e5f4a;
  --danger: #f87171;
}

Global Theme CSS Custom Properties

All global theme tokens are available as CSS custom properties prefixed with --hanap-labs-.

Color Tokens

| Property | Description | Light Mode Default | Dark Mode Default | | --- | --- | --- | --- | | --hanap-labs-primary | Primary brand color | #15803d | #85bb65 | | --hanap-labs-secondary | Secondary brand color | #9fcb98 | #3e5f4a | | --hanap-labs-tertiary | Tertiary brand color | #79ae6f | #2f4a39 | | --hanap-labs-success | Success state color | #059669 | #34d399 | | --hanap-labs-danger | Danger/error state color | #dc2626 | #f87171 | | --hanap-labs-warning | Warning state color | #f59e0b | #fbbf24 | | --hanap-labs-info | Info state color | #38bdf8 | #60a5fa | | --hanap-labs-light | Light neutral color | #ede9e6 | #1f2937 | | --hanap-labs-dark | Dark neutral color | #030712 | #030712 | | --hanap-labs-muted | Muted neutral color | #6b8274 | #9ca3af |

Surface Tokens

| Property | Description | Light Mode Default | Dark Mode Default | | --- | --- | --- | --- | | --hanap-labs-surface | Primary surface background | #ffffff | #0f172a | | --hanap-labs-surface-subtle | Subtle surface background | #f8fafc | #111827 | | --hanap-labs-surface-muted | Muted surface background | #f1f5f9 | #1f2937 | | --hanap-labs-overlay | Overlay/backdrop color | rgba(15, 23, 42, 0.55) | rgba(2, 6, 23, 0.72) |

Border Tokens

| Property | Description | Light Mode Default | Dark Mode Default | | --- | --- | --- | --- | | --hanap-labs-border-default | Default border color | #e5e7eb | #334155 | | --hanap-labs-border-strong | Strong border color | #cbd5e1 | #475569 |

Text Tokens

| Property | Description | Light Mode Default | Dark Mode Default | | --- | --- | --- | --- | | --hanap-labs-text-default | Default text color | #0f172a | #f8fafc | | --hanap-labs-text-muted | Muted text color | #64748b | #94a3b8 | | --hanap-labs-text-subtle | Subtle text color | #475569 | #cbd5e1 | | --hanap-labs-text-light | Light text color (for dark backgrounds) | #ffffff | #030712 | | --hanap-labs-text-primary | Primary text color | #15803d | #85bb65 | | --hanap-labs-text-theme | Theme text color | #0f172a | #f8fafc |

Typography Tokens

| Property | Description | Default | | -------------------------- | ----------- | ------------------------- | | --hanap-labs-font-family | Font family | "Work Sans", sans-serif |

TanStack Vue Query Setup (useQuery)

The useQuery and useMutation composables require TanStack Vue Query (optional peer dependency) to be installed, then registered once.

npm install @tanstack/vue-query

In your app entry (e.g., main.ts):

import { createApp } from "vue";
import App from "./App.vue";
import { createQueryPlugin } from "hanap-labs";

createApp(App)
  .use(
    createQueryPlugin({
      queries: {
        staleTime: 1000 * 60 * 5,
      },
    }),
  )
  .mount("#app");

Without this setup, useQuery and useMutation will throw a runtime error in fresh consumer apps.