UNPKG

@mskcc/carbon-react

Version:

Carbon react components for the MSKCC DSM

214 lines (205 loc) 6.75 kB
/** * 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;