{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "highlighter",
  "type": "registry:ui",
  "title": "Highlighter",
  "description": "A text highlighter that mimics the effect of a human-drawn marker stroke.",
  "dependencies": [
    "motion",
    "rough-notation"
  ],
  "files": [
    {
      "path": "registry/magicui/highlighter.tsx",
      "content": "\"use client\"\n\nimport { useLayoutEffect, useRef } from \"react\"\nimport type React from \"react\"\nimport { useInView } from \"motion/react\"\nimport { annotate } from \"rough-notation\"\nimport { type RoughAnnotation } from \"rough-notation/lib/model\"\n\ntype AnnotationAction =\n  | \"highlight\"\n  | \"underline\"\n  | \"box\"\n  | \"circle\"\n  | \"strike-through\"\n  | \"crossed-off\"\n  | \"bracket\"\n\ninterface HighlighterProps {\n  children: React.ReactNode\n  action?: AnnotationAction\n  color?: string\n  strokeWidth?: number\n  animationDuration?: number\n  iterations?: number\n  padding?: number\n  multiline?: boolean\n  isView?: boolean\n}\n\nexport function Highlighter({\n  children,\n  action = \"highlight\",\n  color = \"#ffd1dc\",\n  strokeWidth = 1.5,\n  animationDuration = 600,\n  iterations = 2,\n  padding = 2,\n  multiline = true,\n  isView = false,\n}: HighlighterProps) {\n  const elementRef = useRef<HTMLSpanElement>(null)\n\n  const isInView = useInView(elementRef, {\n    once: true,\n    margin: \"-10%\",\n  })\n\n  // If isView is false, always show. If isView is true, wait for inView\n  const shouldShow = !isView || isInView\n\n  useLayoutEffect(() => {\n    const element = elementRef.current\n    let annotation: RoughAnnotation | null = null\n    let resizeObserver: ResizeObserver | null = null\n\n    if (shouldShow && element) {\n      const annotationConfig = {\n        type: action,\n        color,\n        strokeWidth,\n        animationDuration,\n        iterations,\n        padding,\n        multiline,\n      }\n\n      const currentAnnotation = annotate(element, annotationConfig)\n      annotation = currentAnnotation\n      currentAnnotation.show()\n\n      resizeObserver = new ResizeObserver(() => {\n        currentAnnotation.hide()\n        currentAnnotation.show()\n      })\n\n      resizeObserver.observe(element)\n      resizeObserver.observe(document.body)\n    }\n\n    return () => {\n      annotation?.remove()\n      if (resizeObserver) {\n        resizeObserver.disconnect()\n      }\n    }\n  }, [\n    shouldShow,\n    action,\n    color,\n    strokeWidth,\n    animationDuration,\n    iterations,\n    padding,\n    multiline,\n  ])\n\n  return (\n    <span ref={elementRef} className=\"relative inline-block bg-transparent\">\n      {children}\n    </span>\n  )\n}\n",
      "type": "registry:ui"
    }
  ]
}