feat: redesign settings page

This commit is contained in:
butterfly
2024-04-24 15:44:24 +08:00
parent f7074bba8c
commit c99086447e
55 changed files with 2603 additions and 1446 deletions

View File

@@ -1,5 +1,7 @@
import useRelativePosition from "@/app/hooks/useRelativePosition";
import { getCSSVar } from "@/app/utils";
import { useMemo, useState } from "react";
import { createPortal } from "react-dom";
const ArrowIcon = ({ color }: { color: string }) => {
return (
@@ -19,6 +21,20 @@ const ArrowIcon = ({ color }: { color: string }) => {
};
const baseZIndex = 100;
const popoverRootName = "popoverRoot";
let popoverRoot = document.querySelector(
`#${popoverRootName}`,
) as HTMLDivElement;
if (!popoverRoot) {
popoverRoot = document.createElement("div");
document.body.appendChild(popoverRoot);
popoverRoot.style.height = "0px";
popoverRoot.style.width = "100%";
popoverRoot.style.position = "fixed";
popoverRoot.style.bottom = "0";
popoverRoot.style.zIndex = "100";
popoverRoot.id = "popoverRootName";
}
export default function Popover(props: {
content?: JSX.Element | string;
@@ -46,6 +62,21 @@ export default function Popover(props: {
} = props;
const [internalShow, setShow] = useState(false);
const { position, getRelativePosition } = useRelativePosition({
delay: 0,
});
const {
distanceToBottomBoundary = 0,
distanceToLeftBoundary = 0,
distanceToRightBoundary = -10000,
distanceToTopBoundary = 0,
targetH = 0,
targetW = 0,
} = position?.poi || {};
let placementStyle: React.CSSProperties = {};
const popoverCommonClass = `absolute p-2 box-border`;
const mergedShow = show ?? internalShow;
@@ -56,6 +87,13 @@ export default function Popover(props: {
switch (placement) {
case "b":
placementStyle = {
top: `calc(-${distanceToBottomBoundary}px + 0.5rem)`,
left: `calc(${distanceToLeftBoundary + targetW}px - ${
targetW * 0.02
}px)`,
transform: "translateX(-50%)",
};
placementClassName =
"top-[calc(100%+0.5rem)] left-[50%] translate-x-[calc(-50%)]";
arrowClassName += "top-[calc(100%+0.5rem)] translate-y-[calc(-100%)]";
@@ -67,32 +105,51 @@ export default function Popover(props: {
// placementClassName = '';
// break;
case "rb":
placementClassName = "top-[calc(100%+0.5rem)] translate-x-[calc(-2%)]";
arrowClassName += "top-[calc(100%+0.5rem)] translate-y-[calc(-100%)]";
break;
case "lt":
placementClassName =
"bottom-[calc(100%+0.5rem)] left-[100%] translate-x-[calc(-98%)]";
arrowClassName += "bottom-[calc(100%+0.5rem)] translate-y-[calc(100%)]";
break;
case "lb":
placementClassName =
"top-[calc(100%+0.5rem)] left-[100%] translate-x-[calc(-98%)]";
placementStyle = {
top: `calc(-${distanceToBottomBoundary}px + 0.5rem)`,
right: `calc(${distanceToRightBoundary}px - ${targetW * 0.02}px)`,
};
placementClassName = "top-[calc(100%+0.5rem)] right-[calc(-2%)]";
arrowClassName += "top-[calc(100%+0.5rem)] translate-y-[calc(-100%)]";
break;
case "rt":
placementClassName = "bottom-[calc(100%+0.5rem)] translate-x-[calc(-2%)]";
placementStyle = {
bottom: `calc(${distanceToBottomBoundary + targetH}px + 0.5rem)`,
right: `calc(${distanceToRightBoundary}px - ${targetW * 0.02}px)`,
};
placementClassName = "bottom-[calc(100%+0.5rem)] right-[calc(-2%)]";
arrowClassName += "bottom-[calc(100%+0.5rem)] translate-y-[calc(100%)]";
break;
case "lt":
placementStyle = {
bottom: `calc(${distanceToBottomBoundary + targetH}px + 0.5rem)`,
left: `calc(${distanceToLeftBoundary}px - ${targetW * 0.02}px)`,
};
placementClassName = "bottom-[calc(100%+0.5rem)] left-[calc(-2%)]";
arrowClassName += "bottom-[calc(100%+0.5rem)] translate-y-[calc(100%)]";
break;
case "lb":
placementStyle = {
top: `calc(-${distanceToBottomBoundary}px + 0.5rem)`,
left: `calc(${distanceToLeftBoundary}px - ${targetW * 0.02}px)`,
};
placementClassName = "top-[calc(100%+0.5rem)] left-[calc(-2%)]";
arrowClassName += "top-[calc(100%+0.5rem)] translate-y-[calc(-100%)]";
break;
case "t":
default:
placementStyle = {
bottom: `calc(${distanceToBottomBoundary + targetH}px + 0.5rem)`,
left: `calc(${distanceToLeftBoundary + targetW}px - ${
targetW * 0.02
}px)`,
transform: "translateX(-50%)",
};
placementClassName =
"bottom-[calc(100%+0.5rem)] left-[50%] translate-x-[calc(-50%)]";
arrowClassName += "bottom-[calc(100%+0.5rem)] translate-y-[calc(100%)]";
}
const popoverCommonClass = "absolute p-2 box-border";
if (noArrow) {
arrowClassName = "hidden";
}
@@ -109,6 +166,12 @@ export default function Popover(props: {
e.preventDefault();
onShow?.(!mergedShow);
setShow(!mergedShow);
if (!mergedShow) {
getRelativePosition(e.currentTarget, "");
window.document.documentElement.style.overflow = "hidden";
} else {
window.document.documentElement.style.overflow = "auto";
}
}}
>
{children}
@@ -119,12 +182,15 @@ export default function Popover(props: {
<ArrowIcon color={internalBgColor} />
</div>
)}
<div
className={`${popoverCommonClass} ${placementClassName} ${popoverClassName}`}
style={{ zIndex: baseZIndex + 1 }}
>
{content}
</div>
{createPortal(
<div
className={`${popoverCommonClass} ${popoverClassName}`}
style={{ zIndex: baseZIndex + 1, ...placementStyle }}
>
{content}
</div>,
popoverRoot,
)}
<div
className=" fixed w-[100%] h-[100%] top-0 left-0 right-0 bottom-0"
style={{ zIndex: baseZIndex }}