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>
|