mirror of
https://github.com/nonebot/nonebot2.git
synced 2025-09-16 00:46:39 +00:00
🚧 add modal
This commit is contained in:
67
website/src/libs/resize.ts
Normal file
67
website/src/libs/resize.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import { useLayoutEffect, useRef } from "react";
|
||||
import ResizeObserver from "resize-observer-polyfill";
|
||||
|
||||
export function useResizeNotifier(
|
||||
element: HTMLElement | undefined,
|
||||
callback: () => void
|
||||
) {
|
||||
const callBackRef = useRef(callback);
|
||||
useLayoutEffect(() => {
|
||||
callBackRef.current = callback;
|
||||
}, [callback]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!element) return;
|
||||
|
||||
const resizeObserver = new ResizeObserver(
|
||||
withResizeLoopDetection(() => {
|
||||
callBackRef.current!();
|
||||
})
|
||||
);
|
||||
|
||||
resizeObserver.observe(element);
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect();
|
||||
};
|
||||
}, [element]);
|
||||
}
|
||||
|
||||
function withResizeLoopDetection(callback: () => void) {
|
||||
return (entries: ResizeObserverEntry[], resizeObserver: ResizeObserver) => {
|
||||
const elements = entries.map((entry) => entry.target);
|
||||
|
||||
const rectsBefore = elements.map((element) =>
|
||||
element.getBoundingClientRect()
|
||||
);
|
||||
|
||||
callback();
|
||||
|
||||
const rectsAfter = elements.map((element) =>
|
||||
element.getBoundingClientRect()
|
||||
);
|
||||
|
||||
const changedElements = elements.filter(
|
||||
(_, i) => !areRectSizesEqual(rectsBefore[i], rectsAfter[i])
|
||||
);
|
||||
|
||||
changedElements.forEach((element) =>
|
||||
unobserveUntilNextFrame(element, resizeObserver)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
function unobserveUntilNextFrame(
|
||||
element: Element,
|
||||
resizeObserver: ResizeObserver
|
||||
) {
|
||||
resizeObserver.unobserve(element);
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
resizeObserver.observe(element);
|
||||
});
|
||||
}
|
||||
|
||||
function areRectSizesEqual(rect1: DOMRect, rect2: DOMRect) {
|
||||
return rect1.width === rect2.width && rect1.height === rect2.height;
|
||||
}
|
Reference in New Issue
Block a user