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

custom-headless-header

v1.0.0

Published

Accessible React header with keyboard navigation, scoped Tailwind CSS, and dark mode support

Readme

Header Component

Description

The Header component is a customizable, accessible header with a built-in dropdown menu, keyboard navigation, dark mode support, and scoped Tailwind CSS styling. It provides three content slots (left, center, right) and a hover/focus-activated dropdown.

Installation

npm install custom-headless-header@latest

Usage

import React from "react";
import { Header } from "custom-headless-header";

const App = () => {
  return (
    <Header
      farLeft={<div className="cursor-pointer">My App</div>}
      sectionTitle={<span>Hello, User</span>}
      headerOptions={
        <button onClick={() => navigate("/about")}>About</button>
      }
      dropDownOptions={
        <div>
          <li>
            <button
              className="w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
              onClick={() => navigate("/profile")}
            >
              My Profile
            </button>
          </li>
          <li>
            <button
              className="w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
              onClick={handleLogout}
            >
              Log out
            </button>
          </li>
        </div>
      }
    />
  );
};

export default App;

Custom Styling Example

<Header
  farLeft={<Logo />}
  sectionTitle="Menu"
  dropDownOptions={menuItems}
  className="bg-blue-900"
  navClassName="max-w-7xl px-6"
  dropdownClassName="w-64 bg-blue-50"
  onDropdownToggle={(open) => console.log("Dropdown:", open)}
  hoverDelay={300}
/>

Props

| Prop | Type | Default | Description | | --- | --- | --- | --- | | farLeft | ReactNode | - | Content displayed on the far left (logo, app name, etc.) | | sectionTitle | ReactNode | - | Content displayed as the dropdown trigger on the far right | | dropDownOptions | ReactNode | - | Content for the dropdown menu items (buttons, links, etc.) | | headerOptions | ReactNode | - | Content displayed in the center section (nav links, images, etc.) | | className | string | "" | Additional CSS classes for the root <header> element | | navClassName | string | "" | Additional CSS classes for the inner <nav> element | | dropdownClassName | string | "" | Additional CSS classes for the dropdown menu panel | | onDropdownToggle | (open: boolean) => void | - | Callback fired when the dropdown opens or closes | | hoverDelay | number | 200 | Delay in milliseconds before the dropdown closes on mouse leave |

Accessibility

The header is fully accessible and meets WCAG 2.1 AA standards.

Keyboard Navigation

| Key | Action | | --- | --- | | Tab | Move focus to the dropdown trigger; opens dropdown on focus | | Enter / Space | Toggle dropdown open/closed | | Arrow Down | Open dropdown (when closed) or move to next item (when open) | | Arrow Up | Move to previous dropdown item | | Escape | Close dropdown and return focus to trigger |

Focus is automatically managed — when the dropdown opens via keyboard, focus moves into the menu. When it closes, focus returns to the trigger. When focus leaves the dropdown area entirely, the menu closes.

Screen Reader Support

  • Trigger uses <button> with aria-expanded and aria-haspopup="true"
  • Dropdown menu uses role="menu" with a unique id linked via aria-controls
  • Arrow key navigation works with any focusable children (buttons, links, [role="menuitem"])

Styling

The Header component uses Tailwind CSS v4 with built-in dark mode support. Styles are scoped via a .header-scoped wrapper to prevent CSS leakage.

Dark Mode

The dropdown menu automatically adapts to dark mode when a parent element has the dark class:

  • Light Mode: White dropdown background with gray borders
  • Dark Mode: Dark gray dropdown background with subtle borders
// Toggle dark mode
document.documentElement.classList.toggle("dark");

Tailwind CSS Setup

If you haven't set up Tailwind CSS yet:

  1. Install Tailwind CSS:
npm install -D tailwindcss@^4.1.11 @tailwindcss/postcss@^4.1.11 postcss
  1. Configure your postcss.config.js:
export default {
  plugins: {
    "@tailwindcss/postcss": {},
  },
};
  1. Include Tailwind in your CSS file:
@import "tailwindcss";

Features

  • Three Content Slots: Left (logo), center (nav), and right (dropdown trigger) sections
  • Hover & Focus Dropdown: Opens on mouse hover or keyboard focus with configurable delay
  • Keyboard Navigation: Full Arrow key, Enter, Space, Escape, and Tab support
  • Screen Reader Support: Semantic HTML, ARIA attributes, and focus management
  • Dark Mode: Automatic theme switching via parent dark class
  • Scoped CSS: Tailwind styles scoped to prevent conflicts with your app
  • Custom Styling: Override any section via className, navClassName, and dropdownClassName props
  • Dropdown Callback: onDropdownToggle notifies your app when the menu opens/closes