u
This commit is contained in:
@@ -15,6 +15,9 @@ import { alpha } from '@mui/material/styles';
|
|||||||
* @prop {Array} items - Wheel flips pages.
|
* @prop {Array} items - Wheel flips pages.
|
||||||
* @prop {React.ComponentType|Function} renderItem - Row renderer (component or callback).
|
* @prop {React.ComponentType|Function} renderItem - Row renderer (component or callback).
|
||||||
* @prop {number} [minPageSize=10] - Rows per page.
|
* @prop {number} [minPageSize=10] - Rows per page.
|
||||||
|
* @prop {number} [maxPageSize] - Maximum rows per page.
|
||||||
|
* @prop {number} [totalCount] - Total items in unfiltered dataset. When unfiltered count <= pageSize, pagination header is removed entirely. When filtering, the header height is preserved to prevent layout shift.
|
||||||
|
* @prop {number} [unfilteredCount] - Alias for totalCount.
|
||||||
* @prop {(page: number) => void} [onPageChange] - Called on page change.
|
* @prop {(page: number) => void} [onPageChange] - Called on page change.
|
||||||
* @prop {boolean} [debug=false] - Dashed outline for layout debugging.
|
* @prop {boolean} [debug=false] - Dashed outline for layout debugging.
|
||||||
* @prop {object} [sx] - Extra styles.
|
* @prop {object} [sx] - Extra styles.
|
||||||
@@ -68,6 +71,13 @@ class FillSpace extends Component {
|
|||||||
this.wheelAcc = 0;
|
this.wheelAcc = 0;
|
||||||
this.observer = null;
|
this.observer = null;
|
||||||
this.raf = null;
|
this.raf = null;
|
||||||
|
const explicitCount = props.unfilteredCount ?? props.totalCount;
|
||||||
|
this.maxSeenCount =
|
||||||
|
explicitCount != null
|
||||||
|
? Number(explicitCount)
|
||||||
|
: Array.isArray(props.items)
|
||||||
|
? props.items.length
|
||||||
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -99,6 +109,12 @@ class FillSpace extends Component {
|
|||||||
this._observe();
|
this._observe();
|
||||||
this._viewportMeasure();
|
this._viewportMeasure();
|
||||||
}
|
}
|
||||||
|
const explicitCount = this.props.unfilteredCount ?? this.props.totalCount;
|
||||||
|
if (explicitCount != null) {
|
||||||
|
this.maxSeenCount = Number(explicitCount);
|
||||||
|
} else if (Array.isArray(this.props.items)) {
|
||||||
|
this.maxSeenCount = Math.max(this.maxSeenCount || 0, this.props.items.length);
|
||||||
|
}
|
||||||
// Clamp current page when the item list shrinks (e.g. brand deleted).
|
// Clamp current page when the item list shrinks (e.g. brand deleted).
|
||||||
if (
|
if (
|
||||||
Array.isArray(this.props.items) &&
|
Array.isArray(this.props.items) &&
|
||||||
@@ -265,6 +281,8 @@ class FillSpace extends Component {
|
|||||||
maxHeight,
|
maxHeight,
|
||||||
minPageSize,
|
minPageSize,
|
||||||
maxPageSize,
|
maxPageSize,
|
||||||
|
totalCount,
|
||||||
|
unfilteredCount,
|
||||||
listRef,
|
listRef,
|
||||||
onPageChange,
|
onPageChange,
|
||||||
onWheel,
|
onWheel,
|
||||||
@@ -281,21 +299,26 @@ class FillSpace extends Component {
|
|||||||
const { pageSize, currentPage, viewportHeight } = this.state;
|
const { pageSize, currentPage, viewportHeight } = this.state;
|
||||||
const list = Array.isArray(items) ? items : [];
|
const list = Array.isArray(items) ? items : [];
|
||||||
const total = list.length;
|
const total = list.length;
|
||||||
|
const fullTotal = unfilteredCount ?? totalCount ?? Math.max(this.maxSeenCount || 0, total);
|
||||||
|
const needsPaginationContainer = fullTotal > pageSize;
|
||||||
|
const showPaginationControls = total > pageSize;
|
||||||
const pageCount = Math.max(1, Math.ceil(total / Math.max(1, pageSize)));
|
const pageCount = Math.max(1, Math.ceil(total / Math.max(1, pageSize)));
|
||||||
const safePage = Math.min(Math.max(1, currentPage), pageCount);
|
const safePage = Math.min(Math.max(1, currentPage), pageCount);
|
||||||
const offset = (safePage - 1) * pageSize;
|
const offset = (safePage - 1) * pageSize;
|
||||||
const pageItems = list.slice(offset, offset + pageSize);
|
const pageItems = list.slice(offset, offset + pageSize);
|
||||||
const showPagination = total > pageSize;
|
|
||||||
// Hidden data-free probe: measures `renderItem` itself (no data).
|
// Hidden data-free probe: measures `renderItem` itself (no data).
|
||||||
const probe = renderProbeElement(renderItem);
|
const probe = renderProbeElement(renderItem);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{showPagination ? (
|
{needsPaginationContainer ? (
|
||||||
<Box
|
<Box
|
||||||
|
// Fixed single-line bar: the header height must not depend on the
|
||||||
|
// filtered count so the content never shifts when filtering.
|
||||||
sx={{ mb: 1, height: 44, overflow: 'hidden' }}
|
sx={{ mb: 1, height: 44, overflow: 'hidden' }}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
|
aria-hidden={!showPaginationControls || undefined}
|
||||||
sx={{
|
sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
justifyContent: 'space-between',
|
justifyContent: 'space-between',
|
||||||
@@ -304,6 +327,8 @@ class FillSpace extends Component {
|
|||||||
gap: 1,
|
gap: 1,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: 44,
|
height: 44,
|
||||||
|
visibility: showPaginationControls ? 'visible' : 'hidden',
|
||||||
|
pointerEvents: showPaginationControls ? 'auto' : 'none',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography
|
<Typography
|
||||||
|
|||||||
Reference in New Issue
Block a user