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

v0.76.5

Published

Pagination bar with first/prev/next/last and nearby page buttons, optional “showing X–Y of total” text, configurable page-size input or select, and optional sort field and direction controls with i18n labels.

Downloads

4,073

Readme

hb-paginate — integrator guide

Category: utilities · Tags: utilities, navigation · Package: @htmlbricks/hb-paginate

Summary

Pagination bar with first, previous, next, and last controls plus nearby page number buttons. Optionally shows a “from–to of total” range line, a configurable page size control (numeric input or dropdown backed by nested web components), and optional sort field and direction controls with localized labels.

Nested components: this element registers hb-input-number and hb-input-select (same bundle version) for page size editing when info.page_size_type is set.

Internationalization

Supported languages in metadata: English (en) and Italian (it). Set the optional i18nlang attribute to choose dictionary strings (for example labels such as “of”, “size”, “sort”, “default”, “asc”, “desc”).

Attributes (HTML / reflected props)

Web component attributes use snake_case. Values from HTML are strings; numeric props accept string forms that parse to integers.

| Attribute | Required | Description | |-----------|----------|-------------| | page | No | Current zero-based page index (coerced to a non‑negative integer; invalid or empty values fall back to 0). | | pages | No | Total number of pages (coerced to a non‑negative integer; implementation default 1). When 0, numbered navigation is not shown. | | id | No | Optional element id. | | style | No | Optional inline host style (typed on the component interface). | | info | No | Optional toolbar configuration: either an object (e.g. Svelte/JS) or a JSON string (typical in HTML). Parsed once; invalid JSON is ignored. See Info object. | | i18nlang | No | Language code, e.g. en or it. |

Info object

When present, info drives the optional top row (range text and/or page size) and sort UI. All fields are optional unless noted.

| Field | Type (logical) | Description | |-------|----------------|-------------| | total | number | Total item count. Together with size, enables the range label “start–end of total”. total may be 0 and still show the line if size is set. | | size | number | Page size used for the range calculation and as the current value for page size controls. | | page_size_type | "number" | "select" | If set, shows a page size block: number uses hb-input-number (min 1); select uses hb-input-select when options resolve to a non‑empty list. | | page_size_options | string, string[], or number[] | For select: comma‑separated list (e.g. "10,25,50,100"), a JSON array string, or an array after info is parsed. Values become option value and label. | | sort_fields | { value: string; label?: string }[] | If the array has at least one entry, the sort field dropdown appears. Option values are field.value; labels default to the value when label is omitted. | | sort_by | string | Currently selected sort field value. Empty string selects the synthetic Default row when applicable. | | sort_direction | "asc" | "desc" | "default" | Current sort direction; drives the direction toggle icon and labels. | | sort_disabled | boolean | Disables the sort <select> and the direction button. | | sort_direction_disabled | boolean | Hides the direction toggle entirely (sort field may still show). | | sort_strict_direction | boolean | When true, direction cycles asc ↔ desc only (no default state). Choosing “Default” in the field list sets direction to asc instead of default. | | sort_default_value | string | Value for the Default sort option (per type definition: emitted as sort_by when default is selected). Example: withSortDefaultMatchingField in extra/docs.ts. | | sort_default_label | string | Overrides the translated Default label for the empty-value option (e.g. "Relevance"). Also affects whether an extra default <option> is rendered when it would duplicate a field label. |

Top row visibility: A compact paginate bar (range and/or page size) is rendered when total is defined (including 0) together with size, and/or when page_size_type is set. If neither applies, only the pagination <nav> is shown so layout stays tight.

Range text: Displays indices size * page + 1 through min(size * (page + 1), total), then the localized “of” and total.

Page size change: changePageSize fires only for a finite integer > 0 that differs from the current info.size (after numeric coercion).

Sort change: changeSort fires when the user changes the sort field or toggles direction. The component syncs internal state from info.sort_by / info.sort_direction when those props update. Changing the field to empty sets direction to default unless sort_strict_direction is set (then asc). Selecting a non‑empty field while direction was default moves direction to asc.

Events

Listen with addEventListener or framework equivalents. detail shapes:

| Event | detail | |-------|----------| | pageChange | { page: number; pages: number }page is the new zero-based index; pages is the total page count the component used. | | changePageSize | { page_size: number } | | changeSort | { sort_by: string; sort_direction: "asc" \| "desc" \| "default" } |

Styling (Bulma CSS variables)

The component uses Bulma 1.x inside the shadow root. Theme it by setting these --bulma-* variables on a host ancestor (for example :root or body) so they inherit onto the custom element. Defaults below match extra/docs.ts.

| Variable | Type | Default | Role | |----------|------|---------|------| | --bulma-primary | color | #00d1b2 | Primary brand color (current page and accents). | | --bulma-link | color | #485fc7 | Link and interactive accent. | | --bulma-border | color | #dbdbdb | Borders for controls and pagination. | | --bulma-radius | length | 0.375rem | Base border radius for controls. | | --bulma-text | color | #363636 | Primary copy (labels, page numbers, toolbar). | | --bulma-text-weak | color | #7a7a7a | Muted text (e.g. range line). |

CSS ::part

| Part | Description | |------|-------------| | page-size-input | Exposed on the nested hb-input-number used for page_size_type: "number" (page size width and styling). |

Slots

None (htmlSlots is empty in extra/docs.ts).

TypeScript typings (authoring)

From types/webcomponent.type.d.ts:

export type Component = {
  id?: string;
  style?: string;
  pages?: number;
  page?: number;
  info?: {
    total?: number;
    size?: number;
    /** Type of page size selector: "number" for free input, "select" for dropdown */
    page_size_type?: "number" | "select";
    /** Page size options for select mode: comma-separated string, JSON array string, or array after `info` is parsed */
    page_size_options?: string | string[] | number[];
    /** Available sort fields. At least one must be present to show the sort indicator */
    sort_fields?: { value: string; label?: string }[];
    /** Currently selected sort field */
    sort_by?: string;
    /** Current sort direction */
    sort_direction?: "asc" | "desc" | "default";
    /** Whether the sort controls are disabled */
    sort_disabled?: boolean;
    /** Whether the sort direction is disabled */
    sort_direction_disabled?: boolean;
    /** When true, sort_direction can only be "asc" or "desc" (no "default" state) */
    sort_strict_direction?: boolean;
    /** Value for the "Default" sort option (emitted as sort_by when default is selected) */
    sort_default_value?: string;
    /** Custom label for the "Default" sort option (e.g. "Relevance") */
    sort_default_label?: string;
  };
  i18nlang?: string;
};

export type Events = {
  pageChange: { page: number; pages: number };
  changePageSize: { page_size: number };
  changeSort: { sort_by: string; sort_direction: "asc" | "desc" | "default" };
};

HTML examples

Minimal pagination (five pages, start on first page):

<hb-paginate page="0" pages="5" i18nlang="en"></hb-paginate>

Range line and disabled sort direction control:

<hb-paginate
  page="1"
  pages="4"
  i18nlang="en"
  info='{"total":47,"size":10,"sort_direction_disabled":true}'
></hb-paginate>

Page size as a number input:

<hb-paginate
  page="0"
  pages="10"
  i18nlang="en"
  info='{"total":100,"size":10,"page_size_type":"number"}'
></hb-paginate>

Page size as a select (comma-separated options):

<hb-paginate
  page="0"
  pages="4"
  i18nlang="en"
  info='{"total":100,"size":25,"page_size_type":"select","page_size_options":"10,25,50,100"}'
></hb-paginate>

Sort field and direction (JSON array for sort_fields is also supported when encoded as a string attribute):

<hb-paginate
  page="0"
  pages="4"
  i18nlang="en"
  info='{"total":100,"size":25,"sort_fields":[{"value":"title","label":"Title"},{"value":"date","label":"Date"}],"sort_by":"title","sort_direction":"asc"}'
></hb-paginate>
const el = document.querySelector("hb-paginate");
el.addEventListener("pageChange", (e) => {
  console.log(e.detail.page, e.detail.pages);
});
el.addEventListener("changePageSize", (e) => {
  console.log(e.detail.page_size);
});
el.addEventListener("changeSort", (e) => {
  console.log(e.detail.sort_by, e.detail.sort_direction);
});

Additional named scenarios (strict direction, custom default label, combined sort and page size) are listed under examples in extra/docs.ts.