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

@htmlbricks/hb-sidenav-link

v0.76.5

Published

Sidebar nav item: Bootstrap Icons (bi-*), label, optional Bulma-style tag badge (outlined pill: transparent fill, border uses tag foreground color), and either a flat button that dispatches pageChange on click or an expandable group of subLinks with activ

Downloads

3,607

Readme

hb-sidenav-link (sidenav-link)

Category: layout
Tags: layout, navigation
Package: @htmlbricks/hb-sidenav-link

Overview

hb-sidenav-link is a single sidebar navigation row for hierarchical menus. It renders a Bootstrap Icons label row, an optional Bulma-style tag badge (outlined pill: transparent fill, border and text from the tag color), and either:

  • a leaf link that dispatches pageChange when the user activates it, or
  • a parent row with subLinks that expands to show nested links.

Active styling applies when the current page key (navpage) matches a link key, or when the selected flag is enabled. The component is intended for use inside hb-sidebar-desktop lists (and shares the INavLink shape with related layout components).

Bootstrap Icons are loaded from the component (bootstrap-icons CSS on jsDelivr). Icon names are the bi-* suffix only (for example house-doorbi-house-door).

Custom element

<hb-sidenav-link …></hb-sidenav-link>

Props (TypeScript Component)

| Property | Type | Required | Notes | |------------|-------------|----------|--------| | navlink | INavLink | yes | From HTML, pass a JSON string (see below). | | navpage | string | no | Current page key; drives active row and expanded groups. | | selected | boolean | no | When true, forces the “current page” appearance. From HTML use string encodings (see Attributes). | | id | string | no | Optional identifier (typed on the component API). | | style | string | no | Optional inline style (typed on the component API). |

INavLink shape

Used for the root navlink and, recursively, for each entry in subLinks.

| Field | Type | Required | Description | |------------|----------------|----------|-------------| | key | string | yes | Stable id for the link; sent as page in pageChange for leaf clicks. | | label | string | yes | Visible label. | | icon | string | no | Bootstrap Icons name without the bi- prefix. | | group | string | no | Present in the shared nav typings for interoperability. | | badge | object | no | text (string), optional Bulma modifier classes class and classcolor (for example is-rounded, is-light). | | subLinks | INavLink[] | no | If non-empty, the row becomes an expandable group instead of a single leaf. | | active | boolean | no | Present on the shared type; not read by this component’s markup. | | open | boolean | no | When navlink is provided as a JSON string, open: true initializes the group as expanded. |

Badges

badge supports:

  • text — badge label.
  • class — optional Bulma tag class (defaults to is-rounded in the template).
  • classcolor — optional color modifier (defaults to is-light).

Attributes (snake_case; string values in HTML)

Reflects the web component contract: attributes are strings.

| Attribute | Required | Description | |------------|----------|-------------| | navlink | yes | JSON string representing INavLink. | | navpage | no | Current page key string. | | selected | no | Boolean-as-string: yes / no per project conventions. The implementation also treats the literal strings true / yes as true, and treats an empty string as true; any other value becomes false unless already boolean true inside the app. Prefer explicit yes or no from HTML. | | id | no | String. | | style | no | String. |

If navlink arrives as a string, the component parses it as JSON and applies open from the parsed object when open === true.

Events

| Event | detail | When it fires | |-------------|------------------------|----------------| | pageChange | { page: string } | User activates a non-active leaf: either the root row (no subLinks) or a sub-link whose key does not match navpage and is not forced selected. Active rows (matching navpage or selected) are static for accessibility (aria-current="page") and do not dispatch pageChange on click. |

Listen in plain DOM:

document.querySelector('hb-sidenav-link').addEventListener('pageChange', (e) => {
  console.log(e.detail.page);
});

Behavior

Leaf row (no subLinks)

  • If navlink.key === navpage or selected is true: one full-width “current” button (link styling), no click navigation event.
  • Otherwise: ghost button; click dispatches pageChange with detail.page === navlink.key.

Parent row (non-empty subLinks)

  • The parent row is a control that toggles expand/collapse and shows when open or when any child key equals navpage, otherwise .
  • The nested list is shown when the group is open or when some child has key === navpage.
  • Each child follows the same active vs ghost rules as a leaf; inactive children dispatch pageChange with detail.page === that child’s key.

Layout

Labels use a flexible middle column; a fixed-width trail column (--hb-sidenav-trail-width) keeps titles aligned when some rows omit a badge or use the expand chevron. Long badge text is truncated with an ellipsis in the component styles.

Styling (Bulma and component variables)

Buttons and tags live in the shadow root. Theme with public --bulma-* variables on body, :root, or an ancestor; see Bulma CSS variables. Additional tokens are listed in extra/docs.ts.

| CSS custom property | Default (from docs) | Purpose | |--------------------|---------------------|---------| | --bulma-link | #485fc7 | Active row stripe, chevrons, and interactive accents. | | --bulma-link-text | #ffffff | Text color on the active row background mix. | | --bulma-text | #363636 | Default label color for inactive rows. | | --bulma-scheme-main | #ffffff | Row surface behind ghost buttons. | | --bulma-radius | 0.375rem | Row rounding for list items. | | --hb-sidenav-trail-width | 3.5rem | Width of the right column (badges / expand chevron); keeps labels aligned when some rows omit a badge. |

CSS parts

| Part | Description | |------|-------------| | li | Bulma menu list row (li) wrapping the ghost or link button, label column, badge or chevron trail, and nested sub-links. |

Slots: none (htmlSlots is empty).

Examples

Simple leaf

<hb-sidenav-link
  navpage="home"
  navlink='{"label":"Home","key":"home","icon":"house-door"}'
></hb-sidenav-link>

Leaf with badge

<hb-sidenav-link
  navlink='{"label":"Home","key":"home","icon":"house-door","badge":{"text":"3","classcolor":"is-danger"}}'
></hb-sidenav-link>

Expandable group with sub-links

<hb-sidenav-link
  navpage="dash"
  navlink='{"label":"Workspace","key":"workspace","icon":"folder2-open","subLinks":[{"label":"Dashboard","key":"dash","icon":"speedometer2"},{"label":"Projects","key":"projects","icon":"kanban"}]}'
></hb-sidenav-link>

Force selected appearance

<hb-sidenav-link
  selected="yes"
  navlink='{"label":"Home","key":"home","icon":"house-door"}'
></hb-sidenav-link>

Related types

INavLink matches the structure used by hb-offcanvas and hb-sidebar-desktop for navlinks arrays, so the same serialized objects can be reused across layout components.

License

Package metadata references Apache-2.0 (see LICENSE.md in the published package when consuming from npm).