mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
120 lines
4.0 KiB
JavaScript
120 lines
4.0 KiB
JavaScript
"use client";
|
|
import { useLocale, useTranslator } from "../../i18n/context.js";
|
|
import { usePlayer } from "../../player/context.js";
|
|
import { useLatestRef } from "../../utils/use-latest-ref.js";
|
|
import { renderElement } from "../../utils/use-render.js";
|
|
import { useSlider } from "../hooks/use-slider.js";
|
|
import { SliderProvider } from "../slider/context.js";
|
|
import { createWheelStep, getSliderCSSVars, logMissingFeature, selectVolume } from "@videojs/core/dom";
|
|
import { translateText } from "@videojs/core/i18n";
|
|
import { forwardRef, useCallback, useRef, useState } from "react";
|
|
import { listen } from "@videojs/utils/dom";
|
|
import { jsx } from "react/jsx-runtime";
|
|
import { VolumeSliderCore, VolumeSliderDataAttrs } from "@videojs/core";
|
|
//#region src/ui/volume-slider/volume-slider-root.tsx
|
|
const noopVolume = {
|
|
volume: 0,
|
|
muted: false,
|
|
volumeAvailability: "unsupported",
|
|
setVolume: () => 0,
|
|
toggleMuted: () => false
|
|
};
|
|
const VolumeSliderRoot = forwardRef(function VolumeSliderRoot(componentProps, forwardedRef) {
|
|
const { render, className, style, label, orientation, step = VolumeSliderCore.defaultProps.step, largeStep = VolumeSliderCore.defaultProps.largeStep, wheelStep = VolumeSliderCore.defaultProps.wheelStep, disabled, thumbAlignment, onDragStart, onDragEnd, ...elementProps } = componentProps;
|
|
const volume = usePlayer(selectVolume);
|
|
const translator = useTranslator();
|
|
const locale = useLocale();
|
|
const [core] = useState(() => new VolumeSliderCore());
|
|
core.setProps({
|
|
label,
|
|
orientation,
|
|
step,
|
|
largeStep,
|
|
wheelStep,
|
|
disabled,
|
|
thumbAlignment
|
|
});
|
|
core.setFormatLocale(locale);
|
|
const volumeRef = useLatestRef(volume);
|
|
const disabledRef = useLatestRef(disabled);
|
|
const getPercent = () => (volumeRef.current?.volume ?? 0) * 100;
|
|
const getStepPercent = () => core.getStepPercent();
|
|
const setVolume = (percent) => volumeRef.current?.setVolume(percent / 100);
|
|
const { state, cssVars, rootRef, thumbRef, rootProps, rootStyle, thumbProps } = useSlider({
|
|
computeState: (input) => {
|
|
core.setInput(input);
|
|
core.setMedia(volume ?? noopVolume);
|
|
return core.getState();
|
|
},
|
|
getPercent,
|
|
getStepPercent,
|
|
getLargeStepPercent: () => core.getLargeStepPercent(),
|
|
orientation,
|
|
disabled,
|
|
adjustPercent: (rawPercent, thumbSize, trackSize) => core.adjustPercentForAlignment(rawPercent, thumbSize, trackSize),
|
|
getCSSVars: getSliderCSSVars,
|
|
onValueChange: setVolume,
|
|
onValueCommit: setVolume,
|
|
onDragStart,
|
|
onDragEnd
|
|
});
|
|
const [wheelHandler] = useState(() => createWheelStep({
|
|
isDisabled: () => !!disabledRef.current || !volumeRef.current,
|
|
getPercent: () => (volumeRef.current?.volume ?? 0) * 100,
|
|
getStepPercent: () => core.getWheelStepPercent(),
|
|
onValueChange: (percent) => volumeRef.current?.setVolume(percent / 100)
|
|
}));
|
|
const wheelCleanupRef = useRef(null);
|
|
const wheelRef = useCallback((element) => {
|
|
wheelCleanupRef.current?.();
|
|
wheelCleanupRef.current = null;
|
|
if (element) wheelCleanupRef.current = listen(element, "wheel", wheelHandler.onWheel, { passive: false });
|
|
}, [wheelHandler]);
|
|
if (!volume) {
|
|
logMissingFeature("VolumeSlider", "volume");
|
|
return null;
|
|
}
|
|
return /* @__PURE__ */ jsx(SliderProvider, {
|
|
value: {
|
|
state,
|
|
pointerValue: core.valueFromPercent(state.pointerPercent),
|
|
thumbRef,
|
|
thumbProps,
|
|
stateAttrMap: VolumeSliderDataAttrs,
|
|
getAttrs: (sliderState) => {
|
|
const attrs = core.getAttrs(sliderState);
|
|
return {
|
|
...attrs,
|
|
"aria-label": translateText(attrs["aria-label"], translator),
|
|
"aria-valuetext": translateText(attrs["aria-valuetext"], translator, core.getValueTextParams(sliderState))
|
|
};
|
|
},
|
|
formatValue: (value) => `${Math.round(value)}%`
|
|
},
|
|
children: renderElement("div", {
|
|
render,
|
|
className,
|
|
style
|
|
}, {
|
|
state,
|
|
stateAttrMap: VolumeSliderDataAttrs,
|
|
ref: [
|
|
forwardedRef,
|
|
rootRef,
|
|
wheelRef
|
|
],
|
|
props: [
|
|
{ style: {
|
|
...cssVars,
|
|
...rootStyle
|
|
} },
|
|
rootProps,
|
|
elementProps
|
|
]
|
|
})
|
|
});
|
|
});
|
|
//#endregion
|
|
export { VolumeSliderRoot };
|
|
|
|
//# sourceMappingURL=volume-slider-root.js.map
|