dirk-cfx-react 1.1.69 → 1.1.71

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.
@@ -852,6 +852,26 @@ type PositionPickerProps = {
852
852
  showHeading?: boolean;
853
853
  };
854
854
  declare function PositionPicker(props: PositionPickerProps): react_jsx_runtime.JSX.Element;
855
+ /** Read-only `vector4(x, y, z, w)` line in the same boxed style as PositionPicker. */
856
+ declare function Vector4Display({ value }: {
857
+ value: Vector4Value;
858
+ }): react_jsx_runtime.JSX.Element;
859
+ /** Grabs the player's current world coords+heading via `GET_POSITION`. */
860
+ declare function WorldPositionSetButton({ value, onChange, compact, }: {
861
+ value: Vector4Value;
862
+ onChange: (v: Vector4Value) => void;
863
+ compact?: boolean;
864
+ }): react_jsx_runtime.JSX.Element;
865
+ /** Teleports the player to the stored coords via `GOTO_POSITION`. */
866
+ declare function WorldPositionGotoButton({ value, compact, }: {
867
+ value: Vector4Value;
868
+ compact?: boolean;
869
+ }): react_jsx_runtime.JSX.Element;
870
+ /** Red-tinted Delete button matching the Set/Goto styling. */
871
+ declare function Vector4DeleteButton({ onClick, compact, }: {
872
+ onClick: () => void;
873
+ compact?: boolean;
874
+ }): react_jsx_runtime.JSX.Element;
855
875
 
856
876
  type GroupValue = {
857
877
  name?: string;
@@ -956,4 +976,4 @@ interface TestBedProps {
956
976
  }
957
977
  declare function TestBed({ items, storageKey, disablePersistence, title, }: TestBedProps): react_jsx_runtime.JSX.Element | null;
958
978
 
959
- export { AdminPageTitle, type AdminPageTitleProps, AsyncSaveButton, BlipColorSelect, type BlipColorSelectProps, BlipDisplaySelect, type BlipDisplaySelectProps, BlipIconSelect, type BlipIconSelectProps, BorderedIcon, type BorderedIconProps, type ButtonProps, ConfigPanel, type ConfigPanelProps, ConfirmModal, type ConfirmModalProps, ControlMultiSelect, type ControlMultiSelectProps, ControlSelect, type ControlSelectProps, Counter, type FiveMControls, FiveMKeyBindInput, FloatingParticles, type FloatingParticlesProps, GroupName, type GroupNameProps, GroupRank, type GroupRankProps, GroupSelect, type GroupSelectProps, type GroupType, type GroupValue, InfoBox, type InfoBoxProps, InputContainer, type InputContainerProps, LevelBanner, LevelPanel, Modal, ModalContext, type ModalProps, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, type NavItem, NavigationContext, NavigationProvider, type NavigationStore, type ParticleState, PositionPicker, type PositionPickerProps, type ProgressProps, type Prompt, type PromptButton, PromptModal, type SegmentProps, SegmentedControl, type SegmentedControlProps, SegmentedProgress, SelectItem, type SelectItemProps, type StoreModalProps, TestBed, type TestBedItem, type TestBedProps, Title, type TitleProps, type Vector4Value, useModal, useModalActions, useNavigation, useNavigationStore };
979
+ export { AdminPageTitle, type AdminPageTitleProps, AsyncSaveButton, BlipColorSelect, type BlipColorSelectProps, BlipDisplaySelect, type BlipDisplaySelectProps, BlipIconSelect, type BlipIconSelectProps, BorderedIcon, type BorderedIconProps, type ButtonProps, ConfigPanel, type ConfigPanelProps, ConfirmModal, type ConfirmModalProps, ControlMultiSelect, type ControlMultiSelectProps, ControlSelect, type ControlSelectProps, Counter, type FiveMControls, FiveMKeyBindInput, FloatingParticles, type FloatingParticlesProps, GroupName, type GroupNameProps, GroupRank, type GroupRankProps, GroupSelect, type GroupSelectProps, type GroupType, type GroupValue, InfoBox, type InfoBoxProps, InputContainer, type InputContainerProps, LevelBanner, LevelPanel, Modal, ModalContext, type ModalProps, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, type NavItem, NavigationContext, NavigationProvider, type NavigationStore, type ParticleState, PositionPicker, type PositionPickerProps, type ProgressProps, type Prompt, type PromptButton, PromptModal, type SegmentProps, SegmentedControl, type SegmentedControlProps, SegmentedProgress, SelectItem, type SelectItemProps, type StoreModalProps, TestBed, type TestBedItem, type TestBedProps, Title, type TitleProps, Vector4DeleteButton, Vector4Display, type Vector4Value, WorldPositionGotoButton, WorldPositionSetButton, useModal, useModalActions, useNavigation, useNavigationStore };
@@ -852,6 +852,26 @@ type PositionPickerProps = {
852
852
  showHeading?: boolean;
853
853
  };
854
854
  declare function PositionPicker(props: PositionPickerProps): react_jsx_runtime.JSX.Element;
855
+ /** Read-only `vector4(x, y, z, w)` line in the same boxed style as PositionPicker. */
856
+ declare function Vector4Display({ value }: {
857
+ value: Vector4Value;
858
+ }): react_jsx_runtime.JSX.Element;
859
+ /** Grabs the player's current world coords+heading via `GET_POSITION`. */
860
+ declare function WorldPositionSetButton({ value, onChange, compact, }: {
861
+ value: Vector4Value;
862
+ onChange: (v: Vector4Value) => void;
863
+ compact?: boolean;
864
+ }): react_jsx_runtime.JSX.Element;
865
+ /** Teleports the player to the stored coords via `GOTO_POSITION`. */
866
+ declare function WorldPositionGotoButton({ value, compact, }: {
867
+ value: Vector4Value;
868
+ compact?: boolean;
869
+ }): react_jsx_runtime.JSX.Element;
870
+ /** Red-tinted Delete button matching the Set/Goto styling. */
871
+ declare function Vector4DeleteButton({ onClick, compact, }: {
872
+ onClick: () => void;
873
+ compact?: boolean;
874
+ }): react_jsx_runtime.JSX.Element;
855
875
 
856
876
  type GroupValue = {
857
877
  name?: string;
@@ -956,4 +976,4 @@ interface TestBedProps {
956
976
  }
957
977
  declare function TestBed({ items, storageKey, disablePersistence, title, }: TestBedProps): react_jsx_runtime.JSX.Element | null;
958
978
 
959
- export { AdminPageTitle, type AdminPageTitleProps, AsyncSaveButton, BlipColorSelect, type BlipColorSelectProps, BlipDisplaySelect, type BlipDisplaySelectProps, BlipIconSelect, type BlipIconSelectProps, BorderedIcon, type BorderedIconProps, type ButtonProps, ConfigPanel, type ConfigPanelProps, ConfirmModal, type ConfirmModalProps, ControlMultiSelect, type ControlMultiSelectProps, ControlSelect, type ControlSelectProps, Counter, type FiveMControls, FiveMKeyBindInput, FloatingParticles, type FloatingParticlesProps, GroupName, type GroupNameProps, GroupRank, type GroupRankProps, GroupSelect, type GroupSelectProps, type GroupType, type GroupValue, InfoBox, type InfoBoxProps, InputContainer, type InputContainerProps, LevelBanner, LevelPanel, Modal, ModalContext, type ModalProps, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, type NavItem, NavigationContext, NavigationProvider, type NavigationStore, type ParticleState, PositionPicker, type PositionPickerProps, type ProgressProps, type Prompt, type PromptButton, PromptModal, type SegmentProps, SegmentedControl, type SegmentedControlProps, SegmentedProgress, SelectItem, type SelectItemProps, type StoreModalProps, TestBed, type TestBedItem, type TestBedProps, Title, type TitleProps, type Vector4Value, useModal, useModalActions, useNavigation, useNavigationStore };
979
+ export { AdminPageTitle, type AdminPageTitleProps, AsyncSaveButton, BlipColorSelect, type BlipColorSelectProps, BlipDisplaySelect, type BlipDisplaySelectProps, BlipIconSelect, type BlipIconSelectProps, BorderedIcon, type BorderedIconProps, type ButtonProps, ConfigPanel, type ConfigPanelProps, ConfirmModal, type ConfirmModalProps, ControlMultiSelect, type ControlMultiSelectProps, ControlSelect, type ControlSelectProps, Counter, type FiveMControls, FiveMKeyBindInput, FloatingParticles, type FloatingParticlesProps, GroupName, type GroupNameProps, GroupRank, type GroupRankProps, GroupSelect, type GroupSelectProps, type GroupType, type GroupValue, InfoBox, type InfoBoxProps, InputContainer, type InputContainerProps, LevelBanner, LevelPanel, Modal, ModalContext, type ModalProps, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, type NavItem, NavigationContext, NavigationProvider, type NavigationStore, type ParticleState, PositionPicker, type PositionPickerProps, type ProgressProps, type Prompt, type PromptButton, PromptModal, type SegmentProps, SegmentedControl, type SegmentedControlProps, SegmentedProgress, SelectItem, type SelectItemProps, type StoreModalProps, TestBed, type TestBedItem, type TestBedProps, Title, type TitleProps, Vector4DeleteButton, Vector4Display, type Vector4Value, WorldPositionGotoButton, WorldPositionSetButton, useModal, useModalActions, useNavigation, useNavigationStore };
@@ -7,6 +7,7 @@ import { motion, AnimatePresence, useMotionValue } from 'framer-motion';
7
7
  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';
8
8
  import clickSoundUrl from '../click_sound-PNCRRTM4.mp3';
9
9
  import hoverSoundUrl from '../hover_sound-NBUA222C.mp3';
10
+ import { notifications } from '@mantine/notifications';
10
11
  import { QueryClient, QueryClientProvider, useInfiniteQuery } from '@tanstack/react-query';
11
12
 
12
13
  // src/components/BlipSelect.tsx
@@ -4075,12 +4076,25 @@ function ConfigPanel(props) {
4075
4076
  if (result?.success) {
4076
4077
  form.reinitialize(cloneConfig(form.values));
4077
4078
  configPanelQueryClient.invalidateQueries({ queryKey: ["scriptConfigHistory"] });
4079
+ notifications.show({
4080
+ color: "green",
4081
+ title: locale("ConfigSaveSuccessTitle"),
4082
+ message: locale("ConfigSaveSuccessBody"),
4083
+ autoClose: 3e3
4084
+ });
4078
4085
  return;
4079
4086
  }
4080
4087
  form.reinitialize(cloneConfig(store.getState()));
4081
- if (result?._error) {
4082
- console.warn(`[ConfigPanel] config save failed: ${result._error}`);
4083
- }
4088
+ const err = result?._error || "Unknown";
4089
+ console.warn(`[ConfigPanel] config save failed: ${err}`);
4090
+ const titleKey = err === "NoPermission" ? "ConfigSaveNoPermissionTitle" : err === "VersionConflict" ? "ConfigSaveVersionConflictTitle" : err === "NotReady" ? "ConfigSaveNotReadyTitle" : "ConfigSaveFailedTitle";
4091
+ const bodyKey = err === "NoPermission" ? "ConfigSaveNoPermissionBody" : err === "VersionConflict" ? "ConfigSaveVersionConflictBody" : err === "NotReady" ? "ConfigSaveNotReadyBody" : "ConfigSaveFailedBody";
4092
+ notifications.show({
4093
+ color: "red",
4094
+ title: locale(titleKey),
4095
+ message: locale(bodyKey, err),
4096
+ autoClose: 6e3
4097
+ });
4084
4098
  } finally {
4085
4099
  setIsSaving(false);
4086
4100
  }
@@ -4099,7 +4113,7 @@ function ConfigPanel(props) {
4099
4113
  }
4100
4114
  ) });
4101
4115
  }
4102
- function LazyImage({ src, alt, style }) {
4116
+ function LazyImage({ src, style }) {
4103
4117
  const [visible, setVisible] = useState(false);
4104
4118
  const ref = useRef(null);
4105
4119
  useEffect(() => {
@@ -4112,7 +4126,7 @@ function LazyImage({ src, alt, style }) {
4112
4126
  if (ref.current) observer.observe(ref.current);
4113
4127
  return () => observer.disconnect();
4114
4128
  }, []);
4115
- return /* @__PURE__ */ jsx("div", { ref, style: { width: "4vh", height: "4vh" }, children: visible && /* @__PURE__ */ jsx(Image, { src, alt, fit: "contain", style }) });
4129
+ return /* @__PURE__ */ jsx("div", { ref, style: { width: "4vh", height: "4vh" }, children: visible && /* @__PURE__ */ jsx(Image, { src, fit: "contain", style }) });
4116
4130
  }
4117
4131
  function SelectItem(props) {
4118
4132
  const invItems = useItems();
@@ -4140,12 +4154,12 @@ function SelectItem(props) {
4140
4154
  searchable: true,
4141
4155
  comboboxProps: { withinPortal: true, zIndex: 2e3 },
4142
4156
  leftSectionWidth: "4vh",
4157
+ leftSectionPointerEvents: "none",
4143
4158
  leftSection: props.value ? /* @__PURE__ */ jsx(
4144
4159
  Image,
4145
4160
  {
4146
4161
  fallbackSrc: "/placeholder.png",
4147
4162
  src: invItems[props.value]?.image || "",
4148
- alt: props.value,
4149
4163
  fit: "contain",
4150
4164
  maw: "4vh",
4151
4165
  style: { aspectRatio: "1 / 1" }
@@ -4157,7 +4171,6 @@ function SelectItem(props) {
4157
4171
  LazyImage,
4158
4172
  {
4159
4173
  src: invItems[item.option.value]?.image || "",
4160
- alt: item.option.label,
4161
4174
  style: { aspectRatio: "1 / 1" }
4162
4175
  }
4163
4176
  ),
@@ -4382,6 +4395,148 @@ function PickerButton({
4382
4395
  }
4383
4396
  ) });
4384
4397
  }
4398
+ function fmtV4(n) {
4399
+ return Number.isFinite(n) ? n.toFixed(2) : "0.00";
4400
+ }
4401
+ function Vector4Display({ value }) {
4402
+ const theme = useMantineTheme();
4403
+ return /* @__PURE__ */ jsx(
4404
+ Flex,
4405
+ {
4406
+ align: "center",
4407
+ gap: "xs",
4408
+ p: "xs",
4409
+ style: {
4410
+ background: alpha(theme.colors.dark[5], 0.35),
4411
+ border: "0.1vh solid rgba(255,255,255,0.05)",
4412
+ borderRadius: theme.radius.xs
4413
+ },
4414
+ children: /* @__PURE__ */ jsxs(
4415
+ Text,
4416
+ {
4417
+ ff: "monospace",
4418
+ size: "xxs",
4419
+ c: "rgba(255,255,255,0.85)",
4420
+ style: { flex: 1, letterSpacing: "0.02em", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" },
4421
+ children: [
4422
+ "vector4(",
4423
+ fmtV4(value.x),
4424
+ ", ",
4425
+ fmtV4(value.y),
4426
+ ", ",
4427
+ fmtV4(value.z),
4428
+ ", ",
4429
+ fmtV4(value.w),
4430
+ ")"
4431
+ ]
4432
+ }
4433
+ )
4434
+ }
4435
+ );
4436
+ }
4437
+ function Vector4ActionButton({
4438
+ icon,
4439
+ label,
4440
+ tooltip,
4441
+ onClick,
4442
+ color,
4443
+ compact
4444
+ }) {
4445
+ const theme = useMantineTheme();
4446
+ return /* @__PURE__ */ jsx(Tooltip, { label: tooltip, position: "top", withArrow: true, withinPortal: true, zIndex: 2e3, children: /* @__PURE__ */ jsxs(
4447
+ motion.button,
4448
+ {
4449
+ onClick,
4450
+ whileHover: { background: alpha(color, 0.18) },
4451
+ whileTap: { scale: 0.95 },
4452
+ style: {
4453
+ background: alpha(color, 0.1),
4454
+ border: `0.1vh solid ${alpha(color, 0.35)}`,
4455
+ borderRadius: theme.radius.xs,
4456
+ padding: compact ? "0.25vh 0.6vh" : "0.5vh 0.8vh",
4457
+ cursor: "pointer",
4458
+ display: "flex",
4459
+ alignItems: "center",
4460
+ gap: compact ? "0.3vh" : "0.4vh"
4461
+ },
4462
+ children: [
4463
+ icon,
4464
+ /* @__PURE__ */ jsx(Text, { ff: "Akrobat Bold", size: "xxs", tt: "uppercase", lts: "0.06em", c: color, children: label })
4465
+ ]
4466
+ }
4467
+ ) });
4468
+ }
4469
+ function WorldPositionSetButton({
4470
+ value,
4471
+ onChange,
4472
+ compact
4473
+ }) {
4474
+ const theme = useMantineTheme();
4475
+ const color = theme.colors[theme.primaryColor][5];
4476
+ const grab = async () => {
4477
+ try {
4478
+ const resp = await fetchNui("GET_POSITION", {}, value);
4479
+ if (!resp || typeof resp !== "object") return;
4480
+ onChange({
4481
+ x: Number(resp.x ?? 0),
4482
+ y: Number(resp.y ?? 0),
4483
+ z: Number(resp.z ?? 0),
4484
+ w: Number(resp.w ?? 0)
4485
+ });
4486
+ } catch {
4487
+ }
4488
+ };
4489
+ return /* @__PURE__ */ jsx(
4490
+ Vector4ActionButton,
4491
+ {
4492
+ icon: /* @__PURE__ */ jsx(Crosshair, { size: compact ? "1.1vh" : "1.3vh", color }),
4493
+ label: locale("Set"),
4494
+ tooltip: locale("SetWorldTooltip"),
4495
+ onClick: grab,
4496
+ color,
4497
+ compact
4498
+ }
4499
+ );
4500
+ }
4501
+ function WorldPositionGotoButton({
4502
+ value,
4503
+ compact
4504
+ }) {
4505
+ const theme = useMantineTheme();
4506
+ const color = theme.colors[theme.primaryColor][5];
4507
+ const goto = () => {
4508
+ fetchNui("GOTO_POSITION", value).catch(() => {
4509
+ });
4510
+ };
4511
+ return /* @__PURE__ */ jsx(
4512
+ Vector4ActionButton,
4513
+ {
4514
+ icon: /* @__PURE__ */ jsx(MapPin, { size: compact ? "1.1vh" : "1.3vh", color }),
4515
+ label: locale("Goto"),
4516
+ tooltip: locale("GotoWorldTooltip"),
4517
+ onClick: goto,
4518
+ color,
4519
+ compact
4520
+ }
4521
+ );
4522
+ }
4523
+ function Vector4DeleteButton({
4524
+ onClick,
4525
+ compact
4526
+ }) {
4527
+ const color = "#ef4444";
4528
+ return /* @__PURE__ */ jsx(
4529
+ Vector4ActionButton,
4530
+ {
4531
+ icon: /* @__PURE__ */ jsx(Trash2, { size: compact ? "1.1vh" : "1.3vh", color }),
4532
+ label: locale("Delete"),
4533
+ tooltip: locale("Delete"),
4534
+ onClick,
4535
+ color,
4536
+ compact
4537
+ }
4538
+ );
4539
+ }
4385
4540
  var GroupSelectContext = createContext(null);
4386
4541
  function GroupSelect({
4387
4542
  value,
@@ -4833,6 +4988,6 @@ function TestBed({
4833
4988
  );
4834
4989
  }
4835
4990
 
4836
- export { AdminPageTitle, AsyncSaveButton, BlipColorSelect, BlipDisplaySelect, BlipIconSelect, BorderedIcon, ConfigPanel, ConfirmModal, ControlMultiSelect, ControlSelect, Counter, FiveMKeyBindInput, FloatingParticles, GroupName, GroupRank, GroupSelect, InfoBox, InputContainer, LevelBanner, LevelPanel, Modal, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, PositionPicker, PromptModal, SegmentedControl, SegmentedProgress, SelectItem, TestBed, Title, useModal, useModalActions, useNavigation, useNavigationStore };
4991
+ export { AdminPageTitle, AsyncSaveButton, BlipColorSelect, BlipDisplaySelect, BlipIconSelect, BorderedIcon, ConfigPanel, ConfirmModal, ControlMultiSelect, ControlSelect, Counter, FiveMKeyBindInput, FloatingParticles, GroupName, GroupRank, GroupSelect, InfoBox, InputContainer, LevelBanner, LevelPanel, Modal, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, PositionPicker, PromptModal, SegmentedControl, SegmentedProgress, SelectItem, TestBed, Title, Vector4DeleteButton, Vector4Display, WorldPositionGotoButton, WorldPositionSetButton, useModal, useModalActions, useNavigation, useNavigationStore };
4837
4992
  //# sourceMappingURL=index.js.map
4838
4993
  //# sourceMappingURL=index.js.map