mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 21:27:06 +04:00
70 lines
2.6 KiB
Plaintext
70 lines
2.6 KiB
Plaintext
---
|
|
import type { HTMLTag } from 'astro/types'
|
|
import CaptureScript from '../components/CaptureScript.astro'
|
|
interface Props {
|
|
id: string
|
|
multiple?: boolean
|
|
custom?: boolean
|
|
text?: string
|
|
description?: string
|
|
/** heading level for the custom message title; match it to the surrounding context */
|
|
titleAs?: HTMLTag
|
|
}
|
|
|
|
const { id, multiple, custom, text, description, titleAs: Title = 'h3' } = Astro.props
|
|
const label = 'Upload file'
|
|
|
|
const dropzoneId = `dropzone-${id}`
|
|
const dropzoneSelector = `#dropzone-${id}`
|
|
const fileInputId = `${dropzoneId}-file`
|
|
---
|
|
|
|
<form class="dropzone" id={dropzoneId} action="./" autocomplete="off" novalidate>
|
|
<div class="fallback">
|
|
<label class="visually-hidden" for={fileInputId}>{label}</label>
|
|
<input id={fileInputId} name="file" type="file" multiple={multiple ? '' : undefined} />
|
|
</div>
|
|
{
|
|
custom && (
|
|
<div class="dz-message">
|
|
<Title>{text}</Title>
|
|
<span>{description}</span>
|
|
</div>
|
|
)
|
|
}
|
|
</form>
|
|
<CaptureScript>
|
|
<!-- BEGIN DROPZONE -->
|
|
<script is:inline define:vars={{ dropzoneId, dropzoneSelector }}>
|
|
window.tabler_dropzone ??= {}
|
|
|
|
function initDropzone() {
|
|
const dropzoneEl = document.querySelector(dropzoneSelector)
|
|
const instance = new Dropzone(dropzoneSelector)
|
|
window.tabler_dropzone[dropzoneId] = instance
|
|
|
|
// Dropzone.js hides the .fallback label/input once it initializes, which is why
|
|
// role="button" + tabindex only get added here rather than in the static markup —
|
|
// adding them upfront would nest one focusable control (the fallback input) inside
|
|
// another (this "button"). Dropzone.js is also click/drag-only by default: it binds
|
|
// a click handler on the whole element but never wires a keyboard equivalent, so
|
|
// forward Enter/Space to a programmatic click on Dropzone's own hidden file input.
|
|
// Note: that input is appended to <body> (hiddenInputContainer default), not inside
|
|
// dropzoneEl, so it must be reached via the instance rather than a DOM query here.
|
|
dropzoneEl?.setAttribute('role', 'button')
|
|
dropzoneEl?.setAttribute('tabindex', '0')
|
|
dropzoneEl?.setAttribute('aria-label', 'Click or drag files to upload')
|
|
|
|
dropzoneEl?.addEventListener('keydown', (event) => {
|
|
if (event.target !== dropzoneEl) return
|
|
if (event.key !== 'Enter' && event.key !== ' ' && event.key !== 'Spacebar') return
|
|
event.preventDefault()
|
|
instance.hiddenFileInput?.click()
|
|
})
|
|
}
|
|
|
|
document.readyState !== 'loading' ? initDropzone() : document.addEventListener('DOMContentLoaded', initDropzone, { once: true })
|
|
</script>
|
|
<!-- END DROPZONE -->
|
|
</CaptureScript>
|