react-json-tree
Version:
React JSON Viewer Component, Extracted from redux-devtools
46 lines (45 loc) • 3.14 kB
JavaScript
import React, { useCallback, useState } from 'react';
import JSONArrow from './JSONArrow.js';
import getCollectionEntries from './getCollectionEntries.js';
import JSONNode from './JSONNode.js';
import ItemRange from './ItemRange.js';
function isRange(rangeOrEntry) {
return rangeOrEntry.to !== undefined;
}
function renderChildNodes(props, from, to) {
const { nodeType, data, collectionLimit, circularCache, keyPath, postprocessValue, sortObjectKeys, } = props;
const childNodes = [];
getCollectionEntries(nodeType, data, sortObjectKeys, collectionLimit, from, to).forEach((entry) => {
if (isRange(entry)) {
childNodes.push(React.createElement(ItemRange, { ...props, key: `ItemRange--${entry.from}-${entry.to}`, from: entry.from, to: entry.to, renderChildNodes: renderChildNodes }));
}
else {
const { key, value } = entry;
const isCircular = circularCache.includes(value);
childNodes.push(React.createElement(JSONNode, { ...props, postprocessValue, collectionLimit, key: `Node--${key}`, keyPath: [key, ...keyPath], value: postprocessValue(value), circularCache: [...circularCache, value], isCircular: isCircular, hideRoot: false }));
}
});
return childNodes;
}
export default function JSONNestedNode(props) {
const { circularCache = [], collectionLimit, createItemString, data, expandable, getItemString, hideRoot, isCircular, keyPath, labelRenderer, level = 0, nodeType, nodeTypeIndicator, shouldExpandNodeInitially, styling, } = props;
const [expanded, setExpanded] = useState(
// calculate individual node expansion if necessary
isCircular ? false : shouldExpandNodeInitially(keyPath, data, level));
const handleClick = useCallback(() => {
if (expandable)
setExpanded(!expanded);
}, [expandable, expanded]);
const renderedChildren = expanded || (hideRoot && level === 0)
? renderChildNodes({ ...props, circularCache, level: level + 1 })
: null;
const itemType = (React.createElement("span", { ...styling('nestedNodeItemType', expanded) }, nodeTypeIndicator));
const renderedItemString = getItemString(nodeType, data, itemType, createItemString(data, collectionLimit), keyPath);
const stylingArgs = [keyPath, nodeType, expanded, expandable];
return hideRoot ? (React.createElement("li", { ...styling('rootNode', ...stylingArgs) },
React.createElement("ul", { ...styling('rootNodeChildren', ...stylingArgs) }, renderedChildren))) : (React.createElement("li", { ...styling('nestedNode', ...stylingArgs) },
expandable && (React.createElement(JSONArrow, { styling: styling, nodeType: nodeType, expanded: expanded, onClick: handleClick })),
React.createElement("label", { ...styling(['label', 'nestedNodeLabel'], ...stylingArgs), onClick: handleClick }, labelRenderer(...stylingArgs)),
React.createElement("span", { ...styling('nestedNodeItemString', ...stylingArgs), onClick: handleClick }, renderedItemString),
React.createElement("ul", { ...styling('nestedNodeChildren', ...stylingArgs) }, renderedChildren)));
}