Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions packages/core/docs/advanced-customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -515,12 +515,13 @@ A field component will always be passed the following props:

#### The `registry` object

The `registry` is an object containing the registered custom fields and widgets as well as root schema definitions.
The `registry` is an object containing the registered custom fields and widgets as well as the root schema definitions.

- `fields`: The [custom registered fields](#custom-field-components). By default this object contains the standard `SchemaField`, `TitleField` and `DescriptionField` components;
- `widgets`: The [custom registered widgets](#custom-widget-components), if any;
- `definitions`: The root schema [definitions](#schema-definitions-and-references), if any.
- `formContext`: The [formContext](#the-formcontext-object) object.
- `rootSchema`: The root schema, which can contain referenced [definitions](#schema-definitions-and-references);
- `formContext`: The [formContext](#the-formcontext-object) object;
- `definitions` (deprecated since v2): Equal to `rootSchema.definitions`.

The registry is passed down the component tree, so you can access it from your custom field and `SchemaField` components.

Expand Down
5 changes: 1 addition & 4 deletions packages/core/docs/definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,4 @@ This library partially supports [inline schema definition dereferencing]( http:/
}
```

*(Sample schema courtesy of the [Space Telescope Science Institute](http://spacetelescope.github.io/understanding-json-schema/structuring.html))*

Note that it only supports local definition referencing; we do not plan on fetching foreign schemas over HTTP anytime soon. Basically, you can only reference a definition from the very schema object defining it.

Note that this library only supports local definition referencing. The value in the `$ref` keyword should be a [JSON Pointer](https://tools.ietf.org/html/rfc6901) in URI fragment identifier format.
5 changes: 5 additions & 0 deletions packages/core/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"@babel/runtime-corejs2": "^7.4.5",
"ajv": "^6.7.0",
"core-js": "^2.5.7",
"jsonpointer": "^4.0.1",
"json-schema-merge-allof": "^0.6.0",
"lodash": "^4.17.15",
"prop-types": "^15.7.2",
Expand Down
21 changes: 11 additions & 10 deletions packages/core/src/components/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ export default class Form extends Component {
const edit = typeof inputFormData !== "undefined";
const liveValidate = props.liveValidate || this.props.liveValidate;
const mustValidate = edit && !props.noValidate && liveValidate;
const { definitions } = schema;
const formData = getDefaultFormState(schema, inputFormData, definitions);
const retrievedSchema = retrieveSchema(schema, definitions, formData);
const rootSchema = schema;
const formData = getDefaultFormState(schema, inputFormData, rootSchema);
const retrievedSchema = retrieveSchema(schema, rootSchema, formData);
const customFormats = props.customFormats;
const additionalMetaSchemas = props.additionalMetaSchemas;
let { errors, errorSchema } = mustValidate
Expand All @@ -78,7 +78,7 @@ export default class Form extends Component {
const idSchema = toIdSchema(
retrievedSchema,
uiSchema["ui:rootFieldId"],
definitions,
rootSchema,
formData,
props.idPrefix
);
Expand All @@ -105,8 +105,8 @@ export default class Form extends Component {
customFormats = this.props.customFormats
) {
const { validate, transformErrors } = this.props;
const { definitions } = this.getRegistry();
const resolvedSchema = retrieveSchema(schema, definitions, formData);
const { rootSchema } = this.getRegistry();
const resolvedSchema = retrieveSchema(schema, rootSchema, formData);
return validateFormData(
formData,
resolvedSchema,
Expand Down Expand Up @@ -185,13 +185,13 @@ export default class Form extends Component {
if (this.props.omitExtraData === true && this.props.liveOmit === true) {
const retrievedSchema = retrieveSchema(
this.state.schema,
this.state.schema.definitions,
this.state.schema,
formData
);
const pathSchema = toPathSchema(
retrievedSchema,
"",
this.state.schema.definitions,
this.state.schema,
formData
);

Expand Down Expand Up @@ -250,13 +250,13 @@ export default class Form extends Component {
if (this.props.omitExtraData === true) {
const retrievedSchema = retrieveSchema(
this.state.schema,
this.state.schema.definitions,
this.state.schema,
newFormData
);
const pathSchema = toPathSchema(
retrievedSchema,
"",
this.state.schema.definitions,
this.state.schema,
newFormData
);

Expand Down Expand Up @@ -317,6 +317,7 @@ export default class Form extends Component {
ObjectFieldTemplate: this.props.ObjectFieldTemplate,
FieldTemplate: this.props.FieldTemplate,
definitions: this.props.schema.definitions || {},
rootSchema: this.props.schema,
formContext: this.props.formContext || {},
};
}
Expand Down
32 changes: 16 additions & 16 deletions packages/core/src/components/fields/ArrayField.js
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,12 @@ class ArrayField extends Component {

_getNewFormDataRow = () => {
const { schema, registry = getDefaultRegistry() } = this.props;
const { definitions } = registry;
const { rootSchema } = registry;
let itemSchema = schema.items;
if (isFixedItems(schema) && allowAdditionalItems(schema)) {
itemSchema = schema.additionalItems;
}
return getDefaultFormState(itemSchema, undefined, definitions);
return getDefaultFormState(itemSchema, undefined, rootSchema);
};

onAddClick = event => {
Expand Down Expand Up @@ -425,7 +425,7 @@ class ArrayField extends Component {
idSchema,
registry = getDefaultRegistry(),
} = this.props;
const { definitions } = registry;
const { rootSchema } = registry;
if (!schema.hasOwnProperty("items")) {
return (
<UnsupportedField
Expand All @@ -438,10 +438,10 @@ class ArrayField extends Component {
if (isFixedItems(schema)) {
return this.renderFixedArray();
}
if (isFilesArray(schema, uiSchema, definitions)) {
if (isFilesArray(schema, uiSchema, rootSchema)) {
return this.renderFiles();
}
if (isMultiSelect(schema, definitions)) {
if (isMultiSelect(schema, rootSchema)) {
return this.renderMultiSelect();
}
return this.renderNormalArray();
Expand All @@ -465,21 +465,21 @@ class ArrayField extends Component {
rawErrors,
} = this.props;
const title = schema.title === undefined ? name : schema.title;
const { ArrayFieldTemplate, definitions, fields, formContext } = registry;
const { ArrayFieldTemplate, rootSchema, fields, formContext } = registry;
const { TitleField, DescriptionField } = fields;
const itemsSchema = retrieveSchema(schema.items, definitions);
const itemsSchema = retrieveSchema(schema.items, rootSchema);
const formData = keyedToPlainFormData(this.state.keyedFormData);
const arrayProps = {
canAdd: this.canAddItem(formData),
items: this.state.keyedFormData.map((keyedItem, index) => {
const { key, item } = keyedItem;
const itemSchema = retrieveSchema(schema.items, definitions, item);
const itemSchema = retrieveSchema(schema.items, rootSchema, item);
const itemErrorSchema = errorSchema ? errorSchema[index] : undefined;
const itemIdPrefix = idSchema.$id + "_" + index;
const itemIdSchema = toIdSchema(
itemSchema,
itemIdPrefix,
definitions,
rootSchema,
item,
idPrefix
);
Expand Down Expand Up @@ -541,8 +541,8 @@ class ArrayField extends Component {
rawErrors,
} = this.props;
const items = this.props.formData;
const { widgets, definitions, formContext } = registry;
const itemsSchema = retrieveSchema(schema.items, definitions, formData);
const { widgets, rootSchema, formContext } = registry;
const itemsSchema = retrieveSchema(schema.items, rootSchema, formData);
const enumOptions = optionsList(itemsSchema);
const { widget = "select", ...options } = {
...getUiOptions(uiSchema),
Expand Down Expand Up @@ -631,13 +631,13 @@ class ArrayField extends Component {
} = this.props;
const title = schema.title || name;
let items = this.props.formData;
const { ArrayFieldTemplate, definitions, fields, formContext } = registry;
const { ArrayFieldTemplate, rootSchema, fields, formContext } = registry;
const { TitleField } = fields;
const itemSchemas = schema.items.map((item, index) =>
retrieveSchema(item, definitions, formData[index])
retrieveSchema(item, rootSchema, formData[index])
);
const additionalSchema = allowAdditionalItems(schema)
? retrieveSchema(schema.additionalItems, definitions, formData)
? retrieveSchema(schema.additionalItems, rootSchema, formData)
: null;

if (!items || items.length < itemSchemas.length) {
Expand All @@ -657,13 +657,13 @@ class ArrayField extends Component {
const { key, item } = keyedItem;
const additional = index >= itemSchemas.length;
const itemSchema = additional
? retrieveSchema(schema.additionalItems, definitions, item)
? retrieveSchema(schema.additionalItems, rootSchema, item)
: itemSchemas[index];
const itemIdPrefix = idSchema.$id + "_" + index;
const itemIdSchema = toIdSchema(
itemSchema,
itemIdPrefix,
definitions,
rootSchema,
item,
idPrefix
);
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/components/fields/MultiSchemaField.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ class AnyOfField extends Component {
}

getMatchingOption(formData, options) {
const { definitions } = this.props.registry;
const { rootSchema } = this.props.registry;

let option = getMatchingOption(formData, options, definitions);
let option = getMatchingOption(formData, options, rootSchema);
if (option !== 0) {
return option;
}
Expand All @@ -57,10 +57,10 @@ class AnyOfField extends Component {
onOptionChange = option => {
const selectedOption = parseInt(option, 10);
const { formData, onChange, options, registry } = this.props;
const { definitions } = registry;
const { rootSchema } = registry;
const newOption = retrieveSchema(
options[selectedOption],
definitions,
rootSchema,
formData
);

Expand Down Expand Up @@ -89,7 +89,7 @@ class AnyOfField extends Component {
}
// Call getDefaultFormState to make sure defaults are populated on change.
onChange(
getDefaultFormState(options[selectedOption], newFormData, definitions)
getDefaultFormState(options[selectedOption], newFormData, rootSchema)
);

this.setState({
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/components/fields/ObjectField.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ class ObjectField extends Component {
const { registry = getDefaultRegistry() } = this.props;
const refSchema = retrieveSchema(
{ $ref: schema.additionalProperties["$ref"] },
registry.definitions,
registry.rootSchema,
this.props.formData
);

Expand Down Expand Up @@ -210,9 +210,9 @@ class ObjectField extends Component {
registry = getDefaultRegistry(),
} = this.props;

const { definitions, fields, formContext } = registry;
const { rootSchema, fields, formContext } = registry;
const { SchemaField, TitleField, DescriptionField } = fields;
const schema = retrieveSchema(this.props.schema, definitions, formData);
const schema = retrieveSchema(this.props.schema, rootSchema, formData);

// If this schema has a title defined, but the user has set a new key/label, retain their input.
let title;
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/components/fields/SchemaField.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,13 @@ function SchemaFieldRender(props) {
registry = getDefaultRegistry(),
wasPropertyKeyModified = false,
} = props;
const { definitions, fields, formContext } = registry;
const { rootSchema, fields, formContext } = registry;
const FieldTemplate =
uiSchema["ui:FieldTemplate"] || registry.FieldTemplate || DefaultTemplate;
let idSchema = props.idSchema;
const schema = retrieveSchema(props.schema, definitions, formData);
const schema = retrieveSchema(props.schema, rootSchema, formData);
idSchema = mergeObjects(
toIdSchema(schema, null, definitions, formData, idPrefix),
toIdSchema(schema, null, rootSchema, formData, idPrefix),
idSchema
);
const FieldComponent = getFieldComponent(schema, uiSchema, idSchema, fields);
Expand All @@ -264,8 +264,8 @@ function SchemaFieldRender(props) {
let { label: displayLabel = true } = uiOptions;
if (schema.type === "array") {
displayLabel =
isMultiSelect(schema, definitions) ||
isFilesArray(schema, uiSchema, definitions);
isMultiSelect(schema, rootSchema) ||
isFilesArray(schema, uiSchema, rootSchema);
}
if (schema.type === "object") {
displayLabel = false;
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const registry = PropTypes.shape({
FieldTemplate: PropTypes.elementType,
ObjectFieldTemplate: PropTypes.elementType,
definitions: PropTypes.object.isRequired,
rootSchema: PropTypes.object,
fields: PropTypes.objectOf(PropTypes.elementType).isRequired,
formContext: PropTypes.object.isRequired,
widgets: PropTypes.objectOf(
Expand Down
Loading