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

@browninglogic/ng-file-drop

v4.0.0

Published

Configurable file input component with cross-browser drag & drop functionality for Angular 6+

Downloads

22

Readme

ng-file-drop - Configurable file input component with cross-browser drag & drop functionality for Angular 8

npm version Build Status Coverage Status dependency Status

Introduction

ng-file-drop is an Angular component intended as a drop-in replacement for <input type="file"> with custom display content, a bindable dragging property, cross-browser file drop support, and file size & type checking.

Peer Dependencies

Upgrade Notes

  • As of version 4.0.0, Angular 8 is required. For support for Angular 6 & 7, please refer to version 3.0.0.
  • As of version 3.0.0, the nfdDragDropHandler class has been renamed to nfd-drag-drop-handler. As with nfdDragging, if you're applying your own styles using the nfdDragDropHandler class, then rename it accordingly in your stylesheets upon upgrading.
  • As of version 2.0.0, the nfdDragging class has been renamed to nfd-dragging. If you're already using the nfdDragging class, then rename it accordingly in your stylesheets upon upgrading to 2.0.0.
  • As of version 1.1.0, the preferred approach for styling is now to apply your own CSS classes via the containerDivClass property, rather than overriding the internal nfdDragDropHandler class. See the usage and styling section for details.

Installation

Install @browninglogic/ng-file-drop via:

npm install --save @browninglogic/ng-file-drop

Then include the imported module in your application module:

import { FileDropModule } from '@browninglogic/ng-file-drop';

@NgModule({
  declarations: [AppComponent, ...],
  imports: [FileDropModule, ...],  
  bootstrap: [AppComponent]
})
export class AppModule {
}

Motivation

The motivation for this component is to abstract away the following complexities of the native <input type="file"> and the HTML5 drag & drop functionality:

  • The visual customization that's possible on a native <input type="file"> is extremely limited. If one wants to display custom content for a file input, such as a styled list of selected files, they must resort to one of a number of hacks.
  • Setting a ":drag"-like style on an element with children (similar to the CSS :hover selector) also involves resorting to one of a number of hacks. Simply setting a property / style on dragenter and removing it on dragleave will not have the desired effect because the dragenter and dragleave events fire on the child elements as you drag through.
  • Modern browsers generally handle the case of the user dragging and dropping a file on a file input seamlessly: you just drop the file on the input and they're automatically selected. However, in order to achieve similar functionality in IE11, one must cancel the dragover event and pull the files from event.dataTransfer.files within a drop handler. Even after doing so, you have to get creative and put the files somewhere else, because you can't programmatically put them in the file input due to security reasons.
  • The "accept" attribute only tells the browser to filter the specified file types within the file selection window. If you want to actually prevent the user from selecting unsupported filetypes, you have to check it yourself with some simple javascript by checking the file size and extension. It's important to note that you should always implement server-side validation, because a malicious user can easily circumvent any client-side validations. The purpose of client-side validation is simply to provide a better user experience, and should never be considered a substitute for server-side validation.

Usage

By design, the component has no display of its own and only displays the content that you place inside it. To use it, simply place an nfd-file-input component within your template and place the non-interactive content that you want to display inside. The provided content will be displayed, and clicking anywhere on the component will open the browser's file selection dialog.

Consider this example from the demo:

<nfd-file-input #fileInput containerDivClass="file-input-demo" (filesRejected)="onFilesRejected($event)" allowedExtensions="pdf,doc,docx,xls,xlsx,json" [maxFileSize]="4194304">
  <ng-container *ngIf="fileInput.filesSelected; then filesSelected else noFilesSelected"></ng-container>
  <!-- If there are selected files, then show them in a list. -->
  <ng-template #filesSelected>
    <ul class="file-list">
      <li *ngFor="let file of fileInput.selectedFiles">
        {{file['name']}}
      </li>
    </ul>
  </ng-template>
  <ng-template #noFilesSelected>
    <!-- If there are no selected files, then tell the user to either 
    click / drag or to drop, depending on whether files are currently
    being dragged. -->
    <ng-container *ngIf="fileInput.dragging; then dragging else notDragging"></ng-container>
    <ng-template #dragging>Drop Files Here</ng-template>
    <ng-template #notDragging>Click or Drag Files Here</ng-template>
  </ng-template>
</nfd-file-input>
<!-- Show a "Clear Selection" button when files are selected in order to demonstrate the clearSelection functionality.-->
<input type="button" *ngIf="fileInput.filesSelected" (click)="fileInput.clearSelection()" value="Clear Selection">

|Name|Category|Type|Description| |:---|:---|:---|:---| |filesSelected|Component Property|Boolean|Denotes whether any files are currently selected.| |selectedFiles|Component Property|Array|Exposes an array of the currently selected files.| |dragging|Component Property|Boolean|Denotes whether the user is currently dragging a file. Useful for changing the bound content for the duration of the drag.| |containerDivClass|Optional Input Property|String|CSS classes to apply to the file input container div| |maxFileSize|Optional Input Property|Number|The max file size in bytes to validate for on file selection.| |allowedExtensions|Optional Input Property|String|A comma-separated list of file extensions to validate on file selection.| |filesRejected|Event||This event is emitted when allowedExtensions or maxFileSize are specified and the user selects a file which violates either constraint. It emits an array of file rejections, each of which contains the file itself and an enum stating which constraint the file violated.| |clearSelection|Method||Clears the current selection|

Styling

You can apply your own styles using the containerDivClass property. In addition, the nfd-dragging class can be used to apply styles while the user is dragging files over the component, similar to the CSS hover selector.

Consider the following example CSS, taken directly from the demo:

Global Styles

/* Apply some simple styles to the container div. */
.file-input-demo {
    cursor: pointer;
    background-color: #e6e6e6;
    border: 1px dashed grey;
    border-radius: 10px;
    padding: 10px 18px;
    text-align: center;
}

/* Set a light blue background when in a dragging or hovering state */
.file-input-demo.nfd-dragging,
.file-input-demo:hover
 {
    background-color:lightblue;
}

Component Styles

/* Remove the margin / padding / bullets from the file list */
ul.file-list {
    padding: 0;
    margin: 0;
}

ul.file-list li {
    margin:0;
    list-style:none;
}

/*
If you're applying styles to your containerDivClass from a component stylesheet, rather than
from a global stylesheet, then apply the ::ng-deep combinator in order to apply 
your styles within the modal-window component.  The shadow-piercing operators 
were recently removed without replacement in the evolving W3C spec.  This is an 
evolving topic and ng-deep is Angular's answer to this for the time being, although 
it's marked as deprecated and thus should be considered a temporary solution.  
I would suggest using this with caution in case the Angular team removes ng-deep 
before a clear replacement comes around.  See:
https://stackoverflow.com/questions/47024236/what-to-use-in-place-of-ng-deep
https://hackernoon.com/the-new-angular-ng-deep-and-the-shadow-piercing-combinators-deep-and-drop-4b088dbe459
https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep
*/
::ng-deep .file-input-demo {
    max-width: 375px;
    width:80%;
    margin:auto;
}

Pointer-Events

Since this component is designed to be a drop-in replacement for a file input, it only supports non-interactive display-oriented content. Pointer-events are disabled on all of the content inside the nfd-file-input component in order to provide consistent "drag" functionality across browsers. As a side-effect, any pointer-events-based functionality placed inside the component, such as click handlers and :hover selectors, are not supported. Hover and related CSS selectors can be hooked by using the nfd-drag-drop-handler CSS class.

Demo

View it in action here: https://pfbrowning.github.io/ng-file-drop

Browser Support

The following browsers have been tested and confirmed to be working as of the specified versions:

|Browser|Version| |:---|:---| |Firefox|61| |Chrome|68| |Opera|54| |Internet Explorer|11| |Edge|42| |Firefox (Android)|61| |Chrome (Android)|67|

I haven't been able to test on Safari for Mac or IOS because I don't own any Macs or IOS devices. If somebody who does is inclined to report with how it works on either, I would be grateful.

On touch devices, the component works as a file input in that it opens the file dialog when you touch it, but "file drop" functionality isn't supported for touch devices in that it may or may not work depending on your device.

Documentation

More detailed documentation can be found here.

License

Copyright (c) 2018 Patrick Browning. Licensed under the MIT License (MIT)