diff --git a/packages/taler-merchant-webui/src/screens/PosScreen.tsx b/packages/taler-merchant-webui/src/screens/PosScreen.tsx index d324f83f3..bfe0cc4a8 100644 --- a/packages/taler-merchant-webui/src/screens/PosScreen.tsx +++ b/packages/taler-merchant-webui/src/screens/PosScreen.tsx @@ -285,6 +285,26 @@ export function PosScreen({ const [isRefundDetailsLoading, setIsRefundDetailsLoading] = useState(false); + // Each overlay and the paid screen asks for one thing first; put focus there + // when it appears instead of leaving it on the control behind the overlay. + const customDescInput = useRef(null); + const refundAmountInput = useRef(null); + const refundCancelButton = useRef(null); + const newSaleButton = useRef(null); + useEffect(() => { + if (showCustomModal) customDescInput.current?.focus(); + }, [showCustomModal]); + // The refund amount stays disabled until the order's refundable remainder + // has loaded; if nothing is left to refund, only Cancel is useful. + useEffect(() => { + if (!refundOrderId || isRefundDetailsLoading) return; + const amount = refundAmountInput.current; + (amount && !amount.disabled ? amount : refundCancelButton.current)?.focus(); + }, [refundOrderId, isRefundDetailsLoading]); + useEffect(() => { + if (activeTab === "success") newSaleButton.current?.focus(); + }, [activeTab]); + const { copied: copiedPayUrl, error: copyPayUrlError, copy } = useClipboard(); // Which order the caller last asked for. Seeded with the mount value so the @@ -1268,6 +1288,7 @@ export function PosScreen({ )}