@redheadphone/react-json-grid
Version:
React Component that converts JSON to nested grid tables.
650 lines (637 loc) • 28.5 kB
JavaScript
;
var React = require('react');
function styleInject(css, ref) {
if ( ref === void 0 ) ref = {};
var insertAt = ref.insertAt;
if (typeof document === 'undefined') { return; }
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
if (insertAt === 'top') {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
var css_248z = ".json-grid-container {\n --jg-bg-color: #222;\n --jg-border-color: #b5b5b5;\n --jg-cell-border-color: #474747;\n --jg-key-color: #ffffff;\n --jg-index-color: #949494;\n --jg-number-color: #6c99bb;\n --jg-boolean-color: #6c99bb;\n --jg-string-color: #a5c261;\n --jg-object-color: #ffffff;\n --jg-table-header-bg-color: #444;\n --jg-table-icon-color: #ffffff;\n --jg-select-highlight-bg-color: #3b3b3b;\n --jg-search-highlight-bg-color: #565a36;\n display: inline-block;\n margin: 0;\n font-family: \"Segoe UI\", Roboto, Arial, sans-serif;\n line-height: 1.5;\n text-align: left;\n background-color: var(--jg-bg-color);\n}\n.json-grid-container,\n.json-grid-container .json-grid-table {\n border-radius: 3px;\n overflow: hidden;\n}\n.json-grid-container .json-grid-table {\n border-collapse: separate;\n border-spacing: 0;\n border: solid var(--jg-table-border-color) 1px;\n}\n.json-grid-container .json-grid-table .json-grid-table {\n margin: 3px 0px;\n}\n.json-grid-container .json-grid-table .glyphicon {\n position: relative;\n top: 3px;\n display: inline-block;\n color: var(--jg-table-icon-color);\n}\n.json-grid-container .highlight {\n background-color: var(--jg-select-highlight-bg-color);\n}\n.json-grid-container .obj {\n border: 1px solid var(--jg-cell-border-color);\n padding: 3px 10px;\n padding-bottom: 4px;\n cursor: pointer;\n white-space: nowrap;\n}\n.json-grid-container .obj,\n.json-grid-container .obj .name {\n color: var(--jg-key-color);\n}\n.json-grid-container .obj .index {\n color: var(--jg-index-color);\n}\n.json-grid-container .obj .number {\n color: var(--jg-number-color);\n}\n.json-grid-container .obj .boolean {\n color: var(--jg-boolean-color);\n}\n.json-grid-container .obj .string {\n color: var(--jg-string-color);\n}\n.json-grid-container .obj .undefined {\n color: var(--jg-object-color);\n}\n.json-grid-container .obj .object {\n color: var(--jg-object-color);\n}\n.json-grid-container .order {\n background-color: var(--jg-table-header-bg-color);\n font-weight: normal !important;\n}\n.json-grid-container .key {\n vertical-align: top;\n}\n.json-grid-container .title {\n font-weight: bold;\n}\n.json-grid-container .plusminus {\n font-size: 15px;\n font-weight: bold;\n cursor: pointer;\n margin-right: 2px;\n}\n.json-grid-container .search-highlight {\n background-color: var(--jg-search-highlight-bg-color);\n padding: 1px 5px;\n padding-top: 0;\n border-radius: 2px;\n}";
var styles = {"json-grid-container":"json-grid-container","json-grid-table":"json-grid-table","glyphicon":"glyphicon","highlight":"highlight","obj":"obj","name":"name","index":"index","number":"number","boolean":"boolean","string":"string","undefined":"undefined","object":"object","order":"order","key":"key","title":"title","plusminus":"plusminus","search-highlight":"search-highlight"};
styleInject(css_248z);
const themes = {
default: {
bgColor: "#222",
borderColor: "#b5b5b5",
selectHighlightBgColor: "#3b3b3b",
cellBorderColor: "#474747",
keyColor: "#ffffff",
indexColor: "#949494",
numberColor: "#6c99bb",
booleanColor: "#6c99bb",
stringColor: "#a5c261",
objectColor: "#ffffff",
tableHeaderBgColor: "#444",
tableIconColor: "#ffffff",
searchHighlightBgColor: "#565a36",
},
dracula: {
bgColor: "#2b2e3b",
borderColor: "#44475a",
selectHighlightBgColor: "#363949",
cellBorderColor: "#44475a",
keyColor: "#F8F8F2",
indexColor: "#6272a4",
numberColor: "#f1fa8c",
booleanColor: "#ff79c6",
stringColor: "#50FA7B",
objectColor: "#ff79c6",
tableHeaderBgColor: "#363949",
tableIconColor: "#f8f8f2",
searchHighlightBgColor: "#4c4f67",
},
monokai: {
bgColor: "#272822",
borderColor: "#49483e",
selectHighlightBgColor: "#49483e",
cellBorderColor: "#373a2c",
keyColor: "#c1c1bd",
indexColor: "#75715e",
numberColor: "#a3e8f5",
booleanColor: "#ae81ff",
stringColor: "#ece393",
objectColor: "#a6e22e",
tableHeaderBgColor: "#414434",
tableIconColor: "#f8f8f2",
searchHighlightBgColor: "#72705a",
},
oceanicPark: {
bgColor: "#17242B",
borderColor: "#2c3e50",
selectHighlightBgColor: "#345365",
cellBorderColor: "#2b4554",
keyColor: "#89adc2",
indexColor: "#546e7a",
numberColor: "#89ddff",
booleanColor: "#35A6B3",
stringColor: "#c3e88d",
objectColor: "#ffcb6b",
tableHeaderBgColor: "#2c3e50",
tableIconColor: "#ffffff",
searchHighlightBgColor: "#185e70",
},
panda: {
bgColor: "#292A2B",
borderColor: "#4d4e50",
selectHighlightBgColor: "#3e4042",
cellBorderColor: "#4c4c4d",
keyColor: "#b4fdf2",
indexColor: "#9aedfe",
numberColor: "#35dcfd",
booleanColor: "#FF9AA4",
stringColor: "#FFB857",
objectColor: "#ff6b72",
tableHeaderBgColor: "#3b3c3d",
tableIconColor: "#ffffff",
searchHighlightBgColor: "#4a4d4f",
},
gruvboxMaterial: {
bgColor: "#282828",
borderColor: "#3c3836",
selectHighlightBgColor: "#3c3836",
cellBorderColor: "#504945",
keyColor: "#d3869b",
indexColor: "#bdae93",
numberColor: "#8ec07c",
booleanColor: "#8ec07c",
stringColor: "#ebdbb2",
objectColor: "#d3869b",
tableHeaderBgColor: "#3c3836",
tableIconColor: "#ebdbb2",
searchHighlightBgColor: "#62564f",
},
tokyoNight: {
bgColor: "#1A1B26",
borderColor: "#272a36",
selectHighlightBgColor: "#34374c",
cellBorderColor: "#272a36",
keyColor: "#C0CAF5",
indexColor: "#89b8ff",
numberColor: "#7CCE6A",
booleanColor: "#7AA2F7",
stringColor: "#AC94F7",
objectColor: "#9d88f5",
tableHeaderBgColor: "#363a4a",
tableIconColor: "#f3f3f3",
searchHighlightBgColor: "#53577b",
},
remedy: {
bgColor: "#ffffff",
borderColor: "#d3d3d3",
selectHighlightBgColor: "#f5f5f5",
cellBorderColor: "#eaeaea",
keyColor: "#6e5494",
indexColor: "#4d4d4d",
numberColor: "#007acc",
booleanColor: "#007acc",
stringColor: "#2c8ebb",
objectColor: "#6e5494",
tableHeaderBgColor: "#f5f5f5",
tableIconColor: "#6e5494",
searchHighlightBgColor: "#FCEED1",
},
atlanticNight: {
bgColor: "#000720",
borderColor: "#000b33",
selectHighlightBgColor: "#1f2647",
cellBorderColor: "#00114d",
keyColor: "#6cb6ff",
indexColor: "#6cb6ff",
numberColor: "#a2d6ff",
booleanColor: "#a2d6ff",
stringColor: "#BF90C9",
objectColor: "#6cb6ff",
tableHeaderBgColor: "#001666",
tableIconColor: "#ffffff",
searchHighlightBgColor: "#1C2341",
},
defaultLight: {
bgColor: "#f5f5f5",
borderColor: "#d3d3d3",
selectHighlightBgColor: "#e0e0e0",
cellBorderColor: "#c0c0c0",
keyColor: "#333333",
indexColor: "#666666",
numberColor: "#007acc",
booleanColor: "#007acc",
stringColor: "#2ca22c",
objectColor: "#333333",
tableHeaderBgColor: "#dddddd",
tableIconColor: "#333333",
searchHighlightBgColor: "#cccccc",
},
defaultLight2: {
bgColor: "#fafafa",
borderColor: "#e0e0e0",
selectHighlightBgColor: "#e6e6e6",
cellBorderColor: "#c7c7c7",
keyColor: "#4caf50",
indexColor: "#757575",
numberColor: "#2196f3",
booleanColor: "#2196f3",
stringColor: "#ff9800",
objectColor: "#4caf50",
tableHeaderBgColor: "#e0e0e0",
tableIconColor: "#333333",
searchHighlightBgColor: "#cccccc",
},
slime: {
bgColor: "#1E2324",
borderColor: "#333333",
selectHighlightBgColor: "#333333",
cellBorderColor: "#444444",
keyColor: "#8EC199",
indexColor: "#999999",
numberColor: "#BE9287",
booleanColor: "#B081B9",
stringColor: "#D88F56",
objectColor: "#dcdcaa",
tableHeaderBgColor: "#333333",
tableIconColor: "#cccccc",
searchHighlightBgColor: "#404040",
},
spacegray: {
bgColor: "#212835",
borderColor: "#2c313a",
selectHighlightBgColor: "#2c313a",
cellBorderColor: "#394147",
keyColor: "#9ec7fa",
indexColor: "#768390",
numberColor: "#E9B672",
booleanColor: "#D49FF4",
stringColor: "#63F49C",
objectColor: "#61afef",
tableHeaderBgColor: "#2c313a",
tableIconColor: "#e0e0e0",
searchHighlightBgColor: "#303b4f",
},
blueberryDark: {
bgColor: "#242938",
borderColor: "#343d4a",
selectHighlightBgColor: "#343d4a",
cellBorderColor: "#444f5c",
keyColor: "#ADD7FF",
indexColor: "#8c98a6",
numberColor: "#38B0B2",
booleanColor: "#c3e88d",
stringColor: "#27E8A7",
objectColor: "#c792ea",
tableHeaderBgColor: "#343d4a",
tableIconColor: "#ffffff",
searchHighlightBgColor: "#30435a",
},
nord: {
bgColor: "#2e3440",
borderColor: "#3b4252",
selectHighlightBgColor: "#363c4a",
cellBorderColor: "#434c5e",
keyColor: "#81a1c1",
indexColor: "#D8DEE9",
numberColor: "#88C0D0",
booleanColor: "#8fbcbb",
stringColor: "#A3BE8C",
objectColor: "#b48ead",
tableHeaderBgColor: "#3b4252",
tableIconColor: "#e5e9f0",
searchHighlightBgColor: "#404859",
},
nightOwl: {
bgColor: "#011627",
borderColor: "#02233d",
selectHighlightBgColor: "#02233d",
cellBorderColor: "#03314b",
keyColor: "#dbb8e0",
indexColor: "#dcdcaa",
numberColor: "#F77D48",
booleanColor: "#82aaff",
stringColor: "#ECC48D",
objectColor: "#ffcb6b",
tableHeaderBgColor: "#02233d",
tableIconColor: "#e0e0e0",
searchHighlightBgColor: "#033963",
},
oneMonokai: {
bgColor: "#282c34",
borderColor: "#2c313a",
selectHighlightBgColor: "#2c313a",
cellBorderColor: "#3e4451",
keyColor: "#abb2bf",
indexColor: "#5c6370",
numberColor: "#d19a66",
booleanColor: "#61AFEF",
stringColor: "#98c379",
objectColor: "#61afef",
tableHeaderBgColor: "#2c313a",
tableIconColor: "#ffffff",
searchHighlightBgColor: "#383E4A",
},
cobaltNext: {
bgColor: "#1B2B34",
borderColor: "#234666",
selectHighlightBgColor: "#2b333b",
cellBorderColor: "#29546a",
keyColor: "#dcd0e2",
indexColor: "#dcd0e2",
numberColor: "#5A9BCF",
booleanColor: "#ce9178",
stringColor: "#89C794",
objectColor: "#d1d2d3",
tableHeaderBgColor: "#234666",
tableIconColor: "#ffffff",
searchHighlightBgColor: "#343D46",
},
shadesOfPurple: {
bgColor: "#2d2b55",
borderColor: "#463d69",
selectHighlightBgColor: "#463d69",
cellBorderColor: "#54496b",
keyColor: "#fad000",
indexColor: "#a599e9",
numberColor: "#ff6188",
booleanColor: "#ff6188",
stringColor: "#A5FF90",
objectColor: "#fad000",
tableHeaderBgColor: "#463d69",
tableIconColor: "#ffffff",
searchHighlightBgColor: "#554a82",
},
codeBlue: {
bgColor: "#081620",
borderColor: "#233544",
selectHighlightBgColor: "#233544",
cellBorderColor: "#194666",
keyColor: "#B2A8B4",
indexColor: "#96b5b4",
numberColor: "#99cc99",
booleanColor: "#99cc99",
stringColor: "#d2cd87",
objectColor: "#ff8d00",
tableHeaderBgColor: "#233544",
tableIconColor: "#fff",
searchHighlightBgColor: "#233544",
},
softEra: {
bgColor: "#F9F5F5",
borderColor: "#d3d3d3",
selectHighlightBgColor: "#E3E6ED",
cellBorderColor: "#c0c0c0",
keyColor: "#696462",
indexColor: "#888888",
numberColor: "#82B4E3",
booleanColor: "#DA8FBD",
stringColor: "#87B6BE",
objectColor: "#C1AFDF",
tableHeaderBgColor: "#E3E6ED",
tableIconColor: "#333333",
searchHighlightBgColor: "#d0d5e1",
},
atomMaterial: {
bgColor: "#263238",
borderColor: "#37474f",
selectHighlightBgColor: "#37474f",
cellBorderColor: "#546e7a",
keyColor: "#EEFFFF",
indexColor: "#90a4ae",
numberColor: "#F78150",
booleanColor: "#82b1ff",
stringColor: "#C3E88D",
objectColor: "#ffcb6b",
tableHeaderBgColor: "#455a64",
tableIconColor: "#ffffff",
searchHighlightBgColor: "#4F6875",
},
evaDark: {
bgColor: "#282C34",
borderColor: "#343c47",
selectHighlightBgColor: "#343c47",
cellBorderColor: "#3d4752",
keyColor: "#B0B7C3",
indexColor: "#5c6773",
numberColor: "#FF9070",
booleanColor: "#56B7C3",
stringColor: "#82BE79",
objectColor: "#b4be82",
tableHeaderBgColor: "#343c47",
tableIconColor: "#ffffff",
searchHighlightBgColor: "#4e5765",
},
moonLight: {
bgColor: "#222436",
borderColor: "#343c47",
selectHighlightBgColor: "#31344e",
cellBorderColor: "#3d4752",
keyColor: "#C8D3F5",
indexColor: "#C8D3F5",
numberColor: "#7CAFFF",
booleanColor: "#FF6F78",
stringColor: "#7AF8CA",
objectColor: "#ff9e64",
tableHeaderBgColor: "#31344e",
tableIconColor: "#C8D3F5",
searchHighlightBgColor: "#4e5765",
},
};
function isObject(obj) {
return typeof obj === "object" && !Array.isArray(obj) && obj !== null;
}
function classnames(...args) {
return args.filter(Boolean).join(" ");
}
function lookup(obj, searchText) {
const keyTree = {};
let matchesInKey = false;
if (!isObject(obj) && !Array.isArray(obj))
return null;
for (const key in obj) {
if (isObject(obj) && matchesText(key, searchText)) {
matchesInKey = true;
}
if (isObject(obj[key]) || Array.isArray(obj[key])) {
const nestedKeyTree = lookup(obj[key], searchText);
if (nestedKeyTree != null) {
keyTree[key] = nestedKeyTree;
}
}
else if (matchesText(obj[key], searchText)) {
keyTree[key] = true;
}
}
if (Object.keys(keyTree).length !== 0)
return keyTree;
else if (matchesInKey)
return true;
else
return null;
}
function matchesText(obj, searchText) {
if (searchText == null)
return false;
return String(obj).toLowerCase().includes(searchText.toLowerCase());
}
function mergeKeyTrees(keyTree1, keyTree2) {
if (keyTree1 == null)
return keyTree2;
if (keyTree2 == null)
return keyTree1;
if (keyTree1 === true)
return keyTree2;
if (keyTree2 === true)
return keyTree1;
const mergedKeyTree = {};
for (const key in keyTree1) {
mergedKeyTree[key] = mergeKeyTrees(keyTree1[key], keyTree2[key]);
}
for (const key in keyTree2) {
if (!mergedKeyTree.hasOwnProperty(key)) {
mergedKeyTree[key] = keyTree2[key];
}
}
return mergedKeyTree;
}
function checkAllObjects(data) {
let allObjects = false;
let keys = [];
let isArray = Array.isArray(data);
if (Array.isArray(data)) {
allObjects = data.length > 0;
let keysSet = new Set();
for (let i = 0; i < data.length; i++) {
if (!isObject(data[i])) {
allObjects = false;
break;
}
Object.keys(data[i]).forEach((k) => keysSet.add(k));
}
if (allObjects)
keys = Array.from(keysSet);
else
keys = Object.keys(data);
}
else if (isObject(data)) {
keys = Object.keys(data);
}
return { allObjects, keys, isArray };
}
function validateProps({ data, defaultExpandDepth, defaultExpandKeyTree, onSelect, onBlur, highlightSelected, searchText, theme, }) {
if (!data) {
throw new Error("JSONGrid: data prop cannot be null or undefined");
}
if (!Array.isArray(data) && typeof data !== "object") {
throw new Error("JSONGrid: data prop must be an object or an array");
}
if (defaultExpandDepth && defaultExpandDepth < 0) {
throw new Error("JSONGrid: defaultExpandDepth prop must not be a negative number");
}
if (defaultExpandKeyTree && !isObject(defaultExpandKeyTree)) {
throw new Error("JSONGrid: defaultExpandKeyTree prop must be an object");
}
if (onSelect && typeof onSelect !== "function") {
throw new Error("JSONGrid: onSelect prop must be a function");
}
if (onBlur && typeof onBlur !== "function") {
throw new Error("JSONGrid: onBlur prop must be a function");
}
if (highlightSelected && typeof highlightSelected !== "boolean") {
throw new Error("JSONGrid: highlightSelected prop must be a boolean");
}
if (searchText && typeof searchText !== "string") {
throw new Error("JSONGrid: searchText prop must be a string");
}
if (theme && !themes[theme]) {
throw new Error(`JSONGrid: theme prop must be one of ${Object.keys(themes).join(", ")}`);
}
}
function getThemeStyles(customTheme, theme) {
const themeDetails = themes[theme];
return {
"--jg-bg-color": customTheme.bgColor || themeDetails.bgColor,
"--jg-border-color": customTheme.borderColor || themeDetails.borderColor,
"--jg-cell-border-color": customTheme.cellBorderColor || themeDetails.cellBorderColor,
"--jg-key-color": customTheme.keyColor || themeDetails.keyColor,
"--jg-index-color": customTheme.indexColor || themeDetails.indexColor,
"--jg-number-color": customTheme.numberColor || themeDetails.numberColor,
"--jg-boolean-color": customTheme.booleanColor || themeDetails.booleanColor,
"--jg-string-color": customTheme.stringColor || themeDetails.stringColor,
"--jg-object-color": customTheme.objectColor || themeDetails.objectColor,
"--jg-table-header-bg-color": customTheme.tableHeaderBgColor || themeDetails.tableHeaderBgColor,
"--jg-table-icon-color": customTheme.tableIconColor || themeDetails.tableIconColor,
"--jg-select-highlight-bg-color": customTheme.selectHighlightBgColor || themeDetails.selectHighlightBgColor,
"--jg-search-highlight-bg-color": customTheme.searchHighlightBgColor || themeDetails.searchHighlightBgColor,
};
}
const NestedJSONGrid = (props) => {
const { level, keyPath, data, dataKey, highlightedElement, highlightSelected, onSelect, setHighlightedElement, defaultExpandDepth, defaultExpandKeyTree, searchText, } = props;
const highlight = (event) => {
event.stopPropagation();
const target = event.target;
const currentTarget = event.currentTarget;
if ((target !== currentTarget && target.hasAttribute("data-clickable")) ||
(target.parentElement !== currentTarget && target.parentElement?.hasAttribute("data-clickable")))
return;
let nextKeyPath = [];
let nextHighlightElement = currentTarget;
if (highlightedElement != null)
highlightedElement.classList.remove(styles.highlight);
if (currentTarget.hasAttribute("data-rowhighlight")) {
nextHighlightElement = currentTarget.parentElement;
const rowIndex = Array.prototype.indexOf.call(nextHighlightElement?.parentElement?.children, nextHighlightElement);
nextKeyPath = [(isArray && !allObjects ? [rowIndex] : rowIndex)];
}
else if (currentTarget.hasAttribute("data-colhighlight")) {
const colIndex = Array.prototype.indexOf.call(currentTarget.parentElement?.children, currentTarget);
nextHighlightElement = currentTarget.parentElement?.parentElement?.previousElementSibling?.children[colIndex];
nextKeyPath = [[keys[colIndex - 1]]];
}
else {
const rowIndex = Array.prototype.indexOf.call(nextHighlightElement?.parentElement?.parentElement?.children, nextHighlightElement.parentElement);
const colIndex = Array.prototype.indexOf.call(nextHighlightElement?.parentElement?.children, nextHighlightElement);
if (allObjects) {
nextKeyPath = [rowIndex, keys[colIndex - 1]];
}
else {
const key = keys[rowIndex];
if (colIndex === 0) {
nextKeyPath = [[key]];
}
else {
nextKeyPath = [(isArray ? parseInt(key) : key)];
}
}
}
if (highlightSelected)
nextHighlightElement?.classList.add(styles.highlight);
setHighlightedElement(nextHighlightElement);
onSelect(keyPath.concat(nextKeyPath));
};
const renderValue = (key, value, level, keyTree, nextKeyPath) => {
if (value && typeof value === "object")
return (React.createElement("td", { className: classnames(styles.obj, styles.value), onClick: highlight, "data-clickable": "true", key: key },
React.createElement(NestedJSONGrid, { level: level + 1, keyPath: keyPath.concat(nextKeyPath), dataKey: key, data: value, highlightedElement: highlightedElement, highlightSelected: highlightSelected, onSelect: onSelect, setHighlightedElement: setHighlightedElement, defaultExpandDepth: defaultExpandDepth, defaultExpandKeyTree: keyTree && keyTree[key], searchText: searchText })));
return (React.createElement("td", { className: classnames(styles.obj, styles.value), onClick: highlight, "data-clickable": "true", key: key },
React.createElement("span", { className: classnames(styles[typeof value], matchesText(value, searchText) && styles["search-highlight"]) }, String(value))));
};
const renderTable = (data, level, allObjects, keys) => {
return (React.createElement("table", { className: styles["json-grid-table"] },
allObjects && (React.createElement(React.Fragment, null,
React.createElement("colgroup", null,
React.createElement("col", null),
keys.map((key) => (React.createElement("col", { key: key })))),
React.createElement("thead", null,
React.createElement("tr", null,
React.createElement("th", { className: classnames(styles.obj, styles.order), "data-clickable": "true" },
React.createElement("svg", { className: styles.glyphicon, "data-clickable": "true", xmlns: "http://www.w3.org/2000/svg", height: "1em", viewBox: "0 0 448 512" },
React.createElement("path", { fill: "currentColor", d: "M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z" }))),
keys.map((key) => (React.createElement("th", { className: classnames(styles.obj, styles.order, styles.name), key: key, onClick: highlight, "data-clickable": "true", "data-colhighlight": "true" },
React.createElement("span", { className: matchesText(key, searchText) ? styles["search-highlight"] : undefined }, key)))))))),
React.createElement("tbody", null, Object.keys(data).map((key) => (React.createElement("tr", { key: key },
Array.isArray(data) ? (React.createElement("td", { className: classnames(styles.obj, styles.order, styles.index), onClick: highlight, "data-clickable": "true", "data-rowhighlight": "true" }, parseInt(key) + 1)) : (React.createElement("td", { className: classnames(styles.obj, styles.key, styles.name), onClick: highlight, "data-clickable": "true" },
React.createElement("span", { className: matchesText(key, searchText) ? styles["search-highlight"] : undefined }, key))),
allObjects
? keys.map((nestedKey) => renderValue(nestedKey, data[key][nestedKey], level, defaultExpandKeyTree && defaultExpandKeyTree[key], [parseInt(key), nestedKey]))
: renderValue(key, data[key], level, defaultExpandKeyTree, [key])))))));
};
const { allObjects, keys, isArray } = checkAllObjects(data);
if (level !== 0) {
const [open, setOpen] = React.useState(Boolean(level <= defaultExpandDepth || defaultExpandKeyTree));
return (React.createElement("div", { className: styles.box },
React.createElement("span", { className: styles.plusminus, onClick: () => setOpen(!open), "data-clickable": "true" }, open ? "[-]" : "[+]"),
React.createElement("span", { className: styles.title },
dataKey,
"\u00A0",
Array.isArray(data) ? `[${data.length}]` : "{}"),
open && renderTable(data, level, allObjects, keys)));
}
return renderTable(data, level, allObjects, keys);
};
const JSONGrid = ({ data, defaultExpandDepth = 0, defaultExpandKeyTree = {}, onSelect = (keyPath) => { }, onBlur = () => { }, highlightSelected = true, searchText = null, theme = "default", customTheme = {}, }) => {
const [highlightedElement, setHighlightedElement] = React.useState(null);
const wrapperRef = React.useRef(null);
React.useEffect(() => {
function handleClickOutside(event) {
if (wrapperRef.current && !wrapperRef.current.contains(event.target)) {
if (highlightedElement !== null) {
highlightedElement.classList.remove(styles.highlight);
onBlur();
}
setHighlightedElement(null);
}
}
document.addEventListener("click", handleClickOutside);
return () => document.removeEventListener("click", handleClickOutside);
}, [highlightedElement, onBlur]);
React.useEffect(() => {
validateProps({
data,
defaultExpandDepth,
defaultExpandKeyTree,
onSelect,
highlightSelected,
searchText,
theme
});
}, [data, defaultExpandDepth, onSelect, highlightSelected, searchText, theme]);
const themeStyles = getThemeStyles(customTheme, theme);
const mergedKeyTree = searchText
? mergeKeyTrees(defaultExpandKeyTree, lookup(data, searchText))
: defaultExpandKeyTree;
return (React.createElement("div", { className: styles["json-grid-container"], style: themeStyles, ref: wrapperRef },
React.createElement(NestedJSONGrid, { level: 0, keyPath: [], data: data, highlightedElement: highlightedElement, highlightSelected: highlightSelected, onSelect: onSelect, setHighlightedElement: setHighlightedElement, defaultExpandDepth: defaultExpandDepth, defaultExpandKeyTree: mergedKeyTree, searchText: searchText })));
};
module.exports = JSONGrid;
//# sourceMappingURL=index.js.map