"use client"; import { Minus, Plus } from "lucide-react"; import { useEffect, useState, type KeyboardEvent } from "react"; /** 后台数字步进器:0 是合法值;加减与手输都会提交数字 */ export default function AdminStepper({ id, value, onChange, min = 0, max = 999, step = 1, unit, ariaLabel, disabled, }: { id?: string; value: number; onChange: (n: number) => void; min?: number; max?: number; step?: number; unit?: string; ariaLabel: string; disabled?: boolean; }) { const clamp = (n: number) => Math.min(max, Math.max(min, Math.round(n))); const [text, setText] = useState(() => String(value)); useEffect(() => { setText(String(value)); }, [value]); const emit = (n: number) => { const next = clamp(Number.isFinite(n) ? n : min); onChange(next); setText(String(next)); }; const onKeyDown = (e: KeyboardEvent) => { if (e.key === "ArrowUp") { e.preventDefault(); emit(value + step); } else if (e.key === "ArrowDown") { e.preventDefault(); emit(value - step); } }; return (
e.target.select()} onChange={(e) => { const raw = e.target.value.replace(/[^\d]/g, ""); setText(raw); if (raw === "") return; onChange(clamp(Number(raw))); }} onBlur={() => emit(text === "" ? min : Number(text))} onKeyDown={onKeyDown} /> {unit ? {unit} : null}
); }