Files
v10/dist/dev/ui/hooks/use-slider.js

63 lines
2.5 KiB
JavaScript

"use client";
import { useLatestRef } from "../../utils/use-latest-ref.js";
import { useDestroy } from "../../utils/use-destroy.js";
import { useForceRender } from "../../utils/use-force-render.js";
import { createSlider } from "@videojs/core/dom";
import { useSnapshot } from "@videojs/store/react";
import { useCallback, useLayoutEffect, useRef, useState } from "react";
import { isRTL } from "@videojs/utils/dom";
//#region src/ui/hooks/use-slider.ts
/**
* Manages slider input lifecycle for React.
*
* Wraps `createSlider()` from `@videojs/core/dom` and subscribes to its
* input state via `useSnapshot`. Returns split props for the root
* (pointer events) and thumb (keyboard/focus) elements.
*/
function useSlider(options) {
const optionsRef = useLatestRef(options);
const rootElementRef = useRef(null);
const thumbElementRef = useRef(null);
const forceRender = useForceRender();
const [slider] = useState(() => {
return createSlider({
getElement: () => rootElementRef.current,
getThumbElement: () => thumbElementRef.current,
getOrientation: () => optionsRef.current.orientation ?? "horizontal",
isRTL: () => rootElementRef.current ? isRTL(rootElementRef.current) : false,
isDisabled: () => optionsRef.current.disabled ?? false,
getPercent: () => optionsRef.current.getPercent(),
getStepPercent: () => optionsRef.current.getStepPercent(),
getLargeStepPercent: () => optionsRef.current.getLargeStepPercent(),
changeThrottle: optionsRef.current.changeThrottle,
adjustPercent: optionsRef.current.adjustPercent,
onValueChange: (percent) => optionsRef.current.onValueChange?.(percent),
onValueCommit: (percent) => optionsRef.current.onValueCommit?.(percent),
onDragStart: () => optionsRef.current.onDragStart?.(),
onDragEnd: () => optionsRef.current.onDragEnd?.()
});
});
useDestroy(slider);
const input = useSnapshot(slider.input);
const state = options.computeState(input);
useLayoutEffect(() => {
if (state.thumbAlignment === "edge" && rootElementRef.current && thumbElementRef.current) forceRender();
}, [state.thumbAlignment]);
return {
state,
cssVars: options.getCSSVars(slider.adjustForAlignment(state)),
rootRef: useCallback((element) => {
rootElementRef.current = element;
}, []),
thumbRef: useCallback((element) => {
thumbElementRef.current = element;
}, []),
rootProps: slider.rootProps,
rootStyle: slider.rootStyle,
thumbProps: slider.thumbProps
};
}
//#endregion
export { useSlider };
//# sourceMappingURL=use-slider.js.map