Таблица данных и списки для Angular | ng-hub-ui-paginable

Таблица данных и постраничный список для Angular с серверной пагинацией, сортировкой, фильтрацией, выбором, шаблонами и CSS-переменными.

Справочник API

Вот полный контракт paginable: всё, что можно привязать, прослушать, спроецировать и тематизировать, собрано в одном месте. Подключите то, что нужно, и оформите так, как хотите — это standalone и дружит с сигналами.

Входные свойства

Настройте paginable с помощью 36 входных свойств. Привязывайте их, как любой @Input в Angular.

ИмяТипПо умолчаниюОписание
idstring—Identifier of this table instance. Defaults to a generated unique id, so two tables on the same page never share one.
dataT[] | PaginationState<T> | null—Table data, bound with the `data` alias. Pass a plain array to let the table paginate/filter/sort in memory (client mode, when `paginate` is true and `totalItems` is unset); pass a `PaginationState` for server mode (the table renders it as-is and reads `page`/`perPage`/`totalItems` from it).
resourceHubPaginableResource<T> | null—A signal-based resource — `resource()`, `httpResource()` or anything with the same three signals — bound whole. Its value is read exactly as `data` is (array or `PaginationState`), `isLoading()` drives the loading state and `error()` the error state. Bound alongside `data` the resource wins, and changing page never calls `reload()`: whoever owns the request keeps owning it.
headers(PaginableTableHeader | string)[]—Column definitions. A string is shorthand for `{ property, title }`; a `PaginableTableHeader` enables sorting, per-column filters, buttons, sticky/visibility, alignment and templates. Two-way bindable (`model`).
pagenumber | null—Current 1-based page. Two-way bindable (`model`) — emits `pageChange`. Defaults to `null`.
perPagenumber | null—Items per page. Two-way bindable (`model`) — emits `perPageChange`. Defaults to `10`.
perPageOptionsnumber[]—Selectable page sizes shown in the per-page selector. Defaults to `[10, 20, 50, 100]`.
totalItemsnumber | null—Total number of items across all pages (server mode). Setting it keeps the table in server mode even for a plain array. Two-way bindable (`model`) — emits `totalItemsChange`.
paginateboolean—Enables pagination. When `true` (default) with a plain array and no `totalItems`, the table searches, filters, sorts and slices in memory (client mode). Set `false` to render the whole array without pagination.
ordinationPaginableTableOrdination—Active sort (`{ property, direction }`). Two-way bindable (`model`) — emits `ordinationChange` when a sortable header is clicked.
searchableboolean—Shows the global search box. Defaults to `true`.
searchTermstring—Global search term. Two-way bindable (`model`) — emits `searchTermChange` (debounced by `debounce`).
searchFn(item: T, term: string) => boolean—Decides row by row what survives the global search, instead of scanning the searchable columns — which is how you match on a field no column shows. Consulted in client mode only; the term arrives already trimmed and lowercased, the same contract hub-list honours.
compareFn(a: T, b: T) => boolean—Decides when two selection values are the same record, everywhere the table matches the selection against the rows. It receives what the selection stores: the row data, or the `bindValue` property when one is set. Unbound, the matching is what it always was.
filtersRecord<string, unknown> | null—Per-column filter values keyed by `filter.key` or `property`. Two-way bindable (`model`) — emits `filtersChange`.
selectableSelectionTypes | boolean | null—Enables row selection (`true`/`single` draws a radio per row, `multiple` a checkbox). The selected value is read/written through `ControlValueAccessor` (`[(ngModel)]` or a `formControl`).
multipleboolean—Forces multiple selection regardless of `selectable`. Defaults to `false`.
selectWhileSelectingboolean—While at least one row is selected, a click (or Enter/Space on a focused row) marks it instead of running `clickFn`. Off by default: on a pointer a click keeps the meaning the consumer gave it. The mode holds no state — it starts with the first row ticked and ends with the last one unticked. It is a pointer shortcut only: the keyboard marks a row through the checkbox the row itself draws, which is a tab stop already, so the row itself takes focus only when `clickFn` makes it a control in its own right.
bindValuestring—Property of each row used as the selection value instead of the whole object.
clickFn(event: TableRowEvent<T>) => void | Promise<void>—Callback invoked when a row is clicked, receiving the row data plus the originating event.
rowClassstring | ((item: T) => string)—CSS class applied to every row, either a fixed string or a function of the row data.
responsiveTableBreakpoint | null—Breakpoint at which the table switches to its responsive (stacked) layout.
paginationPosition'bottom' | 'top' | 'both'—Where the pagination bar is drawn: `bottom` under the rows, `top` above them, `both` in each place. The whole bar moves — paginator, page-size selector and row count — and each one carries a `hub-table__bottom-bar--top` or `--bottom` modifier. Defaults to `bottom`.
paginationInfoboolean—Shows the "Showing X of Y" info line. Defaults to `true`.
stickyActionsboolean—Keeps the row action column stuck to the viewport while scrolling. Defaults to `false`.
stickyHeaderboolean—Pins the header (`position: sticky; top: 0`) while the body scrolls, inside any consumer `max-height`/`overflow:auto` container — decoupled from `options.scrollable`. Overridable via `--hub-table-head-position`. Defaults to `false`.
flushFieldsbooleanfalseDraws the form controls inside the cells as a spreadsheet does: no border, no surface of their own. A field is boxed so it can be told apart from the page around it, and a table cell already does that job — so the box gets drawn twice and an editable table reads as a form that fell into a table. Static prepend/append content loses its chip and reads as the plain text or icon it is; a projected button stops being welded to its neighbour, getting its corners back, a gap and its own border colour, because two actions in a cell are two things to press rather than one strip. The control regains its shared corners too. It is a token assignment on the cells rather than an input on each field, which is both why it reaches your own cellTpt content and why it needs ng-hub-ui-forms 22.21.0 for the seam tokens.
flushboolean—Draws the collection as a list rather than as a stack of cards: no border, radius or surface per row, a rule between them instead. On `hub-table` it drops the outer border, the radius, the head rule and the cell padding while keeping the row divider, because a table with no line between rows stops being readable across its columns. Right for a list of choices inside a dialog or a panel, where the surface has already drawn the frame. An input rather than something CSS can reach: the token defaults sit on the host, so a consumer class on the same element ties on specificity and loses on source order. Defaults to `false`.
batchActions(PaginableTableDropdown | PaginableActionButton)[]—Actions shown in the toolbar that operate on the currently selected rows. Each button shows its `label`, or its `title` when it declares none.
debouncenumber—Debounce in milliseconds applied to search and filter changes. Defaults to `0`.
optionsPaginableTableOptions—Visual/behavioural options: `striped`, `hoverableRows`, `variant`, `cursor`, `scrollable`, `rtl`…
loadingboolean—Renders the loading state. Two-way bindable (`model`) — emits `loadingChange`.
errorunknown | null—When truthy, renders the error state. Two-way bindable (`model`) — emits `errorChange`.
loadingComponentPaginableStateDefault | null—Per-instance default component for the loading state.
errorComponentPaginableStateDefault | null—Per-instance default component for the error state.
noResultsComponentPaginableStateDefault | null—Per-instance default component for the no-results state.

События

Реагируйте на то, что делает paginable, — 9 событий, к которым можно подключить вашу логику.

ИмяТипОписание
pageChangenumber | nullEmitted by the two-way `page` model when the current page changes.
perPageChangenumber | nullEmitted by the two-way `perPage` model when the page size changes.
totalItemsChangenumber | nullEmitted by the two-way `totalItems` model (e.g. when a `PaginationState` is bound).
ordinationChangePaginableTableOrdinationEmitted by the two-way `ordination` model when sorting changes — use it to drive server-side sorting.
filtersChangeRecord<string, unknown> | nullEmitted by the two-way `filters` model when a column filter changes — use it to drive server-side filtering.
searchTermChangestringEmitted by the two-way `searchTerm` model when the global search changes (debounced by `debounce`).
loadingChangebooleanEmitted by the two-way `loading` model.
errorChangeunknown | nullEmitted by the two-way `error` model.
headersChange(PaginableTableHeader | string)[]Emitted by the two-way `headers` model when the column configuration changes.

Шаблоны

Сделайте его своим — 7 слотов шаблона позволяют проецировать собственную разметку.

ИмяОписаниеПример
headerTptПользовательский шаблон заголовка для определения пользовательских заголовков столбцов<ng-template headerTpt header="name" let-header="header">{{ header.title }}</ng-template>
cellTptПользовательский шаблон ячейки для настройки отрисовки содержимого ячейки<ng-template cellTpt header="name" let-item="item">{{ item.name }}</ng-template>
rowTptПользовательский шаблон строки для определения структуры всей строки<ng-template rowTpt let-row><tr><td>{{ row.data.name }}</td></tr></ng-template>
filterTptПользовательский шаблон фильтра для добавления элементов UI фильтрации<ng-template filterTpt header="name" let-fc="formControl"><input [formControl]="fc"></ng-template>
loadingTptШаблон состояния загрузки для пользовательских индикаторов загрузки<ng-template loadingTpt><div class="spinner"></div></ng-template>
noResultsTptШаблон пустого состояния, отображаемый, когда данные недоступны<ng-template noResultsTpt><p>No data found</p></ng-template>
errorTptШаблон состояния ошибки для обработки ошибочных ситуаций<ng-template errorTpt><p>Something went wrong</p></ng-template>