···11# Changelog
2233+## Next
44+- Support file extensions like `.jpg` in `acceptedMimes`, but with the caveat that it will not enable `droppable` when hovering.
55+36## 0.3.0 - 2022 Dec 28
47- Add `name` property
58
+1-1
README.md
···3535| Prop | Type | Description |
3636| :-------------- | :--------------- | :-------------------- |
3737| `handleFiles` | (files: File[]) => void | File handler function |
3838-| `acceptedMimes` | string[] \| null | List of allowed mime types, like `image/jpeg` or `image/*`. Invalid files are ignored.<br>Defaults to `null` (all are allowed) |
3838+| `acceptedMimes` | string[] \| null | List of allowed MIME types, like `image/jpeg` or `image/*`. Invalid files are ignored.<br>You can also use file extensions like `.jpg` but it will not enable `droppable` when the file is hovering, meaning you can't display a hover effect.<br>Defaults to `null` (all are allowed) |
3939| `max` | number \| null | Max number of files allowed. Extra files are ignored. Defaults to 0 (no limit) |
4040| `disabled` | boolean | Disables the component |
4141| `name` | string \| null | Name of the input field, useful for forms |
+19-13
src/lib/FileDrop.svelte
···44 }
5566 /**
77- * List of allowed mime types, like `image/jpeg` or `image/*`. Invalid files are ignored.
77+ * List of allowed MIME types, like `image/jpeg` or `image/*`. Invalid files are ignored.
88 *
99- * Defaults to `null` (all are allowed)
99+ * You can also use file extensions like `.jpg` but it will not enable `droppable` when the file is hovering, meaning you can't display a hover effect.
1010 *
1111- * Null: all are allowed (default)
1111+ * Defaults to `null` (all are allowed)
1212 */
1313 export let acceptedMimes: string[] | null = null
1414···4242 function getAcceptedFiles(files: FileList | File[] = []): File[] {
4343 let acceptedFiles = []
4444 for (let i = 0; i < files.length; i++) {
4545- if (acceptedMimes === null || isAcceptedMime(files[i].type)) {
4545+ if (acceptedMimes === null || isAccepted(files[i])) {
4646 acceptedFiles.push(files[i])
4747 }
4848 }
···5252 return acceptedFiles
5353 }
54545555- function isAcceptedMime(mime: string): boolean {
5555+ function isAccepted(item: DataTransferItem | File): boolean {
5656 if (acceptedMimes === null) {
5757 return true
5858 }
5959- for (const acceptedMime of acceptedMimes) {
6060- if (acceptedMime === 'application/*' && mime.startsWith('application/')) {
5959+ for (const acceptedType of acceptedMimes) {
6060+ if (acceptedType.startsWith('.')) {
6161+ const file = item instanceof DataTransferItem ? item.getAsFile() : item
6262+ if (file?.name.endsWith(acceptedType)) {
6363+ return true
6464+ }
6565+ }
6666+ if (acceptedType === 'application/*' && item.type.startsWith('application/')) {
6167 return true
6262- } else if (acceptedMime === 'audio/*' && mime.startsWith('audio/')) {
6868+ } else if (acceptedType === 'audio/*' && item.type.startsWith('audio/')) {
6369 return true
6464- } else if (acceptedMime === 'video/*' && mime.startsWith('video/')) {
7070+ } else if (acceptedType === 'video/*' && item.type.startsWith('video/')) {
6571 return true
6666- } else if (acceptedMime === 'image/*' && mime.startsWith('image/')) {
7272+ } else if (acceptedType === 'image/*' && item.type.startsWith('image/')) {
6773 return true
6868- } else if (acceptedMime === 'text/*' && mime.startsWith('text/')) {
7474+ } else if (acceptedType === 'text/*' && item.type.startsWith('text/')) {
6975 return true
7070- } else if (mime === acceptedMime) {
7676+ } else if (item.type === acceptedType) {
7177 return true
7278 }
7379 }
···8086 }
8187 const items = Array.from(e.dataTransfer?.items || [])
8288 for (const item of items) {
8383- if (item.kind === 'file' && isAcceptedMime(item.type)) {
8989+ if (item.kind === 'file' && isAccepted(item)) {
8490 droppable = true
8591 return
8692 }