lazy-video
jolyui-ui/lazy-videoFreeComponent
jolyui/ui publishes no description for this item.
Install it
npx shadcn@latest add https://jolyui.dev/r/lazy-video.jsonSource
1"use client";23import type React from "react";4import { useEffect, useRef, useState } from "react";56export interface LazyVideoProps7 extends React.VideoHTMLAttributes<HTMLVideoElement> {8 src: string;9 fallback?: string;10 threshold?: number;11 rootMargin?: string;12}1314export function LazyVideo({15 src,16 className = "",17 poster,18 autoPlay = false,19 loop = false,20 muted = true,21 controls = false,22 playsInline = true,23 "aria-label": ariaLabel,24 ...props25}: LazyVideoProps) {26 const videoRef = useRef<HTMLVideoElement | null>(null);27 const [loaded, setLoaded] = useState(false);2829 useEffect(() => {30 const el = videoRef.current;31 if (!el) return;3233 const prefersReducedMotion =34 window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches ?? false;35 const saveData =36 (navigator as unknown as { connection?: { saveData?: boolean } })37 ?.connection?.saveData === true;38 const shouldAutoplay = autoPlay && !prefersReducedMotion && !saveData;3940 let observer: IntersectionObserver | null = null;4142 const onIntersect: IntersectionObserverCallback = (entries) => {43 entries.forEach(async (entry) => {44 if (entry.isIntersecting && !loaded) {45 el.src = src;46 el.load();4748 if (shouldAutoplay) {49 const playVideo = async () => {50 try {51 await el.play();52 } catch (_error) {53 // Autoplay might be blocked54 // console.log("[v0] Autoplay blocked:", error)55 }56 };57 if (el.readyState >= 3) {58 playVideo();59 } else {60 el.addEventListener("canplay", playVideo, { once: true });61 }62 }6364 setLoaded(true);65 } else if (!entry.isIntersecting && loaded && shouldAutoplay) {66 try {67 el.pause();68 } catch {}69 } else if (entry.isIntersecting && loaded && shouldAutoplay) {70 try {71 await el.play();72 } catch {}73 }74 });75 };7677 observer = new IntersectionObserver(onIntersect, {78 rootMargin: "80px",79 threshold: 0.15,80 });81 observer.observe(el);8283 const onVisibility = () => {84 if (!el) return;85 const hidden = document.visibilityState === "hidden";86 if (hidden) {87 try {88 el.pause();89 } catch {}90 } else if (shouldAutoplay && loaded) {91 // resume only if we were auto-playing92// … truncated
Files it writes
More from jolyui/ui
All 199 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| ai-prompt-boxai-prompt-box | jolyui/ui | Components | Free | 4 deps | |
| animated-beamanimated-beam | jolyui/ui | Components | Free | 1 dep | |
| animated-tableanimated-table | jolyui/ui | Components | Free | 2 deps | |
| animated-theme-toggleanimated-theme-toggle | jolyui/ui | Components | Free | 2 deps | |
| animated-toastanimated-toast | jolyui/ui | Components | Free | 2 deps | |
| animated-tooltipanimated-tooltip | jolyui/ui | Components | Free | 1 dep | |
| bento-gridbento-grid | jolyui/ui | Components | Free | no deps | |
| buttonbutton | jolyui/ui | Components | Free | 3 deps |
