@sanring/gx-pagination
v1.0.6
Published
完整、靈活且高效能的 Angular 分頁組件庫,基於 Angular 20+ 和 Signal-based 架構。
Readme
@sanring/gx-pagination
完整、靈活且高效能的 Angular 分頁組件庫,基於 Angular 20+ 和 Signal-based 架構。
特性
- ✅ 多種模式: 支援 Select(下拉)、Input(輸入)、List(按鈕列表)三種分頁選擇模式
- ✅ 完全響應式: 使用 Angular Signals 實現高效能狀態管理
- ✅ 模組化設計: 可組合的子組件,靈活搭配使用
- ✅ 彈性佈局: 支援多種佈局位置(left, center, right, between)
- ✅ 每頁數量選擇: 內建每頁顯示數量選擇器
- ✅ TypeScript: 完整的類型定義
- ✅ 獨立組件: 完全支援 Standalone API
- ✅ PaginationService: 提供完整的分頁狀態管理
安裝
```bash npm install @sanring/gx-pagination
or
yarn add @sanring/gx-pagination ```
快速開始
1. 基本使用(Select 模式)
```typescript import { Component } from '@angular/core'; import { GxPagination, SelectType } from '@sanring/gx-pagination';
@Component({ selector: 'app-basic-pagination', standalone: true, imports: [GxPagination], template: ` <gx-pagination [currentPageInput]="currentPage" [pageSizeInput]="pageSize" [totalItemsInput]="totalItems" [selectType]="SelectType.SELECT" (pageChange)="onPageChange($event)" /> ` }) export class BasicPaginationComponent { SelectType = SelectType; currentPage = 1; pageSize = 10; totalItems = 100;
onPageChange(page: number) { this.currentPage = page; console.log('當前頁:', page); } } ```
2. Input 輸入模式
```typescript @Component({ template: ` <gx-pagination [currentPageInput]="currentPage" [pageSizeInput]="pageSize" [totalItemsInput]="totalItems" [selectType]="SelectType.INPUT" [inputConfig]="{ placeholder: '請輸入頁碼', inputClass: 'custom-input' }" (pageChange)="onPageChange($event)" /> ` }) export class InputPaginationComponent { SelectType = SelectType; // ... } ```
3. List 按鈕列表模式
```typescript @Component({ template: ` <gx-pagination [currentPageInput]="currentPage" [pageSizeInput]="pageSize" [totalItemsInput]="totalItems" [selectType]="SelectType.LIST" (pageChange)="onPageChange($event)" /> ` }) export class ListPaginationComponent { SelectType = SelectType; // ... } ```
4. 帶每頁數量選擇器
```typescript @Component({ template: ` <gx-pagination [currentPageInput]="currentPage" [pageSizeInput]="pageSize" [totalItemsInput]="totalItems" [showPerPageSelector]="true" [perPageOptions]="[10, 20, 50, 100]" [currentPerPage]="pageSize" (pageChange)="onPageChange($event)" (perPageChange)="onPerPageChange($event)" /> ` }) export class PerPagePaginationComponent { currentPage = 1; pageSize = 10; totalItems = 100;
onPageChange(page: number) { this.currentPage = page; // 載入新頁面資料 }
onPerPageChange(size: number) { this.pageSize = size; this.currentPage = 1; // 重置到第一頁 // 重新載入資料 } } ```
5. 自訂佈局位置
```typescript @Component({ template: ` <gx-pagination [currentPageInput]="currentPage" [pageSizeInput]="pageSize" [totalItemsInput]="totalItems" [selectorPosition]="'center'" [showPerPageSelector]="true" (pageChange)="onPageChange($event)" />
<!-- 兩端對齊(預設) -->
<gx-pagination
[currentPageInput]="currentPage"
[pageSizeInput]="pageSize"
[totalItemsInput]="totalItems"
[selectorPosition]="'between'"
[showPerPageSelector]="true"
(pageChange)="onPageChange($event)"
/>` }) export class LayoutPaginationComponent { // ... } ```
6. 使用 PaginationService(進階)
```typescript import { Component, signal, effect } from '@angular/core'; import { GxPagination, PaginationService } from '@sanring/gx-pagination';
@Component({ selector: 'app-advanced-pagination', standalone: true, imports: [GxPagination], providers: [PaginationService], template: ` <gx-pagination [currentPageInput]="paginationService.currentPage()" [pageSizeInput]="paginationService.pageSize()" [totalItemsInput]="paginationService.totalItems()" (pageChange)="paginationService.goToPage($event)" (perPageChange)="paginationService.changePageSize($event)" />
<div>
目前顯示: {{ paginationService.startIndex() }} -
{{ paginationService.endIndex() }} /
{{ paginationService.totalItems() }}
</div>` }) export class AdvancedPaginationComponent { constructor(public paginationService: PaginationService) { // 初始化分頁服務 this.paginationService.initialize({ currentPage: 1, pageSize: 10, totalItems: 100, pageSizeOptions: [10, 20, 50, 100] });
// 監聽分頁狀態變化
effect(() => {
const state = this.paginationService.getState();
console.log('分頁狀態:', state);
// 這裡可以呼叫 API 載入資料
});} } ```
API 文件
GxPagination Inputs
| 屬性 | 類型 | 預設值 | 說明 |
|------|------|--------|------|
| currentPageInput | number | 必填 | 當前頁碼 |
| pageSizeInput | number | 必填 | 每頁顯示數量 |
| totalItemsInput | number | 必填 | 總項目數 |
| selectType | SelectType | SelectType.SELECT | 選擇模式 |
| button | PaginationButton | 預設按鈕配置 | 上一頁/下一頁按鈕配置 |
| customClass | PaginationCustomClass | {} | 自訂 CSS class |
| inputConfig | PaginationInputProps | {} | 輸入框配置(INPUT 模式) |
| selectorPosition | SelectorPosition | 'between' | 分頁控制器位置 |
| showPerPageSelector | boolean | false | 是否顯示每頁數量選擇器 |
| perPageOptions | number[] | [5, 10, 20, 50] | 每頁選項 |
| currentPerPage | number \| undefined | undefined | 當前每頁數量(同步用) |
GxPagination Outputs
| 事件 | 參數 | 說明 |
|------|------|------|
| pageChange | number | 頁碼變更 |
| pageNext | number | 下一頁 |
| pagePrevious | number | 上一頁 |
| perPageChange | number | 每頁數量變更 |
SelectType 枚舉
```typescript enum SelectType { SELECT = 'select', // 下拉選單 INPUT = 'input', // 輸入框 LIST = 'list' // 按鈕列表 } ```
SelectorPosition 類型
```typescript type SelectorPosition = 'left' | 'center' | 'right' | 'between'; ```
left: 分頁控制器靠左center: 分頁控制器居中right: 分頁控制器靠右(靠近每頁選擇器)between: 兩端對齊(預設)
PaginationService 方法
| 方法 | 參數 | 說明 |
|------|------|------|
| initialize() | PaginationServiceOptions | 初始化服務 |
| goToPage() | page: number | 跳轉到指定頁 |
| nextPage() | - | 下一頁 |
| previousPage() | - | 上一頁 |
| firstPage() | - | 第一頁 |
| lastPage() | - | 最後一頁 |
| changePageSize() | size: number | 更改每頁數量 |
| updateTotalItems() | total: number | 更新總項目數 |
| reset() | - | 重置到第一頁 |
| getState() | - | 獲取當前狀態 |
PaginationService 計算屬性(Signals)
| 屬性 | 類型 | 說明 |
|------|------|------|
| currentPage() | number | 當前頁碼 |
| pageSize() | number | 每頁數量 |
| totalItems() | number | 總項目數 |
| totalPages() | number | 總頁數 |
| hasPrevious() | boolean | 是否有上一頁 |
| hasNext() | boolean | 是否有下一頁 |
| startIndex() | number | 當前頁起始索引 |
| endIndex() | number | 當前頁結束索引 |
| isFirstPage() | boolean | 是否為第一頁 |
| isLastPage() | boolean | 是否為最後一頁 |
子組件
GxPaginationInput
輸入框形式的頁碼選擇器。
```typescript import { GxPaginationInput } from '@sanring/gx-pagination';
<gx-pagination-input [currentPage]="1" [totalPages]="10" [placeholder]="'頁碼'" (pageChange)="onPageChange($event)" /> ```
GxPaginationSelect
下拉選單形式的頁碼選擇器。
```typescript import { GxPaginationSelect } from '@sanring/gx-pagination';
<gx-pagination-select [currentPage]="1" [totalPages]="10" (pageChange)="onPageChange($event)" /> ```
GxPaginationList
按鈕列表形式的頁碼選擇器。
```typescript import { GxPaginationList } from '@sanring/gx-pagination';
<gx-pagination-list [currentPage]="1" [totalPages]="10" (pageChange)="onPageChange($event)" /> ```
GxPaginationPerPage
每頁數量選擇器。
```typescript import { GxPaginationPerPage } from '@sanring/gx-pagination';
<gx-pagination-per-page name="per-page" [(perPage)]="pageSize" [perPageOptions]="[10, 20, 50]" (perPageChange)="onPerPageChange($event)" /> ```
樣式自訂
所有組件都支援 CSS 變數自訂:
```css :root { /* 按鈕 */ --gx-pagination-button-color: #374151; --gx-pagination-button-bg: #ffffff; --gx-pagination-button-border: #d1d5db;
/* 懸停狀態 */ --gx-pagination-button-hover-bg: #f3f4f6;
/* 當前頁 */ --gx-pagination-active-color: #ffffff; --gx-pagination-active-bg: #3b82f6; } ```
與 @sanring/gx-table 整合
```typescript import { GxPagination } from '@sanring/gx-pagination'; import { GxTableShell, TableService } from '@sanring/gx-table';
@Component({ template: ` <thead gx-table-header [columns]="columns"> <tbody gx-table-body [data]="pagedData()">
<div footer>
<gx-pagination
[currentPageInput]="currentPage"
[pageSizeInput]="pageSize"
[totalItemsInput]="totalItems"
(pageChange)="onPageChange($event)"
/>
</div>
</gx-table-shell>` }) export class TableWithPaginationComponent { // ... } ```
版本要求
- Angular >= 20.0.0
- TypeScript >= 5.8.0
授權
MIT
