import type { InputHTMLAttributes, ReactNode, Ref } from 'react'; import { cx } from '../utils/cx'; import type { Size } from '../utils/types'; import { useControllableState } from '../hooks/useControllableState'; import { describedBy, Field, useFieldIds } from './Field'; export interface SliderProps extends Omit, 'size' | 'type' | 'value' | 'defaultValue' | 'onChange'> { label?: ReactNode; description?: ReactNode; error?: ReactNode; size?: Exclude; min?: number; max?: number; step?: number; value?: number; defaultValue?: number; onValueChange?: (value: number) => void; showValue?: boolean; formatValue?: (value: number) => string; ref?: Ref; } export function Slider({ label, description, error, size = 'md', min = 0, max = 100, step = 1, value, defaultValue = min, onValueChange, showValue = false, formatValue, className, id, disabled, 'aria-describedby': ariaDescribedBy, ...rest }: SliderProps) { const ids = useFieldIds(id); const [current, setCurrent] = useControllableState(value, defaultValue, onValueChange); const percent = max === min ? 0 : ((current - min) / (max - min)) * 100; return ( {label} {formatValue ? formatValue(current) : current} ) : ( label ) } description={description} error={error} size={size === 'sm' ? 'sm' : 'md'} > setCurrent(Number(event.currentTarget.value))} {...rest} /> ); }