flotilla/src/lib/components/InputProfilePicture.svelte

98 lines
2.3 KiB
Svelte
Raw Normal View History

2024-08-08 23:32:46 +00:00
<script lang="ts">
2024-08-16 17:50:38 +00:00
import {randomId} from "@welshman/lib"
2025-02-04 03:28:29 +00:00
import {preventDefault, stopPropagation} from "@lib/html"
2024-08-16 17:50:38 +00:00
import Icon from "@lib/components/Icon.svelte"
2024-08-08 23:32:46 +00:00
2025-02-04 00:37:14 +00:00
interface Props {
file?: File | null
url?: string | null
}
let {file = $bindable(null), url = $bindable(null)}: Props = $props()
2024-08-08 23:32:46 +00:00
const id = randomId()
const onDragEnter = () => {
active = true
}
const onDragOver = () => {
active = true
}
const onDragLeave = () => {
active = false
}
const onDrop = (e: any) => {
active = false
file = e.dataTransfer.files[0]
}
const onChange = (e: any) => {
file = e.target.files[0]
}
const onClear = () => {
initialUrl = null
file = null
url = null
}
2025-02-04 00:37:14 +00:00
let active = $state(false)
let initialUrl = $state(url)
2024-08-08 23:32:46 +00:00
2025-02-04 03:28:29 +00:00
$effect(() => {
2024-08-08 23:32:46 +00:00
if (file) {
const reader = new FileReader()
2024-08-16 17:50:38 +00:00
reader.addEventListener(
"load",
() => {
url = reader.result as string
},
false,
)
2024-08-08 23:32:46 +00:00
reader.readAsDataURL(file)
} else {
url = initialUrl
}
2025-02-04 00:37:14 +00:00
})
2024-08-08 23:32:46 +00:00
</script>
<form>
2025-02-04 00:37:14 +00:00
<input {id} type="file" accept="image/*" onchange={onChange} class="hidden" />
2024-08-08 23:32:46 +00:00
<label
for={id}
aria-label="Drag and drop files here."
style="background-image: url({url});"
2024-10-03 19:27:41 +00:00
class="relative flex h-24 w-24 shrink-0 cursor-pointer items-center justify-center rounded-full border-2 border-solid border-base-content bg-base-300 bg-cover bg-center transition-all"
class:transparent={!url}
2024-08-08 23:32:46 +00:00
class:border-primary={active}
2025-02-04 00:37:14 +00:00
ondragenter={stopPropagation(preventDefault(onDragEnter))}
ondragover={stopPropagation(preventDefault(onDragOver))}
ondragleave={stopPropagation(preventDefault(onDragLeave))}
ondrop={stopPropagation(preventDefault(onDrop))}>
2024-08-08 23:32:46 +00:00
<div
2024-08-26 21:43:43 +00:00
class="absolute right-0 top-0 h-5 w-5 overflow-hidden rounded-full bg-primary"
2024-10-03 19:27:41 +00:00
class:bg-error={url}
class:bg-primary={!url}>
{#if url}
2024-08-08 23:32:46 +00:00
<span
role="button"
tabindex="-1"
2025-02-04 00:37:14 +00:00
onmousedown={stopPropagation(onClear)}
ontouchstart={stopPropagation(onClear)}>
2024-08-16 17:50:38 +00:00
<Icon icon="close-circle" class="scale-150 !bg-base-300" />
2024-08-08 23:32:46 +00:00
</span>
{:else}
2024-08-16 17:50:38 +00:00
<Icon icon="add-circle" class="scale-150 !bg-base-300" />
2024-08-08 23:32:46 +00:00
{/if}
</div>
2024-10-03 19:27:41 +00:00
{#if !url}
2024-08-08 23:32:46 +00:00
<Icon icon="gallery-send" size={7} />
{/if}
</label>
</form>