diff --git a/src/renderer/src/pages/catalogue/pagination.tsx b/src/renderer/src/pages/catalogue/pagination.tsx index 9febc8f8..8dd85cab 100644 --- a/src/renderer/src/pages/catalogue/pagination.tsx +++ b/src/renderer/src/pages/catalogue/pagination.tsx @@ -29,9 +29,11 @@ function JumpControl({ return isOpen ? ( ) => { - const val = e.target.value; - if (val === "") { + const raw = e.target.value; + const digitsOnly = raw.replace(/\D+/g, ""); + if (digitsOnly === "") { setJumpValue(""); return; } - const num = Number(val); + const num = parseInt(digitsOnly, 10); if (Number.isNaN(num)) { + setJumpValue(""); return; } if (num < 1) { @@ -104,19 +108,38 @@ export function Pagination({ setJumpValue(String(totalPages)); return; } - setJumpValue(val); + setJumpValue(String(num)); }; const onJumpKeyDown = (e: KeyboardEvent) => { + // Allow common control keys + const controlKeys = [ + "Backspace", + "Delete", + "Tab", + "ArrowLeft", + "ArrowRight", + "Home", + "End", + ]; + + if (controlKeys.includes(e.key) || e.ctrlKey || e.metaKey) { + return; + } + if (e.key === "Enter") { - if (jumpValue.trim() === "") return; - const parsed = Number(jumpValue); + const sanitized = jumpValue.replace(/\D+/g, ""); + if (sanitized.trim() === "") return; + const parsed = parseInt(sanitized, 10); if (Number.isNaN(parsed)) return; const target = Math.max(1, Math.min(totalPages, parsed)); onPageChange(target); setIsJumpOpen(false); } else if (e.key === "Escape") { setIsJumpOpen(false); + } else if (!/^\d$/.test(e.key)) { + // Block any non-digit input (e.g., '.', ',') + e.preventDefault(); } };