@rjsf/utils 6.0.0-beta.16 → 6.0.0-beta.18

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.
package/lib/types.d.ts CHANGED
@@ -330,6 +330,21 @@ export type GlobalUISchemaOptions = GenericObjectType & {
330
330
  */
331
331
  enableMarkdownInDescription?: boolean;
332
332
  };
333
+ /** The set of options from the `Form` that will be available on the `Registry` for use in everywhere the `registry` is
334
+ * available.
335
+ */
336
+ export type GlobalFormOptions = {
337
+ /** To avoid collisions with existing ids in the DOM, it is possible to change the prefix used for ids;
338
+ * Default is `root`. This prop is passed to the `toIdSchema()` function within the RJSF field implementations.
339
+ */
340
+ readonly idPrefix?: string;
341
+ /** To avoid using a path separator that is present in field names, it is possible to change the separator used for
342
+ * ids; Default is `_`. This prop is passed to the `toIdSchema()` function within the RJSF field implementations.
343
+ */
344
+ readonly idSeparator?: string;
345
+ /** The component update strategy used by the Form and its fields for performance optimization */
346
+ readonly experimental_componentUpdateStrategy?: 'customDeep' | 'shallow' | 'always';
347
+ };
333
348
  /** The object containing the registered core, theme and custom fields and widgets as well as the root schema, form
334
349
  * context, schema utils and templates.
335
350
  */
@@ -338,7 +353,7 @@ export interface Registry<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
338
353
  * registered fields
339
354
  */
340
355
  fields: RegistryFieldsType<T, S, F>;
341
- /** The set of templates used by the `Form`. Includes templates from `core`, theme-specific fields and any custom
356
+ /** The set of templates used by the `Form`. Includes templates from `core`, theme-specific templates and any custom
342
357
  * registered templates
343
358
  */
344
359
  templates: TemplatesType<T, S, F>;
@@ -356,10 +371,10 @@ export interface Registry<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
356
371
  schemaUtils: SchemaUtilsType<T, S>;
357
372
  /** The string translation function to use when displaying any of the RJSF strings in templates, fields or widgets */
358
373
  translateString: (stringKey: TranslatableString, params?: string[]) => string;
374
+ /** The global Form Options that are available for all templates, fields and widgets to access */
375
+ readonly globalFormOptions: GlobalFormOptions;
359
376
  /** The optional global UI Options that are available for all templates, fields and widgets to access */
360
377
  globalUiOptions?: GlobalUISchemaOptions;
361
- /** The component update strategy used by the Form and its fields for performance optimization */
362
- experimental_componentUpdateStrategy?: 'customDeep' | 'shallow' | 'always';
363
378
  }
364
379
  /** The properties that are passed to a `Field` implementation */
365
380
  export interface FieldProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> extends GenericObjectType, RJSFBaseProps<T, S, F>, Pick<HTMLAttributes<HTMLElement>, Exclude<keyof HTMLAttributes<HTMLElement>, 'onBlur' | 'onFocus' | 'onChange'>> {
@@ -389,14 +404,6 @@ export interface FieldProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F
389
404
  required?: boolean;
390
405
  /** The unique name of the field, usually derived from the name of the property in the JSONSchema */
391
406
  name: string;
392
- /** To avoid collisions with existing ids in the DOM, it is possible to change the prefix used for ids;
393
- * Default is `root`
394
- */
395
- idPrefix?: string;
396
- /** To avoid using a path separator that is present in field names, it is possible to change the separator used for
397
- * ids (Default is `_`)
398
- */
399
- idSeparator?: string;
400
407
  /** An array of strings listing all generated error messages from encountered errors for this field */
401
408
  rawErrors?: string[];
402
409
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rjsf/utils",
3
- "version": "6.0.0-beta.16",
3
+ "version": "6.0.0-beta.18",
4
4
  "main": "dist/index.js",
5
5
  "module": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -84,6 +84,24 @@ export function getInnerSchemaForArrayItem<S extends StrictRJSFSchema = RJSFSche
84
84
  return {} as S;
85
85
  }
86
86
 
87
+ /** Checks if the given `schema` contains the `null` type along with another type AND if the `default` contained within
88
+ * the schema is `null` AND the `computedDefault` is empty. If all of those conditions are true, then the `schema`'s
89
+ * default should be `null` rather than `computedDefault`.
90
+ *
91
+ * @param schema - The schema to inspect
92
+ * @param computedDefault - The computed default for the schema
93
+ * @returns - Flag indicating whether a null should be returned instead of the computedDefault
94
+ */
95
+ export function computeDefaultBasedOnSchemaTypeAndDefaults<T = any, S extends StrictRJSFSchema = RJSFSchema>(
96
+ schema: S,
97
+ computedDefault: T,
98
+ ) {
99
+ const { default: schemaDefault, type } = schema;
100
+ const shouldReturnNullAsDefault =
101
+ Array.isArray(type) && type.includes('null') && isEmpty(computedDefault) && schemaDefault === null;
102
+ return shouldReturnNullAsDefault ? (null as T) : computedDefault;
103
+ }
104
+
87
105
  /** Either add `computedDefault` at `key` into `obj` or not add it based on its value, the value of
88
106
  * `includeUndefinedValues`, the value of `emptyObjectFields` and if its parent field is required. Generally undefined
89
107
  * `computedDefault` values are added only when `includeUndefinedValues` is either true/"excludeObjectChildren". If `
@@ -446,7 +464,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
446
464
  required,
447
465
  shouldMergeDefaultsIntoFormData,
448
466
  }: ComputeDefaultsProps<T, S> = {},
449
- defaults?: T | T[] | undefined,
467
+ defaults?: T | T[],
450
468
  ): T {
451
469
  {
452
470
  const formData: T = (isObject(rawFormData) ? rawFormData : {}) as T;
@@ -539,7 +557,7 @@ export function getObjectDefaults<T = any, S extends StrictRJSFSchema = RJSFSche
539
557
  );
540
558
  });
541
559
  }
542
- return objectDefaults;
560
+ return computeDefaultBasedOnSchemaTypeAndDefaults<T, S>(rawSchema, objectDefaults);
543
561
  }
544
562
  }
545
563
 
@@ -563,8 +581,8 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
563
581
  required,
564
582
  shouldMergeDefaultsIntoFormData,
565
583
  }: ComputeDefaultsProps<T, S> = {},
566
- defaults?: T | T[] | undefined,
567
- ): T | T[] | undefined {
584
+ defaults?: T[],
585
+ ): T[] | undefined {
568
586
  const schema: S = rawSchema;
569
587
 
570
588
  const arrayMinItemsStateBehavior = experimental_defaultFormStateBehavior?.arrayMinItems ?? {};
@@ -576,7 +594,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
576
594
  const computeSkipPopulate = arrayMinItemsStateBehavior?.computeSkipPopulate ?? (() => false);
577
595
  const isSkipEmptyDefaults = experimental_defaultFormStateBehavior?.emptyObjectFields === 'skipEmptyDefaults';
578
596
 
579
- const emptyDefault = isSkipEmptyDefaults ? undefined : [];
597
+ const emptyDefault: T[] | undefined = isSkipEmptyDefaults ? undefined : [];
580
598
 
581
599
  // Inject defaults into existing array defaults
582
600
  if (Array.isArray(defaults)) {
@@ -598,7 +616,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
598
616
  if (Array.isArray(rawFormData)) {
599
617
  const schemaItem: S = getInnerSchemaForArrayItem<S>(schema);
600
618
  if (neverPopulate) {
601
- defaults = rawFormData;
619
+ defaults = rawFormData as typeof defaults;
602
620
  } else {
603
621
  const itemDefaults = rawFormData.map((item: T, idx: number) => {
604
622
  return computeDefaults<T, S, F>(validator, schemaItem, {
@@ -635,6 +653,7 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
635
653
  }
636
654
  }
637
655
 
656
+ let arrayDefault: T[] | undefined;
638
657
  const defaultsLength = Array.isArray(defaults) ? defaults.length : 0;
639
658
  if (
640
659
  !schema.minItems ||
@@ -642,27 +661,29 @@ export function getArrayDefaults<T = any, S extends StrictRJSFSchema = RJSFSchem
642
661
  computeSkipPopulate<T, S, F>(validator, schema, rootSchema) ||
643
662
  schema.minItems <= defaultsLength
644
663
  ) {
645
- return defaults ? defaults : emptyDefault;
664
+ arrayDefault = defaults ? defaults : emptyDefault;
665
+ } else {
666
+ const defaultEntries: T[] = (defaults || []) as T[];
667
+ const fillerSchema: S = getInnerSchemaForArrayItem<S>(schema, AdditionalItemsHandling.Invert);
668
+ const fillerDefault = fillerSchema.default;
669
+
670
+ // Calculate filler entries for remaining items (minItems - existing raw data/defaults)
671
+ const fillerEntries: T[] = Array.from({ length: schema.minItems - defaultsLength }, () =>
672
+ computeDefaults<any, S, F>(validator, fillerSchema, {
673
+ parentDefaults: fillerDefault,
674
+ rootSchema,
675
+ _recurseList,
676
+ experimental_defaultFormStateBehavior,
677
+ experimental_customMergeAllOf,
678
+ required,
679
+ shouldMergeDefaultsIntoFormData,
680
+ }),
681
+ ) as T[];
682
+ // then fill up the rest with either the item default or empty, up to minItems
683
+ arrayDefault = defaultEntries.concat(fillerEntries);
646
684
  }
647
685
 
648
- const defaultEntries: T[] = (defaults || []) as T[];
649
- const fillerSchema: S = getInnerSchemaForArrayItem<S>(schema, AdditionalItemsHandling.Invert);
650
- const fillerDefault = fillerSchema.default;
651
-
652
- // Calculate filler entries for remaining items (minItems - existing raw data/defaults)
653
- const fillerEntries: T[] = Array.from({ length: schema.minItems - defaultsLength }, () =>
654
- computeDefaults<any, S, F>(validator, fillerSchema, {
655
- parentDefaults: fillerDefault,
656
- rootSchema,
657
- _recurseList,
658
- experimental_defaultFormStateBehavior,
659
- experimental_customMergeAllOf,
660
- required,
661
- shouldMergeDefaultsIntoFormData,
662
- }),
663
- ) as T[];
664
- // then fill up the rest with either the item default or empty, up to minItems
665
- return defaultEntries.concat(fillerEntries);
686
+ return computeDefaultBasedOnSchemaTypeAndDefaults<T[] | undefined, S>(rawSchema, arrayDefault);
666
687
  }
667
688
 
668
689
  /** Computes the default value based on the schema type.
@@ -689,7 +710,7 @@ export function getDefaultBasedOnSchemaType<
689
710
  return getObjectDefaults(validator, rawSchema, computeDefaultsProps, defaults);
690
711
  }
691
712
  case 'array': {
692
- return getArrayDefaults(validator, rawSchema, computeDefaultsProps, defaults);
713
+ return getArrayDefaults(validator, rawSchema, computeDefaultsProps, defaults as T[]);
693
714
  }
694
715
  }
695
716
  }
package/src/types.ts CHANGED
@@ -395,6 +395,22 @@ export type GlobalUISchemaOptions = GenericObjectType & {
395
395
  enableMarkdownInDescription?: boolean;
396
396
  };
397
397
 
398
+ /** The set of options from the `Form` that will be available on the `Registry` for use in everywhere the `registry` is
399
+ * available.
400
+ */
401
+ export type GlobalFormOptions = {
402
+ /** To avoid collisions with existing ids in the DOM, it is possible to change the prefix used for ids;
403
+ * Default is `root`. This prop is passed to the `toIdSchema()` function within the RJSF field implementations.
404
+ */
405
+ readonly idPrefix?: string;
406
+ /** To avoid using a path separator that is present in field names, it is possible to change the separator used for
407
+ * ids; Default is `_`. This prop is passed to the `toIdSchema()` function within the RJSF field implementations.
408
+ */
409
+ readonly idSeparator?: string;
410
+ /** The component update strategy used by the Form and its fields for performance optimization */
411
+ readonly experimental_componentUpdateStrategy?: 'customDeep' | 'shallow' | 'always';
412
+ };
413
+
398
414
  /** The object containing the registered core, theme and custom fields and widgets as well as the root schema, form
399
415
  * context, schema utils and templates.
400
416
  */
@@ -403,7 +419,7 @@ export interface Registry<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
403
419
  * registered fields
404
420
  */
405
421
  fields: RegistryFieldsType<T, S, F>;
406
- /** The set of templates used by the `Form`. Includes templates from `core`, theme-specific fields and any custom
422
+ /** The set of templates used by the `Form`. Includes templates from `core`, theme-specific templates and any custom
407
423
  * registered templates
408
424
  */
409
425
  templates: TemplatesType<T, S, F>;
@@ -421,10 +437,10 @@ export interface Registry<T = any, S extends StrictRJSFSchema = RJSFSchema, F ex
421
437
  schemaUtils: SchemaUtilsType<T, S>;
422
438
  /** The string translation function to use when displaying any of the RJSF strings in templates, fields or widgets */
423
439
  translateString: (stringKey: TranslatableString, params?: string[]) => string;
440
+ /** The global Form Options that are available for all templates, fields and widgets to access */
441
+ readonly globalFormOptions: GlobalFormOptions;
424
442
  /** The optional global UI Options that are available for all templates, fields and widgets to access */
425
443
  globalUiOptions?: GlobalUISchemaOptions;
426
- /** The component update strategy used by the Form and its fields for performance optimization */
427
- experimental_componentUpdateStrategy?: 'customDeep' | 'shallow' | 'always';
428
444
  }
429
445
 
430
446
  /** The properties that are passed to a `Field` implementation */
@@ -458,14 +474,6 @@ export interface FieldProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F
458
474
  required?: boolean;
459
475
  /** The unique name of the field, usually derived from the name of the property in the JSONSchema */
460
476
  name: string;
461
- /** To avoid collisions with existing ids in the DOM, it is possible to change the prefix used for ids;
462
- * Default is `root`
463
- */
464
- idPrefix?: string;
465
- /** To avoid using a path separator that is present in field names, it is possible to change the separator used for
466
- * ids (Default is `_`)
467
- */
468
- idSeparator?: string;
469
477
  /** An array of strings listing all generated error messages from encountered errors for this field */
470
478
  rawErrors?: string[];
471
479
  }