Spaces:
Running
Running
| import React from 'react'; | |
| import { Minus, Plus } from 'lucide-react'; | |
| interface NumberInputProps { | |
| value: number; | |
| onChange: (val: number) => void; | |
| min?: number; | |
| max?: number; | |
| className?: string; | |
| } | |
| export const NumberInput: React.FC<NumberInputProps> = ({ value, onChange, min = 0, max = 9999, className = '' }) => { | |
| const handleDec = (e: React.MouseEvent) => { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| if (value > min) onChange(value - 1); | |
| }; | |
| const handleInc = (e: React.MouseEvent) => { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| if (value < max) onChange(value + 1); | |
| }; | |
| const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { | |
| let val = parseInt(e.target.value); | |
| if (isNaN(val)) val = min; | |
| if (val < min) val = min; | |
| if (val > max) val = max; | |
| onChange(val); | |
| }; | |
| return ( | |
| <div className={`flex items-center border border-gray-300 rounded-lg overflow-hidden bg-white shadow-sm shrink-0 ${className}`}> | |
| <button | |
| type="button" | |
| onClick={handleDec} | |
| disabled={value <= min} | |
| className="p-2 md:p-1.5 bg-gray-50 text-gray-600 hover:bg-gray-100 disabled:opacity-30 border-r border-gray-200 active:bg-gray-200 transition-colors touch-manipulation" | |
| > | |
| <Minus size={14} strokeWidth={3} /> | |
| </button> | |
| <input | |
| type="number" | |
| className="w-10 md:w-12 text-center text-sm font-bold text-gray-800 outline-none p-1 appearance-none bg-transparent" | |
| value={value} | |
| onChange={handleChange} | |
| style={{MozAppearance: 'textfield'}} | |
| /> | |
| <button | |
| type="button" | |
| onClick={handleInc} | |
| disabled={value >= max} | |
| className="p-2 md:p-1.5 bg-gray-50 text-gray-600 hover:bg-gray-100 disabled:opacity-30 border-l border-gray-200 active:bg-gray-200 transition-colors touch-manipulation" | |
| > | |
| <Plus size={14} strokeWidth={3} /> | |
| </button> | |
| </div> | |
| ); | |
| }; | |