# ⚡ Click-to-Component
A zero-config, high-precision component inspector and **Click-to-Component** developer tool for Next.js and React applications.
Hover over any UI element on your web page while holding Alt (or Option ) to highlight component boundaries in real time, and **click to instantly jump to the exact file, line, and column in your IDE** (Antigravity IDE, VS Code, Cursor, WebStorm, Sublime Text, etc.).
---
## ✨ Features
- 🎯 **Direct IDE Jump**: Opens your active IDE and focuses the exact file and cursor position (`file.tsx:line:col`).
- 🔍 **Live Hover Highlighting**: Holding Alt outlines the component under your mouse with dynamic bounding box tracking and smooth scroll support.
- 🔀 **Dual Hierarchy Modes**:
- **Outer Component Mode (Alt )**: Selects the outer component or section container.
- **Inner Leaf Mode (Alt + Ctrl / Cmd )**: Drills down directly to the exact innermost child element (e.g. ``, ``, ``).
- **Live Dynamic Toggle**: Press or release Ctrl while hovering to switch between Outer and Inner mode in real time!
- 🏷️ **Smart Component Badge**: Displays the JSX tag name (e.g. ``, ``), short relative file path, line number, and active inspection mode pill (`OUTER` / `INNER`).
- 📱 **Mobile & Tablet Ready**: Floating draggable inspector button with tap-to-inspect on touch devices.
- 🛡️ **Zero Production Overhead**: Completely disabled, tree-shaken, and stripped out in production builds.
---
## 🏗️ Architecture & How It Works
The system operates across three interconnected layers:
```mermaid
flowchart TD
subgraph BuildTime["1. Build-Time AST Transform"]
A[Babel / Compiler] -->|add-data-locator.cjs| B[Injects data-locator attribute on JSX elements]
end
subgraph ClientSide["2. Client Runtime"]
B --> C[DevClickToComponent]
C -->|Alt + Hover| D[Draws Emerald Bounding Box for Outer Component]
C -->|Alt + Ctrl + Hover| E[Draws Cyan Bounding Box for Inner Element]
C -->|Alt + Click| F[Sends locator to API]
end
subgraph ServerSide["3. Local Server API"]
F -->|POST /api/open-in-ide| G[route.ts]
G -->|CLI Command Execution| H[antigravity-ide / code -r -g filepath:line:col]
H --> I[IDE Opens & Focuses Line]
end
```
---
## 📁 Repository Structure
```
click-to-component/
├── add-data-locator.cjs # Babel AST plugin to inject data-locator attributes
├── .babelrc.example # Babel configuration example
├── client/
│ └── dev-click-to-component.tsx # React Client Component (Inspector UI & Listeners)
├── server/
│ └── route.ts # Next.js App Router API Route (/api/open-in-ide)
├── package.json # Standalone package metadata
└── README.md # Documentation
```
---
## 🚀 Quick Setup & Installation
### Step 1: Install Babel Plugin
Copy `add-data-locator.cjs` to your project root.
Create or update `.babelrc` in your project root:
```json
{
"presets": ["next/babel"],
"env": {
"development": {
"plugins": [
"./add-data-locator.cjs"
]
}
}
}
```
> **Note**: Scoping the plugin inside `"env": { "development": ... }` guarantees that no `data-locator` attributes will be added to your production builds.
---
### Step 2: Add the Server API Route
Create the file `app/api/open-in-ide/route.ts` and copy `server/route.ts` into it:
```ts
import { NextResponse } from "next/server";
import { exec } from "child_process";
import os from "os";
export async function POST(req: Request) {
if (process.env.NODE_ENV !== "development") {
return NextResponse.json(
{ message: "Not available in production" },
{ status: 404 }
);
}
try {
const { locator } = await req.json();
if (!locator) {
return NextResponse.json({ message: "Locator is required" }, { status: 400 });
}
const isWindows = os.platform() === "win32";
const bin = isWindows ? "antigravity-ide.cmd" : "antigravity-ide";
const cmd = `${bin} -r -g "${locator}"`;
return new Promise((resolve) => {
exec(cmd, (error) => {
if (error) {
const fallbackBin = isWindows ? "code.cmd" : "code";
const fallbackCmd = `${fallbackBin} -r -g "${locator}"`;
exec(fallbackCmd, (fallbackError) => {
if (fallbackError) {
resolve(
NextResponse.json(
{ message: "Failed to open file in IDE", error: error.message },
{ status: 500 }
)
);
} else {
resolve(NextResponse.json({ success: true, via: "code" }));
}
});
return;
}
resolve(NextResponse.json({ success: true, via: "antigravity" }));
});
});
} catch (err: unknown) {
const message = err instanceof Error ? err.message : String(err);
return NextResponse.json(
{ message: "Internal server error", error: message },
{ status: 500 }
);
}
}
```
---
### Step 3: Add the Client Component
Copy `client/dev-click-to-component.tsx` to `app/components/dev-click-to-component.tsx` (or `components/dev-click-to-component.tsx`).
Include it in your root layout (`app/layout.tsx`):
```tsx
import { DevClickToComponent } from "./components/dev-click-to-component";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
{children}
{process.env.NODE_ENV === "development" && }
);
}
```
---
## 🎮 How to Use
### Desktop Shortcuts
| Shortcut | Mode | Highlight Color | Target |
| :--- | :--- | :--- | :--- |
| **Alt + Hover** | **`OUTER`** | 🟩 Emerald Green (`#2dd9a4`) | Outer Component / Section Container |
| **Alt + Ctrl + Hover** *(or Alt +Cmd on Mac)* | **`INNER`** | 🟦 Electric Cyan (`#38bdf8`) | Innermost leaf element under mouse cursor |
| **Alt + Click** | **Open** | ⚡ Flash Pulse | Opens the currently highlighted element in your IDE |
### Mobile / Touch Devices
- A floating draggable button appears on screens $\le 768\text{px}$.
- Tap the button to toggle **Inspect Mode**.
- Tap any element on screen to highlight it and open its source code in the IDE.
---
## 💻 Supported IDEs & Protocol Fallbacks
When the local CLI is invoked, the system opens your existing active IDE window using `-r -g :: `:
- **Antigravity IDE** (`antigravity-ide -r -g`)
- **VS Code / VS Code Insiders** (`code -r -g`)
- **Cursor** (`cursor -r -g`)
If the API route is unreachable (e.g. running inside certain sandboxed iframe environments), the client automatically falls back to browser URL protocol schemes:
- `antigravity://file/`
- `cursor://file/`
- `vscode://file/`
- `webstorm://open?file=`
- `subl://open?url=file://`
- `atom://open?url=file://`
---
## 🛡️ Production Safety & Performance
1. **Compiler Level**: In `NODE_ENV === "production"`, `add-data-locator.cjs` returns early without modifying the AST.
2. **Bundle Level**: In `app/layout.tsx`, `{process.env.NODE_ENV === "development" && }` evaluates to `false` during `next build`, allowing bundlers to completely tree-shake the client component out of the production bundle.
3. **Runtime Level**: Event listeners and rendering are guarded with `process.env.NODE_ENV !== "development"`.
4. **Security Level**: The `/api/open-in-ide` route returns a `404` in production environments, preventing arbitrary command execution.
---
## 📄 License
MIT