UNPKG

@geneui/components

Version:

The Gene UI components library designed for BI tools

993 lines (981 loc) 44.9 kB
import { _ as _extends } from '../_rollupPluginBabelHelpers-e8fb2e5c.js'; import React__default, { useState, useCallback, useEffect, forwardRef, useMemo, useRef } from 'react'; import PropTypes from 'prop-types'; import { c as classnames } from '../index-031ff73c.js'; import { u as uploaderConfig } from '../configs-00612ce0.js'; import { p as getImageDimensions, s as stopEvent, f as fileSizeDisplay, n as noop } from '../index-a0e4e333.js'; import Button from '../Button/index.js'; import ExtendedInput from '../ExtendedInput/index.js'; import { Row, Col } from '../Grid/index.js'; import useKeyDown from '../hooks/useKeyDown.js'; import useImgDownload from '../hooks/useImgDownload.js'; import BusyLoader from '../BusyLoader/index.js'; import Icon from '../Icon/index.js'; import Image from '../Image/index.js'; import { T as Tooltip } from '../index-6d7e99cd.js'; import { s as styleInject } from '../style-inject.es-746bb8ed.js'; import '../dateValidation-67caec66.js'; import '../_commonjsHelpers-24198af3.js'; import 'react-dom'; import '../tslib.es6-f211516f.js'; import '../hooks/useDeviceType.js'; import '../hooks/useWindowSize.js'; import '../hooks/useDebounce.js'; import '../useEllipsisDetection-4d997d5d.js'; import '../SuggestionList/index.js'; import '../hooks/useClickOutside.js'; import '../config-1053d64d.js'; import '../Scrollbar/index.js'; import '../callAfterDelay-7272faca.js'; import '../GeneUIProvider/index.js'; import '../hooks/useWidth.js'; import '../Empty/index.js'; import '../Checkbox/index.js'; import '../checkboxRadioSwitcher-5b69d7bd.js'; import '../guid-8ddf77b3.js'; // Helpers const typeListReplacer = 'TYPE_LIST'; const maxFileSizeReplacer = 'MAX_FILE_SIZE'; const getFileByUrl = async (url, file, isImageUpload, customHeaders) => { const res = await fetch(url, { headers: { ...customHeaders } }); const blob = await res.blob(); const blobFile = { blob, ...file }; if (isImageUpload) { blobFile.dimensions = await getImageDimensions(blob); } return blobFile; }; const addDragEventListener = (element, handleDragIn, handleDragOut, handleDrop) => { element.addEventListener('dragenter', handleDragIn); element.addEventListener('dragover', handleDragIn); element.addEventListener('dragleave', handleDragOut); element.addEventListener('dragend', handleDragOut); element.addEventListener('drop', handleDrop); }; const removeDragEventListener = (element, handleDragIn, handleDragOut, handleDrop) => { element.removeEventListener('dragenter', handleDragIn); element.removeEventListener('dragover', handleDragIn); element.removeEventListener('dragleave', handleDragOut); element.removeEventListener('dragend', handleDragOut); element.removeEventListener('drop', handleDrop); }; const toBlobFile = async (file, isImageUpload) => { const blob = new Blob([file], { type: file.type }); const blobFile = { name: file.name, blob, path: URL.createObjectURL(blob) }; if (isImageUpload) { const dimensions = await getImageDimensions(blob); blobFile.dimensions = dimensions; } return blobFile; }; /** * Checking the file for the size and type of rules * and return each one of them. */ const isValidFile = _ref => { var _file$name$split$pop; let { allTypesAccepted, isImageUpload, maxFileSize, typesList, file } = _ref; const fileType = file && file.name && ((_file$name$split$pop = file.name.split('.').pop()) === null || _file$name$split$pop === void 0 ? void 0 : _file$name$split$pop.toLowerCase()); return { isValidSize: file.size <= maxFileSize, isValidType: typesList.length ? typesList.includes(fileType) : allTypesAccepted }; }; const generateFilesByPage = files => { if (files && files.length) { const data = files.map(path => { const binary = new ArrayBuffer(path.length); const blob = new Blob([binary], { type: 'image/jpeg' }); return { blob, path, name: path.split('/').pop() }; }); return data; } return []; }; const getLastMod = (url, cb) => { fetch(url).then(response => { const headersObj = Object.fromEntries([...response.headers]); return cb(headersObj['last-modified']); }); }; var css_248z$3 = "[data-gene-ui-version=\"2.16.5\"] .media-preview-holder{background-color:#000c;color:#fff;display:flex;height:100%;left:0;position:fixed;top:0;width:100%;z-index:500}[data-gene-ui-version=\"2.16.5\"] .media-preview-holder .bc-icon-close{cursor:pointer;position:absolute;right:2.2rem;top:2.2rem}[data-gene-ui-version=\"2.16.5\"] .media-preview{display:flex;flex-direction:column;margin:auto;padding:3rem 0 0;position:relative}[data-gene-ui-version=\"2.16.5\"] .media-preview .mp-title{font:600 1.4rem/1.8rem var(--font-family);left:0;position:absolute;top:0;width:100%}[data-gene-ui-version=\"2.16.5\"] .mp-details{font:600 1.4rem/2rem var(--font-family);margin:.5rem 0 0}[data-gene-ui-version=\"2.16.5\"] .mp-details>li{margin:1rem 0 0}[data-gene-ui-version=\"2.16.5\"] .mp-details span{opacity:.7}[data-gene-ui-version=\"2.16.5\"] .mp-element{height:auto;max-height:calc(100vh - 20rem);max-width:100%;width:auto}"; styleInject(css_248z$3); function Preview(_ref) { let { previewImage: { name, path, blob: { size }, dimensions }, hideName, onClose } = _ref; return /*#__PURE__*/React__default.createElement("div", { className: "media-preview-holder", onClick: onClose }, /*#__PURE__*/React__default.createElement(Icon, { type: "bc-icon-close" }), /*#__PURE__*/React__default.createElement("div", { className: "media-preview", onClick: stopEvent }, /*#__PURE__*/React__default.createElement("div", { className: "mp-title ellipsis-text" }, !hideName && name), /*#__PURE__*/React__default.createElement("img", { className: "mp-element", src: path, alt: name }), /*#__PURE__*/React__default.createElement("ul", { className: "mp-details" }, /*#__PURE__*/React__default.createElement("li", null, /*#__PURE__*/React__default.createElement("span", null, "Image size:"), " ", fileSizeDisplay(size), ' '), dimensions && /*#__PURE__*/React__default.createElement("li", null, /*#__PURE__*/React__default.createElement("span", null, "Image dimensions: "), dimensions.width, " x ", dimensions.height)))); } Preview.propTypes = { previewImage: PropTypes.object.isRequired, onClose: PropTypes.func.isRequired, dimensions: PropTypes.object, name: PropTypes.string, path: PropTypes.string, blob: PropTypes.object }; Preview.defaultProps = { dimensions: {} }; var css_248z$2 = "[data-gene-ui-version=\"2.16.5\"] .uploaded-item{align-items:center;border-radius:.4rem;display:flex;height:2.8rem;padding:0 1px 0 .8rem;transition:background .4s,color .4s,border-color .4s;width:100%}html[dir=rtl] .uploaded-item{padding:0 .8rem 0 1px}[data-gene-ui-version=\"2.16.5\"] .uploaded-item:not(.error){cursor:pointer}[data-gene-ui-version=\"2.16.5\"] .uploaded-item>li{align-items:center;display:flex;flex-shrink:0}[data-gene-ui-version=\"2.16.5\"] .uploaded-item>li.ui-title{flex:auto;overflow:hidden}[data-gene-ui-version=\"2.16.5\"] .uploaded-item .ui-preview-holder{position:relative}[data-gene-ui-version=\"2.16.5\"] .uploaded-item .ui-preview-holder small{display:block;font:700 .5rem/.9rem var(--font-family);left:0;position:absolute;text-align:center;text-transform:uppercase;top:.8rem;width:100%}[data-gene-ui-version=\"2.16.5\"] .uploaded-item .ui-title{font:600 1.4rem/normal var(--font-family);padding:0 2rem}[data-gene-ui-version=\"2.16.5\"] .uploaded-item .ui-actions-holder small{display:block;font:600 1rem/1.4rem var(--font-family);opacity:.7;padding-inline-end:.8rem;text-transform:uppercase}[data-gene-ui-version=\"2.16.5\"] .uploaded-item .ui-actions-holder .icon{cursor:pointer;transition:opacity .4s}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-light .ui-actions-holder .icon,[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-minimal .ui-actions-holder .icon{opacity:0}@media (hover:hover){[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-light .ui-actions-holder .icon:hover,[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-minimal .ui-actions-holder .icon:hover{opacity:1}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-light:hover,[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-minimal:hover{background:rgba(var(--background-sc-rgb),.05)}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-light:hover .ui-actions-holder .icon:not(:hover),[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-minimal:hover .ui-actions-holder .icon:not(:hover){opacity:.5}}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-light.error,[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-minimal.error{color:var(--danger)}@media (hover:hover){[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-light.error:hover,[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-minimal.error:hover{background:rgba(var(--danger-rgb),.05)}}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-light.error .ui-actions-holder .icon:not(:hover),[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-minimal.error .ui-actions-holder .icon:not(:hover){opacity:.5}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-detailed{border:1px solid rgba(var(--background-sc-rgb),.08);border-radius:.8rem;height:4.2rem;padding:0 .8rem 0 1.4rem}html[dir=rtl] .uploaded-item.ui-detailed{padding:0 1.4rem 0 .8rem}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-detailed img{border-radius:.4rem;height:2.6rem;object-fit:cover;width:2.6rem}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-detailed .ui-title{font-size:1.2rem;padding:0 1.4rem}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-detailed .ui-actions-holder .icon{opacity:.5}@media (hover:hover){[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-detailed .ui-actions-holder .icon:hover{opacity:1}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-detailed:hover{border-color:rgba(var(--background-sc-rgb),.38)}}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-detailed.error{border-color:rgba(var(--danger-rgb),.5)}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-detailed.error .ui-actions-holder .icon{color:var(--danger)}@media (hover:hover){[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-detailed.error:hover{border-color:var(--danger)}[data-gene-ui-version=\"2.16.5\"] .uploaded-item.ui-detailed.error:hover .ui-actions-holder .icon{opacity:1}}"; styleInject(css_248z$2); function UploadedItem(_ref) { let { notUploadedFileList, uploadErrorText, metaDataHeaders, customHeaders, appearance, retryIndex, onRemove, showTrash, onRetry, isBusy, index, file, showDownloadButton, showRemoveButton, showResetButton, showPreviewButton, additionalContext, hideName } = _ref; const [previewImage, setPreviewImage] = useState(null); const [lastModifiedDate, setLastModifiedDate] = useState(null); const toPreview = useCallback(image => { if (file.blob.type.search('pdf') > -1) { const link = document.createElement('a'); link.href = file.path; link.target = '_blank'; link.click(); } else { setPreviewImage(image); } }, []); const doClosePreview = useCallback(() => setPreviewImage(null), []); useKeyDown(doClosePreview, [], { current: window }, ['Escape']); const { name, blob: { size, type }, path, dimensions } = file; useEffect(() => { switch (metaDataHeaders === null || metaDataHeaders === void 0 ? void 0 : metaDataHeaders.type) { case 'LAST-MODIFIED': if (metaDataHeaders.formatter) { getLastMod(path, date => { date ? setLastModifiedDate(metaDataHeaders.formatter(date)) : setLastModifiedDate(metaDataHeaders.formatter(new Date(Date.now()))); }); } else { getLastMod(path, date => { date ? setLastModifiedDate(new Date(date).toLocaleDateString()) : setLastModifiedDate(new Date(Date.now()).toLocaleDateString()); }); } break; } }, [file]); const uploadedError = notUploadedFileList.find(item => item && item.file === file); const [image, fileExtension] = type.split('/'); const isImage = image === 'image'; const renderPreview = () => { switch (appearance) { case uploaderConfig.uploadedItemsAppearance[0]: return /*#__PURE__*/React__default.createElement(Icon, { type: "bc-icon-attachment" }); case uploaderConfig.uploadedItemsAppearance[1]: return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Icon, { type: "bc-icon-file-type" }), /*#__PURE__*/React__default.createElement("small", null, fileExtension)); case uploaderConfig.uploadedItemsAppearance[2]: return isImage ? /*#__PURE__*/React__default.createElement("img", { src: path, alt: name }) : /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Icon, { type: "bc-icon-file-type" }), /*#__PURE__*/React__default.createElement("small", null, fileExtension)); } }; const onDownload = useImgDownload(); return previewImage ? /*#__PURE__*/React__default.createElement(Preview, { onClose: doClosePreview, previewImage: previewImage, hideName: hideName }) : /*#__PURE__*/React__default.createElement(BusyLoader, { isBusy: isBusy && retryIndex === index, loadingText: "" }, /*#__PURE__*/React__default.createElement(Tooltip, { title: uploadedError ? uploadErrorText : '', text: uploadedError && uploadedError.error || '' }, appearance === uploaderConfig.uploadedItemsAppearance[3] && isImage ? /*#__PURE__*/React__default.createElement(Image, { src: path, withBorder: true, isValid: !uploadedError, actions: /*#__PURE__*/React__default.createElement(React__default.Fragment, null, uploadedError && showResetButton ? /*#__PURE__*/React__default.createElement(Button, { icon: "bc-icon-reset", appearance: "minimal", "data-index": index, onClick: onRetry, type: "button" }) : showPreviewButton && /*#__PURE__*/React__default.createElement(Button, { icon: "bc-icon-view", appearance: "minimal", onClick: () => toPreview(file), type: "button" }), showRemoveButton && /*#__PURE__*/React__default.createElement(Button, { icon: "bc-icon-trash", "data-index": index, onClick: onRemove, appearance: "minimal", color: "danger", type: "button" })) }) : /*#__PURE__*/React__default.createElement("ul", { className: classnames('uploaded-item', "ui-".concat(appearance), { error: uploadedError }) }, /*#__PURE__*/React__default.createElement("li", { className: "ui-preview-holder" }, renderPreview()), /*#__PURE__*/React__default.createElement("li", { className: "ui-title" }, /*#__PURE__*/React__default.createElement("div", { className: "ellipsis-text" }, name)), /*#__PURE__*/React__default.createElement("li", { className: "ui-actions-holder" }, /*#__PURE__*/React__default.createElement("small", null, lastModifiedDate || fileSizeDisplay(size)), uploadedError && showResetButton && /*#__PURE__*/React__default.createElement(Icon, { type: "bc-icon-upload-reset", "data-index": index, onClick: onRetry }), showPreviewButton && /*#__PURE__*/React__default.createElement(Icon, { type: "bc-icon-activate", appearance: "minimal", "data-index": index, onClick: () => toPreview(file) }), showRemoveButton && /*#__PURE__*/React__default.createElement(Icon, { type: "bc-icon-trash", appearance: "minimal", "data-index": index, onClick: onRemove }), showDownloadButton && /*#__PURE__*/React__default.createElement(Icon, { type: "bc-icon-download", appearance: "minimal", "data-index": index, onClick: () => onDownload(file.path, file.name, customHeaders) }))))); } UploadedItem.propTypes = { file: PropTypes.object, index: PropTypes.number, isBusy: PropTypes.bool, showTrash: PropTypes.bool, notUploadedFileList: PropTypes.array, onRemove: PropTypes.func, onRetry: PropTypes.func, retryIndex: PropTypes.number, uploadErrorText: PropTypes.string, appearance: PropTypes.oneOf(uploaderConfig.uploadedItemsAppearance), showDownloadButton: PropTypes.bool, showRemoveButton: PropTypes.bool, showResetButton: PropTypes.bool, showPreviewButton: PropTypes.bool }; UploadedItem.defaultProps = { appearance: uploaderConfig.uploadedItemsAppearance[0], isBusy: false, uploadErrorText: 'Upload Error', onRetry: noop, onRemove: noop, showDownloadButton: true, showRemoveButton: true, showResetButton: true, showPreviewButton: true }; var css_248z$1 = "[data-gene-ui-version=\"2.16.5\"] .drop-area-holder{max-width:100%;position:relative;transition:opacity .4s}[data-gene-ui-version=\"2.16.5\"] .drop-area-holder.disabled{opacity:.5;pointer-events:none}[data-gene-ui-version=\"2.16.5\"] .drop-area-holder:not(.ua-button){width:100%}[data-gene-ui-version=\"2.16.5\"] .drop-area-holder.ua-input .uploader-chooser-holder{display:grid;grid-template-areas:\"input button\";grid-template-columns:1fr auto;position:relative}[data-gene-ui-version=\"2.16.5\"] .drop-area-holder.ua-input .uploader-chooser-holder .input-holder{grid-area:input}html:not([dir=rtl]) .drop-area-holder.ua-input .uploader-chooser-holder .input-element-back{border-top-right-radius:0}html[dir=rtl] .drop-area-holder.ua-input .uploader-chooser-holder .input-element-back{border-top-left-radius:0}html:not([dir=rtl]) .drop-area-holder.ua-input .uploader-chooser-holder .input-element-back{border-bottom-right-radius:0}html[dir=rtl] .drop-area-holder.ua-input .uploader-chooser-holder .input-element-back{border-bottom-left-radius:0}html:not([dir=rtl]) .drop-area-holder.ua-input .uploader-chooser-holder .input-element-back{border-right:0}html[dir=rtl] .drop-area-holder.ua-input .uploader-chooser-holder .input-element-back{border-left:0}[data-gene-ui-version=\"2.16.5\"] .drop-area-holder.ua-input .uploader-chooser-holder .btn{grid-area:button}html:not([dir=rtl]) .drop-area-holder.ua-input .uploader-chooser-holder .btn{border-top-left-radius:0}html[dir=rtl] .drop-area-holder.ua-input .uploader-chooser-holder .btn{border-top-right-radius:0}html:not([dir=rtl]) .drop-area-holder.ua-input .uploader-chooser-holder .btn{border-bottom-left-radius:0}html[dir=rtl] .drop-area-holder.ua-input .uploader-chooser-holder .btn{border-bottom-right-radius:0}html:not([dir=rtl]) .drop-area-holder.ua-input .uploader-chooser-holder .btn{border-left:0}html[dir=rtl] .drop-area-holder.ua-input .uploader-chooser-holder .btn{border-right:0}[data-gene-ui-version=\"2.16.5\"] .drop-area-holder.ua-input .uploader-chooser-holder.dirty input[type=file]{grid-area:input}[data-gene-ui-version=\"2.16.5\"] .drop-area-holder.ua-box .uploader-chooser-holder{padding:100% 0 0;position:relative}[data-gene-ui-version=\"2.16.5\"] .uploader-chooser-holder{display:block;transition:opacity .4s}[data-gene-ui-version=\"2.16.5\"] .drop-area-holder.active .uploader-chooser-holder{opacity:0}[data-gene-ui-version=\"2.16.5\"] .uploader-chooser-holder input[type=file]{cursor:pointer;height:100%;left:0;opacity:0;position:absolute;top:0;width:100%;z-index:1}[data-gene-ui-version=\"2.16.5\"] .uploader-chooser-holder input[type=file]::-webkit-file-upload-button{visibility:hidden}[data-gene-ui-version=\"2.16.5\"] .drop-here-element{align-items:center;background:rgba(var(--hero-rgb),.1);border:1px dashed var(--hero);border-radius:1rem;color:var(--hero);display:flex;font:600 1.4rem/1.8rem var(--font-family);height:100%;justify-content:center;left:0;padding:0 1rem;pointer-events:none;position:absolute;top:0;transition:opacity .4s;width:100%;z-index:10}[data-gene-ui-version=\"2.16.5\"] .drop-area-holder:not(.active) .drop-here-element{opacity:0}[data-gene-ui-version=\"2.16.5\"] .ua-button .drop-here-element.cr-round,[data-gene-ui-version=\"2.16.5\"] .ua-input .drop-here-element.cr-round{border-radius:3.6rem}[data-gene-ui-version=\"2.16.5\"] .ua-button .drop-here-element.cr-smooth,[data-gene-ui-version=\"2.16.5\"] .ua-input .drop-here-element.cr-smooth{border-radius:.4rem}[data-gene-ui-version=\"2.16.5\"] .ua-cloud .drop-here-element{border-radius:.8rem}[data-gene-ui-version=\"2.16.5\"] .cloud-box-uploader{align-items:center;border:1px dashed rgba(var(--background-sc-rgb),.2);border-radius:.8rem;display:flex;flex-direction:column;font:600 2rem/2.4rem var(--font-family);justify-content:center;min-height:28rem;text-align:center;transition:background .4s,border-color .4s;width:100%}[data-gene-ui-version=\"2.16.5\"] .uploader-chooser-holder:hover .cloud-box-uploader{background:rgba(var(--hero-rgb),.02);border-color:var(--hero)}[data-gene-ui-version=\"2.16.5\"] .s-uploading .cloud-box-uploader{background:rgba(var(--background-sc-rgb),.01)}[data-gene-ui-version=\"2.16.5\"] .cloud-box-uploader.error{background:rgba(var(--danger-rgb),.02);border-color:var(--danger)}[data-gene-ui-version=\"2.16.5\"] .cloud-box-uploader>p{opacity:.8}[data-gene-ui-version=\"2.16.5\"] .cloud-box-uploader>.icon{font-size:9.6rem;margin:1rem 0 .4rem;opacity:.23}[data-gene-ui-version=\"2.16.5\"] .cloud-box-uploader>h5{font:inherit;opacity:.8}[data-gene-ui-version=\"2.16.5\"] .cloud-box-uploader>small{display:block;font:600 1.4rem/1.8rem var(--font-family);margin:1rem 0 1.5rem;opacity:.5}[data-gene-ui-version=\"2.16.5\"] .box-uploader{align-items:center;border:1px dashed rgba(var(--background-sc-rgb),.2);border-radius:1rem;display:flex;flex-direction:column;height:100%;justify-content:center;left:0;position:absolute;text-align:center;top:0;transition:background .4s,border-color .4s;width:100%}[data-gene-ui-version=\"2.16.5\"] .uploader-chooser-holder:hover .box-uploader{background:rgba(var(--hero-rgb),.02);border-color:var(--hero)}[data-gene-ui-version=\"2.16.5\"] .s-uploading .box-uploader{border-style:solid}[data-gene-ui-version=\"2.16.5\"] .box-uploader.error{background:rgba(var(--danger-rgb),.02);border-color:var(--danger)}[data-gene-ui-version=\"2.16.5\"] .box-uploader h5{font:600 1.4rem/normal var(--font-family);margin:1rem 0 0;opacity:.8}[data-gene-ui-version=\"2.16.5\"] .box-uploader .responsive-plus-icon-holder{max-height:6.4rem;max-width:6.4rem;min-height:3.6rem;min-width:3.6rem;opacity:.2;width:23.2456140351%}[data-gene-ui-version=\"2.16.5\"] .responsive-plus-icon{padding:100% 0 0;position:relative}[data-gene-ui-version=\"2.16.5\"] .responsive-plus-icon:after,[data-gene-ui-version=\"2.16.5\"] .responsive-plus-icon:before{background:var(--background-sc);border-radius:1rem;content:\"\";display:block;left:50%;padding:7.5471698113% 0 0;position:absolute;top:50%;width:88.679245283%}[data-gene-ui-version=\"2.16.5\"] .responsive-plus-icon:before{transform:translate(-50%,-50%)}[data-gene-ui-version=\"2.16.5\"] .responsive-plus-icon:after{transform:translate(-50%,-50%) rotate(90deg)}"; styleInject(css_248z$1); const UploadView = /*#__PURE__*/forwardRef((_ref, ref) => { let { immediatelyUploadAfterSelect, inputCornerRadius, startUploadLabel, chooseFileLabel, dropHereLabel, cornerRadius, loadingLabel, browseLabel, appearance, isDisabled, className, draggable, typesList, onUpload, multiple, isValid, isBusy, icon, ...restProps } = _ref; const handleChange = useCallback(e => { onUpload && onUpload(e); e.target.value = ''; }, [onUpload]); const acceptTypes = useMemo(() => typesList.map(type => ".".concat(type)).toString(), [typesList]); const dirty = false; const renderUploadHolder = () => { const placeholder = isBusy ? loadingLabel : chooseFileLabel; switch (appearance) { case uploaderConfig.uploaderAppearance[0]: return /*#__PURE__*/React__default.createElement(Button, { appearance: "outline", cornerRadius: cornerRadius, color: isValid ? '' : 'danger', icon: isBusy ? 'bc-icon-loader' : icon }, placeholder); case uploaderConfig.uploaderAppearance[1]: return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(ExtendedInput, { cornerRadius: inputCornerRadius, placeholder: placeholder, inputSize: "big", writeProtected: true, colorBorderOnError: true, isValid: isValid }), /*#__PURE__*/React__default.createElement(Button, { cornerRadius: cornerRadius, size: "big", icon: isBusy ? 'bc-icon-loader' : '', color: isValid ? 'confirm' : 'danger' }, browseLabel)); case uploaderConfig.uploaderAppearance[2]: return /*#__PURE__*/React__default.createElement("div", { className: classnames('cloud-box-uploader', { error: !isValid }) }, isBusy ? /*#__PURE__*/React__default.createElement("p", null, loadingLabel) : /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(Icon, { type: icon || 'bc-icon-cloud-upload' }), /*#__PURE__*/React__default.createElement("h5", null, chooseFileLabel), /*#__PURE__*/React__default.createElement("small", null, "or"), /*#__PURE__*/React__default.createElement(Button, { cornerRadius: cornerRadius, color: isValid ? '' : 'danger' }, browseLabel))); case uploaderConfig.uploaderAppearance[3]: return /*#__PURE__*/React__default.createElement("div", { className: classnames('box-uploader', { error: !isValid }) }, /*#__PURE__*/React__default.createElement(BusyLoader, { isBusy: isBusy, loadingText: loadingLabel, className: "p-absolute" }, /*#__PURE__*/React__default.createElement("div", { className: "responsive-plus-icon-holder" }, /*#__PURE__*/React__default.createElement("div", { className: "responsive-plus-icon" })), /*#__PURE__*/React__default.createElement("h5", null, chooseFileLabel))); } }; return /*#__PURE__*/React__default.createElement("ul", _extends({ className: classnames('drop-area-holder', className, "ua-".concat(appearance), { active: draggable, disabled: isDisabled, 'pointer-events-none s-uploading': isBusy }), ref: ref }, restProps), /*#__PURE__*/React__default.createElement("label", { className: classnames('uploader-chooser-holder', { dirty }) }, renderUploadHolder(), /*#__PURE__*/React__default.createElement("input", { type: "file", onChange: handleChange, disabled: isDisabled, accept: acceptTypes, title: "", multiple: multiple })), !isDisabled && /*#__PURE__*/React__default.createElement("div", { className: classnames('drop-here-element', "cr-".concat(cornerRadius)) }, /*#__PURE__*/React__default.createElement("p", { className: "ellipsis-text" }, dropHereLabel))); }); UploadView.propTypes = { appearance: PropTypes.oneOf(uploaderConfig.uploaderAppearance), immediatelyUploadAfterSelect: PropTypes.bool, onUpload: PropTypes.func.isRequired, draggable: PropTypes.bool, icon: PropTypes.string, cornerRadius: 'smooth', inputCornerRadius: ExtendedInput.propTypes.cornerRadius, isDisabled: PropTypes.bool, isBusy: PropTypes.bool, chooseFileLabel: PropTypes.string, browseLabel: PropTypes.string, startUploadLabel: PropTypes.string, dropHereLabel: PropTypes.string, loadingLabel: PropTypes.string, className: PropTypes.string, isValid: PropTypes.bool, typesList: PropTypes.arrayOf(PropTypes.string) }; UploadView.defaultProps = { appearance: uploaderConfig.uploaderAppearance[0], immediatelyUploadAfterSelect: true, draggable: false, cornerRadius: 'smooth', inputCornerRadius: ExtendedInput.defaultProps.cornerRadius, isDisabled: false, isBusy: false, chooseFileLabel: 'Upload File', browseLabel: 'Browse', startUploadLabel: 'Start Upload', dropHereLabel: 'Drop here', loadingLabel: 'Uploading...', typesList: [], isValid: true, multiple: false }; var css_248z = "[data-gene-ui-version=\"2.16.5\"] .uploader-holder{align-items:flex-start;display:flex;flex-direction:column;width:100%}[data-gene-ui-version=\"2.16.5\"] .uploader-holder .grid-child{min-height:2.8rem;position:relative}[data-gene-ui-version=\"2.16.5\"] .uploader-header{align-items:flex-start;display:flex;flex-direction:column;width:100%}[data-gene-ui-version=\"2.16.5\"] .uploader-header:not(.only-child){margin:0 0 1.4rem}[data-gene-ui-version=\"2.16.5\"] .uploader-footer{align-items:flex-start;display:flex;flex-direction:column;width:100%}[data-gene-ui-version=\"2.16.5\"] .ua-cloud>.uploader-footer{align-items:center}[data-gene-ui-version=\"2.16.5\"] .ua-input>.uploader-footer{padding:0 2rem}[data-gene-ui-version=\"2.16.5\"] .uploader-footer .uploader-footer-button{margin:1.8rem 0 0}"; styleInject(css_248z); const lowGrid = 10; const highGrid = 20; function Uploader(_ref) { let { immediatelyUploadAfterSelect, uploadedItemsAppearance, informationMessage, uploaderAppearance, inputCornerRadius, allTypesAccepted, startUploadLabel, noFileChosenText, chooseFileLabel, getInitialState, showLocalErrors, metaDataHeaders, showDownloadButton, showResetButton, showPreviewButton, uploadErrorText, uploadingLabel, fileChosenText, fileAppearance, customHeaders, isImageUpload, dropHereLabel, maxFileCount, cornerRadius, deleteAction, sizeErrorMsg, typeErrorMsg, isActiveDrop, loadingLabel, browseLabel, maxFileSize, isDisabled, typesList, showTrash, className, draggText, onChange, required, multiple, isValid, upload, icon, data, initialData, images, initialImages, additionalContext, hideName, ...restProps } = _ref; const isControlled = useMemo(() => Array.isArray(images), [images]); const dropRef = useRef(null); const [fileList, setFileList] = useState(generateFilesByPage(initialImages)); const [deletedFileList, setDeletedFileList] = useState([]); const [errorMsg, setErrorMsg] = useState(''); const [notUploadedFileList, setNotUploadedFileList] = useState([]); const [draggable, setDraggable] = useState(false); const [isBusy, setIsBusy] = useState(false); const [refreshIndex, setRefreshIndex] = useState(null); const [valid, setValidation] = useState(true); useEffect(() => { isControlled && setFileList(generateFilesByPage(images)); }, [isControlled, images]); useEffect(() => getInitialState && getInitialState(valid), [getInitialState, valid]); useEffect(() => setValidation(required ? !!fileList.length : true), [fileList, required]); useEffect(() => { if (Array.isArray(data)) { if (data && data.length > 0) { setIsBusy(true); Promise.all([...data.map(file => getFileByUrl(file.path, file, isImageUpload, customHeaders))]).then(res => { setFileList(res); }).finally(() => setIsBusy(false)); } else { setFileList([]); } } }, [data, isImageUpload]); const startUpload = useCallback((uploadedFiles, deletedFiles) => { setIsBusy(true); return new Promise((resolve, reject) => { upload({ uploadedFiles, deletedFiles }).then(resolve).catch(reject).finally(() => setIsBusy(false)); }); }, [upload]); const fileChangeHandler = useCallback((newList, del) => { !isControlled && (!multiple || del) && setFileList(prev => maxFileCount >= prev.length ? newList : prev); !isControlled && multiple && !del && setFileList(prev => maxFileCount > prev.length ? [newList[0], ...prev] : prev); onChange({ value: newList }); }, [isControlled, onChange]); const checkFileValidation = useCallback(file => { if (file.size) { const { isValidSize, isValidType } = isValidFile({ allTypesAccepted, isImageUpload, maxFileSize, typesList, file }); if (showLocalErrors) { const msg = isValidSize ? isValidType ? '' : typeErrorMsg.replace(typeListReplacer, typesList.join(', ')) : sizeErrorMsg.replace(maxFileSizeReplacer, maxFileSize); setErrorMsg(msg); } return isValidSize && isValidType; } }, [allTypesAccepted, isImageUpload, maxFileSize, typesList, showLocalErrors, typeErrorMsg, sizeErrorMsg]); const addFile = useCallback(async file => { if (checkFileValidation(file)) { const blobFile = await toBlobFile(file, isImageUpload); const newList = maxFileCount ? [blobFile, ...fileList].slice(0, maxFileCount) : [blobFile, ...fileList]; if (immediatelyUploadAfterSelect && upload) { startUpload(newList, deletedFileList).catch(error => { setNotUploadedFileList([{ file: blobFile, error }, ...notUploadedFileList]); }).finally(() => { fileChangeHandler(newList, false); }); } else { fileChangeHandler(newList, false); } } }, [checkFileValidation, isImageUpload, maxFileCount, fileList.length, immediatelyUploadAfterSelect, upload, startUpload, deletedFileList, notUploadedFileList, fileChangeHandler]); const handleDrop = useCallback(e => { stopEvent(e, true); setDraggable(false); const { dataTransfer: { files = [] } } = e; if (isActiveDrop && files.length) { addFile(files[0]); } }, [isActiveDrop, addFile]); const handleDragIn = useCallback(e => { stopEvent(e, true); e.dataTransfer.items.length && setDraggable(true); }, []); const handleDragOut = useCallback(e => { stopEvent(e, true); setDraggable(false); }, []); useEffect(() => { const div = dropRef.current; if (div && !isBusy) { addDragEventListener(div, handleDragIn, handleDragOut, handleDrop); return () => { removeDragEventListener(div, handleDragIn, handleDragOut, handleDrop); }; } }, [handleDrop, dropRef.current, isBusy]); const onUpload = useCallback(e => { for (const file in e.target.files) addFile(e.target.files[file]); e.target.value = null; }, [addFile]); const doUpload = useCallback(e => { stopEvent(e, true); if (upload && fileList.length) { setNotUploadedFileList([]); startUpload(fileList, deletedFileList).then(_ref2 => { let { fileErrors } = _ref2; fileErrors && setNotUploadedFileList([...fileErrors]); }).catch(() => setNotUploadedFileList([...fileList])); } }, [upload, fileList, startUpload, deletedFileList]); const deleteItemByIndex = useCallback(e => { const { index } = e.currentTarget.dataset; const newList = [...fileList]; newList.splice(index, 1); if (data && data.find(file => file.id === (fileList[index] && fileList[index].id))) { setDeletedFileList([...deletedFileList, fileList[index]]); if (isImageUpload) { deleteAction(fileList[index]); } } fileChangeHandler(newList, true); }, [fileList, data, fileChangeHandler, deletedFileList, isImageUpload, deleteAction]); const uploadRefresh = useCallback(e => { const { index } = e.currentTarget.dataset; const file = fileList[index]; if (file && upload) { setRefreshIndex(Number(index)); startUpload(file, deletedFileList).then(() => { const newList = notUploadedFileList.filter(notUploaded => notUploaded.file !== file); setNotUploadedFileList(newList); }).finally(() => setRefreshIndex(null)); } }, [startUpload, notUploadedFileList, fileList, upload, deletedFileList]); const isBoxApperance = uploaderAppearance === uploaderConfig.uploaderAppearance[3]; const gridGap = isBoxApperance ? highGrid : lowGrid; const isExistFile = !!fileList.length; return /*#__PURE__*/React__default.createElement("div", _extends({ className: classnames('uploader-holder', "ua-".concat(uploaderAppearance), className) }, restProps), !isBoxApperance && /*#__PURE__*/React__default.createElement("div", { className: classnames('uploader-header', { 'only-child': !isExistFile }) }, /*#__PURE__*/React__default.createElement(UploadView, { appearance: uploaderAppearance, immediatelyUploadAfterSelect: immediatelyUploadAfterSelect, onUpload: onUpload, ref: dropRef, draggable: draggable, icon: icon, cornerRadius: cornerRadius, isDisabled: isDisabled, isBusy: isBusy, chooseFileLabel: chooseFileLabel, browseLabel: browseLabel, startUploadLabel: startUploadLabel, dropHereLabel: dropHereLabel, loadingLabel: loadingLabel, isValid: isValid, typesList: typesList, multiple: multiple })), (isExistFile || isBoxApperance) && /*#__PURE__*/React__default.createElement(Row, { padding: gridGap, gutter: gridGap }, fileList.map((file, index) => /*#__PURE__*/React__default.createElement(Col, _extends({}, uploaderConfig.gridColumnSize, { key: index }), /*#__PURE__*/React__default.createElement(UploadedItem, { file: file, index: index, isBusy: isBusy, onRetry: uploadRefresh, retryIndex: refreshIndex, showRemoveButton: showTrash, onRemove: deleteItemByIndex, uploadErrorText: uploadErrorText, showResetButton: showResetButton, metaDataHeaders: metaDataHeaders, appearance: uploadedItemsAppearance, showPreviewButton: showPreviewButton, additionalContext: additionalContext, showDownloadButton: showDownloadButton, notUploadedFileList: notUploadedFileList, customHeaders: customHeaders, hideName: hideName }))), isBoxApperance && /*#__PURE__*/React__default.createElement(Col, uploaderConfig.gridColumnSize, /*#__PURE__*/React__default.createElement(UploadView, { appearance: uploadedItemsAppearance }))), /*#__PURE__*/React__default.createElement("div", { className: "uploader-footer" }, (informationMessage || showLocalErrors && errorMsg) && /*#__PURE__*/React__default.createElement("div", { className: classnames('information-message', { 'color-danger': !!errorMsg }) }, errorMsg || informationMessage), !immediatelyUploadAfterSelect && isExistFile && uploaderAppearance !== uploaderConfig.uploaderAppearance[1] && /*#__PURE__*/React__default.createElement("div", { className: "uploader-footer-button" }, /*#__PURE__*/React__default.createElement(Button, { onClick: doUpload, disabled: isDisabled || isBusy, cornerRadius: cornerRadius }, startUploadLabel)))); } Uploader.propTypes = { /** * Disable type check */ allTypesAccepted: PropTypes.bool, /** * Browse label text */ browseLabel: PropTypes.string, /** * Choose file label text */ chooseFileLabel: PropTypes.string, /** * Your custom className, for div */ className: PropTypes.string, /** * Button corner radius */ cornerRadius: 'smooth', /** * ExtendedInput corner radius */ inputCornerRadius: ExtendedInput.propTypes.cornerRadius, /** * Default data for loaded items. The data array should have: * path - URL to file/image, * name - file/image display name, * id - unique identifier, */ data: PropTypes.arrayOf(PropTypes.shape({ path: PropTypes.string, name: PropTypes.string, id: PropTypes.number })), /** * Delete action to process delete default data deleteAction((file: deletedFile) => void) */ deleteAction: PropTypes.func, /** * Drop here label text */ dropHereLabel: PropTypes.string, /** * Size error message. If in the string you write MAX_FILE_SIZE it will be replaced maxFileSize prop. */ sizeErrorMsg: PropTypes.string, /** * Type error message. If in the string you write TYPE_LIST it will be replaced typesList prop. */ typeErrorMsg: PropTypes.string, getInitialState: PropTypes.func, /** * Upload holder icon */ icon: PropTypes.string, /** * Immediate upload after selecting or using the "Start Upload" button. */ immediatelyUploadAfterSelect: PropTypes.bool, /** * Information message text */ informationMessage: PropTypes.string, /** * Activation drugover */ isActiveDrop: PropTypes.bool, /** * Disable uploader */ isDisabled: PropTypes.bool, /** * Enable image upload mode */ isImageUpload: PropTypes.bool, /** * Loading label text */ loadingLabel: PropTypes.string, /** * Max upload file size in bytes */ maxFileSize: PropTypes.number, /** * File list changes handling onChange((files: fileList) => void); */ onChange: PropTypes.func, /** * Required file */ required: PropTypes.bool, /** * Show local validation errors */ showLocalErrors: PropTypes.bool, /** * Start upload label text */ startUploadLabel: PropTypes.string, /** * Array of upload item types */ typesList: PropTypes.arrayOf(PropTypes.string), /** * Upload file function, upload((files: {uploadedFiles, deletedFiles}) => Promise); */ upload: PropTypes.func, /** * Uploaded items appearance */ uploadedItemsAppearance: PropTypes.oneOf(uploaderConfig.uploadedItemsAppearance), /** * Uploader appearance */ uploaderAppearance: PropTypes.oneOf(uploaderConfig.uploaderAppearance), /** * Upload error text showing in tooltip */ uploadErrorText: PropTypes.string, /** * Maximum upload file count */ maxFileCount: PropTypes.number, /** * Control Uploader validation. */ isValid: PropTypes.bool, /** * Show/Hide trash icon */ showTrash: PropTypes.bool, /** * Show/Hide Reset icon */ showResetButton: PropTypes.bool, /** * Show/Hide Preview icon */ showPreviewButton: PropTypes.bool, /** * Show/Hide Download icon */ showDownloadButton: PropTypes.bool, /** * initialImages - an array of URL strings. Use to specify the initial value of the component. * * NOTE: previously, data property could be used to handle the component value. Now, instead * of using entire image objects, you can use just URL strings with images and initialImages props */ initialImages: PropTypes.arrayOf(PropTypes.string), /** * images - an array of URL strings; required for a controlled component */ images: PropTypes.arrayOf(PropTypes.string), /** * change files size with any custom string. */ additionalContext: PropTypes.string, /** * multi file upload option. */ multiple: PropTypes.bool, /** * This is for fetch image for example through this prop you can pass token. * Provide an Object that will spread in Request Headers:{...customHeaders} in second parameter for fetch function. * For example { 'Content-Type': 'application/json'} it will convert fetch(URL,{headers{'Content-Type': 'application/json'}}) */ customHeaders: PropTypes.object, /** * set true to hide image name from preview mode. */ hideName: PropTypes.bool, /** * metaDataHeaders is an object where type can be "LAST-MODIFIED" (for future requirement can be added new types) and * formatter that returns callback function with 'last modified data string' parameter that can be formatted and returned. * { * type: "LAST-MODIFIED", * formatter:(date)=>{return new Date(date).toLocaleDateString()} * } */ metaDataHeaders: PropTypes.shape({ type: PropTypes.string, formatter: PropTypes.func }) }; Uploader.defaultProps = { allTypesAccepted: true, browseLabel: 'Browse', chooseFileLabel: 'Upload File', cornerRadius: 'smooth', inputCornerRadius: ExtendedInput.defaultProps.cornerRadius, dropHereLabel: 'Drop here', sizeErrorMsg: "File must be smaller than ".concat(maxFileSizeReplacer, " bytes."), typeErrorMsg: "You can only upload ".concat(typeListReplacer, " File."), immediatelyUploadAfterSelect: true, isActiveDrop: false, isDisabled: false, isImageUpload: false, loadingLabel: 'Uploading...', maxFileSize: 5000000, required: false, showTrash: true, showDownloadButton: true, showResetButton: true, showPreviewButton: true, showLocalErrors: false, startUploadLabel: 'Start Upload', typesList: [], uploadedItemsAppearance: uploaderConfig.uploadedItemsAppearance[0], uploaderAppearance: uploaderConfig.uploaderAppearance[0], uploadErrorText: 'Upload Error', onChange: noop, isValid: true, hideName: false }; export { Uploader as default };