diff --git a/src/FillSpace.jsx b/src/FillSpace.jsx index 07c506f..41acd13 100644 --- a/src/FillSpace.jsx +++ b/src/FillSpace.jsx @@ -15,6 +15,9 @@ import { alpha } from '@mui/material/styles'; * @prop {Array} items - Wheel flips pages. * @prop {React.ComponentType|Function} renderItem - Row renderer (component or callback). * @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 {boolean} [debug=false] - Dashed outline for layout debugging. * @prop {object} [sx] - Extra styles. @@ -68,6 +71,13 @@ class FillSpace extends Component { this.wheelAcc = 0; this.observer = 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() { @@ -99,6 +109,12 @@ class FillSpace extends Component { this._observe(); 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). if ( Array.isArray(this.props.items) && @@ -265,6 +281,8 @@ class FillSpace extends Component { maxHeight, minPageSize, maxPageSize, + totalCount, + unfilteredCount, listRef, onPageChange, onWheel, @@ -281,21 +299,26 @@ class FillSpace extends Component { const { pageSize, currentPage, viewportHeight } = this.state; const list = Array.isArray(items) ? items : []; 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 safePage = Math.min(Math.max(1, currentPage), pageCount); const offset = (safePage - 1) * pageSize; const pageItems = list.slice(offset, offset + pageSize); - const showPagination = total > pageSize; // Hidden data-free probe: measures `renderItem` itself (no data). const probe = renderProbeElement(renderItem); return ( <> - {showPagination ? ( + {needsPaginationContainer ? (