dirk-cfx-react 1.1.72 → 1.1.75

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.
package/dist/index.cjs CHANGED
@@ -12,6 +12,7 @@ var clickSoundUrl = require('./click_sound-PNCRRTM4.mp3');
12
12
  var hoverSoundUrl = require('./hover_sound-NBUA222C.mp3');
13
13
  var notifications = require('@mantine/notifications');
14
14
  var reactQuery = require('@tanstack/react-query');
15
+ var colorsGenerator = require('@mantine/colors-generator');
15
16
  require('@mantine/core/styles.css');
16
17
  require('@mantine/notifications/styles.css');
17
18
  require('./styles/fonts.css');
@@ -22,6 +23,7 @@ var fontawesomeSvgCore = require('@fortawesome/fontawesome-svg-core');
22
23
  var freeBrandsSvgIcons = require('@fortawesome/free-brands-svg-icons');
23
24
  var freeRegularSvgIcons = require('@fortawesome/free-regular-svg-icons');
24
25
  var freeSolidSvgIcons = require('@fortawesome/free-solid-svg-icons');
26
+ var zod = require('zod');
25
27
 
26
28
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
27
29
 
@@ -1340,7 +1342,11 @@ async function fetchNui(eventName, data, mockData) {
1340
1342
  return {};
1341
1343
  }
1342
1344
  const overrideResourceName = useSettings.getState().overideResourceName;
1343
- const resourceName = window.GetParentResourceName ? window.GetParentResourceName() : overrideResourceName ? overrideResourceName : "dirk-cfx-react";
1345
+ const hasResourceContext = typeof window.GetParentResourceName === "function" || !!overrideResourceName;
1346
+ if (!hasResourceContext) {
1347
+ return mockData ?? {};
1348
+ }
1349
+ const resourceName = window.GetParentResourceName ? window.GetParentResourceName() : overrideResourceName;
1344
1350
  try {
1345
1351
  const resp = await fetch(`https://${resourceName}/${eventName}`, options);
1346
1352
  return await resp.json();
@@ -3083,9 +3089,25 @@ function SegmentedProgress(props) {
3083
3089
  }
3084
3090
  );
3085
3091
  }
3092
+ function getSizePreset(size, themeMdFontSize) {
3093
+ switch (size) {
3094
+ case "xs":
3095
+ return { iconFontSize: "1.2vh", iconPadding: "xxs", titleSize: "xxs", titleLineHeight: "1.2vh", descriptionSize: "xxs", innerGap: "xs", bottomPad: "xs" };
3096
+ case "sm":
3097
+ return { iconFontSize: "1.6vh", iconPadding: "xxs", titleSize: "xs", titleLineHeight: "1.6vh", descriptionSize: "xxs", innerGap: "xs", bottomPad: "xs" };
3098
+ case "lg":
3099
+ return { iconFontSize: "2.6vh", iconPadding: "sm", titleSize: "md", titleLineHeight: "2.6vh", descriptionSize: "sm", innerGap: "sm", bottomPad: "sm" };
3100
+ case "xl":
3101
+ return { iconFontSize: "3.2vh", iconPadding: "sm", titleSize: "lg", titleLineHeight: "3.2vh", descriptionSize: "md", innerGap: "md", bottomPad: "md" };
3102
+ case "md":
3103
+ default:
3104
+ return { iconFontSize: themeMdFontSize, iconPadding: "xs", titleSize: "sm", titleLineHeight: themeMdFontSize, descriptionSize: "xs", innerGap: "sm", bottomPad: "sm" };
3105
+ }
3106
+ }
3086
3107
  function Title(props) {
3087
3108
  const game = useSettings((state) => state.game);
3088
3109
  const theme2 = core.useMantineTheme();
3110
+ const preset = getSizePreset(props.size ?? "md", theme2.fontSizes.md);
3089
3111
  return /* @__PURE__ */ jsxRuntime.jsx(
3090
3112
  core.Flex,
3091
3113
  {
@@ -3094,71 +3116,50 @@ function Title(props) {
3094
3116
  gap: "xs",
3095
3117
  w: props.w || "100%",
3096
3118
  p: props.p || "unset",
3097
- pb: !props.p ? "sm" : props.p,
3119
+ pb: !props.p ? preset.bottomPad : props.p,
3098
3120
  style: {
3099
3121
  userSelect: "none",
3100
3122
  borderBottom: props.removeBorder ? "none" : `0.3vh solid ${props.borderColor || colorWithAlpha(theme2.colors[theme2.primaryColor][9], 0.5)}`
3101
3123
  },
3102
- children: /* @__PURE__ */ jsxRuntime.jsxs(
3103
- core.Flex,
3104
- {
3105
- align: "center",
3106
- justify: "center",
3107
- children: [
3108
- /* @__PURE__ */ jsxRuntime.jsxs(
3109
- core.Flex,
3124
+ children: /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", justify: "center", children: [
3125
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: preset.innerGap, pr: "xs", children: [
3126
+ /* @__PURE__ */ jsxRuntime.jsx(
3127
+ BorderedIcon,
3128
+ {
3129
+ icon: props.icon,
3130
+ fontSize: preset.iconFontSize,
3131
+ color: props.iconColor,
3132
+ p: preset.iconPadding
3133
+ }
3134
+ ),
3135
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", gap: "0.25vh", children: [
3136
+ /* @__PURE__ */ jsxRuntime.jsx(
3137
+ core.Text,
3110
3138
  {
3111
- align: "center",
3112
- gap: "sm",
3113
- pr: "xs",
3114
- children: [
3115
- /* @__PURE__ */ jsxRuntime.jsx(
3116
- BorderedIcon,
3117
- {
3118
- icon: props.icon,
3119
- fontSize: theme2.fontSizes.md,
3120
- color: props.iconColor
3121
- }
3122
- ),
3123
- /* @__PURE__ */ jsxRuntime.jsxs(
3124
- core.Flex,
3125
- {
3126
- direction: "column",
3127
- gap: "0.25vh",
3128
- children: [
3129
- /* @__PURE__ */ jsxRuntime.jsx(core.Text, { p: "0", size: "sm", style: {
3130
- lineHeight: theme2.fontSizes.md,
3131
- fontFamily: game == "fivem" ? "Akrobat Bold" : "Red Dead",
3132
- letterSpacing: "0.05em",
3133
- textTransform: "uppercase"
3134
- }, children: props.title }),
3135
- /* @__PURE__ */ jsxRuntime.jsx(
3136
- core.Text,
3137
- {
3138
- size: "xs",
3139
- c: "grey",
3140
- style: { whiteSpace: "normal", wordWrap: "break-word" },
3141
- children: props.description
3142
- }
3143
- )
3144
- ]
3145
- }
3146
- )
3147
- ]
3139
+ p: "0",
3140
+ size: preset.titleSize,
3141
+ style: {
3142
+ lineHeight: preset.titleLineHeight,
3143
+ fontFamily: game == "fivem" ? "Akrobat Bold" : "Red Dead",
3144
+ letterSpacing: "0.05em",
3145
+ textTransform: "uppercase"
3146
+ },
3147
+ children: props.title
3148
3148
  }
3149
3149
  ),
3150
3150
  /* @__PURE__ */ jsxRuntime.jsx(
3151
- core.Flex,
3151
+ core.Text,
3152
3152
  {
3153
- ml: "auto",
3154
- align: "center",
3155
- gap: "xs",
3156
- children: props.rightSection
3153
+ size: preset.descriptionSize,
3154
+ c: "grey",
3155
+ style: { whiteSpace: "normal", wordWrap: "break-word" },
3156
+ children: props.description
3157
3157
  }
3158
3158
  )
3159
- ]
3160
- }
3161
- )
3159
+ ] })
3160
+ ] }),
3161
+ /* @__PURE__ */ jsxRuntime.jsx(core.Flex, { ml: "auto", align: "center", gap: "xs", children: props.rightSection })
3162
+ ] })
3162
3163
  }
3163
3164
  );
3164
3165
  }
@@ -4835,7 +4836,22 @@ function ConfigPanelInner({
4835
4836
  if (result?.success) {
4836
4837
  const { store } = getScriptConfigInstance();
4837
4838
  form.reinitialize(cloneConfig(store.getState()));
4839
+ notifications.notifications.show({
4840
+ color: "green",
4841
+ title: locale("ConfigResetSuccessTitle"),
4842
+ message: locale("ConfigResetSuccessBody"),
4843
+ autoClose: 3e3
4844
+ });
4845
+ return;
4838
4846
  }
4847
+ const err = result?._error || "Unknown";
4848
+ console.warn(`[ConfigPanel] config reset failed: ${err}`);
4849
+ notifications.notifications.show({
4850
+ color: "red",
4851
+ title: locale("ConfigResetFailedTitle"),
4852
+ message: locale("ConfigResetFailedBody", err),
4853
+ autoClose: 6e3
4854
+ });
4839
4855
  },
4840
4856
  onClose: () => setResetOpen(false),
4841
4857
  zIndex: 300
@@ -4903,8 +4919,8 @@ function ConfigPanelInner({
4903
4919
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { size: "1.4vh", color })
4904
4920
  }
4905
4921
  ),
4906
- /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { minWidth: 0, lineHeight: 1 }, children: [
4907
- /* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "lg", ff: "Akrobat Bold", tt: "uppercase", lts: "0.04em", truncate: true, children: title }),
4922
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", style: { minWidth: 0, flex: 1, lineHeight: 1, overflow: "hidden" }, children: [
4923
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { size: "md", ff: "Akrobat Bold", tt: "uppercase", lts: "0.04em", truncate: true, children: title }),
4908
4924
  subtitle && /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.08em", c: color, truncate: true, children: subtitle })
4909
4925
  ] })
4910
4926
  ] }),
@@ -5845,6 +5861,17 @@ function AdminPageTitle(props) {
5845
5861
  /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", tt: "uppercase", lts: "0.1em", size: "sm", c: "rgba(255,255,255,0.6)", children: locale(props.title) })
5846
5862
  ] });
5847
5863
  }
5864
+ var placementStyle = (placement) => {
5865
+ switch (placement) {
5866
+ case "top-center":
5867
+ return { top: "1vh", left: "50%", transform: "translateX(-50%)" };
5868
+ case "top-right":
5869
+ return { top: "1vh", right: "1vh" };
5870
+ case "top-left":
5871
+ default:
5872
+ return { top: "1vh", left: "1vh" };
5873
+ }
5874
+ };
5848
5875
  var loadPersistedState = (storageKey) => {
5849
5876
  try {
5850
5877
  const raw = localStorage.getItem(storageKey);
@@ -5863,7 +5890,8 @@ function TestBed({
5863
5890
  items,
5864
5891
  storageKey = "testbed:open-state",
5865
5892
  disablePersistence = false,
5866
- title = "TestBed"
5893
+ title = "TestBed",
5894
+ placement = "top-left"
5867
5895
  }) {
5868
5896
  const [open, setOpen] = React6.useState(false);
5869
5897
  const itemsRef = React6.useRef(items);
@@ -5893,8 +5921,7 @@ function TestBed({
5893
5921
  {
5894
5922
  style: {
5895
5923
  position: "fixed",
5896
- top: "1vh",
5897
- left: "1vh",
5924
+ ...placementStyle(placement),
5898
5925
  zIndex: 2147483647,
5899
5926
  pointerEvents: "auto",
5900
5927
  fontSize: "1.4vh"
@@ -5999,6 +6026,281 @@ function TestBed({
5999
6026
  }
6000
6027
  );
6001
6028
  }
6029
+ var MANTINE_COLOR_OPTIONS = [
6030
+ "dirk",
6031
+ "red",
6032
+ "pink",
6033
+ "grape",
6034
+ "violet",
6035
+ "indigo",
6036
+ "blue",
6037
+ "cyan",
6038
+ "teal",
6039
+ "green",
6040
+ "lime",
6041
+ "yellow",
6042
+ "orange"
6043
+ ].map((value) => ({ value, label: value }));
6044
+ var DEFAULT_PALETTE = [
6045
+ "#f0f4ff",
6046
+ "#d9e3ff",
6047
+ "#bfcfff",
6048
+ "#a6bbff",
6049
+ "#8ca7ff",
6050
+ "#7393ff",
6051
+ "#5a7fff",
6052
+ "#406bff",
6053
+ "#2547ff",
6054
+ "#0b33ff"
6055
+ ];
6056
+ var DEFAULT_VALUE = {
6057
+ useOverride: false,
6058
+ primaryColor: "dirk",
6059
+ primaryShade: 5,
6060
+ customTheme: DEFAULT_PALETTE
6061
+ };
6062
+ function GroupLabel({ label: label2 }) {
6063
+ return /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", gap: "xs", mt: "xxs", children: [
6064
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.07em", c: "rgba(255,255,255,0.2)", children: label2 }),
6065
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, height: "0.05vh", background: "rgba(255,255,255,0.06)" } })
6066
+ ] });
6067
+ }
6068
+ function ThemeOverrideSection({
6069
+ schemaKey = "theme",
6070
+ title
6071
+ }) {
6072
+ const mantineTheme = core.useMantineTheme();
6073
+ const color = mantineTheme.colors[mantineTheme.primaryColor][5];
6074
+ const raw = useFormField(schemaKey);
6075
+ const value = {
6076
+ useOverride: raw?.useOverride ?? DEFAULT_VALUE.useOverride,
6077
+ primaryColor: raw?.primaryColor ?? DEFAULT_VALUE.primaryColor,
6078
+ primaryShade: raw?.primaryShade ?? DEFAULT_VALUE.primaryShade,
6079
+ customTheme: Array.isArray(raw?.customTheme) && raw.customTheme.length === 10 ? raw.customTheme : DEFAULT_VALUE.customTheme
6080
+ };
6081
+ const { setValue } = useFormActions();
6082
+ const set = (key, val) => setValue(schemaKey, { ...value, [key]: val });
6083
+ const useCustom = value.primaryColor === "custom";
6084
+ const editable = value.useOverride;
6085
+ const setSwatch = (index, hex) => {
6086
+ const next = [...value.customTheme];
6087
+ next[index] = hex;
6088
+ set("customTheme", next);
6089
+ };
6090
+ const generateFromBase = (hex) => {
6091
+ try {
6092
+ const generated = colorsGenerator.generateColors(hex);
6093
+ set("customTheme", generated);
6094
+ } catch {
6095
+ }
6096
+ };
6097
+ const resetPalette = () => set("customTheme", DEFAULT_PALETTE);
6098
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6099
+ core.Flex,
6100
+ {
6101
+ direction: "column",
6102
+ gap: "xs",
6103
+ p: "sm",
6104
+ style: { flex: 1, minHeight: 0, overflowY: "auto" },
6105
+ children: [
6106
+ /* @__PURE__ */ jsxRuntime.jsx(
6107
+ AdminPageTitle,
6108
+ {
6109
+ icon: lucideReact.Palette,
6110
+ title: title || locale("Theme") || "Theme",
6111
+ color
6112
+ }
6113
+ ),
6114
+ /* @__PURE__ */ jsxRuntime.jsxs(
6115
+ core.Flex,
6116
+ {
6117
+ align: "center",
6118
+ justify: "space-between",
6119
+ p: "xs",
6120
+ style: {
6121
+ background: `rgba(255,255,255,${editable ? 0.04 : 0.02})`,
6122
+ border: `0.1vh solid ${editable ? color : "rgba(255,255,255,0.08)"}`,
6123
+ borderRadius: mantineTheme.radius.xs,
6124
+ transition: "background 0.15s, border-color 0.15s"
6125
+ },
6126
+ children: [
6127
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { direction: "column", gap: "xxs", style: { flex: 1, minWidth: 0 }, children: [
6128
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xs", c: "rgba(255,255,255,0.9)", children: locale("OverrideGlobalTheme") || "Override global theme" }),
6129
+ /* @__PURE__ */ jsxRuntime.jsx(core.Text, { ff: "Akrobat Bold", size: "xxs", c: "rgba(255,255,255,0.4)", children: locale("OverrideGlobalThemeDesc") || "When on, this resource uses its own primary colour and palette instead of dirk_lib's. Turn off to fall back to the global theme \u2014 your custom palette is kept." })
6130
+ ] }),
6131
+ /* @__PURE__ */ jsxRuntime.jsx(
6132
+ core.Switch,
6133
+ {
6134
+ size: "md",
6135
+ checked: value.useOverride,
6136
+ onChange: (e) => set("useOverride", e.currentTarget.checked)
6137
+ }
6138
+ )
6139
+ ]
6140
+ }
6141
+ ),
6142
+ /* @__PURE__ */ jsxRuntime.jsxs(
6143
+ "div",
6144
+ {
6145
+ style: {
6146
+ opacity: editable ? 1 : 0.4,
6147
+ pointerEvents: editable ? "auto" : "none",
6148
+ transition: "opacity 0.15s"
6149
+ },
6150
+ children: [
6151
+ /* @__PURE__ */ jsxRuntime.jsx(GroupLabel, { label: locale("PrimaryColor") || "Primary Colour" }),
6152
+ /* @__PURE__ */ jsxRuntime.jsx(
6153
+ core.Switch,
6154
+ {
6155
+ label: locale("UseCustomPalette") || "Use custom palette",
6156
+ size: "md",
6157
+ checked: useCustom,
6158
+ onChange: (e) => set("primaryColor", e.currentTarget.checked ? "custom" : "dirk"),
6159
+ styles: {
6160
+ label: {
6161
+ fontFamily: "Akrobat Bold",
6162
+ fontSize: "0.65em",
6163
+ letterSpacing: "0.06em",
6164
+ textTransform: "uppercase",
6165
+ color: "rgba(255,255,255,0.35)"
6166
+ }
6167
+ }
6168
+ }
6169
+ ),
6170
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { gap: "xs", mt: "xs", children: [
6171
+ !useCustom && /* @__PURE__ */ jsxRuntime.jsx(
6172
+ core.Select,
6173
+ {
6174
+ label: locale("MantinePalette") || "Mantine palette",
6175
+ size: "xs",
6176
+ style: { flex: 1 },
6177
+ value: value.primaryColor,
6178
+ data: MANTINE_COLOR_OPTIONS,
6179
+ allowDeselect: false,
6180
+ onChange: (v) => v && set("primaryColor", v)
6181
+ }
6182
+ ),
6183
+ /* @__PURE__ */ jsxRuntime.jsx(
6184
+ core.NumberInput,
6185
+ {
6186
+ label: locale("Shade") || "Shade",
6187
+ size: "xs",
6188
+ style: { flex: 1 },
6189
+ min: 0,
6190
+ max: 9,
6191
+ value: value.primaryShade,
6192
+ onChange: (v) => set("primaryShade", Number(v))
6193
+ }
6194
+ )
6195
+ ] }),
6196
+ useCustom && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6197
+ /* @__PURE__ */ jsxRuntime.jsxs(core.Flex, { align: "center", justify: "space-between", mt: "sm", children: [
6198
+ /* @__PURE__ */ jsxRuntime.jsx(
6199
+ core.Text,
6200
+ {
6201
+ ff: "Akrobat Bold",
6202
+ size: "xxs",
6203
+ tt: "uppercase",
6204
+ lts: "0.07em",
6205
+ c: "rgba(255,255,255,0.2)",
6206
+ children: locale("CustomPalette") || "Custom palette"
6207
+ }
6208
+ ),
6209
+ /* @__PURE__ */ jsxRuntime.jsx(
6210
+ core.ActionIcon,
6211
+ {
6212
+ size: "sm",
6213
+ variant: "subtle",
6214
+ onClick: resetPalette,
6215
+ title: locale("ResetPalette") || "Reset palette",
6216
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { size: "1.4vh" })
6217
+ }
6218
+ )
6219
+ ] }),
6220
+ /* @__PURE__ */ jsxRuntime.jsx(
6221
+ core.ColorInput,
6222
+ {
6223
+ label: locale("BaseColor") || "Base colour",
6224
+ size: "xs",
6225
+ value: value.customTheme[value.primaryShade] ?? value.customTheme[5] ?? "#000000",
6226
+ onChange: generateFromBase,
6227
+ eyeDropperIcon: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {})
6228
+ }
6229
+ ),
6230
+ /* @__PURE__ */ jsxRuntime.jsx(core.Flex, { gap: "xxs", mt: "xxs", children: value.customTheme.map((swatch, i) => /* @__PURE__ */ jsxRuntime.jsx(
6231
+ SwatchTile,
6232
+ {
6233
+ index: i,
6234
+ value: swatch,
6235
+ isPrimary: i === value.primaryShade,
6236
+ onChange: (v) => setSwatch(i, v)
6237
+ },
6238
+ i
6239
+ )) })
6240
+ ] })
6241
+ ]
6242
+ }
6243
+ )
6244
+ ]
6245
+ }
6246
+ );
6247
+ }
6248
+ function SwatchTile({
6249
+ index,
6250
+ value,
6251
+ isPrimary,
6252
+ onChange
6253
+ }) {
6254
+ const [opened, setOpened] = React6.useState(false);
6255
+ return /* @__PURE__ */ jsxRuntime.jsxs(core.Popover, { opened, onChange: setOpened, position: "bottom", withArrow: true, zIndex: 1e4, children: [
6256
+ /* @__PURE__ */ jsxRuntime.jsx(core.Popover.Target, { children: /* @__PURE__ */ jsxRuntime.jsx(
6257
+ "button",
6258
+ {
6259
+ onClick: () => setOpened((o) => !o),
6260
+ title: `${index} \xB7 ${value}`,
6261
+ style: {
6262
+ flex: 1,
6263
+ aspectRatio: "1 / 1",
6264
+ background: value,
6265
+ border: isPrimary ? "0.2vh solid rgba(255,255,255,0.85)" : "0.1vh solid rgba(255,255,255,0.15)",
6266
+ borderRadius: "0.4vh",
6267
+ cursor: "pointer",
6268
+ padding: 0,
6269
+ display: "flex",
6270
+ alignItems: "flex-end",
6271
+ justifyContent: "flex-end",
6272
+ position: "relative"
6273
+ },
6274
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6275
+ "span",
6276
+ {
6277
+ style: {
6278
+ fontFamily: "Akrobat Bold",
6279
+ fontSize: "0.9vh",
6280
+ lineHeight: 1,
6281
+ padding: "0.2vh 0.3vh",
6282
+ color: "rgba(0,0,0,0.55)",
6283
+ background: "rgba(255,255,255,0.55)",
6284
+ borderRadius: "0.25vh",
6285
+ margin: "0.2vh"
6286
+ },
6287
+ children: index
6288
+ }
6289
+ )
6290
+ }
6291
+ ) }),
6292
+ /* @__PURE__ */ jsxRuntime.jsx(core.Popover.Dropdown, { p: "xs", children: /* @__PURE__ */ jsxRuntime.jsx(
6293
+ core.ColorInput,
6294
+ {
6295
+ size: "xs",
6296
+ value,
6297
+ onChange,
6298
+ format: "hex",
6299
+ eyeDropperIcon: /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {})
6300
+ }
6301
+ ) })
6302
+ ] });
6303
+ }
6002
6304
  function useTornEdges() {
6003
6305
  const game = useSettings((state) => state.game);
6004
6306
  return game === "rdr3" ? "torn-edge-wrapper" : "";
@@ -6280,6 +6582,12 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
6280
6582
  }, []);
6281
6583
  useNuiEvent("UPDATE_DIRK_LIB_SETTINGS", (data) => {
6282
6584
  if (!data || typeof data !== "object") return;
6585
+ const current = useSettings.getState();
6586
+ if (current.themeOverride) {
6587
+ const { primaryColor: _pc, primaryShade: _ps, customTheme: _ct, ...rest } = data;
6588
+ useSettings.setState(rest);
6589
+ return;
6590
+ }
6283
6591
  useSettings.setState(data);
6284
6592
  });
6285
6593
  const mergedTheme = React6.useMemo(
@@ -6304,6 +6612,21 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
6304
6612
  ) : children;
6305
6613
  return /* @__PURE__ */ jsxRuntime.jsx(core.MantineProvider, { theme: mergedTheme, defaultColorScheme: "dark", children: /* @__PURE__ */ jsxRuntime.jsx(DirkErrorBoundary, { children: content }) });
6306
6614
  }
6615
+ var Vector2Schema = zod.z.object({
6616
+ x: zod.z.number(),
6617
+ y: zod.z.number()
6618
+ });
6619
+ var Vector3Schema = zod.z.object({
6620
+ x: zod.z.number(),
6621
+ y: zod.z.number(),
6622
+ z: zod.z.number()
6623
+ });
6624
+ var Vector4Schema = zod.z.object({
6625
+ x: zod.z.number(),
6626
+ y: zod.z.number(),
6627
+ z: zod.z.number(),
6628
+ w: zod.z.number()
6629
+ });
6307
6630
 
6308
6631
  exports.AdminPageTitle = AdminPageTitle;
6309
6632
  exports.AsyncSaveButton = AsyncSaveButton;
@@ -6348,10 +6671,14 @@ exports.SegmentedControl = SegmentedControl;
6348
6671
  exports.SegmentedProgress = SegmentedProgress;
6349
6672
  exports.SelectItem = SelectItem;
6350
6673
  exports.TestBed = TestBed;
6674
+ exports.ThemeOverrideSection = ThemeOverrideSection;
6351
6675
  exports.Title = Title;
6352
6676
  exports.TornEdgeSVGFilter = TornEdgeSVGFilter;
6677
+ exports.Vector2Schema = Vector2Schema;
6678
+ exports.Vector3Schema = Vector3Schema;
6353
6679
  exports.Vector4DeleteButton = Vector4DeleteButton;
6354
6680
  exports.Vector4Display = Vector4Display;
6681
+ exports.Vector4Schema = Vector4Schema;
6355
6682
  exports.WorldPositionGotoButton = WorldPositionGotoButton;
6356
6683
  exports.WorldPositionSetButton = WorldPositionSetButton;
6357
6684
  exports.colorWithAlpha = colorWithAlpha;