'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}
{helperText}
)} {error && ({error}
)}