dirk-cfx-react 1.0.40 → 1.0.41

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,6 +1,6 @@
1
1
  export { BorderedIcon, BorderedIconProps, ButtonProps, Counter, FloatingParticles, FloatingParticlesProps, InfoBox, InfoBoxProps, InputContainer, InputContainerProps, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, NavigationStore, ParticleState, ProgressProps, SegmentProps, SegmentedControl, SegmentedControlProps, SegmentedProgress, Title, TitleProps, useModal, useModalActions, useNavigation, useNavigationStore } from './components/index.cjs';
2
2
  export { InitialFetch, InternalEvent, SkillSettings, colorWithAlpha, copyToClipboard, createSkill, fetchNui, initialFetches, internalEvent, isEnvBrowser, isProfanity, locale, localeStore, noop, numberToRoman, openLink, registerInitialFetch, runFetches, splitFAString, useAutoFetcher, useProfanityStore } from './utils/index.cjs';
3
- export { TornEdgeSVGFilter, useNuiEvent, useTornEdges } from './hooks/index.cjs';
3
+ export { FormProvider, FormState, TornEdgeSVGFilter, ValidationRules, createFormStore, useForm, useNuiEvent, useTornEdges } from './hooks/index.cjs';
4
4
  export { DirkProvider, DirkProviderProps, useSettings } from './providers/index.cjs';
5
5
  import 'react/jsx-runtime';
6
6
  import 'react';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { BorderedIcon, BorderedIconProps, ButtonProps, Counter, FloatingParticles, FloatingParticlesProps, InfoBox, InfoBoxProps, InputContainer, InputContainerProps, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, NavigationStore, ParticleState, ProgressProps, SegmentProps, SegmentedControl, SegmentedControlProps, SegmentedProgress, Title, TitleProps, useModal, useModalActions, useNavigation, useNavigationStore } from './components/index.js';
2
2
  export { InitialFetch, InternalEvent, SkillSettings, colorWithAlpha, copyToClipboard, createSkill, fetchNui, initialFetches, internalEvent, isEnvBrowser, isProfanity, locale, localeStore, noop, numberToRoman, openLink, registerInitialFetch, runFetches, splitFAString, useAutoFetcher, useProfanityStore } from './utils/index.js';
3
- export { TornEdgeSVGFilter, useNuiEvent, useTornEdges } from './hooks/index.js';
3
+ export { FormProvider, FormState, TornEdgeSVGFilter, ValidationRules, createFormStore, useForm, useNuiEvent, useTornEdges } from './hooks/index.js';
4
4
  export { DirkProvider, DirkProviderProps, useSettings } from './providers/index.js';
5
5
  import 'react/jsx-runtime';
6
6
  import 'react';
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
2
2
  import { createTheme, Flex, Text, Image, MantineProvider, BackgroundImage, useMantineTheme, alpha } from '@mantine/core';
3
- import { createContext, useRef, useEffect, useMemo, useState, useContext } from 'react';
3
+ import { createContext, useRef, useEffect, useContext, useMemo, useState } from 'react';
4
+ import { create, createStore, useStore } from 'zustand';
5
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
4
6
  import '@mantine/core/styles.css';
5
7
  import '@mantine/notifications/styles.css';
6
8
  import './styles/fonts.css';
@@ -10,8 +12,6 @@ import { library } from '@fortawesome/fontawesome-svg-core';
10
12
  import { fab } from '@fortawesome/free-brands-svg-icons';
11
13
  import { far } from '@fortawesome/free-regular-svg-icons';
12
14
  import { fas } from '@fortawesome/free-solid-svg-icons';
13
- import { create, useStore } from 'zustand';
14
- import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
15
15
  import { motion, AnimatePresence, useMotionValue } from 'framer-motion';
16
16
  import clickSoundUrl from './click_sound-PNCRRTM4.mp3';
17
17
  import hoverSoundUrl from './hover_sound-NBUA222C.mp3';
@@ -235,6 +235,197 @@ var useNuiEvent = (action, handler) => {
235
235
  return () => window.removeEventListener("message", eventListener);
236
236
  }, [action]);
237
237
  };
238
+ function getNested(obj, path) {
239
+ return path.split(".").reduce((acc, key) => acc ? acc[key] : void 0, obj);
240
+ }
241
+ function setNested(obj, path, value) {
242
+ const keys = path.split(".");
243
+ const newObj = { ...obj };
244
+ let current = newObj;
245
+ for (let i = 0; i < keys.length - 1; i++) {
246
+ const key = keys[i];
247
+ current[key] = { ...current[key] || {} };
248
+ current = current[key];
249
+ }
250
+ current[keys[keys.length - 1]] = value;
251
+ return newObj;
252
+ }
253
+ function deleteNested(obj, path) {
254
+ const keys = path.split(".");
255
+ const newObj = { ...obj };
256
+ let current = newObj;
257
+ for (let i = 0; i < keys.length - 1; i++) {
258
+ const key = keys[i];
259
+ if (!current[key]) return obj;
260
+ current[key] = { ...current[key] };
261
+ current = current[key];
262
+ }
263
+ delete current[keys[keys.length - 1]];
264
+ return newObj;
265
+ }
266
+ function flattenRules(rules, prefix = "") {
267
+ const result = {};
268
+ for (const key in rules) {
269
+ const fullPath = prefix ? `${prefix}.${key}` : key;
270
+ const val = rules[key];
271
+ if (typeof val === "function") result[fullPath] = val;
272
+ else if (typeof val === "object")
273
+ Object.assign(result, flattenRules(val, fullPath));
274
+ }
275
+ return result;
276
+ }
277
+ function createFormStore(initialValues, validationRules, onSubmit) {
278
+ const flatRules = validationRules ? flattenRules(validationRules) : {};
279
+ const history = [];
280
+ const future = [];
281
+ const changed = /* @__PURE__ */ new Set();
282
+ return createStore((set, get) => ({
283
+ initialValues,
284
+ values: initialValues,
285
+ errors: {},
286
+ canBack: false,
287
+ canForward: false,
288
+ changedFields: [],
289
+ changedCount: 0,
290
+ onSubmit,
291
+ submit: () => {
292
+ const state = get();
293
+ const isValid = state.validate();
294
+ if (isValid && state.onSubmit) state.onSubmit(get());
295
+ },
296
+ resetChangeCount: () => {
297
+ changed.clear();
298
+ set(() => ({
299
+ changedFields: [],
300
+ changedCount: 0
301
+ }));
302
+ },
303
+ setInitialValues: (newInitialValues) => set({ initialValues: newInitialValues }),
304
+ setValue: (path, value) => {
305
+ const currentValues = get().values;
306
+ const newValues = setNested(currentValues, path, value);
307
+ const oldValue = getNested(get().initialValues, path);
308
+ history.push(currentValues);
309
+ future.length = 0;
310
+ if (value !== oldValue) changed.add(path);
311
+ else changed.delete(path);
312
+ set({
313
+ values: newValues,
314
+ canBack: history.length > 0,
315
+ canForward: false,
316
+ changedFields: Array.from(changed),
317
+ changedCount: changed.size
318
+ });
319
+ const rule = flatRules[path];
320
+ if (rule) {
321
+ const error = rule(value, newValues);
322
+ if (error)
323
+ set((state) => ({ errors: setNested(state.errors, path, error) }));
324
+ else set((state) => ({ errors: deleteNested(state.errors, path) }));
325
+ }
326
+ },
327
+ setError: (path, message) => set((state) => ({ errors: setNested(state.errors, path, message) })),
328
+ clearError: (path) => set((state) => ({ errors: deleteNested(state.errors, path) })),
329
+ validateField: (path) => {
330
+ const state = get();
331
+ const rule = flatRules[path];
332
+ if (!rule) return true;
333
+ const value = getNested(state.values, path);
334
+ const error = rule(value, state.values);
335
+ if (error) {
336
+ set((state2) => ({ errors: setNested(state2.errors, path, error) }));
337
+ return false;
338
+ } else {
339
+ set((state2) => ({ errors: deleteNested(state2.errors, path) }));
340
+ return true;
341
+ }
342
+ },
343
+ validate: () => {
344
+ const state = get();
345
+ let isValid = true;
346
+ let newErrors = {};
347
+ for (const path in flatRules) {
348
+ const rule = flatRules[path];
349
+ const value = getNested(state.values, path);
350
+ const error = rule(value, state.values);
351
+ if (error) {
352
+ isValid = false;
353
+ newErrors = setNested(newErrors, path, error);
354
+ }
355
+ }
356
+ set({ errors: newErrors });
357
+ return isValid;
358
+ },
359
+ reset: () => {
360
+ history.length = 0;
361
+ future.length = 0;
362
+ changed.clear();
363
+ set({
364
+ values: initialValues,
365
+ errors: {},
366
+ canBack: false,
367
+ canForward: false,
368
+ changedFields: [],
369
+ changedCount: 0
370
+ });
371
+ },
372
+ back: () => {
373
+ const state = get();
374
+ if (history.length === 0) return;
375
+ const prev = history.pop();
376
+ future.push(state.values);
377
+ changed.clear();
378
+ const current = prev;
379
+ const initial = get().initialValues;
380
+ for (const key in current) {
381
+ if (JSON.stringify(current[key]) !== JSON.stringify(initial[key]))
382
+ changed.add(key);
383
+ }
384
+ set({
385
+ values: prev,
386
+ canBack: history.length > 0,
387
+ canForward: true,
388
+ changedFields: Array.from(changed),
389
+ changedCount: changed.size
390
+ });
391
+ },
392
+ forward: () => {
393
+ const state = get();
394
+ if (future.length === 0) return;
395
+ const next = future.pop();
396
+ history.push(state.values);
397
+ changed.clear();
398
+ const current = next;
399
+ const initial = get().initialValues;
400
+ for (const key in current) {
401
+ if (JSON.stringify(current[key]) !== JSON.stringify(initial[key]))
402
+ changed.add(key);
403
+ }
404
+ set({
405
+ values: next,
406
+ canBack: true,
407
+ canForward: future.length > 0,
408
+ changedFields: Array.from(changed),
409
+ changedCount: changed.size
410
+ });
411
+ }
412
+ }));
413
+ }
414
+ var FormContext = createContext(null);
415
+ function FormProvider({
416
+ initialValues,
417
+ validate,
418
+ onSubmit,
419
+ children
420
+ }) {
421
+ const storeRef = useRef(createFormStore(initialValues, validate, onSubmit));
422
+ return /* @__PURE__ */ jsx(FormContext.Provider, { value: storeRef.current, children });
423
+ }
424
+ function useForm() {
425
+ const store = useContext(FormContext);
426
+ if (!store) throw new Error("useForm must be used inside a <FormProvider>");
427
+ return useStore(store);
428
+ }
238
429
  async function fetchNui(eventName, data, mockData) {
239
430
  const options = {
240
431
  method: "post",
@@ -715,7 +906,7 @@ function getLevelFromXP(xp, levelMap, settings) {
715
906
  return settings.maxLevel;
716
907
  }
717
908
  function createSkill(defaultSettings) {
718
- const useStore3 = create((set) => ({
909
+ const useStore4 = create((set) => ({
719
910
  settings: defaultSettings,
720
911
  levelMap: generateLevelMap(defaultSettings),
721
912
  setSettings: (updater) => set((state) => {
@@ -727,7 +918,7 @@ function createSkill(defaultSettings) {
727
918
  })
728
919
  }));
729
920
  const useSkill = (xp) => {
730
- const { settings, levelMap } = useStore3();
921
+ const { settings, levelMap } = useStore4();
731
922
  return useMemo(() => {
732
923
  const currentLevel = getLevelFromXP(xp, levelMap, settings);
733
924
  const nextLevel = Math.min(currentLevel + 1, settings.maxLevel);
@@ -749,12 +940,12 @@ function createSkill(defaultSettings) {
749
940
  };
750
941
  const skill = {
751
942
  get settings() {
752
- return useStore3.getState().settings;
943
+ return useStore4.getState().settings;
753
944
  },
754
945
  setSettings: (updater) => {
755
- useStore3.getState().setSettings(updater);
946
+ useStore4.getState().setSettings(updater);
756
947
  },
757
- useSettings: () => useStore3((state) => state.settings)
948
+ useSettings: () => useStore4((state) => state.settings)
758
949
  };
759
950
  return {
760
951
  skill,
@@ -1900,6 +2091,6 @@ function Modal() {
1900
2091
  ) });
1901
2092
  }
1902
2093
 
1903
- export { BorderedIcon, Counter, DirkProvider, FloatingParticles, InfoBox, InputContainer, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, SegmentedControl, SegmentedProgress, Title, TornEdgeSVGFilter, colorWithAlpha, copyToClipboard, createSkill, fetchNui, initialFetches, internalEvent, isEnvBrowser, isProfanity, locale, localeStore, noop, numberToRoman, openLink, registerInitialFetch, runFetches, splitFAString, useAutoFetcher, useModal, useModalActions, useNavigation, useNavigationStore, useNuiEvent, useProfanityStore, useSettings, useTornEdges };
2094
+ export { BorderedIcon, Counter, DirkProvider, FloatingParticles, FormProvider, InfoBox, InputContainer, ModalContext, ModalProvider, MotionFlex, MotionIcon, MotionImage, MotionText, NavBar, NavigationContext, NavigationProvider, SegmentedControl, SegmentedProgress, Title, TornEdgeSVGFilter, colorWithAlpha, copyToClipboard, createFormStore, createSkill, fetchNui, initialFetches, internalEvent, isEnvBrowser, isProfanity, locale, localeStore, noop, numberToRoman, openLink, registerInitialFetch, runFetches, splitFAString, useAutoFetcher, useForm, useModal, useModalActions, useNavigation, useNavigationStore, useNuiEvent, useProfanityStore, useSettings, useTornEdges };
1904
2095
  //# sourceMappingURL=index.js.map
1905
2096
  //# sourceMappingURL=index.js.map