react-jsonschema-form-extras 0.9.72 → 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.
- package/README.md +785 -785
- package/dist/form-with-extras.js +2 -2
- package/dist/form-with-extras.js.map +1 -1
- package/lib/DraftRte.js +32 -32
- package/lib/TypeaheadField.js +8 -8
- package/lib/css/form-extras.css +9 -9
- package/lib/table/index.js +42 -25
- package/package.json +138 -138
- package/lib/CollapsibleField.js.orig +0 -402
@@ -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>
|
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;
|