CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-inspector

Browser DevTools-style inspectors for React applications to display JavaScript objects, tables, and DOM nodes.

Pending
Overview
Eval results
Files

universal-inspector.mddocs/

Universal Inspector

The Inspector component serves as a universal interface that automatically selects the appropriate inspector type based on the provided data. It provides a single, convenient entry point for most inspection needs.

Capabilities

Inspector Component

Main universal component that automatically routes to the appropriate inspector based on data type and props.

/**
 * Universal inspector component that automatically selects inspector type
 * @param props - Inspector configuration props
 * @returns React element with appropriate inspector (Object, Table, or DOM)
 */
function Inspector(props: InspectorProps): React.ReactElement;

interface InspectorProps {
  /** Data to inspect - any JavaScript value */
  data: any;
  /** When true, forces TableInspector regardless of data type */
  table?: boolean;
  /** Theme configuration - preset string or custom theme object */
  theme?: string | ThemeObject;
  
  // ObjectInspector-specific props (when table=false or auto-selected)
  /** Optional root node name */
  name?: string;
  /** Initial expansion level for ObjectInspector */
  expandLevel?: number;
  /** Paths to expand on initialization */
  expandPaths?: string | string[];
  /** Show non-enumerable properties */
  showNonenumerable?: boolean;
  /** Sort object keys */
  sortObjectKeys?: boolean | ((a: string, b: string) => number);
  /** Custom node renderer function */
  nodeRenderer?: (props: NodeRendererProps) => React.ReactElement;
  
  // TableInspector-specific props (when table=true)
  /** Column names for TableInspector */
  columns?: string[];
}

Automatic Inspector Selection

The Inspector component uses the following logic to determine which inspector to use:

  1. Table Mode: If table={true}TableInspector
  2. DOM Node Detection: If data is a DOM node → DOMInspector
  3. Default: Otherwise → ObjectInspector
import React from "react";
import { Inspector } from "react-inspector";

// Automatic selection examples
const data = { name: "Alice", age: 30 };
const arrayData = [{ id: 1 }, { id: 2 }];
const domNode = document.getElementById("myDiv");

function AutoSelectionExamples() {
  return (
    <div>
      {/* Uses ObjectInspector (object data) */}
      <Inspector data={data} />
      
      {/* Uses ObjectInspector (array data, but table=false) */}
      <Inspector data={arrayData} />
      
      {/* Uses TableInspector (table=true forces table mode) */}
      <Inspector data={arrayData} table={true} />
      
      {/* Uses DOMInspector (DOM node detected) */}
      <Inspector data={domNode} />
    </div>
  );
}

Universal Props Handling

The Inspector component intelligently passes props to the selected inspector:

Common Props (passed to all inspectors):

  • data
  • theme

ObjectInspector Props (passed when ObjectInspector is selected):

  • name
  • expandLevel
  • expandPaths
  • showNonenumerable
  • sortObjectKeys
  • nodeRenderer

TableInspector Props (passed when TableInspector is selected):

  • columns

DOMInspector Props (passed when DOMInspector is selected):

  • name
  • expandLevel
  • expandPaths
// Props are automatically routed to the correct inspector
function SmartPropsExample() {
  return (
    <div>
      {/* ObjectInspector receives expandLevel, sortObjectKeys */}
      <Inspector 
        data={{ z: 1, a: 2, b: 3 }}
        expandLevel={1}
        sortObjectKeys={true}
        columns={["irrelevant"]} // Ignored for ObjectInspector
      />
      
      {/* TableInspector receives columns */}
      <Inspector 
        data={[{ name: "Alice" }, { name: "Bob" }]}
        table={true}
        columns={["name"]}
        expandLevel={2} // Ignored for TableInspector
      />
    </div>
  );
}

DOM Node Detection

The Inspector uses the is-dom library to detect DOM nodes and automatically switch to DOMInspector.

DOM Node Types Detected:

  • Element nodes (DIV, SPAN, etc.)
  • Text nodes
  • Comment nodes
  • Document nodes
  • Document fragments
function DOMDetectionExample() {
  const element = document.createElement("div");
  element.innerHTML = "<span>Hello</span>";
  element.setAttribute("class", "example");
  
  return (
    <div>
      {/* Automatically uses DOMInspector */}
      <Inspector data={element} />
      
      {/* Can still override with table=true */}
      <Inspector data={element} table={true} />
    </div>
  );
}

Usage Patterns

Common patterns for using the universal Inspector:

Quick Debugging:

// Drop-in replacement for console.log
function debug(value: any, label?: string) {
  return <Inspector data={value} name={label} expandLevel={1} />;
}

Conditional Display:

function ConditionalExample({ data, showAsTable }: { data: any, showAsTable: boolean }) {
  return (
    <Inspector 
      data={data} 
      table={showAsTable}
      expandLevel={showAsTable ? undefined : 1}
      columns={showAsTable ? ["name", "value"] : undefined}
    />
  );
}

Multi-format Data Viewer:

function DataViewer({ data }: { data: any }) {
  const [viewMode, setViewMode] = useState<'auto' | 'table' | 'object'>('auto');
  
  const getInspectorProps = () => {
    switch (viewMode) {
      case 'table':
        return { table: true };
      case 'object':
        return { table: false, expandLevel: 1 };
      default:
        return {}; // Auto-detect
    }
  };
  
  return (
    <div>
      <select onChange={(e) => setViewMode(e.target.value as any)}>
        <option value="auto">Auto</option>
        <option value="table">Table</option>
        <option value="object">Object</option>
      </select>
      <Inspector data={data} {...getInspectorProps()} />
    </div>
  );
}

Type Safety

The Inspector component maintains type safety through union types that ensure only valid prop combinations are accepted:

type InspectorProps = TableInspectorProps | ObjectInspectorProps;

interface TableInspectorProps extends ComponentProps<typeof TableInspector> {
  table: true;
}

interface ObjectInspectorProps extends ComponentProps<typeof ObjectInspector> {
  table?: false;
}

This ensures that TypeScript will catch invalid prop combinations at compile time:

// ✅ Valid - table mode with columns
<Inspector data={data} table={true} columns={["name"]} />

// ✅ Valid - object mode with expand level
<Inspector data={data} expandLevel={2} />

// ❌ TypeScript error - conflicting props
<Inspector data={data} table={true} expandLevel={2} />

Performance Considerations

The Inspector component has minimal overhead since it simply routes to the appropriate inspector:

  • No re-rendering: Inspector selection happens once per render
  • Props passing: Direct prop forwarding to selected inspector
  • DOM detection: Fast DOM node type checking via is-dom

For performance-critical applications, consider using the specific inspector components directly if the data type is known at compile time.

Install with Tessl CLI

npx tessl i tessl/npm-react-inspector

docs

dom-inspector.md

index.md

object-inspector.md

table-inspector.md

themes.md

universal-inspector.md

utility-components.md

tile.json