@mantine/form 9.0.0-alpha.5 → 9.0.0-alpha.7

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 (173) hide show
  1. package/cjs/FormProvider/FormProvider.cjs +26 -21
  2. package/cjs/FormProvider/FormProvider.cjs.map +1 -1
  3. package/cjs/_virtual/_rolldown/runtime.cjs +24 -0
  4. package/cjs/actions/actions.cjs +86 -117
  5. package/cjs/actions/actions.cjs.map +1 -1
  6. package/cjs/form-index.cjs +5 -5
  7. package/cjs/form-index.cjs.map +1 -1
  8. package/cjs/get-input-on-change/get-input-on-change.cjs +15 -25
  9. package/cjs/get-input-on-change/get-input-on-change.cjs.map +1 -1
  10. package/cjs/get-status/get-status.cjs +11 -11
  11. package/cjs/get-status/get-status.cjs.map +1 -1
  12. package/cjs/hooks/use-form-errors/filter-errors/filter-errors.cjs +11 -15
  13. package/cjs/hooks/use-form-errors/filter-errors/filter-errors.cjs.map +1 -1
  14. package/cjs/hooks/use-form-errors/use-form-errors.cjs +39 -48
  15. package/cjs/hooks/use-form-errors/use-form-errors.cjs.map +1 -1
  16. package/cjs/hooks/use-form-list/use-form-list.cjs +47 -51
  17. package/cjs/hooks/use-form-list/use-form-list.cjs.map +1 -1
  18. package/cjs/hooks/use-form-status/use-form-status.cjs +95 -128
  19. package/cjs/hooks/use-form-status/use-form-status.cjs.map +1 -1
  20. package/cjs/hooks/use-form-validating/use-form-validating.cjs +49 -51
  21. package/cjs/hooks/use-form-validating/use-form-validating.cjs.map +1 -1
  22. package/cjs/hooks/use-form-values/use-form-values.cjs +92 -107
  23. package/cjs/hooks/use-form-values/use-form-values.cjs.map +1 -1
  24. package/cjs/hooks/use-form-watch/use-form-watch.cjs +41 -57
  25. package/cjs/hooks/use-form-watch/use-form-watch.cjs.map +1 -1
  26. package/cjs/index.cjs +35 -38
  27. package/cjs/lists/change-error-indices.cjs +34 -41
  28. package/cjs/lists/change-error-indices.cjs.map +1 -1
  29. package/cjs/lists/clear-list-state.cjs +11 -15
  30. package/cjs/lists/clear-list-state.cjs.map +1 -1
  31. package/cjs/lists/reorder-errors.cjs +30 -32
  32. package/cjs/lists/reorder-errors.cjs.map +1 -1
  33. package/cjs/paths/get-data-path.cjs +6 -6
  34. package/cjs/paths/get-data-path.cjs.map +1 -1
  35. package/cjs/paths/get-path.cjs +14 -19
  36. package/cjs/paths/get-path.cjs.map +1 -1
  37. package/cjs/paths/get-splitted-path.cjs +7 -9
  38. package/cjs/paths/get-splitted-path.cjs.map +1 -1
  39. package/cjs/paths/insert-path.cjs +12 -15
  40. package/cjs/paths/insert-path.cjs.map +1 -1
  41. package/cjs/paths/remove-path.cjs +10 -17
  42. package/cjs/paths/remove-path.cjs.map +1 -1
  43. package/cjs/paths/reorder-path.cjs +14 -17
  44. package/cjs/paths/reorder-path.cjs.map +1 -1
  45. package/cjs/paths/replace-path.cjs +13 -18
  46. package/cjs/paths/replace-path.cjs.map +1 -1
  47. package/cjs/paths/set-path.cjs +22 -26
  48. package/cjs/paths/set-path.cjs.map +1 -1
  49. package/cjs/schema-resolver.cjs +24 -0
  50. package/cjs/schema-resolver.cjs.map +1 -0
  51. package/cjs/use-field.cjs +94 -131
  52. package/cjs/use-field.cjs.map +1 -1
  53. package/cjs/use-form.cjs +316 -379
  54. package/cjs/use-form.cjs.map +1 -1
  55. package/cjs/validate/get-rule-for-path.cjs +16 -24
  56. package/cjs/validate/get-rule-for-path.cjs.map +1 -1
  57. package/cjs/validate/should-validate-on-change.cjs +10 -17
  58. package/cjs/validate/should-validate-on-change.cjs.map +1 -1
  59. package/cjs/validate/validate-field-value.cjs +58 -54
  60. package/cjs/validate/validate-field-value.cjs.map +1 -1
  61. package/cjs/validate/validate-values.cjs +77 -108
  62. package/cjs/validate/validate-values.cjs.map +1 -1
  63. package/cjs/validators/has-length/has-length.cjs +17 -27
  64. package/cjs/validators/has-length/has-length.cjs.map +1 -1
  65. package/cjs/validators/is-email/is-email.cjs +7 -8
  66. package/cjs/validators/is-email/is-email.cjs.map +1 -1
  67. package/cjs/validators/is-in-range/is-in-range.cjs +13 -19
  68. package/cjs/validators/is-in-range/is-in-range.cjs.map +1 -1
  69. package/cjs/validators/is-json-string/is-json-string.cjs +15 -17
  70. package/cjs/validators/is-json-string/is-json-string.cjs.map +1 -1
  71. package/cjs/validators/is-not-empty/is-not-empty.cjs +13 -21
  72. package/cjs/validators/is-not-empty/is-not-empty.cjs.map +1 -1
  73. package/cjs/validators/is-not-empty-html/is-not-empty-html.cjs +11 -13
  74. package/cjs/validators/is-not-empty-html/is-not-empty-html.cjs.map +1 -1
  75. package/cjs/validators/is-one-of/is-one-of.cjs +9 -9
  76. package/cjs/validators/is-one-of/is-one-of.cjs.map +1 -1
  77. package/cjs/validators/is-url/is-url.cjs +25 -33
  78. package/cjs/validators/is-url/is-url.cjs.map +1 -1
  79. package/cjs/validators/matches/matches.cjs +10 -12
  80. package/cjs/validators/matches/matches.cjs.map +1 -1
  81. package/cjs/validators/matches-field/matches-field.cjs +10 -12
  82. package/cjs/validators/matches-field/matches-field.cjs.map +1 -1
  83. package/esm/FormProvider/FormProvider.mjs +25 -19
  84. package/esm/FormProvider/FormProvider.mjs.map +1 -1
  85. package/esm/actions/actions.mjs +85 -114
  86. package/esm/actions/actions.mjs.map +1 -1
  87. package/esm/form-index.mjs +5 -3
  88. package/esm/form-index.mjs.map +1 -1
  89. package/esm/get-input-on-change/get-input-on-change.mjs +15 -23
  90. package/esm/get-input-on-change/get-input-on-change.mjs.map +1 -1
  91. package/esm/get-status/get-status.mjs +11 -9
  92. package/esm/get-status/get-status.mjs.map +1 -1
  93. package/esm/hooks/use-form-errors/filter-errors/filter-errors.mjs +11 -13
  94. package/esm/hooks/use-form-errors/filter-errors/filter-errors.mjs.map +1 -1
  95. package/esm/hooks/use-form-errors/use-form-errors.mjs +38 -46
  96. package/esm/hooks/use-form-errors/use-form-errors.mjs.map +1 -1
  97. package/esm/hooks/use-form-list/use-form-list.mjs +46 -49
  98. package/esm/hooks/use-form-list/use-form-list.mjs.map +1 -1
  99. package/esm/hooks/use-form-status/use-form-status.mjs +93 -122
  100. package/esm/hooks/use-form-status/use-form-status.mjs.map +1 -1
  101. package/esm/hooks/use-form-validating/use-form-validating.mjs +48 -49
  102. package/esm/hooks/use-form-validating/use-form-validating.mjs.map +1 -1
  103. package/esm/hooks/use-form-values/use-form-values.mjs +91 -105
  104. package/esm/hooks/use-form-values/use-form-values.mjs.map +1 -1
  105. package/esm/hooks/use-form-watch/use-form-watch.mjs +40 -55
  106. package/esm/hooks/use-form-watch/use-form-watch.mjs.map +1 -1
  107. package/esm/index.mjs +18 -17
  108. package/esm/lists/change-error-indices.mjs +34 -39
  109. package/esm/lists/change-error-indices.mjs.map +1 -1
  110. package/esm/lists/clear-list-state.mjs +11 -13
  111. package/esm/lists/clear-list-state.mjs.map +1 -1
  112. package/esm/lists/reorder-errors.mjs +30 -30
  113. package/esm/lists/reorder-errors.mjs.map +1 -1
  114. package/esm/paths/get-data-path.mjs +6 -4
  115. package/esm/paths/get-data-path.mjs.map +1 -1
  116. package/esm/paths/get-path.mjs +14 -17
  117. package/esm/paths/get-path.mjs.map +1 -1
  118. package/esm/paths/get-splitted-path.mjs +7 -7
  119. package/esm/paths/get-splitted-path.mjs.map +1 -1
  120. package/esm/paths/insert-path.mjs +12 -13
  121. package/esm/paths/insert-path.mjs.map +1 -1
  122. package/esm/paths/remove-path.mjs +10 -15
  123. package/esm/paths/remove-path.mjs.map +1 -1
  124. package/esm/paths/reorder-path.mjs +14 -15
  125. package/esm/paths/reorder-path.mjs.map +1 -1
  126. package/esm/paths/replace-path.mjs +13 -16
  127. package/esm/paths/replace-path.mjs.map +1 -1
  128. package/esm/paths/set-path.mjs +21 -24
  129. package/esm/paths/set-path.mjs.map +1 -1
  130. package/esm/schema-resolver.mjs +24 -0
  131. package/esm/schema-resolver.mjs.map +1 -0
  132. package/esm/use-field.mjs +93 -129
  133. package/esm/use-field.mjs.map +1 -1
  134. package/esm/use-form.mjs +315 -377
  135. package/esm/use-form.mjs.map +1 -1
  136. package/esm/validate/get-rule-for-path.mjs +16 -22
  137. package/esm/validate/get-rule-for-path.mjs.map +1 -1
  138. package/esm/validate/should-validate-on-change.mjs +10 -15
  139. package/esm/validate/should-validate-on-change.mjs.map +1 -1
  140. package/esm/validate/validate-field-value.mjs +58 -52
  141. package/esm/validate/validate-field-value.mjs.map +1 -1
  142. package/esm/validate/validate-values.mjs +77 -106
  143. package/esm/validate/validate-values.mjs.map +1 -1
  144. package/esm/validators/has-length/has-length.mjs +17 -25
  145. package/esm/validators/has-length/has-length.mjs.map +1 -1
  146. package/esm/validators/is-email/is-email.mjs +7 -6
  147. package/esm/validators/is-email/is-email.mjs.map +1 -1
  148. package/esm/validators/is-in-range/is-in-range.mjs +13 -17
  149. package/esm/validators/is-in-range/is-in-range.mjs.map +1 -1
  150. package/esm/validators/is-json-string/is-json-string.mjs +15 -15
  151. package/esm/validators/is-json-string/is-json-string.mjs.map +1 -1
  152. package/esm/validators/is-not-empty/is-not-empty.mjs +13 -19
  153. package/esm/validators/is-not-empty/is-not-empty.mjs.map +1 -1
  154. package/esm/validators/is-not-empty-html/is-not-empty-html.mjs +11 -11
  155. package/esm/validators/is-not-empty-html/is-not-empty-html.mjs.map +1 -1
  156. package/esm/validators/is-one-of/is-one-of.mjs +9 -7
  157. package/esm/validators/is-one-of/is-one-of.mjs.map +1 -1
  158. package/esm/validators/is-url/is-url.mjs +25 -31
  159. package/esm/validators/is-url/is-url.mjs.map +1 -1
  160. package/esm/validators/matches/matches.mjs +10 -10
  161. package/esm/validators/matches/matches.mjs.map +1 -1
  162. package/esm/validators/matches-field/matches-field.mjs +10 -10
  163. package/esm/validators/matches-field/matches-field.mjs.map +1 -1
  164. package/lib/hooks/use-form-status/use-form-status.d.ts +2 -2
  165. package/lib/hooks/use-form-values/use-form-values.d.ts +9 -9
  166. package/lib/hooks/use-form-watch/use-form-watch.d.ts +5 -5
  167. package/lib/index.d.mts +1 -0
  168. package/lib/index.d.ts +1 -0
  169. package/lib/schema-resolver.d.ts +5 -0
  170. package/lib/types.d.ts +19 -18
  171. package/package.json +5 -1
  172. package/cjs/index.cjs.map +0 -1
  173. package/esm/index.mjs.map +0 -1
package/cjs/use-form.cjs CHANGED
@@ -1,381 +1,318 @@
1
- 'use client';
2
- 'use strict';
3
-
4
- var react = require('react');
5
- var actions = require('./actions/actions.cjs');
6
- var getInputOnChange = require('./get-input-on-change/get-input-on-change.cjs');
7
- var useFormErrors = require('./hooks/use-form-errors/use-form-errors.cjs');
8
- var useFormList = require('./hooks/use-form-list/use-form-list.cjs');
9
- var useFormStatus = require('./hooks/use-form-status/use-form-status.cjs');
10
- var useFormValidating = require('./hooks/use-form-validating/use-form-validating.cjs');
11
- var useFormValues = require('./hooks/use-form-values/use-form-values.cjs');
12
- var useFormWatch = require('./hooks/use-form-watch/use-form-watch.cjs');
13
- var getPath = require('./paths/get-path.cjs');
14
- require('klona/full');
15
- var getDataPath = require('./paths/get-data-path.cjs');
16
- var validateValues = require('./validate/validate-values.cjs');
17
- var validateFieldValue = require('./validate/validate-field-value.cjs');
18
- var shouldValidateOnChange = require('./validate/should-validate-on-change.cjs');
19
-
20
- function useForm({
21
- name,
22
- mode = "controlled",
23
- initialValues,
24
- initialErrors = {},
25
- initialDirty = {},
26
- initialTouched = {},
27
- clearInputErrorOnChange = true,
28
- validateInputOnChange = false,
29
- validateInputOnBlur = false,
30
- onValuesChange,
31
- transformValues = ((values) => values),
32
- enhanceGetInputProps,
33
- validate: rules,
34
- onSubmitPreventDefault = "always",
35
- touchTrigger = "change",
36
- cascadeUpdates = false,
37
- validateDebounce = 0,
38
- resolveValidationError = (err) => err instanceof Error ? err.message : String(err)
39
- } = {}) {
40
- const $errors = useFormErrors.useFormErrors(initialErrors);
41
- const $values = useFormValues.useFormValues({ initialValues, onValuesChange, mode });
42
- const $status = useFormStatus.useFormStatus({ initialDirty, initialTouched, $values, mode });
43
- const $list = useFormList.useFormList({ $values, $errors, $status });
44
- const $watch = useFormWatch.useFormWatch({ $status, cascadeUpdates });
45
- const $validating = useFormValidating.useFormValidating();
46
- const [formKey, setFormKey] = react.useState(0);
47
- const [fieldKeys, setFieldKeys] = react.useState({});
48
- const [submitting, setSubmitting] = react.useState(false);
49
- const validateGeneration = react.useRef(0);
50
- const reset = react.useCallback(() => {
51
- $values.resetValues();
52
- $errors.clearErrors();
53
- $status.resetDirty();
54
- $status.resetTouched();
55
- $validating.clearValidating();
56
- mode === "uncontrolled" && setFormKey((key2) => key2 + 1);
57
- }, []);
58
- const handleValuesChanges = react.useCallback(
59
- (previousValues) => {
60
- clearInputErrorOnChange && $errors.clearErrors();
61
- mode === "uncontrolled" && setFormKey((key2) => key2 + 1);
62
- Object.keys($watch.subscribers.current).forEach((path) => {
63
- const value = getPath.getPath(path, $values.refValues.current);
64
- const previousValue = getPath.getPath(path, previousValues);
65
- if (value !== previousValue) {
66
- $watch.getFieldSubscribers(path).forEach((cb) => cb({ previousValues, updatedValues: $values.refValues.current }));
67
- }
68
- });
69
- },
70
- [clearInputErrorOnChange]
71
- );
72
- const initialize = react.useCallback(
73
- (values) => {
74
- const previousValues = $values.refValues.current;
75
- $values.initialize(values, () => mode === "uncontrolled" && setFormKey((key2) => key2 + 1));
76
- handleValuesChanges(previousValues);
77
- },
78
- [handleValuesChanges]
79
- );
80
- const debouncedValidateField = react.useMemo(() => {
81
- const timers = {};
82
- const handleValidation = (path) => {
83
- const signal = $validating.getAbortSignal(path);
84
- const result = validateFieldValue.validateFieldValue(
85
- path,
86
- rules,
87
- $values.refValues.current,
88
- resolveValidationError,
89
- signal
90
- );
91
- const applyResult = (results) => {
92
- if (signal.aborted) {
93
- return;
94
- }
95
- if (results.hasError) {
96
- $errors.setFieldError(path, results.error);
97
- } else {
98
- $errors.clearFieldError(path);
99
- }
100
- };
101
- const cleanup = () => {
102
- if (!signal.aborted) {
103
- $validating.setFieldValidating(path, false);
104
- }
105
- };
106
- if (result instanceof Promise) {
107
- $validating.setFieldValidating(path, true);
108
- result.then(applyResult).finally(cleanup);
109
- } else {
110
- applyResult(result);
111
- }
112
- };
113
- return (path) => {
114
- clearTimeout(timers[path]);
115
- if (validateDebounce > 0) {
116
- timers[path] = setTimeout(() => handleValidation(path), validateDebounce);
117
- } else {
118
- handleValidation(path);
119
- }
120
- };
121
- }, [validateDebounce, rules, resolveValidationError]);
122
- const setFieldValue = react.useCallback(
123
- (path, value, options) => {
124
- const shouldValidate = shouldValidateOnChange.shouldValidateOnChange(path, validateInputOnChange);
125
- const resolvedValue = value instanceof Function ? value(getPath.getPath(path, $values.refValues.current)) : value;
126
- $status.setCalculatedFieldDirty(path, resolvedValue);
127
- touchTrigger === "change" && $status.setFieldTouched(path, true);
128
- !shouldValidate && clearInputErrorOnChange && $errors.clearFieldError(path);
129
- $values.setFieldValue({
130
- path,
131
- value,
132
- updateState: mode === "controlled",
133
- subscribers: [
134
- ...$watch.getFieldSubscribers(path),
135
- shouldValidate ? () => debouncedValidateField(String(path)) : null,
136
- options?.forceUpdate !== false && mode !== "controlled" ? () => setFieldKeys((keys) => ({
137
- ...keys,
138
- [path]: (keys[path] || 0) + 1
139
- })) : null
140
- ]
141
- });
142
- },
143
- [onValuesChange, rules, debouncedValidateField]
144
- );
145
- const setValues = react.useCallback(
146
- (values) => {
147
- const previousValues = $values.refValues.current;
148
- $values.setValues({ values, updateState: mode === "controlled" });
149
- handleValuesChanges(previousValues);
150
- },
151
- [onValuesChange, handleValuesChanges]
152
- );
153
- const validate = react.useCallback(() => {
154
- const generation = ++validateGeneration.current;
155
- const signal = $validating.getAbortSignal("__form__");
156
- const handleResult = (results) => {
157
- if (generation !== validateGeneration.current) {
158
- return { hasErrors: false, errors: {} };
159
- }
160
- $errors.setErrors(results.errors);
161
- return results;
162
- };
163
- const cleanup = () => {
164
- if (generation === validateGeneration.current) {
165
- $validating.setFormValidating(false);
166
- }
167
- };
168
- const result = validateValues.validateValues(rules, $values.refValues.current, resolveValidationError, signal);
169
- if (result instanceof Promise) {
170
- $validating.setFormValidating(true);
171
- return result.then(handleResult).finally(cleanup);
172
- }
173
- return handleResult(result);
174
- }, [rules, resolveValidationError]);
175
- const validateField = react.useCallback(
176
- (path) => {
177
- const signal = $validating.getAbortSignal(String(path));
178
- const applyResult = (results) => {
179
- if (signal.aborted) {
180
- return { hasError: false, error: null };
181
- }
182
- if (results.hasError) {
183
- $errors.setFieldError(path, results.error);
184
- } else {
185
- $errors.clearFieldError(path);
186
- }
187
- return results;
188
- };
189
- const cleanup = () => {
190
- if (!signal.aborted) {
191
- $validating.setFieldValidating(String(path), false);
192
- }
193
- };
194
- const result = validateFieldValue.validateFieldValue(
195
- path,
196
- rules,
197
- $values.refValues.current,
198
- resolveValidationError,
199
- signal
200
- );
201
- if (result instanceof Promise) {
202
- $validating.setFieldValidating(String(path), true);
203
- return result.then(applyResult).finally(cleanup);
204
- }
205
- return applyResult(result);
206
- },
207
- [rules, resolveValidationError]
208
- );
209
- const getInputProps = (path, { type = "input", withError = true, withFocus, ...otherOptions } = {}) => {
210
- const _withFocus = withFocus ?? type !== "radio";
211
- const onChange = getInputOnChange.getInputOnChange(
212
- (value) => setFieldValue(path, value, { forceUpdate: false })
213
- );
214
- const payload = { onChange, "data-path": getDataPath.getDataPath(name, path) };
215
- if (withError) {
216
- payload.error = $errors.errorsState[path];
217
- }
218
- if (type === "checkbox") {
219
- payload[mode === "controlled" ? "checked" : "defaultChecked"] = getPath.getPath(
220
- path,
221
- $values.refValues.current
222
- );
223
- } else if (type === "radio") {
224
- payload[mode === "controlled" ? "checked" : "defaultChecked"] = getPath.getPath(path, $values.refValues.current) === otherOptions.value;
225
- payload.value = otherOptions.value;
226
- } else {
227
- payload[mode === "controlled" ? "value" : "defaultValue"] = getPath.getPath(
228
- path,
229
- $values.refValues.current
230
- );
231
- }
232
- if (_withFocus) {
233
- payload.onFocus = () => $status.setFieldTouched(path, true);
234
- payload.onBlur = () => {
235
- if (shouldValidateOnChange.shouldValidateOnChange(path, validateInputOnBlur)) {
236
- debouncedValidateField(String(path));
237
- }
238
- };
239
- }
240
- return Object.assign(
241
- payload,
242
- enhanceGetInputProps?.({
243
- inputProps: payload,
244
- field: path,
245
- options: { type, withError, withFocus: _withFocus, ...otherOptions },
246
- form
247
- })
248
- );
249
- };
250
- const onSubmit = (handleSubmit, handleValidationFailure) => (event) => {
251
- if (onSubmitPreventDefault === "always") {
252
- event?.preventDefault();
253
- }
254
- setSubmitting(true);
255
- const handleValidation = (results) => {
256
- if (results.hasErrors) {
257
- if (onSubmitPreventDefault === "validation-failed") {
258
- event?.preventDefault();
259
- }
260
- handleValidationFailure?.(results.errors, $values.refValues.current, event);
261
- setSubmitting(false);
262
- } else {
263
- const submitResult = handleSubmit?.(
264
- transformValues($values.refValues.current),
265
- event
266
- );
267
- if (submitResult instanceof Promise) {
268
- submitResult.finally(() => setSubmitting(false));
269
- } else {
270
- setSubmitting(false);
271
- }
272
- }
273
- };
274
- const result = validate();
275
- if (result instanceof Promise) {
276
- result.then(handleValidation).catch(() => {
277
- setSubmitting(false);
278
- });
279
- } else {
280
- handleValidation(result);
281
- }
282
- };
283
- const getTransformedValues = (input) => transformValues(input || $values.refValues.current);
284
- const onReset = react.useCallback((event) => {
285
- event.preventDefault();
286
- reset();
287
- }, []);
288
- const isValid = react.useCallback(
289
- (path) => {
290
- const signal = new AbortController().signal;
291
- if (path) {
292
- const result2 = validateFieldValue.validateFieldValue(
293
- path,
294
- rules,
295
- $values.refValues.current,
296
- resolveValidationError,
297
- signal
298
- );
299
- if (result2 instanceof Promise) {
300
- return result2.then((r) => !r.hasError);
301
- }
302
- return !result2.hasError;
303
- }
304
- const result = validateValues.validateValues(
305
- rules,
306
- $values.refValues.current,
307
- resolveValidationError,
308
- signal
309
- );
310
- if (result instanceof Promise) {
311
- return result.then((r) => !r.hasErrors);
312
- }
313
- return !result.hasErrors;
314
- },
315
- [rules, resolveValidationError]
316
- );
317
- const key = (path) => `${formKey}-${String(path)}-${fieldKeys[String(path)] || 0}`;
318
- const getInputNode = react.useCallback(
319
- (path) => document.querySelector(`[data-path="${getDataPath.getDataPath(name, path)}"]`),
320
- []
321
- );
322
- const resetField = react.useCallback(
323
- (path) => {
324
- $values.resetField(path, [
325
- mode !== "controlled" ? () => setFieldKeys((keys) => ({
326
- ...keys,
327
- [path]: (keys[path] || 0) + 1
328
- })) : null
329
- ]);
330
- },
331
- [$values.resetField, mode, setFieldKeys]
332
- );
333
- const form = {
334
- watch: $watch.watch,
335
- initialized: $values.initialized.current,
336
- values: mode === "uncontrolled" ? $values.refValues.current : $values.stateValues,
337
- getValues: $values.getValues,
338
- getInitialValues: $values.getValuesSnapshot,
339
- setInitialValues: $values.setValuesSnapshot,
340
- resetField,
341
- initialize,
342
- setValues,
343
- setFieldValue,
344
- submitting,
345
- setSubmitting,
346
- validating: $validating.validating,
347
- isValidating: $validating.isValidating,
348
- errors: $errors.errorsState,
349
- setErrors: $errors.setErrors,
350
- setFieldError: $errors.setFieldError,
351
- clearFieldError: $errors.clearFieldError,
352
- clearErrors: $errors.clearErrors,
353
- resetDirty: $status.resetDirty,
354
- setTouched: $status.setTouched,
355
- setDirty: $status.setDirty,
356
- isTouched: $status.isTouched,
357
- resetTouched: $status.resetTouched,
358
- isDirty: $status.isDirty,
359
- getTouched: $status.getTouched,
360
- getDirty: $status.getDirty,
361
- reorderListItem: $list.reorderListItem,
362
- insertListItem: $list.insertListItem,
363
- removeListItem: $list.removeListItem,
364
- replaceListItem: $list.replaceListItem,
365
- reset,
366
- validate,
367
- validateField,
368
- getInputProps,
369
- onSubmit,
370
- onReset,
371
- isValid,
372
- getTransformedValues,
373
- key,
374
- getInputNode
375
- };
376
- actions.useFormActions(name, form);
377
- return form;
1
+ "use client";
2
+ require("./_virtual/_rolldown/runtime.cjs");
3
+ const require_actions = require("./actions/actions.cjs");
4
+ const require_get_input_on_change = require("./get-input-on-change/get-input-on-change.cjs");
5
+ const require_use_form_errors = require("./hooks/use-form-errors/use-form-errors.cjs");
6
+ const require_get_path = require("./paths/get-path.cjs");
7
+ const require_get_data_path = require("./paths/get-data-path.cjs");
8
+ const require_use_form_list = require("./hooks/use-form-list/use-form-list.cjs");
9
+ const require_use_form_status = require("./hooks/use-form-status/use-form-status.cjs");
10
+ const require_use_form_validating = require("./hooks/use-form-validating/use-form-validating.cjs");
11
+ const require_use_form_values = require("./hooks/use-form-values/use-form-values.cjs");
12
+ const require_use_form_watch = require("./hooks/use-form-watch/use-form-watch.cjs");
13
+ const require_validate_values = require("./validate/validate-values.cjs");
14
+ const require_validate_field_value = require("./validate/validate-field-value.cjs");
15
+ const require_should_validate_on_change = require("./validate/should-validate-on-change.cjs");
16
+ let react = require("react");
17
+ //#region packages/@mantine/form/src/use-form.ts
18
+ function useForm({ name, mode = "controlled", initialValues, initialErrors = {}, initialDirty = {}, initialTouched = {}, clearInputErrorOnChange = true, validateInputOnChange = false, validateInputOnBlur = false, onValuesChange, transformValues = ((values) => values), enhanceGetInputProps, validate: rules, onSubmitPreventDefault = "always", touchTrigger = "change", cascadeUpdates = false, validateDebounce = 0, resolveValidationError = (err) => err instanceof Error ? err.message : String(err) } = {}) {
19
+ const $errors = require_use_form_errors.useFormErrors(initialErrors);
20
+ const $values = require_use_form_values.useFormValues({
21
+ initialValues,
22
+ onValuesChange,
23
+ mode
24
+ });
25
+ const $status = require_use_form_status.useFormStatus({
26
+ initialDirty,
27
+ initialTouched,
28
+ $values,
29
+ mode
30
+ });
31
+ const $list = require_use_form_list.useFormList({
32
+ $values,
33
+ $errors,
34
+ $status
35
+ });
36
+ const $watch = require_use_form_watch.useFormWatch({
37
+ $status,
38
+ cascadeUpdates
39
+ });
40
+ const $validating = require_use_form_validating.useFormValidating();
41
+ const [formKey, setFormKey] = (0, react.useState)(0);
42
+ const [fieldKeys, setFieldKeys] = (0, react.useState)({});
43
+ const [submitting, setSubmitting] = (0, react.useState)(false);
44
+ const validateGeneration = (0, react.useRef)(0);
45
+ const reset = (0, react.useCallback)(() => {
46
+ $values.resetValues();
47
+ $errors.clearErrors();
48
+ $status.resetDirty();
49
+ $status.resetTouched();
50
+ $validating.clearValidating();
51
+ mode === "uncontrolled" && setFormKey((key) => key + 1);
52
+ }, []);
53
+ const notifyWatchSubscribers = (0, react.useCallback)((previousValues) => {
54
+ Object.keys($watch.subscribers.current).forEach((path) => {
55
+ if (require_get_path.getPath(path, $values.refValues.current) !== require_get_path.getPath(path, previousValues)) $watch.subscribers.current[path]?.forEach((cb) => cb({
56
+ previousValue: require_get_path.getPath(path, previousValues),
57
+ value: require_get_path.getPath(path, $values.refValues.current),
58
+ touched: $status.isTouched(path),
59
+ dirty: $status.isDirty(path)
60
+ }));
61
+ });
62
+ }, []);
63
+ const handleValuesChanges = (0, react.useCallback)((previousValues) => {
64
+ clearInputErrorOnChange && $errors.clearErrors();
65
+ mode === "uncontrolled" && setFormKey((key) => key + 1);
66
+ notifyWatchSubscribers(previousValues);
67
+ }, [clearInputErrorOnChange, notifyWatchSubscribers]);
68
+ const initialize = (0, react.useCallback)((values) => {
69
+ const previousValues = $values.refValues.current;
70
+ $values.initialize(values, () => mode === "uncontrolled" && setFormKey((key) => key + 1));
71
+ handleValuesChanges(previousValues);
72
+ }, [handleValuesChanges]);
73
+ const debouncedValidateField = (0, react.useMemo)(() => {
74
+ const timers = {};
75
+ const handleValidation = (path) => {
76
+ const signal = $validating.getAbortSignal(path);
77
+ const result = require_validate_field_value.validateFieldValue(path, rules, $values.refValues.current, resolveValidationError, signal);
78
+ const applyResult = (results) => {
79
+ if (signal.aborted) return;
80
+ if (results.hasError) $errors.setFieldError(path, results.error);
81
+ else $errors.clearFieldError(path);
82
+ };
83
+ const cleanup = () => {
84
+ if (!signal.aborted) $validating.setFieldValidating(path, false);
85
+ };
86
+ if (result instanceof Promise) {
87
+ $validating.setFieldValidating(path, true);
88
+ result.then(applyResult).finally(cleanup);
89
+ } else applyResult(result);
90
+ };
91
+ return (path) => {
92
+ clearTimeout(timers[path]);
93
+ if (validateDebounce > 0) timers[path] = setTimeout(() => handleValidation(path), validateDebounce);
94
+ else handleValidation(path);
95
+ };
96
+ }, [
97
+ validateDebounce,
98
+ rules,
99
+ resolveValidationError
100
+ ]);
101
+ const setFieldValue = (0, react.useCallback)((path, value, options) => {
102
+ const shouldValidate = require_should_validate_on_change.shouldValidateOnChange(path, validateInputOnChange);
103
+ const resolvedValue = value instanceof Function ? value(require_get_path.getPath(path, $values.refValues.current)) : value;
104
+ $status.setCalculatedFieldDirty(path, resolvedValue);
105
+ touchTrigger === "change" && $status.setFieldTouched(path, true);
106
+ !shouldValidate && clearInputErrorOnChange && $errors.clearFieldError(path);
107
+ $values.setFieldValue({
108
+ path,
109
+ value,
110
+ updateState: mode === "controlled",
111
+ subscribers: [
112
+ ...$watch.getFieldSubscribers(path),
113
+ shouldValidate ? () => debouncedValidateField(String(path)) : null,
114
+ options?.forceUpdate !== false && mode !== "controlled" ? () => setFieldKeys((keys) => ({
115
+ ...keys,
116
+ [path]: (keys[path] || 0) + 1
117
+ })) : null
118
+ ]
119
+ });
120
+ }, [
121
+ onValuesChange,
122
+ rules,
123
+ debouncedValidateField
124
+ ]);
125
+ const setValues = (0, react.useCallback)((values) => {
126
+ const previousValues = $values.refValues.current;
127
+ $values.setValues({
128
+ values,
129
+ updateState: mode === "controlled"
130
+ });
131
+ handleValuesChanges(previousValues);
132
+ }, [onValuesChange, handleValuesChanges]);
133
+ const validate = (0, react.useCallback)(() => {
134
+ const generation = ++validateGeneration.current;
135
+ const signal = $validating.getAbortSignal("__form__");
136
+ const handleResult = (results) => {
137
+ if (generation !== validateGeneration.current) return {
138
+ hasErrors: false,
139
+ errors: {}
140
+ };
141
+ $errors.setErrors(results.errors);
142
+ return results;
143
+ };
144
+ const cleanup = () => {
145
+ if (generation === validateGeneration.current) $validating.setFormValidating(false);
146
+ };
147
+ const result = require_validate_values.validateValues(rules, $values.refValues.current, resolveValidationError, signal);
148
+ if (result instanceof Promise) {
149
+ $validating.setFormValidating(true);
150
+ return result.then(handleResult).finally(cleanup);
151
+ }
152
+ return handleResult(result);
153
+ }, [rules, resolveValidationError]);
154
+ const validateField = (0, react.useCallback)((path) => {
155
+ const signal = $validating.getAbortSignal(String(path));
156
+ const applyResult = (results) => {
157
+ if (signal.aborted) return {
158
+ hasError: false,
159
+ error: null
160
+ };
161
+ if (results.hasError) $errors.setFieldError(path, results.error);
162
+ else $errors.clearFieldError(path);
163
+ return results;
164
+ };
165
+ const cleanup = () => {
166
+ if (!signal.aborted) $validating.setFieldValidating(String(path), false);
167
+ };
168
+ const result = require_validate_field_value.validateFieldValue(path, rules, $values.refValues.current, resolveValidationError, signal);
169
+ if (result instanceof Promise) {
170
+ $validating.setFieldValidating(String(path), true);
171
+ return result.then(applyResult).finally(cleanup);
172
+ }
173
+ return applyResult(result);
174
+ }, [rules, resolveValidationError]);
175
+ const getInputProps = (path, { type = "input", withError = true, withFocus, ...otherOptions } = {}) => {
176
+ const _withFocus = withFocus ?? type !== "radio";
177
+ const payload = {
178
+ onChange: require_get_input_on_change.getInputOnChange((value) => setFieldValue(path, value, { forceUpdate: false })),
179
+ "data-path": require_get_data_path.getDataPath(name, path)
180
+ };
181
+ if (withError) payload.error = $errors.errorsState[path];
182
+ if (type === "checkbox") payload[mode === "controlled" ? "checked" : "defaultChecked"] = require_get_path.getPath(path, $values.refValues.current);
183
+ else if (type === "radio") {
184
+ payload[mode === "controlled" ? "checked" : "defaultChecked"] = require_get_path.getPath(path, $values.refValues.current) === otherOptions.value;
185
+ payload.value = otherOptions.value;
186
+ } else payload[mode === "controlled" ? "value" : "defaultValue"] = require_get_path.getPath(path, $values.refValues.current);
187
+ if (_withFocus) {
188
+ payload.onFocus = () => $status.setFieldTouched(path, true);
189
+ payload.onBlur = () => {
190
+ if (require_should_validate_on_change.shouldValidateOnChange(path, validateInputOnBlur)) debouncedValidateField(String(path));
191
+ };
192
+ }
193
+ return Object.assign(payload, enhanceGetInputProps?.({
194
+ inputProps: payload,
195
+ field: path,
196
+ options: {
197
+ type,
198
+ withError,
199
+ withFocus: _withFocus,
200
+ ...otherOptions
201
+ },
202
+ form
203
+ }));
204
+ };
205
+ const onSubmit = (handleSubmit, handleValidationFailure) => (event) => {
206
+ if (onSubmitPreventDefault === "always") event?.preventDefault();
207
+ setSubmitting(true);
208
+ const handleValidation = (results) => {
209
+ if (results.hasErrors) {
210
+ if (onSubmitPreventDefault === "validation-failed") event?.preventDefault();
211
+ handleValidationFailure?.(results.errors, $values.refValues.current, event);
212
+ setSubmitting(false);
213
+ } else {
214
+ const submitResult = handleSubmit?.(transformValues($values.refValues.current), event);
215
+ if (submitResult instanceof Promise) submitResult.finally(() => setSubmitting(false));
216
+ else setSubmitting(false);
217
+ }
218
+ };
219
+ const result = validate();
220
+ if (result instanceof Promise) result.then(handleValidation).catch(() => {
221
+ setSubmitting(false);
222
+ });
223
+ else handleValidation(result);
224
+ };
225
+ const getTransformedValues = (input) => transformValues(input || $values.refValues.current);
226
+ const onReset = (0, react.useCallback)((event) => {
227
+ event.preventDefault();
228
+ reset();
229
+ }, []);
230
+ const isValid = (0, react.useCallback)((path) => {
231
+ const signal = new AbortController().signal;
232
+ if (path) {
233
+ const result = require_validate_field_value.validateFieldValue(path, rules, $values.refValues.current, resolveValidationError, signal);
234
+ if (result instanceof Promise) return result.then((r) => !r.hasError);
235
+ return !result.hasError;
236
+ }
237
+ const result = require_validate_values.validateValues(rules, $values.refValues.current, resolveValidationError, signal);
238
+ if (result instanceof Promise) return result.then((r) => !r.hasErrors);
239
+ return !result.hasErrors;
240
+ }, [rules, resolveValidationError]);
241
+ const key = (path) => `${formKey}-${String(path)}-${fieldKeys[String(path)] || 0}`;
242
+ const getInputNode = (0, react.useCallback)((path) => document.querySelector(`[data-path="${require_get_data_path.getDataPath(name, path)}"]`), []);
243
+ const resetField = (0, react.useCallback)((path) => {
244
+ $values.resetField(path, [mode !== "controlled" ? () => setFieldKeys((keys) => ({
245
+ ...keys,
246
+ [path]: (keys[path] || 0) + 1
247
+ })) : null]);
248
+ }, [
249
+ $values.resetField,
250
+ mode,
251
+ setFieldKeys
252
+ ]);
253
+ const form = {
254
+ watch: $watch.watch,
255
+ initialized: $values.initialized.current,
256
+ values: mode === "uncontrolled" ? $values.refValues.current : $values.stateValues,
257
+ getValues: $values.getValues,
258
+ getInitialValues: $values.getValuesSnapshot,
259
+ setInitialValues: $values.setValuesSnapshot,
260
+ resetField,
261
+ initialize,
262
+ setValues,
263
+ setFieldValue,
264
+ submitting,
265
+ setSubmitting,
266
+ validating: $validating.validating,
267
+ isValidating: $validating.isValidating,
268
+ errors: $errors.errorsState,
269
+ setErrors: $errors.setErrors,
270
+ setFieldError: $errors.setFieldError,
271
+ clearFieldError: $errors.clearFieldError,
272
+ clearErrors: $errors.clearErrors,
273
+ resetDirty: $status.resetDirty,
274
+ setTouched: $status.setTouched,
275
+ setDirty: $status.setDirty,
276
+ isTouched: $status.isTouched,
277
+ resetTouched: $status.resetTouched,
278
+ isDirty: $status.isDirty,
279
+ getTouched: $status.getTouched,
280
+ getDirty: $status.getDirty,
281
+ reorderListItem: ((path, payload) => {
282
+ const previousValues = $values.refValues.current;
283
+ $list.reorderListItem(path, payload);
284
+ notifyWatchSubscribers(previousValues);
285
+ }),
286
+ insertListItem: ((path, item, index) => {
287
+ const previousValues = $values.refValues.current;
288
+ $list.insertListItem(path, item, index);
289
+ notifyWatchSubscribers(previousValues);
290
+ }),
291
+ removeListItem: ((path, index) => {
292
+ const previousValues = $values.refValues.current;
293
+ $list.removeListItem(path, index);
294
+ notifyWatchSubscribers(previousValues);
295
+ }),
296
+ replaceListItem: ((path, index, item) => {
297
+ const previousValues = $values.refValues.current;
298
+ $list.replaceListItem(path, index, item);
299
+ notifyWatchSubscribers(previousValues);
300
+ }),
301
+ reset,
302
+ validate,
303
+ validateField,
304
+ getInputProps,
305
+ onSubmit,
306
+ onReset,
307
+ isValid,
308
+ getTransformedValues,
309
+ key,
310
+ getInputNode
311
+ };
312
+ require_actions.useFormActions(name, form);
313
+ return form;
378
314
  }
379
-
315
+ //#endregion
380
316
  exports.useForm = useForm;
381
- //# sourceMappingURL=use-form.cjs.map
317
+
318
+ //# sourceMappingURL=use-form.cjs.map