Coves frontend - a photon fork
at main 79 lines 2.1 kB view raw
1<script lang="ts"> 2 import { Button, Label } from 'mono-svelte' 3 import { generateID } from './helper' 4 5 interface Props { 6 accept?: string 7 id?: string 8 files?: FileList | null 9 multiple?: boolean 10 preview?: boolean 11 label?: string | undefined 12 class?: string 13 customLabel?: import('svelte').Snippet 14 button?: import('svelte').Snippet 15 choose?: import('svelte').Snippet 16 } 17 18 let { 19 accept = '*', 20 id = generateID(), 21 files = $bindable(), 22 multiple = false, 23 preview = true, 24 label = undefined, 25 class: clazz = '', 26 customLabel, 27 button, 28 choose, 29 }: Props = $props() 30 31 let previewURLs = $derived( 32 preview && files ? Array.from(files).map(URL.createObjectURL) : undefined, 33 ) 34</script> 35 36<div class="flex flex-col gap-1 {clazz}"> 37 {#if customLabel || label} 38 <Label for={id} text={label}> 39 {@render customLabel?.()} 40 </Label> 41 {/if} 42 <label 43 class="w-max relative cursor-pointer space-x-2 flex flex-row items-center" 44 > 45 {#if button}{@render button()}{:else} 46 <Button>Browse</Button> 47 {/if} 48 {#if previewURLs} 49 <div 50 class="flex flex-row items-center -space-x-1 hover:space-x-1 z-20 h-8" 51 > 52 {#each previewURLs as file (file)} 53 <img 54 src={file} 55 onload={() => URL.revokeObjectURL(file)} 56 alt="" 57 class="w-8 h-8 object-cover rounded-full hover:w-16 58 hover:h-16 transition-all border border-slate-200 ring-1 59 ring-slate-50 dark:ring-zinc-950 bg-white dark:bg-zinc-950" 60 /> 61 {/each} 62 </div> 63 {/if} 64 <span class="flex flex-row items-center text-slate-600 dark:text-zinc-400"> 65 {#if choose}{@render choose()}{:else if (files ?? []).length == 0} 66 No file selected. 67 {:else} 68 {(files ?? []).length} files selected 69 {/if} 70 </span> 71 <input 72 type="file" 73 bind:files 74 {accept} 75 {multiple} 76 class="w-full h-full inset-0 opacity-0 absolute cursor-pointer" 77 /> 78 </label> 79</div>