UNPKG

@smitch/fluid

Version:

A lightweight, Tailwind-powered React/Next.js UI component library.

130 lines 7.05 kB
"use client"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useRef, useEffect, useCallback, useMemo, useState } from "react"; import VideoTracks from "./VideoTracks"; import { twMerge } from "tailwind-merge"; import { Loading, Alert } from ".."; var posterSrc = "/poster.png"; var loadingClasses = "[&&::-webkit-media-controls-panel]:!hidden [&&::-webkit-media-controls-enclosure]:!hidden [&&::-webkit-media-controls]:!hidden"; var grayscaleClasses = { none: "", grayscale: "grayscale", sepia: "sepia", }; var aspects = { square: "aspect-square", phone: "aspect-[9/16]", video: "aspect-video", television: "aspect-[4/3]", cinema: "aspect-[21/9]", ultrawide: "aspect-[12/5]", }; var Video = function (_a) { var src = _a.src, _b = _a.poster, poster = _b === void 0 ? posterSrc : _b, tracks = _a.tracks, srcLangs = _a.srcLangs, trackIndex = _a.trackIndex, _c = _a.controls, controls = _c === void 0 ? true : _c, _d = _a.aspect, aspect = _d === void 0 ? "video" : _d, _e = _a.videoWidth, videoWidth = _e === void 0 ? "100%" : _e, _f = _a.videoHeight, videoHeight = _f === void 0 ? "auto" : _f, _g = _a.loop, loop = _g === void 0 ? false : _g, muted = _a.muted, autoplay = _a.autoplay, setDuration = _a.setDuration, setTime = _a.setTime, play = _a.play, togglePlay = _a.togglePlay, _h = _a.preload, preload = _h === void 0 ? "metadata" : _h, _j = _a.fallback, fallback = _j === void 0 ? "Your browser does not support the video tag." : _j, currentTime = _a.currentTime, playEnded = _a.playEnded, _k = _a.volume, volume = _k === void 0 ? 5 : _k, _l = _a.formats, formats = _l === void 0 ? ["mp4"] : _l, _m = _a.pictureInPicture, pictureInPicture = _m === void 0 ? false : _m, _o = _a.defaultError, defaultError = _o === void 0 ? "Video cannot be loaded." : _o, _p = _a.grayscale, grayscale = _p === void 0 ? "none" : _p, _q = _a.blur, blur = _q === void 0 ? false : _q, _r = _a.className, className = _r === void 0 ? "" : _r; var videoRef = useRef(null); var _s = useState(false), loading = _s[0], setLoading = _s[1]; var _t = useState(""), error = _t[0], setError = _t[1]; var aspectRatioClasses = useMemo(function () { return aspects[aspect]; }, [aspect]); useEffect(function () { var node = videoRef.current; if (node) { if (play) node.play(); else node.pause(); } }, [play]); useEffect(function () { var node = videoRef.current; if (node && trackIndex) { var textTracks = node.textTracks; for (var i = 0; i < textTracks.length; i++) { if (i === Number(trackIndex)) textTracks[i].mode = "showing"; else textTracks[i].mode = "disabled"; } } }, [trackIndex]); useEffect(function () { var node = videoRef.current; if (node && typeof document !== null && node.duration) { if (document.pictureInPictureElement) { document.exitPictureInPicture(); } else if (document.pictureInPictureEnabled) { node.requestPictureInPicture(); } } }, [pictureInPicture]); useEffect(function () { var node = videoRef.current; if (node && currentTime) { node.currentTime = currentTime; } }, [currentTime]); useEffect(function () { var node = videoRef.current; if (node) node.volume = volume / 10; }, [volume]); var handleLoadedmetadata = useCallback(function () { if (videoRef.current && setDuration) setDuration(videoRef.current.duration); }, [setDuration]); var handleTogglePlay = function () { if (togglePlay) togglePlay(); }; var handleEnd = useCallback(function () { var node = videoRef.current; if (node && !loop) { node.currentTime = 0; } if (playEnded) playEnded(); }, [playEnded, loop]); var handleTime = useCallback(function () { if (videoRef.current && setTime) setTime(videoRef.current.currentTime); }, [setTime]); var handleError = useCallback(function () { var _a; var node = videoRef.current; if (node) { var error_1 = ((_a = node.error) === null || _a === void 0 ? void 0 : _a.message) || defaultError; setError(error_1); setLoading(false); } }, [setError, defaultError]); var handleWaiting = useCallback(function () { setLoading(true); }, [setLoading]); var handleCanPlay = useCallback(function () { setLoading(false); }, [setLoading]); var setVideoRef = useCallback(function (node) { if (node) { videoRef.current = node; node.addEventListener("waiting", handleWaiting); node.addEventListener("canplay", handleCanPlay); node.addEventListener("loadedmetadata", handleLoadedmetadata, true); node.addEventListener("ended", handleEnd, true); node.addEventListener("timeupdate", handleTime, true); node.addEventListener("error", handleError, true); } return function () { if (node) { node.removeEventListener("waiting", handleWaiting); node.removeEventListener("canplay", handleCanPlay); node.removeEventListener("loadedmetadata", handleLoadedmetadata, true); node.removeEventListener("ended", handleEnd, true); node.removeEventListener("timeupdate", handleTime, true); node.removeEventListener("error", handleError, true); } }; }, [handleEnd, handleError, handleLoadedmetadata, handleTime, handleWaiting, handleCanPlay]); return (_jsxs("figure", { className: twMerge("video-figure group overflow-hidden flex items-center relative ".concat(aspectRatioClasses), className), children: [_jsxs("video", { poster: poster, width: videoWidth, height: videoHeight, controls: controls, loop: loop, ref: setVideoRef, className: "video bg-black ".concat(grayscaleClasses[grayscale], " ").concat(blur ? "blur" : "", " ").concat(videoHeight === "100%" ? "object-cover h-full" : "", " ").concat(loading ? loadingClasses : ""), muted: muted, autoPlay: autoplay, preload: preload, onClick: handleTogglePlay, children: [formats.map(function (format, index) { return (_jsx("source", { src: "".concat(src.slice(0, src.lastIndexOf(".")), ".").concat(format), type: "video/".concat(format) }, index)); }), tracks ? _jsx(VideoTracks, { tracks: tracks, srcLangs: srcLangs }) : null, _jsx("p", { children: fallback })] }), error && (_jsx(Alert, { title: "Error", message: error, status: "error", layout: "solid", className: "!absolute inset-0" })), loading && _jsx(Loading, { className: "absolute w-full", size: "lg" })] })); }; export default Video; //# sourceMappingURL=Video.js.map