@mskcc/carbon-react
Version:
Carbon react components for the MSKCC DSM
214 lines (205 loc) • 6.75 kB
JavaScript
/**
* MSKCC 2021, 2024
*/
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
var React = require('react');
var PropTypes = require('prop-types');
var cx = require('classnames');
var uniqueId = require('../../tools/uniqueId.js');
var usePrefix = require('../../internal/usePrefix.js');
var events = require('../../tools/events.js');
var deprecate = require('../../prop-types/deprecate.js');
var match = require('../../internal/keyboard/match.js');
var keys = require('../../internal/keyboard/keys.js');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
function FileUploaderDropContainer(_ref) {
let {
accept,
className,
id,
disabled,
labelText,
multiple,
name,
onAddFiles,
onClick,
pattern,
// eslint-disable-next-line react/prop-types
innerRef,
...rest
} = _ref;
const prefix = usePrefix.usePrefix();
const inputRef = React.useRef(null);
const {
current: uid
} = React.useRef(id || uniqueId["default"]());
const [isActive, setActive] = React.useState(false);
const dropareaClasses = cx__default["default"](`${prefix}--file__drop-container`, `${prefix}--file-browse-btn`, {
[`${prefix}--file__drop-container--drag-over`]: isActive,
[`${prefix}--file-browse-btn--disabled`]: disabled,
[className]: className
});
/**
* Filters the array of added files based on file type restrictions
* @param {Event} event - Event object, used to get the list of files added
*/
function validateFiles(event) {
const transferredFiles = event.type === 'drop' ? [...event.dataTransfer.files] : [...event.target.files];
if (!accept.length) {
return transferredFiles;
}
const acceptedTypes = new Set(accept);
return transferredFiles.reduce((acc, curr) => {
const {
name,
type: mimeType = ''
} = curr;
const fileExtensionRegExp = new RegExp(pattern, 'i');
const hasFileExtension = fileExtensionRegExp.test(name);
if (!hasFileExtension) {
return acc;
}
const [fileExtension] = name.match(fileExtensionRegExp);
if (acceptedTypes.has(mimeType) || acceptedTypes.has(fileExtension.toLowerCase())) {
return acc.concat([curr]);
}
curr.invalidFileType = true;
return acc.concat([curr]);
}, []);
}
function handleChange(event) {
const addedFiles = validateFiles(event);
return onAddFiles(event, {
addedFiles
});
}
const handleClick = () => {
if (!disabled) {
inputRef.current?.click();
}
};
return /*#__PURE__*/React__default["default"].createElement("div", {
className: `${prefix}--file`,
onDragOver: evt => {
evt.stopPropagation();
evt.preventDefault();
if (disabled) {
return;
}
setActive(true);
evt.dataTransfer.dropEffect = 'copy';
},
onDragLeave: evt => {
evt.stopPropagation();
evt.preventDefault();
if (disabled) {
return;
}
setActive(false);
evt.dataTransfer.dropEffect = 'move';
},
onDrop: evt => {
evt.stopPropagation();
evt.preventDefault();
if (disabled) {
return;
}
setActive(false);
handleChange(evt);
}
}, /*#__PURE__*/React__default["default"].createElement("button", _rollupPluginBabelHelpers["extends"]({
type: "button",
className: dropareaClasses,
ref: innerRef,
onKeyDown: evt => {
if (match.matches(evt, [keys.Enter, keys.Space])) {
evt.preventDefault();
inputRef.current?.click();
}
},
onClick: events.composeEventHandlers([onClick, handleClick])
}, rest), labelText), /*#__PURE__*/React__default["default"].createElement("label", {
htmlFor: uid,
className: `${prefix}--visually-hidden`
}, labelText), /*#__PURE__*/React__default["default"].createElement("input", {
type: "file",
id: uid,
className: `${prefix}--file-input`,
ref: inputRef,
tabIndex: -1,
disabled: disabled,
accept: accept,
name: name,
multiple: multiple,
onChange: handleChange,
onClick: evt => {
evt.target.value = null;
}
}));
}
FileUploaderDropContainer.propTypes = {
/**
* Specify the types of files that this input should be able to receive
*/
accept: PropTypes__default["default"].arrayOf(PropTypes__default["default"].string),
/**
* Provide a custom className to be applied to the container node
*/
className: PropTypes__default["default"].string,
/**
* Specify whether file input is disabled
*/
disabled: PropTypes__default["default"].bool,
/**
* Provide a unique id for the underlying `<input>` node
*/
id: PropTypes__default["default"].string,
/**
* Provide the label text to be read by screen readers when interacting with
* this control
*/
labelText: PropTypes__default["default"].string.isRequired,
/**
* Specify if the component should accept multiple files to upload
*/
multiple: PropTypes__default["default"].bool,
/**
* Provide a name for the underlying `<input>` node
*/
name: PropTypes__default["default"].string,
/**
* Event handler that is called after files are added to the uploader
* The event handler signature looks like `onAddFiles(evt, { addedFiles })`
*/
onAddFiles: PropTypes__default["default"].func,
/**
* Provide an optional function to be called when the button element
* is clicked
*/
onClick: PropTypes__default["default"].func,
/**
* Provide a custom regex pattern for the acceptedTypes
*/
pattern: PropTypes__default["default"].string,
/**
* Provide an accessibility role for the `<FileUploaderButton>`
*/
role: deprecate["default"](PropTypes__default["default"].number, 'The `role` prop for `FileUploaderButton` has ' + 'been deprecated since it now renders a button element by default, and has an implicit role of button.'),
/**
* Provide a custom tabIndex value for the `<FileUploaderButton>`
*/
tabIndex: deprecate["default"](PropTypes__default["default"].number, 'The `tabIndex` prop for `FileUploaderButton` has ' + 'been deprecated since it now renders a button element by default.')
};
FileUploaderDropContainer.defaultProps = {
labelText: 'Add file',
multiple: false,
onAddFiles: () => {},
accept: [],
pattern: '.[0-9a-z]+$'
};
exports["default"] = FileUploaderDropContainer;