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

pict-section-navigation

v1.2.0

Published

Pict Section for categorized, searchable application navigation — a navigation graph with swappable render types (hub, sidebar, command palette, list), a docked-sidebar style, and a ⌘K launcher overlay.

Readme

pict-section-navigation

Categorized, searchable application navigation for Pict apps. One navigation graph, four swappable render types — a Hub of cards, a search-first Sidebar, a Command Palette, and a Grouped List — all with live search and inline help.

A Pict section built around a provider that holds your navigation as a JSON tree and a set of views that render that same tree different ways. Decide the information architecture once; try it as cards, a sidebar, a ⌘K palette, or a settings list without touching your data.

Installation

npm install pict-section-navigation

Usage

const libPict = require('pict');
const libPictSectionNavigation = require('pict-section-navigation');

const _Pict = new libPict();

// Register the provider with your navigation graph. It registers the four
// render-type views (Navigation-Hub, Navigation-Sidebar, Navigation-Palette,
// Navigation-List) for you.
_Pict.addProvider('Pict-Navigation',
    {
        NavigationGraph:
        [
            {
                Name: 'Catalog', Icon: 'fas fa-book', Accent: 'var(--theme-color-brand-primary)', Blurb: 'The books.',
                Children:
                [
                    { Name: 'Books',   Icon: 'fas fa-book',     Route: '#/books',   Keywords: 'title isbn', Description: 'Every title you sell.' },
                    { Name: 'Authors', Icon: 'fas fa-user-pen', Route: '#/authors',                         Description: 'Who wrote the books.' }
                ]
            }
        ]
    },
    libPictSectionNavigation);

// Route for real when an item is activated (otherwise hash-style Routes are followed).
_Pict.providers['Pict-Navigation'].onNavigate = (pNode) =>
{
    window.location.hash = (pNode.Route || '').replace(/^#/, '');
};

// Render any render type into a container.
_Pict.providers['Pict-Navigation'].render('Hub', '#Navigation-Container');
<div id="Navigation-Container"></div>

The navigation graph

A JSON tree of nodes. Top-level nodes are categories; their Children are the destinations. Nodes are normalized on load (each gets a Hash).

| Field | Applies to | Meaning | |---|---|---| | Name | all | Display label. | | Description | items | One-line inline help shown under the name. | | Blurb | categories | Short tagline shown beside the category heading. | | Icon | all | An icon class string, rendered as <i class="…"> (Font Awesome, etc.). | | Accent | all | A CSS color (or theme token) for the node's icon. | | Route | items | Where the node goes. Hash routes (#/…) are followed by default. | | Keywords | items | Extra words search should match. | | Advanced | items | Hidden while browsing; revealed by "Show advanced" or a search. | | Secondary | categories | De-emphasized section (e.g. analytics). | | Hash | all | Stable id (auto-derived from Name if omitted). | | Children | categories | The nodes inside the category. |

Render types

All four read the same graph and provide live search; advanced items are progressively disclosed and revealed by search. Each has a layoutpage (renders as a home screen) or rail (a persistent docked sidebar) — exposed via getRenderTypes() so a host can build a "navigation style" chooser without hard-coding the list.

| Render type | View | Layout | | |---|---|---|---| | Sidebar | Navigation-Sidebar | rail | A grouped, searchable rail. Docked (ShowDetail: false) it is a persistent app sidebar; standalone (ShowDetail: true, the default) it is a two-pane home screen with a detail pane. | | Hub | Navigation-Hub | page | Categorized cards with descriptions — the "settings home". | | List | Navigation-List | page | A scannable single column of grouped name + description rows. | | Palette | Navigation-Palette | page | A ⌘K-style search list with keyboard navigation (↑/↓/Enter/Esc) and category tags. Also the engine behind the launcher overlay. |

Each view takes a NavigationProviderHash option (default Pict-Navigation) so you can point custom view instances at a specific provider.

Page vs. rail — the docked sidebar

getRenderTypeLayout(type) / isRailRenderType(type) let a host treat the Sidebar style as a persistent docked rail and the others as home screens. Render the docked rail with one call:

const nav = _Pict.providers['Pict-Navigation'];
if (nav.isRailRenderType(style))
{
    nav.renderSidebarDocked('#App-Sidebar');   // rail only; item clicks navigate the host
}
else
{
    nav.render(style, '#App-Home');             // Hub / List / Palette as a home screen
}

Keep the docked rail's active highlight in step with the current route from your router:

nav.setActiveByRoute(window.location.hash);
_Pict.views['Navigation-Sidebar-Docked'].syncActive();

Pre-filtered (scoped) rendering

Render a subset of the graph — the basis for topic / per-area nav pages. Pass Scope (an array of category hashes) and/or Filter (an item predicate) to render():

// A topic page showing only the "people-access" category:
nav.render('List', '#Users-Nav', { Scope: ['people-access'] });

For app-wide gating (session/role visibility) set a global filter once — every render (lists, docked sidebar, launcher) honors it, on top of any per-call Scope/Filter:

// Hide items flagged { Headlight: true } unless this is the Headlight session:
nav.setGlobalFilter((item) => !item.Headlight || isHeadlightSession());

getFilteredCategories({ Scope, Filter }) and searchFlat(query, { Scope, Filter }) accept the same options directly.

Command-palette launcher (⌘K) + keyboard

The provider ships a built-in launcher overlay — the Palette render type in a centered modal over a backdrop, the Slack/Linear quick-switcher. It has its own local search (so it never disturbs a docked sidebar's state) and closes on navigate, backdrop click, or Escape.

nav.bindLauncherHotkey();   // ⌘K / Ctrl+K toggles the launcher; Escape closes it
// or drive it yourself:
nav.openLauncher();  nav.closeLauncher();  nav.toggleLauncher();  nav.isLauncherOpen();

bindLauncherHotkey() installs one safe, capture-phase keydown listener (it only ever intercepts ⌘/Ctrl+K and Escape-while-open) and returns an idempotent unbind function.

Provider API

Graph & search

  • setNavigationGraph(pGraph) / getNavigationGraph() — set / get the (normalized) tree.
  • getFilteredCategories(pOptions?) — categories with their items filtered by Query + ShowAdvanced (and optional Scope / Filter). The data source for hub / sidebar / list.
  • searchFlat(pQuery?, pOptions?) — a flat [{ Item, Category }] of all matching items (palette); honors Scope / Filter.
  • setGlobalFilter(fn) / getGlobalFilter() — an app-wide item gate applied to every render.
  • setQuery / getQuery, setShowAdvanced / getShowAdvanced, setActive / getActive.
  • matchesNode(pNode, pQuery), highlight(pText, pQuery), escapeHTML(pStr).

Lookup & navigation

  • getNodeByHash(pHash) / getNodeByRoute(pRoute) — find a node by hash or route (leading # optional).
  • setActiveByRoute(pRoute) — mark the node matching a route active (for syncing a docked rail).
  • navigate(pNodeOrHash) — activate a node (calls onNavigate, else follows a hash Route; dismisses the launcher if open).

Render types & layout

  • getRenderTypes()[{ Key, Label, Layout, Icon, Blurb }], in display order (build a chooser from this).
  • getRenderTypeLayout(pType) / isRailRenderType(pType)'page' vs 'rail'.
  • render(pRenderType, pDestinationAddress?) — render a render type into a destination.
  • renderSidebarDocked(pDestinationAddress) — render the Sidebar as a docked rail (rail only; item clicks navigate).

Launcher & keyboard

  • openLauncher() / closeLauncher() / toggleLauncher() / isLauncherOpen().
  • bindLauncherHotkey() — install the ⌘/Ctrl+K + Escape global shortcut; returns an idempotent unbind fn.

Theming

The views paint with the pict --theme-color-* tokens (with neutral fallbacks), so they inherit a pict-provider-theme / host theme automatically. Node icons use the host's icon font; the views' own chrome glyphs come from the Pict icon registry.

Example Application

See example_applications/bookstore/ — one bookstore back-office navigation graph rendered all four ways, with a render-type switcher.

cd example_applications/bookstore
npm run build      # quack build + copy
npm run serve      # http://localhost:8236

License

MIT — same as the rest of the Retold suite.