diff --git a/src/frontend/src/components/barcodes/BarcodeKeyboardInput.tsx b/src/frontend/src/components/barcodes/BarcodeKeyboardInput.tsx index 0aa7341d968c..e820d5d54e2d 100644 --- a/src/frontend/src/components/barcodes/BarcodeKeyboardInput.tsx +++ b/src/frontend/src/components/barcodes/BarcodeKeyboardInput.tsx @@ -4,6 +4,15 @@ import { IconQrcode } from '@tabler/icons-react'; import { useCallback, useState } from 'react'; import type { BarcodeInputProps } from './BarcodeInput'; +// Control keys commonly used for ASCII control codes by barcode scanners +// emulating keyboard input. +// See for example: https://docs.zebra.com/us/en/scanners/general/sm72-ig/ascii-character-sets.html +const BarcodeControlKeys: Record = { + KeyD: String.fromCharCode(4), // End of transmission + BracketRight: String.fromCharCode(29), // Group separator + Digit6: String.fromCharCode(30) // Record separator +} as const; + export default function BarcodeKeyboardInput({ onScan, actionText = t`Scan` @@ -32,7 +41,23 @@ export default function BarcodeKeyboardInput({ setText(event.currentTarget?.value); }} onKeyDown={(event) => { - if (event.code === 'Enter') { + let key = event.key; + + if (event.ctrlKey) { + if (event.code in BarcodeControlKeys) { + // Prevent most of the keyboard shortcuts. + // Not all of them will be blocked, browser don't allow this: + // https://stackoverflow.com/questions/59952382/using-preventdefault-to-override-opening-new-tab + event.preventDefault(); + key = BarcodeControlKeys[event.code]; + setText((prev) => prev + key); + } + } + + if ( + key === 'Enter' || + key === String.fromCharCode(4) // End of transmission + ) { onTextScan(text); } }}