(null)\n const shouldPlayVimeo = isMobile ? controlsVisible : isHovering\n const shouldPlayVimeoRef = useRef(shouldPlayVimeo)\n\n useEffect(() => {\n shouldPlayVimeoRef.current = shouldPlayVimeo\n }, [shouldPlayVimeo])\n\n useEffect(() => {\n if (!isVimeoVideo || !containerRef.current) return\n\n const videoId = src.split(\"/\").pop() || \"\"\n let player: VimeoPlayer | null = null\n setVideoLoading(true)\n\n loadVimeoSDK()\n .then((Vimeo) => {\n if (!containerRef.current) return\n\n player = new Vimeo.Player(containerRef.current, {\n id: videoId,\n autopause: false,\n muted,\n loop,\n responsive: true,\n controls: false,\n autoplay: false,\n volume: 1,\n })\n\n playerRef.current = player\n\n player.ready().then(() => {\n console.log(\"Vimeo video loaded\")\n setVideoLoading(false)\n\n if (shouldPlayVimeoRef.current) {\n player\n ?.play()\n .then(() => setVideoPlaying(true))\n .catch((error) => {\n setVideoPlaying(false)\n console.error(\"Vimeo play error:\", error)\n })\n }\n })\n\n player.on(\"play\", () => {\n console.log(\"Vimeo video playing\")\n setVideoLoading(false)\n setVideoPlaying(true)\n })\n player.on(\"pause\", () => {\n console.log(\"Vimeo video paused\")\n setVideoPlaying(false)\n })\n player.on(\"error\", (err) => {\n setVideoLoading(false)\n setVideoPlaying(false)\n console.error(\"Vimeo player error:\", err)\n })\n })\n .catch((error) => {\n setVideoLoading(false)\n console.error(\"Failed to load Vimeo SDK:\", error)\n })\n\n return () => {\n if (player) {\n player.destroy()\n playerRef.current = null\n }\n }\n }, [isVimeoVideo, src, muted, loop, setVideoLoading, setVideoPlaying])\n\n useEffect(() => {\n if (!isVimeoVideo) return\n\n const player = playerRef.current\n if (!player) return\n\n if (shouldPlayVimeo) {\n setVideoLoading(true)\n player\n .play()\n .then(() => {\n setVideoLoading(false)\n setVideoPlaying(true)\n })\n .catch((error) => {\n setVideoLoading(false)\n setVideoPlaying(false)\n console.error(\"Vimeo play error:\", error)\n })\n } else {\n player\n .pause()\n .then(() => setVideoPlaying(false))\n .catch((error) => {\n console.error(\"Vimeo pause error:\", error)\n })\n }\n }, [isVimeoVideo, shouldPlayVimeo, setVideoLoading, setVideoPlaying])\n\n if (isVimeoVideo) {\n return \n }\n\n return (\n \n )\n}\n\n/**\n * Thumbnail component shown when video is not playing\n */\nconst HoverVideoPlayerThumbnail: React.FC<{ src: string }> = ({ src }) => {\n const { cropTop, cropBottom, isLoading, isPlaying } = useHoverVideoPlayer()\n const shouldReduceMotion = useReducedMotion()\n const shouldShowThumbnail = !isPlaying || isLoading\n\n return (\n \n \n \n )\n}\n\n/**\n * Controls overlay with play/pause, volume, and progress bar\n */\nconst HoverVideoPlayerControls: React.FC<{ children: React.ReactNode }> = ({\n children,\n}) => {\n const { isHovering, isMobile, controlsVisible } = useHoverVideoPlayer()\n const shouldReduceMotion = useReducedMotion()\n\n const shouldShowControls = isMobile ? controlsVisible : isHovering\n\n return (\n \n {shouldShowControls && (\n \n {children}\n \n )}\n \n )\n}\n\n/**\n * Overlay shown when hovering over the video\n */\nconst HoverVideoPlayerHoverOverlay: React.FC<{ children: React.ReactNode }> = ({\n children,\n}) => {\n const { isHovering, isLoading } = useHoverVideoPlayer()\n const shouldReduceMotion = useReducedMotion()\n\n return (\n \n {isHovering && !isLoading && (\n \n {children}\n \n )}\n \n )\n}\n\n/**\n * Overlay shown when video is paused\n */\nconst HoverVideoPlayerPausedOverlay: React.FC<{\n children: React.ReactNode\n}> = ({ children }) => {\n const { isPlaying, isLoading, isHovering } = useHoverVideoPlayer()\n const shouldReduceMotion = useReducedMotion()\n\n return (\n \n {!isPlaying && !isLoading && !isHovering && (\n \n {children}\n \n )}\n \n )\n}\n\n/**\n * Overlay shown while video is loading\n */\nconst HoverVideoPlayerLoadingOverlay: React.FC<{\n children: React.ReactNode\n}> = ({ children }) => {\n const { isLoading } = useHoverVideoPlayer()\n const shouldReduceMotion = useReducedMotion()\n\n return (\n \n {isLoading && (\n \n {children}\n \n )}\n \n )\n}\n\n/**\n * Play/Pause button component\n */\nconst HoverVideoPlayerPlayPauseButton: React.FC = () => {\n const { isPlaying, togglePlay } = useHoverVideoPlayer()\n\n return (\n \n )\n}\n\n/**\n * Volume control component with mute toggle and volume slider\n */\nconst HoverVideoPlayerVolumeControl: React.FC = () => {\n const { muted, toggleMute, volume, setVolume } = useHoverVideoPlayer()\n\n return (\n \n \n setVolume(value[0] / 100)}\n aria-label=\"Volume\"\n />\n
\n )\n}\n\n/**\n * Progress bar component for video timeline\n */\nconst HoverVideoPlayerProgressBar: React.FC = () => {\n const { progress, setProgress, videoRef } = useHoverVideoPlayer()\n\n return (\n {\n if (videoRef.current) {\n const newTime = (value[0] / 100) * videoRef.current.duration\n videoRef.current.currentTime = newTime\n setProgress(value[0])\n }\n }}\n aria-label=\"Video progress\"\n />\n )\n}\n\n/**\n * Picture-in-Picture toggle button\n */\nconst HoverVideoPlayerPiPButton: React.FC = () => {\n const { isPiP, togglePiP } = useHoverVideoPlayer()\n\n return (\n \n )\n}\n\n/**\n * Wrapper component for maintaining aspect ratio with padding\n */\nconst HoverVideoPaddingWrapper: React.FC<{\n width: number\n height: number\n className?: string\n children?: ReactNode\n}> = ({ width, height, className, children }) => {\n return (\n \n )\n}\n\n// Add display names for better debugging\nHoverVideoPlayerControls.displayName = \"HoverVideoPlayerControls\"\nHoverVideoPaddingWrapper.displayName = \"HoverVideoPaddingWrapper\"\nHoverVideoPlayerHoverOverlay.displayName = \"HoverVideoPlayerHoverOverlay\"\nHoverVideoPlayerPausedOverlay.displayName = \"HoverVideoPlayerPausedOverlay\"\nHoverVideoPlayerLoadingOverlay.displayName = \"HoverVideoPlayerLoadingOverlay\"\nHoverVideoPlayerPlayPauseButton.displayName = \"HoverVideoPlayerPlayPauseButton\"\nHoverVideoPlayerVolumeControl.displayName = \"HoverVideoPlayerVolumeControl\"\nHoverVideoPlayerProgressBar.displayName = \"HoverVideoPlayerProgressBar\"\nHoverVideoPlayerPiPButton.displayName = \"HoverVideoPlayerPiPButton\"\n\nexport {\n HoverVideoPlayer,\n HoverVideoPlayerControls,\n HoverVideoPlayerHoverOverlay,\n HoverVideoPlayerPausedOverlay,\n HoverVideoPlayerLoadingOverlay,\n HoverVideoPlayerPlayPauseButton,\n HoverVideoPlayerVolumeControl,\n HoverVideoPlayerProgressBar,\n HoverVideoPlayerPiPButton,\n HoverVideoPaddingWrapper,\n}\n\nexport default HoverVideoPlayer\n",
"type": "registry:ui"
}
]
}