@conform-to/react 1.15.1 → 1.17.0

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.
@@ -1,5 +1,5 @@
1
1
  import { objectSpread2 as _objectSpread2 } from '../_virtual/_rollupPluginBabelHelpers.mjs';
2
- import { getPathSegments, getRelativePath, isPlainObject, appendPathSegment } from '@conform-to/dom/future';
2
+ import { getPathSegments, getRelativePath, isPlainObject, appendPathSegment, getValueAtPath } from '@conform-to/dom/future';
3
3
  import { isOptional, isUndefined, isNullable, appendUniqueItem, merge, updateValueAtPath, isString, getArrayAtPath, createPathIndexUpdater, compactMap, generateUniqueKey, isNumber, transformKeys } from './util.mjs';
4
4
  import { getDefaultListKey } from './state.mjs';
5
5
 
@@ -42,19 +42,35 @@ function deserializeIntent(value) {
42
42
  * Applies intent transformation to submission payload.
43
43
  * Returns modified payload or null for reset intent.
44
44
  */
45
- function applyIntent(submission, options) {
46
- var _options$handlers, _handler$validatePayl, _handler$validatePayl2;
45
+ function resolveIntent(submission, options) {
46
+ var _options$handlers, _handler$validate, _handler$validate2;
47
47
  if (!submission.intent) {
48
48
  return submission.payload;
49
49
  }
50
50
  var intent = deserializeIntent(submission.intent);
51
- var handlers = (_options$handlers = options === null || options === void 0 ? void 0 : options.handlers) !== null && _options$handlers !== void 0 ? _options$handlers : actionHandlers;
51
+ var handlers = (_options$handlers = options === null || options === void 0 ? void 0 : options.handlers) !== null && _options$handlers !== void 0 ? _options$handlers : intentHandlers;
52
52
  var handler = handlers[intent.type];
53
- if (handler && handler.onApply && ((_handler$validatePayl = (_handler$validatePayl2 = handler.validatePayload) === null || _handler$validatePayl2 === void 0 ? void 0 : _handler$validatePayl2.call(handler, intent.payload)) !== null && _handler$validatePayl !== void 0 ? _handler$validatePayl : true)) {
54
- return handler.onApply(submission.payload, intent.payload);
53
+ if (handler !== null && handler !== void 0 && handler.resolve && ((_handler$validate = (_handler$validate2 = handler.validate) === null || _handler$validate2 === void 0 ? void 0 : _handler$validate2.call(handler, intent.payload)) !== null && _handler$validate !== void 0 ? _handler$validate : true)) {
54
+ return handler.resolve(submission.payload, intent.payload);
55
55
  }
56
56
  return submission.payload;
57
57
  }
58
+
59
+ /**
60
+ * Resolves an intent after validation by calling the handler's onResolve.
61
+ * Mutates the result with updated value/error and returns whether the intent was cancelled.
62
+ */
63
+ function applyIntent(result, intent, options) {
64
+ if (intent) {
65
+ var _options$handlers2, _handler$validate3, _handler$validate4;
66
+ var handlers = (_options$handlers2 = options === null || options === void 0 ? void 0 : options.handlers) !== null && _options$handlers2 !== void 0 ? _options$handlers2 : intentHandlers;
67
+ var handler = handlers[intent.type];
68
+ if (handler !== null && handler !== void 0 && handler.apply && ((_handler$validate3 = (_handler$validate4 = handler.validate) === null || _handler$validate4 === void 0 ? void 0 : _handler$validate4.call(handler, intent.payload)) !== null && _handler$validate3 !== void 0 ? _handler$validate3 : true)) {
69
+ return handler.apply(result, intent.payload);
70
+ }
71
+ }
72
+ return result;
73
+ }
58
74
  function insertItem(list, item, index) {
59
75
  list.splice(index, 0, item);
60
76
  }
@@ -86,36 +102,34 @@ function updateListKeys() {
86
102
  * - update: updates specific field values
87
103
  * - insert/remove/reorder: manages array field operations
88
104
  */
89
- var actionHandlers = {
105
+ var intentHandlers = {
90
106
  reset: {
91
- validatePayload(options) {
107
+ validate(options) {
92
108
  return isOptional(options, isPlainObject) && (isUndefined(options === null || options === void 0 ? void 0 : options.defaultValue) || isNullable(options === null || options === void 0 ? void 0 : options.defaultValue, isPlainObject));
93
109
  },
94
- onApply(_, options) {
110
+ resolve(_, options) {
95
111
  if ((options === null || options === void 0 ? void 0 : options.defaultValue) === null) {
96
112
  return {};
97
113
  }
98
114
  return options === null || options === void 0 ? void 0 : options.defaultValue;
99
115
  },
100
- onUpdate(_, _ref) {
101
- var {
102
- targetValue,
103
- ctx
104
- } = _ref;
105
- return ctx.reset(targetValue);
116
+ apply(result) {
117
+ return _objectSpread2(_objectSpread2({}, result), {}, {
118
+ reset: true
119
+ });
106
120
  }
107
121
  },
108
122
  validate: {
109
- validatePayload(name) {
123
+ validate(name) {
110
124
  return isOptional(name, isString);
111
125
  },
112
- onUpdate(state, _ref2) {
126
+ update(state, _ref) {
113
127
  var _intent$payload;
114
128
  var {
115
129
  submission,
116
130
  intent,
117
131
  error
118
- } = _ref2;
132
+ } = _ref;
119
133
  var name = (_intent$payload = intent.payload) !== null && _intent$payload !== void 0 ? _intent$payload : '';
120
134
  var basePath = getPathSegments(name);
121
135
  var allFields = error ?
@@ -134,20 +148,20 @@ var actionHandlers = {
134
148
  }
135
149
  },
136
150
  update: {
137
- validatePayload(options) {
151
+ validate(options) {
138
152
  return isPlainObject(options) && isOptional(options.name, isString) && isOptional(options.index, isNumber) && !isUndefined(options.value);
139
153
  },
140
- onApply(value, options) {
154
+ resolve(value, options) {
141
155
  var _options$value;
142
156
  var name = appendPathSegment(options.name, options.index);
143
157
  return updateValueAtPath(value, name, (_options$value = options.value) !== null && _options$value !== void 0 ? _options$value : name === '' ? {} : null);
144
158
  },
145
- onUpdate(state, _ref3) {
159
+ update(state, _ref2) {
146
160
  var {
147
161
  type,
148
162
  submission,
149
163
  intent
150
- } = _ref3;
164
+ } = _ref2;
151
165
  if (type === 'server') {
152
166
  return state;
153
167
  }
@@ -174,63 +188,141 @@ var actionHandlers = {
174
188
  }
175
189
  },
176
190
  insert: {
177
- validatePayload(options) {
178
- return isPlainObject(options) && isString(options.name) && isOptional(options.index, isNumber);
191
+ validate(options) {
192
+ return isPlainObject(options) && isString(options.name) && isOptional(options.index, isNumber) && isOptional(options.from, isString) && isOptional(options.onInvalid, mode => mode === 'revert');
179
193
  },
180
- onApply(value, options) {
194
+ resolve(value, options) {
181
195
  var _options$index;
182
- var list = Array.from(getArrayAtPath(value, options.name));
183
- insertItem(list, options.defaultValue, (_options$index = options.index) !== null && _options$index !== void 0 ? _options$index : list.length);
184
- return updateValueAtPath(value, options.name, list);
196
+ var result = value;
197
+ var itemValue = options.defaultValue;
198
+ if (options.from !== undefined) {
199
+ itemValue = getValueAtPath(result, options.from);
200
+ result = updateValueAtPath(result, options.from, '');
201
+ }
202
+ var list = Array.from(getArrayAtPath(result, options.name));
203
+ insertItem(list, itemValue, (_options$index = options.index) !== null && _options$index !== void 0 ? _options$index : list.length);
204
+ return updateValueAtPath(result, options.name, list);
185
205
  },
186
- onUpdate(state, _ref4) {
206
+ apply(result, options) {
207
+ var _result$error;
208
+ // Warn if validation result is not yet available
209
+ if (typeof result.error === 'undefined' && (options.onInvalid || options.from)) {
210
+ // eslint-disable-next-line no-console
211
+ console.warn('intent.insert() with `onInvalid` or `from` requires the validation result to be available synchronously. ' + 'These options are ignored because the error is not yet known.');
212
+ return result;
213
+ }
214
+ var arrayErrors = (_result$error = result.error) === null || _result$error === void 0 ? void 0 : _result$error.fieldErrors[options.name];
215
+ if (options.onInvalid === 'revert' && arrayErrors !== null && arrayErrors !== void 0 && arrayErrors.length) {
216
+ return _objectSpread2(_objectSpread2({}, result), {}, {
217
+ targetValue: undefined
218
+ });
219
+ }
220
+ if (options.from !== undefined) {
221
+ var _options$index2, _result$error2;
222
+ var index = (_options$index2 = options.index) !== null && _options$index2 !== void 0 ? _options$index2 : getArrayAtPath(result.submission.payload, options.name).length;
223
+ var insertedItemPath = appendPathSegment(options.name, index);
224
+ var insertedItemErrors = (_result$error2 = result.error) === null || _result$error2 === void 0 ? void 0 : _result$error2.fieldErrors[insertedItemPath];
225
+ if (insertedItemErrors !== null && insertedItemErrors !== void 0 && insertedItemErrors.length) {
226
+ var _result$error$fieldEr, _result$error3, _result$error$formErr, _result$error4, _result$error5;
227
+ var fromErrors = (_result$error$fieldEr = (_result$error3 = result.error) === null || _result$error3 === void 0 ? void 0 : _result$error3.fieldErrors[options.from]) !== null && _result$error$fieldEr !== void 0 ? _result$error$fieldEr : [];
228
+ return _objectSpread2(_objectSpread2({}, result), {}, {
229
+ targetValue: undefined,
230
+ error: {
231
+ formErrors: (_result$error$formErr = (_result$error4 = result.error) === null || _result$error4 === void 0 ? void 0 : _result$error4.formErrors) !== null && _result$error$formErr !== void 0 ? _result$error$formErr : [],
232
+ fieldErrors: _objectSpread2(_objectSpread2({}, (_result$error5 = result.error) === null || _result$error5 === void 0 ? void 0 : _result$error5.fieldErrors), {}, {
233
+ [options.from]: [...fromErrors, ...insertedItemErrors],
234
+ [insertedItemPath]: []
235
+ })
236
+ }
237
+ });
238
+ }
239
+ }
240
+ return result;
241
+ },
242
+ update(state, _ref3) {
187
243
  var _intent$payload$index;
188
244
  var {
189
245
  type,
190
246
  submission,
191
- intent
192
- } = _ref4;
247
+ intent,
248
+ ctx
249
+ } = _ref3;
193
250
  if (type === 'server') {
194
251
  return state;
195
252
  }
196
- var currentValue = submission.payload;
197
- var list = getArrayAtPath(currentValue, intent.payload.name);
198
- var index = (_intent$payload$index = intent.payload.index) !== null && _intent$payload$index !== void 0 ? _intent$payload$index : list.length;
253
+ var from = intent.payload.from;
254
+ var index = (_intent$payload$index = intent.payload.index) !== null && _intent$payload$index !== void 0 ? _intent$payload$index : getArrayAtPath(submission.payload, intent.payload.name).length;
199
255
  var updateListIndex = createPathIndexUpdater(intent.payload.name, currentIndex => index <= currentIndex ? currentIndex + 1 : currentIndex);
200
- var touchedFields = appendUniqueItem(compactMap(state.touchedFields, updateListIndex), intent.payload.name);
201
- var keys = state.listKeys;
256
+ var touchedFields = state.touchedFields;
257
+ var listKeys = state.listKeys;
258
+ if (!ctx.cancelled) {
259
+ touchedFields = compactMap(state.touchedFields, updateListIndex);
202
260
 
203
- // Update the keys only for client updates to avoid double updates if there is no client validation
204
- if (type === 'client') {
205
- var _state$listKeys$inten;
206
- var listKeys = Array.from((_state$listKeys$inten = state.listKeys[intent.payload.name]) !== null && _state$listKeys$inten !== void 0 ? _state$listKeys$inten : getDefaultListKey(state.resetKey, currentValue, intent.payload.name));
207
- insertItem(listKeys, generateUniqueKey(), index);
208
- keys = _objectSpread2(_objectSpread2({}, updateListKeys(state.listKeys, appendPathSegment(intent.payload.name, index), updateListIndex)), {}, {
209
- // Update existing list keys
210
- [intent.payload.name]: listKeys
211
- });
261
+ // Update the keys only for client updates to avoid double updates if there is no client validation
262
+ if (type === 'client') {
263
+ var _state$listKeys$inten;
264
+ var selectedListKeys = Array.from((_state$listKeys$inten = state.listKeys[intent.payload.name]) !== null && _state$listKeys$inten !== void 0 ? _state$listKeys$inten : getDefaultListKey(state.resetKey, submission.payload, intent.payload.name));
265
+ insertItem(selectedListKeys, generateUniqueKey(), index);
266
+ listKeys = _objectSpread2(_objectSpread2({}, updateListKeys(state.listKeys, appendPathSegment(intent.payload.name, index), updateListIndex)), {}, {
267
+ // Update existing list keys
268
+ [intent.payload.name]: selectedListKeys
269
+ });
270
+ }
271
+ }
272
+ touchedFields = appendUniqueItem(touchedFields, intent.payload.name);
273
+ if (from !== undefined) {
274
+ touchedFields = appendUniqueItem(touchedFields, from);
212
275
  }
213
276
  return _objectSpread2(_objectSpread2({}, state), {}, {
214
- listKeys: keys,
277
+ listKeys,
215
278
  touchedFields
216
279
  });
217
280
  }
218
281
  },
219
282
  remove: {
220
- validatePayload(options) {
221
- return isPlainObject(options) && isString(options.name) && isNumber(options.index);
283
+ validate(options) {
284
+ return isPlainObject(options) && isString(options.name) && isNumber(options.index) && isOptional(options.onInvalid, v => v === 'revert' || v === 'insert');
222
285
  },
223
- onApply(value, options) {
286
+ resolve(value, options) {
224
287
  var list = Array.from(getArrayAtPath(value, options.name));
225
288
  removeItem(list, options.index);
226
289
  return updateValueAtPath(value, options.name, list);
227
290
  },
228
- onUpdate(state, _ref5) {
291
+ apply(result, options) {
292
+ var _result$error6;
293
+ // Warn if validation result is not yet available
294
+ if (typeof result.error === 'undefined' && options.onInvalid) {
295
+ if (process.env.NODE_ENV !== 'production') {
296
+ // eslint-disable-next-line no-console
297
+ console.warn('intent.remove() with `onInvalid` requires the validation result to be available synchronously. ' + 'This option is ignored because the error is not yet known.');
298
+ }
299
+ return result;
300
+ }
301
+ if (result.targetValue && (_result$error6 = result.error) !== null && _result$error6 !== void 0 && _result$error6.fieldErrors[options.name]) {
302
+ switch (options.onInvalid) {
303
+ case 'revert':
304
+ return _objectSpread2(_objectSpread2({}, result), {}, {
305
+ targetValue: undefined
306
+ });
307
+ case 'insert':
308
+ {
309
+ var list = Array.from(getArrayAtPath(result.targetValue, options.name));
310
+ insertItem(list, options.defaultValue, list.length);
311
+ return _objectSpread2(_objectSpread2({}, result), {}, {
312
+ targetValue: updateValueAtPath(result.targetValue, options.name, list)
313
+ });
314
+ }
315
+ }
316
+ }
317
+ return result;
318
+ },
319
+ update(state, _ref4) {
229
320
  var {
230
321
  type,
231
322
  submission,
232
- intent
233
- } = _ref5;
323
+ intent,
324
+ ctx
325
+ } = _ref4;
234
326
  if (type === 'server') {
235
327
  return state;
236
328
  }
@@ -241,40 +333,54 @@ var actionHandlers = {
241
333
  }
242
334
  return intent.payload.index < currentIndex ? currentIndex - 1 : currentIndex;
243
335
  });
244
- var touchedFields = appendUniqueItem(compactMap(state.touchedFields, updateListIndex), intent.payload.name);
245
- var keys = state.listKeys;
336
+ var touchedFields = state.touchedFields;
337
+ var listKeys = state.listKeys;
246
338
 
247
- // Update the keys only for client updates to avoid double updates if there is no client validation
248
- if (type === 'client') {
249
- var _state$listKeys$inten2;
250
- var listKeys = Array.from((_state$listKeys$inten2 = state.listKeys[intent.payload.name]) !== null && _state$listKeys$inten2 !== void 0 ? _state$listKeys$inten2 : getDefaultListKey(state.resetKey, currentValue, intent.payload.name));
251
- removeItem(listKeys, intent.payload.index);
252
- keys = _objectSpread2(_objectSpread2({}, updateListKeys(state.listKeys, appendPathSegment(intent.payload.name, intent.payload.index), updateListIndex)), {}, {
253
- // Update existing list keys
254
- [intent.payload.name]: listKeys
255
- });
339
+ // If onInvalid is 'insert', we still remove the item and then insert a new item at the end
340
+ if (!ctx.cancelled || intent.payload.onInvalid === 'insert') {
341
+ touchedFields = compactMap(touchedFields, updateListIndex);
342
+
343
+ // Update the keys only for client updates to avoid double updates if there is no client validation
344
+ if (type === 'client') {
345
+ var _state$listKeys$inten2;
346
+ var selectedListKeys = Array.from((_state$listKeys$inten2 = state.listKeys[intent.payload.name]) !== null && _state$listKeys$inten2 !== void 0 ? _state$listKeys$inten2 : getDefaultListKey(state.resetKey, currentValue, intent.payload.name));
347
+ removeItem(selectedListKeys, intent.payload.index);
348
+ listKeys = _objectSpread2(_objectSpread2({}, updateListKeys(state.listKeys, appendPathSegment(intent.payload.name, intent.payload.index), updateListIndex)), {}, {
349
+ // Update existing list keys
350
+ [intent.payload.name]: selectedListKeys
351
+ });
352
+ if (ctx.cancelled) {
353
+ var index = selectedListKeys.length;
354
+ insertItem(selectedListKeys, generateUniqueKey(), index);
355
+ listKeys = _objectSpread2(_objectSpread2({}, updateListKeys(state.listKeys, appendPathSegment(intent.payload.name, index), updateListIndex)), {}, {
356
+ // Update existing list keys
357
+ [intent.payload.name]: selectedListKeys
358
+ });
359
+ }
360
+ }
256
361
  }
362
+ touchedFields = appendUniqueItem(touchedFields, intent.payload.name);
257
363
  return _objectSpread2(_objectSpread2({}, state), {}, {
258
- listKeys: keys,
364
+ listKeys: listKeys,
259
365
  touchedFields
260
366
  });
261
367
  }
262
368
  },
263
369
  reorder: {
264
- validatePayload(options) {
370
+ validate(options) {
265
371
  return isPlainObject(options) && isString(options.name) && isNumber(options.from) && isNumber(options.to);
266
372
  },
267
- onApply(value, options) {
373
+ resolve(value, options) {
268
374
  var list = Array.from(getArrayAtPath(value, options.name));
269
375
  reorderItems(list, options.from, options.to);
270
376
  return updateValueAtPath(value, options.name, list);
271
377
  },
272
- onUpdate(state, _ref6) {
378
+ update(state, _ref5) {
273
379
  var {
274
380
  type,
275
381
  submission,
276
382
  intent
277
- } = _ref6;
383
+ } = _ref5;
278
384
  if (type === 'server') {
279
385
  return state;
280
386
  }
@@ -312,4 +418,4 @@ var actionHandlers = {
312
418
  }
313
419
  };
314
420
 
315
- export { actionHandlers, applyIntent, deserializeIntent, insertItem, removeItem, reorderItems, serializeIntent, updateListKeys };
421
+ export { applyIntent, deserializeIntent, insertItem, intentHandlers, removeItem, reorderItems, resolveIntent, serializeIntent, updateListKeys };
@@ -1,5 +1,5 @@
1
1
  import { type FieldName, type ValidationAttributes, type Serialize } from '@conform-to/dom/future';
2
- import type { FieldMetadata, Fieldset, FormContext, FormMetadata, FormState, FormAction, UnknownIntent, ActionHandler, CustomMetadataDefinition } from './types';
2
+ import type { FieldMetadata, Fieldset, FormContext, FormMetadata, FormState, FormAction, UnknownIntent, IntentHandler, BaseFieldMetadata, BaseFormMetadata, DefineConditionalField } from './types';
3
3
  export declare function initializeState<ErrorShape>(options?: {
4
4
  defaultValue?: Record<string, unknown> | null | undefined;
5
5
  resetKey?: string | undefined;
@@ -11,7 +11,8 @@ export declare function initializeState<ErrorShape>(options?: {
11
11
  * - Initialize: set initial server value
12
12
  */
13
13
  export declare function updateState<ErrorShape>(state: FormState<ErrorShape>, action: FormAction<ErrorShape, UnknownIntent | null, {
14
- handlers: Record<string, ActionHandler>;
14
+ handlers: Record<string, IntentHandler>;
15
+ cancelled: boolean;
15
16
  reset: (defaultValue?: Record<string, unknown> | null | undefined) => FormState<ErrorShape>;
16
17
  }>): FormState<ErrorShape>;
17
18
  /**
@@ -39,32 +40,47 @@ export declare function isValid(state: FormState<any>, name?: string): boolean;
39
40
  * e.g. "array[0].key" falls back to "array[].key" if specific constraint not found.
40
41
  */
41
42
  export declare function getConstraint(context: FormContext<any>, name: string): ValidationAttributes | undefined;
42
- export declare function getFormMetadata<ErrorShape>(context: FormContext<ErrorShape>, options?: {
43
+ export declare function getFormMetadata<ErrorShape, CustomFormMetadata extends Record<string, unknown> = {}, CustomFieldMetadata extends Record<string, unknown> = {}>(context: FormContext<ErrorShape>, options?: {
43
44
  serialize?: Serialize | undefined;
44
- customize?: CustomMetadataDefinition | undefined;
45
- }): FormMetadata<ErrorShape>;
46
- export declare function getField<FieldShape, ErrorShape = string>(context: FormContext<ErrorShape>, options: {
45
+ extendFormMetadata?: ((metadata: BaseFormMetadata<ErrorShape>) => CustomFormMetadata) | undefined;
46
+ extendFieldMetadata?: (<FieldShape>(metadata: BaseFieldMetadata<FieldShape, ErrorShape>, ctx: {
47
+ form: BaseFormMetadata<ErrorShape>;
48
+ when: DefineConditionalField;
49
+ }) => CustomFieldMetadata) | undefined;
50
+ }): FormMetadata<ErrorShape, CustomFormMetadata, CustomFieldMetadata>;
51
+ export declare function getField<FieldShape, ErrorShape = string, CustomFieldMetadata extends Record<string, unknown> = {}>(context: FormContext<ErrorShape>, options: {
47
52
  name: FieldName<FieldShape>;
48
53
  serialize?: Serialize | undefined;
49
- customize?: CustomMetadataDefinition | undefined;
54
+ extendFieldMetadata?: (<F>(metadata: BaseFieldMetadata<F, ErrorShape>, ctx: {
55
+ form: BaseFormMetadata<ErrorShape>;
56
+ when: DefineConditionalField;
57
+ }) => CustomFieldMetadata) | undefined;
58
+ form?: BaseFormMetadata<ErrorShape, CustomFieldMetadata> | undefined;
50
59
  key?: string | undefined;
51
- }): FieldMetadata<FieldShape, ErrorShape>;
60
+ }): FieldMetadata<FieldShape, ErrorShape, CustomFieldMetadata>;
52
61
  /**
53
62
  * Creates a proxy that dynamically generates field objects when properties are accessed.
54
63
  */
55
- export declare function getFieldset<FieldShape = Record<string, any>, ErrorShape = string>(context: FormContext<ErrorShape>, options: {
64
+ export declare function getFieldset<FieldShape = Record<string, any>, ErrorShape = string, CustomFieldMetadata extends Record<string, unknown> = {}>(context: FormContext<ErrorShape>, options: {
56
65
  name?: FieldName<FieldShape> | undefined;
57
66
  serialize?: Serialize | undefined;
58
- customize?: CustomMetadataDefinition | undefined;
59
- }): Fieldset<FieldShape, ErrorShape>;
67
+ extendFieldMetadata?: (<F>(metadata: BaseFieldMetadata<F, ErrorShape>, ctx: {
68
+ form: BaseFormMetadata<ErrorShape>;
69
+ when: DefineConditionalField;
70
+ }) => CustomFieldMetadata) | undefined;
71
+ form?: BaseFormMetadata<ErrorShape, CustomFieldMetadata> | undefined;
72
+ }): Fieldset<FieldShape, ErrorShape, CustomFieldMetadata>;
60
73
  /**
61
74
  * Creates an array of field objects for list/array inputs
62
75
  */
63
- export declare function getFieldList<FieldShape = Array<any>, ErrorShape = string>(context: FormContext<ErrorShape>, options: {
76
+ export declare function getFieldList<FieldShape = Array<any>, ErrorShape = string, CustomFieldMetadata extends Record<string, unknown> = {}>(context: FormContext<ErrorShape>, options: {
64
77
  name: FieldName<FieldShape>;
65
78
  serialize?: Serialize | undefined;
66
- customize?: CustomMetadataDefinition | undefined;
79
+ extendFieldMetadata?: (<F>(metadata: BaseFieldMetadata<F, ErrorShape>, ctx: {
80
+ form: BaseFormMetadata<ErrorShape>;
81
+ when: DefineConditionalField;
82
+ }) => CustomFieldMetadata) | undefined;
67
83
  }): FieldMetadata<[
68
84
  FieldShape
69
- ] extends [Array<infer ItemShape> | null | undefined] ? ItemShape : unknown, ErrorShape>[];
85
+ ] extends [Array<infer ItemShape> | null | undefined] ? ItemShape : unknown, ErrorShape, CustomFieldMetadata>[];
70
86
  //# sourceMappingURL=state.d.ts.map
@@ -57,12 +57,13 @@ function updateState(state, action) {
57
57
  type: 'validate'
58
58
  };
59
59
  var handler = (_action$ctx$handlers = action.ctx.handlers) === null || _action$ctx$handlers === void 0 ? void 0 : _action$ctx$handlers[intent.type];
60
- if (typeof (handler === null || handler === void 0 ? void 0 : handler.onUpdate) === 'function') {
61
- var _handler$validatePayl, _handler$validatePayl2;
62
- if ((_handler$validatePayl = (_handler$validatePayl2 = handler.validatePayload) === null || _handler$validatePayl2 === void 0 ? void 0 : _handler$validatePayl2.call(handler, intent.payload)) !== null && _handler$validatePayl !== void 0 ? _handler$validatePayl : true) {
63
- return handler.onUpdate(state, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, action), {}, {
60
+ if (typeof (handler === null || handler === void 0 ? void 0 : handler.update) === 'function') {
61
+ var _handler$validate, _handler$validate2;
62
+ if ((_handler$validate = (_handler$validate2 = handler.validate) === null || _handler$validate2 === void 0 ? void 0 : _handler$validate2.call(handler, intent.payload)) !== null && _handler$validate !== void 0 ? _handler$validate : true) {
63
+ return handler.update(state, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, action), {}, {
64
64
  ctx: {
65
- reset: action.ctx.reset
65
+ reset: action.ctx.reset,
66
+ cancelled: action.ctx.cancelled
66
67
  },
67
68
  intent: {
68
69
  type: intent.type,
@@ -241,7 +242,8 @@ function getConstraint(context, name) {
241
242
  return constraint;
242
243
  }
243
244
  function getFormMetadata(context, options) {
244
- return {
245
+ var _options$extendFormMe, _options$extendFormMe2;
246
+ var metadata = {
245
247
  key: context.state.resetKey,
246
248
  id: context.formId,
247
249
  errorId: "".concat(context.formId, "-form-error"),
@@ -274,31 +276,41 @@ function getFormMetadata(context, options) {
274
276
  return getField(context, {
275
277
  name,
276
278
  serialize: options === null || options === void 0 ? void 0 : options.serialize,
277
- customize: options === null || options === void 0 ? void 0 : options.customize
279
+ extendFieldMetadata: options === null || options === void 0 ? void 0 : options.extendFieldMetadata
278
280
  });
279
281
  },
280
282
  getFieldset(name) {
281
283
  return getFieldset(context, {
282
284
  name,
283
285
  serialize: options === null || options === void 0 ? void 0 : options.serialize,
284
- customize: options === null || options === void 0 ? void 0 : options.customize
286
+ extendFieldMetadata: options === null || options === void 0 ? void 0 : options.extendFieldMetadata
285
287
  });
286
288
  },
287
289
  getFieldList(name) {
288
290
  return getFieldList(context, {
289
291
  name,
290
292
  serialize: options === null || options === void 0 ? void 0 : options.serialize,
291
- customize: options === null || options === void 0 ? void 0 : options.customize
293
+ extendFieldMetadata: options === null || options === void 0 ? void 0 : options.extendFieldMetadata
292
294
  });
293
295
  }
294
296
  };
297
+ var customMetadata = (_options$extendFormMe = options === null || options === void 0 || (_options$extendFormMe2 = options.extendFormMetadata) === null || _options$extendFormMe2 === void 0 ? void 0 : _options$extendFormMe2.call(options, metadata)) !== null && _options$extendFormMe !== void 0 ? _options$extendFormMe : {};
298
+ var descriptors = Object.getOwnPropertyDescriptors(customMetadata);
299
+ var extended = Object.create(metadata);
300
+ Object.defineProperties(extended, descriptors);
301
+ return extended;
295
302
  }
296
303
  function getField(context, options) {
304
+ var _extendFieldMetadata;
297
305
  var {
298
306
  key,
299
307
  name,
300
308
  serialize = future.serialize,
301
- customize
309
+ extendFieldMetadata,
310
+ form = getFormMetadata(context, {
311
+ serialize,
312
+ extendFieldMetadata
313
+ })
302
314
  } = options;
303
315
  var id = "".concat(context.formId, "-field-").concat(name.replace(/[^a-zA-Z0-9._-]/g, '_'));
304
316
  var constraint = getConstraint(context, name);
@@ -317,6 +329,7 @@ function getField(context, options) {
317
329
  max: constraint === null || constraint === void 0 ? void 0 : constraint.max,
318
330
  step: constraint === null || constraint === void 0 ? void 0 : constraint.step,
319
331
  multiple: constraint === null || constraint === void 0 ? void 0 : constraint.multiple,
332
+ accept: constraint === null || constraint === void 0 ? void 0 : constraint.accept,
320
333
  get defaultValue() {
321
334
  return getDefaultValue(context, name, serialize);
322
335
  },
@@ -351,40 +364,27 @@ function getField(context, options) {
351
364
  return getFieldset(context, {
352
365
  name: name,
353
366
  serialize,
354
- customize
367
+ extendFieldMetadata
355
368
  });
356
369
  },
370
+ // @ts-expect-error The return type includes CustomFieldMetadata which BaseFieldMetadata
371
+ // doesn't account for. This is a type-level limitation; runtime behavior is correct.
357
372
  getFieldList() {
358
373
  return getFieldList(context, {
359
- name: name,
374
+ name,
360
375
  serialize,
361
- customize
376
+ extendFieldMetadata
362
377
  });
363
378
  }
364
379
  };
365
- if (typeof customize !== 'function') {
366
- return metadata;
367
- }
368
- var customMetadata = null;
369
- return new Proxy(metadata, {
370
- get(target, prop, receiver) {
371
- var _customMetadata;
372
- if (Reflect.has(target, prop)) {
373
- return Reflect.get(target, prop, receiver);
374
- }
375
- (_customMetadata = customMetadata) !== null && _customMetadata !== void 0 ? _customMetadata : customMetadata = customize(metadata);
376
- if (Reflect.has(customMetadata, prop)) {
377
- return Reflect.get(customMetadata, prop, receiver);
378
- }
379
-
380
- // Allow React DevTools to inspect the object
381
- // without throwing errors for internal properties
382
- if (typeof prop === 'symbol' || prop === '$$typeof') {
383
- return undefined;
384
- }
385
- throw new Error("Property \"".concat(String(prop), "\" does not exist on field metadata. ") + "If you have defined the CustomMetadata interface to include \"".concat(String(prop), "\", make sure to also implement it through the \"defineCustomMetadata\" property on <FormOptionsProvider />."));
386
- }
387
- });
380
+ var customMetadata = (_extendFieldMetadata = extendFieldMetadata === null || extendFieldMetadata === void 0 ? void 0 : extendFieldMetadata(metadata, {
381
+ form,
382
+ when: util.when
383
+ })) !== null && _extendFieldMetadata !== void 0 ? _extendFieldMetadata : {};
384
+ var descriptors = Object.getOwnPropertyDescriptors(customMetadata);
385
+ var extended = Object.create(metadata);
386
+ Object.defineProperties(extended, descriptors);
387
+ return extended;
388
388
  }
389
389
 
390
390
  /**
@@ -394,10 +394,16 @@ function getFieldset(context, options) {
394
394
  return new Proxy({}, {
395
395
  get(target, name, receiver) {
396
396
  if (typeof name === 'string') {
397
+ var _options$form;
398
+ (_options$form = options.form) !== null && _options$form !== void 0 ? _options$form : options.form = getFormMetadata(context, {
399
+ serialize: options === null || options === void 0 ? void 0 : options.serialize,
400
+ extendFieldMetadata: options === null || options === void 0 ? void 0 : options.extendFieldMetadata
401
+ });
397
402
  return getField(context, {
398
403
  name: future.appendPathSegment(options === null || options === void 0 ? void 0 : options.name, name),
399
404
  serialize: options.serialize,
400
- customize: options.customize
405
+ extendFieldMetadata: options.extendFieldMetadata,
406
+ form: options.form
401
407
  });
402
408
  }
403
409
  return Reflect.get(target, name, receiver);
@@ -414,7 +420,7 @@ function getFieldList(context, options) {
414
420
  return getField(context, {
415
421
  name: future.appendPathSegment(options.name, index),
416
422
  serialize: options.serialize,
417
- customize: options.customize,
423
+ extendFieldMetadata: options.extendFieldMetadata,
418
424
  key
419
425
  });
420
426
  });