@mskcc/carbon-react
Version:
Carbon react components for the MSKCC DSM
228 lines (224 loc) • 7.13 kB
JavaScript
/**
* MSKCC 2021, 2024
*/
import { defineProperty as _defineProperty, extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
import cx from 'classnames';
import PropTypes from 'prop-types';
import React__default from 'react';
import Filename from './Filename.js';
import FileUploaderButton from './FileUploaderButton.js';
import { PrefixContext } from '../../internal/usePrefix.js';
import { ButtonKinds } from '../Button/Button.js';
import '../Button/Button.Skeleton.js';
import { matches } from '../../internal/keyboard/match.js';
import { Enter, Space } from '../../internal/keyboard/keys.js';
class FileUploader extends React__default.Component {
constructor() {
super(...arguments);
_defineProperty(this, "state", {
filenames: []
});
_defineProperty(this, "nodes", []);
_defineProperty(this, "uploaderButton", /*#__PURE__*/React__default.createRef());
_defineProperty(this, "handleChange", evt => {
evt.stopPropagation();
const filenames = Array.prototype.map.call(evt.target.files, file => file.name);
this.setState({
filenames: this.props.multiple ? this.state.filenames.concat(filenames) : filenames
});
if (this.props.onChange) {
this.props.onChange(evt);
}
});
_defineProperty(this, "handleClick", (evt, _ref) => {
let {
index,
filenameStatus
} = _ref;
if (filenameStatus === 'edit') {
evt.stopPropagation();
const filteredArray = this.state.filenames.filter(filename => filename !== this.nodes[index].innerText.trim());
this.setState({
filenames: filteredArray
});
if (this.props.onDelete) {
this.props.onDelete(evt);
this.uploaderButton.current?.focus?.();
}
this.props.onClick?.(evt);
}
});
_defineProperty(this, "clearFiles", () => {
// A clearFiles function that resets filenames and can be referenced using a ref by the parent.
this.setState({
filenames: []
});
});
}
static getDerivedStateFromProps(_ref2, state) {
let {
filenameStatus
} = _ref2;
const {
prevFilenameStatus
} = state;
return prevFilenameStatus === filenameStatus ? null : {
filenameStatus,
prevFilenameStatus: filenameStatus
};
}
render() {
const {
iconDescription,
buttonLabel,
buttonKind,
disabled,
filenameStatus,
labelDescription,
labelTitle,
className,
multiple,
accept,
name,
size = 'md',
onDelete,
// eslint-disable-line
...other
} = this.props;
const prefix = this.context;
const classes = cx({
[`${prefix}--form-item`]: true,
[className]: className
});
const getHelperLabelClasses = baseClass => cx(baseClass, {
[`${prefix}--label-description--disabled`]: disabled
});
const selectedFileClasses = cx(`${prefix}--file__selected-file`, {
[`${prefix}--file__selected-file--md`]: size === 'md',
[`${prefix}--file__selected-file--sm`]: size === 'sm'
});
return /*#__PURE__*/React__default.createElement("div", _extends({
className: classes
}, other), !labelTitle ? null : /*#__PURE__*/React__default.createElement("p", {
className: getHelperLabelClasses(`${prefix}--file--label`)
}, labelTitle), /*#__PURE__*/React__default.createElement("p", {
className: getHelperLabelClasses(`${prefix}--label-description`)
}, labelDescription), /*#__PURE__*/React__default.createElement(FileUploaderButton, {
innerRef: this.uploaderButton,
disabled: disabled,
labelText: buttonLabel,
multiple: multiple,
buttonKind: buttonKind,
onChange: this.handleChange,
disableLabelChanges: true,
accept: accept,
name: name,
size: size
}), /*#__PURE__*/React__default.createElement("div", {
className: `${prefix}--file-container`
}, this.state.filenames.length === 0 ? null : this.state.filenames.map((name, index) => /*#__PURE__*/React__default.createElement("span", _extends({
key: index,
className: selectedFileClasses,
ref: node => this.nodes[index] = node // eslint-disable-line
}, other), /*#__PURE__*/React__default.createElement("p", {
className: `${prefix}--file-filename`,
id: name
}, name), /*#__PURE__*/React__default.createElement("span", {
className: `${prefix}--file__state-container`
}, /*#__PURE__*/React__default.createElement(Filename, {
name: name,
iconDescription: iconDescription,
status: filenameStatus,
onKeyDown: evt => {
if (matches(evt, [Enter, Space])) {
this.handleClick(evt, {
index,
filenameStatus
});
}
},
onClick: evt => this.handleClick(evt, {
index,
filenameStatus
})
}))))));
}
}
_defineProperty(FileUploader, "propTypes", {
/**
* Specify the types of files that this input should be able to receive
*/
accept: PropTypes.arrayOf(PropTypes.string),
/**
* Specify the type of the `<FileUploaderButton>`
*/
buttonKind: PropTypes.oneOf(ButtonKinds),
/**
* Provide the label text to be read by screen readers when interacting with
* the `<FileUploaderButton>`
*/
buttonLabel: PropTypes.string,
/**
* Provide a custom className to be applied to the container node
*/
className: PropTypes.string,
/**
* Specify whether file input is disabled
*/
disabled: PropTypes.bool,
/**
* Specify the status of the File Upload
*/
filenameStatus: PropTypes.oneOf(['edit', 'complete', 'uploading']).isRequired,
/**
* Provide a description for the complete/close icon that can be read by screen readers
*/
iconDescription: PropTypes.string.isRequired,
/**
* Specify the description text of this `<FileUploader>`
*/
labelDescription: PropTypes.string,
/**
* Specify the title text of this `<FileUploader>`
*/
labelTitle: PropTypes.string,
/**
* Specify if the component should accept multiple files to upload
*/
multiple: PropTypes.bool,
/**
* Provide a name for the underlying `<input>` node
*/
name: PropTypes.string,
/**
* Provide an optional `onChange` hook that is called each time the input is
* changed
*/
onChange: PropTypes.func,
/**
* Provide an optional `onClick` hook that is called each time the
* FileUploader is clicked
*/
onClick: PropTypes.func,
/**
* Provide an optional `onDelete` hook that is called when an uploaded item
* is removed
*/
onDelete: PropTypes.func,
/**
* Specify the size of the FileUploaderButton, from a list of available
* sizes.
*/
size: PropTypes.oneOf(['sm', 'md', 'lg'])
});
_defineProperty(FileUploader, "contextType", PrefixContext);
_defineProperty(FileUploader, "defaultProps", {
disabled: false,
filenameStatus: 'uploading',
buttonLabel: '',
buttonKind: 'primary',
multiple: false,
onClick: () => {},
accept: []
});
export { FileUploader as default };