uilint-react 0.2.9 → 0.2.11

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.
Files changed (50) hide show
  1. package/README.md +35 -31
  2. package/dist/DevTool.d.ts +3 -3
  3. package/dist/DevTool.d.ts.map +1 -1
  4. package/dist/components/ui-lint/ElementBadges.d.ts.map +1 -1
  5. package/dist/components/ui-lint/InspectionPanel.d.ts.map +1 -1
  6. package/dist/components/ui-lint/LocatorOverlay.d.ts.map +1 -1
  7. package/dist/components/ui-lint/ScanResultsPopover.d.ts.map +1 -1
  8. package/dist/components/ui-lint/UILintUI.d.ts +5 -0
  9. package/dist/components/ui-lint/UILintUI.d.ts.map +1 -0
  10. package/dist/components/ui-lint/hooks/index.d.ts +4 -0
  11. package/dist/components/ui-lint/hooks/index.d.ts.map +1 -0
  12. package/dist/components/ui-lint/hooks/useAutoScans.d.ts +5 -0
  13. package/dist/components/ui-lint/hooks/useAutoScans.d.ts.map +1 -0
  14. package/dist/components/ui-lint/hooks/useDevToolEventHandlers.d.ts +5 -0
  15. package/dist/components/ui-lint/hooks/useDevToolEventHandlers.d.ts.map +1 -0
  16. package/dist/components/ui-lint/hooks/useNavigationDetection.d.ts +6 -0
  17. package/dist/components/ui-lint/hooks/useNavigationDetection.d.ts.map +1 -0
  18. package/dist/components/ui-lint/index.d.ts +1 -2
  19. package/dist/components/ui-lint/index.d.ts.map +1 -1
  20. package/dist/components/ui-lint/store.d.ts +18 -6
  21. package/dist/components/ui-lint/store.d.ts.map +1 -1
  22. package/dist/components/ui-lint/toolbar/icons.d.ts +4 -0
  23. package/dist/components/ui-lint/toolbar/icons.d.ts.map +1 -1
  24. package/dist/components/ui-lint/toolbar/index.d.ts.map +1 -1
  25. package/dist/components/ui-lint/toolbar/tabs/ConfigureTab.d.ts.map +1 -1
  26. package/dist/components/ui-lint/toolbar/tabs/ESLintTab.d.ts.map +1 -1
  27. package/dist/components/ui-lint/toolbar/tabs/VisionTab.d.ts.map +1 -1
  28. package/dist/components/ui-lint/types.d.ts +80 -35
  29. package/dist/components/ui-lint/types.d.ts.map +1 -1
  30. package/dist/devtools-types.d.ts +31 -0
  31. package/dist/devtools.js +93 -93
  32. package/dist/devtools.js.map +1 -1
  33. package/dist/index.d.ts +2 -2
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +12953 -42
  36. package/dist/index.js.map +1 -1
  37. package/dist/scanner/vision-capture.d.ts +1 -1
  38. package/dist/scanner/vision-capture.d.ts.map +1 -1
  39. package/dist/{vision-capture-EIrYA_XF.js → vision-capture-l4ZJB8M8.js} +89 -76
  40. package/dist/vision-capture-l4ZJB8M8.js.map +1 -0
  41. package/package.json +5 -4
  42. package/dist/ElementBadges-H5_y7fLt.js +0 -672
  43. package/dist/ElementBadges-H5_y7fLt.js.map +0 -1
  44. package/dist/VisionIssueBadge-Bw_1zmLh.js +0 -154
  45. package/dist/VisionIssueBadge-Bw_1zmLh.js.map +0 -1
  46. package/dist/components/ui-lint/UILintProvider.d.ts +0 -11
  47. package/dist/components/ui-lint/UILintProvider.d.ts.map +0 -1
  48. package/dist/index-Cu1-cGo1.js +0 -12839
  49. package/dist/index-Cu1-cGo1.js.map +0 -1
  50. package/dist/vision-capture-EIrYA_XF.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"ElementBadges-H5_y7fLt.js","sources":["../src/components/ui-lint/badge-layout.ts","../src/components/ui-lint/visibility-utils.ts","../src/components/ui-lint/ElementBadges.tsx"],"sourcesContent":["/**\n * Badge Layout - Force-directed algorithm for positioning badges\n *\n * Uses a force simulation to nudge overlapping badges apart while\n * keeping them anchored near their original positions.\n */\n\nimport type { ScannedElement, ElementIssue } from \"./types\";\n\n/**\n * Input badge position (from DOM element positions)\n */\nexport interface BadgePosition {\n element: ScannedElement;\n issue: ElementIssue;\n x: number;\n y: number;\n rect: DOMRect;\n}\n\n/**\n * Output badge position with nudged coordinates\n */\nexport interface NudgedBadgePosition extends BadgePosition {\n nudgedX: number;\n nudgedY: number;\n}\n\n/**\n * Configuration for the layout algorithm\n */\nexport interface LayoutConfig {\n /** How strongly badges push apart (default: 50) */\n repulsionForce: number;\n /** How strongly badges stay near origin (default: 0.3) */\n anchorStrength: number;\n /** Minimum gap between badge centers (default: 24) */\n minDistance: number;\n /** Number of simulation steps (default: 50) */\n iterations: number;\n /** Velocity decay per step (default: 0.9) */\n damping: number;\n}\n\n/**\n * Default configuration values\n */\nconst DEFAULT_CONFIG: LayoutConfig = {\n repulsionForce: 50,\n anchorStrength: 0.3,\n minDistance: 24,\n iterations: 50,\n damping: 0.9,\n};\n\n/**\n * Internal state for simulation\n */\ninterface SimulationNode {\n position: BadgePosition;\n nudgedX: number;\n nudgedY: number;\n velocityX: number;\n velocityY: number;\n}\n\n/**\n * Run force-directed simulation to compute nudged positions\n */\nfunction computeLayout(\n positions: BadgePosition[],\n config: LayoutConfig\n): NudgedBadgePosition[] {\n if (positions.length === 0) return [];\n if (positions.length === 1) {\n return [\n { ...positions[0], nudgedX: positions[0].x, nudgedY: positions[0].y },\n ];\n }\n\n // Initialize simulation nodes at original locations\n const nodes: SimulationNode[] = positions.map((p) => ({\n position: p,\n nudgedX: p.x,\n nudgedY: p.y,\n velocityX: 0,\n velocityY: 0,\n }));\n\n // Run simulation iterations\n for (let iter = 0; iter < config.iterations; iter++) {\n for (let i = 0; i < nodes.length; i++) {\n let fx = 0;\n let fy = 0;\n\n // Calculate repulsion from other badges\n for (let j = 0; j < nodes.length; j++) {\n if (i === j) continue;\n\n const dx = nodes[i].nudgedX - nodes[j].nudgedX;\n const dy = nodes[i].nudgedY - nodes[j].nudgedY;\n const dist = Math.max(Math.hypot(dx, dy), 1);\n\n // Only apply repulsion when within minimum distance\n if (dist < config.minDistance) {\n const force = config.repulsionForce / (dist * dist);\n fx += (dx / dist) * force;\n fy += (dy / dist) * force;\n }\n }\n\n // Calculate anchor attraction (spring back to original position)\n const anchorDx = positions[i].x - nodes[i].nudgedX;\n const anchorDy = positions[i].y - nodes[i].nudgedY;\n fx += anchorDx * config.anchorStrength;\n fy += anchorDy * config.anchorStrength;\n\n // Apply forces with damping\n nodes[i].velocityX = (nodes[i].velocityX + fx) * config.damping;\n nodes[i].velocityY = (nodes[i].velocityY + fy) * config.damping;\n nodes[i].nudgedX += nodes[i].velocityX;\n nodes[i].nudgedY += nodes[i].velocityY;\n }\n }\n\n // Return nudged positions\n return nodes.map((node) => ({\n ...node.position,\n nudgedX: node.nudgedX,\n nudgedY: node.nudgedY,\n }));\n}\n\n/**\n * Builder class for configuring and running badge layout\n *\n * Example usage:\n * ```ts\n * const nudged = BadgeLayoutBuilder\n * .create(positions)\n * .minDistance(24)\n * .repulsion(50)\n * .anchorStrength(0.3)\n * .iterations(50)\n * .compute();\n * ```\n */\nexport class BadgeLayoutBuilder {\n private config: LayoutConfig;\n private positions: BadgePosition[];\n\n private constructor(positions: BadgePosition[]) {\n this.positions = positions;\n this.config = { ...DEFAULT_CONFIG };\n }\n\n /**\n * Create a new layout builder with badge positions\n */\n static create(positions: BadgePosition[]): BadgeLayoutBuilder {\n return new BadgeLayoutBuilder(positions);\n }\n\n /**\n * Set the repulsion force (how strongly badges push apart)\n * Higher values = badges spread more aggressively\n */\n repulsion(force: number): this {\n this.config.repulsionForce = force;\n return this;\n }\n\n /**\n * Set the anchor strength (how strongly badges stay near origin)\n * Higher values = badges stay closer to their original positions\n */\n anchorStrength(strength: number): this {\n this.config.anchorStrength = strength;\n return this;\n }\n\n /**\n * Set the minimum distance between badge centers\n * Badges closer than this will be pushed apart\n */\n minDistance(distance: number): this {\n this.config.minDistance = distance;\n return this;\n }\n\n /**\n * Set the number of simulation iterations\n * More iterations = more stable but slower\n */\n iterations(count: number): this {\n this.config.iterations = count;\n return this;\n }\n\n /**\n * Set the damping factor (velocity decay per step)\n * Lower values = system settles faster but may be less stable\n */\n damping(factor: number): this {\n this.config.damping = factor;\n return this;\n }\n\n /**\n * Run the simulation and return nudged positions\n */\n compute(): NudgedBadgePosition[] {\n return computeLayout(this.positions, this.config);\n }\n}\n\n/**\n * Find badges that are close to a given position\n * Useful for showing dropdowns when hovering near multiple badges\n */\nexport function findNearbyBadges(\n positions: NudgedBadgePosition[],\n x: number,\n y: number,\n threshold: number\n): NudgedBadgePosition[] {\n return positions.filter((p) => {\n const dist = Math.hypot(p.nudgedX - x, p.nudgedY - y);\n return dist <= threshold;\n });\n}\n","/**\n * Visibility utilities for detecting when elements are covered by overlays\n *\n * Used to hide UILint badges when app modals/overlays cover the underlying elements.\n */\n\ntype Rect = {\n top: number;\n left: number;\n right: number;\n bottom: number;\n width: number;\n height: number;\n};\n\nfunction rectFromLTRB(\n left: number,\n top: number,\n right: number,\n bottom: number\n): Rect {\n const width = Math.max(0, right - left);\n const height = Math.max(0, bottom - top);\n return { left, top, right, bottom, width, height };\n}\n\nfunction intersectRects(a: Rect, b: Rect): Rect | null {\n const left = Math.max(a.left, b.left);\n const top = Math.max(a.top, b.top);\n const right = Math.min(a.right, b.right);\n const bottom = Math.min(a.bottom, b.bottom);\n if (right <= left || bottom <= top) return null;\n return rectFromLTRB(left, top, right, bottom);\n}\n\nfunction isOverflowClipping(style: CSSStyleDeclaration): boolean {\n const vals = [style.overflow, style.overflowX, style.overflowY];\n // \"visible\" means no clipping, everything else can clip to some extent.\n return vals.some((v) => v && v !== \"visible\");\n}\n\n/**\n * Compute the visible portion of an element in viewport coordinates.\n *\n * This accounts for:\n * - viewport bounds\n * - ancestor overflow clipping (scroll/hidden/auto/clip)\n *\n * Returns null when no visible area remains.\n */\nexport function getElementVisibleRect(element: Element): Rect | null {\n const el = element as HTMLElement;\n const base = el.getBoundingClientRect();\n let visible: Rect | null = rectFromLTRB(\n base.left,\n base.top,\n base.right,\n base.bottom\n );\n\n // Intersect with viewport\n const viewport = rectFromLTRB(0, 0, window.innerWidth, window.innerHeight);\n visible = intersectRects(visible, viewport);\n if (!visible) return null;\n\n // Intersect with overflow clipping ancestors\n let cur: HTMLElement | null = el.parentElement;\n while (cur) {\n const style = window.getComputedStyle(cur);\n if (isOverflowClipping(style)) {\n const r = cur.getBoundingClientRect();\n const clip = rectFromLTRB(r.left, r.top, r.right, r.bottom);\n visible = intersectRects(visible, clip);\n if (!visible) return null;\n }\n cur = cur.parentElement;\n }\n\n return visible;\n}\n\n/**\n * Check if an element is covered by an overlay (modal, popover, etc.)\n * at a specific point (typically the badge position).\n *\n * Uses elementsFromPoint() to detect all elements at the given coordinates\n * and checks if any non-UILint overlay element is covering the target.\n *\n * IMPORTANT: Elements that are children/descendants of an overlay are NOT considered\n * \"covered\" - they should show badges since the overlay is their container, not a cover.\n *\n * @param element - The target element that should be checked for coverage\n * @param badgeX - X coordinate of the badge position (in viewport coordinates)\n * @param badgeY - Y coordinate of the badge position (in viewport coordinates)\n * @returns true if the element is covered by an overlay, false otherwise\n */\nexport function isElementCoveredByOverlay(\n element: Element,\n badgeX: number,\n badgeY: number\n): boolean {\n // Get all elements at this point, ordered from front to back\n const elementsAtPoint = document.elementsFromPoint(badgeX, badgeY);\n\n for (const el of elementsAtPoint) {\n // Skip UILint elements - they shouldn't hide badges\n if (el.hasAttribute(\"data-ui-lint\")) continue;\n\n // If we hit the element itself, a descendant, or an ancestor container,\n // then anything further \"behind\" in the stack cannot be covering it.\n //\n // This is critical for modal dialogs: the backdrop is often behind the dialog,\n // but still shows up in elementsFromPoint(). We must stop before we reach it.\n if (el === element || element.contains(el) || el.contains(element)) {\n return false;\n }\n\n // Check if this element is an overlay\n // Overlays typically have fixed/absolute positioning with a z-index\n const style = window.getComputedStyle(el);\n const position = style.position;\n const zIndex = parseInt(style.zIndex, 10);\n\n // Consider it an overlay if:\n // 1. It's positioned (fixed or absolute) - these are commonly used for overlays\n // 2. It has a positive z-index (or auto/inherit which might still stack)\n // 3. It's not static positioned (which wouldn't create a stacking context)\n const isOverlay =\n (position === \"fixed\" || position === \"absolute\") &&\n (zIndex > 0 || style.zIndex === \"auto\" || style.zIndex === \"inherit\");\n\n if (isOverlay) {\n return true;\n }\n }\n\n return false;\n}\n","\"use client\";\n\n/**\n * ElementBadges - Shows issue count badges on scanned elements\n *\n * Renders notification-style badges at the top-right corner of each\n * scanned element during auto-scan mode.\n */\n\nimport React, { useState, useEffect, useCallback, useMemo } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useUILintContext } from \"./UILintProvider\";\nimport { useUILintStore, type UILintStore } from \"./store\";\nimport type { ScannedElement, ElementIssue, InspectedElement } from \"./types\";\nimport { getUILintPortalHost } from \"./portal-host\";\nimport {\n BadgeLayoutBuilder,\n findNearbyBadges,\n type BadgePosition,\n type NudgedBadgePosition,\n} from \"./badge-layout\";\nimport {\n getElementVisibleRect,\n isElementCoveredByOverlay,\n} from \"./visibility-utils\";\n\n/**\n * Design tokens - uses CSS variables for theme support\n */\nconst STYLES = {\n bg: \"var(--uilint-backdrop)\",\n success: \"var(--uilint-success)\",\n warning: \"var(--uilint-warning)\",\n error: \"var(--uilint-error)\",\n text: \"var(--uilint-text-primary)\",\n border: \"var(--uilint-border)\",\n highlight: \"var(--uilint-accent)\",\n font: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n shadow: \"var(--uilint-shadow)\",\n};\n\n/**\n * Proximity scaling constants\n * Badges scale from MIN_SCALE at FAR_DISTANCE to MAX_SCALE at NEAR_DISTANCE\n */\nconst NEAR_DISTANCE = 0;\nconst FAR_DISTANCE = 150;\nconst MIN_SCALE = 0.5;\nconst MAX_SCALE = 1.0;\n\n/**\n * Calculate scale factor based on distance from cursor\n */\nfunction getScaleFromDistance(distance: number): number {\n if (distance <= NEAR_DISTANCE) return MAX_SCALE;\n if (distance >= FAR_DISTANCE) return MIN_SCALE;\n // Linear interpolation\n const t = (distance - NEAR_DISTANCE) / (FAR_DISTANCE - NEAR_DISTANCE);\n return MAX_SCALE - t * (MAX_SCALE - MIN_SCALE);\n}\n\n/**\n * Get badge color based on issue count\n */\nfunction getBadgeColor(issueCount: number): string {\n if (issueCount === 0) return STYLES.success;\n return STYLES.warning; // Amber for all issues\n}\n\n/**\n * Format element label as \"tag > Filename.tsx\"\n */\nfunction formatElementLabel(element: ScannedElement): string {\n const tag = element.tagName.toLowerCase();\n const source = element.source;\n\n if (source) {\n const fileName = source.fileName.split(\"/\").pop() || \"Unknown\";\n return `${tag} > ${fileName}`;\n }\n\n return tag;\n}\n\n/**\n * Threshold for detecting nearby badges (for dropdown grouping)\n */\nconst NEARBY_THRESHOLD = 30;\n\n/**\n * Minimum distance from window edge before snapping badge to be fully visible\n */\nconst WINDOW_EDGE_THRESHOLD = 20;\n\n/**\n * Badge size for collision detection with window bounds\n */\nconst BADGE_SIZE = 18;\n\n/**\n * Snap badge position to be fully visible within window bounds\n */\nfunction snapToWindowBounds(x: number, y: number): { x: number; y: number } {\n const minX = WINDOW_EDGE_THRESHOLD;\n const maxX = window.innerWidth - BADGE_SIZE - WINDOW_EDGE_THRESHOLD;\n const minY = WINDOW_EDGE_THRESHOLD;\n const maxY = window.innerHeight - BADGE_SIZE - WINDOW_EDGE_THRESHOLD;\n\n return {\n x: Math.max(minX, Math.min(maxX, x)),\n y: Math.max(minY, Math.min(maxY, y)),\n };\n}\n\n/**\n * Determine if a badge should be shown based on its status and alt key state\n * - Green badges (no issues): never show (optimization: skip rendering entirely)\n * - Progress badges (scanning/pending): only show when alt/option is held\n * - Issue badges (error or issues > 0): always show\n */\nfunction shouldShowBadge(\n issue: ElementIssue,\n isAltKeyPressed: boolean\n): boolean {\n // Never show green badges (no issues) - optimization to skip rendering\n if (issue.status === \"complete\" && issue.issues.length === 0) {\n return false;\n }\n\n // Always show badges with issues\n if (issue.status === \"error\") return true;\n if (issue.status === \"complete\" && issue.issues.length > 0) return true;\n\n // Only show progress badges (scanning/pending) when alt/option is held\n if (issue.status === \"scanning\" || issue.status === \"pending\") {\n return isAltKeyPressed;\n }\n\n return false;\n}\n\n/**\n * Global CSS for badge animations (injected once)\n */\nfunction BadgeAnimationStyles() {\n return (\n <style>{`\n @keyframes uilint-badge-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `}</style>\n );\n}\n\n/**\n * Main ElementBadges component\n */\nexport function ElementBadges() {\n const { autoScanState, elementIssuesCache, setInspectedElement } =\n useUILintContext();\n const [mounted, setMounted] = useState(false);\n const [cursorPos, setCursorPos] = useState({ x: 0, y: 0 });\n const [badgePositions, setBadgePositions] = useState<BadgePosition[]>([]);\n const [isAltKeyPressed, setIsAltKeyPressed] = useState(false);\n\n // Get file filtering state from store\n const hoveredFilePath = useUILintStore((s: UILintStore) => s.hoveredFilePath);\n const selectedFilePath = useUILintStore(\n (s: UILintStore) => s.selectedFilePath\n );\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n // Track alt/option key state\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.altKey) {\n setIsAltKeyPressed(true);\n }\n };\n const handleKeyUp = (e: KeyboardEvent) => {\n if (!e.altKey) {\n setIsAltKeyPressed(false);\n }\n };\n const handleBlur = () => {\n // Reset alt key state when window loses focus\n setIsAltKeyPressed(false);\n };\n window.addEventListener(\"keydown\", handleKeyDown);\n window.addEventListener(\"keyup\", handleKeyUp);\n window.addEventListener(\"blur\", handleBlur);\n return () => {\n window.removeEventListener(\"keydown\", handleKeyDown);\n window.removeEventListener(\"keyup\", handleKeyUp);\n window.removeEventListener(\"blur\", handleBlur);\n };\n }, []);\n\n // Track cursor position\n useEffect(() => {\n const handleMouseMove = (e: MouseEvent) => {\n setCursorPos({ x: e.clientX, y: e.clientY });\n };\n window.addEventListener(\"mousemove\", handleMouseMove);\n return () => window.removeEventListener(\"mousemove\", handleMouseMove);\n }, []);\n\n // Calculate badge positions\n useEffect(() => {\n if (autoScanState.status === \"idle\") {\n setBadgePositions([]);\n return;\n }\n\n const updatePositions = () => {\n const positions: BadgePosition[] = [];\n for (const element of autoScanState.elements) {\n const issue = elementIssuesCache.get(element.id);\n if (!issue) continue;\n if (!element.element || !document.contains(element.element)) continue;\n\n const rect = element.element.getBoundingClientRect();\n const visible = getElementVisibleRect(element.element);\n if (!visible) continue;\n\n // Badge is positioned near the top-right corner, but clamped to stay\n // within the visible (non-clipped) portion of the element.\n const desiredX = rect.right - 8;\n const desiredY = rect.top - 8;\n const x = Math.min(desiredX, visible.right - 8);\n const y = Math.max(visible.top + 2, desiredY);\n\n // Check if element is covered by an overlay (modal, popover, etc.)\n // Use a point INSIDE the visible portion of the element to avoid\n // false positives from backdrops behind modal containers.\n const testX = visible.left + Math.min(8, visible.width / 2);\n const testY = visible.top + Math.min(8, visible.height / 2);\n if (isElementCoveredByOverlay(element.element, testX, testY)) {\n continue;\n }\n\n // Use the visible rect for drawing/hover highlight so it matches what the\n // user can actually see when the element is clipped by overflow containers.\n const visibleRect = DOMRect.fromRect({\n x: visible.left,\n y: visible.top,\n width: visible.width,\n height: visible.height,\n });\n\n positions.push({ element, issue, x, y, rect: visibleRect });\n }\n setBadgePositions(positions);\n };\n\n let rafId: number | null = null;\n const scheduleUpdate = () => {\n if (rafId !== null) return;\n rafId = requestAnimationFrame(() => {\n rafId = null;\n updatePositions();\n });\n };\n\n // Initial position calculation\n scheduleUpdate();\n\n // Recalculate on common viewport changes rather than every frame\n const handleScroll = () => scheduleUpdate();\n const handleResize = () => scheduleUpdate();\n const handleVisibility = () => {\n if (document.visibilityState === \"visible\") {\n scheduleUpdate();\n }\n };\n\n window.addEventListener(\"scroll\", handleScroll, true);\n window.addEventListener(\"resize\", handleResize);\n document.addEventListener(\"visibilitychange\", handleVisibility);\n\n return () => {\n if (rafId !== null) {\n cancelAnimationFrame(rafId);\n }\n window.removeEventListener(\"scroll\", handleScroll, true);\n window.removeEventListener(\"resize\", handleResize);\n document.removeEventListener(\"visibilitychange\", handleVisibility);\n };\n }, [autoScanState.status, autoScanState.elements, elementIssuesCache]);\n\n // Handle badge selection\n const handleSelect = useCallback(\n (element: ScannedElement, issue: ElementIssue) => {\n const inspected: InspectedElement = {\n element: element.element,\n source: element.source,\n rect: element.element.getBoundingClientRect(),\n scannedElementId: element.id,\n };\n setInspectedElement(inspected);\n },\n [setInspectedElement]\n );\n\n // Apply force-directed nudging to separate overlapping badges\n const nudgedPositions = useMemo(\n () =>\n BadgeLayoutBuilder.create(badgePositions)\n .minDistance(24)\n .repulsion(50)\n .anchorStrength(0.3)\n .iterations(50)\n .compute(),\n [badgePositions]\n );\n\n // Filter badges based on visibility rules (must be before conditional returns)\n const visibleBadges = useMemo(() => {\n let filtered = nudgedPositions.filter((pos) =>\n shouldShowBadge(pos.issue, isAltKeyPressed)\n );\n\n // Filter by file if hovering or selecting a file\n const activeFilePath = selectedFilePath || hoveredFilePath;\n if (activeFilePath) {\n filtered = filtered.filter(\n (pos) => pos.element.source.fileName === activeFilePath\n );\n }\n\n return filtered;\n }, [nudgedPositions, isAltKeyPressed, selectedFilePath, hoveredFilePath]);\n\n // Event handlers to prevent UILint interactions from propagating to the app\n const handleUILintInteraction = useCallback(\n (e: React.MouseEvent | React.KeyboardEvent | React.PointerEvent) => {\n e.stopPropagation();\n },\n []\n );\n\n if (!mounted) return null;\n if (autoScanState.status === \"idle\") return null;\n\n const content = (\n <div\n data-ui-lint\n onMouseDown={handleUILintInteraction}\n onPointerDown={handleUILintInteraction}\n onClick={handleUILintInteraction}\n onKeyDown={handleUILintInteraction}\n style={{ pointerEvents: \"none\" }}\n >\n <BadgeAnimationStyles />\n {visibleBadges\n // Defensive: in case upstream ever returns duplicate IDs, avoid\n // React duplicate-key warnings and layout duplication.\n .filter((pos, idx, arr) => {\n const id = pos.element.id;\n return arr.findIndex((p) => p.element.id === id) === idx;\n })\n .map((nudgedPos) => {\n const distance = Math.hypot(\n nudgedPos.nudgedX - cursorPos.x,\n nudgedPos.nudgedY - cursorPos.y\n );\n\n // Find nearby badges for potential dropdown grouping (only from visible badges)\n const nearbyBadges = findNearbyBadges(\n visibleBadges,\n nudgedPos.nudgedX,\n nudgedPos.nudgedY,\n NEARBY_THRESHOLD\n );\n\n return (\n <NudgedBadge\n key={nudgedPos.element.id}\n position={nudgedPos}\n distance={distance}\n nearbyBadges={nearbyBadges}\n cursorPos={cursorPos}\n onSelect={handleSelect}\n />\n );\n })}\n </div>\n );\n\n return createPortal(content, getUILintPortalHost());\n}\n\n/**\n * Badge at nudged position with optional dropdown for nearby badges\n */\ninterface NudgedBadgeProps {\n position: NudgedBadgePosition;\n distance: number;\n nearbyBadges: NudgedBadgePosition[];\n cursorPos: { x: number; y: number };\n onSelect: (element: ScannedElement, issue: ElementIssue) => void;\n}\n\nfunction NudgedBadge({\n position,\n distance,\n nearbyBadges,\n cursorPos,\n onSelect,\n}: NudgedBadgeProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);\n const closeTimeoutRef = React.useRef<NodeJS.Timeout | null>(null);\n\n const { element, issue, rect, nudgedX, nudgedY } = position;\n const hasNearbyBadges = nearbyBadges.length > 1;\n\n // Snap badge position to stay within window bounds\n const snappedPosition = useMemo(\n () => snapToWindowBounds(nudgedX, nudgedY),\n [nudgedX, nudgedY]\n );\n\n // Calculate badge color based on issue status\n const badgeColor = useMemo(() => {\n if (issue.status === \"error\") return STYLES.error;\n if (issue.status === \"scanning\") return STYLES.highlight;\n if (issue.status === \"pending\") return \"rgba(156, 163, 175, 0.7)\";\n if (issue.status === \"complete\") {\n return getBadgeColor(issue.issues.length);\n }\n return STYLES.success;\n }, [issue]);\n\n const handleMouseEnter = useCallback(() => {\n if (closeTimeoutRef.current) {\n clearTimeout(closeTimeoutRef.current);\n closeTimeoutRef.current = null;\n }\n setIsExpanded(true);\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n closeTimeoutRef.current = setTimeout(() => {\n setIsExpanded(false);\n setHoveredIndex(null);\n }, 150);\n }, []);\n\n const handleClick = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onSelect(element, issue);\n },\n [element, issue, onSelect]\n );\n\n // Get the hovered element's rect for highlighting\n const hoveredBadge = useMemo(() => {\n if (hoveredIndex === null) return null;\n return nearbyBadges[hoveredIndex] ?? null;\n }, [hoveredIndex, nearbyBadges]);\n\n // Position dropdown to avoid going off-screen\n const dropdownStyle = useMemo((): React.CSSProperties => {\n const preferRight = snappedPosition.x < window.innerWidth - 220;\n const preferBelow = snappedPosition.y < window.innerHeight - 200;\n\n return {\n position: \"fixed\",\n top: preferBelow ? snappedPosition.y + 12 : undefined,\n bottom: preferBelow\n ? undefined\n : window.innerHeight - snappedPosition.y + 12,\n left: preferRight ? snappedPosition.x - 8 : undefined,\n right: preferRight\n ? undefined\n : window.innerWidth - snappedPosition.x - 8,\n zIndex: 100000,\n backgroundColor: STYLES.bg,\n borderRadius: \"8px\",\n border: `1px solid ${STYLES.border}`,\n boxShadow: \"0 4px 20px rgba(0, 0, 0, 0.4)\",\n padding: \"4px 0\",\n minWidth: \"200px\",\n fontFamily: STYLES.font,\n pointerEvents: \"auto\", // Re-enable pointer events for interactive dropdown\n };\n }, [snappedPosition]);\n\n // Calculate scale based on distance (hover overrides to full scale)\n const scale = isExpanded ? 1.1 : getScaleFromDistance(distance);\n\n // Determine what to show in badge\n const issueCount = issue.status === \"complete\" ? issue.issues.length : 0;\n\n return (\n <>\n {/* Element highlight when badge is hovered (self or from dropdown) */}\n {isExpanded && !hoveredBadge && (\n <div\n style={{\n position: \"fixed\",\n top: rect.top - 2,\n left: rect.left - 2,\n width: rect.width + 4,\n height: rect.height + 4,\n border: `2px solid ${STYLES.highlight}`,\n borderRadius: \"4px\",\n pointerEvents: \"none\",\n zIndex: 99994,\n boxShadow: `0 0 0 1px rgba(59, 130, 246, 0.3)`,\n }}\n data-ui-lint\n />\n )}\n\n {/* Highlight for hovered element in dropdown */}\n {hoveredBadge && (\n <div\n style={{\n position: \"fixed\",\n top: hoveredBadge.rect.top - 2,\n left: hoveredBadge.rect.left - 2,\n width: hoveredBadge.rect.width + 4,\n height: hoveredBadge.rect.height + 4,\n border: `2px solid ${STYLES.highlight}`,\n borderRadius: \"4px\",\n pointerEvents: \"none\",\n zIndex: 99994,\n boxShadow: `0 0 0 1px rgba(59, 130, 246, 0.3)`,\n }}\n data-ui-lint\n />\n )}\n\n {/* Circle badge at nudged position */}\n <div\n style={{\n position: \"fixed\",\n top: snappedPosition.y - 0,\n left: snappedPosition.x - 0,\n zIndex: isExpanded ? 99999 : 99995,\n cursor: \"pointer\",\n transition: \"transform 0.1s ease-out\",\n transform: `scale(${scale})`,\n transformOrigin: \"center center\",\n pointerEvents: \"auto\", // Re-enable pointer events for interactive badge\n }}\n data-ui-lint\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onClick={handleClick}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"18px\",\n height: \"18px\",\n borderRadius: \"50%\",\n backgroundColor: badgeColor,\n boxShadow: STYLES.shadow,\n border: `1px solid ${STYLES.border}`,\n }}\n >\n {issue.status === \"scanning\" ? (\n <div\n style={{\n width: \"10px\",\n height: \"10px\",\n border: \"2px solid rgba(255, 255, 255, 0.3)\",\n borderTopColor: \"#FFFFFF\",\n borderRadius: \"50%\",\n animation: \"uilint-badge-spin 0.8s linear infinite\",\n }}\n />\n ) : issue.status === \"error\" ? (\n <ExclamationIconTiny />\n ) : issue.status === \"pending\" ? (\n <div\n style={{\n width: \"6px\",\n height: \"6px\",\n borderRadius: \"50%\",\n backgroundColor: \"rgba(255, 255, 255, 0.4)\",\n }}\n />\n ) : issueCount === 0 ? (\n <CheckIconTiny />\n ) : (\n <span\n style={{\n color: STYLES.text,\n fontSize: \"10px\",\n fontWeight: 700,\n fontFamily: STYLES.font,\n }}\n >\n {issueCount > 9 ? \"9+\" : issueCount}\n </span>\n )}\n </div>\n </div>\n\n {/* Dropdown showing nearby badges when expanded and there are nearby ones */}\n {isExpanded && hasNearbyBadges && (\n <div\n style={dropdownStyle}\n data-ui-lint\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n {nearbyBadges.map((badge, index) => (\n <DropdownItem\n key={badge.element.id}\n badge={badge}\n isHovered={hoveredIndex === index}\n onMouseEnter={() => setHoveredIndex(index)}\n onMouseLeave={() => setHoveredIndex(null)}\n onClick={() => onSelect(badge.element, badge.issue)}\n />\n ))}\n </div>\n )}\n </>\n );\n}\n\n/**\n * Single item in dropdown menu\n */\ninterface DropdownItemProps {\n badge: NudgedBadgePosition;\n isHovered: boolean;\n onMouseEnter: () => void;\n onMouseLeave: () => void;\n onClick: () => void;\n}\n\nfunction DropdownItem({\n badge,\n isHovered,\n onMouseEnter,\n onMouseLeave,\n onClick,\n}: DropdownItemProps) {\n const elementLabel = formatElementLabel(badge.element);\n\n const issueCount =\n badge.issue.status === \"complete\" ? badge.issue.issues.length : 0;\n const color = getBadgeColor(issueCount);\n\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"8px 12px\",\n cursor: \"pointer\",\n backgroundColor: isHovered ? \"rgba(59, 130, 246, 0.15)\" : \"transparent\",\n transition: \"background-color 0.1s\",\n }}\n onMouseEnter={onMouseEnter}\n onMouseLeave={onMouseLeave}\n onClick={onClick}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <div\n style={{\n width: \"6px\",\n height: \"6px\",\n borderRadius: \"50%\",\n backgroundColor: color,\n }}\n />\n <span\n style={{\n fontSize: \"12px\",\n color: STYLES.text,\n maxWidth: \"160px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {elementLabel}\n </span>\n </div>\n\n {badge.issue.status === \"complete\" &&\n (issueCount === 0 ? (\n <div\n style={{\n width: \"14px\",\n height: \"14px\",\n borderRadius: \"50%\",\n backgroundColor: color,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <CheckIcon />\n </div>\n ) : (\n <div\n style={{\n minWidth: \"16px\",\n height: \"16px\",\n padding: \"0 4px\",\n borderRadius: \"8px\",\n backgroundColor: color,\n color: STYLES.text,\n fontSize: \"10px\",\n fontWeight: 700,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n {issueCount > 9 ? \"9+\" : issueCount}\n </div>\n ))}\n\n {badge.issue.status === \"scanning\" && (\n <div\n style={{\n width: \"12px\",\n height: \"12px\",\n border: \"2px solid rgba(59, 130, 246, 0.3)\",\n borderTopColor: STYLES.highlight,\n borderRadius: \"50%\",\n animation: \"uilint-badge-spin 0.8s linear infinite\",\n }}\n />\n )}\n\n {badge.issue.status === \"error\" && (\n <div\n style={{\n width: \"14px\",\n height: \"14px\",\n borderRadius: \"50%\",\n backgroundColor: STYLES.error,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <ExclamationIcon />\n </div>\n )}\n\n {badge.issue.status === \"pending\" && (\n <div\n style={{\n width: \"8px\",\n height: \"8px\",\n borderRadius: \"50%\",\n backgroundColor: \"rgba(156, 163, 175, 0.5)\",\n }}\n />\n )}\n </div>\n );\n}\n\n// Icons\n\nfunction CheckIcon() {\n return (\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M20 6L9 17l-5-5\"\n stroke={STYLES.text}\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction CheckIconTiny() {\n return (\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M20 6L9 17l-5-5\"\n stroke={STYLES.text}\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction ExclamationIconTiny() {\n return (\n <svg width=\"8\" height=\"8\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M12 8v4M12 16h.01\"\n stroke={STYLES.text}\n strokeWidth=\"4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\nfunction ExclamationIcon() {\n return (\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M12 8v4M12 16h.01\"\n stroke={STYLES.text}\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n"],"names":["DEFAULT_CONFIG","computeLayout","positions","config","nodes","p","iter","fx","fy","j","dx","dy","dist","force","anchorDx","anchorDy","node","BadgeLayoutBuilder","strength","distance","count","factor","findNearbyBadges","x","y","threshold","rectFromLTRB","left","top","right","bottom","width","height","intersectRects","a","b","isOverflowClipping","style","v","getElementVisibleRect","element","el","base","visible","viewport","cur","r","clip","isElementCoveredByOverlay","badgeX","badgeY","elementsAtPoint","position","zIndex","STYLES","NEAR_DISTANCE","FAR_DISTANCE","MIN_SCALE","MAX_SCALE","getScaleFromDistance","getBadgeColor","issueCount","formatElementLabel","tag","source","fileName","NEARBY_THRESHOLD","WINDOW_EDGE_THRESHOLD","BADGE_SIZE","snapToWindowBounds","minX","maxX","minY","maxY","shouldShowBadge","issue","isAltKeyPressed","BadgeAnimationStyles","ElementBadges","autoScanState","elementIssuesCache","setInspectedElement","useUILintContext","mounted","setMounted","useState","cursorPos","setCursorPos","badgePositions","setBadgePositions","setIsAltKeyPressed","hoveredFilePath","useUILintStore","s","selectedFilePath","useEffect","handleKeyDown","e","handleKeyUp","handleBlur","handleMouseMove","updatePositions","rect","desiredX","desiredY","testX","testY","visibleRect","rafId","scheduleUpdate","handleScroll","handleResize","handleVisibility","handleSelect","useCallback","inspected","nudgedPositions","useMemo","visibleBadges","filtered","pos","activeFilePath","handleUILintInteraction","content","jsxs","jsx","idx","arr","id","nudgedPos","nearbyBadges","NudgedBadge","createPortal","getUILintPortalHost","onSelect","isExpanded","setIsExpanded","hoveredIndex","setHoveredIndex","closeTimeoutRef","React","nudgedX","nudgedY","hasNearbyBadges","snappedPosition","badgeColor","handleMouseEnter","handleMouseLeave","handleClick","hoveredBadge","dropdownStyle","preferRight","preferBelow","scale","Fragment","ExclamationIconTiny","CheckIconTiny","badge","index","DropdownItem","isHovered","onMouseEnter","onMouseLeave","onClick","elementLabel","color","CheckIcon","ExclamationIcon"],"mappings":"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"}
@@ -1,154 +0,0 @@
1
- import { a as f, j as g, g as x } from "./index-Cu1-cGo1.js";
2
- import { useMemo as u, useCallback as m } from "react";
3
- import { createPortal as b } from "react-dom";
4
- const i = {
5
- // Vision-specific colors (purple/violet theme to distinguish from ESLint)
6
- badgeBg: "oklch(0.585 0.233 283.04 / 95%)",
7
- // violet-500
8
- badgeBgWarning: "var(--uilint-warning)",
9
- badgeBgInfo: "var(--uilint-accent)",
10
- badgeText: "var(--uilint-text-primary)",
11
- badgeShadow: "var(--uilint-shadow)",
12
- highlightBorder: "oklch(0.585 0.233 283.04 / 80%)",
13
- // Severity-based highlight colors
14
- error: "var(--uilint-error)",
15
- warning: "var(--uilint-warning)",
16
- info: "var(--uilint-accent)"
17
- };
18
- function v(r) {
19
- switch (r) {
20
- case "error":
21
- return i.badgeBg;
22
- case "warning":
23
- return i.badgeBgWarning;
24
- case "info":
25
- return i.badgeBgInfo;
26
- default:
27
- return i.badgeBg;
28
- }
29
- }
30
- function y(r) {
31
- return r.some((t) => t.severity === "error") ? "error" : r.some((t) => t.severity === "warning") ? "warning" : "info";
32
- }
33
- function w({
34
- element: r,
35
- issues: t,
36
- isHighlighted: l,
37
- onBadgeClick: c
38
- }) {
39
- const o = u(() => r.getBoundingClientRect(), [r]), d = y(t), e = v(d), a = u(() => {
40
- switch (d) {
41
- case "error":
42
- return i.error;
43
- case "warning":
44
- return i.warning;
45
- case "info":
46
- return i.info;
47
- default:
48
- return i.highlightBorder;
49
- }
50
- }, [d]), n = {
51
- position: "fixed",
52
- top: o.top - 8,
53
- left: o.right - 8,
54
- zIndex: 99997,
55
- display: "flex",
56
- alignItems: "center",
57
- justifyContent: "center",
58
- minWidth: "18px",
59
- height: "18px",
60
- padding: "0 5px",
61
- borderRadius: "9px",
62
- backgroundColor: e,
63
- color: i.badgeText,
64
- fontSize: "10px",
65
- fontWeight: 600,
66
- fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
67
- boxShadow: i.badgeShadow,
68
- cursor: "pointer",
69
- transition: "transform 0.15s ease",
70
- transform: l ? "scale(1.2)" : "scale(1)",
71
- pointerEvents: "auto"
72
- }, s = l ? {
73
- position: "fixed",
74
- top: o.top - 2,
75
- left: o.left - 2,
76
- width: o.width + 4,
77
- height: o.height + 4,
78
- border: `2px solid ${a}`,
79
- backgroundColor: `${a}15`,
80
- borderRadius: "4px",
81
- zIndex: 99996,
82
- pointerEvents: "none"
83
- } : {}, h = m(
84
- (p) => {
85
- p.stopPropagation(), p.preventDefault(), c();
86
- },
87
- [c]
88
- );
89
- return /* @__PURE__ */ g.jsxs(g.Fragment, { children: [
90
- l && /* @__PURE__ */ g.jsx("div", { style: s }),
91
- /* @__PURE__ */ g.jsx(
92
- "div",
93
- {
94
- style: n,
95
- onClick: h,
96
- title: `${t.length} vision issue${t.length !== 1 ? "s" : ""}`,
97
- role: "button",
98
- "aria-label": `${t.length} vision issues detected`,
99
- children: t.length
100
- }
101
- )
102
- ] });
103
- }
104
- function E() {
105
- const r = f(
106
- (e) => e.visionIssuesCache
107
- ), t = f(
108
- (e) => e.highlightedVisionElementId
109
- ), l = f(
110
- (e) => e.setHighlightedVisionElementId
111
- ), c = u(() => {
112
- const e = /* @__PURE__ */ new Map();
113
- return r.forEach((a) => {
114
- a.forEach((n) => {
115
- if (n.elementId) {
116
- const s = e.get(n.elementId) || [];
117
- s.push(n), e.set(n.elementId, s);
118
- }
119
- });
120
- }), e;
121
- }, [r]), o = u(() => {
122
- const e = [];
123
- return c.forEach((a, n) => {
124
- const s = a[0]?.dataLoc;
125
- if (!s) return;
126
- const h = document.querySelector(`[data-loc="${s}"]`);
127
- h && !h.closest("[data-ui-lint]") && e.push({ element: h, issues: a, elementId: n });
128
- }), e;
129
- }, [c]), d = m(
130
- (e) => {
131
- l(
132
- t === e ? null : e
133
- );
134
- },
135
- [t, l]
136
- );
137
- return o.length === 0 ? null : b(
138
- /* @__PURE__ */ g.jsx("div", { "data-ui-lint": !0, style: { pointerEvents: "none" }, children: o.map(({ element: e, issues: a, elementId: n }) => /* @__PURE__ */ g.jsx(
139
- w,
140
- {
141
- element: e,
142
- issues: a,
143
- isHighlighted: t === n,
144
- onBadgeClick: () => d(n)
145
- },
146
- n
147
- )) }),
148
- x()
149
- );
150
- }
151
- export {
152
- E as VisionIssueBadges
153
- };
154
- //# sourceMappingURL=VisionIssueBadge-Bw_1zmLh.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"VisionIssueBadge-Bw_1zmLh.js","sources":["../src/components/ui-lint/VisionIssueBadge.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Vision Issue Badge Component\n *\n * Displays overlay badges on elements that have vision-detected issues.\n * Similar to ESLint badges but with a distinct visual style for vision issues.\n */\n\nimport React, { useMemo, useCallback } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { useUILintStore, type UILintStore } from \"./store\";\nimport type { VisionIssue } from \"../../scanner/vision-capture\";\nimport { getUILintPortalHost } from \"./portal-host\";\n\n/**\n * Design tokens for vision badges - uses CSS variables for theme support\n */\nconst STYLES = {\n // Vision-specific colors (purple/violet theme to distinguish from ESLint)\n badgeBg: \"oklch(0.585 0.233 283.04 / 95%)\", // violet-500\n badgeBgWarning: \"var(--uilint-warning)\",\n badgeBgInfo: \"var(--uilint-accent)\",\n badgeText: \"var(--uilint-text-primary)\",\n badgeShadow: \"var(--uilint-shadow)\",\n highlightBorder: \"oklch(0.585 0.233 283.04 / 80%)\",\n highlightBg: \"oklch(0.585 0.233 283.04 / 10%)\",\n // Severity-based highlight colors\n error: \"var(--uilint-error)\",\n warning: \"var(--uilint-warning)\",\n info: \"var(--uilint-accent)\",\n};\n\n/**\n * Get badge color based on severity\n */\nfunction getBadgeColor(severity: VisionIssue[\"severity\"]): string {\n switch (severity) {\n case \"error\":\n return STYLES.badgeBg;\n case \"warning\":\n return STYLES.badgeBgWarning;\n case \"info\":\n return STYLES.badgeBgInfo;\n default:\n return STYLES.badgeBg;\n }\n}\n\n/**\n * Get highest severity from issues\n */\nfunction getHighestSeverity(issues: VisionIssue[]): VisionIssue[\"severity\"] {\n if (issues.some((i) => i.severity === \"error\")) return \"error\";\n if (issues.some((i) => i.severity === \"warning\")) return \"warning\";\n return \"info\";\n}\n\ninterface VisionBadgeProps {\n element: Element;\n issues: VisionIssue[];\n isHighlighted: boolean;\n onBadgeClick: () => void;\n}\n\n/**\n * Single vision issue badge positioned on an element\n */\nfunction VisionBadge({\n element,\n issues,\n isHighlighted,\n onBadgeClick,\n}: VisionBadgeProps) {\n const rect = useMemo(() => {\n return element.getBoundingClientRect();\n }, [element]);\n\n const severity = getHighestSeverity(issues);\n const badgeColor = getBadgeColor(severity);\n\n // Get color for highlight border based on severity\n const highlightColor = useMemo(() => {\n switch (severity) {\n case \"error\":\n return STYLES.error;\n case \"warning\":\n return STYLES.warning;\n case \"info\":\n return STYLES.info;\n default:\n return STYLES.highlightBorder;\n }\n }, [severity]);\n\n // Position badge at top-right of element\n const badgeStyle: React.CSSProperties = {\n position: \"fixed\",\n top: rect.top - 8,\n left: rect.right - 8,\n zIndex: 99997,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minWidth: \"18px\",\n height: \"18px\",\n padding: \"0 5px\",\n borderRadius: \"9px\",\n backgroundColor: badgeColor,\n color: STYLES.badgeText,\n fontSize: \"10px\",\n fontWeight: 600,\n fontFamily:\n 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n boxShadow: STYLES.badgeShadow,\n cursor: \"pointer\",\n transition: \"transform 0.15s ease\",\n transform: isHighlighted ? \"scale(1.2)\" : \"scale(1)\",\n pointerEvents: \"auto\",\n };\n\n // Highlight overlay for the element\n const highlightStyle: React.CSSProperties = isHighlighted\n ? {\n position: \"fixed\",\n top: rect.top - 2,\n left: rect.left - 2,\n width: rect.width + 4,\n height: rect.height + 4,\n border: `2px solid ${highlightColor}`,\n backgroundColor: `${highlightColor}15`,\n borderRadius: \"4px\",\n zIndex: 99996,\n pointerEvents: \"none\",\n }\n : {};\n\n const handleClick = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation();\n e.preventDefault();\n onBadgeClick();\n },\n [onBadgeClick]\n );\n\n return (\n <>\n {isHighlighted && <div style={highlightStyle} />}\n <div\n style={badgeStyle}\n onClick={handleClick}\n title={`${issues.length} vision issue${issues.length !== 1 ? \"s\" : \"\"}`}\n role=\"button\"\n aria-label={`${issues.length} vision issues detected`}\n >\n {issues.length}\n </div>\n </>\n );\n}\n\n/**\n * Container component for all vision issue badges\n */\nexport function VisionIssueBadges() {\n const visionIssuesCache = useUILintStore(\n (s: UILintStore) => s.visionIssuesCache\n );\n const highlightedVisionElementId = useUILintStore(\n (s: UILintStore) => s.highlightedVisionElementId\n );\n const setHighlightedVisionElementId = useUILintStore(\n (s: UILintStore) => s.setHighlightedVisionElementId\n );\n\n // Group issues by elementId\n const issuesByElement = useMemo(() => {\n const map = new Map<string, VisionIssue[]>();\n\n visionIssuesCache.forEach((issues) => {\n issues.forEach((issue) => {\n if (issue.elementId) {\n const existing = map.get(issue.elementId) || [];\n existing.push(issue);\n map.set(issue.elementId, existing);\n }\n });\n });\n\n return map;\n }, [visionIssuesCache]);\n\n // Find elements and render badges\n const badges = useMemo(() => {\n const result: Array<{\n element: Element;\n issues: VisionIssue[];\n elementId: string;\n }> = [];\n\n issuesByElement.forEach((issues, elementId) => {\n // Try to find element by data-loc\n const dataLoc = issues[0]?.dataLoc;\n if (!dataLoc) return;\n\n const element = document.querySelector(`[data-loc=\"${dataLoc}\"]`);\n if (element && !element.closest(\"[data-ui-lint]\")) {\n result.push({ element, issues, elementId });\n }\n });\n\n return result;\n }, [issuesByElement]);\n\n const handleBadgeClick = useCallback(\n (elementId: string) => {\n setHighlightedVisionElementId(\n highlightedVisionElementId === elementId ? null : elementId\n );\n },\n [highlightedVisionElementId, setHighlightedVisionElementId]\n );\n\n if (badges.length === 0) return null;\n\n return createPortal(\n <div data-ui-lint style={{ pointerEvents: \"none\" }}>\n {badges.map(({ element, issues, elementId }) => (\n <VisionBadge\n key={elementId}\n element={element}\n issues={issues}\n isHighlighted={highlightedVisionElementId === elementId}\n onBadgeClick={() => handleBadgeClick(elementId)}\n />\n ))}\n </div>,\n getUILintPortalHost()\n );\n}\n"],"names":["STYLES","getBadgeColor","severity","getHighestSeverity","issues","i","VisionBadge","element","isHighlighted","onBadgeClick","rect","useMemo","badgeColor","highlightColor","badgeStyle","highlightStyle","handleClick","useCallback","e","jsxs","Fragment","jsx","VisionIssueBadges","visionIssuesCache","useUILintStore","s","highlightedVisionElementId","setHighlightedVisionElementId","issuesByElement","map","issue","existing","badges","result","elementId","dataLoc","handleBadgeClick","createPortal","getUILintPortalHost"],"mappings":"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"}
@@ -1,11 +0,0 @@
1
- import { UILintContextValue, UILintProviderProps } from './types';
2
- /**
3
- * Hook to access UILint context
4
- * For backwards compatibility - delegates to Zustand store
5
- */
6
- export declare function useUILintContext(): UILintContextValue;
7
- /**
8
- * UILint Provider Component
9
- */
10
- export declare function UILintProvider({ children, enabled, }: UILintProviderProps): import("react/jsx-runtime").JSX.Element;
11
- //# sourceMappingURL=UILintProvider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"UILintProvider.d.ts","sourceRoot":"","sources":["../../../src/components/ui-lint/UILintProvider.tsx"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EAEpB,MAAM,SAAS,CAAC;AA+EjB;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,kBAAkB,CAMrD;AASD;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,OAAc,GACf,EAAE,mBAAmB,2CAwUrB"}