Merge pull request #1 from netlify/imageWidget

Support for image preview & drag and drop
This commit is contained in:
Cássio Souza 2016-06-06 21:50:12 -03:00
commit a0be4e0ae8
4 changed files with 101 additions and 4 deletions

View File

@ -9,7 +9,7 @@
window.repoFiles = {
_posts: {
"2015-02-14-this-is-a-post.md": {
content: "---\ntitle: This is a post\ndate: 2015-02-14T00:00:00.000Z\n---\n\n# I Am a Title in Markdown\n\nHello, world\n"
content: "---\ntitle: This is a post\nimage: /nf-logo.png\ndate: 2015-02-14T00:00:00.000Z\n---\n\n# I Am a Title in Markdown\n\nHello, world\n"
}
},
_faqs: {

BIN
example/nf-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -3,14 +3,112 @@ import React from 'react';
export default class ImageControl extends React.Component {
constructor(props) {
super(props);
this.state = {
currentImage: props.value
};
this.revokeCurrentImage = this.revokeCurrentImage.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleFileInputRef = this.handleFileInputRef.bind(this);
this.handleClick = this.handleClick.bind(this);
this.handleDragEnter = this.handleDragEnter.bind(this);
this.handleDragOver = this.handleDragOver.bind(this);
this.renderImageName = this.renderImageName.bind(this);
}
componentWillUnmount() {
this.revokeCurrentImage();
}
revokeCurrentImage() {
if (this.state.currentImage instanceof File) {
window.URL.revokeObjectURL(this.state.currentImage);
}
}
handleFileInputRef(el) {
this._fileInput = el;
}
handleClick(e) {
this._fileInput.click();
}
handleDragEnter(e) {
e.stopPropagation();
e.preventDefault();
}
handleDragOver(e) {
e.stopPropagation();
e.preventDefault();
}
handleChange(e) {
this.props.onChange(e.target.value);
e.stopPropagation();
e.preventDefault();
this.revokeCurrentImage();
const fileList = e.dataTransfer ? e.dataTransfer.files : e.target.files;
const files = [...fileList];
const imageType = /^image\//;
// Iterate through the list of files and return the first image on the list
const file = files.find((currentFile) => {
if (imageType.test(currentFile.type)) {
return currentFile;
}
});
if (file) {
// Custom toString function on file, so it can be used on regular image fields
file.toString = function() {
return window.URL.createObjectURL(file);
};
}
this.props.onChange(file);
this.setState({currentImage: file});
}
renderImageName() {
if (!this.state.currentImage) return null;
if (this.state.currentImage instanceof File) {
return this.state.currentImage.name;
} else if (typeof this.state.currentImage === 'string') {
const fileName = this.state.currentImage;
return fileName.substring(fileName.lastIndexOf('/') + 1);
}
return null;
}
render() {
return <input type="file" onChange={this.handleChange}/>;
const imageName = this.renderImageName();
return (
<div
onDragEnter={this.handleDragEnter}
onDragOver={this.handleDragOver}
onDrop={this.handleChange}
>
<span onClick={this.handleClick}>
{imageName ? imageName : 'Click or drop imag here.'}
</span>
<input
type="file"
accept="image/*"
onChange={this.handleChange}
style={styles.input}
ref={this.handleFileInputRef}
/>
</div>
);
}
}
const styles = {
input: {
display: 'none'
}
};

View File

@ -7,7 +7,6 @@ export default class ImagePreview extends React.Component {
render() {
const { value } = this.props;
return value ? <img src={value}/> : null;
}
}