Get the right grid offset even when offsetParent is a layout element
This commit is contained in:
@@ -91,6 +91,28 @@ export const Slot: FC<SlotProps> = ({ tile, style, className, ...props }) => (
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
interface Offset {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the offset of one element relative to an ancestor.
|
||||||
|
*/
|
||||||
|
function offset(element: HTMLElement, relativeTo: Element): Offset {
|
||||||
|
if (
|
||||||
|
!(element.offsetParent instanceof HTMLElement) ||
|
||||||
|
element.offsetParent === relativeTo
|
||||||
|
) {
|
||||||
|
return { x: element.offsetLeft, y: element.offsetTop };
|
||||||
|
} else {
|
||||||
|
const o = offset(element.offsetParent, relativeTo);
|
||||||
|
o.x += element.offsetLeft;
|
||||||
|
o.y += element.offsetTop;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface LayoutProps<Model, R extends HTMLElement> {
|
export interface LayoutProps<Model, R extends HTMLElement> {
|
||||||
ref: LegacyRef<R>;
|
ref: LegacyRef<R>;
|
||||||
model: Model;
|
model: Model;
|
||||||
@@ -228,24 +250,23 @@ export function Grid<
|
|||||||
const slotRects = useMemo(() => {
|
const slotRects = useMemo(() => {
|
||||||
const rects = new Map<string, Rect>();
|
const rects = new Map<string, Rect>();
|
||||||
|
|
||||||
if (layoutRoot !== null) {
|
if (gridRoot !== null && layoutRoot !== null) {
|
||||||
const slots = layoutRoot.getElementsByClassName(
|
const slots = layoutRoot.getElementsByClassName(
|
||||||
styles.slot,
|
styles.slot,
|
||||||
) as HTMLCollectionOf<HTMLElement>;
|
) as HTMLCollectionOf<HTMLElement>;
|
||||||
for (const slot of slots)
|
for (const slot of slots)
|
||||||
rects.set(slot.getAttribute("data-tile")!, {
|
rects.set(slot.getAttribute("data-tile")!, {
|
||||||
x: slot.offsetLeft,
|
...offset(slot, gridRoot),
|
||||||
y: slot.offsetTop,
|
|
||||||
width: slot.offsetWidth,
|
width: slot.offsetWidth,
|
||||||
height: slot.offsetHeight,
|
height: slot.offsetHeight,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return rects;
|
return rects;
|
||||||
// The rects may change due to the grid being resized or rerendered, but
|
// The rects may change due to the grid updating to a new generation, but
|
||||||
// eslint can't statically verify this
|
// eslint can't statically verify this
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [layoutRoot, generation]);
|
}, [gridRoot, layoutRoot, generation]);
|
||||||
|
|
||||||
const tileModels = useMemo(
|
const tileModels = useMemo(
|
||||||
() => getTileModels(model),
|
() => getTileModels(model),
|
||||||
|
|||||||
Reference in New Issue
Block a user