iter(g21): pagination 跳页输入框

This commit is contained in:
HIsheR
2026-10-26 11:11:23 +08:00
parent e009f5c775
commit c5a4a37508
9 changed files with 48 additions and 8 deletions
+11 -1
View File
@@ -15,7 +15,7 @@ function pageSequence(page: number, totalPages: number): (number | null)[] {
return seq;
}
/*** 独立分页器:受控组件,page 为双向绑定信号;页码过多折叠省略号,首末页禁用翻页,原生 button 保证键盘可达 ***/
/*** 独立分页器:受控组件,page 为双向绑定信号;页码过多折叠省略号,首末页禁用翻页,jumpable 时末尾可跳页,原生 button 保证键盘可达 ***/
export function pagination(props: PaginationProps): HTMLElement {
const totalPages = Math.max(1, Math.ceil(props.total / props.pageSize)); // 总页数
const go = (p: number) => {
@@ -23,6 +23,15 @@ export function pagination(props: PaginationProps): HTMLElement {
props.page(next);
props.onChange?.(next);
};
// —— 跳页输入:jumpable 且多页时渲染在末尾,回车跳转 ——
const jump = props.jumpable && totalPages > 1 ? (h('input', { class: 'ua-page-jump', inputmode: 'numeric', 'aria-label': `跳转到指定页,共 ${totalPages} 页` }) as HTMLInputElement) : null;
if (jump) {
jump.addEventListener('change', () => {
const n = parseInt(jump.value, 10);
jump.value = ''; // 跳转后清空输入,避免残留旧页码
if (!Number.isNaN(n)) go(n); // 非数字忽略,由 go 钳制范围
});
}
const nav = h('nav', { class: 'ua-pagination', 'aria-label': '分页' });
renderList(nav, () => {
@@ -36,6 +45,7 @@ export function pagination(props: PaginationProps): HTMLElement {
);
}
items.push(h('button', { class: 'ua-page-btn', disabled: page >= totalPages, 'aria-label': '下一页', onClick: () => go(page + 1) }, '›'));
if (jump) items.push(h('span', { class: 'ua-page-jump-wrap' }, jump, h('span', { class: 'ua-page-total' }, `/ ${totalPages} 页`))); // 跳页入口固定在末尾
return items;
});
return nav;
+1
View File
@@ -278,6 +278,7 @@ export interface PaginationProps {
page: Signal<number>; // 当前页码信号,双向绑定(外部赋值自动翻页)
pageSize: number; // 每页条数
total: number; // 总条数
jumpable?: boolean; // 开启后在末尾显示跳页输入框(总页数 > 1 才出现)
onChange?: (page: number) => void; // 翻页回调
}
+1 -1
View File
@@ -35,7 +35,7 @@
"tooltip(props, trigger):悬浮提示,包裹触发器,hover / focus 延迟 150ms 出场,移出 / 失焦 / Esc 收起;视口一侧空间不足时自动翻转",
"popover(props, trigger):可交互气泡卡片,包裹触发器,默认点击开合 + 点外部 / Esc 收起,content 可放按钮等交互元素;视口一侧空间不足时自动翻转",
"skeleton(props):骨架屏占位,variant = text | rect | circle,text 支持 rows 多行,扫光微动画",
"pagination(props):独立分页器,page 信号双向绑定,页码过多折叠省略号,首末页禁用翻页,键盘可达",
"pagination(props):独立分页器,page 信号双向绑定,页码过多折叠省略号,首末页禁用翻页,jumpable 时末尾可输入页码直接跳转,键盘可达",
"spinner(props):加载指示器,size 控制直径",
"progress(props):进度条,value 信号驱动 0-100(满格切 success 色);不传 value 退化为不确定态无限往复",
"tabs(props):标签页,active 信号双向绑定,滑动指示条 + 方向键环形导航,支持禁用页签",
+21
View File
@@ -998,6 +998,27 @@ button.ua-step-dot:hover {
align-items: center;
gap: var(--ua-space-1);
}
.ua-page-jump-wrap {
display: inline-flex; /* 跳页输入 + 总页数说明 */
align-items: center;
gap: 4px;
margin-left: var(--ua-space-2);
color: var(--ua-color-text-muted);
font-size: var(--ua-font-size-sm);
}
.ua-page-jump {
width: 48px;
padding: 4px 6px;
border: 1px solid var(--ua-color-border);
border-radius: var(--ua-radius-sm);
background: var(--ua-color-bg);
color: var(--ua-color-text);
font-size: var(--ua-font-size-sm);
text-align: center;
}
.ua-page-total {
white-space: nowrap;
}
.ua-page-btn {
min-width: 28px;
height: 28px;