mirror of
https://github.com/nonebot/nonebot2.git
synced 2025-09-07 20:46:45 +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;
|
||||
}
|
@ -23,7 +23,8 @@ export function filterObjs(filter: string, objs: Obj[]): Obj[] {
|
||||
o.project_link?.indexOf(filter) != -1 ||
|
||||
o.name.indexOf(filter) != -1 ||
|
||||
o.desc.indexOf(filter) != -1 ||
|
||||
o.author.indexOf(filter) != -1
|
||||
o.author.indexOf(filter) != -1 ||
|
||||
o.tags.filter((t) => t.label.indexOf(filter) != -1).length > 0
|
||||
);
|
||||
});
|
||||
}
|
||||
|
64
website/src/libs/width.ts
Normal file
64
website/src/libs/width.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { useLayoutEffect, useState } from "react";
|
||||
|
||||
import { useResizeNotifier } from "./resize";
|
||||
|
||||
export function getElementWidth(element: HTMLElement) {
|
||||
const style = getComputedStyle(element);
|
||||
|
||||
return (
|
||||
styleMetricToInt(style.marginLeft) +
|
||||
getWidth(element) +
|
||||
styleMetricToInt(style.marginRight)
|
||||
);
|
||||
}
|
||||
|
||||
export function getContentWidth(element: HTMLElement) {
|
||||
const style = getComputedStyle(element);
|
||||
|
||||
return (
|
||||
element.getBoundingClientRect().width -
|
||||
styleMetricToInt(style.borderLeftWidth) -
|
||||
styleMetricToInt(style.paddingLeft) -
|
||||
styleMetricToInt(style.paddingRight) -
|
||||
styleMetricToInt(style.borderRightWidth)
|
||||
);
|
||||
}
|
||||
|
||||
export function getNonContentWidth(element: HTMLElement) {
|
||||
const style = getComputedStyle(element);
|
||||
|
||||
return (
|
||||
styleMetricToInt(style.marginLeft) +
|
||||
styleMetricToInt(style.borderLeftWidth) +
|
||||
styleMetricToInt(style.paddingLeft) +
|
||||
styleMetricToInt(style.paddingRight) +
|
||||
styleMetricToInt(style.borderRightWidth) +
|
||||
styleMetricToInt(style.marginRight)
|
||||
);
|
||||
}
|
||||
|
||||
export function getWidth(element: HTMLElement) {
|
||||
return element.getBoundingClientRect().width;
|
||||
}
|
||||
|
||||
function styleMetricToInt(styleAttribute: string | null) {
|
||||
return styleAttribute ? parseInt(styleAttribute) : 0;
|
||||
}
|
||||
|
||||
export function useContentWidth(element: HTMLElement | undefined) {
|
||||
const [width, setWidth] = useState<number>();
|
||||
|
||||
function syncWidth() {
|
||||
const newWidth = element ? getContentWidth(element) : undefined;
|
||||
|
||||
if (width !== newWidth) {
|
||||
setWidth(newWidth);
|
||||
}
|
||||
}
|
||||
|
||||
useResizeNotifier(element, syncWidth);
|
||||
|
||||
useLayoutEffect(syncWidth);
|
||||
|
||||
return width;
|
||||
}
|
Reference in New Issue
Block a user