@rjsf/utils 6.0.0-beta.20 → 6.0.0-beta.22

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 (63) hide show
  1. package/dist/index.cjs +202 -68
  2. package/dist/index.cjs.map +4 -4
  3. package/dist/utils.esm.js +202 -68
  4. package/dist/utils.esm.js.map +4 -4
  5. package/dist/utils.umd.js +175 -57
  6. package/lib/ErrorSchemaBuilder.d.ts +2 -2
  7. package/lib/createSchemaUtils.js +6 -4
  8. package/lib/createSchemaUtils.js.map +1 -1
  9. package/lib/enums.d.ts +6 -0
  10. package/lib/enums.js +6 -0
  11. package/lib/enums.js.map +1 -1
  12. package/lib/guessType.d.ts +1 -1
  13. package/lib/idGenerators.d.ts +8 -1
  14. package/lib/idGenerators.js +10 -1
  15. package/lib/idGenerators.js.map +1 -1
  16. package/lib/index.d.ts +9 -4
  17. package/lib/index.js +9 -4
  18. package/lib/index.js.map +1 -1
  19. package/lib/isFormDataAvailable.d.ts +7 -0
  20. package/lib/isFormDataAvailable.js +13 -0
  21. package/lib/isFormDataAvailable.js.map +1 -0
  22. package/lib/isRootSchema.d.ts +13 -0
  23. package/lib/isRootSchema.js +25 -0
  24. package/lib/isRootSchema.js.map +1 -0
  25. package/lib/nameGenerators.d.ts +13 -0
  26. package/lib/nameGenerators.js +30 -0
  27. package/lib/nameGenerators.js.map +1 -0
  28. package/lib/schema/getDefaultFormState.d.ts +8 -3
  29. package/lib/schema/getDefaultFormState.js +15 -6
  30. package/lib/schema/getDefaultFormState.js.map +1 -1
  31. package/lib/schema/retrieveSchema.d.ts +10 -5
  32. package/lib/schema/retrieveSchema.js +37 -14
  33. package/lib/schema/retrieveSchema.js.map +1 -1
  34. package/lib/shouldRenderOptionalField.d.ts +18 -0
  35. package/lib/shouldRenderOptionalField.js +47 -0
  36. package/lib/shouldRenderOptionalField.js.map +1 -0
  37. package/lib/toFieldPathId.d.ts +4 -2
  38. package/lib/toFieldPathId.js +10 -3
  39. package/lib/toFieldPathId.js.map +1 -1
  40. package/lib/tsconfig.tsbuildinfo +1 -1
  41. package/lib/types.d.ts +87 -43
  42. package/lib/useDeepCompareMemo.d.ts +8 -0
  43. package/lib/useDeepCompareMemo.js +17 -0
  44. package/lib/useDeepCompareMemo.js.map +1 -0
  45. package/lib/validationDataMerge.d.ts +2 -1
  46. package/lib/validationDataMerge.js +3 -2
  47. package/lib/validationDataMerge.js.map +1 -1
  48. package/package.json +1 -1
  49. package/src/ErrorSchemaBuilder.ts +2 -2
  50. package/src/createSchemaUtils.ts +6 -1
  51. package/src/enums.ts +6 -0
  52. package/src/idGenerators.ts +11 -1
  53. package/src/index.ts +15 -2
  54. package/src/isFormDataAvailable.ts +13 -0
  55. package/src/isRootSchema.ts +30 -0
  56. package/src/nameGenerators.ts +43 -0
  57. package/src/schema/getDefaultFormState.ts +20 -2
  58. package/src/schema/retrieveSchema.ts +39 -5
  59. package/src/shouldRenderOptionalField.ts +56 -0
  60. package/src/toFieldPathId.ts +12 -2
  61. package/src/types.ts +100 -47
  62. package/src/useDeepCompareMemo.ts +17 -0
  63. package/src/validationDataMerge.ts +7 -1
@@ -200,10 +200,14 @@ interface ComputeDefaultsProps<T = any, S extends StrictRJSFSchema = RJSFSchema>
200
200
  experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>;
201
201
  /** Optional flag, if true, indicates this schema was required in the parent schema. */
202
202
  required?: boolean;
203
+ /** Optional flag, if true, indicates this schema was required because it is the root. */
204
+ requiredAsRoot?: boolean;
203
205
  /** Optional flag, if true, It will merge defaults into formData.
204
206
  * The formData should take precedence unless it's not valid. This is useful when for example the value from formData does not exist in the schema 'enum' property, in such cases we take the value from the defaults because the value from the formData is not valid.
205
207
  */
206
208
  shouldMergeDefaultsIntoFormData?: boolean;
209
+ /** Indicates whether initial defaults have been generated */
210
+ initialDefaultsGenerated?: boolean;
207
211
  }
208
212
 
209
213
  /** Computes the defaults for the current `schema` given the `rawFormData` and `parentDefaults` if any. This drills into
@@ -229,6 +233,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
229
233
  experimental_customMergeAllOf = undefined,
230
234
  required,
231
235
  shouldMergeDefaultsIntoFormData = false,
236
+ initialDefaultsGenerated,
232
237
  } = computeDefaultsProps;
233
238
  let formData: T = (isObject(rawFormData) ? rawFormData : {}) as T;
234
239
  const schema: S = isObject(rawSchema) ? rawSchema : ({} as S);
@@ -363,6 +368,7 @@ export function computeDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema
363
368
  rawFormData: (rawFormData ?? formData) as T,
364
369
  required,
365
370
  shouldMergeDefaultsIntoFormData,
371
+ initialDefaultsGenerated,
366
372
  });
367
373
  }
368
374
 
@@ -463,6 +469,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
463
469
  experimental_customMergeAllOf = undefined,
464
470
  required,
465
471
  shouldMergeDefaultsIntoFormData,
472
+ initialDefaultsGenerated,
466
473
  }: ComputeDefaultsProps<T, S> = {},
467
474
  defaults?: T | T[],
468
475
  ): T {
@@ -498,6 +505,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
498
505
  rawFormData: get(formData, [key]),
499
506
  required: retrievedSchema.required?.includes(key),
500
507
  shouldMergeDefaultsIntoFormData,
508
+ initialDefaultsGenerated,
501
509
  });
502
510
 
503
511
  maybeAddDefaultToObject<T>(
@@ -515,7 +523,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
515
523
  },
516
524
  {},
517
525
  ) as T;
518
- if (retrievedSchema.additionalProperties) {
526
+ if (retrievedSchema.additionalProperties && !initialDefaultsGenerated) {
519
527
  // as per spec additionalProperties may be either schema or boolean
520
528
  const additionalPropertiesSchema = isObject(retrievedSchema.additionalProperties)
521
529
  ? retrievedSchema.additionalProperties
@@ -545,6 +553,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
545
553
  rawFormData: get(formData, [key]),
546
554
  required: retrievedSchema.required?.includes(key),
547
555
  shouldMergeDefaultsIntoFormData,
556
+ initialDefaultsGenerated,
548
557
  });
549
558
  // Since these are additional properties we don't need to add the `experimental_defaultFormStateBehavior` prop
550
559
  maybeAddDefaultToObject<T>(
@@ -579,7 +588,9 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
579
588
  experimental_defaultFormStateBehavior = undefined,
580
589
  experimental_customMergeAllOf = undefined,
581
590
  required,
591
+ requiredAsRoot = false,
582
592
  shouldMergeDefaultsIntoFormData,
593
+ initialDefaultsGenerated,
583
594
  }: ComputeDefaultsProps<T, S> = {},
584
595
  defaults?: T[],
585
596
  ): T[] | undefined {
@@ -608,6 +619,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
608
619
  parentDefaults: item,
609
620
  required,
610
621
  shouldMergeDefaultsIntoFormData,
622
+ initialDefaultsGenerated,
611
623
  });
612
624
  }) as T[];
613
625
  }
@@ -628,6 +640,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
628
640
  parentDefaults: get(defaults, [idx]),
629
641
  required,
630
642
  shouldMergeDefaultsIntoFormData,
643
+ initialDefaultsGenerated,
631
644
  });
632
645
  }) as T[];
633
646
 
@@ -661,7 +674,8 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
661
674
  computeSkipPopulate<T, S, F>(validator, schema, rootSchema) ||
662
675
  schema.minItems <= defaultsLength
663
676
  ) {
664
- arrayDefault = defaults ? defaults : emptyDefault;
677
+ // we don't want undefined defaults unless it is both not required or not required as root
678
+ arrayDefault = defaults || (!required && !requiredAsRoot) ? defaults : emptyDefault;
665
679
  } else {
666
680
  const defaultEntries: T[] = (defaults || []) as T[];
667
681
  const fillerSchema: S = getInnerSchemaForArrayItem<S>(schema, AdditionalItemsHandling.Invert);
@@ -727,6 +741,7 @@ export function getDefaultBasedOnSchemaType<
727
741
  * false when computing defaults for any nested object properties.
728
742
  * @param [experimental_defaultFormStateBehavior] Optional configuration object, if provided, allows users to override default form state behavior
729
743
  * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
744
+ * @param initialDefaultsGenerated - Optional flag, indicates whether or not initial defaults have been generated
730
745
  * @returns - The resulting `formData` with all the defaults provided
731
746
  */
732
747
  export default function getDefaultFormState<
@@ -741,6 +756,7 @@ export default function getDefaultFormState<
741
756
  includeUndefinedValues: boolean | 'excludeObjectChildren' = false,
742
757
  experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior,
743
758
  experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
759
+ initialDefaultsGenerated?: boolean,
744
760
  ) {
745
761
  if (!isObject(theSchema)) {
746
762
  throw new Error('Invalid schema: ' + theSchema);
@@ -757,6 +773,8 @@ export default function getDefaultFormState<
757
773
  experimental_customMergeAllOf,
758
774
  rawFormData: formData,
759
775
  shouldMergeDefaultsIntoFormData: true,
776
+ initialDefaultsGenerated,
777
+ requiredAsRoot: true,
760
778
  });
761
779
 
762
780
  if (schema.type !== 'object' && isObject(schema.default)) {
@@ -47,6 +47,7 @@ import isEmpty from 'lodash/isEmpty';
47
47
  * @param [rootSchema={}] - The root schema that will be forwarded to all the APIs
48
48
  * @param [rawFormData] - The current formData, if any, to assist retrieving a schema
49
49
  * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
50
+ * @param [resolveAnyOfOrOneOfRefs = false] - Optional flag indicating whether to resolved refs in anyOf/oneOf lists
50
51
  * @returns - The schema having its conditions, additional properties, references and dependencies resolved
51
52
  */
52
53
  export default function retrieveSchema<
@@ -59,6 +60,7 @@ export default function retrieveSchema<
59
60
  rootSchema: S = {} as S,
60
61
  rawFormData?: T,
61
62
  experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
63
+ resolveAnyOfOrOneOfRefs = false,
62
64
  ): S {
63
65
  return retrieveSchemaInternal<T, S, F>(
64
66
  validator,
@@ -68,6 +70,7 @@ export default function retrieveSchema<
68
70
  undefined,
69
71
  undefined,
70
72
  experimental_customMergeAllOf,
73
+ resolveAnyOfOrOneOfRefs,
71
74
  )[0];
72
75
  }
73
76
 
@@ -223,6 +226,7 @@ export function getMatchingPatternProperties<S extends StrictRJSFSchema = RJSFSc
223
226
  * @param recurseList - The list of recursive references already processed
224
227
  * @param [formData] - The current formData, if any, to assist retrieving a schema
225
228
  * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
229
+ * @param [resolveAnyOfOrOneOfRefs] - Optional flag indicating whether to resolved refs in anyOf/oneOf lists
226
230
  * @returns - The list of schemas having its references, dependencies and allOf schemas resolved
227
231
  */
228
232
  export function resolveSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
@@ -233,6 +237,7 @@ export function resolveSchema<T = any, S extends StrictRJSFSchema = RJSFSchema,
233
237
  recurseList: string[],
234
238
  formData?: T,
235
239
  experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
240
+ resolveAnyOfOrOneOfRefs?: boolean,
236
241
  ): S[] {
237
242
  const updatedSchemas = resolveReference<T, S, F>(
238
243
  validator,
@@ -242,6 +247,7 @@ export function resolveSchema<T = any, S extends StrictRJSFSchema = RJSFSchema,
242
247
  recurseList,
243
248
  formData,
244
249
  experimental_customMergeAllOf,
250
+ resolveAnyOfOrOneOfRefs,
245
251
  );
246
252
  if (updatedSchemas.length > 1 || updatedSchemas[0] !== schema) {
247
253
  // return the updatedSchemas array if it has either multiple schemas within it
@@ -270,7 +276,7 @@ export function resolveSchema<T = any, S extends StrictRJSFSchema = RJSFSchema,
270
276
  );
271
277
  });
272
278
  }
273
- if (ALL_OF_KEY in schema && Array.isArray(schema.allOf)) {
279
+ if (ALL_OF_KEY in schema && Array.isArray(schema[ALL_OF_KEY])) {
274
280
  const allOfSchemaElements: S[][] = schema.allOf.map((allOfSubschema) =>
275
281
  retrieveSchemaInternal<T, S, F>(
276
282
  validator,
@@ -304,6 +310,7 @@ export function resolveSchema<T = any, S extends StrictRJSFSchema = RJSFSchema,
304
310
  * @param recurseList - The list of recursive references already processed
305
311
  * @param [formData] - The current formData, if any, to assist retrieving a schema
306
312
  * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
313
+ * @param [resolveAnyOfOrOneOfRefs] - Optional flag indicating whether to resolved refs in anyOf/oneOf lists
307
314
  * @returns - The list schemas retrieved after having all references resolved
308
315
  */
309
316
  export function resolveReference<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
@@ -314,8 +321,9 @@ export function resolveReference<T = any, S extends StrictRJSFSchema = RJSFSchem
314
321
  recurseList: string[],
315
322
  formData?: T,
316
323
  experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
324
+ resolveAnyOfOrOneOfRefs?: boolean,
317
325
  ): S[] {
318
- const updatedSchema = resolveAllReferences<S>(schema, rootSchema, recurseList);
326
+ const updatedSchema = resolveAllReferences<S>(schema, rootSchema, recurseList, undefined, resolveAnyOfOrOneOfRefs);
319
327
  if (updatedSchema !== schema) {
320
328
  // Only call this if the schema was actually changed by the `resolveAllReferences()` function
321
329
  return retrieveSchemaInternal<T, S, F>(
@@ -326,6 +334,7 @@ export function resolveReference<T = any, S extends StrictRJSFSchema = RJSFSchem
326
334
  expandAllBranches,
327
335
  recurseList,
328
336
  experimental_customMergeAllOf,
337
+ resolveAnyOfOrOneOfRefs,
329
338
  );
330
339
  }
331
340
  return [schema];
@@ -337,6 +346,7 @@ export function resolveReference<T = any, S extends StrictRJSFSchema = RJSFSchem
337
346
  * @param rootSchema - The root schema that will be forwarded to all the APIs
338
347
  * @param recurseList - List of $refs already resolved to prevent recursion
339
348
  * @param [baseURI] - The base URI to be used for resolving relative references
349
+ * @param [resolveAnyOfOrOneOfRefs] - Optional flag indicating whether to resolved refs in anyOf/oneOf lists
340
350
  * @returns - given schema will all references resolved or the original schema if no internal `$refs` were resolved
341
351
  */
342
352
  export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(
@@ -344,6 +354,7 @@ export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(
344
354
  rootSchema: S,
345
355
  recurseList: string[],
346
356
  baseURI?: string,
357
+ resolveAnyOfOrOneOfRefs?: boolean,
347
358
  ): S {
348
359
  if (!isObject(schema)) {
349
360
  return schema;
@@ -371,7 +382,7 @@ export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(
371
382
  resolvedSchema[PROPERTIES_KEY]!,
372
383
  (result, value, key: string) => {
373
384
  const childList: string[] = [...recurseList];
374
- result[key] = resolveAllReferences(value as S, rootSchema, childList, baseURI);
385
+ result[key] = resolveAllReferences(value as S, rootSchema, childList, baseURI, resolveAnyOfOrOneOfRefs);
375
386
  childrenLists.push(childList);
376
387
  },
377
388
  {} as RJSFSchema,
@@ -387,10 +398,30 @@ export function resolveAllReferences<S extends StrictRJSFSchema = RJSFSchema>(
387
398
  ) {
388
399
  resolvedSchema = {
389
400
  ...resolvedSchema,
390
- items: resolveAllReferences(resolvedSchema.items as S, rootSchema, recurseList, baseURI),
401
+ items: resolveAllReferences(resolvedSchema.items as S, rootSchema, recurseList, baseURI, resolveAnyOfOrOneOfRefs),
391
402
  };
392
403
  }
393
404
 
405
+ if (resolveAnyOfOrOneOfRefs) {
406
+ let key: 'anyOf' | 'oneOf' | undefined;
407
+ let schemas: S[] | undefined;
408
+ if (ANY_OF_KEY in schema && Array.isArray(schema[ANY_OF_KEY])) {
409
+ key = ANY_OF_KEY;
410
+ schemas = resolvedSchema[ANY_OF_KEY] as S[];
411
+ } else if (ONE_OF_KEY in schema && Array.isArray(schema[ONE_OF_KEY])) {
412
+ key = ONE_OF_KEY;
413
+ schemas = resolvedSchema[ONE_OF_KEY] as S[];
414
+ }
415
+ if (key && schemas) {
416
+ resolvedSchema = {
417
+ ...resolvedSchema,
418
+ [key]: schemas.map((s: S) =>
419
+ resolveAllReferences(s, rootSchema, recurseList, baseURI, resolveAnyOfOrOneOfRefs),
420
+ ),
421
+ };
422
+ }
423
+ }
424
+
394
425
  return deepEquals(schema, resolvedSchema) ? schema : resolvedSchema;
395
426
  }
396
427
 
@@ -442,7 +473,7 @@ export function stubExistingAdditionalProperties<
442
473
  }
443
474
  }
444
475
  if (ADDITIONAL_PROPERTIES_KEY in schema && schema.additionalProperties !== false) {
445
- let additionalProperties: S['additionalProperties'] = {};
476
+ let additionalProperties: S['additionalProperties'];
446
477
  if (typeof schema.additionalProperties !== 'boolean') {
447
478
  if (REF_KEY in schema.additionalProperties!) {
448
479
  additionalProperties = retrieveSchema<T, S, F>(
@@ -494,6 +525,7 @@ export function stubExistingAdditionalProperties<
494
525
  * dependencies as a list of schemas
495
526
  * @param [recurseList=[]] - The optional, list of recursive references already processed
496
527
  * @param [experimental_customMergeAllOf] - Optional function that allows for custom merging of `allOf` schemas
528
+ * @param [resolveAnyOfOrOneOfRefs] - Optional flag indicating whether to resolved refs in anyOf/oneOf lists
497
529
  * @returns - The schema(s) resulting from having its conditions, additional properties, references and dependencies
498
530
  * resolved. Multiple schemas may be returned if `expandAllBranches` is true.
499
531
  */
@@ -509,6 +541,7 @@ export function retrieveSchemaInternal<
509
541
  expandAllBranches = false,
510
542
  recurseList: string[] = [],
511
543
  experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>,
544
+ resolveAnyOfOrOneOfRefs?: boolean,
512
545
  ): S[] {
513
546
  if (!isObject(schema)) {
514
547
  return [{} as S];
@@ -521,6 +554,7 @@ export function retrieveSchemaInternal<
521
554
  recurseList,
522
555
  rawFormData,
523
556
  experimental_customMergeAllOf,
557
+ resolveAnyOfOrOneOfRefs,
524
558
  );
525
559
  return resolvedSchemas.flatMap((s: S) => {
526
560
  let resolvedSchema = s;
@@ -0,0 +1,56 @@
1
+ import isObject from 'lodash/isObject';
2
+ import uniq from 'lodash/uniq';
3
+
4
+ import { FormContextType, Registry, RJSFSchema, StrictRJSFSchema, UiSchema } from './types';
5
+ import getSchemaType from './getSchemaType';
6
+ import getUiOptions from './getUiOptions';
7
+ import isRootSchema from './isRootSchema';
8
+ import { ANY_OF_KEY, ONE_OF_KEY } from './constants';
9
+
10
+ /** Returns the unique list of schema types for all of the options in a anyOf/oneOf
11
+ *
12
+ * @param schemas - The list of schemas representing the XxxOf options
13
+ * @returns - All of the unique types contained within the oneOf list
14
+ */
15
+ export function getSchemaTypesForXxxOf<S extends StrictRJSFSchema = RJSFSchema>(schemas: S[]): string | string[] {
16
+ const allTypes: string[] = uniq(
17
+ schemas
18
+ .map((s) => (isObject(s) ? getSchemaType(s) : undefined))
19
+ .flat()
20
+ .filter((t) => t !== undefined),
21
+ );
22
+ return allTypes.length === 1 ? allTypes[0] : allTypes;
23
+ }
24
+
25
+ /** Determines whether the field information from the combination of `schema` and `required` along with the
26
+ * `enableOptionalDataFieldForType` settings from the global UI options in the `registry` all indicate that this field
27
+ * should be rendered with the Optional Data Controls UI.
28
+ *
29
+ * @param registry - The `registry` object
30
+ * @param schema - The schema for the field
31
+ * @param required - Flag indicating whether the field is required
32
+ * @param [uiSchema] - The uiSchema for the field
33
+ * @return - True if the field should be rendered with the optional field UI, otherwise false
34
+ */
35
+ export default function shouldRenderOptionalField<
36
+ T = any,
37
+ S extends StrictRJSFSchema = RJSFSchema,
38
+ F extends FormContextType = any,
39
+ >(registry: Registry<T, S, F>, schema: S, required: boolean, uiSchema?: UiSchema<T, S, F>): boolean {
40
+ const { enableOptionalDataFieldForType = [] } = getUiOptions<T, S, F>(uiSchema, registry.globalUiOptions);
41
+ let schemaType: ReturnType<typeof getSchemaType<S>>;
42
+ if (ANY_OF_KEY in schema && Array.isArray(schema[ANY_OF_KEY])) {
43
+ schemaType = getSchemaTypesForXxxOf<S>(schema[ANY_OF_KEY] as S[]);
44
+ } else if (ONE_OF_KEY in schema && Array.isArray(schema[ONE_OF_KEY])) {
45
+ schemaType = getSchemaTypesForXxxOf<S>(schema[ONE_OF_KEY] as S[]);
46
+ } else {
47
+ schemaType = getSchemaType<S>(schema);
48
+ }
49
+ return (
50
+ !isRootSchema<T, S, F>(registry, schema) &&
51
+ !required &&
52
+ !!schemaType &&
53
+ !Array.isArray(schemaType) &&
54
+ !!enableOptionalDataFieldForType.find((val) => val === schemaType)
55
+ );
56
+ }
@@ -4,21 +4,31 @@ import { FieldPathId, FieldPathList, GlobalFormOptions } from './types';
4
4
  /** Constructs the `FieldPathId` for `fieldPath`. If `parentPathId` is provided, the `fieldPath` is appended to the end
5
5
  * of the parent path. Then the `ID_KEY` of the resulting `FieldPathId` is constructed from the `idPrefix` and
6
6
  * `idSeparator` contained within the `globalFormOptions`. If `fieldPath` is passed as an empty string, it will simply
7
- * generate the path from the `parentPath` (if provided) and the `idPrefix` and `idSeparator`
7
+ * generate the path from the `parentPath` (if provided) and the `idPrefix` and `idSeparator`. If a `nameGenerator`
8
+ * is provided in `globalFormOptions`, it will also generate the HTML `name` attribute.
8
9
  *
9
10
  * @param fieldPath - The property name or array index of the current field element
10
11
  * @param globalFormOptions - The `GlobalFormOptions` used to get the `idPrefix` and `idSeparator`
11
12
  * @param [parentPath] - The optional `FieldPathId` or `FieldPathList` of the parent element for this field element
13
+ * @param [isMultiValue] - Optional flag indicating this field accepts multiple values
12
14
  * @returns - The `FieldPathId` for the given `fieldPath` and the optional `parentPathId`
13
15
  */
14
16
  export default function toFieldPathId(
15
17
  fieldPath: string | number,
16
18
  globalFormOptions: GlobalFormOptions,
17
19
  parentPath?: FieldPathId | FieldPathList,
20
+ isMultiValue?: boolean,
18
21
  ): FieldPathId {
19
22
  const basePath = Array.isArray(parentPath) ? parentPath : parentPath?.path;
20
23
  const childPath = fieldPath === '' ? [] : [fieldPath];
21
24
  const path = basePath ? basePath.concat(...childPath) : childPath;
22
25
  const id = [globalFormOptions.idPrefix, ...path].join(globalFormOptions.idSeparator);
23
- return { path, [ID_KEY]: id };
26
+
27
+ // Generate name attribute if nameGenerator is provided
28
+ let name: string | undefined;
29
+ if (globalFormOptions.nameGenerator && path.length > 0) {
30
+ name = globalFormOptions.nameGenerator(path, globalFormOptions.idPrefix, isMultiValue);
31
+ }
32
+
33
+ return { path, [ID_KEY]: id, ...(name !== undefined && { name }) };
24
34
  }