"use client"; import * as React from "react"; import type { Slider as SliderPrimitive } from "@base-ui/react/slider"; import { normalizeSliderValueShape, snapSliderValue, valuesMatch, type SliderRuntimeValue, type SliderValue, } from "./slider-value"; export type SliderThumbDoubleClickHandler = ( event: React.MouseEvent | React.PointerEvent, index: number, ) => void; type UseSliderThumbResetOptions = { defaultValue?: Value; disabled?: boolean; handleValueChange: SliderPrimitive.Root.Props["onValueChange"]; handleValueCommitted: ( value: SliderValue, eventDetails: SliderPrimitive.Root.CommitEventDetails, ) => void; isDiscrete: boolean; max: number; min: number; resetValue?: Value; snapValues?: readonly number[]; step: number; value?: Value; values: readonly number[]; }; function createSliderResetChangeEventDetails( event: React.MouseEvent | React.PointerEvent, activeThumbIndex: number, ): SliderPrimitive.Root.ChangeEventDetails { return { activeThumbIndex, allowPropagation: () => undefined, cancel: () => undefined, event: event.nativeEvent, isCanceled: false, isPropagationAllowed: false, reason: "none", trigger: event.currentTarget, }; } function createSliderResetCommitEventDetails( event: React.MouseEvent | React.PointerEvent, ): SliderPrimitive.Root.CommitEventDetails { return { event: event.nativeEvent, reason: "none", }; } function getThumbResetValue( currentValue: Value, resetValue: Value, index: number, ): Value { if (!Array.isArray(currentValue) || !Array.isArray(resetValue)) { return resetValue; } const nextValue = [...currentValue]; const nextThumbValue = resetValue[index] ?? currentValue[index]; if (nextThumbValue === undefined) { return currentValue; } nextValue[index] = nextThumbValue; return nextValue as unknown as Value; } export function useSliderThumbReset({ defaultValue, disabled, handleValueChange, handleValueCommitted, isDiscrete, max, min, resetValue, snapValues, step, value, values, }: UseSliderThumbResetOptions): SliderThumbDoubleClickHandler { const initialResetValueRef = React.useRef(resetValue ?? defaultValue ?? value); return React.useCallback( (event, index) => { if (disabled) { return; } const resetTarget = resetValue ?? defaultValue ?? initialResetValueRef.current; if (resetTarget === undefined) { return; } event.preventDefault(); event.stopPropagation(); const normalizedResetValue = normalizeSliderValueShape( resetTarget as SliderRuntimeValue, value, defaultValue, min, ); const currentValue = normalizeSliderValueShape(values, value, defaultValue, min); const resetThumbValue = getThumbResetValue(currentValue, normalizedResetValue, index); const nextValue = isDiscrete ? snapSliderValue(resetThumbValue, min, max, step, snapValues) : resetThumbValue; if (valuesMatch(currentValue, nextValue)) { return; } handleValueChange?.( nextValue as SliderValue, createSliderResetChangeEventDetails(event, index), ); handleValueCommitted( nextValue as SliderValue, createSliderResetCommitEventDetails(event), ); }, [ defaultValue, disabled, handleValueChange, handleValueCommitted, isDiscrete, max, min, resetValue, snapValues, step, value, values, ], ); }