@rjsf/utils
Version:
Utility functions for @rjsf/core
73 lines • 3.64 kB
JavaScript
import isEmpty from 'lodash-es/isEmpty.js';
import { ANY_OF_KEY, ONE_OF_KEY, REF_KEY, RJSF_REF_KEY } from './constants.js';
import findSchemaDefinition from './findSchemaDefinition.js';
import mergeObjects from './mergeObjects.js';
/** Resolves the uiSchema for a given schema, considering `ui:definitions` stored in the registry.
*
* Called at runtime for each field. When the schema contains a `$ref`, looks up the corresponding
* uiSchema definition from `registry.uiSchemaDefinitions` and merges it with local overrides.
* For schemas with `oneOf`/`anyOf` branches, also populates `uiSchema[keyword][i]` for branches
* whose `$ref` matches a definition, so `MultiSchemaField` can read dropdown option titles.
*
* Resolution order (later sources override earlier):
* 1. `ui:definitions[$ref]` - base definition from registry
* 2. `localUiSchema` - local overrides at current path
*
* @param schema - The JSON schema (may contain `$ref` or `RJSF_REF_KEY`)
* @param localUiSchema - The uiSchema at the current path (local overrides)
* @param registry - The registry containing `uiSchemaDefinitions`
* @returns - The resolved uiSchema with definitions merged in
*/
export default function resolveUiSchema(schema, localUiSchema, registry) {
var _a, _b;
const ref = ((_a = schema[RJSF_REF_KEY]) !== null && _a !== void 0 ? _a : schema[REF_KEY]);
const definitions = registry.uiSchemaDefinitions;
const definitionUiSchema = ref && definitions ? definitions[ref] : undefined;
let result;
if (!definitionUiSchema) {
result = localUiSchema || {};
}
else if (!localUiSchema || isEmpty(localUiSchema)) {
result = { ...definitionUiSchema };
}
else {
result = mergeObjects(definitionUiSchema, localUiSchema);
}
// Walk oneOf/anyOf branches to populate uiSchema[keyword][i] so MultiSchemaField
// can read dropdown option titles at the parent level.
if (definitions) {
let resolvedSchema = schema;
if (ref && schema[REF_KEY] && !schema[RJSF_REF_KEY]) {
try {
resolvedSchema = findSchemaDefinition(ref, registry.rootSchema);
}
catch (e) {
// oxlint-disable-next-line no-console
console.warn('could not resolve $ref in resolveUiSchema:\n', e);
return result;
}
}
for (const keyword of [ONE_OF_KEY, ANY_OF_KEY]) {
const schemaOptions = resolvedSchema[keyword];
if (Array.isArray(schemaOptions) && schemaOptions.length > 0) {
const currentUiSchemaArray = result[keyword];
const uiSchemaArray = Array.isArray(currentUiSchemaArray) ? [...currentUiSchemaArray] : [];
let hasExpanded = false;
for (let i = 0; i < schemaOptions.length; i++) {
const option = schemaOptions[i];
const optionRef = ((_b = option === null || option === void 0 ? void 0 : option[RJSF_REF_KEY]) !== null && _b !== void 0 ? _b : option === null || option === void 0 ? void 0 : option[REF_KEY]);
if (optionRef && optionRef in definitions) {
const optionUiSchema = (uiSchemaArray[i] || {});
uiSchemaArray[i] = mergeObjects(definitions[optionRef], optionUiSchema);
hasExpanded = true;
}
}
if (hasExpanded) {
result[keyword] = uiSchemaArray;
}
}
}
}
return result;
}
//# sourceMappingURL=resolveUiSchema.js.map