Files
v10/dist/dev/ui/input-indicators/use-rendered-indicator-state.js

43 lines
1.7 KiB
JavaScript

"use client";
import { useDestroy } from "../../utils/use-destroy.js";
import { createTransition } from "@videojs/core/dom";
import { useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
import { getRenderedIndicatorState, isIndicatorPresent } from "@videojs/core";
//#region src/ui/input-indicators/use-rendered-indicator-state.ts
function useRenderedIndicatorState(currentState, options = {}) {
const elementRef = useRef(null);
const currentStateRef = useRef(currentState);
const snapshotRef = useRef(currentState);
const [transition] = useState(() => createTransition());
useDestroy(transition);
currentStateRef.current = currentState;
const transitionState = useSyncExternalStore((callback) => transition.state.subscribe(callback), () => transition.state.current, () => transition.state.current);
const { generation, open } = currentState;
useLayoutEffect(() => {
if (open) {
const nextState = currentStateRef.current;
if (nextState.generation !== generation) return;
snapshotRef.current = nextState;
const transitionState = transition.state.current;
if (!transitionState.active || options.replayOnUpdate !== false) transition.open(elementRef.current);
else if (transitionState.status === "ending") transition.cancel();
return;
}
const { active, status } = transition.state.current;
if (active && status !== "ending") transition.close(elementRef.current);
}, [
generation,
open,
options.replayOnUpdate,
transition
]);
return {
elementRef,
present: isIndicatorPresent(currentState, transitionState),
state: getRenderedIndicatorState(currentState, snapshotRef.current, transitionState)
};
}
//#endregion
export { useRenderedIndicatorState };
//# sourceMappingURL=use-rendered-indicator-state.js.map