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-offcanvas

v0.76.5

Published

Slide-in panel that hosts hb-sidebar-desktop navigation, with Bulma `modal-background` as optional backdrop when `type` is autohide. Can start open or closed; dispatches page changes and open/close state.

Readme

hb-offcanvas — integrator guide

Category: layout · Tags: layout, navigation · Package: @htmlbricks/hb-offcanvas

Summary

hb-offcanvas is a fixed, slide-in drawer on the start edge of the viewport that embeds hb-sidebar-desktop for branded navigation, page selection, optional theme switching, and optional language switching. When type is autohide, a full-viewport Bulma modal-background layer sits under the panel; clicking the dimmed area closes the drawer. The host raises custom events when the drawer opens or closes, when the active page changes, and when the nested sidebar changes language or theme.

The package depends on hb-sidebar-desktop (which in turn uses hb-sidenav-link). Navigation items use the same JSON shape as the sidebar, including optional Bootstrap Icons glyph names on each link.

Behavior

  • type

    • autohide (default): Renders the backdrop while the drawer is open. Clicking the backdrop calls the internal close path and dispatches offcanvasswitch with isOpen: false.
    • open: After the host’s reactive setup runs, the drawer is treated as always open (the opened attribute is forced to an open state for display).
    • small: No backdrop; open state follows opened like a non-open mode. Use when you want a sliding panel without modal dismissal (same stacking and panel animation as other modes, without the overlay).
  • opened: Initial and runtime open state for modes that are not type="open". In HTML, use string booleans yes / no as for other web components in this library. The implementation treats a truthy opened that is not the string no as open.

  • Page changes: Choosing a nav entry inside hb-sidebar-desktop runs the sidebar’s page handler; the host re-dispatches pageChange with { page: string } and closes the drawer via OpenSwitch(false) (so the drawer does not stay open after navigation in the default wiring).

  • groups: May be a parsed JSON string in the effect; invalid JSON is ignored and leaves the previous value.

Styling (Bulma and host tokens)

The shadow tree uses Bulma-derived tokens for the panel fill, shadow, and (when autohide) backdrop color. Stacking and drawer width are controlled on :host so the drawer can sit above siblings such as a mobile layout shell. See Bulma CSS variables and extra/docs.ts for metadata.

| Variable | Purpose | |----------|---------| | --hb-offcanvas-host-z | Host stacking context so fixed panel and backdrop paint above following light-DOM siblings (default 1038). | | --hb-offcanvas-panel-z | Drawer layer above the backdrop (default 1045). | | --hb-offcanvas-backdrop-z | Backdrop layer (default 1040). | | --hb-offcanvas-panel-width | Drawer width, capped by the viewport (default 240px). | | --bulma-scheme-main | Panel background. | | --bulma-shadow | Elevation shadow on the open drawer. | | --bulma-modal-background-background-color | Backdrop tint when type is autohide. |

The component also loads Bootstrap Icons from jsDelivr for icon font classes used by nested navigation.

CSS parts

None on hb-offcanvas. hb-sidebar-desktop defines its own parts (for example the header row); see the sidebar README for ::part names.

HTML slots

| Slot | Purpose | |------|---------| | test | Optional content at the host root inside #webcomponent, before the panel (for advanced integrations). Main navigation UI lives inside the nested hb-sidebar-desktop, not in this slot. |

Custom element tag

<hb-offcanvas …></hb-offcanvas>

Attributes (snake_case; string values in HTML)

Reflectable props follow the usual conventions: booleans as yes / no, objects and arrays as JSON strings, numbers as decimal strings where applicable.

| Attribute | Required | Description | |-----------|----------|-------------| | id | No | Optional element id. | | style | No | Optional inline host styles. | | type | No | autohide | open | small — backdrop and forced-open behavior (see above). Default in implementation: autohide. | | opened | No | yes / no — whether the drawer is open (ignored for forced-open when type is open). | | navlinks | No | JSON string — INavLink[]: key, label, optional icon (Bootstrap Icons name), group, badge, subLinks, etc. Same contract as hb-sidebar-desktop. | | navpage | No | Active page key string. | | groups | No | JSON string — { key: string; label: string }[] for section labels in the sidebar. | | companylogouri | No | Logo image URI for the sidebar header. | | companytitle | No | Company or product title next to the logo. | | enablefooter | No | yes / no / false (same contract as hb-sidebar-desktop). Forwarded to the nested sidebar; omitted or truthy values keep the sidebar footer enabled (yes). | | enablethemeswitch | No | yes / no — passed through to hb-sidebar-desktop (defaults to yes when unset). | | themepreference | No | light | dark | auto — optional controlled theme for the nested sidebar. | | i18nlang | No | Language code for the nested sidebar. | | i18nlanguages | No | JSON string or structured options — { code: string; label: string }[] for the language picker. |

Events

| Event | Detail | |-------|--------| | offcanvasswitch | { isOpen: boolean } — emitted when the drawer opens or closes (including initial open when type is open or opened is truthy, and when the backdrop closes the drawer). | | pageChange | { page: string } — forwarded from hb-sidebar-desktop when the user selects a page; the offcanvas also closes after dispatching. | | languageChange | { code: string } — bubbled from the nested sidebar’s language control. | | themeChange | { mode: ThemePreference } where ThemePreference is "light" | "dark" | "auto" — bubbled from the nested sidebar’s theme control. |

Usage notes

  • Icons: Use Bootstrap Icons names only (for example house-door), not class strings — same rule as hb-sidebar-desktop.
  • Layering: If the drawer or backdrop appears under a sibling layout, raise --hb-offcanvas-host-z (and panel/backdrop z-tokens if needed) on the host.
  • Examples: Storybook-style examples in extra/docs.ts cover default, closed, autohide, and grouped navigation with footer metadata on the data model.

TypeScript typings (authoring)

From types/webcomponent.type.d.ts:

import type { INavLink } from "../../sidenav-link/types/webcomponent.type";
import type {
  I18nLanguageOption,
  ThemePreference,
} from "../../sidebar-desktop/types/webcomponent.type";

export type Component = {
  id?: string;
  style?: string;
  opened?: boolean;
  navlinks?: INavLink[];
  navpage?: string;
  groups?: { key: string; label: string }[];
  companylogouri?: string;
  companytitle?: string;
  enablefooter?: "yes" | "no" | "false" | null | "" | undefined;
  enablethemeswitch?: "yes" | "no" | null | "" | undefined;
  themepreference?: ThemePreference | null | "" | undefined;
  i18nlang?: string | null | "" | undefined;
  i18nlanguages?: I18nLanguageOption[] | string | null | "" | undefined;
  type?: "open" | "autohide" | "small";
};

export type Events = {
  offcanvasswitch: { isOpen: boolean };
  pageChange: { page: string };
  languageChange: { code: string };
  themeChange: { mode: ThemePreference };
};

Minimal HTML

<hb-offcanvas
  opened="yes"
  type="autohide"
  companytitle="Acme"
  navpage="home"
  navlinks='[{"label":"Home","key":"home","icon":"house-door"}]'
></hb-offcanvas>

Listen for open state and navigation:

<script>
  const el = document.querySelector("hb-offcanvas");
  el.addEventListener("offcanvasswitch", (e) => {
    console.log("open:", e.detail.isOpen);
  });
  el.addEventListener("pageChange", (e) => {
    console.log("page:", e.detail.page);
  });
</script>