{
  "name": "video-text-mask",
  "type": "registry:ui",
  "title": "Video Text Mask",
  "description": "Dynamic looping video masked inside responsive SVG typography with fluid background illumination.",
  "dependencies": [
    "framer-motion"
  ],
  "files": [
    {
      "path": "registry/text/video-text-mask/video-text-mask.tsx",
      "type": "registry:ui",
      "target": "components/ui/video-text-mask.tsx",
      "content": "import React, { ReactNode, useEffect, useState } from \"react\";\nimport { motion, HTMLMotionProps } from \"framer-motion\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface VideoTextMaskProps {\n  src?: string;\n  className?: string;\n  autoPlay?: boolean;\n  muted?: boolean;\n  loop?: boolean;\n  preload?: \"auto\" | \"metadata\" | \"none\";\n  children: ReactNode;\n  fontSize?: string | number;\n  fontWeight?: string | number;\n  textAnchor?: string;\n  dominantBaseline?: string;\n  fontFamily?: string;\n  as?: \"div\" | \"span\" | \"section\" | \"article\" | \"p\" | \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\";\n}\n\nexport function VideoTextMask({\n  src = \"https://assets.mixkit.co/videos/preview/mixkit-fluid-lines-moving-in-slow-motion-41857-large.mp4\",\n  children,\n  className = \"\",\n  autoPlay = true,\n  muted = true,\n  loop = true,\n  preload = \"auto\",\n  fontSize = \"16vw\",\n  fontWeight = \"900\",\n  textAnchor = \"middle\",\n  dominantBaseline = \"middle\",\n  fontFamily = \"system-ui, -apple-system, sans-serif\",\n  as = \"div\",\n  ...motionProps\n}: VideoTextMaskProps & HTMLMotionProps<\"div\">) {\n  const [svgMask, setSvgMask] = useState(\"\");\n  const content = React.Children.toArray(children).join(\"\");\n\n  useEffect(() => {\n    const responsiveFontSize =\n      typeof fontSize === \"number\" ? `${fontSize}px` : fontSize;\n\n    const newSvgMask = `<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%' viewBox='0 0 1000 300'>\n      <text x='50%' y='50%'\n            font-size='${responsiveFontSize}'\n            font-weight='${fontWeight}'\n            text-anchor='${textAnchor}'\n            dominant-baseline='${dominantBaseline}'\n            font-family='${fontFamily}'\n            letter-spacing='-0.03em'\n            fill='black'>${content}</text>\n    </svg>`;\n    setSvgMask(newSvgMask);\n  }, [content, fontSize, fontWeight, textAnchor, dominantBaseline, fontFamily]);\n\n  const validTags = [\"div\", \"span\", \"section\", \"article\", \"p\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\"] as const;\n  type ValidTag = (typeof validTags)[number];\n  const MotionComponent = motion[validTags.includes(as) ? as : \"div\"] as any;\n\n  if (!svgMask) {\n    return React.createElement(\n      MotionComponent,\n      {\n        className: cn(\"relative size-full\", className),\n        ...motionProps,\n      },\n      <span className=\"sr-only\">{content}</span>\n    );\n  }\n\n  const dataUrlMask = `url(\"data:image/svg+xml,${encodeURIComponent(svgMask)}\")`;\n\n  return React.createElement(\n    MotionComponent,\n    {\n      className: cn(\"relative w-full h-48 sm:h-56 overflow-hidden rounded-xl bg-zinc-950 flex items-center justify-center select-none\", className),\n      ...motionProps,\n    },\n    <>\n      <div\n        className=\"absolute inset-0 flex items-center justify-center pointer-events-none\"\n        style={{\n          maskImage: dataUrlMask,\n          WebkitMaskImage: dataUrlMask,\n          maskSize: \"contain\",\n          WebkitMaskSize: \"contain\",\n          maskRepeat: \"no-repeat\",\n          WebkitMaskRepeat: \"no-repeat\",\n          maskPosition: \"center\",\n          WebkitMaskPosition: \"center\",\n        }}\n      >\n        <video\n          className=\"w-full h-full object-cover scale-105\"\n          autoPlay={autoPlay}\n          muted={muted}\n          loop={loop}\n          preload={preload}\n          playsInline\n        >\n          <source src={src} type=\"video/mp4\" />\n        </video>\n      </div>\n      <span className=\"sr-only\">{content}</span>\n    </>\n  );\n}\n\nexport default VideoTextMask;\n"
    }
  ],
  "$schema": "https://www.cooki-ui.design/schema/registry-item.json"
}