diff --git a/src/FillSpace.jsx b/src/FillSpace.jsx
index 724e661..5262e0e 100644
--- a/src/FillSpace.jsx
+++ b/src/FillSpace.jsx
@@ -54,6 +54,21 @@ function renderRowElement(renderItem, item, index) {
return renderItem(item, index);
}
+/**
+ * Data-free probe of the row height, rendered hidden. Class components
+ * (e.g. `renderItem={ArtikelMarke}`) tolerate empty props
+ * (`brand`/`item` undefined) and keep a fixed height (40px thumb /
+ * text field), so the probe measures the row without depending on the
+ * first data element. Plain callbacks are NOT probed — calling arbitrary
+ * user code with `undefined` could throw — they fall back to the first
+ * rendered data row.
+ */
+function renderProbeElement(renderItem) {
+ if (!isRowComponent(renderItem)) return null;
+ const Row = renderItem;
+ return
;
+}
+
class FillSpace extends Component {
constructor(props) {
super(props);
@@ -74,6 +89,7 @@ class FillSpace extends Component {
this.ref = null;
this.contentRef = null;
this.unitRef = null;
+ this.probeRef = null;
this.paginationRef = null;
this.wheelAcc = 0;
this.observer = null;
@@ -232,13 +248,19 @@ class FillSpace extends Component {
contentHeight = this.contentRef.offsetHeight;
}
- // Paginated: first rendered row is the measure element. Legacy: hidden copy.
+ // Paginated: hidden probe rendered from `renderItem` itself (no data).
+ // Legacy: hidden copy.
const paginated = Array.isArray(items) && typeof renderItem === 'function';
let unitHeight = this.state.unitHeight;
if (paginated) {
- const firstRow = this.contentRef?.querySelector?.('[data-fill-row]') ?? this.contentRef?.firstElementChild;
- const h = firstRow?.offsetHeight;
- if (h > 0) unitHeight = h;
+ const probeH = this.probeRef?.offsetHeight;
+ if (probeH > 0) {
+ unitHeight = probeH;
+ } else {
+ const firstRow = this.contentRef?.querySelector?.('[data-fill-row]') ?? this.contentRef?.firstElementChild;
+ const h = firstRow?.offsetHeight;
+ if (h > 0) unitHeight = h;
+ }
if (!(unitHeight > 0) && measureElement != null && this.unitRef) {
const fallback = this.unitRef.offsetHeight;
if (fallback > 0) unitHeight = fallback;
@@ -476,7 +498,7 @@ class FillSpace extends Component {
/** Pagination header + one page of rows. Wheel over the list flips pages. */
renderPaginated({ minHeight, maxHeight, debug, measureGap, sx, rest }) {
- const { items, renderItem, onWheel } = this.props;
+ const { items, renderItem, measureElement, onWheel } = this.props;
const { height, pageSize, currentPage, measured } = this.state;
const total = items.length;
const pageCount = Math.max(1, Math.ceil(total / Math.max(1, pageSize)));
@@ -485,6 +507,9 @@ class FillSpace extends Component {
const pageItems = items.slice(offset, offset + pageSize);
// Hidden until the fit is measured — no "1–10" flash on load.
const showPagination = measured && total > pageSize;
+ // Hidden data-free probe: measures `renderItem` itself (no data), so
+ // the first pass already uses the final row height — one pass, no flip.
+ const probe = renderProbeElement(renderItem) ?? measureElement;
return (
<>
@@ -588,6 +613,28 @@ class FillSpace extends Component {
))}
+ {probe != null ? (
+ {
+ this.probeRef = el;
+ }}
+ aria-hidden
+ sx={{
+ position: 'absolute',
+ left: 0,
+ top: 0,
+ width: '100%',
+ visibility: 'hidden',
+ pointerEvents: 'none',
+ }}
+ >
+
+
+ {probe}
+
+
+
+ ) : null}
{debug ? (