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

@k4k3ru/components-tab

v1.1.0

Published

Utility for tab component

Readme

Tab

Reusable framework-independent tabs. Use the default underline presentation or tab__container--segmented; both share the existing design tokens, icon/badge parts and compact sizing. No runtime dependency is required.

Page navigation

For different URLs, use native links inside a labelled nav. Set aria-current="page" on the current link. No JavaScript, role="tab", aria-selected, or roving tabindex is needed. Browser navigation, modifier-clicks, back/forward and application departure guards remain native.

<nav class="tab__container tab__container--scrollable" aria-label="Market views">
  <div class="tab__list">
    <a class="tab" href="/snapshot/" aria-current="page">
      <span class="tab__label">Snapshot</span>
      <span class="tab__indicator" aria-hidden="true"></span>
    </a>
    <a class="tab" href="/live/">
      <span class="tab__label">Live</span>
      <span class="tab__indicator" aria-hidden="true"></span>
    </a>
  </div>
</nav>

In-page panels

import { Tab } from '@k4k3ru/components-tab';
import '@k4k3ru/components-tab/dist/style.css';
const tabs = new Tab();
tabs.Run(); // Or Run(element) for a scoped view.
// On view disposal:
tabs.Destroy();
<div class="tab__container">
  <div class="tab__list" role="tablist" aria-label="Quote views">
    <button class="tab" type="button" role="tab" aria-selected="true"
      data-tab-target="quote"><span class="tab__label">Quote</span>
      <span class="tab__indicator" aria-hidden="true"></span></button>
    <button class="tab" type="button" role="tab" aria-selected="false"
      data-tab-target="sources"><span class="tab__label">Sources</span>
      <span class="tab__indicator" aria-hidden="true"></span></button>
  </div>
</div>
<div class="tab__panels">
  <section class="tab__panel" data-tab-id="quote">Current quote</section>
  <section class="tab__panel" data-tab-id="sources" hidden>Quote sources</section>
</div>
  • Panel wrapper must be a direct child of the container or its immediate next sibling. Each tab targets a distinct panel using aria-controls / panel id, or the existing data-tab-target / data-tab-id attributes. Invalid groups are left untouched. No document-wide panel fallback is used.
  • Initialization assigns missing unique IDs, roles, panel labels, controls and selected state without moving focus. Existing IDs are retained.
  • Arrow keys move focus and skip disabled tabs; Enter/Space activates the focused button. Home/End moves to the first/last enabled tab. Tab leaves the list. Manual activation avoids starting work merely by moving keyboard focus.
  • Set aria-orientation="vertical" on the list for Up/Down keys and a vertical layout. Horizontal keys follow RTL direction. Existing tab--vertical means icon above label, and is independent of list orientation.
  • Use native disabled or aria-disabled="true" on panel buttons. Navigation links should be omitted when unavailable; do not put aria-disabled on a live href and expect CSS to prevent navigation.
  • Run() is idempotent across instances. Destroy() releases owned handlers and permits reinitialization; it retains the current DOM state.
  • tab__container--scrollable keeps long lists within the viewport. Focus rings stay inside the control. Reduced-motion and forced-colors modes are supported.

Smaller size

Use tab--smaller on a tab or tab__container--smaller on the container for 32px horizontal tabs, reduced padding and vertical icon size. Defaults remain 40px. See shared sizing guidance.

Build and examples

Run npm run build:tab from the repository root. Open example/index.html through a local HTTP server. The package retains Tab, Run(), custom class options, and existing dist/* import paths. Version 1.1.0 adds navigation styling, panel accessibility, scoped initialization, keyboard handling, cleanup and TypeScript declarations.

References: shadcn/ui Tabs, Material 3 Tabs, Material Web Tabs, WAI-ARIA Tabs Pattern. The supplied Downloads/tab files informed the existing class and indicator design.