@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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/SourceAnnotator.tsx","../src/capture.ts","../src/clipboard.ts","../src/format.ts"],"sourcesContent":["export { SourceAnnotator } from \"./SourceAnnotator\";\nexport { copyTextToClipboard } from \"./clipboard\";\nexport { captureElementAnnotation, getElementSelector, trimText } from \"./capture\";\nexport { createAnnotationCollection, formatAnnotationCollection, formatMarkdown } from \"./format\";\nexport type {\n Annotation,\n AnnotationCollection,\n AnnotationElement,\n AnnotationSource,\n SourceAnnotatorOutput,\n SourceAnnotatorProps,\n} from \"./types\";\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { CSSProperties } from \"react\";\nimport { Toaster, toast } from \"sonner\";\nimport { captureElementAnnotation } from \"./capture\";\nimport { copyTextToClipboard } from \"./clipboard\";\nimport { createAnnotationCollection, formatAnnotationCollection } from \"./format\";\nimport type { Annotation, SourceAnnotatorOutput, SourceAnnotatorProps } from \"./types\";\n\ntype Rect = {\n top: number;\n left: number;\n width: number;\n height: number;\n};\n\ntype SelectedElement = {\n element: Element;\n rect: Rect;\n annotation: Annotation | null;\n loading: boolean;\n};\n\ntype StoredAnnotation = Annotation & {\n targetElement: Element;\n rect: Rect;\n};\n\nconst ROOT_ATTR = \"data-mikuexe-annotator-root\";\nconst DEFAULT_HOTKEY = \"alt+a\";\nconst DEFAULT_OUTPUT: SourceAnnotatorOutput = \"markdown\";\n\nexport function SourceAnnotator({\n enabled = true,\n hotkey = DEFAULT_HOTKEY,\n output = DEFAULT_OUTPUT,\n onCollect,\n renderToaster = true,\n}: SourceAnnotatorProps) {\n const [isAnnotating, setIsAnnotating] = useState(false);\n const [hoverRect, setHoverRect] = useState<Rect | null>(null);\n const [selected, setSelected] = useState<SelectedElement | null>(null);\n const [note, setNote] = useState(\"\");\n const [annotations, setAnnotations] = useState<StoredAnnotation[]>([]);\n const [status, setStatus] = useState<string | null>(null);\n const selectedRef = useRef<SelectedElement | null>(null);\n\n selectedRef.current = selected;\n\n const collection = useMemo(\n () => createAnnotationCollection(annotations.map(({ rect: _rect, targetElement: _targetElement, ...annotation }) => annotation)),\n [annotations],\n );\n\n const refreshTrackedRects = useCallback(() => {\n setHoverRect(null);\n setSelected((current) => (current ? { ...current, rect: getRect(current.element) } : current));\n setAnnotations((existing) => existing.map((annotation) => ({ ...annotation, rect: getRect(annotation.targetElement) })));\n }, []);\n\n useEffect(() => {\n if (!enabled) {\n setIsAnnotating(false);\n }\n }, [enabled]);\n\n useEffect(() => {\n const onKeyDown = (event: KeyboardEvent) => {\n if (!matchesHotkey(event, hotkey)) {\n return;\n }\n\n event.preventDefault();\n setIsAnnotating((current) => enabled && !current);\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [enabled, hotkey]);\n\n useEffect(() => {\n if (!enabled || !isAnnotating) {\n setHoverRect(null);\n return;\n }\n\n const onPointerOver = (event: PointerEvent) => {\n const target = getAnnotatableTarget(event.target);\n if (!target) {\n setHoverRect(null);\n return;\n }\n\n setHoverRect(getRect(target));\n };\n\n const onClick = (event: MouseEvent) => {\n const target = getAnnotatableTarget(event.target);\n if (!target) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n\n const rect = getRect(target);\n setSelected({ element: target, rect, annotation: null, loading: true });\n setNote(\"\");\n setStatus(\"Resolving source…\");\n\n captureElementAnnotation(target, \"\")\n .then((annotation) => {\n setSelected((current) => {\n if (current?.element !== target) {\n return current;\n }\n\n return { ...current, annotation, loading: false };\n });\n setStatus(annotation.source ? \"Source captured.\" : \"Element captured without source info.\");\n })\n .catch(() => {\n setSelected((current) => (current?.element === target ? { ...current, loading: false } : current));\n setStatus(\"Element captured without source info.\");\n });\n };\n\n document.addEventListener(\"pointerover\", onPointerOver, true);\n document.addEventListener(\"click\", onClick, true);\n\n return () => {\n document.removeEventListener(\"pointerover\", onPointerOver, true);\n document.removeEventListener(\"click\", onClick, true);\n };\n }, [enabled, isAnnotating]);\n\n useEffect(() => {\n if (!enabled || !isAnnotating) {\n return;\n }\n\n document.addEventListener(\"scroll\", refreshTrackedRects, true);\n window.addEventListener(\"resize\", refreshTrackedRects);\n\n return () => {\n document.removeEventListener(\"scroll\", refreshTrackedRects, true);\n window.removeEventListener(\"resize\", refreshTrackedRects);\n };\n }, [enabled, isAnnotating, refreshTrackedRects]);\n\n const addAnnotation = useCallback(async () => {\n const current = selectedRef.current;\n if (!current || current.loading) {\n return;\n }\n\n const trimmedNote = note.trim();\n if (!trimmedNote) {\n setStatus(\"Add a note before saving this annotation.\");\n return;\n }\n\n const annotation = current.annotation\n ? { ...current.annotation, note: trimmedNote }\n : await captureElementAnnotation(current.element, trimmedNote);\n\n setAnnotations((existing) => [...existing, { ...annotation, targetElement: current.element, rect: getRect(current.element) }]);\n setSelected(null);\n setNote(\"\");\n setStatus(\"Annotation saved.\");\n }, [note]);\n\n const collect = useCallback(async () => {\n const payload = createAnnotationCollection(annotations.map(({ rect: _rect, targetElement: _targetElement, ...annotation }) => annotation));\n const text = formatAnnotationCollection(payload, output);\n\n try {\n await copyTextToClipboard(text);\n onCollect?.(payload);\n setIsAnnotating(false);\n setSelected(null);\n setHoverRect(null);\n setNote(\"\");\n toast.success(\"Annotations copied\", { description: `${payload.annotations.length} copied to clipboard.` });\n setStatus(`Copied ${payload.annotations.length} annotation${payload.annotations.length === 1 ? \"\" : \"s\"}.`);\n } catch (error) {\n toast.error(\"Copy failed\", { description: error instanceof Error ? error.message : \"Clipboard copy failed.\" });\n setStatus(error instanceof Error ? error.message : \"Clipboard copy failed.\");\n }\n }, [annotations, onCollect, output]);\n\n if (!enabled) {\n return null;\n }\n\n return (\n <div {...{ [ROOT_ATTR]: \"\" }} style={styles.root} aria-live=\"polite\">\n {renderToaster ? <Toaster position=\"bottom-right\" richColors /> : null}\n <button\n type=\"button\"\n onClick={() => setIsAnnotating((current) => !current)}\n style={{ ...styles.floatingButton, ...(isAnnotating ? styles.floatingButtonActive : null) }}\n aria-pressed={isAnnotating}\n title={`Toggle annotator (${hotkey})`}\n >\n {isAnnotating ? \"Annotating\" : \"Annotate\"}\n </button>\n\n {isAnnotating && hoverRect ? <Box rect={hoverRect} kind=\"hover\" /> : null}\n {selected ? <Box rect={selected.rect} kind=\"selected\" /> : null}\n {isAnnotating\n ? annotations.map((annotation, index) => (\n <Pin key={annotation.id} annotation={annotation} index={index} />\n ))\n : null}\n\n {selected ? (\n <div style={getPopoverStyle(selected.rect)} role=\"dialog\" aria-label=\"Add source annotation\">\n <div style={styles.popoverTitle}>Annotation</div>\n <div style={styles.metaText}>{selected.loading ? \"Resolving source…\" : formatSelectedSource(selected.annotation)}</div>\n <textarea\n value={note}\n onChange={(event) => setNote(event.target.value)}\n placeholder=\"What should change here?\"\n style={styles.textarea}\n rows={4}\n autoFocus\n />\n <div style={styles.popoverActions}>\n <button type=\"button\" onClick={() => setSelected(null)} style={styles.secondaryButton}>\n Cancel\n </button>\n <button type=\"button\" onClick={addAnnotation} style={styles.primaryButton} disabled={selected.loading}>\n Save note\n </button>\n </div>\n </div>\n ) : null}\n\n {isAnnotating ? (\n <section style={styles.panel} aria-label=\"Collected annotations\">\n <div style={styles.panelHeader}>\n <strong>Annotations</strong>\n <span style={styles.badge}>{collection.annotations.length}</span>\n </div>\n {annotations.length ? (\n <ol style={styles.annotationList}>\n {annotations.map((annotation) => (\n <li key={annotation.id} style={styles.annotationItem}>\n <div style={styles.noteText}>{annotation.note}</div>\n <div style={styles.metaText}>{formatSelectedSource(annotation)}</div>\n </li>\n ))}\n </ol>\n ) : (\n <p style={styles.emptyText}>Hover an element, click it, then add a note.</p>\n )}\n <button type=\"button\" onClick={collect} style={styles.collectButton} disabled={!annotations.length}>\n Collect\n </button>\n {status ? <div style={styles.status}>{status}</div> : null}\n </section>\n ) : null}\n </div>\n );\n}\n\nfunction Box({ rect, kind }: { rect: Rect; kind: \"hover\" | \"selected\" }) {\n return (\n <div\n style={{\n ...styles.box,\n ...(kind === \"selected\" ? styles.selectedBox : styles.hoverBox),\n top: rect.top,\n left: rect.left,\n width: rect.width,\n height: rect.height,\n }}\n />\n );\n}\n\nfunction Pin({ annotation, index }: { annotation: StoredAnnotation; index: number }) {\n return (\n <div\n style={{ ...styles.pin, top: Math.max(8, annotation.rect.top - 10), left: Math.max(8, annotation.rect.left - 10) }}\n title={annotation.note}\n >\n {index + 1}\n </div>\n );\n}\n\nfunction getAnnotatableTarget(target: EventTarget | null): Element | null {\n if (!(target instanceof Element)) {\n return null;\n }\n\n if (target.closest(`[${ROOT_ATTR}]`)) {\n return null;\n }\n\n if (target === document.body || target === document.documentElement) {\n return null;\n }\n\n return target;\n}\n\nfunction getRect(element: Element): Rect {\n const rect = element.getBoundingClientRect();\n return {\n top: rect.top,\n left: rect.left,\n width: rect.width,\n height: rect.height,\n };\n}\n\nfunction getPopoverStyle(rect: Rect): CSSProperties {\n const top = Math.min(window.innerHeight - 260, rect.top + rect.height + 8);\n const left = Math.min(window.innerWidth - 340, Math.max(8, rect.left));\n\n return {\n ...styles.popover,\n top: Math.max(8, top),\n left,\n };\n}\n\nfunction formatSelectedSource(annotation: Annotation | null): string {\n const componentPath = annotation?.componentPath.length ? annotation.componentPath.join(\" › \") : null;\n\n if (!annotation) {\n return \"Source unavailable\";\n }\n\n if (!annotation.source?.filePath) {\n return `${annotation.element.selector} · source unavailable`;\n }\n\n const line = annotation.source.lineNumber ? `:${annotation.source.lineNumber}` : \"\";\n const component = componentPath ? ` · ${componentPath}` : \"\";\n return `${annotation.source.filePath}${line}${component}`;\n}\n\nfunction matchesHotkey(event: KeyboardEvent, hotkey: string): boolean {\n const parts = hotkey.toLowerCase().split(\"+\").map((part) => part.trim()).filter(Boolean);\n const key = parts.find((part) => ![\"ctrl\", \"control\", \"cmd\", \"meta\", \"mod\", \"shift\", \"alt\", \"option\"].includes(part));\n\n const wantsMeta = parts.includes(\"meta\") || parts.includes(\"cmd\") || (parts.includes(\"mod\") && isMac());\n const wantsCtrl = parts.includes(\"ctrl\") || parts.includes(\"control\") || (parts.includes(\"mod\") && !isMac());\n const wantsShift = parts.includes(\"shift\");\n const wantsAlt = parts.includes(\"alt\") || parts.includes(\"option\");\n\n return (\n event.key.toLowerCase() === key &&\n event.metaKey === wantsMeta &&\n event.ctrlKey === wantsCtrl &&\n event.shiftKey === wantsShift &&\n event.altKey === wantsAlt\n );\n}\n\nfunction isMac(): boolean {\n return typeof navigator !== \"undefined\" && /mac|iphone|ipad|ipod/i.test(navigator.platform);\n}\n\nconst baseFont = '13px/1.35 -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif';\n\nconst styles = {\n root: {\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n pointerEvents: \"none\",\n font: baseFont,\n color: \"#0f172a\",\n } satisfies CSSProperties,\n floatingButton: {\n position: \"fixed\",\n right: 16,\n bottom: 16,\n pointerEvents: \"auto\",\n borderWidth: 1,\n borderStyle: \"solid\",\n borderColor: \"#cbd5e1\",\n background: \"#ffffff\",\n color: \"#0f172a\",\n borderRadius: 999,\n padding: \"10px 14px\",\n font: baseFont,\n fontWeight: 700,\n boxShadow: \"0 10px 25px rgba(15, 23, 42, 0.16)\",\n cursor: \"pointer\",\n } satisfies CSSProperties,\n floatingButtonActive: {\n background: \"#0f172a\",\n color: \"#ffffff\",\n borderColor: \"#0f172a\",\n } satisfies CSSProperties,\n box: {\n position: \"fixed\",\n borderRadius: 6,\n pointerEvents: \"none\",\n boxSizing: \"border-box\",\n } satisfies CSSProperties,\n hoverBox: {\n border: \"2px solid #38bdf8\",\n background: \"rgba(56, 189, 248, 0.08)\",\n } satisfies CSSProperties,\n selectedBox: {\n border: \"2px solid #f97316\",\n background: \"rgba(249, 115, 22, 0.1)\",\n } satisfies CSSProperties,\n popover: {\n position: \"fixed\",\n width: 320,\n pointerEvents: \"auto\",\n background: \"#ffffff\",\n border: \"1px solid #cbd5e1\",\n borderRadius: 12,\n padding: 12,\n boxShadow: \"0 18px 45px rgba(15, 23, 42, 0.22)\",\n } satisfies CSSProperties,\n popoverTitle: {\n fontWeight: 800,\n marginBottom: 4,\n } satisfies CSSProperties,\n metaText: {\n color: \"#64748b\",\n fontSize: 12,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n } satisfies CSSProperties,\n textarea: {\n width: \"100%\",\n boxSizing: \"border-box\",\n marginTop: 10,\n border: \"1px solid #cbd5e1\",\n borderRadius: 8,\n padding: 10,\n resize: \"vertical\",\n font: baseFont,\n } satisfies CSSProperties,\n popoverActions: {\n display: \"flex\",\n justifyContent: \"flex-end\",\n gap: 8,\n marginTop: 10,\n } satisfies CSSProperties,\n secondaryButton: {\n border: \"1px solid #cbd5e1\",\n borderRadius: 8,\n background: \"#ffffff\",\n padding: \"7px 10px\",\n cursor: \"pointer\",\n } satisfies CSSProperties,\n primaryButton: {\n border: \"1px solid #0f172a\",\n borderRadius: 8,\n background: \"#0f172a\",\n color: \"#ffffff\",\n padding: \"7px 10px\",\n cursor: \"pointer\",\n } satisfies CSSProperties,\n panel: {\n position: \"fixed\",\n right: 16,\n bottom: 68,\n width: 300,\n pointerEvents: \"auto\",\n background: \"#ffffff\",\n border: \"1px solid #cbd5e1\",\n borderRadius: 12,\n padding: 12,\n boxShadow: \"0 18px 45px rgba(15, 23, 42, 0.18)\",\n } satisfies CSSProperties,\n panelHeader: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: 8,\n } satisfies CSSProperties,\n badge: {\n minWidth: 20,\n height: 20,\n borderRadius: 999,\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"#e2e8f0\",\n color: \"#334155\",\n fontWeight: 700,\n fontSize: 12,\n } satisfies CSSProperties,\n annotationList: {\n listStyle: \"decimal\",\n margin: \"0 0 10px 18px\",\n padding: 0,\n maxHeight: 180,\n overflow: \"auto\",\n } satisfies CSSProperties,\n annotationItem: {\n marginBottom: 8,\n } satisfies CSSProperties,\n noteText: {\n color: \"#0f172a\",\n fontWeight: 650,\n } satisfies CSSProperties,\n emptyText: {\n color: \"#64748b\",\n margin: \"6px 0 10px\",\n } satisfies CSSProperties,\n collectButton: {\n width: \"100%\",\n border: \"1px solid #0f172a\",\n borderRadius: 8,\n background: \"#0f172a\",\n color: \"#ffffff\",\n padding: \"9px 10px\",\n fontWeight: 800,\n cursor: \"pointer\",\n } satisfies CSSProperties,\n status: {\n marginTop: 8,\n color: \"#475569\",\n fontSize: 12,\n } satisfies CSSProperties,\n pin: {\n position: \"fixed\",\n width: 20,\n height: 20,\n borderRadius: 999,\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"none\",\n background: \"#f97316\",\n color: \"#ffffff\",\n fontSize: 12,\n fontWeight: 800,\n boxShadow: \"0 8px 18px rgba(15, 23, 42, 0.2)\",\n } satisfies CSSProperties,\n};\n","import { resolveElementInfo } from \"element-source\";\nimport type { Annotation, AnnotationSource } from \"./types\";\n\nconst MAX_TEXT_LENGTH = 240;\nconst MAX_HTML_LENGTH = 640;\nconst MAX_SELECTOR_DEPTH = 6;\n\nexport async function captureElementAnnotation(\n element: Element,\n note: string,\n id = createAnnotationId(),\n): Promise<Annotation> {\n const elementInfo = await safeResolveElementInfo(element);\n const source = normalizeSource(elementInfo?.source, elementInfo?.componentName);\n const sourceStack = normalizeSourceStack(elementInfo?.stack, source);\n const componentPath = getComponentPath(sourceStack, source);\n\n return {\n id,\n note,\n source,\n sourceStack,\n componentPath,\n element: {\n tagName: element.tagName.toLowerCase(),\n text: trimText(element.textContent ?? \"\", MAX_TEXT_LENGTH),\n html: trimText(getOuterHtml(element), MAX_HTML_LENGTH),\n selector: getElementSelector(element),\n },\n };\n}\n\nexport function createAnnotationId(): string {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n return crypto.randomUUID();\n }\n\n return `annotation-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nexport function getElementSelector(element: Element): string {\n const parts: string[] = [];\n let current: Element | null = element;\n\n while (current && current.nodeType === Node.ELEMENT_NODE && parts.length < MAX_SELECTOR_DEPTH) {\n parts.unshift(getSelectorPart(current));\n\n if (current.id) {\n break;\n }\n\n current = current.parentElement;\n if (current?.tagName.toLowerCase() === \"html\") {\n break;\n }\n }\n\n return parts.join(\" \");\n}\n\nexport function trimText(value: string, maxLength: number): string {\n const normalized = value.replace(/\\s+/g, \" \").trim();\n\n if (normalized.length <= maxLength) {\n return normalized;\n }\n\n return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;\n}\n\nasync function safeResolveElementInfo(element: Element) {\n try {\n return await resolveElementInfo(element);\n } catch {\n return null;\n }\n}\n\nfunction normalizeSource(\n source: AnnotationSource | null | undefined,\n componentName: string | null | undefined,\n): AnnotationSource | null {\n if (!source) {\n return componentName\n ? { filePath: \"\", lineNumber: null, columnNumber: null, componentName }\n : null;\n }\n\n return {\n filePath: source.filePath,\n lineNumber: source.lineNumber ?? null,\n columnNumber: source.columnNumber ?? null,\n componentName: source.componentName ?? componentName ?? null,\n };\n}\n\nfunction normalizeSourceStack(\n stack: AnnotationSource[] | null | undefined,\n source: AnnotationSource | null,\n): AnnotationSource[] {\n const normalizedStack = (stack ?? []).map((frame) => ({\n filePath: frame.filePath,\n lineNumber: frame.lineNumber ?? null,\n columnNumber: frame.columnNumber ?? null,\n componentName: frame.componentName ?? null,\n }));\n\n if (source && !normalizedStack.some((frame) => isSameSourceFrame(frame, source))) {\n normalizedStack.unshift(source);\n }\n\n return normalizedStack;\n}\n\nfunction getComponentPath(stack: AnnotationSource[], source: AnnotationSource | null): string[] {\n const names = stack.map((frame) => frame.componentName).filter((name): name is string => Boolean(name));\n return Array.from(new Set(names.length ? names : source?.componentName ? [source.componentName] : []));\n}\n\nfunction isSameSourceFrame(a: AnnotationSource, b: AnnotationSource): boolean {\n return a.filePath === b.filePath && a.lineNumber === b.lineNumber && a.columnNumber === b.columnNumber;\n}\n\nfunction getOuterHtml(element: Element): string {\n if (\"outerHTML\" in element && typeof element.outerHTML === \"string\") {\n return element.outerHTML;\n }\n\n return `<${element.tagName.toLowerCase()}>`;\n}\n\nfunction getSelectorPart(element: Element): string {\n const tagName = element.tagName.toLowerCase();\n\n if (element.id) {\n return `#${escapeIdentifier(element.id)}`;\n }\n\n const testId = element.getAttribute(\"data-testid\");\n if (testId) {\n return `${tagName}[data-testid=\"${escapeAttribute(testId)}\"]`;\n }\n\n const classes = Array.from(element.classList)\n .filter(Boolean)\n .slice(0, 2)\n .map((className) => `.${escapeIdentifier(className)}`)\n .join(\"\");\n\n const siblingIndex = getNthOfType(element);\n const needsNth = siblingIndex > 1 || hasFollowingSiblingOfSameType(element);\n\n return `${tagName}${classes}${needsNth ? `:nth-of-type(${siblingIndex})` : \"\"}`;\n}\n\nfunction getNthOfType(element: Element): number {\n let index = 1;\n let sibling = element.previousElementSibling;\n\n while (sibling) {\n if (sibling.tagName === element.tagName) {\n index += 1;\n }\n sibling = sibling.previousElementSibling;\n }\n\n return index;\n}\n\nfunction hasFollowingSiblingOfSameType(element: Element): boolean {\n let sibling = element.nextElementSibling;\n\n while (sibling) {\n if (sibling.tagName === element.tagName) {\n return true;\n }\n sibling = sibling.nextElementSibling;\n }\n\n return false;\n}\n\nfunction escapeIdentifier(value: string): string {\n if (typeof CSS !== \"undefined\" && typeof CSS.escape === \"function\") {\n return CSS.escape(value);\n }\n\n return value.replace(/[^a-zA-Z0-9_-]/g, \"\\\\$&\");\n}\n\nfunction escapeAttribute(value: string): string {\n return value.replace(/\"/g, \"\\\\\\\"\");\n}\n","export async function copyTextToClipboard(text: string): Promise<void> {\n if (typeof navigator !== \"undefined\" && navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n return;\n }\n\n if (typeof document === \"undefined\") {\n throw new Error(\"Clipboard is not available outside a browser environment.\");\n }\n\n const textarea = document.createElement(\"textarea\");\n textarea.value = text;\n textarea.setAttribute(\"readonly\", \"\");\n textarea.style.position = \"fixed\";\n textarea.style.left = \"-9999px\";\n textarea.style.top = \"0\";\n document.body.appendChild(textarea);\n textarea.select();\n\n const copied = document.execCommand(\"copy\");\n textarea.remove();\n\n if (!copied) {\n throw new Error(\"Clipboard copy failed.\");\n }\n}\n","import type { Annotation, AnnotationCollection, SourceAnnotatorOutput } from \"./types\";\n\nconst TASK_FRAMING = \"Please update the UI based on these source-linked annotations.\";\n\nexport function createAnnotationCollection(annotations: Annotation[]): AnnotationCollection {\n return {\n annotations,\n createdAt: new Date().toISOString(),\n };\n}\n\nexport function formatAnnotationCollection(\n collection: AnnotationCollection,\n output: SourceAnnotatorOutput = \"markdown\",\n): string {\n if (output === \"json\") {\n return formatJson(collection);\n }\n\n const markdown = formatMarkdown(collection);\n\n if (output === \"markdown\") {\n return markdown;\n }\n\n return `${markdown}\\n\\n## JSON Payload\\n\\n\\`\\`\\`json\\n${formatJson(collection)}\\n\\`\\`\\``;\n}\n\nexport function formatMarkdown(collection: AnnotationCollection): string {\n const lines = [TASK_FRAMING, \"\", `Collected at: ${collection.createdAt}`, \"\"];\n\n if (collection.annotations.length === 0) {\n lines.push(\"No annotations were collected.\");\n return lines.join(\"\\n\");\n }\n\n collection.annotations.forEach((annotation, index) => {\n const source = formatSource(annotation);\n const sourceStack = formatSourceStack(annotation);\n const nearestComponent = annotation.source?.componentName;\n const ownerPath = annotation.componentPath.join(\" › \");\n\n lines.push(`## Annotation ${index + 1}`);\n lines.push(\"\");\n lines.push(`ID: ${annotation.id}`);\n lines.push(`Note: ${annotation.note || \"(no note provided)\"}`);\n\n if (source) {\n lines.push(`Source: ${source}`);\n }\n\n if (nearestComponent) {\n lines.push(`Nearest React component: ${nearestComponent}`);\n }\n\n if (ownerPath && ownerPath !== nearestComponent) {\n lines.push(`React owner path: ${ownerPath}`);\n }\n\n if (sourceStack.length) {\n lines.push(\"React source stack:\");\n sourceStack.forEach((frame) => lines.push(`- ${frame}`));\n }\n\n lines.push(`Element tag: ${annotation.element.tagName}`);\n\n if (annotation.element.html) {\n lines.push(`Element HTML: ${annotation.element.html}`);\n }\n\n if (annotation.element.text) {\n lines.push(`Element text: ${annotation.element.text}`);\n }\n\n if (annotation.element.selector) {\n lines.push(`Selector: ${annotation.element.selector}`);\n }\n\n lines.push(\"\");\n });\n\n return lines.join(\"\\n\").trimEnd();\n}\n\nfunction formatJson(collection: AnnotationCollection): string {\n return JSON.stringify(collection, null, 2);\n}\n\nfunction formatSource(annotation: Annotation): string {\n const source = annotation.source;\n\n if (!source?.filePath) {\n return \"\";\n }\n\n const line = source.lineNumber ? `:${source.lineNumber}` : \"\";\n const column = source.columnNumber ? `:${source.columnNumber}` : \"\";\n\n return `${source.filePath}${line}${column}`;\n}\n\nfunction formatSourceStack(annotation: Annotation): string[] {\n return annotation.sourceStack\n .map((frame) => {\n const location = formatSourceFrame(frame);\n const component = frame.componentName ? ` (${frame.componentName})` : \"\";\n\n return location ? `${location}${component}` : frame.componentName || \"\";\n })\n .filter(Boolean);\n}\n\nfunction formatSourceFrame(frame: Annotation[\"sourceStack\"][number]): string {\n if (!frame.filePath) {\n return \"\";\n }\n\n const line = frame.lineNumber ? `:${frame.lineNumber}` : \"\";\n const column = frame.columnNumber ? `:${frame.columnNumber}` : \"\";\n\n return `${frame.filePath}${line}${column}`;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/SourceAnnotator.tsx","../src/capture.ts","../src/clipboard.ts","../src/format.ts"],"sourcesContent":["export { SourceAnnotator } from \"./SourceAnnotator\";\nexport { copyTextToClipboard } from \"./clipboard\";\nexport { captureAnnotationTarget, captureElementAnnotation, getElementSelector, trimText } from \"./capture\";\nexport { createAnnotationCollection, formatAnnotationCollection, formatMarkdown, getPageContext } from \"./format\";\nexport type {\n Annotation,\n AnnotationCollection,\n AnnotationElement,\n AnnotationSource,\n AnnotationTarget,\n PageContext,\n SourceAnnotatorOutput,\n SourceAnnotatorProps,\n SourceAnnotatorTarget,\n} from \"./types\";\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { CSSProperties } from \"react\";\nimport { Toaster, toast } from \"sonner\";\nimport { captureAnnotationTarget, captureElementAnnotation, createAnnotationId } from \"./capture\";\nimport { copyTextToClipboard } from \"./clipboard\";\nimport { createAnnotationCollection, formatAnnotationCollection, getPageContext } from \"./format\";\nimport type {\n Annotation,\n AnnotationTarget,\n SourceAnnotatorOutput,\n SourceAnnotatorProps,\n SourceAnnotatorTarget,\n} from \"./types\";\n\ntype Rect = {\n top: number;\n left: number;\n width: number;\n height: number;\n};\n\ntype DraftTarget = {\n element: Element;\n rect: Rect;\n frameElement: HTMLIFrameElement | null;\n target: AnnotationTarget | null;\n loading: boolean;\n};\n\ntype DraftSelection = {\n targets: DraftTarget[];\n editingId?: string;\n};\n\ntype StoredTarget = {\n targetElement: Element;\n rect: Rect;\n frameElement: HTMLIFrameElement | null;\n data: AnnotationTarget;\n};\n\ntype StoredAnnotation = {\n id: string;\n note: string;\n targets: StoredTarget[];\n};\n\ntype ResolvedTarget = {\n document: Document | null;\n frameElement: HTMLIFrameElement | null;\n};\n\nconst ROOT_ATTR = \"data-mikuexe-annotator-root\";\nconst DEFAULT_HOTKEY = \"alt+a\";\nconst DEFAULT_OUTPUT: SourceAnnotatorOutput = \"markdown\";\nconst BLOCKED_INTERACTION_EVENTS = [\n \"pointerdown\",\n \"pointerup\",\n \"mousedown\",\n \"mouseup\",\n \"dblclick\",\n \"auxclick\",\n \"contextmenu\",\n \"touchstart\",\n \"touchend\",\n] as const;\n\nexport function SourceAnnotator({\n enabled = true,\n hotkey = DEFAULT_HOTKEY,\n output = DEFAULT_OUTPUT,\n target,\n onCollect,\n renderToaster = true,\n}: SourceAnnotatorProps) {\n const [isAnnotating, setIsAnnotating] = useState(false);\n const [hoverRect, setHoverRect] = useState<Rect | null>(null);\n const [selected, setSelected] = useState<DraftSelection | null>(null);\n const [note, setNote] = useState(\"\");\n const [annotations, setAnnotations] = useState<StoredAnnotation[]>([]);\n const [previewedAnnotation, setPreviewedAnnotation] = useState<StoredAnnotation | null>(null);\n const [status, setStatus] = useState<string | null>(null);\n const [linkingAnnotationId, setLinkingAnnotationId] = useState<string | null>(null);\n const selectedRef = useRef<DraftSelection | null>(null);\n\n const resolvedTarget = useResolvedTarget(target);\n\n selectedRef.current = selected;\n\n useEffect(() => {\n setHoverRect(null);\n setSelected(null);\n setAnnotations([]);\n setPreviewedAnnotation(null);\n setNote(\"\");\n setStatus(null);\n setLinkingAnnotationId(null);\n }, [resolvedTarget.document, resolvedTarget.frameElement]);\n\n const refreshTrackedRects = useCallback(() => {\n setHoverRect(null);\n setSelected((current) =>\n current\n ? {\n ...current,\n targets: current.targets.map((targetEntry) => ({\n ...targetEntry,\n rect: getRect(targetEntry.element, targetEntry.frameElement),\n })),\n }\n : current,\n );\n setAnnotations((existing) =>\n existing.map((annotation) => ({\n ...annotation,\n targets: annotation.targets.map((targetEntry) => ({\n ...targetEntry,\n rect: getRect(targetEntry.targetElement, targetEntry.frameElement),\n })),\n })),\n );\n }, []);\n\n useEffect(() => {\n if (!enabled) {\n setIsAnnotating(false);\n }\n }, [enabled]);\n\n useEffect(() => {\n const onKeyDown = (event: KeyboardEvent) => {\n if (!matchesHotkey(event, hotkey)) {\n return;\n }\n\n event.preventDefault();\n setIsAnnotating((current) => enabled && !current);\n };\n\n if (typeof document === \"undefined\") {\n return;\n }\n\n document.addEventListener(\"keydown\", onKeyDown);\n if (resolvedTarget.document && resolvedTarget.document !== document) {\n resolvedTarget.document.addEventListener(\"keydown\", onKeyDown);\n }\n\n return () => {\n document.removeEventListener(\"keydown\", onKeyDown);\n if (resolvedTarget.document && resolvedTarget.document !== document) {\n resolvedTarget.document.removeEventListener(\"keydown\", onKeyDown);\n }\n };\n }, [enabled, hotkey, resolvedTarget.document]);\n\n const handleElementSelection = useCallback(\n async (eventTarget: Element, frameElement: HTMLIFrameElement | null, extendSelection: boolean) => {\n if (linkingAnnotationId) {\n const rect = getRect(eventTarget, frameElement);\n setStatus(\"Resolving linked element…\");\n\n try {\n const targetData = await captureAnnotationTarget(eventTarget);\n setAnnotations((existing) =>\n existing.map((annotation) => {\n if (annotation.id !== linkingAnnotationId) {\n return annotation;\n }\n\n if (annotation.targets.some((targetEntry) => targetEntry.targetElement === eventTarget)) {\n return annotation;\n }\n\n return {\n ...annotation,\n targets: [\n ...annotation.targets,\n {\n targetElement: eventTarget,\n rect,\n frameElement,\n data: targetData,\n },\n ],\n };\n }),\n );\n setLinkingAnnotationId(null);\n setPreviewedAnnotation(null);\n setStatus(\"Element linked to annotation.\");\n } catch {\n setStatus(\"Element linked without source info.\");\n setAnnotations((existing) =>\n existing.map((annotation) => {\n if (annotation.id !== linkingAnnotationId) {\n return annotation;\n }\n\n if (annotation.targets.some((targetEntry) => targetEntry.targetElement === eventTarget)) {\n return annotation;\n }\n\n return {\n ...annotation,\n targets: [\n ...annotation.targets,\n {\n targetElement: eventTarget,\n rect,\n frameElement,\n data: {\n source: null,\n sourceStack: [],\n componentPath: [],\n element: {\n tagName: eventTarget.tagName.toLowerCase(),\n text: eventTarget.textContent?.trim() ?? \"\",\n html: \"\",\n selector: \"\",\n },\n },\n },\n ],\n };\n }),\n );\n setLinkingAnnotationId(null);\n }\n\n return;\n }\n\n const rect = getRect(eventTarget, frameElement);\n const shouldAppend = extendSelection && Boolean(selectedRef.current) && !selectedRef.current?.editingId;\n setSelected((current) => {\n if (shouldAppend && current) {\n if (current.targets.some((targetEntry) => targetEntry.element === eventTarget)) {\n return current;\n }\n\n return {\n ...current,\n targets: [...current.targets, { element: eventTarget, rect, frameElement, target: null, loading: true }],\n };\n }\n\n return {\n targets: [{ element: eventTarget, rect, frameElement, target: null, loading: true }],\n };\n });\n\n if (!shouldAppend) {\n setNote(\"\");\n }\n setStatus(\"Resolving source…\");\n\n try {\n const targetData = await captureAnnotationTarget(eventTarget);\n setSelected((current) => {\n if (!current) {\n return current;\n }\n\n return {\n ...current,\n targets: current.targets.map((targetEntry) =>\n targetEntry.element === eventTarget ? { ...targetEntry, target: targetData, loading: false } : targetEntry,\n ),\n };\n });\n setStatus(targetData.source ? \"Source captured.\" : \"Element captured without source info.\");\n } catch {\n setSelected((current) => {\n if (!current) {\n return current;\n }\n\n return {\n ...current,\n targets: current.targets.map((targetEntry) =>\n targetEntry.element === eventTarget ? { ...targetEntry, loading: false } : targetEntry,\n ),\n };\n });\n setStatus(\"Element captured without source info.\");\n }\n },\n [linkingAnnotationId],\n );\n\n useEffect(() => {\n if (!enabled || !isAnnotating || !resolvedTarget.document) {\n setHoverRect(null);\n return;\n }\n\n const activeDocument = resolvedTarget.document;\n\n const onPointerOver = (event: PointerEvent) => {\n const eventTarget = getAnnotatableTarget(event.target, activeDocument);\n if (!eventTarget) {\n setHoverRect(null);\n return;\n }\n\n setHoverRect(getRect(eventTarget, resolvedTarget.frameElement));\n };\n\n const suppressInteraction = (event: Event) => {\n const eventTarget = getAnnotatableTarget(event.target, activeDocument);\n if (!eventTarget) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n };\n\n const onClick = (event: MouseEvent) => {\n const eventTarget = getAnnotatableTarget(event.target, activeDocument);\n if (!eventTarget) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n\n void handleElementSelection(eventTarget, resolvedTarget.frameElement, shouldExtendSelection(event));\n };\n\n const onFramePointerLeave = () => {\n setHoverRect(null);\n };\n\n activeDocument.addEventListener(\"pointerover\", onPointerOver, true);\n activeDocument.addEventListener(\"click\", onClick, true);\n BLOCKED_INTERACTION_EVENTS.forEach((eventName) => activeDocument.addEventListener(eventName, suppressInteraction, true));\n resolvedTarget.frameElement?.addEventListener(\"pointerleave\", onFramePointerLeave);\n\n return () => {\n activeDocument.removeEventListener(\"pointerover\", onPointerOver, true);\n activeDocument.removeEventListener(\"click\", onClick, true);\n BLOCKED_INTERACTION_EVENTS.forEach((eventName) => activeDocument.removeEventListener(eventName, suppressInteraction, true));\n resolvedTarget.frameElement?.removeEventListener(\"pointerleave\", onFramePointerLeave);\n };\n }, [enabled, handleElementSelection, isAnnotating, resolvedTarget]);\n\n useEffect(() => {\n if (!enabled || !isAnnotating || !resolvedTarget.document) {\n return;\n }\n\n const activeDocument = resolvedTarget.document;\n\n activeDocument.addEventListener(\"scroll\", refreshTrackedRects, true);\n if (typeof document !== \"undefined\" && activeDocument !== document) {\n document.addEventListener(\"scroll\", refreshTrackedRects, true);\n }\n window.addEventListener(\"resize\", refreshTrackedRects);\n\n return () => {\n activeDocument.removeEventListener(\"scroll\", refreshTrackedRects, true);\n if (typeof document !== \"undefined\" && activeDocument !== document) {\n document.removeEventListener(\"scroll\", refreshTrackedRects, true);\n }\n window.removeEventListener(\"resize\", refreshTrackedRects);\n };\n }, [enabled, isAnnotating, refreshTrackedRects, resolvedTarget.document]);\n useEffect(() => {\n if (!previewedAnnotation) {\n return;\n }\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n setPreviewedAnnotation(null);\n }\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n if (resolvedTarget.document && resolvedTarget.document !== document) {\n resolvedTarget.document.addEventListener(\"keydown\", onKeyDown);\n }\n\n return () => {\n document.removeEventListener(\"keydown\", onKeyDown);\n if (resolvedTarget.document && resolvedTarget.document !== document) {\n resolvedTarget.document.removeEventListener(\"keydown\", onKeyDown);\n }\n };\n }, [previewedAnnotation, resolvedTarget.document]);\n\n const addAnnotation = useCallback(async () => {\n const current = selectedRef.current;\n if (!current || current.targets.some((targetEntry) => targetEntry.loading)) {\n return;\n }\n\n const trimmedNote = note.trim();\n if (!trimmedNote) {\n setStatus(\"Add a note before saving this annotation.\");\n return;\n }\n\n const currentTargets = await Promise.all(\n current.targets.map(async (targetEntry) => {\n if (targetEntry.target) {\n return targetEntry;\n }\n\n const annotation = await captureElementAnnotation(targetEntry.element, trimmedNote);\n return { ...targetEntry, target: annotation.targets[0], loading: false };\n }),\n );\n\n const storedAnnotation: StoredAnnotation = {\n id: current.editingId ?? createAnnotationId(),\n note: trimmedNote,\n targets: currentTargets.map((targetEntry) => ({\n targetElement: targetEntry.element,\n rect: getRect(targetEntry.element, targetEntry.frameElement),\n frameElement: targetEntry.frameElement,\n data: targetEntry.target as AnnotationTarget,\n })),\n };\n\n setAnnotations((existing) => {\n if (!current.editingId) {\n return [...existing, storedAnnotation];\n }\n\n return existing.map((item) => (item.id === current.editingId ? storedAnnotation : item));\n });\n setSelected(null);\n setNote(\"\");\n setPreviewedAnnotation(null);\n setStatus(current.editingId ? \"Annotation updated.\" : \"Annotation saved.\");\n }, [note]);\n\n const editAnnotation = useCallback((annotation: StoredAnnotation) => {\n setLinkingAnnotationId(null);\n setSelected({\n editingId: annotation.id,\n targets: annotation.targets.map((targetEntry) => ({\n element: targetEntry.targetElement,\n rect: getRect(targetEntry.targetElement, targetEntry.frameElement),\n frameElement: targetEntry.frameElement,\n target: targetEntry.data,\n loading: false,\n })),\n });\n setNote(annotation.note);\n setPreviewedAnnotation(null);\n setStatus(\"Editing annotation.\");\n }, []);\n\n const startLinkingAnnotation = useCallback((annotationId: string) => {\n setSelected(null);\n setPreviewedAnnotation(null);\n setLinkingAnnotationId(annotationId);\n setStatus(\"Click another element to link it to this annotation.\");\n }, []);\n\n const deleteAnnotation = useCallback((annotationId: string) => {\n setAnnotations((existing) => existing.filter((annotation) => annotation.id !== annotationId));\n setSelected((current) => (current?.editingId === annotationId ? null : current));\n setPreviewedAnnotation((current) => (current?.id === annotationId ? null : current));\n setLinkingAnnotationId((current) => (current === annotationId ? null : current));\n setStatus(\"Annotation deleted.\");\n }, []);\n\n const collect = useCallback(async () => {\n const payload = createAnnotationCollection(stripStoredAnnotations(annotations), getPageContext(resolvedTarget.document));\n const text = formatAnnotationCollection(payload, output);\n\n try {\n await copyTextToClipboard(text);\n onCollect?.(payload);\n setIsAnnotating(false);\n setSelected(null);\n setHoverRect(null);\n setAnnotations([]);\n setPreviewedAnnotation(null);\n setNote(\"\");\n setStatus(null);\n setLinkingAnnotationId(null);\n toast.success(\"Annotations copied\", { description: `${payload.annotations.length} copied to clipboard.` });\n } catch (error) {\n toast.error(\"Copy failed\", { description: error instanceof Error ? error.message : \"Clipboard copy failed.\" });\n setStatus(error instanceof Error ? error.message : \"Clipboard copy failed.\");\n }\n }, [annotations, onCollect, output, resolvedTarget.document]);\n\n if (!enabled) {\n return null;\n }\n\n return (\n <div {...{ [ROOT_ATTR]: \"\" }} style={styles.root} aria-live=\"polite\">\n {renderToaster ? <Toaster position=\"bottom-right\" richColors /> : null}\n <button\n type=\"button\"\n onClick={() => setIsAnnotating((current) => !current)}\n style={{ ...styles.floatingButton, ...(isAnnotating ? styles.floatingButtonActive : null) }}\n aria-pressed={isAnnotating}\n title={`Toggle annotator (${hotkey})`}\n >\n {isAnnotating ? \"Annotating\" : \"Annotate\"}\n </button>\n\n {isAnnotating && hoverRect ? <Box rect={hoverRect} kind=\"hover\" /> : null}\n {selected?.targets.map((targetEntry, index) => <Box key={index} rect={targetEntry.rect} kind=\"selected\" />)}\n {isAnnotating\n ? annotations.map((annotation, index) =>\n annotation.targets.map((targetEntry, targetIndex) => (\n <Pin\n key={`${annotation.id}:${targetIndex}`}\n annotation={annotation}\n rect={targetEntry.rect}\n index={index}\n isPreviewed={previewedAnnotation?.id === annotation.id}\n onPreview={setPreviewedAnnotation}\n />\n )),\n )\n : null}\n {isAnnotating && previewedAnnotation ? (\n <AnnotationPreview\n annotation={previewedAnnotation}\n index={annotations.findIndex((annotation) => annotation.id === previewedAnnotation.id)}\n onEdit={editAnnotation}\n onDelete={deleteAnnotation}\n onClose={() => setPreviewedAnnotation(null)}\n />\n ) : null}\n\n {selected?.targets.length ? (\n <div style={getPopoverStyle(selected.targets[selected.targets.length - 1].rect)} role=\"dialog\" aria-label=\"Add source annotation\">\n <div style={styles.popoverTitle}>Annotation</div>\n <div style={styles.metaText}>{formatSelectedTargets(selected.targets)}</div>\n <textarea\n value={note}\n onChange={(event) => setNote(event.target.value)}\n placeholder=\"What should change here?\"\n style={styles.textarea}\n rows={4}\n autoFocus\n />\n <div style={styles.popoverActions}>\n <button type=\"button\" onClick={() => setSelected(null)} style={styles.secondaryButton}>\n Cancel\n </button>\n <button type=\"button\" onClick={addAnnotation} style={styles.primaryButton} disabled={selected.targets.some((targetEntry) => targetEntry.loading)}>\n {selected.editingId ? \"Update note\" : \"Save note\"}\n </button>\n </div>\n </div>\n ) : null}\n\n {isAnnotating ? (\n <section style={styles.panel} aria-label=\"Collected annotations\">\n <div style={styles.panelHeader}>\n <strong>Annotations</strong>\n <span style={styles.badge}>{annotations.length}</span>\n </div>\n {annotations.length ? (\n <ol style={styles.annotationList}>\n {annotations.map((annotation, index) => (\n <li key={annotation.id} style={styles.annotationItem}>\n <div style={styles.annotationContent}>\n <div style={styles.noteText}>{annotation.note}</div>\n <div style={styles.metaText}>{formatStoredAnnotationSummary(annotation)}</div>\n </div>\n <div style={styles.annotationActions}>\n <button type=\"button\" onClick={() => startLinkingAnnotation(annotation.id)} style={styles.linkButton}>\n Link element\n </button>\n <button\n type=\"button\"\n onClick={() => deleteAnnotation(annotation.id)}\n style={{ ...styles.deleteButton, ...styles.iconButton }}\n aria-label={`Delete annotation ${index + 1}`}\n title={`Delete annotation ${index + 1}`}\n >\n 🗑\n </button>\n </div>\n </li>\n ))}\n </ol>\n ) : (\n <p style={styles.emptyText}>Hover an element, click it, then add a note.</p>\n )}\n <button type=\"button\" onClick={collect} style={styles.collectButton} disabled={!annotations.length}>\n Collect\n </button>\n {status ? <div style={styles.status}>{status}</div> : null}\n </section>\n ) : null}\n </div>\n );\n}\n\nfunction Box({ rect, kind }: { rect: Rect; kind: \"hover\" | \"selected\" }) {\n return (\n <div\n data-mikuexe-annotator-box={kind}\n style={{\n ...styles.box,\n ...(kind === \"selected\" ? styles.selectedBox : styles.hoverBox),\n top: rect.top,\n left: rect.left,\n width: rect.width,\n height: rect.height,\n }}\n />\n );\n}\n\nfunction Pin({\n annotation,\n rect,\n index,\n isPreviewed,\n onPreview,\n}: {\n annotation: StoredAnnotation;\n rect: Rect;\n index: number;\n isPreviewed: boolean;\n onPreview: (annotation: StoredAnnotation) => void;\n}) {\n return (\n <button\n type=\"button\"\n style={{ ...styles.pin, top: Math.max(8, rect.top - 10), left: Math.max(8, rect.left - 10) }}\n title={annotation.note}\n aria-label={`Show annotation ${index + 1}`}\n aria-haspopup=\"dialog\"\n aria-expanded={isPreviewed}\n onClick={() => onPreview(annotation)}\n onMouseOver={() => onPreview(annotation)}\n onFocus={() => onPreview(annotation)}\n >\n {index + 1}\n </button>\n );\n}\n\nfunction AnnotationPreview({\n annotation,\n index,\n onEdit,\n onDelete,\n onClose,\n}: {\n annotation: StoredAnnotation;\n index: number;\n onEdit: (annotation: StoredAnnotation) => void;\n onDelete: (annotationId: string) => void;\n onClose: () => void;\n}) {\n const displayIndex = index >= 0 ? index + 1 : 1;\n\n return (\n <div\n role=\"dialog\"\n aria-label={`Annotation ${displayIndex}`}\n style={getPreviewStyle(annotation.targets[0]?.rect ?? { top: 8, left: 8, width: 0, height: 0 })}\n >\n <div style={styles.previewHeader}>\n <div style={styles.previewTitle}>Annotation {displayIndex}</div>\n <div style={styles.previewActions}>\n <button\n type=\"button\"\n onClick={onClose}\n style={{ ...styles.secondaryButton, ...styles.iconButton }}\n aria-label={`Close annotation ${displayIndex}`}\n title={`Close annotation ${displayIndex}`}\n >\n ×\n </button>\n <button\n type=\"button\"\n onClick={() => onEdit(annotation)}\n style={{ ...styles.secondaryButton, ...styles.iconButton }}\n aria-label={`Edit annotation ${displayIndex}`}\n title={`Edit annotation ${displayIndex}`}\n >\n ✎\n </button>\n <button\n type=\"button\"\n onClick={() => onDelete(annotation.id)}\n style={{ ...styles.deleteButton, ...styles.iconButton }}\n aria-label={`Delete annotation ${displayIndex}`}\n title={`Delete annotation ${displayIndex}`}\n >\n 🗑\n </button>\n </div>\n </div>\n <div style={styles.noteText}>{annotation.note}</div>\n <div style={styles.metaText}>{formatStoredAnnotationSummary(annotation)}</div>\n </div>\n );\n}\n\nfunction stripStoredAnnotations(annotations: StoredAnnotation[]): Annotation[] {\n return annotations.map((annotation) => ({\n id: annotation.id,\n note: annotation.note,\n targets: annotation.targets.map((targetEntry) => targetEntry.data),\n }));\n}\n\nfunction getAnnotatableTarget(target: EventTarget | null, ownerDocument: Document): Element | null {\n if (!isElement(target, ownerDocument)) {\n return null;\n }\n\n if (target.closest(`[${ROOT_ATTR}]`)) {\n return null;\n }\n\n if (target === ownerDocument.body || target === ownerDocument.documentElement) {\n return null;\n }\n\n return target;\n}\n\nfunction getRect(element: Element, frameElement: HTMLIFrameElement | null): Rect {\n const rect = element.getBoundingClientRect();\n const frameRect = frameElement?.getBoundingClientRect();\n\n return {\n top: rect.top + (frameRect?.top ?? 0),\n left: rect.left + (frameRect?.left ?? 0),\n width: rect.width,\n height: rect.height,\n };\n}\n\nfunction useResolvedTarget(target: SourceAnnotatorTarget | undefined): ResolvedTarget {\n const [navigationVersion, setNavigationVersion] = useState(0);\n const resolvedTarget = useMemo(() => resolveTarget(target), [target, navigationVersion]);\n const currentDocumentRef = useRef<Document | null>(resolvedTarget.document);\n currentDocumentRef.current = resolvedTarget.document;\n\n useEffect(() => {\n if (typeof HTMLIFrameElement !== \"undefined\" && target instanceof HTMLIFrameElement) {\n const updateTarget = () => {\n const nextTarget = resolveTarget(target);\n if (nextTarget.document !== currentDocumentRef.current) {\n setNavigationVersion((version) => version + 1);\n }\n };\n target.addEventListener(\"load\", updateTarget);\n return () => target.removeEventListener(\"load\", updateTarget);\n }\n }, [target]);\n\n return resolvedTarget;\n}\n\nfunction resolveTarget(target: SourceAnnotatorTarget | undefined): ResolvedTarget {\n const hostDocument = typeof document === \"undefined\" ? null : document;\n\n if (typeof HTMLIFrameElement !== \"undefined\" && target instanceof HTMLIFrameElement) {\n const frameDocument = target.contentDocument;\n if (!frameDocument) {\n console.warn(\"@mikuexe/annotator-react: SourceAnnotator target iframe must be same-origin; iframe contentDocument is not accessible.\");\n return {\n document: null,\n frameElement: target,\n };\n }\n\n return {\n document: frameDocument,\n frameElement: target,\n };\n }\n\n if (typeof Document !== \"undefined\" && target instanceof Document) {\n return {\n document: target,\n frameElement: null,\n };\n }\n\n return {\n document: hostDocument,\n frameElement: null,\n };\n}\n\nfunction isElement(target: EventTarget | null, ownerDocument: Document): target is Element {\n const elementConstructor = ownerDocument.defaultView?.Element ?? Element;\n return target instanceof elementConstructor;\n}\n\nfunction getPopoverStyle(rect: Rect): CSSProperties {\n const top = Math.min(window.innerHeight - 260, rect.top + rect.height + 8);\n const left = Math.min(window.innerWidth - 340, Math.max(8, rect.left));\n\n return {\n ...styles.popover,\n top: Math.max(8, top),\n left,\n };\n}\n\nfunction getPreviewStyle(rect: Rect): CSSProperties {\n const top = Math.min(window.innerHeight - 120, rect.top + rect.height + 8);\n const left = Math.min(window.innerWidth - 260, Math.max(8, rect.left));\n\n return {\n ...styles.preview,\n top: Math.max(8, top),\n left,\n };\n}\n\nfunction formatSelectedTargets(targets: DraftTarget[]): string {\n if (!targets.length) {\n return \"Source unavailable\";\n }\n\n if (targets.length === 1) {\n return formatTargetSource(targets[0].target);\n }\n\n const resolvedCount = targets.filter((targetEntry) => targetEntry.target).length;\n return `${targets.length} elements selected · ${resolvedCount}/${targets.length} resolved`;\n}\n\nfunction formatStoredAnnotationSummary(annotation: StoredAnnotation): string {\n const firstTarget = annotation.targets[0]?.data;\n const targetSummary = formatTargetSource(firstTarget);\n const linkedSummary = annotation.targets.length > 1 ? ` · ${annotation.targets.length} linked elements` : \"\";\n return `${targetSummary}${linkedSummary}`;\n}\n\nfunction formatTargetSource(target: AnnotationTarget | null | undefined): string {\n const componentPath = target?.componentPath.length ? target.componentPath.join(\" › \") : null;\n\n if (!target) {\n return \"Source unavailable\";\n }\n\n if (!target.source?.filePath) {\n return `${target.element.selector} · source unavailable`;\n }\n\n const line = target.source.lineNumber ? `:${target.source.lineNumber}` : \"\";\n const component = componentPath ? ` · ${componentPath}` : \"\";\n return `${target.source.filePath}${line}${component}`;\n}\n\nfunction shouldExtendSelection(event: MouseEvent): boolean {\n return event.metaKey || event.ctrlKey;\n}\n\nfunction matchesHotkey(event: KeyboardEvent, hotkey: string): boolean {\n const parts = hotkey.toLowerCase().split(\"+\").map((part) => part.trim()).filter(Boolean);\n const key = parts.find((part) => ![\"ctrl\", \"control\", \"cmd\", \"meta\", \"mod\", \"shift\", \"alt\", \"option\"].includes(part));\n\n const wantsMeta = parts.includes(\"meta\") || parts.includes(\"cmd\") || (parts.includes(\"mod\") && isMac());\n const wantsCtrl = parts.includes(\"ctrl\") || parts.includes(\"control\") || (parts.includes(\"mod\") && !isMac());\n const wantsShift = parts.includes(\"shift\");\n const wantsAlt = parts.includes(\"alt\") || parts.includes(\"option\");\n\n return (\n event.key.toLowerCase() === key &&\n event.metaKey === wantsMeta &&\n event.ctrlKey === wantsCtrl &&\n event.shiftKey === wantsShift &&\n event.altKey === wantsAlt\n );\n}\n\nfunction isMac(): boolean {\n return typeof navigator !== \"undefined\" && /mac|iphone|ipad|ipod/i.test(navigator.platform);\n}\n\nconst baseFont = '13px/1.35 -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif';\n\nconst styles = {\n root: {\n position: \"fixed\",\n inset: 0,\n zIndex: 2147483647,\n pointerEvents: \"none\",\n font: baseFont,\n color: \"#0f172a\",\n } satisfies CSSProperties,\n floatingButton: {\n position: \"fixed\",\n right: 16,\n bottom: 16,\n pointerEvents: \"auto\",\n borderWidth: 1,\n borderStyle: \"solid\",\n borderColor: \"#cbd5e1\",\n background: \"#ffffff\",\n color: \"#0f172a\",\n borderRadius: 999,\n padding: \"10px 14px\",\n font: baseFont,\n fontWeight: 700,\n boxShadow: \"0 10px 25px rgba(15, 23, 42, 0.16)\",\n cursor: \"pointer\",\n } satisfies CSSProperties,\n floatingButtonActive: {\n background: \"#0f172a\",\n color: \"#ffffff\",\n borderColor: \"#0f172a\",\n } satisfies CSSProperties,\n box: {\n position: \"fixed\",\n borderRadius: 6,\n pointerEvents: \"none\",\n boxSizing: \"border-box\",\n } satisfies CSSProperties,\n hoverBox: {\n border: \"2px solid #38bdf8\",\n background: \"rgba(56, 189, 248, 0.08)\",\n } satisfies CSSProperties,\n selectedBox: {\n border: \"2px solid #f97316\",\n background: \"rgba(249, 115, 22, 0.1)\",\n } satisfies CSSProperties,\n popover: {\n position: \"fixed\",\n zIndex: 2,\n width: 320,\n pointerEvents: \"auto\",\n background: \"#ffffff\",\n border: \"1px solid #cbd5e1\",\n borderRadius: 12,\n padding: 12,\n boxShadow: \"0 18px 45px rgba(15, 23, 42, 0.22)\",\n } satisfies CSSProperties,\n popoverTitle: {\n fontWeight: 800,\n marginBottom: 4,\n } satisfies CSSProperties,\n metaText: {\n color: \"#64748b\",\n fontSize: 12,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n } satisfies CSSProperties,\n textarea: {\n width: \"100%\",\n boxSizing: \"border-box\",\n marginTop: 10,\n border: \"1px solid #cbd5e1\",\n borderRadius: 8,\n padding: 10,\n resize: \"vertical\",\n font: baseFont,\n } satisfies CSSProperties,\n popoverActions: {\n display: \"flex\",\n justifyContent: \"flex-end\",\n gap: 8,\n marginTop: 10,\n } satisfies CSSProperties,\n secondaryButton: {\n border: \"1px solid #cbd5e1\",\n borderRadius: 8,\n background: \"#ffffff\",\n padding: \"7px 10px\",\n cursor: \"pointer\",\n } satisfies CSSProperties,\n primaryButton: {\n border: \"1px solid #0f172a\",\n borderRadius: 8,\n background: \"#0f172a\",\n color: \"#ffffff\",\n padding: \"7px 10px\",\n cursor: \"pointer\",\n } satisfies CSSProperties,\n panel: {\n position: \"fixed\",\n zIndex: 1,\n right: 16,\n bottom: 68,\n width: 300,\n pointerEvents: \"auto\",\n background: \"#ffffff\",\n border: \"1px solid #cbd5e1\",\n borderRadius: 12,\n padding: 12,\n boxShadow: \"0 18px 45px rgba(15, 23, 42, 0.18)\",\n } satisfies CSSProperties,\n panelHeader: {\n display: \"flex\",\n justifyContent: \"space-between\",\n alignItems: \"center\",\n marginBottom: 8,\n } satisfies CSSProperties,\n badge: {\n minWidth: 20,\n height: 20,\n borderRadius: 999,\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n background: \"#e2e8f0\",\n color: \"#334155\",\n fontWeight: 700,\n fontSize: 12,\n } satisfies CSSProperties,\n annotationList: {\n listStyle: \"decimal\",\n margin: \"0 0 10px 18px\",\n padding: 0,\n maxHeight: 180,\n overflow: \"auto\",\n } satisfies CSSProperties,\n annotationItem: {\n display: \"grid\",\n gap: 8,\n alignItems: \"start\",\n marginBottom: 8,\n } satisfies CSSProperties,\n annotationContent: {\n minWidth: 0,\n } satisfies CSSProperties,\n annotationActions: {\n display: \"flex\",\n gap: 8,\n flexWrap: \"wrap\",\n } satisfies CSSProperties,\n noteText: {\n color: \"#0f172a\",\n fontWeight: 650,\n overflowWrap: \"anywhere\",\n } satisfies CSSProperties,\n emptyText: {\n color: \"#64748b\",\n margin: \"6px 0 10px\",\n } satisfies CSSProperties,\n collectButton: {\n width: \"100%\",\n border: \"1px solid #0f172a\",\n borderRadius: 8,\n background: \"#0f172a\",\n color: \"#ffffff\",\n padding: \"9px 10px\",\n fontWeight: 800,\n cursor: \"pointer\",\n } satisfies CSSProperties,\n status: {\n marginTop: 8,\n color: \"#475569\",\n fontSize: 12,\n } satisfies CSSProperties,\n linkButton: {\n border: \"1px solid #bfdbfe\",\n borderRadius: 999,\n background: \"#eff6ff\",\n color: \"#1d4ed8\",\n padding: \"4px 7px\",\n fontSize: 11,\n fontWeight: 750,\n cursor: \"pointer\",\n } satisfies CSSProperties,\n deleteButton: {\n border: \"1px solid #fecaca\",\n borderRadius: 999,\n background: \"#fff1f2\",\n color: \"#be123c\",\n padding: \"4px 7px\",\n fontSize: 11,\n fontWeight: 750,\n cursor: \"pointer\",\n } satisfies CSSProperties,\n preview: {\n position: \"fixed\",\n maxWidth: 240,\n pointerEvents: \"auto\",\n background: \"#ffffff\",\n border: \"1px solid #cbd5e1\",\n borderRadius: 10,\n padding: 10,\n boxShadow: \"0 14px 35px rgba(15, 23, 42, 0.18)\",\n } satisfies CSSProperties,\n previewHeader: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: 8,\n marginBottom: 6,\n } satisfies CSSProperties,\n previewTitle: {\n color: \"#475569\",\n fontSize: 12,\n fontWeight: 800,\n } satisfies CSSProperties,\n previewActions: {\n display: \"inline-flex\",\n gap: 6,\n } satisfies CSSProperties,\n iconButton: {\n width: 26,\n height: 26,\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 0,\n lineHeight: 1,\n } satisfies CSSProperties,\n pin: {\n position: \"fixed\",\n border: 0,\n width: 20,\n height: 20,\n borderRadius: 999,\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n pointerEvents: \"auto\",\n background: \"#f97316\",\n color: \"#ffffff\",\n fontSize: 12,\n fontWeight: 800,\n boxShadow: \"0 8px 18px rgba(15, 23, 42, 0.2)\",\n cursor: \"pointer\",\n padding: 0,\n } satisfies CSSProperties,\n};\n","import { resolveElementInfo } from \"element-source\";\nimport type { Annotation, AnnotationSource, AnnotationTarget } from \"./types\";\n\nconst MAX_TEXT_LENGTH = 240;\nconst MAX_HTML_LENGTH = 640;\nconst MAX_SELECTOR_DEPTH = 6;\n\nexport async function captureElementAnnotation(\n element: Element,\n note: string,\n id = createAnnotationId(),\n): Promise<Annotation> {\n return {\n id,\n note,\n targets: [await captureAnnotationTarget(element)],\n };\n}\n\nexport async function captureAnnotationTarget(element: Element): Promise<AnnotationTarget> {\n const elementInfo = await safeResolveElementInfo(element);\n const source = normalizeSource(elementInfo?.source, elementInfo?.componentName);\n const sourceStack = normalizeSourceStack(elementInfo?.stack, source);\n const componentPath = getComponentPath(sourceStack, source);\n\n return {\n source,\n sourceStack,\n componentPath,\n element: {\n tagName: element.tagName.toLowerCase(),\n text: trimText(element.textContent ?? \"\", MAX_TEXT_LENGTH),\n html: trimText(getOuterHtml(element), MAX_HTML_LENGTH),\n selector: getElementSelector(element),\n },\n };\n}\n\nexport function createAnnotationId(): string {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n return crypto.randomUUID();\n }\n\n return `annotation-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nexport function getElementSelector(element: Element): string {\n const parts: string[] = [];\n let current: Element | null = element;\n\n while (current && current.nodeType === Node.ELEMENT_NODE && parts.length < MAX_SELECTOR_DEPTH) {\n parts.unshift(getSelectorPart(current));\n\n if (current.id) {\n break;\n }\n\n current = current.parentElement;\n if (current?.tagName.toLowerCase() === \"html\") {\n break;\n }\n }\n\n return parts.join(\" \");\n}\n\nexport function trimText(value: string, maxLength: number): string {\n const normalized = value.replace(/\\s+/g, \" \").trim();\n\n if (normalized.length <= maxLength) {\n return normalized;\n }\n\n return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;\n}\n\nasync function safeResolveElementInfo(element: Element) {\n try {\n return await resolveElementInfo(element);\n } catch {\n return null;\n }\n}\n\nfunction normalizeSource(\n source: AnnotationSource | null | undefined,\n componentName: string | null | undefined,\n): AnnotationSource | null {\n if (!source) {\n return componentName\n ? { filePath: \"\", lineNumber: null, columnNumber: null, componentName }\n : null;\n }\n\n return {\n filePath: source.filePath,\n lineNumber: source.lineNumber ?? null,\n columnNumber: source.columnNumber ?? null,\n componentName: source.componentName ?? componentName ?? null,\n };\n}\n\nfunction normalizeSourceStack(\n stack: AnnotationSource[] | null | undefined,\n source: AnnotationSource | null,\n): AnnotationSource[] {\n const normalizedStack = (stack ?? []).map((frame) => ({\n filePath: frame.filePath,\n lineNumber: frame.lineNumber ?? null,\n columnNumber: frame.columnNumber ?? null,\n componentName: frame.componentName ?? null,\n }));\n\n if (source && !normalizedStack.some((frame) => isSameSourceFrame(frame, source))) {\n normalizedStack.unshift(source);\n }\n\n return normalizedStack;\n}\n\nfunction getComponentPath(stack: AnnotationSource[], source: AnnotationSource | null): string[] {\n const names = stack.map((frame) => frame.componentName).filter((name): name is string => Boolean(name));\n return Array.from(new Set(names.length ? names : source?.componentName ? [source.componentName] : []));\n}\n\nfunction isSameSourceFrame(a: AnnotationSource, b: AnnotationSource): boolean {\n return a.filePath === b.filePath && a.lineNumber === b.lineNumber && a.columnNumber === b.columnNumber;\n}\n\nfunction getOuterHtml(element: Element): string {\n if (\"outerHTML\" in element && typeof element.outerHTML === \"string\") {\n return element.outerHTML;\n }\n\n return `<${element.tagName.toLowerCase()}>`;\n}\n\nfunction getSelectorPart(element: Element): string {\n const tagName = element.tagName.toLowerCase();\n\n if (element.id) {\n return `#${escapeIdentifier(element.id)}`;\n }\n\n const testId = element.getAttribute(\"data-testid\");\n if (testId) {\n return `${tagName}[data-testid=\"${escapeAttribute(testId)}\"]`;\n }\n\n const classes = Array.from(element.classList)\n .filter(Boolean)\n .slice(0, 2)\n .map((className) => `.${escapeIdentifier(className)}`)\n .join(\"\");\n\n const siblingIndex = getNthOfType(element);\n const needsNth = siblingIndex > 1 || hasFollowingSiblingOfSameType(element);\n\n return `${tagName}${classes}${needsNth ? `:nth-of-type(${siblingIndex})` : \"\"}`;\n}\n\nfunction getNthOfType(element: Element): number {\n let index = 1;\n let sibling = element.previousElementSibling;\n\n while (sibling) {\n if (sibling.tagName === element.tagName) {\n index += 1;\n }\n sibling = sibling.previousElementSibling;\n }\n\n return index;\n}\n\nfunction hasFollowingSiblingOfSameType(element: Element): boolean {\n let sibling = element.nextElementSibling;\n\n while (sibling) {\n if (sibling.tagName === element.tagName) {\n return true;\n }\n sibling = sibling.nextElementSibling;\n }\n\n return false;\n}\n\nfunction escapeIdentifier(value: string): string {\n if (typeof CSS !== \"undefined\" && typeof CSS.escape === \"function\") {\n return CSS.escape(value);\n }\n\n return value.replace(/[^a-zA-Z0-9_-]/g, \"\\\\$&\");\n}\n\nfunction escapeAttribute(value: string): string {\n return value.replace(/\"/g, \"\\\\\\\"\");\n}\n","export async function copyTextToClipboard(text: string): Promise<void> {\n if (typeof navigator !== \"undefined\" && navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n return;\n }\n\n if (typeof document === \"undefined\") {\n throw new Error(\"Clipboard is not available outside a browser environment.\");\n }\n\n const textarea = document.createElement(\"textarea\");\n textarea.value = text;\n textarea.setAttribute(\"readonly\", \"\");\n textarea.style.position = \"fixed\";\n textarea.style.left = \"-9999px\";\n textarea.style.top = \"0\";\n document.body.appendChild(textarea);\n textarea.select();\n\n const copied = document.execCommand(\"copy\");\n textarea.remove();\n\n if (!copied) {\n throw new Error(\"Clipboard copy failed.\");\n }\n}\n","import type { Annotation, AnnotationCollection, AnnotationTarget, PageContext, SourceAnnotatorOutput } from \"./types\";\n\nconst TASK_FRAMING = \"Please update the UI based on these source-linked annotations.\";\n\nexport function createAnnotationCollection(annotations: Annotation[], page = getPageContext()): AnnotationCollection {\n return {\n annotations,\n createdAt: new Date().toISOString(),\n page,\n };\n}\n\nexport function getPageContext(targetDocument?: Document | null): PageContext {\n const activeDocument = targetDocument ?? (typeof document === \"undefined\" ? null : document);\n const location = activeDocument?.location;\n\n return {\n domain: location?.hostname ?? \"\",\n path: location?.pathname ?? \"\",\n };\n}\n\nexport function formatAnnotationCollection(\n collection: AnnotationCollection,\n output: SourceAnnotatorOutput = \"markdown\",\n): string {\n if (output === \"json\") {\n return formatJson(collection);\n }\n\n const markdown = formatMarkdown(collection);\n\n if (output === \"markdown\") {\n return markdown;\n }\n\n return `${markdown}\\n\\n## JSON Payload\\n\\n\\`\\`\\`json\\n${formatJson(collection)}\\n\\`\\`\\``;\n}\n\nexport function formatMarkdown(collection: AnnotationCollection): string {\n const lines = [\n TASK_FRAMING,\n \"\",\n `Collected at: ${collection.createdAt}`,\n `Domain: ${collection.page.domain}`,\n `Path: ${collection.page.path}`,\n \"\",\n ];\n\n if (collection.annotations.length === 0) {\n lines.push(\"No annotations were collected.\");\n return lines.join(\"\\n\");\n }\n\n collection.annotations.forEach((annotation, index) => {\n lines.push(`## Annotation ${index + 1}`);\n lines.push(\"\");\n lines.push(`ID: ${annotation.id}`);\n lines.push(`Note: ${annotation.note || \"(no note provided)\"}`);\n\n annotation.targets.forEach((target, targetIndex) => {\n const isSingleTarget = annotation.targets.length === 1;\n const label = isSingleTarget ? \"\" : `Target ${targetIndex + 1} `;\n appendTargetMarkdown(lines, target, label);\n });\n\n lines.push(\"\");\n });\n\n return lines.join(\"\\n\").trimEnd();\n}\n\nfunction formatJson(collection: AnnotationCollection): string {\n return JSON.stringify(collection, null, 2);\n}\n\nfunction appendTargetMarkdown(lines: string[], target: AnnotationTarget, label: string) {\n const source = formatSource(target);\n const sourceStack = formatSourceStack(target);\n const nearestComponent = target.source?.componentName;\n const ownerPath = target.componentPath.join(\" › \");\n\n if (source) {\n lines.push(`${label}Source: ${source}`);\n }\n\n if (nearestComponent) {\n lines.push(`${label}Nearest React component: ${nearestComponent}`);\n }\n\n if (ownerPath && ownerPath !== nearestComponent) {\n lines.push(`${label}React owner path: ${ownerPath}`);\n }\n\n if (sourceStack.length) {\n lines.push(`${label}React source stack:`);\n sourceStack.forEach((frame) => lines.push(`- ${frame}`));\n }\n\n lines.push(`${label}Element tag: ${target.element.tagName}`);\n\n if (target.element.html) {\n lines.push(`${label}Element HTML: ${target.element.html}`);\n }\n\n if (target.element.text) {\n lines.push(`${label}Element text: ${target.element.text}`);\n }\n\n if (target.element.selector) {\n lines.push(`${label}Selector: ${target.element.selector}`);\n }\n}\n\nfunction formatSource(target: AnnotationTarget): string {\n const source = target.source;\n\n if (!source?.filePath) {\n return \"\";\n }\n\n const line = source.lineNumber ? `:${source.lineNumber}` : \"\";\n const column = source.columnNumber ? `:${source.columnNumber}` : \"\";\n\n return `${source.filePath}${line}${column}`;\n}\n\nfunction formatSourceStack(target: AnnotationTarget): string[] {\n return target.sourceStack\n .map((frame) => {\n const location = formatSourceFrame(frame);\n const component = frame.componentName ? ` (${frame.componentName})` : \"\";\n\n return location ? `${location}${component}` : frame.componentName || \"\";\n })\n .filter(Boolean);\n}\n\nfunction formatSourceFrame(frame: AnnotationTarget[\"sourceStack\"][number]): string {\n if (!frame.filePath) {\n return \"\";\n }\n\n const line = frame.lineNumber ? `:${frame.lineNumber}` : \"\";\n const column = frame.columnNumber ? `:${frame.columnNumber}` : \"\";\n\n return `${frame.filePath}${line}${column}`;\n}\n"],"mappings":"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","names":["rect"]}
package/dist/index.d.cts CHANGED
@@ -12,37 +12,49 @@ type AnnotationElement = {
12
12
  html: string;
13
13
  selector: string;
14
14
  };
15
- type Annotation = {
16
- id: string;
17
- note: string;
15
+ type AnnotationTarget = {
18
16
  source: AnnotationSource | null;
19
17
  sourceStack: AnnotationSource[];
20
18
  componentPath: string[];
21
19
  element: AnnotationElement;
22
20
  };
21
+ type Annotation = {
22
+ id: string;
23
+ note: string;
24
+ targets: AnnotationTarget[];
25
+ };
26
+ type PageContext = {
27
+ domain: string;
28
+ path: string;
29
+ };
23
30
  type AnnotationCollection = {
24
31
  annotations: Annotation[];
25
32
  createdAt: string;
33
+ page: PageContext;
26
34
  };
27
35
  type SourceAnnotatorOutput = "markdown" | "json" | "both";
36
+ type SourceAnnotatorTarget = Document | HTMLIFrameElement | null;
28
37
  type SourceAnnotatorProps = {
29
38
  enabled?: boolean;
30
39
  hotkey?: string;
31
40
  output?: SourceAnnotatorOutput;
41
+ target?: SourceAnnotatorTarget;
32
42
  onCollect?: (payload: AnnotationCollection) => void;
33
43
  renderToaster?: boolean;
34
44
  };
35
45
 
36
- declare function SourceAnnotator({ enabled, hotkey, output, onCollect, renderToaster, }: SourceAnnotatorProps): react_jsx_runtime.JSX.Element | null;
46
+ declare function SourceAnnotator({ enabled, hotkey, output, target, onCollect, renderToaster, }: SourceAnnotatorProps): react_jsx_runtime.JSX.Element | null;
37
47
 
38
48
  declare function copyTextToClipboard(text: string): Promise<void>;
39
49
 
40
50
  declare function captureElementAnnotation(element: Element, note: string, id?: string): Promise<Annotation>;
51
+ declare function captureAnnotationTarget(element: Element): Promise<AnnotationTarget>;
41
52
  declare function getElementSelector(element: Element): string;
42
53
  declare function trimText(value: string, maxLength: number): string;
43
54
 
44
- declare function createAnnotationCollection(annotations: Annotation[]): AnnotationCollection;
55
+ declare function createAnnotationCollection(annotations: Annotation[], page?: PageContext): AnnotationCollection;
56
+ declare function getPageContext(targetDocument?: Document | null): PageContext;
45
57
  declare function formatAnnotationCollection(collection: AnnotationCollection, output?: SourceAnnotatorOutput): string;
46
58
  declare function formatMarkdown(collection: AnnotationCollection): string;
47
59
 
48
- export { type Annotation, type AnnotationCollection, type AnnotationElement, type AnnotationSource, SourceAnnotator, type SourceAnnotatorOutput, type SourceAnnotatorProps, captureElementAnnotation, copyTextToClipboard, createAnnotationCollection, formatAnnotationCollection, formatMarkdown, getElementSelector, trimText };
60
+ export { type Annotation, type AnnotationCollection, type AnnotationElement, type AnnotationSource, type AnnotationTarget, type PageContext, SourceAnnotator, type SourceAnnotatorOutput, type SourceAnnotatorProps, type SourceAnnotatorTarget, captureAnnotationTarget, captureElementAnnotation, copyTextToClipboard, createAnnotationCollection, formatAnnotationCollection, formatMarkdown, getElementSelector, getPageContext, trimText };
package/dist/index.d.ts CHANGED
@@ -12,37 +12,49 @@ type AnnotationElement = {
12
12
  html: string;
13
13
  selector: string;
14
14
  };
15
- type Annotation = {
16
- id: string;
17
- note: string;
15
+ type AnnotationTarget = {
18
16
  source: AnnotationSource | null;
19
17
  sourceStack: AnnotationSource[];
20
18
  componentPath: string[];
21
19
  element: AnnotationElement;
22
20
  };
21
+ type Annotation = {
22
+ id: string;
23
+ note: string;
24
+ targets: AnnotationTarget[];
25
+ };
26
+ type PageContext = {
27
+ domain: string;
28
+ path: string;
29
+ };
23
30
  type AnnotationCollection = {
24
31
  annotations: Annotation[];
25
32
  createdAt: string;
33
+ page: PageContext;
26
34
  };
27
35
  type SourceAnnotatorOutput = "markdown" | "json" | "both";
36
+ type SourceAnnotatorTarget = Document | HTMLIFrameElement | null;
28
37
  type SourceAnnotatorProps = {
29
38
  enabled?: boolean;
30
39
  hotkey?: string;
31
40
  output?: SourceAnnotatorOutput;
41
+ target?: SourceAnnotatorTarget;
32
42
  onCollect?: (payload: AnnotationCollection) => void;
33
43
  renderToaster?: boolean;
34
44
  };
35
45
 
36
- declare function SourceAnnotator({ enabled, hotkey, output, onCollect, renderToaster, }: SourceAnnotatorProps): react_jsx_runtime.JSX.Element | null;
46
+ declare function SourceAnnotator({ enabled, hotkey, output, target, onCollect, renderToaster, }: SourceAnnotatorProps): react_jsx_runtime.JSX.Element | null;
37
47
 
38
48
  declare function copyTextToClipboard(text: string): Promise<void>;
39
49
 
40
50
  declare function captureElementAnnotation(element: Element, note: string, id?: string): Promise<Annotation>;
51
+ declare function captureAnnotationTarget(element: Element): Promise<AnnotationTarget>;
41
52
  declare function getElementSelector(element: Element): string;
42
53
  declare function trimText(value: string, maxLength: number): string;
43
54
 
44
- declare function createAnnotationCollection(annotations: Annotation[]): AnnotationCollection;
55
+ declare function createAnnotationCollection(annotations: Annotation[], page?: PageContext): AnnotationCollection;
56
+ declare function getPageContext(targetDocument?: Document | null): PageContext;
45
57
  declare function formatAnnotationCollection(collection: AnnotationCollection, output?: SourceAnnotatorOutput): string;
46
58
  declare function formatMarkdown(collection: AnnotationCollection): string;
47
59
 
48
- export { type Annotation, type AnnotationCollection, type AnnotationElement, type AnnotationSource, SourceAnnotator, type SourceAnnotatorOutput, type SourceAnnotatorProps, captureElementAnnotation, copyTextToClipboard, createAnnotationCollection, formatAnnotationCollection, formatMarkdown, getElementSelector, trimText };
60
+ export { type Annotation, type AnnotationCollection, type AnnotationElement, type AnnotationSource, type AnnotationTarget, type PageContext, SourceAnnotator, type SourceAnnotatorOutput, type SourceAnnotatorProps, type SourceAnnotatorTarget, captureAnnotationTarget, captureElementAnnotation, copyTextToClipboard, createAnnotationCollection, formatAnnotationCollection, formatMarkdown, getElementSelector, getPageContext, trimText };