feat(machine): add scanning frame to QR code component

Wrap QrcodeVue in animated scanning frame with 4 pulsing corner
brackets and a sweep line. Increase default size from 300 to 380
for split-screen contexts. Use font-mono-code for URI preview.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Patrick Mulligan 2026-03-01 12:11:28 -05:00
commit 9cfd2f2907

View file

@ -7,7 +7,7 @@ const props = defineProps<{
size?: number size?: number
}>() }>()
const qrSize = computed(() => props.size ?? 200) const qrSize = computed(() => props.size ?? 380)
// Read CSS variables for theme-aware colors // Read CSS variables for theme-aware colors
const qrBackground = ref('#f5f0e6') const qrBackground = ref('#f5f0e6')
@ -37,7 +37,32 @@ onUnmounted(() => {
</script> </script>
<template> <template>
<div class="flex flex-col items-center justify-center rounded-xl bg-qr p-5"> <div class="flex flex-col items-center justify-center">
<!-- Scanning frame wrapper -->
<div class="relative inline-block">
<!-- Corner brackets -->
<!-- Top-left -->
<div
class="absolute -left-3 -top-3 h-8 w-8 border-l-4 border-t-4 border-primary rounded-tl-md animate-corner-pulse"
/>
<!-- Top-right -->
<div
class="absolute -right-3 -top-3 h-8 w-8 border-r-4 border-t-4 border-primary rounded-tr-md animate-corner-pulse"
style="animation-delay: 0.5s"
/>
<!-- Bottom-left -->
<div
class="absolute -bottom-3 -left-3 h-8 w-8 border-b-4 border-l-4 border-primary rounded-bl-md animate-corner-pulse"
style="animation-delay: 1s"
/>
<!-- Bottom-right -->
<div
class="absolute -bottom-3 -right-3 h-8 w-8 border-b-4 border-r-4 border-primary rounded-br-md animate-corner-pulse"
style="animation-delay: 1.5s"
/>
<!-- QR code -->
<div class="rounded-xl bg-qr p-6">
<QrcodeVue <QrcodeVue
:value="value" :value="value"
:size="qrSize" :size="qrSize"
@ -46,7 +71,28 @@ onUnmounted(() => {
:background="qrBackground" :background="qrBackground"
:foreground="qrForeground" :foreground="qrForeground"
/> />
<code class="mt-3 block max-w-full break-all px-2 text-center text-xs text-qr-foreground"> </div>
<!-- Scanning line overlay -->
<div class="pointer-events-none absolute inset-0 overflow-hidden rounded-xl">
<div
class="absolute left-0 right-0 h-[3px] animate-qr-scan"
style="
background: linear-gradient(
90deg,
transparent 0%,
var(--primary) 50%,
transparent 100%
);
"
/>
</div>
</div>
<!-- URI preview -->
<code
class="font-mono-code mt-4 block max-w-full break-all px-2 text-center text-sm text-muted-foreground"
>
{{ value.slice(0, 32) }}... {{ value.slice(0, 32) }}...
</code> </code>
</div> </div>