@ui-context-kit/overlay 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/overlay.ts","../src/ui/toast.ts","../src/ui/toolbar.ts","../src/fiber-walker.ts","../src/context-extractor.ts","../src/screenshot.ts","../src/selection.ts","../src/transport.ts","../src/ui/onboarding.ts","../src/index.ts","../src/inject.ts"],"sourcesContent":["let hostEl: HTMLDivElement | null = null;\nlet shadowRoot: ShadowRoot | null = null;\nlet highlightEl: HTMLDivElement | null = null;\n\nexport function createOverlay(): { highlight: (rect: DOMRect | null, label?: string) => void; destroy: () => void } {\n hostEl = document.createElement('div');\n hostEl.id = 'ui-context-host';\n hostEl.style.cssText = 'position:fixed;top:0;left:0;width:0;height:0;z-index:2147483647;pointer-events:none;';\n document.body.appendChild(hostEl);\n\n shadowRoot = hostEl.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = `\n .highlight {\n position: fixed;\n border: 2px solid #3b82f6;\n background: rgba(59, 130, 246, 0.1);\n pointer-events: none;\n transition: all 0.1s ease;\n border-radius: 4px;\n z-index: 2147483647;\n }\n .highlight-label {\n position: absolute;\n top: -24px;\n left: -2px;\n background: #3b82f6;\n color: white;\n font-size: 11px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n padding: 2px 6px;\n border-radius: 3px 3px 0 0;\n white-space: nowrap;\n pointer-events: none;\n }\n `;\n shadowRoot.appendChild(style);\n\n highlightEl = document.createElement('div');\n highlightEl.className = 'highlight';\n highlightEl.style.display = 'none';\n\n const labelEl = document.createElement('div');\n labelEl.className = 'highlight-label';\n highlightEl.appendChild(labelEl);\n\n shadowRoot.appendChild(highlightEl);\n\n return {\n highlight(rect: DOMRect | null, label?: string) {\n if (!rect || !highlightEl) {\n if (highlightEl) highlightEl.style.display = 'none';\n return;\n }\n highlightEl.style.display = 'block';\n highlightEl.style.top = rect.top + 'px';\n highlightEl.style.left = rect.left + 'px';\n highlightEl.style.width = rect.width + 'px';\n highlightEl.style.height = rect.height + 'px';\n const lbl = highlightEl.querySelector('.highlight-label') as HTMLDivElement;\n if (lbl && label) {\n lbl.textContent = label;\n lbl.style.display = 'block';\n } else if (lbl) {\n lbl.style.display = 'none';\n }\n },\n destroy() {\n hostEl?.remove();\n hostEl = null;\n shadowRoot = null;\n highlightEl = null;\n },\n };\n}\n","let toastContainer: HTMLDivElement | null = null;\nlet toastShadow: ShadowRoot | null = null;\n\nfunction ensureContainer() {\n if (toastContainer) return;\n toastContainer = document.createElement('div');\n toastContainer.id = 'ui-context-toast';\n toastContainer.style.cssText = 'position:fixed;top:0;left:0;width:0;height:0;z-index:2147483647;pointer-events:none;';\n document.body.appendChild(toastContainer);\n toastShadow = toastContainer.attachShadow({ mode: 'open' });\n const style = document.createElement('style');\n style.textContent = `\n .toast {\n position: fixed;\n bottom: 24px;\n right: 24px;\n background: #1e293b;\n color: #f1f5f9;\n padding: 12px 20px;\n border-radius: 8px;\n font-size: 13px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\n pointer-events: auto;\n animation: slideIn 0.3s ease, fadeOut 0.3s ease 2.7s;\n z-index: 2147483647;\n }\n @keyframes slideIn { from { transform: translateY(20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }\n @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }\n `;\n toastShadow.appendChild(style);\n}\n\nexport function showToast(message: string, duration = 3000) {\n ensureContainer();\n if (!toastShadow) return;\n const el = document.createElement('div');\n el.className = 'toast';\n el.textContent = message;\n toastShadow.appendChild(el);\n setTimeout(() => el.remove(), duration);\n}\n","export function createToolbar(opts: {\n onCapture: () => void;\n onCaptureAll?: () => void;\n onClose: () => void;\n onFreeze?: () => void;\n}): { el: HTMLElement; destroy: () => void; updateBadge: (count: number) => void; updateFreezeState: (frozen: boolean) => void } {\n const host = document.createElement('div');\n host.style.cssText = 'position:fixed;top:0;left:0;width:0;height:0;z-index:2147483647;';\n document.body.appendChild(host);\n\n const shadow = host.attachShadow({ mode: 'open' });\n const style = document.createElement('style');\n style.textContent = `\n .toolbar {\n position: fixed;\n bottom: 24px;\n left: 50%;\n transform: translateX(-50%);\n background: #1e293b;\n border: 1px solid #334155;\n border-radius: 12px;\n padding: 8px 12px;\n display: flex;\n gap: 6px;\n align-items: center;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n box-shadow: 0 4px 20px rgba(0,0,0,0.4);\n }\n .toolbar-btn {\n background: #3b82f6;\n color: white;\n border: none;\n padding: 6px 14px;\n border-radius: 6px;\n font-size: 12px;\n font-weight: 500;\n cursor: pointer;\n white-space: nowrap;\n }\n .toolbar-btn:hover { background: #2563eb; }\n .toolbar-btn.secondary { background: #475569; }\n .toolbar-btn.secondary:hover { background: #64748b; }\n .toolbar-btn.freeze { background: #475569; }\n .toolbar-btn.freeze:hover { background: #64748b; }\n .toolbar-btn.freeze.active { background: #f59e0b; color: #1e293b; }\n .toolbar-btn.freeze.active:hover { background: #d97706; }\n .toolbar-label {\n color: #94a3b8;\n font-size: 12px;\n padding: 0 4px;\n }\n .badge {\n display: inline-block;\n background: #f59e0b;\n color: #1e293b;\n font-size: 10px;\n font-weight: 700;\n padding: 1px 5px;\n border-radius: 10px;\n margin-left: 4px;\n }\n .badge.hidden { display: none; }\n .divider {\n width: 1px;\n height: 20px;\n background: #334155;\n }\n `;\n shadow.appendChild(style);\n\n const toolbar = document.createElement('div');\n toolbar.className = 'toolbar';\n toolbar.innerHTML = `\n <span class=\"toolbar-label\">UI Context</span>\n <div class=\"divider\"></div>\n <button class=\"toolbar-btn capture\">Capture</button>\n <button class=\"toolbar-btn secondary capture-all\" style=\"display:none\">Capture All <span class=\"badge hidden\">0</span></button>\n <div class=\"divider\"></div>\n <button class=\"toolbar-btn freeze\" title=\"Freeze DOM (Ctrl+Shift+F)\">Freeze</button>\n <button class=\"toolbar-btn secondary close\">\\u2715</button>\n `;\n shadow.appendChild(toolbar);\n\n const captureBtn = toolbar.querySelector('.capture') as HTMLButtonElement;\n const captureAllBtn = toolbar.querySelector('.capture-all') as HTMLButtonElement;\n const freezeBtn = toolbar.querySelector('.freeze') as HTMLButtonElement;\n const closeBtn = toolbar.querySelector('.close') as HTMLButtonElement;\n const badge = toolbar.querySelector('.badge') as HTMLSpanElement;\n\n captureBtn.addEventListener('click', opts.onCapture);\n captureAllBtn.addEventListener('click', () => opts.onCaptureAll?.());\n freezeBtn.addEventListener('click', () => opts.onFreeze?.());\n closeBtn.addEventListener('click', opts.onClose);\n\n return {\n el: host,\n destroy() { host.remove(); },\n updateBadge(count: number) {\n if (count > 0) {\n captureAllBtn.style.display = '';\n badge.textContent = String(count);\n badge.classList.remove('hidden');\n } else {\n captureAllBtn.style.display = 'none';\n badge.classList.add('hidden');\n }\n },\n updateFreezeState(frozen: boolean) {\n if (frozen) {\n freezeBtn.classList.add('active');\n freezeBtn.textContent = 'Frozen';\n } else {\n freezeBtn.classList.remove('active');\n freezeBtn.textContent = 'Freeze';\n }\n },\n };\n}\n","export function extractComponentHierarchy(el: HTMLElement): string[] {\n const fiber = getFiber(el);\n if (!fiber) return [];\n\n const hierarchy: string[] = [];\n let current = fiber;\n\n while (current) {\n if (typeof current.type === 'function' || typeof current.type === 'object') {\n const name = typeof current.type === 'function'\n ? current.type.displayName || current.type.name\n : current.type?.displayName || current.type?.render?.displayName || current.type?.render?.name;\n if (name && !name.startsWith('_') && name !== 'Fragment') {\n hierarchy.unshift(name);\n }\n }\n current = current.return;\n }\n\n return hierarchy;\n}\n\nfunction getFiber(el: HTMLElement): any {\n const key = Object.keys(el).find(\n k => k.startsWith('__reactFiber$') || k.startsWith('__reactInternalInstance$')\n );\n return key ? (el as any)[key] : null;\n}\n","import { ElementContext, SourceLocation } from './types';\nimport { extractComponentHierarchy } from './fiber-walker';\n\nconst STYLE_PROPERTIES = [\n 'padding', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft',\n 'margin', 'marginTop', 'marginRight', 'marginBottom', 'marginLeft',\n 'backgroundColor', 'color', 'fontSize', 'fontWeight', 'fontFamily',\n 'borderRadius', 'display', 'flexDirection', 'justifyContent', 'alignItems',\n 'gap', 'width', 'height', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight',\n 'overflow', 'position', 'zIndex', 'opacity', 'border', 'boxShadow',\n 'lineHeight', 'letterSpacing', 'textAlign',\n];\n\nexport function extractSource(el: HTMLElement): SourceLocation | null {\n const file = el.getAttribute('data-source-file');\n const line = el.getAttribute('data-source-line');\n const col = el.getAttribute('data-source-col');\n if (!file || !line) return null;\n return {\n file,\n line: parseInt(line, 10),\n col: parseInt(col || '0', 10),\n component: el.getAttribute('data-source-component') || undefined,\n };\n}\n\nexport function extractContext(el: HTMLElement): ElementContext {\n const computed = getComputedStyle(el);\n const rect = el.getBoundingClientRect();\n const styles: Record<string, string> = {};\n for (const prop of STYLE_PROPERTIES) {\n const value = computed.getPropertyValue(\n prop.replace(/[A-Z]/g, m => '-' + m.toLowerCase())\n );\n if (value && value !== 'none' && value !== 'normal' && value !== 'auto' && value !== '0px' && value !== 'rgba(0, 0, 0, 0)') {\n styles[prop] = value;\n }\n }\n\n return {\n source: extractSource(el),\n tagName: el.tagName.toLowerCase(),\n classes: typeof el.className === 'string' ? el.className : '',\n computedStyles: styles,\n dimensions: { width: rect.width, height: rect.height, x: rect.x, y: rect.y },\n componentHierarchy: extractComponentHierarchy(el),\n url: window.location.href,\n };\n}\n","export async function captureElementScreenshot(el: HTMLElement): Promise<string | undefined> {\n try {\n // Use native canvas approach - works well for most elements\n // without requiring external dependencies like html2canvas\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return undefined;\n\n const canvas = document.createElement('canvas');\n const dpr = window.devicePixelRatio || 1;\n const padding = 8; // visual padding around element\n\n const captureWidth = Math.ceil(rect.width + padding * 2);\n const captureHeight = Math.ceil(rect.height + padding * 2);\n\n canvas.width = captureWidth * dpr;\n canvas.height = captureHeight * dpr;\n canvas.style.width = captureWidth + 'px';\n canvas.style.height = captureHeight + 'px';\n\n const ctx = canvas.getContext('2d');\n if (!ctx) return undefined;\n\n ctx.scale(dpr, dpr);\n\n // Try using html-to-image approach via SVG foreignObject\n const screenshot = await captureViaSvgForeignObject(el, rect, ctx, canvas, padding);\n if (screenshot) return screenshot;\n\n // Fallback: capture visible viewport area containing the element\n return await captureViaRange(el, rect, canvas, ctx, padding);\n } catch {\n return undefined;\n }\n}\n\nasync function captureViaSvgForeignObject(\n el: HTMLElement,\n rect: DOMRect,\n ctx: CanvasRenderingContext2D,\n canvas: HTMLCanvasElement,\n padding: number,\n): Promise<string | undefined> {\n try {\n // Clone the element to avoid modifying the original\n const clone = el.cloneNode(true) as HTMLElement;\n\n // Copy computed styles inline\n copyComputedStyles(el, clone);\n\n const width = Math.ceil(rect.width + padding * 2);\n const height = Math.ceil(rect.height + padding * 2);\n\n const svgNs = 'http://www.w3.org/2000/svg';\n const svg = document.createElementNS(svgNs, 'svg');\n svg.setAttribute('width', String(width));\n svg.setAttribute('height', String(height));\n svg.setAttribute('xmlns', svgNs);\n\n const foreignObject = document.createElementNS(svgNs, 'foreignObject');\n foreignObject.setAttribute('width', '100%');\n foreignObject.setAttribute('height', '100%');\n\n const container = document.createElement('div');\n container.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');\n container.style.cssText = `\n width: ${width}px;\n height: ${height}px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: white;\n padding: ${padding}px;\n box-sizing: border-box;\n `;\n container.appendChild(clone);\n foreignObject.appendChild(container);\n svg.appendChild(foreignObject);\n\n const svgString = new XMLSerializer().serializeToString(svg);\n const svgBlob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' });\n const url = URL.createObjectURL(svgBlob);\n\n return new Promise<string | undefined>((resolve) => {\n const img = new Image();\n img.onload = () => {\n ctx.drawImage(img, 0, 0);\n URL.revokeObjectURL(url);\n try {\n resolve(canvas.toDataURL('image/png'));\n } catch {\n resolve(undefined);\n }\n };\n img.onerror = () => {\n URL.revokeObjectURL(url);\n resolve(undefined);\n };\n img.src = url;\n });\n } catch {\n return undefined;\n }\n}\n\nasync function captureViaRange(\n _el: HTMLElement,\n rect: DOMRect,\n canvas: HTMLCanvasElement,\n ctx: CanvasRenderingContext2D,\n padding: number,\n): Promise<string | undefined> {\n // Fallback: draw a placeholder with element info\n try {\n const width = canvas.width / (window.devicePixelRatio || 1);\n const height = canvas.height / (window.devicePixelRatio || 1);\n\n ctx.fillStyle = '#f8fafc';\n ctx.fillRect(0, 0, width, height);\n ctx.strokeStyle = '#3b82f6';\n ctx.lineWidth = 2;\n ctx.strokeRect(padding, padding, rect.width, rect.height);\n\n ctx.fillStyle = '#64748b';\n ctx.font = '11px -apple-system, BlinkMacSystemFont, sans-serif';\n ctx.fillText(\n `${Math.round(rect.width)} x ${Math.round(rect.height)}px`,\n padding + 4,\n padding + rect.height / 2 + 4,\n );\n\n return canvas.toDataURL('image/png');\n } catch {\n return undefined;\n }\n}\n\nfunction copyComputedStyles(source: HTMLElement, target: HTMLElement): void {\n const computed = getComputedStyle(source);\n const important = [\n 'display', 'width', 'height', 'padding', 'margin', 'border',\n 'border-radius', 'background', 'background-color', 'color',\n 'font-size', 'font-weight', 'font-family', 'line-height',\n 'text-align', 'box-shadow', 'opacity', 'flex-direction',\n 'justify-content', 'align-items', 'gap', 'overflow',\n ];\n for (const prop of important) {\n target.style.setProperty(prop, computed.getPropertyValue(prop));\n }\n\n // Recurse for children\n const sourceChildren = source.children;\n const targetChildren = target.children;\n for (let i = 0; i < sourceChildren.length && i < targetChildren.length; i++) {\n if (sourceChildren[i] instanceof HTMLElement && targetChildren[i] instanceof HTMLElement) {\n copyComputedStyles(sourceChildren[i] as HTMLElement, targetChildren[i] as HTMLElement);\n }\n }\n}\n","import { extractContext } from './context-extractor';\nimport { captureElementScreenshot } from './screenshot';\nimport { ElementContext } from './types';\n\ntype SelectionCallback = (context: ElementContext) => void;\ntype MultiSelectionCallback = (contexts: ElementContext[]) => void;\n\nexport function createSelectionHandler(opts: {\n onHover: (el: HTMLElement | null) => void;\n onSelect: SelectionCallback;\n onMultiSelect?: MultiSelectionCallback;\n onSelectionChange?: (count: number) => void;\n}) {\n let isActive = false;\n let selectedEl: HTMLElement | null = null;\n const multiSelected: Set<HTMLElement> = new Set();\n\n function handleMouseMove(e: MouseEvent) {\n if (!isActive) return;\n const target = e.target as HTMLElement;\n if (target.id === 'ui-context-host' || target.id === 'ui-context-toast' || target.closest('#ui-context-host')) return;\n opts.onHover(target);\n }\n\n function handleClick(e: MouseEvent) {\n if (!isActive) return;\n e.preventDefault();\n e.stopPropagation();\n\n const target = e.target as HTMLElement;\n if (target.id === 'ui-context-host' || target.closest('#ui-context-host')) return;\n\n // Shift+Click: add to multi-selection\n if (e.shiftKey) {\n if (multiSelected.has(target)) {\n multiSelected.delete(target);\n target.style.outline = '';\n } else {\n multiSelected.add(target);\n target.style.outline = '2px dashed #f59e0b';\n }\n opts.onSelectionChange?.(multiSelected.size);\n return;\n }\n\n selectedEl = target;\n const context = extractContext(target);\n\n captureElementScreenshot(target).then(screenshot => {\n if (screenshot) context.screenshotDataUrl = screenshot;\n opts.onSelect(context);\n });\n }\n\n return {\n activate() {\n isActive = true;\n document.addEventListener('mousemove', handleMouseMove, true);\n document.addEventListener('click', handleClick, true);\n document.body.style.cursor = 'crosshair';\n },\n deactivate() {\n isActive = false;\n selectedEl = null;\n // Clear multi-selection outlines\n for (const el of multiSelected) {\n el.style.outline = '';\n }\n multiSelected.clear();\n document.removeEventListener('mousemove', handleMouseMove, true);\n document.removeEventListener('click', handleClick, true);\n document.body.style.cursor = '';\n opts.onHover(null);\n },\n get isActive() { return isActive; },\n get selectedElement() { return selectedEl; },\n get multiSelectedElements() { return multiSelected; },\n get multiSelectedCount() { return multiSelected.size; },\n\n async captureMultiSelection(): Promise<ElementContext[]> {\n const contexts: ElementContext[] = [];\n for (const el of multiSelected) {\n const ctx = extractContext(el);\n const screenshot = await captureElementScreenshot(el);\n if (screenshot) ctx.screenshotDataUrl = screenshot;\n contexts.push(ctx);\n }\n return contexts;\n },\n\n clearMultiSelection() {\n for (const el of multiSelected) {\n el.style.outline = '';\n }\n multiSelected.clear();\n opts.onSelectionChange?.(0);\n },\n };\n}\n","import { ElementContext } from './types';\n\nlet ws: WebSocket | null = null;\nlet wsUrl = '';\n\nexport function initTransport(url?: string) {\n wsUrl = url || `ws://${location.hostname}:${location.port}`;\n}\n\nexport function sendContext(context: ElementContext | ElementContext[]): Promise<boolean> {\n return new Promise((resolve) => {\n try {\n // Use Vite's built-in HMR WebSocket if available\n if (typeof import.meta !== 'undefined' && (import.meta as any).hot) {\n (import.meta as any).hot.send('ui-context:capture', context);\n resolve(true);\n return;\n }\n\n // Fallback: direct WebSocket\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n ws = new WebSocket(wsUrl);\n ws.onopen = () => {\n ws!.send(JSON.stringify({ type: 'ui-context:capture', data: context }));\n resolve(true);\n };\n ws.onerror = () => resolve(false);\n } else {\n ws.send(JSON.stringify({ type: 'ui-context:capture', data: context }));\n resolve(true);\n }\n } catch {\n resolve(false);\n }\n });\n}\n","const STORAGE_KEY = 'ui-context-kit-onboarding-dismissed';\n\nexport function showOnboarding(shortcut: string): void {\n // Don't show if already dismissed\n try {\n if (localStorage.getItem(STORAGE_KEY)) return;\n } catch {\n return; // localStorage not available\n }\n\n const host = document.createElement('div');\n host.style.cssText = 'position:fixed;top:0;left:0;width:0;height:0;z-index:2147483646;';\n document.body.appendChild(host);\n\n const shadow = host.attachShadow({ mode: 'open' });\n const style = document.createElement('style');\n style.textContent = `\n .banner {\n position: fixed;\n bottom: 20px;\n left: 50%;\n transform: translateX(-50%);\n background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);\n border: 1px solid #334155;\n border-radius: 12px;\n padding: 12px 20px;\n display: flex;\n gap: 12px;\n align-items: center;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n box-shadow: 0 8px 32px rgba(0,0,0,0.4);\n animation: slideUp 0.4s ease;\n max-width: 480px;\n }\n @keyframes slideUp {\n from { opacity: 0; transform: translateX(-50%) translateY(20px); }\n to { opacity: 1; transform: translateX(-50%) translateY(0); }\n }\n .icon {\n font-size: 20px;\n flex-shrink: 0;\n }\n .text {\n color: #e2e8f0;\n font-size: 13px;\n line-height: 1.4;\n }\n .text strong {\n color: #60a5fa;\n }\n .kbd {\n display: inline-block;\n background: #334155;\n color: #e2e8f0;\n padding: 1px 6px;\n border-radius: 4px;\n font-size: 12px;\n font-family: monospace;\n border: 1px solid #475569;\n }\n .close-btn {\n background: none;\n border: none;\n color: #64748b;\n cursor: pointer;\n padding: 4px;\n font-size: 16px;\n flex-shrink: 0;\n }\n .close-btn:hover { color: #94a3b8; }\n `;\n shadow.appendChild(style);\n\n const shortcutDisplay = shortcut.split('+').map(k =>\n k.charAt(0).toUpperCase() + k.slice(1)\n ).join(' + ');\n\n const banner = document.createElement('div');\n banner.className = 'banner';\n banner.innerHTML = `\n <span class=\"icon\">\\u{1F3AF}</span>\n <span class=\"text\">\n <strong>UI Context Kit</strong> is ready!\n Press <kbd class=\"kbd\">${shortcutDisplay}</kbd> to select any UI element and capture its context for AI.\n Use <strong>Shift+Click</strong> for multi-select, <strong>Ctrl+Shift+F</strong> to freeze state.\n </span>\n <button class=\"close-btn\" title=\"Dismiss\">\\u2715</button>\n `;\n shadow.appendChild(banner);\n\n banner.querySelector('.close-btn')!.addEventListener('click', () => {\n host.remove();\n try {\n localStorage.setItem(STORAGE_KEY, '1');\n } catch { /* ignore */ }\n });\n\n // Auto-dismiss after 8 seconds\n setTimeout(() => {\n if (host.parentNode) {\n banner.style.transition = 'opacity 0.3s ease';\n banner.style.opacity = '0';\n setTimeout(() => host.remove(), 300);\n }\n }, 8000);\n}\n","import { createOverlay } from './ui/overlay';\nimport { showToast } from './ui/toast';\nimport { createToolbar } from './ui/toolbar';\nimport { createSelectionHandler } from './selection';\nimport { sendContext, initTransport } from './transport';\nimport { extractContext, extractSource } from './context-extractor';\nimport { showOnboarding } from './ui/onboarding';\nimport type { ElementContext } from './types';\n\nexport type { ElementContext, SourceLocation } from './types';\n\nexport interface UIContextOptions {\n shortcut?: string;\n wsUrl?: string;\n}\n\nexport function initUIContext(options: UIContextOptions = {}) {\n const { shortcut = 'alt+x' } = options;\n\n initTransport(options.wsUrl);\n\n let overlay: ReturnType<typeof createOverlay> | null = null;\n let toolbar: ReturnType<typeof createToolbar> | null = null;\n let isFrozen = false;\n let frozenObservers: MutationObserver[] = [];\n\n const selection = createSelectionHandler({\n onHover(el) {\n if (!el) {\n overlay?.highlight(null);\n return;\n }\n const rect = el.getBoundingClientRect();\n const source = extractSource(el);\n const label = source\n ? `${source.component || el.tagName.toLowerCase()} \\u00b7 ${source.file}:${source.line}`\n : el.tagName.toLowerCase();\n overlay?.highlight(rect, label);\n },\n async onSelect(context: ElementContext) {\n showToast('Capturing context...');\n const success = await sendContext(context);\n if (success) {\n showToast('Context captured!');\n } else {\n showToast('Failed to send context. Is the dev server running?');\n }\n },\n onSelectionChange(count) {\n toolbar?.updateBadge(count);\n },\n });\n\n function activate() {\n if (selection.isActive) return;\n overlay = createOverlay();\n toolbar = createToolbar({\n onCapture() {\n if (selection.selectedElement) {\n const context = extractContext(selection.selectedElement);\n sendContext(context);\n }\n },\n async onCaptureAll() {\n if (selection.multiSelectedCount === 0) {\n showToast('No elements selected. Use Shift+Click to select multiple.');\n return;\n }\n showToast(`Capturing ${selection.multiSelectedCount} elements...`);\n const contexts = await selection.captureMultiSelection();\n const success = await sendContext(contexts);\n if (success) {\n showToast(`${contexts.length} elements captured!`);\n selection.clearMultiSelection();\n } else {\n showToast('Failed to send context. Is the dev server running?');\n }\n },\n onClose() { deactivate(); },\n onFreeze() { toggleFreeze(); },\n });\n selection.activate();\n showToast('UI Context active \\u2014 click to capture, Shift+click for multi-select');\n }\n\n function deactivate() {\n if (isFrozen) unfreezeDOM();\n selection.deactivate();\n overlay?.destroy();\n toolbar?.destroy();\n overlay = null;\n toolbar = null;\n }\n\n function toggleFreeze() {\n if (isFrozen) {\n unfreezeDOM();\n showToast('DOM unfrozen');\n } else {\n freezeDOM();\n showToast('DOM frozen \\u2014 hover states preserved');\n }\n toolbar?.updateFreezeState(isFrozen);\n }\n\n function freezeDOM() {\n isFrozen = true;\n // Disconnect all existing MutationObservers by creating a blocking one\n // This prevents DOM updates (dropdowns closing, tooltips hiding, etc.)\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n // Revert added/removed nodes\n for (const node of mutation.addedNodes) {\n if (node instanceof HTMLElement && !node.id?.includes('ui-context')) {\n node.remove();\n }\n }\n // Revert attribute changes\n if (mutation.type === 'attributes' && mutation.target instanceof HTMLElement) {\n if (!mutation.target.id?.includes('ui-context')) {\n const old = mutation.oldValue;\n if (old !== null) {\n mutation.target.setAttribute(mutation.attributeName!, old);\n }\n }\n }\n }\n });\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeOldValue: true,\n });\n frozenObservers.push(observer);\n }\n\n function unfreezeDOM() {\n isFrozen = false;\n for (const obs of frozenObservers) {\n obs.disconnect();\n }\n frozenObservers = [];\n }\n\n // Register keyboard shortcuts\n document.addEventListener('keydown', (e) => {\n // Main shortcut (Alt+X)\n const keys = shortcut.split('+');\n const needsAlt = keys.includes('alt');\n const needsCtrl = keys.includes('ctrl');\n const needsShift = keys.includes('shift');\n const mainKey = keys[keys.length - 1].toLowerCase();\n\n if (\n e.altKey === needsAlt &&\n e.ctrlKey === needsCtrl &&\n e.shiftKey === needsShift &&\n e.key.toLowerCase() === mainKey\n ) {\n e.preventDefault();\n if (selection.isActive) {\n deactivate();\n } else {\n activate();\n }\n return;\n }\n\n // Freeze shortcut: Ctrl+Shift+F (only when active)\n if (selection.isActive && e.ctrlKey && e.shiftKey && e.key.toLowerCase() === 'f') {\n e.preventDefault();\n toggleFreeze();\n }\n });\n\n // Show onboarding on first use\n showOnboarding(shortcut);\n\n return { activate, deactivate };\n}\n","import { initUIContext } from './index';\n\n// Auto-initialize when loaded\nif (typeof window !== 'undefined') {\n (window as any).__uiContext = initUIContext();\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/inject.js ADDED
@@ -0,0 +1,9 @@
1
+ import {
2
+ initUIContext
3
+ } from "./chunk-ISOPDZ5A.js";
4
+
5
+ // src/inject.ts
6
+ if (typeof window !== "undefined") {
7
+ window.__uiContext = initUIContext();
8
+ }
9
+ //# sourceMappingURL=inject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/inject.ts"],"sourcesContent":["import { initUIContext } from './index';\n\n// Auto-initialize when loaded\nif (typeof window !== 'undefined') {\n (window as any).__uiContext = initUIContext();\n}\n"],"mappings":";;;;;AAGA,IAAI,OAAO,WAAW,aAAa;AACjC,EAAC,OAAe,cAAc,cAAc;AAC9C;","names":[]}