Fixes the issue with less forgiving Typescript

This commit is contained in:
Kr3mu
2025-08-31 15:34:50 +02:00
parent 8aca701c40
commit 8dc6f8dfab
2 changed files with 83 additions and 93 deletions
+16 -16
View File
@@ -1,19 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="https://kit-pro.fontawesome.com/releases/v6.2.0/css/pro.min.css" rel="stylesheet">
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ESX Menu Default</title>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="https://kit-pro.fontawesome.com/releases/v6.2.0/css/pro.min.css" rel="stylesheet">
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ESX Menu Default</title>
<script type="module" crossorigin src="./assets/index-Begvl3m4.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-DB0yiboF.css">
</head>
<body>
<div id="root"></div>
</body>
</head>
<body>
<div id="root"></div>
</body>
+67 -77
View File
@@ -1,106 +1,96 @@
import React, { useEffect, useState } from "react";
import { useNuiEvent } from "@/hooks/useNuiEvent";
import { AnimatePresence, motion } from "framer-motion";
import { AnimatePresence, HTMLMotionProps, motion } from "framer-motion";
import Menu from "@/components/menu";
import { IconProp } from "@fortawesome/fontawesome-svg-core";
export interface Element {
label: string;
name: string;
description?: string;
icon?: IconProp;
value?: number;
type?: "slider";
min: number;
max: number;
options?: string[];
usable?: boolean;
unselectable?: boolean;
disableRightArrow?: boolean;
label: string;
name: string;
description?: string;
icon?: IconProp;
value?: number;
type?: "slider";
min: number;
max: number;
options?: string[];
usable?: boolean;
unselectable?: boolean;
disableRightArrow?: boolean;
}
export interface MenuData {
title: string;
namespace: string;
name: string;
align:
| "top-left"
| "top-right"
| "bottom-left"
| "bottom-right"
| "center"
| "left-center"
| "right-center";
elements: Element[];
title: string;
namespace: string;
name: string;
align: "top-left" | "top-right" | "bottom-left" | "bottom-right" | "center" | "left-center" | "right-center";
elements: Element[];
}
export interface CloseData {
namespace: string;
name: string;
namespace: string;
name: string;
}
const visibility_animation = {
initial: { opacity: 0 },
animate: {
opacity: 1,
transition: { duration: 0.3, ease: [0, 0, 0.2, 1] },
},
exit: {
opacity: 0,
transition: { duration: 0.3, ease: [0.4, 0, 1, 1] },
},
const visibility_animation: HTMLMotionProps<"div"> = {
initial: { opacity: 0 },
animate: {
opacity: 1,
transition: { duration: 0.3, ease: [0, 0, 0.2, 1] },
},
exit: {
opacity: 0,
transition: { duration: 0.3, ease: [0.4, 0, 1, 1] },
},
};
const App: React.FC = () => {
const [_, setCreatedMenus] = useState<Record<string, MenuData[]>>({});
const [_, setCreatedMenus] = useState<Record<string, MenuData[]>>({});
const [currentMenu, setCurrentMenu] = useState<MenuData | null>(null);
const [currentMenu, setCurrentMenu] = useState<MenuData | null>(null);
useNuiEvent<MenuData>("openMenu", (data) => {
setCreatedMenus((prev) => {
const list = prev[data.namespace] ?? [];
return {
...prev,
[data.namespace]: [...list, data],
};
useNuiEvent<MenuData>("openMenu", (data) => {
setCreatedMenus((prev) => {
const list = prev[data.namespace] ?? [];
return {
...prev,
[data.namespace]: [...list, data],
};
});
console.log(JSON.stringify(data));
setCurrentMenu(data);
});
console.log(JSON.stringify(data))
useNuiEvent<CloseData>("closeMenu", ({ namespace, name }) => {
setCreatedMenus((prev) => {
const list = prev[namespace] ?? [];
const nextList = list.filter((m) => m.name !== name);
setCurrentMenu(data);
});
const next = { ...prev };
if (nextList.length > 0) {
next[namespace] = nextList;
} else {
delete next[namespace];
}
useNuiEvent<CloseData>("closeMenu", ({ namespace, name }) => {
setCreatedMenus((prev) => {
const list = prev[namespace] ?? [];
const nextList = list.filter((m) => m.name !== name);
const all = Object.values(next).flat();
setCurrentMenu(all.length > 0 ? all[all.length - 1] : null);
const next = { ...prev };
if (nextList.length > 0) {
next[namespace] = nextList;
} else {
delete next[namespace];
}
const all = Object.values(next).flat();
setCurrentMenu(all.length > 0 ? all[all.length - 1] : null);
return next;
return next;
});
});
});
return (
<AnimatePresence mode="wait">
{currentMenu && (
<motion.div
key={`${currentMenu.namespace}:${currentMenu.name}`}
{...visibility_animation}
>
<Menu data={currentMenu} />
</motion.div>
)}
</AnimatePresence>
);
return (
<AnimatePresence mode="wait">
{currentMenu && (
<motion.div key={`${currentMenu.namespace}:${currentMenu.name}`} {...visibility_animation}>
<Menu data={currentMenu} />
</motion.div>
)}
</AnimatePresence>
);
};
export default App;