dirk-cfx-react 1.1.2 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,298 @@
1
+ 'use strict';
2
+
3
+ require('@mantine/core/styles.css');
4
+ require('@mantine/notifications/styles.css');
5
+ var core = require('@mantine/core');
6
+ var React = require('react');
7
+ var zustand = require('zustand');
8
+ var jsxRuntime = require('react/jsx-runtime');
9
+
10
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
+
12
+ var React__default = /*#__PURE__*/_interopDefault(React);
13
+
14
+ var __defProp = Object.defineProperty;
15
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
16
+ var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
17
+ var label = {
18
+ fontSize: "var(--mantine-font-size-xs)",
19
+ fontFamily: "Akrobat Bold",
20
+ letterSpacing: "0.05em",
21
+ textTransform: "uppercase"
22
+ };
23
+ var error = {
24
+ fontSize: "var(--mantine-font-size-xs)",
25
+ fontFamily: "Akrobat Regular"
26
+ };
27
+ var theme = core.createTheme({
28
+ primaryColor: "dirk",
29
+ primaryShade: 9,
30
+ defaultRadius: "xs",
31
+ fontFamily: "Akrobat Regular, sans-serif",
32
+ radius: {
33
+ xxs: "0.3vh",
34
+ xs: "0.5vh",
35
+ sm: "0.75vh",
36
+ md: "1vh",
37
+ lg: "1.5vh",
38
+ xl: "2vh",
39
+ xxl: "3vh"
40
+ },
41
+ fontSizes: {
42
+ xxs: "1.2vh",
43
+ xs: "1.5vh",
44
+ sm: "1.8vh",
45
+ md: "2.2vh",
46
+ lg: "2.8vh",
47
+ xl: "3.3vh",
48
+ xxl: "3.8vh"
49
+ },
50
+ lineHeights: {
51
+ xxs: "1.4vh",
52
+ xs: "1.8vh",
53
+ sm: "2.2vh",
54
+ md: "2.8vh",
55
+ lg: "3.3vh",
56
+ xl: "3.8vh"
57
+ },
58
+ spacing: {
59
+ xxs: "0.5vh",
60
+ xs: "0.75vh",
61
+ sm: "1.5vh",
62
+ md: "2vh",
63
+ lg: "3vh",
64
+ xl: "4vh",
65
+ xxl: "5vh"
66
+ },
67
+ components: {
68
+ Progress: {
69
+ styles: {
70
+ label: {
71
+ fontFamily: "Akrobat Bold",
72
+ letterSpacing: "0.05em",
73
+ textTransform: "uppercase"
74
+ },
75
+ root: {
76
+ backgroundColor: "rgba(77, 77, 77, 0.4)"
77
+ }
78
+ }
79
+ },
80
+ Textarea: {
81
+ styles: {
82
+ label,
83
+ error
84
+ }
85
+ },
86
+ Button: {
87
+ styles: {
88
+ root: {
89
+ fontSize: "var(--mantine-font-size-xs)"
90
+ }
91
+ }
92
+ },
93
+ Select: {
94
+ styles: {
95
+ label,
96
+ input: {
97
+ padding: "var(--mantine-spacing-sm)"
98
+ }
99
+ }
100
+ },
101
+ Pill: {
102
+ styles: (theme2) => ({
103
+ root: {
104
+ display: "inline-flex",
105
+ alignItems: "center",
106
+ justifyContent: "space-between",
107
+ backgroundColor: "rgba(76, 76, 76, 0.3)",
108
+ height: "fit-content",
109
+ textTransform: "uppercase",
110
+ letterSpacing: "0.05em",
111
+ fontFamily: "Akrobat Bold",
112
+ fontSize: theme2.fontSizes.xs,
113
+ borderRadius: theme2.defaultRadius,
114
+ padding: `${theme2.spacing.xs} ${theme2.spacing.sm}`
115
+ }
116
+ })
117
+ },
118
+ Input: {
119
+ styles: {
120
+ label,
121
+ error,
122
+ input: {
123
+ padding: "var(--mantine-spacing-sm)",
124
+ backgroundColor: "rgba(76, 76, 76, 0.3)"
125
+ }
126
+ }
127
+ },
128
+ ColorInput: {
129
+ styles: {
130
+ label,
131
+ input: {
132
+ padding: "var(--mantine-spacing-sm)"
133
+ }
134
+ }
135
+ },
136
+ TextInput: {
137
+ styles: {
138
+ label,
139
+ wrapper: {},
140
+ section: {
141
+ marginRight: "0.2vh"
142
+ },
143
+ input: {
144
+ padding: "var(--mantine-spacing-sm)"
145
+ }
146
+ }
147
+ },
148
+ NumberInput: {
149
+ styles: {
150
+ label,
151
+ input: {
152
+ padding: "var(--mantine-spacing-sm)"
153
+ },
154
+ section: {
155
+ pointerEvents: "all"
156
+ }
157
+ }
158
+ }
159
+ },
160
+ colors: {
161
+ dirk: [
162
+ "#ffffff",
163
+ "#f3fce9",
164
+ "#dbf5bd",
165
+ "#c3ee91",
166
+ "#ace765",
167
+ "#94e039",
168
+ "#7ac61f",
169
+ "#5f9a18",
170
+ "#29420a",
171
+ "#446e11"
172
+ ]
173
+ }
174
+ });
175
+ var theme_default = theme;
176
+
177
+ // src/utils/misc.ts
178
+ var isEnvBrowser = () => !window.invokeNative;
179
+
180
+ // src/utils/fetchNui.ts
181
+ async function fetchNui(eventName, data, mockData) {
182
+ const options = {
183
+ method: "post",
184
+ headers: {
185
+ "Content-Type": "application/json; charset=UTF-8"
186
+ },
187
+ body: JSON.stringify(data)
188
+ };
189
+ if (isEnvBrowser() && mockData === void 0) {
190
+ console.warn(
191
+ `[fetchNui] Called fetchNui for event "${eventName}" in browser environment without mockData. Returning empty object.`
192
+ );
193
+ return {};
194
+ }
195
+ const resourceName = window.GetParentResourceName ? window.GetParentResourceName() : "nui-frame-app";
196
+ const resp = await fetch(`https://${resourceName}/${eventName}`, options);
197
+ return await resp.json();
198
+ }
199
+ async function registerInitialFetch(eventName, data, mockData) {
200
+ const fetcher = () => fetchNui(eventName, data, mockData);
201
+ return fetcher();
202
+ }
203
+
204
+ // src/utils/useSettings.ts
205
+ var useSettings = zustand.create(() => ({
206
+ hydrated: false,
207
+ game: "fivem",
208
+ primaryColor: "dirk",
209
+ primaryShade: 9,
210
+ itemImgPath: "",
211
+ customTheme: {}
212
+ }));
213
+ registerInitialFetch("GET_SETTINGS").then((data) => {
214
+ useSettings.setState({
215
+ ...data,
216
+ hydrated: true
217
+ });
218
+ }).catch(() => {
219
+ useSettings.setState({ hydrated: true });
220
+ });
221
+
222
+ // src/utils/mergeMantineTheme.ts
223
+ var isValidColorScale = (v) => Array.isArray(v) && v.length >= 5 && v.every((c) => typeof c === "string");
224
+ function mergeMantineThemeSafe(base, custom, override) {
225
+ const colors = { ...base.colors };
226
+ for (const [key, value] of Object.entries(custom ?? {})) {
227
+ if (isValidColorScale(value)) {
228
+ colors[key] = value;
229
+ } else {
230
+ console.warn(`[theme] invalid color ignored: ${key}`, value);
231
+ }
232
+ }
233
+ return {
234
+ ...base,
235
+ ...override,
236
+ colors: {
237
+ ...colors,
238
+ ...override?.colors ?? {}
239
+ }
240
+ };
241
+ }
242
+ var DirkErrorBoundary = class extends React__default.default.Component {
243
+ constructor() {
244
+ super(...arguments);
245
+ __publicField(this, "state", { error: null });
246
+ }
247
+ static getDerivedStateFromError(error2) {
248
+ return { error: error2 };
249
+ }
250
+ componentDidCatch(error2, info) {
251
+ console.group("\u{1F525} Dirk UI Crash");
252
+ console.error(error2);
253
+ console.error(info.componentStack);
254
+ console.groupEnd();
255
+ }
256
+ render() {
257
+ if (!this.state.error) return this.props.children;
258
+ return /* @__PURE__ */ jsxRuntime.jsxs(core.Box, { p: "md", bg: "dark.8", children: [
259
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { c: "red", fw: 600, children: "UI crashed" }),
260
+ /* @__PURE__ */ jsxRuntime.jsx(core.Code, { block: true, mt: "sm", children: this.state.error.message })
261
+ ] });
262
+ }
263
+ };
264
+ function DirkProvider({ children, themeOverride }) {
265
+ const {
266
+ hydrated,
267
+ primaryColor,
268
+ primaryShade,
269
+ customTheme,
270
+ game
271
+ } = useSettings();
272
+ if (!hydrated) return null;
273
+ const mergedTheme = React.useMemo(
274
+ () => mergeMantineThemeSafe(
275
+ { ...theme_default, primaryColor, primaryShade },
276
+ customTheme,
277
+ themeOverride
278
+ ),
279
+ [primaryColor, primaryShade, customTheme, themeOverride]
280
+ );
281
+ React.useEffect(() => {
282
+ document.body.style.fontFamily = game === "rdr3" ? '"Red Dead", sans-serif' : '"Akrobat Regular", sans-serif';
283
+ }, [game]);
284
+ const content = isEnvBrowser() ? /* @__PURE__ */ jsxRuntime.jsx(
285
+ core.BackgroundImage,
286
+ {
287
+ w: "100vw",
288
+ h: "100vh",
289
+ src: game === "fivem" ? "https://i.ytimg.com/vi/TOxuNbXrO28/maxresdefault.jpg" : "https://raw.githubusercontent.com/Jump-On-Studios/RedM-jo_libs/refs/heads/main/source-repositories/Menu/public/assets/images/background_dev.jpg",
290
+ children
291
+ }
292
+ ) : children;
293
+ return /* @__PURE__ */ jsxRuntime.jsx(DirkErrorBoundary, { children: /* @__PURE__ */ jsxRuntime.jsx(core.MantineProvider, { theme: mergedTheme, defaultColorScheme: "dark", children: content }) });
294
+ }
295
+
296
+ exports.DirkProvider = DirkProvider;
297
+ //# sourceMappingURL=index.cjs.map
298
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/theme.ts","../../src/utils/misc.ts","../../src/utils/fetchNui.ts","../../src/utils/useSettings.ts","../../src/utils/mergeMantineTheme.ts","../../src/providers/DirkErrorBoundary.tsx","../../src/providers/DirkProvider.tsx"],"names":["createTheme","theme","create","React","error","jsxs","Box","jsx","Text","Code","useMemo","useEffect","BackgroundImage","MantineProvider"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createTheme, MantineTheme, NumberInput } from \"@mantine/core\";\r\n\r\nexport const label = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n fontFamily: 'Akrobat Bold',\r\n letterSpacing: '0.05em',\r\n textTransform: 'uppercase', \r\n};\r\nexport const error = {\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n fontFamily: 'Akrobat Regular',\r\n};\r\n\r\nconst theme = createTheme({\r\n primaryColor: \"dirk\",\r\n primaryShade: 9,\r\n defaultRadius: \"xs\",\r\n fontFamily: \"Akrobat Regular, sans-serif\",\r\n\r\n radius:{\r\n xxs: '0.3vh',\r\n xs: '0.5vh',\r\n sm: '0.75vh',\r\n md: '1vh',\r\n lg: '1.5vh',\r\n xl: '2vh',\r\n xxl: '3vh',\r\n },\r\n\r\n fontSizes: {\r\n xxs: '1.2vh',\r\n xs: '1.5vh',\r\n sm: '1.8vh',\r\n md: '2.2vh',\r\n lg: '2.8vh',\r\n xl: '3.3vh',\r\n xxl: '3.8vh',\r\n },\r\n\r\n lineHeights: {\r\n xxs: '1.4vh',\r\n xs: '1.8vh',\r\n sm: '2.2vh',\r\n md: '2.8vh',\r\n lg: '3.3vh',\r\n xl: '3.8vh',\r\n },\r\n\r\n spacing:{\r\n xxs: '0.5vh',\r\n xs: '0.75vh',\r\n sm: '1.5vh',\r\n md: '2vh',\r\n lg: '3vh',\r\n xl: '4vh',\r\n xxl: '5vh',\r\n },\r\n\r\n components:{\r\n Progress:{\r\n styles:{\r\n label: {\r\n fontFamily: 'Akrobat Bold',\r\n letterSpacing: '0.05em',\r\n textTransform: 'uppercase', \r\n \r\n },\r\n root:{\r\n backgroundColor: 'rgba(77, 77, 77, 0.4)',\r\n },\r\n \r\n }\r\n },\r\n Textarea: {\r\n styles:{\r\n label: label,\r\n error: error,\r\n },\r\n },\r\n\r\n Button:{\r\n styles:{\r\n root:{\r\n fontSize: 'var(--mantine-font-size-xs)',\r\n },\r\n },\r\n },\r\n\r\n Select:{\r\n styles:{\r\n label: label,\r\n input:{\r\n padding: 'var(--mantine-spacing-sm)',\r\n },\r\n }\r\n },\r\n\r\n Pill: {\r\n styles: (theme: MantineTheme) => ({\r\n root: {\r\n display: 'inline-flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n backgroundColor: 'rgba(76, 76, 76, 0.3)',\r\n height: 'fit-content',\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.05em',\r\n fontFamily: 'Akrobat Bold',\r\n fontSize: theme.fontSizes.xs,\r\n borderRadius: theme.defaultRadius,\r\n padding: `${theme.spacing.xs} ${theme.spacing.sm}`,\r\n }\r\n })\r\n },\r\n\r\n Input:{\r\n styles: {\r\n label: label,\r\n error: error,\r\n\r\n input:{\r\n padding: 'var(--mantine-spacing-sm)',\r\n backgroundColor: 'rgba(76, 76, 76, 0.3)', \r\n },\r\n },\r\n },\r\n ColorInput:{\r\n styles: {\r\n label: label,\r\n input:{\r\n padding: 'var(--mantine-spacing-sm)',\r\n },\r\n },\r\n },\r\n TextInput:{\r\n styles:{\r\n label: label,\r\n wrapper:{\r\n \r\n },\r\n section:{\r\n marginRight: '0.2vh',\r\n },\r\n\r\n input:{\r\n padding: 'var(--mantine-spacing-sm)',\r\n \r\n \r\n },\r\n }\r\n },\r\n NumberInput:{\r\n \r\n styles:{\r\n label: label,\r\n input:{\r\n padding: 'var(--mantine-spacing-sm)',\r\n },\r\n section:{\r\n pointerEvents: 'all',\r\n },\r\n }\r\n }\r\n },\r\n\r\n colors: {\r\n\r\n dirk:[\r\n \"#ffffff\",\r\n \"#f3fce9\",\r\n \"#dbf5bd\",\r\n \"#c3ee91\",\r\n \"#ace765\",\r\n \"#94e039\",\r\n \"#7ac61f\",\r\n \"#5f9a18\",\r\n \"#29420a\",\r\n \"#446e11\",\r\n ],\r\n },\r\n});\r\n\r\n\r\nexport default theme;","export const isEnvBrowser = (): boolean => !(window as any).invokeNative;\r\n\r\n// Basic no operation function\r\nexport const noop = () => {};\r\n\r\nexport const splitFAString = (faString:string) => {\r\n const [prefix, newIcon] = faString.split('-');\r\n if (!prefix || !newIcon) return {prefix: 'fas', newIcon: 'question'};\r\n return {prefix, newIcon};\r\n}\r\n\r\nexport const numberToRoman = (num:number) => {\r\n const romanNumerals = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X', 'XI', 'XII', 'XIII', 'XIV', 'XV', 'XVI', 'XVII', 'XVIII', 'XIX', 'XX'] \r\n return romanNumerals[num]\r\n}\r\n\r\nexport const copyToClipboard = (text:string) => {\r\n const el = document.createElement('textarea');\r\n el.value = text;\r\n document.body.appendChild(el);\r\n el.select();\r\n document.execCommand('copy');\r\n document.body.removeChild(el);\r\n}\r\n\r\nexport const openLink = (url:string) => {\r\n if (isEnvBrowser()) {\r\n window.open(url, '_blank');\r\n } else {\r\n // @ts-expect-error -- invokeNative exists in NUI\r\n window.invokeNative('openLink', url);\r\n } \r\n}","import { useEffect } from \"react\";\r\nimport { isEnvBrowser } from \"./misc\";\r\n\r\n/**\r\n * Simple wrapper around fetch API tailored for CEF/NUI use.\r\n */\r\nexport async function fetchNui<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const options = {\r\n method: \"post\",\r\n headers: {\r\n \"Content-Type\": \"application/json; charset=UTF-8\",\r\n },\r\n body: JSON.stringify(data),\r\n };\r\n\r\n if (isEnvBrowser() && mockData) return mockData;\r\n if (isEnvBrowser() && mockData === undefined) {\r\n console.warn(\r\n `[fetchNui] Called fetchNui for event \"${eventName}\" in browser environment without mockData. Returning empty object.`,\r\n );\r\n return {} as T;\r\n }\r\n\r\n const resourceName = (window as any).GetParentResourceName\r\n ? (window as any).GetParentResourceName()\r\n : \"nui-frame-app\";\r\n\r\n const resp = await fetch(`https://${resourceName}/${eventName}`, options);\r\n return await resp.json();\r\n}\r\n\r\n// -----------------------------\r\n// Initial fetch registration\r\n// -----------------------------\r\nexport type InitialFetch<T> = () => Promise<T>;\r\nexport const initialFetches: Record<string, InitialFetch<unknown>> = {};\r\n\r\n/**\r\n * Registers an initial fetch that automatically uses fetchNui.\r\n * Works like:\r\n * ```ts\r\n * registerInitialFetch<{ name: string }>(\"MY_EVENT_NAME\", undefined, { name: \"Mocky\" });\r\n * ```\r\n * and returns a Promise resolving to the same type as fetchNui.\r\n */\r\nexport async function registerInitialFetch<T = unknown>(\r\n eventName: string,\r\n data?: unknown,\r\n mockData?: T,\r\n): Promise<T> {\r\n const fetcher = () => fetchNui<T>(eventName, data, mockData);\r\n initialFetches[eventName] = fetcher;\r\n return fetcher(); // run immediately if needed\r\n}\r\n\r\n/**\r\n * Runs all registered initial fetches in parallel.\r\n */\r\nexport async function runFetches() {\r\n return Promise.all(\r\n Object.entries(initialFetches).map(async ([eventName, fetcher]) => {\r\n const data = await fetcher();\r\n return { eventName, data };\r\n }),\r\n );\r\n}\r\n\r\n/**\r\n * React hook to automatically run all registered fetches on mount.\r\n */\r\nexport const useAutoFetcher = () => {\r\n useEffect(() => {\r\n if (isEnvBrowser()) return;\r\n const run = async () => {\r\n const results = await runFetches();\r\n };\r\n run();\r\n }, []);\r\n};\r\n","import { create } from \"zustand\";\r\nimport { registerInitialFetch } from \"./fetchNui\";\r\n\r\nexport type SettingsState = {\r\n hydrated: boolean;\r\n game: \"fivem\" | \"rdr3\";\r\n primaryColor: string;\r\n primaryShade: number;\r\n itemImgPath: string;\r\n customTheme: Record<string, string[]>;\r\n};\r\n\r\nexport const useSettings = create<SettingsState>(() => ({\r\n hydrated: false,\r\n game: \"fivem\",\r\n primaryColor: \"dirk\",\r\n primaryShade: 9,\r\n itemImgPath: \"\",\r\n customTheme: {},\r\n}));\r\n\r\n\r\nregisterInitialFetch<Partial<SettingsState>>(\"GET_SETTINGS\")\r\n .then((data) => {\r\n useSettings.setState({\r\n ...data,\r\n hydrated: true,\r\n });\r\n })\r\n .catch(() => {\r\n useSettings.setState({ hydrated: true });\r\n });\r\n","import type { MantineThemeOverride } from \"@mantine/core\";\r\n\r\nconst isValidColorScale = (v: unknown): v is string[] =>\r\n Array.isArray(v) && v.length >= 5 && v.every(c => typeof c === \"string\");\r\n\r\nexport function mergeMantineThemeSafe(\r\n base: MantineThemeOverride,\r\n custom?: Record<string, string[]>,\r\n override?: MantineThemeOverride\r\n): MantineThemeOverride {\r\n const colors = { ...base.colors };\r\n\r\n for (const [key, value] of Object.entries(custom ?? {})) {\r\n if (isValidColorScale(value)) {\r\n colors[key] = value as [string, string, string, string, string, string, string, string, string, string, ...string[]];\r\n } else {\r\n console.warn(`[theme] invalid color ignored: ${key}`, value);\r\n }\r\n }\r\n\r\n return {\r\n ...base,\r\n ...override,\r\n colors: {\r\n ...colors,\r\n ...(override?.colors ?? {}),\r\n },\r\n };\r\n}\r\n","\"use client\";\r\n\r\nimport React from \"react\";\r\nimport { Box, Code, Text } from \"@mantine/core\";\r\n\r\nexport class DirkErrorBoundary extends React.Component<\r\n { children: React.ReactNode },\r\n { error: Error | null }\r\n> {\r\n state: { error: Error | null } = { error: null };\r\n\r\n static getDerivedStateFromError(error: Error) {\r\n return { error };\r\n }\r\n\r\n componentDidCatch(error: Error, info: React.ErrorInfo) {\r\n console.group(\"🔥 Dirk UI Crash\");\r\n console.error(error);\r\n console.error(info.componentStack);\r\n console.groupEnd();\r\n }\r\n\r\n render() {\r\n if (!this.state.error) return this.props.children;\r\n\r\n return (\r\n <Box p=\"md\" bg=\"dark.8\">\r\n <Text c=\"red\" fw={600}>UI crashed</Text>\r\n <Code block mt=\"sm\">{this.state.error.message}</Code>\r\n </Box>\r\n );\r\n }\r\n}\r\n","\"use client\";\r\n\r\nimport \"@mantine/core/styles.css\";\r\nimport \"@mantine/notifications/styles.css\";\r\n\r\nimport { MantineProvider, BackgroundImage, MantineColorShade } from \"@mantine/core\";\r\nimport { useMemo, useEffect } from \"react\";\r\nimport theme from \"@/theme\";\r\n\r\nimport { useSettings } from \"@/utils/useSettings\";\r\nimport { mergeMantineThemeSafe } from \"@/utils/mergeMantineTheme\";\r\nimport { DirkErrorBoundary } from \"./DirkErrorBoundary\";\r\nimport { isEnvBrowser } from \"@/utils\";\r\n\r\nexport type DirkProviderProps = {\r\n children: React.ReactNode;\r\n themeOverride?: any;\r\n};\r\n\r\nexport function DirkProvider({ children, themeOverride }: DirkProviderProps) {\r\n const {\r\n hydrated,\r\n primaryColor,\r\n primaryShade,\r\n customTheme,\r\n game,\r\n } = useSettings();\r\n\r\n // 🚫 do not render until state is stable\r\n if (!hydrated) return null;\r\n\r\n const mergedTheme = useMemo(\r\n () =>\r\n mergeMantineThemeSafe(\r\n { ...theme, primaryColor, primaryShade: primaryShade as MantineColorShade },\r\n customTheme,\r\n themeOverride\r\n ),\r\n [primaryColor, primaryShade, customTheme, themeOverride]\r\n );\r\n\r\n useEffect(() => {\r\n document.body.style.fontFamily =\r\n game === \"rdr3\"\r\n ? '\"Red Dead\", sans-serif'\r\n : '\"Akrobat Regular\", sans-serif';\r\n }, [game]);\r\n\r\n const content = isEnvBrowser() ? (\r\n <BackgroundImage\r\n w=\"100vw\"\r\n h=\"100vh\"\r\n src={game === \"fivem\"\r\n ? \"https://i.ytimg.com/vi/TOxuNbXrO28/maxresdefault.jpg\"\r\n : \"https://raw.githubusercontent.com/Jump-On-Studios/RedM-jo_libs/refs/heads/main/source-repositories/Menu/public/assets/images/background_dev.jpg\"}\r\n >\r\n {children}\r\n </BackgroundImage>\r\n ) : (\r\n children\r\n );\r\n\r\n return (\r\n <DirkErrorBoundary>\r\n <MantineProvider theme={mergedTheme} defaultColorScheme=\"dark\">\r\n {content}\r\n </MantineProvider>\r\n </DirkErrorBoundary>\r\n );\r\n}\r\n"]}
@@ -0,0 +1,9 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type DirkProviderProps = {
4
+ children: React.ReactNode;
5
+ themeOverride?: any;
6
+ };
7
+ declare function DirkProvider({ children, themeOverride }: DirkProviderProps): react_jsx_runtime.JSX.Element | null;
8
+
9
+ export { DirkProvider, type DirkProviderProps };
@@ -0,0 +1,9 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ type DirkProviderProps = {
4
+ children: React.ReactNode;
5
+ themeOverride?: any;
6
+ };
7
+ declare function DirkProvider({ children, themeOverride }: DirkProviderProps): react_jsx_runtime.JSX.Element | null;
8
+
9
+ export { DirkProvider, type DirkProviderProps };
@@ -0,0 +1,292 @@
1
+ import '@mantine/core/styles.css';
2
+ import '@mantine/notifications/styles.css';
3
+ import { createTheme, Box, Text, Code, MantineProvider, BackgroundImage } from '@mantine/core';
4
+ import React, { useMemo, useEffect } from 'react';
5
+ import { create } from 'zustand';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ var __defProp = Object.defineProperty;
9
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
+ var __publicField = (obj, key, value) => __defNormalProp(obj, key + "" , value);
11
+ var label = {
12
+ fontSize: "var(--mantine-font-size-xs)",
13
+ fontFamily: "Akrobat Bold",
14
+ letterSpacing: "0.05em",
15
+ textTransform: "uppercase"
16
+ };
17
+ var error = {
18
+ fontSize: "var(--mantine-font-size-xs)",
19
+ fontFamily: "Akrobat Regular"
20
+ };
21
+ var theme = createTheme({
22
+ primaryColor: "dirk",
23
+ primaryShade: 9,
24
+ defaultRadius: "xs",
25
+ fontFamily: "Akrobat Regular, sans-serif",
26
+ radius: {
27
+ xxs: "0.3vh",
28
+ xs: "0.5vh",
29
+ sm: "0.75vh",
30
+ md: "1vh",
31
+ lg: "1.5vh",
32
+ xl: "2vh",
33
+ xxl: "3vh"
34
+ },
35
+ fontSizes: {
36
+ xxs: "1.2vh",
37
+ xs: "1.5vh",
38
+ sm: "1.8vh",
39
+ md: "2.2vh",
40
+ lg: "2.8vh",
41
+ xl: "3.3vh",
42
+ xxl: "3.8vh"
43
+ },
44
+ lineHeights: {
45
+ xxs: "1.4vh",
46
+ xs: "1.8vh",
47
+ sm: "2.2vh",
48
+ md: "2.8vh",
49
+ lg: "3.3vh",
50
+ xl: "3.8vh"
51
+ },
52
+ spacing: {
53
+ xxs: "0.5vh",
54
+ xs: "0.75vh",
55
+ sm: "1.5vh",
56
+ md: "2vh",
57
+ lg: "3vh",
58
+ xl: "4vh",
59
+ xxl: "5vh"
60
+ },
61
+ components: {
62
+ Progress: {
63
+ styles: {
64
+ label: {
65
+ fontFamily: "Akrobat Bold",
66
+ letterSpacing: "0.05em",
67
+ textTransform: "uppercase"
68
+ },
69
+ root: {
70
+ backgroundColor: "rgba(77, 77, 77, 0.4)"
71
+ }
72
+ }
73
+ },
74
+ Textarea: {
75
+ styles: {
76
+ label,
77
+ error
78
+ }
79
+ },
80
+ Button: {
81
+ styles: {
82
+ root: {
83
+ fontSize: "var(--mantine-font-size-xs)"
84
+ }
85
+ }
86
+ },
87
+ Select: {
88
+ styles: {
89
+ label,
90
+ input: {
91
+ padding: "var(--mantine-spacing-sm)"
92
+ }
93
+ }
94
+ },
95
+ Pill: {
96
+ styles: (theme2) => ({
97
+ root: {
98
+ display: "inline-flex",
99
+ alignItems: "center",
100
+ justifyContent: "space-between",
101
+ backgroundColor: "rgba(76, 76, 76, 0.3)",
102
+ height: "fit-content",
103
+ textTransform: "uppercase",
104
+ letterSpacing: "0.05em",
105
+ fontFamily: "Akrobat Bold",
106
+ fontSize: theme2.fontSizes.xs,
107
+ borderRadius: theme2.defaultRadius,
108
+ padding: `${theme2.spacing.xs} ${theme2.spacing.sm}`
109
+ }
110
+ })
111
+ },
112
+ Input: {
113
+ styles: {
114
+ label,
115
+ error,
116
+ input: {
117
+ padding: "var(--mantine-spacing-sm)",
118
+ backgroundColor: "rgba(76, 76, 76, 0.3)"
119
+ }
120
+ }
121
+ },
122
+ ColorInput: {
123
+ styles: {
124
+ label,
125
+ input: {
126
+ padding: "var(--mantine-spacing-sm)"
127
+ }
128
+ }
129
+ },
130
+ TextInput: {
131
+ styles: {
132
+ label,
133
+ wrapper: {},
134
+ section: {
135
+ marginRight: "0.2vh"
136
+ },
137
+ input: {
138
+ padding: "var(--mantine-spacing-sm)"
139
+ }
140
+ }
141
+ },
142
+ NumberInput: {
143
+ styles: {
144
+ label,
145
+ input: {
146
+ padding: "var(--mantine-spacing-sm)"
147
+ },
148
+ section: {
149
+ pointerEvents: "all"
150
+ }
151
+ }
152
+ }
153
+ },
154
+ colors: {
155
+ dirk: [
156
+ "#ffffff",
157
+ "#f3fce9",
158
+ "#dbf5bd",
159
+ "#c3ee91",
160
+ "#ace765",
161
+ "#94e039",
162
+ "#7ac61f",
163
+ "#5f9a18",
164
+ "#29420a",
165
+ "#446e11"
166
+ ]
167
+ }
168
+ });
169
+ var theme_default = theme;
170
+
171
+ // src/utils/misc.ts
172
+ var isEnvBrowser = () => !window.invokeNative;
173
+
174
+ // src/utils/fetchNui.ts
175
+ async function fetchNui(eventName, data, mockData) {
176
+ const options = {
177
+ method: "post",
178
+ headers: {
179
+ "Content-Type": "application/json; charset=UTF-8"
180
+ },
181
+ body: JSON.stringify(data)
182
+ };
183
+ if (isEnvBrowser() && mockData === void 0) {
184
+ console.warn(
185
+ `[fetchNui] Called fetchNui for event "${eventName}" in browser environment without mockData. Returning empty object.`
186
+ );
187
+ return {};
188
+ }
189
+ const resourceName = window.GetParentResourceName ? window.GetParentResourceName() : "nui-frame-app";
190
+ const resp = await fetch(`https://${resourceName}/${eventName}`, options);
191
+ return await resp.json();
192
+ }
193
+ async function registerInitialFetch(eventName, data, mockData) {
194
+ const fetcher = () => fetchNui(eventName, data, mockData);
195
+ return fetcher();
196
+ }
197
+
198
+ // src/utils/useSettings.ts
199
+ var useSettings = create(() => ({
200
+ hydrated: false,
201
+ game: "fivem",
202
+ primaryColor: "dirk",
203
+ primaryShade: 9,
204
+ itemImgPath: "",
205
+ customTheme: {}
206
+ }));
207
+ registerInitialFetch("GET_SETTINGS").then((data) => {
208
+ useSettings.setState({
209
+ ...data,
210
+ hydrated: true
211
+ });
212
+ }).catch(() => {
213
+ useSettings.setState({ hydrated: true });
214
+ });
215
+
216
+ // src/utils/mergeMantineTheme.ts
217
+ var isValidColorScale = (v) => Array.isArray(v) && v.length >= 5 && v.every((c) => typeof c === "string");
218
+ function mergeMantineThemeSafe(base, custom, override) {
219
+ const colors = { ...base.colors };
220
+ for (const [key, value] of Object.entries(custom ?? {})) {
221
+ if (isValidColorScale(value)) {
222
+ colors[key] = value;
223
+ } else {
224
+ console.warn(`[theme] invalid color ignored: ${key}`, value);
225
+ }
226
+ }
227
+ return {
228
+ ...base,
229
+ ...override,
230
+ colors: {
231
+ ...colors,
232
+ ...override?.colors ?? {}
233
+ }
234
+ };
235
+ }
236
+ var DirkErrorBoundary = class extends React.Component {
237
+ constructor() {
238
+ super(...arguments);
239
+ __publicField(this, "state", { error: null });
240
+ }
241
+ static getDerivedStateFromError(error2) {
242
+ return { error: error2 };
243
+ }
244
+ componentDidCatch(error2, info) {
245
+ console.group("\u{1F525} Dirk UI Crash");
246
+ console.error(error2);
247
+ console.error(info.componentStack);
248
+ console.groupEnd();
249
+ }
250
+ render() {
251
+ if (!this.state.error) return this.props.children;
252
+ return /* @__PURE__ */ jsxs(Box, { p: "md", bg: "dark.8", children: [
253
+ /* @__PURE__ */ jsx(Text, { c: "red", fw: 600, children: "UI crashed" }),
254
+ /* @__PURE__ */ jsx(Code, { block: true, mt: "sm", children: this.state.error.message })
255
+ ] });
256
+ }
257
+ };
258
+ function DirkProvider({ children, themeOverride }) {
259
+ const {
260
+ hydrated,
261
+ primaryColor,
262
+ primaryShade,
263
+ customTheme,
264
+ game
265
+ } = useSettings();
266
+ if (!hydrated) return null;
267
+ const mergedTheme = useMemo(
268
+ () => mergeMantineThemeSafe(
269
+ { ...theme_default, primaryColor, primaryShade },
270
+ customTheme,
271
+ themeOverride
272
+ ),
273
+ [primaryColor, primaryShade, customTheme, themeOverride]
274
+ );
275
+ useEffect(() => {
276
+ document.body.style.fontFamily = game === "rdr3" ? '"Red Dead", sans-serif' : '"Akrobat Regular", sans-serif';
277
+ }, [game]);
278
+ const content = isEnvBrowser() ? /* @__PURE__ */ jsx(
279
+ BackgroundImage,
280
+ {
281
+ w: "100vw",
282
+ h: "100vh",
283
+ src: game === "fivem" ? "https://i.ytimg.com/vi/TOxuNbXrO28/maxresdefault.jpg" : "https://raw.githubusercontent.com/Jump-On-Studios/RedM-jo_libs/refs/heads/main/source-repositories/Menu/public/assets/images/background_dev.jpg",
284
+ children
285
+ }
286
+ ) : children;
287
+ return /* @__PURE__ */ jsx(DirkErrorBoundary, { children: /* @__PURE__ */ jsx(MantineProvider, { theme: mergedTheme, defaultColorScheme: "dark", children: content }) });
288
+ }
289
+
290
+ export { DirkProvider };
291
+ //# sourceMappingURL=index.js.map
292
+ //# sourceMappingURL=index.js.map