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();
}
};