diff --git a/web-admin/scripts/check-list-table-viewport-height.ts b/web-admin/scripts/check-list-table-viewport-height.ts new file mode 100644 index 000000000..72dca4903 --- /dev/null +++ b/web-admin/scripts/check-list-table-viewport-height.ts @@ -0,0 +1,55 @@ +import assert from 'node:assert/strict' +import { + LIST_TABLE_VIEWPORT_BOTTOM_GAP, + LIST_TABLE_VIEWPORT_MIN_HEIGHT, + calcListTableViewportHeight +} from '../src/composables/listTableViewportHeight' + +assert.equal(LIST_TABLE_VIEWPORT_BOTTOM_GAP, 10) +assert.equal(LIST_TABLE_VIEWPORT_MIN_HEIGHT, 240) + +// contentBottom=1000, tableTop=200, pager=48 → 1000-200-48-10 = 742 +assert.equal( + calcListTableViewportHeight({ + contentViewportBottom: 1000, + tableTop: 200, + pagerHeight: 48 + }), + 742 +) + +// 无分页 +assert.equal( + calcListTableViewportHeight({ + contentViewportBottom: 800, + tableTop: 100, + pagerHeight: 0 + }), + 690 +) + +// 过矮时夹到 minHeight +assert.equal( + calcListTableViewportHeight({ + contentViewportBottom: 400, + tableTop: 300, + pagerHeight: 48, + minHeight: 240, + bottomGap: 10 + }), + 240 +) + +// 自定义 min / gap +assert.equal( + calcListTableViewportHeight({ + contentViewportBottom: 1000, + tableTop: 100, + pagerHeight: 40, + minHeight: 100, + bottomGap: 16 + }), + 844 +) + +console.log('check-list-table-viewport-height: ok') diff --git a/web-admin/src/composables/listTableViewportHeight.ts b/web-admin/src/composables/listTableViewportHeight.ts new file mode 100644 index 000000000..fe3c04194 --- /dev/null +++ b/web-admin/src/composables/listTableViewportHeight.ts @@ -0,0 +1,32 @@ +/** 分页底边到内容区底的默认空隙(px) */ +export const LIST_TABLE_VIEWPORT_BOTTOM_GAP = 10 + +/** 表体动态高度下限(px),避免筛选展开时表被压没 */ +export const LIST_TABLE_VIEWPORT_MIN_HEIGHT = 240 + +export type CalcListTableViewportHeightInput = { + /** 主内容滚动容器可视底边(如 #app-content.getBoundingClientRect().bottom) */ + contentViewportBottom: number + /** 表格锚点顶边(同坐标系,通常 getBoundingClientRect().top) */ + tableTop: number + /** 分页条实际高度;无分页传 0 */ + pagerHeight: number + minHeight?: number + bottomGap?: number +} + +/** + * 计算列表表体应设置的 height,使「表 + 分页」落在内容视口内,且分页下方留 bottomGap。 + * tableHeight = floor(contentBottom - tableTop - pagerHeight - bottomGap),再与 minHeight 取大。 + */ +export function calcListTableViewportHeight( + input: CalcListTableViewportHeightInput +): number { + const minHeight = input.minHeight ?? LIST_TABLE_VIEWPORT_MIN_HEIGHT + const bottomGap = input.bottomGap ?? LIST_TABLE_VIEWPORT_BOTTOM_GAP + const raw = Math.floor( + input.contentViewportBottom - input.tableTop - input.pagerHeight - bottomGap + ) + if (!Number.isFinite(raw)) return minHeight + return Math.max(raw, minHeight) +}