Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-dropzone

Package Overview
Dependencies
Maintainers
2
Versions
189
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-dropzone - npm Package Compare versions

Comparing version 5.1.1 to 6.0.0

examples/Folders/Readme.md

76

dist/es/index.js

@@ -20,3 +20,3 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

import PropTypes from 'prop-types';
import { supportMultiple, fileAccepted, allFilesAccepted, fileMatchSize, onDocumentDragOver, getDataTransferItems as defaultGetDataTransferItem, isIeOrEdge } from './utils';
import { supportMultiple, fileAccepted, allFilesAccepted, fileMatchSize, onDocumentDragOver, getDataTransferItems as defaultGetDataTransferItem, isIeOrEdge, hasFiles } from './utils';
import styles from './utils/styles';

@@ -119,5 +119,9 @@

value: function onDragStart(evt) {
if (this.props.onDragStart) {
this.props.onDragStart.call(this, evt);
}
var _this2 = this;
Promise.resolve(this.props.getDataTransferItems(evt)).then(function (draggedFiles) {
if (hasFiles(draggedFiles) && _this2.props.onDragStart) {
_this2.props.onDragStart.call(_this2, evt);
}
});
}

@@ -127,3 +131,3 @@ }, {

value: function onDragEnter(evt) {
var _this2 = this;
var _this3 = this;

@@ -140,10 +144,13 @@ evt.preventDefault();

Promise.resolve(this.props.getDataTransferItems(evt)).then(function (draggedFiles) {
_this2.setState({
isDragActive: true, // Do not rely on files for the drag state. It doesn't work in Safari.
draggedFiles: draggedFiles
});
if (hasFiles(draggedFiles)) {
_this3.setState({
isDragActive: true, // Do not rely on files for the drag state. It doesn't work in Safari.
draggedFiles: draggedFiles
});
if (_this3.props.onDragEnter) {
_this3.props.onDragEnter.call(_this3, evt);
}
}
});
if (this.props.onDragEnter) {
this.props.onDragEnter.call(this, evt);
}
}

@@ -153,2 +160,4 @@ }, {

value: function onDragOver(evt) {
var _this4 = this;
// eslint-disable-line class-methods-use-this

@@ -166,5 +175,8 @@ evt.preventDefault();

if (this.props.onDragOver) {
this.props.onDragOver.call(this, evt);
}
Promise.resolve(this.props.getDataTransferItems(evt)).then(function (draggedFiles) {
if (hasFiles(draggedFiles) && _this4.props.onDragOver) {
_this4.props.onDragOver.call(_this4, evt);
}
});
return false;

@@ -175,3 +187,3 @@ }

value: function onDragLeave(evt) {
var _this3 = this;
var _this5 = this;

@@ -182,3 +194,3 @@ evt.preventDefault();

this.dragTargets = this.dragTargets.filter(function (el) {
return el !== evt.target && _this3.node.contains(el);
return el !== evt.target && _this5.node.contains(el);
});

@@ -195,5 +207,7 @@ if (this.dragTargets.length > 0) {

if (this.props.onDragLeave) {
this.props.onDragLeave.call(this, evt);
}
Promise.resolve(this.props.getDataTransferItems(evt)).then(function (draggedFiles) {
if (hasFiles(draggedFiles) && _this5.props.onDragLeave) {
_this5.props.onDragLeave.call(_this5, evt);
}
});
}

@@ -203,3 +217,3 @@ }, {

value: function onDrop(evt) {
var _this4 = this;
var _this6 = this;

@@ -250,3 +264,3 @@ var _props = this.props,

if (fileAccepted(file, accept) && fileMatchSize(file, _this4.props.maxSize, _this4.props.minSize)) {
if (fileAccepted(file, accept) && fileMatchSize(file, _this6.props.maxSize, _this6.props.minSize)) {
acceptedFiles.push(file);

@@ -264,12 +278,12 @@ } else {

if (onDrop) {
onDrop.call(_this4, acceptedFiles, rejectedFiles, evt);
if (hasFiles(fileList) && onDrop) {
onDrop.call(_this6, acceptedFiles, rejectedFiles, evt);
}
if (rejectedFiles.length > 0 && onDropRejected) {
onDropRejected.call(_this4, rejectedFiles, evt);
onDropRejected.call(_this6, rejectedFiles, evt);
}
if (acceptedFiles.length > 0 && onDropAccepted) {
onDropAccepted.call(_this4, acceptedFiles, evt);
onDropAccepted.call(_this6, acceptedFiles, evt);
}

@@ -280,3 +294,3 @@

// values
_this4.setState({ acceptedFiles: acceptedFiles, rejectedFiles: rejectedFiles });
_this6.setState({ acceptedFiles: acceptedFiles, rejectedFiles: rejectedFiles });
});

@@ -319,3 +333,3 @@ }

value: function onFileDialogCancel() {
var _this5 = this;
var _this7 = this;

@@ -328,9 +342,9 @@ // timeout will not recognize context of this method

setTimeout(function () {
if (_this5.fileInputEl != null) {
if (_this7.fileInputEl != null) {
// Returns an object as FileList
var files = _this5.fileInputEl.files;
var files = _this7.fileInputEl.files;
if (!files.length) {
_this5.isFileDialogActive = false;
_this7.isFileDialogActive = false;
}

@@ -337,0 +351,0 @@ }

@@ -15,3 +15,11 @@ import accepts from 'attr-accept';

// but Chrome implements some drag store, which is accesible via dataTransfer.items
dataTransferItemsList = dt.items;
// Map the items to File objects,
// and filter non-File items
// see https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem/getAsFile
var files = Array.prototype.map.call(dt.items, function (item) {
return item.getAsFile();
});
dataTransferItemsList = Array.prototype.filter.call(files, function (file) {
return file !== null;
});
}

@@ -42,2 +50,10 @@ } else if (event.target && event.target.files) {

export function hasFiles(files) {
// Allow only files and retun the items as a list of File,
// see https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem for details
return Array.isArray(files) && files.length > 0 && Array.prototype.every.call(files, function (file) {
return file instanceof File;
});
}
// allow the entire document to be a drag target

@@ -44,0 +60,0 @@ export function onDocumentDragOver(evt) {

@@ -113,2 +113,3 @@ {

"eslint-plugin-react": "7.x",
"html5-file-selector": "^2.1.0",
"husky": "^0.14.3",

@@ -146,3 +147,3 @@ "imagemin-cli": "^3.0.0",

},
"version": "5.1.1",
"version": "6.0.0",
"engines": {

@@ -149,0 +150,0 @@ "node": ">= 6"

@@ -13,3 +13,4 @@ /* global process */

getDataTransferItems as defaultGetDataTransferItem,
isIeOrEdge
isIeOrEdge,
hasFiles
} from './utils'

@@ -88,5 +89,7 @@ import styles from './utils/styles'

onDragStart(evt) {
if (this.props.onDragStart) {
this.props.onDragStart.call(this, evt)
}
Promise.resolve(this.props.getDataTransferItems(evt)).then(draggedFiles => {
if (hasFiles(draggedFiles) && this.props.onDragStart) {
this.props.onDragStart.call(this, evt)
}
})
}

@@ -105,10 +108,13 @@

Promise.resolve(this.props.getDataTransferItems(evt)).then(draggedFiles => {
this.setState({
isDragActive: true, // Do not rely on files for the drag state. It doesn't work in Safari.
draggedFiles
})
if (hasFiles(draggedFiles)) {
this.setState({
isDragActive: true, // Do not rely on files for the drag state. It doesn't work in Safari.
draggedFiles
})
if (this.props.onDragEnter) {
this.props.onDragEnter.call(this, evt)
}
}
})
if (this.props.onDragEnter) {
this.props.onDragEnter.call(this, evt)
}
}

@@ -129,5 +135,8 @@

if (this.props.onDragOver) {
this.props.onDragOver.call(this, evt)
}
Promise.resolve(this.props.getDataTransferItems(evt)).then(draggedFiles => {
if (hasFiles(draggedFiles) && this.props.onDragOver) {
this.props.onDragOver.call(this, evt)
}
})
return false

@@ -151,5 +160,7 @@ }

if (this.props.onDragLeave) {
this.props.onDragLeave.call(this, evt)
}
Promise.resolve(this.props.getDataTransferItems(evt)).then(draggedFiles => {
if (hasFiles(draggedFiles) && this.props.onDragLeave) {
this.props.onDragLeave.call(this, evt)
}
})
}

@@ -218,3 +229,3 @@

if (onDrop) {
if (hasFiles(fileList) && onDrop) {
onDrop.call(this, acceptedFiles, rejectedFiles, evt)

@@ -221,0 +232,0 @@ }

@@ -18,3 +18,14 @@ /* eslint jsx-a11y/click-events-have-key-events: 0 */

const createFile = (name, size, type) => {
const file = new File([], name, { type })
Object.defineProperty(file, 'size', {
get() {
return size
}
})
return file
}
let files
let nonFileItems
let images

@@ -37,22 +48,15 @@

beforeEach(() => {
files = [
files = [createFile('file1.pdf', 1111, 'application/pdf')]
nonFileItems = [
{
name: 'file1.pdf',
size: 1111,
type: 'application/pdf'
kind: 'string',
type: 'text/plain',
getAsFile() {
return null
}
}
]
images = [
{
name: 'cats.gif',
size: 1234,
type: 'image/gif'
},
{
name: 'dogs.jpg',
size: 2345,
type: 'image/jpeg'
}
]
images = [createFile('cats.gif', 1234, 'image/gif'), createFile('dogs.gif', 2345, 'image/jpeg')]
})

@@ -303,4 +307,4 @@

describe('drag-n-drop', () => {
it('should override onDrag* methods', () => {
describe('drag-n-drop', async () => {
it('should override onDrag* methods', async () => {
const props = {

@@ -313,13 +317,21 @@ onDragStart: jest.fn(),

const component = mount(<Dropzone {...props} />)
component.simulate('dragStart')
component.simulate('dragStart', { dataTransfer: { files } })
await flushPromises(component)
expect(props.onDragStart).toHaveBeenCalled()
component.simulate('dragEnter', { dataTransfer: { items: files } })
await component.simulate('dragEnter', { dataTransfer: { files } })
await flushPromises(component)
expect(props.onDragEnter).toHaveBeenCalled()
component.simulate('dragOver', { dataTransfer: { items: files } })
await component.simulate('dragOver', { dataTransfer: { files } })
await flushPromises(component)
expect(props.onDragOver).toHaveBeenCalled()
component.simulate('dragLeave', { dataTransfer: { items: files } })
await component.simulate('dragLeave', { dataTransfer: { files } })
await flushPromises(component)
expect(props.onDragLeave).toHaveBeenCalled()
})
it('should guard dropEffect in onDragOver for IE', () => {
it('should guard dropEffect in onDragOver for IE', async () => {
const props = {

@@ -333,38 +345,82 @@ onDragStart: jest.fn(),

// Using Proxy we'll emulate IE throwing when setting dataTransfer.dropEffect
const eventProxy = new Proxy(
{},
{
get: (target, prop) => {
switch (prop) {
case 'dataTransfer':
throw new Error('IE does not support rrror')
default:
return function noop() {}
const eventProxy = {
preventDefault() {},
stopPropagation() {},
dataTransfer: new Proxy(
{},
{
set: (target, prop) => {
switch (prop) {
case 'dropEffect':
throw new Error('IE does not support setting {dropEffect}')
default:
break
}
}
}
}
)
)
}
// And using then we'll call the onDragOver with the proxy instead of event
const componentOnDragOver = component.instance().onDragOver
const instance = component.instance()
const componentOnDragOver = instance.onDragOver
const onDragOver = jest
.spyOn(component.instance(), 'onDragOver')
.spyOn(instance, 'onDragOver')
.mockImplementation(() => componentOnDragOver(eventProxy))
component.simulate('dragStart', { dataTransfer: { items: files } })
component.simulate('dragStart', { dataTransfer: { files } })
await flushPromises(component)
expect(props.onDragStart).toHaveBeenCalled()
component.simulate('dragEnter', { dataTransfer: { items: files } })
component.simulate('dragEnter', { dataTransfer: { files } })
await flushPromises(component)
expect(props.onDragEnter).toHaveBeenCalled()
component.simulate('dragLeave', { dataTransfer: { items: files } })
component.simulate('dragLeave', { dataTransfer: { files } })
await flushPromises(component)
expect(props.onDragLeave).toHaveBeenCalled()
// It should not throw the error
component.simulate('dragOver', { dataTransfer: { items: files } })
component.simulate('dragOver', { dataTransfer: { files } })
await flushPromises(component)
expect(onDragOver).not.toThrow()
})
it('should not call onDrag* if there are no files', async () => {
const props = {
onDragStart: jest.fn(),
onDragEnter: jest.fn(),
onDragOver: jest.fn(),
onDragLeave: jest.fn(),
onDrop: jest.fn()
}
const component = mount(<Dropzone {...props} />)
component.simulate('dragStart', { dataTransfer: { items: nonFileItems } })
await flushPromises(component)
expect(props.onDragStart).not.toHaveBeenCalled()
component.simulate('dragEnter', { dataTransfer: { items: nonFileItems } })
await flushPromises(component)
expect(props.onDragEnter).not.toHaveBeenCalled()
component.simulate('dragOver', { dataTransfer: { items: nonFileItems } })
await flushPromises(component)
expect(props.onDragOver).not.toHaveBeenCalled()
component.simulate('dragLeave', { dataTransfer: { items: nonFileItems } })
await flushPromises(component)
expect(props.onDragLeave).not.toHaveBeenCalled()
component.simulate('drop', { dataTransfer: { items: nonFileItems } })
await flushPromises(component)
expect(props.onDrop).not.toHaveBeenCalled()
})
it('should set proper dragActive state on dragEnter', async () => {
const dropzone = mount(<Dropzone>{props => <DummyChildComponent {...props} />}</Dropzone>)
dropzone.simulate('dragEnter', { dataTransfer: { files } })
const component = mount(<Dropzone>{props => <DummyChildComponent {...props} />}</Dropzone>)
component.simulate('dragEnter', { dataTransfer: { files } })
const updatedDropzone = await flushPromises(dropzone)
const updatedDropzone = await flushPromises(component)
const child = updatedDropzone.find(DummyChildComponent)

@@ -610,3 +666,3 @@

dropzone.simulate('dragLeave', { dataTransfer: { files } })
await dropzone.simulate('dragLeave', { dataTransfer: { files } })
expect(dropzone.find(DragActiveComponent).children()).toHaveLength(0)

@@ -774,9 +830,3 @@ expect(dropzone.find(ChildComponent)).toHaveProp('isDragAccept', false)

)
const bogusImages = [
{
name: 'bogus.gif',
size: 1234,
type: 'application/x-moz-file'
}
]
const bogusImages = [createFile('bogus.gif', 1234, 'application/x-moz-file')]

@@ -783,0 +833,0 @@ await dropzone.simulate('drop', { dataTransfer: { files: bogusImages } })

@@ -18,3 +18,7 @@ import accepts from 'attr-accept'

// but Chrome implements some drag store, which is accesible via dataTransfer.items
dataTransferItemsList = dt.items
// Map the items to File objects,
// and filter non-File items
// see https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem/getAsFile
const files = Array.prototype.map.call(dt.items, item => item.getAsFile())
dataTransferItemsList = Array.prototype.filter.call(files, file => file !== null)
}

@@ -43,2 +47,12 @@ } else if (event.target && event.target.files) {

export function hasFiles(files) {
// Allow only files and retun the items as a list of File,
// see https://developer.mozilla.org/en-US/docs/Web/API/DataTransferItem for details
return (
Array.isArray(files) &&
files.length > 0 &&
Array.prototype.every.call(files, file => file instanceof File)
)
}
// allow the entire document to be a drag target

@@ -45,0 +59,0 @@ export function onDocumentDragOver(evt) {

@@ -1,2 +0,2 @@

import { getDataTransferItems, isIeOrEdge } from './'
import { getDataTransferItems, isIeOrEdge, hasFiles } from './'

@@ -21,2 +21,29 @@ const files = [

const nonFileItems = [
{
kind: 'string',
type: 'text/plain',
getAsFile() {
return null
}
}
]
const json = JSON.stringify({
ping: true
})
const file = new File([json], 'test.json', {
type: 'application/json'
})
const fileItems = [
{
kind: 'file',
type: 'application/json',
getAsFile() {
return file
}
}
]
describe('getDataTransferItems', () => {

@@ -49,3 +76,3 @@ it('should return an array', () => {

dataTransfer: {
items: files
items: fileItems
}

@@ -55,5 +82,19 @@ }

expect(res).toBeInstanceOf(Array)
expect(res).toHaveLength(3)
expect(res).toHaveLength(1)
})
it('should ignore dataTransfer.items that are not of kind "file"', () => {
const event = {
target: {
files: [{}]
},
dataTransfer: {
items: nonFileItems
}
}
const res = getDataTransferItems(event)
expect(res).toBeInstanceOf(Array)
expect(res).toHaveLength(0)
})
it('should use event.target if dataTransfer is not defined', () => {

@@ -70,3 +111,3 @@ const event = {

it('should prioritize dataTransfer.files over .files', () => {
it('should prioritize dataTransfer.files over .items', () => {
const event = {

@@ -123,1 +164,10 @@ dataTransfer: {

})
describe('hasFiles', () => {
it('should only return true for an Array of File objects', () => {
expect(hasFiles([file])).toBe(true)
expect(hasFiles(['domNode'])).toBe(false)
expect(hasFiles([])).toBe(false)
expect(hasFiles(null)).toBe(false)
})
})

@@ -46,2 +46,18 @@ /* eslint import/no-extraneous-dependencies: 0 */

content: 'examples/Fullscreen/Readme.md'
},
{
name: 'Extending Dropzone',
context: {
Dropzone: './src/index'
},
sections: [
{
name: 'Using third-party plugins',
content: 'examples/PluginArchitecture/Readme.md'
},
{
name: 'Dropzone for folders',
content: 'examples/Folders/Readme.md'
}
]
}

@@ -48,0 +64,0 @@ ]

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc