diff --git a/src/FillSpace.jsx b/src/FillSpace.jsx index b3485eb..9fc2b11 100644 --- a/src/FillSpace.jsx +++ b/src/FillSpace.jsx @@ -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 ``) 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 ``, callbacks are called. */ +function renderRowElement(renderItem, item, index) { + if (isRowComponent(renderItem)) { + const Row = renderItem; + return ; + } + 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 { {pageItems.map((item, i) => ( - {renderItem(item, offset + i)} + {renderRowElement(renderItem, item, offset + i)} ))}