Highlighter
magicui/highlighterFreeComponent
A text highlighter that mimics the effect of a human-drawn marker stroke.
Live preview
live · rendered by the registry
Rendered by magicui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://magicui.design/r/highlighter.jsonSource
1"use client"23import { useLayoutEffect, useRef } from "react"4import type React from "react"5import { useInView } from "motion/react"6import { annotate } from "rough-notation"7import { type RoughAnnotation } from "rough-notation/lib/model"89type AnnotationAction =10 | "highlight"11 | "underline"12 | "box"13 | "circle"14 | "strike-through"15 | "crossed-off"16 | "bracket"1718interface HighlighterProps {19 children: React.ReactNode20 action?: AnnotationAction21 color?: string22 strokeWidth?: number23 animationDuration?: number24 iterations?: number25 padding?: number26 multiline?: boolean27 isView?: boolean28}2930export function Highlighter({31 children,32 action = "highlight",33 color = "#ffd1dc",34 strokeWidth = 1.5,35 animationDuration = 600,36 iterations = 2,37 padding = 2,38 multiline = true,39 isView = false,40}: HighlighterProps) {41 const elementRef = useRef<HTMLSpanElement>(null)4243 const isInView = useInView(elementRef, {44 once: true,45 margin: "-10%",46 })4748 // If isView is false, always show. If isView is true, wait for inView49 const shouldShow = !isView || isInView5051 useLayoutEffect(() => {52 const element = elementRef.current53 let annotation: RoughAnnotation | null = null54 let resizeObserver: ResizeObserver | null = null5556 if (shouldShow && element) {57 const annotationConfig = {58 type: action,59 color,60 strokeWidth,61 animationDuration,62 iterations,63 padding,64 multiline,65 }6667 const currentAnnotation = annotate(element, annotationConfig)68 annotation = currentAnnotation69 currentAnnotation.show()7071 resizeObserver = new ResizeObserver(() => {72 currentAnnotation.hide()73 currentAnnotation.show()74 })7576 resizeObserver.observe(element)77 resizeObserver.observe(document.body)78 }7980 return () => {81 annotation?.remove()82 if (resizeObserver) {83 resizeObserver.disconnect()84 }85 }86 }, [87 shouldShow,88 action,89 color,90 strokeWidth,91 animationDuration,92 iterations,93 padding,94 multiline,95 ])9697 return (98 <span ref={elementRef} className="relative inline-block bg-transparent">99 {children}100 </span>101 )102}
What it pulls in
npm packages
Files it writes
More from magicui
All 247 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Androidandroid | magicui | Components | Free | no deps | |
| Animated Beamanimated-beam | magicui | Components | Free | 1 dep | |
| Animated Circular Progress Baranimated-circular-progress-bar | magicui | Components | Free | no deps | |
| Animated Gradient Textanimated-gradient-text | magicui | Components | Free | no deps | |
| Animated Grid Patternanimated-grid-pattern | magicui | Components | Free | 1 dep | |
| Animated Listanimated-list | magicui | Components | Free | 1 dep | |
| Animated Shiny Textanimated-shiny-text | magicui | Components | Free | no deps | |
| Theme Toggleranimated-theme-toggler | magicui | Components | Free | 1 dep |
