File size: 1,106 Bytes
00a912e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | import { Input } from '@/components/ui/input'
import { useEffect, useState } from 'react'
/**
* 数值输入组件:使用本地 state 让用户自由输入,
* 仅在失焦或按回车时校验范围并提交。
*/
export function NumericInput({
value,
onChange,
min = 10,
max = 200,
}: {
value: number
onChange: (v: number) => void
min?: number
max?: number
}) {
const [local, setLocal] = useState(String(value))
// 外部值变化时同步(例如重置设置)
useEffect(() => {
setLocal(String(value))
}, [value])
const commit = () => {
const v = parseInt(local, 10)
if (Number.isFinite(v)) {
const clamped = Math.max(min, Math.min(max, v))
onChange(clamped)
setLocal(String(clamped))
} else {
setLocal(String(value)) // 无效输入回退
}
}
return (
<Input
type="number"
min={min}
max={max}
value={local}
onChange={(e) => setLocal(e.target.value)}
onBlur={commit}
onKeyDown={(e) => { if (e.key === 'Enter') commit() }}
className="w-20 text-center"
/>
)
}
|