feat: add settings menu
All checks were successful
Deploy to VPS (dist) / deploy (push) Successful in 1m40s
All checks were successful
Deploy to VPS (dist) / deploy (push) Successful in 1m40s
This commit is contained in:
@@ -1,11 +1,27 @@
|
||||
@layer base {
|
||||
.overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.modalContainer {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 100;
|
||||
z-index: 102;
|
||||
}
|
||||
|
||||
.modalInner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: 320px;
|
||||
}
|
||||
|
||||
.modal {
|
||||
@@ -13,7 +29,19 @@
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
width: 100%;
|
||||
max-width: 320px;
|
||||
max-height: calc(
|
||||
var(--safe-area-height) - var(--header-total) - var(--navigation-total) - 70px
|
||||
);
|
||||
overflow: auto;
|
||||
padding: 13px;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #ffffff;
|
||||
-webkit-text-stroke: 0.7px #331b01;
|
||||
font-weight: 700;
|
||||
font-size: 24px;
|
||||
margin-bottom: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,85 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import type { ReactNode } from "react";
|
||||
import { AnimatePresence, motion } from "motion/react";
|
||||
|
||||
import SectionSurface from "../../surface/SectionSurface/SectionSurface";
|
||||
import SectionSurface from "@components/surface/SectionSurface";
|
||||
import { useLift } from "@components/lift";
|
||||
import classes from "./Modal.module.css";
|
||||
import { clsx, type ClassValue } from "clsx";
|
||||
|
||||
type Props = {
|
||||
open: boolean;
|
||||
children: ReactNode;
|
||||
onClose: () => void;
|
||||
liftIds?: string[];
|
||||
title?: ReactNode;
|
||||
className?: ClassValue;
|
||||
};
|
||||
|
||||
export default function Modal({ open, children, onClose }: Props) {
|
||||
export default function Modal({ open, children, onClose, liftIds, title, className }: Props) {
|
||||
const { setLiftedIds } = useLift();
|
||||
const prevLiftIdsRef = useRef<string>("");
|
||||
|
||||
useEffect(() => {
|
||||
const key = liftIds?.join(",") ?? "";
|
||||
|
||||
if (open && key) {
|
||||
if (key !== prevLiftIdsRef.current) {
|
||||
prevLiftIdsRef.current = key;
|
||||
setLiftedIds(liftIds!);
|
||||
}
|
||||
}
|
||||
|
||||
if (!open && prevLiftIdsRef.current) {
|
||||
prevLiftIdsRef.current = "";
|
||||
setLiftedIds([]);
|
||||
}
|
||||
}, [open, liftIds, setLiftedIds]);
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (prevLiftIdsRef.current) {
|
||||
setLiftedIds([]);
|
||||
}
|
||||
};
|
||||
}, [setLiftedIds]);
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{open && (
|
||||
<motion.div
|
||||
className={classes.overlay}
|
||||
initial={{ backdropFilter: "blur(0px)" }}
|
||||
animate={{ backdropFilter: "blur(8px)" }}
|
||||
exit={{ backdropFilter: "blur(0px)" }}
|
||||
transition={{ duration: 0.2 }}
|
||||
onClick={onClose}
|
||||
>
|
||||
<SectionSurface
|
||||
className={classes.modal}
|
||||
exit={{ scale: 0 }}
|
||||
transition={{ duration: 0.2, type: "spring" }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
<>
|
||||
<motion.div
|
||||
className={classes.overlay}
|
||||
initial={{ backdropFilter: "blur(0px)" }}
|
||||
animate={{ backdropFilter: "blur(8px)" }}
|
||||
exit={{ backdropFilter: "blur(0px)" }}
|
||||
transition={{ duration: 0.2 }}
|
||||
onClick={onClose}
|
||||
/>
|
||||
<motion.div
|
||||
className={classes.modalContainer}
|
||||
initial={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
onClick={onClose}
|
||||
>
|
||||
{children}
|
||||
</SectionSurface>
|
||||
</motion.div>
|
||||
{/* oxlint-disable-next-line jsx_a11y/no-static-element-interactions*/}
|
||||
<div
|
||||
className={classes.modalInner}
|
||||
// oxlint-disable-next-line jsx_a11y/click-events-have-key-events
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{title && <div className={classes.title}>{title}</div>}
|
||||
<SectionSurface
|
||||
className={clsx(classes.modal, className)}
|
||||
exit={{ scale: 0 }}
|
||||
transition={{ duration: 0.2, type: "spring" }}
|
||||
>
|
||||
{children}
|
||||
</SectionSurface>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user