npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

nuxt-dropzone-filelist

v1.0.11

Published

File list style for dropzone as Nuxt 3 module

Downloads

145

Readme

Dropzone Filelist

npm version npm downloads License Nuxt

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

  1. 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
  2. Add nuxt-dropzone-filelist to the modules section of nuxt.config.ts

    export default defineNuxtConfig({
      modules: [
        'nuxt-dropzone-filelist'
      ]
    })
  3. 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 = {}

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:
  1. nameOrFileObj: | string | { name: string; size?: number; imageUrl?: string }
  2. size?: number
  3. imageUrl?: string
  4. color?: string | false
  5. 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
  • 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}" />
  • allow specific files only
    • use dropzone's options, namely acceptedFiles:string
      <DropzoneFilelist upload-url="/api/upload" :options="{acceptedFiles: 'image/jpeg,image/png,application/pdf'}" />
  • 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)

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