This commit is contained in:
seb
2026-10-09 21:19:36 +02:00
parent eda3b193c6
commit 649239a930

View File

@@ -23,7 +23,7 @@ import { alpha } from '@mui/material/styles';
* @prop {number} [minHeight=0] - Minimum spacer height in px.
* @prop {number} [minCount=0] - Minimum number of `measureElement` units the spacer must fit. When the viewport is too small, the spacer grows beyond the viewport so the page scrolls instead of clipping.
* @prop {Array} [items] - When provided with `renderItem`, FillSpace paginates: it measures the page size from the rendered row height, slices `items`, renders the current page as a list, and owns wheel-pagination plus the pagination header. Omit for legacy children mode.
* @prop {(item: any, index: number) => ReactNode} [renderItem] - Renders one row element (e.g. a brand row). The first rendered row doubles as the measure element, so no separate `measureElement` is needed in paginated mode.
* @prop {React.ComponentType|((item: any, index: number) => ReactNode)} [renderItem] - Row renderer. Either a component type (e.g. `renderItem={ArtikelMarke}`, rendered as `<ArtikelMarke brand={item} item={item} index={index} />`) or a callback `(item, index) => element`. The first rendered row doubles as the measure element, so no separate `measureElement` is needed in paginated mode.
* @prop {number} [minPageSize=10] - Minimum rows per page in paginated mode.
* @prop {(page: number) => void} [onPageChange] - Called when the current page changes (wheel or header).
* @prop {number} [maxHeight] - Optional maximum spacer height in px.
@@ -46,6 +46,23 @@ function minHeightFromCount(count, unitHeight, gap) {
return n * unitHeight + Math.max(0, n - 1) * (Number(gap) || 0);
}
/** True for class components (e.g. `renderItem={ArtikelMarke}`). Rendered as element, not called. */
function isRowComponent(renderItem) {
return (
typeof renderItem === 'function' &&
(renderItem.prototype?.isReactComponent || renderItem.isFillRowComponent === true)
);
}
/** Renders one row: component types become `<Row brand item index />`, callbacks are called. */
function renderRowElement(renderItem, item, index) {
if (isRowComponent(renderItem)) {
const Row = renderItem;
return <Row brand={item} item={item} index={index} />;
}
return renderItem(item, index);
}
class FillSpace extends Component {
constructor(props) {
super(props);
@@ -367,7 +384,8 @@ class FillSpace extends Component {
// Paginated mode: FillSpace owns page size (from the rendered row
// height), current page, wheel-pagination and the pagination header.
// Caller feeds `items` plus one row element via `renderItem`.
// Caller feeds `items` plus one row element via `renderItem` (component
// type or callback).
if (Array.isArray(items) && typeof renderItem === 'function') {
return this.renderPaginated({
minHeight,
@@ -574,7 +592,7 @@ class FillSpace extends Component {
<List dense disablePadding sx={{ width: '100%' }}>
{pageItems.map((item, i) => (
<Box key={item?.id ?? offset + i} data-fill-row sx={{ width: '100%' }}>
{renderItem(item, offset + i)}
{renderRowElement(renderItem, item, offset + i)}
</Box>
))}
</List>