Skip to content

Commit 19e143c

Browse files
Added new utility functions needed by LayoutGridForm (#4503)
* Added new utility functions needed by LayoutGridForm Adding new functions to `@rjsf/utils` to support the upcoming `LayoutGridForm` - Updated `@rjsf/utils` to add new types and functions in support of the `LayoutGridForm` - Updated the `utility-functions.md` documentation for the new functions - Updated the `v6.x upgrade guide.md` documentation for the new functions and types - Updated the `CHANGELOG_V6.md` for the new functions and types * - Fixed build and removed console.log * Update packages/utils/src/schema/findSelectedOptionInXxxOf.ts - Reviewer feedback
1 parent bdf1a2e commit 19e143c

25 files changed

+1252
-36
lines changed

CHANGELOG_v6.md

+16-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,22 @@ should change the heading of the (upcoming) version to include a major version b
6868
- BREAKING CHANGE: Added two the following new, required props to `TemplatesType`:
6969
- `ArrayFieldItemButtonsTemplate: ComponentType<ArrayFieldItemButtonsTemplateType<T, S, F>>;`
7070
- `GridTemplate: ComponentType<GridTemplateProps>`
71-
- Added a new `buttonId<T>(id: IdSchema<T> | string, btn: 'add' | 'copy' | 'moveDown' | 'moveUp' | 'remove')` used to generate consistent ids for RJSF buttons
71+
- BREAKING CHANGE: Updated the `SchemaUtilsType` to add new validator-based functions to the interface
72+
- Added the following new non-validator utility functions:
73+
- `buttonId<T>(id: IdSchema<T> | string, btn: 'add' | 'copy' | 'moveDown' | 'moveUp' | 'remove')`: used to generate consistent ids for RJSF buttons
74+
- `getTestIds(): TestIdShape`: Returns an object of test IDs that can only be used in test mode, helpful for writing unit tests for React components
75+
- `hashObject(object: unknown): string`: Stringifies an `object` and returns the hash of the resulting string
76+
- `hashString(string: string): string`: Hashes a string into hex format
77+
- `lookupFromFormContext<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(regOrFc: Registry<T, S, F> | Registry<T, S, F>['formContext'], toLookup: string, fallback?: unknown)`: Given a React JSON Schema Form registry or formContext object, return the value associated with `toLookup`
78+
- Added the following new validator-based utility functions:
79+
- `findFieldInSchema<T = undefined, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(validator: ValidatorType<T, S, F>, rootSchema: S, path: string | string[], schema: S, formData?: T, experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>): FoundFieldType<S>`: Finds the field specified by the `path` within the root or recursed `schema`
80+
- `findSelectedOptionInXxxOf<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(validator: ValidatorType<T, S, F>, rootSchema: S, schema: S, fallbackField: string,xxx: 'anyOf' | 'oneOf', formData?: T, experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>): S | undefined`: Finds the option that matches the selector field in the `schema` or undefined if nothing is selected
81+
- `getFromSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(validator: ValidatorType<T, S, F>, rootSchema: S, schema: S, path: string | string[], defaultValue: T | S, experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>): T | S`: Helper that acts like lodash's `get` but additionally retrieves `$ref`s as needed to get the path for schemas
82+
83+
84+
## @rjsf/validator-ajv6
85+
86+
- BREAKING CHANGE: This deprecated validator has been removed
7287

7388
## Dev / docs / playground
7489

packages/docs/docs/api-reference/utility-functions.md

+137-26
Original file line numberDiff line numberDiff line change
@@ -414,34 +414,51 @@ Extracts any `ui:submitButtonOptions` from the `uiSchema` and merges them onto t
414414

415415
- UISchemaSubmitButtonOptions: The merging of the `DEFAULT_OPTIONS` with any custom ones
416416

417-
### getUiOptions<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
417+
### getTemplate<Name extends keyof TemplatesType<T, S, F>, T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
418418

419-
Get all passed options from ui:options, and ui:&lt;optionName>, returning them in an object with the `ui:` stripped off.
420-
Any `globalOptions` will always be returned, unless they are overridden by options in the `uiSchema`.
419+
Returns the template with the given `name` from either the `uiSchema` if it is defined or from the `registry`
420+
otherwise. NOTE, since `ButtonTemplates` are not overridden in `uiSchema` only those in the `registry` are returned.
421421

422422
#### Parameters
423423

424-
- [uiSchema={}]: UiSchema<T, S, F> - The UI Schema from which to get any `ui:xxx` options
425-
- [globalOptions={}]: GlobalUISchemaOptions - The optional Global UI Schema from which to get any fallback `xxx` options
424+
- name: Name - The name of the template to fetch, restricted to the keys of `TemplatesType`
425+
- registry: Registry<T, S, F> - The `Registry` from which to read the template
426+
- [uiOptions={}]: UIOptionsType<T, S, F> - The `UIOptionsType` from which to read an alternate template
426427

427428
#### Returns
428429

429-
- UIOptionsType<T, S, F> An object containing all of the `ui:xxx` options with the `ui:` stripped off along with all `globalOptions`
430+
- TemplatesType<T, S, F>[Name] - The template from either the `uiSchema` or `registry` for the `name`
430431

431-
### getTemplate<Name extends keyof TemplatesType<T, S, F>, T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
432+
### getTestIds()
432433

433-
Returns the template with the given `name` from either the `uiSchema` if it is defined or from the `registry`
434-
otherwise. NOTE, since `ButtonTemplates` are not overridden in `uiSchema` only those in the `registry` are returned.
434+
Returns an object of test IDs that can only be used in test mode.
435+
If the function is called in a test environment (`NODE_ENV === 'test'`, this is set by jest) then a Proxy object will be returned.
436+
If a key within the returned object is accessed, if the value already exists the object will return that value, otherwise it will create that key
437+
with a generated `uuid` value and return the generated ID.
438+
If it is called outside of a test environment, the function will return an empty object, therefore returning `undefined` for any property within the object and excluding the prop from the rendered output of the component in which it is used.
439+
To use this helper, you will want to generate a separate object for each component to avoid potential overlapping of ID names.
440+
You will also want to export the object for use in tests, because the keys will be generated in the component file, and used in the test file.
441+
Within the component file, add: `export const TEST_IDS = getTestIds();`
442+
Then pass `TEST_IDS.examplePropertyName` as the value of the test ID attribute of the intended component.
443+
This will allow you to use `TEST_IDS.examplePropertyName` within your tests, while keeping the test IDs out of your rendered output.
444+
445+
#### Returns
446+
447+
- TestIdShape: An object that auto-generates test ids upon request the first time and then returns the same value on subsequent calls
448+
449+
### getUiOptions<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
450+
451+
Get all passed options from ui:options, and ui:&lt;optionName>, returning them in an object with the `ui:` stripped off.
452+
Any `globalOptions` will always be returned, unless they are overridden by options in the `uiSchema`.
435453

436454
#### Parameters
437455

438-
- name: Name - The name of the template to fetch, restricted to the keys of `TemplatesType`
439-
- registry: Registry<T, S, F> - The `Registry` from which to read the template
440-
- [uiOptions={}]: UIOptionsType<T, S, F> - The `UIOptionsType` from which to read an alternate template
456+
- [uiSchema={}]: UiSchema<T, S, F> - The UI Schema from which to get any `ui:xxx` options
457+
- [globalOptions={}]: GlobalUISchemaOptions - The optional Global UI Schema from which to get any fallback `xxx` options
441458

442459
#### Returns
443460

444-
- TemplatesType<T, S, F>[Name] - The template from either the `uiSchema` or `registry` for the `name`
461+
- UIOptionsType<T, S, F> An object containing all of the `ui:xxx` options with the `ui:` stripped off along with all `globalOptions`
445462

446463
### getWidget<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
447464

@@ -464,6 +481,31 @@ on the schema type and `widget` name. If no widget component can be found an `Er
464481

465482
- An error if there is no `Widget` component that can be returned
466483

484+
### hashObject()
485+
486+
Stringifies an `object` and returns the hash of the resulting string.
487+
Sorts object fields in consistent order before stringify to prevent different hash ids for the same object.
488+
489+
#### Parameters
490+
491+
- object: object - The object for which the hash is desired
492+
493+
#### Returns
494+
495+
- string: The string obtained from the hash of the stringified object
496+
497+
### hashString()
498+
499+
Hashes a string using the algorithm based on Java's hashing function.
500+
501+
#### Parameters
502+
503+
- string: string - The string for which to get the hash
504+
505+
#### Returns
506+
507+
- string: The resulting hash of the string in hex format
508+
467509
### guessType()
468510

469511
Given a specific `value` attempts to guess the type of a schema element. In the case where we have to implicitly
@@ -595,7 +637,23 @@ Converts a local Date string into a UTC date string
595637

596638
- string | undefined: A UTC date string if `dateString` is truthy, otherwise undefined
597639

598-
### mergeDefaultsWithFormData<T = any, S extends StrictRJSFSchema = RJSFSchema,>()
640+
### lookupFromFormContext<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
641+
642+
Given a React JSON Schema Form registry or formContext object, return the value associated with `toLookup`.
643+
This might be contained within the lookup map in the formContext.
644+
If no such value exists, return the `fallback` value.
645+
646+
#### Parameters
647+
648+
- regOrFc: Registry<T, S, F> | Registry<T, S, F>['formContext'] - The @rjsf registry or form context in which the lookup will occur
649+
- toLookup: string - The name of the field in the lookup map in the form context to get the value for
650+
- [fallback]: unknown - The fallback value to use if the form context does not contain a value for `toLookup`
651+
652+
#### Returns
653+
654+
- any: The value associated with `toLookup` in the form context or `fallback`
655+
656+
### mergeDefaultsWithFormData<T = any>()
599657

600658
Merges the `defaults` object of type `T` into the `formData` of type `T`
601659

@@ -924,6 +982,42 @@ This is used in isValid to make references to the rootSchema
924982

925983
## Validator-based utility functions
926984

985+
### findFieldInSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
986+
987+
Returns the superset of `formData` that includes the given set updated to include any missing fields that have computed to have defaults provided in the `schema`.
988+
989+
#### Parameters
990+
991+
- validator: ValidatorType<T, S, F> - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
992+
- rootSchema: S | undefined - The root schema that will be forwarded to all the APIs
993+
- schema: S - The node within the JSON schema in which to search
994+
- path: string | string[] - The keys in the path to the desired field
995+
- [formData={}]: T - The form data that is used to determine which anyOf/oneOf option to descend
996+
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop
997+
998+
#### Returns
999+
1000+
- FoundFieldType&lt;S>: An object that contains the field and its required state. If no field can be found then`{ field: undefined, isRequired: undefined }` is returned.
1001+
1002+
### findSelectedOptionInXxxOf<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
1003+
1004+
Finds the option inside the `schema['any/oneOf']` list which has the `properties[selectorField].default` or `properties[selectorField].const` that matches the `formData[selectorField]` value.
1005+
For the purposes of this function, `selectorField` is either `schema.discriminator.propertyName` or `fallbackField`.
1006+
1007+
#### Parameters
1008+
1009+
- validator: ValidatorType<T, S, F> - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
1010+
- rootSchema: S | undefined - The root schema that will be forwarded to all the APIs
1011+
- schema: S - The schema element in which to search for the selected anyOf/oneOf option
1012+
- fallbackField: string - The field to use as a backup selector field if the schema does not have a required field
1013+
- xxx: 'anyOf' | 'oneOf' - Either `anyOf` or `oneOf`, defines which value is being sought
1014+
- [formData={}]: T - The form data that is used to determine which anyOf/oneOf option to descend
1015+
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop
1016+
1017+
#### Returns
1018+
1019+
- S | undefined: The anyOf/oneOf option that matches the selector field in the schema or undefined if nothing is selected
1020+
9271021
### getDefaultFormState<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
9281022

9291023
Returns the superset of `formData` that includes the given set updated to include any missing fields that have computed to have defaults provided in the `schema`.
@@ -942,6 +1036,27 @@ Returns the superset of `formData` that includes the given set updated to includ
9421036

9431037
- T: The resulting `formData` with all the defaults provided
9441038

1039+
### getClosestMatchingOption<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
1040+
1041+
Determines which of the given `options` provided most closely matches the `formData`.
1042+
Returns the index of the option that is valid and is the closest match, or 0 if there is no match.
1043+
1044+
The closest match is determined using the number of matching properties, and more heavily favors options with matching readOnly, default, or const values.
1045+
1046+
#### Parameters
1047+
1048+
- validator: ValidatorType<T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
1049+
- rootSchema: S - The root schema, used to primarily to look up `$ref`s
1050+
- [formData]: T | undefined - The current formData, if any, used to figure out a match
1051+
- options: S[] - The list of options to find a matching options from
1052+
- [selectedOption=-1]: number - The index of the currently selected option, defaulted to -1 if not specified
1053+
- [discriminatorField]: string | undefined - The optional name of the field within the options object whose value is used to determine which option is selected
1054+
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop
1055+
1056+
#### Returns
1057+
1058+
- number: The index of the option that is the closest match to the `formData` or the `selectedOption` if no match
1059+
9451060
### getDisplayLabel<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
9461061

9471062
Determines whether the combination of `schema` and `uiSchema` properties indicates that the label for the `schema` should be displayed in a UI.
@@ -959,26 +1074,22 @@ Determines whether the combination of `schema` and `uiSchema` properties indicat
9591074

9601075
- boolean: True if the label should be displayed or false if it should not
9611076

962-
### getClosestMatchingOption<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
1077+
### getFromSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
9631078

964-
Determines which of the given `options` provided most closely matches the `formData`.
965-
Returns the index of the option that is valid and is the closest match, or 0 if there is no match.
966-
967-
The closest match is determined using the number of matching properties, and more heavily favors options with matching readOnly, default, or const values.
1079+
Helper that acts like lodash's `get` but additionally retrieves `$ref`s as needed to get the path for schemas containing potentially nested `$ref`s.
9681080

9691081
#### Parameters
9701082

971-
- validator: ValidatorType<T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
972-
- rootSchema: S - The root schema, used to primarily to look up `$ref`s
973-
- [formData]: T | undefined - The current formData, if any, used to figure out a match
974-
- options: S[] - The list of options to find a matching options from
975-
- [selectedOption=-1]: number - The index of the currently selected option, defaulted to -1 if not specified
976-
- [discriminatorField]: string | undefined - The optional name of the field within the options object whose value is used to determine which option is selected
1083+
- validator: ValidatorType<T, S, F> - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
1084+
- rootSchema: S - The root schema that will be forwarded to all the APIs
1085+
- schema: S - The current node within the JSON schema recursion
1086+
- path: string | string[] - The keys in the path to the desired field
1087+
- defaultValue: T | S - The value to return if a value is not found for the `pathList` path
9771088
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop
9781089

9791090
#### Returns
9801091

981-
- number: The index of the option that is the closest match to the `formData` or the `selectedOption` if no match
1092+
- T | S: The inner schema from the `schema` for the given `path` or the `defaultValue` if not found
9821093

9831094
### getFirstMatchingOption<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()
9841095

0 commit comments

Comments
 (0)