'use client'; import Input from '@/components/ui/Input'; interface RangeFieldProps { label: string; value: number; min: number; max: number; step?: number; onChange: (value: number) => void; helperText?: string; error?: string; disabled?: boolean; /** * Optional unit label, defaults to "min". */ unitLabel?: string; /** * Optional override for the right-hand range hint. */ rangeHint?: string; } export default function RangeField({ label, value, min, max, step = 1, onChange, helperText, error, disabled, unitLabel = 'min', rangeHint, }: RangeFieldProps) { const clampedValue = Number.isFinite(value) ? Math.min(Math.max(value, min), max) : min; const handleSliderChange = (raw: string) => { const parsed = parseInt(raw, 10); if (Number.isNaN(parsed)) { return; } const next = Math.min(Math.max(parsed, min), max); onChange(next); }; const handleNumberChange = (raw: string) => { if (raw.trim() === '') { // Allow the field to clear without jumping the slider; // keep the previous value until the user types a number. return; } const parsed = parseInt(raw, 10); if (Number.isNaN(parsed)) { return; } const next = Math.min(Math.max(parsed, min), max); onChange(next); }; const rangePercent = ((clampedValue - min) / Math.max(max - min, 1)) * 100; const effectiveRangeHint = rangeHint ?? (min === 0 ? `Up to ${max} ${unitLabel}` : `${min}–${max} ${unitLabel}`); return (

{effectiveRangeHint}

handleSliderChange(e.target.value)} disabled={disabled} className="relative z-10 h-2 w-full appearance-none bg-transparent focus:outline-none accent-primary-blue" />
handleNumberChange(e.target.value)} min={min} max={max} step={step} disabled={disabled} className="px-3 py-2 text-sm" error={!!error} />
{unitLabel}
{helperText && (

{helperText}

)} {error && (

{error}

)}
); }