@rjsf/core 5.11.2 → 5.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core.umd.js +3464 -0
- package/dist/index.esm.js +3814 -0
- package/dist/index.esm.js.map +7 -0
- package/dist/index.js +3714 -5
- package/dist/index.js.map +7 -0
- package/{dist/index.d.ts → lib/components/Form.d.ts} +321 -337
- package/lib/components/Form.js +474 -0
- package/lib/components/Form.js.map +1 -0
- package/lib/components/fields/ArrayField.d.ts +179 -0
- package/lib/components/fields/ArrayField.js +568 -0
- package/lib/components/fields/ArrayField.js.map +1 -0
- package/lib/components/fields/BooleanField.d.ts +9 -0
- package/lib/components/fields/BooleanField.js +62 -0
- package/lib/components/fields/BooleanField.js.map +1 -0
- package/lib/components/fields/MultiSchemaField.d.ts +47 -0
- package/lib/components/fields/MultiSchemaField.js +129 -0
- package/lib/components/fields/MultiSchemaField.js.map +1 -0
- package/lib/components/fields/NullField.d.ts +8 -0
- package/lib/components/fields/NullField.js +17 -0
- package/lib/components/fields/NullField.js.map +1 -0
- package/lib/components/fields/NumberField.d.ts +21 -0
- package/lib/components/fields/NumberField.js +70 -0
- package/lib/components/fields/NumberField.js.map +1 -0
- package/lib/components/fields/ObjectField.d.ts +73 -0
- package/lib/components/fields/ObjectField.js +222 -0
- package/lib/components/fields/ObjectField.js.map +1 -0
- package/lib/components/fields/SchemaField.d.ts +10 -0
- package/lib/components/fields/SchemaField.js +172 -0
- package/lib/components/fields/SchemaField.js.map +1 -0
- package/lib/components/fields/StringField.d.ts +8 -0
- package/lib/components/fields/StringField.js +25 -0
- package/lib/components/fields/StringField.js.map +1 -0
- package/lib/components/fields/index.d.ts +3 -0
- package/lib/components/fields/index.js +24 -0
- package/lib/components/fields/index.js.map +1 -0
- package/lib/components/templates/ArrayFieldDescriptionTemplate.d.ts +8 -0
- package/lib/components/templates/ArrayFieldDescriptionTemplate.js +18 -0
- package/lib/components/templates/ArrayFieldDescriptionTemplate.js.map +1 -0
- package/lib/components/templates/ArrayFieldItemTemplate.d.ts +7 -0
- package/lib/components/templates/ArrayFieldItemTemplate.js +20 -0
- package/lib/components/templates/ArrayFieldItemTemplate.js.map +1 -0
- package/lib/components/templates/ArrayFieldTemplate.d.ts +7 -0
- package/lib/components/templates/ArrayFieldTemplate.js +22 -0
- package/lib/components/templates/ArrayFieldTemplate.js.map +1 -0
- package/lib/components/templates/ArrayFieldTitleTemplate.d.ts +8 -0
- package/lib/components/templates/ArrayFieldTitleTemplate.js +18 -0
- package/lib/components/templates/ArrayFieldTitleTemplate.js.map +1 -0
- package/lib/components/templates/BaseInputTemplate.d.ts +9 -0
- package/lib/components/templates/BaseInputTemplate.js +39 -0
- package/lib/components/templates/BaseInputTemplate.js.map +1 -0
- package/lib/components/templates/ButtonTemplates/AddButton.d.ts +5 -0
- package/lib/components/templates/ButtonTemplates/AddButton.js +10 -0
- package/lib/components/templates/ButtonTemplates/AddButton.js.map +1 -0
- package/lib/components/templates/ButtonTemplates/IconButton.d.ts +7 -0
- package/lib/components/templates/ButtonTemplates/IconButton.js +24 -0
- package/lib/components/templates/ButtonTemplates/IconButton.js.map +1 -0
- package/lib/components/templates/ButtonTemplates/SubmitButton.d.ts +5 -0
- package/lib/components/templates/ButtonTemplates/SubmitButton.js +12 -0
- package/lib/components/templates/ButtonTemplates/SubmitButton.js.map +1 -0
- package/lib/components/templates/ButtonTemplates/index.d.ts +3 -0
- package/lib/components/templates/ButtonTemplates/index.js +15 -0
- package/lib/components/templates/ButtonTemplates/index.js.map +1 -0
- package/lib/components/templates/DescriptionField.d.ts +7 -0
- package/lib/components/templates/DescriptionField.js +18 -0
- package/lib/components/templates/DescriptionField.js.map +1 -0
- package/lib/components/templates/ErrorList.d.ts +7 -0
- package/lib/components/templates/ErrorList.js +13 -0
- package/lib/components/templates/ErrorList.js.map +1 -0
- package/lib/components/templates/FieldErrorTemplate.d.ts +7 -0
- package/lib/components/templates/FieldErrorTemplate.js +19 -0
- package/lib/components/templates/FieldErrorTemplate.js.map +1 -0
- package/lib/components/templates/FieldHelpTemplate.d.ts +7 -0
- package/lib/components/templates/FieldHelpTemplate.js +18 -0
- package/lib/components/templates/FieldHelpTemplate.js.map +1 -0
- package/lib/components/templates/FieldTemplate/FieldTemplate.d.ts +8 -0
- package/lib/components/templates/FieldTemplate/FieldTemplate.js +18 -0
- package/lib/components/templates/FieldTemplate/FieldTemplate.js.map +1 -0
- package/lib/components/templates/FieldTemplate/Label.d.ts +14 -0
- package/lib/components/templates/FieldTemplate/Label.js +14 -0
- package/lib/components/templates/FieldTemplate/Label.js.map +1 -0
- package/lib/components/templates/FieldTemplate/index.d.ts +2 -0
- package/lib/components/templates/FieldTemplate/index.js +3 -0
- package/lib/components/templates/FieldTemplate/index.js.map +1 -0
- package/lib/components/templates/ObjectFieldTemplate.d.ts +9 -0
- package/lib/components/templates/ObjectFieldTemplate.js +18 -0
- package/lib/components/templates/ObjectFieldTemplate.js.map +1 -0
- package/lib/components/templates/TitleField.d.ts +7 -0
- package/lib/components/templates/TitleField.js +11 -0
- package/lib/components/templates/TitleField.js.map +1 -0
- package/lib/components/templates/UnsupportedField.d.ts +9 -0
- package/lib/components/templates/UnsupportedField.js +28 -0
- package/lib/components/templates/UnsupportedField.js.map +1 -0
- package/lib/components/templates/WrapIfAdditionalTemplate.d.ts +8 -0
- package/lib/components/templates/WrapIfAdditionalTemplate.js +21 -0
- package/lib/components/templates/WrapIfAdditionalTemplate.js.map +1 -0
- package/lib/components/templates/index.d.ts +3 -0
- package/lib/components/templates/index.js +36 -0
- package/lib/components/templates/index.js.map +1 -0
- package/lib/components/widgets/AltDateTimeWidget.d.ts +9 -0
- package/lib/components/widgets/AltDateTimeWidget.js +14 -0
- package/lib/components/widgets/AltDateTimeWidget.js.map +1 -0
- package/lib/components/widgets/AltDateWidget.d.ts +7 -0
- package/lib/components/widgets/AltDateWidget.js +77 -0
- package/lib/components/widgets/AltDateWidget.js.map +1 -0
- package/lib/components/widgets/CheckboxWidget.d.ts +9 -0
- package/lib/components/widgets/CheckboxWidget.js +23 -0
- package/lib/components/widgets/CheckboxWidget.js.map +1 -0
- package/lib/components/widgets/CheckboxesWidget.d.ts +9 -0
- package/lib/components/widgets/CheckboxesWidget.js +31 -0
- package/lib/components/widgets/CheckboxesWidget.js.map +1 -0
- package/lib/components/widgets/ColorWidget.d.ts +8 -0
- package/lib/components/widgets/ColorWidget.js +13 -0
- package/lib/components/widgets/ColorWidget.js.map +1 -0
- package/lib/components/widgets/DateTimeWidget.d.ts +8 -0
- package/lib/components/widgets/DateTimeWidget.js +13 -0
- package/lib/components/widgets/DateTimeWidget.js.map +1 -0
- package/lib/components/widgets/DateWidget.d.ts +8 -0
- package/lib/components/widgets/DateWidget.js +15 -0
- package/lib/components/widgets/DateWidget.js.map +1 -0
- package/lib/components/widgets/EmailWidget.d.ts +7 -0
- package/lib/components/widgets/EmailWidget.js +12 -0
- package/lib/components/widgets/EmailWidget.js.map +1 -0
- package/lib/components/widgets/FileWidget.d.ts +8 -0
- package/lib/components/widgets/FileWidget.js +105 -0
- package/lib/components/widgets/FileWidget.js.map +1 -0
- package/lib/components/widgets/HiddenWidget.d.ts +9 -0
- package/lib/components/widgets/HiddenWidget.js +11 -0
- package/lib/components/widgets/HiddenWidget.js.map +1 -0
- package/lib/components/widgets/PasswordWidget.d.ts +7 -0
- package/lib/components/widgets/PasswordWidget.js +12 -0
- package/lib/components/widgets/PasswordWidget.js.map +1 -0
- package/lib/components/widgets/RadioWidget.d.ts +9 -0
- package/lib/components/widgets/RadioWidget.js +24 -0
- package/lib/components/widgets/RadioWidget.js.map +1 -0
- package/lib/components/widgets/RangeWidget.d.ts +8 -0
- package/lib/components/widgets/RangeWidget.js +11 -0
- package/lib/components/widgets/RangeWidget.js.map +1 -0
- package/lib/components/widgets/SelectWidget.d.ts +9 -0
- package/lib/components/widgets/SelectWidget.js +41 -0
- package/lib/components/widgets/SelectWidget.js.map +1 -0
- package/lib/components/widgets/TextWidget.d.ts +7 -0
- package/lib/components/widgets/TextWidget.js +12 -0
- package/lib/components/widgets/TextWidget.js.map +1 -0
- package/lib/components/widgets/TextareaWidget.d.ts +14 -0
- package/lib/components/widgets/TextareaWidget.js +19 -0
- package/lib/components/widgets/TextareaWidget.js.map +1 -0
- package/lib/components/widgets/TimeWidget.d.ts +8 -0
- package/lib/components/widgets/TimeWidget.js +15 -0
- package/lib/components/widgets/TimeWidget.js.map +1 -0
- package/lib/components/widgets/URLWidget.d.ts +7 -0
- package/lib/components/widgets/URLWidget.js +12 -0
- package/lib/components/widgets/URLWidget.js.map +1 -0
- package/lib/components/widgets/UpDownWidget.d.ts +7 -0
- package/lib/components/widgets/UpDownWidget.js +12 -0
- package/lib/components/widgets/UpDownWidget.js.map +1 -0
- package/lib/components/widgets/index.d.ts +3 -0
- package/lib/components/widgets/index.js +44 -0
- package/lib/components/widgets/index.js.map +1 -0
- package/lib/getDefaultRegistry.d.ts +6 -0
- package/lib/getDefaultRegistry.js +19 -0
- package/lib/getDefaultRegistry.js.map +1 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.js +6 -0
- package/lib/index.js.map +1 -0
- package/lib/withTheme.d.ts +9 -0
- package/lib/withTheme.js +16 -0
- package/lib/withTheme.js.map +1 -0
- package/package.json +23 -16
- package/src/components/Form.tsx +853 -0
- package/src/components/fields/ArrayField.tsx +875 -0
- package/src/components/fields/BooleanField.tsx +114 -0
- package/src/components/fields/MultiSchemaField.tsx +221 -0
- package/src/components/fields/NullField.tsx +22 -0
- package/src/components/fields/NumberField.tsx +86 -0
- package/src/components/fields/ObjectField.tsx +331 -0
- package/src/components/fields/SchemaField.tsx +360 -0
- package/src/components/fields/StringField.tsx +71 -0
- package/src/components/fields/index.ts +31 -0
- package/src/components/templates/ArrayFieldDescriptionTemplate.tsx +41 -0
- package/src/components/templates/ArrayFieldItemTemplate.tsx +90 -0
- package/src/components/templates/ArrayFieldTemplate.tsx +88 -0
- package/src/components/templates/ArrayFieldTitleTemplate.tsx +43 -0
- package/src/components/templates/BaseInputTemplate.tsx +102 -0
- package/src/components/templates/ButtonTemplates/AddButton.tsx +29 -0
- package/src/components/templates/ButtonTemplates/IconButton.tsx +77 -0
- package/src/components/templates/ButtonTemplates/SubmitButton.tsx +21 -0
- package/src/components/templates/ButtonTemplates/index.ts +22 -0
- package/src/components/templates/DescriptionField.tsx +29 -0
- package/src/components/templates/ErrorList.tsx +35 -0
- package/src/components/templates/FieldErrorTemplate.tsx +33 -0
- package/src/components/templates/FieldHelpTemplate.tsx +29 -0
- package/src/components/templates/FieldTemplate/FieldTemplate.tsx +41 -0
- package/src/components/templates/FieldTemplate/Label.tsx +27 -0
- package/src/components/templates/FieldTemplate/index.ts +3 -0
- package/src/components/templates/ObjectFieldTemplate.tsx +83 -0
- package/src/components/templates/TitleField.tsx +19 -0
- package/src/components/templates/UnsupportedField.tsx +37 -0
- package/src/components/templates/WrapIfAdditionalTemplate.tsx +80 -0
- package/src/components/templates/index.ts +43 -0
- package/src/components/widgets/AltDateTimeWidget.tsx +16 -0
- package/src/components/widgets/AltDateWidget.tsx +198 -0
- package/src/components/widgets/CheckboxWidget.tsx +92 -0
- package/src/components/widgets/CheckboxesWidget.tsx +92 -0
- package/src/components/widgets/ColorWidget.tsx +14 -0
- package/src/components/widgets/DateTimeWidget.tsx +31 -0
- package/src/components/widgets/DateWidget.tsx +17 -0
- package/src/components/widgets/EmailWidget.tsx +13 -0
- package/src/components/widgets/FileWidget.tsx +178 -0
- package/src/components/widgets/HiddenWidget.tsx +15 -0
- package/src/components/widgets/PasswordWidget.tsx +15 -0
- package/src/components/widgets/RadioWidget.tsx +88 -0
- package/src/components/widgets/RangeWidget.tsx +23 -0
- package/src/components/widgets/SelectWidget.tsx +100 -0
- package/src/components/widgets/TextWidget.tsx +13 -0
- package/src/components/widgets/TextareaWidget.tsx +61 -0
- package/src/components/widgets/TimeWidget.tsx +17 -0
- package/src/components/widgets/URLWidget.tsx +13 -0
- package/src/components/widgets/UpDownWidget.tsx +13 -0
- package/src/components/widgets/index.ts +51 -0
- package/src/getDefaultRegistry.ts +24 -0
- package/src/index.ts +8 -0
- package/src/withTheme.tsx +42 -0
- package/dist/core.cjs.development.js +0 -4403
- package/dist/core.cjs.development.js.map +0 -1
- package/dist/core.cjs.production.min.js +0 -2
- package/dist/core.cjs.production.min.js.map +0 -1
- package/dist/core.esm.js +0 -4383
- package/dist/core.esm.js.map +0 -1
- package/dist/core.umd.development.js +0 -4393
- package/dist/core.umd.development.js.map +0 -1
- package/dist/core.umd.production.min.js +0 -2
- package/dist/core.umd.production.min.js.map +0 -1
package/dist/core.umd.js
ADDED
|
@@ -0,0 +1,3464 @@
|
|
|
1
|
+
(function (global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@rjsf/utils'), require('lodash/get'), require('lodash/isEmpty'), require('lodash/pick'), require('lodash/toPath'), require('lodash/cloneDeep'), require('lodash/isObject'), require('lodash/set'), require('nanoid'), require('react/jsx-runtime'), require('lodash/omit'), require('lodash/unset'), require('markdown-to-jsx'), require('lodash/has')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'react', '@rjsf/utils', 'lodash/get', 'lodash/isEmpty', 'lodash/pick', 'lodash/toPath', 'lodash/cloneDeep', 'lodash/isObject', 'lodash/set', 'nanoid', 'react/jsx-runtime', 'lodash/omit', 'lodash/unset', 'markdown-to-jsx', 'lodash/has'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.JSONSchemaForm = {}, global.react, global.utils, global.get3, global.isEmpty, global._pick, global._toPath, global.cloneDeep, global.isObject, global.set, global.nanoid, global.jsxRuntime, global.omit2, global.unset, global.Markdown, global.has));
|
|
5
|
+
})(this, (function (exports, react, utils, get3, isEmpty, _pick, _toPath, cloneDeep, isObject, set, nanoid, jsxRuntime, omit2, unset, Markdown, has) { 'use strict';
|
|
6
|
+
|
|
7
|
+
// src/components/Form.tsx
|
|
8
|
+
function generateRowId() {
|
|
9
|
+
return nanoid.nanoid();
|
|
10
|
+
}
|
|
11
|
+
function generateKeyedFormData(formData) {
|
|
12
|
+
return !Array.isArray(formData) ? [] : formData.map((item) => {
|
|
13
|
+
return {
|
|
14
|
+
key: generateRowId(),
|
|
15
|
+
item
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function keyedToPlainFormData(keyedFormData) {
|
|
20
|
+
if (Array.isArray(keyedFormData)) {
|
|
21
|
+
return keyedFormData.map((keyedItem) => keyedItem.item);
|
|
22
|
+
}
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
var ArrayField = class extends react.Component {
|
|
26
|
+
/** Constructs an `ArrayField` from the `props`, generating the initial keyed data from the `formData`
|
|
27
|
+
*
|
|
28
|
+
* @param props - The `FieldProps` for this template
|
|
29
|
+
*/
|
|
30
|
+
constructor(props) {
|
|
31
|
+
super(props);
|
|
32
|
+
/** Returns the default form information for an item based on the schema for that item. Deals with the possibility
|
|
33
|
+
* that the schema is fixed and allows additional items.
|
|
34
|
+
*/
|
|
35
|
+
this._getNewFormDataRow = () => {
|
|
36
|
+
const { schema, registry } = this.props;
|
|
37
|
+
const { schemaUtils } = registry;
|
|
38
|
+
let itemSchema = schema.items;
|
|
39
|
+
if (utils.isFixedItems(schema) && utils.allowAdditionalItems(schema)) {
|
|
40
|
+
itemSchema = schema.additionalItems;
|
|
41
|
+
}
|
|
42
|
+
return schemaUtils.getDefaultFormState(itemSchema);
|
|
43
|
+
};
|
|
44
|
+
/** Callback handler for when the user clicks on the add button. Creates a new row of keyed form data at the end of
|
|
45
|
+
* the list, adding it into the state, and then returning `onChange()` with the plain form data converted from the
|
|
46
|
+
* keyed data
|
|
47
|
+
*
|
|
48
|
+
* @param event - The event for the click
|
|
49
|
+
*/
|
|
50
|
+
this.onAddClick = (event) => {
|
|
51
|
+
this._handleAddClick(event);
|
|
52
|
+
};
|
|
53
|
+
/** Callback handler for when the user clicks on the add button on an existing array element. Creates a new row of
|
|
54
|
+
* keyed form data inserted at the `index`, adding it into the state, and then returning `onChange()` with the plain
|
|
55
|
+
* form data converted from the keyed data
|
|
56
|
+
*
|
|
57
|
+
* @param index - The index at which the add button is clicked
|
|
58
|
+
*/
|
|
59
|
+
this.onAddIndexClick = (index) => {
|
|
60
|
+
return (event) => {
|
|
61
|
+
this._handleAddClick(event, index);
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
/** Callback handler for when the user clicks on the copy button on an existing array element. Clones the row of
|
|
65
|
+
* keyed form data at the `index` into the next position in the state, and then returning `onChange()` with the plain
|
|
66
|
+
* form data converted from the keyed data
|
|
67
|
+
*
|
|
68
|
+
* @param index - The index at which the copy button is clicked
|
|
69
|
+
*/
|
|
70
|
+
this.onCopyIndexClick = (index) => {
|
|
71
|
+
return (event) => {
|
|
72
|
+
if (event) {
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
}
|
|
75
|
+
const { onChange } = this.props;
|
|
76
|
+
const { keyedFormData } = this.state;
|
|
77
|
+
const newKeyedFormDataRow = {
|
|
78
|
+
key: generateRowId(),
|
|
79
|
+
item: cloneDeep(keyedFormData[index].item)
|
|
80
|
+
};
|
|
81
|
+
const newKeyedFormData = [...keyedFormData];
|
|
82
|
+
if (index !== void 0) {
|
|
83
|
+
newKeyedFormData.splice(index + 1, 0, newKeyedFormDataRow);
|
|
84
|
+
} else {
|
|
85
|
+
newKeyedFormData.push(newKeyedFormDataRow);
|
|
86
|
+
}
|
|
87
|
+
this.setState(
|
|
88
|
+
{
|
|
89
|
+
keyedFormData: newKeyedFormData,
|
|
90
|
+
updatedKeyedFormData: true
|
|
91
|
+
},
|
|
92
|
+
() => onChange(keyedToPlainFormData(newKeyedFormData))
|
|
93
|
+
);
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
/** Callback handler for when the user clicks on the remove button on an existing array element. Removes the row of
|
|
97
|
+
* keyed form data at the `index` in the state, and then returning `onChange()` with the plain form data converted
|
|
98
|
+
* from the keyed data
|
|
99
|
+
*
|
|
100
|
+
* @param index - The index at which the remove button is clicked
|
|
101
|
+
*/
|
|
102
|
+
this.onDropIndexClick = (index) => {
|
|
103
|
+
return (event) => {
|
|
104
|
+
if (event) {
|
|
105
|
+
event.preventDefault();
|
|
106
|
+
}
|
|
107
|
+
const { onChange, errorSchema } = this.props;
|
|
108
|
+
const { keyedFormData } = this.state;
|
|
109
|
+
let newErrorSchema;
|
|
110
|
+
if (errorSchema) {
|
|
111
|
+
newErrorSchema = {};
|
|
112
|
+
for (const idx in errorSchema) {
|
|
113
|
+
const i = parseInt(idx);
|
|
114
|
+
if (i < index) {
|
|
115
|
+
set(newErrorSchema, [i], errorSchema[idx]);
|
|
116
|
+
} else if (i > index) {
|
|
117
|
+
set(newErrorSchema, [i - 1], errorSchema[idx]);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const newKeyedFormData = keyedFormData.filter((_, i) => i !== index);
|
|
122
|
+
this.setState(
|
|
123
|
+
{
|
|
124
|
+
keyedFormData: newKeyedFormData,
|
|
125
|
+
updatedKeyedFormData: true
|
|
126
|
+
},
|
|
127
|
+
() => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
|
|
128
|
+
);
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
/** Callback handler for when the user clicks on one of the move item buttons on an existing array element. Moves the
|
|
132
|
+
* row of keyed form data at the `index` to the `newIndex` in the state, and then returning `onChange()` with the
|
|
133
|
+
* plain form data converted from the keyed data
|
|
134
|
+
*
|
|
135
|
+
* @param index - The index of the item to move
|
|
136
|
+
* @param newIndex - The index to where the item is to be moved
|
|
137
|
+
*/
|
|
138
|
+
this.onReorderClick = (index, newIndex) => {
|
|
139
|
+
return (event) => {
|
|
140
|
+
if (event) {
|
|
141
|
+
event.preventDefault();
|
|
142
|
+
event.currentTarget.blur();
|
|
143
|
+
}
|
|
144
|
+
const { onChange, errorSchema } = this.props;
|
|
145
|
+
let newErrorSchema;
|
|
146
|
+
if (errorSchema) {
|
|
147
|
+
newErrorSchema = {};
|
|
148
|
+
for (const idx in errorSchema) {
|
|
149
|
+
const i = parseInt(idx);
|
|
150
|
+
if (i == index) {
|
|
151
|
+
set(newErrorSchema, [newIndex], errorSchema[index]);
|
|
152
|
+
} else if (i == newIndex) {
|
|
153
|
+
set(newErrorSchema, [index], errorSchema[newIndex]);
|
|
154
|
+
} else {
|
|
155
|
+
set(newErrorSchema, [idx], errorSchema[i]);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const { keyedFormData } = this.state;
|
|
160
|
+
function reOrderArray() {
|
|
161
|
+
const _newKeyedFormData = keyedFormData.slice();
|
|
162
|
+
_newKeyedFormData.splice(index, 1);
|
|
163
|
+
_newKeyedFormData.splice(newIndex, 0, keyedFormData[index]);
|
|
164
|
+
return _newKeyedFormData;
|
|
165
|
+
}
|
|
166
|
+
const newKeyedFormData = reOrderArray();
|
|
167
|
+
this.setState(
|
|
168
|
+
{
|
|
169
|
+
keyedFormData: newKeyedFormData
|
|
170
|
+
},
|
|
171
|
+
() => onChange(keyedToPlainFormData(newKeyedFormData), newErrorSchema)
|
|
172
|
+
);
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
/** Callback handler used to deal with changing the value of the data in the array at the `index`. Calls the
|
|
176
|
+
* `onChange` callback with the updated form data
|
|
177
|
+
*
|
|
178
|
+
* @param index - The index of the item being changed
|
|
179
|
+
*/
|
|
180
|
+
this.onChangeForIndex = (index) => {
|
|
181
|
+
return (value, newErrorSchema, id) => {
|
|
182
|
+
const { formData, onChange, errorSchema } = this.props;
|
|
183
|
+
const arrayData = Array.isArray(formData) ? formData : [];
|
|
184
|
+
const newFormData = arrayData.map((item, i) => {
|
|
185
|
+
const jsonValue = typeof value === "undefined" ? null : value;
|
|
186
|
+
return index === i ? jsonValue : item;
|
|
187
|
+
});
|
|
188
|
+
onChange(
|
|
189
|
+
newFormData,
|
|
190
|
+
errorSchema && errorSchema && {
|
|
191
|
+
...errorSchema,
|
|
192
|
+
[index]: newErrorSchema
|
|
193
|
+
},
|
|
194
|
+
id
|
|
195
|
+
);
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
/** Callback handler used to change the value for a checkbox */
|
|
199
|
+
this.onSelectChange = (value) => {
|
|
200
|
+
const { onChange, idSchema } = this.props;
|
|
201
|
+
onChange(value, void 0, idSchema && idSchema.$id);
|
|
202
|
+
};
|
|
203
|
+
const { formData = [] } = props;
|
|
204
|
+
const keyedFormData = generateKeyedFormData(formData);
|
|
205
|
+
this.state = {
|
|
206
|
+
keyedFormData,
|
|
207
|
+
updatedKeyedFormData: false
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/** React lifecycle method that is called when the props are about to change allowing the state to be updated. It
|
|
211
|
+
* regenerates the keyed form data and returns it
|
|
212
|
+
*
|
|
213
|
+
* @param nextProps - The next set of props data
|
|
214
|
+
* @param prevState - The previous set of state data
|
|
215
|
+
*/
|
|
216
|
+
static getDerivedStateFromProps(nextProps, prevState) {
|
|
217
|
+
if (prevState.updatedKeyedFormData) {
|
|
218
|
+
return {
|
|
219
|
+
updatedKeyedFormData: false
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
const nextFormData = Array.isArray(nextProps.formData) ? nextProps.formData : [];
|
|
223
|
+
const previousKeyedFormData = prevState.keyedFormData || [];
|
|
224
|
+
const newKeyedFormData = nextFormData.length === previousKeyedFormData.length ? previousKeyedFormData.map((previousKeyedFormDatum, index) => {
|
|
225
|
+
return {
|
|
226
|
+
key: previousKeyedFormDatum.key,
|
|
227
|
+
item: nextFormData[index]
|
|
228
|
+
};
|
|
229
|
+
}) : generateKeyedFormData(nextFormData);
|
|
230
|
+
return {
|
|
231
|
+
keyedFormData: newKeyedFormData
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/** Returns the appropriate title for an item by getting first the title from the schema.items, then falling back to
|
|
235
|
+
* the description from the schema.items, and finally the string "Item"
|
|
236
|
+
*/
|
|
237
|
+
get itemTitle() {
|
|
238
|
+
const { schema, registry } = this.props;
|
|
239
|
+
const { translateString } = registry;
|
|
240
|
+
return get3(
|
|
241
|
+
schema,
|
|
242
|
+
[utils.ITEMS_KEY, "title"],
|
|
243
|
+
get3(schema, [utils.ITEMS_KEY, "description"], translateString(utils.TranslatableString.ArrayItemTitle))
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
/** Determines whether the item described in the schema is always required, which is determined by whether any item
|
|
247
|
+
* may be null.
|
|
248
|
+
*
|
|
249
|
+
* @param itemSchema - The schema for the item
|
|
250
|
+
* @return - True if the item schema type does not contain the "null" type
|
|
251
|
+
*/
|
|
252
|
+
isItemRequired(itemSchema) {
|
|
253
|
+
if (Array.isArray(itemSchema.type)) {
|
|
254
|
+
return !itemSchema.type.includes("null");
|
|
255
|
+
}
|
|
256
|
+
return itemSchema.type !== "null";
|
|
257
|
+
}
|
|
258
|
+
/** Determines whether more items can be added to the array. If the uiSchema indicates the array doesn't allow adding
|
|
259
|
+
* then false is returned. Otherwise, if the schema indicates that there are a maximum number of items and the
|
|
260
|
+
* `formData` matches that value, then false is returned, otherwise true is returned.
|
|
261
|
+
*
|
|
262
|
+
* @param formItems - The list of items in the form
|
|
263
|
+
* @returns - True if the item is addable otherwise false
|
|
264
|
+
*/
|
|
265
|
+
canAddItem(formItems) {
|
|
266
|
+
const { schema, uiSchema, registry } = this.props;
|
|
267
|
+
let { addable } = utils.getUiOptions(uiSchema, registry.globalUiOptions);
|
|
268
|
+
if (addable !== false) {
|
|
269
|
+
if (schema.maxItems !== void 0) {
|
|
270
|
+
addable = formItems.length < schema.maxItems;
|
|
271
|
+
} else {
|
|
272
|
+
addable = true;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return addable;
|
|
276
|
+
}
|
|
277
|
+
/** Callback handler for when the user clicks on the add or add at index buttons. Creates a new row of keyed form data
|
|
278
|
+
* either at the end of the list (when index is not specified) or inserted at the `index` when it is, adding it into
|
|
279
|
+
* the state, and then returning `onChange()` with the plain form data converted from the keyed data
|
|
280
|
+
*
|
|
281
|
+
* @param event - The event for the click
|
|
282
|
+
* @param [index] - The optional index at which to add the new data
|
|
283
|
+
*/
|
|
284
|
+
_handleAddClick(event, index) {
|
|
285
|
+
if (event) {
|
|
286
|
+
event.preventDefault();
|
|
287
|
+
}
|
|
288
|
+
const { onChange } = this.props;
|
|
289
|
+
const { keyedFormData } = this.state;
|
|
290
|
+
const newKeyedFormDataRow = {
|
|
291
|
+
key: generateRowId(),
|
|
292
|
+
item: this._getNewFormDataRow()
|
|
293
|
+
};
|
|
294
|
+
const newKeyedFormData = [...keyedFormData];
|
|
295
|
+
if (index !== void 0) {
|
|
296
|
+
newKeyedFormData.splice(index, 0, newKeyedFormDataRow);
|
|
297
|
+
} else {
|
|
298
|
+
newKeyedFormData.push(newKeyedFormDataRow);
|
|
299
|
+
}
|
|
300
|
+
this.setState(
|
|
301
|
+
{
|
|
302
|
+
keyedFormData: newKeyedFormData,
|
|
303
|
+
updatedKeyedFormData: true
|
|
304
|
+
},
|
|
305
|
+
() => onChange(keyedToPlainFormData(newKeyedFormData))
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
/** Renders the `ArrayField` depending on the specific needs of the schema and uischema elements
|
|
309
|
+
*/
|
|
310
|
+
render() {
|
|
311
|
+
const { schema, uiSchema, idSchema, registry } = this.props;
|
|
312
|
+
const { schemaUtils, translateString } = registry;
|
|
313
|
+
if (!(utils.ITEMS_KEY in schema)) {
|
|
314
|
+
const uiOptions = utils.getUiOptions(uiSchema);
|
|
315
|
+
const UnsupportedFieldTemplate = utils.getTemplate(
|
|
316
|
+
"UnsupportedFieldTemplate",
|
|
317
|
+
registry,
|
|
318
|
+
uiOptions
|
|
319
|
+
);
|
|
320
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
321
|
+
UnsupportedFieldTemplate,
|
|
322
|
+
{
|
|
323
|
+
schema,
|
|
324
|
+
idSchema,
|
|
325
|
+
reason: translateString(utils.TranslatableString.MissingItems),
|
|
326
|
+
registry
|
|
327
|
+
}
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
if (schemaUtils.isMultiSelect(schema)) {
|
|
331
|
+
return this.renderMultiSelect();
|
|
332
|
+
}
|
|
333
|
+
if (utils.isCustomWidget(uiSchema)) {
|
|
334
|
+
return this.renderCustomWidget();
|
|
335
|
+
}
|
|
336
|
+
if (utils.isFixedItems(schema)) {
|
|
337
|
+
return this.renderFixedArray();
|
|
338
|
+
}
|
|
339
|
+
if (schemaUtils.isFilesArray(schema, uiSchema)) {
|
|
340
|
+
return this.renderFiles();
|
|
341
|
+
}
|
|
342
|
+
return this.renderNormalArray();
|
|
343
|
+
}
|
|
344
|
+
/** Renders a normal array without any limitations of length
|
|
345
|
+
*/
|
|
346
|
+
renderNormalArray() {
|
|
347
|
+
const {
|
|
348
|
+
schema,
|
|
349
|
+
uiSchema = {},
|
|
350
|
+
errorSchema,
|
|
351
|
+
idSchema,
|
|
352
|
+
name,
|
|
353
|
+
disabled = false,
|
|
354
|
+
readonly = false,
|
|
355
|
+
autofocus = false,
|
|
356
|
+
required = false,
|
|
357
|
+
registry,
|
|
358
|
+
onBlur,
|
|
359
|
+
onFocus,
|
|
360
|
+
idPrefix,
|
|
361
|
+
idSeparator = "_",
|
|
362
|
+
rawErrors
|
|
363
|
+
} = this.props;
|
|
364
|
+
const { keyedFormData } = this.state;
|
|
365
|
+
const title = schema.title === void 0 ? name : schema.title;
|
|
366
|
+
const { schemaUtils, formContext } = registry;
|
|
367
|
+
const uiOptions = utils.getUiOptions(uiSchema);
|
|
368
|
+
const _schemaItems = isObject(schema.items) ? schema.items : {};
|
|
369
|
+
const itemsSchema = schemaUtils.retrieveSchema(_schemaItems);
|
|
370
|
+
const formData = keyedToPlainFormData(this.state.keyedFormData);
|
|
371
|
+
const canAdd = this.canAddItem(formData);
|
|
372
|
+
const arrayProps = {
|
|
373
|
+
canAdd,
|
|
374
|
+
items: keyedFormData.map((keyedItem, index) => {
|
|
375
|
+
const { key, item } = keyedItem;
|
|
376
|
+
const itemCast = item;
|
|
377
|
+
const itemSchema = schemaUtils.retrieveSchema(_schemaItems, itemCast);
|
|
378
|
+
const itemErrorSchema = errorSchema ? errorSchema[index] : void 0;
|
|
379
|
+
const itemIdPrefix = idSchema.$id + idSeparator + index;
|
|
380
|
+
const itemIdSchema = schemaUtils.toIdSchema(itemSchema, itemIdPrefix, itemCast, idPrefix, idSeparator);
|
|
381
|
+
return this.renderArrayFieldItem({
|
|
382
|
+
key,
|
|
383
|
+
index,
|
|
384
|
+
name: name && `${name}-${index}`,
|
|
385
|
+
canAdd,
|
|
386
|
+
canMoveUp: index > 0,
|
|
387
|
+
canMoveDown: index < formData.length - 1,
|
|
388
|
+
itemSchema,
|
|
389
|
+
itemIdSchema,
|
|
390
|
+
itemErrorSchema,
|
|
391
|
+
itemData: itemCast,
|
|
392
|
+
itemUiSchema: uiSchema.items,
|
|
393
|
+
autofocus: autofocus && index === 0,
|
|
394
|
+
onBlur,
|
|
395
|
+
onFocus,
|
|
396
|
+
rawErrors,
|
|
397
|
+
totalItems: keyedFormData.length
|
|
398
|
+
});
|
|
399
|
+
}),
|
|
400
|
+
className: `field field-array field-array-of-${itemsSchema.type}`,
|
|
401
|
+
disabled,
|
|
402
|
+
idSchema,
|
|
403
|
+
uiSchema,
|
|
404
|
+
onAddClick: this.onAddClick,
|
|
405
|
+
readonly,
|
|
406
|
+
required,
|
|
407
|
+
schema,
|
|
408
|
+
title,
|
|
409
|
+
formContext,
|
|
410
|
+
formData,
|
|
411
|
+
rawErrors,
|
|
412
|
+
registry
|
|
413
|
+
};
|
|
414
|
+
const Template = utils.getTemplate("ArrayFieldTemplate", registry, uiOptions);
|
|
415
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Template, { ...arrayProps });
|
|
416
|
+
}
|
|
417
|
+
/** Renders an array using the custom widget provided by the user in the `uiSchema`
|
|
418
|
+
*/
|
|
419
|
+
renderCustomWidget() {
|
|
420
|
+
const {
|
|
421
|
+
schema,
|
|
422
|
+
idSchema,
|
|
423
|
+
uiSchema,
|
|
424
|
+
disabled = false,
|
|
425
|
+
readonly = false,
|
|
426
|
+
autofocus = false,
|
|
427
|
+
required = false,
|
|
428
|
+
hideError,
|
|
429
|
+
placeholder,
|
|
430
|
+
onBlur,
|
|
431
|
+
onFocus,
|
|
432
|
+
formData: items = [],
|
|
433
|
+
registry,
|
|
434
|
+
rawErrors,
|
|
435
|
+
name
|
|
436
|
+
} = this.props;
|
|
437
|
+
const { widgets: widgets2, formContext, globalUiOptions, schemaUtils } = registry;
|
|
438
|
+
const { widget, title: uiTitle, ...options } = utils.getUiOptions(uiSchema, globalUiOptions);
|
|
439
|
+
const Widget = utils.getWidget(schema, widget, widgets2);
|
|
440
|
+
const label = uiTitle ?? schema.title ?? name;
|
|
441
|
+
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
|
|
442
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
443
|
+
Widget,
|
|
444
|
+
{
|
|
445
|
+
id: idSchema.$id,
|
|
446
|
+
name,
|
|
447
|
+
multiple: true,
|
|
448
|
+
onChange: this.onSelectChange,
|
|
449
|
+
onBlur,
|
|
450
|
+
onFocus,
|
|
451
|
+
options,
|
|
452
|
+
schema,
|
|
453
|
+
uiSchema,
|
|
454
|
+
registry,
|
|
455
|
+
value: items,
|
|
456
|
+
disabled,
|
|
457
|
+
readonly,
|
|
458
|
+
hideError,
|
|
459
|
+
required,
|
|
460
|
+
label,
|
|
461
|
+
hideLabel: !displayLabel,
|
|
462
|
+
placeholder,
|
|
463
|
+
formContext,
|
|
464
|
+
autofocus,
|
|
465
|
+
rawErrors
|
|
466
|
+
}
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
/** Renders an array as a set of checkboxes
|
|
470
|
+
*/
|
|
471
|
+
renderMultiSelect() {
|
|
472
|
+
const {
|
|
473
|
+
schema,
|
|
474
|
+
idSchema,
|
|
475
|
+
uiSchema,
|
|
476
|
+
formData: items = [],
|
|
477
|
+
disabled = false,
|
|
478
|
+
readonly = false,
|
|
479
|
+
autofocus = false,
|
|
480
|
+
required = false,
|
|
481
|
+
placeholder,
|
|
482
|
+
onBlur,
|
|
483
|
+
onFocus,
|
|
484
|
+
registry,
|
|
485
|
+
rawErrors,
|
|
486
|
+
name
|
|
487
|
+
} = this.props;
|
|
488
|
+
const { widgets: widgets2, schemaUtils, formContext, globalUiOptions } = registry;
|
|
489
|
+
const itemsSchema = schemaUtils.retrieveSchema(schema.items, items);
|
|
490
|
+
const enumOptions = utils.optionsList(itemsSchema);
|
|
491
|
+
const { widget = "select", title: uiTitle, ...options } = utils.getUiOptions(uiSchema, globalUiOptions);
|
|
492
|
+
const Widget = utils.getWidget(schema, widget, widgets2);
|
|
493
|
+
const label = uiTitle ?? schema.title ?? name;
|
|
494
|
+
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
|
|
495
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
496
|
+
Widget,
|
|
497
|
+
{
|
|
498
|
+
id: idSchema.$id,
|
|
499
|
+
name,
|
|
500
|
+
multiple: true,
|
|
501
|
+
onChange: this.onSelectChange,
|
|
502
|
+
onBlur,
|
|
503
|
+
onFocus,
|
|
504
|
+
options: { ...options, enumOptions },
|
|
505
|
+
schema,
|
|
506
|
+
uiSchema,
|
|
507
|
+
registry,
|
|
508
|
+
value: items,
|
|
509
|
+
disabled,
|
|
510
|
+
readonly,
|
|
511
|
+
required,
|
|
512
|
+
label,
|
|
513
|
+
hideLabel: !displayLabel,
|
|
514
|
+
placeholder,
|
|
515
|
+
formContext,
|
|
516
|
+
autofocus,
|
|
517
|
+
rawErrors
|
|
518
|
+
}
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
/** Renders an array of files using the `FileWidget`
|
|
522
|
+
*/
|
|
523
|
+
renderFiles() {
|
|
524
|
+
const {
|
|
525
|
+
schema,
|
|
526
|
+
uiSchema,
|
|
527
|
+
idSchema,
|
|
528
|
+
name,
|
|
529
|
+
disabled = false,
|
|
530
|
+
readonly = false,
|
|
531
|
+
autofocus = false,
|
|
532
|
+
required = false,
|
|
533
|
+
onBlur,
|
|
534
|
+
onFocus,
|
|
535
|
+
registry,
|
|
536
|
+
formData: items = [],
|
|
537
|
+
rawErrors
|
|
538
|
+
} = this.props;
|
|
539
|
+
const { widgets: widgets2, formContext, globalUiOptions, schemaUtils } = registry;
|
|
540
|
+
const { widget = "files", title: uiTitle, ...options } = utils.getUiOptions(uiSchema, globalUiOptions);
|
|
541
|
+
const Widget = utils.getWidget(schema, widget, widgets2);
|
|
542
|
+
const label = uiTitle ?? schema.title ?? name;
|
|
543
|
+
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
|
|
544
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
545
|
+
Widget,
|
|
546
|
+
{
|
|
547
|
+
options,
|
|
548
|
+
id: idSchema.$id,
|
|
549
|
+
name,
|
|
550
|
+
multiple: true,
|
|
551
|
+
onChange: this.onSelectChange,
|
|
552
|
+
onBlur,
|
|
553
|
+
onFocus,
|
|
554
|
+
schema,
|
|
555
|
+
uiSchema,
|
|
556
|
+
value: items,
|
|
557
|
+
disabled,
|
|
558
|
+
readonly,
|
|
559
|
+
required,
|
|
560
|
+
registry,
|
|
561
|
+
formContext,
|
|
562
|
+
autofocus,
|
|
563
|
+
rawErrors,
|
|
564
|
+
label,
|
|
565
|
+
hideLabel: !displayLabel
|
|
566
|
+
}
|
|
567
|
+
);
|
|
568
|
+
}
|
|
569
|
+
/** Renders an array that has a maximum limit of items
|
|
570
|
+
*/
|
|
571
|
+
renderFixedArray() {
|
|
572
|
+
const {
|
|
573
|
+
schema,
|
|
574
|
+
uiSchema = {},
|
|
575
|
+
formData = [],
|
|
576
|
+
errorSchema,
|
|
577
|
+
idPrefix,
|
|
578
|
+
idSeparator = "_",
|
|
579
|
+
idSchema,
|
|
580
|
+
name,
|
|
581
|
+
disabled = false,
|
|
582
|
+
readonly = false,
|
|
583
|
+
autofocus = false,
|
|
584
|
+
required = false,
|
|
585
|
+
registry,
|
|
586
|
+
onBlur,
|
|
587
|
+
onFocus,
|
|
588
|
+
rawErrors
|
|
589
|
+
} = this.props;
|
|
590
|
+
const { keyedFormData } = this.state;
|
|
591
|
+
let { formData: items = [] } = this.props;
|
|
592
|
+
const title = schema.title || name;
|
|
593
|
+
const uiOptions = utils.getUiOptions(uiSchema);
|
|
594
|
+
const { schemaUtils, formContext } = registry;
|
|
595
|
+
const _schemaItems = isObject(schema.items) ? schema.items : [];
|
|
596
|
+
const itemSchemas = _schemaItems.map(
|
|
597
|
+
(item, index) => schemaUtils.retrieveSchema(item, formData[index])
|
|
598
|
+
);
|
|
599
|
+
const additionalSchema = isObject(schema.additionalItems) ? schemaUtils.retrieveSchema(schema.additionalItems, formData) : null;
|
|
600
|
+
if (!items || items.length < itemSchemas.length) {
|
|
601
|
+
items = items || [];
|
|
602
|
+
items = items.concat(new Array(itemSchemas.length - items.length));
|
|
603
|
+
}
|
|
604
|
+
const canAdd = this.canAddItem(items) && !!additionalSchema;
|
|
605
|
+
const arrayProps = {
|
|
606
|
+
canAdd,
|
|
607
|
+
className: "field field-array field-array-fixed-items",
|
|
608
|
+
disabled,
|
|
609
|
+
idSchema,
|
|
610
|
+
formData,
|
|
611
|
+
items: keyedFormData.map((keyedItem, index) => {
|
|
612
|
+
const { key, item } = keyedItem;
|
|
613
|
+
const itemCast = item;
|
|
614
|
+
const additional = index >= itemSchemas.length;
|
|
615
|
+
const itemSchema = additional && isObject(schema.additionalItems) ? schemaUtils.retrieveSchema(schema.additionalItems, itemCast) : itemSchemas[index];
|
|
616
|
+
const itemIdPrefix = idSchema.$id + idSeparator + index;
|
|
617
|
+
const itemIdSchema = schemaUtils.toIdSchema(itemSchema, itemIdPrefix, itemCast, idPrefix, idSeparator);
|
|
618
|
+
const itemUiSchema = additional ? uiSchema.additionalItems || {} : Array.isArray(uiSchema.items) ? uiSchema.items[index] : uiSchema.items || {};
|
|
619
|
+
const itemErrorSchema = errorSchema ? errorSchema[index] : void 0;
|
|
620
|
+
return this.renderArrayFieldItem({
|
|
621
|
+
key,
|
|
622
|
+
index,
|
|
623
|
+
name: name && `${name}-${index}`,
|
|
624
|
+
canAdd,
|
|
625
|
+
canRemove: additional,
|
|
626
|
+
canMoveUp: index >= itemSchemas.length + 1,
|
|
627
|
+
canMoveDown: additional && index < items.length - 1,
|
|
628
|
+
itemSchema,
|
|
629
|
+
itemData: itemCast,
|
|
630
|
+
itemUiSchema,
|
|
631
|
+
itemIdSchema,
|
|
632
|
+
itemErrorSchema,
|
|
633
|
+
autofocus: autofocus && index === 0,
|
|
634
|
+
onBlur,
|
|
635
|
+
onFocus,
|
|
636
|
+
rawErrors,
|
|
637
|
+
totalItems: keyedFormData.length
|
|
638
|
+
});
|
|
639
|
+
}),
|
|
640
|
+
onAddClick: this.onAddClick,
|
|
641
|
+
readonly,
|
|
642
|
+
required,
|
|
643
|
+
registry,
|
|
644
|
+
schema,
|
|
645
|
+
uiSchema,
|
|
646
|
+
title,
|
|
647
|
+
formContext,
|
|
648
|
+
rawErrors
|
|
649
|
+
};
|
|
650
|
+
const Template = utils.getTemplate("ArrayFieldTemplate", registry, uiOptions);
|
|
651
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Template, { ...arrayProps });
|
|
652
|
+
}
|
|
653
|
+
/** Renders the individual array item using a `SchemaField` along with the additional properties required to be send
|
|
654
|
+
* back to the `ArrayFieldItemTemplate`.
|
|
655
|
+
*
|
|
656
|
+
* @param props - The props for the individual array item to be rendered
|
|
657
|
+
*/
|
|
658
|
+
renderArrayFieldItem(props) {
|
|
659
|
+
const {
|
|
660
|
+
key,
|
|
661
|
+
index,
|
|
662
|
+
name,
|
|
663
|
+
canAdd,
|
|
664
|
+
canRemove = true,
|
|
665
|
+
canMoveUp,
|
|
666
|
+
canMoveDown,
|
|
667
|
+
itemSchema,
|
|
668
|
+
itemData,
|
|
669
|
+
itemUiSchema,
|
|
670
|
+
itemIdSchema,
|
|
671
|
+
itemErrorSchema,
|
|
672
|
+
autofocus,
|
|
673
|
+
onBlur,
|
|
674
|
+
onFocus,
|
|
675
|
+
rawErrors,
|
|
676
|
+
totalItems
|
|
677
|
+
} = props;
|
|
678
|
+
const { disabled, hideError, idPrefix, idSeparator, readonly, uiSchema, registry, formContext } = this.props;
|
|
679
|
+
const {
|
|
680
|
+
fields: { ArraySchemaField, SchemaField: SchemaField2 },
|
|
681
|
+
globalUiOptions
|
|
682
|
+
} = registry;
|
|
683
|
+
const ItemSchemaField = ArraySchemaField || SchemaField2;
|
|
684
|
+
const { orderable = true, removable = true, copyable = false } = utils.getUiOptions(uiSchema, globalUiOptions);
|
|
685
|
+
const has2 = {
|
|
686
|
+
moveUp: orderable && canMoveUp,
|
|
687
|
+
moveDown: orderable && canMoveDown,
|
|
688
|
+
copy: copyable && canAdd,
|
|
689
|
+
remove: removable && canRemove,
|
|
690
|
+
toolbar: false
|
|
691
|
+
};
|
|
692
|
+
has2.toolbar = Object.keys(has2).some((key2) => has2[key2]);
|
|
693
|
+
return {
|
|
694
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
695
|
+
ItemSchemaField,
|
|
696
|
+
{
|
|
697
|
+
name,
|
|
698
|
+
index,
|
|
699
|
+
schema: itemSchema,
|
|
700
|
+
uiSchema: itemUiSchema,
|
|
701
|
+
formData: itemData,
|
|
702
|
+
formContext,
|
|
703
|
+
errorSchema: itemErrorSchema,
|
|
704
|
+
idPrefix,
|
|
705
|
+
idSeparator,
|
|
706
|
+
idSchema: itemIdSchema,
|
|
707
|
+
required: this.isItemRequired(itemSchema),
|
|
708
|
+
onChange: this.onChangeForIndex(index),
|
|
709
|
+
onBlur,
|
|
710
|
+
onFocus,
|
|
711
|
+
registry,
|
|
712
|
+
disabled,
|
|
713
|
+
readonly,
|
|
714
|
+
hideError,
|
|
715
|
+
autofocus,
|
|
716
|
+
rawErrors
|
|
717
|
+
}
|
|
718
|
+
),
|
|
719
|
+
className: "array-item",
|
|
720
|
+
disabled,
|
|
721
|
+
canAdd,
|
|
722
|
+
hasCopy: has2.copy,
|
|
723
|
+
hasToolbar: has2.toolbar,
|
|
724
|
+
hasMoveUp: has2.moveUp,
|
|
725
|
+
hasMoveDown: has2.moveDown,
|
|
726
|
+
hasRemove: has2.remove,
|
|
727
|
+
index,
|
|
728
|
+
totalItems,
|
|
729
|
+
key,
|
|
730
|
+
onAddIndexClick: this.onAddIndexClick,
|
|
731
|
+
onCopyIndexClick: this.onCopyIndexClick,
|
|
732
|
+
onDropIndexClick: this.onDropIndexClick,
|
|
733
|
+
onReorderClick: this.onReorderClick,
|
|
734
|
+
readonly,
|
|
735
|
+
registry,
|
|
736
|
+
schema: itemSchema,
|
|
737
|
+
uiSchema: itemUiSchema
|
|
738
|
+
};
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
var ArrayField_default = ArrayField;
|
|
742
|
+
function BooleanField(props) {
|
|
743
|
+
const {
|
|
744
|
+
schema,
|
|
745
|
+
name,
|
|
746
|
+
uiSchema,
|
|
747
|
+
idSchema,
|
|
748
|
+
formData,
|
|
749
|
+
registry,
|
|
750
|
+
required,
|
|
751
|
+
disabled,
|
|
752
|
+
readonly,
|
|
753
|
+
autofocus,
|
|
754
|
+
onChange,
|
|
755
|
+
onFocus,
|
|
756
|
+
onBlur,
|
|
757
|
+
rawErrors
|
|
758
|
+
} = props;
|
|
759
|
+
const { title } = schema;
|
|
760
|
+
const { widgets: widgets2, formContext, translateString, globalUiOptions } = registry;
|
|
761
|
+
const {
|
|
762
|
+
widget = "checkbox",
|
|
763
|
+
title: uiTitle,
|
|
764
|
+
// Unlike the other fields, don't use `getDisplayLabel()` since it always returns false for the boolean type
|
|
765
|
+
label: displayLabel = true,
|
|
766
|
+
...options
|
|
767
|
+
} = utils.getUiOptions(uiSchema, globalUiOptions);
|
|
768
|
+
const Widget = utils.getWidget(schema, widget, widgets2);
|
|
769
|
+
const yes = translateString(utils.TranslatableString.YesLabel);
|
|
770
|
+
const no = translateString(utils.TranslatableString.NoLabel);
|
|
771
|
+
let enumOptions;
|
|
772
|
+
const label = uiTitle ?? title ?? name;
|
|
773
|
+
if (Array.isArray(schema.oneOf)) {
|
|
774
|
+
enumOptions = utils.optionsList({
|
|
775
|
+
oneOf: schema.oneOf.map((option) => {
|
|
776
|
+
if (isObject(option)) {
|
|
777
|
+
return {
|
|
778
|
+
...option,
|
|
779
|
+
title: option.title || (option.const === true ? yes : no)
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
return void 0;
|
|
783
|
+
}).filter((o) => o)
|
|
784
|
+
// cast away the error that typescript can't grok is fixed
|
|
785
|
+
});
|
|
786
|
+
} else {
|
|
787
|
+
const schemaWithEnumNames = schema;
|
|
788
|
+
const enums = schema.enum ?? [true, false];
|
|
789
|
+
if (!schemaWithEnumNames.enumNames && enums.length === 2 && enums.every((v) => typeof v === "boolean")) {
|
|
790
|
+
enumOptions = [
|
|
791
|
+
{
|
|
792
|
+
value: enums[0],
|
|
793
|
+
label: enums[0] ? yes : no
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
value: enums[1],
|
|
797
|
+
label: enums[1] ? yes : no
|
|
798
|
+
}
|
|
799
|
+
];
|
|
800
|
+
} else {
|
|
801
|
+
enumOptions = utils.optionsList({
|
|
802
|
+
enum: enums,
|
|
803
|
+
// NOTE: enumNames is deprecated, but still supported for now.
|
|
804
|
+
enumNames: schemaWithEnumNames.enumNames
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
809
|
+
Widget,
|
|
810
|
+
{
|
|
811
|
+
options: { ...options, enumOptions },
|
|
812
|
+
schema,
|
|
813
|
+
uiSchema,
|
|
814
|
+
id: idSchema.$id,
|
|
815
|
+
name,
|
|
816
|
+
onChange,
|
|
817
|
+
onFocus,
|
|
818
|
+
onBlur,
|
|
819
|
+
label,
|
|
820
|
+
hideLabel: !displayLabel,
|
|
821
|
+
value: formData,
|
|
822
|
+
required,
|
|
823
|
+
disabled,
|
|
824
|
+
readonly,
|
|
825
|
+
registry,
|
|
826
|
+
formContext,
|
|
827
|
+
autofocus,
|
|
828
|
+
rawErrors
|
|
829
|
+
}
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
var BooleanField_default = BooleanField;
|
|
833
|
+
var AnyOfField = class extends react.Component {
|
|
834
|
+
/** Constructs an `AnyOfField` with the given `props` to initialize the initially selected option in state
|
|
835
|
+
*
|
|
836
|
+
* @param props - The `FieldProps` for this template
|
|
837
|
+
*/
|
|
838
|
+
constructor(props) {
|
|
839
|
+
super(props);
|
|
840
|
+
/** Callback handler to remember what the currently selected option is. In addition to that the `formData` is updated
|
|
841
|
+
* to remove properties that are not part of the newly selected option schema, and then the updated data is passed to
|
|
842
|
+
* the `onChange` handler.
|
|
843
|
+
*
|
|
844
|
+
* @param option - The new option value being selected
|
|
845
|
+
*/
|
|
846
|
+
this.onOptionChange = (option) => {
|
|
847
|
+
const { selectedOption, retrievedOptions } = this.state;
|
|
848
|
+
const { formData, onChange, registry } = this.props;
|
|
849
|
+
const { schemaUtils } = registry;
|
|
850
|
+
const intOption = option !== void 0 ? parseInt(option, 10) : -1;
|
|
851
|
+
if (intOption === selectedOption) {
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
const newOption = intOption >= 0 ? retrievedOptions[intOption] : void 0;
|
|
855
|
+
const oldOption = selectedOption >= 0 ? retrievedOptions[selectedOption] : void 0;
|
|
856
|
+
let newFormData = schemaUtils.sanitizeDataForNewSchema(newOption, oldOption, formData);
|
|
857
|
+
if (newFormData && newOption) {
|
|
858
|
+
newFormData = schemaUtils.getDefaultFormState(newOption, newFormData, "excludeObjectChildren");
|
|
859
|
+
}
|
|
860
|
+
onChange(newFormData, void 0, this.getFieldId());
|
|
861
|
+
this.setState({ selectedOption: intOption });
|
|
862
|
+
};
|
|
863
|
+
const {
|
|
864
|
+
formData,
|
|
865
|
+
options,
|
|
866
|
+
registry: { schemaUtils }
|
|
867
|
+
} = this.props;
|
|
868
|
+
const retrievedOptions = options.map((opt) => schemaUtils.retrieveSchema(opt, formData));
|
|
869
|
+
this.state = {
|
|
870
|
+
retrievedOptions,
|
|
871
|
+
selectedOption: this.getMatchingOption(0, formData, retrievedOptions)
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
/** React lifecycle method that is called when the props and/or state for this component is updated. It recomputes the
|
|
875
|
+
* currently selected option based on the overall `formData`
|
|
876
|
+
*
|
|
877
|
+
* @param prevProps - The previous `FieldProps` for this template
|
|
878
|
+
* @param prevState - The previous `AnyOfFieldState` for this template
|
|
879
|
+
*/
|
|
880
|
+
componentDidUpdate(prevProps, prevState) {
|
|
881
|
+
const { formData, options, idSchema } = this.props;
|
|
882
|
+
const { selectedOption } = this.state;
|
|
883
|
+
let newState = this.state;
|
|
884
|
+
if (!utils.deepEquals(prevProps.options, options)) {
|
|
885
|
+
const {
|
|
886
|
+
registry: { schemaUtils }
|
|
887
|
+
} = this.props;
|
|
888
|
+
const retrievedOptions = options.map((opt) => schemaUtils.retrieveSchema(opt, formData));
|
|
889
|
+
newState = { selectedOption, retrievedOptions };
|
|
890
|
+
}
|
|
891
|
+
if (!utils.deepEquals(formData, prevProps.formData) && idSchema.$id === prevProps.idSchema.$id) {
|
|
892
|
+
const { retrievedOptions } = newState;
|
|
893
|
+
const matchingOption = this.getMatchingOption(selectedOption, formData, retrievedOptions);
|
|
894
|
+
if (prevState && matchingOption !== selectedOption) {
|
|
895
|
+
newState = { selectedOption: matchingOption, retrievedOptions };
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
if (newState !== this.state) {
|
|
899
|
+
this.setState(newState);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
/** Determines the best matching option for the given `formData` and `options`.
|
|
903
|
+
*
|
|
904
|
+
* @param formData - The new formData
|
|
905
|
+
* @param options - The list of options to choose from
|
|
906
|
+
* @return - The index of the `option` that best matches the `formData`
|
|
907
|
+
*/
|
|
908
|
+
getMatchingOption(selectedOption, formData, options) {
|
|
909
|
+
const {
|
|
910
|
+
schema,
|
|
911
|
+
registry: { schemaUtils }
|
|
912
|
+
} = this.props;
|
|
913
|
+
const discriminator = utils.getDiscriminatorFieldFromSchema(schema);
|
|
914
|
+
const option = schemaUtils.getClosestMatchingOption(formData, options, selectedOption, discriminator);
|
|
915
|
+
return option;
|
|
916
|
+
}
|
|
917
|
+
getFieldId() {
|
|
918
|
+
const { idSchema, schema } = this.props;
|
|
919
|
+
return `${idSchema.$id}${schema.oneOf ? "__oneof_select" : "__anyof_select"}`;
|
|
920
|
+
}
|
|
921
|
+
/** Renders the `AnyOfField` selector along with a `SchemaField` for the value of the `formData`
|
|
922
|
+
*/
|
|
923
|
+
render() {
|
|
924
|
+
const {
|
|
925
|
+
name,
|
|
926
|
+
disabled = false,
|
|
927
|
+
errorSchema = {},
|
|
928
|
+
formContext,
|
|
929
|
+
onBlur,
|
|
930
|
+
onFocus,
|
|
931
|
+
registry,
|
|
932
|
+
schema,
|
|
933
|
+
uiSchema
|
|
934
|
+
} = this.props;
|
|
935
|
+
const { widgets: widgets2, fields: fields2, translateString, globalUiOptions, schemaUtils } = registry;
|
|
936
|
+
const { SchemaField: _SchemaField } = fields2;
|
|
937
|
+
const { selectedOption, retrievedOptions } = this.state;
|
|
938
|
+
const {
|
|
939
|
+
widget = "select",
|
|
940
|
+
placeholder,
|
|
941
|
+
autofocus,
|
|
942
|
+
autocomplete,
|
|
943
|
+
title = schema.title,
|
|
944
|
+
...uiOptions
|
|
945
|
+
} = utils.getUiOptions(uiSchema, globalUiOptions);
|
|
946
|
+
const Widget = utils.getWidget({ type: "number" }, widget, widgets2);
|
|
947
|
+
const rawErrors = get3(errorSchema, utils.ERRORS_KEY, []);
|
|
948
|
+
const fieldErrorSchema = omit2(errorSchema, [utils.ERRORS_KEY]);
|
|
949
|
+
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
|
|
950
|
+
const option = selectedOption >= 0 ? retrievedOptions[selectedOption] || null : null;
|
|
951
|
+
let optionSchema;
|
|
952
|
+
if (option) {
|
|
953
|
+
const { oneOf, anyOf, ...remaining } = schema;
|
|
954
|
+
unset(remaining, utils.ADDITIONAL_PROPERTY_FLAG);
|
|
955
|
+
optionSchema = !isEmpty(remaining) ? utils.mergeSchemas(remaining, option) : option;
|
|
956
|
+
}
|
|
957
|
+
const translateEnum = title ? utils.TranslatableString.TitleOptionPrefix : utils.TranslatableString.OptionPrefix;
|
|
958
|
+
const translateParams = title ? [title] : [];
|
|
959
|
+
const enumOptions = retrievedOptions.map((opt, index) => ({
|
|
960
|
+
label: opt.title || translateString(translateEnum, translateParams.concat(String(index + 1))),
|
|
961
|
+
value: index
|
|
962
|
+
}));
|
|
963
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel panel-default panel-body", children: [
|
|
964
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "form-group", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
965
|
+
Widget,
|
|
966
|
+
{
|
|
967
|
+
id: this.getFieldId(),
|
|
968
|
+
name: `${name}${schema.oneOf ? "__oneof_select" : "__anyof_select"}`,
|
|
969
|
+
schema: { type: "number", default: 0 },
|
|
970
|
+
onChange: this.onOptionChange,
|
|
971
|
+
onBlur,
|
|
972
|
+
onFocus,
|
|
973
|
+
disabled: disabled || isEmpty(enumOptions),
|
|
974
|
+
multiple: false,
|
|
975
|
+
rawErrors,
|
|
976
|
+
errorSchema: fieldErrorSchema,
|
|
977
|
+
value: selectedOption >= 0 ? selectedOption : void 0,
|
|
978
|
+
options: { enumOptions, ...uiOptions },
|
|
979
|
+
registry,
|
|
980
|
+
formContext,
|
|
981
|
+
placeholder,
|
|
982
|
+
autocomplete,
|
|
983
|
+
autofocus,
|
|
984
|
+
label: title ?? name,
|
|
985
|
+
hideLabel: !displayLabel
|
|
986
|
+
}
|
|
987
|
+
) }),
|
|
988
|
+
option !== null && /* @__PURE__ */ jsxRuntime.jsx(_SchemaField, { ...this.props, schema: optionSchema })
|
|
989
|
+
] });
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
var MultiSchemaField_default = AnyOfField;
|
|
993
|
+
var trailingCharMatcherWithPrefix = /\.([0-9]*0)*$/;
|
|
994
|
+
var trailingCharMatcher = /[0.]0*$/;
|
|
995
|
+
function NumberField(props) {
|
|
996
|
+
const { registry, onChange, formData, value: initialValue } = props;
|
|
997
|
+
const [lastValue, setLastValue] = react.useState(initialValue);
|
|
998
|
+
const { StringField: StringField2 } = registry.fields;
|
|
999
|
+
let value = formData;
|
|
1000
|
+
const handleChange = react.useCallback(
|
|
1001
|
+
(value2) => {
|
|
1002
|
+
setLastValue(value2);
|
|
1003
|
+
if (`${value2}`.charAt(0) === ".") {
|
|
1004
|
+
value2 = `0${value2}`;
|
|
1005
|
+
}
|
|
1006
|
+
const processed = typeof value2 === "string" && value2.match(trailingCharMatcherWithPrefix) ? utils.asNumber(value2.replace(trailingCharMatcher, "")) : utils.asNumber(value2);
|
|
1007
|
+
onChange(processed);
|
|
1008
|
+
},
|
|
1009
|
+
[onChange]
|
|
1010
|
+
);
|
|
1011
|
+
if (typeof lastValue === "string" && typeof value === "number") {
|
|
1012
|
+
const re = new RegExp(`${value}`.replace(".", "\\.") + "\\.?0*$");
|
|
1013
|
+
if (lastValue.match(re)) {
|
|
1014
|
+
value = lastValue;
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
return /* @__PURE__ */ jsxRuntime.jsx(StringField2, { ...props, formData: value, onChange: handleChange });
|
|
1018
|
+
}
|
|
1019
|
+
var NumberField_default = NumberField;
|
|
1020
|
+
var ObjectField = class extends react.Component {
|
|
1021
|
+
constructor() {
|
|
1022
|
+
super(...arguments);
|
|
1023
|
+
/** Set up the initial state */
|
|
1024
|
+
this.state = {
|
|
1025
|
+
wasPropertyKeyModified: false,
|
|
1026
|
+
additionalProperties: {}
|
|
1027
|
+
};
|
|
1028
|
+
/** Returns the `onPropertyChange` handler for the `name` field. Handles the special case where a user is attempting
|
|
1029
|
+
* to clear the data for a field added as an additional property. Calls the `onChange()` handler with the updated
|
|
1030
|
+
* formData.
|
|
1031
|
+
*
|
|
1032
|
+
* @param name - The name of the property
|
|
1033
|
+
* @param addedByAdditionalProperties - Flag indicating whether this property is an additional property
|
|
1034
|
+
* @returns - The onPropertyChange callback for the `name` property
|
|
1035
|
+
*/
|
|
1036
|
+
this.onPropertyChange = (name, addedByAdditionalProperties = false) => {
|
|
1037
|
+
return (value, newErrorSchema, id) => {
|
|
1038
|
+
const { formData, onChange, errorSchema } = this.props;
|
|
1039
|
+
if (value === void 0 && addedByAdditionalProperties) {
|
|
1040
|
+
value = "";
|
|
1041
|
+
}
|
|
1042
|
+
const newFormData = { ...formData, [name]: value };
|
|
1043
|
+
onChange(
|
|
1044
|
+
newFormData,
|
|
1045
|
+
errorSchema && errorSchema && {
|
|
1046
|
+
...errorSchema,
|
|
1047
|
+
[name]: newErrorSchema
|
|
1048
|
+
},
|
|
1049
|
+
id
|
|
1050
|
+
);
|
|
1051
|
+
};
|
|
1052
|
+
};
|
|
1053
|
+
/** Returns a callback to handle the onDropPropertyClick event for the given `key` which removes the old `key` data
|
|
1054
|
+
* and calls the `onChange` callback with it
|
|
1055
|
+
*
|
|
1056
|
+
* @param key - The key for which the drop callback is desired
|
|
1057
|
+
* @returns - The drop property click callback
|
|
1058
|
+
*/
|
|
1059
|
+
this.onDropPropertyClick = (key) => {
|
|
1060
|
+
return (event) => {
|
|
1061
|
+
event.preventDefault();
|
|
1062
|
+
const { onChange, formData } = this.props;
|
|
1063
|
+
const copiedFormData = { ...formData };
|
|
1064
|
+
unset(copiedFormData, key);
|
|
1065
|
+
onChange(copiedFormData);
|
|
1066
|
+
};
|
|
1067
|
+
};
|
|
1068
|
+
/** Computes the next available key name from the `preferredKey`, indexing through the already existing keys until one
|
|
1069
|
+
* that is already not assigned is found.
|
|
1070
|
+
*
|
|
1071
|
+
* @param preferredKey - The preferred name of a new key
|
|
1072
|
+
* @param [formData] - The form data in which to check if the desired key already exists
|
|
1073
|
+
* @returns - The name of the next available key from `preferredKey`
|
|
1074
|
+
*/
|
|
1075
|
+
this.getAvailableKey = (preferredKey, formData) => {
|
|
1076
|
+
const { uiSchema, registry } = this.props;
|
|
1077
|
+
const { duplicateKeySuffixSeparator = "-" } = utils.getUiOptions(uiSchema, registry.globalUiOptions);
|
|
1078
|
+
let index = 0;
|
|
1079
|
+
let newKey = preferredKey;
|
|
1080
|
+
while (has(formData, newKey)) {
|
|
1081
|
+
newKey = `${preferredKey}${duplicateKeySuffixSeparator}${++index}`;
|
|
1082
|
+
}
|
|
1083
|
+
return newKey;
|
|
1084
|
+
};
|
|
1085
|
+
/** Returns a callback function that deals with the rename of a key for an additional property for a schema. That
|
|
1086
|
+
* callback will attempt to rename the key and move the existing data to that key, calling `onChange` when it does.
|
|
1087
|
+
*
|
|
1088
|
+
* @param oldValue - The old value of a field
|
|
1089
|
+
* @returns - The key change callback function
|
|
1090
|
+
*/
|
|
1091
|
+
this.onKeyChange = (oldValue) => {
|
|
1092
|
+
return (value, newErrorSchema) => {
|
|
1093
|
+
if (oldValue === value) {
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
const { formData, onChange, errorSchema } = this.props;
|
|
1097
|
+
value = this.getAvailableKey(value, formData);
|
|
1098
|
+
const newFormData = {
|
|
1099
|
+
...formData
|
|
1100
|
+
};
|
|
1101
|
+
const newKeys = { [oldValue]: value };
|
|
1102
|
+
const keyValues = Object.keys(newFormData).map((key) => {
|
|
1103
|
+
const newKey = newKeys[key] || key;
|
|
1104
|
+
return { [newKey]: newFormData[key] };
|
|
1105
|
+
});
|
|
1106
|
+
const renamedObj = Object.assign({}, ...keyValues);
|
|
1107
|
+
this.setState({ wasPropertyKeyModified: true });
|
|
1108
|
+
onChange(
|
|
1109
|
+
renamedObj,
|
|
1110
|
+
errorSchema && errorSchema && {
|
|
1111
|
+
...errorSchema,
|
|
1112
|
+
[value]: newErrorSchema
|
|
1113
|
+
}
|
|
1114
|
+
);
|
|
1115
|
+
};
|
|
1116
|
+
};
|
|
1117
|
+
/** Handles the adding of a new additional property on the given `schema`. Calls the `onChange` callback once the new
|
|
1118
|
+
* default data for that field has been added to the formData.
|
|
1119
|
+
*
|
|
1120
|
+
* @param schema - The schema element to which the new property is being added
|
|
1121
|
+
*/
|
|
1122
|
+
this.handleAddClick = (schema) => () => {
|
|
1123
|
+
if (!schema.additionalProperties) {
|
|
1124
|
+
return;
|
|
1125
|
+
}
|
|
1126
|
+
const { formData, onChange, registry } = this.props;
|
|
1127
|
+
const newFormData = { ...formData };
|
|
1128
|
+
let type = void 0;
|
|
1129
|
+
if (isObject(schema.additionalProperties)) {
|
|
1130
|
+
type = schema.additionalProperties.type;
|
|
1131
|
+
let apSchema = schema.additionalProperties;
|
|
1132
|
+
if (utils.REF_KEY in apSchema) {
|
|
1133
|
+
const { schemaUtils } = registry;
|
|
1134
|
+
apSchema = schemaUtils.retrieveSchema({ $ref: apSchema[utils.REF_KEY] }, formData);
|
|
1135
|
+
type = apSchema.type;
|
|
1136
|
+
}
|
|
1137
|
+
if (!type && (utils.ANY_OF_KEY in apSchema || utils.ONE_OF_KEY in apSchema)) {
|
|
1138
|
+
type = "object";
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
const newKey = this.getAvailableKey("newKey", newFormData);
|
|
1142
|
+
set(newFormData, newKey, this.getDefaultValue(type));
|
|
1143
|
+
onChange(newFormData);
|
|
1144
|
+
};
|
|
1145
|
+
}
|
|
1146
|
+
/** Returns a flag indicating whether the `name` field is required in the object schema
|
|
1147
|
+
*
|
|
1148
|
+
* @param name - The name of the field to check for required-ness
|
|
1149
|
+
* @returns - True if the field `name` is required, false otherwise
|
|
1150
|
+
*/
|
|
1151
|
+
isRequired(name) {
|
|
1152
|
+
const { schema } = this.props;
|
|
1153
|
+
return Array.isArray(schema.required) && schema.required.indexOf(name) !== -1;
|
|
1154
|
+
}
|
|
1155
|
+
/** Returns a default value to be used for a new additional schema property of the given `type`
|
|
1156
|
+
*
|
|
1157
|
+
* @param type - The type of the new additional schema property
|
|
1158
|
+
*/
|
|
1159
|
+
getDefaultValue(type) {
|
|
1160
|
+
const {
|
|
1161
|
+
registry: { translateString }
|
|
1162
|
+
} = this.props;
|
|
1163
|
+
switch (type) {
|
|
1164
|
+
case "array":
|
|
1165
|
+
return [];
|
|
1166
|
+
case "boolean":
|
|
1167
|
+
return false;
|
|
1168
|
+
case "null":
|
|
1169
|
+
return null;
|
|
1170
|
+
case "number":
|
|
1171
|
+
return 0;
|
|
1172
|
+
case "object":
|
|
1173
|
+
return {};
|
|
1174
|
+
case "string":
|
|
1175
|
+
default:
|
|
1176
|
+
return translateString(utils.TranslatableString.NewStringDefault);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
/** Renders the `ObjectField` from the given props
|
|
1180
|
+
*/
|
|
1181
|
+
render() {
|
|
1182
|
+
const {
|
|
1183
|
+
schema: rawSchema,
|
|
1184
|
+
uiSchema = {},
|
|
1185
|
+
formData,
|
|
1186
|
+
errorSchema,
|
|
1187
|
+
idSchema,
|
|
1188
|
+
name,
|
|
1189
|
+
required = false,
|
|
1190
|
+
disabled = false,
|
|
1191
|
+
readonly = false,
|
|
1192
|
+
hideError,
|
|
1193
|
+
idPrefix,
|
|
1194
|
+
idSeparator,
|
|
1195
|
+
onBlur,
|
|
1196
|
+
onFocus,
|
|
1197
|
+
registry
|
|
1198
|
+
} = this.props;
|
|
1199
|
+
const { fields: fields2, formContext, schemaUtils, translateString, globalUiOptions } = registry;
|
|
1200
|
+
const { SchemaField: SchemaField2 } = fields2;
|
|
1201
|
+
const schema = schemaUtils.retrieveSchema(rawSchema, formData);
|
|
1202
|
+
const uiOptions = utils.getUiOptions(uiSchema, globalUiOptions);
|
|
1203
|
+
const { properties: schemaProperties = {} } = schema;
|
|
1204
|
+
const title = uiOptions.title ?? schema.title ?? name;
|
|
1205
|
+
const description = uiOptions.description ?? schema.description;
|
|
1206
|
+
let orderedProperties;
|
|
1207
|
+
try {
|
|
1208
|
+
const properties = Object.keys(schemaProperties);
|
|
1209
|
+
orderedProperties = utils.orderProperties(properties, uiOptions.order);
|
|
1210
|
+
} catch (err) {
|
|
1211
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1212
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "config-error", style: { color: "red" }, children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { children: translateString(utils.TranslatableString.InvalidObjectField, [name || "root", err.message]) }) }),
|
|
1213
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { children: JSON.stringify(schema) })
|
|
1214
|
+
] });
|
|
1215
|
+
}
|
|
1216
|
+
const Template = utils.getTemplate("ObjectFieldTemplate", registry, uiOptions);
|
|
1217
|
+
const templateProps = {
|
|
1218
|
+
// getDisplayLabel() always returns false for object types, so just check the `uiOptions.label`
|
|
1219
|
+
title: uiOptions.label === false ? "" : title,
|
|
1220
|
+
description: uiOptions.label === false ? void 0 : description,
|
|
1221
|
+
properties: orderedProperties.map((name2) => {
|
|
1222
|
+
const addedByAdditionalProperties = has(schema, [utils.PROPERTIES_KEY, name2, utils.ADDITIONAL_PROPERTY_FLAG]);
|
|
1223
|
+
const fieldUiSchema = addedByAdditionalProperties ? uiSchema.additionalProperties : uiSchema[name2];
|
|
1224
|
+
const hidden = utils.getUiOptions(fieldUiSchema).widget === "hidden";
|
|
1225
|
+
const fieldIdSchema = get3(idSchema, [name2], {});
|
|
1226
|
+
return {
|
|
1227
|
+
content: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1228
|
+
SchemaField2,
|
|
1229
|
+
{
|
|
1230
|
+
name: name2,
|
|
1231
|
+
required: this.isRequired(name2),
|
|
1232
|
+
schema: get3(schema, [utils.PROPERTIES_KEY, name2], {}),
|
|
1233
|
+
uiSchema: fieldUiSchema,
|
|
1234
|
+
errorSchema: get3(errorSchema, name2),
|
|
1235
|
+
idSchema: fieldIdSchema,
|
|
1236
|
+
idPrefix,
|
|
1237
|
+
idSeparator,
|
|
1238
|
+
formData: get3(formData, name2),
|
|
1239
|
+
formContext,
|
|
1240
|
+
wasPropertyKeyModified: this.state.wasPropertyKeyModified,
|
|
1241
|
+
onKeyChange: this.onKeyChange(name2),
|
|
1242
|
+
onChange: this.onPropertyChange(name2, addedByAdditionalProperties),
|
|
1243
|
+
onBlur,
|
|
1244
|
+
onFocus,
|
|
1245
|
+
registry,
|
|
1246
|
+
disabled,
|
|
1247
|
+
readonly,
|
|
1248
|
+
hideError,
|
|
1249
|
+
onDropPropertyClick: this.onDropPropertyClick
|
|
1250
|
+
},
|
|
1251
|
+
name2
|
|
1252
|
+
),
|
|
1253
|
+
name: name2,
|
|
1254
|
+
readonly,
|
|
1255
|
+
disabled,
|
|
1256
|
+
required,
|
|
1257
|
+
hidden
|
|
1258
|
+
};
|
|
1259
|
+
}),
|
|
1260
|
+
readonly,
|
|
1261
|
+
disabled,
|
|
1262
|
+
required,
|
|
1263
|
+
idSchema,
|
|
1264
|
+
uiSchema,
|
|
1265
|
+
errorSchema,
|
|
1266
|
+
schema,
|
|
1267
|
+
formData,
|
|
1268
|
+
formContext,
|
|
1269
|
+
registry
|
|
1270
|
+
};
|
|
1271
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Template, { ...templateProps, onAddClick: this.handleAddClick });
|
|
1272
|
+
}
|
|
1273
|
+
};
|
|
1274
|
+
var ObjectField_default = ObjectField;
|
|
1275
|
+
var COMPONENT_TYPES = {
|
|
1276
|
+
array: "ArrayField",
|
|
1277
|
+
boolean: "BooleanField",
|
|
1278
|
+
integer: "NumberField",
|
|
1279
|
+
number: "NumberField",
|
|
1280
|
+
object: "ObjectField",
|
|
1281
|
+
string: "StringField",
|
|
1282
|
+
null: "NullField"
|
|
1283
|
+
};
|
|
1284
|
+
function getFieldComponent(schema, uiOptions, idSchema, registry) {
|
|
1285
|
+
const field = uiOptions.field;
|
|
1286
|
+
const { fields: fields2, translateString } = registry;
|
|
1287
|
+
if (typeof field === "function") {
|
|
1288
|
+
return field;
|
|
1289
|
+
}
|
|
1290
|
+
if (typeof field === "string" && field in fields2) {
|
|
1291
|
+
return fields2[field];
|
|
1292
|
+
}
|
|
1293
|
+
const schemaType = utils.getSchemaType(schema);
|
|
1294
|
+
const type = Array.isArray(schemaType) ? schemaType[0] : schemaType || "";
|
|
1295
|
+
const schemaId = schema.$id;
|
|
1296
|
+
let componentName = COMPONENT_TYPES[type];
|
|
1297
|
+
if (schemaId && schemaId in fields2) {
|
|
1298
|
+
componentName = schemaId;
|
|
1299
|
+
}
|
|
1300
|
+
if (!componentName && (schema.anyOf || schema.oneOf)) {
|
|
1301
|
+
return () => null;
|
|
1302
|
+
}
|
|
1303
|
+
return componentName in fields2 ? fields2[componentName] : () => {
|
|
1304
|
+
const UnsupportedFieldTemplate = utils.getTemplate(
|
|
1305
|
+
"UnsupportedFieldTemplate",
|
|
1306
|
+
registry,
|
|
1307
|
+
uiOptions
|
|
1308
|
+
);
|
|
1309
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1310
|
+
UnsupportedFieldTemplate,
|
|
1311
|
+
{
|
|
1312
|
+
schema,
|
|
1313
|
+
idSchema,
|
|
1314
|
+
reason: translateString(utils.TranslatableString.UnknownFieldType, [String(schema.type)]),
|
|
1315
|
+
registry
|
|
1316
|
+
}
|
|
1317
|
+
);
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
function SchemaFieldRender(props) {
|
|
1321
|
+
const {
|
|
1322
|
+
schema: _schema,
|
|
1323
|
+
idSchema: _idSchema,
|
|
1324
|
+
uiSchema,
|
|
1325
|
+
formData,
|
|
1326
|
+
errorSchema,
|
|
1327
|
+
idPrefix,
|
|
1328
|
+
idSeparator,
|
|
1329
|
+
name,
|
|
1330
|
+
onChange,
|
|
1331
|
+
onKeyChange,
|
|
1332
|
+
onDropPropertyClick,
|
|
1333
|
+
required,
|
|
1334
|
+
registry,
|
|
1335
|
+
wasPropertyKeyModified = false
|
|
1336
|
+
} = props;
|
|
1337
|
+
const { formContext, schemaUtils, globalUiOptions } = registry;
|
|
1338
|
+
const uiOptions = utils.getUiOptions(uiSchema, globalUiOptions);
|
|
1339
|
+
const FieldTemplate2 = utils.getTemplate("FieldTemplate", registry, uiOptions);
|
|
1340
|
+
const DescriptionFieldTemplate = utils.getTemplate(
|
|
1341
|
+
"DescriptionFieldTemplate",
|
|
1342
|
+
registry,
|
|
1343
|
+
uiOptions
|
|
1344
|
+
);
|
|
1345
|
+
const FieldHelpTemplate2 = utils.getTemplate("FieldHelpTemplate", registry, uiOptions);
|
|
1346
|
+
const FieldErrorTemplate2 = utils.getTemplate("FieldErrorTemplate", registry, uiOptions);
|
|
1347
|
+
const schema = schemaUtils.retrieveSchema(_schema, formData);
|
|
1348
|
+
const fieldId = _idSchema[utils.ID_KEY];
|
|
1349
|
+
const idSchema = utils.mergeObjects(
|
|
1350
|
+
schemaUtils.toIdSchema(schema, fieldId, formData, idPrefix, idSeparator),
|
|
1351
|
+
_idSchema
|
|
1352
|
+
);
|
|
1353
|
+
const handleFieldComponentChange = react.useCallback(
|
|
1354
|
+
(formData2, newErrorSchema, id2) => {
|
|
1355
|
+
const theId = id2 || fieldId;
|
|
1356
|
+
return onChange(formData2, newErrorSchema, theId);
|
|
1357
|
+
},
|
|
1358
|
+
[fieldId, onChange]
|
|
1359
|
+
);
|
|
1360
|
+
const FieldComponent = getFieldComponent(schema, uiOptions, idSchema, registry);
|
|
1361
|
+
const disabled = Boolean(props.disabled || uiOptions.disabled);
|
|
1362
|
+
const readonly = Boolean(props.readonly || uiOptions.readonly || props.schema.readOnly || schema.readOnly);
|
|
1363
|
+
const uiSchemaHideError = uiOptions.hideError;
|
|
1364
|
+
const hideError = uiSchemaHideError === void 0 ? props.hideError : Boolean(uiSchemaHideError);
|
|
1365
|
+
const autofocus = Boolean(props.autofocus || uiOptions.autofocus);
|
|
1366
|
+
if (Object.keys(schema).length === 0) {
|
|
1367
|
+
return null;
|
|
1368
|
+
}
|
|
1369
|
+
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
|
|
1370
|
+
const { __errors, ...fieldErrorSchema } = errorSchema || {};
|
|
1371
|
+
const fieldUiSchema = omit2(uiSchema, ["ui:classNames", "classNames", "ui:style"]);
|
|
1372
|
+
if (utils.UI_OPTIONS_KEY in fieldUiSchema) {
|
|
1373
|
+
fieldUiSchema[utils.UI_OPTIONS_KEY] = omit2(fieldUiSchema[utils.UI_OPTIONS_KEY], ["classNames", "style"]);
|
|
1374
|
+
}
|
|
1375
|
+
const field = /* @__PURE__ */ jsxRuntime.jsx(
|
|
1376
|
+
FieldComponent,
|
|
1377
|
+
{
|
|
1378
|
+
...props,
|
|
1379
|
+
onChange: handleFieldComponentChange,
|
|
1380
|
+
idSchema,
|
|
1381
|
+
schema,
|
|
1382
|
+
uiSchema: fieldUiSchema,
|
|
1383
|
+
disabled,
|
|
1384
|
+
readonly,
|
|
1385
|
+
hideError,
|
|
1386
|
+
autofocus,
|
|
1387
|
+
errorSchema: fieldErrorSchema,
|
|
1388
|
+
formContext,
|
|
1389
|
+
rawErrors: __errors
|
|
1390
|
+
}
|
|
1391
|
+
);
|
|
1392
|
+
const id = idSchema[utils.ID_KEY];
|
|
1393
|
+
let label;
|
|
1394
|
+
if (wasPropertyKeyModified) {
|
|
1395
|
+
label = name;
|
|
1396
|
+
} else {
|
|
1397
|
+
label = utils.ADDITIONAL_PROPERTY_FLAG in schema ? name : uiOptions.title || props.schema.title || schema.title || name;
|
|
1398
|
+
}
|
|
1399
|
+
const description = uiOptions.description || props.schema.description || schema.description || "";
|
|
1400
|
+
const richDescription = uiOptions.enableMarkdownInDescription ? /* @__PURE__ */ jsxRuntime.jsx(Markdown, { children: description }) : description;
|
|
1401
|
+
const help = uiOptions.help;
|
|
1402
|
+
const hidden = uiOptions.widget === "hidden";
|
|
1403
|
+
const classNames = ["form-group", "field", `field-${utils.getSchemaType(schema)}`];
|
|
1404
|
+
if (!hideError && __errors && __errors.length > 0) {
|
|
1405
|
+
classNames.push("field-error has-error has-danger");
|
|
1406
|
+
}
|
|
1407
|
+
if (uiSchema?.classNames) {
|
|
1408
|
+
{
|
|
1409
|
+
console.warn(
|
|
1410
|
+
"'uiSchema.classNames' is deprecated and may be removed in a major release; Use 'ui:classNames' instead."
|
|
1411
|
+
);
|
|
1412
|
+
}
|
|
1413
|
+
classNames.push(uiSchema.classNames);
|
|
1414
|
+
}
|
|
1415
|
+
if (uiOptions.classNames) {
|
|
1416
|
+
classNames.push(uiOptions.classNames);
|
|
1417
|
+
}
|
|
1418
|
+
const helpComponent = /* @__PURE__ */ jsxRuntime.jsx(
|
|
1419
|
+
FieldHelpTemplate2,
|
|
1420
|
+
{
|
|
1421
|
+
help,
|
|
1422
|
+
idSchema,
|
|
1423
|
+
schema,
|
|
1424
|
+
uiSchema,
|
|
1425
|
+
hasErrors: !hideError && __errors && __errors.length > 0,
|
|
1426
|
+
registry
|
|
1427
|
+
}
|
|
1428
|
+
);
|
|
1429
|
+
const errorsComponent = hideError || schema.anyOf || schema.oneOf ? void 0 : /* @__PURE__ */ jsxRuntime.jsx(
|
|
1430
|
+
FieldErrorTemplate2,
|
|
1431
|
+
{
|
|
1432
|
+
errors: __errors,
|
|
1433
|
+
errorSchema,
|
|
1434
|
+
idSchema,
|
|
1435
|
+
schema,
|
|
1436
|
+
uiSchema,
|
|
1437
|
+
registry
|
|
1438
|
+
}
|
|
1439
|
+
);
|
|
1440
|
+
const fieldProps = {
|
|
1441
|
+
description: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1442
|
+
DescriptionFieldTemplate,
|
|
1443
|
+
{
|
|
1444
|
+
id: utils.descriptionId(id),
|
|
1445
|
+
description: richDescription,
|
|
1446
|
+
schema,
|
|
1447
|
+
uiSchema,
|
|
1448
|
+
registry
|
|
1449
|
+
}
|
|
1450
|
+
),
|
|
1451
|
+
rawDescription: description,
|
|
1452
|
+
help: helpComponent,
|
|
1453
|
+
rawHelp: typeof help === "string" ? help : void 0,
|
|
1454
|
+
errors: errorsComponent,
|
|
1455
|
+
rawErrors: hideError ? void 0 : __errors,
|
|
1456
|
+
id,
|
|
1457
|
+
label,
|
|
1458
|
+
hidden,
|
|
1459
|
+
onChange,
|
|
1460
|
+
onKeyChange,
|
|
1461
|
+
onDropPropertyClick,
|
|
1462
|
+
required,
|
|
1463
|
+
disabled,
|
|
1464
|
+
readonly,
|
|
1465
|
+
hideError,
|
|
1466
|
+
displayLabel,
|
|
1467
|
+
classNames: classNames.join(" ").trim(),
|
|
1468
|
+
style: uiOptions.style,
|
|
1469
|
+
formContext,
|
|
1470
|
+
formData,
|
|
1471
|
+
schema,
|
|
1472
|
+
uiSchema,
|
|
1473
|
+
registry
|
|
1474
|
+
};
|
|
1475
|
+
const _AnyOfField = registry.fields.AnyOfField;
|
|
1476
|
+
const _OneOfField = registry.fields.OneOfField;
|
|
1477
|
+
const isReplacingAnyOrOneOf = uiSchema?.["ui:field"] && uiSchema?.["ui:fieldReplacesAnyOrOneOf"] === true;
|
|
1478
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FieldTemplate2, { ...fieldProps, children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1479
|
+
field,
|
|
1480
|
+
schema.anyOf && !isReplacingAnyOrOneOf && !schemaUtils.isSelect(schema) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1481
|
+
_AnyOfField,
|
|
1482
|
+
{
|
|
1483
|
+
name,
|
|
1484
|
+
disabled,
|
|
1485
|
+
readonly,
|
|
1486
|
+
hideError,
|
|
1487
|
+
errorSchema,
|
|
1488
|
+
formData,
|
|
1489
|
+
formContext,
|
|
1490
|
+
idPrefix,
|
|
1491
|
+
idSchema,
|
|
1492
|
+
idSeparator,
|
|
1493
|
+
onBlur: props.onBlur,
|
|
1494
|
+
onChange: props.onChange,
|
|
1495
|
+
onFocus: props.onFocus,
|
|
1496
|
+
options: schema.anyOf.map(
|
|
1497
|
+
(_schema2) => schemaUtils.retrieveSchema(isObject(_schema2) ? _schema2 : {}, formData)
|
|
1498
|
+
),
|
|
1499
|
+
registry,
|
|
1500
|
+
schema,
|
|
1501
|
+
uiSchema
|
|
1502
|
+
}
|
|
1503
|
+
),
|
|
1504
|
+
schema.oneOf && !isReplacingAnyOrOneOf && !schemaUtils.isSelect(schema) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1505
|
+
_OneOfField,
|
|
1506
|
+
{
|
|
1507
|
+
name,
|
|
1508
|
+
disabled,
|
|
1509
|
+
readonly,
|
|
1510
|
+
hideError,
|
|
1511
|
+
errorSchema,
|
|
1512
|
+
formData,
|
|
1513
|
+
formContext,
|
|
1514
|
+
idPrefix,
|
|
1515
|
+
idSchema,
|
|
1516
|
+
idSeparator,
|
|
1517
|
+
onBlur: props.onBlur,
|
|
1518
|
+
onChange: props.onChange,
|
|
1519
|
+
onFocus: props.onFocus,
|
|
1520
|
+
options: schema.oneOf.map(
|
|
1521
|
+
(_schema2) => schemaUtils.retrieveSchema(isObject(_schema2) ? _schema2 : {}, formData)
|
|
1522
|
+
),
|
|
1523
|
+
registry,
|
|
1524
|
+
schema,
|
|
1525
|
+
uiSchema
|
|
1526
|
+
}
|
|
1527
|
+
)
|
|
1528
|
+
] }) });
|
|
1529
|
+
}
|
|
1530
|
+
var SchemaField = class extends react.Component {
|
|
1531
|
+
shouldComponentUpdate(nextProps) {
|
|
1532
|
+
return !utils.deepEquals(this.props, nextProps);
|
|
1533
|
+
}
|
|
1534
|
+
render() {
|
|
1535
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SchemaFieldRender, { ...this.props });
|
|
1536
|
+
}
|
|
1537
|
+
};
|
|
1538
|
+
var SchemaField_default = SchemaField;
|
|
1539
|
+
function StringField(props) {
|
|
1540
|
+
const {
|
|
1541
|
+
schema,
|
|
1542
|
+
name,
|
|
1543
|
+
uiSchema,
|
|
1544
|
+
idSchema,
|
|
1545
|
+
formData,
|
|
1546
|
+
required,
|
|
1547
|
+
disabled = false,
|
|
1548
|
+
readonly = false,
|
|
1549
|
+
autofocus = false,
|
|
1550
|
+
onChange,
|
|
1551
|
+
onBlur,
|
|
1552
|
+
onFocus,
|
|
1553
|
+
registry,
|
|
1554
|
+
rawErrors
|
|
1555
|
+
} = props;
|
|
1556
|
+
const { title, format } = schema;
|
|
1557
|
+
const { widgets: widgets2, formContext, schemaUtils, globalUiOptions } = registry;
|
|
1558
|
+
const enumOptions = schemaUtils.isSelect(schema) ? utils.optionsList(schema) : void 0;
|
|
1559
|
+
let defaultWidget = enumOptions ? "select" : "text";
|
|
1560
|
+
if (format && utils.hasWidget(schema, format, widgets2)) {
|
|
1561
|
+
defaultWidget = format;
|
|
1562
|
+
}
|
|
1563
|
+
const { widget = defaultWidget, placeholder = "", title: uiTitle, ...options } = utils.getUiOptions(uiSchema);
|
|
1564
|
+
const displayLabel = schemaUtils.getDisplayLabel(schema, uiSchema, globalUiOptions);
|
|
1565
|
+
const label = uiTitle ?? title ?? name;
|
|
1566
|
+
const Widget = utils.getWidget(schema, widget, widgets2);
|
|
1567
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1568
|
+
Widget,
|
|
1569
|
+
{
|
|
1570
|
+
options: { ...options, enumOptions },
|
|
1571
|
+
schema,
|
|
1572
|
+
uiSchema,
|
|
1573
|
+
id: idSchema.$id,
|
|
1574
|
+
name,
|
|
1575
|
+
label,
|
|
1576
|
+
hideLabel: !displayLabel,
|
|
1577
|
+
value: formData,
|
|
1578
|
+
onChange,
|
|
1579
|
+
onBlur,
|
|
1580
|
+
onFocus,
|
|
1581
|
+
required,
|
|
1582
|
+
disabled,
|
|
1583
|
+
readonly,
|
|
1584
|
+
formContext,
|
|
1585
|
+
autofocus,
|
|
1586
|
+
registry,
|
|
1587
|
+
placeholder,
|
|
1588
|
+
rawErrors
|
|
1589
|
+
}
|
|
1590
|
+
);
|
|
1591
|
+
}
|
|
1592
|
+
var StringField_default = StringField;
|
|
1593
|
+
function NullField(props) {
|
|
1594
|
+
const { formData, onChange } = props;
|
|
1595
|
+
react.useEffect(() => {
|
|
1596
|
+
if (formData === void 0) {
|
|
1597
|
+
onChange(null);
|
|
1598
|
+
}
|
|
1599
|
+
}, [formData, onChange]);
|
|
1600
|
+
return null;
|
|
1601
|
+
}
|
|
1602
|
+
var NullField_default = NullField;
|
|
1603
|
+
|
|
1604
|
+
// src/components/fields/index.ts
|
|
1605
|
+
function fields() {
|
|
1606
|
+
return {
|
|
1607
|
+
AnyOfField: MultiSchemaField_default,
|
|
1608
|
+
ArrayField: ArrayField_default,
|
|
1609
|
+
// ArrayField falls back to SchemaField if ArraySchemaField is not defined, which it isn't by default
|
|
1610
|
+
BooleanField: BooleanField_default,
|
|
1611
|
+
NumberField: NumberField_default,
|
|
1612
|
+
ObjectField: ObjectField_default,
|
|
1613
|
+
OneOfField: MultiSchemaField_default,
|
|
1614
|
+
SchemaField: SchemaField_default,
|
|
1615
|
+
StringField: StringField_default,
|
|
1616
|
+
NullField: NullField_default
|
|
1617
|
+
};
|
|
1618
|
+
}
|
|
1619
|
+
var fields_default = fields;
|
|
1620
|
+
function ArrayFieldDescriptionTemplate(props) {
|
|
1621
|
+
const { idSchema, description, registry, schema, uiSchema } = props;
|
|
1622
|
+
const options = utils.getUiOptions(uiSchema, registry.globalUiOptions);
|
|
1623
|
+
const { label: displayLabel = true } = options;
|
|
1624
|
+
if (!description || !displayLabel) {
|
|
1625
|
+
return null;
|
|
1626
|
+
}
|
|
1627
|
+
const DescriptionFieldTemplate = utils.getTemplate(
|
|
1628
|
+
"DescriptionFieldTemplate",
|
|
1629
|
+
registry,
|
|
1630
|
+
options
|
|
1631
|
+
);
|
|
1632
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1633
|
+
DescriptionFieldTemplate,
|
|
1634
|
+
{
|
|
1635
|
+
id: utils.descriptionId(idSchema),
|
|
1636
|
+
description,
|
|
1637
|
+
schema,
|
|
1638
|
+
uiSchema,
|
|
1639
|
+
registry
|
|
1640
|
+
}
|
|
1641
|
+
);
|
|
1642
|
+
}
|
|
1643
|
+
function ArrayFieldItemTemplate(props) {
|
|
1644
|
+
const {
|
|
1645
|
+
children,
|
|
1646
|
+
className,
|
|
1647
|
+
disabled,
|
|
1648
|
+
hasToolbar,
|
|
1649
|
+
hasMoveDown,
|
|
1650
|
+
hasMoveUp,
|
|
1651
|
+
hasRemove,
|
|
1652
|
+
hasCopy,
|
|
1653
|
+
index,
|
|
1654
|
+
onCopyIndexClick,
|
|
1655
|
+
onDropIndexClick,
|
|
1656
|
+
onReorderClick,
|
|
1657
|
+
readonly,
|
|
1658
|
+
registry,
|
|
1659
|
+
uiSchema
|
|
1660
|
+
} = props;
|
|
1661
|
+
const { CopyButton: CopyButton2, MoveDownButton: MoveDownButton2, MoveUpButton: MoveUpButton2, RemoveButton: RemoveButton2 } = registry.templates.ButtonTemplates;
|
|
1662
|
+
const btnStyle = {
|
|
1663
|
+
flex: 1,
|
|
1664
|
+
paddingLeft: 6,
|
|
1665
|
+
paddingRight: 6,
|
|
1666
|
+
fontWeight: "bold"
|
|
1667
|
+
};
|
|
1668
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
|
|
1669
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: hasToolbar ? "col-xs-9" : "col-xs-12", children }),
|
|
1670
|
+
hasToolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-xs-3 array-item-toolbox", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1671
|
+
"div",
|
|
1672
|
+
{
|
|
1673
|
+
className: "btn-group",
|
|
1674
|
+
style: {
|
|
1675
|
+
display: "flex",
|
|
1676
|
+
justifyContent: "space-around"
|
|
1677
|
+
},
|
|
1678
|
+
children: [
|
|
1679
|
+
(hasMoveUp || hasMoveDown) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1680
|
+
MoveUpButton2,
|
|
1681
|
+
{
|
|
1682
|
+
style: btnStyle,
|
|
1683
|
+
disabled: disabled || readonly || !hasMoveUp,
|
|
1684
|
+
onClick: onReorderClick(index, index - 1),
|
|
1685
|
+
uiSchema,
|
|
1686
|
+
registry
|
|
1687
|
+
}
|
|
1688
|
+
),
|
|
1689
|
+
(hasMoveUp || hasMoveDown) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1690
|
+
MoveDownButton2,
|
|
1691
|
+
{
|
|
1692
|
+
style: btnStyle,
|
|
1693
|
+
disabled: disabled || readonly || !hasMoveDown,
|
|
1694
|
+
onClick: onReorderClick(index, index + 1),
|
|
1695
|
+
uiSchema,
|
|
1696
|
+
registry
|
|
1697
|
+
}
|
|
1698
|
+
),
|
|
1699
|
+
hasCopy && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1700
|
+
CopyButton2,
|
|
1701
|
+
{
|
|
1702
|
+
style: btnStyle,
|
|
1703
|
+
disabled: disabled || readonly,
|
|
1704
|
+
onClick: onCopyIndexClick(index),
|
|
1705
|
+
uiSchema,
|
|
1706
|
+
registry
|
|
1707
|
+
}
|
|
1708
|
+
),
|
|
1709
|
+
hasRemove && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1710
|
+
RemoveButton2,
|
|
1711
|
+
{
|
|
1712
|
+
style: btnStyle,
|
|
1713
|
+
disabled: disabled || readonly,
|
|
1714
|
+
onClick: onDropIndexClick(index),
|
|
1715
|
+
uiSchema,
|
|
1716
|
+
registry
|
|
1717
|
+
}
|
|
1718
|
+
)
|
|
1719
|
+
]
|
|
1720
|
+
}
|
|
1721
|
+
) })
|
|
1722
|
+
] });
|
|
1723
|
+
}
|
|
1724
|
+
function ArrayFieldTemplate(props) {
|
|
1725
|
+
const {
|
|
1726
|
+
canAdd,
|
|
1727
|
+
className,
|
|
1728
|
+
disabled,
|
|
1729
|
+
idSchema,
|
|
1730
|
+
uiSchema,
|
|
1731
|
+
items,
|
|
1732
|
+
onAddClick,
|
|
1733
|
+
readonly,
|
|
1734
|
+
registry,
|
|
1735
|
+
required,
|
|
1736
|
+
schema,
|
|
1737
|
+
title
|
|
1738
|
+
} = props;
|
|
1739
|
+
const uiOptions = utils.getUiOptions(uiSchema);
|
|
1740
|
+
const ArrayFieldDescriptionTemplate2 = utils.getTemplate(
|
|
1741
|
+
"ArrayFieldDescriptionTemplate",
|
|
1742
|
+
registry,
|
|
1743
|
+
uiOptions
|
|
1744
|
+
);
|
|
1745
|
+
const ArrayFieldItemTemplate2 = utils.getTemplate(
|
|
1746
|
+
"ArrayFieldItemTemplate",
|
|
1747
|
+
registry,
|
|
1748
|
+
uiOptions
|
|
1749
|
+
);
|
|
1750
|
+
const ArrayFieldTitleTemplate2 = utils.getTemplate(
|
|
1751
|
+
"ArrayFieldTitleTemplate",
|
|
1752
|
+
registry,
|
|
1753
|
+
uiOptions
|
|
1754
|
+
);
|
|
1755
|
+
const {
|
|
1756
|
+
ButtonTemplates: { AddButton: AddButton2 }
|
|
1757
|
+
} = registry.templates;
|
|
1758
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className, id: idSchema.$id, children: [
|
|
1759
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1760
|
+
ArrayFieldTitleTemplate2,
|
|
1761
|
+
{
|
|
1762
|
+
idSchema,
|
|
1763
|
+
title: uiOptions.title || title,
|
|
1764
|
+
required,
|
|
1765
|
+
schema,
|
|
1766
|
+
uiSchema,
|
|
1767
|
+
registry
|
|
1768
|
+
}
|
|
1769
|
+
),
|
|
1770
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1771
|
+
ArrayFieldDescriptionTemplate2,
|
|
1772
|
+
{
|
|
1773
|
+
idSchema,
|
|
1774
|
+
description: uiOptions.description || schema.description,
|
|
1775
|
+
schema,
|
|
1776
|
+
uiSchema,
|
|
1777
|
+
registry
|
|
1778
|
+
}
|
|
1779
|
+
),
|
|
1780
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "row array-item-list", children: items && items.map(({ key, ...itemProps }) => /* @__PURE__ */ jsxRuntime.jsx(ArrayFieldItemTemplate2, { ...itemProps }, key)) }),
|
|
1781
|
+
canAdd && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1782
|
+
AddButton2,
|
|
1783
|
+
{
|
|
1784
|
+
className: "array-item-add",
|
|
1785
|
+
onClick: onAddClick,
|
|
1786
|
+
disabled: disabled || readonly,
|
|
1787
|
+
uiSchema,
|
|
1788
|
+
registry
|
|
1789
|
+
}
|
|
1790
|
+
)
|
|
1791
|
+
] });
|
|
1792
|
+
}
|
|
1793
|
+
function ArrayFieldTitleTemplate(props) {
|
|
1794
|
+
const { idSchema, title, schema, uiSchema, required, registry } = props;
|
|
1795
|
+
const options = utils.getUiOptions(uiSchema, registry.globalUiOptions);
|
|
1796
|
+
const { label: displayLabel = true } = options;
|
|
1797
|
+
if (!title || !displayLabel) {
|
|
1798
|
+
return null;
|
|
1799
|
+
}
|
|
1800
|
+
const TitleFieldTemplate = utils.getTemplate(
|
|
1801
|
+
"TitleFieldTemplate",
|
|
1802
|
+
registry,
|
|
1803
|
+
options
|
|
1804
|
+
);
|
|
1805
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1806
|
+
TitleFieldTemplate,
|
|
1807
|
+
{
|
|
1808
|
+
id: utils.titleId(idSchema),
|
|
1809
|
+
title,
|
|
1810
|
+
required,
|
|
1811
|
+
schema,
|
|
1812
|
+
uiSchema,
|
|
1813
|
+
registry
|
|
1814
|
+
}
|
|
1815
|
+
);
|
|
1816
|
+
}
|
|
1817
|
+
function BaseInputTemplate(props) {
|
|
1818
|
+
const {
|
|
1819
|
+
id,
|
|
1820
|
+
name,
|
|
1821
|
+
// remove this from ...rest
|
|
1822
|
+
value,
|
|
1823
|
+
readonly,
|
|
1824
|
+
disabled,
|
|
1825
|
+
autofocus,
|
|
1826
|
+
onBlur,
|
|
1827
|
+
onFocus,
|
|
1828
|
+
onChange,
|
|
1829
|
+
onChangeOverride,
|
|
1830
|
+
options,
|
|
1831
|
+
schema,
|
|
1832
|
+
uiSchema,
|
|
1833
|
+
formContext,
|
|
1834
|
+
registry,
|
|
1835
|
+
rawErrors,
|
|
1836
|
+
type,
|
|
1837
|
+
hideLabel,
|
|
1838
|
+
// remove this from ...rest
|
|
1839
|
+
hideError,
|
|
1840
|
+
// remove this from ...rest
|
|
1841
|
+
...rest
|
|
1842
|
+
} = props;
|
|
1843
|
+
if (!id) {
|
|
1844
|
+
console.log("No id for", props);
|
|
1845
|
+
throw new Error(`no id for props ${JSON.stringify(props)}`);
|
|
1846
|
+
}
|
|
1847
|
+
const inputProps = {
|
|
1848
|
+
...rest,
|
|
1849
|
+
...utils.getInputProps(schema, type, options)
|
|
1850
|
+
};
|
|
1851
|
+
let inputValue;
|
|
1852
|
+
if (inputProps.type === "number" || inputProps.type === "integer") {
|
|
1853
|
+
inputValue = value || value === 0 ? value : "";
|
|
1854
|
+
} else {
|
|
1855
|
+
inputValue = value == null ? "" : value;
|
|
1856
|
+
}
|
|
1857
|
+
const _onChange = react.useCallback(
|
|
1858
|
+
({ target: { value: value2 } }) => onChange(value2 === "" ? options.emptyValue : value2),
|
|
1859
|
+
[onChange, options]
|
|
1860
|
+
);
|
|
1861
|
+
const _onBlur = react.useCallback(({ target: { value: value2 } }) => onBlur(id, value2), [onBlur, id]);
|
|
1862
|
+
const _onFocus = react.useCallback(
|
|
1863
|
+
({ target: { value: value2 } }) => onFocus(id, value2),
|
|
1864
|
+
[onFocus, id]
|
|
1865
|
+
);
|
|
1866
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1867
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1868
|
+
"input",
|
|
1869
|
+
{
|
|
1870
|
+
id,
|
|
1871
|
+
name: id,
|
|
1872
|
+
className: "form-control",
|
|
1873
|
+
readOnly: readonly,
|
|
1874
|
+
disabled,
|
|
1875
|
+
autoFocus: autofocus,
|
|
1876
|
+
value: inputValue,
|
|
1877
|
+
...inputProps,
|
|
1878
|
+
list: schema.examples ? utils.examplesId(id) : void 0,
|
|
1879
|
+
onChange: onChangeOverride || _onChange,
|
|
1880
|
+
onBlur: _onBlur,
|
|
1881
|
+
onFocus: _onFocus,
|
|
1882
|
+
"aria-describedby": utils.ariaDescribedByIds(id, !!schema.examples)
|
|
1883
|
+
}
|
|
1884
|
+
),
|
|
1885
|
+
Array.isArray(schema.examples) && /* @__PURE__ */ jsxRuntime.jsx("datalist", { id: utils.examplesId(id), children: schema.examples.concat(schema.default && !schema.examples.includes(schema.default) ? [schema.default] : []).map((example) => {
|
|
1886
|
+
return /* @__PURE__ */ jsxRuntime.jsx("option", { value: example }, example);
|
|
1887
|
+
}) }, `datalist_${id}`)
|
|
1888
|
+
] });
|
|
1889
|
+
}
|
|
1890
|
+
function SubmitButton({ uiSchema }) {
|
|
1891
|
+
const { submitText, norender, props: submitButtonProps = {} } = utils.getSubmitButtonOptions(uiSchema);
|
|
1892
|
+
if (norender) {
|
|
1893
|
+
return null;
|
|
1894
|
+
}
|
|
1895
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", ...submitButtonProps, className: `btn btn-info ${submitButtonProps.className || ""}`, children: submitText }) });
|
|
1896
|
+
}
|
|
1897
|
+
function IconButton(props) {
|
|
1898
|
+
const { iconType = "default", icon, className, uiSchema, registry, ...otherProps } = props;
|
|
1899
|
+
return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: `btn btn-${iconType} ${className}`, ...otherProps, children: /* @__PURE__ */ jsxRuntime.jsx("i", { className: `glyphicon glyphicon-${icon}` }) });
|
|
1900
|
+
}
|
|
1901
|
+
function CopyButton(props) {
|
|
1902
|
+
const {
|
|
1903
|
+
registry: { translateString }
|
|
1904
|
+
} = props;
|
|
1905
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1906
|
+
IconButton,
|
|
1907
|
+
{
|
|
1908
|
+
title: translateString(utils.TranslatableString.CopyButton),
|
|
1909
|
+
className: "array-item-copy",
|
|
1910
|
+
...props,
|
|
1911
|
+
icon: "copy"
|
|
1912
|
+
}
|
|
1913
|
+
);
|
|
1914
|
+
}
|
|
1915
|
+
function MoveDownButton(props) {
|
|
1916
|
+
const {
|
|
1917
|
+
registry: { translateString }
|
|
1918
|
+
} = props;
|
|
1919
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1920
|
+
IconButton,
|
|
1921
|
+
{
|
|
1922
|
+
title: translateString(utils.TranslatableString.MoveDownButton),
|
|
1923
|
+
className: "array-item-move-down",
|
|
1924
|
+
...props,
|
|
1925
|
+
icon: "arrow-down"
|
|
1926
|
+
}
|
|
1927
|
+
);
|
|
1928
|
+
}
|
|
1929
|
+
function MoveUpButton(props) {
|
|
1930
|
+
const {
|
|
1931
|
+
registry: { translateString }
|
|
1932
|
+
} = props;
|
|
1933
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1934
|
+
IconButton,
|
|
1935
|
+
{
|
|
1936
|
+
title: translateString(utils.TranslatableString.MoveUpButton),
|
|
1937
|
+
className: "array-item-move-up",
|
|
1938
|
+
...props,
|
|
1939
|
+
icon: "arrow-up"
|
|
1940
|
+
}
|
|
1941
|
+
);
|
|
1942
|
+
}
|
|
1943
|
+
function RemoveButton(props) {
|
|
1944
|
+
const {
|
|
1945
|
+
registry: { translateString }
|
|
1946
|
+
} = props;
|
|
1947
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1948
|
+
IconButton,
|
|
1949
|
+
{
|
|
1950
|
+
title: translateString(utils.TranslatableString.RemoveButton),
|
|
1951
|
+
className: "array-item-remove",
|
|
1952
|
+
...props,
|
|
1953
|
+
iconType: "danger",
|
|
1954
|
+
icon: "remove"
|
|
1955
|
+
}
|
|
1956
|
+
);
|
|
1957
|
+
}
|
|
1958
|
+
function AddButton({
|
|
1959
|
+
className,
|
|
1960
|
+
onClick,
|
|
1961
|
+
disabled,
|
|
1962
|
+
registry
|
|
1963
|
+
}) {
|
|
1964
|
+
const { translateString } = registry;
|
|
1965
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "row", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: `col-xs-3 col-xs-offset-9 text-right ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1966
|
+
IconButton,
|
|
1967
|
+
{
|
|
1968
|
+
iconType: "info",
|
|
1969
|
+
icon: "plus",
|
|
1970
|
+
className: "btn-add col-xs-12",
|
|
1971
|
+
title: translateString(utils.TranslatableString.AddButton),
|
|
1972
|
+
onClick,
|
|
1973
|
+
disabled,
|
|
1974
|
+
registry
|
|
1975
|
+
}
|
|
1976
|
+
) }) });
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
// src/components/templates/ButtonTemplates/index.ts
|
|
1980
|
+
function buttonTemplates() {
|
|
1981
|
+
return {
|
|
1982
|
+
SubmitButton,
|
|
1983
|
+
AddButton,
|
|
1984
|
+
CopyButton,
|
|
1985
|
+
MoveDownButton,
|
|
1986
|
+
MoveUpButton,
|
|
1987
|
+
RemoveButton
|
|
1988
|
+
};
|
|
1989
|
+
}
|
|
1990
|
+
var ButtonTemplates_default = buttonTemplates;
|
|
1991
|
+
function DescriptionField(props) {
|
|
1992
|
+
const { id, description } = props;
|
|
1993
|
+
if (!description) {
|
|
1994
|
+
return null;
|
|
1995
|
+
}
|
|
1996
|
+
if (typeof description === "string") {
|
|
1997
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { id, className: "field-description", children: description });
|
|
1998
|
+
} else {
|
|
1999
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { id, className: "field-description", children: description });
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
function ErrorList({
|
|
2003
|
+
errors,
|
|
2004
|
+
registry
|
|
2005
|
+
}) {
|
|
2006
|
+
const { translateString } = registry;
|
|
2007
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "panel panel-danger errors", children: [
|
|
2008
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "panel-heading", children: /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "panel-title", children: translateString(utils.TranslatableString.ErrorsLabel) }) }),
|
|
2009
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "list-group", children: errors.map((error, i) => {
|
|
2010
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { className: "list-group-item text-danger", children: error.stack }, i);
|
|
2011
|
+
}) })
|
|
2012
|
+
] });
|
|
2013
|
+
}
|
|
2014
|
+
var REQUIRED_FIELD_SYMBOL = "*";
|
|
2015
|
+
function Label(props) {
|
|
2016
|
+
const { label, required, id } = props;
|
|
2017
|
+
if (!label) {
|
|
2018
|
+
return null;
|
|
2019
|
+
}
|
|
2020
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "control-label", htmlFor: id, children: [
|
|
2021
|
+
label,
|
|
2022
|
+
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "required", children: REQUIRED_FIELD_SYMBOL })
|
|
2023
|
+
] });
|
|
2024
|
+
}
|
|
2025
|
+
function FieldTemplate(props) {
|
|
2026
|
+
const { id, label, children, errors, help, description, hidden, required, displayLabel, registry, uiSchema } = props;
|
|
2027
|
+
const uiOptions = utils.getUiOptions(uiSchema);
|
|
2028
|
+
const WrapIfAdditionalTemplate2 = utils.getTemplate(
|
|
2029
|
+
"WrapIfAdditionalTemplate",
|
|
2030
|
+
registry,
|
|
2031
|
+
uiOptions
|
|
2032
|
+
);
|
|
2033
|
+
if (hidden) {
|
|
2034
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden", children });
|
|
2035
|
+
}
|
|
2036
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(WrapIfAdditionalTemplate2, { ...props, children: [
|
|
2037
|
+
displayLabel && /* @__PURE__ */ jsxRuntime.jsx(Label, { label, required, id }),
|
|
2038
|
+
displayLabel && description ? description : null,
|
|
2039
|
+
children,
|
|
2040
|
+
errors,
|
|
2041
|
+
help
|
|
2042
|
+
] });
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
// src/components/templates/FieldTemplate/index.ts
|
|
2046
|
+
var FieldTemplate_default = FieldTemplate;
|
|
2047
|
+
function FieldErrorTemplate(props) {
|
|
2048
|
+
const { errors = [], idSchema } = props;
|
|
2049
|
+
if (errors.length === 0) {
|
|
2050
|
+
return null;
|
|
2051
|
+
}
|
|
2052
|
+
const id = utils.errorId(idSchema);
|
|
2053
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx("ul", { id, className: "error-detail bs-callout bs-callout-info", children: errors.filter((elem) => !!elem).map((error, index) => {
|
|
2054
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { className: "text-danger", children: error }, index);
|
|
2055
|
+
}) }) });
|
|
2056
|
+
}
|
|
2057
|
+
function FieldHelpTemplate(props) {
|
|
2058
|
+
const { idSchema, help } = props;
|
|
2059
|
+
if (!help) {
|
|
2060
|
+
return null;
|
|
2061
|
+
}
|
|
2062
|
+
const id = utils.helpId(idSchema);
|
|
2063
|
+
if (typeof help === "string") {
|
|
2064
|
+
return /* @__PURE__ */ jsxRuntime.jsx("p", { id, className: "help-block", children: help });
|
|
2065
|
+
}
|
|
2066
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { id, className: "help-block", children: help });
|
|
2067
|
+
}
|
|
2068
|
+
function ObjectFieldTemplate(props) {
|
|
2069
|
+
const {
|
|
2070
|
+
description,
|
|
2071
|
+
disabled,
|
|
2072
|
+
formData,
|
|
2073
|
+
idSchema,
|
|
2074
|
+
onAddClick,
|
|
2075
|
+
properties,
|
|
2076
|
+
readonly,
|
|
2077
|
+
registry,
|
|
2078
|
+
required,
|
|
2079
|
+
schema,
|
|
2080
|
+
title,
|
|
2081
|
+
uiSchema
|
|
2082
|
+
} = props;
|
|
2083
|
+
const options = utils.getUiOptions(uiSchema);
|
|
2084
|
+
const TitleFieldTemplate = utils.getTemplate("TitleFieldTemplate", registry, options);
|
|
2085
|
+
const DescriptionFieldTemplate = utils.getTemplate(
|
|
2086
|
+
"DescriptionFieldTemplate",
|
|
2087
|
+
registry,
|
|
2088
|
+
options
|
|
2089
|
+
);
|
|
2090
|
+
const {
|
|
2091
|
+
ButtonTemplates: { AddButton: AddButton2 }
|
|
2092
|
+
} = registry.templates;
|
|
2093
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { id: idSchema.$id, children: [
|
|
2094
|
+
title && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2095
|
+
TitleFieldTemplate,
|
|
2096
|
+
{
|
|
2097
|
+
id: utils.titleId(idSchema),
|
|
2098
|
+
title,
|
|
2099
|
+
required,
|
|
2100
|
+
schema,
|
|
2101
|
+
uiSchema,
|
|
2102
|
+
registry
|
|
2103
|
+
}
|
|
2104
|
+
),
|
|
2105
|
+
description && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2106
|
+
DescriptionFieldTemplate,
|
|
2107
|
+
{
|
|
2108
|
+
id: utils.descriptionId(idSchema),
|
|
2109
|
+
description,
|
|
2110
|
+
schema,
|
|
2111
|
+
uiSchema,
|
|
2112
|
+
registry
|
|
2113
|
+
}
|
|
2114
|
+
),
|
|
2115
|
+
properties.map((prop) => prop.content),
|
|
2116
|
+
utils.canExpand(schema, uiSchema, formData) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2117
|
+
AddButton2,
|
|
2118
|
+
{
|
|
2119
|
+
className: "object-property-expand",
|
|
2120
|
+
onClick: onAddClick(schema),
|
|
2121
|
+
disabled: disabled || readonly,
|
|
2122
|
+
uiSchema,
|
|
2123
|
+
registry
|
|
2124
|
+
}
|
|
2125
|
+
)
|
|
2126
|
+
] });
|
|
2127
|
+
}
|
|
2128
|
+
var REQUIRED_FIELD_SYMBOL2 = "*";
|
|
2129
|
+
function TitleField(props) {
|
|
2130
|
+
const { id, title, required } = props;
|
|
2131
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("legend", { id, children: [
|
|
2132
|
+
title,
|
|
2133
|
+
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "required", children: REQUIRED_FIELD_SYMBOL2 })
|
|
2134
|
+
] });
|
|
2135
|
+
}
|
|
2136
|
+
function UnsupportedField(props) {
|
|
2137
|
+
const { schema, idSchema, reason, registry } = props;
|
|
2138
|
+
const { translateString } = registry;
|
|
2139
|
+
let translateEnum = utils.TranslatableString.UnsupportedField;
|
|
2140
|
+
const translateParams = [];
|
|
2141
|
+
if (idSchema && idSchema.$id) {
|
|
2142
|
+
translateEnum = utils.TranslatableString.UnsupportedFieldWithId;
|
|
2143
|
+
translateParams.push(idSchema.$id);
|
|
2144
|
+
}
|
|
2145
|
+
if (reason) {
|
|
2146
|
+
translateEnum = translateEnum === utils.TranslatableString.UnsupportedField ? utils.TranslatableString.UnsupportedFieldWithReason : utils.TranslatableString.UnsupportedFieldWithIdAndReason;
|
|
2147
|
+
translateParams.push(reason);
|
|
2148
|
+
}
|
|
2149
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "unsupported-field", children: [
|
|
2150
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: /* @__PURE__ */ jsxRuntime.jsx(Markdown, { children: translateString(translateEnum, translateParams) }) }),
|
|
2151
|
+
schema && /* @__PURE__ */ jsxRuntime.jsx("pre", { children: JSON.stringify(schema, null, 2) })
|
|
2152
|
+
] });
|
|
2153
|
+
}
|
|
2154
|
+
var UnsupportedField_default = UnsupportedField;
|
|
2155
|
+
function WrapIfAdditionalTemplate(props) {
|
|
2156
|
+
const {
|
|
2157
|
+
id,
|
|
2158
|
+
classNames,
|
|
2159
|
+
style,
|
|
2160
|
+
disabled,
|
|
2161
|
+
label,
|
|
2162
|
+
onKeyChange,
|
|
2163
|
+
onDropPropertyClick,
|
|
2164
|
+
readonly,
|
|
2165
|
+
required,
|
|
2166
|
+
schema,
|
|
2167
|
+
children,
|
|
2168
|
+
uiSchema,
|
|
2169
|
+
registry
|
|
2170
|
+
} = props;
|
|
2171
|
+
const { templates: templates2, translateString } = registry;
|
|
2172
|
+
const { RemoveButton: RemoveButton2 } = templates2.ButtonTemplates;
|
|
2173
|
+
const keyLabel = translateString(utils.TranslatableString.KeyLabel, [label]);
|
|
2174
|
+
const additional = utils.ADDITIONAL_PROPERTY_FLAG in schema;
|
|
2175
|
+
if (!additional) {
|
|
2176
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames, style, children });
|
|
2177
|
+
}
|
|
2178
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: classNames, style, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "row", children: [
|
|
2179
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-xs-5 form-additional", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "form-group", children: [
|
|
2180
|
+
/* @__PURE__ */ jsxRuntime.jsx(Label, { label: keyLabel, required, id: `${id}-key` }),
|
|
2181
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2182
|
+
"input",
|
|
2183
|
+
{
|
|
2184
|
+
className: "form-control",
|
|
2185
|
+
type: "text",
|
|
2186
|
+
id: `${id}-key`,
|
|
2187
|
+
onBlur: (event) => onKeyChange(event.target.value),
|
|
2188
|
+
defaultValue: label
|
|
2189
|
+
}
|
|
2190
|
+
)
|
|
2191
|
+
] }) }),
|
|
2192
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "form-additional form-group col-xs-5", children }),
|
|
2193
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "col-xs-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2194
|
+
RemoveButton2,
|
|
2195
|
+
{
|
|
2196
|
+
className: "array-item-remove btn-block",
|
|
2197
|
+
style: { border: "0" },
|
|
2198
|
+
disabled: disabled || readonly,
|
|
2199
|
+
onClick: onDropPropertyClick(label),
|
|
2200
|
+
uiSchema,
|
|
2201
|
+
registry
|
|
2202
|
+
}
|
|
2203
|
+
) })
|
|
2204
|
+
] }) });
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
// src/components/templates/index.ts
|
|
2208
|
+
function templates() {
|
|
2209
|
+
return {
|
|
2210
|
+
ArrayFieldDescriptionTemplate,
|
|
2211
|
+
ArrayFieldItemTemplate,
|
|
2212
|
+
ArrayFieldTemplate,
|
|
2213
|
+
ArrayFieldTitleTemplate,
|
|
2214
|
+
ButtonTemplates: ButtonTemplates_default(),
|
|
2215
|
+
BaseInputTemplate,
|
|
2216
|
+
DescriptionFieldTemplate: DescriptionField,
|
|
2217
|
+
ErrorListTemplate: ErrorList,
|
|
2218
|
+
FieldTemplate: FieldTemplate_default,
|
|
2219
|
+
FieldErrorTemplate,
|
|
2220
|
+
FieldHelpTemplate,
|
|
2221
|
+
ObjectFieldTemplate,
|
|
2222
|
+
TitleFieldTemplate: TitleField,
|
|
2223
|
+
UnsupportedFieldTemplate: UnsupportedField_default,
|
|
2224
|
+
WrapIfAdditionalTemplate
|
|
2225
|
+
};
|
|
2226
|
+
}
|
|
2227
|
+
var templates_default = templates;
|
|
2228
|
+
function rangeOptions(start, stop) {
|
|
2229
|
+
const options = [];
|
|
2230
|
+
for (let i = start; i <= stop; i++) {
|
|
2231
|
+
options.push({ value: i, label: utils.pad(i, 2) });
|
|
2232
|
+
}
|
|
2233
|
+
return options;
|
|
2234
|
+
}
|
|
2235
|
+
function readyForChange(state) {
|
|
2236
|
+
return Object.values(state).every((value) => value !== -1);
|
|
2237
|
+
}
|
|
2238
|
+
function dateElementProps(state, time, yearsRange = [1900, (/* @__PURE__ */ new Date()).getFullYear() + 2]) {
|
|
2239
|
+
const { year, month, day, hour, minute, second } = state;
|
|
2240
|
+
const data = [
|
|
2241
|
+
{
|
|
2242
|
+
type: "year",
|
|
2243
|
+
range: yearsRange,
|
|
2244
|
+
value: year
|
|
2245
|
+
},
|
|
2246
|
+
{ type: "month", range: [1, 12], value: month },
|
|
2247
|
+
{ type: "day", range: [1, 31], value: day }
|
|
2248
|
+
];
|
|
2249
|
+
if (time) {
|
|
2250
|
+
data.push(
|
|
2251
|
+
{ type: "hour", range: [0, 23], value: hour },
|
|
2252
|
+
{ type: "minute", range: [0, 59], value: minute },
|
|
2253
|
+
{ type: "second", range: [0, 59], value: second }
|
|
2254
|
+
);
|
|
2255
|
+
}
|
|
2256
|
+
return data;
|
|
2257
|
+
}
|
|
2258
|
+
function DateElement({
|
|
2259
|
+
type,
|
|
2260
|
+
range,
|
|
2261
|
+
value,
|
|
2262
|
+
select,
|
|
2263
|
+
rootId,
|
|
2264
|
+
name,
|
|
2265
|
+
disabled,
|
|
2266
|
+
readonly,
|
|
2267
|
+
autofocus,
|
|
2268
|
+
registry,
|
|
2269
|
+
onBlur,
|
|
2270
|
+
onFocus
|
|
2271
|
+
}) {
|
|
2272
|
+
const id = rootId + "_" + type;
|
|
2273
|
+
const { SelectWidget: SelectWidget2 } = registry.widgets;
|
|
2274
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2275
|
+
SelectWidget2,
|
|
2276
|
+
{
|
|
2277
|
+
schema: { type: "integer" },
|
|
2278
|
+
id,
|
|
2279
|
+
name,
|
|
2280
|
+
className: "form-control",
|
|
2281
|
+
options: { enumOptions: rangeOptions(range[0], range[1]) },
|
|
2282
|
+
placeholder: type,
|
|
2283
|
+
value,
|
|
2284
|
+
disabled,
|
|
2285
|
+
readonly,
|
|
2286
|
+
autofocus,
|
|
2287
|
+
onChange: (value2) => select(type, value2),
|
|
2288
|
+
onBlur,
|
|
2289
|
+
onFocus,
|
|
2290
|
+
registry,
|
|
2291
|
+
label: "",
|
|
2292
|
+
"aria-describedby": utils.ariaDescribedByIds(rootId)
|
|
2293
|
+
}
|
|
2294
|
+
);
|
|
2295
|
+
}
|
|
2296
|
+
function AltDateWidget({
|
|
2297
|
+
time = false,
|
|
2298
|
+
disabled = false,
|
|
2299
|
+
readonly = false,
|
|
2300
|
+
autofocus = false,
|
|
2301
|
+
options,
|
|
2302
|
+
id,
|
|
2303
|
+
name,
|
|
2304
|
+
registry,
|
|
2305
|
+
onBlur,
|
|
2306
|
+
onFocus,
|
|
2307
|
+
onChange,
|
|
2308
|
+
value
|
|
2309
|
+
}) {
|
|
2310
|
+
const { translateString } = registry;
|
|
2311
|
+
const [lastValue, setLastValue] = react.useState(value);
|
|
2312
|
+
const [state, setState] = react.useReducer((state2, action) => {
|
|
2313
|
+
return { ...state2, ...action };
|
|
2314
|
+
}, utils.parseDateString(value, time));
|
|
2315
|
+
react.useEffect(() => {
|
|
2316
|
+
const stateValue = utils.toDateString(state, time);
|
|
2317
|
+
if (readyForChange(state) && stateValue !== value) {
|
|
2318
|
+
onChange(stateValue);
|
|
2319
|
+
} else if (lastValue !== value) {
|
|
2320
|
+
setLastValue(value);
|
|
2321
|
+
setState(utils.parseDateString(value, time));
|
|
2322
|
+
}
|
|
2323
|
+
}, [time, value, onChange, state, lastValue]);
|
|
2324
|
+
const handleChange = react.useCallback((property, value2) => {
|
|
2325
|
+
setState({ [property]: value2 });
|
|
2326
|
+
}, []);
|
|
2327
|
+
const handleSetNow = react.useCallback(
|
|
2328
|
+
(event) => {
|
|
2329
|
+
event.preventDefault();
|
|
2330
|
+
if (disabled || readonly) {
|
|
2331
|
+
return;
|
|
2332
|
+
}
|
|
2333
|
+
const nextState = utils.parseDateString((/* @__PURE__ */ new Date()).toJSON(), time);
|
|
2334
|
+
onChange(utils.toDateString(nextState, time));
|
|
2335
|
+
},
|
|
2336
|
+
[disabled, readonly, time]
|
|
2337
|
+
);
|
|
2338
|
+
const handleClear = react.useCallback(
|
|
2339
|
+
(event) => {
|
|
2340
|
+
event.preventDefault();
|
|
2341
|
+
if (disabled || readonly) {
|
|
2342
|
+
return;
|
|
2343
|
+
}
|
|
2344
|
+
onChange(void 0);
|
|
2345
|
+
},
|
|
2346
|
+
[disabled, readonly, onChange]
|
|
2347
|
+
);
|
|
2348
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: "list-inline", children: [
|
|
2349
|
+
dateElementProps(state, time, options.yearsRange).map((elemProps, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: "list-inline-item", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2350
|
+
DateElement,
|
|
2351
|
+
{
|
|
2352
|
+
rootId: id,
|
|
2353
|
+
name,
|
|
2354
|
+
select: handleChange,
|
|
2355
|
+
...elemProps,
|
|
2356
|
+
disabled,
|
|
2357
|
+
readonly,
|
|
2358
|
+
registry,
|
|
2359
|
+
onBlur,
|
|
2360
|
+
onFocus,
|
|
2361
|
+
autofocus: autofocus && i === 0
|
|
2362
|
+
}
|
|
2363
|
+
) }, i)),
|
|
2364
|
+
(options.hideNowButton !== "undefined" ? !options.hideNowButton : true) && /* @__PURE__ */ jsxRuntime.jsx("li", { className: "list-inline-item", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: "#", className: "btn btn-info btn-now", onClick: handleSetNow, children: translateString(utils.TranslatableString.NowLabel) }) }),
|
|
2365
|
+
(options.hideClearButton !== "undefined" ? !options.hideClearButton : true) && /* @__PURE__ */ jsxRuntime.jsx("li", { className: "list-inline-item", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: "#", className: "btn btn-warning btn-clear", onClick: handleClear, children: translateString(utils.TranslatableString.ClearLabel) }) })
|
|
2366
|
+
] });
|
|
2367
|
+
}
|
|
2368
|
+
var AltDateWidget_default = AltDateWidget;
|
|
2369
|
+
function AltDateTimeWidget({
|
|
2370
|
+
time = true,
|
|
2371
|
+
...props
|
|
2372
|
+
}) {
|
|
2373
|
+
const { AltDateWidget: AltDateWidget2 } = props.registry.widgets;
|
|
2374
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AltDateWidget2, { time, ...props });
|
|
2375
|
+
}
|
|
2376
|
+
var AltDateTimeWidget_default = AltDateTimeWidget;
|
|
2377
|
+
function CheckboxWidget({
|
|
2378
|
+
schema,
|
|
2379
|
+
uiSchema,
|
|
2380
|
+
options,
|
|
2381
|
+
id,
|
|
2382
|
+
value,
|
|
2383
|
+
disabled,
|
|
2384
|
+
readonly,
|
|
2385
|
+
label,
|
|
2386
|
+
hideLabel,
|
|
2387
|
+
autofocus = false,
|
|
2388
|
+
onBlur,
|
|
2389
|
+
onFocus,
|
|
2390
|
+
onChange,
|
|
2391
|
+
registry
|
|
2392
|
+
}) {
|
|
2393
|
+
const DescriptionFieldTemplate = utils.getTemplate(
|
|
2394
|
+
"DescriptionFieldTemplate",
|
|
2395
|
+
registry,
|
|
2396
|
+
options
|
|
2397
|
+
);
|
|
2398
|
+
const required = utils.schemaRequiresTrueValue(schema);
|
|
2399
|
+
const handleChange = react.useCallback(
|
|
2400
|
+
(event) => onChange(event.target.checked),
|
|
2401
|
+
[onChange]
|
|
2402
|
+
);
|
|
2403
|
+
const handleBlur = react.useCallback(
|
|
2404
|
+
(event) => onBlur(id, event.target.checked),
|
|
2405
|
+
[onBlur, id]
|
|
2406
|
+
);
|
|
2407
|
+
const handleFocus = react.useCallback(
|
|
2408
|
+
(event) => onFocus(id, event.target.checked),
|
|
2409
|
+
[onFocus, id]
|
|
2410
|
+
);
|
|
2411
|
+
const description = options.description ?? schema.description;
|
|
2412
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `checkbox ${disabled || readonly ? "disabled" : ""}`, children: [
|
|
2413
|
+
!hideLabel && !!description && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2414
|
+
DescriptionFieldTemplate,
|
|
2415
|
+
{
|
|
2416
|
+
id: utils.descriptionId(id),
|
|
2417
|
+
description,
|
|
2418
|
+
schema,
|
|
2419
|
+
uiSchema,
|
|
2420
|
+
registry
|
|
2421
|
+
}
|
|
2422
|
+
),
|
|
2423
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
|
|
2424
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2425
|
+
"input",
|
|
2426
|
+
{
|
|
2427
|
+
type: "checkbox",
|
|
2428
|
+
id,
|
|
2429
|
+
name: id,
|
|
2430
|
+
checked: typeof value === "undefined" ? false : value,
|
|
2431
|
+
required,
|
|
2432
|
+
disabled: disabled || readonly,
|
|
2433
|
+
autoFocus: autofocus,
|
|
2434
|
+
onChange: handleChange,
|
|
2435
|
+
onBlur: handleBlur,
|
|
2436
|
+
onFocus: handleFocus,
|
|
2437
|
+
"aria-describedby": utils.ariaDescribedByIds(id)
|
|
2438
|
+
}
|
|
2439
|
+
),
|
|
2440
|
+
utils.labelValue(/* @__PURE__ */ jsxRuntime.jsx("span", { children: label }), hideLabel)
|
|
2441
|
+
] })
|
|
2442
|
+
] });
|
|
2443
|
+
}
|
|
2444
|
+
var CheckboxWidget_default = CheckboxWidget;
|
|
2445
|
+
function CheckboxesWidget({
|
|
2446
|
+
id,
|
|
2447
|
+
disabled,
|
|
2448
|
+
options: { inline = false, enumOptions, enumDisabled, emptyValue },
|
|
2449
|
+
value,
|
|
2450
|
+
autofocus = false,
|
|
2451
|
+
readonly,
|
|
2452
|
+
onChange,
|
|
2453
|
+
onBlur,
|
|
2454
|
+
onFocus
|
|
2455
|
+
}) {
|
|
2456
|
+
const checkboxesValues = Array.isArray(value) ? value : [value];
|
|
2457
|
+
const handleBlur = react.useCallback(
|
|
2458
|
+
({ target: { value: value2 } }) => onBlur(id, utils.enumOptionsValueForIndex(value2, enumOptions, emptyValue)),
|
|
2459
|
+
[onBlur, id]
|
|
2460
|
+
);
|
|
2461
|
+
const handleFocus = react.useCallback(
|
|
2462
|
+
({ target: { value: value2 } }) => onFocus(id, utils.enumOptionsValueForIndex(value2, enumOptions, emptyValue)),
|
|
2463
|
+
[onFocus, id]
|
|
2464
|
+
);
|
|
2465
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "checkboxes", id, children: Array.isArray(enumOptions) && enumOptions.map((option, index) => {
|
|
2466
|
+
const checked = utils.enumOptionsIsSelected(option.value, checkboxesValues);
|
|
2467
|
+
const itemDisabled = Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) !== -1;
|
|
2468
|
+
const disabledCls = disabled || itemDisabled || readonly ? "disabled" : "";
|
|
2469
|
+
const handleChange = (event) => {
|
|
2470
|
+
if (event.target.checked) {
|
|
2471
|
+
onChange(utils.enumOptionsSelectValue(index, checkboxesValues, enumOptions));
|
|
2472
|
+
} else {
|
|
2473
|
+
onChange(utils.enumOptionsDeselectValue(index, checkboxesValues, enumOptions));
|
|
2474
|
+
}
|
|
2475
|
+
};
|
|
2476
|
+
const checkbox = /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
2477
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2478
|
+
"input",
|
|
2479
|
+
{
|
|
2480
|
+
type: "checkbox",
|
|
2481
|
+
id: utils.optionId(id, index),
|
|
2482
|
+
name: id,
|
|
2483
|
+
checked,
|
|
2484
|
+
value: String(index),
|
|
2485
|
+
disabled: disabled || itemDisabled || readonly,
|
|
2486
|
+
autoFocus: autofocus && index === 0,
|
|
2487
|
+
onChange: handleChange,
|
|
2488
|
+
onBlur: handleBlur,
|
|
2489
|
+
onFocus: handleFocus,
|
|
2490
|
+
"aria-describedby": utils.ariaDescribedByIds(id)
|
|
2491
|
+
}
|
|
2492
|
+
),
|
|
2493
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label })
|
|
2494
|
+
] });
|
|
2495
|
+
return inline ? /* @__PURE__ */ jsxRuntime.jsx("label", { className: `checkbox-inline ${disabledCls}`, children: checkbox }, index) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: `checkbox ${disabledCls}`, children: /* @__PURE__ */ jsxRuntime.jsx("label", { children: checkbox }) }, index);
|
|
2496
|
+
}) });
|
|
2497
|
+
}
|
|
2498
|
+
var CheckboxesWidget_default = CheckboxesWidget;
|
|
2499
|
+
function ColorWidget(props) {
|
|
2500
|
+
const { disabled, readonly, options, registry } = props;
|
|
2501
|
+
const BaseInputTemplate2 = utils.getTemplate("BaseInputTemplate", registry, options);
|
|
2502
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BaseInputTemplate2, { type: "color", ...props, disabled: disabled || readonly });
|
|
2503
|
+
}
|
|
2504
|
+
function DateWidget(props) {
|
|
2505
|
+
const { onChange, options, registry } = props;
|
|
2506
|
+
const BaseInputTemplate2 = utils.getTemplate("BaseInputTemplate", registry, options);
|
|
2507
|
+
const handleChange = react.useCallback((value) => onChange(value || void 0), [onChange]);
|
|
2508
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BaseInputTemplate2, { type: "date", ...props, onChange: handleChange });
|
|
2509
|
+
}
|
|
2510
|
+
function DateTimeWidget(props) {
|
|
2511
|
+
const { onChange, value, options, registry } = props;
|
|
2512
|
+
const BaseInputTemplate2 = utils.getTemplate("BaseInputTemplate", registry, options);
|
|
2513
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2514
|
+
BaseInputTemplate2,
|
|
2515
|
+
{
|
|
2516
|
+
type: "datetime-local",
|
|
2517
|
+
...props,
|
|
2518
|
+
value: utils.utcToLocal(value),
|
|
2519
|
+
onChange: (value2) => onChange(utils.localToUTC(value2))
|
|
2520
|
+
}
|
|
2521
|
+
);
|
|
2522
|
+
}
|
|
2523
|
+
function EmailWidget(props) {
|
|
2524
|
+
const { options, registry } = props;
|
|
2525
|
+
const BaseInputTemplate2 = utils.getTemplate("BaseInputTemplate", registry, options);
|
|
2526
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BaseInputTemplate2, { type: "email", ...props });
|
|
2527
|
+
}
|
|
2528
|
+
function addNameToDataURL(dataURL, name) {
|
|
2529
|
+
if (dataURL === null) {
|
|
2530
|
+
return null;
|
|
2531
|
+
}
|
|
2532
|
+
return dataURL.replace(";base64", `;name=${encodeURIComponent(name)};base64`);
|
|
2533
|
+
}
|
|
2534
|
+
function processFile(file) {
|
|
2535
|
+
const { name, size, type } = file;
|
|
2536
|
+
return new Promise((resolve, reject) => {
|
|
2537
|
+
const reader = new window.FileReader();
|
|
2538
|
+
reader.onerror = reject;
|
|
2539
|
+
reader.onload = (event) => {
|
|
2540
|
+
if (typeof event.target?.result === "string") {
|
|
2541
|
+
resolve({
|
|
2542
|
+
dataURL: addNameToDataURL(event.target.result, name),
|
|
2543
|
+
name,
|
|
2544
|
+
size,
|
|
2545
|
+
type
|
|
2546
|
+
});
|
|
2547
|
+
} else {
|
|
2548
|
+
resolve({
|
|
2549
|
+
dataURL: null,
|
|
2550
|
+
name,
|
|
2551
|
+
size,
|
|
2552
|
+
type
|
|
2553
|
+
});
|
|
2554
|
+
}
|
|
2555
|
+
};
|
|
2556
|
+
reader.readAsDataURL(file);
|
|
2557
|
+
});
|
|
2558
|
+
}
|
|
2559
|
+
function processFiles(files) {
|
|
2560
|
+
return Promise.all(Array.from(files).map(processFile));
|
|
2561
|
+
}
|
|
2562
|
+
function FileInfoPreview({
|
|
2563
|
+
fileInfo,
|
|
2564
|
+
registry
|
|
2565
|
+
}) {
|
|
2566
|
+
const { translateString } = registry;
|
|
2567
|
+
const { dataURL, type, name } = fileInfo;
|
|
2568
|
+
if (!dataURL) {
|
|
2569
|
+
return null;
|
|
2570
|
+
}
|
|
2571
|
+
if (type.indexOf("image") !== -1) {
|
|
2572
|
+
return /* @__PURE__ */ jsxRuntime.jsx("img", { src: dataURL, style: { maxWidth: "100%" }, className: "file-preview" });
|
|
2573
|
+
}
|
|
2574
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2575
|
+
" ",
|
|
2576
|
+
/* @__PURE__ */ jsxRuntime.jsx("a", { download: `preview-${name}`, href: dataURL, className: "file-download", children: translateString(utils.TranslatableString.PreviewLabel) })
|
|
2577
|
+
] });
|
|
2578
|
+
}
|
|
2579
|
+
function FilesInfo({
|
|
2580
|
+
filesInfo,
|
|
2581
|
+
registry,
|
|
2582
|
+
preview
|
|
2583
|
+
}) {
|
|
2584
|
+
if (filesInfo.length === 0) {
|
|
2585
|
+
return null;
|
|
2586
|
+
}
|
|
2587
|
+
const { translateString } = registry;
|
|
2588
|
+
return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "file-info", children: filesInfo.map((fileInfo, key) => {
|
|
2589
|
+
const { name, size, type } = fileInfo;
|
|
2590
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("li", { children: [
|
|
2591
|
+
/* @__PURE__ */ jsxRuntime.jsx(Markdown, { children: translateString(utils.TranslatableString.FilesInfo, [name, type, String(size)]) }),
|
|
2592
|
+
preview && /* @__PURE__ */ jsxRuntime.jsx(FileInfoPreview, { fileInfo, registry })
|
|
2593
|
+
] }, key);
|
|
2594
|
+
}) });
|
|
2595
|
+
}
|
|
2596
|
+
function extractFileInfo(dataURLs) {
|
|
2597
|
+
return dataURLs.filter((dataURL) => dataURL).map((dataURL) => {
|
|
2598
|
+
const { blob, name } = utils.dataURItoBlob(dataURL);
|
|
2599
|
+
return {
|
|
2600
|
+
dataURL,
|
|
2601
|
+
name,
|
|
2602
|
+
size: blob.size,
|
|
2603
|
+
type: blob.type
|
|
2604
|
+
};
|
|
2605
|
+
});
|
|
2606
|
+
}
|
|
2607
|
+
function FileWidget(props) {
|
|
2608
|
+
const { disabled, readonly, required, multiple, onChange, value, options, registry } = props;
|
|
2609
|
+
const BaseInputTemplate2 = utils.getTemplate("BaseInputTemplate", registry, options);
|
|
2610
|
+
const [filesInfo, setFilesInfo] = react.useState(
|
|
2611
|
+
Array.isArray(value) ? extractFileInfo(value) : extractFileInfo([value])
|
|
2612
|
+
);
|
|
2613
|
+
const handleChange = react.useCallback(
|
|
2614
|
+
(event) => {
|
|
2615
|
+
if (!event.target.files) {
|
|
2616
|
+
return;
|
|
2617
|
+
}
|
|
2618
|
+
processFiles(event.target.files).then((filesInfoEvent) => {
|
|
2619
|
+
const newValue = filesInfoEvent.map((fileInfo) => fileInfo.dataURL);
|
|
2620
|
+
if (multiple) {
|
|
2621
|
+
setFilesInfo(filesInfo.concat(filesInfoEvent[0]));
|
|
2622
|
+
onChange(value.concat(newValue[0]));
|
|
2623
|
+
} else {
|
|
2624
|
+
setFilesInfo(filesInfoEvent);
|
|
2625
|
+
onChange(newValue[0]);
|
|
2626
|
+
}
|
|
2627
|
+
});
|
|
2628
|
+
},
|
|
2629
|
+
[multiple, value, filesInfo, onChange]
|
|
2630
|
+
);
|
|
2631
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
2632
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2633
|
+
BaseInputTemplate2,
|
|
2634
|
+
{
|
|
2635
|
+
...props,
|
|
2636
|
+
disabled: disabled || readonly,
|
|
2637
|
+
type: "file",
|
|
2638
|
+
required: value ? false : required,
|
|
2639
|
+
onChangeOverride: handleChange,
|
|
2640
|
+
value: "",
|
|
2641
|
+
accept: options.accept ? String(options.accept) : void 0
|
|
2642
|
+
}
|
|
2643
|
+
),
|
|
2644
|
+
/* @__PURE__ */ jsxRuntime.jsx(FilesInfo, { filesInfo, registry, preview: options.filePreview })
|
|
2645
|
+
] });
|
|
2646
|
+
}
|
|
2647
|
+
var FileWidget_default = FileWidget;
|
|
2648
|
+
function HiddenWidget({
|
|
2649
|
+
id,
|
|
2650
|
+
value
|
|
2651
|
+
}) {
|
|
2652
|
+
return /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", id, name: id, value: typeof value === "undefined" ? "" : value });
|
|
2653
|
+
}
|
|
2654
|
+
var HiddenWidget_default = HiddenWidget;
|
|
2655
|
+
function PasswordWidget(props) {
|
|
2656
|
+
const { options, registry } = props;
|
|
2657
|
+
const BaseInputTemplate2 = utils.getTemplate("BaseInputTemplate", registry, options);
|
|
2658
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BaseInputTemplate2, { type: "password", ...props });
|
|
2659
|
+
}
|
|
2660
|
+
function RadioWidget({
|
|
2661
|
+
options,
|
|
2662
|
+
value,
|
|
2663
|
+
required,
|
|
2664
|
+
disabled,
|
|
2665
|
+
readonly,
|
|
2666
|
+
autofocus = false,
|
|
2667
|
+
onBlur,
|
|
2668
|
+
onFocus,
|
|
2669
|
+
onChange,
|
|
2670
|
+
id
|
|
2671
|
+
}) {
|
|
2672
|
+
const { enumOptions, enumDisabled, inline, emptyValue } = options;
|
|
2673
|
+
const handleBlur = react.useCallback(
|
|
2674
|
+
({ target: { value: value2 } }) => onBlur(id, utils.enumOptionsValueForIndex(value2, enumOptions, emptyValue)),
|
|
2675
|
+
[onBlur, id]
|
|
2676
|
+
);
|
|
2677
|
+
const handleFocus = react.useCallback(
|
|
2678
|
+
({ target: { value: value2 } }) => onFocus(id, utils.enumOptionsValueForIndex(value2, enumOptions, emptyValue)),
|
|
2679
|
+
[onFocus, id]
|
|
2680
|
+
);
|
|
2681
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "field-radio-group", id, children: Array.isArray(enumOptions) && enumOptions.map((option, i) => {
|
|
2682
|
+
const checked = utils.enumOptionsIsSelected(option.value, value);
|
|
2683
|
+
const itemDisabled = Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) !== -1;
|
|
2684
|
+
const disabledCls = disabled || itemDisabled || readonly ? "disabled" : "";
|
|
2685
|
+
const handleChange = () => onChange(option.value);
|
|
2686
|
+
const radio = /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
2687
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2688
|
+
"input",
|
|
2689
|
+
{
|
|
2690
|
+
type: "radio",
|
|
2691
|
+
id: utils.optionId(id, i),
|
|
2692
|
+
checked,
|
|
2693
|
+
name: id,
|
|
2694
|
+
required,
|
|
2695
|
+
value: String(i),
|
|
2696
|
+
disabled: disabled || itemDisabled || readonly,
|
|
2697
|
+
autoFocus: autofocus && i === 0,
|
|
2698
|
+
onChange: handleChange,
|
|
2699
|
+
onBlur: handleBlur,
|
|
2700
|
+
onFocus: handleFocus,
|
|
2701
|
+
"aria-describedby": utils.ariaDescribedByIds(id)
|
|
2702
|
+
}
|
|
2703
|
+
),
|
|
2704
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label })
|
|
2705
|
+
] });
|
|
2706
|
+
return inline ? /* @__PURE__ */ jsxRuntime.jsx("label", { className: `radio-inline ${disabledCls}`, children: radio }, i) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: `radio ${disabledCls}`, children: /* @__PURE__ */ jsxRuntime.jsx("label", { children: radio }) }, i);
|
|
2707
|
+
}) });
|
|
2708
|
+
}
|
|
2709
|
+
var RadioWidget_default = RadioWidget;
|
|
2710
|
+
function RangeWidget(props) {
|
|
2711
|
+
const {
|
|
2712
|
+
value,
|
|
2713
|
+
registry: {
|
|
2714
|
+
templates: { BaseInputTemplate: BaseInputTemplate2 }
|
|
2715
|
+
}
|
|
2716
|
+
} = props;
|
|
2717
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "field-range-wrapper", children: [
|
|
2718
|
+
/* @__PURE__ */ jsxRuntime.jsx(BaseInputTemplate2, { type: "range", ...props }),
|
|
2719
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "range-view", children: value })
|
|
2720
|
+
] });
|
|
2721
|
+
}
|
|
2722
|
+
function getValue(event, multiple) {
|
|
2723
|
+
if (multiple) {
|
|
2724
|
+
return Array.from(event.target.options).slice().filter((o) => o.selected).map((o) => o.value);
|
|
2725
|
+
}
|
|
2726
|
+
return event.target.value;
|
|
2727
|
+
}
|
|
2728
|
+
function SelectWidget({
|
|
2729
|
+
schema,
|
|
2730
|
+
id,
|
|
2731
|
+
options,
|
|
2732
|
+
value,
|
|
2733
|
+
required,
|
|
2734
|
+
disabled,
|
|
2735
|
+
readonly,
|
|
2736
|
+
multiple = false,
|
|
2737
|
+
autofocus = false,
|
|
2738
|
+
onChange,
|
|
2739
|
+
onBlur,
|
|
2740
|
+
onFocus,
|
|
2741
|
+
placeholder
|
|
2742
|
+
}) {
|
|
2743
|
+
const { enumOptions, enumDisabled, emptyValue: optEmptyVal } = options;
|
|
2744
|
+
const emptyValue = multiple ? [] : "";
|
|
2745
|
+
const handleFocus = react.useCallback(
|
|
2746
|
+
(event) => {
|
|
2747
|
+
const newValue = getValue(event, multiple);
|
|
2748
|
+
return onFocus(id, utils.enumOptionsValueForIndex(newValue, enumOptions, optEmptyVal));
|
|
2749
|
+
},
|
|
2750
|
+
[onFocus, id, schema, multiple, options]
|
|
2751
|
+
);
|
|
2752
|
+
const handleBlur = react.useCallback(
|
|
2753
|
+
(event) => {
|
|
2754
|
+
const newValue = getValue(event, multiple);
|
|
2755
|
+
return onBlur(id, utils.enumOptionsValueForIndex(newValue, enumOptions, optEmptyVal));
|
|
2756
|
+
},
|
|
2757
|
+
[onBlur, id, schema, multiple, options]
|
|
2758
|
+
);
|
|
2759
|
+
const handleChange = react.useCallback(
|
|
2760
|
+
(event) => {
|
|
2761
|
+
const newValue = getValue(event, multiple);
|
|
2762
|
+
return onChange(utils.enumOptionsValueForIndex(newValue, enumOptions, optEmptyVal));
|
|
2763
|
+
},
|
|
2764
|
+
[onChange, schema, multiple, options]
|
|
2765
|
+
);
|
|
2766
|
+
const selectedIndexes = utils.enumOptionsIndexForValue(value, enumOptions, multiple);
|
|
2767
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2768
|
+
"select",
|
|
2769
|
+
{
|
|
2770
|
+
id,
|
|
2771
|
+
name: id,
|
|
2772
|
+
multiple,
|
|
2773
|
+
className: "form-control",
|
|
2774
|
+
value: typeof selectedIndexes === "undefined" ? emptyValue : selectedIndexes,
|
|
2775
|
+
required,
|
|
2776
|
+
disabled: disabled || readonly,
|
|
2777
|
+
autoFocus: autofocus,
|
|
2778
|
+
onBlur: handleBlur,
|
|
2779
|
+
onFocus: handleFocus,
|
|
2780
|
+
onChange: handleChange,
|
|
2781
|
+
"aria-describedby": utils.ariaDescribedByIds(id),
|
|
2782
|
+
children: [
|
|
2783
|
+
!multiple && schema.default === void 0 && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: placeholder }),
|
|
2784
|
+
Array.isArray(enumOptions) && enumOptions.map(({ value: value2, label }, i) => {
|
|
2785
|
+
const disabled2 = enumDisabled && enumDisabled.indexOf(value2) !== -1;
|
|
2786
|
+
return /* @__PURE__ */ jsxRuntime.jsx("option", { value: String(i), disabled: disabled2, children: label }, i);
|
|
2787
|
+
})
|
|
2788
|
+
]
|
|
2789
|
+
}
|
|
2790
|
+
);
|
|
2791
|
+
}
|
|
2792
|
+
var SelectWidget_default = SelectWidget;
|
|
2793
|
+
function TextareaWidget({
|
|
2794
|
+
id,
|
|
2795
|
+
options = {},
|
|
2796
|
+
placeholder,
|
|
2797
|
+
value,
|
|
2798
|
+
required,
|
|
2799
|
+
disabled,
|
|
2800
|
+
readonly,
|
|
2801
|
+
autofocus = false,
|
|
2802
|
+
onChange,
|
|
2803
|
+
onBlur,
|
|
2804
|
+
onFocus
|
|
2805
|
+
}) {
|
|
2806
|
+
const handleChange = react.useCallback(
|
|
2807
|
+
({ target: { value: value2 } }) => onChange(value2 === "" ? options.emptyValue : value2),
|
|
2808
|
+
[onChange, options.emptyValue]
|
|
2809
|
+
);
|
|
2810
|
+
const handleBlur = react.useCallback(
|
|
2811
|
+
({ target: { value: value2 } }) => onBlur(id, value2),
|
|
2812
|
+
[onBlur, id]
|
|
2813
|
+
);
|
|
2814
|
+
const handleFocus = react.useCallback(
|
|
2815
|
+
({ target: { value: value2 } }) => onFocus(id, value2),
|
|
2816
|
+
[id, onFocus]
|
|
2817
|
+
);
|
|
2818
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2819
|
+
"textarea",
|
|
2820
|
+
{
|
|
2821
|
+
id,
|
|
2822
|
+
name: id,
|
|
2823
|
+
className: "form-control",
|
|
2824
|
+
value: value ? value : "",
|
|
2825
|
+
placeholder,
|
|
2826
|
+
required,
|
|
2827
|
+
disabled,
|
|
2828
|
+
readOnly: readonly,
|
|
2829
|
+
autoFocus: autofocus,
|
|
2830
|
+
rows: options.rows,
|
|
2831
|
+
onBlur: handleBlur,
|
|
2832
|
+
onFocus: handleFocus,
|
|
2833
|
+
onChange: handleChange,
|
|
2834
|
+
"aria-describedby": utils.ariaDescribedByIds(id)
|
|
2835
|
+
}
|
|
2836
|
+
);
|
|
2837
|
+
}
|
|
2838
|
+
TextareaWidget.defaultProps = {
|
|
2839
|
+
autofocus: false,
|
|
2840
|
+
options: {}
|
|
2841
|
+
};
|
|
2842
|
+
var TextareaWidget_default = TextareaWidget;
|
|
2843
|
+
function TextWidget(props) {
|
|
2844
|
+
const { options, registry } = props;
|
|
2845
|
+
const BaseInputTemplate2 = utils.getTemplate("BaseInputTemplate", registry, options);
|
|
2846
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BaseInputTemplate2, { ...props });
|
|
2847
|
+
}
|
|
2848
|
+
function TimeWidget(props) {
|
|
2849
|
+
const { onChange, options, registry } = props;
|
|
2850
|
+
const BaseInputTemplate2 = utils.getTemplate("BaseInputTemplate", registry, options);
|
|
2851
|
+
const handleChange = react.useCallback((value) => onChange(value ? `${value}:00` : void 0), [onChange]);
|
|
2852
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BaseInputTemplate2, { type: "time", ...props, onChange: handleChange });
|
|
2853
|
+
}
|
|
2854
|
+
function URLWidget(props) {
|
|
2855
|
+
const { options, registry } = props;
|
|
2856
|
+
const BaseInputTemplate2 = utils.getTemplate("BaseInputTemplate", registry, options);
|
|
2857
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BaseInputTemplate2, { type: "url", ...props });
|
|
2858
|
+
}
|
|
2859
|
+
function UpDownWidget(props) {
|
|
2860
|
+
const { options, registry } = props;
|
|
2861
|
+
const BaseInputTemplate2 = utils.getTemplate("BaseInputTemplate", registry, options);
|
|
2862
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BaseInputTemplate2, { type: "number", ...props });
|
|
2863
|
+
}
|
|
2864
|
+
|
|
2865
|
+
// src/components/widgets/index.ts
|
|
2866
|
+
function widgets() {
|
|
2867
|
+
return {
|
|
2868
|
+
AltDateWidget: AltDateWidget_default,
|
|
2869
|
+
AltDateTimeWidget: AltDateTimeWidget_default,
|
|
2870
|
+
CheckboxWidget: CheckboxWidget_default,
|
|
2871
|
+
CheckboxesWidget: CheckboxesWidget_default,
|
|
2872
|
+
ColorWidget,
|
|
2873
|
+
DateWidget,
|
|
2874
|
+
DateTimeWidget,
|
|
2875
|
+
EmailWidget,
|
|
2876
|
+
FileWidget: FileWidget_default,
|
|
2877
|
+
HiddenWidget: HiddenWidget_default,
|
|
2878
|
+
PasswordWidget,
|
|
2879
|
+
RadioWidget: RadioWidget_default,
|
|
2880
|
+
RangeWidget,
|
|
2881
|
+
SelectWidget: SelectWidget_default,
|
|
2882
|
+
TextWidget,
|
|
2883
|
+
TextareaWidget: TextareaWidget_default,
|
|
2884
|
+
TimeWidget,
|
|
2885
|
+
UpDownWidget,
|
|
2886
|
+
URLWidget
|
|
2887
|
+
};
|
|
2888
|
+
}
|
|
2889
|
+
var widgets_default = widgets;
|
|
2890
|
+
|
|
2891
|
+
// src/getDefaultRegistry.ts
|
|
2892
|
+
function getDefaultRegistry() {
|
|
2893
|
+
return {
|
|
2894
|
+
fields: fields_default(),
|
|
2895
|
+
templates: templates_default(),
|
|
2896
|
+
widgets: widgets_default(),
|
|
2897
|
+
rootSchema: {},
|
|
2898
|
+
formContext: {},
|
|
2899
|
+
translateString: utils.englishStringTranslator
|
|
2900
|
+
};
|
|
2901
|
+
}
|
|
2902
|
+
var Form = class extends react.Component {
|
|
2903
|
+
/** Constructs the `Form` from the `props`. Will setup the initial state from the props. It will also call the
|
|
2904
|
+
* `onChange` handler if the initially provided `formData` is modified to add missing default values as part of the
|
|
2905
|
+
* state construction.
|
|
2906
|
+
*
|
|
2907
|
+
* @param props - The initial props for the `Form`
|
|
2908
|
+
*/
|
|
2909
|
+
constructor(props) {
|
|
2910
|
+
super(props);
|
|
2911
|
+
/** Returns the `formData` with only the elements specified in the `fields` list
|
|
2912
|
+
*
|
|
2913
|
+
* @param formData - The data for the `Form`
|
|
2914
|
+
* @param fields - The fields to keep while filtering
|
|
2915
|
+
*/
|
|
2916
|
+
this.getUsedFormData = (formData, fields2) => {
|
|
2917
|
+
if (fields2.length === 0 && typeof formData !== "object") {
|
|
2918
|
+
return formData;
|
|
2919
|
+
}
|
|
2920
|
+
const data = _pick(formData, fields2);
|
|
2921
|
+
if (Array.isArray(formData)) {
|
|
2922
|
+
return Object.keys(data).map((key) => data[key]);
|
|
2923
|
+
}
|
|
2924
|
+
return data;
|
|
2925
|
+
};
|
|
2926
|
+
/** Returns the list of field names from inspecting the `pathSchema` as well as using the `formData`
|
|
2927
|
+
*
|
|
2928
|
+
* @param pathSchema - The `PathSchema` object for the form
|
|
2929
|
+
* @param [formData] - The form data to use while checking for empty objects/arrays
|
|
2930
|
+
*/
|
|
2931
|
+
this.getFieldNames = (pathSchema, formData) => {
|
|
2932
|
+
const getAllPaths = (_obj, acc = [], paths = [[]]) => {
|
|
2933
|
+
Object.keys(_obj).forEach((key) => {
|
|
2934
|
+
if (typeof _obj[key] === "object") {
|
|
2935
|
+
const newPaths = paths.map((path) => [...path, key]);
|
|
2936
|
+
if (_obj[key][utils.RJSF_ADDITONAL_PROPERTIES_FLAG] && _obj[key][utils.NAME_KEY] !== "") {
|
|
2937
|
+
acc.push(_obj[key][utils.NAME_KEY]);
|
|
2938
|
+
} else {
|
|
2939
|
+
getAllPaths(_obj[key], acc, newPaths);
|
|
2940
|
+
}
|
|
2941
|
+
} else if (key === utils.NAME_KEY && _obj[key] !== "") {
|
|
2942
|
+
paths.forEach((path) => {
|
|
2943
|
+
const formValue = get3(formData, path);
|
|
2944
|
+
if (typeof formValue !== "object" || isEmpty(formValue)) {
|
|
2945
|
+
acc.push(path);
|
|
2946
|
+
}
|
|
2947
|
+
});
|
|
2948
|
+
}
|
|
2949
|
+
});
|
|
2950
|
+
return acc;
|
|
2951
|
+
};
|
|
2952
|
+
return getAllPaths(pathSchema);
|
|
2953
|
+
};
|
|
2954
|
+
/** Function to handle changes made to a field in the `Form`. This handler receives an entirely new copy of the
|
|
2955
|
+
* `formData` along with a new `ErrorSchema`. It will first update the `formData` with any missing default fields and
|
|
2956
|
+
* then, if `omitExtraData` and `liveOmit` are turned on, the `formData` will be filterer to remove any extra data not
|
|
2957
|
+
* in a form field. Then, the resulting formData will be validated if required. The state will be updated with the new
|
|
2958
|
+
* updated (potentially filtered) `formData`, any errors that resulted from validation. Finally the `onChange`
|
|
2959
|
+
* callback will be called if specified with the updated state.
|
|
2960
|
+
*
|
|
2961
|
+
* @param formData - The new form data from a change to a field
|
|
2962
|
+
* @param newErrorSchema - The new `ErrorSchema` based on the field change
|
|
2963
|
+
* @param id - The id of the field that caused the change
|
|
2964
|
+
*/
|
|
2965
|
+
this.onChange = (formData, newErrorSchema, id) => {
|
|
2966
|
+
const { extraErrors, omitExtraData, liveOmit, noValidate, liveValidate, onChange } = this.props;
|
|
2967
|
+
const { schemaUtils, schema } = this.state;
|
|
2968
|
+
if (utils.isObject(formData) || Array.isArray(formData)) {
|
|
2969
|
+
const newState = this.getStateFromProps(this.props, formData);
|
|
2970
|
+
formData = newState.formData;
|
|
2971
|
+
}
|
|
2972
|
+
const mustValidate = !noValidate && liveValidate;
|
|
2973
|
+
let state = { formData, schema };
|
|
2974
|
+
let newFormData = formData;
|
|
2975
|
+
if (omitExtraData === true && liveOmit === true) {
|
|
2976
|
+
const retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
|
|
2977
|
+
const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", formData);
|
|
2978
|
+
const fieldNames = this.getFieldNames(pathSchema, formData);
|
|
2979
|
+
newFormData = this.getUsedFormData(formData, fieldNames);
|
|
2980
|
+
state = {
|
|
2981
|
+
formData: newFormData
|
|
2982
|
+
};
|
|
2983
|
+
}
|
|
2984
|
+
if (mustValidate) {
|
|
2985
|
+
const schemaValidation = this.validate(newFormData);
|
|
2986
|
+
let errors = schemaValidation.errors;
|
|
2987
|
+
let errorSchema = schemaValidation.errorSchema;
|
|
2988
|
+
const schemaValidationErrors = errors;
|
|
2989
|
+
const schemaValidationErrorSchema = errorSchema;
|
|
2990
|
+
if (extraErrors) {
|
|
2991
|
+
const merged = utils.validationDataMerge(schemaValidation, extraErrors);
|
|
2992
|
+
errorSchema = merged.errorSchema;
|
|
2993
|
+
errors = merged.errors;
|
|
2994
|
+
}
|
|
2995
|
+
state = {
|
|
2996
|
+
formData: newFormData,
|
|
2997
|
+
errors,
|
|
2998
|
+
errorSchema,
|
|
2999
|
+
schemaValidationErrors,
|
|
3000
|
+
schemaValidationErrorSchema
|
|
3001
|
+
};
|
|
3002
|
+
} else if (!noValidate && newErrorSchema) {
|
|
3003
|
+
const errorSchema = extraErrors ? utils.mergeObjects(newErrorSchema, extraErrors, "preventDuplicates") : newErrorSchema;
|
|
3004
|
+
state = {
|
|
3005
|
+
formData: newFormData,
|
|
3006
|
+
errorSchema,
|
|
3007
|
+
errors: utils.toErrorList(errorSchema)
|
|
3008
|
+
};
|
|
3009
|
+
}
|
|
3010
|
+
this.setState(state, () => onChange && onChange({ ...this.state, ...state }, id));
|
|
3011
|
+
};
|
|
3012
|
+
/**
|
|
3013
|
+
* Callback function to handle reset form data.
|
|
3014
|
+
* - Reset all fields with default values.
|
|
3015
|
+
* - Reset validations and errors
|
|
3016
|
+
*
|
|
3017
|
+
*/
|
|
3018
|
+
this.reset = () => {
|
|
3019
|
+
const { onChange } = this.props;
|
|
3020
|
+
const newState = this.getStateFromProps(this.props, void 0);
|
|
3021
|
+
const newFormData = newState.formData;
|
|
3022
|
+
const state = {
|
|
3023
|
+
formData: newFormData,
|
|
3024
|
+
errorSchema: {},
|
|
3025
|
+
errors: [],
|
|
3026
|
+
schemaValidationErrors: [],
|
|
3027
|
+
schemaValidationErrorSchema: {}
|
|
3028
|
+
};
|
|
3029
|
+
this.setState(state, () => onChange && onChange({ ...this.state, ...state }));
|
|
3030
|
+
};
|
|
3031
|
+
/** Callback function to handle when a field on the form is blurred. Calls the `onBlur` callback for the `Form` if it
|
|
3032
|
+
* was provided.
|
|
3033
|
+
*
|
|
3034
|
+
* @param id - The unique `id` of the field that was blurred
|
|
3035
|
+
* @param data - The data associated with the field that was blurred
|
|
3036
|
+
*/
|
|
3037
|
+
this.onBlur = (id, data) => {
|
|
3038
|
+
const { onBlur } = this.props;
|
|
3039
|
+
if (onBlur) {
|
|
3040
|
+
onBlur(id, data);
|
|
3041
|
+
}
|
|
3042
|
+
};
|
|
3043
|
+
/** Callback function to handle when a field on the form is focused. Calls the `onFocus` callback for the `Form` if it
|
|
3044
|
+
* was provided.
|
|
3045
|
+
*
|
|
3046
|
+
* @param id - The unique `id` of the field that was focused
|
|
3047
|
+
* @param data - The data associated with the field that was focused
|
|
3048
|
+
*/
|
|
3049
|
+
this.onFocus = (id, data) => {
|
|
3050
|
+
const { onFocus } = this.props;
|
|
3051
|
+
if (onFocus) {
|
|
3052
|
+
onFocus(id, data);
|
|
3053
|
+
}
|
|
3054
|
+
};
|
|
3055
|
+
/** Callback function to handle when the form is submitted. First, it prevents the default event behavior. Nothing
|
|
3056
|
+
* happens if the target and currentTarget of the event are not the same. It will omit any extra data in the
|
|
3057
|
+
* `formData` in the state if `omitExtraData` is true. It will validate the resulting `formData`, reporting errors
|
|
3058
|
+
* via the `onError()` callback unless validation is disabled. Finally, it will add in any `extraErrors` and then call
|
|
3059
|
+
* back the `onSubmit` callback if it was provided.
|
|
3060
|
+
*
|
|
3061
|
+
* @param event - The submit HTML form event
|
|
3062
|
+
*/
|
|
3063
|
+
this.onSubmit = (event) => {
|
|
3064
|
+
event.preventDefault();
|
|
3065
|
+
if (event.target !== event.currentTarget) {
|
|
3066
|
+
return;
|
|
3067
|
+
}
|
|
3068
|
+
event.persist();
|
|
3069
|
+
const { omitExtraData, extraErrors, noValidate, onSubmit } = this.props;
|
|
3070
|
+
let { formData: newFormData } = this.state;
|
|
3071
|
+
const { schema, schemaUtils } = this.state;
|
|
3072
|
+
if (omitExtraData === true) {
|
|
3073
|
+
const retrievedSchema = schemaUtils.retrieveSchema(schema, newFormData);
|
|
3074
|
+
const pathSchema = schemaUtils.toPathSchema(retrievedSchema, "", newFormData);
|
|
3075
|
+
const fieldNames = this.getFieldNames(pathSchema, newFormData);
|
|
3076
|
+
newFormData = this.getUsedFormData(newFormData, fieldNames);
|
|
3077
|
+
}
|
|
3078
|
+
if (noValidate || this.validateForm()) {
|
|
3079
|
+
const errorSchema = extraErrors || {};
|
|
3080
|
+
const errors = extraErrors ? utils.toErrorList(extraErrors) : [];
|
|
3081
|
+
this.setState(
|
|
3082
|
+
{
|
|
3083
|
+
formData: newFormData,
|
|
3084
|
+
errors,
|
|
3085
|
+
errorSchema,
|
|
3086
|
+
schemaValidationErrors: [],
|
|
3087
|
+
schemaValidationErrorSchema: {}
|
|
3088
|
+
},
|
|
3089
|
+
() => {
|
|
3090
|
+
if (onSubmit) {
|
|
3091
|
+
onSubmit({ ...this.state, formData: newFormData, status: "submitted" }, event);
|
|
3092
|
+
}
|
|
3093
|
+
}
|
|
3094
|
+
);
|
|
3095
|
+
}
|
|
3096
|
+
};
|
|
3097
|
+
if (!props.validator) {
|
|
3098
|
+
throw new Error("A validator is required for Form functionality to work");
|
|
3099
|
+
}
|
|
3100
|
+
this.state = this.getStateFromProps(props, props.formData);
|
|
3101
|
+
if (this.props.onChange && !utils.deepEquals(this.state.formData, this.props.formData)) {
|
|
3102
|
+
this.props.onChange(this.state);
|
|
3103
|
+
}
|
|
3104
|
+
this.formElement = react.createRef();
|
|
3105
|
+
}
|
|
3106
|
+
/** React lifecycle method that gets called before new props are provided, updates the state based on new props. It
|
|
3107
|
+
* will also call the`onChange` handler if the `formData` is modified to add missing default values as part of the
|
|
3108
|
+
* state construction.
|
|
3109
|
+
*
|
|
3110
|
+
* @param nextProps - The new set of props about to be applied to the `Form`
|
|
3111
|
+
*/
|
|
3112
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
3113
|
+
const nextState = this.getStateFromProps(nextProps, nextProps.formData);
|
|
3114
|
+
if (!utils.deepEquals(nextState.formData, nextProps.formData) && !utils.deepEquals(nextState.formData, this.state.formData) && nextProps.onChange) {
|
|
3115
|
+
nextProps.onChange(nextState);
|
|
3116
|
+
}
|
|
3117
|
+
this.setState(nextState);
|
|
3118
|
+
}
|
|
3119
|
+
/** Extracts the updated state from the given `props` and `inputFormData`. As part of this process, the
|
|
3120
|
+
* `inputFormData` is first processed to add any missing required defaults. After that, the data is run through the
|
|
3121
|
+
* validation process IF required by the `props`.
|
|
3122
|
+
*
|
|
3123
|
+
* @param props - The props passed to the `Form`
|
|
3124
|
+
* @param inputFormData - The new or current data for the `Form`
|
|
3125
|
+
* @returns - The new state for the `Form`
|
|
3126
|
+
*/
|
|
3127
|
+
getStateFromProps(props, inputFormData) {
|
|
3128
|
+
const state = this.state || {};
|
|
3129
|
+
const schema = "schema" in props ? props.schema : this.props.schema;
|
|
3130
|
+
const uiSchema = ("uiSchema" in props ? props.uiSchema : this.props.uiSchema) || {};
|
|
3131
|
+
const edit = typeof inputFormData !== "undefined";
|
|
3132
|
+
const liveValidate = "liveValidate" in props ? props.liveValidate : this.props.liveValidate;
|
|
3133
|
+
const mustValidate = edit && !props.noValidate && liveValidate;
|
|
3134
|
+
const rootSchema = schema;
|
|
3135
|
+
const experimental_defaultFormStateBehavior = "experimental_defaultFormStateBehavior" in props ? props.experimental_defaultFormStateBehavior : this.props.experimental_defaultFormStateBehavior;
|
|
3136
|
+
let schemaUtils = state.schemaUtils;
|
|
3137
|
+
if (!schemaUtils || schemaUtils.doesSchemaUtilsDiffer(props.validator, rootSchema, experimental_defaultFormStateBehavior)) {
|
|
3138
|
+
schemaUtils = utils.createSchemaUtils(props.validator, rootSchema, experimental_defaultFormStateBehavior);
|
|
3139
|
+
}
|
|
3140
|
+
const formData = schemaUtils.getDefaultFormState(schema, inputFormData);
|
|
3141
|
+
const retrievedSchema = schemaUtils.retrieveSchema(schema, formData);
|
|
3142
|
+
const getCurrentErrors = () => {
|
|
3143
|
+
if (props.noValidate) {
|
|
3144
|
+
return { errors: [], errorSchema: {} };
|
|
3145
|
+
} else if (!props.liveValidate) {
|
|
3146
|
+
return {
|
|
3147
|
+
errors: state.schemaValidationErrors || [],
|
|
3148
|
+
errorSchema: state.schemaValidationErrorSchema || {}
|
|
3149
|
+
};
|
|
3150
|
+
}
|
|
3151
|
+
return {
|
|
3152
|
+
errors: state.errors || [],
|
|
3153
|
+
errorSchema: state.errorSchema || {}
|
|
3154
|
+
};
|
|
3155
|
+
};
|
|
3156
|
+
let errors;
|
|
3157
|
+
let errorSchema;
|
|
3158
|
+
let schemaValidationErrors = state.schemaValidationErrors;
|
|
3159
|
+
let schemaValidationErrorSchema = state.schemaValidationErrorSchema;
|
|
3160
|
+
if (mustValidate) {
|
|
3161
|
+
const schemaValidation = this.validate(formData, schema, schemaUtils);
|
|
3162
|
+
errors = schemaValidation.errors;
|
|
3163
|
+
errorSchema = schemaValidation.errorSchema;
|
|
3164
|
+
schemaValidationErrors = errors;
|
|
3165
|
+
schemaValidationErrorSchema = errorSchema;
|
|
3166
|
+
} else {
|
|
3167
|
+
const currentErrors = getCurrentErrors();
|
|
3168
|
+
errors = currentErrors.errors;
|
|
3169
|
+
errorSchema = currentErrors.errorSchema;
|
|
3170
|
+
}
|
|
3171
|
+
if (props.extraErrors) {
|
|
3172
|
+
const merged = utils.validationDataMerge({ errorSchema, errors }, props.extraErrors);
|
|
3173
|
+
errorSchema = merged.errorSchema;
|
|
3174
|
+
errors = merged.errors;
|
|
3175
|
+
}
|
|
3176
|
+
const idSchema = schemaUtils.toIdSchema(
|
|
3177
|
+
retrievedSchema,
|
|
3178
|
+
uiSchema["ui:rootFieldId"],
|
|
3179
|
+
formData,
|
|
3180
|
+
props.idPrefix,
|
|
3181
|
+
props.idSeparator
|
|
3182
|
+
);
|
|
3183
|
+
const nextState = {
|
|
3184
|
+
schemaUtils,
|
|
3185
|
+
schema,
|
|
3186
|
+
uiSchema,
|
|
3187
|
+
idSchema,
|
|
3188
|
+
formData,
|
|
3189
|
+
edit,
|
|
3190
|
+
errors,
|
|
3191
|
+
errorSchema,
|
|
3192
|
+
schemaValidationErrors,
|
|
3193
|
+
schemaValidationErrorSchema
|
|
3194
|
+
};
|
|
3195
|
+
return nextState;
|
|
3196
|
+
}
|
|
3197
|
+
/** React lifecycle method that is used to determine whether component should be updated.
|
|
3198
|
+
*
|
|
3199
|
+
* @param nextProps - The next version of the props
|
|
3200
|
+
* @param nextState - The next version of the state
|
|
3201
|
+
* @returns - True if the component should be updated, false otherwise
|
|
3202
|
+
*/
|
|
3203
|
+
shouldComponentUpdate(nextProps, nextState) {
|
|
3204
|
+
return utils.shouldRender(this, nextProps, nextState);
|
|
3205
|
+
}
|
|
3206
|
+
/** Validates the `formData` against the `schema` using the `altSchemaUtils` (if provided otherwise it uses the
|
|
3207
|
+
* `schemaUtils` in the state), returning the results.
|
|
3208
|
+
*
|
|
3209
|
+
* @param formData - The new form data to validate
|
|
3210
|
+
* @param schema - The schema used to validate against
|
|
3211
|
+
* @param altSchemaUtils - The alternate schemaUtils to use for validation
|
|
3212
|
+
*/
|
|
3213
|
+
validate(formData, schema = this.props.schema, altSchemaUtils) {
|
|
3214
|
+
const schemaUtils = altSchemaUtils ? altSchemaUtils : this.state.schemaUtils;
|
|
3215
|
+
const { customValidate, transformErrors, uiSchema } = this.props;
|
|
3216
|
+
const resolvedSchema = schemaUtils.retrieveSchema(schema, formData);
|
|
3217
|
+
return schemaUtils.getValidator().validateFormData(formData, resolvedSchema, customValidate, transformErrors, uiSchema);
|
|
3218
|
+
}
|
|
3219
|
+
/** Renders any errors contained in the `state` in using the `ErrorList`, if not disabled by `showErrorList`. */
|
|
3220
|
+
renderErrors(registry) {
|
|
3221
|
+
const { errors, errorSchema, schema, uiSchema } = this.state;
|
|
3222
|
+
const { formContext } = this.props;
|
|
3223
|
+
const options = utils.getUiOptions(uiSchema);
|
|
3224
|
+
const ErrorListTemplate = utils.getTemplate("ErrorListTemplate", registry, options);
|
|
3225
|
+
if (errors && errors.length) {
|
|
3226
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3227
|
+
ErrorListTemplate,
|
|
3228
|
+
{
|
|
3229
|
+
errors,
|
|
3230
|
+
errorSchema: errorSchema || {},
|
|
3231
|
+
schema,
|
|
3232
|
+
uiSchema,
|
|
3233
|
+
formContext,
|
|
3234
|
+
registry
|
|
3235
|
+
}
|
|
3236
|
+
);
|
|
3237
|
+
}
|
|
3238
|
+
return null;
|
|
3239
|
+
}
|
|
3240
|
+
/** Returns the registry for the form */
|
|
3241
|
+
getRegistry() {
|
|
3242
|
+
const { translateString: customTranslateString, uiSchema = {} } = this.props;
|
|
3243
|
+
const { schemaUtils } = this.state;
|
|
3244
|
+
const { fields: fields2, templates: templates2, widgets: widgets2, formContext, translateString } = getDefaultRegistry();
|
|
3245
|
+
return {
|
|
3246
|
+
fields: { ...fields2, ...this.props.fields },
|
|
3247
|
+
templates: {
|
|
3248
|
+
...templates2,
|
|
3249
|
+
...this.props.templates,
|
|
3250
|
+
ButtonTemplates: {
|
|
3251
|
+
...templates2.ButtonTemplates,
|
|
3252
|
+
...this.props.templates?.ButtonTemplates
|
|
3253
|
+
}
|
|
3254
|
+
},
|
|
3255
|
+
widgets: { ...widgets2, ...this.props.widgets },
|
|
3256
|
+
rootSchema: this.props.schema,
|
|
3257
|
+
formContext: this.props.formContext || formContext,
|
|
3258
|
+
schemaUtils,
|
|
3259
|
+
translateString: customTranslateString || translateString,
|
|
3260
|
+
globalUiOptions: uiSchema[utils.UI_GLOBAL_OPTIONS_KEY]
|
|
3261
|
+
};
|
|
3262
|
+
}
|
|
3263
|
+
/** Provides a function that can be used to programmatically submit the `Form` */
|
|
3264
|
+
submit() {
|
|
3265
|
+
if (this.formElement.current) {
|
|
3266
|
+
this.formElement.current.dispatchEvent(
|
|
3267
|
+
new CustomEvent("submit", {
|
|
3268
|
+
cancelable: true
|
|
3269
|
+
})
|
|
3270
|
+
);
|
|
3271
|
+
this.formElement.current.requestSubmit();
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3274
|
+
/** Attempts to focus on the field associated with the `error`. Uses the `property` field to compute path of the error
|
|
3275
|
+
* field, then, using the `idPrefix` and `idSeparator` converts that path into an id. Then the input element with that
|
|
3276
|
+
* id is attempted to be found using the `formElement` ref. If it is located, then it is focused.
|
|
3277
|
+
*
|
|
3278
|
+
* @param error - The error on which to focus
|
|
3279
|
+
*/
|
|
3280
|
+
focusOnError(error) {
|
|
3281
|
+
const { idPrefix = "root", idSeparator = "_" } = this.props;
|
|
3282
|
+
const { property } = error;
|
|
3283
|
+
const path = _toPath(property);
|
|
3284
|
+
if (path[0] === "") {
|
|
3285
|
+
path[0] = idPrefix;
|
|
3286
|
+
} else {
|
|
3287
|
+
path.unshift(idPrefix);
|
|
3288
|
+
}
|
|
3289
|
+
const elementId = path.join(idSeparator);
|
|
3290
|
+
let field = this.formElement.current.elements[elementId];
|
|
3291
|
+
if (!field) {
|
|
3292
|
+
field = this.formElement.current.querySelector(`input[id^=${elementId}`);
|
|
3293
|
+
}
|
|
3294
|
+
if (field && field.length) {
|
|
3295
|
+
field = field[0];
|
|
3296
|
+
}
|
|
3297
|
+
if (field) {
|
|
3298
|
+
field.focus();
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
/** Programmatically validate the form. If `onError` is provided, then it will be called with the list of errors the
|
|
3302
|
+
* same way as would happen on form submission.
|
|
3303
|
+
*
|
|
3304
|
+
* @returns - True if the form is valid, false otherwise.
|
|
3305
|
+
*/
|
|
3306
|
+
validateForm() {
|
|
3307
|
+
const { extraErrors, extraErrorsBlockSubmit, focusOnFirstError, onError } = this.props;
|
|
3308
|
+
const { formData } = this.state;
|
|
3309
|
+
const schemaValidation = this.validate(formData);
|
|
3310
|
+
let errors = schemaValidation.errors;
|
|
3311
|
+
let errorSchema = schemaValidation.errorSchema;
|
|
3312
|
+
const schemaValidationErrors = errors;
|
|
3313
|
+
const schemaValidationErrorSchema = errorSchema;
|
|
3314
|
+
if (errors.length > 0 || extraErrors && extraErrorsBlockSubmit) {
|
|
3315
|
+
if (extraErrors) {
|
|
3316
|
+
const merged = utils.validationDataMerge(schemaValidation, extraErrors);
|
|
3317
|
+
errorSchema = merged.errorSchema;
|
|
3318
|
+
errors = merged.errors;
|
|
3319
|
+
}
|
|
3320
|
+
if (focusOnFirstError) {
|
|
3321
|
+
if (typeof focusOnFirstError === "function") {
|
|
3322
|
+
focusOnFirstError(errors[0]);
|
|
3323
|
+
} else {
|
|
3324
|
+
this.focusOnError(errors[0]);
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3327
|
+
this.setState(
|
|
3328
|
+
{
|
|
3329
|
+
errors,
|
|
3330
|
+
errorSchema,
|
|
3331
|
+
schemaValidationErrors,
|
|
3332
|
+
schemaValidationErrorSchema
|
|
3333
|
+
},
|
|
3334
|
+
() => {
|
|
3335
|
+
if (onError) {
|
|
3336
|
+
onError(errors);
|
|
3337
|
+
} else {
|
|
3338
|
+
console.error("Form validation failed", errors);
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3341
|
+
);
|
|
3342
|
+
return false;
|
|
3343
|
+
}
|
|
3344
|
+
return true;
|
|
3345
|
+
}
|
|
3346
|
+
/** Renders the `Form` fields inside the <form> | `tagName` or `_internalFormWrapper`, rendering any errors if
|
|
3347
|
+
* needed along with the submit button or any children of the form.
|
|
3348
|
+
*/
|
|
3349
|
+
render() {
|
|
3350
|
+
const {
|
|
3351
|
+
children,
|
|
3352
|
+
id,
|
|
3353
|
+
idPrefix,
|
|
3354
|
+
idSeparator,
|
|
3355
|
+
className = "",
|
|
3356
|
+
tagName,
|
|
3357
|
+
name,
|
|
3358
|
+
method,
|
|
3359
|
+
target,
|
|
3360
|
+
action,
|
|
3361
|
+
autoComplete,
|
|
3362
|
+
enctype,
|
|
3363
|
+
acceptcharset,
|
|
3364
|
+
noHtml5Validate = false,
|
|
3365
|
+
disabled = false,
|
|
3366
|
+
readonly = false,
|
|
3367
|
+
formContext,
|
|
3368
|
+
showErrorList = "top",
|
|
3369
|
+
_internalFormWrapper
|
|
3370
|
+
} = this.props;
|
|
3371
|
+
const { schema, uiSchema, formData, errorSchema, idSchema } = this.state;
|
|
3372
|
+
const registry = this.getRegistry();
|
|
3373
|
+
const { SchemaField: _SchemaField } = registry.fields;
|
|
3374
|
+
const { SubmitButton: SubmitButton2 } = registry.templates.ButtonTemplates;
|
|
3375
|
+
const as = _internalFormWrapper ? tagName : void 0;
|
|
3376
|
+
const FormTag = _internalFormWrapper || tagName || "form";
|
|
3377
|
+
let { [utils.SUBMIT_BTN_OPTIONS_KEY]: submitOptions = {} } = utils.getUiOptions(uiSchema);
|
|
3378
|
+
if (disabled) {
|
|
3379
|
+
submitOptions = { ...submitOptions, props: { ...submitOptions.props, disabled: true } };
|
|
3380
|
+
}
|
|
3381
|
+
const submitUiSchema = { [utils.UI_OPTIONS_KEY]: { [utils.SUBMIT_BTN_OPTIONS_KEY]: submitOptions } };
|
|
3382
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3383
|
+
FormTag,
|
|
3384
|
+
{
|
|
3385
|
+
className: className ? className : "rjsf",
|
|
3386
|
+
id,
|
|
3387
|
+
name,
|
|
3388
|
+
method,
|
|
3389
|
+
target,
|
|
3390
|
+
action,
|
|
3391
|
+
autoComplete,
|
|
3392
|
+
encType: enctype,
|
|
3393
|
+
acceptCharset: acceptcharset,
|
|
3394
|
+
noValidate: noHtml5Validate,
|
|
3395
|
+
onSubmit: this.onSubmit,
|
|
3396
|
+
as,
|
|
3397
|
+
ref: this.formElement,
|
|
3398
|
+
children: [
|
|
3399
|
+
showErrorList === "top" && this.renderErrors(registry),
|
|
3400
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3401
|
+
_SchemaField,
|
|
3402
|
+
{
|
|
3403
|
+
name: "",
|
|
3404
|
+
schema,
|
|
3405
|
+
uiSchema,
|
|
3406
|
+
errorSchema,
|
|
3407
|
+
idSchema,
|
|
3408
|
+
idPrefix,
|
|
3409
|
+
idSeparator,
|
|
3410
|
+
formContext,
|
|
3411
|
+
formData,
|
|
3412
|
+
onChange: this.onChange,
|
|
3413
|
+
onBlur: this.onBlur,
|
|
3414
|
+
onFocus: this.onFocus,
|
|
3415
|
+
registry,
|
|
3416
|
+
disabled,
|
|
3417
|
+
readonly
|
|
3418
|
+
}
|
|
3419
|
+
),
|
|
3420
|
+
children ? children : /* @__PURE__ */ jsxRuntime.jsx(SubmitButton2, { uiSchema: submitUiSchema, registry }),
|
|
3421
|
+
showErrorList === "bottom" && this.renderErrors(registry)
|
|
3422
|
+
]
|
|
3423
|
+
}
|
|
3424
|
+
);
|
|
3425
|
+
}
|
|
3426
|
+
};
|
|
3427
|
+
function withTheme(themeProps) {
|
|
3428
|
+
return react.forwardRef(
|
|
3429
|
+
({ fields: fields2, widgets: widgets2, templates: templates2, ...directProps }, ref) => {
|
|
3430
|
+
fields2 = { ...themeProps?.fields, ...fields2 };
|
|
3431
|
+
widgets2 = { ...themeProps?.widgets, ...widgets2 };
|
|
3432
|
+
templates2 = {
|
|
3433
|
+
...themeProps?.templates,
|
|
3434
|
+
...templates2,
|
|
3435
|
+
ButtonTemplates: {
|
|
3436
|
+
...themeProps?.templates?.ButtonTemplates,
|
|
3437
|
+
...templates2?.ButtonTemplates
|
|
3438
|
+
}
|
|
3439
|
+
};
|
|
3440
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3441
|
+
Form,
|
|
3442
|
+
{
|
|
3443
|
+
...themeProps,
|
|
3444
|
+
...directProps,
|
|
3445
|
+
fields: fields2,
|
|
3446
|
+
widgets: widgets2,
|
|
3447
|
+
templates: templates2,
|
|
3448
|
+
ref
|
|
3449
|
+
}
|
|
3450
|
+
);
|
|
3451
|
+
}
|
|
3452
|
+
);
|
|
3453
|
+
}
|
|
3454
|
+
|
|
3455
|
+
// src/index.ts
|
|
3456
|
+
var src_default = Form;
|
|
3457
|
+
|
|
3458
|
+
exports.default = src_default;
|
|
3459
|
+
exports.getDefaultRegistry = getDefaultRegistry;
|
|
3460
|
+
exports.withTheme = withTheme;
|
|
3461
|
+
|
|
3462
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3463
|
+
|
|
3464
|
+
}));
|