u
This commit is contained in:
@@ -17,8 +17,9 @@ import { alpha } from '@mui/material/styles';
|
||||
* @prop {React.ReactNode} [header] - Rendered below pagination controls and above the list items.
|
||||
* @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 {number} [totalCount] - Total items in current dataset (or filtered dataset when paginating).
|
||||
* @prop {number} [unfilteredTotal] - Total items in unfiltered dataset. When unfilteredTotal > pageSize, pagination space is reserved even if current filtered count <= pageSize, preventing layout shift.
|
||||
* @prop {number} [unfilteredCount] - Alias for unfilteredTotal.
|
||||
* @prop {(page: number) => void} [onPageChange] - Called on page change.
|
||||
* @prop {boolean} [virtualScrollbar=false] - Shows a synchronized scrollbar alongside pagination controls.
|
||||
* @prop {boolean} [reserveScrollbar] - Reserves raceway space even when items do not overflow (defaults to true when virtualScrollbar is true).
|
||||
@@ -84,13 +85,15 @@ class FillSpace extends Component {
|
||||
this.raf = null;
|
||||
this.dragStartY = 0;
|
||||
this.dragStartThumbTop = 0;
|
||||
const explicitCount = props.unfilteredCount ?? props.totalCount;
|
||||
this.maxSeenCount =
|
||||
explicitCount != null
|
||||
? Number(explicitCount)
|
||||
const rawUnfiltered = props.unfilteredTotal ?? props.unfilteredCount;
|
||||
const unfilteredTotal = rawUnfiltered != null ? Number(rawUnfiltered) : null;
|
||||
const total =
|
||||
props.totalCount != null
|
||||
? Number(props.totalCount)
|
||||
: Array.isArray(props.items)
|
||||
? props.items.length
|
||||
: 0;
|
||||
this.maxSeenCount = unfilteredTotal != null ? unfilteredTotal : total;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -123,20 +126,24 @@ 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);
|
||||
const rawUnfiltered = this.props.unfilteredTotal ?? this.props.unfilteredCount;
|
||||
const unfilteredTotal = rawUnfiltered != null ? Number(rawUnfiltered) : null;
|
||||
const total =
|
||||
this.props.totalCount != null
|
||||
? Number(this.props.totalCount)
|
||||
: Array.isArray(this.props.items)
|
||||
? this.props.items.length
|
||||
: 0;
|
||||
if (unfilteredTotal != null) {
|
||||
this.maxSeenCount = unfilteredTotal;
|
||||
} else {
|
||||
this.maxSeenCount = Math.max(this.maxSeenCount || 0, total);
|
||||
}
|
||||
// Clamp current page when the item list shrinks (e.g. brand deleted).
|
||||
if (
|
||||
Array.isArray(this.props.items) &&
|
||||
this.props.items !== prevProps.items
|
||||
) {
|
||||
const explicitTotal = this.props.unfilteredCount ?? this.props.totalCount;
|
||||
const total =
|
||||
explicitTotal != null ? Number(explicitTotal) : this.props.items.length;
|
||||
const pageCount = Math.max(
|
||||
1,
|
||||
Math.ceil(total / Math.max(1, this.state.pageSize)),
|
||||
@@ -173,10 +180,9 @@ class FillSpace extends Component {
|
||||
_onThumbMouseDown = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const { totalCount, unfilteredCount, items } = this.props;
|
||||
const { totalCount, items } = this.props;
|
||||
const { viewportHeight, pageSize, currentPage } = this.state;
|
||||
const explicitTotal = unfilteredCount ?? totalCount;
|
||||
const total = explicitTotal != null ? Number(explicitTotal) : (items?.length || 0);
|
||||
const total = totalCount != null ? Number(totalCount) : (items?.length || 0);
|
||||
const pageCount = Math.max(1, Math.ceil(total / Math.max(1, pageSize)));
|
||||
const racewayBottom = Math.max(0, Number(this.props.racewayMarginBottom ?? RACEWAY_BOTTOM_MARGIN) || 0);
|
||||
const trackHeight = Math.max(0, (viewportHeight || 0) - racewayBottom);
|
||||
@@ -195,10 +201,9 @@ class FillSpace extends Component {
|
||||
|
||||
_onThumbDragMove = (e) => {
|
||||
if (!this.state.isDragging) return;
|
||||
const { totalCount, unfilteredCount, items } = this.props;
|
||||
const { totalCount, items } = this.props;
|
||||
const { viewportHeight, pageSize } = this.state;
|
||||
const explicitTotal = unfilteredCount ?? totalCount;
|
||||
const total = explicitTotal != null ? Number(explicitTotal) : (items?.length || 0);
|
||||
const total = totalCount != null ? Number(totalCount) : (items?.length || 0);
|
||||
const pageCount = Math.max(1, Math.ceil(total / Math.max(1, pageSize)));
|
||||
if (pageCount <= 1) return;
|
||||
|
||||
@@ -232,9 +237,8 @@ class FillSpace extends Component {
|
||||
const trackRect = this.trackRef.getBoundingClientRect();
|
||||
const clickY = e.clientY - trackRect.top;
|
||||
const { viewportHeight, pageSize } = this.state;
|
||||
const { items, totalCount, unfilteredCount } = this.props;
|
||||
const explicitTotal = unfilteredCount ?? totalCount;
|
||||
const total = explicitTotal != null ? Number(explicitTotal) : (items?.length || 0);
|
||||
const { items, totalCount } = this.props;
|
||||
const total = totalCount != null ? Number(totalCount) : (items?.length || 0);
|
||||
const pageCount = Math.max(1, Math.ceil(total / Math.max(1, pageSize)));
|
||||
if (pageCount <= 1) return;
|
||||
|
||||
@@ -356,12 +360,11 @@ class FillSpace extends Component {
|
||||
}
|
||||
|
||||
_handleWheel = (event) => {
|
||||
const { items, totalCount, unfilteredCount } = this.props;
|
||||
const { items, totalCount } = this.props;
|
||||
if (!Array.isArray(items)) return;
|
||||
if (this.ref && event.target && !this.ref.contains(event.target)) return;
|
||||
const { pageSize, currentPage } = this.state;
|
||||
const explicitTotal = unfilteredCount ?? totalCount;
|
||||
const total = explicitTotal != null ? Number(explicitTotal) : items.length;
|
||||
const total = totalCount != null ? Number(totalCount) : items.length;
|
||||
const pageCount = Math.max(1, Math.ceil(total / Math.max(1, pageSize)));
|
||||
const delta = event.deltaY || 0;
|
||||
if (pageCount <= 1) return;
|
||||
@@ -380,11 +383,10 @@ class FillSpace extends Component {
|
||||
};
|
||||
|
||||
_goToPage = (page) => {
|
||||
const { items, onPageChange, totalCount, unfilteredCount } = this.props;
|
||||
const explicitTotal = unfilteredCount ?? totalCount;
|
||||
const { items, onPageChange, totalCount } = this.props;
|
||||
const total =
|
||||
explicitTotal != null
|
||||
? Number(explicitTotal)
|
||||
totalCount != null
|
||||
? Number(totalCount)
|
||||
: Array.isArray(items)
|
||||
? items.length
|
||||
: 0;
|
||||
@@ -408,6 +410,7 @@ class FillSpace extends Component {
|
||||
maxPageSize,
|
||||
totalCount,
|
||||
unfilteredCount,
|
||||
unfilteredTotal: propUnfilteredTotal,
|
||||
listRef,
|
||||
onPageChange,
|
||||
onWheel,
|
||||
@@ -428,9 +431,10 @@ class FillSpace extends Component {
|
||||
// type or callback). `items` may be undefined while data is loading.
|
||||
const { pageSize, currentPage, viewportHeight } = this.state;
|
||||
const list = Array.isArray(items) ? items : [];
|
||||
const explicitTotal = unfilteredCount ?? totalCount;
|
||||
const total = explicitTotal != null ? Number(explicitTotal) : list.length;
|
||||
const fullTotal = Math.max(this.maxSeenCount || 0, total);
|
||||
const total = totalCount != null ? Number(totalCount) : list.length;
|
||||
const rawUnfiltered = propUnfilteredTotal ?? unfilteredCount;
|
||||
const unfilteredTotal = rawUnfiltered != null ? Number(rawUnfiltered) : null;
|
||||
const fullTotal = unfilteredTotal != null ? unfilteredTotal : 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)));
|
||||
|
||||
Reference in New Issue
Block a user