/** * This component is an object inspector, similar to what you'd see if you did console.log(MyFancyObject) inside of chrome dev tools. It was forked so that I could add highlighting to the nodes and values. */ import React, { Component } from "react"; import TreeView from "../tree-view/TreeView"; import ObjectRootLabel from "./ObjectRootLabel"; import ObjectLabel from "./ObjectLabel"; import ThemeProvider from "../styles/ThemeProvider"; const createIterator = () => function* (obj: any) { // If obj is a primitive then return immediately const shouldIterate = (typeof obj === "object" && obj !== null) || typeof obj === "function"; if (!shouldIterate) return; // Objects and Arrays are processed by this if (Array.isArray(obj) || !obj[Symbol.iterator]) { const keys = Object.getOwnPropertyNames(obj); for (const propertyName of keys) { if (obj.propertyIsEnumerable(propertyName)) { const propertyValue = obj[propertyName]; yield { name: propertyName || '""', data: propertyValue, }; } } return; } // This code doesn't seem to get hit. Possibly it gets called if a function is passed, though the central logger never has that situation let i = 0; for (const entry of obj) { // Normally, the entries are tuples, name value pairs (though it's technically possible for an object to have non-tuple members) const isTuple = Array.isArray(entry) && entry.length === 2; yield isTuple ? { name: entry[0], data: entry[1], } : { name: i.toString(), data: entry, }; i++; } }; const defaultNodeRenderer = ({ onMatchFound, searchBoxText, filterStrings, depth, name, data, isNonenumerable }) => depth === 0 ? ( ) : ( ); /** * Tree-view for objects */ class ObjectInspector extends Component<{ /** An integer specifying to which level the tree should be initially expanded. */ expandLevel?: number; /** An array containing all the paths that should be expanded when the component is initialized, or a string of just one path */ expandPaths?: string[]; name?: string; /** Not required prop because we also allow undefined value */ data: any; /** A known theme or theme object */ theme: string | object; /** Provide a custom nodeRenderer */ nodeRenderer?: (args: any) => JSX.Element; searchBoxText: string; filterStrings: string[]; expanded?: boolean; }> { state: any; constructor(props) { super(props); this.state = { expandLevel: props.expandLevel, allExpanded: false, }; } render() { const { nodeRenderer, theme = "chromeLight", name = "", expanded = false } = this.props; const { expandLevel } = this.state; const dataIterator = createIterator(); const renderer = nodeRenderer || defaultNodeRenderer; return ( ); } } export default React.memo(ObjectInspector);