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

bn-dashboard

v0.10.1

Published

Reusable React dashboard component library

Readme

bn-dashboard

A React component library for building glassmorphic admin dashboards. Includes layout templates, navigation, data-display components, and a two-theme (light/dark) token system.


Installation

npm install bn-dashboard

For local development against an unpublished build, see Local development below.


Setup

Three things must happen once at the app root before any components render.

1. Import the stylesheet

// Next.js: app/layout.tsx  or  pages/_app.tsx
// Vite:    main.tsx / index.tsx
import 'bn-dashboard/style.css';

This single file contains all component styles and CSS custom-property tokens.

2. Load the fonts

The library does not bundle fonts. It expects Poppins (headings) and Inter (body) to be available.

Next.js (recommended):

// app/layout.tsx
import { Poppins, Inter } from 'next/font/google';

const poppins = Poppins({ subsets: ['latin'], weight: ['400', '600'] });
const inter   = Inter({ subsets: ['latin'] });

HTML <head> (any framework):

<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
  href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=Poppins:wght@400;600&display=swap"
  rel="stylesheet"
/>

If neither font loads the library falls back to system-ui — everything remains readable.

3. Add bn-root and a theme

bn-root activates the token layer. data-theme selects light or dark:

// Next.js app/layout.tsx
<html lang="en" data-theme="dark">
  <body className="bn-root">
    {children}
  </body>
</html>

Valid values: "light" (default) · "dark"


Quick start

'use client'; // Next.js — see note below

import { useState } from 'react';
import {
  BnSidenavLayout, BnSidebar, BnBrand,
  BnNavItem, BnDivider, BnHeader, BnButton,
} from 'bn-dashboard';

const IconHome = () => (
  <svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
    <path d="M2 7L8 2l6 5v7a1 1 0 01-1 1H3a1 1 0 01-1-1V7z" stroke="currentColor" strokeWidth="1.4"/>
  </svg>
);

export default function AppShell({ children }: { children: React.ReactNode }) {
  const [collapsed, setCollapsed] = useState(false);
  return (
    <BnSidenavLayout
      sidebar={
        <BnSidebar
          collapsed={collapsed}
          onToggle={() => setCollapsed(v => !v)}
          brand={<BnBrand name="My App" logoSize={28} />}
        >
          <BnNavItem label="Dashboard" icon={<IconHome />} active />
          <BnDivider />
        </BnSidebar>
      }
      header={
        <BnHeader
          title="Dashboard"
          bare
          actions={<BnButton size="sm">New Report</BnButton>}
        />
      }
    >
      {children}
    </BnSidenavLayout>
  );
}

Next.js — server components

All components use useState, useRef, or React context and must run on the client. Keep your layout shell in a dedicated file marked 'use client' and import it from your server root layout:

// app/layout-shell.tsx
'use client';
export { AppShell } from './AppShell';
// app/layout.tsx  (server component)
import 'bn-dashboard/style.css';
import { AppShell } from './layout-shell';

export default function RootLayout({ children }) {
  return (
    <html lang="en" data-theme="dark">
      <body className="bn-root">
        <AppShell>{children}</AppShell>
      </body>
    </html>
  );
}

Theme switching

// Dark
document.documentElement.setAttribute('data-theme', 'dark');

// Light (remove attribute — light is the default)
document.documentElement.removeAttribute('data-theme');

Follow OS preference on first load:

if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
  document.documentElement.setAttribute('data-theme', 'dark');
}

Accent colour

The default accent is sage green. Change it for your brand using BnAccentUtils.applyToRoot:

import { BnAccentUtils } from 'bn-dashboard';

// Call once at app startup
BnAccentUtils.applyToRoot('#6366f1'); // indigo

This derives all four accent tokens (--bn-color-accent, --bn-color-accent-hover, --bn-color-accent-subtle, --bn-color-accent-contrast) and automatically selects a legible contrast colour.

To derive tokens without applying them (e.g. to store in state):

const tokens = BnAccentUtils.derive('#6366f1');
// { accent, accentHover, accentSubtle, accentContrast }

Background gradient

The ambient gradient behind all glass panels is a CSS custom property. Override it in your own stylesheet after importing bn-dashboard/style.css:

:root {
  --bn-bg-gradient:
    radial-gradient(ellipse at 20% 40%, rgba(99, 102, 241, 0.18) 0%, transparent 50%),
    radial-gradient(ellipse at 80% 80%, rgba(236, 72, 153, 0.12) 0%, transparent 45%);
}

[data-theme="dark"] {
  --bn-bg-gradient:
    radial-gradient(ellipse at 20% 50%, rgba(99, 102, 241, 0.25) 0%, transparent 50%),
    radial-gradient(ellipse at 80% 85%, rgba(236, 72, 153, 0.20) 0%, transparent 45%);
}

Component reference

| Export | Category | Description | |---|---|---| | BnSidenavLayout | Layout | Full-height layout: collapsible sidebar + header + scrollable main | | BnDashboardLayout | Layout | Alias of BnSidenavLayout | | BnTopnavLayout | Layout | Full-height layout: top navigation bar + scrollable main | | BnSidebar | Layout | Collapsible glass sidebar with brand slot and nav items | | BnBrand | Layout | Logo / letter-avatar + name, collapses with sidebar | | BnPanel | Layout | Glass card container | | BnGrid | Layout | Responsive CSS-grid wrapper | | BnDivider | Layout | Thin rule for sidebar sections | | BnHero | Layout | Full-width hero / banner panel | | BnHeader | Navigation | Page header with title, actions slot; optional bare mode | | BnNavItem | Navigation | Sidebar nav item with icon, active state, tooltip on collapse | | BnBreadcrumb | Navigation | Breadcrumb trail | | BnTabs | Navigation | Horizontal tab bar | | BnButton | Actions | Button with size, variant, intent, icon slots | | BnBadge | Data display | Inline status badge | | BnAlert | Data display | Dismissible alert / banner | | BnStatCard | Data display | KPI card: value, title, trend line | | BnProgressBar | Data display | Labelled progress bar | | BnTimeline | Data display | Vertical event timeline | | BnDataTable | Data display | Sortable, typed data table | | Bn | Tokens | JS token map (Bn.color.accent, Bn.radius.lg, …) | | BnToken | Tokens | CSS custom-property name map | | BnAccentUtils | Tokens | Derive and apply accent colour tokens |


TypeScript

Full type declarations ship with the package — no @types/ package required.

import type {
  BnVariant, BnSize, BnIntent,
  BnBreadcrumbItem, BnTab, BnTimelineItem, BnDataTableColumn,
} from 'bn-dashboard';

Publishing a new version

# 1. Bump the version
npm version patch   # or minor / major

# 2. Publish — prepublishOnly runs the build automatically
npm publish

# 3. Push the version commit and tag
git push && git push --tags

prepublishOnly runs npm run build before every publish, so dist/ is always fresh. Only the dist/ directory is shipped to the registry ("files": ["dist"] in package.json).

Use semver conventions:

  • patch — bug fixes, style tweaks
  • minor — new components or props, backwards-compatible
  • major — breaking changes (renamed exports, removed props, token renames)

Local development

To work against a local unpublished build in a consuming project:

# 1. Build in this repo
npm run build

# 2. In the consuming project
# package.json → "bn-dashboard": "file:../bn-dashboard"
npm install

After any change to this library, run npm run build here and npm install again in the consuming project.


Development

npm run dev          # Storybook at http://localhost:6006
npm test             # Vitest unit tests
npm run typecheck    # TypeScript strict check (no emit)
npm run build        # Build distributable to dist/