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

react-files

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-files - npm Package Compare versions

Comparing version 0.0.2 to 1.0.0

demo.gif

2

package.json
{
"name": "react-files",
"version": "0.0.2",
"version": "1.0.0",
"main": "src/Files.js",

@@ -5,0 +5,0 @@ "description": "A file input (dropzone) management component for React",

react-files
=======================
A file input (dropzone) management component for React.
> A file input (dropzone) management component for React
## Demo
![Alt text](/demo.gif?raw=true "Demo")
## Installation

@@ -17,12 +21,77 @@

```
import React from 'react'
import ReactDOM from 'react-dom'
import Files from './Files'
var FilesDemo = React.createClass({
onSubmit: function(files) {
console.log(files)
},
ReactDOM.render(<Files name="Jane" />, document.getElementById('container'));
onUnaccepted: function(file) {
console.log(file.name + ' is not a valid file type.')
},
render: function() {
return (
<div className="files">
<Files
onSubmit={this.onSubmit}
onUnaccepted={this.onUnaccepted}
accepts={['image/*', 'application/pdf', '.txt']}
/>
</div>
)
}
})
ReactDOM.render(<FilesDemo />, document.getElementById('container'))
```
### Test
### Props
> `onSubmit(files)` - Function
Perform work on files added when submit is clicked.
> `onUnaccepted(file)` - Function
Perform work or notify the user when a file is dropped/added that is unacceptable.
> `accepts` - Array of String
Control what types of generic/specific MIME types, or specific extensions can be dropped/added.
Example
```js
accepts={['image/*', 'video/mp4', 'audio/*', '.pdf', '.txt']}
```
### Styling
Be sure to style your Files component, available selectors are (view `style.css`):
- .files-container
- .files-dropzone-outer
- .files-dropzone
- .files-dropzone:before
- .files-dropzone-ondragenter
- .files-buttons
- .files-button-submit
- .files-button-submit:before
- .files-button-clear
- .files-button-clear:before
- .files-list
- .files-list ul
- .files-list li:last-child
- .files-list-item
- .files-list-item-content
- .files-list-item-content-item
- .files-list-item-content-item-1
- .files-list-item-content-item-2
- .files-list-item-preview
- .files-list-item-preview-image
- .files-list-item-preview-extension
- .files-list-item-remove
- .files-list-item-remove-image
### Test (todo)
```
npm test

@@ -29,0 +98,0 @@ ```

@@ -6,19 +6,126 @@ import React from 'react'

super(props, context)
this.onClick = this.onClick.bind(this)
this.onDrop = this.onDrop.bind(this)
// this.onDragStart = this.onDragStart.bind(this)
// this.onDragEnter = this.onDragEnter.bind(this)
// this.onDragLeave = this.onDragLeave.bind(this)
// this.onDragOver = this.onDragOver.bind(this)
this.onSubmit = this.onSubmit.bind(this)
this.onUnaccepted = this.onUnaccepted.bind(this)
this.onClear = this.onClear.bind(this)
this.openFileChooser = this.openFileChooser.bind(this)
this.removeFile = this.removeFile.bind(this)
this.fileAcceptable = this.fileAcceptable.bind(this)
this.id = 1
this.state = {
files: []
}
}
onClick() {
onDrop(event) {
event.preventDefault()
this.onDragLeave(event)
// Collect added files and cast pseudo-array to Array, then return to method
const filesAdded = event.dataTransfer ? event.dataTransfer.files : event.target.files
let files = []
for (let i = 0; i < filesAdded.length; i++) {
let file = filesAdded[i]
file.id = 'files-list-item-' + this.id++
if (file.type && this.mimeTypeLeft(file.type) === 'image') {
file.preview = {
type: 'image',
url: window.URL.createObjectURL(file)
}
} else {
file.preview = {
type: 'file',
extension: this.fileExtension(file)
}
}
if (this.fileAcceptable(file)) files.unshift(file)
}
this.setState({ files: [...files, ...this.state.files] })
}
onDragOver(event) {
event.preventDefault()
event.stopPropagation()
}
onDragEnter(event) {
event.target.className += ' files-dropzone-ondragenter'
}
onDragLeave(event) {
event.target.className = event.target.className.replace(' files-dropzone-ondragenter', '')
}
openFileChooser() {
this.inputElement.value = null
this.inputElement.click()
}
onDrop(e) {
const files = e.dataTransfer ? e.dataTransfer.files : e.target.files
this.props.onDrop(files)
removeFile(fileId) {
this.setState({
files: this.state.files.filter(file => file.id !== fileId)
})
}
fileAcceptable(file) {
let accepts = this.props.accepts
if (accepts) {
if (accepts.indexOf(this.fileExtension(file)) !== -1) return true
if (file.type) {
let typeLeft = this.mimeTypeLeft(file.type)
let typeRight = this.mimeTypeRight(file.type)
for (let i = 0; i < accepts.length; i++) {
let accept = accepts[i]
let acceptLeft = accept.split('/')[0]
let acceptRight = accept.split('/')[1]
if (acceptLeft && acceptRight) {
if (acceptLeft === typeLeft && acceptRight === '*') {
return true
}
if (acceptLeft === typeLeft && acceptRight === typeRight) {
return true
}
}
}
}
this.onUnaccepted(file)
return false
} else {
return true
}
}
mimeTypeLeft(mime) {
return mime.split('/')[0]
}
mimeTypeRight(mime) {
return mime.split('/')[1]
}
fileExtension(file) {
let extensionSplit = file.name.split('.')
if (extensionSplit.length > 1) {
return '.' + extensionSplit[extensionSplit.length - 1]
} else {
return 'none'
}
}
onSubmit() {
this.props.onSubmit.call(this, this.state.files);
}
onUnaccepted(file) {
this.props.onUnaccepted.call(this, file);
}
onClear() {
this.setState({
files: []
})
}
render() {

@@ -36,10 +143,50 @@

<div
className="div"
onClick={this.onClick}
onDrop={this.onDrop}
className="files-container"
>
<input
// {...inputProps/* expand user provided inputProps first so inputAttributes override them */}
{...inputAttributes}
/>
<input
// {...inputProps/* expand user provided inputProps first so inputAttributes override them */}
{...inputAttributes}
/>
<div
className="files-dropzone-outer"
>
<div className="files-dropzone"
onClick={this.openFileChooser}
onDrop={this.onDrop}
onDragOver={this.onDragOver}
onDragEnter={this.onDragEnter}
onDragLeave={this.onDragLeave}
/>
</div>
{this.props.children}
{
this.state.files.length > 0
? <div>
<div className="files-list">
<ul>{this.state.files.map((file) =>
<li className="files-list-item" key={file.id}>
<div className="files-list-item-preview">
{file.preview.type === 'image'
? <img className="files-list-item-preview-image" src={file.preview.url} />
: <div className="files-list-item-preview-extension">{file.preview.extension}</div>}
</div>
<div className="files-list-item-content">
<div id="files-list-item-content-item-1" className="files-list-item-content-item">{file.name}</div>
<div id="files-list-item-content-item-2" className="files-list-item-content-item">{file.size} bytes</div>
</div>
<div
id={file.id}
className="files-list-item-remove"
onClick={this.removeFile.bind(this, file.id)}
/>
</li>
)}</ul>
</div>
<div className="files-buttons">
<div onClick={this.onSubmit} className="files-button-submit" />
<div onClick={this.onClear} className="files-button-clear" />
</div>
</div>
: null
}
</div>

@@ -46,0 +193,0 @@

@@ -6,16 +6,17 @@ import React from 'react'

var FilesDemo = React.createClass({
onDrop: function (files) {
onSubmit: function(files) {
console.log(files)
},
onClick: function () {
console.log('click')
onUnaccepted: function(file) {
console.log(file.name + ' is not a valid file type.')
},
render: function () {
render: function() {
return (
<div>
<Files className="wow" onDrop={this.onDrop} onClick={this.onClick}>
<div>Try dropping some files here, or click to select files.</div>
</Files>
<div className="files">
<Files
onSubmit={this.onSubmit}
onUnaccepted={this.onUnaccepted}
/>
</div>

@@ -26,2 +27,2 @@ )

ReactDOM.render(<FilesDemo name="Jane" />, document.getElementById('container'))
ReactDOM.render(<FilesDemo />, document.getElementById('container'))

@@ -9,2 +9,3 @@ import React from 'react'

/*
describe('Files', () => {

@@ -19,1 +20,2 @@ it('works', () => {

})
*/

Sorry, the diff of this file is not supported yet

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