mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-29 01:08:54 +00:00
Fixes the issue with less forgiving Typescript
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user