@povio/ui 3.3.0-rc.4 → 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 (125) hide show
  1. package/README.md +15 -1
  2. package/dist/components/Breadcrumbs/Breadcrumbs.js +55 -206
  3. package/dist/components/buttons/InlineIconButton/InlineIconButton.js +9 -34
  4. package/dist/components/buttons/shared/ButtonContent.js +22 -80
  5. package/dist/components/inputs/Checkbox/Checkbox.d.ts +1 -2
  6. package/dist/components/inputs/Checkbox/Checkbox.js +93 -100
  7. package/dist/components/inputs/Checkbox/CheckboxCheckmark.js +10 -24
  8. package/dist/components/inputs/Checkbox/CheckboxGroup.d.ts +1 -2
  9. package/dist/components/inputs/Checkbox/CheckboxGroup.js +109 -113
  10. package/dist/components/inputs/DateTime/DatePicker/DatePicker.d.ts +1 -2
  11. package/dist/components/inputs/DateTime/DatePicker/DatePicker.js +97 -238
  12. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.d.ts +1 -2
  13. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +88 -214
  14. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.d.ts +1 -2
  15. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +64 -143
  16. package/dist/components/inputs/DateTime/TimePicker/TimePicker.d.ts +1 -2
  17. package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +275 -294
  18. package/dist/components/inputs/DateTime/shared/Calendar.js +139 -339
  19. package/dist/components/inputs/DateTime/shared/CalendarCell.js +114 -308
  20. package/dist/components/inputs/DateTime/shared/CalendarGrid.js +35 -150
  21. package/dist/components/inputs/DateTime/shared/CalendarHeader.js +95 -229
  22. package/dist/components/inputs/DateTime/shared/CalendarSelectHeader.js +115 -296
  23. package/dist/components/inputs/DateTime/shared/DateField.js +135 -306
  24. package/dist/components/inputs/DateTime/shared/DatePickerInput.d.ts +1 -2
  25. package/dist/components/inputs/DateTime/shared/DatePickerInput.js +136 -343
  26. package/dist/components/inputs/DateTime/shared/DateTimeDialogFooter.js +10 -59
  27. package/dist/components/inputs/DateTime/shared/TimePickerInput.d.ts +1 -2
  28. package/dist/components/inputs/DateTime/shared/TimePickerInput.js +43 -46
  29. package/dist/components/inputs/File/FileUpload.d.ts +1 -1
  30. package/dist/components/inputs/File/FileUpload.js +18 -18
  31. package/dist/components/inputs/File/InputUpload.d.ts +1 -1
  32. package/dist/components/inputs/File/InputUpload.js +82 -278
  33. package/dist/components/inputs/File/fileUpload.types.d.ts +1 -1
  34. package/dist/components/inputs/File/inputUpload.types.d.ts +1 -1
  35. package/dist/components/inputs/File/shared/FileUploadContentEmpty.js +48 -180
  36. package/dist/components/inputs/File/shared/FileUploadContentError.js +95 -265
  37. package/dist/components/inputs/File/shared/FileUploadContentFilled.js +99 -261
  38. package/dist/components/inputs/File/shared/FileUploadContentLoading.js +56 -234
  39. package/dist/components/inputs/File/shared/ProgressBar.js +15 -102
  40. package/dist/components/inputs/FormField/FormField.js +34 -47
  41. package/dist/components/inputs/Input/NumberInput/NumberInput.d.ts +1 -1
  42. package/dist/components/inputs/Input/NumberInput/NumberInput.js +19 -19
  43. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.d.ts +1 -1
  44. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.js +93 -331
  45. package/dist/components/inputs/Input/PasswordInput/PasswordInput.d.ts +1 -1
  46. package/dist/components/inputs/Input/TextArea/TextArea.d.ts +1 -1
  47. package/dist/components/inputs/Input/TextArea/TextArea.js +18 -18
  48. package/dist/components/inputs/Input/TextInput/TextInput.d.ts +2 -2
  49. package/dist/components/inputs/Input/TextInput/TextInput.js +36 -38
  50. package/dist/components/inputs/Inputs/Form.d.ts +4 -4
  51. package/dist/components/inputs/Inputs/InputItem.d.ts +22 -22
  52. package/dist/components/inputs/Inputs/InputItem.js +35 -36
  53. package/dist/components/inputs/Inputs/Inputs.d.ts +2 -2
  54. package/dist/components/inputs/RadioGroup/RadioGroup.d.ts +1 -2
  55. package/dist/components/inputs/RadioGroup/RadioGroup.js +107 -111
  56. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.d.ts +1 -1
  57. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +26 -86
  58. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.d.ts +1 -1
  59. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.js +19 -19
  60. package/dist/components/inputs/Selection/Autocomplete/queryAutocomplete.types.d.ts +1 -1
  61. package/dist/components/inputs/Selection/Select/QuerySelect.d.ts +1 -1
  62. package/dist/components/inputs/Selection/Select/QuerySelect.js +49 -115
  63. package/dist/components/inputs/Selection/Select/Select.d.ts +1 -1
  64. package/dist/components/inputs/Selection/Select/Select.js +22 -22
  65. package/dist/components/inputs/Selection/shared/SelectBase.d.ts +0 -1
  66. package/dist/components/inputs/Selection/shared/SelectBase.js +34 -37
  67. package/dist/components/inputs/Selection/shared/SelectInput.js +1 -0
  68. package/dist/components/inputs/Selection/shared/SelectListBox.js +51 -163
  69. package/dist/components/inputs/Selection/shared/select.context.d.ts +2 -2
  70. package/dist/components/inputs/Selection/shared/select.context.js +4 -8
  71. package/dist/components/inputs/Selection/shared/select.types.d.ts +1 -1
  72. package/dist/components/inputs/Selection/shared/useSelectItems.js +48 -108
  73. package/dist/components/inputs/Skeleton/InputFrame.js +177 -552
  74. package/dist/components/inputs/Slider/Slider.d.ts +1 -1
  75. package/dist/components/inputs/Slider/Slider.js +18 -18
  76. package/dist/components/inputs/TextEditor/TextEditor.d.ts +1 -1
  77. package/dist/components/inputs/TextEditor/TextEditor.js +105 -407
  78. package/dist/components/inputs/Toggle/Toggle.d.ts +1 -2
  79. package/dist/components/inputs/Toggle/Toggle.js +59 -63
  80. package/dist/components/inputs/shared/InputClear.js +24 -40
  81. package/dist/components/inputs/shared/form.binding.d.ts +27 -0
  82. package/dist/components/inputs/shared/form.binding.js +57 -0
  83. package/dist/components/inputs/shared/form.types.d.ts +9 -8
  84. package/dist/components/inputs/shared/form.types.js +8 -0
  85. package/dist/components/navigation/Accordion/Accordion.js +22 -69
  86. package/dist/components/navigation/Accordion/AccordionItem.js +41 -86
  87. package/dist/components/navigation/Stepper/Stepper.js +22 -67
  88. package/dist/components/overlays/ActionModal/ActionModal.js +35 -169
  89. package/dist/components/overlays/ResponsivePopover/ResponsivePopover.js +29 -110
  90. package/dist/components/segment/Segment.d.ts +1 -1
  91. package/dist/components/segment/Segment.js +17 -17
  92. package/dist/components/segment/segment.types.d.ts +1 -1
  93. package/dist/components/shared/pagination/Pagination.js +22 -108
  94. package/dist/components/status/Alert/Alert.js +30 -97
  95. package/dist/components/table/InfiniteTable.js +16 -67
  96. package/dist/components/table/Table.d.ts +2 -8
  97. package/dist/components/table/Table.js +33 -55
  98. package/dist/components/text/Typography/Typography.js +8 -23
  99. package/dist/config/confirmation.context.js +1 -1
  100. package/dist/config/theme.context.js +45 -98
  101. package/dist/config/uiConfig.context.d.ts +5 -5
  102. package/dist/config/uiConfig.context.js +11 -51
  103. package/dist/config/uiOverrides.context.d.ts +0 -1
  104. package/dist/helpers/dynamicColumns.d.ts +1 -1
  105. package/dist/helpers/dynamicInputs.d.ts +7 -7
  106. package/dist/hooks/useAutosave.d.ts +4 -4
  107. package/dist/hooks/useAutosave.js +64 -49
  108. package/dist/hooks/useDebounceCallback.js +17 -51
  109. package/dist/hooks/useForm.d.ts +39 -15
  110. package/dist/hooks/useForm.js +96 -43
  111. package/dist/hooks/useFormAutosave.d.ts +8 -9
  112. package/dist/hooks/useFormAutosave.js +49 -122
  113. package/dist/hooks/useLongPressRepeat.js +20 -55
  114. package/dist/index.d.ts +2 -3
  115. package/dist/index.js +3 -4
  116. package/package.json +3 -4
  117. package/dist/components/inputs/FormField/formField.cva.d.ts +0 -11
  118. package/dist/components/inputs/FormField/formField.cva.js +0 -16
  119. package/dist/components/table/TableColumnFilterInput.d.ts +0 -9
  120. package/dist/components/table/TableColumnFilterInput.js +0 -108
  121. package/dist/components/table/TableColumnFilterPlaceholder.d.ts +0 -5
  122. package/dist/components/table/TableColumnFilterPlaceholder.js +0 -41
  123. package/dist/components/table/TableColumnFilterRow.d.ts +0 -16
  124. package/dist/components/table/TableColumnFilterRow.js +0 -68
  125. package/dist/hooks/useAutosave.spec.d.ts +0 -1
@@ -24,7 +24,7 @@ var Confirmation;
24
24
  const [state, setState] = useState(DEFAULT_STATE);
25
25
  const { t } = useTranslation("ui");
26
26
  const onCancel = () => setState(DEFAULT_STATE);
27
- const confirm = useCallback(async ({ heading, description, buttonSize, textAlign, modalClassName, cancelLabel = t(($) => $.ui.confirmation.cancel), confirmLabel = t(($_0) => $_0.ui.confirmation.confirm), confirmVariant, confirmColor, cancelVariant, cancelColor }) => {
27
+ const confirm = useCallback(async ({ heading, description, buttonSize, textAlign, modalClassName, cancelLabel = t(($) => $.ui.confirmation.cancel), confirmLabel = t(($) => $.ui.confirmation.confirm), confirmVariant, confirmColor, cancelVariant, cancelColor }) => {
28
28
  return new Promise((resolve) => {
29
29
  setState({
30
30
  heading,
@@ -1,7 +1,6 @@
1
1
  import { useLocalStorage } from "../hooks/useLocalStorage.js";
2
- import { c } from "react/compiler-runtime";
3
2
  import { jsx } from "react/jsx-runtime";
4
- import { createContext, use, useEffect, useState } from "react";
3
+ import { createContext, use, useCallback, useEffect, useMemo, useState } from "react";
5
4
  import { z } from "zod";
6
5
  //#region src/config/theme.context.tsx
7
6
  var ThemeContext;
@@ -13,108 +12,56 @@ var ThemeContext;
13
12
  "system"
14
13
  ]);
15
14
  const ThemeContext = createContext(null);
16
- _ThemeContext.ThemeContextProvider = (t0) => {
17
- const $ = c(17);
18
- const { children, storageKey: t1 } = t0;
19
- const storageKey = t1 === void 0 ? DEFAULT_STORAGE_KEY : t1;
20
- const [systemTheme, setSystemTheme] = useState(_temp);
21
- let t2;
22
- if ($[0] !== storageKey) {
23
- t2 = {
24
- key: storageKey,
25
- schema: ThemeSchema
15
+ _ThemeContext.ThemeContextProvider = ({ children, storageKey = DEFAULT_STORAGE_KEY }) => {
16
+ const [systemTheme, setSystemTheme] = useState(() => {
17
+ if (typeof window === "undefined") return;
18
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
19
+ });
20
+ const { value: theme, set } = useLocalStorage({
21
+ key: storageKey,
22
+ schema: ThemeSchema
23
+ });
24
+ const updateTheme = useCallback((theme_0) => {
25
+ set(theme_0);
26
+ }, [set]);
27
+ useEffect(() => {
28
+ if (typeof window === "undefined") return;
29
+ const onChange = (event) => {
30
+ setSystemTheme(event.matches ? "dark" : "light");
26
31
  };
27
- $[0] = storageKey;
28
- $[1] = t2;
29
- } else t2 = $[1];
30
- const { value: theme, set } = useLocalStorage(t2);
31
- let t3;
32
- if ($[2] !== set) {
33
- t3 = (theme_0) => {
34
- set(theme_0);
32
+ const media_0 = window.matchMedia("(prefers-color-scheme: dark)");
33
+ media_0.addEventListener("change", onChange);
34
+ return () => {
35
+ media_0.removeEventListener("change", onChange);
35
36
  };
36
- $[2] = set;
37
- $[3] = t3;
38
- } else t3 = $[3];
39
- const updateTheme = t3;
40
- let t4;
41
- let t5;
42
- if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
43
- t4 = () => {
44
- if (typeof window === "undefined") return;
45
- const onChange = (event) => {
46
- setSystemTheme(event.matches ? "dark" : "light");
47
- };
48
- const media_0 = window.matchMedia("(prefers-color-scheme: dark)");
49
- media_0.addEventListener("change", onChange);
50
- return () => {
51
- media_0.removeEventListener("change", onChange);
52
- };
53
- };
54
- t5 = [];
55
- $[4] = t4;
56
- $[5] = t5;
57
- } else {
58
- t4 = $[4];
59
- t5 = $[5];
60
- }
61
- useEffect(t4, t5);
62
- let t6;
63
- let t7;
64
- if ($[6] !== systemTheme || $[7] !== theme) {
65
- t6 = () => {
66
- document.documentElement.classList.remove("dark");
67
- if ((!theme || theme === "system") && systemTheme === "dark" || theme === "dark") {
68
- document.documentElement.classList.add("dark");
69
- document.documentElement.style.colorScheme = "dark";
70
- } else if (theme === "light") {
71
- document.documentElement.classList.add("light");
72
- document.documentElement.style.colorScheme = "light";
73
- } else document.documentElement.style.colorScheme = "light";
74
- };
75
- t7 = [theme, systemTheme];
76
- $[6] = systemTheme;
77
- $[7] = theme;
78
- $[8] = t6;
79
- $[9] = t7;
80
- } else {
81
- t6 = $[8];
82
- t7 = $[9];
83
- }
84
- useEffect(t6, t7);
85
- const t8 = theme ?? "system";
86
- let t9;
87
- if ($[10] !== systemTheme || $[11] !== t8 || $[12] !== updateTheme) {
88
- t9 = {
89
- theme: t8,
90
- systemTheme,
91
- updateTheme
92
- };
93
- $[10] = systemTheme;
94
- $[11] = t8;
95
- $[12] = updateTheme;
96
- $[13] = t9;
97
- } else t9 = $[13];
98
- const contextValue = t9;
99
- let t10;
100
- if ($[14] !== children || $[15] !== contextValue) {
101
- t10 = /* @__PURE__ */ jsx(ThemeContext.Provider, {
102
- value: contextValue,
103
- children
104
- });
105
- $[14] = children;
106
- $[15] = contextValue;
107
- $[16] = t10;
108
- } else t10 = $[16];
109
- return t10;
37
+ }, []);
38
+ useEffect(() => {
39
+ document.documentElement.classList.remove("dark");
40
+ if ((!theme || theme === "system") && systemTheme === "dark" || theme === "dark") {
41
+ document.documentElement.classList.add("dark");
42
+ document.documentElement.style.colorScheme = "dark";
43
+ } else if (theme === "light") {
44
+ document.documentElement.classList.add("light");
45
+ document.documentElement.style.colorScheme = "light";
46
+ } else document.documentElement.style.colorScheme = "light";
47
+ }, [theme, systemTheme]);
48
+ const contextValue = useMemo(() => ({
49
+ theme: theme ?? "system",
50
+ systemTheme,
51
+ updateTheme
52
+ }), [
53
+ theme,
54
+ systemTheme,
55
+ updateTheme
56
+ ]);
57
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, {
58
+ value: contextValue,
59
+ children
60
+ });
110
61
  };
111
62
  _ThemeContext.useTheme = () => {
112
63
  return use(ThemeContext);
113
64
  };
114
65
  })(ThemeContext || (ThemeContext = {}));
115
- function _temp() {
116
- if (typeof window === "undefined") return;
117
- return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
118
- }
119
66
  //#endregion
120
67
  export { ThemeContext };
@@ -26,9 +26,9 @@ export declare namespace UIConfig {
26
26
  };
27
27
  button: Pick<ButtonProps, "variant" | "size">;
28
28
  numberInput: Pick<NumberInputProps, "formatOptions">;
29
- radioGroup: Pick<RadioGroupProps, "variant" | "hideLabel" | "fireBlurOnChange">;
30
- checkbox: Pick<CheckboxProps, "variant" | "fireBlurOnChange">;
31
- select: Pick<SelectBaseProps, "selectionMode" | "isSearchable" | "collapseAfter" | "selectedTagsType" | "hideSearchIcon" | "fireBlurOnChange" | "multiSelectAutoConfirm">;
29
+ radioGroup: Pick<RadioGroupProps, "variant" | "hideLabel">;
30
+ checkbox: Pick<CheckboxProps, "variant">;
31
+ select: Pick<SelectBaseProps, "selectionMode" | "isSearchable" | "collapseAfter" | "selectedTagsType" | "hideSearchIcon" | "multiSelectAutoConfirm">;
32
32
  queryAutocomplete: {
33
33
  isInitialQueryDisabled?: boolean;
34
34
  resolveSelectedItemsWithIds?: boolean;
@@ -39,9 +39,9 @@ export declare namespace UIConfig {
39
39
  resolveSelectedItemsWithIds?: boolean;
40
40
  searchDebounceDelay?: number;
41
41
  };
42
- toggle: Pick<ToggleProps, "variant" | "fireBlurOnChange">;
42
+ toggle: Pick<ToggleProps, "variant">;
43
43
  slider: Pick<SliderProps, "minValue" | "maxValue">;
44
- dateInput: Pick<DatePickerProps, "todayIcon" | "todayIconButtonSize" | "todayIconPlacement" | "shouldForceLeadingZeros" | "disableManualEntry" | "shouldUpdateDateOnMonthYearChange" | "granularity" | "autoFixYear" | "fireBlurOnChange"> & {
44
+ dateInput: Pick<DatePickerProps, "todayIcon" | "todayIconButtonSize" | "todayIconPlacement" | "shouldForceLeadingZeros" | "disableManualEntry" | "shouldUpdateDateOnMonthYearChange" | "granularity" | "autoFixYear"> & {
45
45
  calendarIcon?: ReactElement;
46
46
  dateTimeIcon?: ReactElement;
47
47
  timeIcon?: ReactElement;
@@ -3,7 +3,6 @@ import { ClockIcon } from "../assets/icons/Clock.js";
3
3
  import { DateTimeIcon } from "../assets/icons/DateTime.js";
4
4
  import { ObjectUtils } from "../utils/object.utils.js";
5
5
  import { useDeepCompareMemo } from "../hooks/useDeepCompare.js";
6
- import { c } from "react/compiler-runtime";
7
6
  import { jsx } from "react/jsx-runtime";
8
7
  import { createContext, use } from "react";
9
8
  //#region src/config/uiConfig.context.tsx
@@ -29,20 +28,15 @@ var UIConfig;
29
28
  } },
30
29
  radioGroup: {
31
30
  variant: "default",
32
- hideLabel: false,
33
- fireBlurOnChange: false
34
- },
35
- checkbox: {
36
- variant: "default",
37
- fireBlurOnChange: false
31
+ hideLabel: false
38
32
  },
33
+ checkbox: { variant: "default" },
39
34
  select: {
40
35
  selectionMode: "single",
41
36
  isSearchable: false,
42
37
  selectedTagsType: "list",
43
38
  collapseAfter: 3,
44
39
  hideSearchIcon: false,
45
- fireBlurOnChange: false,
46
40
  multiSelectAutoConfirm: false
47
41
  },
48
42
  queryAutocomplete: {
@@ -55,10 +49,7 @@ var UIConfig;
55
49
  resolveSelectedItemsWithIds: false,
56
50
  searchDebounceDelay: 500
57
51
  },
58
- toggle: {
59
- variant: "default",
60
- fireBlurOnChange: false
61
- },
52
+ toggle: { variant: "default" },
62
53
  slider: {
63
54
  minValue: 0,
64
55
  maxValue: 100
@@ -71,7 +62,6 @@ var UIConfig;
71
62
  shouldForceLeadingZeros: false,
72
63
  disableManualEntry: false,
73
64
  autoFixYear: false,
74
- fireBlurOnChange: false,
75
65
  calendarIcon: /* @__PURE__ */ jsx(CalendarIcon, { className: "size-5" }),
76
66
  dateTimeIcon: /* @__PURE__ */ jsx(DateTimeIcon, { className: "size-5" }),
77
67
  timeIcon: /* @__PURE__ */ jsx(ClockIcon, { className: "size-6 text-interactive-text-secondary-idle" }),
@@ -115,42 +105,15 @@ var UIConfig;
115
105
  }
116
106
  };
117
107
  const Context = createContext(DEFAULT_CONFIG);
118
- _UIConfig.Provider = (t0) => {
119
- const $ = c(9);
120
- const { config: t1, children } = t0;
121
- let t2;
122
- if ($[0] !== t1) {
123
- t2 = t1 === void 0 ? {} : t1;
124
- $[0] = t1;
125
- $[1] = t2;
126
- } else t2 = $[1];
127
- const config = t2;
108
+ _UIConfig.Provider = ({ config = {}, children }) => {
128
109
  const parentConfig = use(Context) || DEFAULT_CONFIG;
129
- let t3;
130
- let t4;
131
- if ($[2] !== config || $[3] !== parentConfig) {
132
- t3 = () => ObjectUtils.deepConditionalMerge(parentConfig, config, _temp);
133
- t4 = [config, parentConfig];
134
- $[2] = config;
135
- $[3] = parentConfig;
136
- $[4] = t3;
137
- $[5] = t4;
138
- } else {
139
- t3 = $[4];
140
- t4 = $[5];
141
- }
142
- const value = useDeepCompareMemo(t3, t4);
143
- let t5;
144
- if ($[6] !== children || $[7] !== value) {
145
- t5 = /* @__PURE__ */ jsx(Context.Provider, {
146
- value,
147
- children
148
- });
149
- $[6] = children;
150
- $[7] = value;
151
- $[8] = t5;
152
- } else t5 = $[8];
153
- return t5;
110
+ const value = useDeepCompareMemo(() => {
111
+ return ObjectUtils.deepConditionalMerge(parentConfig, config, (val) => val !== null && val !== void 0);
112
+ }, [config, parentConfig]);
113
+ return /* @__PURE__ */ jsx(Context.Provider, {
114
+ value,
115
+ children
116
+ });
154
117
  };
155
118
  _UIConfig.useConfig = () => {
156
119
  const context = use(Context);
@@ -158,8 +121,5 @@ var UIConfig;
158
121
  return context;
159
122
  };
160
123
  })(UIConfig || (UIConfig = {}));
161
- function _temp(val) {
162
- return val !== null && val !== void 0;
163
- }
164
124
  //#endregion
165
125
  export { UIConfig };
@@ -158,7 +158,6 @@ export declare namespace UIOverrides {
158
158
  cva?: GenericCvaOption;
159
159
  };
160
160
  formField: {
161
- cva?: GenericCvaOption;
162
161
  headerCva?: GenericCvaOption;
163
162
  errorLabelCva?: GenericCvaOption;
164
163
  helperLabelCva?: GenericCvaOption;
@@ -1,6 +1,6 @@
1
1
  import { CellContext, ColumnDef, ColumnMeta } from '@tanstack/react-table';
2
2
  import { ReactNode } from 'react';
3
- import { FieldPath } from 'react-hook-form';
3
+ import { FieldPath } from '../components/inputs/shared/form.binding';
4
4
  import { z } from 'zod';
5
5
  type NestedTypeFromKey<T, K extends string> = K extends keyof T ? T[K] : K extends `${infer First}.${infer Rest}` ? First extends keyof T ? NestedTypeFromKey<T[First], Rest> : never : never;
6
6
  type SchemaType<TSchema extends z.ZodObject<any>> = z.infer<TSchema>;
@@ -1,5 +1,5 @@
1
1
  import { ReactElement } from 'react';
2
- import { Control, UseFormReturn } from 'react-hook-form';
2
+ import { FormInstance } from '../components/inputs/shared/form.binding';
3
3
  import { z } from 'zod';
4
4
  import { InputComponentProps, InputComponentType, InputDef, InputDefBaseProps, InputWrapperType } from '../components/inputs/Inputs/InputItem';
5
5
  import { ZodUtils } from '../utils/zod.utils';
@@ -47,17 +47,17 @@ type UnknownInputDef<TSchema extends z.ZodObject<any>, K extends keyof z.infer<T
47
47
  } & DynamicInputDefBase<InputDefBaseProps<InputComponentProps<T>>>;
48
48
  }[DefaultComponentType<TSchema["shape"][K]>];
49
49
  type RenderInputDef<TSchema extends z.ZodObject<any>, K extends keyof z.infer<TSchema>> = {
50
- render: (formControl: {
51
- control: Control<z.infer<TSchema>>;
50
+ render: (field: {
51
+ form: FormInstance<z.infer<TSchema>>;
52
52
  name: K;
53
- }, form: UseFormReturn<z.infer<TSchema>>) => ReactElement;
53
+ }, form: FormInstance<z.infer<TSchema>>) => ReactElement;
54
54
  } & DynamicInputDefBase<Record<string, never>>;
55
55
  type DynamicInputDef<TSchema extends z.ZodObject<any>, K extends keyof z.infer<TSchema>> = ConfigInputDef<TSchema, K> | UnknownInputDef<TSchema, K> | RenderInputDef<TSchema, K>;
56
56
  type InputsConfig<TSchema extends z.ZodObject<any>> = {
57
- [K in keyof z.infer<TSchema>]?: DynamicInputDef<TSchema, K> | ((formControl: {
58
- control: Control<z.infer<TSchema>>;
57
+ [K in keyof z.infer<TSchema>]?: DynamicInputDef<TSchema, K> | ((field: {
58
+ form: FormInstance<z.infer<TSchema>>;
59
59
  name: K;
60
- }, form: UseFormReturn<z.infer<TSchema>>) => ReactElement) | boolean;
60
+ }, form: FormInstance<z.infer<TSchema>>) => ReactElement) | boolean;
61
61
  };
62
62
  type GlobalProps = {
63
63
  [T in Exclude<InputComponentType, "unknown">]: InputDefBaseProps<InputComponentProps<T>>;
@@ -1,10 +1,10 @@
1
- import { FieldValues, UseFormReturn } from 'react-hook-form';
2
- export interface UseAutosaveProps<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues = TFieldValues, TResponse = unknown> {
3
- form: UseFormReturn<TFieldValues, TContext, TTransformedValues>;
1
+ import { UIForm } from './useForm';
2
+ export interface UseAutosaveProps<TFieldValues extends Record<string, unknown>, TTransformedValues = TFieldValues, TResponse = unknown> {
3
+ form: UIForm<TFieldValues>;
4
4
  delay?: number;
5
5
  enabled?: boolean;
6
6
  trigger?: "change" | "blur";
7
7
  onSave: (data: Partial<TTransformedValues>) => Promise<TResponse>;
8
8
  onSaveSuccess?: () => void;
9
9
  }
10
- export declare function useAutosave<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues = TFieldValues, TResponse = unknown>({ form, delay, enabled, trigger, onSave, onSaveSuccess, }: UseAutosaveProps<TFieldValues, TContext, TTransformedValues, TResponse>): void;
10
+ export declare function useAutosave<TFieldValues extends Record<string, unknown>, TTransformedValues = TFieldValues, TResponse = unknown>({ form, delay, enabled, trigger, onSave, onSaveSuccess, }: UseAutosaveProps<TFieldValues, TTransformedValues, TResponse>): void;
@@ -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,59 +1,25 @@
1
- import { c } from "react/compiler-runtime";
2
- import { useEffect, useRef, useState } from "react";
1
+ import { useCallback, useEffect, useRef, useState } from "react";
3
2
  //#region src/hooks/useDebounceCallback.ts
4
- function useDebounceCallback(callback, t0) {
5
- const $ = c(10);
6
- let t1;
7
- if ($[0] !== t0) {
8
- t1 = t0 === void 0 ? {} : t0;
9
- $[0] = t0;
10
- $[1] = t1;
11
- } else t1 = $[1];
12
- const { delay: t2 } = t1;
13
- const delay = t2 === void 0 ? 500 : t2;
3
+ function useDebounceCallback(callback, { delay = 500 } = {}) {
14
4
  const timeoutRef = useRef(null);
15
5
  const [isDebouncing, setIsDebouncing] = useState(false);
16
- let t3;
17
- if ($[2] !== callback || $[3] !== delay) {
18
- t3 = (...t4) => {
19
- const args = t4;
6
+ const debouncedCallback = useCallback((...args) => {
7
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
8
+ setIsDebouncing(true);
9
+ timeoutRef.current = setTimeout(() => {
10
+ setIsDebouncing(false);
11
+ callback?.(...args);
12
+ }, delay);
13
+ }, [callback, delay]);
14
+ useEffect(() => {
15
+ return () => {
20
16
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
21
- setIsDebouncing(true);
22
- timeoutRef.current = setTimeout(() => {
23
- setIsDebouncing(false);
24
- callback?.(...args);
25
- }, delay);
26
17
  };
27
- $[2] = callback;
28
- $[3] = delay;
29
- $[4] = t3;
30
- } else t3 = $[4];
31
- const debouncedCallback = t3;
32
- let t4;
33
- let t5;
34
- if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
35
- t4 = () => () => {
36
- if (timeoutRef.current) clearTimeout(timeoutRef.current);
37
- };
38
- t5 = [];
39
- $[5] = t4;
40
- $[6] = t5;
41
- } else {
42
- t4 = $[5];
43
- t5 = $[6];
44
- }
45
- useEffect(t4, t5);
46
- let t6;
47
- if ($[7] !== debouncedCallback || $[8] !== isDebouncing) {
48
- t6 = {
49
- callback: debouncedCallback,
50
- isDebouncing
51
- };
52
- $[7] = debouncedCallback;
53
- $[8] = isDebouncing;
54
- $[9] = t6;
55
- } else t6 = $[9];
56
- return t6;
18
+ }, []);
19
+ return {
20
+ callback: debouncedCallback,
21
+ isDebouncing
22
+ };
57
23
  }
58
24
  //#endregion
59
25
  export { useDebounceCallback };
@@ -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 };