import { FormControl, FormControlProps, FormLabel, FormLabelProps, HStack, NumberDecrementStepper, NumberIncrementStepper, NumberInput, NumberInputField, NumberInputFieldProps, NumberInputProps, NumberInputStepper, NumberInputStepperProps, Slider, SliderFilledTrack, SliderMark, SliderMarkProps, SliderThumb, SliderThumbProps, SliderTrack, SliderTrackProps, Tooltip, TooltipProps, } from '@chakra-ui/react'; import { clamp } from 'lodash'; import { useTranslation } from 'react-i18next'; import { FocusEvent, memo, useEffect, useMemo, useState } from 'react'; import { BiReset } from 'react-icons/bi'; import IAIIconButton, { IAIIconButtonProps } from './IAIIconButton'; export type IAIFullSliderProps = { label: string; value: number; min?: number; max?: number; step?: number; onChange: (v: number) => void; withSliderMarks?: boolean; withInput?: boolean; isInteger?: boolean; inputWidth?: string | number; inputReadOnly?: boolean; withReset?: boolean; handleReset?: () => void; tooltipSuffix?: string; hideTooltip?: boolean; isCompact?: boolean; isDisabled?: boolean; sliderFormControlProps?: FormControlProps; sliderFormLabelProps?: FormLabelProps; sliderMarkProps?: Omit; sliderTrackProps?: SliderTrackProps; sliderThumbProps?: SliderThumbProps; sliderNumberInputProps?: NumberInputProps; sliderNumberInputFieldProps?: NumberInputFieldProps; sliderNumberInputStepperProps?: NumberInputStepperProps; sliderTooltipProps?: Omit; sliderIAIIconButtonProps?: IAIIconButtonProps; }; const IAISlider = (props: IAIFullSliderProps) => { const [showTooltip, setShowTooltip] = useState(false); const { label, value, min = 1, max = 100, step = 1, onChange, tooltipSuffix = '', withSliderMarks = false, withInput = false, isInteger = false, inputWidth = 16, inputReadOnly = false, withReset = false, hideTooltip = false, isCompact = false, isDisabled = false, handleReset, sliderFormControlProps, sliderFormLabelProps, sliderMarkProps, sliderTrackProps, sliderThumbProps, sliderNumberInputProps, sliderNumberInputFieldProps, sliderNumberInputStepperProps, sliderTooltipProps, sliderIAIIconButtonProps, ...rest } = props; const { t } = useTranslation(); const [localInputValue, setLocalInputValue] = useState< string | number | undefined >(String(value)); useEffect(() => { setLocalInputValue(value); }, [value]); const numberInputMax = useMemo( () => (sliderNumberInputProps?.max ? sliderNumberInputProps.max : max), [max, sliderNumberInputProps?.max] ); const handleSliderChange = (v: number) => { onChange(v); }; const handleInputBlur = (e: FocusEvent) => { if (e.target.value === '') e.target.value = String(min); const clamped = clamp( isInteger ? Math.floor(Number(e.target.value)) : Number(localInputValue), min, numberInputMax ); onChange(clamped); }; const handleInputChange = (v: number | string) => { setLocalInputValue(v); }; const handleResetDisable = () => { if (!handleReset) return; handleReset(); }; return ( {label} setShowTooltip(true)} onMouseLeave={() => setShowTooltip(false)} focusThumbOnChange={false} isDisabled={isDisabled} {...rest} > {withSliderMarks && ( <> {min} {max} )} {withInput && ( onChange(Number(localInputValue))} /> onChange(Number(localInputValue))} /> )} {withReset && ( } isDisabled={isDisabled} onClick={handleResetDisable} {...sliderIAIIconButtonProps} /> )} ); }; export default memo(IAISlider);