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.
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);
}}
/>
);
}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>;
}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>
);
}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>
);
}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;
}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;
}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;
}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;
}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>;
}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;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
)}
</>
);
}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>
);
}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>
);
}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>
);
}