@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.
