import React, { useCallback, useMemo, useState } from 'react'; import MultiSlider from '@ptomasroos/react-native-multi-slider'; import type { LayoutChangeEvent, StyleProp, ViewStyle } from 'react-native'; import { View } from 'react-native'; import { useTheme } from '../../theme'; import { StyledMarker } from './StyledRangeSlider'; import { DISABLED_UNSELECTED_TRACK_OPACITY, DISABLED_SELECTED_TRACK_OPACITY, } from './constants'; export type SliderRangeValue = { start: number; end: number; }; interface RangeSliderProps { /** * Minimum value of the slider. */ minimumValue: number; /** * Maximum value of the slider. */ maximumValue: number; /** * Step value of the slider. * The value should be between 1 and (maximumValue - minimumValue). * Defaults to 1. */ step?: number; /** * Range value of the slider. * Defaults to minimumValue. */ value?: SliderRangeValue; /** * Whether the two markers should be allowed to overlap. * Defaults to false. */ allowOverlap?: boolean; /** * Callback continuously called while the user is dragging the slider. */ onValueChange?: (value: SliderRangeValue) => void; /** * Callback that is called when the user picks up the slider. * The initial value is passed as an argument to the callback handler. */ onSlidingStart?: () => void; /** * Callback that is called when the user releases the slider, regardless if the value has changed. * The current value is passed as an argument to the callback handler. */ onSlidingComplete?: (value: SliderRangeValue) => void; /** * Whether the slider is disabled. */ disabled?: boolean; /** * Additional style. */ style?: StyleProp; /** * Testing id of the component. */ testID?: string; } const Slider = ({ minimumValue, maximumValue, step = 1, value, onValueChange, onSlidingStart, onSlidingComplete, disabled = false, style, testID, allowOverlap = false, }: RangeSliderProps) => { const theme = useTheme(); const handleTwoWaySliderChange = React.useCallback( (values: number[]) => { if (onValueChange) { onValueChange({ start: values[0], end: values[1] }); } }, [onValueChange] ); const [layoutSize, setLayoutSize] = useState({ width: 0, height: 0 }); const nativeValue = useMemo(() => { return [value?.start ?? minimumValue, value?.end ?? maximumValue]; }, [value?.start, value?.end, minimumValue, maximumValue]); const { unselectedTrack, disabledUnselectedTrack, selectedTrack, disabledSelectedTrack, } = theme.__hd__.slider.colors; const { trackHeight } = theme.__hd__.slider.sizes; // Define styles for disabled and enabled states const disabledStyles = { track: { opacity: DISABLED_UNSELECTED_TRACK_OPACITY, backgroundColor: disabledUnselectedTrack, height: trackHeight, }, selected: { opacity: DISABLED_SELECTED_TRACK_OPACITY, backgroundColor: disabledSelectedTrack, }, }; const enabledStyles = { track: { backgroundColor: unselectedTrack, height: trackHeight, }, selected: { backgroundColor: selectedTrack, }, }; // Use styles based on the `disabled` state const trackStyle = disabled ? disabledStyles.track : enabledStyles.track; const selectedStyle = disabled ? disabledStyles.selected : enabledStyles.selected; const handleOnValueChangeStart = useCallback(() => { if (onSlidingStart) { onSlidingStart(); } }, [onSlidingStart]); const handleOnValueChangeFinish = useCallback( (values: number[]) => { if (onSlidingComplete) { onSlidingComplete({ start: values[0], end: values[1], }); } }, [onSlidingComplete] ); const onLayoutCallback = useCallback((event: LayoutChangeEvent) => { setLayoutSize({ width: event.nativeEvent.layout.width, height: event.nativeEvent.layout.height, }); }, []); const CustomMarker = useMemo(() => { return () => ; }, [disabled]); return ( ); }; export default Slider;