@mikuexe/annotator-react 0.1.0 → 0.2.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 24b4250: Show editable annotation popovers from collapsed pins and use icon-only delete controls.
8
+
9
+ ## 0.2.1
10
+
11
+ ### Patch Changes
12
+
13
+ - 41c21a6: Clarify README positioning, upstream credit, and support expectations.
14
+
15
+ ## 0.2.0
16
+
17
+ ### Minor Changes
18
+
19
+ - d9ab7b3: Add collection page context, multi-element annotations, and link-element follow-up selection for existing notes.
20
+ - 533db2a: Add same-origin iframe target support so parent review shells can annotate elements inside framed prototypes.
21
+
22
+ ## 0.1.2
23
+
24
+ ### Patch Changes
25
+
26
+ - cb4043a: Improve annotation mode interactions: block host pointer events while selecting, edit/delete saved annotations, preview pins on hover, and clear copied annotations after collect.
27
+
28
+ ## 0.1.1
29
+
30
+ ### Patch Changes
31
+
32
+ - be9d607: update naming around package
33
+
3
34
  ## 0.1.0 - Initial MVP
4
35
 
5
36
  ### Added
package/README.md CHANGED
@@ -2,6 +2,19 @@
2
2
 
3
3
  React devtool overlay for source-aware UI annotations. Select live DOM elements, write notes, then copy an agent-ready Markdown prompt.
4
4
 
5
+ ## Start here first
6
+
7
+ If you want a polished, supported tool in this space, look at these first:
8
+
9
+ - [react-grab](https://www.react-grab.com/)
10
+ - [Agentation](https://www.agentation.com/)
11
+
12
+ This package exists for my own local-agent UI workflow. It is intentionally small, experimental, and likely to change whenever my needs change.
13
+
14
+ Important credit: Aiden Bai created [react-grab](https://www.react-grab.com/) and [`element-source`](https://github.com/aidenybai/element-source), the source-resolution library this package builds on.
15
+
16
+ I made this repo because I wanted custom UI behavior on top of `element-source`. You are welcome to use it, but please treat it as personal tooling, not a supported product. I am not committing to issue triage, feature requests, roadmap stability, or compatibility guarantees. Requests are fine, but this package will continue to follow my own needs first.
17
+
5
18
  ## Install
6
19
 
7
20
  ```bash
@@ -16,7 +29,7 @@ npm install react react-dom
16
29
 
17
30
  ## Quick start
18
31
 
19
- `register` must be the first import in your app entry, before React loads.
32
+ `register` must load before React.
20
33
 
21
34
  ```tsx
22
35
  // src/main.tsx
@@ -34,10 +47,12 @@ createRoot(document.getElementById("root")!).render(
34
47
  );
35
48
  ```
36
49
 
37
- `SourceAnnotator` is a client component: render it only from browser/client React trees. In Next.js, place it behind a client boundary such as a file with `"use client"`.
50
+ `SourceAnnotator` is a client component: render it only from browser/client React trees.
38
51
 
39
52
  Click **Annotate**, select an element, write a note, then click **Collect**.
40
53
 
54
+ Desktop multi-select: while annotating, hold **Ctrl** (Windows/Linux) or **⌘ Cmd** (macOS) and click more elements to attach them to the same note. You can also use **Link element** on an existing annotation to attach one more element to that same comment.
55
+
41
56
  ## API
42
57
 
43
58
  ```ts
@@ -45,12 +60,35 @@ type SourceAnnotatorProps = {
45
60
  enabled?: boolean;
46
61
  hotkey?: string; // default: "alt+a"
47
62
  output?: "markdown" | "json" | "both"; // default: "markdown"
63
+ target?: Document | HTMLIFrameElement | null; // default: document
48
64
  onCollect?: (payload: AnnotationCollection) => void;
49
65
  renderToaster?: boolean; // default: true
50
66
  };
51
67
  ```
52
68
 
53
- `onCollect(payload)` fires after the clipboard write succeeds.
69
+ `onCollect(payload)` fires after the clipboard write succeeds. The payload includes collection-level page context as `page: { domain, path }`.
70
+
71
+ ### Annotating same-origin iframes
72
+
73
+ Pass a same-origin iframe element as `target` when the annotator UI lives in a parent shell but users need to select elements inside the framed app. The annotator listens inside the iframe document, captures the actual clicked element, and offsets highlights, pins, and popovers into the parent viewport.
74
+
75
+ ```tsx
76
+ import { useState } from "react";
77
+ import { SourceAnnotator } from "@mikuexe/annotator-react";
78
+
79
+ export function ReviewShell() {
80
+ const [iframe, setIframe] = useState<HTMLIFrameElement | null>(null);
81
+
82
+ return (
83
+ <>
84
+ <iframe ref={setIframe} src="/prototype/" />
85
+ <SourceAnnotator target={iframe} />
86
+ </>
87
+ );
88
+ }
89
+ ```
90
+
91
+ The iframe must be same-origin so the browser allows access to `iframe.contentDocument`. Cross-origin iframes cannot expose their internal DOM to the parent page.
54
92
 
55
93
  ### Sonner toaster ownership
56
94
 
@@ -83,6 +121,8 @@ Example copied Markdown:
83
121
  Please update the UI based on these source-linked annotations.
84
122
 
85
123
  Collected at: 2026-04-25T00:00:00.000Z
124
+ Domain: example.com
125
+ Path: /prototype
86
126
 
87
127
  ## Annotation 1
88
128
 
@@ -103,16 +143,16 @@ Selector: #root main.app-shell section.hero button.primary-cta:nth-of-type(1)
103
143
  ## Captured data
104
144
 
105
145
  ```ts
106
- type Annotation = {
107
- id: string;
108
- note: string;
109
- source: {
110
- filePath: string;
111
- lineNumber: number | null;
112
- columnNumber: number | null;
113
- componentName: string | null;
114
- } | null;
115
- sourceStack: Annotation["source"][];
146
+ type AnnotationSource = {
147
+ filePath: string;
148
+ lineNumber: number | null;
149
+ columnNumber: number | null;
150
+ componentName: string | null;
151
+ };
152
+
153
+ type AnnotationTarget = {
154
+ source: AnnotationSource | null;
155
+ sourceStack: AnnotationSource[];
116
156
  componentPath: string[];
117
157
  element: {
118
158
  tagName: string;
@@ -121,13 +161,28 @@ type Annotation = {
121
161
  selector: string;
122
162
  };
123
163
  };
164
+
165
+ type Annotation = {
166
+ id: string;
167
+ note: string;
168
+ targets: AnnotationTarget[];
169
+ };
170
+
171
+ type AnnotationCollection = {
172
+ createdAt: string;
173
+ page: {
174
+ domain: string;
175
+ path: string;
176
+ };
177
+ annotations: Annotation[];
178
+ };
124
179
  ```
125
180
 
126
181
  ## How source capture works
127
182
 
128
183
  `@mikuexe/annotator-react/register` installs the React DevTools hook through `bippy/install-hook-only`. `element-source` then uses React ownership data to resolve selected DOM elements back to React components/source.
129
184
 
130
- If source resolution fails, annotations still include DOM context: tag, HTML, text, selector, and any nearest React component/owner path that could be resolved.
185
+ If source resolution fails, annotations still include DOM context: tag, HTML, text, selector, and any nearest React component/owner path that could be resolved. Copied/exported payloads contain only serializable data and never internal DOM references.
131
186
 
132
187
  ## Local example
133
188
 
@@ -139,19 +194,6 @@ npm run dev
139
194
 
140
195
  The example app aliases linked source to one React copy in Vite to avoid duplicate-React invalid hook errors during local development.
141
196
 
142
- ## Package scripts
143
-
144
- ```bash
145
- npm run check # typecheck + unit tests + build
146
- npm run check:all # check + example build + npm pack dry-run
147
- npm run pack:dry-run # inspect npm package contents
148
- ```
149
-
150
- ## Publish support
151
-
152
- Package support links currently target `https://github.com/mikuexe/annotator-react`. Confirm `repository`, `homepage`, and `bugs` in `package.json` point at the final public repo before publishing.
153
-
154
-
155
197
  ## Current constraints
156
198
 
157
199
  - Vite-first support.