Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | 1x 5x 5x 3x 5x 5x 5x 5x 1x 1x 5x 1x 1x | import {useEffect, useState} from 'react' import cx from 'classnames' import PropTypes from 'prop-types' import { BASE_CLASS, capitalize, CLASS_BLOCK_TEXT, CLASS_BLOCK_TEXT_MAIN, CLASS_BLOCK_TEXT_SECONDARY, Dropzone, STATUSES } from './settings.js' const AtomUpload = ({ status, onFilesSelection, textExplanation, actionButton: Button, multiple, maxSize, accept, ...props }) => { const [ready, setReady] = useState(false) useEffect(() => { setReady(true) }, []) const renderStatusBlock = (status, getRootProps, getInputProps) => { const classNameIcon = `${BASE_CLASS}-icon${capitalize(status)}` const IconStatus = props[`icon${capitalize(status)}`] const textStatus = props[`text${capitalize(status)}`] const isActive = status === STATUSES.ACTIVE const hasTextExplanation = Boolean(textExplanation) const hasButton = Boolean(Button) return ( <div className={cx(BASE_CLASS, `${BASE_CLASS}--${status}`)} {...getRootProps()}> <input type="hiden" {...getInputProps()} /> <span className={classNameIcon}>{IconStatus}</span> <div className={CLASS_BLOCK_TEXT}> <h4 className={CLASS_BLOCK_TEXT_MAIN}>{textStatus}</h4> {isActive && (hasTextExplanation || hasButton) && ( <> {Button} <p className={CLASS_BLOCK_TEXT_SECONDARY}>{textExplanation}</p> </> )} </div> </div> ) } const hasValidStatus = Object.values(STATUSES).includes(status) const shouldRender = hasValidStatus && ready const onDrop = handler => { Iif (typeof handler === 'function') { return (acceptedFiles, rejectedFiles, event) => handler( acceptedFiles.map(file => Object.assign(file, { preview: URL.createObjectURL(file) }) ), rejectedFiles, event ) } return undefined } return ( shouldRender && ( <Dropzone accept={accept} className={`${BASE_CLASS}-dropzone`} disabled={status !== STATUSES.ACTIVE} maxSize={maxSize} multiple={multiple} onDrop={onDrop(onFilesSelection)} > {({getRootProps, getInputProps}) => renderStatusBlock(status, getRootProps, getInputProps)} </Dropzone> ) ) } AtomUpload.displayName = 'AtomUpload' AtomUpload.propTypes = { /** Icon (component) to be displayed on active status */ iconActive: PropTypes.oneOfType([PropTypes.element, PropTypes.func]), // eslint-disable-line react/no-unused-prop-types /** Icon (component) to be displayed on upload status */ iconUpload: PropTypes.oneOfType([PropTypes.element, PropTypes.func]), // eslint-disable-line react/no-unused-prop-types /** Icon (component) to be displayed on success status */ iconSuccess: PropTypes.oneOfType([PropTypes.element, PropTypes.func]), // eslint-disable-line react/no-unused-prop-types /** Icon (component) to be displayed on error status */ iconError: PropTypes.oneOfType([PropTypes.element, PropTypes.func]), // eslint-disable-line react/no-unused-prop-types /** Text to be displayed on error status */ textActive: PropTypes.string, // eslint-disable-line react/no-unused-prop-types /** Text to be displayed on upload status */ textUpload: PropTypes.string, // eslint-disable-line react/no-unused-prop-types /** Text to be displayed on success status */ textSuccess: PropTypes.string, // eslint-disable-line react/no-unused-prop-types /** Text to be displayed on error status */ textError: PropTypes.string, // eslint-disable-line react/no-unused-prop-types /** Button component to be displayed on active status */ actionButton: PropTypes.node, // eslint-disable-line react/no-unused-prop-types /** Text to be displayed as explanation on active status */ textExplanation: PropTypes.string, /** * Status of the upload * ACTIVE → 'active' * UPLOAD →'upload' * SUCCESS → 'success' * ERROR → 'error' */ status: PropTypes.oneOf(Object.values(STATUSES)).isRequired, /** Callback to be called (with files selected) when there`s a file selection (via click or drag & drop) */ onFilesSelection: PropTypes.func, /** * Allow drag 'n' drop (or selection from the file dialog) of multiple files */ multiple: PropTypes.bool, /** Maximum file size (in bytes) */ maxSize: PropTypes.number, /** * Set accepted file types. * See https://github.com/okonet/attr-accept for more information. */ accept: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]) } export {STATUSES as uploadStatuses} export default AtomUpload |