nuxt-dropzone-filelist
v1.0.11
Published
File list style for dropzone as Nuxt 3 module
Downloads
136
Maintainers
Readme
Dropzone Filelist
A Nuxt module with opinionated settings to show a file list, directly based on dropzone.js, NOT based on any other dropzone plugin or module.
Features
- no secondary vue dependencies
- opinionated to enable a specific style
- inbuild file icon
- places text input fields for filenames, while uploads files directly to custom url
- filling files on load
- even files added by code, have an input
- it is always relyably multifile internally, dropzone options can limit the file amount
Quick Setup
Add
nuxt-dropzone-filelist
dependency to your project# Using pnpm pnpm add -D nuxt-dropzone-filelist # Using yarn yarn add --dev nuxt-dropzone-filelist # Using npm npm install --save-dev nuxt-dropzone-filelist
Add
nuxt-dropzone-filelist
to themodules
section ofnuxt.config.ts
export default defineNuxtConfig({ modules: [ 'nuxt-dropzone-filelist' ] })
Use it
<template> <DropzoneFilelist uploadUrl="/api/upload" /> </template>
Properties:
Note: When using as attributes, the properies will need to be kebab-case.
id: String = null
- used for the file[id][] file-input name, falls back to
options.paramName
-> element id -> random number
nameTemplate: String = 'file[${id}][]'
- template for name to use, supports:
${id}
,${name}
,${num}
(current file index, no logic) - Note: no template-string content support
uploadUrl: String
(required)
- upload target url to post the files to
uploadText: String = 'Drag files here or click to upload'
- upload area text
removeText: String = 'remove?'
- string to use on the remove file item button
imgMaxSize: String = '2.5em'
- cube side size for the image preview and file icon
hasClick: Boolean = false
- false will not show the click highlight and message, but still trigger the click-handler
clickText: String = 'Clicked!'
- text on the click highlight
clickFn: ( fileName: string, fileElement: HTMLDivElement, dropzone: Dropzone ):void => ...
- default:
console.log("clicked", fileName, { fileElement, dropzone })
- handler on clicking on an item
clickDurrationMs: Number = 1000
- how long the click highlight should be shown, 0 will not show the click highlight and message
initialFiles: Array = []
- list of files to fill in on initialization
filesIconColor: Object = ...
- default:
{ txt: "#E9EAEB", rtf: "#7C54AB", pdf: "#f40f02", doc: "#1B5EBE", docx: "#1B5EBE", xls: "#1d6f42", xlsx: "#1d6f42" }
- file color map for file icon template
fileIconTemplate: String | null = null
- supply an alternative data string to use as file icon, placeholders: 🔆 = color, ❓ = font-family, 👑 = title
- be aware: it has to be a image url (base64 or passed through
encodeURIComponent()
), resulting in something for SVGs like:"data:image/svg+xml,%3Csvg ..."
usePreviewIcon: Boolean = true
- use to show file icon while loading preview or if preview is not available
useFontAwesomeIcons: Boolean = false
- uses the fontawesome 5 icons, fontawesome css needs to be available allready
addFileInputs: Boolean = true
- enable adding text input fields with filenames for each added file
columnMode: String = 'container'
- adds
.***-width
classes to adjust to available space, select the method to use:'media'
== media-query,'container'
== container-query,'column'
/ nothing == 1fr
useFormelement: Boolean = false
- usually uses a div as wrapper, this changes it to
<form>
disabled: Boolean = false
- disables using of the element like a form element (also sets a real
disabled
property)
options: Object = {}
- any native dropzone options
uploadMultiple
has no effect
Events:
@init: (options: {dropzone: Dropzone, element: HTMLElement}): void
- event handler that gt4s called after initialization
@addedFile: (options: {file: DropzoneFile, dropzone: Dropzone, element: HTMLElement}): void
- event handler that gets called when a file got added (as well as for
initialFiles
) - use to add event handlers to slotted elements
@removedFile: (options: { file: DropzoneFile, dropzone: Dropzone, element: HTMLElement}): void
- event handler that gets called when a file got removed
Methods:
To use Methods, you need a ref on the component, then access it as usual.
.addFile()
Params:
nameOrFileObj: | string | { name: string; size?: number; imageUrl?: string }
size?: number
imageUrl?: string
color?: string | false
crossOrigin: "anonymous" | "use-credentials" | undefined = 'anonymous'
Examples:
// add image
this.$refs.dropzoneFilelist.addFile('name.jpg', 123123/*bytes*/, '/assets/preview.jpg');
// add non-image
this.$refs.dropzoneFilelist.addFile('name.ext', 123123/*bytes*/, undefined, '#FF0000');
// as object
this.$refs.dropzoneFilelist.addFile({
name: 'name.ext',
size: 123123,
color: '#ff0000',
// imageUrl: '/assets/preview.jpg'
});
Slots
default
- use to add html to use as actions that will be visible on hover
- use event
@addedFile
to add click handlers
Solutions & Examples
Tests are available here in the ./pages/ *.vue files
- item click handler
- to have a click action on a file item, add a handler with
:click-fn
- appearance can be changed by
:has-click
,:click-text
,:click-durration-ms
- to have a click action on a file item, add a handler with
- action buttons
- use default slot for additional buttons/links
- handler: use
@addedFile
to add click handler by finding it with.querySelector()
<template> <DropzoneFilelist upload-url="/api/upload" @addedFile="addedFile"> <button data-action-open-external>open</button> </DropzoneFilelist> </template> <script> export default defineComponent({ methods: { addedFile({file, dropzone, element}) { element .querySelector('[data-action-open-external]') .addEventListener('click', (ev) => { ev.preventDefault(); ev.stopPropagation(); // custom action alert(file.name); }); }, }, }); </script>
- loading initial files
:initial-files
needs an array of:{name, filesize , imgUrl?, color?}
(imgUrl or color, color for file icon)
- getting a count of added files
this.$refs.dzf.dropzone.files.length
- getting list of added files
this.$refs.dzf.dropzone.files
=>File[]
- item select toggle
- use an item click handler
- toggle a class on
element
to change the background color - use an array to add or remove the file names to keep track
- limit files
- use dropzone's options, namely
maxFiles:number
<DropzoneFilelist upload-url="/api/upload" :options="{maxFiles: 2}" />
- use dropzone's options, namely
- allow specific files only
- use dropzone's options, namely
acceptedFiles:string
<DropzoneFilelist upload-url="/api/upload" :options="{acceptedFiles: 'image/jpeg,image/png,application/pdf'}" />
- use dropzone's options, namely
- upload to nuxt /api
- use
npm/h3-formidable
- ... to let formidable save the file first, then copy it to where it should go (moving is usually a problem due to file permissions on temp files)
// ./server/api/upload.post.ts import fs from "node:fs/promises"; import path from "node:path"; import { readFiles } from "h3-formidable"; export default defineEventHandler(async (event) => { // ... do some validation here: session / bearer-token / jwt / ... const { fields, files } = await readFiles(event, { includeFields: true, maxFileSize: 20 * 1024 * 1024, filter: () => true, // filter: ({ name, originalFilename, mimetype }) => mimetype && mimetype.includes("image"), // uploadDir: './upload', // direct uploading // keepExtensions: true, // other formidable options here // https://github.com/node-formidable/formidable#options }); // if not `uploadDir` ... we move the file: let f: any = files.file[0]; const targetPath = path.join( await fs.realpath("./upload"), f.originalFilename ); await fs.copyFile(f.filepath, targetPath); await fs.unlink(f.filepath); // if a string is returned, it will be shown as error by DropZone return "";
- Nuxt (h3) has native Session support: useSession() (my documentation and example)
- the server could also be a PHP/ASPx/... server (when using the dropzone component from this package without the nuxt module part)
- use
Development
# Install dependencies
npm install
# Generate type stubs
npm run dev:prepare
# Develop with the playground
npm run dev
# Build the playground
npm run dev:build
# Run ESLint
npm run lint
# Run Vitest
npm run test
npm run test:watch
# Release new version
npm run release