Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve preview 166 tidy #171

Merged
merged 2 commits into from
Jun 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 75 additions & 7 deletions src/components/DropzoneArea.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,45 @@ import { DropzoneArea } from 'material-ui-dropzone';

### Basic usage

Add up to 3 files

```jsx
<DropzoneArea
onChange={(files) => console.log('Files:', files)}
/>
```

### Single file upload

```jsx
<DropzoneArea
filesLimit={1}
onChange={(files) => console.log('Files:', files)}
/>
```

### Up to 20 files (previewed inside dropzone area)

```jsx
<DropzoneArea
filesLimit={20}
onChange={(files) => console.log('Files:', files)}
/>
```


### Up to 20 Files (previewed below dropzone area)

```jsx
<DropzoneArea
filesLimit={20}
previewType='below'
showFileNames
onChange={(files) => console.log('Files:', files)}
/>
```


### Accept only images

```jsx
Expand All @@ -33,29 +66,64 @@ Demonstration of how to customize the preview icon for:

```jsx
import * as React from 'react';
import Grid from '@material-ui/core/Grid'
import { AttachFile, AudioTrack, Description, PictureAsPdf, Theaters } from '@material-ui/icons';
import clsx from 'clsx'

const handlePreviewIcon = (fileObject, classes) => {
const handlePreviewIcon = (fileObject, classes, isImage, titleBarTop) => {
const {type} = fileObject.file
const iconProps = {
className : classes.image,
className : clsx(classes.fileIcon, {[classes.fileIconBottom]: titleBarTop})
}

if (type.startsWith("video/")) return <Theaters {...iconProps} />
if (type.startsWith("audio/")) return <AudioTrack {...iconProps} />
let icon

if (type.startsWith("video/")) icon = <Theaters {...iconProps} />
if (type.startsWith("audio/")) icon = <AudioTrack {...iconProps} />

switch (type) {
case "application/msword":
case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
return <Description {...iconProps} />
icon = <Description {...iconProps} />;
break;
case "application/pdf":
return <PictureAsPdf {...iconProps} />
icon = <PictureAsPdf {...iconProps} />;
break;
default:
return <AttachFile {...iconProps} />
icon = <AttachFile {...iconProps} />;
break;
}

return <Grid container className={classes.iconWrapper} justify="center" >
{icon}
</Grid>
}

<DropzoneArea
getPreviewIcon={handlePreviewIcon}

/>
```


### With custom preview props

```jsx
<DropzoneArea
filesLimit={20}
showFileNames
previewGridProps={{
gridList : {
cellHeight: 220, // the mui default is 180
cols: 4, // force the number of columns
},
gridListTitleBar : {
titlePosition : 'top', // mui default is bottom
actionPosition: 'left', // mui default is right
style: {backgroundColor: 'rgba(248, 132, 132, 0.63)'}
},
}}

onChange={(files) => console.log('Files:', files)}
/>
```
80 changes: 56 additions & 24 deletions src/components/DropzoneAreaBase.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Snackbar from '@material-ui/core/Snackbar';
import Typography from '@material-ui/core/Typography';
import Grid from '@material-ui/core/Grid';
import {withStyles} from '@material-ui/core/styles';
import AttachFileIcon from '@material-ui/icons/AttachFile';
import CloudUploadIcon from '@material-ui/icons/CloudUpload';
Expand All @@ -22,6 +23,7 @@ const styles = ({palette, shape, spacing}) => ({
},
},
root: {
display: 'flex',
position: 'relative',
width: '100%',
minHeight: '250px',
Expand All @@ -32,6 +34,8 @@ const styles = ({palette, shape, spacing}) => ({
boxSizing: 'border-box',
cursor: 'pointer',
overflow: 'hidden',
flexDirection: 'column',
justifyContent: 'center',
},
active: {
animation: '$progress 2s linear infinite !important',
Expand All @@ -47,7 +51,7 @@ const styles = ({palette, shape, spacing}) => ({
borderColor: palette.error.main,
},
textContainer: {
textAlign: 'center',
display: 'flex',
},
text: {
marginBottom: spacing(3),
Expand All @@ -60,21 +64,40 @@ const styles = ({palette, shape, spacing}) => ({
},
});

const defaultGetCols = (width, filesLimit) => {
const returnBelowLimit = (number) => {
if (number < filesLimit) {
return number;
}
return filesLimit;
};

switch (width) {
case 'xs': return returnBelowLimit(1) ;
case 'sm': return returnBelowLimit(2);
case 'md': return returnBelowLimit(3);
case 'lg': return returnBelowLimit(4);
case 'xl' : return returnBelowLimit(5);
}
};

const defaultSnackbarAnchorOrigin = {
horizontal: 'left',
vertical: 'bottom',
};

const defaultGetPreviewIcon = (fileObject, classes) => {
if (isImage(fileObject.file)) {
const defaultGetPreviewIcon = (fileObject, classes, isImage, titleBarTop) => {
if (isImage) {
return (<img
className={classes.image}
role="presentation"
src={fileObject.data}
/>);
}

return <AttachFileIcon className={classes.image} />;
return <Grid container className={classes.iconWrapper} justify="center" >
<AttachFileIcon className={clsx(classes.fileIcon, {[classes.fileIconBottom]: titleBarTop})} />
</Grid>;
};

/**
Expand Down Expand Up @@ -186,26 +209,24 @@ class DropzoneAreaBase extends React.PureComponent {
dropzoneText,
fileObjects,
filesLimit,
getCols,
getPreviewIcon,
inputProps,
maxFileSize,
previewChipProps,
previewGridClasses,
previewGridProps,
previewText,
previewType,
showAlerts,
showFileNames,
showFileNamesInPreview,
showPreviews,
showPreviewsInDropzone,
useChipsForPreview,
} = this.props;
const {openSnackBar, snackbarMessage, snackbarVariant} = this.state;

const acceptFiles = acceptedFiles?.join(',');
const isMultiple = filesLimit > 1;
const previewsVisible = showPreviews && fileObjects.length > 0;
const previewsInDropzoneVisible = showPreviewsInDropzone && fileObjects.length > 0;
const someFiles = fileObjects.length > 0;

return (
<Fragment>
Expand All @@ -229,7 +250,7 @@ class DropzoneAreaBase extends React.PureComponent {
>
<input {...inputProps} {...getInputProps()} />

<div className={classes.textContainer}>
<Grid container className={classes.textContainer} direction="column" justifyContent="center" alignItems="center">
<Typography
variant="h5"
component="p"
Expand All @@ -238,39 +259,45 @@ class DropzoneAreaBase extends React.PureComponent {
{dropzoneText}
</Typography>
<CloudUploadIcon className={classes.icon} />
</div>
</Grid>

{previewsInDropzoneVisible &&
{someFiles && previewType === 'inside' &&
<PreviewList
fileObjects={fileObjects}
filesLimit={filesLimit}
getCols={getCols}
handleRemove={this.handleRemove}
getPreviewIcon={getPreviewIcon}
showFileNames={showFileNames}
useChipsForPreview={useChipsForPreview}
previewChipProps={previewChipProps}
previewGridClasses={previewGridClasses}
previewGridProps={previewGridProps}
previewType={previewType}
/>
}
</div>
)}
</Dropzone>

{previewsVisible &&
{someFiles && previewType === 'below' &&
<Fragment>
<Typography variant="subtitle1" component="span">
{previewText}
</Typography>

<PreviewList
fileObjects={fileObjects}
filesLimit={filesLimit}
getCols={getCols}
handleRemove={this.handleRemove}
getPreviewIcon={getPreviewIcon}
showFileNames={showFileNamesInPreview}
showFileNames={showFileNames}
useChipsForPreview={useChipsForPreview}
previewChipProps={previewChipProps}
previewGridClasses={previewGridClasses}
previewGridProps={previewGridProps}
previewType={previewType}
/>
</Fragment>
}
Expand Down Expand Up @@ -303,11 +330,9 @@ DropzoneAreaBase.defaultProps = {
maxFileSize: 3000000,
dropzoneText: 'Drag and drop a file here or click',
previewText: 'Preview:',
previewType: 'inside',
disableRejectionFeedback: false,
showPreviews: false, // By default previews show up under in the dialog and inside in the standalone
showPreviewsInDropzone: true,
showFileNames: false,
showFileNamesInPreview: false,
showFileNames: true,
useChipsForPreview: false,
previewChipProps: {},
previewGridClasses: {},
Expand All @@ -320,6 +345,7 @@ DropzoneAreaBase.defaultProps = {
},
autoHideDuration: 6000,
},
getCols: defaultGetCols,
getFileLimitExceedMessage: (filesLimit) => (`Maximum allowed number of files exceeded. Only ${filesLimit} allowed`),
getFileAddedMessage: (fileName) => (`File ${fileName} successfully added.`),
getPreviewIcon: defaultGetPreviewIcon,
Expand Down Expand Up @@ -362,15 +388,9 @@ DropzoneAreaBase.propTypes = {
dropzoneParagraphClass: PropTypes.string,
/** Disable feedback effect when dropping rejected files. */
disableRejectionFeedback: PropTypes.bool,
/** Shows previews **BELOW** the dropzone. */
showPreviews: PropTypes.bool,
/** Shows preview **INSIDE** the dropzone area. */
showPreviewsInDropzone: PropTypes.bool,
/** Shows file name under the dropzone image. */
showFileNames: PropTypes.bool,
/** Shows file name under the image. */
showFileNamesInPreview: PropTypes.bool,
/** Uses deletable Material-UI Chip components to display file names. */
useChipsForPreview: PropTypes.bool,
/**
* Props to pass to the Material-UI Chip components.<br/>Requires `useChipsForPreview` prop to be `true`.
Expand All @@ -392,6 +412,8 @@ DropzoneAreaBase.propTypes = {
previewGridProps: PropTypes.object,
/** The label for the file preview section. */
previewText: PropTypes.string,
/** Determines whether previews are shown inside the dropzone area, below, or not at all. Acceptable values are 'inside', 'below', 'none'. */
previewType: PropTypes.string,
/**
* Shows styled Material-UI Snackbar when files are dropped, deleted or rejected.
*
Expand Down Expand Up @@ -424,6 +446,16 @@ DropzoneAreaBase.propTypes = {
* @see See [MDN Input File attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#Additional_attributes) for available values.
*/
inputProps: PropTypes.object,
/**
* A function which determines which the number of columns to display in the preview list
*
* *Default*: Returns a sensible number of columns depending on the screen size (i.e. xs=1, sm=2, md=3, lg=4, xl=5) without exceeding the filesLimit (e.g. There would be no point displaying 4 columns if the filesLimit is 3)
*
* @param {string} width Width prop from withWidth, this will be one of ['xs','sm','md','lg','xl'] depending on the current screen size
* @param {number} filesLimit The `filesLimit` prop
* @param {number} currentNumberOfFiles The number of files in the `state.fileObjects`
*/
getCols: PropTypes.func,
/**
* Get alert message to display when files limit is exceed.
*
Expand Down
2 changes: 1 addition & 1 deletion src/components/DropzoneDialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const [open, setOpen] = React.useState(false);
console.log('Files:', files);
setOpen(false);
}}
showPreviews={true}
previewType='below'
showFileNamesInPreview={true}
/>
</div>
Expand Down
Loading