react-jsonschema-form-extras 0.9.70 → 0.9.73

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.
@@ -1,402 +0,0 @@
1
- import React, { Component } from "react";
2
- import {
3
- deepEquals,
4
- getDefaultFormState
5
- } from "react-jsonschema-form/lib/utils";
6
- import PropTypes from "prop-types";
7
-
8
- import { getFieldName } from "./utils";
9
-
10
- class CollapseMenuAction extends Component {
11
- render() {
12
- let { action, allActions = {} } = this.props;
13
- if (!action) {
14
- return null;
15
- }
16
- if (typeof action === "string") {
17
- return <div>{action}</div>;
18
- } else if (typeof action === "object") {
19
- const Component = allActions[action.component];
20
- if (!Component) {
21
- console.error(
22
- `Can't find ${action.component} in formContext.allActions`
23
- );
24
- return (
25
- <h2 className="warning bg-error" style={{ color: "red" }}>
26
- Can't find <b>{action.component}</b> in <b>formContext</b>.<b>allActions</b>
27
- </h2>
28
- );
29
- }
30
- return <Component {...action.props} />;
31
- }
32
- }
33
- }
34
-
35
- function CollapseMenu(props) {
36
- let {
37
- headerElementsSchemas,
38
- uiSchema,
39
- formContext = {},
40
- formData = {},
41
- onChange,
42
- onAdd,
43
- title,
44
- name,
45
- collapsed,
46
- fields,
47
- propsOnChange
48
- } = props;
49
-
50
- const {
51
- collapse: {
52
- collapsibleHeaderElements = {},
53
- icon: {
54
- enabled = "glyphicon glyphicon-chevron-down",
55
- disabled = "glyphicon glyphicon-chevron-right",
56
- add = "glyphicon glyphicon-plus-sign"
57
- } = {},
58
- separate = true,
59
- addTo,
60
- wrapClassName = "lead",
61
- actions = [],
62
- classNames = "collapsibleHeading",
63
- collapseDivStyles: {
64
- textColor = "white",
65
- background = "linear-gradient(to right, #0472B6, white)",
66
- collapseGlyphColor = "white",
67
- addGlyphColor = "white",
68
- padding = "14px",
69
- margin = "",
70
- marginLeft = "-5px",
71
- marginBottom = "5px",
72
- zIndex = -1,
73
- divCursor = "pointer",
74
- addCursor = "copy"
75
- } = {}
76
- }
77
- } = uiSchema;
78
-
79
- const handleAdd = event => {
80
- event.stopPropagation();
81
- onAdd(event);
82
- };
83
-
84
- let headerElements = [];
85
- let {
86
- className: headerElementsWrapperClass = "header-element-wrapper"
87
- } = collapsibleHeaderElements;
88
-
89
- Object.keys(headerElementsSchemas).map(key => {
90
- const fieldSchema = headerElementsSchemas[key];
91
- const fieldName = getFieldName(fieldSchema.type);
92
-
93
- if (fieldName) {
94
- let FieldElement = fields[fieldName];
95
- const fieldId = `${key}`;
96
- const fieldUiSchema = uiSchema[key];
97
- const fieldFormData = formData[key];
98
-
99
- const elementOnChange = (value, options) => {
100
- formData[key] = value;
101
- propsOnChange(formData, options);
102
- };
103
-
104
- headerElements.push(
105
- <FieldElement
106
- formContext={formContext}
107
- formData={fieldFormData}
108
- idSchema={{ $id: fieldId }}
109
- key={key}
110
- onChange={elementOnChange}
111
- schema={fieldSchema}
112
- uiSchema={fieldUiSchema}
113
- />
114
- );
115
- }
116
- });
117
-
118
- return (
119
- <div className={`${wrapClassName}`}>
120
- <div
121
- className={classNames}
122
- onClick={onChange}
123
- style={{
124
- padding,
125
- margin,
126
- marginLeft,
127
- marginBottom,
128
- zIndex,
129
- cursor: divCursor,
130
- background
131
- }}
132
- >
133
- <span style={{ color: textColor }}>{title || name}</span>&nbsp;
134
- {addTo && (
135
- <a
136
- onClick={handleAdd}
137
- style={{ color: addGlyphColor, cursor: addCursor }}
138
- >
139
- <i style={{ cursor: addCursor }} className={add} />
140
- </a>
141
- )}
142
- <a>
143
- <i
144
- style={{ color: collapseGlyphColor }}
145
- className={collapsed ? disabled : enabled}
146
- />
147
- </a>
148
- {!!headerElements.length && (
149
- <div
150
- className={headerElementsWrapperClass}
151
- onClick={event => event.stopPropagation()}
152
- >
153
- {headerElements}
154
- </div>
155
- )}
156
- {actions.map((action, i) => (
157
- <CollapseMenuAction
158
- key={i}
159
- action={action}
160
- allActions={formContext.allActions}
161
- />
162
- ))}
163
- </div>
164
- {separate && <hr />}
165
- </div>
166
- );
167
- }
168
-
169
- class CollapseLegend extends Component {
170
- render() {
171
- let {
172
- uiSchema: { collapse: { legend } },
173
- formContext: { legends = {} } = {}
174
- } = this.props;
175
- if (!legend) {
176
- return null;
177
- }
178
- if (typeof legend === "string") {
179
- return <div>{legend}</div>;
180
- } else if (typeof legend === "object") {
181
- const Component = legends[legend.component];
182
- if (!Component) {
183
- console.error(`Can't find ${legend.components} in formContext.legends`);
184
- return (
185
- <h2 className="warning bg-error" style={{ color: "red" }}>
186
- Can't find <b>{legend.component}</b> in <b>formContext</b>.<b>legends</b>
187
- </h2>
188
- );
189
- }
190
- return <Component {...legend.props} />;
191
- }
192
- return <div>I'm a legend</div>;
193
- }
194
- }
195
-
196
- class CollapsibleField extends Component {
197
- constructor(props) {
198
- super(props);
199
-
200
- let { uiSchema: { collapse: { collapsed = true } = {} } } = props;
201
-
202
- this.state = { collapsed };
203
- }
204
-
205
- appendToArray = (formData = [], newVal) => {
206
- let { uiSchema: { collapse: { addToBottom = true } = {} } } = this.props;
207
- if (formData.some(v => deepEquals(v, newVal))) {
208
- return formData;
209
- } else {
210
- // newVal can be either array or a single element, concat flattens value
211
- if (addToBottom) {
212
- return formData.concat(newVal);
213
- } else {
214
- return [newVal].concat(formData);
215
- }
216
- }
217
- };
218
-
219
- doAdd = (field, formData, newVal) => {
220
- if (field === "self") {
221
- this.props.onChange(this.appendToArray(formData, newVal));
222
- } else {
223
- let fieldVal = this.appendToArray(formData[field], newVal);
224
- let change = Object.assign({}, formData, { [field]: fieldVal });
225
- this.props.onChange(change);
226
- }
227
- };
228
-
229
- handleAdd = () => {
230
- this.setState({ collapsed: false });
231
- this.forceUpdate(() => {
232
- let {
233
- schema,
234
- uiSchema,
235
- formData,
236
- registry: { fields },
237
- formContext
238
- } = this.props;
239
- let { collapse: { addTo, addElement } } = uiSchema;
240
-
241
- let fieldSchema =
242
- addTo === "self"
243
- ? schema.items
244
- : schema.properties
245
- ? schema.properties[addTo] ? schema.properties[addTo].items : null
246
- : null;
247
- if (!fieldSchema) {
248
- return false;
249
- }
250
- let fieldUiSchema = addTo === "self" ? uiSchema : uiSchema[addTo];
251
- let fieldFormData = addTo === "self" ? formData : formData[addTo];
252
-
253
- if (addElement) {
254
- if (typeof addElement === "function") {
255
- let onSubmit = newVal => {
256
- this.setState({ AddElement: undefined });
257
- this.doAdd(addTo, formData, newVal);
258
- };
259
- let AddElement = addElement(fieldSchema, fieldUiSchema, onSubmit);
260
- this.setState({ AddElement });
261
- } else {
262
- let FieldElement = fields[addElement];
263
- let onBlur = newVal => {
264
- this.setState({ AddElement: undefined });
265
- this.doAdd(addTo, formData, newVal);
266
- };
267
- let AddElement = () => (
268
- <FieldElement
269
- schema={fieldSchema}
270
- uiSchema={fieldUiSchema}
271
- onChange={formData => {
272
- onBlur(formData);
273
- }}
274
- formContext={formContext}
275
- formData={fieldFormData}
276
- />
277
- );
278
- this.setState({ AddElement });
279
- }
280
- } else {
281
- let newVal = getDefaultFormState(fieldSchema, {});
282
- this.doAdd(addTo, formData, newVal);
283
- }
284
- });
285
- };
286
-
287
- handleCollapsed = () => {
288
- this.setState(function(state) {
289
- return { collapsed: !state.collapsed };
290
- });
291
- };
292
-
293
- componentDidCatch(error, errorInfo) {
294
- // You can also log the error to an error reporting service
295
- console.log({ error, errorInfo });
296
- }
297
-
298
- render() {
299
- let {
300
- schema: { title, properties = {} },
301
- uiSchema,
302
- registry: { fields },
303
- idSchema: { $id } = {},
304
- name,
305
- formContext,
306
- formData,
307
- onChange: propsOnChange
308
- } = this.props;
309
- let { collapsed, AddElement } = this.state;
310
- let { collapse: { collapsibleHeaderElements = {}, field } } = uiSchema;
311
- let CollapseElement = fields[field];
312
- <<<<<<< HEAD
313
-
314
- // uischema retains the value for the state
315
- =======
316
- let { elements = [] } = collapsibleHeaderElements;
317
- // uischema retains the value form the state
318
- >>>>>>> origin/master
319
- uiSchema.collapse.collapsed = this.state.collapsed;
320
-
321
- title = uiSchema["ui:title"] ? uiSchema["ui:title"] : title ? title : name;
322
- let customizedId = collapsed ? $id : undefined;
323
-
324
- //remove header elements from the schema
325
- let headerElementsSchemas = {};
326
- let propertiesNoHeader = { ...properties };
327
- let orderNoHeader = uiSchema["ui:order"]
328
- ? uiSchema["ui:order"].filter(x => elements.indexOf(x) < 0)
329
- : uiSchema["ui:order"];
330
-
331
- elements.forEach(key => {
332
- if (propertiesNoHeader[key]) {
333
- headerElementsSchemas[key] = propertiesNoHeader[key];
334
- delete propertiesNoHeader[key];
335
- }
336
- });
337
-
338
- const collapseElementProps = {
339
- ...this.props,
340
- schema: { ...this.props.schema, properties: propertiesNoHeader },
341
- uiSchema: { ...this.props.uiSchema, "ui:order": orderNoHeader }
342
- };
343
-
344
- return (
345
- <div id={customizedId}>
346
- <CollapseMenu
347
- headerElementsSchemas={headerElementsSchemas}
348
- collapsibleFieldId={$id}
349
- title={title}
350
- uiSchema={uiSchema}
351
- collapsed={collapsed}
352
- formContext={formContext}
353
- formData={formData}
354
- fields={fields}
355
- onAdd={this.handleAdd}
356
- onChange={this.handleCollapsed}
357
- propsOnChange={propsOnChange}
358
- />
359
- <div className="form-group">
360
- {AddElement && <AddElement />}
361
- {!collapsed && <CollapseLegend {...this.props} />}
362
- {!collapsed && <CollapseElement {...collapseElementProps} />}
363
- </div>
364
- </div>
365
- );
366
- }
367
- }
368
-
369
- CollapsibleField.propTypes = {
370
- uiSchema: PropTypes.shape({
371
- collapse: PropTypes.shape({
372
- field: PropTypes.string.isRequired,
373
- icon: PropTypes.shape({
374
- enabled: PropTypes.string,
375
- disabled: PropTypes.string,
376
- add: PropTypes.string
377
- }),
378
- separate: PropTypes.boolean,
379
- addTo: PropTypes.string,
380
- addElement: PropTypes.oneOfType([PropTypes.string, PropTypes.string]),
381
- legend: PropTypes.oneOfType([
382
- PropTypes.string,
383
- PropTypes.shape({
384
- component: PropTypes.string.isRequired,
385
- props: PropTypes.object
386
- })
387
- ]),
388
- actions: PropTypes.arrayOf(
389
- PropTypes.shape({
390
- component: PropTypes.string.isRequired,
391
- props: PropTypes.object
392
- })
393
- ),
394
- wrapClassName: PropTypes.string
395
- }).isRequired
396
- }).isRequired,
397
- registry: PropTypes.shape({
398
- fields: PropTypes.object.isRequired
399
- }).isRequired
400
- };
401
-
402
- export default CollapsibleField;