mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
121 lines
4.8 KiB
Svelte
121 lines
4.8 KiB
Svelte
<script lang="ts">
|
|
import { Trim } from '$lib/components';
|
|
import { humanFileSize } from '$lib/helpers/sizeConvertion';
|
|
|
|
export let label: string = null;
|
|
export let files: FileList;
|
|
export let list = new DataTransfer();
|
|
export let allowedFileExtensions: string[] = [];
|
|
export let maxSize: number = null;
|
|
|
|
let input: HTMLInputElement;
|
|
let hovering = false;
|
|
|
|
function dropHandler(ev: DragEvent) {
|
|
ev.dataTransfer.dropEffect = 'move';
|
|
hovering = false;
|
|
if (ev.dataTransfer.items) {
|
|
for (let i = 0; i < ev.dataTransfer.items.length; i++) {
|
|
if (ev.dataTransfer.items[i].kind === 'file') {
|
|
list.items.clear();
|
|
list.items.add(ev.dataTransfer.items[i].getAsFile());
|
|
files = list.files;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function dragOverHandler() {
|
|
hovering = true;
|
|
}
|
|
|
|
$: fileArray = files?.length ? Array.from(files) : [];
|
|
</script>
|
|
|
|
<input
|
|
bind:files
|
|
bind:this={input}
|
|
accept={allowedFileExtensions.map((n) => `.${n}`).join(',')}
|
|
type="file"
|
|
style="display: none" />
|
|
|
|
<div>
|
|
{#if label}
|
|
<p class="text">{label}</p>
|
|
{/if}
|
|
<div
|
|
class="box is-no-shadow u-padding-24"
|
|
style="--box-border-radius:var(--border-radius-xsmall); z-index: 1"
|
|
class:is-border-dashed={!hovering}
|
|
class:is-hover-with-file={hovering}
|
|
on:drop|preventDefault={dropHandler}
|
|
on:dragover|preventDefault={dragOverHandler}
|
|
on:dragenter|preventDefault
|
|
on:dragleave|preventDefault={() => (hovering = false)}>
|
|
<div class="upload-file-box">
|
|
<div class="upload-file-box-image">
|
|
<span class="icon-upload" aria-hidden="true" />
|
|
</div>
|
|
<div class="u-min-width-0 u-text-center">
|
|
<h5 class="upload-file-box-title heading-level-7 u-inline">
|
|
<span class="is-only-desktop">Drag and drop files here to upload</span>
|
|
<span class="is-not-desktop">Upload a File</span>
|
|
</h5>
|
|
{#if allowedFileExtensions?.length}
|
|
<button
|
|
class="tooltip u-inline u-margin-inline-start-4"
|
|
aria-label="variables info">
|
|
<span class="icon-info" aria-hidden="true" />
|
|
<span class="tooltip-popup" role="tooltip"
|
|
>Only {allowedFileExtensions.join(', ')} accepted.</span>
|
|
</button>
|
|
{/if}
|
|
</div>
|
|
<div class="u-flex u-main-center u-cross-center u-gap-16 u-flex-vertical-mobile">
|
|
{#if maxSize}
|
|
{@const readableMaxSize = humanFileSize(maxSize)}
|
|
<p class="upload-file-box-info body-text-2 u-normal">
|
|
Max file size: {readableMaxSize.value + readableMaxSize.unit}
|
|
</p>
|
|
{/if}
|
|
<button
|
|
class="button is-secondary is-full-width-mobile"
|
|
type="button"
|
|
on:click={() => input.click()}>
|
|
<span class="text">Choose a file</span>
|
|
</button>
|
|
</div>
|
|
|
|
{#if files?.length}
|
|
<ul class="upload-file-box-list u-min-width-0">
|
|
{#each fileArray as file}
|
|
{@const fileName = file.name.split('.')}
|
|
{@const fileSize = humanFileSize(file.size)}
|
|
<li class="u-flex u-cross-center u-min-width-0">
|
|
<span class="icon-document" aria-hidden="true" />
|
|
<span class="upload-file-box-name u-trim u-min-width-0">
|
|
<Trim>{fileName[0]}</Trim>
|
|
</span>
|
|
<span class="upload-file-box-name u-min-width-0 u-flex-shrink-0">
|
|
.{fileName[1]}
|
|
</span>
|
|
<span
|
|
class="upload-file-box-size u-margin-inline-start-4 u-margin-inline-end-16">
|
|
{fileSize.value + fileSize.unit}
|
|
</span>
|
|
<button
|
|
on:click={() => (files = null)}
|
|
type="button"
|
|
class="button is-text is-only-icon u-margin-inline-start-auto"
|
|
aria-label="remove file"
|
|
style="--button-size:1.5rem;">
|
|
<span class="icon-x" aria-hidden="true" />
|
|
</button>
|
|
</li>
|
|
{/each}
|
|
</ul>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
</div>
|