@povio/ui 3.3.0 → 3.4.0-rc.1

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.
Files changed (78) hide show
  1. package/dist/components/inputs/Checkbox/Checkbox.d.ts +1 -2
  2. package/dist/components/inputs/Checkbox/Checkbox.js +93 -100
  3. package/dist/components/inputs/Checkbox/CheckboxGroup.d.ts +1 -2
  4. package/dist/components/inputs/Checkbox/CheckboxGroup.js +109 -113
  5. package/dist/components/inputs/DateTime/DatePicker/DatePicker.d.ts +1 -2
  6. package/dist/components/inputs/DateTime/DatePicker/DatePicker.js +14 -21
  7. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.d.ts +1 -2
  8. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +14 -22
  9. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.d.ts +1 -2
  10. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +14 -21
  11. package/dist/components/inputs/DateTime/TimePicker/TimePicker.d.ts +1 -2
  12. package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +275 -294
  13. package/dist/components/inputs/DateTime/shared/DatePickerInput.d.ts +1 -2
  14. package/dist/components/inputs/DateTime/shared/DatePickerInput.js +1 -10
  15. package/dist/components/inputs/DateTime/shared/TimePickerInput.d.ts +1 -2
  16. package/dist/components/inputs/DateTime/shared/TimePickerInput.js +43 -46
  17. package/dist/components/inputs/File/FileUpload.d.ts +1 -1
  18. package/dist/components/inputs/File/FileUpload.js +17 -17
  19. package/dist/components/inputs/File/InputUpload.d.ts +1 -1
  20. package/dist/components/inputs/File/InputUpload.js +17 -17
  21. package/dist/components/inputs/File/fileUpload.types.d.ts +1 -1
  22. package/dist/components/inputs/File/inputUpload.types.d.ts +1 -1
  23. package/dist/components/inputs/Input/NumberInput/NumberInput.d.ts +1 -1
  24. package/dist/components/inputs/Input/NumberInput/NumberInput.js +19 -19
  25. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.d.ts +1 -1
  26. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.js +18 -18
  27. package/dist/components/inputs/Input/PasswordInput/PasswordInput.d.ts +1 -1
  28. package/dist/components/inputs/Input/TextArea/TextArea.d.ts +1 -1
  29. package/dist/components/inputs/Input/TextArea/TextArea.js +18 -18
  30. package/dist/components/inputs/Input/TextInput/TextInput.d.ts +2 -2
  31. package/dist/components/inputs/Input/TextInput/TextInput.js +36 -38
  32. package/dist/components/inputs/Inputs/Form.d.ts +4 -4
  33. package/dist/components/inputs/Inputs/InputItem.d.ts +22 -22
  34. package/dist/components/inputs/Inputs/InputItem.js +35 -36
  35. package/dist/components/inputs/Inputs/Inputs.d.ts +2 -2
  36. package/dist/components/inputs/RadioGroup/RadioGroup.d.ts +1 -2
  37. package/dist/components/inputs/RadioGroup/RadioGroup.js +107 -111
  38. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.d.ts +1 -1
  39. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +13 -13
  40. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.d.ts +1 -1
  41. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.js +19 -19
  42. package/dist/components/inputs/Selection/Autocomplete/queryAutocomplete.types.d.ts +1 -1
  43. package/dist/components/inputs/Selection/Select/QuerySelect.d.ts +1 -1
  44. package/dist/components/inputs/Selection/Select/QuerySelect.js +19 -19
  45. package/dist/components/inputs/Selection/Select/Select.d.ts +1 -1
  46. package/dist/components/inputs/Selection/Select/Select.js +19 -19
  47. package/dist/components/inputs/Selection/shared/SelectBase.d.ts +0 -1
  48. package/dist/components/inputs/Selection/shared/SelectBase.js +34 -37
  49. package/dist/components/inputs/Selection/shared/select.context.d.ts +2 -2
  50. package/dist/components/inputs/Selection/shared/select.context.js +4 -8
  51. package/dist/components/inputs/Selection/shared/select.types.d.ts +1 -1
  52. package/dist/components/inputs/Slider/Slider.d.ts +1 -1
  53. package/dist/components/inputs/Slider/Slider.js +18 -18
  54. package/dist/components/inputs/TextEditor/TextEditor.d.ts +1 -1
  55. package/dist/components/inputs/TextEditor/TextEditor.js +18 -18
  56. package/dist/components/inputs/Toggle/Toggle.d.ts +1 -2
  57. package/dist/components/inputs/Toggle/Toggle.js +59 -63
  58. package/dist/components/inputs/shared/form.binding.d.ts +27 -0
  59. package/dist/components/inputs/shared/form.binding.js +57 -0
  60. package/dist/components/inputs/shared/form.types.d.ts +9 -8
  61. package/dist/components/inputs/shared/form.types.js +8 -0
  62. package/dist/components/segment/Segment.d.ts +1 -1
  63. package/dist/components/segment/Segment.js +17 -17
  64. package/dist/components/segment/segment.types.d.ts +1 -1
  65. package/dist/config/uiConfig.context.d.ts +5 -5
  66. package/dist/config/uiConfig.context.js +3 -12
  67. package/dist/helpers/dynamicColumns.d.ts +1 -1
  68. package/dist/helpers/dynamicInputs.d.ts +7 -7
  69. package/dist/hooks/useAutosave.d.ts +4 -4
  70. package/dist/hooks/useAutosave.js +64 -49
  71. package/dist/hooks/useForm.d.ts +39 -15
  72. package/dist/hooks/useForm.js +96 -43
  73. package/dist/hooks/useFormAutosave.d.ts +8 -9
  74. package/dist/hooks/useFormAutosave.js +23 -9
  75. package/dist/index.d.ts +2 -2
  76. package/dist/index.js +3 -3
  77. package/package.json +2 -3
  78. package/dist/hooks/useAutosave.spec.d.ts +0 -1
@@ -1,70 +1,85 @@
1
1
  import { ObjectUtils } from "../utils/object.utils.js";
2
2
  import { isEqual } from "../utils/isEqual.js";
3
3
  import { useEffect, useRef } from "react";
4
- import { useFormState, useWatch } from "react-hook-form";
5
4
  //#region src/hooks/useAutosave.ts
6
- function isNilOrEqual(left, right) {
7
- if (ObjectUtils.isNil(left) && ObjectUtils.isNil(right)) return true;
8
- return isEqual(left, right);
9
- }
10
- function diffLeftOnly(left, right, shallowKeys) {
11
- if (!ObjectUtils.isObject(left) || ObjectUtils.isDate(left) || ObjectUtils.isRegExp(left)) return !isNilOrEqual(left, right) ? left : void 0;
12
- if (Array.isArray(left)) return !isNilOrEqual(left, right) ? left : void 0;
5
+ function diffLeftOnly(left, right) {
6
+ if (!ObjectUtils.isObject(left) || ObjectUtils.isDate(left) || ObjectUtils.isRegExp(left)) return isEqual(left, right) ? void 0 : left;
7
+ if (Array.isArray(left)) return isEqual(left, right) ? void 0 : left;
13
8
  const result = Object.entries(left).reduce((acc, [key, value]) => {
14
- const shallowSubtree = shallowKeys?.[key];
15
- if (shallowSubtree === true) {
16
- if (!isNilOrEqual(value, right?.[key])) acc[key] = value;
17
- return acc;
18
- }
19
- const diff = diffLeftOnly(value, right?.[key], shallowSubtree);
9
+ const diff = diffLeftOnly(value, right?.[key]);
20
10
  if (diff !== void 0 && (!ObjectUtils.isObject(diff) || !ObjectUtils.isEmpty(diff))) acc[key] = diff;
21
11
  return acc;
22
12
  }, {});
23
13
  return ObjectUtils.isEmpty(result) ? void 0 : result;
24
14
  }
15
+ var snapshot = (value) => structuredClone(value);
16
+ function pickChangedValues(source, changes) {
17
+ if (!ObjectUtils.isObject(changes) || Array.isArray(changes)) return source;
18
+ return Object.entries(changes).reduce((result, [key, value]) => {
19
+ result[key] = pickChangedValues(source?.[key], value);
20
+ return result;
21
+ }, {});
22
+ }
25
23
  function useAutosave({ form, delay = 500, enabled = true, trigger = "change", onSave, onSaveSuccess }) {
26
24
  const timeoutRef = useRef(void 0);
27
- const previousBlurTriggerFieldsRef = useRef(void 0);
28
- const { control, reset, handleSubmit } = form;
29
- const { dirtyFields, touchedFields, defaultValues } = useFormState({ control });
30
- const formData = useWatch({ control });
25
+ const savedSnapshotRef = useRef(snapshot(form.state.values));
26
+ const saveQueueRef = useRef(Promise.resolve());
27
+ const latestSaveRef = useRef({
28
+ onSave,
29
+ onSaveSuccess
30
+ });
31
+ latestSaveRef.current = {
32
+ onSave,
33
+ onSaveSuccess
34
+ };
31
35
  useEffect(() => {
32
- if (!enabled || Object.keys(dirtyFields).length === 0) return;
33
- if (trigger === "blur") {
34
- const blurTriggerFields = JSON.stringify(touchedFields);
35
- if (Object.keys(touchedFields).length === 0 || previousBlurTriggerFieldsRef.current === blurTriggerFields) return;
36
- previousBlurTriggerFieldsRef.current = blurTriggerFields;
37
- }
38
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
39
- timeoutRef.current = setTimeout(() => {
40
- handleSubmit(async (data) => {
41
- const changedData = diffLeftOnly(Object.entries(dirtyFields).filter(([, value]) => value).reduce((acc, [key]) => {
42
- acc[key] = data[key];
43
- return acc;
44
- }, {}), defaultValues, dirtyFields) ?? {};
45
- if (Object.keys(changedData).length === 0) return;
46
- try {
47
- reset(void 0, { keepValues: true });
48
- await onSave(changedData);
49
- onSaveSuccess?.();
50
- } catch {
51
- reset(defaultValues);
52
- return;
53
- }
54
- })();
55
- }, delay);
36
+ const clearPending = () => {
37
+ if (timeoutRef.current) {
38
+ clearTimeout(timeoutRef.current);
39
+ timeoutRef.current = void 0;
40
+ }
41
+ };
42
+ const queueSave = () => {
43
+ if (!enabled) return;
44
+ clearPending();
45
+ timeoutRef.current = setTimeout(() => {
46
+ saveQueueRef.current = saveQueueRef.current.then(async () => {
47
+ const valuesAtSaveTime = snapshot(form.state.values);
48
+ const changedValues = diffLeftOnly(valuesAtSaveTime, savedSnapshotRef.current);
49
+ if (!changedValues) return;
50
+ let transformedValues;
51
+ try {
52
+ transformedValues = form.parseValues(valuesAtSaveTime);
53
+ } catch {
54
+ return;
55
+ }
56
+ const payload = pickChangedValues(transformedValues, changedValues);
57
+ if (ObjectUtils.isEmpty(payload)) return;
58
+ try {
59
+ await latestSaveRef.current.onSave(payload);
60
+ savedSnapshotRef.current = valuesAtSaveTime;
61
+ for (const name of Object.keys(payload)) form.setFieldMeta(name, (meta) => ({
62
+ ...meta,
63
+ isDirty: false
64
+ }));
65
+ latestSaveRef.current.onSaveSuccess?.();
66
+ } catch {}
67
+ });
68
+ }, delay);
69
+ };
70
+ const unsubscribeStore = trigger === "change" ? form.store.subscribe(() => {
71
+ if (!isEqual(form.state.values, savedSnapshotRef.current)) queueSave();
72
+ }) : void 0;
73
+ const unsubscribeBlur = trigger === "blur" ? form.subscribeBlur(queueSave) : void 0;
56
74
  return () => {
57
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
75
+ clearPending();
76
+ unsubscribeStore?.unsubscribe();
77
+ unsubscribeBlur?.();
58
78
  };
59
79
  }, [
60
- defaultValues,
61
- dirtyFields,
62
- trigger === "change" ? formData : touchedFields,
63
80
  delay,
64
- onSave,
65
- handleSubmit,
66
81
  enabled,
67
- reset,
82
+ form,
68
83
  trigger
69
84
  ]);
70
85
  }
@@ -1,18 +1,42 @@
1
- import { BrowserNativeObject, ExtractObjects, FieldValues, NestedValue, UseFormProps as UseReactHookFormProps } from 'react-hook-form';
1
+ import { AnyFormApi, DeepKeys, DeepValue, ReactFormExtendedApi } from '@tanstack/react-form';
2
2
  import { z } from 'zod';
3
- type DeepNullablePartial<T> = T extends BrowserNativeObject | NestedValue ? T : {
4
- [K in keyof T]?: ExtractObjects<T[K]> extends never ? T[K] | null : DeepNullablePartial<T[K]>;
3
+ type FormMode = "all" | "onBlur" | "onChange" | "onSubmit" | "onTouched";
4
+ type FieldValidators = {
5
+ onBlur?: ({ value }: {
6
+ value: unknown;
7
+ }) => string | undefined;
8
+ onChange?: ({ value }: {
9
+ value: unknown;
10
+ }) => string | undefined;
5
11
  };
6
- type AsyncDefaultValues<TFieldValues> = (payload?: unknown) => Promise<TFieldValues>;
7
- type NullableDefaultValues<TFieldValues> = TFieldValues extends AsyncDefaultValues<TFieldValues> ? DeepNullablePartial<Awaited<TFieldValues>> : DeepNullablePartial<TFieldValues>;
8
- export type UseFormResolverProps<TFieldValues extends FieldValues, TTransformedValues = TFieldValues> = {
9
- zodSchema: z.ZodType<TTransformedValues, TFieldValues>;
10
- resolver?: never;
11
- } | {
12
- zodSchema?: never;
13
- };
14
- export type UseFormProps<TFieldValues extends FieldValues, TContext, TTransformedValues = TFieldValues> = Omit<UseReactHookFormProps<TFieldValues, TContext, TTransformedValues>, "defaultValues"> & {
15
- defaultValues?: NullableDefaultValues<TFieldValues> | AsyncDefaultValues<TFieldValues>;
12
+ export type FormSubmitHandler<TValues> = (values: TValues) => void | Promise<void>;
13
+ export type FormSubmitErrorHandler<TValues> = (errors: unknown, values: TValues) => unknown;
14
+ type TanStackForm<TFieldValues> = ReactFormExtendedApi<TFieldValues, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, never>;
15
+ export type UIForm<TFieldValues extends Record<string, unknown> = Record<string, unknown>> = Omit<TanStackForm<TFieldValues>, "handleSubmit"> & {
16
+ readonly disabled: boolean;
17
+ getFieldValidators: (name: DeepKeys<TFieldValues>) => FieldValidators | undefined;
18
+ notifyBlur: (name: DeepKeys<TFieldValues>) => void;
19
+ parseValues: (values: TFieldValues) => unknown;
20
+ subscribeBlur: (listener: (name: DeepKeys<TFieldValues>) => void) => () => void;
21
+ handleSubmit: (onValid: FormSubmitHandler<any>, onInvalid?: FormSubmitErrorHandler<TFieldValues>) => (event?: {
22
+ preventDefault?: () => void;
23
+ stopPropagation?: () => void;
24
+ }) => Promise<void>;
16
25
  };
17
- export declare function useForm<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues = TFieldValues>({ resolver, zodSchema, defaultValues, ...props }: UseFormProps<TFieldValues, TContext, TTransformedValues> & UseFormResolverProps<TFieldValues, TTransformedValues>): import('react-hook-form').UseFormReturn<TFieldValues, TContext, TTransformedValues>;
18
- export {};
26
+ type AsyncDefaultValues<TFieldValues> = (payload?: unknown) => Promise<TFieldValues>;
27
+ type NullableDefaults<T> = T extends Date | File | Blob ? T : T extends Array<infer TItem> ? Array<NullableDefaults<TItem>> : T extends object ? {
28
+ [K in keyof T]?: NullableDefaults<T[K]> | null;
29
+ } : T | null;
30
+ export interface UseFormProps<TFieldValues, TTransformedValues = TFieldValues> {
31
+ defaultValues?: NullableDefaults<TFieldValues> | AsyncDefaultValues<TFieldValues>;
32
+ disabled?: boolean;
33
+ mode?: FormMode;
34
+ onSubmitAsync?: (props: {
35
+ value: TFieldValues;
36
+ }) => Promise<unknown>;
37
+ zodSchema?: z.ZodType<TTransformedValues, TFieldValues>;
38
+ }
39
+ export declare function useForm<TFieldValues extends Record<string, unknown> = Record<string, unknown>, _TContext = unknown, TTransformedValues = TFieldValues>({ defaultValues, disabled, mode, onSubmitAsync, zodSchema, }?: UseFormProps<TFieldValues, TTransformedValues>): UIForm<TFieldValues>;
40
+ export declare const useFormValue: <TFieldValues extends Record<string, unknown>, TSelected>(form: UIForm<TFieldValues>, selector: (values: TFieldValues) => TSelected) => TSelected;
41
+ export declare const useFormState: <TFieldValues extends Record<string, unknown>, TSelected>(form: UIForm<TFieldValues>, selector: (state: UIForm<TFieldValues>["state"]) => TSelected) => TSelected;
42
+ export type { AnyFormApi, DeepKeys, DeepValue };
@@ -1,48 +1,101 @@
1
1
  import { c } from "react/compiler-runtime";
2
- import { useForm } from "react-hook-form";
3
- import { zodResolver } from "@hookform/resolvers/zod";
2
+ import { useEffect, useMemo, useRef } from "react";
3
+ import { useForm, useStore } from "@tanstack/react-form";
4
4
  //#region src/hooks/useForm.ts
5
- function useForm$1(t0) {
6
- const $ = c(12);
7
- let defaultValues;
8
- let props;
9
- let resolver;
10
- let zodSchema;
11
- if ($[0] !== t0) {
12
- ({resolver, zodSchema, defaultValues, ...props} = t0);
13
- $[0] = t0;
14
- $[1] = defaultValues;
15
- $[2] = props;
16
- $[3] = resolver;
17
- $[4] = zodSchema;
18
- } else {
19
- defaultValues = $[1];
20
- props = $[2];
21
- resolver = $[3];
22
- zodSchema = $[4];
23
- }
24
- let t1;
25
- if ($[5] !== resolver || $[6] !== zodSchema) {
26
- t1 = resolver ?? (zodSchema ? zodResolver(zodSchema) : void 0);
27
- $[5] = resolver;
28
- $[6] = zodSchema;
29
- $[7] = t1;
30
- } else t1 = $[7];
31
- const formResolver = t1;
32
- const t2 = defaultValues;
33
- let t3;
34
- if ($[8] !== formResolver || $[9] !== props || $[10] !== t2) {
35
- t3 = {
36
- ...props,
37
- resolver: formResolver,
38
- defaultValues: t2
5
+ function useForm$1({ defaultValues, disabled = false, mode = "onSubmit", onSubmitAsync, zodSchema } = {}) {
6
+ const submitHandlerRef = useRef(() => void 0);
7
+ const submitErrorHandlerRef = useRef(void 0);
8
+ const blurListenersRef = useRef(/* @__PURE__ */ new Set());
9
+ const fieldValidators = useMemo(() => {
10
+ return /* @__PURE__ */ new Map();
11
+ }, [mode, zodSchema]);
12
+ const formValidator = useMemo(() => {
13
+ if (!zodSchema) return;
14
+ return ({ value }) => {
15
+ const result = zodSchema.safeParse(value);
16
+ if (result.success) return;
17
+ return { fields: Object.fromEntries(result.error.issues.map((issue) => [pathToString(issue.path), issue.message])) };
18
+ };
19
+ }, [zodSchema]);
20
+ const form = useForm({
21
+ defaultValues: (typeof defaultValues === "function" ? {} : defaultValues) ?? {},
22
+ validators: formValidator || onSubmitAsync ? {
23
+ onSubmit: formValidator,
24
+ onSubmitAsync
25
+ } : void 0,
26
+ onSubmit: async ({ value: value_0 }) => {
27
+ const transformed = zodSchema ? zodSchema.parse(value_0) : value_0;
28
+ await submitHandlerRef.current(transformed);
29
+ },
30
+ onSubmitInvalid: ({ value: value_1, formApi }) => {
31
+ submitErrorHandlerRef.current?.(formApi.state.errors, value_1);
32
+ }
33
+ });
34
+ const originalHandleSubmit = useMemo(() => form.handleSubmit.bind(form), [form]);
35
+ const uiForm = form;
36
+ Object.defineProperties(uiForm, { disabled: {
37
+ configurable: true,
38
+ get: () => disabled
39
+ } });
40
+ uiForm.getFieldValidators = (name) => {
41
+ const cached = fieldValidators.get(name);
42
+ if (cached || fieldValidators.has(name)) return cached;
43
+ const schema = zodSchema ? getSchemaAtPath(zodSchema, name) : void 0;
44
+ if (!schema || mode === "onSubmit") {
45
+ fieldValidators.set(name, void 0);
46
+ return;
47
+ }
48
+ const validate = ({ value: value_2 }) => {
49
+ const result_0 = schema.safeParse(value_2);
50
+ return result_0.success ? void 0 : result_0.error.issues[0]?.message;
39
51
  };
40
- $[8] = formResolver;
41
- $[9] = props;
42
- $[10] = t2;
43
- $[11] = t3;
44
- } else t3 = $[11];
45
- return useForm(t3);
52
+ const validators = mode === "onChange" || mode === "all" ? { onChange: validate } : { onBlur: validate };
53
+ fieldValidators.set(name, validators);
54
+ return validators;
55
+ };
56
+ uiForm.notifyBlur = (name_0) => {
57
+ for (const listener of blurListenersRef.current) listener(name_0);
58
+ };
59
+ uiForm.parseValues = (values) => zodSchema ? zodSchema.parse(values) : values;
60
+ uiForm.subscribeBlur = (listener_0) => {
61
+ blurListenersRef.current.add(listener_0);
62
+ return () => blurListenersRef.current.delete(listener_0);
63
+ };
64
+ uiForm.handleSubmit = (onValid, onInvalid) => async (event) => {
65
+ event?.preventDefault?.();
66
+ event?.stopPropagation?.();
67
+ submitHandlerRef.current = onValid;
68
+ submitErrorHandlerRef.current = onInvalid;
69
+ await originalHandleSubmit();
70
+ };
71
+ useEffect(() => {
72
+ if (typeof defaultValues === "function") defaultValues().then((values_0) => form.reset(values_0));
73
+ }, [defaultValues, form]);
74
+ return uiForm;
46
75
  }
76
+ var useFormValue = (form, selector) => {
77
+ const $ = c(2);
78
+ let t0;
79
+ if ($[0] !== selector) {
80
+ t0 = (state) => selector(state.values);
81
+ $[0] = selector;
82
+ $[1] = t0;
83
+ } else t0 = $[1];
84
+ return useStore(form.store, t0);
85
+ };
86
+ var useFormState = (form, selector) => {
87
+ return useStore(form.store, selector);
88
+ };
89
+ var getSchemaAtPath = (rootSchema, path) => {
90
+ let schema = rootSchema;
91
+ for (const segment of parsePath(path)) {
92
+ while (schema?.unwrap && !schema.shape && !schema.element && !schema.items) schema = schema.unwrap();
93
+ schema = typeof segment === "number" ? schema?.element ?? schema?.items?.[segment] : schema?.shape?.[segment];
94
+ if (!schema) return;
95
+ }
96
+ return schema;
97
+ };
98
+ var parsePath = (path) => path.replaceAll("[", ".").replaceAll("]", "").split(".").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
99
+ var pathToString = (path) => path.reduce((result, segment) => typeof segment === "number" ? `${result}[${segment}]` : result ? `${result}.${String(segment)}` : String(segment), "");
47
100
  //#endregion
48
- export { useForm$1 as useForm };
101
+ export { useForm$1 as useForm, useFormState, useFormValue };
@@ -1,15 +1,14 @@
1
1
  import { DependencyList } from 'react';
2
- import { FieldValues } from 'react-hook-form';
3
2
  import { UseAutosaveProps } from './useAutosave';
4
- import { UseFormProps, UseFormResolverProps } from './useForm';
5
- export type UseFormAutosaveProps<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues = TFieldValues, TResponse = unknown> = Omit<UseFormProps<TFieldValues, TContext, TTransformedValues>, "defaultValues"> & UseFormResolverProps<TFieldValues, TTransformedValues> & {
6
- autosaveDelay?: UseAutosaveProps<TFieldValues, TContext, TTransformedValues, TResponse>["delay"];
7
- enableAutosave?: UseAutosaveProps<TFieldValues, TContext, TTransformedValues, TResponse>["enabled"];
8
- autosaveOn?: UseAutosaveProps<TFieldValues, TContext, TTransformedValues, TResponse>["trigger"];
3
+ import { UseFormProps } from './useForm';
4
+ export type UseFormAutosaveProps<TFieldValues extends Record<string, unknown> = Record<string, unknown>, _TContext = any, TTransformedValues = TFieldValues, TResponse = unknown> = Omit<UseFormProps<TFieldValues, TTransformedValues>, "defaultValues"> & {
5
+ autosaveDelay?: UseAutosaveProps<TFieldValues, TTransformedValues, TResponse>["delay"];
6
+ enableAutosave?: UseAutosaveProps<TFieldValues, TTransformedValues, TResponse>["enabled"];
7
+ autosaveOn?: UseAutosaveProps<TFieldValues, TTransformedValues, TResponse>["trigger"];
9
8
  normalizeAutosaveData?: (data: Partial<TTransformedValues>) => Partial<TTransformedValues> | undefined;
10
- onAutosave: UseAutosaveProps<TFieldValues, TContext, TTransformedValues, TResponse>["onSave"];
11
- getResetValues: () => UseFormProps<TFieldValues, TContext, TTransformedValues>["defaultValues"];
9
+ onAutosave: UseAutosaveProps<TFieldValues, TTransformedValues, TResponse>["onSave"];
10
+ getResetValues: () => UseFormProps<TFieldValues, TTransformedValues>["defaultValues"];
12
11
  resetDeps: DependencyList;
13
12
  resetTimeout?: number;
14
13
  };
15
- export declare function useFormAutosave<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues = TFieldValues, TResponse = any>({ autosaveDelay, enableAutosave, autosaveOn, normalizeAutosaveData, onAutosave, getResetValues, resetDeps, resetTimeout, ...props }: UseFormAutosaveProps<TFieldValues, TContext, TTransformedValues, TResponse>): import('react-hook-form').UseFormReturn<TFieldValues, TContext, TTransformedValues>;
14
+ export declare function useFormAutosave<TFieldValues extends Record<string, unknown> = Record<string, unknown>, TContext = any, TTransformedValues = TFieldValues, TResponse = any>({ autosaveDelay, enableAutosave, autosaveOn, normalizeAutosaveData, onAutosave, getResetValues, resetDeps, resetTimeout, ...props }: UseFormAutosaveProps<TFieldValues, TContext, TTransformedValues, TResponse>): import('./useForm').UIForm<TFieldValues>;
@@ -26,15 +26,19 @@ function useFormAutosave({ autosaveDelay, enableAutosave, autosaveOn = "change",
26
26
  const resetValues = getResetValues();
27
27
  if (resetValues === void 0) return;
28
28
  const resetFormValues = async () => {
29
- const keepStateOptions = shouldResetFormValuesRef.current ? { keepDirtyValues: true } : void 0;
29
+ const keepCurrentValues = shouldResetFormValuesRef.current;
30
30
  shouldResetFormValuesRef.current = false;
31
- let values = resetValues;
31
+ let values;
32
32
  if (ObjectUtils.isFunction(resetValues)) values = await resetValues();
33
- form.reset(values, keepStateOptions);
33
+ else values = resetValues;
34
+ form.reset(keepCurrentValues ? {
35
+ ...values,
36
+ ...form.state.values
37
+ } : values);
34
38
  };
35
39
  resetFormValues();
36
40
  }, [...resetDeps]);
37
- const onSaveSuccess = () => {
41
+ const prepareForSaveReset = () => {
38
42
  shouldResetFormValuesRef.current = true;
39
43
  if (resetFormValuesTimeoutRef.current) clearTimeout(resetFormValuesTimeoutRef.current);
40
44
  resetFormValuesTimeoutRef.current = setTimeout(() => {
@@ -46,12 +50,22 @@ function useFormAutosave({ autosaveDelay, enableAutosave, autosaveOn = "change",
46
50
  delay: autosaveDelay,
47
51
  enabled: enableAutosave,
48
52
  trigger: autosaveOn,
49
- onSave: useCallback((data) => {
53
+ onSave: useCallback(async (data) => {
50
54
  const normalizedData = normalizeAutosaveData ? normalizeAutosaveData(data) : data;
51
- if (!normalizedData || ObjectUtils.isEmpty(normalizedData)) return Promise.resolve(void 0);
52
- return onAutosave(normalizedData);
53
- }, [normalizeAutosaveData, onAutosave]),
54
- onSaveSuccess
55
+ if (!normalizedData || ObjectUtils.isEmpty(normalizedData)) return;
56
+ prepareForSaveReset();
57
+ try {
58
+ return await onAutosave(normalizedData);
59
+ } catch (error) {
60
+ shouldResetFormValuesRef.current = false;
61
+ if (resetFormValuesTimeoutRef.current) clearTimeout(resetFormValuesTimeoutRef.current);
62
+ throw error;
63
+ }
64
+ }, [
65
+ normalizeAutosaveData,
66
+ onAutosave,
67
+ resetTimeout
68
+ ])
55
69
  });
56
70
  return form;
57
71
  }
package/dist/index.d.ts CHANGED
@@ -230,8 +230,8 @@ export { useDebounceCallback } from './hooks/useDebounceCallback';
230
230
  export { useDeepCompareEffect, useDeepCompareLayoutEffect, useDeepCompareMemo } from './hooks/useDeepCompare';
231
231
  export type { FilterStore } from './hooks/useFilters';
232
232
  export { useFilters } from './hooks/useFilters';
233
- export type { UseFormProps, UseFormResolverProps } from './hooks/useForm';
234
- export { useForm } from './hooks/useForm';
233
+ export type { DeepKeys, DeepValue, FormSubmitErrorHandler, FormSubmitHandler, UIForm, UseFormProps, } from './hooks/useForm';
234
+ export { useForm, useFormState, useFormValue } from './hooks/useForm';
235
235
  export type { UseFormAutosaveProps } from './hooks/useFormAutosave';
236
236
  export { useFormAutosave } from './hooks/useFormAutosave';
237
237
  export { useIntersectionObserver } from './hooks/useIntersectionObserver';
package/dist/index.js CHANGED
@@ -87,10 +87,10 @@ import { DateTimeUtils } from "./utils/date-time.utils.js";
87
87
  import { datePickerInputContentRowDefinition } from "./components/inputs/DateTime/shared/datePickerInput.cva.js";
88
88
  import { popoverDefinition } from "./components/shared/popover.cva.js";
89
89
  import { tooltipWrapperTriggerDefinition } from "./components/inputs/shared/tooltipWrapper.cva.js";
90
- import { useDebounceCallback } from "./hooks/useDebounceCallback.js";
91
90
  import { DatePicker } from "./components/inputs/DateTime/DatePicker/DatePicker.js";
92
91
  import { tagDefinition } from "./components/text/Tag/tag.cva.js";
93
92
  import { Tag } from "./components/text/Tag/Tag.js";
93
+ import { useDebounceCallback } from "./hooks/useDebounceCallback.js";
94
94
  import { selectInputTagsContentWrapperDefinition } from "./components/inputs/Selection/shared/selectInput.cva.js";
95
95
  import { createKeyInteractionsHandler, getKeyInteractionAction, useKeyInteractions } from "./hooks/useKeyInteractions.js";
96
96
  import { selectListBoxItemDefinition } from "./components/inputs/Selection/shared/selectItem.cva.js";
@@ -170,11 +170,11 @@ import { dynamicColumns } from "./helpers/dynamicColumns.js";
170
170
  import { useAutosave } from "./hooks/useAutosave.js";
171
171
  import { RoutingUtils } from "./utils/routing.utils.js";
172
172
  import { useFilters } from "./hooks/useFilters.js";
173
- import { useForm } from "./hooks/useForm.js";
173
+ import { useForm, useFormState, useFormValue } from "./hooks/useForm.js";
174
174
  import { useFormAutosave } from "./hooks/useFormAutosave.js";
175
175
  import { usePagination } from "./hooks/usePagination.js";
176
176
  import { useSorting } from "./hooks/useSorting.js";
177
177
  import { useTableColumnConfig } from "./hooks/useTableColumnConfig.js";
178
178
  import { ArrayUtils } from "./utils/array.utils.js";
179
179
  import { QueriesUtils } from "./utils/queries.utils.js";
180
- export { Accordion, ActionModal, Alert, AlignCenterIcon, AlignLeftIcon, AlignLeftRightIcon, AlignRightIcon, ArrayUtils, ArrowDropDownIcon, ArrowDropUpIcon, ArrowLeftIcon, ArrowRightIcon, Autocomplete, BoldIcon, BottomSheet, Breadcrumbs, BulletedListIcon, Button, CalendarIcon, CellText, CheckIcon, Checkbox, CheckboxCheckmarkIcon, CheckboxGroup, CheckboxIndeterminateIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsLeftIcon, ChevronsRightIcon, ClockIcon, CloseIcon, ColumnConfigModal, Confirmation, DatePicker, DateRangePicker, DateTimeIcon, DateTimePicker, DateTimeUtils, DateUtils, DomUtils, Drawer, FileUpload, FileUploadContainer, FileUtils, Form, FormField, HeaderText, HighlightIcon, HighlightOnIcon, HomeIcon, IconButton, InfiniteTable, InfoIcon, InlineIconButton, InputUpload, Inputs, IntlUtils, ItalicIcon, Link, LinkContext, LinkIcon, Loader, Menu, MenuIcon, MenuItem, MenuPopover, Modal, NumberInput, NumberRangeInput, NumberedListIcon, ObjectUtils, PaginatedTable, Pagination, PaginationList, PasswordInput, Pill, PillButton, PointerHorizontalIcon, PointerVerticalIcon, ProgressBar, QueriesUtils, QueryAutocomplete, QuerySelect, RadioGroup, ResponsivePopover, RestUtils, RoutingUtils, Segment, Select, SendIcon, Slider, SplitButton, Stepper, StrikethroughIcon, StringUtils, Table, Tag, TextArea, TextButton, TextColorIcon, TextInput, ThemeContext, TimePicker, Toast, ToastContainer, Toggle, ToggleButton, Tooltip, TooltipEllipsis, Typography, UIConfig, UIOverrides, UIRouter, UnderlinedIcon, VisibilityIcon, VisibilityOffIcon, ZodUtils, accordionChevronDefinition, accordionDefinition, accordionHeadingDefinition, accordionHeadingSubtitleDefinition, accordionHeadingTitleDefinition, accordionIconDefinition, accordionItemDefinition, accordionPanelContentDefinition, accordionPanelDefinition, accordionTriggerDefinition, alertDefinition, breadcrumbChevronDefinition, breadcrumbIconDefinition, breadcrumbItemDefinition, breadcrumbSegmentDefinition, breadcrumbsDefinition, buttonContentDefinition, buttonDefinition, buttonIconSizeDefinition, buttonSizeDefinition, checkboxContentRowDefinition, checkboxContentWrapperDefinition, checkboxDefinition, checkboxGroupLabelDefinition, checkboxIconDefinition, compoundMapper, createKeyInteractionsHandler, datePickerInputContentRowDefinition, dynamicColumns, dynamicInputs, fileUploadDropZoneDefinition, formFieldErrorDefinition, formFieldHeaderDefinition, formFieldHelperDefinition, getKeyInteractionAction, inputBaseDefinition, inputClearClassDefinition, inputContentWrapperDefinition, inputSideDefinition, inputSizeDefinition, inputUploadButtonDefinition, inputUploadDropZoneDefinition, isEqual, labelDefinition, linkDefinition, loaderDefinition, loaderWrapperDefinition, logger, menuDefinition, menuItemDefinition, menuPopoverDefinition, menuPopoverWrapperDefinition, modalContentDefinition, modalMainDefinition, modalOverlayDefinition, ns, pillButtonContentDefinition, pillButtonDefinition, popoverDefinition, progressBarDefinition, progressBarFillDefinition, progressBarTrackDefinition, progressBarTrackWrapperDefinition, progressBarValueDefinition, radioContentRowDefinition, radioContentWrapperDefinition, radioDefinition, resources, segmentDefinition, segmentItemDefinition, selectInputTagsContentWrapperDefinition, selectListBoxItemDefinition, selectPopoverDefinition, statusIconDefinition, statusSeparatorDefinition, stepperDefinition, stepperIconDefinition, stepperItemDefinition, stepperNumberDefinition, stepperSeparatorDefinition, stepperSubtextDefinition, stepperTitleDefinition, tableCellTextDefinition, tableDataDefinition, tableHeadDataDefinition, tableHeadRowDefinition, tableHeaderTextDefinition, tableRowDefinition, tagDefinition, textAreaWrapperDefinition, toastDefinition, statusIconDefinition$1 as toastStatusIconDefinition, statusSeparatorDefinition$1 as toastStatusSeparatorDefinition, toggleDefinition, tooltipDefinition, tooltipPointerHorizontalDefinition, tooltipPointerVerticalDefinition, tooltipTextDefinition, tooltipWrapperTriggerDefinition, typographyDefinition, uiOutlineClass, useAutosave, useBreakpoint, useDebounceCallback, useDeepCompareEffect, useDeepCompareLayoutEffect, useDeepCompareMemo, useFilters, useForm, useFormAutosave, useIntersectionObserver, useKeyInteractions, useLocalStorage, useLongPressRepeat, usePagination, useScrollableListBox, useSorting, useStateAndRef, useTableColumnConfig, useTableNav, useToast, useTranslationMemo };
180
+ export { Accordion, ActionModal, Alert, AlignCenterIcon, AlignLeftIcon, AlignLeftRightIcon, AlignRightIcon, ArrayUtils, ArrowDropDownIcon, ArrowDropUpIcon, ArrowLeftIcon, ArrowRightIcon, Autocomplete, BoldIcon, BottomSheet, Breadcrumbs, BulletedListIcon, Button, CalendarIcon, CellText, CheckIcon, Checkbox, CheckboxCheckmarkIcon, CheckboxGroup, CheckboxIndeterminateIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsLeftIcon, ChevronsRightIcon, ClockIcon, CloseIcon, ColumnConfigModal, Confirmation, DatePicker, DateRangePicker, DateTimeIcon, DateTimePicker, DateTimeUtils, DateUtils, DomUtils, Drawer, FileUpload, FileUploadContainer, FileUtils, Form, FormField, HeaderText, HighlightIcon, HighlightOnIcon, HomeIcon, IconButton, InfiniteTable, InfoIcon, InlineIconButton, InputUpload, Inputs, IntlUtils, ItalicIcon, Link, LinkContext, LinkIcon, Loader, Menu, MenuIcon, MenuItem, MenuPopover, Modal, NumberInput, NumberRangeInput, NumberedListIcon, ObjectUtils, PaginatedTable, Pagination, PaginationList, PasswordInput, Pill, PillButton, PointerHorizontalIcon, PointerVerticalIcon, ProgressBar, QueriesUtils, QueryAutocomplete, QuerySelect, RadioGroup, ResponsivePopover, RestUtils, RoutingUtils, Segment, Select, SendIcon, Slider, SplitButton, Stepper, StrikethroughIcon, StringUtils, Table, Tag, TextArea, TextButton, TextColorIcon, TextInput, ThemeContext, TimePicker, Toast, ToastContainer, Toggle, ToggleButton, Tooltip, TooltipEllipsis, Typography, UIConfig, UIOverrides, UIRouter, UnderlinedIcon, VisibilityIcon, VisibilityOffIcon, ZodUtils, accordionChevronDefinition, accordionDefinition, accordionHeadingDefinition, accordionHeadingSubtitleDefinition, accordionHeadingTitleDefinition, accordionIconDefinition, accordionItemDefinition, accordionPanelContentDefinition, accordionPanelDefinition, accordionTriggerDefinition, alertDefinition, breadcrumbChevronDefinition, breadcrumbIconDefinition, breadcrumbItemDefinition, breadcrumbSegmentDefinition, breadcrumbsDefinition, buttonContentDefinition, buttonDefinition, buttonIconSizeDefinition, buttonSizeDefinition, checkboxContentRowDefinition, checkboxContentWrapperDefinition, checkboxDefinition, checkboxGroupLabelDefinition, checkboxIconDefinition, compoundMapper, createKeyInteractionsHandler, datePickerInputContentRowDefinition, dynamicColumns, dynamicInputs, fileUploadDropZoneDefinition, formFieldErrorDefinition, formFieldHeaderDefinition, formFieldHelperDefinition, getKeyInteractionAction, inputBaseDefinition, inputClearClassDefinition, inputContentWrapperDefinition, inputSideDefinition, inputSizeDefinition, inputUploadButtonDefinition, inputUploadDropZoneDefinition, isEqual, labelDefinition, linkDefinition, loaderDefinition, loaderWrapperDefinition, logger, menuDefinition, menuItemDefinition, menuPopoverDefinition, menuPopoverWrapperDefinition, modalContentDefinition, modalMainDefinition, modalOverlayDefinition, ns, pillButtonContentDefinition, pillButtonDefinition, popoverDefinition, progressBarDefinition, progressBarFillDefinition, progressBarTrackDefinition, progressBarTrackWrapperDefinition, progressBarValueDefinition, radioContentRowDefinition, radioContentWrapperDefinition, radioDefinition, resources, segmentDefinition, segmentItemDefinition, selectInputTagsContentWrapperDefinition, selectListBoxItemDefinition, selectPopoverDefinition, statusIconDefinition, statusSeparatorDefinition, stepperDefinition, stepperIconDefinition, stepperItemDefinition, stepperNumberDefinition, stepperSeparatorDefinition, stepperSubtextDefinition, stepperTitleDefinition, tableCellTextDefinition, tableDataDefinition, tableHeadDataDefinition, tableHeadRowDefinition, tableHeaderTextDefinition, tableRowDefinition, tagDefinition, textAreaWrapperDefinition, toastDefinition, statusIconDefinition$1 as toastStatusIconDefinition, statusSeparatorDefinition$1 as toastStatusSeparatorDefinition, toggleDefinition, tooltipDefinition, tooltipPointerHorizontalDefinition, tooltipPointerVerticalDefinition, tooltipTextDefinition, tooltipWrapperTriggerDefinition, typographyDefinition, uiOutlineClass, useAutosave, useBreakpoint, useDebounceCallback, useDeepCompareEffect, useDeepCompareLayoutEffect, useDeepCompareMemo, useFilters, useForm, useFormAutosave, useFormState, useFormValue, useIntersectionObserver, useKeyInteractions, useLocalStorage, useLongPressRepeat, usePagination, useScrollableListBox, useSorting, useStateAndRef, useTableColumnConfig, useTableNav, useToast, useTranslationMemo };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@povio/ui",
3
- "version": "3.3.0",
3
+ "version": "3.4.0-rc.1",
4
4
  "type": "module",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -20,7 +20,6 @@
20
20
  "@dnd-kit/modifiers": "^9.0.0",
21
21
  "@dnd-kit/sortable": "^10.0.0",
22
22
  "@dnd-kit/utilities": "^3.2.2",
23
- "@hookform/resolvers": "^5.2.2",
24
23
  "@internationalized/date": "^3.11.0",
25
24
  "@react-aria/button": "^3.14.4",
26
25
  "@react-aria/calendar": "^3.9.4",
@@ -30,6 +29,7 @@
30
29
  "@react-stately/calendar": "^3.9.2",
31
30
  "@react-stately/datepicker": "^3.16.0",
32
31
  "@react-types/shared": "^3.33.0",
32
+ "@tanstack/react-form": "^1.33.2",
33
33
  "@tanstack/react-table": "^8.21.3",
34
34
  "axios": "^1.13.2",
35
35
  "class-variance-authority": "^0.7.1",
@@ -40,7 +40,6 @@
40
40
  "motion": "~12.23.24",
41
41
  "react-aria": "^3.46.0",
42
42
  "react-aria-components": "^1.15.1",
43
- "react-hook-form": "^7.65.0",
44
43
  "react-responsive": "^10.0.1",
45
44
  "react-stately": "^3.44.0",
46
45
  "react-toastify": "^11.0.5",
@@ -1 +0,0 @@
1
- export {};