Files
tabler/shared/ui/Dropzone.astro

51 lines
2.0 KiB
Plaintext

---
// Dropzone initializes from `data-bs-toggle="dropzone"` and its `data-bs-*` options (tabler.js, core/js/src/dropzone.ts).
// Styles: core/scss/ui/forms/_form-dropzone.scss.
import Icon from './Icon.astro'
interface Props {
/** id of the file input */
id?: string
/** name of the file input, and the upload field name unless `data-bs-param-name` is set */
name?: string
/** `.dropzone-title`: main line of the drop area */
title?: string
/** `.dropzone-hint`: second line, for the accepted types and the size limit */
description?: string
/** icon above the title; `false` leaves it out */
icon?: string | false
multiple?: boolean
disabled?: boolean
required?: boolean
/** native `accept` of the input; the plugin checks dropped files against it too */
accept?: string
/** data-bs-max-files: how many files the dropzone takes */
maxFiles?: number
/** data-bs-max-size: largest file, in bytes */
maxSize?: number
/** data-bs-url: sends every file there by XHR instead of leaving it in the input */
url?: string
class?: string
/** remaining attributes (data-bs-*, aria-*, …) are forwarded to the `.dropzone` wrapper */
[key: string]: unknown
}
const { id, name = 'file', title = 'Drop files here or click to upload', description, icon = 'cloud-upload', multiple, disabled, required, accept, maxFiles, maxSize, url, class: className, ...rest } = Astro.props
---
<div class:list={['dropzone', className]} data-bs-toggle="dropzone" data-bs-max-files={maxFiles} data-bs-max-size={maxSize} data-bs-url={url} {...rest}>
<label class="dropzone-area">
<input class="dropzone-input" type="file" id={id} name={name} accept={accept} multiple={multiple ? '' : undefined} disabled={disabled} required={required} />
{icon && <Icon name={icon} size="md" />}
<span class="dropzone-title">{title}</span>
{description && <span class="dropzone-hint">{description}</span>}
</label>
{
Astro.slots.has('default') && (
<div class="dropzone-list" aria-live="polite">
<slot />
</div>
)
}
</div>