diff --git a/src/FillSpace.jsx b/src/FillSpace.jsx index 2b06748..07c506f 100644 --- a/src/FillSpace.jsx +++ b/src/FillSpace.jsx @@ -55,10 +55,12 @@ function renderProbeElement(renderItem) { class FillSpace extends Component { constructor(props) { super(props); + const minSize = Math.max(1, Number(props.minPageSize) || 10); + const maxSize = Number(props.maxPageSize) > 0 ? Number(props.maxPageSize) : Infinity; this.state = { unitHeight: 0, viewportHeight: null, - pageSize: Number(props.minPageSize) || 10, + pageSize: Math.min(maxSize, minSize), currentPage: 1, }; this.ref = null; @@ -79,8 +81,13 @@ class FillSpace extends Component { if (prevProps.renderItem !== this.props.renderItem) { this._probeMeasure(); } - if (prevProps.minPageSize !== this.props.minPageSize) { - this.setState({ pageSize: Number(this.props.minPageSize) || 10 }); + if ( + prevProps.minPageSize !== this.props.minPageSize || + prevProps.maxPageSize !== this.props.maxPageSize + ) { + const minSize = Math.max(1, Number(this.props.minPageSize) || 10); + const maxSize = Number(this.props.maxPageSize) > 0 ? Number(this.props.maxPageSize) : Infinity; + this.setState({ pageSize: Math.min(maxSize, minSize) }); } if ( prevProps.aboveRef !== this.props.aboveRef || @@ -165,7 +172,8 @@ class FillSpace extends Component { /** Only measures the height of the `renderItem` probe. Nothing else. */ _probeMeasure() { - const h = this.probeRef?.offsetHeight; + const firstRow = this.ref?.querySelector('[data-fill-row]'); + const h = this.probeRef?.offsetHeight || firstRow?.offsetHeight; if (h > 0 && h !== this.state.unitHeight) { this.setState({ unitHeight: h }, () => this._viewportMeasure()); } @@ -197,14 +205,20 @@ class FillSpace extends Component { available = Math.max(0, window.innerHeight - rect.top - belowPx); } const minSize = Math.max(1, Number(minPageSize) || 10); + const maxSize = Number(this.props.maxPageSize) > 0 ? Number(this.props.maxPageSize) : Infinity; const { unitHeight } = this.state; - const nextPageSize = + const calculated = unitHeight > 0 ? Math.max(minSize, Math.floor(available / unitHeight)) : minSize; + const nextPageSize = Math.min(maxSize, calculated); + const nextViewportHeight = + Number.isFinite(maxSize) && unitHeight > 0 + ? Math.min(available, nextPageSize * unitHeight) + : available; if ( - available !== this.state.viewportHeight || + nextViewportHeight !== this.state.viewportHeight || nextPageSize !== this.state.pageSize ) { - this.setState({ viewportHeight: available, pageSize: nextPageSize }); + this.setState({ viewportHeight: nextViewportHeight, pageSize: nextPageSize }); } } @@ -250,6 +264,8 @@ class FillSpace extends Component { minHeight, maxHeight, minPageSize, + maxPageSize, + listRef, onPageChange, onWheel, debug = false, @@ -275,60 +291,54 @@ class FillSpace extends Component { return ( <> - + {showPagination ? ( - - {total === 0 ? '0' : `${offset + 1}–${Math.min(offset + pageSize, total)}`} von{' '} - {total} - - this._goToPage(page)} - color="primary" - size="large" - onMouseDown={(e) => e.preventDefault()} + + > + + {total === 0 ? '0' : `${offset + 1}–${Math.min(offset + pageSize, total)}`} von{' '} + {total} + + this._goToPage(page)} + color="primary" + size="large" + onMouseDown={(e) => e.preventDefault()} + sx={{ + flexShrink: 0, + maxWidth: '100%', + overflowX: 'auto', + scrollbarWidth: 'none', + '&::-webkit-scrollbar': { display: 'none' }, + '& .MuiPagination-ul': { flexWrap: 'nowrap' }, + '& .MuiPaginationItem-root': { + minWidth: 44, + height: 44, + fontSize: '1rem', + }, + }} + /> + - + ) : null} { this.ref = el; @@ -357,7 +367,7 @@ class FillSpace extends Component { ]} > - + {pageItems.map((item, i) => ( {renderRowElement(renderItem, item, offset + i)}