json-edit-react 0.9.4 → 1.0.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/README.md +96 -31
- package/build/index.cjs.js +246 -67
- package/build/index.d.ts +47 -6
- package/build/index.esm.js +248 -66
- package/package.json +15 -13
package/build/index.cjs.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
4
|
var react = require('react');
|
|
7
5
|
var assign = require('object-property-assigner');
|
|
@@ -28,7 +26,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
28
26
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
29
27
|
PERFORMANCE OF THIS SOFTWARE.
|
|
30
28
|
***************************************************************************** */
|
|
31
|
-
/* global Reflect, Promise */
|
|
29
|
+
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
32
30
|
|
|
33
31
|
|
|
34
32
|
function __rest(s, e) {
|
|
@@ -51,11 +49,16 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
51
49
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
52
50
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
53
51
|
});
|
|
54
|
-
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
55
|
+
var e = new Error(message);
|
|
56
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
57
|
+
};
|
|
55
58
|
|
|
56
59
|
var e=[],t=[];function n(n,r){if(n&&"undefined"!=typeof document){var a,s=!0===r.prepend?"prepend":"append",d=!0===r.singleTag,i="string"==typeof r.container?document.querySelector(r.container):document.getElementsByTagName("head")[0];if(d){var u=e.indexOf(i);-1===u&&(u=e.push(i)-1,t[u]={}),a=t[u]&&t[u][s]?t[u][s]:t[u][s]=c();}else a=c();65279===n.charCodeAt(0)&&(n=n.substring(1)),a.styleSheet?a.styleSheet.cssText+=n:a.appendChild(document.createTextNode(n));}function c(){var e=document.createElement("style");if(e.setAttribute("type","text/css"),r.attributes)for(var t=Object.keys(r.attributes),n=0;n<t.length;n++)e.setAttribute(t[n],r.attributes[t[n]]);var a="prepend"===s?"afterbegin":"beforeend";return i.insertAdjacentElement(a,e),e}}
|
|
57
60
|
|
|
58
|
-
var css = ":root {\n --jer-select-border: #b6b6b6;\n --jer-select-focus: #777;\n --jer-select-arrow: #777;\n --jer-form-border: 1px solid #ededf0;\n --jer-form-border-focus: 1px solid #e2e2e2;\n --jer-expand-transition-time: 0.
|
|
61
|
+
var css = ":root {\n --jer-select-border: #b6b6b6;\n --jer-select-focus: #777;\n --jer-select-arrow: #777;\n --jer-form-border: 1px solid #ededf0;\n --jer-form-border-focus: 1px solid #e2e2e2;\n --jer-expand-transition-time: 0.5s;\n --jer-highlight-color: #b3d8ff;\n}\n\n.jer-visible {\n opacity: 1;\n transition: var(--jer-expand-transition-time);\n}\n\n.jer-hidden {\n opacity: 0;\n transition: var(--jer-expand-transition-time);\n}\n\n/* Select styled as per:\nhttps://moderncss.dev/custom-select-styles-with-pure-css/\n*/\n\n.jer-select select {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n background-color: transparent;\n border: none;\n padding: 0 1em 0 0;\n margin: 0;\n /* width: 100%; */\n font-family: inherit;\n font-size: inherit;\n color: black;\n cursor: inherit;\n line-height: inherit;\n z-index: 1;\n outline: none;\n}\nselect::-ms-expand {\n display: none;\n}\n\n.jer-select {\n display: grid;\n grid-template-areas: 'select';\n align-items: center;\n position: relative;\n min-width: 12ch;\n max-width: 15ch;\n border: 1px solid var(--jer-select-border);\n border-radius: 0.25em;\n padding: 0.25em 0.5em;\n font-size: 1em;\n cursor: pointer;\n line-height: 1.1;\n background-color: #fff;\n background-image: linear-gradient(to top, #f9f9f9, #fff 33%);\n}\n.jer-select select,\n.jer-select::after {\n grid-area: select;\n}\n.jer-select:not(.jer-select--multiple)::after {\n content: '';\n justify-self: end;\n width: 0.8em;\n height: 0.5em;\n background-color: var(--jer-select-arrow);\n -webkit-clip-path: polygon(100% 0%, 0 0%, 50% 100%);\n clip-path: polygon(100% 0%, 0 0%, 50% 100%);\n}\n\nselect:focus + .focus {\n position: absolute;\n top: -1px;\n left: -1px;\n right: -1px;\n bottom: -1px;\n border: 1px solid var(--jer-select-focus);\n border-radius: inherit;\n}\n\n.jer-editor-container {\n font-size: 1.1em;\n /* font-size: 20px; */\n padding: 1em;\n margin-top: 1em;\n margin-bottom: 1em;\n border-radius: 0.5em;\n}\n\n.jer-editor-container textarea {\n /* width: 90%; */\n color: var(--jer-input-color);\n border: var(--jer-form-border);\n border-radius: 0.3em;\n outline: none;\n}\n\n.jer-editor-container textarea:focus {\n border: var(--jer-form-border-focus);\n}\n\n.jer-editor-container input {\n border: var(--jer-form-border);\n border-radius: 0.3em;\n outline: none;\n}\n\n.jer-editor-container input:focus {\n border: var(--jer-form-border-focus);\n}\n\n/* Input highlighted text */\n.jer-editor-container ::selection {\n background-color: var(--jer-highlight-color);\n}\n\n.jer-editor-container select {\n /* color: red; */\n}\n\n.jer-component {\n}\n\n.jer-collection-header-row,\n.jer-value-main-row {\n display: flex;\n min-height: 1.7em;\n gap: 0.3em;\n align-items: center;\n}\n\n.jer-collection-header-row {\n display: flex;\n flex-wrap: wrap;\n}\n\n.jer-brackets {\n}\n\n.jer-collection-item-count {\n}\n\n.jer-collection-inner {\n position: relative;\n}\n\n.jer-collection-text-edit {\n display: flex;\n flex-direction: column;\n gap: 0.3em;\n align-items: flex-start;\n}\n\n.jer-collection-text-area {\n resize: both;\n padding-top: 0.2em;\n padding-left: 0.5em;\n padding-right: 0.5em;\n padding-bottom: 0;\n overflow: hidden;\n max-height: 40em;\n}\n\n.jer-collection-input-button-row {\n display: flex;\n justify-content: flex-end;\n font-size: 150%;\n}\n\n.jer-collection-element {\n}\n\n.jer-collection-error-row {\n position: absolute;\n bottom: 0;\n}\n\n.jer-collection-error-row-edit {\n}\n\n.jer-error-slug {\n margin-left: 1em;\n}\n\n.jer-value-component {\n position: relative;\n}\n\n.jer-value-main-row {\n display: flex;\n gap: 0;\n}\n\n.jer-value-and-buttons {\n display: flex;\n justify-content: flex-start;\n align-items: center;\n padding-left: 0.5em;\n}\n\n.jer-value-error-row {\n position: absolute;\n}\n\n.jer-value-string {\n line-height: 1.3em;\n}\n\n.jer-input-text {\n resize: none;\n margin: 0;\n height: 1.4em;\n padding-left: 0.5em;\n padding-right: 0.5em;\n padding-bottom: 0;\n min-width: 6em;\n overflow: hidden;\n max-height: 30em;\n}\n\n.jer-value-number {\n}\n\n.jer-value-boolean {\n}\n\n.jer-input-boolean {\n transform: scale(1.5);\n margin-left: 0.3em;\n margin-right: 0.3em;\n}\n\n.jer-value-null {\n}\n\n.jer-value-object {\n}\n\n.jer-object-key {\n word-break: break-word;\n line-height: 1.1em;\n}\n\n.jer-value-array {\n}\n\n.jer-value-invalid {\n opacity: 0.5;\n font-style: italic;\n}\n\n/* .jer-input-text, */\n.jer-input-number {\n height: 1.6em;\n}\n\n.jer-input-number {\n min-width: 3em;\n}\n\n.jer-input-component {\n}\n\n.jer-edit-buttons,\n.jer-confirm-buttons {\n display: flex;\n align-items: center;\n cursor: pointer;\n}\n\n.jer-input-buttons {\n gap: 0.4em;\n}\n\n.jer-edit-buttons {\n gap: 0.4em;\n margin-left: 0.5em;\n opacity: 0;\n}\n\n.jer-confirm-buttons {\n gap: 0.2em;\n margin-left: 0.4em;\n}\n\n.jer-edit-buttons:hover {\n opacity: 1;\n position: relative;\n}\n\n.jer-collection-header-row:hover > .jer-edit-buttons {\n opacity: 1;\n}\n\n.jer-value-main-row:hover > .jer-edit-buttons {\n opacity: 1;\n}\n\n.jer-value-and-buttons:hover > .jer-edit-buttons {\n opacity: 1;\n}\n\n.jer-input-buttons {\n}\n\n.jer-copy-pulse {\n position: relative;\n transition: transform var(--jer-expand-transition-time);\n}\n\n.jer-copy-pulse:hover {\n opacity: 0.85;\n transition: 0.3s;\n transform: scale(1.2);\n}\n\n.jer-copy-pulse:after {\n content: '';\n display: block;\n position: absolute;\n border-radius: 50%;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n opacity: 0;\n transition: all 0.5s;\n box-shadow: 0 0 15px 5px var(--jer-icon-copy-color);\n}\n\n.jer-copy-pulse:active:after {\n box-shadow: 0 0 0 0 var(--jer-icon-copy-color);\n position: absolute;\n border-radius: 4em;\n left: 0;\n top: 0;\n opacity: 1;\n transition: 0s;\n}\n\n.jer-copy-pulse:active {\n top: 0.07em;\n}\n\n.jer-rotate-90 {\n transform: rotate(-90deg);\n transition: transform var(--jer-expand-transition-time);\n}\n\n.jer-accordion-icon {\n /* font-size: '2em'; */\n transition: transform var(--jer-expand-transition-time);\n}\n\n.jer-icon:hover {\n opacity: 0.85;\n transition: 0.3s;\n transform: scale(1.2);\n}\n";
|
|
59
62
|
n(css,{});
|
|
60
63
|
|
|
61
64
|
const defaultTheme$1 = {
|
|
@@ -314,7 +317,7 @@ const ThemeProvider = ({ children }) => {
|
|
|
314
317
|
const [styles, setStyles] = react.useState(emptyStyleObject);
|
|
315
318
|
const [icons, setIcons] = react.useState({});
|
|
316
319
|
const setTheme = (theme) => setStyles(compileStyles(theme));
|
|
317
|
-
return (jsxRuntime.jsx(ThemeProviderContext.Provider,
|
|
320
|
+
return (jsxRuntime.jsx(ThemeProviderContext.Provider, { value: { styles, setTheme, icons, setIcons }, children: children }));
|
|
318
321
|
};
|
|
319
322
|
const useTheme = () => react.useContext(ThemeProviderContext);
|
|
320
323
|
const compileStyles = (themeInput) => {
|
|
@@ -388,12 +391,13 @@ const defaultStyleProperties = {
|
|
|
388
391
|
const AutogrowTextArea = ({ className, name, value, setValue, handleKeyPress, }) => {
|
|
389
392
|
const { styles } = useTheme();
|
|
390
393
|
const dummyValue = value.slice(-1) === '\n' ? value + '.' : value;
|
|
391
|
-
return (jsxRuntime.jsxs("div",
|
|
394
|
+
return (jsxRuntime.jsxs("div", { style: { display: 'grid' }, children: [jsxRuntime.jsx("textarea", { style: Object.assign({ height: 'auto', gridArea: '1 / 1 / 2 / 2', overflowY: 'auto' }, styles.input), rows: 1, className: className, name: name, value: value, onChange: (e) => setValue(e.target.value), autoFocus: true, onFocus: (e) => {
|
|
392
395
|
if (value.length < 40)
|
|
393
396
|
e.target.select();
|
|
394
|
-
}, onKeyDown: handleKeyPress }), jsxRuntime.jsx("span",
|
|
397
|
+
}, onKeyDown: handleKeyPress }), jsxRuntime.jsx("span", { className: className, style: Object.assign({ visibility: 'hidden', height: 'auto', gridArea: '1 / 1 / 2 / 2', color: 'red', opacity: 0.9, whiteSpace: 'pre-wrap', overflow: 'clip', border: '1px solid transparent' }, styles.input), children: dummyValue })] }));
|
|
395
398
|
};
|
|
396
399
|
|
|
400
|
+
const INVALID_FUNCTION_STRING = '**INVALID_FUNCTION**';
|
|
397
401
|
const truncate = (string, length = 200) => string.length < length ? string : `${string.slice(0, length - 2).trim()}...`;
|
|
398
402
|
const StringValue = ({ value, setValue, isEditing, path, setIsEditing, handleEdit, handleCancel, stringTruncate, }) => {
|
|
399
403
|
const { styles } = useTheme();
|
|
@@ -404,10 +408,10 @@ const StringValue = ({ value, setValue, isEditing, path, setIsEditing, handleEdi
|
|
|
404
408
|
handleCancel();
|
|
405
409
|
};
|
|
406
410
|
const breakString = (text) => text.split('\n').map((line, index, arr) => (jsxRuntime.jsxs("span", { children: [line, index < arr.length - 1 ? jsxRuntime.jsx("br", {}) : null] }, index)));
|
|
407
|
-
return isEditing ? (jsxRuntime.jsx(AutogrowTextArea, { className: "jer-input-text", name: path.join('.'), value: value, setValue: setValue, isEditing: isEditing, handleKeyPress: handleKeyPress })) : (jsxRuntime.jsxs("div",
|
|
411
|
+
return isEditing ? (jsxRuntime.jsx(AutogrowTextArea, { className: "jer-input-text", name: path.join('.'), value: value, setValue: setValue, isEditing: isEditing, handleKeyPress: handleKeyPress })) : (jsxRuntime.jsxs("div", { onDoubleClick: () => setIsEditing(true), onClick: (e) => {
|
|
408
412
|
if (e.getModifierState('Control') || e.getModifierState('Meta'))
|
|
409
413
|
setIsEditing(true);
|
|
410
|
-
}, className: "jer-value-string", style: styles.string
|
|
414
|
+
}, className: "jer-value-string", style: styles.string, children: ["\"", breakString(truncate(value, stringTruncate)), "\""] }));
|
|
411
415
|
};
|
|
412
416
|
const NumberValue = ({ value, setValue, isEditing, path, setIsEditing, handleEdit, handleCancel, }) => {
|
|
413
417
|
const { styles } = useTheme();
|
|
@@ -420,24 +424,85 @@ const NumberValue = ({ value, setValue, isEditing, path, setIsEditing, handleEdi
|
|
|
420
424
|
const validateNumber = (input) => {
|
|
421
425
|
return input.replace(/[^0-9.-]/g, '');
|
|
422
426
|
};
|
|
423
|
-
return isEditing ? (jsxRuntime.jsx("input", { className: "jer-input-number", type: "text", name: path.join('.'), value: value, onChange: (e) => setValue(validateNumber(e.target.value)), autoFocus: true, onFocus: (e) => e.target.select(), onKeyDown: handleKeyPress, style: { width: `${String(value).length / 1.5 + 2}em` } })) : (jsxRuntime.jsx("span",
|
|
427
|
+
return isEditing ? (jsxRuntime.jsx("input", { className: "jer-input-number", type: "text", name: path.join('.'), value: value, onChange: (e) => setValue(validateNumber(e.target.value)), autoFocus: true, onFocus: (e) => e.target.select(), onKeyDown: handleKeyPress, style: { width: `${String(value).length / 1.5 + 2}em` } })) : (jsxRuntime.jsx("span", { onDoubleClick: () => setIsEditing(true), className: "jer-value-number", style: styles.number, children: value }));
|
|
424
428
|
};
|
|
425
|
-
const BooleanValue = ({ value, setValue, isEditing, path, setIsEditing, }) => {
|
|
429
|
+
const BooleanValue = ({ value, setValue, isEditing, path, setIsEditing, handleEdit, handleCancel, }) => {
|
|
426
430
|
const { styles } = useTheme();
|
|
427
|
-
|
|
431
|
+
react.useEffect(() => {
|
|
432
|
+
if (isEditing)
|
|
433
|
+
document.addEventListener('keydown', listenForSubmit);
|
|
434
|
+
return () => document.removeEventListener('keydown', listenForSubmit);
|
|
435
|
+
}, [isEditing]);
|
|
436
|
+
const listenForSubmit = (event) => {
|
|
437
|
+
if (event.key === 'Enter') {
|
|
438
|
+
handleEdit();
|
|
439
|
+
}
|
|
440
|
+
else if (event.key === 'Escape')
|
|
441
|
+
handleCancel();
|
|
442
|
+
};
|
|
443
|
+
return isEditing ? (jsxRuntime.jsx("input", { className: "jer-input-boolean", type: "checkbox", name: path.join('.'), checked: value, onChange: () => setValue(!value) })) : (jsxRuntime.jsx("span", { onDoubleClick: () => setIsEditing(true), className: "jer-value-boolean", style: styles.boolean, children: String(value) }));
|
|
428
444
|
};
|
|
429
|
-
const NullValue = ({ value, isEditing, setIsEditing }) => {
|
|
445
|
+
const NullValue = ({ value, isEditing, setIsEditing, handleEdit, handleCancel, }) => {
|
|
430
446
|
const { styles } = useTheme();
|
|
431
|
-
|
|
447
|
+
react.useEffect(() => {
|
|
448
|
+
if (isEditing)
|
|
449
|
+
document.addEventListener('keydown', listenForSubmit);
|
|
450
|
+
return () => document.removeEventListener('keydown', listenForSubmit);
|
|
451
|
+
}, [isEditing]);
|
|
452
|
+
const listenForSubmit = (event) => {
|
|
453
|
+
if (event.key === 'Enter') {
|
|
454
|
+
handleEdit();
|
|
455
|
+
}
|
|
456
|
+
else if (event.key === 'Escape')
|
|
457
|
+
handleCancel();
|
|
458
|
+
};
|
|
459
|
+
return isEditing ? (jsxRuntime.jsx("div", { className: "jer-input-null", children: "null" })) : (jsxRuntime.jsx("div", { onDoubleClick: () => setIsEditing(true), className: "jer-value-null", style: styles.null, children: String(value) }));
|
|
432
460
|
};
|
|
433
|
-
const ObjectValue = () => {
|
|
434
|
-
|
|
461
|
+
const ObjectValue = ({ value, translate, isEditing, handleEdit, handleCancel, }) => {
|
|
462
|
+
react.useEffect(() => {
|
|
463
|
+
if (isEditing)
|
|
464
|
+
document.addEventListener('keydown', listenForSubmit);
|
|
465
|
+
return () => document.removeEventListener('keydown', listenForSubmit);
|
|
466
|
+
}, []);
|
|
467
|
+
const listenForSubmit = (event) => {
|
|
468
|
+
if (event.key === 'Enter') {
|
|
469
|
+
handleEdit();
|
|
470
|
+
}
|
|
471
|
+
else if (event.key === 'Escape')
|
|
472
|
+
handleCancel();
|
|
473
|
+
};
|
|
474
|
+
return (jsxRuntime.jsx("span", { className: "jer-value-object", children: `{${translate('DEFAULT_NEW_KEY')}: "${value}" }` }));
|
|
435
475
|
};
|
|
436
|
-
const ArrayValue = ({ value }) => {
|
|
437
|
-
|
|
476
|
+
const ArrayValue = ({ value, isEditing, handleEdit, handleCancel, }) => {
|
|
477
|
+
react.useEffect(() => {
|
|
478
|
+
if (isEditing)
|
|
479
|
+
document.addEventListener('keydown', listenForSubmit);
|
|
480
|
+
return () => document.removeEventListener('keydown', listenForSubmit);
|
|
481
|
+
}, []);
|
|
482
|
+
const listenForSubmit = (event) => {
|
|
483
|
+
if (event.key === 'Enter') {
|
|
484
|
+
handleEdit();
|
|
485
|
+
}
|
|
486
|
+
else if (event.key === 'Escape')
|
|
487
|
+
handleCancel();
|
|
488
|
+
};
|
|
489
|
+
return jsxRuntime.jsx("span", { className: "jer-value-array", children: `[${value === null ? '' : value}]` });
|
|
438
490
|
};
|
|
439
|
-
const InvalidValue = () => {
|
|
440
|
-
|
|
491
|
+
const InvalidValue = ({ value }) => {
|
|
492
|
+
let message = 'Error!';
|
|
493
|
+
switch (typeof value) {
|
|
494
|
+
case 'string':
|
|
495
|
+
if (value === INVALID_FUNCTION_STRING)
|
|
496
|
+
message = 'Function';
|
|
497
|
+
break;
|
|
498
|
+
case 'undefined':
|
|
499
|
+
message = 'Undefined';
|
|
500
|
+
break;
|
|
501
|
+
case 'symbol':
|
|
502
|
+
message = 'Symbol';
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
505
|
+
return jsxRuntime.jsx("span", { className: "jer-value-invalid", children: message });
|
|
441
506
|
};
|
|
442
507
|
|
|
443
508
|
const Icon = ({ name, rotate }) => {
|
|
@@ -458,7 +523,7 @@ const Icon = ({ name, rotate }) => {
|
|
|
458
523
|
case 'cancel':
|
|
459
524
|
return ((_f = icons === null || icons === void 0 ? void 0 : icons.cancel) !== null && _f !== void 0 ? _f : (jsxRuntime.jsx(ti.TiCancel, Object.assign({}, commonProps, { style: Object.assign({ fontSize: '130%' }, styles.iconCancel) }))));
|
|
460
525
|
case 'chevron':
|
|
461
|
-
return ((_g = icons === null || icons === void 0 ? void 0 : icons.chevron) !== null && _g !== void 0 ? _g : (jsxRuntime.jsx(fa.FaChevronDown, { className:
|
|
526
|
+
return ((_g = icons === null || icons === void 0 ? void 0 : icons.chevron) !== null && _g !== void 0 ? _g : (jsxRuntime.jsx(fa.FaChevronDown, { className: `jer-accordion-icon${rotate ? ' jer-rotate-90' : ''}`, style: styles.iconCollection })));
|
|
462
527
|
default:
|
|
463
528
|
return jsxRuntime.jsx(jsxRuntime.Fragment, {});
|
|
464
529
|
}
|
|
@@ -482,38 +547,41 @@ const EditButtons = ({ startEdit, handleDelete, handleAdd, enableClipboard, type
|
|
|
482
547
|
setIsAdding(false);
|
|
483
548
|
};
|
|
484
549
|
const handleCopy = (e) => {
|
|
485
|
-
let
|
|
486
|
-
let value
|
|
550
|
+
let copyType = 'value';
|
|
551
|
+
let value;
|
|
552
|
+
let stringValue = '';
|
|
487
553
|
if (enableClipboard) {
|
|
488
554
|
switch (e.ctrlKey || e.metaKey) {
|
|
489
555
|
case true:
|
|
490
556
|
value = stringifyPath(path);
|
|
491
|
-
|
|
557
|
+
stringValue = value;
|
|
558
|
+
copyType = 'path';
|
|
492
559
|
break;
|
|
493
560
|
default:
|
|
494
|
-
value =
|
|
561
|
+
value = data;
|
|
562
|
+
stringValue = type ? JSON.stringify(data, null, 2) : String(value);
|
|
495
563
|
}
|
|
496
|
-
navigator.clipboard.writeText(
|
|
564
|
+
navigator.clipboard.writeText(stringValue);
|
|
497
565
|
}
|
|
498
566
|
if (typeof enableClipboard === 'function')
|
|
499
|
-
enableClipboard({ value, path, key: name, type });
|
|
567
|
+
enableClipboard({ value, stringValue, path, key: name, type: copyType });
|
|
500
568
|
};
|
|
501
|
-
return (jsxRuntime.jsxs("div",
|
|
569
|
+
return (jsxRuntime.jsxs("div", { className: "jer-edit-buttons", style: isAdding ? { opacity: 1 } : undefined, children: [enableClipboard && (jsxRuntime.jsx("div", { onClick: handleCopy, className: "jer-copy-pulse", children: jsxRuntime.jsx(Icon, { name: "copy" }) })), startEdit && (jsxRuntime.jsx("div", { onClick: startEdit, children: jsxRuntime.jsx(Icon, { name: "edit" }) })), handleDelete && (jsxRuntime.jsx("div", { onClick: handleDelete, children: jsxRuntime.jsx(Icon, { name: "delete" }) })), handleAdd && (jsxRuntime.jsx("div", { onClick: () => {
|
|
502
570
|
if (type === 'object')
|
|
503
571
|
setIsAdding(true);
|
|
504
572
|
else
|
|
505
573
|
handleAdd('');
|
|
506
|
-
}
|
|
574
|
+
}, children: jsxRuntime.jsx(Icon, { name: "add" }) })), isAdding && handleAdd && type === 'object' && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("input", { className: "jer-input-new-key", type: "text", name: "new-object-key", value: newKey, onChange: (e) => setNewKey(e.target.value), autoFocus: true, onFocus: (e) => e.target.select(), onKeyDown: handleKeyPress, style: Object.assign({}, styles.input) }), jsxRuntime.jsx(InputButtons, { onOk: () => {
|
|
507
575
|
if (!!newKey) {
|
|
508
576
|
setIsAdding(false);
|
|
509
577
|
handleAdd(newKey);
|
|
510
578
|
}
|
|
511
579
|
}, onCancel: () => {
|
|
512
580
|
setIsAdding(false);
|
|
513
|
-
} })] }))] }))
|
|
581
|
+
} })] }))] }));
|
|
514
582
|
};
|
|
515
583
|
const InputButtons = ({ onOk, onCancel }) => {
|
|
516
|
-
return (jsxRuntime.jsxs("div",
|
|
584
|
+
return (jsxRuntime.jsxs("div", { className: "jer-confirm-buttons", children: [jsxRuntime.jsx("div", { onClick: onOk, children: jsxRuntime.jsx(Icon, { name: "ok" }) }), jsxRuntime.jsx("div", { onClick: onCancel, children: jsxRuntime.jsx(Icon, { name: "cancel" }) })] }));
|
|
517
585
|
};
|
|
518
586
|
const stringifyPath = (path) => path.reduce((str, part) => {
|
|
519
587
|
if (typeof part === 'number')
|
|
@@ -527,19 +595,43 @@ const ValueDataTypes = ['string', 'number', 'boolean', 'null'];
|
|
|
527
595
|
const CollectionDataTypes = ['object', 'array'];
|
|
528
596
|
const DataTypes = [...ValueDataTypes, ...CollectionDataTypes];
|
|
529
597
|
|
|
530
|
-
const
|
|
598
|
+
const getCustomNode = (customNodeDefinitions = [], filterProps) => {
|
|
599
|
+
const matchingDefinitions = customNodeDefinitions.filter(({ condition }) => condition(filterProps));
|
|
600
|
+
if (matchingDefinitions.length === 0)
|
|
601
|
+
return {};
|
|
602
|
+
const { element, props, hideKey = false } = matchingDefinitions[0];
|
|
603
|
+
return { CustomNode: element, customNodeProps: props, hideKey };
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
const CustomNodeWrapper = ({ name, hideKey, children, indent, }) => {
|
|
607
|
+
const { styles } = useTheme();
|
|
608
|
+
const indentStyle = indent ? { marginLeft: `${indent / 2}em` } : {};
|
|
609
|
+
return (jsxRuntime.jsx("div", { className: "jer-component jer-value-component", style: indentStyle, children: jsxRuntime.jsxs("div", { className: "jer-value-main-row", style: {
|
|
610
|
+
flexWrap: name.length > 10 ? 'wrap' : 'nowrap',
|
|
611
|
+
}, children: [!hideKey && (jsxRuntime.jsxs("label", { htmlFor: name, className: "jer-object-key", style: Object.assign(Object.assign({}, styles.property), { minWidth: `${Math.min(String(name).length + 1, 5)}ch`, flexShrink: name.length > 10 ? 1 : 0 }), children: [name, ":", ' '] })), jsxRuntime.jsx("div", { className: "jer-value-and-buttons", style: { paddingLeft: hideKey ? 0 : undefined }, children: children })] }) }));
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
const ValueNodeWrapper = (props) => {
|
|
615
|
+
const { data, parentData, name, path, onEdit, onDelete, enableClipboard, restrictEditFilter, restrictDeleteFilter, restrictTypeSelection, showLabel, stringTruncate, indent, translate, customNodeDefinitions, } = props;
|
|
531
616
|
const { styles } = useTheme();
|
|
532
617
|
const [isEditing, setIsEditing] = react.useState(false);
|
|
533
|
-
const [
|
|
618
|
+
const [isEditingKey, setIsEditingKey] = react.useState(false);
|
|
619
|
+
const [value, setValue] = react.useState(typeof data === 'function' ? INVALID_FUNCTION_STRING : data);
|
|
534
620
|
const [error, setError] = react.useState(null);
|
|
535
621
|
const [dataType, setDataType] = react.useState(getDataType(data));
|
|
536
622
|
react.useEffect(() => {
|
|
537
|
-
setValue(typeof data === 'function' ?
|
|
623
|
+
setValue(typeof data === 'function' ? INVALID_FUNCTION_STRING : data);
|
|
538
624
|
setDataType(getDataType(data));
|
|
539
625
|
}, [data, error]);
|
|
540
626
|
const handleChangeDataType = (type) => {
|
|
541
|
-
|
|
542
|
-
|
|
627
|
+
const customNode = customNodeDefinitions.find((customNode) => customNode.name === type);
|
|
628
|
+
if (customNode) {
|
|
629
|
+
onEdit(customNode.defaultValue, path);
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
setValue(convertValue(value, type));
|
|
633
|
+
setDataType(type);
|
|
634
|
+
}
|
|
543
635
|
};
|
|
544
636
|
const logError = (errorString) => {
|
|
545
637
|
setError(errorString);
|
|
@@ -551,10 +643,10 @@ const ValueNodeWrapper = ({ data, name, path, onEdit, onDelete, enableClipboard,
|
|
|
551
643
|
let newValue;
|
|
552
644
|
switch (dataType) {
|
|
553
645
|
case 'object':
|
|
554
|
-
newValue = {};
|
|
646
|
+
newValue = { [translate('DEFAULT_NEW_KEY')]: value };
|
|
555
647
|
break;
|
|
556
648
|
case 'array':
|
|
557
|
-
newValue = value !== null ?
|
|
649
|
+
newValue = value !== null ? value : [];
|
|
558
650
|
break;
|
|
559
651
|
case 'number':
|
|
560
652
|
const n = Number(value);
|
|
@@ -571,9 +663,27 @@ const ValueNodeWrapper = ({ data, name, path, onEdit, onDelete, enableClipboard,
|
|
|
571
663
|
logError(error);
|
|
572
664
|
});
|
|
573
665
|
};
|
|
666
|
+
const handleEditKey = (newKey) => {
|
|
667
|
+
setIsEditingKey(false);
|
|
668
|
+
if (!parentData)
|
|
669
|
+
return;
|
|
670
|
+
const parentPath = path.slice(0, -1);
|
|
671
|
+
if (!newKey)
|
|
672
|
+
return;
|
|
673
|
+
const newData = Object.fromEntries(Object.entries(parentData).map(([key, val]) => (key === name ? [newKey, val] : [key, val])));
|
|
674
|
+
onEdit(newData, parentPath);
|
|
675
|
+
};
|
|
676
|
+
const handleKeyPress = (e) => {
|
|
677
|
+
if (e.key === 'Enter')
|
|
678
|
+
handleEditKey(e.target.value);
|
|
679
|
+
else if (e.key === 'Escape')
|
|
680
|
+
handleCancel();
|
|
681
|
+
};
|
|
574
682
|
const handleCancel = () => {
|
|
575
683
|
setIsEditing(false);
|
|
684
|
+
setIsEditingKey(false);
|
|
576
685
|
setValue(data);
|
|
686
|
+
setDataType(getDataType(data));
|
|
577
687
|
};
|
|
578
688
|
const handleDelete = () => {
|
|
579
689
|
onDelete(value, path).then((error) => {
|
|
@@ -584,20 +694,47 @@ const ValueNodeWrapper = ({ data, name, path, onEdit, onDelete, enableClipboard,
|
|
|
584
694
|
const filterProps = { key: name, path, level: path.length, value: data, size: null };
|
|
585
695
|
const canEdit = react.useMemo(() => !restrictEditFilter(filterProps), [filterProps]);
|
|
586
696
|
const canDelete = react.useMemo(() => !restrictDeleteFilter(filterProps), [filterProps]);
|
|
697
|
+
const isArray = typeof path.slice(-1)[0] === 'number';
|
|
698
|
+
const canEditKey = !isArray && canEdit && canDelete;
|
|
587
699
|
const inputProps = {
|
|
588
700
|
value,
|
|
701
|
+
parentData,
|
|
589
702
|
setValue,
|
|
590
703
|
isEditing,
|
|
591
|
-
setIsEditing,
|
|
704
|
+
setIsEditing: canEdit ? () => setIsEditing(true) : () => { },
|
|
592
705
|
handleEdit,
|
|
593
706
|
handleCancel,
|
|
594
707
|
path,
|
|
595
708
|
stringTruncate,
|
|
709
|
+
translate,
|
|
596
710
|
};
|
|
597
|
-
|
|
711
|
+
const { CustomNode, customNodeProps, hideKey } = getCustomNode(customNodeDefinitions, {
|
|
712
|
+
key: name,
|
|
713
|
+
path,
|
|
714
|
+
level: path.length,
|
|
715
|
+
value: data,
|
|
716
|
+
size: 0,
|
|
717
|
+
});
|
|
718
|
+
const allDataTypes = [
|
|
719
|
+
...customNodeDefinitions
|
|
720
|
+
.filter(({ showInTypesSelector = false }) => showInTypesSelector)
|
|
721
|
+
.map(({ name }) => name),
|
|
722
|
+
...DataTypes,
|
|
723
|
+
];
|
|
724
|
+
const allowedDataTypes = react.useMemo(() => {
|
|
725
|
+
if (typeof restrictTypeSelection === 'boolean')
|
|
726
|
+
return restrictTypeSelection ? [] : allDataTypes;
|
|
727
|
+
if (Array.isArray(restrictTypeSelection))
|
|
728
|
+
return restrictTypeSelection;
|
|
729
|
+
const result = restrictTypeSelection(filterProps);
|
|
730
|
+
if (typeof result === 'boolean')
|
|
731
|
+
return result ? [] : allDataTypes;
|
|
732
|
+
return result;
|
|
733
|
+
}, [filterProps, restrictTypeSelection]);
|
|
734
|
+
return CustomNode ? (jsxRuntime.jsx(CustomNodeWrapper, { name: name, hideKey: hideKey, indent: indent, children: jsxRuntime.jsx(CustomNode, Object.assign({ customProps: customNodeProps }, props)) })) : (jsxRuntime.jsx("div", { className: "jer-component jer-value-component", style: { marginLeft: `${indent / 2}em` }, children: jsxRuntime.jsxs("div", { className: "jer-value-main-row", style: {
|
|
598
735
|
flexWrap: name.length > 10 ? 'wrap' : 'nowrap',
|
|
599
|
-
}
|
|
600
|
-
!error && (jsxRuntime.jsx(EditButtons, { startEdit: canEdit ? () => setIsEditing(true) : undefined, handleDelete: canDelete ? handleDelete : undefined, data: data, enableClipboard: enableClipboard, name: name, path: path, translate: translate }))), isEditing && (jsxRuntime.jsxs("div",
|
|
736
|
+
}, children: [showLabel && !isEditingKey && (jsxRuntime.jsxs("label", { htmlFor: path.join('.'), className: "jer-object-key", style: Object.assign(Object.assign({}, styles.property), { minWidth: `${Math.min(String(name).length + 1, 5)}ch`, flexShrink: name.length > 10 ? 1 : 0 }), onDoubleClick: () => canEditKey && setIsEditingKey(true), children: [name, ":", ' '] })), showLabel && isEditingKey && (jsxRuntime.jsx("input", { className: "jer-object-key", type: "text", name: path.join('.'), defaultValue: name, autoFocus: true, onFocus: (e) => e.target.select(), onKeyDown: handleKeyPress, style: { width: `${String(name).length / 1.5 + 0.5}em` } })), jsxRuntime.jsxs("div", { className: "jer-value-and-buttons", children: [jsxRuntime.jsx("div", { className: "jer-input-component", children: getInputComponent(dataType, inputProps) }), isEditing ? (jsxRuntime.jsx(InputButtons, { onOk: handleEdit, onCancel: handleCancel })) : (dataType !== 'invalid' &&
|
|
737
|
+
!error && (jsxRuntime.jsx(EditButtons, { startEdit: canEdit ? () => setIsEditing(true) : undefined, handleDelete: canDelete ? handleDelete : undefined, data: data, enableClipboard: enableClipboard, name: name, path: path, translate: translate }))), isEditing && allowedDataTypes.length > 0 && (jsxRuntime.jsxs("div", { className: "jer-select", children: [jsxRuntime.jsx("select", { name: `${name}-type-select`, className: "jer-type-select", onChange: (e) => handleChangeDataType(e.target.value), value: dataType, children: allowedDataTypes.map((type) => (jsxRuntime.jsx("option", { value: type, children: type }, type))) }), jsxRuntime.jsx("span", { className: "focus" })] })), !isEditing && error && (jsxRuntime.jsx("span", { className: "jer-error-slug", style: styles.error, children: error }))] })] }) }));
|
|
601
738
|
};
|
|
602
739
|
const getDataType = (value) => {
|
|
603
740
|
if (typeof value === 'string')
|
|
@@ -622,7 +759,7 @@ const getInputComponent = (dataType, inputProps) => {
|
|
|
622
759
|
case 'null':
|
|
623
760
|
return jsxRuntime.jsx(NullValue, Object.assign({}, inputProps));
|
|
624
761
|
case 'object':
|
|
625
|
-
return jsxRuntime.jsx(ObjectValue, Object.assign({}, inputProps));
|
|
762
|
+
return jsxRuntime.jsx(ObjectValue, Object.assign({}, inputProps, { value: value }));
|
|
626
763
|
case 'array':
|
|
627
764
|
return jsxRuntime.jsx(ArrayValue, Object.assign({}, inputProps));
|
|
628
765
|
default:
|
|
@@ -641,7 +778,7 @@ const convertValue = (value, type) => {
|
|
|
641
778
|
case 'null':
|
|
642
779
|
return null;
|
|
643
780
|
case 'object':
|
|
644
|
-
return
|
|
781
|
+
return value;
|
|
645
782
|
case 'array':
|
|
646
783
|
return [value];
|
|
647
784
|
default:
|
|
@@ -651,15 +788,19 @@ const convertValue = (value, type) => {
|
|
|
651
788
|
|
|
652
789
|
const isCollection = (value) => value !== null && typeof value == 'object';
|
|
653
790
|
const CollectionNode = (_a) => {
|
|
654
|
-
var { data, path, name } = _a, props = __rest(_a, ["data", "path", "name"]);
|
|
791
|
+
var { data, path, name, parentData, showCollectionCount } = _a, props = __rest(_a, ["data", "path", "name", "parentData", "showCollectionCount"]);
|
|
655
792
|
const { styles } = useTheme();
|
|
656
|
-
const { onEdit, onAdd, onDelete, restrictEditFilter, restrictDeleteFilter, restrictAddFilter, collapseFilter, enableClipboard, indent, keySort, showArrayIndices, defaultValue, translate, } = props;
|
|
793
|
+
const { onEdit, onAdd, onDelete, restrictEditFilter, restrictDeleteFilter, restrictAddFilter, collapseFilter, enableClipboard, indent, keySort, showArrayIndices, defaultValue, translate, customNodeDefinitions, } = props;
|
|
657
794
|
const [isEditing, setIsEditing] = react.useState(false);
|
|
795
|
+
const [isEditingKey, setIsEditingKey] = react.useState(false);
|
|
658
796
|
const [stringifiedValue, setStringifiedValue] = react.useState(JSON.stringify(data, null, 2));
|
|
659
797
|
const [error, setError] = react.useState(null);
|
|
660
798
|
const collectionSize = Object.keys(data).length;
|
|
661
799
|
const filterProps = { key: name, path, level: path.length, value: data, size: collectionSize };
|
|
662
|
-
const
|
|
800
|
+
const startCollapsed = collapseFilter(filterProps);
|
|
801
|
+
const [collapsed, setCollapsed] = react.useState(startCollapsed);
|
|
802
|
+
const hasBeenOpened = react.useRef(!startCollapsed);
|
|
803
|
+
const [isAnimating, setIsAnimating] = react.useState(false);
|
|
663
804
|
react.useEffect(() => {
|
|
664
805
|
setStringifiedValue(JSON.stringify(data, null, 2));
|
|
665
806
|
}, [data]);
|
|
@@ -675,6 +816,14 @@ const CollectionNode = (_a) => {
|
|
|
675
816
|
else if (e.key === 'Escape')
|
|
676
817
|
handleCancel();
|
|
677
818
|
};
|
|
819
|
+
const handleCollapse = () => {
|
|
820
|
+
if (!isEditing) {
|
|
821
|
+
setIsAnimating(true);
|
|
822
|
+
hasBeenOpened.current = true;
|
|
823
|
+
setCollapsed(!collapsed);
|
|
824
|
+
setTimeout(() => setIsAnimating(false), 500);
|
|
825
|
+
}
|
|
826
|
+
};
|
|
678
827
|
const showError = (errorString) => {
|
|
679
828
|
setError(errorString);
|
|
680
829
|
setTimeout(() => setError(null), ERROR_DISPLAY_TIME);
|
|
@@ -697,6 +846,22 @@ const CollectionNode = (_a) => {
|
|
|
697
846
|
return;
|
|
698
847
|
}
|
|
699
848
|
};
|
|
849
|
+
const handleEditKey = (newKey) => {
|
|
850
|
+
setIsEditingKey(false);
|
|
851
|
+
if (!parentData)
|
|
852
|
+
return;
|
|
853
|
+
const parentPath = path.slice(0, -1);
|
|
854
|
+
if (!newKey)
|
|
855
|
+
return;
|
|
856
|
+
const newData = Object.fromEntries(Object.entries(parentData).map(([key, val]) => (key === name ? [newKey, val] : [key, val])));
|
|
857
|
+
onEdit(newData, parentPath);
|
|
858
|
+
};
|
|
859
|
+
const handleKeyPressKeyEdit = (e) => {
|
|
860
|
+
if (e.key === 'Enter')
|
|
861
|
+
handleEditKey(e.target.value);
|
|
862
|
+
else if (e.key === 'Escape')
|
|
863
|
+
handleCancel();
|
|
864
|
+
};
|
|
700
865
|
const handleAdd = (key) => {
|
|
701
866
|
setCollapsed(false);
|
|
702
867
|
if (collectionType === 'array') {
|
|
@@ -731,7 +896,10 @@ const CollectionNode = (_a) => {
|
|
|
731
896
|
const canEdit = react.useMemo(() => !restrictEditFilter(filterProps), [filterProps]);
|
|
732
897
|
const canDelete = react.useMemo(() => !restrictDeleteFilter(filterProps), [filterProps]);
|
|
733
898
|
const canAdd = react.useMemo(() => !restrictAddFilter(filterProps), [filterProps]);
|
|
734
|
-
const
|
|
899
|
+
const canEditKey = parentData !== null && canEdit && canAdd && canDelete;
|
|
900
|
+
const isArray = typeof path.slice(-1)[0] === 'number';
|
|
901
|
+
const showLabel = showArrayIndices || !isArray;
|
|
902
|
+
const showCount = showCollectionCount === 'when-closed' ? collapsed : showCollectionCount;
|
|
735
903
|
const keyValueArray = Object.entries(data).map(([key, value]) => [
|
|
736
904
|
collectionType === 'array' ? Number(key) : key,
|
|
737
905
|
value,
|
|
@@ -739,21 +907,27 @@ const CollectionNode = (_a) => {
|
|
|
739
907
|
if (keySort && collectionType === 'object')
|
|
740
908
|
keyValueArray.sort(typeof keySort === 'function' ? (a, b) => keySort(a[0], b[0]) : undefined);
|
|
741
909
|
const numOfLines = JSON.stringify(data, null, 2).split('\n').length;
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
910
|
+
const { CustomNode, customNodeProps, hideKey } = getCustomNode(customNodeDefinitions, {
|
|
911
|
+
key: name,
|
|
912
|
+
path,
|
|
913
|
+
level: path.length,
|
|
914
|
+
value: data,
|
|
915
|
+
size: Object.keys(data).length,
|
|
916
|
+
});
|
|
917
|
+
return (jsxRuntime.jsx("div", { className: "jer-component fb-collection-component", style: { marginLeft: `${path.length === 0 ? 0 : indent / 2}em` }, children: CustomNode ? (jsxRuntime.jsx(CustomNodeWrapper, { name: name, hideKey: hideKey, children: jsxRuntime.jsx(CustomNode, Object.assign({ data: data, path: path, name: name, parentData: parentData, customProps: customNodeProps }, props)) })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "jer-collection-header-row", children: [jsxRuntime.jsx("div", { onClick: handleCollapse, children: jsxRuntime.jsx(Icon, { name: "chevron", rotate: collapsed }) }), jsxRuntime.jsxs("div", { className: "jer-collection-name", children: [!isEditingKey && (jsxRuntime.jsx("span", { style: styles.property, onDoubleClick: () => canEditKey && setIsEditingKey(true), children: showLabel && name !== '' && name !== undefined ? `${name}:` : null })), isEditingKey && (jsxRuntime.jsx("input", { className: "jer-collection-name", type: "text", name: path.join('.'), defaultValue: name, autoFocus: true, onFocus: (e) => e.target.select(), onKeyDown: handleKeyPressKeyEdit, style: { width: `${String(name).length / 1.5 + 0.5}em` } })), !isEditing && (jsxRuntime.jsx("span", { className: "jer-brackets", style: styles.bracket, children: brackets.open }))] }), !isEditing && showCollectionCount && (jsxRuntime.jsx("div", { className: `jer-collection-item-count${showCount ? ' jer-visible' : ' jer-hidden'}`, style: styles.itemCount, children: collectionSize === 1
|
|
918
|
+
? translate('ITEM_SINGLE', 1)
|
|
919
|
+
: translate('ITEMS_MULTIPLE', collectionSize) })), jsxRuntime.jsx("div", { className: `jer-brackets${collapsed ? ' jer-visible' : ' jer-hidden'}`, style: styles.bracket, children: brackets.close }), !isEditing && (jsxRuntime.jsx(EditButtons, { startEdit: canEdit
|
|
920
|
+
? () => {
|
|
921
|
+
setIsEditing(true);
|
|
922
|
+
setCollapsed(false);
|
|
923
|
+
}
|
|
924
|
+
: undefined, handleAdd: canAdd ? handleAdd : undefined, handleDelete: canDelete ? handleDelete : undefined, enableClipboard: enableClipboard, type: collectionType, data: data, name: name, path: path, translate: translate }))] }), jsxRuntime.jsxs("div", { className: 'jer-collection-inner', style: {
|
|
925
|
+
maxHeight: collapsed ? 0 : !isEditing ? `${numOfLines * 3}em` : undefined,
|
|
926
|
+
overflowY: collapsed || isAnimating ? 'hidden' : 'visible',
|
|
927
|
+
transition: `max-height ${transitionTime}`,
|
|
928
|
+
}, children: [isEditing ? (jsxRuntime.jsx("div", { className: "jer-collection-text-edit", children: jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx(AutogrowTextArea, { className: "jer-collection-text-area", name: path.join('.'), value: stringifiedValue, setValue: setStringifiedValue, isEditing: isEditing, handleKeyPress: handleKeyPress }), jsxRuntime.jsx("div", { className: "jer-collection-input-button-row", children: jsxRuntime.jsx(InputButtons, { onOk: handleEdit, onCancel: handleCancel, isCollection: true }) })] }) })) : (jsxRuntime.jsx(jsxRuntime.Fragment, { children: !hasBeenOpened.current
|
|
929
|
+
? null
|
|
930
|
+
: keyValueArray.map(([key, value]) => (jsxRuntime.jsx("div", { className: "jer-collection-element", children: isCollection(value) ? (jsxRuntime.jsx(CollectionNode, Object.assign({ data: value, parentData: data, path: [...path, key], name: key, showCollectionCount: showCollectionCount }, props), key)) : (jsxRuntime.jsx(ValueNodeWrapper, Object.assign({ data: value, parentData: data, path: [...path, key], name: key }, props, { showLabel: collectionType === 'object' ? true : showArrayIndices }), key)) }, key))) })), jsxRuntime.jsx("div", { className: isEditing ? 'jer-collection-error-row' : 'jer-collection-error-row-edit', children: error && (jsxRuntime.jsx("span", { className: "jer-error-slug", style: styles.error, children: error })) }), jsxRuntime.jsx("div", { className: "jer-brackets", style: styles.bracket, children: brackets.close })] })] })) }));
|
|
757
931
|
};
|
|
758
932
|
|
|
759
933
|
const localisedStrings = {
|
|
@@ -765,6 +939,8 @@ const localisedStrings = {
|
|
|
765
939
|
ERROR_UPDATE: 'Update unsuccessful',
|
|
766
940
|
ERROR_DELETE: 'Delete unsuccessful',
|
|
767
941
|
ERROR_ADD: 'Adding node unsuccessful',
|
|
942
|
+
DEFAULT_STRING: 'New data!',
|
|
943
|
+
DEFAULT_NEW_KEY: 'key',
|
|
768
944
|
};
|
|
769
945
|
const translate = (translations, key, count) => {
|
|
770
946
|
const string = key in translations ? translations[key] : localisedStrings[key];
|
|
@@ -772,7 +948,7 @@ const translate = (translations, key, count) => {
|
|
|
772
948
|
};
|
|
773
949
|
const getTranslateFunction = (translations) => (key, count) => translate(translations, key, count);
|
|
774
950
|
|
|
775
|
-
const Editor = ({ data: srcData, rootName = 'root', onUpdate, onEdit: srcEdit = onUpdate, onDelete: srcDelete = onUpdate, onAdd: srcAdd = onUpdate, enableClipboard = true, theme = 'default', icons, indent = 4, collapse = false, restrictEdit = false, restrictDelete = false, restrictAdd = false, keySort = false, showArrayIndices = true, defaultValue = null, minWidth = 250, maxWidth =
|
|
951
|
+
const Editor = ({ data: srcData, rootName = 'root', onUpdate, onEdit: srcEdit = onUpdate, onDelete: srcDelete = onUpdate, onAdd: srcAdd = onUpdate, enableClipboard = true, theme = 'default', icons, indent = 4, collapse = false, showCollectionCount = true, restrictEdit = false, restrictDelete = false, restrictAdd = false, restrictTypeSelection = false, keySort = false, showArrayIndices = true, defaultValue = null, minWidth = 250, maxWidth = 'min(600px, 90vw)', stringTruncate = 250, translations = {}, className, customNodeDefinitions = [], }) => {
|
|
776
952
|
const [data, setData] = react.useState(srcData);
|
|
777
953
|
const { styles, setTheme, setIcons } = useTheme();
|
|
778
954
|
const collapseFilter = react.useCallback(getFilterFunction(collapse), [collapse]);
|
|
@@ -854,10 +1030,12 @@ const Editor = ({ data: srcData, rootName = 'root', onUpdate, onEdit: srcEdit =
|
|
|
854
1030
|
onEdit,
|
|
855
1031
|
onDelete,
|
|
856
1032
|
onAdd,
|
|
1033
|
+
showCollectionCount,
|
|
857
1034
|
collapseFilter,
|
|
858
1035
|
restrictEditFilter,
|
|
859
1036
|
restrictDeleteFilter,
|
|
860
1037
|
restrictAddFilter,
|
|
1038
|
+
restrictTypeSelection,
|
|
861
1039
|
enableClipboard,
|
|
862
1040
|
keySort,
|
|
863
1041
|
showArrayIndices,
|
|
@@ -865,10 +1043,12 @@ const Editor = ({ data: srcData, rootName = 'root', onUpdate, onEdit: srcEdit =
|
|
|
865
1043
|
defaultValue,
|
|
866
1044
|
stringTruncate,
|
|
867
1045
|
translate,
|
|
1046
|
+
customNodeDefinitions,
|
|
1047
|
+
parentData: null,
|
|
868
1048
|
};
|
|
869
1049
|
if (!styles)
|
|
870
1050
|
return null;
|
|
871
|
-
return (jsxRuntime.jsx("div",
|
|
1051
|
+
return (jsxRuntime.jsx("div", { className: 'jer-editor-container ' + className, style: Object.assign(Object.assign({}, styles.container), { minWidth, maxWidth }), children: isCollection(data) ? (jsxRuntime.jsx(CollectionNode, Object.assign({ data: data, path: [] }, otherProps))) : (jsxRuntime.jsx(ValueNodeWrapper, Object.assign({ data: data, path: [], showLabel: true }, otherProps))) }));
|
|
872
1052
|
};
|
|
873
1053
|
const JsonEditor = (props) => (jsxRuntime.jsx(ThemeProvider, { children: jsxRuntime.jsx(Editor, Object.assign({}, props)) }));
|
|
874
1054
|
const updateDataObject = (data, path, newValue, action) => {
|
|
@@ -898,5 +1078,4 @@ const getFilterFunction = (propValue) => {
|
|
|
898
1078
|
};
|
|
899
1079
|
|
|
900
1080
|
exports.JsonEditor = JsonEditor;
|
|
901
|
-
exports.default = JsonEditor;
|
|
902
1081
|
exports.themes = themes;
|