or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

backend-agent.mdbridge-communication.mddata-hydration.mddevtools-ui.mdfrontend-store.mdhook-system.mdindex.mdperformance-profiling.md
tile.json

devtools-ui.mddocs/

DevTools UI

The DevTools UI system provides React components for rendering the complete DevTools interface including element tree inspection, performance profiler, settings panels, and cross-browser compatibility features.

Capabilities

Main DevTools Component

The primary DevTools component that orchestrates the entire UI experience.

/**
 * Main DevTools UI component
 * Renders the complete DevTools interface with tabs, panels, and functionality
 * @param props - DevTools configuration and dependencies
 * @returns React element for DevTools UI
 */
function DevTools(props: DevToolsProps): React$Element<any>;

interface DevToolsProps {
  /** Bridge for backend communication */
  bridge: Bridge;
  /** Store for state management */
  store: Store;
  /** Browser name for compatibility ('Chrome' | 'Firefox') */
  browserName?: BrowserName;
  /** Browser theme ('dark' | 'light') */
  browserTheme?: BrowserTheme;
  /** Container for elements panel portal */
  elementsPortalContainer?: HTMLElement;
  /** Override default tab selection */
  overrideTab?: TabID;
  /** Container for profiler panel portal */
  profilerPortalContainer?: HTMLElement;
  /** Container for settings panel portal */
  settingsPortalContainer?: HTMLElement;
  /** Whether to show the tab bar */
  showTabBar?: boolean;
  /** Function to view element source code */
  viewElementSource?: Function;
}

type BrowserName = 'Chrome' | 'Firefox';
type BrowserTheme = 'dark' | 'light';
type TabID = 'elements' | 'profiler' | 'settings';

Usage Examples:

import { DevTools } from "react-devtools-experimental/src/devtools/views/DevTools";
import Store from "react-devtools-experimental/src/devtools/store";
import Bridge from "react-devtools-experimental/src/bridge";

function App() {
  const bridge = new Bridge(wall);
  const store = new Store(bridge, { supportsProfiling: true });
  
  return (
    <DevTools
      bridge={bridge}
      store={store}
      browserName="Chrome"
      browserTheme="dark"
      showTabBar={true}
      viewElementSource={(id, rendererID) => {
        // Open source code in editor
        openInEditor(id, rendererID);
      }}
    />
  );
}

Context Providers

React contexts for sharing DevTools dependencies throughout the component tree.

/**
 * Context for sharing bridge instance
 */
const BridgeContext: React$Context<Bridge>;

/**
 * Context for sharing store instance
 */
const StoreContext: React$Context<Store>;

Usage Examples:

import { BridgeContext, StoreContext } from "react-devtools-experimental/src/devtools/views/context";

function DevToolsProvider({ bridge, store, children }) {
  return (
    <BridgeContext.Provider value={bridge}>
      <StoreContext.Provider value={store}>
        {children}
      </StoreContext.Provider>
    </BridgeContext.Provider>
  );
}

function ElementInspector() {
  const bridge = useContext(BridgeContext);
  const store = useContext(StoreContext);
  
  const handleInspect = (elementID) => {
    const rendererID = store.getRendererIDForElement(elementID);
    bridge.send('inspect-element', { id: elementID, rendererID });
  };
  
  return <button onClick={() => handleInspect(42)}>Inspect Element</button>;
}

Settings Management

Context and components for managing DevTools user settings and preferences.

/**
 * Settings context for user preferences
 */
const SettingsContext: React$Context<SettingsContextValue>;

interface SettingsContextValue {
  /** Current display density setting */
  displayDensity: DisplayDensity;
  /** Function to update display density */
  setDisplayDensity: (density: DisplayDensity) => void;
  /** Current theme setting */
  theme: Theme;
  /** Function to update theme */
  setTheme: (theme: Theme) => void;
}

type DisplayDensity = 'compact' | 'comfortable';
type Theme = 'auto' | 'light' | 'dark';

Usage Examples:

import { SettingsContext } from "react-devtools-experimental/src/devtools/views/Settings/SettingsContext";

function SettingsPanel() {
  const { theme, setTheme, displayDensity, setDisplayDensity } = useContext(SettingsContext);
  
  return (
    <div>
      <div>
        <label>Theme:</label>
        <select value={theme} onChange={(e) => setTheme(e.target.value)}>
          <option value="auto">Auto</option>
          <option value="light">Light</option>
          <option value="dark">Dark</option>
        </select>
      </div>
      
      <div>
        <label>Display Density:</label>
        <select value={displayDensity} onChange={(e) => setDisplayDensity(e.target.value)}>
          <option value="compact">Compact</option>
          <option value="comfortable">Comfortable</option>
        </select>
      </div>
    </div>
  );
}

Custom Hooks

Utility hooks for common DevTools UI patterns and state management.

/**
 * Hook for managing localStorage-synchronized state
 * @param key - localStorage key to sync with
 * @param initialValue - Initial value if no stored value exists
 * @returns State value and setter function
 */
function useLocalStorage<T>(key: string, initialValue: T): [T, (value: T) => void];

/**
 * Hook for detecting modal dismiss signals (clicks outside, escape key)
 * @param modalRef - Ref to modal element
 * @returns Whether modal should be dismissed
 */
function useModalDismissSignal(modalRef: { current: HTMLElement | null }): boolean;

/**
 * Hook for subscribing to external data sources with automatic cleanup
 * @param config - Subscription configuration
 * @returns Current subscription value
 */
function useSubscription<Value>(config: SubscriptionConfig<Value>): Value;

interface SubscriptionConfig<Value> {
  /** Function to get current value */
  getCurrentValue: () => Value;
  /** Function to subscribe to changes */
  subscribe: (callback: Function) => () => void;
}

Usage Examples:

import { useLocalStorage, useModalDismissSignal, useSubscription } from "react-devtools-experimental/src/devtools/views/hooks";

function ElementTree() {
  // Persist tree expansion state
  const [expandedElements, setExpandedElements] = useLocalStorage('expanded-elements', new Set());
  
  // Subscribe to store updates
  const revision = useSubscription({
    getCurrentValue: () => store.revision,
    subscribe: (callback) => {
      store.on('tree-updated', callback);
      return () => store.off('tree-updated', callback);
    }
  });
  
  return (
    <div>
      Tree revision: {revision}
      {/* Tree content */}
    </div>
  );
}

function Modal({ onClose, children }) {
  const modalRef = useRef(null);
  const shouldDismiss = useModalDismissSignal(modalRef);
  
  useEffect(() => {
    if (shouldDismiss) {
      onClose();
    }
  }, [shouldDismiss, onClose]);
  
  return (
    <div className="modal-overlay">
      <div ref={modalRef} className="modal">
        {children}
      </div>
    </div>
  );
}

UI Component Architecture

Tab System

DevTools uses a tabbed interface for organizing different views and functionality.

/**
 * Tab bar component for switching between DevTools panels
 */
function TabBar(props: TabBarProps): React$Element<any>;

interface TabBarProps {
  /** Currently active tab ID */
  activeTab: TabID;
  /** Function called when tab is selected */
  onTabSelect: (tabID: TabID) => void;
  /** Whether profiling tab should be shown */
  showProfilerTab: boolean;
}

Elements Panel

The elements panel provides the React component tree view and inspection capabilities.

/**
 * Elements panel showing React component tree
 */
function Elements(props: ElementsProps): React$Element<any>;

interface ElementsProps {
  /** Portal container for rendering */
  portalContainer?: HTMLElement;
}

/**
 * Individual element node in the tree
 */
function Element(props: ElementProps): React$Element<any>;

interface ElementProps {
  /** Element data to render */
  element: Element;
  /** Current nesting depth */
  depth: number;
  /** Whether element is selected */
  isSelected: boolean;
  /** Selection change handler */
  onSelect: (elementID: number) => void;
}

Profiler Panel

The profiler panel displays performance analysis and timing data.

/**
 * Profiler panel for performance analysis
 */
function Profiler(props: ProfilerProps): React$Element<any>;

interface ProfilerProps {
  /** Portal container for rendering */
  portalContainer?: HTMLElement;
}

/**
 * Profiler controls for starting/stopping sessions
 */
function ProfilerControls(props: ProfilerControlsProps): React$Element<any>;

interface ProfilerControlsProps {
  /** Whether profiling is currently active */
  isProfiling: boolean;
  /** Function to start profiling */
  onStart: () => void;
  /** Function to stop profiling */
  onStop: () => void;
}

Inspection Details

Components for displaying detailed element inspection information.

/**
 * Element inspection details panel
 */
function InspectedElementTree(props: InspectedElementProps): React$Element<any>;

interface InspectedElementProps {
  /** Element ID being inspected */
  elementID: number;
  /** Inspection data */
  inspectedElement: InspectedElement;
}

/**
 * Component for displaying and editing key-value pairs
 */
function KeyValue(props: KeyValueProps): React$Element<any>;

interface KeyValueProps {
  /** Property name */
  name: string;
  /** Property value */
  value: any;
  /** Whether value is editable */
  isEditable: boolean;
  /** Value change handler */
  onChange?: (newValue: any) => void;
}

Utility Functions

Data Serialization

Utilities for preparing data for display and clipboard operations.

/**
 * Create regular expression from user input string
 * Handles special characters and invalid regex patterns
 * @param string - User input string
 * @returns Valid RegExp object
 */
function createRegExp(string: string): RegExp;

/**
 * Get display label for metadata values
 * @param data - Data object with metadata
 * @returns Human-readable label or null
 */
function getMetaValueLabel(data: Object): string | null;

/**
 * Serialize object data for clipboard copying
 * @param props - Object to serialize
 * @returns Formatted string representation
 */
function serializeDataForCopy(props: Object): string;

/**
 * Serialize hooks data for clipboard copying
 * @param hooks - Hooks tree to serialize
 * @returns Formatted string representation
 */
function serializeHooksForCopy(hooks: HooksTree | null): string;

Usage Examples:

import { 
  createRegExp, 
  serializeDataForCopy, 
  serializeHooksForCopy 
} from "react-devtools-experimental/src/devtools/views/utils";

// Safe regex creation from user input
function FilterElements({ onFilter }) {
  const [filterText, setFilterText] = useState('');
  
  const handleFilter = () => {
    const regex = createRegExp(filterText);
    onFilter(regex);
  };
  
  return (
    <div>
      <input value={filterText} onChange={(e) => setFilterText(e.target.value)} />
      <button onClick={handleFilter}>Filter</button>
    </div>
  );
}

// Copy element data to clipboard
function CopyButton({ elementData, hooksData }) {
  const handleCopy = () => {
    const propsString = serializeDataForCopy(elementData.props);
    const hooksString = serializeHooksForCopy(hooksData);
    
    const combined = `Props:\n${propsString}\n\nHooks:\n${hooksString}`;
    navigator.clipboard.writeText(combined);
  };
  
  return <button onClick={handleCopy}>Copy to Clipboard</button>;
}

Browser Compatibility

Utilities for handling cross-browser differences and capabilities.

/**
 * Get current browser name
 * @returns Browser identifier string
 */
function getBrowserName(): BrowserName;

/**
 * Get current browser theme preference
 * @returns Theme identifier string
 */
function getBrowserTheme(): BrowserTheme;

/**
 * Create view source function for browser environment
 * @param bridge - Bridge for communication
 * @param store - Store for element data
 * @returns Function to view element source
 */
function createViewElementSource(bridge: Bridge, store: Store): Function;

Integration Patterns

Portal Usage

DevTools components can be rendered into specific DOM containers using React portals.

import { createPortal } from 'react-dom';

function DevToolsApp() {
  const elementsContainer = document.getElementById('elements-panel');
  const profilerContainer = document.getElementById('profiler-panel');
  
  return (
    <>
      <TabBar activeTab="elements" onTabSelect={handleTabSelect} />
      
      {elementsContainer && createPortal(
        <Elements />,
        elementsContainer
      )}
      
      {profilerContainer && createPortal(
        <Profiler />,
        profilerContainer
      )}
    </>
  );
}

Event Handling

DevTools components integrate with the store event system for reactive updates.

function ElementTreeView() {
  const store = useContext(StoreContext);
  const [selectedElementID, setSelectedElementID] = useState(null);
  
  useEffect(() => {
    const handleSelection = (elementID) => {
      setSelectedElementID(elementID);
    };
    
    store.on('element-selected', handleSelection);
    return () => store.off('element-selected', handleSelection);
  }, [store]);
  
  return (
    <div>
      {store.roots.map(rootID => (
        <ElementSubtree
          key={rootID}
          elementID={rootID}
          selectedElementID={selectedElementID}
          onSelect={setSelectedElementID}
        />
      ))}
    </div>
  );
}

Theme Integration

Components automatically adapt to browser theme preferences and user settings.

function ThemedComponent() {
  const { theme } = useContext(SettingsContext);
  const browserTheme = getBrowserTheme();
  
  const effectiveTheme = theme === 'auto' ? browserTheme : theme;
  
  return (
    <div className={`component theme-${effectiveTheme}`}>
      {/* Component content */}
    </div>
  );
}

Accessibility Features

DevTools components include comprehensive accessibility support.

function AccessibleTree() {
  return (
    <div
      role="tree"
      aria-label="React component tree"
      onKeyDown={handleKeyboardNavigation}
    >
      {elements.map(element => (
        <div
          key={element.id}
          role="treeitem"
          aria-expanded={element.children.length > 0 ? expanded : undefined}
          aria-level={element.depth + 1}
          tabIndex={selected ? 0 : -1}
        >
          {element.displayName}
        </div>
      ))}
    </div>
  );
}