UNPKG

@rjsf/core

Version:

A simple React component capable of building HTML forms out of a JSON schema.

81 lines (80 loc) 3.99 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { getTemplate, getUiOptions, hashObject, toFieldPathId, TranslatableString, useDeepCompareMemo, } from '@rjsf/utils'; import { useMemo, useState } from 'react'; /** * Get the schema for the type selection component. * @param title - The translated title for the type selection schema. */ function getFallbackTypeSelectionSchema(title) { return { type: 'string', enum: ['string', 'number', 'boolean', 'object', 'array'], default: 'string', title: title, }; } /** * Determines the JSON Schema type of the given formData. * @param formData - The form data whose type is to be determined. */ function getTypeOfFormData(formData) { const dataType = typeof formData; if (dataType === 'string' || dataType === 'number' || dataType === 'boolean') { return dataType; } if (dataType === 'object') { return Array.isArray(formData) ? 'array' : 'object'; } // Treat everything else as a string return 'string'; } /** * Casts the given formData to the specified type. * @param formData - The form data to be casted. * @param newType - The target type to which the form data should be casted. */ function castToNewType(formData, newType) { switch (newType) { case 'string': return String(formData); case 'number': { const castedNumber = Number(formData); return (isNaN(castedNumber) ? 0 : castedNumber); } case 'boolean': return Boolean(formData); default: return formData; } } /** * The `FallbackField` component is used to render a field for unsupported or unknown schema types. If * `useFallbackUiForUnsupportedType` is enabled in the `globalUiOptions`, it provides a type selector */ export default function FallbackField(props) { const { id, formData, displayLabel = true, schema, name, uiSchema, required, disabled = false, readonly = false, onBlur, onFocus, registry, fieldPathId, onChange, errorSchema, } = props; const { translateString, fields, globalFormOptions } = registry; const [type, setType] = useState(getTypeOfFormData(formData)); const uiOptions = getUiOptions(uiSchema); const typeSelectorInnerFieldPathId = useDeepCompareMemo(toFieldPathId('__internal_type_selector', globalFormOptions, fieldPathId)); const schemaTitle = translateString(TranslatableString.Type); const typesOptionSchema = useMemo(() => getFallbackTypeSelectionSchema(schemaTitle), [schemaTitle]); const onTypeChange = (newType) => { if (newType != null) { setType(newType); onChange(castToNewType(formData, newType), fieldPathId.path, errorSchema, id); } }; if (!globalFormOptions.useFallbackUiForUnsupportedType) { const { reason = translateString(TranslatableString.UnknownFieldType, [String(schema.type)]) } = props; const UnsupportedFieldTemplate = getTemplate('UnsupportedFieldTemplate', registry, uiOptions); return _jsx(UnsupportedFieldTemplate, { schema: schema, fieldPathId: fieldPathId, reason: reason, registry: registry }); } const FallbackFieldTemplate = getTemplate('FallbackFieldTemplate', registry, uiOptions); const { SchemaField } = fields; return (_jsx(FallbackFieldTemplate, { schema: schema, registry: registry, typeSelector: _jsx(SchemaField, { fieldPathId: typeSelectorInnerFieldPathId, name: `${name}__fallback_type`, schema: typesOptionSchema, formData: type, onChange: onTypeChange, onBlur: onBlur, onFocus: onFocus, registry: registry, hideLabel: !displayLabel, disabled: disabled, readonly: readonly, required: required }, formData ? hashObject(formData) : '__empty__'), schemaField: _jsx(SchemaField, { ...props, schema: { type, title: translateString(TranslatableString.Value), ...(type === 'object' && { additionalProperties: true }), } }) })); }