@vidstack/react
Advanced tools
Comparing version 0.0.2 to 0.1.0
148
dist/dev.js
@@ -19,31 +19,37 @@ // src/components.ts | ||
} from "vidstack"; | ||
var Media = createLiteReactElement(MediaDefinition); | ||
var Audio = createLiteReactElement(AudioDefinition); | ||
var HLSVideo = createLiteReactElement(HLSVideoDefinition); | ||
var Video = createLiteReactElement(VideoDefinition); | ||
var AspectRatio = createLiteReactElement(AspectRatioDefinition); | ||
var FullscreenButton = createLiteReactElement(FullscreenButtonDefinition); | ||
var MuteButton = createLiteReactElement(MuteButtonDefinition); | ||
var PlayButton = createLiteReactElement(PlayButtonDefinition); | ||
var Poster = createLiteReactElement(PosterDefinition); | ||
var SliderValueText = createLiteReactElement(SliderValueTextDefinition); | ||
var SliderVideo = createLiteReactElement(SliderVideoDefinition); | ||
var TimeSlider = createLiteReactElement(TimeSliderDefinition); | ||
var Time = createLiteReactElement(TimeDefinition); | ||
var VolumeSlider = createLiteReactElement(VolumeSliderDefinition); | ||
var Media = /* @__PURE__ */ createLiteReactElement(MediaDefinition); | ||
var Audio = /* @__PURE__ */ createLiteReactElement(AudioDefinition); | ||
var HLSVideo = /* @__PURE__ */ createLiteReactElement(HLSVideoDefinition); | ||
var Video = /* @__PURE__ */ createLiteReactElement(VideoDefinition); | ||
var AspectRatio = /* @__PURE__ */ createLiteReactElement(AspectRatioDefinition); | ||
var FullscreenButton = /* @__PURE__ */ createLiteReactElement(FullscreenButtonDefinition); | ||
var MuteButton = /* @__PURE__ */ createLiteReactElement(MuteButtonDefinition); | ||
var PlayButton = /* @__PURE__ */ createLiteReactElement(PlayButtonDefinition); | ||
var Poster = /* @__PURE__ */ createLiteReactElement(PosterDefinition); | ||
var SliderValueText = /* @__PURE__ */ createLiteReactElement(SliderValueTextDefinition); | ||
var SliderVideo = /* @__PURE__ */ createLiteReactElement(SliderVideoDefinition); | ||
var TimeSlider = /* @__PURE__ */ createLiteReactElement(TimeSliderDefinition); | ||
var Time = /* @__PURE__ */ createLiteReactElement(TimeDefinition); | ||
var VolumeSlider = /* @__PURE__ */ createLiteReactElement(VolumeSliderDefinition); | ||
// src/context.ts | ||
import { createReactContextProvider } from "maverick.js/react"; | ||
import { mediaContext } from "vidstack"; | ||
var MediaProvider = createReactContextProvider(mediaContext); | ||
// src/use-media-element.ts | ||
import { useReactContext } from "maverick.js/react"; | ||
import { useEffect, useState } from "react"; | ||
import { MediaElementContext } from "vidstack"; | ||
import { mediaContext as mediaContext2 } from "vidstack"; | ||
function useMediaElement() { | ||
const [element, setElement] = useState(null), $mediaElement = useReactContext(MediaElementContext); | ||
if (!$mediaElement) { | ||
console.warn( | ||
"[vidstack] `useMediaElement` can only be called inside a child component of `<Media>`." | ||
); | ||
const [element, setElement] = useState(null), context = useReactContext(mediaContext2); | ||
if (!context) { | ||
throw Error("[vidstack] no media context was found - did you forget to provide it?"); | ||
} | ||
useEffect(() => { | ||
if ($mediaElement) | ||
setElement($mediaElement()); | ||
if (!context) | ||
return; | ||
const media = context.$element(); | ||
media.onAttach(() => void setElement(media)); | ||
return () => setElement(null); | ||
}, []); | ||
@@ -53,23 +59,46 @@ return element; | ||
// src/use-media-remote.ts | ||
// src/use-media-provider-element.ts | ||
import { effect } from "maverick.js"; | ||
import { useReactContext as useReactContext2 } from "maverick.js/react"; | ||
import { useEffect as useEffect2, useRef } from "react"; | ||
import { MediaElementContext as MediaElementContext2, MediaRemoteControl } from "vidstack"; | ||
import { useEffect as useEffect2, useState as useState2 } from "react"; | ||
import { mediaContext as mediaContext3 } from "vidstack"; | ||
function useMediaProviderElement() { | ||
const [element, setElement] = useState2(null), context = useReactContext2(mediaContext3); | ||
if (!context) { | ||
throw Error("[vidstack] no media context was found - did you forget to provide it?"); | ||
} | ||
useEffect2(() => { | ||
if (!context) | ||
return; | ||
return effect(() => { | ||
const provider = context.$provider(); | ||
provider?.onAttach(() => void setElement(provider)); | ||
}); | ||
}, []); | ||
return element; | ||
} | ||
// src/use-media-remote.ts | ||
import { scoped } from "maverick.js"; | ||
import { useReactContext as useReactContext3, useReactScope } from "maverick.js/react"; | ||
import { isUndefined } from "maverick.js/std"; | ||
import { useEffect as useEffect3, useMemo } from "react"; | ||
import { mediaContext as mediaContext4, MediaRemoteControl } from "vidstack"; | ||
function useMediaRemote(target) { | ||
const remote = useRef(new MediaRemoteControl()), $mediaElement = useReactContext2(MediaElementContext2); | ||
if (!target && !$mediaElement) { | ||
console.warn( | ||
"[vidstack] `useMediaRemote` requires second argument containing a ref to a DOM element if _not_ called inside a child component of `<Media>`." | ||
const scope = useReactScope(), context = useReactContext3(mediaContext4); | ||
if (isUndefined(target) && !context) { | ||
throw Error( | ||
"[vidstack] `useMediaRemote` requires `target` argument containing a ref to a DOM element if no media context is provided - did you forget to provide it?`." | ||
); | ||
} | ||
useEffect2(() => { | ||
const remoteTarget = target || $mediaElement?.(); | ||
if (remoteTarget) { | ||
remote.current.setTarget("current" in remoteTarget ? remoteTarget.current : remoteTarget); | ||
} else if ($mediaElement) { | ||
return effect(() => void remote.current.setTarget($mediaElement())); | ||
const remote = useMemo(() => scoped(() => new MediaRemoteControl(), scope), []); | ||
useEffect3(() => { | ||
if (!isUndefined(target)) { | ||
remote.setTarget(target && "current" in target ? target.current : target); | ||
} else if (context) { | ||
remote.setTarget(context.$element()); | ||
} | ||
return () => remote.setTarget(null); | ||
}, [target]); | ||
return remote.current; | ||
return remote; | ||
} | ||
@@ -79,31 +108,36 @@ | ||
import { effect as effect2, signal } from "maverick.js"; | ||
import { useReactContext as useReactContext3 } from "maverick.js/react"; | ||
import { useReactContext as useReactContext4 } from "maverick.js/react"; | ||
import { noop } from "maverick.js/std"; | ||
import { useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState2 } from "react"; | ||
import { mediaStore, MediaStoreContext } from "vidstack"; | ||
function useMediaState(target) { | ||
const [_, update] = useState2(0), stop = useRef2(null), $store = useReactContext3(MediaStoreContext); | ||
if (!target && !$store) { | ||
console.warn( | ||
"[vidstack] `useMediaState` requires second argument containing a ref to `<vds-media>` element if _not_ called inside a child component of `<Media>`. This hook will _not_ be updated when media state changes until this is resolved." | ||
); | ||
import { useEffect as useEffect4, useMemo as useMemo2, useRef, useState as useState3 } from "react"; | ||
import { mediaContext as mediaContext5 } from "vidstack"; | ||
function useMediaState() { | ||
const [_, update] = useState3(0), tracking = useRef({ | ||
$props: signal([]), | ||
observing: /* @__PURE__ */ new Set() | ||
}), context = useReactContext4(mediaContext5); | ||
if (!context) { | ||
throw Error("[vidstack] no media context was found - did you forget to provide it?"); | ||
} | ||
useEffect3(() => () => stop.current?.(), []); | ||
return useMemo(() => { | ||
const media = target && "current" in target ? target.current : target, state = media?.state ?? $store ?? mediaStore.initial, $props = signal([]); | ||
stop.current?.(); | ||
stop.current = effect2(() => { | ||
const props = $props; | ||
useEffect4(() => { | ||
return effect2(() => { | ||
const props = tracking.current.$props(); | ||
const $store = context.$store; | ||
for (let i = 0; i < props.length; i++) | ||
state[props[i]]; | ||
$store[props[i]]; | ||
update((n) => n + 1); | ||
}); | ||
return new Proxy(state, { | ||
}, []); | ||
return useMemo2(() => { | ||
const { observing, $props } = tracking.current, $store = context.$store; | ||
return new Proxy($store, { | ||
get(_2, prop) { | ||
$props.set((prev) => [...prev, prop]); | ||
return state[prop]; | ||
if (!observing.has(prop)) { | ||
$props.set((prev) => [...prev, prop]); | ||
observing.add(prop); | ||
} | ||
return $store[prop]; | ||
}, | ||
set: noop | ||
}); | ||
}, [target]); | ||
}, []); | ||
} | ||
@@ -116,2 +150,3 @@ export { | ||
Media, | ||
MediaProvider, | ||
MuteButton, | ||
@@ -127,4 +162,5 @@ PlayButton, | ||
useMediaElement, | ||
useMediaProviderElement, | ||
useMediaRemote, | ||
useMediaState | ||
}; |
142
dist/prod.js
@@ -19,31 +19,37 @@ // src/components.ts | ||
} from "vidstack"; | ||
var Media = createLiteReactElement(MediaDefinition); | ||
var Audio = createLiteReactElement(AudioDefinition); | ||
var HLSVideo = createLiteReactElement(HLSVideoDefinition); | ||
var Video = createLiteReactElement(VideoDefinition); | ||
var AspectRatio = createLiteReactElement(AspectRatioDefinition); | ||
var FullscreenButton = createLiteReactElement(FullscreenButtonDefinition); | ||
var MuteButton = createLiteReactElement(MuteButtonDefinition); | ||
var PlayButton = createLiteReactElement(PlayButtonDefinition); | ||
var Poster = createLiteReactElement(PosterDefinition); | ||
var SliderValueText = createLiteReactElement(SliderValueTextDefinition); | ||
var SliderVideo = createLiteReactElement(SliderVideoDefinition); | ||
var TimeSlider = createLiteReactElement(TimeSliderDefinition); | ||
var Time = createLiteReactElement(TimeDefinition); | ||
var VolumeSlider = createLiteReactElement(VolumeSliderDefinition); | ||
var Media = /* @__PURE__ */ createLiteReactElement(MediaDefinition); | ||
var Audio = /* @__PURE__ */ createLiteReactElement(AudioDefinition); | ||
var HLSVideo = /* @__PURE__ */ createLiteReactElement(HLSVideoDefinition); | ||
var Video = /* @__PURE__ */ createLiteReactElement(VideoDefinition); | ||
var AspectRatio = /* @__PURE__ */ createLiteReactElement(AspectRatioDefinition); | ||
var FullscreenButton = /* @__PURE__ */ createLiteReactElement(FullscreenButtonDefinition); | ||
var MuteButton = /* @__PURE__ */ createLiteReactElement(MuteButtonDefinition); | ||
var PlayButton = /* @__PURE__ */ createLiteReactElement(PlayButtonDefinition); | ||
var Poster = /* @__PURE__ */ createLiteReactElement(PosterDefinition); | ||
var SliderValueText = /* @__PURE__ */ createLiteReactElement(SliderValueTextDefinition); | ||
var SliderVideo = /* @__PURE__ */ createLiteReactElement(SliderVideoDefinition); | ||
var TimeSlider = /* @__PURE__ */ createLiteReactElement(TimeSliderDefinition); | ||
var Time = /* @__PURE__ */ createLiteReactElement(TimeDefinition); | ||
var VolumeSlider = /* @__PURE__ */ createLiteReactElement(VolumeSliderDefinition); | ||
// src/context.ts | ||
import { createReactContextProvider } from "maverick.js/react"; | ||
import { mediaContext } from "vidstack"; | ||
var MediaProvider = createReactContextProvider(mediaContext); | ||
// src/use-media-element.ts | ||
import { useReactContext } from "maverick.js/react"; | ||
import { useEffect, useState } from "react"; | ||
import { MediaElementContext } from "vidstack"; | ||
import { mediaContext as mediaContext2 } from "vidstack"; | ||
function useMediaElement() { | ||
const [element, setElement] = useState(null), $mediaElement = useReactContext(MediaElementContext); | ||
const [element, setElement] = useState(null), context = useReactContext(mediaContext2); | ||
if (false) { | ||
console.warn( | ||
"[vidstack] `useMediaElement` can only be called inside a child component of `<Media>`." | ||
); | ||
throw Error("[vidstack] no media context was found - did you forget to provide it?"); | ||
} | ||
useEffect(() => { | ||
if ($mediaElement) | ||
setElement($mediaElement()); | ||
if (!context) | ||
return; | ||
const media = context.$element(); | ||
media.onAttach(() => void setElement(media)); | ||
return () => setElement(null); | ||
}, []); | ||
@@ -53,23 +59,46 @@ return element; | ||
// src/use-media-remote.ts | ||
// src/use-media-provider-element.ts | ||
import { effect } from "maverick.js"; | ||
import { useReactContext as useReactContext2 } from "maverick.js/react"; | ||
import { useEffect as useEffect2, useRef } from "react"; | ||
import { MediaElementContext as MediaElementContext2, MediaRemoteControl } from "vidstack"; | ||
import { useEffect as useEffect2, useState as useState2 } from "react"; | ||
import { mediaContext as mediaContext3 } from "vidstack"; | ||
function useMediaProviderElement() { | ||
const [element, setElement] = useState2(null), context = useReactContext2(mediaContext3); | ||
if (false) { | ||
throw Error("[vidstack] no media context was found - did you forget to provide it?"); | ||
} | ||
useEffect2(() => { | ||
if (!context) | ||
return; | ||
return effect(() => { | ||
const provider = context.$provider(); | ||
provider?.onAttach(() => void setElement(provider)); | ||
}); | ||
}, []); | ||
return element; | ||
} | ||
// src/use-media-remote.ts | ||
import { scoped } from "maverick.js"; | ||
import { useReactContext as useReactContext3, useReactScope } from "maverick.js/react"; | ||
import { isUndefined } from "maverick.js/std"; | ||
import { useEffect as useEffect3, useMemo } from "react"; | ||
import { mediaContext as mediaContext4, MediaRemoteControl } from "vidstack"; | ||
function useMediaRemote(target) { | ||
const remote = useRef(new MediaRemoteControl()), $mediaElement = useReactContext2(MediaElementContext2); | ||
const scope = useReactScope(), context = useReactContext3(mediaContext4); | ||
if (false) { | ||
console.warn( | ||
"[vidstack] `useMediaRemote` requires second argument containing a ref to a DOM element if _not_ called inside a child component of `<Media>`." | ||
throw Error( | ||
"[vidstack] `useMediaRemote` requires `target` argument containing a ref to a DOM element if no media context is provided - did you forget to provide it?`." | ||
); | ||
} | ||
useEffect2(() => { | ||
const remoteTarget = target || $mediaElement?.(); | ||
if (remoteTarget) { | ||
remote.current.setTarget("current" in remoteTarget ? remoteTarget.current : remoteTarget); | ||
} else if ($mediaElement) { | ||
return effect(() => void remote.current.setTarget($mediaElement())); | ||
const remote = useMemo(() => scoped(() => new MediaRemoteControl(), scope), []); | ||
useEffect3(() => { | ||
if (!isUndefined(target)) { | ||
remote.setTarget(target && "current" in target ? target.current : target); | ||
} else if (context) { | ||
remote.setTarget(context.$element()); | ||
} | ||
return () => remote.setTarget(null); | ||
}, [target]); | ||
return remote.current; | ||
return remote; | ||
} | ||
@@ -79,31 +108,36 @@ | ||
import { effect as effect2, signal } from "maverick.js"; | ||
import { useReactContext as useReactContext3 } from "maverick.js/react"; | ||
import { useReactContext as useReactContext4 } from "maverick.js/react"; | ||
import { noop } from "maverick.js/std"; | ||
import { useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState2 } from "react"; | ||
import { mediaStore, MediaStoreContext } from "vidstack"; | ||
function useMediaState(target) { | ||
const [_, update] = useState2(0), stop = useRef2(null), $store = useReactContext3(MediaStoreContext); | ||
import { useEffect as useEffect4, useMemo as useMemo2, useRef, useState as useState3 } from "react"; | ||
import { mediaContext as mediaContext5 } from "vidstack"; | ||
function useMediaState() { | ||
const [_, update] = useState3(0), tracking = useRef({ | ||
$props: signal([]), | ||
observing: /* @__PURE__ */ new Set() | ||
}), context = useReactContext4(mediaContext5); | ||
if (false) { | ||
console.warn( | ||
"[vidstack] `useMediaState` requires second argument containing a ref to `<vds-media>` element if _not_ called inside a child component of `<Media>`. This hook will _not_ be updated when media state changes until this is resolved." | ||
); | ||
throw Error("[vidstack] no media context was found - did you forget to provide it?"); | ||
} | ||
useEffect3(() => () => stop.current?.(), []); | ||
return useMemo(() => { | ||
const media = target && "current" in target ? target.current : target, state = media?.state ?? $store ?? mediaStore.initial, $props = signal([]); | ||
stop.current?.(); | ||
stop.current = effect2(() => { | ||
const props = $props; | ||
useEffect4(() => { | ||
return effect2(() => { | ||
const props = tracking.current.$props(); | ||
const $store = context.$store; | ||
for (let i = 0; i < props.length; i++) | ||
state[props[i]]; | ||
$store[props[i]]; | ||
update((n) => n + 1); | ||
}); | ||
return new Proxy(state, { | ||
}, []); | ||
return useMemo2(() => { | ||
const { observing, $props } = tracking.current, $store = context.$store; | ||
return new Proxy($store, { | ||
get(_2, prop) { | ||
$props.set((prev) => [...prev, prop]); | ||
return state[prop]; | ||
if (!observing.has(prop)) { | ||
$props.set((prev) => [...prev, prop]); | ||
observing.add(prop); | ||
} | ||
return $store[prop]; | ||
}, | ||
set: noop | ||
}); | ||
}, [target]); | ||
}, []); | ||
} | ||
@@ -116,2 +150,3 @@ export { | ||
Media, | ||
MediaProvider, | ||
MuteButton, | ||
@@ -127,4 +162,5 @@ PlayButton, | ||
useMediaElement, | ||
useMediaProviderElement, | ||
useMediaRemote, | ||
useMediaState | ||
}; |
@@ -19,31 +19,37 @@ // src/components.ts | ||
} from "vidstack"; | ||
var Media = createLiteReactElement(MediaDefinition); | ||
var Audio = createLiteReactElement(AudioDefinition); | ||
var HLSVideo = createLiteReactElement(HLSVideoDefinition); | ||
var Video = createLiteReactElement(VideoDefinition); | ||
var AspectRatio = createLiteReactElement(AspectRatioDefinition); | ||
var FullscreenButton = createLiteReactElement(FullscreenButtonDefinition); | ||
var MuteButton = createLiteReactElement(MuteButtonDefinition); | ||
var PlayButton = createLiteReactElement(PlayButtonDefinition); | ||
var Poster = createLiteReactElement(PosterDefinition); | ||
var SliderValueText = createLiteReactElement(SliderValueTextDefinition); | ||
var SliderVideo = createLiteReactElement(SliderVideoDefinition); | ||
var TimeSlider = createLiteReactElement(TimeSliderDefinition); | ||
var Time = createLiteReactElement(TimeDefinition); | ||
var VolumeSlider = createLiteReactElement(VolumeSliderDefinition); | ||
var Media = /* @__PURE__ */ createLiteReactElement(MediaDefinition); | ||
var Audio = /* @__PURE__ */ createLiteReactElement(AudioDefinition); | ||
var HLSVideo = /* @__PURE__ */ createLiteReactElement(HLSVideoDefinition); | ||
var Video = /* @__PURE__ */ createLiteReactElement(VideoDefinition); | ||
var AspectRatio = /* @__PURE__ */ createLiteReactElement(AspectRatioDefinition); | ||
var FullscreenButton = /* @__PURE__ */ createLiteReactElement(FullscreenButtonDefinition); | ||
var MuteButton = /* @__PURE__ */ createLiteReactElement(MuteButtonDefinition); | ||
var PlayButton = /* @__PURE__ */ createLiteReactElement(PlayButtonDefinition); | ||
var Poster = /* @__PURE__ */ createLiteReactElement(PosterDefinition); | ||
var SliderValueText = /* @__PURE__ */ createLiteReactElement(SliderValueTextDefinition); | ||
var SliderVideo = /* @__PURE__ */ createLiteReactElement(SliderVideoDefinition); | ||
var TimeSlider = /* @__PURE__ */ createLiteReactElement(TimeSliderDefinition); | ||
var Time = /* @__PURE__ */ createLiteReactElement(TimeDefinition); | ||
var VolumeSlider = /* @__PURE__ */ createLiteReactElement(VolumeSliderDefinition); | ||
// src/context.ts | ||
import { createReactContextProvider } from "maverick.js/react"; | ||
import { mediaContext } from "vidstack"; | ||
var MediaProvider = createReactContextProvider(mediaContext); | ||
// src/use-media-element.ts | ||
import { useReactContext } from "maverick.js/react"; | ||
import { useEffect, useState } from "react"; | ||
import { MediaElementContext } from "vidstack"; | ||
import { mediaContext as mediaContext2 } from "vidstack"; | ||
function useMediaElement() { | ||
const [element, setElement] = useState(null), $mediaElement = useReactContext(MediaElementContext); | ||
const [element, setElement] = useState(null), context = useReactContext(mediaContext2); | ||
if (false) { | ||
console.warn( | ||
"[vidstack] `useMediaElement` can only be called inside a child component of `<Media>`." | ||
); | ||
throw Error("[vidstack] no media context was found - did you forget to provide it?"); | ||
} | ||
useEffect(() => { | ||
if ($mediaElement) | ||
setElement($mediaElement()); | ||
if (!context) | ||
return; | ||
const media = context.$element(); | ||
media.onAttach(() => void setElement(media)); | ||
return () => setElement(null); | ||
}, []); | ||
@@ -53,23 +59,46 @@ return element; | ||
// src/use-media-remote.ts | ||
// src/use-media-provider-element.ts | ||
import { effect } from "maverick.js"; | ||
import { useReactContext as useReactContext2 } from "maverick.js/react"; | ||
import { useEffect as useEffect2, useRef } from "react"; | ||
import { MediaElementContext as MediaElementContext2, MediaRemoteControl } from "vidstack"; | ||
import { useEffect as useEffect2, useState as useState2 } from "react"; | ||
import { mediaContext as mediaContext3 } from "vidstack"; | ||
function useMediaProviderElement() { | ||
const [element, setElement] = useState2(null), context = useReactContext2(mediaContext3); | ||
if (false) { | ||
throw Error("[vidstack] no media context was found - did you forget to provide it?"); | ||
} | ||
useEffect2(() => { | ||
if (!context) | ||
return; | ||
return effect(() => { | ||
const provider = context.$provider(); | ||
provider == null ? void 0 : provider.onAttach(() => void setElement(provider)); | ||
}); | ||
}, []); | ||
return element; | ||
} | ||
// src/use-media-remote.ts | ||
import { scoped } from "maverick.js"; | ||
import { useReactContext as useReactContext3, useReactScope } from "maverick.js/react"; | ||
import { isUndefined } from "maverick.js/std"; | ||
import { useEffect as useEffect3, useMemo } from "react"; | ||
import { mediaContext as mediaContext4, MediaRemoteControl } from "vidstack"; | ||
function useMediaRemote(target) { | ||
const remote = useRef(new MediaRemoteControl()), $mediaElement = useReactContext2(MediaElementContext2); | ||
const scope = useReactScope(), context = useReactContext3(mediaContext4); | ||
if (false) { | ||
console.warn( | ||
"[vidstack] `useMediaRemote` requires second argument containing a ref to a DOM element if _not_ called inside a child component of `<Media>`." | ||
throw Error( | ||
"[vidstack] `useMediaRemote` requires `target` argument containing a ref to a DOM element if no media context is provided - did you forget to provide it?`." | ||
); | ||
} | ||
useEffect2(() => { | ||
const remoteTarget = target || ($mediaElement == null ? void 0 : $mediaElement()); | ||
if (remoteTarget) { | ||
remote.current.setTarget("current" in remoteTarget ? remoteTarget.current : remoteTarget); | ||
} else if ($mediaElement) { | ||
return effect(() => void remote.current.setTarget($mediaElement())); | ||
const remote = useMemo(() => scoped(() => new MediaRemoteControl(), scope), []); | ||
useEffect3(() => { | ||
if (!isUndefined(target)) { | ||
remote.setTarget(target && "current" in target ? target.current : target); | ||
} else if (context) { | ||
remote.setTarget(context.$element()); | ||
} | ||
return () => remote.setTarget(null); | ||
}, [target]); | ||
return remote.current; | ||
return remote; | ||
} | ||
@@ -79,35 +108,36 @@ | ||
import { effect as effect2, signal } from "maverick.js"; | ||
import { useReactContext as useReactContext3 } from "maverick.js/react"; | ||
import { useReactContext as useReactContext4 } from "maverick.js/react"; | ||
import { noop } from "maverick.js/std"; | ||
import { useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState2 } from "react"; | ||
import { mediaStore, MediaStoreContext } from "vidstack"; | ||
function useMediaState(target) { | ||
const [_, update] = useState2(0), stop = useRef2(null), $store = useReactContext3(MediaStoreContext); | ||
import { useEffect as useEffect4, useMemo as useMemo2, useRef, useState as useState3 } from "react"; | ||
import { mediaContext as mediaContext5 } from "vidstack"; | ||
function useMediaState() { | ||
const [_, update] = useState3(0), tracking = useRef({ | ||
$props: signal([]), | ||
observing: /* @__PURE__ */ new Set() | ||
}), context = useReactContext4(mediaContext5); | ||
if (false) { | ||
console.warn( | ||
"[vidstack] `useMediaState` requires second argument containing a ref to `<vds-media>` element if _not_ called inside a child component of `<Media>`. This hook will _not_ be updated when media state changes until this is resolved." | ||
); | ||
throw Error("[vidstack] no media context was found - did you forget to provide it?"); | ||
} | ||
useEffect3(() => () => { | ||
var _a; | ||
return (_a = stop.current) == null ? void 0 : _a.call(stop); | ||
}, []); | ||
return useMemo(() => { | ||
var _a; | ||
const media = target && "current" in target ? target.current : target, state = (media == null ? void 0 : media.state) ?? $store ?? mediaStore.initial, $props = signal([]); | ||
(_a = stop.current) == null ? void 0 : _a.call(stop); | ||
stop.current = effect2(() => { | ||
const props = $props; | ||
useEffect4(() => { | ||
return effect2(() => { | ||
const props = tracking.current.$props(); | ||
const $store = context.$store; | ||
for (let i = 0; i < props.length; i++) | ||
state[props[i]]; | ||
$store[props[i]]; | ||
update((n) => n + 1); | ||
}); | ||
return new Proxy(state, { | ||
}, []); | ||
return useMemo2(() => { | ||
const { observing, $props } = tracking.current, $store = context.$store; | ||
return new Proxy($store, { | ||
get(_2, prop) { | ||
$props.set((prev) => [...prev, prop]); | ||
return state[prop]; | ||
if (!observing.has(prop)) { | ||
$props.set((prev) => [...prev, prop]); | ||
observing.add(prop); | ||
} | ||
return $store[prop]; | ||
}, | ||
set: noop | ||
}); | ||
}, [target]); | ||
}, []); | ||
} | ||
@@ -120,2 +150,3 @@ export { | ||
Media, | ||
MediaProvider, | ||
MuteButton, | ||
@@ -131,4 +162,5 @@ PlayButton, | ||
useMediaElement, | ||
useMediaProviderElement, | ||
useMediaRemote, | ||
useMediaState | ||
}; |
/** | ||
All media elements exist inside the `<vds-media>` component. It's main jobs are to host the | ||
media controller, and expose media state through HTML attributes and CSS properties for styling | ||
All media elements exist inside the `<vds-media>` component. This component's main | ||
responsibilities are to manage media state updates, dispatch media events, handle media | ||
requests, and expose media state through HTML attributes and CSS properties for styling | ||
purposes. | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/media/media} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/layout/media} | ||
* @example | ||
@@ -20,24 +21,26 @@ *```tsx | ||
/** | ||
The `<vds-audio>` component adapts the slotted `<audio>` element to satisfy the media provider | ||
contract, which generally involves providing a consistent API for loading, managing, and | ||
tracking media state. | ||
The `<vds-audio>` component adapts the slotted `<audio>` element to enable loading audio | ||
via the HTML Media Element API. | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/providers/audio} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/providers/audio} | ||
* @example | ||
*```tsx | ||
*<Audio> | ||
* <audio | ||
* controls | ||
* preload="none" | ||
* src="https://media-files.vidstack.io/audio.mp3" | ||
* ></audio> | ||
*</Audio> | ||
*<Media controls view="audio"> | ||
* <Audio> | ||
* <audio | ||
* preload="none" | ||
* src="https://media-files.vidstack.io/audio.mp3" | ||
* ></audio> | ||
* </Audio> | ||
*</Media> | ||
*``` | ||
* @example | ||
*```tsx | ||
*<Audio> | ||
* <audio controls preload="none"> | ||
* <source src="https://media-files.vidstack.io/audio.mp3" type="audio/mp3" /> | ||
* </audio> | ||
*</Audio> | ||
*<Media controls view="audio"> | ||
* <Audio> | ||
* <audio preload="none"> | ||
* <source src="https://media-files.vidstack.io/audio.mp3" type="audio/mp3" /> | ||
* </audio> | ||
* </Audio> | ||
*</Media> | ||
*``` | ||
@@ -56,29 +59,33 @@ */ | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/providers/hls-video} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/providers/hls-video} | ||
* @example | ||
*```tsx | ||
*<HlsVideo poster="https://media-files.vidstack.io/poster.png"> | ||
* <video | ||
* preload="none" | ||
* src="https://media-files.vidstack.io/hls/index.m3u8" | ||
* ></video> | ||
*</HlsVideo> | ||
*<Media poster="https://media-files.vidstack.io/poster.png"> | ||
* <HlsVideo> | ||
* <video | ||
* preload="none" | ||
* src="https://media-files.vidstack.io/hls/index.m3u8" | ||
* ></video> | ||
* </HlsVideo> | ||
*</Media> | ||
*``` | ||
* @example | ||
*```tsx | ||
*<HlsVideo poster="https://media-files.vidstack.io/poster.png"> | ||
* <video preload="none"> | ||
* <source | ||
* src="https://media-files.vidstack.io/hls/index.m3u8" | ||
* type="application/x-mpegURL" | ||
* /> | ||
* <track | ||
* default | ||
* kind="subtitles" | ||
* srclang="en" | ||
* label="English" | ||
* src="https://media-files.vidstack.io/subs/english.vtt" | ||
* /> | ||
* </video> | ||
*</HlsVideo> | ||
*<Media poster="https://media-files.vidstack.io/poster.png"> | ||
* <HlsVideo> | ||
* <video preload="none"> | ||
* <source | ||
* src="https://media-files.vidstack.io/hls/index.m3u8" | ||
* type="application/x-mpegURL" | ||
* /> | ||
* <track | ||
* default | ||
* kind="subtitles" | ||
* srclang="en" | ||
* label="English" | ||
* src="https://media-files.vidstack.io/subs/english.vtt" | ||
* /> | ||
* </video> | ||
* </HlsVideo> | ||
*</Media> | ||
*``` | ||
@@ -88,33 +95,36 @@ */ | ||
/** | ||
The `<vds-video>` component adapts the slotted `<video>` element to satisfy the media provider | ||
contract, which generally involves providing a consistent API for loading, managing, and | ||
tracking media state. | ||
The `<vds-video>` component adapts the slotted `<video>` element to enable loading videos | ||
via the HTML Media Element API. | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/providers/video} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/providers/video} | ||
* @example | ||
*```tsx | ||
*<Video poster="https://media-files.vidstack.io/poster.png"> | ||
* <video | ||
* preload="none" | ||
* src="https://media-files.vidstack.io/720p.mp4" | ||
* ></video> | ||
*</Video> | ||
*<Media poster="https://media-files.vidstack.io/poster.png"> | ||
* <Video> | ||
* <video | ||
* preload="none" | ||
* src="https://media-files.vidstack.io/720p.mp4" | ||
* ></video> | ||
* </Video> | ||
*</Media> | ||
*``` | ||
* @example | ||
*```tsx | ||
*<Video poster="https://media-files.vidstack.io/poster.png"> | ||
* <video preload="none"> | ||
* <source | ||
* src="https://media-files.vidstack.io/720p.mp4" | ||
* type="video/mp4" | ||
* /> | ||
* <track | ||
* default | ||
* kind="subtitles" | ||
* srclang="en" | ||
* label="English" | ||
* src="https://media-files.vidstack.io/subs/english.vtt" | ||
* /> | ||
* </video> | ||
*</Video> | ||
*<Media poster="https://media-files.vidstack.io/poster.png"> | ||
* <Video> | ||
* <video preload="none"> | ||
* <source | ||
* src="https://media-files.vidstack.io/720p.mp4" | ||
* type="video/mp4" | ||
* /> | ||
* <track | ||
* default | ||
* kind="subtitles" | ||
* srclang="en" | ||
* label="English" | ||
* src="https://media-files.vidstack.io/subs/english.vtt" | ||
* /> | ||
* </video> | ||
* </Video> | ||
*</Media> | ||
*``` | ||
@@ -136,3 +146,3 @@ */ | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/ui/aspect-ratio} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/layout/aspect-ratio} | ||
* @example | ||
@@ -151,3 +161,3 @@ *```tsx | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/ui/fullscreen-button} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/buttons/fullscreen-button} | ||
* @example | ||
@@ -162,3 +172,3 @@ *```tsx | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/ui/mute-button} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/buttons/mute-button} | ||
* @example | ||
@@ -173,3 +183,3 @@ *```tsx | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/ui/play-button} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/buttons/play-button} | ||
* @example | ||
@@ -185,3 +195,3 @@ *```tsx | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/ui/poster} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/layout/poster} | ||
* @example | ||
@@ -198,3 +208,3 @@ *```tsx | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/ui/slider-value-text} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/sliders/slider-value-text} | ||
* @example | ||
@@ -239,3 +249,3 @@ *```tsx | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/ui/slider-video} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/sliders/slider-video} | ||
* @example | ||
@@ -252,3 +262,3 @@ *```tsx | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/ui/time-slider} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/sliders/time-slider} | ||
* @example | ||
@@ -274,3 +284,3 @@ *```tsx | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/ui/time} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/display/time} | ||
* @example | ||
@@ -290,3 +300,3 @@ *```tsx | ||
* @docs {@link https://www.vidstack./io/docs/react/player/components/ui/volume-slider} | ||
* @docs {@link https://www.vidstack.io/docs/react/player/components/sliders/volume-slider} | ||
* @example | ||
@@ -293,0 +303,0 @@ *```tsx |
export * from './components'; | ||
export * from './context'; | ||
export * from './use-media-element'; | ||
export * from './use-media-provider-element'; | ||
export * from './use-media-remote'; | ||
export * from './use-media-state'; |
import { MediaElement } from 'vidstack'; | ||
/** | ||
* Returns the nearest parent media element (i.e., `<vds-media>`). This hook can only be used | ||
* inside a child of the `<Media>` component. | ||
* Returns the nearest parent media element (i.e., `<vds-media>`). | ||
* | ||
* @docs {@link https://vidstack.io/docs/react/player/core-concepts/state-management#media-element} | ||
*/ | ||
export declare function useMediaElement(): MediaElement | null; |
@@ -7,14 +7,7 @@ import { RefObject } from 'react'; | ||
* | ||
* @param target - The DOM event target to dispatch request events from. | ||
* @param target - The DOM event target to dispatch request events from. Defaults to `<vds-media>` | ||
* if no target is provided. | ||
* | ||
* @example | ||
* ```tsx | ||
* import { useMediaRemote } from '@vidstack/react'; | ||
* | ||
* function PlayButton() { | ||
* const remote = useMediaRemote(); | ||
* return <button onPointerUp={({ nativeEvent }) => remote.play(nativeEvent)}>Play</button>; | ||
* } | ||
* ``` | ||
* @docs {@link https://vidstack.io/docs/react/player/core-concepts/state-management#updating} | ||
*/ | ||
export declare function useMediaRemote(target?: EventTarget | null | RefObject<EventTarget>): MediaRemoteControl; | ||
export declare function useMediaRemote(target?: EventTarget | null | RefObject<EventTarget | null>): MediaRemoteControl; |
@@ -1,3 +0,2 @@ | ||
import { RefObject } from 'react'; | ||
import { MediaElement, MediaState } from 'vidstack'; | ||
import { MediaState } from 'vidstack'; | ||
/** | ||
@@ -7,12 +6,4 @@ * This hook is used to access the current media state on the nearest parent media element (i.e., | ||
* | ||
* @example | ||
* ```tsx | ||
* import { useMediaState } from '@vidstack/react'; | ||
* | ||
* function Component() { | ||
* const { playing } = useMediaState(); | ||
* return <div>{playing ? 'Media is _not_ playing.' : 'Media is playing.'}</div> | ||
* } | ||
* ``` | ||
* @docs {@link https://vidstack.io/docs/react/player/core-concepts/state-management#reading} | ||
*/ | ||
export declare function useMediaState(target?: MediaElement | null | RefObject<MediaElement>): Readonly<MediaState>; | ||
export declare function useMediaState(): Readonly<MediaState>; |
{ | ||
"name": "@vidstack/react", | ||
"version": "0.0.2", | ||
"version": "0.1.0", | ||
"description": "Build awesome media experiences on the web.", | ||
@@ -24,11 +24,11 @@ "license": "MIT", | ||
"peerDependencies": { | ||
"@types/react": "^17.0.0", | ||
"maverick.js": "^0.27.0", | ||
"react": "^17.0.0", | ||
"vidstack": "0.0.2" | ||
"@types/react": "^18.0.0", | ||
"maverick.js": "^0.31.1", | ||
"react": "^18.0.0", | ||
"vidstack": "0.1.0" | ||
}, | ||
"devDependencies": { | ||
"@types/react": "^17.0.0", | ||
"maverick.js": "^0.27.0", | ||
"react": "^17.0.0", | ||
"@types/react": "^18.0.0", | ||
"maverick.js": "^0.31.1", | ||
"react": "^18.0.0", | ||
"rimraf": "^3.0.0", | ||
@@ -52,6 +52,6 @@ "tsup": "^6.5.0", | ||
".": { | ||
"development": "./dist/dev.js", | ||
"require": "./dist/server.cjs", | ||
"node": "./dist/server.js", | ||
"deno": "./dist/server.js", | ||
"development": "./dist/dev.js", | ||
"default": "./dist/prod.js" | ||
@@ -58,0 +58,0 @@ } |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
39015
14
981