@useclickly/react 0.2.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -19
- package/dist/Clickly.d.ts +25 -0
- package/dist/Clickly.d.ts.map +1 -0
- package/dist/hooks/useDraggable.d.ts +28 -0
- package/dist/hooks/useDraggable.d.ts.map +1 -0
- package/dist/hooks/usePersistedState.d.ts +6 -0
- package/dist/hooks/usePersistedState.d.ts.map +1 -0
- package/dist/index.cjs +2650 -370
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +12 -69
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2581 -327
- package/dist/index.js.map +1 -1
- package/dist/internal/AnnotationList.d.ts +11 -0
- package/dist/internal/AnnotationList.d.ts.map +1 -0
- package/dist/internal/AnnotationPins.d.ts +7 -0
- package/dist/internal/AnnotationPins.d.ts.map +1 -0
- package/dist/internal/AnnotationPopup.d.ts +5 -0
- package/dist/internal/AnnotationPopup.d.ts.map +1 -0
- package/dist/internal/ClicklyRoot.d.ts +15 -0
- package/dist/internal/ClicklyRoot.d.ts.map +1 -0
- package/dist/internal/CollapsedFAB.d.ts +10 -0
- package/dist/internal/CollapsedFAB.d.ts.map +1 -0
- package/dist/internal/SettingsPopover.d.ts +11 -0
- package/dist/internal/SettingsPopover.d.ts.map +1 -0
- package/dist/internal/Toolbar.d.ts +8 -0
- package/dist/internal/Toolbar.d.ts.map +1 -0
- package/dist/internal/globalStyles.d.ts +13 -0
- package/dist/internal/globalStyles.d.ts.map +1 -0
- package/dist/internal/icons.d.ts +12 -0
- package/dist/internal/icons.d.ts.map +1 -0
- package/dist/internal/styles.d.ts +7 -0
- package/dist/internal/styles.d.ts.map +1 -0
- package/dist/output/markdown.d.ts +5 -0
- package/dist/output/markdown.d.ts.map +1 -0
- package/dist/output/markdown.test.d.ts +2 -0
- package/dist/output/markdown.test.d.ts.map +1 -0
- package/dist/state/annotations.d.ts +21 -0
- package/dist/state/annotations.d.ts.map +1 -0
- package/dist/state/annotations.test.d.ts +2 -0
- package/dist/state/annotations.test.d.ts.map +1 -0
- package/dist/state/settings.d.ts +14 -0
- package/dist/state/settings.d.ts.map +1 -0
- package/dist/state/settings.test.d.ts +2 -0
- package/dist/state/settings.test.d.ts.map +1 -0
- package/dist/state/useEngineState.d.ts +7 -0
- package/dist/state/useEngineState.d.ts.map +1 -0
- package/dist/test/setup.d.ts +7 -0
- package/dist/test/setup.d.ts.map +1 -0
- package/package.json +12 -12
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
# @useclickly/react
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@useclickly/react)
|
|
4
|
+
[](../../LICENSE)
|
|
5
|
+
|
|
3
6
|
> Click-to-annotate dev toolbar for React. Generates prompts your AI coding agent can actually act on.
|
|
4
7
|
|
|
5
|
-
Drop `<Clickly />` into your React app (dev only). A small floating action button appears in the bottom-right. Open it, click any element, write a comment — copy a perfectly-formatted markdown prompt into Claude Code
|
|
8
|
+
Drop `<Clickly />` into your React app (dev only). A small floating action button appears in the bottom-right corner. Open it, click any element, write a comment — copy a perfectly-formatted markdown prompt into **Claude Code**, **Cursor**, **Codex**, or any MCP-aware tool.
|
|
6
9
|
|
|
7
10
|
## Install
|
|
8
11
|
|
|
9
12
|
```bash
|
|
10
13
|
npm install -D @useclickly/react
|
|
11
|
-
# or:
|
|
12
|
-
|
|
14
|
+
# or:
|
|
15
|
+
pnpm add -D @useclickly/react
|
|
16
|
+
yarn add -D @useclickly/react
|
|
13
17
|
```
|
|
14
18
|
|
|
15
19
|
## Use
|
|
@@ -27,20 +31,30 @@ export default function App() {
|
|
|
27
31
|
}
|
|
28
32
|
```
|
|
29
33
|
|
|
30
|
-
That's it.
|
|
34
|
+
That's it. The component returns `null` on the server (safe under SSR / Next App Router) and ships with `"use client"` already baked into the bundle.
|
|
35
|
+
|
|
36
|
+
## What it does
|
|
37
|
+
|
|
38
|
+
| Mode | How |
|
|
39
|
+
|---|---|
|
|
40
|
+
| **Single** | Click any element → popup with comment box |
|
|
41
|
+
| **Multi-select** | Press `2` or shift-click to pin elements, hit **Annotate (N)** when done |
|
|
42
|
+
| **Area drag** | Press `3`, drag a rectangle, every intersecting element gets pinned |
|
|
43
|
+
| **Persistent pins** | Annotated elements stay numbered on the page across page interactions |
|
|
44
|
+
| **Auto-copy** | Submitting an annotation copies markdown to clipboard (toggleable) |
|
|
45
|
+
| **Settings** | Output detail tier, React component info, marker colour — all in the gear menu |
|
|
46
|
+
|
|
47
|
+
## What gets captured
|
|
31
48
|
|
|
32
|
-
|
|
49
|
+
For every selected element, Clickly automatically collects:
|
|
33
50
|
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
41
|
-
- **Crosshair cursor + text-select disabled** while inspecting
|
|
42
|
-
- **Shadow DOM** for zero CSS leakage in either direction
|
|
43
|
-
- **`"use client"` baked in** — Next.js App Router just works
|
|
51
|
+
- Short + full CSS selector (`section.hero > button.cta`)
|
|
52
|
+
- Computed styles (curated by detail tier)
|
|
53
|
+
- Bounding box + position (handles `fixed` / `sticky`)
|
|
54
|
+
- ARIA / `role` / `tabindex` / `title`
|
|
55
|
+
- Visible nearby text (truncated)
|
|
56
|
+
- **React component tree** (`App > Dashboard > Button`) via Fiber walk
|
|
57
|
+
- **Source file + line** (`src/Button.tsx:42`) on Vite/Next — instant grep target
|
|
44
58
|
|
|
45
59
|
## Keyboard shortcuts
|
|
46
60
|
|
|
@@ -53,17 +67,51 @@ That's it.
|
|
|
53
67
|
| `C` | Copy all annotations as markdown |
|
|
54
68
|
| `X` | Clear all annotations |
|
|
55
69
|
|
|
70
|
+
## Props
|
|
71
|
+
|
|
72
|
+
All optional; `<Clickly />` works with zero config.
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
interface ClicklyProps {
|
|
76
|
+
className?: string;
|
|
77
|
+
endpoint?: string; // MCP server URL — see @useclickly/mcp-server
|
|
78
|
+
sessionId?: string;
|
|
79
|
+
onAnnotationAdd?: (id: string) => void;
|
|
80
|
+
onAnnotationDelete?: (id: string) => void;
|
|
81
|
+
onAnnotationsClear?: () => void;
|
|
82
|
+
onCopy?: (markdown: string) => void;
|
|
83
|
+
onSessionCreated?: (sessionId: string) => void;
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Output
|
|
88
|
+
|
|
89
|
+
```md
|
|
90
|
+
## Annotation #1
|
|
91
|
+
**Element:** `button.cta.primary`
|
|
92
|
+
**Path:** `body > main > section.hero > button.cta.primary`
|
|
93
|
+
**Position:** 120px, 480px (200×48px)
|
|
94
|
+
**Source:** `src/components/Hero.tsx:42`
|
|
95
|
+
**React:** App > LandingPage > HeroSection > CTAButton
|
|
96
|
+
**Feedback:** Button is cut off on mobile viewport
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Configurable via the settings popover: `compact` (one-liner) → `standard` → `detailed` → `forensic` (full computed styles).
|
|
100
|
+
|
|
101
|
+
The shape is **[AFS 1.1](https://agentation.dev/schema/annotation.v1.1.json)**-compatible — every MCP-aware agent can parse it.
|
|
102
|
+
|
|
56
103
|
## Requirements
|
|
57
104
|
|
|
58
105
|
- React 18+ or 19+
|
|
59
106
|
- Browser environment (no SSR; component returns `null` server-side)
|
|
60
107
|
- Desktop only — touch / mobile is not optimised
|
|
108
|
+
- **Not for React Native** — see the main [README](https://github.com/useclickly/clickly#react-native)
|
|
109
|
+
|
|
110
|
+
## Advanced
|
|
61
111
|
|
|
62
|
-
|
|
112
|
+
For framework-agnostic engine access — building your own UI on top of Clickly's selection + metadata — see [`@useclickly/core`](https://www.npmjs.com/package/@useclickly/core).
|
|
63
113
|
|
|
64
|
-
|
|
65
|
-
- AFS 1.1 schema: see `@useclickly/core`
|
|
66
|
-
- MCP server (for agent integration): see `@useclickly/mcp-server`
|
|
114
|
+
For agent integration over MCP — your agent reading/responding to annotations directly — see [`@useclickly/mcp-server`](https://www.npmjs.com/package/@useclickly/mcp-server).
|
|
67
115
|
|
|
68
116
|
## License
|
|
69
117
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface ClicklyProps {
|
|
2
|
+
/** Custom class on the host element (for z-index / positioning overrides). */
|
|
3
|
+
className?: string;
|
|
4
|
+
/** Optional MCP server endpoint, e.g. "http://localhost:4747". */
|
|
5
|
+
endpoint?: string;
|
|
6
|
+
/** Join an existing MCP session by ID. */
|
|
7
|
+
sessionId?: string;
|
|
8
|
+
onAnnotationAdd?: (id: string) => void;
|
|
9
|
+
onAnnotationDelete?: (id: string) => void;
|
|
10
|
+
onAnnotationsClear?: () => void;
|
|
11
|
+
onCopy?: (markdown: string) => void;
|
|
12
|
+
onSessionCreated?: (sessionId: string) => void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Mount once near the root of your React app. Dev-only by convention:
|
|
16
|
+
*
|
|
17
|
+
* ```tsx
|
|
18
|
+
* {process.env.NODE_ENV === "development" && <Clickly />}
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* Renders a small floating button (FAB) in the bottom-right corner.
|
|
22
|
+
* Click it (or press `⌘/Ctrl+Shift+F`) to open the full toolbar.
|
|
23
|
+
*/
|
|
24
|
+
export declare function Clickly({ className }?: ClicklyProps): import("react").ReactPortal | null;
|
|
25
|
+
//# sourceMappingURL=Clickly.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Clickly.d.ts","sourceRoot":"","sources":["../src/Clickly.tsx"],"names":[],"mappings":"AAYA,MAAM,WAAW,YAAY;IAC3B,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAChD;AASD;;;;;;;;;GASG;AACH,wBAAgB,OAAO,CAAC,EAAE,SAAS,EAAE,GAAE,YAAiB,sCA6EvD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface Position {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
}
|
|
5
|
+
interface DraggableApi {
|
|
6
|
+
position: Position;
|
|
7
|
+
setPosition: (p: Position) => void;
|
|
8
|
+
/** Spread onto the drag handle. */
|
|
9
|
+
handleProps: {
|
|
10
|
+
onPointerDown: (e: React.PointerEvent) => void;
|
|
11
|
+
style: React.CSSProperties;
|
|
12
|
+
};
|
|
13
|
+
isDragging: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* In-session drag positioning. Position resets to `defaultPos` whenever
|
|
17
|
+
* the consumer remounts (e.g. toolbar collapse → expand cycle).
|
|
18
|
+
*
|
|
19
|
+
* We deliberately do NOT persist across reloads — users expect the
|
|
20
|
+
* toolbar to come back at its default anchor, not where they last left
|
|
21
|
+
* it three sessions ago. Drag is for "get out of my way right now".
|
|
22
|
+
*/
|
|
23
|
+
export declare function useDraggable(defaultPos: Position, size: {
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
}): DraggableApi;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=useDraggable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDraggable.d.ts","sourceRoot":"","sources":["../../src/hooks/useDraggable.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,UAAU,YAAY;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,WAAW,EAAE,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC;IACnC,mCAAmC;IACnC,WAAW,EAAE;QACX,aAAa,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;QAC/C,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC;KAC5B,CAAC;IACF,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,QAAQ,EACpB,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACtC,YAAY,CAqDd"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `useState` + localStorage. Plain JSON-serializable values only.
|
|
3
|
+
* Safe under SSR (returns `initial` on first render).
|
|
4
|
+
*/
|
|
5
|
+
export declare function usePersistedState<T>(key: string, initial: T): [T, (next: T | ((prev: T) => T)) => void];
|
|
6
|
+
//# sourceMappingURL=usePersistedState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePersistedState.d.ts","sourceRoot":"","sources":["../../src/hooks/usePersistedState.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CAAC,GACT,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAqB3C"}
|