@canvas-components/react-components 0.3.28 → 0.3.29
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 +96 -65
- package/dist/index.cjs +127 -32
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +127 -32
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -75,7 +75,10 @@ export function ProfileForm() {
|
|
|
75
75
|
<form onSubmit={(event) => event.preventDefault()}>
|
|
76
76
|
<label>
|
|
77
77
|
姓名
|
|
78
|
-
<ReactInput
|
|
78
|
+
<ReactInput
|
|
79
|
+
value={name}
|
|
80
|
+
onChange={(event) => setName(event.currentTarget.value)}
|
|
81
|
+
/>
|
|
79
82
|
</label>
|
|
80
83
|
<label>
|
|
81
84
|
团队
|
|
@@ -97,7 +100,9 @@ export function ProfileForm() {
|
|
|
97
100
|
接收团队动态
|
|
98
101
|
</ReactCheckbox>
|
|
99
102
|
<ReactFlex gap={8}>
|
|
100
|
-
<ReactButton type="primary" htmlType="submit"
|
|
103
|
+
<ReactButton type="primary" htmlType="submit">
|
|
104
|
+
保存
|
|
105
|
+
</ReactButton>
|
|
101
106
|
<ReactPopconfirm title="确认删除?" onConfirm={() => setName("")}>
|
|
102
107
|
<ReactButton danger>删除</ReactButton>
|
|
103
108
|
</ReactPopconfirm>
|
|
@@ -112,7 +117,10 @@ export function ProfileForm() {
|
|
|
112
117
|
`ReactSelect` 的暗色模式通过 `ReactConfigProvider` 配置。输入框与挂载到页面外层的下拉面板会使用同一组颜色:
|
|
113
118
|
|
|
114
119
|
```tsx
|
|
115
|
-
import {
|
|
120
|
+
import {
|
|
121
|
+
ReactConfigProvider,
|
|
122
|
+
ReactSelect,
|
|
123
|
+
} from "@canvas-components/react-components";
|
|
116
124
|
|
|
117
125
|
<ReactConfigProvider
|
|
118
126
|
theme={{
|
|
@@ -127,7 +135,7 @@ import { ReactConfigProvider, ReactSelect } from "@canvas-components/react-compo
|
|
|
127
135
|
}}
|
|
128
136
|
>
|
|
129
137
|
<ReactSelect options={[{ label: "选项一", value: "one" }]} />
|
|
130
|
-
</ReactConfigProvider
|
|
138
|
+
</ReactConfigProvider>;
|
|
131
139
|
```
|
|
132
140
|
|
|
133
141
|
## 组件列表
|
|
@@ -187,6 +195,29 @@ import { ReactConfigProvider, ReactSelect } from "@canvas-components/react-compo
|
|
|
187
195
|
|
|
188
196
|
## 属性说明
|
|
189
197
|
|
|
198
|
+
### `ReactPagination`
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
<ReactPagination
|
|
202
|
+
current={current}
|
|
203
|
+
total={1000}
|
|
204
|
+
pageSize={pageSize}
|
|
205
|
+
showSizeChanger
|
|
206
|
+
allowPageSizeInput
|
|
207
|
+
minPageSize={5}
|
|
208
|
+
maxPageSize={500}
|
|
209
|
+
onChange={setCurrent}
|
|
210
|
+
onPageSizeChange={(page, size) => {
|
|
211
|
+
setCurrent(page);
|
|
212
|
+
setPageSize(size);
|
|
213
|
+
}}
|
|
214
|
+
/>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
`allowPageSizeInput` 默认关闭。开启后可在每页条数下拉框中输入正整数,按回车或失焦提交;合法值触发 `onPageSizeChange(1, size)`,并在当前组件挂载期间作为去重、升序的候选项保留,切换到其他条数后仍可再次选择。空候选列表也支持输入。自定义选项右侧可点击删除,预设选项和默认每页 10 条不可删除;删除当前选中的自定义项时回到每页 10 条并切回第 1 页,若 10 超出配置范围则取范围内最近的值。删除其他项不改变当前分页,删除后仍可重新输入该值。
|
|
218
|
+
|
|
219
|
+
`minPageSize` 默认 `1`,`maxPageSize` 默认 `Number.MAX_SAFE_INTEGER`,上下限均包含边界。非法或越界输入不触发变更,失焦恢复当前值;范围外的候选项不可选择。无效的上下限使用默认值,最大值小于最小值时按最小值处理。组件不会主动修改外部传入的当前 `pageSize`。
|
|
220
|
+
|
|
190
221
|
### `ReactTag`
|
|
191
222
|
|
|
192
223
|
```tsx
|
|
@@ -215,89 +246,89 @@ import { ReactConfigProvider, ReactSelect } from "@canvas-components/react-compo
|
|
|
215
246
|
|
|
216
247
|
### `ReactPopupProps`
|
|
217
248
|
|
|
218
|
-
| 属性
|
|
219
|
-
|
|
|
220
|
-
| `open`
|
|
221
|
-
| `anchorRef`
|
|
222
|
-
| `anchorRect`
|
|
223
|
-
| `placement`
|
|
224
|
-
| `offset`
|
|
225
|
-
| `matchAnchorWidth` | `boolean`
|
|
226
|
-
| `minWidth`
|
|
227
|
-
| `zIndex`
|
|
228
|
-
| `className`
|
|
229
|
-
| `surfaceClassName` | `string`
|
|
230
|
-
| `style`
|
|
231
|
-
| `surfaceStyle`
|
|
232
|
-
| `onOpenChange`
|
|
233
|
-
| `children`
|
|
249
|
+
| 属性 | 类型 | 说明 |
|
|
250
|
+
| ------------------ | ---------------------------------------------------------------------------------------------------------------------- | ------------------ |
|
|
251
|
+
| `open` | `boolean` | 是否显示 |
|
|
252
|
+
| `anchorRef` | `RefObject<HTMLElement \| null>` | 锚点元素引用 |
|
|
253
|
+
| `anchorRect` | `PopupAnchorRect \| null` | 外部传入的锚点矩形 |
|
|
254
|
+
| `placement` | `"bottomLeft" \| "bottomRight" \| "topLeft" \| "topRight" \| "rightTop" \| "rightBottom" \| "leftTop" \| "leftBottom"` | 弹层位置 |
|
|
255
|
+
| `offset` | `number` | 与锚点间距 |
|
|
256
|
+
| `matchAnchorWidth` | `boolean` | 是否跟随锚点宽度 |
|
|
257
|
+
| `minWidth` | `number` | 最小宽度 |
|
|
258
|
+
| `zIndex` | `number` | 层级 |
|
|
259
|
+
| `className` | `string` | 外层类名 |
|
|
260
|
+
| `surfaceClassName` | `string` | 面板类名 |
|
|
261
|
+
| `style` | `CSSProperties` | 外层样式 |
|
|
262
|
+
| `surfaceStyle` | `CSSProperties` | 面板样式 |
|
|
263
|
+
| `onOpenChange` | `(open: boolean) => void` | 打开状态变化回调 |
|
|
264
|
+
| `children` | `ReactNode` | 弹层内容 |
|
|
234
265
|
|
|
235
266
|
### `ReactPopconfirmProps`
|
|
236
267
|
|
|
237
|
-
| 属性
|
|
238
|
-
|
|
|
239
|
-
| `children`
|
|
240
|
-
| `title`
|
|
241
|
-
| `description`
|
|
242
|
-
| `open` / `defaultOpen`
|
|
243
|
-
| `disabled`
|
|
244
|
-
| `placement`
|
|
245
|
-
| `offset`
|
|
246
|
-
| `zIndex`
|
|
247
|
-
| `icon`
|
|
248
|
-
| `okText` / `cancelText`
|
|
249
|
-
| `showCancel`
|
|
250
|
-
| `confirmLoading`
|
|
251
|
-
| `okButtonProps` / `cancelButtonProps` | `ReactPopconfirmButtonProps`
|
|
252
|
-
| `onConfirm`
|
|
253
|
-
| `onCancel`
|
|
254
|
-
| `onOpenChange`
|
|
255
|
-
| `className` / `style`
|
|
256
|
-
| `popupClassName` / `popupStyle`
|
|
268
|
+
| 属性 | 类型 | 说明 |
|
|
269
|
+
| ------------------------------------- | ---------------------------------- | ---------------------------------- |
|
|
270
|
+
| `children` | `ReactNode` | 触发器内容 |
|
|
271
|
+
| `title` | `ReactNode` | 标题 |
|
|
272
|
+
| `description` | `ReactNode` | 描述文本 |
|
|
273
|
+
| `open` / `defaultOpen` | `boolean` | 受控 / 非受控打开状态 |
|
|
274
|
+
| `disabled` | `boolean` | 是否禁用 |
|
|
275
|
+
| `placement` | `ReactPopconfirmPlacement` | 弹层位置 |
|
|
276
|
+
| `offset` | `number` | 触发器与弹层间距 |
|
|
277
|
+
| `zIndex` | `number` | 层级 |
|
|
278
|
+
| `icon` | `ReactNode` | 自定义图标,传 `null` 隐藏默认图标 |
|
|
279
|
+
| `okText` / `cancelText` | `ReactNode` | 按钮文案 |
|
|
280
|
+
| `showCancel` | `boolean` | 是否显示取消按钮 |
|
|
281
|
+
| `confirmLoading` | `boolean` | 是否强制确认按钮 loading |
|
|
282
|
+
| `okButtonProps` / `cancelButtonProps` | `ReactPopconfirmButtonProps` | 按钮透传属性 |
|
|
283
|
+
| `onConfirm` | `(event) => void \| Promise<void>` | 点击确认回调,支持异步 |
|
|
284
|
+
| `onCancel` | `(event) => void` | 点击取消回调 |
|
|
285
|
+
| `onOpenChange` | `(open: boolean) => void` | 状态变化回调 |
|
|
286
|
+
| `className` / `style` | `string` / `CSSProperties` | 触发器样式 |
|
|
287
|
+
| `popupClassName` / `popupStyle` | `string` / `CSSProperties` | 弹层面板样式 |
|
|
257
288
|
|
|
258
289
|
### `ReactTransitionProps`
|
|
259
290
|
|
|
260
|
-
| 属性
|
|
261
|
-
|
|
|
262
|
-
| `show`
|
|
263
|
-
| `name`
|
|
264
|
-
| `duration` | `number \| { enter?: number; leave?: number }` | 动画时长
|
|
265
|
-
| `appear`
|
|
266
|
-
| `children` | `(state: ReactTransitionState) => ReactNode`
|
|
291
|
+
| 属性 | 类型 | 说明 |
|
|
292
|
+
| ---------- | ---------------------------------------------- | ------------------------ |
|
|
293
|
+
| `show` | `boolean` | 是否显示内容 |
|
|
294
|
+
| `name` | `string` | CSS 类名前缀 |
|
|
295
|
+
| `duration` | `number \| { enter?: number; leave?: number }` | 动画时长 |
|
|
296
|
+
| `appear` | `boolean` | 首次显示是否执行进入动画 |
|
|
297
|
+
| `children` | `(state: ReactTransitionState) => ReactNode` | 根据阶段渲染内容 |
|
|
267
298
|
|
|
268
299
|
### `ReactVirtualListProps<Item>`
|
|
269
300
|
|
|
270
|
-
| 属性
|
|
271
|
-
|
|
|
272
|
-
| `items`
|
|
273
|
-
| `height`
|
|
274
|
-
| `itemHeight` | `number`
|
|
275
|
-
| `overscan`
|
|
276
|
-
| `renderItem` | `(item, index, meta) => ReactNode`
|
|
277
|
-
| `itemKey`
|
|
301
|
+
| 属性 | 类型 | 说明 |
|
|
302
|
+
| ------------ | ----------------------------------- | ---------- |
|
|
303
|
+
| `items` | `Item[]` | 数据列表 |
|
|
304
|
+
| `height` | `number` | 视口高度 |
|
|
305
|
+
| `itemHeight` | `number` | 固定项高度 |
|
|
306
|
+
| `overscan` | `number` | 预渲染项数 |
|
|
307
|
+
| `renderItem` | `(item, index, meta) => ReactNode` | 渲染函数 |
|
|
308
|
+
| `itemKey` | `(item, index) => string \| number` | 列表 key |
|
|
278
309
|
|
|
279
310
|
## 方法说明
|
|
280
311
|
|
|
281
312
|
### `ReactTransition`
|
|
282
313
|
|
|
283
|
-
| 导出
|
|
284
|
-
|
|
|
285
|
-
| `ReactTransition`
|
|
286
|
-
| `useReactTransition` | 获取 Vue 风格过渡阶段和 className
|
|
314
|
+
| 导出 | 说明 |
|
|
315
|
+
| -------------------- | -------------------------------------- |
|
|
316
|
+
| `ReactTransition` | 无包装过渡组件,离场动画结束后自动卸载 |
|
|
317
|
+
| `useReactTransition` | 获取 Vue 风格过渡阶段和 className |
|
|
287
318
|
|
|
288
319
|
### `ReactVirtualListRef`
|
|
289
320
|
|
|
290
|
-
| 方法
|
|
291
|
-
|
|
|
292
|
-
| `scrollTo`
|
|
321
|
+
| 方法 | 说明 |
|
|
322
|
+
| --------------- | -------------- |
|
|
323
|
+
| `scrollTo` | 滚动到指定位置 |
|
|
293
324
|
| `scrollToIndex` | 滚动到指定索引 |
|
|
294
325
|
|
|
295
326
|
## 其他导出
|
|
296
327
|
|
|
297
|
-
| 导出
|
|
298
|
-
|
|
|
328
|
+
| 导出 | 说明 |
|
|
329
|
+
| ---------------------------------------------------- | -------------- |
|
|
299
330
|
| `ReactContentScaleProvider` / `useReactContentScale` | 内容缩放上下文 |
|
|
300
|
-
| `REACT_COMPONENT_PREFIX`
|
|
331
|
+
| `REACT_COMPONENT_PREFIX` | 统一类名前缀 |
|
|
301
332
|
|
|
302
333
|
## 说明
|
|
303
334
|
|
package/dist/index.cjs
CHANGED
|
@@ -3578,6 +3578,7 @@ var ReactSelect = React.forwardRef(
|
|
|
3578
3578
|
onFocus,
|
|
3579
3579
|
onKeyDown,
|
|
3580
3580
|
options,
|
|
3581
|
+
renderOptionExtra,
|
|
3581
3582
|
optionHeight = 32,
|
|
3582
3583
|
listHeight = 224,
|
|
3583
3584
|
placeholder,
|
|
@@ -3773,7 +3774,10 @@ var ReactSelect = React.forwardRef(
|
|
|
3773
3774
|
openSelect();
|
|
3774
3775
|
return;
|
|
3775
3776
|
}
|
|
3776
|
-
const targetOption = resolveSelectEnterOption(
|
|
3777
|
+
const targetOption = resolveSelectEnterOption(
|
|
3778
|
+
filteredOptions,
|
|
3779
|
+
activeIndex
|
|
3780
|
+
);
|
|
3777
3781
|
if (targetOption && !targetOption.disabled) {
|
|
3778
3782
|
selectOption(targetOption, "keyboard");
|
|
3779
3783
|
} else if (allowCustomValue && keyword.trim()) {
|
|
@@ -3863,7 +3867,7 @@ var ReactSelect = React.forwardRef(
|
|
|
3863
3867
|
const isSelected = String(option.value) === String(value ?? "");
|
|
3864
3868
|
const isActive = optionIndex === activeIndex;
|
|
3865
3869
|
const isSearching = showSearch && searchKeyword.trim().length > 0;
|
|
3866
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
3870
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3867
3871
|
"div",
|
|
3868
3872
|
{
|
|
3869
3873
|
className: joinClassNames(
|
|
@@ -3886,17 +3890,20 @@ var ReactSelect = React.forwardRef(
|
|
|
3886
3890
|
}
|
|
3887
3891
|
selectOption(option, "mouse");
|
|
3888
3892
|
},
|
|
3889
|
-
children:
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3893
|
+
children: [
|
|
3894
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3895
|
+
"span",
|
|
3896
|
+
{
|
|
3897
|
+
className: `${REACT_COMPONENT_PREFIX}-select-option-label`,
|
|
3898
|
+
title: option.label,
|
|
3899
|
+
children: renderSelectOptionLabel(
|
|
3900
|
+
option.label,
|
|
3901
|
+
showSearch ? searchKeyword : ""
|
|
3902
|
+
)
|
|
3903
|
+
}
|
|
3904
|
+
),
|
|
3905
|
+
renderOptionExtra?.(option)
|
|
3906
|
+
]
|
|
3900
3907
|
},
|
|
3901
3908
|
String(option.value)
|
|
3902
3909
|
);
|
|
@@ -3937,7 +3944,8 @@ function scoreSelectMatch(text, search) {
|
|
|
3937
3944
|
return (index === 0 ? 2 : 1) + search.length / normalized.length;
|
|
3938
3945
|
}
|
|
3939
3946
|
function resolveSelectEnterOption(options, activeIndex = -1) {
|
|
3940
|
-
if (options[activeIndex] && !options[activeIndex].disabled)
|
|
3947
|
+
if (options[activeIndex] && !options[activeIndex].disabled)
|
|
3948
|
+
return options[activeIndex];
|
|
3941
3949
|
return options.find((option) => !option.disabled);
|
|
3942
3950
|
}
|
|
3943
3951
|
function resolveSelectKeywordOnOpen(selectedLabel) {
|
|
@@ -9520,15 +9528,19 @@ function ReactScrollbarPositionDialog(props) {
|
|
|
9520
9528
|
}
|
|
9521
9529
|
|
|
9522
9530
|
// src/components/pagination/style.css
|
|
9523
|
-
styleInject('@import "../../styles/variables.css";\n.canvas-react-pagination {\n --canvas-react-pagination-control-size: 32px;\n --canvas-react-pagination-gap: 8px;\n --canvas-react-pagination-padding-inline: 10px;\n --canvas-react-control-height: var(--canvas-react-pagination-control-size);\n display: flex;\n align-items: center;\n flex-wrap: nowrap;\n gap: var(--canvas-react-pagination-gap);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n white-space: nowrap;\n}\n.canvas-react-pagination-small {\n --canvas-react-pagination-control-size: 24px;\n --canvas-react-pagination-gap: 4px;\n --canvas-react-pagination-padding-inline: 6px;\n}\n.canvas-react-pagination > .canvas-react-select-wrap {\n flex: 0 0 auto;\n width: auto;\n height: auto;\n}\n.canvas-react-pagination > .canvas-react-select-wrap > .canvas-react-select {\n flex-shrink: 0;\n}\n.canvas-react-pagination-large {\n --canvas-react-pagination-control-size: 40px;\n --canvas-react-pagination-gap: 10px;\n --canvas-react-pagination-padding-inline: 14px;\n}\n.canvas-react-pagination-pages {\n display: inline-flex;\n align-items: center;\n gap: var(--canvas-react-pagination-gap);\n flex-wrap: nowrap;\n}\n.canvas-react-pagination-button,\n.canvas-react-pagination-page {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: var(--canvas-react-pagination-control-size);\n height: var(--canvas-react-pagination-control-size);\n padding: 0 var(--canvas-react-pagination-padding-inline);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n cursor: pointer;\n transition:\n border-color 0.2s ease,\n color 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-pagination-button {\n position: relative;\n width: var(--canvas-react-pagination-control-size);\n min-width: var(--canvas-react-pagination-control-size);\n padding: 0;\n}\n.canvas-react-pagination-button:hover,\n.canvas-react-pagination-page:hover {\n border-color: var(--canvas-react-color-primary-hover);\n color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-pagination-page-active {\n border-color: var(--canvas-react-color-primary);\n background: var(--canvas-react-color-bg-active);\n color: var(--canvas-react-color-primary);\n}\n.canvas-react-pagination-button:disabled,\n.canvas-react-pagination-page:disabled {\n opacity: 0.48;\n cursor: not-allowed;\n}\n.canvas-react-pagination-ellipsis {\n color: var(--canvas-react-color-text-muted);\n}\n.canvas-react-pagination-arrow {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 7px;\n height: 7px;\n border-right: 1.5px solid var(--canvas-react-color-text-muted);\n border-bottom: 1.5px solid var(--canvas-react-color-text-muted);\n transition:\n border-color 0.18s ease,\n transform 0.18s ease,\n opacity 0.18s ease;\n}\n.canvas-react-pagination-arrow-prev {\n transform: translate(-42%, -50%) rotate(135deg);\n}\n.canvas-react-pagination-arrow-next {\n transform: translate(-58%, -50%) rotate(-45deg);\n}\n.canvas-react-pagination-button:hover .canvas-react-pagination-arrow {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-pagination-button:disabled .canvas-react-pagination-arrow {\n opacity: 0.56;\n}\n.canvas-react-pagination-quick {\n display: inline-flex;\n align-items: center;\n gap: var(--canvas-react-pagination-gap);\n flex-wrap: nowrap;\n}\n.canvas-react-pagination-total {\n color: var(--canvas-react-color-text-muted);\n}\n.canvas-react-pagination button,\n.canvas-react-pagination input {\n font-family: inherit;\n font-weight: inherit;\n font-size: inherit;\n}\n');
|
|
9531
|
+
styleInject('@import "../../styles/variables.css";\n.canvas-react-pagination {\n --canvas-react-pagination-control-size: 32px;\n --canvas-react-pagination-gap: 8px;\n --canvas-react-pagination-padding-inline: 10px;\n --canvas-react-control-height: var(--canvas-react-pagination-control-size);\n display: flex;\n align-items: center;\n flex-wrap: nowrap;\n gap: var(--canvas-react-pagination-gap);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n white-space: nowrap;\n}\n.canvas-react-pagination-small {\n --canvas-react-pagination-control-size: 24px;\n --canvas-react-pagination-gap: 4px;\n --canvas-react-pagination-padding-inline: 6px;\n}\n.canvas-react-pagination > .canvas-react-select-wrap {\n flex: 0 0 auto;\n width: auto;\n height: auto;\n}\n.canvas-react-pagination > .canvas-react-select-wrap > .canvas-react-select {\n flex-shrink: 0;\n}\n.canvas-react-pagination-large {\n --canvas-react-pagination-control-size: 40px;\n --canvas-react-pagination-gap: 10px;\n --canvas-react-pagination-padding-inline: 14px;\n}\n.canvas-react-pagination-pages {\n display: inline-flex;\n align-items: center;\n gap: var(--canvas-react-pagination-gap);\n flex-wrap: nowrap;\n}\n.canvas-react-pagination-button,\n.canvas-react-pagination-page {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: var(--canvas-react-pagination-control-size);\n height: var(--canvas-react-pagination-control-size);\n padding: 0 var(--canvas-react-pagination-padding-inline);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n cursor: pointer;\n transition:\n border-color 0.2s ease,\n color 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-pagination-button {\n position: relative;\n width: var(--canvas-react-pagination-control-size);\n min-width: var(--canvas-react-pagination-control-size);\n padding: 0;\n}\n.canvas-react-pagination-button:hover,\n.canvas-react-pagination-page:hover {\n border-color: var(--canvas-react-color-primary-hover);\n color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-pagination-page-active {\n border-color: var(--canvas-react-color-primary);\n background: var(--canvas-react-color-bg-active);\n color: var(--canvas-react-color-primary);\n}\n.canvas-react-pagination-button:disabled,\n.canvas-react-pagination-page:disabled {\n opacity: 0.48;\n cursor: not-allowed;\n}\n.canvas-react-pagination-ellipsis {\n color: var(--canvas-react-color-text-muted);\n}\n.canvas-react-pagination-arrow {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 7px;\n height: 7px;\n border-right: 1.5px solid var(--canvas-react-color-text-muted);\n border-bottom: 1.5px solid var(--canvas-react-color-text-muted);\n transition:\n border-color 0.18s ease,\n transform 0.18s ease,\n opacity 0.18s ease;\n}\n.canvas-react-pagination-arrow-prev {\n transform: translate(-42%, -50%) rotate(135deg);\n}\n.canvas-react-pagination-arrow-next {\n transform: translate(-58%, -50%) rotate(-45deg);\n}\n.canvas-react-pagination-button:hover .canvas-react-pagination-arrow {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-pagination-button:disabled .canvas-react-pagination-arrow {\n opacity: 0.56;\n}\n.canvas-react-pagination-quick {\n display: inline-flex;\n align-items: center;\n gap: var(--canvas-react-pagination-gap);\n flex-wrap: nowrap;\n}\n.canvas-react-pagination-total {\n color: var(--canvas-react-color-text-muted);\n}\n.canvas-react-pagination button,\n.canvas-react-pagination input {\n font-family: inherit;\n font-weight: inherit;\n font-size: inherit;\n}\n.canvas-react-pagination-remove-size {\n flex: 0 0 auto;\n margin-left: 6px;\n padding: 0 4px;\n border: 0;\n border-radius: var(--canvas-react-radius-sm);\n background: transparent;\n color: var(--canvas-react-color-text-muted);\n font: inherit;\n cursor: pointer;\n}\n.canvas-react-pagination-remove-size:hover,\n.canvas-react-pagination-remove-size:focus-visible {\n background: var(--canvas-react-color-bg-hover);\n color: var(--canvas-react-color-primary);\n}\n.canvas-react-pagination-remove-size:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n');
|
|
9532
|
+
var DEFAULT_PAGE_SIZE = 10;
|
|
9524
9533
|
var DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 50, 100];
|
|
9525
9534
|
function ReactPagination(props) {
|
|
9526
9535
|
const {
|
|
9536
|
+
allowPageSizeInput = false,
|
|
9537
|
+
minPageSize = 1,
|
|
9538
|
+
maxPageSize = Number.MAX_SAFE_INTEGER,
|
|
9527
9539
|
current,
|
|
9528
9540
|
disabled,
|
|
9529
9541
|
onChange,
|
|
9530
9542
|
onPageSizeChange,
|
|
9531
|
-
pageSize =
|
|
9543
|
+
pageSize = DEFAULT_PAGE_SIZE,
|
|
9532
9544
|
pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,
|
|
9533
9545
|
showLessItems,
|
|
9534
9546
|
showQuickJumper,
|
|
@@ -9542,12 +9554,56 @@ function ReactPagination(props) {
|
|
|
9542
9554
|
} = props;
|
|
9543
9555
|
const style = { ...rootStyle, ...styles?.root };
|
|
9544
9556
|
const [quickValue, setQuickValue] = React.useState("");
|
|
9557
|
+
const [customPageSizes, setCustomPageSizes] = React.useState([]);
|
|
9558
|
+
const pageSizeDraft = React.useRef(null);
|
|
9559
|
+
const sizeChangerRef = React.useRef(null);
|
|
9560
|
+
const minimum = Number.isSafeInteger(minPageSize) && minPageSize > 0 ? minPageSize : 1;
|
|
9561
|
+
const maximum = Number.isSafeInteger(maxPageSize) && maxPageSize > 0 ? Math.max(minimum, maxPageSize) : Number.MAX_SAFE_INTEGER;
|
|
9562
|
+
const defaultPageSize = Math.min(
|
|
9563
|
+
maximum,
|
|
9564
|
+
Math.max(minimum, DEFAULT_PAGE_SIZE)
|
|
9565
|
+
);
|
|
9566
|
+
const isValidPageSize = (value) => Number.isSafeInteger(value) && value >= minimum && value <= maximum;
|
|
9545
9567
|
const resolvedPageSizeOptions = React.useMemo(() => {
|
|
9546
|
-
|
|
9547
|
-
|
|
9568
|
+
const options = allowPageSizeInput ? [.../* @__PURE__ */ new Set([...pageSizeOptions, ...customPageSizes])].sort(
|
|
9569
|
+
(a, b) => a - b
|
|
9570
|
+
) : pageSizeOptions;
|
|
9571
|
+
if (options.length === 0 && !allowPageSizeInput || options.includes(pageSize) || !Number.isSafeInteger(pageSize) || pageSize <= 0) {
|
|
9572
|
+
return options;
|
|
9573
|
+
}
|
|
9574
|
+
return [...options, pageSize].sort((left, right) => left - right);
|
|
9575
|
+
}, [pageSizeOptions, pageSize, customPageSizes, allowPageSizeInput]);
|
|
9576
|
+
const changePageSize = (value) => {
|
|
9577
|
+
pageSizeDraft.current = null;
|
|
9578
|
+
if (disabled || !isValidPageSize(value)) return;
|
|
9579
|
+
if (allowPageSizeInput) {
|
|
9580
|
+
setCustomPageSizes(
|
|
9581
|
+
(sizes) => sizes.includes(value) ? sizes : [...sizes, value]
|
|
9582
|
+
);
|
|
9548
9583
|
}
|
|
9549
|
-
|
|
9550
|
-
}
|
|
9584
|
+
onPageSizeChange?.(1, value);
|
|
9585
|
+
};
|
|
9586
|
+
const removeCustomPageSize = (value) => {
|
|
9587
|
+
if (disabled) return;
|
|
9588
|
+
pageSizeDraft.current = null;
|
|
9589
|
+
sizeChangerRef.current?.blur();
|
|
9590
|
+
setCustomPageSizes((sizes) => sizes.filter((size2) => size2 !== value));
|
|
9591
|
+
if (value === pageSize) {
|
|
9592
|
+
onPageSizeChange?.(1, defaultPageSize);
|
|
9593
|
+
}
|
|
9594
|
+
};
|
|
9595
|
+
const commitPageSizeInput = () => {
|
|
9596
|
+
const draft = pageSizeDraft.current;
|
|
9597
|
+
pageSizeDraft.current = null;
|
|
9598
|
+
if (!allowPageSizeInput || draft == null || !/^\d+$/.test(draft.trim()))
|
|
9599
|
+
return;
|
|
9600
|
+
changePageSize(Number(draft.trim()));
|
|
9601
|
+
};
|
|
9602
|
+
const pageSizeSelectOptions = resolvedPageSizeOptions.map((size2) => ({
|
|
9603
|
+
label: `${size2} / \u9875`,
|
|
9604
|
+
value: size2,
|
|
9605
|
+
...!isValidPageSize(size2) ? { disabled: true } : {}
|
|
9606
|
+
}));
|
|
9551
9607
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
9552
9608
|
const safeCurrent = clampPage(current, totalPages);
|
|
9553
9609
|
const range = total === 0 ? [0, 0] : [
|
|
@@ -9679,26 +9735,65 @@ function ReactPagination(props) {
|
|
|
9679
9735
|
)
|
|
9680
9736
|
}
|
|
9681
9737
|
),
|
|
9682
|
-
showSizeChanger && resolvedPageSizeOptions.length ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
9738
|
+
showSizeChanger && (allowPageSizeInput || resolvedPageSizeOptions.length) ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
9683
9739
|
ReactSelect,
|
|
9684
9740
|
{
|
|
9741
|
+
ref: sizeChangerRef,
|
|
9685
9742
|
value: String(pageSize),
|
|
9686
9743
|
disabled,
|
|
9744
|
+
"aria-label": "\u6BCF\u9875\u6761\u6570",
|
|
9745
|
+
allowClear: false,
|
|
9746
|
+
showSearch: allowPageSizeInput,
|
|
9747
|
+
allowCustomValue: allowPageSizeInput,
|
|
9748
|
+
inputMode: allowPageSizeInput ? "numeric" : void 0,
|
|
9749
|
+
onInputValueChange: (value) => {
|
|
9750
|
+
pageSizeDraft.current = value;
|
|
9751
|
+
},
|
|
9752
|
+
onKeyDown: (event) => {
|
|
9753
|
+
if (event.key === "Escape") pageSizeDraft.current = null;
|
|
9754
|
+
if ((event.key === "ArrowDown" || event.key === "ArrowUp") && pageSizeDraft.current != null && filterSelectOptions(
|
|
9755
|
+
pageSizeSelectOptions,
|
|
9756
|
+
pageSizeDraft.current,
|
|
9757
|
+
true
|
|
9758
|
+
).some((option) => !option.disabled)) {
|
|
9759
|
+
pageSizeDraft.current = null;
|
|
9760
|
+
}
|
|
9761
|
+
if (allowPageSizeInput && event.key === "Enter" && pageSizeDraft.current != null) {
|
|
9762
|
+
event.preventDefault();
|
|
9763
|
+
commitPageSizeInput();
|
|
9764
|
+
event.currentTarget.blur();
|
|
9765
|
+
}
|
|
9766
|
+
},
|
|
9767
|
+
onBlur: () => commitPageSizeInput(),
|
|
9687
9768
|
style: {
|
|
9688
9769
|
width: resolvePaginationSelectWidth(size, resolvedPageSizeOptions),
|
|
9689
9770
|
...styles?.sizeChanger
|
|
9690
9771
|
},
|
|
9691
|
-
options:
|
|
9692
|
-
|
|
9693
|
-
value
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9772
|
+
options: pageSizeSelectOptions,
|
|
9773
|
+
renderOptionExtra: (option) => {
|
|
9774
|
+
const value = Number(option.value);
|
|
9775
|
+
if (!allowPageSizeInput || pageSizeOptions.includes(value) || value === defaultPageSize)
|
|
9776
|
+
return null;
|
|
9777
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9778
|
+
"button",
|
|
9779
|
+
{
|
|
9780
|
+
type: "button",
|
|
9781
|
+
className: `${REACT_COMPONENT_PREFIX}-pagination-remove-size`,
|
|
9782
|
+
"aria-label": `\u5220\u9664\u6BCF\u9875 ${value} \u6761`,
|
|
9783
|
+
disabled,
|
|
9784
|
+
onMouseDown: (event) => {
|
|
9785
|
+
event.preventDefault();
|
|
9786
|
+
event.stopPropagation();
|
|
9787
|
+
},
|
|
9788
|
+
onClick: (event) => {
|
|
9789
|
+
event.stopPropagation();
|
|
9790
|
+
removeCustomPageSize(value);
|
|
9791
|
+
},
|
|
9792
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\xD7" })
|
|
9793
|
+
}
|
|
9794
|
+
);
|
|
9795
|
+
},
|
|
9796
|
+
onChange: (value) => changePageSize(Number(value))
|
|
9702
9797
|
}
|
|
9703
9798
|
) : null,
|
|
9704
9799
|
showQuickJumper ? /* @__PURE__ */ jsxRuntime.jsxs(
|
package/dist/index.d.cts
CHANGED
|
@@ -3353,6 +3353,12 @@ interface ReactPaginationProps {
|
|
|
3353
3353
|
* @default [10, 20, 50, 100]
|
|
3354
3354
|
*/
|
|
3355
3355
|
pageSizeOptions?: number[];
|
|
3356
|
+
/** 是否允许手动输入每页条数,回车或失焦后生效。默认 false。 */
|
|
3357
|
+
allowPageSizeInput?: boolean;
|
|
3358
|
+
/** 可选或输入的最小每页条数,默认 1。 */
|
|
3359
|
+
minPageSize?: number;
|
|
3360
|
+
/** 可选或输入的最大每页条数,默认不限制(安全整数范围内)。 */
|
|
3361
|
+
maxPageSize?: number;
|
|
3356
3362
|
/**
|
|
3357
3363
|
* 是否禁用。
|
|
3358
3364
|
*/
|
|
@@ -3920,6 +3926,8 @@ interface ReactSelectProps extends Omit<ReactInputProps, "value" | "onChange" |
|
|
|
3920
3926
|
* 选项列表。
|
|
3921
3927
|
*/
|
|
3922
3928
|
options: ReactSelectOption[];
|
|
3929
|
+
/** 选项右侧的扩展内容,可用于额外操作。 */
|
|
3930
|
+
renderOptionExtra?: (option: ReactSelectOption) => ReactNode;
|
|
3923
3931
|
/**
|
|
3924
3932
|
* 值变化回调。
|
|
3925
3933
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -3353,6 +3353,12 @@ interface ReactPaginationProps {
|
|
|
3353
3353
|
* @default [10, 20, 50, 100]
|
|
3354
3354
|
*/
|
|
3355
3355
|
pageSizeOptions?: number[];
|
|
3356
|
+
/** 是否允许手动输入每页条数,回车或失焦后生效。默认 false。 */
|
|
3357
|
+
allowPageSizeInput?: boolean;
|
|
3358
|
+
/** 可选或输入的最小每页条数,默认 1。 */
|
|
3359
|
+
minPageSize?: number;
|
|
3360
|
+
/** 可选或输入的最大每页条数,默认不限制(安全整数范围内)。 */
|
|
3361
|
+
maxPageSize?: number;
|
|
3356
3362
|
/**
|
|
3357
3363
|
* 是否禁用。
|
|
3358
3364
|
*/
|
|
@@ -3920,6 +3926,8 @@ interface ReactSelectProps extends Omit<ReactInputProps, "value" | "onChange" |
|
|
|
3920
3926
|
* 选项列表。
|
|
3921
3927
|
*/
|
|
3922
3928
|
options: ReactSelectOption[];
|
|
3929
|
+
/** 选项右侧的扩展内容,可用于额外操作。 */
|
|
3930
|
+
renderOptionExtra?: (option: ReactSelectOption) => ReactNode;
|
|
3923
3931
|
/**
|
|
3924
3932
|
* 值变化回调。
|
|
3925
3933
|
*/
|
package/dist/index.js
CHANGED
|
@@ -3557,6 +3557,7 @@ var ReactSelect = forwardRef(
|
|
|
3557
3557
|
onFocus,
|
|
3558
3558
|
onKeyDown,
|
|
3559
3559
|
options,
|
|
3560
|
+
renderOptionExtra,
|
|
3560
3561
|
optionHeight = 32,
|
|
3561
3562
|
listHeight = 224,
|
|
3562
3563
|
placeholder,
|
|
@@ -3752,7 +3753,10 @@ var ReactSelect = forwardRef(
|
|
|
3752
3753
|
openSelect();
|
|
3753
3754
|
return;
|
|
3754
3755
|
}
|
|
3755
|
-
const targetOption = resolveSelectEnterOption(
|
|
3756
|
+
const targetOption = resolveSelectEnterOption(
|
|
3757
|
+
filteredOptions,
|
|
3758
|
+
activeIndex
|
|
3759
|
+
);
|
|
3756
3760
|
if (targetOption && !targetOption.disabled) {
|
|
3757
3761
|
selectOption(targetOption, "keyboard");
|
|
3758
3762
|
} else if (allowCustomValue && keyword.trim()) {
|
|
@@ -3842,7 +3846,7 @@ var ReactSelect = forwardRef(
|
|
|
3842
3846
|
const isSelected = String(option.value) === String(value ?? "");
|
|
3843
3847
|
const isActive = optionIndex === activeIndex;
|
|
3844
3848
|
const isSearching = showSearch && searchKeyword.trim().length > 0;
|
|
3845
|
-
return /* @__PURE__ */
|
|
3849
|
+
return /* @__PURE__ */ jsxs(
|
|
3846
3850
|
"div",
|
|
3847
3851
|
{
|
|
3848
3852
|
className: joinClassNames(
|
|
@@ -3865,17 +3869,20 @@ var ReactSelect = forwardRef(
|
|
|
3865
3869
|
}
|
|
3866
3870
|
selectOption(option, "mouse");
|
|
3867
3871
|
},
|
|
3868
|
-
children:
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3872
|
+
children: [
|
|
3873
|
+
/* @__PURE__ */ jsx(
|
|
3874
|
+
"span",
|
|
3875
|
+
{
|
|
3876
|
+
className: `${REACT_COMPONENT_PREFIX}-select-option-label`,
|
|
3877
|
+
title: option.label,
|
|
3878
|
+
children: renderSelectOptionLabel(
|
|
3879
|
+
option.label,
|
|
3880
|
+
showSearch ? searchKeyword : ""
|
|
3881
|
+
)
|
|
3882
|
+
}
|
|
3883
|
+
),
|
|
3884
|
+
renderOptionExtra?.(option)
|
|
3885
|
+
]
|
|
3879
3886
|
},
|
|
3880
3887
|
String(option.value)
|
|
3881
3888
|
);
|
|
@@ -3916,7 +3923,8 @@ function scoreSelectMatch(text, search) {
|
|
|
3916
3923
|
return (index === 0 ? 2 : 1) + search.length / normalized.length;
|
|
3917
3924
|
}
|
|
3918
3925
|
function resolveSelectEnterOption(options, activeIndex = -1) {
|
|
3919
|
-
if (options[activeIndex] && !options[activeIndex].disabled)
|
|
3926
|
+
if (options[activeIndex] && !options[activeIndex].disabled)
|
|
3927
|
+
return options[activeIndex];
|
|
3920
3928
|
return options.find((option) => !option.disabled);
|
|
3921
3929
|
}
|
|
3922
3930
|
function resolveSelectKeywordOnOpen(selectedLabel) {
|
|
@@ -9499,15 +9507,19 @@ function ReactScrollbarPositionDialog(props) {
|
|
|
9499
9507
|
}
|
|
9500
9508
|
|
|
9501
9509
|
// src/components/pagination/style.css
|
|
9502
|
-
styleInject('@import "../../styles/variables.css";\n.canvas-react-pagination {\n --canvas-react-pagination-control-size: 32px;\n --canvas-react-pagination-gap: 8px;\n --canvas-react-pagination-padding-inline: 10px;\n --canvas-react-control-height: var(--canvas-react-pagination-control-size);\n display: flex;\n align-items: center;\n flex-wrap: nowrap;\n gap: var(--canvas-react-pagination-gap);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n white-space: nowrap;\n}\n.canvas-react-pagination-small {\n --canvas-react-pagination-control-size: 24px;\n --canvas-react-pagination-gap: 4px;\n --canvas-react-pagination-padding-inline: 6px;\n}\n.canvas-react-pagination > .canvas-react-select-wrap {\n flex: 0 0 auto;\n width: auto;\n height: auto;\n}\n.canvas-react-pagination > .canvas-react-select-wrap > .canvas-react-select {\n flex-shrink: 0;\n}\n.canvas-react-pagination-large {\n --canvas-react-pagination-control-size: 40px;\n --canvas-react-pagination-gap: 10px;\n --canvas-react-pagination-padding-inline: 14px;\n}\n.canvas-react-pagination-pages {\n display: inline-flex;\n align-items: center;\n gap: var(--canvas-react-pagination-gap);\n flex-wrap: nowrap;\n}\n.canvas-react-pagination-button,\n.canvas-react-pagination-page {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: var(--canvas-react-pagination-control-size);\n height: var(--canvas-react-pagination-control-size);\n padding: 0 var(--canvas-react-pagination-padding-inline);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n cursor: pointer;\n transition:\n border-color 0.2s ease,\n color 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-pagination-button {\n position: relative;\n width: var(--canvas-react-pagination-control-size);\n min-width: var(--canvas-react-pagination-control-size);\n padding: 0;\n}\n.canvas-react-pagination-button:hover,\n.canvas-react-pagination-page:hover {\n border-color: var(--canvas-react-color-primary-hover);\n color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-pagination-page-active {\n border-color: var(--canvas-react-color-primary);\n background: var(--canvas-react-color-bg-active);\n color: var(--canvas-react-color-primary);\n}\n.canvas-react-pagination-button:disabled,\n.canvas-react-pagination-page:disabled {\n opacity: 0.48;\n cursor: not-allowed;\n}\n.canvas-react-pagination-ellipsis {\n color: var(--canvas-react-color-text-muted);\n}\n.canvas-react-pagination-arrow {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 7px;\n height: 7px;\n border-right: 1.5px solid var(--canvas-react-color-text-muted);\n border-bottom: 1.5px solid var(--canvas-react-color-text-muted);\n transition:\n border-color 0.18s ease,\n transform 0.18s ease,\n opacity 0.18s ease;\n}\n.canvas-react-pagination-arrow-prev {\n transform: translate(-42%, -50%) rotate(135deg);\n}\n.canvas-react-pagination-arrow-next {\n transform: translate(-58%, -50%) rotate(-45deg);\n}\n.canvas-react-pagination-button:hover .canvas-react-pagination-arrow {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-pagination-button:disabled .canvas-react-pagination-arrow {\n opacity: 0.56;\n}\n.canvas-react-pagination-quick {\n display: inline-flex;\n align-items: center;\n gap: var(--canvas-react-pagination-gap);\n flex-wrap: nowrap;\n}\n.canvas-react-pagination-total {\n color: var(--canvas-react-color-text-muted);\n}\n.canvas-react-pagination button,\n.canvas-react-pagination input {\n font-family: inherit;\n font-weight: inherit;\n font-size: inherit;\n}\n');
|
|
9510
|
+
styleInject('@import "../../styles/variables.css";\n.canvas-react-pagination {\n --canvas-react-pagination-control-size: 32px;\n --canvas-react-pagination-gap: 8px;\n --canvas-react-pagination-padding-inline: 10px;\n --canvas-react-control-height: var(--canvas-react-pagination-control-size);\n display: flex;\n align-items: center;\n flex-wrap: nowrap;\n gap: var(--canvas-react-pagination-gap);\n color: var(--canvas-react-color-text);\n font-size: var(--canvas-react-font-size);\n white-space: nowrap;\n}\n.canvas-react-pagination-small {\n --canvas-react-pagination-control-size: 24px;\n --canvas-react-pagination-gap: 4px;\n --canvas-react-pagination-padding-inline: 6px;\n}\n.canvas-react-pagination > .canvas-react-select-wrap {\n flex: 0 0 auto;\n width: auto;\n height: auto;\n}\n.canvas-react-pagination > .canvas-react-select-wrap > .canvas-react-select {\n flex-shrink: 0;\n}\n.canvas-react-pagination-large {\n --canvas-react-pagination-control-size: 40px;\n --canvas-react-pagination-gap: 10px;\n --canvas-react-pagination-padding-inline: 14px;\n}\n.canvas-react-pagination-pages {\n display: inline-flex;\n align-items: center;\n gap: var(--canvas-react-pagination-gap);\n flex-wrap: nowrap;\n}\n.canvas-react-pagination-button,\n.canvas-react-pagination-page {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-width: var(--canvas-react-pagination-control-size);\n height: var(--canvas-react-pagination-control-size);\n padding: 0 var(--canvas-react-pagination-padding-inline);\n border: 1px solid var(--canvas-react-color-border);\n border-radius: var(--canvas-react-radius-sm);\n background: var(--canvas-react-color-bg);\n color: var(--canvas-react-color-text);\n cursor: pointer;\n transition:\n border-color 0.2s ease,\n color 0.2s ease,\n background-color 0.2s ease;\n}\n.canvas-react-pagination-button {\n position: relative;\n width: var(--canvas-react-pagination-control-size);\n min-width: var(--canvas-react-pagination-control-size);\n padding: 0;\n}\n.canvas-react-pagination-button:hover,\n.canvas-react-pagination-page:hover {\n border-color: var(--canvas-react-color-primary-hover);\n color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-pagination-page-active {\n border-color: var(--canvas-react-color-primary);\n background: var(--canvas-react-color-bg-active);\n color: var(--canvas-react-color-primary);\n}\n.canvas-react-pagination-button:disabled,\n.canvas-react-pagination-page:disabled {\n opacity: 0.48;\n cursor: not-allowed;\n}\n.canvas-react-pagination-ellipsis {\n color: var(--canvas-react-color-text-muted);\n}\n.canvas-react-pagination-arrow {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 7px;\n height: 7px;\n border-right: 1.5px solid var(--canvas-react-color-text-muted);\n border-bottom: 1.5px solid var(--canvas-react-color-text-muted);\n transition:\n border-color 0.18s ease,\n transform 0.18s ease,\n opacity 0.18s ease;\n}\n.canvas-react-pagination-arrow-prev {\n transform: translate(-42%, -50%) rotate(135deg);\n}\n.canvas-react-pagination-arrow-next {\n transform: translate(-58%, -50%) rotate(-45deg);\n}\n.canvas-react-pagination-button:hover .canvas-react-pagination-arrow {\n border-color: var(--canvas-react-color-primary-hover);\n}\n.canvas-react-pagination-button:disabled .canvas-react-pagination-arrow {\n opacity: 0.56;\n}\n.canvas-react-pagination-quick {\n display: inline-flex;\n align-items: center;\n gap: var(--canvas-react-pagination-gap);\n flex-wrap: nowrap;\n}\n.canvas-react-pagination-total {\n color: var(--canvas-react-color-text-muted);\n}\n.canvas-react-pagination button,\n.canvas-react-pagination input {\n font-family: inherit;\n font-weight: inherit;\n font-size: inherit;\n}\n.canvas-react-pagination-remove-size {\n flex: 0 0 auto;\n margin-left: 6px;\n padding: 0 4px;\n border: 0;\n border-radius: var(--canvas-react-radius-sm);\n background: transparent;\n color: var(--canvas-react-color-text-muted);\n font: inherit;\n cursor: pointer;\n}\n.canvas-react-pagination-remove-size:hover,\n.canvas-react-pagination-remove-size:focus-visible {\n background: var(--canvas-react-color-bg-hover);\n color: var(--canvas-react-color-primary);\n}\n.canvas-react-pagination-remove-size:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n}\n');
|
|
9511
|
+
var DEFAULT_PAGE_SIZE = 10;
|
|
9503
9512
|
var DEFAULT_PAGE_SIZE_OPTIONS = [10, 20, 50, 100];
|
|
9504
9513
|
function ReactPagination(props) {
|
|
9505
9514
|
const {
|
|
9515
|
+
allowPageSizeInput = false,
|
|
9516
|
+
minPageSize = 1,
|
|
9517
|
+
maxPageSize = Number.MAX_SAFE_INTEGER,
|
|
9506
9518
|
current,
|
|
9507
9519
|
disabled,
|
|
9508
9520
|
onChange,
|
|
9509
9521
|
onPageSizeChange,
|
|
9510
|
-
pageSize =
|
|
9522
|
+
pageSize = DEFAULT_PAGE_SIZE,
|
|
9511
9523
|
pageSizeOptions = DEFAULT_PAGE_SIZE_OPTIONS,
|
|
9512
9524
|
showLessItems,
|
|
9513
9525
|
showQuickJumper,
|
|
@@ -9521,12 +9533,56 @@ function ReactPagination(props) {
|
|
|
9521
9533
|
} = props;
|
|
9522
9534
|
const style = { ...rootStyle, ...styles?.root };
|
|
9523
9535
|
const [quickValue, setQuickValue] = useState("");
|
|
9536
|
+
const [customPageSizes, setCustomPageSizes] = useState([]);
|
|
9537
|
+
const pageSizeDraft = useRef(null);
|
|
9538
|
+
const sizeChangerRef = useRef(null);
|
|
9539
|
+
const minimum = Number.isSafeInteger(minPageSize) && minPageSize > 0 ? minPageSize : 1;
|
|
9540
|
+
const maximum = Number.isSafeInteger(maxPageSize) && maxPageSize > 0 ? Math.max(minimum, maxPageSize) : Number.MAX_SAFE_INTEGER;
|
|
9541
|
+
const defaultPageSize = Math.min(
|
|
9542
|
+
maximum,
|
|
9543
|
+
Math.max(minimum, DEFAULT_PAGE_SIZE)
|
|
9544
|
+
);
|
|
9545
|
+
const isValidPageSize = (value) => Number.isSafeInteger(value) && value >= minimum && value <= maximum;
|
|
9524
9546
|
const resolvedPageSizeOptions = useMemo(() => {
|
|
9525
|
-
|
|
9526
|
-
|
|
9547
|
+
const options = allowPageSizeInput ? [.../* @__PURE__ */ new Set([...pageSizeOptions, ...customPageSizes])].sort(
|
|
9548
|
+
(a, b) => a - b
|
|
9549
|
+
) : pageSizeOptions;
|
|
9550
|
+
if (options.length === 0 && !allowPageSizeInput || options.includes(pageSize) || !Number.isSafeInteger(pageSize) || pageSize <= 0) {
|
|
9551
|
+
return options;
|
|
9552
|
+
}
|
|
9553
|
+
return [...options, pageSize].sort((left, right) => left - right);
|
|
9554
|
+
}, [pageSizeOptions, pageSize, customPageSizes, allowPageSizeInput]);
|
|
9555
|
+
const changePageSize = (value) => {
|
|
9556
|
+
pageSizeDraft.current = null;
|
|
9557
|
+
if (disabled || !isValidPageSize(value)) return;
|
|
9558
|
+
if (allowPageSizeInput) {
|
|
9559
|
+
setCustomPageSizes(
|
|
9560
|
+
(sizes) => sizes.includes(value) ? sizes : [...sizes, value]
|
|
9561
|
+
);
|
|
9527
9562
|
}
|
|
9528
|
-
|
|
9529
|
-
}
|
|
9563
|
+
onPageSizeChange?.(1, value);
|
|
9564
|
+
};
|
|
9565
|
+
const removeCustomPageSize = (value) => {
|
|
9566
|
+
if (disabled) return;
|
|
9567
|
+
pageSizeDraft.current = null;
|
|
9568
|
+
sizeChangerRef.current?.blur();
|
|
9569
|
+
setCustomPageSizes((sizes) => sizes.filter((size2) => size2 !== value));
|
|
9570
|
+
if (value === pageSize) {
|
|
9571
|
+
onPageSizeChange?.(1, defaultPageSize);
|
|
9572
|
+
}
|
|
9573
|
+
};
|
|
9574
|
+
const commitPageSizeInput = () => {
|
|
9575
|
+
const draft = pageSizeDraft.current;
|
|
9576
|
+
pageSizeDraft.current = null;
|
|
9577
|
+
if (!allowPageSizeInput || draft == null || !/^\d+$/.test(draft.trim()))
|
|
9578
|
+
return;
|
|
9579
|
+
changePageSize(Number(draft.trim()));
|
|
9580
|
+
};
|
|
9581
|
+
const pageSizeSelectOptions = resolvedPageSizeOptions.map((size2) => ({
|
|
9582
|
+
label: `${size2} / \u9875`,
|
|
9583
|
+
value: size2,
|
|
9584
|
+
...!isValidPageSize(size2) ? { disabled: true } : {}
|
|
9585
|
+
}));
|
|
9530
9586
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
9531
9587
|
const safeCurrent = clampPage(current, totalPages);
|
|
9532
9588
|
const range = total === 0 ? [0, 0] : [
|
|
@@ -9658,26 +9714,65 @@ function ReactPagination(props) {
|
|
|
9658
9714
|
)
|
|
9659
9715
|
}
|
|
9660
9716
|
),
|
|
9661
|
-
showSizeChanger && resolvedPageSizeOptions.length ? /* @__PURE__ */ jsx(
|
|
9717
|
+
showSizeChanger && (allowPageSizeInput || resolvedPageSizeOptions.length) ? /* @__PURE__ */ jsx(
|
|
9662
9718
|
ReactSelect,
|
|
9663
9719
|
{
|
|
9720
|
+
ref: sizeChangerRef,
|
|
9664
9721
|
value: String(pageSize),
|
|
9665
9722
|
disabled,
|
|
9723
|
+
"aria-label": "\u6BCF\u9875\u6761\u6570",
|
|
9724
|
+
allowClear: false,
|
|
9725
|
+
showSearch: allowPageSizeInput,
|
|
9726
|
+
allowCustomValue: allowPageSizeInput,
|
|
9727
|
+
inputMode: allowPageSizeInput ? "numeric" : void 0,
|
|
9728
|
+
onInputValueChange: (value) => {
|
|
9729
|
+
pageSizeDraft.current = value;
|
|
9730
|
+
},
|
|
9731
|
+
onKeyDown: (event) => {
|
|
9732
|
+
if (event.key === "Escape") pageSizeDraft.current = null;
|
|
9733
|
+
if ((event.key === "ArrowDown" || event.key === "ArrowUp") && pageSizeDraft.current != null && filterSelectOptions(
|
|
9734
|
+
pageSizeSelectOptions,
|
|
9735
|
+
pageSizeDraft.current,
|
|
9736
|
+
true
|
|
9737
|
+
).some((option) => !option.disabled)) {
|
|
9738
|
+
pageSizeDraft.current = null;
|
|
9739
|
+
}
|
|
9740
|
+
if (allowPageSizeInput && event.key === "Enter" && pageSizeDraft.current != null) {
|
|
9741
|
+
event.preventDefault();
|
|
9742
|
+
commitPageSizeInput();
|
|
9743
|
+
event.currentTarget.blur();
|
|
9744
|
+
}
|
|
9745
|
+
},
|
|
9746
|
+
onBlur: () => commitPageSizeInput(),
|
|
9666
9747
|
style: {
|
|
9667
9748
|
width: resolvePaginationSelectWidth(size, resolvedPageSizeOptions),
|
|
9668
9749
|
...styles?.sizeChanger
|
|
9669
9750
|
},
|
|
9670
|
-
options:
|
|
9671
|
-
|
|
9672
|
-
value
|
|
9673
|
-
|
|
9674
|
-
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
|
|
9678
|
-
|
|
9679
|
-
|
|
9680
|
-
|
|
9751
|
+
options: pageSizeSelectOptions,
|
|
9752
|
+
renderOptionExtra: (option) => {
|
|
9753
|
+
const value = Number(option.value);
|
|
9754
|
+
if (!allowPageSizeInput || pageSizeOptions.includes(value) || value === defaultPageSize)
|
|
9755
|
+
return null;
|
|
9756
|
+
return /* @__PURE__ */ jsx(
|
|
9757
|
+
"button",
|
|
9758
|
+
{
|
|
9759
|
+
type: "button",
|
|
9760
|
+
className: `${REACT_COMPONENT_PREFIX}-pagination-remove-size`,
|
|
9761
|
+
"aria-label": `\u5220\u9664\u6BCF\u9875 ${value} \u6761`,
|
|
9762
|
+
disabled,
|
|
9763
|
+
onMouseDown: (event) => {
|
|
9764
|
+
event.preventDefault();
|
|
9765
|
+
event.stopPropagation();
|
|
9766
|
+
},
|
|
9767
|
+
onClick: (event) => {
|
|
9768
|
+
event.stopPropagation();
|
|
9769
|
+
removeCustomPageSize(value);
|
|
9770
|
+
},
|
|
9771
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\xD7" })
|
|
9772
|
+
}
|
|
9773
|
+
);
|
|
9774
|
+
},
|
|
9775
|
+
onChange: (value) => changePageSize(Number(value))
|
|
9681
9776
|
}
|
|
9682
9777
|
) : null,
|
|
9683
9778
|
showQuickJumper ? /* @__PURE__ */ jsxs(
|