This commit is contained in:
seb
2026-10-09 19:44:57 +02:00
parent db5a64a69a
commit 9f8b46aa49

View File

@@ -12,7 +12,8 @@ import { alpha } from '@mui/material/styles';
* @defaultExport
*
* @prop {React.Ref} [aboveRef] - Ref to the element immediately above the spacer. It is observed (not strictly required) so the spacer re-measures when that element's height changes.
* @prop {React.Ref} [belowRef] - Ref to the footer element below. Its height (plus top margin) is reserved so the footer stays visible without page scrolling.
* @prop {React.Ref | React.Ref[]} [belowRef] - Ref(s) to footer element(s) below. Their heights (plus top margins) are reserved so footers stay visible without page scrolling.
* @prop {number} [reserveBottom=0] - Extra px to reserve below (e.g. app-shell bottom padding, tile padding) so the spacer never overfills the viewport.
* @prop {ReactNode} [measureElement] - When given, this element is used as the measurement unit of the spacer: its height is read from a hidden copy and it is repeated top-to-bottom to fill only the leftover space below `children` (like a repeating ruler/row pattern). When omitted, only `children` are rendered.
* @prop {number} [measureGap=0] - Vertical gap (px) between repeated `measureElement` units.
* @prop {(count: number) => void} [onMeasurement] - Called whenever the number of `measureElement` units that would fit in the whole spacer height changes, as if there were no `children` (i.e. the total row count the space could hold). Fires once after mount with the initial count.
@@ -126,6 +127,7 @@ class FillSpace extends Component {
const {
belowRef,
containerRef,
reserveBottom = 0,
measureElement,
measureGap = 0,
minHeight = 0,
@@ -141,13 +143,19 @@ class FillSpace extends Component {
const abovePx = rect.top + window.scrollY;
// Height to reserve for the footer below (its box + top margin).
const belowEl = belowRef?.current;
const belowList = Array.isArray(belowRef) ? belowRef : [belowRef];
let belowPx = 0;
if (belowEl && belowEl.offsetParent !== null) {
belowPx = belowEl.offsetHeight;
const marginTop = parseFloat(window.getComputedStyle(belowEl).marginTop);
belowPx += Number.isFinite(marginTop) ? marginTop : 0;
for (const ref of belowList) {
const belowEl = ref?.current;
if (belowEl && belowEl.offsetParent !== null) {
belowPx += belowEl.offsetHeight;
const marginTop = parseFloat(window.getComputedStyle(belowEl).marginTop);
belowPx += Number.isFinite(marginTop) ? marginTop : 0;
}
}
// Extra trailing space (app-shell padding, tile padding) that must stay
// visible below the spacer so the page never scrolls.
belowPx += Number(reserveBottom) || 0;
const containerEl = containerRef && 'current' in containerRef ? containerRef.current : containerRef;
let available;