This commit is contained in:
seb
2026-10-15 02:33:26 +02:00
parent b96eb762ae
commit cd3a888a65

View File

@@ -15,6 +15,7 @@ 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 {React.ReactNode} [header] - Rendered below pagination controls and above the list items. * @prop {React.ReactNode} [header] - Rendered below pagination controls and above the list items.
* @prop {any} [headerItem] - Optional dummy/sample item passed to probe element for layout measurement.
* @prop {number} [minPageSize=10] - Rows per page. * @prop {number} [minPageSize=10] - Rows per page.
* @prop {number} [maxPageSize] - Maximum rows per page. * @prop {number} [maxPageSize] - Maximum rows per page.
* @prop {number} [totalCount] - Total items in current dataset (or filtered dataset when paginating). * @prop {number} [totalCount] - Total items in current dataset (or filtered dataset when paginating).
@@ -45,18 +46,16 @@ function renderRowElement(renderItem, item, index) {
} }
/** /**
* Data-free probe of the row height, rendered hidden. Class components * Probe of the row height, rendered hidden. Class components
* (e.g. `renderItem={ArtikelMarke}`) tolerate empty props * (e.g. `renderItem={ArtikelMarke}`) tolerate empty props
* (`brand`/`item` undefined) and keep a fixed height (40px thumb / * (`brand`/`item` undefined) and keep a fixed height (40px thumb /
* text field), so the probe measures the row without depending on the * text field). When `headerItem` is supplied, it is passed to the row
* first data element. Plain callbacks are NOT probed — calling arbitrary * for precise measurement of data-driven layouts.
* user code with `undefined` could throw — they fall back to the first
* rendered data row.
*/ */
function renderProbeElement(renderItem) { function renderProbeElement(renderItem, headerItem) {
if (!isRowComponent(renderItem)) return null; if (!isRowComponent(renderItem)) return null;
const Row = renderItem; const Row = renderItem;
return <Row brand={undefined} item={undefined} index={0} disabled />; return <Row brand={headerItem} item={headerItem} index={0} disabled />;
} }
const MIN_THUMB_HEIGHT = 48; const MIN_THUMB_HEIGHT = 48;
@@ -104,7 +103,10 @@ class FillSpace extends Component {
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
if (prevProps.renderItem !== this.props.renderItem) { if (
prevProps.renderItem !== this.props.renderItem ||
prevProps.headerItem !== this.props.headerItem
) {
this._probeMeasure(); this._probeMeasure();
} }
if ( if (
@@ -487,8 +489,8 @@ class FillSpace extends Component {
: (pageCount > 1 && maxThumbTravel > 0 ? ((safePage - 1) / (pageCount - 1)) * maxThumbTravel : 0); : (pageCount > 1 && maxThumbTravel > 0 ? ((safePage - 1) / (pageCount - 1)) * maxThumbTravel : 0);
} }
// Hidden data-free probe: measures `renderItem` itself (no data). // Hidden probe: measures `renderItem` (passes headerItem when provided).
const probe = renderProbeElement(renderItem); const probe = renderProbeElement(renderItem, this.props.headerItem);
return ( return (
<> <>