UNPKG

jobiqo-cl

Version:

[![CircleCI](https://circleci.com/gh/jobiqo/jobiqo-cl.svg?style=svg&circle-token=5a24efa5b8bbc4879276123e77d0d3f35ca7144c)](https://circleci.com/gh/jobiqo/jobiqo-cl)

145 lines (142 loc) 8.1 kB
import React__default, { Component } from 'react'; import { Button } from '../01-button/index.js'; import { FormLabel } from '../11-form-item/01-form-label/index.js'; import { FormDescription } from '../11-form-item/02-form-description/index.js'; import InlineError from '../09-inline-error/index.js'; import FlexItems from '../../06-layout/03-flex/index.js'; import FlexItem from '../../06-layout/03-flex/02-flex-item/index.js'; import Spacing from '../../06-layout/07-spacing/index.js'; import Text from '../../13-text/03-text/index.js'; import CloseIcon from '../../../../icons/Close.js'; import DownloadIcon from '../../../../icons/Download.js'; import InfoIcon from '../../../../icons/Info.js'; import { JobPerFileIcon } from '../../../../icons/JobPerFile.js'; import { Wrapper, FileWidgetInput, BoxFilePreviewWrapper, RemoveFileButton, FilePreviewWrapper, ImagePreviewWrapper, Preview, PreviewInfo, ImagePreviewInfoLabel, PreviewIcon } from './styles.js'; /** * @file index.tsx * * @fileoverview File input component. Renders a button input together with its label. */ /** * A file input is a form element where users can chose a file from their local * computer and use it to upload. */ class FileInput extends Component { constructor(props) { super(props); this.state = { files: [], errors: [] }; /** * Triggers a click on the input. */ this.handleClick = event => { this.fileInput.current.click(); }; /** * Handle change on the input field. */ this.handleChange = event => { const fileItems = [...event.target.files]; const { maxSizeMessage = 'File is too large' } = this.props; this.setState({ errors: fileItems .filter(f => { return (this.props.maxSize && f.size > this.props.maxSize * 1024 * 1024); }) .map(fileItem => { return `${fileItem.name} : ${maxSizeMessage}`; }), files: fileItems .filter(f => { return (!this.props.maxSize || (this.props.maxSize && f.size <= this.props.maxSize * 1024 * 1024)); }) .map(fileItem => { return { file: fileItem.type.substring(0, 5) === 'image' ? URL.createObjectURL(fileItem) : null, filename: fileItem.name, fileSize: fileItem.size, type: fileItem.type }; }) }, () => { if (this.props.multiple) { this.props.onChange(fileItems); } else { this.props.onChange(fileItems[0]); } }); }; /** * Handle change on the input field. */ this.removeFile = fileIndex => { this.setState({ files: this.state.files .filter((f, index) => index !== fileIndex) .map(fileItem => { return { file: fileItem.file, filename: fileItem.filename, fileSize: fileItem.fileSize, type: fileItem.type }; }) }, () => { if (this.props.multiple) { this.props.onChange(this.state.files); } else { this.props.onChange(this.state.files[0]); } }); }; // create a ref to store the textInput DOM element this.fileInput = React__default.createRef(); } render() { const { label = 'File', placeholder = 'Choose file', id, description, fileTypes, error = false, required = false, multiple = false, buttonStyle = 'default', onClick } = this.props; return (React__default.createElement(React__default.Fragment, null, label && multiple && (React__default.createElement(React__default.Fragment, null, React__default.createElement(FormLabel, { error: error, required: required, htmlFor: id }, label), React__default.createElement(Spacing, null))), React__default.createElement(Wrapper, { multiple: multiple }, multiple && (React__default.createElement(React__default.Fragment, null, React__default.createElement(DownloadIcon, { height: "100px", width: "100px", color: "gray2", title: "Upload" }), React__default.createElement(Spacing, null))), React__default.createElement(React__default.Fragment, null, label && !multiple && (React__default.createElement(FormLabel, { error: error, required: required, htmlFor: id }, label)), description && multiple && (React__default.createElement(Text, { tag: "p", color: "gray3", textAlign: "center" }, description)), React__default.createElement(Spacing, null), React__default.createElement(FileWidgetInput, Object.assign({ ref: this.fileInput, onChange: this.handleChange, type: "file" }, (fileTypes ? { accept: fileTypes.join(', ') } : null), { id: id, name: id, onClick: onClick, multiple: multiple })), React__default.createElement(Button, { onClick: this.handleClick, "data-testid": "trigger", buttonStyle: buttonStyle, type: "button" }, placeholder), description && !multiple && (React__default.createElement(FormDescription, null, description)), React__default.createElement(FlexItems, { flexWrap: "wrap", alignItems: "center" }, this.state.files.map((fileUploaded, index) => (React__default.createElement(FlexItem, { margin: 4, key: index }, React__default.createElement(BoxFilePreviewWrapper, null, React__default.createElement(RemoveFileButton, null, React__default.createElement("button", { onClick: e => this.removeFile(index) }, React__default.createElement(CloseIcon, { title: "Remove file" }))), React__default.createElement(FilePreviewWrapper, null, React__default.createElement(ImagePreviewWrapper, null, fileUploaded.file ? (React__default.createElement(Preview, { src: fileUploaded.file })) : (React__default.createElement(JobPerFileIcon, { title: "Attachment" }))), React__default.createElement(PreviewInfo, null, React__default.createElement("div", null, React__default.createElement(ImagePreviewInfoLabel, null, React__default.createElement(PreviewIcon, { name: "weight", title: label })), fileUploaded.fileSize, " KB")))))))), this.state.errors && this.state.errors.map(errorMessage => (React__default.createElement("div", null, React__default.createElement(Spacing, null), React__default.createElement(FlexItems, { alignItems: "center" }, React__default.createElement(FlexItem, { marginRight: 4 }, React__default.createElement(InfoIcon, { title: "error", color: "danger" }), ' '), React__default.createElement(InlineError, { message: errorMessage }))))))))); } } export { FileInput };