@sultanavtajev/element-picker
v1.0.1
Published
React dev tool for inspecting elements — hover to see component hierarchy, source path, CSS selector, and copy to clipboard
Maintainers
Readme
@sultanavtajev/element-picker
Dev tool for Next.js that gives AI assistants precise context about your UI — hover to highlight, click to copy component hierarchy, source path, CSS selector, and more to clipboard.
Built for AI-assisted development with Claude Code, Cursor, Copilot, and similar tools. Designed for Next.js projects (App Router & Pages Router).
Why?
AI assistants struggle when you say "fix that button" — they don't know which component, file, or selector you mean. Element Picker solves this:
- Activate the picker (
Ctrl+Shift+X) - Click any element in your app
- Paste the copied output into your AI chat
- Done — the AI has full context: component name, source file, CSS selector, hierarchy
No more manual searching for file paths or describing UI elements. One click, one paste.
Features
- Hover any element to see an overlay with component info
- Click to copy a detailed markdown summary to clipboard
- Shows React component hierarchy with source file references
- Generates smart CSS selectors (ID → data-slot → aria-label → semantic class → ancestor path)
- Resolves source files via React
_debugSourcewith heuristic fallback - Filters out Next.js internals (router components, layout wrappers, etc.)
- Keyboard shortcut to toggle (default
Ctrl+Shift+X) - Renders via portal — zero impact on your app's DOM structure
- SSR-safe — works with both App Router and Pages Router
- Fully configurable: custom source paths, component bases, output format
Installation
npm i @sultanavtajev/element-pickerRequires a Next.js project with react ≥ 18 and react-dom ≥ 18.
Icons (lucide-react) and toasts (sonner) are included as regular dependencies and installed automatically.
Quick start
npm i @sultanavtajev/element-pickerThen ask your AI assistant to add it to your Next.js root layout:
Add
<ElementPicker />from@sultanavtajev/element-pickerto my root layout. Only render it in development mode.
Or add it manually to app/layout.tsx:
import { ElementPicker } from "@sultanavtajev/element-picker";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
{process.env.NODE_ENV === "development" && <ElementPicker />}
</body>
</html>
);
}Press Ctrl+Shift+X to activate the picker, hover any element, and click to copy its info.
Clipboard output
Clicking an element copies markdown like this:
## Element Picker
- Page: `http://localhost:3000/dashboard`
- React Component: `UserCard`
- React Key: `user-42`
- Component Tree: `AppLayout → DashboardPage → UserCard`
- Source (exact): `src/components/user-card.tsx:14`
- data-slot: `card`
- Text: `John Doe`
- Selector: `[data-slot="card"]`Fields with no value (like id, aria-label, data-testid) are omitted automatically.
Configuration
All props are optional:
<ElementPicker
componentBases={["button", "card", "dialog"]}
sourcePathPrefix="src/components/ui/"
frameworkInternals={["MyInternalWrapper"]}
shortcut={{ ctrl: true, shift: true, key: "X" }}
formatOutput={(info) => JSON.stringify(info, null, 2)}
/>ElementPickerConfig
| Prop | Type | Default | Description |
|---|---|---|---|
| componentBases | string[] | [] | UI component base names for source file inference (e.g. ["button", "card"]) |
| sourcePathPrefix | string | "src/components/ui/" | Path prefix for inferred source files |
| frameworkInternals | string[] | [] | Additional component names to filter from the hierarchy |
| shortcut | ShortcutConfig | { ctrl: true, shift: true, key: "X" } | Keyboard shortcut to toggle the picker |
| formatOutput | (info: ElementInfo) => string | Built-in markdown | Custom formatter for clipboard output |
ShortcutConfig
| Field | Type | Default |
|---|---|---|
| ctrl | boolean | false |
| shift | boolean | false |
| alt | boolean | false |
| key | string | — |
API reference
Components
ElementPicker
The main React component. Renders a portal-based overlay for element inspection. See Configuration for props.
Functions
extractElementInfo(element: HTMLElement, config?: ElementPickerConfig): ElementInfo
Extracts all info for a given DOM element — component hierarchy, source path, CSS selector, attributes, and more.
formatElementInfo(info: ElementInfo): string
Formats an ElementInfo object into the default markdown clipboard string.
generateSelector(element: HTMLElement): string
Generates a smart CSS selector for an element, preferring stable identifiers (ID, data-slot, aria-label) over brittle positional selectors.
getComponentHierarchy(element: HTMLElement, frameworkInternals?: string[]): ComponentEntry[]
Walks the React Fiber tree to build a component hierarchy, filtering out framework internals.
Types
interface ElementInfo {
pageUrl: string;
reactComponent: string;
reactKey: string;
componentTree: string;
sourcePath: string;
sourceConfidence: string;
tagName: string;
id: string;
dataSlot: string;
dataTestId: string;
ariaLabel: string;
textContent: string;
cssSelector: string;
}
interface ComponentEntry {
name: string;
source: string | null;
key: string | null;
}
interface ShortcutConfig {
ctrl?: boolean;
shift?: boolean;
alt?: boolean;
key: string;
}