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 React, { FocusEvent, useEffect, useMemo, useState } from 'react'; import { BiReset } from 'react-icons/bi'; import IAIIconButton, { IAIIconButtonProps } from './IAIIconButton'; import _ from 'lodash'; export type IAIFullSliderProps = { label: string; value: number; min?: number; max?: number; step?: number; onChange: (v: number) => void; withSliderMarks?: boolean; sliderMarkLeftOffset?: number; sliderMarkRightOffset?: number; withInput?: boolean; isInteger?: boolean; width?: string | number; inputWidth?: string | number; inputReadOnly?: boolean; withReset?: boolean; handleReset?: () => void; isResetDisabled?: boolean; isSliderDisabled?: boolean; isInputDisabled?: boolean; tooltipSuffix?: string; hideTooltip?: boolean; isCompact?: boolean; styleClass?: string; sliderFormControlProps?: FormControlProps; sliderFormLabelProps?: FormLabelProps; sliderMarkProps?: Omit; sliderTrackProps?: SliderTrackProps; sliderThumbProps?: SliderThumbProps; sliderNumberInputProps?: NumberInputProps; sliderNumberInputFieldProps?: NumberInputFieldProps; sliderNumberInputStepperProps?: NumberInputStepperProps; sliderTooltipProps?: Omit; sliderIAIIconButtonProps?: IAIIconButtonProps; }; export default function IAISlider(props: IAIFullSliderProps) { const [showTooltip, setShowTooltip] = useState(false); const { label, value, min = 1, max = 100, step = 1, onChange, width = '100%', tooltipSuffix = '', withSliderMarks = false, sliderMarkLeftOffset = 0, sliderMarkRightOffset = -7, withInput = false, isInteger = false, inputWidth = '5.5rem', inputReadOnly = true, withReset = false, hideTooltip = false, isCompact = false, handleReset, isResetDisabled, isSliderDisabled, isInputDisabled, styleClass, sliderFormControlProps, sliderFormLabelProps, sliderMarkProps, sliderTrackProps, sliderThumbProps, sliderNumberInputProps, sliderNumberInputFieldProps, sliderNumberInputStepperProps, sliderTooltipProps, sliderIAIIconButtonProps, ...rest } = props; const [localInputValue, setLocalInputValue] = useState(String(value)); const numberInputMax = useMemo( () => (sliderNumberInputProps?.max ? sliderNumberInputProps.max : max), [max, sliderNumberInputProps?.max] ); useEffect(() => { if (String(value) !== localInputValue && localInputValue !== '') { setLocalInputValue(String(value)); } }, [value, localInputValue, setLocalInputValue]); const handleInputBlur = (e: FocusEvent) => { const clamped = _.clamp( isInteger ? Math.floor(Number(e.target.value)) : Number(e.target.value), min, numberInputMax ); setLocalInputValue(String(clamped)); onChange(clamped); }; const handleInputChange = (v: number | string) => { setLocalInputValue(String(v)); onChange(Number(v)); }; const handleResetDisable = () => { if (!handleReset) return; handleReset(); }; return ( {label} setShowTooltip(true)} onMouseLeave={() => setShowTooltip(false)} focusThumbOnChange={false} isDisabled={isSliderDisabled} width={width} {...rest} > {withSliderMarks && ( <> {min} {max} )} {withInput && ( )} {withReset && ( } onClick={handleResetDisable} isDisabled={isResetDisabled} {...sliderIAIIconButtonProps} /> )} ); }