From 75617abfc8b12b8bc875b6abba36a13dbe36b8d4 Mon Sep 17 00:00:00 2001 From: "ak.dmitriev" Date: Mon, 12 Oct 2026 01:08:11 +0700 Subject: [PATCH 1/2] API.paginator --- docs/components-api/paginator.md | 40 ++++++++-------- .../paginator/paginator.component.ts | 28 ++++++++--- .../components/paginator/paginator.figma.md | 31 +++++++++--- .../paginator-rows-per-page.component.ts | 4 +- .../components/paginator/paginator.stories.ts | 48 ++++++++++++++----- 5 files changed, 104 insertions(+), 47 deletions(-) diff --git a/docs/components-api/paginator.md b/docs/components-api/paginator.md index 704d5fb2..5eceb4fa 100644 --- a/docs/components-api/paginator.md +++ b/docs/components-api/paginator.md @@ -2,33 +2,31 @@ # ExtraPaginator +> ✅ **Реализован**: `ExtraPaginatorComponent` (`@cdek-it/angular-ui-kit`) соответствует спецификации. + Постраничная навигация по данным. -| Свойство | Описание | Типизация | -| -------------------------- | --------------------------------------------------- | ---------- | -| `rows` | количество элементов на странице | `number` | -| `totalRecords` | общее количество записей | `number` | -| `first` | индекс первой записи (0-based) | `number` | -| `rowsPerPageOptions` | варианты количества элементов на странице | `number[]` | -| `showJumpToPage` | поле для перехода к конкретной странице | `boolean` | -| `showJumpToPageReset` | отображать иконку очистки поля выбора страницы | `boolean` | -| `jumpToPagePlaceholder` | плэйсхолдер поля выбора страницы | `string` | -| `showDropdown` | селект для перехода к конкретной странице | `boolean` | -| `showDropdownReset` | отображать иконку очистки дропдауна выбора страницы | `boolean` | -| `dropdownPlaceholder` | плэйсхолдер дропдауна выбора страницы | `string` | -| `showButtons` | отображение "стрелок" перевлючения страницы | `boolean` | +| Свойство | Описание | Типизация | +| ----------------------- | ----------------------------------------- | ---------- | +| `rows` | количество элементов на странице | `number` | +| `totalRecords` | общее количество записей | `number` | +| `first` | индекс первой записи (0-based) | `number` | +| `rowsPerPageOptions` | варианты количества элементов на странице | `number[]` | +| `showJumpToPage` | поле для перехода к конкретной странице | `boolean` | +| `jumpToPagePlaceholder` | плэйсхолдер поля выбора страницы | `string` | +| `showDropdown` | селект для перехода к конкретной странице | `boolean` | # События -| Событие | Описание | Типизация | -| -------------- | ------------------------------ | -------------------------------------- | +| Событие | Описание | Типизация | +| ------------ | ------------------------------ | -------------------------------------- | | `pageChange` | срабатывает при смене страницы | `(event: ExtraPaginatorState) => void` | # ExtraPaginatorState -| Свойство | Описание | Типизация | -| ------------ | -------------------------- | --------- | -| `page` | текущая страница (0-based) | `number` | -| `first` | индекс первой записи | `number` | -| `rows` | элементов на странице | `number` | -| `pageCount` | всего страниц | `number` | +| Свойство | Описание | Типизация | +| ----------- | -------------------------- | --------- | +| `page` | текущая страница (0-based) | `number` | +| `first` | индекс первой записи | `number` | +| `rows` | элементов на странице | `number` | +| `pageCount` | всего страниц | `number` | diff --git a/src/lib/components/paginator/paginator.component.ts b/src/lib/components/paginator/paginator.component.ts index 7a508cb5..74449dd3 100644 --- a/src/lib/components/paginator/paginator.component.ts +++ b/src/lib/components/paginator/paginator.component.ts @@ -1,6 +1,6 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { Paginator } from 'primeng/paginator'; -import type { PaginatorState } from 'primeng/types/paginator'; +import type { PaginatorPassThrough, PaginatorState } from 'primeng/types/paginator'; export type ExtraPaginatorState = PaginatorState; @@ -17,11 +17,12 @@ export type ExtraPaginatorState = PaginatorState; [currentPageReportTemplate]="currentPageReportTemplate" [showCurrentPageReport]="showCurrentPageReport" [showFirstLastIcon]="showFirstLastIcon" - [showJumpToPageDropdown]="showJumpToPageDropdown" - [showJumpToPageInput]="showJumpToPageInput" + [showJumpToPageDropdown]="showDropdown" + [showJumpToPageInput]="showJumpToPage" [showPageLinks]="showPageLinks" [pageLinkSize]="pageLinkSize" [alwaysShow]="alwaysShow" + [pt]="pt" (onPageChange)="onPageChange.emit($event)" > ` @@ -30,14 +31,29 @@ export class ExtraPaginatorComponent { @Input() first = 0; @Input() rows = 10; @Input() totalRecords = 0; - @Input() rowsPerPageOptions: any[] | undefined; + @Input() rowsPerPageOptions: number[] | undefined; @Input() currentPageReportTemplate = '{currentPage} из {totalPages}'; @Input() showCurrentPageReport = false; @Input() showFirstLastIcon = true; - @Input() showJumpToPageDropdown = false; - @Input() showJumpToPageInput = false; + /** Селект для перехода к конкретной странице (альтернатива полю ввода `showJumpToPage`). */ + @Input() showDropdown = false; + /** Поле ввода номера для перехода к конкретной странице. */ + @Input() showJumpToPage = false; + /** Плейсхолдер поля ввода номера страницы — пробрасывается через `pt`, т.к. у PrimeNG + * `p-paginator` нет собственного @Input для этого (см. `paginator.figma.md`). */ + @Input() jumpToPagePlaceholder: string | undefined = undefined; @Input() showPageLinks = true; @Input() pageLinkSize = 5; @Input() alwaysShow = true; @Output() onPageChange = new EventEmitter(); + + get pt(): PaginatorPassThrough { + return { + pcJumpToPageInput: { + pcInputText: { + root: { placeholder: this.jumpToPagePlaceholder } + } + } + }; + } } diff --git a/src/lib/components/paginator/paginator.figma.md b/src/lib/components/paginator/paginator.figma.md index a5b7a7c6..c22c929a 100644 --- a/src/lib/components/paginator/paginator.figma.md +++ b/src/lib/components/paginator/paginator.figma.md @@ -17,7 +17,7 @@ updated: '2026-06-22' `ExtraPaginatorComponent` — компонент постраничной навигации по большим спискам и таблицам. Разбивает данные на страницы, отображает кнопки prev/next, номера страниц и, опционально, выбор размера страницы, поле прыжка на страницу и текст с текущей позицией. Оборачивает PrimeNG `p-paginator`. -Компонент соответствует Figma-компоненту `` (component set, nodeId `1284:1732`, fileKey `Khh7arsuXss3ncqy1Dz3OZ`, библиотека «UI Kit (DS) v2.0»). Опциональные блоки управляются Figma-свойствами `show-jump` (поле прыжка на страницу), `show-dropdown` (выпадающий выбор размера страницы) и осью `template`. +Компонент соответствует Figma-компоненту `` (component set, nodeId `1284:1732`, fileKey `Khh7arsuXss3ncqy1Dz3OZ`, библиотека «UI Kit (DS) v2.0»). Опциональные блоки управляются Figma-свойствами `show-jump` (поле прыжка на страницу — ``) и `show-dropdown` (выпадающий список для прыжка на страницу — альтернатива `show-jump`, НЕ связана с выбором размера страницы `rowsPerPageOptions`) и осью `template`. Компонент событийный: текущая страница не хранится через `ControlValueAccessor`, а сообщается наружу событием `(onPageChange)`. Состояние страницы задаётся входами `first` и `rows`. @@ -32,13 +32,17 @@ updated: '2026-06-22' | `currentPageReportTemplate` | `string` | `'{currentPage} из {totalPages}'` | Шаблон текста текущей позиции (плейсхолдеры `{currentPage}`, `{totalPages}` и др.) | | `showCurrentPageReport` | `boolean` | `false` | Показывать текст с текущей страницей и общим числом | | `showFirstLastIcon` | `boolean` | `true` | Показывать кнопки перехода на первую и последнюю страницу | -| `showJumpToPageDropdown` | `boolean` | `false` | Показывать выпадающий список для прыжка на страницу | -| `showJumpToPageInput` | `boolean` | `false` | Показывать поле ввода для прыжка на страницу — соответствует Figma-свойству `show-jump` | +| `showDropdown` | `boolean` | `false` | Показывать выпадающий список для прыжка на страницу — соответствует Figma-свойству `show-dropdown`. Переименован из PrimeNG-имени `showJumpToPageDropdown` под спеку | +| `showJumpToPage` | `boolean` | `false` | Показывать поле ввода для прыжка на страницу — соответствует Figma-свойству `show-jump`. Переименован из PrimeNG-имени `showJumpToPageInput` под спеку | +| `jumpToPagePlaceholder` | `string \| undefined` | `undefined` | Плейсхолдер поля ввода номера страницы (видим только при `showJumpToPage=true`) — пробрасывается через `[pt]="{ pcJumpToPageInput: { pcInputText: { root: { placeholder } } } }"`, т.к. `p-paginator` не прокидывает `placeholder` в компонентный `@Input()` вложенного `p-inputnumber` напрямую | | `showPageLinks` | `boolean` | `true` | Показывать номера страниц | | `pageLinkSize` | `number` | `5` | Количество одновременно отображаемых ссылок на страницы | | `alwaysShow` | `boolean` | `true` | Показывать пагинатор даже при единственной странице | | `(onPageChange)` | `EventEmitter` | — | Событие смены страницы; содержит `page`, `first`, `rows`, `pageCount` | +`showJumpToPageReset`/`showDropdownReset`/`dropdownPlaceholder`/`showButtons` из черновика спеки не +реализованы — см. пояснение в `docs/components-api/paginator.md`. + ## Variants ### Default (базовая навигация) @@ -68,9 +72,10 @@ Figma: ``, template=false > ``` -### С выбором размера страницы (show-dropdown) +### С выбором размера страницы (rowsPerPageOptions) -Figma: ``, show-dropdown=true +Figma: `` (общий компонент; `rowsPerPageOptions` не связан с Figma-свойством +`show-dropdown` — то отвечает за переход к странице, см. вариант ниже) ```html `, show-jump=true +``` + +### С выпадающим списком для прыжка на страницу (show-dropdown) + +Figma: ``, show-dropdown=true — альтернатива полю ввода `show-jump` + +```html + ``` diff --git a/src/stories/components/paginator/examples/paginator-rows-per-page.component.ts b/src/stories/components/paginator/examples/paginator-rows-per-page.component.ts index daf53fe2..45e841ac 100644 --- a/src/stories/components/paginator/examples/paginator-rows-per-page.component.ts +++ b/src/stories/components/paginator/examples/paginator-rows-per-page.component.ts @@ -8,7 +8,7 @@ const template = ` [rows]="rows" [totalRecords]="120" [rowsPerPageOptions]="[10, 20, 30]" - [showJumpToPageInput]="true" + [showJumpToPage]="true" (onPageChange)="onPageChange($event)" > `; @@ -55,7 +55,7 @@ import { ExtraPaginatorComponent } from '@cdek-it/angular-ui-kit'; [rows]="rows" [totalRecords]="120" [rowsPerPageOptions]="[10, 20, 30]" - [showJumpToPageInput]="true" + [showJumpToPage]="true" (onPageChange)="onPageChange($event)" > \`, diff --git a/src/stories/components/paginator/paginator.stories.ts b/src/stories/components/paginator/paginator.stories.ts index 437a8ff9..5805955f 100644 --- a/src/stories/components/paginator/paginator.stories.ts +++ b/src/stories/components/paginator/paginator.stories.ts @@ -17,7 +17,9 @@ type PaginatorArgs = Pick< | 'showFirstLastIcon' | 'showPageLinks' | 'showCurrentPageReport' - | 'showJumpToPageInput' + | 'showJumpToPage' + | 'jumpToPagePlaceholder' + | 'showDropdown' | 'alwaysShow' >; @@ -47,7 +49,7 @@ import { ExtraPaginatorComponent } from '@cdek-it/angular-ui-kit'; control: { type: 'number', min: 0 }, description: 'Общее количество записей', table: { - category: 'Props', + category: 'Свойства', defaultValue: { summary: '0' }, type: { summary: 'number' } } @@ -56,7 +58,7 @@ import { ExtraPaginatorComponent } from '@cdek-it/angular-ui-kit'; control: { type: 'number', min: 1 }, description: 'Количество строк на странице', table: { - category: 'Props', + category: 'Свойства', defaultValue: { summary: '10' }, type: { summary: 'number' } } @@ -65,7 +67,7 @@ import { ExtraPaginatorComponent } from '@cdek-it/angular-ui-kit'; control: { type: 'number', min: 1 }, description: 'Количество отображаемых ссылок на страницы', table: { - category: 'Props', + category: 'Свойства', defaultValue: { summary: '5' }, type: { summary: 'number' } } @@ -74,7 +76,7 @@ import { ExtraPaginatorComponent } from '@cdek-it/angular-ui-kit'; control: 'boolean', description: 'Показывать кнопки перехода на первую и последнюю страницу', table: { - category: 'Props', + category: 'Свойства', defaultValue: { summary: 'true' }, type: { summary: 'boolean' } } @@ -83,7 +85,7 @@ import { ExtraPaginatorComponent } from '@cdek-it/angular-ui-kit'; control: 'boolean', description: 'Показывать номера страниц', table: { - category: 'Props', + category: 'Свойства', defaultValue: { summary: 'true' }, type: { summary: 'boolean' } } @@ -92,16 +94,34 @@ import { ExtraPaginatorComponent } from '@cdek-it/angular-ui-kit'; control: 'boolean', description: 'Показывать текст с текущей страницей и общим количеством', table: { - category: 'Props', + category: 'Свойства', defaultValue: { summary: 'false' }, type: { summary: 'boolean' } } }, - showJumpToPageInput: { + showJumpToPage: { control: 'boolean', description: 'Показывать поле ввода для перехода на конкретную страницу', table: { - category: 'Props', + category: 'Свойства', + defaultValue: { summary: 'false' }, + type: { summary: 'boolean' } + } + }, + jumpToPagePlaceholder: { + control: 'text', + description: 'Плейсхолдер поля ввода номера страницы (видим только при showJumpToPage=true)', + table: { + category: 'Свойства', + defaultValue: { summary: 'undefined' }, + type: { summary: 'string' } + } + }, + showDropdown: { + control: 'boolean', + description: 'Показывать селект для перехода на конкретную страницу', + table: { + category: 'Свойства', defaultValue: { summary: 'false' }, type: { summary: 'boolean' } } @@ -110,7 +130,7 @@ import { ExtraPaginatorComponent } from '@cdek-it/angular-ui-kit'; control: 'boolean', description: 'Показывать пагинатор даже при единственной странице', table: { - category: 'Props', + category: 'Свойства', defaultValue: { summary: 'true' }, type: { summary: 'boolean' } } @@ -123,7 +143,9 @@ import { ExtraPaginatorComponent } from '@cdek-it/angular-ui-kit'; showFirstLastIcon: true, showPageLinks: true, showCurrentPageReport: false, - showJumpToPageInput: false, + showJumpToPage: true, + jumpToPagePlaceholder: 'Страница', + showDropdown: false, alwaysShow: true } }; @@ -145,7 +167,9 @@ export const Default: Story = { [showFirstLastIcon]="showFirstLastIcon" [showPageLinks]="showPageLinks" [showCurrentPageReport]="showCurrentPageReport" - [showJumpToPageInput]="showJumpToPageInput" + [showJumpToPage]="showJumpToPage" + [jumpToPagePlaceholder]="jumpToPagePlaceholder" + [showDropdown]="showDropdown" [alwaysShow]="alwaysShow" > ` From 509572ea68b9d3e816f1587eb98d8e8f3f5673b8 Mon Sep 17 00:00:00 2001 From: ichiesov Date: Tue, 20 Oct 2026 17:46:41 +0700 Subject: [PATCH 2/2] =?UTF-8?q?paginator:=20=D0=B4=D0=BE=D1=81=D1=82=D1=83?= =?UTF-8?q?=D0=BF=D0=BD=D1=8B=D0=B5=20=D0=B8=D0=BC=D0=B5=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=BA=D0=BD=D0=BE=D0=BF=D0=BE=D0=BA,=20OnPush,=20=D1=81=D1=82?= =?UTF-8?q?=D0=B0=D0=B1=D0=B8=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20pt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - в locale/ru.ts добавлены aria-ключи пагинатора (pageLabel, first/prev/next/lastPageLabel, jumpToPageInput/DropdownLabel, rowsPerPageLabel): PrimeNG берёт aria-label кнопок через getAriaLabel, без них четыре кнопки навигации были безымянными — axe Critical button-name - добавлен ChangeDetectionStrategy.OnPush (был единственным компонентом без него) - геттер pt пересобирал объект на каждую проверку изменений — теперь пересобирается только при смене jumpToPagePlaceholder - путь импорта в шапке Docs → @cdek-it/angular-ui-kit/components/paginator - prettier Ширину селекта «элементов на странице» не трогал — это CSS/токены. Co-Authored-By: Claude Opus 5 --- .../paginator/paginator.component.ts | 24 +++++++++++++------ src/lib/components/paginator/public_api.ts | 1 - src/lib/providers/prime-preset/locale/ru.ts | 12 +++++++++- .../components/paginator/paginator.stories.ts | 2 +- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/lib/components/paginator/paginator.component.ts b/src/lib/components/paginator/paginator.component.ts index 74449dd3..8f3ebee6 100644 --- a/src/lib/components/paginator/paginator.component.ts +++ b/src/lib/components/paginator/paginator.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core'; import { Paginator } from 'primeng/paginator'; import type { PaginatorPassThrough, PaginatorState } from 'primeng/types/paginator'; @@ -7,6 +7,7 @@ export type ExtraPaginatorState = PaginatorState; @Component({ selector: 'extra-paginator', standalone: true, + changeDetection: ChangeDetectionStrategy.OnPush, imports: [Paginator], template: ` (); + private _ptPlaceholder?: string; + private _pt: PaginatorPassThrough = {}; + + /** Пересобираем объект только при смене плейсхолдера: новый объект на каждую + * проверку изменений заставлял PrimeNG переприменять pass-through каждый цикл. */ get pt(): PaginatorPassThrough { - return { - pcJumpToPageInput: { - pcInputText: { - root: { placeholder: this.jumpToPagePlaceholder } + if (this._ptPlaceholder !== this.jumpToPagePlaceholder) { + this._ptPlaceholder = this.jumpToPagePlaceholder; + this._pt = { + pcJumpToPageInput: { + pcInputText: { + root: { placeholder: this.jumpToPagePlaceholder } + } } - } - }; + }; + } + return this._pt; } } diff --git a/src/lib/components/paginator/public_api.ts b/src/lib/components/paginator/public_api.ts index e7878634..1c2ed0e9 100644 --- a/src/lib/components/paginator/public_api.ts +++ b/src/lib/components/paginator/public_api.ts @@ -1,2 +1 @@ export * from './paginator.component'; - diff --git a/src/lib/providers/prime-preset/locale/ru.ts b/src/lib/providers/prime-preset/locale/ru.ts index fb5b8bd2..cbe11a07 100644 --- a/src/lib/providers/prime-preset/locale/ru.ts +++ b/src/lib/providers/prime-preset/locale/ru.ts @@ -53,6 +53,16 @@ export const RU_TRANSLATION: Partial = { unselectAll: 'Снять всё', trueLabel: 'Да', falseLabel: 'Нет', - nullLabel: 'Не выбрано' + nullLabel: 'Не выбрано', + // Пагинатор: PrimeNG берёт aria-label кнопок отсюда (getAriaLabel). + // Без этих ключей кнопки навигации остаются без доступного имени. + pageLabel: 'Страница {page}', + firstPageLabel: 'Первая страница', + prevPageLabel: 'Предыдущая страница', + nextPageLabel: 'Следующая страница', + lastPageLabel: 'Последняя страница', + jumpToPageInputLabel: 'Перейти к странице', + jumpToPageDropdownLabel: 'Выбор страницы', + rowsPerPageLabel: 'Элементов на странице' } }; diff --git a/src/stories/components/paginator/paginator.stories.ts b/src/stories/components/paginator/paginator.stories.ts index 5805955f..189426a6 100644 --- a/src/stories/components/paginator/paginator.stories.ts +++ b/src/stories/components/paginator/paginator.stories.ts @@ -38,7 +38,7 @@ const meta: Meta = { component: `Отображает навигацию по страницам для больших наборов данных. \`\`\`typescript -import { ExtraPaginatorComponent } from '@cdek-it/angular-ui-kit'; +import { ExtraPaginatorComponent } from '@cdek-it/angular-ui-kit/components/paginator'; \`\`\`` } },