Spaces:
Sleeping
Sleeping
File size: 3,037 Bytes
7aec436 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
<script>
import {_} from '../locales';
import DropArea from './DropArea.svelte';
const ACCEPT = [
'.png',
'.jpg',
'.jpeg',
'.bmp',
'.svg',
'.ico',
'.gif'
];
export let file;
export let previewSizes;
let dropping;
let url;
// This is a bit strange, there's probably a better way to do this
// Seems to create and revoke an extra object URL for each file for some reason
$: if (file) {
if (url) {
URL.revokeObjectURL(url);
}
url = URL.createObjectURL(file);
} else if (url) {
URL.revokeObjectURL(url);
url = null;
}
const clear = (e) => {
e.stopPropagation();
file = null;
};
const handleClickBackground = () => {
const input = document.createElement('input');
input.type = 'file';
input.accept = ACCEPT.join(',');
input.addEventListener('change', (e) => {
const files = e.target.files;
if (files.length) {
file = files[0];
} else {
file = null;
}
});
document.body.appendChild(input);
input.click();
input.remove();
};
const handleDrop = ({detail: dataTransfer}) => {
const droppedFile = dataTransfer.files[0];
if (ACCEPT.some((ext) => droppedFile.name.endsWith(ext))) {
file = droppedFile;
}
};
</script>
<style>
.container {
background: transparent;
color: #555;
width: 100%;
box-sizing: border-box;
border: 3px dashed currentColor;
transition: .2s border-color, .2s color;
border-radius: 20px;
min-height: 90px;
font: inherit;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
overflow: hidden;
position: relative;
cursor: pointer;
padding: 4px;
}
:global([theme="dark"]) .container {
color: #aaa;
}
.dropping,
.container:focus-visible,
.container:active {
color: rgb(79, 123, 211);
}
:global([theme="dark"]) .dropping,
:global([theme="dark"]) .container:focus-visible,
:global([theme="dark"]) .container:active {
color: rgb(178, 195, 228);
}
.placeholder {
font-size: 1.5em;
}
.selected {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
}
.selected > *:not(:last-child) {
margin-right: 12px;
}
</style>
<DropArea bind:dropping={dropping} on:drop={handleDrop}>
<button class="container" class:dropping on:click={handleClickBackground}>
{#if file}
<div class="selected">
{#each previewSizes as size}
<!-- svelte-ignore a11y-missing-attribute -->
<img src={url} width={size[0]} height={size[1]}>
{/each}
<div>{$_('fileInput.selected').replace('{file}', file.name)}</div>
<button on:click={clear}>{$_('fileInput.clear')}</button>
</div>
{:else}
<div class="placeholder">{$_('fileInput.select')}</div>
{/if}
</button>
</DropArea>
|