UNPKG

@aidenlx/vidstack-react

Version:

UI component library for building high-quality, accessible video and audio experiences on the web.

86 lines (81 loc) 2.91 kB
"use client" import * as React from 'react'; import { listenEvent, EventsController, animationFrameThrottle } from 'maverick.js/std'; import { effect } from 'maverick.js'; import { useMediaPlayer } from './vidstack-DZHxgbQz.js'; function useClassName(el, className) { React.useEffect(() => { if (!el || !className) return; const tokens = className.split(" "); for (const token of tokens) el.classList.add(token); return () => { for (const token of tokens) el.classList.remove(token); }; }, [el, className]); } function useResizeObserver(el, callback) { React.useEffect(() => { if (!el) return; callback(); const observer = new ResizeObserver(animationFrameThrottle(callback)); observer.observe(el); return () => observer.disconnect(); }, [el, callback]); } function useTransitionActive(el) { const [isActive, setIsActive] = React.useState(false); React.useEffect(() => { if (!el) return; const events = new EventsController(el).add("transitionstart", () => setIsActive(true)).add("transitionend", () => setIsActive(false)); return () => events.abort(); }, [el]); return isActive; } function useMouseEnter(el) { const [isMouseEnter, setIsMouseEnter] = React.useState(false); React.useEffect(() => { if (!el) return; const events = new EventsController(el).add("mouseenter", () => setIsMouseEnter(true)).add("mouseleave", () => setIsMouseEnter(false)); return () => events.abort(); }, [el]); return isMouseEnter; } function useFocusIn(el) { const [isFocusIn, setIsFocusIn] = React.useState(false); React.useEffect(() => { if (!el) return; const events = new EventsController(el).add("focusin", () => setIsFocusIn(true)).add("focusout", () => setIsFocusIn(false)); return () => events.abort(); }, [el]); return isFocusIn; } function useActive(el) { const isMouseEnter = useMouseEnter(el), isFocusIn = useFocusIn(el), prevMouseEnter = React.useRef(false); if (prevMouseEnter.current && !isMouseEnter) return false; prevMouseEnter.current = isMouseEnter; return isMouseEnter || isFocusIn; } function useColorSchemePreference() { const [colorScheme, setColorScheme] = React.useState("dark"); React.useEffect(() => { const media = window.matchMedia("(prefers-color-scheme: light)"); function onChange() { setColorScheme(media.matches ? "light" : "dark"); } onChange(); return listenEvent(media, "change", onChange); }, []); return colorScheme; } function useLayoutName(name) { const player = useMediaPlayer(); React.useEffect(() => { if (!player) return; return effect(() => { const el = player.$el; el?.setAttribute("data-layout", name); return () => el?.removeAttribute("data-layout"); }); }, [player]); } export { useActive, useClassName, useColorSchemePreference, useLayoutName, useResizeObserver, useTransitionActive };