Files
kycnotme/web/src/components/InputImageFile.astro

61 lines
1.8 KiB
Plaintext
Raw Normal View History

2025-05-19 10:23:36 +00:00
---
import { cn } from '../lib/cn'
import { ACCEPTED_IMAGE_TYPES } from '../lib/zodUtils'
import InputFile from './InputFile.astro'
import type { ComponentProps } from 'astro/types'
type Props = Omit<ComponentProps<typeof InputFile>, 'accept'> & {
square?: boolean
2025-05-19 11:22:11 +00:00
value?: string | null
2025-05-19 10:23:36 +00:00
}
2025-05-19 11:22:11 +00:00
const { class: className, square, value, ...inputFileProps } = Astro.props
2025-05-19 10:23:36 +00:00
---
<div class={cn('flex flex-wrap items-center justify-center gap-4', className)} data-preview-image>
2025-05-19 11:22:11 +00:00
<InputFile
accept={ACCEPTED_IMAGE_TYPES.join(',')}
class="min-w-0 flex-1 basis-[calc(var(--spacing)*32)]"
{...inputFileProps}
/>
2025-05-19 10:23:36 +00:00
<img
2025-05-19 11:22:11 +00:00
src={value}
2025-05-19 10:23:36 +00:00
alt="Preview"
class={cn(
2025-05-19 11:22:11 +00:00
'block h-24 rounded object-cover',
square && 'aspect-square',
'no-js:hidden not-[[src]]:hidden [&[src=""]]:hidden',
'[&:is(:has([data-remove-checkbox]:checked)_~_*)]:hidden'
2025-05-19 10:23:36 +00:00
)}
/>
</div>
<script>
////////////////////////////////////////////////////////////
// Optional script for image preview. //
// Shows a preview of the selected image before upload. //
////////////////////////////////////////////////////////////
document.addEventListener('astro:page-load', () => {
document.querySelectorAll('[data-preview-image]').forEach((wrapper) => {
const input = wrapper.querySelector<HTMLInputElement>('input[type="file"]')
if (!input) return
const previewImageElements = wrapper.querySelectorAll<HTMLImageElement>('img')
if (!previewImageElements.length) return
input.addEventListener('change', () => {
const file = input.files?.[0]
if (!file) return
const fileUrl = URL.createObjectURL(file)
previewImageElements.forEach((previewImage) => {
previewImage.src = fileUrl
})
})
})
})
</script>