import { useCallback, useState } from 'react'; import { TextInput } from '@/internal/components/TextInput'; import { cn, pressable, prefixClassName } from '@/styles/theme'; export const DELAY_MS = 200; type QuantitySelectorReact = { className?: string; disabled?: boolean; minQuantity?: number; maxQuantity?: number; onChange: (s: string) => void; placeholder: string; }; export function QuantitySelector({ className, disabled, minQuantity = 1, maxQuantity = Number.MAX_SAFE_INTEGER, onChange, placeholder, }: QuantitySelectorReact) { const [value, setValue] = useState(`${minQuantity}`); // allow entering '' to enable backspace + new value, fix empty string on blur const isValidQuantity = useCallback( (v: string) => { if (Number.parseInt(v, 10) < minQuantity) { return false; } if (Number.parseInt(v, 10) > maxQuantity) { return false; } // only numbers are valid const regex = /^[0-9]*$/; return regex.test(v); }, [maxQuantity, minQuantity], ); const handleIncrement = useCallback(() => { const next = `${Math.min(maxQuantity, Number.parseInt(value, 10) + 1)}`; setValue(next); onChange(next); }, [onChange, maxQuantity, value]); const handleDecrement = useCallback(() => { const next = `${Math.max(minQuantity, Number.parseInt(value, 10) - 1)}`; setValue(next); onChange(next); }, [onChange, minQuantity, value]); const handleOnChange = useCallback( (v: string) => { if (v === '') { return; } onChange(v); }, [onChange], ); const handleBlur = useCallback(() => { if (value === '') { setValue(minQuantity.toString()); onChange(minQuantity.toString()); } }, [onChange, minQuantity, value]); const classNames = prefixClassName( cn( 'h-11 w-11 rounded-lg border', 'border-ock-background-active', 'text-ock-foreground', 'bg-ock-background', disabled && pressable.disabled, ), ); return (
); }