Files
dticket.tootaio.com/app/components/QrCodeSvg.vue
xiaomai b6749bc5e7 feat(ui): improve mobile responsiveness and touch targets
Add mobile-optimized card view for seat lists on smaller screens
Increase minimum height for buttons and form items for better touch interaction
Adjust grid layouts, padding, and spacing across pages for mobile devices
2026-05-08 16:28:47 +08:00

70 lines
1.5 KiB
Vue

<script lang="ts" setup>
import QRCode from 'qrcode'
const props = withDefaults(defineProps<{
value: string
size?: number
}>(), {
size: 220
})
const markup = ref('')
const renderError = ref('')
async function renderQrCode() {
if (!props.value) {
markup.value = ''
renderError.value = ''
return
}
try {
markup.value = await QRCode.toString(props.value, {
type: 'svg',
errorCorrectionLevel: 'M',
margin: 1,
width: props.size
})
renderError.value = ''
} catch (error: any) {
markup.value = ''
renderError.value = error?.message || 'Unable to generate QR code.'
}
}
watch(
() => [props.value, props.size],
() => {
void renderQrCode()
},
{ immediate: true }
)
</script>
<template>
<div class="inline-flex max-w-full flex-col items-center gap-2">
<div
v-if="markup"
class="max-w-full overflow-hidden rounded-lg border border-default bg-default p-3 shadow-sm sm:p-4"
>
<div
class="max-w-full [&>svg]:block [&>svg]:h-auto [&>svg]:w-full"
:style="{ width: `${size}px` }"
v-html="markup"
/>
</div>
<div
v-else
class="flex max-w-full items-center justify-center rounded-lg border border-dashed border-muted bg-elevated p-4 text-center text-sm text-muted"
:style="{ width: `${size}px`, maxWidth: '100%', minHeight: `${size}px` }"
>
QR code unavailable
</div>
<p v-if="renderError" class="text-center text-xs text-error">
{{ renderError }}
</p>
</div>
</template>