dirk-cfx-react 1.1.64 → 1.1.66

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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- export { AdminPageTitle, AdminPageTitleProps, AsyncSaveButton, BlipColorSelect, BlipColorSelectProps, BlipIconSelect, BlipIconSelectProps, BorderedIcon, BorderedIconProps, ButtonProps, ConfigPanel, ConfigPanelProps, ConfirmModal, ConfirmModalProps, Counter, FiveMControls, FiveMKeyBindInput, FloatingParticles, FloatingParticlesProps, InfoBox, InfoBoxProps, InputContainer, InputContainerProps, LevelBanner, LevelPanel, Modal, ModalContext, ModalProps, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavItem, NavigationContext, NavigationProvider, NavigationStore, ParticleState, ProgressProps, Prompt, PromptButton, PromptModal, SegmentProps, SegmentedControl, SegmentedControlProps, SegmentedProgress, SelectItem, SelectItemProps, StoreModalProps, TestBed, TestBedItem, TestBedProps, Title, TitleProps, useModal, useModalActions, useNavigation, useNavigationStore } from './components/index.cjs';
2
- export { INPUT_MAPPER_KEYS_BY_PRIMARY, INPUT_MAPPER_PRIMARY_OPTIONS, InitialFetch, InternalEvent, InventoryItem, InventoryItems, SettingsState, SkillSettings, UploadImageProps, colorWithAlpha, copyToClipboard, createSkill, extractDefaults, fetchLuaTable, fetchNui, gameToMap, getImageShape, getItemImageUrl, initialFetches, internalEvent, isEnvBrowser, isProfanity, latPr100, locale, localeStore, mapCenter, mapToGame, noop, numberToRoman, openLink, registerInitialFetch, registerInitialLuaTableFetch, runFetches, splitFAString, updatePresignedURL, uploadImage, useAutoFetcher, useItems, useItemsList, useProfanityStore, useSettings } from './utils/index.cjs';
1
+ export { AdminPageTitle, AdminPageTitleProps, AsyncSaveButton, BlipColorSelect, BlipColorSelectProps, BlipDisplaySelect, BlipDisplaySelectProps, BlipIconSelect, BlipIconSelectProps, BorderedIcon, BorderedIconProps, ButtonProps, ConfigPanel, ConfigPanelProps, ConfirmModal, ConfirmModalProps, Counter, FiveMControls, FiveMKeyBindInput, FloatingParticles, FloatingParticlesProps, GroupName, GroupNameProps, GroupRank, GroupRankProps, GroupSelect, GroupSelectProps, GroupType, GroupValue, InfoBox, InfoBoxProps, InputContainer, InputContainerProps, LevelBanner, LevelPanel, Modal, ModalContext, ModalProps, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavItem, NavigationContext, NavigationProvider, NavigationStore, ParticleState, PositionPicker, PositionPickerProps, ProgressProps, Prompt, PromptButton, PromptModal, SegmentProps, SegmentedControl, SegmentedControlProps, SegmentedProgress, SelectItem, SelectItemProps, StoreModalProps, TestBed, TestBedItem, TestBedProps, Title, TitleProps, Vector4Value, useModal, useModalActions, useNavigation, useNavigationStore } from './components/index.cjs';
2
+ export { FrameworkGrade, FrameworkGroup, INPUT_MAPPER_KEYS_BY_PRIMARY, INPUT_MAPPER_PRIMARY_OPTIONS, InitialFetch, InternalEvent, InventoryItem, InventoryItems, SettingsState, SkillSettings, UploadImageProps, colorWithAlpha, copyToClipboard, createSkill, extractDefaults, fetchLuaTable, fetchNui, gameToMap, getImageShape, getItemImageUrl, initialFetches, internalEvent, isEnvBrowser, isProfanity, latPr100, locale, localeStore, mapCenter, mapToGame, noop, numberToRoman, openLink, registerInitialFetch, registerInitialLuaTableFetch, runFetches, selectAllGroups, splitFAString, updatePresignedURL, uploadImage, useAutoFetcher, useFrameworkGroups, useItems, useItemsList, useProfanityStore, useSettings } from './utils/index.cjs';
3
3
  export { FormProvider, FormState, NuiHandlerSignature, NuiMessageData, ScriptConfigHistoryChange, ScriptConfigHistoryEntry, ScriptConfigHistoryRequest, ScriptConfigHistoryResponse, ScriptConfigInstance, TornEdgeSVGFilter, ValidationRules, ValidatorFn, createFormStore, createScriptConfig, getScriptConfigInstance, useAudio, useForm, useFormActions, useFormError, useFormErrors, useFormField, useFormFields, useNuiEvent, useTornEdges } from './hooks/index.cjs';
4
4
  export { DirkProvider, DirkProviderProps } from './providers/index.cjs';
5
5
  import 'react/jsx-runtime';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { AdminPageTitle, AdminPageTitleProps, AsyncSaveButton, BlipColorSelect, BlipColorSelectProps, BlipIconSelect, BlipIconSelectProps, BorderedIcon, BorderedIconProps, ButtonProps, ConfigPanel, ConfigPanelProps, ConfirmModal, ConfirmModalProps, Counter, FiveMControls, FiveMKeyBindInput, FloatingParticles, FloatingParticlesProps, InfoBox, InfoBoxProps, InputContainer, InputContainerProps, LevelBanner, LevelPanel, Modal, ModalContext, ModalProps, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavItem, NavigationContext, NavigationProvider, NavigationStore, ParticleState, ProgressProps, Prompt, PromptButton, PromptModal, SegmentProps, SegmentedControl, SegmentedControlProps, SegmentedProgress, SelectItem, SelectItemProps, StoreModalProps, TestBed, TestBedItem, TestBedProps, Title, TitleProps, useModal, useModalActions, useNavigation, useNavigationStore } from './components/index.js';
2
- export { INPUT_MAPPER_KEYS_BY_PRIMARY, INPUT_MAPPER_PRIMARY_OPTIONS, InitialFetch, InternalEvent, InventoryItem, InventoryItems, SettingsState, SkillSettings, UploadImageProps, colorWithAlpha, copyToClipboard, createSkill, extractDefaults, fetchLuaTable, fetchNui, gameToMap, getImageShape, getItemImageUrl, initialFetches, internalEvent, isEnvBrowser, isProfanity, latPr100, locale, localeStore, mapCenter, mapToGame, noop, numberToRoman, openLink, registerInitialFetch, registerInitialLuaTableFetch, runFetches, splitFAString, updatePresignedURL, uploadImage, useAutoFetcher, useItems, useItemsList, useProfanityStore, useSettings } from './utils/index.js';
1
+ export { AdminPageTitle, AdminPageTitleProps, AsyncSaveButton, BlipColorSelect, BlipColorSelectProps, BlipDisplaySelect, BlipDisplaySelectProps, BlipIconSelect, BlipIconSelectProps, BorderedIcon, BorderedIconProps, ButtonProps, ConfigPanel, ConfigPanelProps, ConfirmModal, ConfirmModalProps, Counter, FiveMControls, FiveMKeyBindInput, FloatingParticles, FloatingParticlesProps, GroupName, GroupNameProps, GroupRank, GroupRankProps, GroupSelect, GroupSelectProps, GroupType, GroupValue, InfoBox, InfoBoxProps, InputContainer, InputContainerProps, LevelBanner, LevelPanel, Modal, ModalContext, ModalProps, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavItem, NavigationContext, NavigationProvider, NavigationStore, ParticleState, PositionPicker, PositionPickerProps, ProgressProps, Prompt, PromptButton, PromptModal, SegmentProps, SegmentedControl, SegmentedControlProps, SegmentedProgress, SelectItem, SelectItemProps, StoreModalProps, TestBed, TestBedItem, TestBedProps, Title, TitleProps, Vector4Value, useModal, useModalActions, useNavigation, useNavigationStore } from './components/index.js';
2
+ export { FrameworkGrade, FrameworkGroup, INPUT_MAPPER_KEYS_BY_PRIMARY, INPUT_MAPPER_PRIMARY_OPTIONS, InitialFetch, InternalEvent, InventoryItem, InventoryItems, SettingsState, SkillSettings, UploadImageProps, colorWithAlpha, copyToClipboard, createSkill, extractDefaults, fetchLuaTable, fetchNui, gameToMap, getImageShape, getItemImageUrl, initialFetches, internalEvent, isEnvBrowser, isProfanity, latPr100, locale, localeStore, mapCenter, mapToGame, noop, numberToRoman, openLink, registerInitialFetch, registerInitialLuaTableFetch, runFetches, selectAllGroups, splitFAString, updatePresignedURL, uploadImage, useAutoFetcher, useFrameworkGroups, useItems, useItemsList, useProfanityStore, useSettings } from './utils/index.js';
3
3
  export { FormProvider, FormState, NuiHandlerSignature, NuiMessageData, ScriptConfigHistoryChange, ScriptConfigHistoryEntry, ScriptConfigHistoryRequest, ScriptConfigHistoryResponse, ScriptConfigInstance, TornEdgeSVGFilter, ValidationRules, ValidatorFn, createFormStore, createScriptConfig, getScriptConfigInstance, useAudio, useForm, useFormActions, useFormError, useFormErrors, useFormField, useFormFields, useNuiEvent, useTornEdges } from './hooks/index.js';
4
4
  export { DirkProvider, DirkProviderProps } from './providers/index.js';
5
5
  import 'react/jsx-runtime';
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
- import { Flex, Text, Image as Image$1, createTheme, Box, Stack, Title as Title$1, Code, TextInput, Select, useMantineTheme, Tooltip, alpha, Progress, RingProgress, Portal, Button, Loader, ActionIcon, MantineProvider, BackgroundImage, Group, JsonInput } from '@mantine/core';
1
+ import { Flex, Text, Image as Image$1, createTheme, Box, Stack, Title as Title$1, Code, TextInput, Select, useMantineTheme, Tooltip, alpha, Progress, RingProgress, Portal, Button, NumberInput, Loader, ActionIcon, MantineProvider, BackgroundImage, Group, JsonInput } from '@mantine/core';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import React5, { createContext, useContext, useEffect, useRef, useState, useMemo, useLayoutEffect } from 'react';
3
+ import React6, { createContext, useContext, useEffect, useRef, useState, useMemo, useLayoutEffect } from 'react';
4
4
  import { create, useStore, createStore } from 'zustand';
5
5
  import axios from 'axios';
6
6
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
7
7
  import { motion, AnimatePresence, useMotionValue } from 'framer-motion';
8
- import { Info, X, AlertTriangle, Trash2, Check, FlaskConical, ChevronUp, ChevronDown, ArrowLeft, Undo2, Redo2, Save, History, XCircle, Code2, RotateCcw, Search, Filter, User } from 'lucide-react';
8
+ import { Info, X, AlertTriangle, Trash2, MapPin, Crosshair, EyeOff, Eye, RotateCcw, Check, FlaskConical, ChevronUp, ChevronDown, ArrowLeft, Undo2, Redo2, Save, History, XCircle, Code2, Search, Filter, User } from 'lucide-react';
9
9
  import clickSoundUrl from './click_sound-PNCRRTM4.mp3';
10
10
  import hoverSoundUrl from './hover_sound-NBUA222C.mp3';
11
11
  import { QueryClient, QueryClientProvider, useInfiniteQuery } from '@tanstack/react-query';
@@ -1070,6 +1070,31 @@ function BlipColorSelect({ value, onChange, label: label2 = "Blip Color", size =
1070
1070
  }
1071
1071
  );
1072
1072
  }
1073
+ var BLIP_DISPLAY_DATA = [
1074
+ { value: "2", label: "2 \u2014 Main map + minimap (selectable)" },
1075
+ { value: "3", label: "3 \u2014 Main map only (selectable)" },
1076
+ { value: "4", label: "4 \u2014 Main map only (selectable)" },
1077
+ { value: "5", label: "5 \u2014 Minimap only" },
1078
+ { value: "6", label: "6 \u2014 Main map + minimap (selectable)" },
1079
+ { value: "8", label: "8 \u2014 Main map + minimap (not selectable)" },
1080
+ { value: "9", label: "9 \u2014 Minimap only" },
1081
+ { value: "10", label: "10 \u2014 Main map + minimap (not selectable)" }
1082
+ ];
1083
+ function BlipDisplaySelect({ value, onChange, label: label2 = "Blip Display", size = "xs", ...rest }) {
1084
+ return /* @__PURE__ */ jsx(
1085
+ Select,
1086
+ {
1087
+ label: label2,
1088
+ size,
1089
+ ...rest,
1090
+ data: BLIP_DISPLAY_DATA,
1091
+ value: value != null ? String(value) : null,
1092
+ onChange: (val) => val != null && onChange(Number(val)),
1093
+ allowDeselect: false,
1094
+ maxDropdownHeight: 300
1095
+ }
1096
+ );
1097
+ }
1073
1098
 
1074
1099
  // src/utils/colorWithAlpha.ts
1075
1100
  var colorNames = {
@@ -1216,11 +1241,11 @@ var colorNames = {
1216
1241
  Yellow: { r: 255, g: 255, b: 0 },
1217
1242
  YellowGreen: { r: 154, g: 205, b: 50 }
1218
1243
  };
1219
- function colorWithAlpha(color, alpha8) {
1244
+ function colorWithAlpha(color, alpha9) {
1220
1245
  const lowerCasedColor = color.toLowerCase();
1221
1246
  if (colorNames[lowerCasedColor]) {
1222
1247
  const rgb = colorNames[lowerCasedColor];
1223
- return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha8})`;
1248
+ return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${alpha9})`;
1224
1249
  }
1225
1250
  if (/^#([A-Fa-f0-9]{6})$/.test(color)) {
1226
1251
  const hex = color.slice(1);
@@ -1228,12 +1253,12 @@ function colorWithAlpha(color, alpha8) {
1228
1253
  const r = bigint >> 16 & 255;
1229
1254
  const g = bigint >> 8 & 255;
1230
1255
  const b = bigint & 255;
1231
- return `rgba(${r}, ${g}, ${b}, ${alpha8})`;
1256
+ return `rgba(${r}, ${g}, ${b}, ${alpha9})`;
1232
1257
  }
1233
1258
  if (/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/.test(color)) {
1234
1259
  const result = color.match(/^rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)$/);
1235
1260
  if (result) {
1236
- return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${alpha8})`;
1261
+ return `rgba(${result[1]}, ${result[2]}, ${result[3]}, ${alpha9})`;
1237
1262
  }
1238
1263
  }
1239
1264
  return color;
@@ -1912,6 +1937,23 @@ registerInitialFetch("FETCH_ALL_ITEMS", null, {
1912
1937
  useItems.setState(fetchedItems);
1913
1938
  }).catch(() => {
1914
1939
  });
1940
+ var useFrameworkGroups = create(() => ({
1941
+ jobs: [],
1942
+ gangs: [],
1943
+ loaded: false
1944
+ }));
1945
+ registerInitialFetch("GET_FRAMEWORK_GROUPS", void 0).then((data) => {
1946
+ useFrameworkGroups.setState({
1947
+ jobs: Array.isArray(data?.jobs) ? data.jobs : [],
1948
+ gangs: Array.isArray(data?.gangs) ? data.gangs : [],
1949
+ loaded: true
1950
+ });
1951
+ }).catch(() => {
1952
+ useFrameworkGroups.setState({ loaded: true });
1953
+ });
1954
+ function selectAllGroups(state) {
1955
+ return [...state.jobs, ...state.gangs];
1956
+ }
1915
1957
 
1916
1958
  // src/utils/inputMapper.ts
1917
1959
  var INPUT_MAPPER_PRIMARY_OPTIONS = [
@@ -4743,6 +4785,307 @@ function SelectItem(props) {
4743
4785
  }
4744
4786
  );
4745
4787
  }
4788
+ var ZERO = { x: 0, y: 0, z: 0, w: 0 };
4789
+ function PositionPicker(props) {
4790
+ const {
4791
+ label: label2,
4792
+ value,
4793
+ onChange,
4794
+ relativeTo,
4795
+ fetchEvent = "GET_POSITION",
4796
+ previewEvent = "PREVIEW_POSITION",
4797
+ stopPreviewEvent = "STOP_PREVIEW_POSITION",
4798
+ description: description2,
4799
+ showHeading = true
4800
+ } = props;
4801
+ const theme2 = useMantineTheme();
4802
+ const color = theme2.colors[theme2.primaryColor][5];
4803
+ const [previewing, setPreviewing] = useState(false);
4804
+ const previewingRef = useRef(false);
4805
+ useEffect(() => {
4806
+ return () => {
4807
+ if (previewingRef.current) {
4808
+ fetchNui(stopPreviewEvent, { relativeTo }).catch(() => {
4809
+ });
4810
+ }
4811
+ };
4812
+ }, [stopPreviewEvent, relativeTo]);
4813
+ const set = (key, val) => {
4814
+ const next = { ...value, [key]: val };
4815
+ onChange(next);
4816
+ if (previewingRef.current) {
4817
+ fetchNui(previewEvent, { value: next, relativeTo }).catch(() => {
4818
+ });
4819
+ }
4820
+ };
4821
+ const grab = async () => {
4822
+ try {
4823
+ const resp = await fetchNui(fetchEvent, { relativeTo }, value);
4824
+ if (resp && typeof resp === "object") {
4825
+ const next = {
4826
+ x: Number(resp.x ?? 0),
4827
+ y: Number(resp.y ?? 0),
4828
+ z: Number(resp.z ?? 0),
4829
+ w: Number(resp.w ?? 0)
4830
+ };
4831
+ onChange(next);
4832
+ if (previewingRef.current) {
4833
+ fetchNui(previewEvent, { value: next, relativeTo }).catch(() => {
4834
+ });
4835
+ }
4836
+ }
4837
+ } catch {
4838
+ }
4839
+ };
4840
+ const togglePreview = async () => {
4841
+ const nextState = !previewing;
4842
+ setPreviewing(nextState);
4843
+ previewingRef.current = nextState;
4844
+ if (nextState) {
4845
+ await fetchNui(previewEvent, { value, relativeTo }).catch(() => {
4846
+ });
4847
+ } else {
4848
+ await fetchNui(stopPreviewEvent, { relativeTo }).catch(() => {
4849
+ });
4850
+ }
4851
+ };
4852
+ const reset = () => {
4853
+ onChange({ ...ZERO });
4854
+ if (previewingRef.current) {
4855
+ fetchNui(previewEvent, { value: ZERO, relativeTo }).catch(() => {
4856
+ });
4857
+ }
4858
+ };
4859
+ const numberStyles = {
4860
+ input: { textAlign: "right", fontFamily: "monospace" }
4861
+ };
4862
+ return /* @__PURE__ */ jsxs(
4863
+ Flex,
4864
+ {
4865
+ direction: "column",
4866
+ gap: "xxs",
4867
+ p: "xs",
4868
+ style: {
4869
+ background: alpha(theme2.colors.dark[5], 0.35),
4870
+ border: "0.1vh solid rgba(255,255,255,0.05)",
4871
+ borderRadius: theme2.radius.xs
4872
+ },
4873
+ children: [
4874
+ (label2 || description2) && /* @__PURE__ */ jsxs(Flex, { justify: "space-between", align: "center", gap: "xs", children: [
4875
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 0, style: { minWidth: 0 }, children: [
4876
+ label2 && /* @__PURE__ */ jsxs(Flex, { align: "center", gap: "xxs", children: [
4877
+ /* @__PURE__ */ jsx(MapPin, { size: "1.4vh", color: alpha(color, 0.7) }),
4878
+ /* @__PURE__ */ jsx(
4879
+ Text,
4880
+ {
4881
+ ff: "Akrobat Bold",
4882
+ size: "xxs",
4883
+ tt: "uppercase",
4884
+ lts: "0.05em",
4885
+ c: "rgba(255,255,255,0.75)",
4886
+ children: locale(label2)
4887
+ }
4888
+ ),
4889
+ relativeTo && /* @__PURE__ */ jsxs(Text, { ff: "Akrobat Bold", size: "xxs", c: alpha(color, 0.5), lts: "0.05em", children: [
4890
+ "\xB7 ",
4891
+ locale("RelativeTo"),
4892
+ " ",
4893
+ relativeTo
4894
+ ] })
4895
+ ] }),
4896
+ description2 && /* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", c: "dimmed", lh: 1.3, children: locale(description2) })
4897
+ ] }),
4898
+ /* @__PURE__ */ jsxs(Flex, { gap: "xxs", style: { flexShrink: 0 }, children: [
4899
+ /* @__PURE__ */ jsx(PickerButton, { tooltip: locale("GrabMyPosition"), onClick: grab, color, children: /* @__PURE__ */ jsx(Crosshair, { size: "1.4vh", color }) }),
4900
+ /* @__PURE__ */ jsx(
4901
+ PickerButton,
4902
+ {
4903
+ tooltip: previewing ? locale("StopPreview") : locale("PreviewInWorld"),
4904
+ onClick: togglePreview,
4905
+ color,
4906
+ active: previewing,
4907
+ children: previewing ? /* @__PURE__ */ jsx(EyeOff, { size: "1.4vh", color }) : /* @__PURE__ */ jsx(Eye, { size: "1.4vh", color: alpha(color, 0.7) })
4908
+ }
4909
+ ),
4910
+ /* @__PURE__ */ jsx(PickerButton, { tooltip: locale("Reset"), onClick: reset, color: "#ef4444", children: /* @__PURE__ */ jsx(RotateCcw, { size: "1.4vh", color: "#ef4444" }) })
4911
+ ] })
4912
+ ] }),
4913
+ /* @__PURE__ */ jsxs(Flex, { gap: "xxs", children: [
4914
+ /* @__PURE__ */ jsx(
4915
+ NumberInput,
4916
+ {
4917
+ size: "xs",
4918
+ label: "X",
4919
+ value: value.x,
4920
+ onChange: (v) => set("x", Number(v)),
4921
+ decimalScale: 4,
4922
+ step: 0.1,
4923
+ style: { flex: 1 },
4924
+ styles: numberStyles
4925
+ }
4926
+ ),
4927
+ /* @__PURE__ */ jsx(
4928
+ NumberInput,
4929
+ {
4930
+ size: "xs",
4931
+ label: "Y",
4932
+ value: value.y,
4933
+ onChange: (v) => set("y", Number(v)),
4934
+ decimalScale: 4,
4935
+ step: 0.1,
4936
+ style: { flex: 1 },
4937
+ styles: numberStyles
4938
+ }
4939
+ ),
4940
+ /* @__PURE__ */ jsx(
4941
+ NumberInput,
4942
+ {
4943
+ size: "xs",
4944
+ label: "Z",
4945
+ value: value.z,
4946
+ onChange: (v) => set("z", Number(v)),
4947
+ decimalScale: 4,
4948
+ step: 0.1,
4949
+ style: { flex: 1 },
4950
+ styles: numberStyles
4951
+ }
4952
+ ),
4953
+ showHeading && /* @__PURE__ */ jsx(
4954
+ NumberInput,
4955
+ {
4956
+ size: "xs",
4957
+ label: "W",
4958
+ value: value.w,
4959
+ onChange: (v) => set("w", Number(v)),
4960
+ decimalScale: 2,
4961
+ step: 1,
4962
+ min: 0,
4963
+ max: 360,
4964
+ style: { flex: 1 },
4965
+ styles: numberStyles
4966
+ }
4967
+ )
4968
+ ] })
4969
+ ]
4970
+ }
4971
+ );
4972
+ }
4973
+ function PickerButton({
4974
+ children,
4975
+ onClick,
4976
+ tooltip,
4977
+ color,
4978
+ active
4979
+ }) {
4980
+ const theme2 = useMantineTheme();
4981
+ return /* @__PURE__ */ jsx(Tooltip, { label: tooltip, position: "top", withArrow: true, children: /* @__PURE__ */ jsx(
4982
+ motion.button,
4983
+ {
4984
+ onClick,
4985
+ whileHover: { background: alpha(color, 0.18) },
4986
+ whileTap: { scale: 0.95 },
4987
+ style: {
4988
+ background: active ? alpha(color, 0.22) : alpha(color, 0.08),
4989
+ border: `0.1vh solid ${alpha(color, active ? 0.5 : 0.3)}`,
4990
+ borderRadius: theme2.radius.xs,
4991
+ padding: "0.4vh 0.6vh",
4992
+ cursor: "pointer",
4993
+ display: "flex",
4994
+ alignItems: "center",
4995
+ justifyContent: "center"
4996
+ },
4997
+ children
4998
+ }
4999
+ ) });
5000
+ }
5001
+ var GroupSelectContext = createContext(null);
5002
+ function GroupSelect({
5003
+ value,
5004
+ onChange,
5005
+ type,
5006
+ children,
5007
+ style
5008
+ }) {
5009
+ return /* @__PURE__ */ jsx(GroupSelectContext.Provider, { value: { value, onChange, type }, children: /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.4vh", ...style }, children }) });
5010
+ }
5011
+ function filterByType(jobs, gangs, type) {
5012
+ if (type === "job") return jobs;
5013
+ if (type === "gang") return gangs;
5014
+ return [...jobs, ...gangs];
5015
+ }
5016
+ function GroupName(props) {
5017
+ const ctx = useContext(GroupSelectContext);
5018
+ const jobs = useFrameworkGroups((s) => s.jobs);
5019
+ const gangs = useFrameworkGroups((s) => s.gangs);
5020
+ const inCompound = ctx !== null;
5021
+ const currentValue = inCompound ? ctx.value.name : props.value;
5022
+ const filterType = inCompound ? ctx.type : props.type;
5023
+ const list = filterByType(jobs, gangs, filterType);
5024
+ const data = filterType === void 0 ? [
5025
+ { group: locale("Jobs") || "Jobs", items: jobs.map((g) => ({ value: g.name, label: g.label })) },
5026
+ { group: locale("Gangs") || "Gangs", items: gangs.map((g) => ({ value: g.name, label: g.label })) }
5027
+ ] : list.map((g) => ({ value: g.name, label: g.label }));
5028
+ return /* @__PURE__ */ jsx(
5029
+ Select,
5030
+ {
5031
+ label: props.label,
5032
+ description: props.description,
5033
+ placeholder: props.placeholder ?? (locale("SelectGroup") || "Select\u2026"),
5034
+ size: props.size ?? "xs",
5035
+ disabled: props.disabled,
5036
+ style: props.style,
5037
+ data,
5038
+ value: currentValue ?? null,
5039
+ searchable: true,
5040
+ onChange: (v) => {
5041
+ const name = v ?? "";
5042
+ if (inCompound) {
5043
+ ctx.onChange({ name: name || void 0, grade: void 0 });
5044
+ } else if (props.onChange) {
5045
+ props.onChange(name);
5046
+ }
5047
+ },
5048
+ allowDeselect: false
5049
+ }
5050
+ );
5051
+ }
5052
+ function GroupRank(props) {
5053
+ const ctx = useContext(GroupSelectContext);
5054
+ if (ctx === null) {
5055
+ throw new Error("<GroupRank> must be a child of <GroupSelect>");
5056
+ }
5057
+ const jobs = useFrameworkGroups((s) => s.jobs);
5058
+ const gangs = useFrameworkGroups((s) => s.gangs);
5059
+ const all = [...jobs, ...gangs];
5060
+ const selectedGroup = all.find((g) => g.name === ctx.value.name) ?? null;
5061
+ const grades = selectedGroup?.grades ?? [];
5062
+ const data = grades.map((g) => ({
5063
+ value: String(g.grade),
5064
+ label: `${g.grade} \u2014 ${g.label || g.name}${g.isBoss ? " (boss)" : ""}`
5065
+ }));
5066
+ return /* @__PURE__ */ jsx(
5067
+ Select,
5068
+ {
5069
+ label: props.label,
5070
+ description: props.description,
5071
+ placeholder: props.placeholder ?? (locale("SelectGrade") || "Select grade\u2026"),
5072
+ size: props.size ?? "xs",
5073
+ style: props.style,
5074
+ data,
5075
+ value: ctx.value.grade != null ? String(ctx.value.grade) : null,
5076
+ onChange: (v) => {
5077
+ ctx.onChange({
5078
+ ...ctx.value,
5079
+ grade: v != null ? Number(v) : void 0
5080
+ });
5081
+ },
5082
+ disabled: !selectedGroup || grades.length === 0,
5083
+ allowDeselect: false
5084
+ }
5085
+ );
5086
+ }
5087
+ GroupSelect.Name = GroupName;
5088
+ GroupSelect.Rank = GroupRank;
4746
5089
  var KeyBindContext = createContext(null);
4747
5090
  function useKeyBindContext() {
4748
5091
  const ctx = useContext(KeyBindContext);
@@ -5220,7 +5563,7 @@ function mergeMantineThemeSafe(base, custom, override) {
5220
5563
  }
5221
5564
  };
5222
5565
  }
5223
- var DirkErrorBoundary = class extends React5.Component {
5566
+ var DirkErrorBoundary = class extends React6.Component {
5224
5567
  constructor() {
5225
5568
  super(...arguments);
5226
5569
  __publicField(this, "state", { error: null, stack: void 0 });
@@ -5331,6 +5674,6 @@ function DirkProvider({ children, overideResourceName, themeOverride }) {
5331
5674
  return /* @__PURE__ */ jsx(MantineProvider, { theme: mergedTheme, defaultColorScheme: "dark", children: /* @__PURE__ */ jsx(DirkErrorBoundary, { children: content }) });
5332
5675
  }
5333
5676
 
5334
- export { AdminPageTitle, AsyncSaveButton, BlipColorSelect, BlipIconSelect, BorderedIcon, ConfigPanel, ConfirmModal, Counter, DirkProvider, FiveMKeyBindInput, FloatingParticles, FormProvider, INPUT_MAPPER_KEYS_BY_PRIMARY, INPUT_MAPPER_PRIMARY_OPTIONS, InfoBox, InputContainer, LevelBanner, LevelPanel, Modal, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, PromptModal, SegmentedControl, SegmentedProgress, SelectItem, TestBed, Title, TornEdgeSVGFilter, colorWithAlpha, copyToClipboard, createFormStore, createScriptConfig, createSkill, extractDefaults, fetchLuaTable, fetchNui, gameToMap, getImageShape, getItemImageUrl, getScriptConfigInstance, initialFetches, internalEvent, isEnvBrowser, isProfanity, latPr100, locale, localeStore, mapCenter, mapToGame, noop, numberToRoman, openLink, registerInitialFetch, registerInitialLuaTableFetch, runFetches, splitFAString, updatePresignedURL, uploadImage, useAudio, useAutoFetcher, useForm, useFormActions, useFormError, useFormErrors, useFormField, useFormFields, useItems, useItemsList, useModal, useModalActions, useNavigation, useNavigationStore, useNuiEvent, useProfanityStore, useSettings, useTornEdges };
5677
+ export { AdminPageTitle, AsyncSaveButton, BlipColorSelect, BlipDisplaySelect, BlipIconSelect, BorderedIcon, ConfigPanel, ConfirmModal, Counter, DirkProvider, FiveMKeyBindInput, FloatingParticles, FormProvider, GroupName, GroupRank, GroupSelect, INPUT_MAPPER_KEYS_BY_PRIMARY, INPUT_MAPPER_PRIMARY_OPTIONS, InfoBox, InputContainer, LevelBanner, LevelPanel, Modal, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, PositionPicker, PromptModal, SegmentedControl, SegmentedProgress, SelectItem, TestBed, Title, TornEdgeSVGFilter, colorWithAlpha, copyToClipboard, createFormStore, createScriptConfig, createSkill, extractDefaults, fetchLuaTable, fetchNui, gameToMap, getImageShape, getItemImageUrl, getScriptConfigInstance, initialFetches, internalEvent, isEnvBrowser, isProfanity, latPr100, locale, localeStore, mapCenter, mapToGame, noop, numberToRoman, openLink, registerInitialFetch, registerInitialLuaTableFetch, runFetches, selectAllGroups, splitFAString, updatePresignedURL, uploadImage, useAudio, useAutoFetcher, useForm, useFormActions, useFormError, useFormErrors, useFormField, useFormFields, useFrameworkGroups, useItems, useItemsList, useModal, useModalActions, useNavigation, useNavigationStore, useNuiEvent, useProfanityStore, useSettings, useTornEdges };
5335
5678
  //# sourceMappingURL=index.js.map
5336
5679
  //# sourceMappingURL=index.js.map