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"
    />
  )
}