Skip to content

Commit

Permalink
Rebuild ImageUpload imagePreview component
Browse files Browse the repository at this point in the history
  • Loading branch information
bearcanrun committed Oct 17, 2018
1 parent 106050b commit 9b21420
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 19 deletions.
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ const YourComponent = ({ handleAvatar, filename, containerName, avatar, AzureSto
fileName={fileName}
containerName={containerName}
existingImage={avatar}
cropContainer={{ x: 10, y: 10, width: 200, height: 200 }}
imagePreviewConfig={{ width: 350, title: 'Change Avatar' }}
cropContainerConfig={{ x: 10, y: 10, width: 200, height: 200 }}
cropPreviewBox={{ width: 350, height: 350 }}
saveImageConfig={{
quality: 0.6,
Expand All @@ -98,7 +99,8 @@ export default YourComponent
| `fileName` | String | *Required.* File name that image is uploaded to storage as |
| `containerName` | String | *Required.* StorageContainer name that image is uploaded to |
| `existingImage` | String (url) | Url of pre-existing image. Usually will be same as URL returned from `handleUrl` |
| `cropContainer` | Object | Size and location of cropper on image in crop mode |
| `imagePreviewConfig` | Object | Existing image preview and change button text |
| `cropContainerConfig` | Object | Size and location of cropper on image in crop mode |
| `cropPreviewBox` | Object | Dimensions of cropper preview |
| `cropRatio` | Number | ratio (width/height) image is cropped at eg. 1/1, 4/1, 16/9, 800/150 |
| `saveImageConfig` | Object | Configuration of image saved to storage |
Expand All @@ -108,7 +110,8 @@ export default YourComponent
#### Default Values
| Props | Default |
| ------------------ | ------------- |
| `cropContainer` | `{ x: 10, y: 10, width: 200, height: 200 }` |
| `imagePreviewConfig` | `{ width: 350, title: 'Change Avatar' }` |
| `cropContainerConfig` | `{ x: 10, y: 10, width: 200, height: 200 }` |
|`cropPreviewBox` | `{ width: 350, height: 350 }` |
|`cropRatio` | `1 / 1` |
|`saveImageConfig` | `{quality: 0.6, maxWidth: 200, maxHeight: 200, autoRotate: true, debug: true, mimeType: 'image/jpeg}` |
Expand Down Expand Up @@ -174,8 +177,8 @@ export class YourComponent extends Component {
fileName={fileName}
containerName={containerName}
existingImage={avatar}
cropContainer={{ x: 10, y: 10, width: 200, height: 200 }}
cropPreviewBox={{ width: 350, height: 350 }}
imagePreviewConfig={{ width: 350, title: 'Change Avatar' }}
cropContainerConfig={{ x: 10, y: 10, width: 200, height: 200 }} cropPreviewBox={{ width: 350, height: 350 }}
saveImageConfig={{
quality: 0.6,
maxWidth: 200,
Expand Down
105 changes: 94 additions & 11 deletions src/image-upload/components/ImagePreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,114 @@ import React from 'react'
import PropTypes from 'prop-types'

import { withStyles } from '@material-ui/core/styles'
import Button from '@material-ui/core/Button'
import ButtonBase from '@material-ui/core/ButtonBase'
import Typography from '@material-ui/core/Typography'

const styles = theme => ({
imagePreview: {
maxWidth: '100%',
height: 'auto'
root: {
display: 'flex',
flexWrap: 'wrap',
minWidth: 300,
width: '100%'
},
image: {
position: 'relative',
height: 200,
[theme.breakpoints.down('xs')]: {
width: '100% !important', // Overrides inline-style
height: 100
},
'&:hover, &$focusVisible': {
zIndex: 1,
'& $imageBackdrop': {
opacity: 0.15
},
'& $imageMarked': {
opacity: 0
},
'& $imageTitle': {
backgroundColor: theme.palette.common.black,
opacity: 0.4
}
}
},
focusVisible: {},
imageButton: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: theme.palette.common.white
},
imageSrc: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
backgroundSize: 'cover',
backgroundPosition: 'center 40%'
},
imageBackdrop: {
position: 'absolute',
left: 0,
right: 0,
top: 0,
bottom: 0,
backgroundColor: theme.palette.common.black,
opacity: 0.4,
transition: theme.transitions.create('opacity')
},
imageTitle: {
position: 'relative',
textTransform: 'uppercase',
fontWeight: 700,
padding: `${theme.spacing.unit * 2}px ${theme.spacing.unit * 4}px ${theme.spacing.unit + 6}px`
}
})

export const ImagePreview = ({ classes, handleChangeImage, image }) => (
export const ImagePreview = ({ classes, handleChangeImage, image, imagePreview }) => (
<React.Fragment>
<img src={image} className={classes.imagePreview} alt='Existing Image Preview' />
<Button
<ButtonBase
focusRipple
key={imagePreview.title}
className={classes.image}
focusVisibleClassName={classes.focusVisible}
onClick={handleChangeImage}
color='primary'
style={{
width: imagePreview.width
}}
>
Change
</Button>
<span
className={classes.imageSrc}
style={{
backgroundImage: `url(${image})`
}}
/>
<span className={classes.imageBackdrop} />
<span className={classes.imageButton}>
<Typography
component='span'
variant='h3'
color='inherit'
className={classes.imageTitle}
>
{imagePreview.title}
</Typography>
</span>
</ButtonBase>
</React.Fragment>
)

ImagePreview.propTypes = {
classes: PropTypes.object.isRequired,
handleChangeImage: PropTypes.func,
image: PropTypes.string
image: PropTypes.string,
imagePreview: PropTypes.object
}

export default withStyles(styles)(ImagePreview)
11 changes: 10 additions & 1 deletion src/image-upload/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ const placeHolder = fileName => {
return `data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22288%22%20height%3D%22225%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20288%20225%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_164edaf95ee%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A14pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_164edaf95ee%22%3E%3Crect%20width%3D%22288%22%20height%3D%22225%22%20fill%3D%22%2355595c%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2296.32500076293945%22%20y%3D%22118.8%22%3E${fileName}%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E`
}

const imagePreviewDefault = {
width: 400,
title: 'Change Avatar'
}

const cropPreviewBoxDefault = {
width: 350,
height: 350
Expand Down Expand Up @@ -60,9 +65,12 @@ class ImageUpload extends Component {
this.saveImage = this.saveImage.bind(this)
this.debug = this.props.debug

let previewConfig = props.imagePreviewConfig !== undefined ? props.imagePreviewConfig : imagePreviewDefault
let cropConfig = props.cropContainerConfig !== undefined ? props.cropContainerConfig : cropConfigDefault
let saveConfig = props.saveImageConfig !== undefined ? props.saveImageConfig : saveImageConfigDefault
let cropPreview = props.cropPreviewBox !== undefined ? props.cropPreviewBox : cropPreviewBoxDefault
this.previewConfig = previewConfig
this.cropConfig = cropConfig
this.saveConfig = saveConfig
this.cropPreview = cropPreview

Expand Down Expand Up @@ -103,7 +111,7 @@ class ImageUpload extends Component {
<React.Fragment>
<div>
{ (this.state.event === 'preview' || this.state.event === 'uploaded') && this.state.event !== 'choose' && (
<ImagePreview handleChangeImage={this.handleChangeImage} image={image} />
<ImagePreview handleChangeImage={this.handleChangeImage} image={image} imagePreview={this.previewConfig} />
)}
{ this.state.event === 'choose' && (
<DropZone onDrop={this.onDrop} handleCancel={this.handleCancel} />
Expand Down Expand Up @@ -200,6 +208,7 @@ class ImageUpload extends Component {

ImageUpload.propTypes = {
classes: PropTypes.object.isRequired,
imagePreviewConfig: PropTypes.object, // { width: 400, title: 'Change Avatar'}
cropContainerConfig: PropTypes.object, // { x: 10, y: 10, width: 200, height: 200 } (default)
cropPreviewBox: PropTypes.object, // { width: 350, height: 350 } (default)
cropRatio: PropTypes.number.isRequired, // ratio (width/height) image is cropped at eg. 1/1, 4/1, 16/9, 800/150
Expand Down
5 changes: 3 additions & 2 deletions stories/index.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ storiesOf('ImageUpload', module)
containerName={text('containerName', 'test-team')}
existingImage={placeholder}
cropRatio={1}
cropContainer={{ x: 10, y: 10, width: 200, height: 200 }}
imagePreviewConfig={{ width: 350, title: 'Change Avatar' }}
cropContainerConfig={{ x: 10, y: 10, width: 200, height: 200 }}
cropPreviewBox={{ width: 350, height: 350 }}
saveImageConfig={{
quality: 0.6,
Expand Down Expand Up @@ -98,7 +99,7 @@ class LoadImage extends React.Component {
storiesOf('ImageUpload Components', module)
.addDecorator(withKnobs)
.add('Image Preview component', () => (
<ImagePreview handleChangeImage={action('Change clicked')} image={placeholder} />
<ImagePreview handleChangeImage={action('Change clicked')} image={placeholder} imagePreview={{ width: 400, title: 'Change Avatar' }} />
))
.add('DropZone component', () => (
<DropZone onDrop={action('Image dropped or selected')} handleCancel={action('Change image cancelled')} />
Expand Down

0 comments on commit 9b21420

Please sign in to comment.