Refactor image upload handling in ReceiptForm and +page components by removing direct input element clicks and replacing them with accessible labels. Update styles for improved user experience and maintainability.
CI / build (push) Has been skipped
CI / deploy (push) Successful in 1m42s

This commit is contained in:
eewing
2026-02-19 11:27:56 -06:00
parent 6e6ad0de05
commit 8af1ee8bd4
2 changed files with 21 additions and 24 deletions
+10 -16
View File
@@ -20,14 +20,9 @@
defaultType?: string;
} = $props();
let imageInputEl = $state<HTMLInputElement | null>(null);
let imageFileName = $state<string | null>(null);
let imageConverting = $state(false);
function openScanReceipt() {
imageInputEl?.click();
}
async function onImageChange(e: Event) {
const input = e.currentTarget as HTMLInputElement;
const file = input.files?.[0];
@@ -79,25 +74,24 @@
<div class="space-y-2">
<Label for="Image">Image</Label>
<div class="flex flex-col gap-2">
<Button
type="button"
variant="outline"
class="w-full"
onclick={openScanReceipt}
>
Scan receipt
</Button>
<div class="relative flex flex-col gap-2">
<input
bind:this={imageInputEl}
id="Image"
name="Image"
type="file"
accept="image/*"
capture="environment"
onchange={onImageChange}
class="hidden"
class="absolute opacity-0 w-0 h-0 overflow-hidden"
tabindex="-1"
aria-label="Scan receipt"
/>
<label
for="Image"
class="border-input bg-background hover:bg-accent hover:text-accent-foreground flex h-9 w-full cursor-pointer items-center justify-center rounded-md border px-4 py-2 text-sm font-medium shadow-xs transition-colors"
>
Scan receipt
</label>
{#if imageConverting}
<p class="text-muted-foreground text-xs">Converting to WebP…</p>
{:else if imageFileName}
+11 -8
View File
@@ -133,9 +133,6 @@
imageOpen = mq.matches;
});
function openReplaceImage() {
imageInputEl?.click();
}
async function onImageChange() {
const input = imageInputEl;
const file = input?.files?.[0] ?? null;
@@ -237,19 +234,25 @@
class="flex flex-col gap-4"
>
<input type="hidden" name="dataJson" value={buildDataJson()} />
<div class="flex items-center gap-2">
<Button type="button" variant="outline" size="sm" onclick={openReplaceImage}>
{receipt.Image ? "Replace image" : "Add image"}
</Button>
<div class="relative flex items-center gap-2">
<input
id="receipt-image-input"
bind:this={imageInputEl}
type="file"
name="Image"
accept="image/*"
capture="environment"
onchange={onImageChange}
class="hidden"
class="absolute opacity-0 w-0 h-0 overflow-hidden"
tabindex="-1"
aria-label={receipt.Image ? "Replace image" : "Add image"}
/>
<label
for="receipt-image-input"
class="border-input bg-background hover:bg-accent hover:text-accent-foreground inline-flex h-8 cursor-pointer items-center justify-center rounded-md border px-3 text-sm font-medium shadow-xs transition-colors"
>
{receipt.Image ? "Replace image" : "Add image"}
</label>
{#if imageFileName}
<span class="text-muted-foreground text-xs">New: {imageFileName}</span>
{/if}