Coves frontend - a photon fork
at main 70 lines 1.9 kB view raw
1<script lang="ts"> 2 import { Label, TextInput } from 'mono-svelte' 3 import { DocumentPlus, Icon } from 'svelte-hero-icons/dist' 4 5 interface Props { 6 accept?: string 7 files?: FileList | undefined | null 8 label?: string | undefined 9 url?: string | undefined 10 } 11 12 let { 13 accept = 'image/*', 14 files = $bindable(null), 15 label = undefined, 16 url = undefined, 17 }: Props = $props() 18 19 let dragover = $state(false) 20 21 let previewURL = $derived(files ? URL.createObjectURL(files[0]) : undefined) 22</script> 23 24<div class="flex flex-col"> 25 <Label text={label} class="mb-1" /> 26 <label 27 class="flex flex-col items-center px-8 py-4 mx-auto w-full rounded-xl 28 border border-slate-200 dark:border-zinc-800 bg-white dark:bg-black 29 cursor-pointer min-h-36 transition-colors {dragover 30 ? 'border-sky-500 text-sky-500' 31 : ''} 32 {url != undefined ? 'rounded-b-none' : ''} 33 " 34 ondrop={(event: DragEvent) => { 35 event.preventDefault() 36 files = event.dataTransfer?.files ?? null 37 }} 38 ondragover={(event: DragEvent) => { 39 event.preventDefault() 40 if (event.dataTransfer) { 41 event.dataTransfer.dropEffect = 'copy' 42 dragover = true 43 } 44 }} 45 ondragleave={(event: DragEvent) => { 46 event.preventDefault() 47 dragover = false 48 }} 49 > 50 {#if files} 51 <!-- svelte-ignore a11y_missing_attribute --> 52 <img 53 src={previewURL} 54 onload={() => { 55 if (previewURL) URL.revokeObjectURL(previewURL) 56 }} 57 class="w-full max-w-sm h-full rounded-lg" 58 /> 59 {:else if url} 60 <img src={url} alt="" /> 61 {:else} 62 <Icon src={DocumentPlus} class="opacity-50" size="36" /> 63 <p class="text-sm opacity-50">Attach a file</p> 64 {/if} 65 <input type="file" bind:files {accept} class="hidden" /> 66 </label> 67 {#if url != undefined} 68 <TextInput class="rounded-t-none border-t-0 rounded-xl" /> 69 {/if} 70</div>