wix-style-react
Version:
133 lines (111 loc) • 3.62 kB
JavaScript
import React from 'react';
import PropTypes from 'prop-types';
import Add from 'wix-ui-icons-common/Add';
import uniqueId from 'lodash/uniqueId';
import { classes } from './FilePicker.st.css';
import FormField from '../FormField';
import TextButton from '../TextButton';
import Text from '../Text';
import FileUpload from '../FileUpload';
/**
* # `<FilePicker/>`
*
* Component that opens system browser dialog for choosing files to upload
*/
class FilePicker extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
selectedFileName: props.subLabel,
};
this.id = props.id || uniqueId('file_picker_input_');
}
/** A callback which is invoked every time a file is chosen */
onChooseFile(file) {
const { maxSize, onChange } = this.props;
if (file) {
onChange(file);
if (file.size <= maxSize) {
this.setState({ selectedFileName: file.name });
}
}
}
render() {
const {
header,
mainLabel,
supportedFormats,
error,
errorMessage,
name,
dataHook,
} = this.props;
return (
<FileUpload
accept={supportedFormats}
onChange={files => this.onChooseFile(files[0])}
name={name}
>
{({ openFileUploadDialog }) => (
<FormField label={header} dataHook={dataHook}>
<label className={classes.label} onClick={openFileUploadDialog}>
<div className={classes.icon}>
<Add />
</div>
<div className={classes.content}>
<TextButton dataHook="main-label">{mainLabel}</TextButton>
<Text
className={classes.info}
size="small"
secondary
dataHook="sub-label"
>
{this.state.selectedFileName}
</Text>
{error && (
<Text skin="error" size="small" dataHook="filePicker-error">
{errorMessage}
</Text>
)}
</div>
</label>
</FormField>
)}
</FileUpload>
);
}
}
FilePicker.displayName = 'FilePicker';
FilePicker.defaultProps = {
mainLabel: 'Choose File',
subLabel: 'No file chosen (Max size 5 MB)',
onChange: () => {},
supportedFormats: '*',
errorMessage: '',
maxSize: 5000000, // 5MB
};
FilePicker.propTypes = {
/** Applies a data-hook HTML attribute that can be used in tests. */
dataHook: PropTypes.string,
/** Defines if an error should show or not. */
error: PropTypes.bool,
/** Sets an error message to display. */
errorMessage: PropTypes.string,
/** Allows to insert overline text at the top left of a component. Can also be overridden with any other component, i.e. <Image/>. */
header: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
/** Specifies a unique id for the element. */
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/** Sets the main action label. */
mainLabel: PropTypes.string,
/** Defines the maximum size of a file that can be uploaded. */
maxSize: PropTypes.number,
/** Defines a name for inner input. */
name: PropTypes.string,
/** Defines a standard input onChange callback. */
onChange: PropTypes.func,
/** Adds a supportive message below the action title. */
subLabel: PropTypes.string,
/** Defines which file types to accept (i.e. .jpeg, .gif, .png). Formats should be separated by a comma. */
supportedFormats: PropTypes.string,
};
export default FilePicker;