/
CustomSchemaField.js
142 lines (128 loc) · 3.89 KB
/
CustomSchemaField.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import React, {PropTypes} from 'react';
import {
isMultiSelect,
retrieveSchema,
getDefaultRegistry,
isFilesArray
} from 'react-jsonschema-form/lib/utils';
import ArrayField from '../fields/ArrayField';
import BooleanField from '../fields/BooleanField';
import NumberField from '../fields/NumberField';
import ObjectField from '../fields/ObjectField';
import StringField from '../fields/StringField';
import UnsupportedField from '../fields/UnsupportedField';
import DescriptionField from '../fields/DescriptionField';
import Help from './Help';
import ErrorList from './ErrorList';
import DefaultTemplate from './DefaultTemplate';
const COMPONENT_TYPES = {
array: ArrayField,
boolean: BooleanField,
integer: NumberField,
number: NumberField,
object: ObjectField,
string: StringField,
};
function getFieldComponent(schema, uiSchema, fields) {
const field = uiSchema['ui:field'];
if (typeof field === 'function') {
return field;
}
if (typeof field === 'string' && field in fields) {
return fields[field];
}
return COMPONENT_TYPES[schema.type] || UnsupportedField;
}
function SchemaField(props) {
const {uiSchema, errorSchema, idSchema, name, required, registry} = props;
const {definitions, fields, formContext, FieldTemplate = DefaultTemplate} = registry;
const schema = retrieveSchema(props.schema, definitions);
const FieldComponent = getFieldComponent(schema, uiSchema, fields);
const disabled = Boolean(props.disabled || uiSchema['ui:disabled']);
const readonly = Boolean(props.readonly || uiSchema['ui:readonly']);
const autofocus = Boolean(props.autofocus || uiSchema['ui:autofocus']);
if (Object.keys(schema).length === 0) {
// See #312: Ensure compatibility with old versions of React.
return <div />;
}
let displayLabel = true;
if (schema.type === 'array') {
displayLabel = isMultiSelect(schema) || isFilesArray(schema, uiSchema);
}
if (schema.type === 'object') {
displayLabel = false;
}
if (schema.type === 'boolean' && !uiSchema['ui:widget']) {
displayLabel = false;
}
if (uiSchema['ui:field']) {
displayLabel = false;
}
const field = (
<FieldComponent {...props}
schema={schema}
disabled={disabled}
readonly={readonly}
autofocus={autofocus}
formContext={formContext}
/>
);
const {type} = schema;
const id = idSchema.$id;
const label = props.schema.title || schema.title || name;
const description = props.schema.description || schema.description;
const errors = errorSchema.__errors;
const help = uiSchema['ui:help'];
const hidden = uiSchema['ui:widget'] === 'hidden';
const classNames = [
'form-group',
'field',
`field-${type}`,
errors && errors.length > 0 ? 'field-error has-error' : '',
uiSchema.classNames,
].join(' ').trim();
const fieldProps = {
description: <DescriptionField id={id + '__description'}
description={description}
formContext={formContext}
/>,
help: <Help help={help} />,
errors: <ErrorList errors={errors} />,
id,
label,
hidden,
required,
readonly,
displayLabel,
classNames,
formContext,
};
return <FieldTemplate {...fieldProps}>{field}</FieldTemplate>;
}
SchemaField.defaultProps = {
uiSchema: {},
errorSchema: {},
idSchema: {},
registry: getDefaultRegistry(),
disabled: false,
readonly: false,
autofocus: false,
};
SchemaField.propTypes = {
schema: PropTypes.object.isRequired,
uiSchema: PropTypes.object,
idSchema: PropTypes.object,
formData: PropTypes.any,
errorSchema: PropTypes.object,
registry: PropTypes.shape({
widgets: PropTypes.objectOf(PropTypes.oneOfType([
PropTypes.func,
PropTypes.object,
])).isRequired,
fields: PropTypes.objectOf(PropTypes.func).isRequired,
definitions: PropTypes.object.isRequired,
FieldTemplate: PropTypes.func,
formContext: PropTypes.object.isRequired,
})
};
export default SchemaField;