{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "beam-border",
  "title": "Beam Border",
  "description": "One beam of light travelling the border of the surface the model is working on, so the eye knows where to wait.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/miseui/ui/beam-border.tsx",
      "content": "import type * as React from \"react\"\nimport { useEffect, useRef, useState } from \"react\"\nimport { useReducedMotion } from \"motion/react\"\nimport { cn } from \"@/registry/miseui/lib/utils\"\n\ntype BeamColor = \"mise\" | \"foreground\"\n\nconst DEFAULT_LAP_SECONDS = 4\nconst DEFAULT_BEAM_PX = 120\nconst DEFAULT_BORDER_WIDTH_PX = 1\nconst MS_PER_SECOND = 1000\n/** Thick enough to cover the ring and its bloom; the ring mask trims it to the border. */\nconst BEAM_THICKNESS_PX = 16\n/** The bloom ring is wider than the sharp one, so the light spills past the edge once blurred. */\nconst BLOOM_EXTRA_WIDTH_PX = 2\nconst STILL_SPAN_DEGREES = 60\n\nconst COLOR_VARS: Record<BeamColor, string> = { mise: \"var(--mise)\", foreground: \"var(--foreground)\" }\n\n/** Transparent tail to a hot head. offset-rotate keeps the gradient pointing along the path. */\nconst BEAM_GRADIENT =\n  \"linear-gradient(90deg, transparent, var(--beam-color) 70%, color-mix(in oklch, var(--beam-color) 55%, white))\"\n/** Reduced motion: one still highlight centred on the top edge, where a lit edge reads as \"active\", not \"stuck\". */\nconst STILL_GRADIENT = `conic-gradient(from ${-STILL_SPAN_DEGREES / 2}deg, transparent 0deg, var(--beam-color) ${STILL_SPAN_DEGREES / 2}deg, transparent ${STILL_SPAN_DEGREES}deg)`\n/** Content box cut out of the border box leaves only the padding ring painted. */\nconst RING_MASK = \"linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0)\"\nconst RING_CLASS = \"pointer-events-none absolute inset-0 overflow-hidden rounded-[inherit]\"\n\ninterface BeamBorderProps extends React.ComponentProps<\"div\"> {\n  /** Whether the beam is travelling. Off, the wrapper adds nothing to its children. */\n  active?: boolean\n  /** Seconds for one lap of the border. */\n  duration?: number\n  /** Beam length in px along the border. */\n  size?: number\n  borderWidth?: number\n  color?: BeamColor\n}\n\nfunction BeamBorder({\n  active = true,\n  duration = DEFAULT_LAP_SECONDS,\n  size = DEFAULT_BEAM_PX,\n  borderWidth = DEFAULT_BORDER_WIDTH_PX,\n  color = \"mise\",\n  className,\n  children,\n  ...props\n}: BeamBorderProps) {\n  return (\n    <div\n      data-slot=\"beam-border\"\n      data-active={active ? \"true\" : \"false\"}\n      className={cn(\"relative rounded-[inherit]\", className)}\n      {...props}\n    >\n      {children}\n      {active ? <BeamLayer duration={duration} size={size} borderWidth={borderWidth} color={color} /> : null}\n    </div>\n  )\n}\n\ninterface BeamLayerProps {\n  duration: number\n  size: number\n  borderWidth: number\n  color: BeamColor\n}\n\n/**\n * A second, blurred copy of the ring gives the head its bloom. Blur sits on the outer element because\n * filters apply before masks on the same element, which would leave a hard edge.\n */\nfunction BeamLayer({ duration, size, borderWidth, color }: BeamLayerProps) {\n  const reduceMotion = Boolean(useReducedMotion())\n  const beamColor = { \"--beam-color\": COLOR_VARS[color] } as React.CSSProperties\n\n  return (\n    <>\n      <div\n        aria-hidden=\"true\"\n        data-testid=\"beam-layer\"\n        data-reduced={reduceMotion ? \"true\" : \"false\"}\n        className={cn(RING_CLASS, \"bg-border\")}\n        style={{ ...beamColor, padding: borderWidth, mask: RING_MASK, maskComposite: \"exclude\" }}\n      >\n        <BeamSweep testId=\"beam\" duration={duration} size={size} still={reduceMotion} />\n      </div>\n      <div\n        aria-hidden=\"true\"\n        data-testid=\"beam-bloom\"\n        className=\"pointer-events-none absolute inset-0 rounded-[inherit] opacity-80 blur-[6px] [@media(prefers-reduced-transparency:reduce)]:hidden\"\n        style={beamColor}\n      >\n        <div\n          className={RING_CLASS}\n          style={{ padding: borderWidth + BLOOM_EXTRA_WIDTH_PX, mask: RING_MASK, maskComposite: \"exclude\" }}\n        >\n          <BeamSweep duration={duration} size={size} still={reduceMotion} />\n        </div>\n      </div>\n    </>\n  )\n}\n\ninterface BeamSweepProps {\n  duration: number\n  size: number\n  still: boolean\n  testId?: string\n}\n\n/** The corner radius in px; offset-path's rect() cannot inherit it the way border-radius can. */\nfunction useInheritedRadius(ref: React.RefObject<HTMLDivElement | null>) {\n  const [radius, setRadius] = useState(\"0px\")\n\n  useEffect(() => {\n    const parent = ref.current?.parentElement\n    if (parent) setRadius(getComputedStyle(parent).borderTopLeftRadius || \"0px\")\n  }, [ref])\n\n  return radius\n}\n\n/**\n * Travels the perimeter on an offset path, so speed and length stay the same on every edge. A spinning\n * conic gradient cannot do that: it crawls and shrinks mid-edge and whips round the corners of a wide card.\n * The Web Animations API needs no stylesheet from the installer and runs without a React render per frame.\n */\nfunction BeamSweep({ duration, size, still, testId }: BeamSweepProps) {\n  const ref = useRef<HTMLDivElement>(null)\n  const radius = useInheritedRadius(ref)\n\n  useEffect(() => {\n    const node = ref.current\n    if (still || !node || typeof node.animate !== \"function\") return\n    const animation = node.animate([{ offsetDistance: \"0%\" }, { offsetDistance: \"100%\" }], {\n      duration: duration * MS_PER_SECOND,\n      iterations: Infinity,\n    })\n    return () => animation.cancel()\n  }, [duration, still])\n\n  if (still) {\n    return <div ref={ref} data-testid={testId} className=\"absolute inset-0\" style={{ backgroundImage: STILL_GRADIENT }} />\n  }\n\n  return (\n    <div\n      ref={ref}\n      data-testid={testId}\n      className=\"absolute top-0 left-0\"\n      style={{\n        width: size,\n        height: BEAM_THICKNESS_PX,\n        backgroundImage: BEAM_GRADIENT,\n        offsetPath: `rect(0 100% 100% 0 round ${radius})`,\n        offsetAnchor: \"100% 50%\",\n        offsetRotate: \"auto\",\n      }}\n    />\n  )\n}\n\nexport { BeamBorder, type BeamBorderProps, type BeamColor }\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "effects"
  ],
  "type": "registry:ui"
}