# Pagination

分页组件，支持普通分页、简单分页、纯数字分页等多种类型。

## 适用场景

- 数据列表的分页导航
- 需要切换每页数量的表格分页
- 页数较少时使用简单分页（prev-next）
- 仅需页码显示的轻量场景（plain-number）

## Props

### Pagination Props

| 名称 | 类型 | 默认值 | 必填 | 说明 |
|------|------|--------|------|------|
| className | `string` | `""` | 否 | 自定义 class |
| size | `"md" \| "sm" \| "xs"` | - | 否 | 尺寸，默认取 config context `baseSize` |
| disabled | `boolean` | `false` | 否 | 是否禁用 |
| type | `"normal" \| "prev-next" \| "plain-number"` | `"normal"` | 否 | 类型：normal 普通，prev-next 上一页/下一页，plain-number 简单页码 |
| withTotal | `boolean` | `true` | 否 | 是否显示总页数 |
| withPageSize | `boolean` | `true` | 否 | 是否显示 pageSize 下拉菜单 |
| withJumper | `boolean` | `true` | 否 | 是否显示跳页 |
| pageNum | `number` | - | 否 | 当前页数控制值 |
| total | `number` | `0` | 否 | 数据总数 |
| defaultPageNum | `number` | `1` | 否 | 当前页数默认值 |
| pageSize | `number` | - | 否 | 每页数量控制值 |
| defaultPageSize | `number` | `10` | 否 | 每页数量默认值 |
| pageSizeOptions | `number[]` | `[10, 30, 50]` | 否 | 每页数选项值 |
| onChangePageNum | `(pageNum: number, bySizeChange: boolean) => void` | - | 否 | 当前页变化回调；`bySizeChange` 表示是否由 pageSize 变化触发 |
| beforeChangePageNum | `(pageNum: number, bySizeChange: boolean) => boolean \| void \| Promise<any>` | - | 否 | pageNum 变化前回调，返回 false 或 reject 可阻止变化 |
| onChangePageSize | `(pageSize: number) => void` | - | 否 | 每页数量变化回调 |
| beforeChangePageSize | `(pageNum: number) => boolean \| void \| Promise<any>` | - | 否 | pageSize 变化前回调，返回 false 或 reject 可阻止变化 |

## 典型用法

### 基础受控分页

```tsx
import { useState, useEffect } from 'react'
import { Pagination } from '@befe/brick'

const [pageSize, setPageSize] = useState(10)
const [pageNum, setPageNum] = useState(1)
const [total, setTotal] = useState(100)

useEffect(() => {
    fetchData(pageNum, pageSize).then(count => setTotal(count))
}, [pageNum, pageSize])

<Pagination
    pageNum={pageNum}
    pageSize={pageSize}
    onChangePageSize={setPageSize}
    onChangePageNum={setPageNum}
    total={total}
/>
```

### 简单分页

```tsx
// 页数较少（<6页）时建议使用
<Pagination total={50} type="prev-next" />
```

### 纯数字分页

```tsx
<Pagination total={100} type="plain-number" />
```

### 变化前拦截

```tsx
import { confirm } from '@befe/brick'

<Pagination
    pageNum={pageNum}
    pageSize={pageSize}
    total={total}
    beforeChangePageNum={(pageNum) => new Promise((resolve, reject) => {
        confirm({
            headline: '注意',
            content: `是否跳转到第 ${pageNum} 页`,
            onConfirm: resolve,
            onCancel: reject,
        })
    })}
    onChangePageNum={setPageNum}
    onChangePageSize={setPageSize}
/>
```

## 注意事项

- change pageSize 会自动触发 `jumpPage(1)` 以保证页码合法，因此不要在 `onChangePageSize` 中重复执行 `onChangePageNum` 的逻辑
- normal 类型支持 `md` | `sm` | `xs`，plain-number 和 prev-next 类型仅支持 `md` | `sm`
- 当 `beforeChangePageNum` 返回 Promise 时，change pageSize 触发的 jumpPage(1) 和 pageSize setting 可能不在同一渲染周期；使用状态驱动的写法时，可在 `onChangePageSize` 中一并设置 `pageNum(1)` 并在 `onChangePageNum` 中忽略 `bySizeChange === true` 的情况，避免 effect 重复触发
