react-jsonschema-form
Advanced tools
Comparing version 1.5.0 to 1.6.0
@@ -482,2 +482,5 @@ "use strict"; | ||
readonly = _props4.readonly, | ||
required = _props4.required, | ||
label = _props4.label, | ||
placeholder = _props4.placeholder, | ||
autofocus = _props4.autofocus, | ||
@@ -514,5 +517,9 @@ onBlur = _props4.onBlur, | ||
schema: schema, | ||
registry: registry, | ||
value: items, | ||
disabled: disabled, | ||
readonly: readonly, | ||
required: required, | ||
label: label, | ||
placeholder: placeholder, | ||
formContext: formContext, | ||
@@ -519,0 +526,0 @@ autofocus: autofocus, |
@@ -23,6 +23,2 @@ "use strict"; | ||
var _keys = require("babel-runtime/core-js/object/keys"); | ||
var _keys2 = _interopRequireDefault(_keys); | ||
var _getPrototypeOf = require("babel-runtime/core-js/object/get-prototype-of"); | ||
@@ -62,4 +58,2 @@ | ||
var _validate = require("../../validate"); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
@@ -104,59 +98,12 @@ | ||
value: function getMatchingOption(formData, options) { | ||
for (var i = 0; i < options.length; i++) { | ||
var option = options[i]; | ||
var definitions = this.props.registry.definitions; | ||
// If the schema describes an object then we need to add slightly more | ||
// strict matching to the schema, because unless the schema uses the | ||
// "requires" keyword, an object will match the schema as long as it | ||
// doesn't have matching keys with a conflicting type. To do this we use an | ||
// "anyOf" with an array of requires. This augmentation expresses that the | ||
// schema should match if any of the keys in the schema are present on the | ||
// object and pass validation. | ||
if (option.properties) { | ||
// Create an "anyOf" schema that requires at least one of the keys in the | ||
// "properties" object | ||
var requiresAnyOf = { | ||
anyOf: (0, _keys2.default)(option.properties).map(function (key) { | ||
return { | ||
required: [key] | ||
}; | ||
}) | ||
}; | ||
var augmentedSchema = void 0; | ||
// If the "anyOf" keyword already exists, wrap the augmentation in an "allOf" | ||
if (option.anyOf) { | ||
// Create a shallow clone of the option | ||
var shallowClone = (0, _objectWithoutProperties3.default)(option, []); | ||
if (!shallowClone.allOf) { | ||
shallowClone.allOf = []; | ||
} else { | ||
// If "allOf" already exists, shallow clone the array | ||
shallowClone.allOf = shallowClone.allOf.slice(); | ||
} | ||
shallowClone.allOf.push(requiresAnyOf); | ||
augmentedSchema = shallowClone; | ||
} else { | ||
augmentedSchema = (0, _assign2.default)({}, option, requiresAnyOf); | ||
} | ||
// Remove the "required" field as it's likely that not all fields have | ||
// been filled in yet, which will mean that the schema is not valid | ||
delete augmentedSchema.required; | ||
if ((0, _validate.isValid)(augmentedSchema, formData)) { | ||
return i; | ||
} | ||
} else if ((0, _validate.isValid)(options[i], formData)) { | ||
return i; | ||
} | ||
var option = (0, _utils.getMatchingOption)(formData, options, definitions); | ||
if (option !== 0) { | ||
return option; | ||
} | ||
// If the form data matches none of the options, use the first option | ||
return 0; | ||
// If the form data matches none of the options, use the currently selected | ||
// option, assuming it's available; otherwise use the first option | ||
return this && this.state ? this.state.selectedOption : 0; | ||
} | ||
@@ -253,11 +200,13 @@ }, { | ||
onChange = _props2.onChange, | ||
options = _props2.options; | ||
options = _props2.options, | ||
registry = _props2.registry; | ||
var definitions = registry.definitions; | ||
var newOption = (0, _utils.retrieveSchema)(options[selectedOption], definitions, formData); | ||
var newOption = options[selectedOption]; | ||
// If the new option is of type object and the current data is an object, | ||
// discard properties added using the old option. | ||
var newFormData = undefined; | ||
if ((0, _utils.guessType)(formData) === "object" && (newOption.type === "object" || newOption.properties)) { | ||
var newFormData = (0, _assign2.default)({}, formData); | ||
newFormData = (0, _assign2.default)({}, formData); | ||
@@ -298,7 +247,5 @@ var optionsToDiscard = options.slice(); | ||
} | ||
onChange(newFormData); | ||
} else { | ||
onChange(undefined); | ||
} | ||
// Call getDefaultFormState to make sure defaults are populated on change. | ||
onChange((0, _utils.getDefaultFormState)(options[selectedOption], newFormData, definitions)); | ||
@@ -305,0 +252,0 @@ _this2.setState({ |
@@ -332,3 +332,3 @@ "use strict"; | ||
var disabled = Boolean(props.disabled || uiSchema["ui:disabled"]); | ||
var readonly = Boolean(props.readonly || uiSchema["ui:readonly"]); | ||
var readonly = Boolean(props.readonly || uiSchema["ui:readonly"] || props.schema.readOnly || schema.readOnly); | ||
var autofocus = Boolean(props.autofocus || uiSchema["ui:autofocus"]); | ||
@@ -430,2 +430,3 @@ if ((0, _keys2.default)(schema).length === 0) { | ||
safeRenderCompletion: props.safeRenderCompletion, | ||
schema: schema, | ||
uiSchema: uiSchema | ||
@@ -446,2 +447,3 @@ }), | ||
safeRenderCompletion: props.safeRenderCompletion, | ||
schema: schema, | ||
uiSchema: uiSchema | ||
@@ -448,0 +450,0 @@ }) |
@@ -51,3 +51,6 @@ "use strict"; | ||
var enumOptions = (0, _utils.isSelect)(schema) && (0, _utils.optionsList)(schema); | ||
var defaultWidget = format || (enumOptions ? "select" : "text"); | ||
var defaultWidget = enumOptions ? "select" : "text"; | ||
if (format && (0, _utils.hasWidget)(schema, format, widgets)) { | ||
defaultWidget = format; | ||
} | ||
@@ -54,0 +57,0 @@ var _getUiOptions = (0, _utils.getUiOptions)(uiSchema), |
@@ -139,3 +139,3 @@ "use strict"; | ||
}; | ||
(0, _utils.setState)(_this, state, function () { | ||
_this.setState(state, function () { | ||
if (multiple) { | ||
@@ -142,0 +142,0 @@ onChange(state.values); |
@@ -6,2 +6,3 @@ "use strict"; | ||
}); | ||
exports.withTheme = undefined; | ||
@@ -12,4 +13,9 @@ var _Form = require("./components/Form"); | ||
var _withTheme = require("./withTheme"); | ||
var _withTheme2 = _interopRequireDefault(_withTheme); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.withTheme = _withTheme2.default; | ||
exports.default = _Form2.default; |
124
lib/utils.js
@@ -59,2 +59,3 @@ "use strict"; | ||
exports.getWidget = getWidget; | ||
exports.hasWidget = hasWidget; | ||
exports.getDefaultFormState = getDefaultFormState; | ||
@@ -86,2 +87,3 @@ exports.getUiOptions = getUiOptions; | ||
exports.rangeSpec = rangeSpec; | ||
exports.getMatchingOption = getMatchingOption; | ||
@@ -92,5 +94,5 @@ var _react = require("react"); | ||
var _validate = require("./validate"); | ||
var _reactIs = require("react-is"); | ||
var _validate2 = _interopRequireDefault(_validate); | ||
var ReactIs = _interopRequireWildcard(_reactIs); | ||
@@ -101,2 +103,8 @@ var _fill = require("core-js/library/fn/array/fill"); | ||
var _validate = require("./validate"); | ||
var _validate2 = _interopRequireDefault(_validate); | ||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -179,2 +187,6 @@ | ||
if (!type && (schema.properties || schema.additionalProperties)) { | ||
return "object"; | ||
} | ||
if (type instanceof Array && type.length === 2 && type.includes("null")) { | ||
@@ -208,3 +220,3 @@ return type.find(function (type) { | ||
if (typeof widget === "function") { | ||
if (typeof widget === "function" || ReactIs.isForwardRef(widget)) { | ||
return mergeOptions(widget); | ||
@@ -234,5 +246,17 @@ } | ||
function computeDefaults(schema, parentDefaults) { | ||
var definitions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
function hasWidget(schema, widget) { | ||
var registeredWidgets = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
try { | ||
getWidget(schema, widget, registeredWidgets); | ||
return true; | ||
} catch (e) { | ||
if (e.message && (e.message.startsWith("No widget") || e.message.startsWith("Unsupported widget"))) { | ||
return false; | ||
} | ||
throw e; | ||
} | ||
} | ||
function computeDefaults(schema, parentDefaults, definitions, formData) { | ||
// Compute the defaults recursively: give highest priority to deepest nodes. | ||
@@ -250,8 +274,16 @@ var defaults = parentDefaults; | ||
var refSchema = findSchemaDefinition(schema.$ref, definitions); | ||
return computeDefaults(refSchema, defaults, definitions); | ||
return computeDefaults(refSchema, defaults, definitions, formData); | ||
} else if ("dependencies" in schema) { | ||
var resolvedSchema = resolveDependencies(schema, definitions, formData); | ||
return computeDefaults(resolvedSchema, defaults, definitions, formData); | ||
} else if (isFixedItems(schema)) { | ||
defaults = schema.items.map(function (itemSchema) { | ||
return computeDefaults(itemSchema, undefined, definitions); | ||
return computeDefaults(itemSchema, undefined, definitions, formData); | ||
}); | ||
} else if ("oneOf" in schema) { | ||
schema = schema.oneOf[getMatchingOption(undefined, schema.oneOf, definitions)]; | ||
} else if ("anyOf" in schema) { | ||
schema = schema.anyOf[getMatchingOption(undefined, schema.anyOf, definitions)]; | ||
} | ||
// Not defaults defined for this node, fallback to generic typed ones. | ||
@@ -268,3 +300,3 @@ if (typeof defaults === "undefined") { | ||
// have from a previous run: defaults[key]. | ||
acc[key] = computeDefaults(schema.properties[key], (defaults || {})[key], definitions); | ||
acc[key] = computeDefaults(schema.properties[key], (defaults || {})[key], definitions, (formData || {})[key]); | ||
return acc; | ||
@@ -287,3 +319,3 @@ }, {}); | ||
} else { | ||
return []; | ||
return defaults ? defaults : []; | ||
} | ||
@@ -302,3 +334,3 @@ } | ||
var schema = retrieveSchema(_schema, definitions, formData); | ||
var defaults = computeDefaults(schema, _schema.default, definitions); | ||
var defaults = computeDefaults(schema, _schema.default, definitions, formData); | ||
if (typeof formData === "undefined") { | ||
@@ -365,2 +397,5 @@ // No form data? Use schema defaults. | ||
} | ||
if (value === null) { | ||
return null; | ||
} | ||
if (/\.$/.test(value)) { | ||
@@ -651,4 +686,9 @@ // "3." can't really be considered a number even if it parses in js. The | ||
resolvedSchema = (0, _objectWithoutProperties3.default)(schema, ["dependencies"]); | ||
if ("oneOf" in resolvedSchema) { | ||
resolvedSchema = resolvedSchema.oneOf[getMatchingOption(formData, resolvedSchema.oneOf, definitions)]; | ||
} else if ("anyOf" in resolvedSchema) { | ||
resolvedSchema = resolvedSchema.anyOf[getMatchingOption(formData, resolvedSchema.anyOf, definitions)]; | ||
} | ||
// Process dependencies updating the local schema properties as appropriate. | ||
for (var dependencyKey in dependencies) { | ||
@@ -953,2 +993,64 @@ // Skip this dependency if its trigger property is not present. | ||
return spec; | ||
} | ||
function getMatchingOption(formData, options, definitions) { | ||
for (var i = 0; i < options.length; i++) { | ||
// Assign the definitions to the option, otherwise the match can fail if | ||
// the new option uses a $ref | ||
var option = (0, _assign2.default)({ | ||
definitions: definitions | ||
}, options[i]); | ||
// If the schema describes an object then we need to add slightly more | ||
// strict matching to the schema, because unless the schema uses the | ||
// "requires" keyword, an object will match the schema as long as it | ||
// doesn't have matching keys with a conflicting type. To do this we use an | ||
// "anyOf" with an array of requires. This augmentation expresses that the | ||
// schema should match if any of the keys in the schema are present on the | ||
// object and pass validation. | ||
if (option.properties) { | ||
// Create an "anyOf" schema that requires at least one of the keys in the | ||
// "properties" object | ||
var requiresAnyOf = { | ||
anyOf: (0, _keys2.default)(option.properties).map(function (key) { | ||
return { | ||
required: [key] | ||
}; | ||
}) | ||
}; | ||
var augmentedSchema = void 0; | ||
// If the "anyOf" keyword already exists, wrap the augmentation in an "allOf" | ||
if (option.anyOf) { | ||
// Create a shallow clone of the option | ||
var shallowClone = (0, _objectWithoutProperties3.default)(option, []); | ||
if (!shallowClone.allOf) { | ||
shallowClone.allOf = []; | ||
} else { | ||
// If "allOf" already exists, shallow clone the array | ||
shallowClone.allOf = shallowClone.allOf.slice(); | ||
} | ||
shallowClone.allOf.push(requiresAnyOf); | ||
augmentedSchema = shallowClone; | ||
} else { | ||
augmentedSchema = (0, _assign2.default)({}, option, requiresAnyOf); | ||
} | ||
// Remove the "required" field as it's likely that not all fields have | ||
// been filled in yet, which will mean that the schema is not valid | ||
delete augmentedSchema.required; | ||
if ((0, _validate.isValid)(augmentedSchema, formData)) { | ||
return i; | ||
} | ||
} else if ((0, _validate.isValid)(options[i], formData)) { | ||
return i; | ||
} | ||
} | ||
return 0; | ||
} |
@@ -54,3 +54,4 @@ "use strict"; | ||
multipleOfPrecision: 8, | ||
schemaId: "auto" | ||
schemaId: "auto", | ||
unknownFormats: "ignore" | ||
}); | ||
@@ -269,5 +270,3 @@ | ||
var unknownFormat = validationError && validationError.message && typeof validationError.message === "string" && validationError.message.includes("unknown format"); | ||
if (noProperMetaSchema || unknownFormat) { | ||
if (noProperMetaSchema) { | ||
errors = [].concat((0, _toConsumableArray3.default)(errors), [{ | ||
@@ -283,3 +282,3 @@ stack: validationError.message | ||
if (noProperMetaSchema || unknownFormat) { | ||
if (noProperMetaSchema) { | ||
errorSchema = (0, _extends7.default)({}, errorSchema, { | ||
@@ -286,0 +285,0 @@ $schema: { |
{ | ||
"name": "react-jsonschema-form", | ||
"version": "1.5.0", | ||
"version": "1.6.0", | ||
"description": "A simple React component capable of building HTML forms out of a JSON schema.", | ||
@@ -50,3 +50,4 @@ "scripts": { | ||
"lodash.topath": "^4.5.2", | ||
"prop-types": "^15.5.8" | ||
"prop-types": "^15.5.8", | ||
"react-is": "^16.8.4" | ||
}, | ||
@@ -53,0 +54,0 @@ "devDependencies": { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
1310573
46
6006
7
+ Addedreact-is@^16.8.4