ps-helix 6.2.0 → 6.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A comprehensive Angular component library built with Angular 22+ featuring modern design patterns, accessibility-first development, and optimal developer experience.
4
4
 
5
- [![npm version](https://img.shields.io/badge/npm-6.2.0-blue.svg)](https://www.npmjs.com/package/ps-helix)
5
+ [![npm version](https://img.shields.io/badge/npm-6.2.1-blue.svg)](https://www.npmjs.com/package/ps-helix)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
  [![Angular](https://img.shields.io/badge/Angular-22.0.0-red.svg)](https://angular.dev/)
8
8
  [![TypeScript](https://img.shields.io/badge/TypeScript-6.0.0-blue.svg)](https://www.typescriptlang.org/)
@@ -106,7 +106,7 @@ After installation, verify that ps-helix is in your `package.json`:
106
106
  ```json
107
107
  {
108
108
  "dependencies": {
109
- "ps-helix": "^6.2.0"
109
+ "ps-helix": "^6.2.1"
110
110
  }
111
111
  }
112
112
  ```
@@ -1182,7 +1182,7 @@ Copyright (c) 2025 PACK Solutions
1182
1182
 
1183
1183
  ---
1184
1184
 
1185
- **Version**: 6.2.0
1185
+ **Version**: 6.2.1
1186
1186
  **Built with**: Angular 22.0.0, TypeScript 6.0.0, Phosphor Icons 2.0.3
1187
1187
  **Author**: Fabrice PEREZ | Design Engineer at PACK Solutions
1188
1188
  **Last Updated**: January 2026
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, computed, ChangeDetectionStrategy, Component, model, inject, ElementRef, signal, PLATFORM_ID, ViewEncapsulation, InjectionToken, viewChild, effect, Injectable, DestroyRef, Directive, ViewContainerRef, ChangeDetectorRef, ViewChild, Injector, afterNextRender, HostListener, Renderer2, contentChild, linkedSignal, EventEmitter, Output, Input, contentChildren } from '@angular/core';
2
+ import { input, output, computed, ChangeDetectionStrategy, Component, model, inject, ElementRef, signal, PLATFORM_ID, ViewEncapsulation, InjectionToken, viewChild, effect, Injectable, DestroyRef, Directive, ViewContainerRef, ChangeDetectorRef, ViewChild, Injector, afterNextRender, HostListener, Renderer2, contentChild, linkedSignal, isDevMode, EventEmitter, Output, Input, contentChildren } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule, DOCUMENT, isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
5
5
  import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
@@ -3505,16 +3505,31 @@ class PshPaginationComponent {
3505
3505
  this.itemsPerPageInput = input(10, { ...(ngDevMode ? { debugName: "itemsPerPageInput" } : /* istanbul ignore next */ {}), alias: 'itemsPerPage' });
3506
3506
  this.itemsPerPage = linkedSignal(this.itemsPerPageInput, /* @ts-ignore */
3507
3507
  ...(ngDevMode ? [{ debugName: "itemsPerPage" }] : /* istanbul ignore next */ []));
3508
+ /**
3509
+ * Number of pages used for rendering and navigation: never below 1, and never
3510
+ * written back to the `totalPages` input. `totalPages` is derived data owned by
3511
+ * the caller (`Math.ceil(total / pageSize)`, or a server-side page count), so the
3512
+ * component reads it and clamps its own view of it instead of correcting it.
3513
+ */
3514
+ this.effectiveTotalPages = computed(() => {
3515
+ const total = this.totalPages();
3516
+ return Number.isInteger(total) && total >= 1 ? total : 1;
3517
+ }, /* @ts-ignore */
3518
+ ...(ngDevMode ? [{ debugName: "effectiveTotalPages" }] : /* istanbul ignore next */ []));
3508
3519
  this.size = input(this.config.size ?? 'medium', { ...(ngDevMode ? { debugName: "size" } : /* istanbul ignore next */ {}), transform: (value) => {
3509
3520
  if (!['small', 'medium', 'large'].includes(value)) {
3510
- console.warn(`[psh-pagination] Invalid size "${value}", falling back to "medium"`);
3521
+ if (isDevMode()) {
3522
+ console.warn(`[psh-pagination] Invalid size "${value}", falling back to "medium"`);
3523
+ }
3511
3524
  return 'medium';
3512
3525
  }
3513
3526
  return value;
3514
3527
  } });
3515
3528
  this.variant = input(this.config.variant ?? 'default', { ...(ngDevMode ? { debugName: "variant" } : /* istanbul ignore next */ {}), transform: (value) => {
3516
3529
  if (!['default', 'outline'].includes(value)) {
3517
- console.warn(`[psh-pagination] Invalid variant "${value}", falling back to "default"`);
3530
+ if (isDevMode()) {
3531
+ console.warn(`[psh-pagination] Invalid variant "${value}", falling back to "default"`);
3532
+ }
3518
3533
  return 'default';
3519
3534
  }
3520
3535
  return value;
@@ -3559,7 +3574,7 @@ class PshPaginationComponent {
3559
3574
  const pages = [];
3560
3575
  const halfVisible = Math.floor(this.maxVisiblePages() / 2);
3561
3576
  let start = Math.max(1, this.currentPage() - halfVisible);
3562
- const end = Math.min(this.totalPages(), start + this.maxVisiblePages() - 1);
3577
+ const end = Math.min(this.effectiveTotalPages(), start + this.maxVisiblePages() - 1);
3563
3578
  if (end - start + 1 < this.maxVisiblePages()) {
3564
3579
  start = Math.max(1, end - this.maxVisiblePages() + 1);
3565
3580
  }
@@ -3571,60 +3586,70 @@ class PshPaginationComponent {
3571
3586
  ...(ngDevMode ? [{ debugName: "pages" }] : /* istanbul ignore next */ []));
3572
3587
  this.state = computed(() => this.getState(), /* @ts-ignore */
3573
3588
  ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
3574
- this.canGoNext = computed(() => this.currentPage() < this.totalPages(), /* @ts-ignore */
3589
+ this.canGoNext = computed(() => this.currentPage() < this.effectiveTotalPages(), /* @ts-ignore */
3575
3590
  ...(ngDevMode ? [{ debugName: "canGoNext" }] : /* istanbul ignore next */ []));
3576
3591
  this.canGoPrevious = computed(() => this.currentPage() > 1, /* @ts-ignore */
3577
3592
  ...(ngDevMode ? [{ debugName: "canGoPrevious" }] : /* istanbul ignore next */ []));
3578
3593
  this.isFirstPage = computed(() => this.currentPage() === 1, /* @ts-ignore */
3579
3594
  ...(ngDevMode ? [{ debugName: "isFirstPage" }] : /* istanbul ignore next */ []));
3580
- this.isLastPage = computed(() => this.currentPage() === this.totalPages(), /* @ts-ignore */
3595
+ this.isLastPage = computed(() => this.currentPage() === this.effectiveTotalPages(), /* @ts-ignore */
3581
3596
  ...(ngDevMode ? [{ debugName: "isLastPage" }] : /* istanbul ignore next */ []));
3582
3597
  this.currentPageAnnouncement = computed(() => {
3583
- return `Page ${this.currentPage()} sur ${this.totalPages()}`;
3598
+ return `Page ${this.currentPage()} sur ${this.effectiveTotalPages()}`;
3584
3599
  }, /* @ts-ignore */
3585
3600
  ...(ngDevMode ? [{ debugName: "currentPageAnnouncement" }] : /* istanbul ignore next */ []));
3586
- effect(() => {
3587
- const total = this.totalPages();
3588
- if (total < 1 || !Number.isFinite(total)) {
3589
- console.warn(`[psh-pagination] Invalid totalPages "${total}", setting to 1`);
3590
- this.totalPages.set(1);
3591
- }
3592
- });
3601
+ if (isDevMode()) {
3602
+ effect(() => {
3603
+ // `0` is a legitimate state (empty list, or a server-side page count that is
3604
+ // not loaded yet): stay silent. Only report what betrays a caller bug.
3605
+ const total = this.totalPages();
3606
+ if (total !== 0 && (!Number.isInteger(total) || total < 1)) {
3607
+ console.warn(`[psh-pagination] Invalid totalPages "${total}", using 1 page`);
3608
+ }
3609
+ });
3610
+ effect(() => {
3611
+ const maxVisible = this.maxVisiblePages();
3612
+ if (maxVisible < 1 || !Number.isFinite(maxVisible)) {
3613
+ console.warn(`[psh-pagination] Invalid maxVisiblePages "${maxVisible}", must be >= 1`);
3614
+ }
3615
+ });
3616
+ }
3617
+ // `currentPage` IS owned by the component (it navigates), so correcting it with
3618
+ // a write-back is the intended behaviour — clamped on the derived page count.
3593
3619
  effect(() => {
3594
3620
  const current = this.currentPage();
3595
- const total = this.totalPages();
3621
+ const total = this.effectiveTotalPages();
3596
3622
  if (current < 1 || !Number.isFinite(current)) {
3597
- console.warn(`[psh-pagination] Invalid currentPage "${current}", setting to 1`);
3623
+ if (isDevMode()) {
3624
+ console.warn(`[psh-pagination] Invalid currentPage "${current}", setting to 1`);
3625
+ }
3598
3626
  this.currentPage.set(1);
3599
3627
  }
3600
- else if (current > total && total >= 1) {
3601
- console.warn(`[psh-pagination] currentPage "${current}" exceeds totalPages "${total}", setting to ${total}`);
3628
+ else if (current > total) {
3629
+ if (isDevMode()) {
3630
+ console.warn(`[psh-pagination] currentPage "${current}" exceeds totalPages "${total}", setting to ${total}`);
3631
+ }
3602
3632
  this.currentPage.set(total);
3603
3633
  }
3604
3634
  });
3605
- effect(() => {
3606
- const maxVisible = this.maxVisiblePages();
3607
- if (maxVisible < 1 || !Number.isFinite(maxVisible)) {
3608
- console.warn(`[psh-pagination] Invalid maxVisiblePages "${maxVisible}", must be >= 1`);
3609
- }
3610
- });
3611
3635
  }
3612
3636
  getState() {
3613
3637
  if (this.currentPage() === 1)
3614
3638
  return 'first';
3615
- if (this.currentPage() === this.totalPages())
3639
+ if (this.currentPage() === this.effectiveTotalPages())
3616
3640
  return 'last';
3617
3641
  return 'default';
3618
3642
  }
3619
3643
  goToPage(page) {
3620
- if (page !== this.currentPage() && page >= 1 && page <= this.totalPages()) {
3644
+ const total = this.effectiveTotalPages();
3645
+ if (page !== this.currentPage() && page >= 1 && page <= total) {
3621
3646
  this.currentPage.set(page);
3622
3647
  this.pageChange.emit(page);
3623
3648
  }
3624
- else if (page < 1 || page > this.totalPages()) {
3649
+ else if (page < 1 || page > total) {
3625
3650
  this.navigationError.emit({
3626
3651
  action: 'goToPage',
3627
- reason: `Page ${page} is out of bounds (1-${this.totalPages()})`,
3652
+ reason: `Page ${page} is out of bounds (1-${total})`,
3628
3653
  });
3629
3654
  }
3630
3655
  }
@@ -3632,7 +3657,7 @@ class PshPaginationComponent {
3632
3657
  this.goToPage(1);
3633
3658
  }
3634
3659
  goToLastPage() {
3635
- this.goToPage(this.totalPages());
3660
+ this.goToPage(this.effectiveTotalPages());
3636
3661
  }
3637
3662
  goToNextPage() {
3638
3663
  if (this.canGoNext()) {