<!DOCTYPE html>
<html>

  <head>
    <title>File Uploader</title>
    <link href = "https://file.myfontastic.com/SLzQsLcd7FmmzjBYTcyVW3/icons.css" rel="stylesheet">
    <link href = "fileuploader.css" rel = "stylesheet">
    <link href = "style.css" rel = "stylesheet">
  </head>

  <body>
    <div id="app">Loading...</div>
    
    <script src = "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.js"></script>
    <script src = "https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
    <script src = "https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
    <script src = "https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.17/system.js"></script>
    <script type = "text/javascript">
        System.config({ transpiler: 'babel' });
        System.import('App.js');
    </script>
  </body>

</html>
/*Demo Styles  */

html, body {
  height: 100%;
  margin: 0;
  padding: 0; 
}

body {
  -webkit-align-items: center;
  align-items: center;
  background-color: #eee;
  display: -webkit-flex;
  display: flex;
  -webkit-justify-content: center;
  justify-content: center; 
}

button {
    display: block;
    margin: 2em auto;
}
* Live preview of the image selected
* Drag and drop support
'use strict';

class FileUploader {
    cache(selector) {
        this.$label = document.querySelector(selector);
        this.$fileInput = this.$label.querySelector('input');
        this.$img = this.$label.querySelector('img');
    }

    constructor(selector) {
        this.cache(selector);
        this.events();
    }

    events() {
        this.$fileInput.addEventListener('change', this._handleInputChange.bind(this));
        this.$img.addEventListener('load', this._handleImageLoaded.bind(this));
        this.$label.addEventListener('dragenter', this._handleDragEnter.bind(this));
        this.$label.addEventListener('dragleave', this._handleDragLeave.bind(this));
        this.$label.addEventListener('drop', this._handleDrop.bind(this));
    }

    _handleDragEnter(e){
        e.preventDefault();

        if (!this.$label.classList.contains('dragging')) {
            this.$label.classList.add('dragging');
        }
    }

    _handleDragLeave(e) {
        e.preventDefault();

        if (this.$label.classList.contains('dragging')) {
            this.$label.classList.remove('dragging');
        }
    }

    _handleDrop(e) {
        e.preventDefault();
        this.$label.classList.remove('dragging');

        this.$img.files = e.dataTransfer.files;
        this._handleInputChange();
    }

    _handleImageLoaded() {
        if (!this.$img.classList.contains('loaded')) {
            this.$img.classList.add('loaded');
        }
    }

    _handleInputChange(e) {
        var file = (undefined !== e)
            ? e.target.files[0]
            : this.$img.files[0];

        var pattern = /image-*/;
        var reader = new FileReader();

        if (!file.type.match(pattern)) {
            alert('invalid format');
            return;
        }

        this.$img.src = "";

        reader.onload = this._handleReaderLoaded.bind(this);

        if (this.$label.classList.contains('loaded')) {
            this.$label.classList.remove('loaded');
        }

        reader.readAsDataURL(file);
    }

    _handleReaderLoaded(e) {
        var reader = e.target;
        this.$img.src = reader.result;
        this.$label.classList.add('loaded');
    }
}

module.exports = FileUploader;
    
/* File Uploader Styles  */

.uploader input {
  display: none; 
}

.uploader {
  -webkit-align-items: center;
  align-items: center;
  background-color: #efefef;
  background-color: rgba(0, 0, 0, 0.02);
  display: -webkit-flex;
  display: flex;
  height: 300px;
  -webkit-justify-content: center;
  justify-content: center;
  outline: 3px dashed #ccc;
  outline-offset: 5px;
  position: relative;
  width: 300px; 
}
  
.uploader img,
.uploader .icon {
  pointer-events: none; 
}

.uploader, 
.uploader .icon {
  -webkit-transition: all 100ms ease-in;
  -moz-transition: all 100ms ease-in;
  -ms-transition: all 100ms ease-in;
  -o-transition: all 100ms ease-in;
  transition: all 100ms ease-in; 
}

.uploader .icon {
  color: #eee;
  color: rgba(0, 0, 0, 0.2);
  font-size: 5em; 
}

.uploader.dragging {
  outline-color: orangered; 
}

.uploader.dragging .icon {
  color: orangered; 
}

.uploader.loaded .icon {
  color: #fff;
  color: rgba(255, 255, 255, 0.5); 
}

.uploader img {
  left: 50%;
  opacity: 0;
  max-height: 100%;
  max-width: 100%;
  position: absolute;
  top: 50%;
  -webkit-transition: all 300ms ease-in;
  -moz-transition: all 300ms ease-in;
  -ms-transition: all 300ms ease-in;
  -o-transition: all 300ms ease-in;
  transition: all 300ms ease-in;
  -webkit-transform: translate(-50%,-50%);
  -moz-transform: translate(-50%,-50%);
  -ms-transform: translate(-50%,-50%);
  -o-transform: translate(-50%,-50%);
  transform: translate(-50%,-50%);
  z-index: -1; 
}
  
.uploader img.loaded {
  opacity: 1; 
}
const propTypes = {
        baseColor   : React.PropTypes.string,
        activeColor : React.PropTypes.string
    },

    defaultProps = {
        baseColor    : 'gray',
        activeColor  : 'green',
        overlayColor : 'rgba(255,255,255,0.3)'
    };

class FileUploader extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            active   : false,
            imageSrc : '',
            loaded   : false
        }

        this.onDragEnter  = this.onDragEnter.bind(this);
        this.onDragLeave  = this.onDragLeave.bind(this);
        this.onDrop       = this.onDrop.bind(this);
        this.onFileChange = this.onFileChange.bind(this);
    }

    onDragEnter(e) {
        this.setState({ active: true });
    }

    onDragLeave(e) {
        this.setState({ active: false });
    }

    onDragOver(e) {
        e.preventDefault();
    }

    onDrop(e) {
        e.preventDefault();
        this.setState({ active: false });
        this.onFileChange(e, e.dataTransfer.files[0]);
    }

    onFileChange(e, fileObject) {
        var file = fileObject || e.target.files[0],
            pattern = /image-*/,
            reader = new FileReader();

        if (!file.type.match(pattern)) {
            alert('Formato inválido');
            return;
        }

        this.setState({
            loaded: false
        });

        reader.onload = () => {
            this.setState({
                imageSrc: reader.result,
                loaded: true
            });
        }

        reader.readAsDataURL(file);
    }

    getFileObject() {
        return this.refs.input.files[0];
    }

    getFileString() {
        return this.state.imageSrc;
    }

    render() {
        let state       = this.state,
            props       = this.props,
            labelClass  = `uploader ${state.loaded && 'loaded'}`,
            borderColor = state.active ? props.activeColor : props.baseColor,
            iconColor   = state.active 
                ? props.activeColor 
                : (state.loaded) 
                    ? props.overlayColor 
                    : props.baseColor;

        return ( 
            <label 
                className   = { labelClass }
                onDragEnter = { this.onDragEnter }
                onDragLeave = { this.onDragLeave }
                onDragOver  = { this.onDragOver }
                onDrop      = { this.onDrop }
                style       = { { outlineColor: borderColor }}>

                <img 
                    src       = { state.imageSrc } 
                    className = { state.loaded && 'loaded' }/> 
            
                <i 
                    className = "icon icon-upload" 
                    style     = { { color: iconColor } } />
            
                < input 
                    type      = "file" 
                    accept    = "image/*" 
                    onChange  = { this.onFileChange } 
                    ref       = "input" />
            </label>
        );
    }
}

FileUploader.propTypes    = propTypes;
FileUploader.defaultProps = defaultProps;

export default FileUploader;
import FileUploader from "./FileUploader.js";

class App extends React.Component {
    constructor(props) {
        super(props);
        this.onClick = this.onClick.bind(this);
    }
    
    onClick(e) {
        e.preventDefault();
        
        var url        = 'http://nowhere.com',
            fileObject = this.refs.uploader.getFileObject(),
            formData   = new FormData(document.getElementById('form'));
            
        if (undefined === fileObject) return;
        
        formData.append('file', fileObject);
        fetch(url, {
            method : 'POST',
            body   : formData
        });
    }
    
    render() {
        return (
            <div>
                <FileUploader ref = "uploader" />
                <button onClick   = { this.onClick }>Enviar</button>
            </div>
        );
    }
}


ReactDOM.render(<App />, document.querySelector('#app'));